71 #include "table/strings.h"
72 #include "table/settings.h"
82 typedef std::list<ErrorMessageData>
ErrorList;
86 typedef void SettingDescProc(
IniFile *ini,
const SettingDesc *desc,
const char *grpname,
void *
object);
87 typedef void SettingDescProcList(
IniFile *ini,
const char *grpname,
StringList *list);
89 static bool IsSignedVarMemType(VarType vt);
98 "server_bind_addresses",
114 if (onelen == 0) onelen = strlen(one);
117 if (*one >=
'0' && *one <=
'9')
return strtoul(one, NULL, 0);
123 while (*s !=
'|' && *s != 0) s++;
124 if ((
size_t)(s - many) == onelen && !memcmp(one, many, onelen))
return idx;
125 if (*s == 0)
return (
size_t)-1;
146 while (*str ==
' ' || *str ==
'\t' || *str ==
'|') str++;
147 if (*str == 0)
break;
150 while (*s != 0 && *s !=
' ' && *s !=
'\t' && *s !=
'|') s++;
153 if (r == (
size_t)-1)
return r;
179 if (!comma)
return -1;
187 if (n == maxitems)
return -1;
189 long v = strtol(p, &end, 0);
190 if (p == end)
return -1;
191 if (
sizeof(
int) <
sizeof(
long)) v =
ClampToI32(v);
202 if (n != 0 && !comma)
return -1;
215 static bool LoadIntList(
const char *str,
void *array,
int nelems, VarType type)
221 memset(items, 0,
sizeof(items));
225 if (nitems != nelems)
return false;
232 for (i = 0; i != nitems; i++) ((byte*)array)[i] = items[i];
237 for (i = 0; i != nitems; i++) ((uint16*)array)[i] = items[i];
242 for (i = 0; i != nitems; i++) ((uint32*)array)[i] = items[i];
245 default: NOT_REACHED();
260 static void MakeIntList(
char *buf,
const char *last,
const void *array,
int nelems, VarType type)
263 const byte *p = (
const byte *)array;
265 for (i = 0; i != nelems; i++) {
268 case SLE_VAR_I8: v = *(
const int8 *)p; p += 1;
break;
269 case SLE_VAR_U8: v = *(
const uint8 *)p; p += 1;
break;
270 case SLE_VAR_I16: v = *(
const int16 *)p; p += 2;
break;
271 case SLE_VAR_U16: v = *(
const uint16 *)p; p += 2;
break;
272 case SLE_VAR_I32: v = *(
const int32 *)p; p += 4;
break;
273 case SLE_VAR_U32: v = *(
const uint32 *)p; p += 4;
break;
274 default: NOT_REACHED();
276 buf +=
seprintf(buf, last, (i == 0) ?
"%d" :
",%d", v);
287 static void MakeOneOfMany(
char *buf,
const char *last,
const char *many,
int id)
293 for (; *many !=
'|'; many++) {
303 while (*many !=
'\0' && *many !=
'|' && buf < last) *buf++ = *many++;
315 static void MakeManyOfMany(
char *buf,
const char *last,
const char *many, uint32 x)
321 for (; x != 0; x >>= 1, i++) {
323 while (*many != 0 && *many !=
'|') many++;
326 if (!init) buf +=
seprintf(buf, last,
"|");
329 buf +=
seprintf(buf, last,
"%d", i);
331 memcpy(buf, start, many - start);
336 if (*many ==
'|') many++;
350 const char *str = orig_str == NULL ?
"" : orig_str;
355 size_t val = strtoul(str, &end, 0);
364 ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_TRAILING_CHARACTERS);
376 if (r != (
size_t)-1)
return (
void*)r;
387 if (r != (
size_t)-1)
return (
void*)r;
396 if (strcmp(str,
"true") == 0 || strcmp(str,
"on") == 0 || strcmp(str,
"1") == 0)
return (
void*)
true;
397 if (strcmp(str,
"false") == 0 || strcmp(str,
"off") == 0 || strcmp(str,
"0") == 0)
return (
void*)
false;
461 default: NOT_REACHED();
485 for (; sd->
save.
cmd != SL_END; sd++) {
492 s = strchr(sdb->
name,
'.');
501 item = group->
GetItem(s,
false);
502 if (item == NULL && group != group_def) {
505 item = group_def->
GetItem(s,
false);
510 const char *sc = strchr(s,
'.');
511 if (sc != NULL) item = ini->
GetGroup(s, sc - s)->
GetItem(sc + 1,
false);
529 if (p != NULL)
strecpy((
char*)ptr, (
const char*)p, (
char*)ptr + sld->
length - 1);
535 *(
char**)ptr = p == NULL ? NULL :
stredup((
const char*)p);
538 case SLE_VAR_CHAR:
if (p != NULL) *(
char *)ptr = *(
const char *)p;
break;
540 default: NOT_REACHED();
557 default: NOT_REACHED();
582 for (; sd->
save.
cmd != SL_END; sd++) {
592 s = strchr(sdb->
name,
'.');
597 if (group_def == NULL) group_def = ini->
GetGroup(grpname);
602 item = group->GetItem(s,
true);
605 if (item->
value != NULL) {
618 if (*(
bool*)ptr == (p != NULL))
continue;
623 if (*(byte*)ptr == (byte)(
size_t)p)
continue;
628 if (*(uint16*)ptr == (uint16)(
size_t)p)
continue;
633 if (*(uint32*)ptr == (uint32)(
size_t)p)
continue;
636 default: NOT_REACHED();
657 default: NOT_REACHED();
669 if (*(
char**)ptr == NULL) {
676 case SLE_VAR_CHAR: buf[0] = *(
char*)ptr; buf[1] =
'\0';
break;
677 default: NOT_REACHED();
685 default: NOT_REACHED();
707 if (group == NULL || list == NULL)
return;
711 for (
const IniItem *item = group->
item; item != NULL; item = item->
next) {
712 if (item->name != NULL) *list->
Append() =
stredup(item->name);
729 if (group == NULL || list == NULL)
return;
732 for (
char **iter = list->
Begin(); iter != list->
End(); iter++) {
770 (_game_mode == GM_NORMAL ||
771 (_game_mode == GM_EDITOR && !(this->desc.flags &
SGF_SCENEDIT_TOO))))
return false;
797 if (_game_mode != GM_MENU) {
805 static bool PopulationInLabelActive(int32 p1)
811 static bool RedrawScreen(int32 p1)
830 static bool InvalidateDetailsWindow(int32 p1)
836 static bool StationSpreadChanged(int32 p1)
843 static bool InvalidateBuildIndustryWindow(int32 p1)
849 static bool CloseSignalGUI(int32 p1)
857 static bool InvalidateTownViewWindow(int32 p1)
863 static bool DeleteSelectStationWindow(int32 p1)
869 static bool UpdateConsists(int32 p1)
881 static bool CheckInterval(int32 p1)
883 bool update_vehicles;
887 update_vehicles =
false;
890 update_vehicles =
true;
905 if (update_vehicles) {
911 v->SetServiceIntervalIsPercent(p1 != 0);
916 InvalidateDetailsWindow(0);
921 static bool UpdateInterval(
VehicleType type, int32 p1)
923 bool update_vehicles;
927 update_vehicles =
false;
930 update_vehicles =
true;
935 if (interval != p1)
return false;
937 if (update_vehicles) {
941 v->SetServiceInterval(p1);
946 InvalidateDetailsWindow(0);
951 static bool UpdateIntervalTrains(int32 p1)
956 static bool UpdateIntervalRoadVeh(int32 p1)
958 return UpdateInterval(
VEH_ROAD, p1);
961 static bool UpdateIntervalShips(int32 p1)
963 return UpdateInterval(
VEH_SHIP, p1);
966 static bool UpdateIntervalAircraft(int32 p1)
971 static bool TrainAccelerationModelChanged(int32 p1)
1013 FOR_ALL_ROADVEHICLES(rv) {
1036 FOR_ALL_ROADVEHICLES(rv) {
1043 static bool DragSignalsDensityChanged(int32)
1050 static bool TownFoundingChanged(int32 p1)
1060 static bool InvalidateVehTimetableWindow(int32 p1)
1066 static bool ZoomMinMaxChanged(int32 p1)
1068 extern void ConstrainAllViewportsZoom();
1069 ConstrainAllViewportsZoom();
1095 static bool InvalidateCompanyLiveryWindow(int32 p1)
1098 return RedrawScreen(p1);
1101 static bool InvalidateIndustryViewWindow(int32 p1)
1107 static bool InvalidateAISettingsWindow(int32 p1)
1156 static bool DifficultyNoiseChange(int32 i)
1158 if (_game_mode == GM_NORMAL) {
1168 static bool MaxNoAIsChange(int32 i)
1203 static bool CheckFreeformEdges(int32 p1)
1205 if (_game_mode == GM_MENU)
return true;
1216 FOR_ALL_BASE_STATIONS(st) {
1226 for (uint i = 0; i <
MapMaxX(); i++) {
1232 for (uint i = 1; i <
MapMaxX(); i++) {
1238 for (uint i = 0; i <
MapMaxY(); i++) {
1244 for (uint i = 1; i <
MapMaxY(); i++) {
1251 for (uint i = 0; i <
MapMaxX(); i++) {
1255 for (uint i = 0; i <
MapMaxY(); i++) {
1270 if (_game_mode == GM_MENU)
return true;
1280 static bool StationCatchmentChanged(int32 p1)
1287 #ifdef ENABLE_NETWORK
1289 static bool UpdateClientName(int32 p1)
1295 static bool UpdateServerPassword(int32 p1)
1304 static bool UpdateRconPassword(int32 p1)
1313 static bool UpdateClientConfigValues(int32 p1)
1330 memset(_old_diff_custom, 0,
sizeof(_old_diff_custom));
1345 bool old_diff_custom_used =
false;
1346 for (uint i = 0; i < options_to_load && !old_diff_custom_used; i++) {
1347 old_diff_custom_used = (_old_diff_custom[i] != 0);
1350 if (!old_diff_custom_used)
return;
1353 for (uint i = 0; i < options_to_load; i++) {
1362 static void AILoadConfig(
IniFile *ini,
const char *grpname)
1373 if (group == NULL)
return;
1376 for (item = group->
item; c < MAX_COMPANIES && item != NULL; c++, item = item->next) {
1381 if (strcmp(item->
name,
"none") != 0) {
1382 DEBUG(script, 0,
"The AI by the name '%s' was no longer found, and removed from the list.", item->
name);
1390 static void GameLoadConfig(
IniFile *ini,
const char *grpname)
1399 if (group == NULL)
return;
1402 if (item == NULL)
return;
1408 if (strcmp(item->
name,
"none") != 0) {
1409 DEBUG(script, 0,
"The GameScript by the name '%s' was no longer found, and removed from the list.", item->
name);
1423 if (c >=
'0' && c <=
'9')
return c -
'0';
1424 if (c >=
'A' && c <=
'F')
return c + 10 -
'A';
1425 if (c >=
'a' && c <=
'f')
return c + 10 -
'a';
1439 while (dest_size > 0) {
1442 if (lo < 0)
return false;
1443 *dest++ = (hi << 4) | lo;
1463 if (group == NULL)
return NULL;
1465 for (item = group->
item; item != NULL; item = item->
next) {
1468 uint8 grfid_buf[4], md5sum[16];
1469 char *filename = item->
name;
1470 bool has_grfid =
false;
1471 bool has_md5sum =
false;
1476 filename += 1 + 2 *
lengthof(grfid_buf);
1478 if (has_md5sum) filename += 1 + 2 *
lengthof(md5sum);
1480 uint32 grfid = grfid_buf[0] | (grfid_buf[1] << 8) | (grfid_buf[2] << 16) | (grfid_buf[3] << 24);
1490 if (c == NULL) c =
new GRFConfig(filename);
1506 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_NOT_FOUND);
1508 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNSAFE);
1510 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_SYSTEM);
1512 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_INCOMPATIBLE);
1514 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN);
1524 bool duplicate =
false;
1525 for (
const GRFConfig *gc = first; gc != NULL; gc = gc->
next) {
1550 static void AISaveConfig(
IniFile *ini,
const char *grpname)
1554 if (group == NULL)
return;
1574 static void GameSaveConfig(
IniFile *ini,
const char *grpname)
1578 if (group == NULL)
return;
1605 seprintf(version,
lastof(version),
"%08X", _openttd_newgrf_version);
1607 const char *
const versions[][2] = {
1608 {
"version_string", _openttd_revision },
1609 {
"version_number", version }
1612 for (uint i = 0; i <
lengthof(versions); i++) {
1618 static void GRFSaveConfig(
IniFile *ini,
const char *grpname,
const GRFConfig *list)
1624 for (c = list; c != NULL; c = c->
next) {
1626 char key[4 * 2 + 1 + 16 * 2 + 1 + MAX_PATH];
1638 static void HandleSettingDescs(
IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list,
bool basic_settings =
true,
bool other_settings =
true)
1640 if (basic_settings) {
1641 proc(ini, (
const SettingDesc*)_misc_settings,
"misc", NULL);
1642 #if defined(WIN32) && !defined(DEDICATED)
1643 proc(ini, (
const SettingDesc*)_win32_settings,
"win32", NULL);
1647 if (other_settings) {
1648 proc(ini, _settings,
"patches", &_settings_newgame);
1649 proc(ini, _currency_settings,
"currency", &_custom_currency);
1650 proc(ini, _company_settings,
"company", &_settings_client.
company);
1652 #ifdef ENABLE_NETWORK
1660 static IniFile *IniLoadConfig()
1673 IniFile *ini = IniLoadConfig();
1682 AILoadConfig(ini,
"ai_players");
1683 GameLoadConfig(ini,
"game_scripts");
1686 IniLoadSettings(ini, _gameopt_settings,
"gameopt", &_settings_newgame);
1703 IniFile *ini = IniLoadConfig();
1713 AISaveConfig(ini,
"ai_players");
1714 GameSaveConfig(ini,
"game_scripts");
1728 IniFile *ini = IniLoadConfig();
1730 for (group = ini->
group; group != NULL; group = group->
next) {
1731 if (strncmp(group->
name,
"preset-", 7) == 0) {
1747 size_t len = strlen(config_name) + 8;
1748 char *section = (
char*)alloca(len);
1749 seprintf(section, section + len - 1,
"preset-%s", config_name);
1751 IniFile *ini = IniLoadConfig();
1766 size_t len = strlen(config_name) + 8;
1767 char *section = (
char*)alloca(len);
1768 seprintf(section, section + len - 1,
"preset-%s", config_name);
1770 IniFile *ini = IniLoadConfig();
1771 GRFSaveConfig(ini, section, config);
1782 size_t len = strlen(config_name) + 8;
1783 char *section = (
char*)alloca(len);
1784 seprintf(section, section + len - 1,
"preset-%s", config_name);
1786 IniFile *ini = IniLoadConfig();
1792 const SettingDesc *GetSettingDescription(uint index)
1794 if (index >=
lengthof(_settings))
return NULL;
1795 return &_settings[index];
1811 const SettingDesc *sd = GetSettingDescription(p1);
1822 int32 newval = (int32)p2;
1865 int32 newval = (int32)p2;
1901 if (_game_mode != GM_MENU) {
1912 if (force_newgame) {
1933 const SettingDesc *sd = &_company_settings[index];
1950 for (sd = _company_settings; sd->
save.
cmd != SL_END; sd++) {
1956 #if defined(ENABLE_NETWORK)
1964 for (sd = _company_settings; sd->
save.
cmd != SL_END; sd++, i++) {
2002 *var = strcmp(value,
"(null)") == 0 ? NULL :
stredup(value);
2024 for (*i = 0, sd = _settings; sd->
save.
cmd != SL_END; sd++, (*i)++) {
2026 if (strcmp(sd->
desc.
name, name) == 0)
return sd;
2030 for (*i = 0, sd = _settings; sd->
save.
cmd != SL_END; sd++, (*i)++) {
2032 const char *short_name = strchr(sd->
desc.
name,
'.');
2033 if (short_name != NULL) {
2035 if (strcmp(short_name, name) == 0)
return sd;
2039 if (strncmp(name,
"company.", 8) == 0) name += 8;
2041 for (*i = 0, sd = _company_settings; sd->
save.
cmd != SL_END; sd++, (*i)++) {
2043 if (strcmp(sd->
desc.
name, name) == 0)
return sd;
2051 void IConsoleSetSetting(
const char *name,
const char *value,
bool force_newgame)
2078 IConsoleError(
"This command/variable is not available during network games.");
2080 IConsoleError(
"This command/variable is only available to a network server.");
2085 void IConsoleSetSetting(
const char *name,
int value)
2110 ptr =
GetVariableAddress((_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game, &sd->
save);
2116 seprintf(value,
lastof(value), (*(
const bool*)ptr != 0) ?
"on" :
"off");
2137 if (prefilter != NULL && strstr(sd->
desc.
name, prefilter) == NULL)
continue;
2142 seprintf(value,
lastof(value), (*(
const bool *)ptr != 0) ?
"on" :
"off");
2162 for (; osd->
save.
cmd != SL_END; osd++) {
2166 if (!SlObjectMember(ptr, sld))
continue;
2183 for (i = sd; i->
save.
cmd != SL_END; i++) {
2184 length += SlCalcObjMemberLength(
object, &i->
save);
2188 for (i = sd; i->
save.
cmd != SL_END; i++) {
2190 SlObjectMember(ptr, &i->
save);
2194 static void Load_OPTS()
2204 static void Load_PATS()
2212 static void Check_PATS()
2217 static void Save_PATS()
2234 extern const ChunkHandler _setting_chunk_handlers[] = {
2235 {
'OPTS', NULL, Load_OPTS, NULL, NULL, CH_RIFF},
2236 {
'PATS', Save_PATS, Load_PATS, NULL, Check_PATS, CH_RIFF |
CH_LAST},
2239 static bool IsSignedVarMemType(VarType vt)