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 ChangeMaxHeightLevel(int32 p1)
1282 if (_game_mode == GM_NORMAL)
return false;
1283 if (_game_mode != GM_EDITOR)
return true;
1301 static bool StationCatchmentChanged(int32 p1)
1307 static bool MaxVehiclesChanged(int32 p1)
1315 #ifdef ENABLE_NETWORK
1317 static bool UpdateClientName(int32 p1)
1323 static bool UpdateServerPassword(int32 p1)
1332 static bool UpdateRconPassword(int32 p1)
1341 static bool UpdateClientConfigValues(int32 p1)
1358 memset(_old_diff_custom, 0,
sizeof(_old_diff_custom));
1373 bool old_diff_custom_used =
false;
1374 for (uint i = 0; i < options_to_load && !old_diff_custom_used; i++) {
1375 old_diff_custom_used = (_old_diff_custom[i] != 0);
1378 if (!old_diff_custom_used)
return;
1381 for (uint i = 0; i < options_to_load; i++) {
1390 static void AILoadConfig(
IniFile *ini,
const char *grpname)
1401 if (group == NULL)
return;
1404 for (item = group->
item; c < MAX_COMPANIES && item != NULL; c++, item = item->next) {
1409 if (strcmp(item->
name,
"none") != 0) {
1410 DEBUG(script, 0,
"The AI by the name '%s' was no longer found, and removed from the list.", item->
name);
1418 static void GameLoadConfig(
IniFile *ini,
const char *grpname)
1427 if (group == NULL)
return;
1430 if (item == NULL)
return;
1436 if (strcmp(item->
name,
"none") != 0) {
1437 DEBUG(script, 0,
"The GameScript by the name '%s' was no longer found, and removed from the list.", item->
name);
1451 if (c >=
'0' && c <=
'9')
return c -
'0';
1452 if (c >=
'A' && c <=
'F')
return c + 10 -
'A';
1453 if (c >=
'a' && c <=
'f')
return c + 10 -
'a';
1467 while (dest_size > 0) {
1470 if (lo < 0)
return false;
1471 *dest++ = (hi << 4) | lo;
1491 if (group == NULL)
return NULL;
1493 for (item = group->
item; item != NULL; item = item->
next) {
1496 uint8 grfid_buf[4], md5sum[16];
1497 char *filename = item->
name;
1498 bool has_grfid =
false;
1499 bool has_md5sum =
false;
1504 filename += 1 + 2 *
lengthof(grfid_buf);
1506 if (has_md5sum) filename += 1 + 2 *
lengthof(md5sum);
1508 uint32 grfid = grfid_buf[0] | (grfid_buf[1] << 8) | (grfid_buf[2] << 16) | (grfid_buf[3] << 24);
1518 if (c == NULL) c =
new GRFConfig(filename);
1534 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_NOT_FOUND);
1536 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNSAFE);
1538 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_SYSTEM);
1540 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_INCOMPATIBLE);
1542 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN);
1552 bool duplicate =
false;
1553 for (
const GRFConfig *gc = first; gc != NULL; gc = gc->
next) {
1578 static void AISaveConfig(
IniFile *ini,
const char *grpname)
1582 if (group == NULL)
return;
1602 static void GameSaveConfig(
IniFile *ini,
const char *grpname)
1606 if (group == NULL)
return;
1633 seprintf(version,
lastof(version),
"%08X", _openttd_newgrf_version);
1635 const char *
const versions[][2] = {
1636 {
"version_string", _openttd_revision },
1637 {
"version_number", version }
1640 for (uint i = 0; i <
lengthof(versions); i++) {
1646 static void GRFSaveConfig(
IniFile *ini,
const char *grpname,
const GRFConfig *list)
1652 for (c = list; c != NULL; c = c->
next) {
1654 char key[4 * 2 + 1 + 16 * 2 + 1 + MAX_PATH];
1666 static void HandleSettingDescs(
IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list,
bool basic_settings =
true,
bool other_settings =
true)
1668 if (basic_settings) {
1669 proc(ini, (
const SettingDesc*)_misc_settings,
"misc", NULL);
1670 #if defined(WIN32) && !defined(DEDICATED)
1671 proc(ini, (
const SettingDesc*)_win32_settings,
"win32", NULL);
1675 if (other_settings) {
1676 proc(ini, _settings,
"patches", &_settings_newgame);
1677 proc(ini, _currency_settings,
"currency", &_custom_currency);
1678 proc(ini, _company_settings,
"company", &_settings_client.
company);
1680 #ifdef ENABLE_NETWORK
1688 static IniFile *IniLoadConfig()
1701 IniFile *ini = IniLoadConfig();
1710 AILoadConfig(ini,
"ai_players");
1711 GameLoadConfig(ini,
"game_scripts");
1714 IniLoadSettings(ini, _gameopt_settings,
"gameopt", &_settings_newgame);
1731 IniFile *ini = IniLoadConfig();
1741 AISaveConfig(ini,
"ai_players");
1742 GameSaveConfig(ini,
"game_scripts");
1756 IniFile *ini = IniLoadConfig();
1758 for (group = ini->
group; group != NULL; group = group->
next) {
1759 if (strncmp(group->
name,
"preset-", 7) == 0) {
1775 size_t len = strlen(config_name) + 8;
1776 char *section = (
char*)alloca(len);
1777 seprintf(section, section + len - 1,
"preset-%s", config_name);
1779 IniFile *ini = IniLoadConfig();
1794 size_t len = strlen(config_name) + 8;
1795 char *section = (
char*)alloca(len);
1796 seprintf(section, section + len - 1,
"preset-%s", config_name);
1798 IniFile *ini = IniLoadConfig();
1799 GRFSaveConfig(ini, section, config);
1810 size_t len = strlen(config_name) + 8;
1811 char *section = (
char*)alloca(len);
1812 seprintf(section, section + len - 1,
"preset-%s", config_name);
1814 IniFile *ini = IniLoadConfig();
1820 const SettingDesc *GetSettingDescription(uint index)
1822 if (index >=
lengthof(_settings))
return NULL;
1823 return &_settings[index];
1839 const SettingDesc *sd = GetSettingDescription(p1);
1850 int32 newval = (int32)p2;
1893 int32 newval = (int32)p2;
1929 if (_game_mode != GM_MENU) {
1940 if (force_newgame) {
1961 const SettingDesc *sd = &_company_settings[index];
1978 for (sd = _company_settings; sd->
save.
cmd != SL_END; sd++) {
1984 #if defined(ENABLE_NETWORK)
1992 for (sd = _company_settings; sd->
save.
cmd != SL_END; sd++, i++) {
2030 *var = strcmp(value,
"(null)") == 0 ? NULL :
stredup(value);
2052 for (*i = 0, sd = _settings; sd->
save.
cmd != SL_END; sd++, (*i)++) {
2054 if (strcmp(sd->
desc.
name, name) == 0)
return sd;
2058 for (*i = 0, sd = _settings; sd->
save.
cmd != SL_END; sd++, (*i)++) {
2060 const char *short_name = strchr(sd->
desc.
name,
'.');
2061 if (short_name != NULL) {
2063 if (strcmp(short_name, name) == 0)
return sd;
2067 if (strncmp(name,
"company.", 8) == 0) name += 8;
2069 for (*i = 0, sd = _company_settings; sd->
save.
cmd != SL_END; sd++, (*i)++) {
2071 if (strcmp(sd->
desc.
name, name) == 0)
return sd;
2079 void IConsoleSetSetting(
const char *name,
const char *value,
bool force_newgame)
2106 IConsoleError(
"This command/variable is not available during network games.");
2108 IConsoleError(
"This command/variable is only available to a network server.");
2113 void IConsoleSetSetting(
const char *name,
int value)
2138 ptr =
GetVariableAddress((_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game, &sd->
save);
2144 seprintf(value,
lastof(value), (*(
const bool*)ptr != 0) ?
"on" :
"off");
2165 if (prefilter != NULL && strstr(sd->
desc.
name, prefilter) == NULL)
continue;
2170 seprintf(value,
lastof(value), (*(
const bool *)ptr != 0) ?
"on" :
"off");
2190 for (; osd->
save.
cmd != SL_END; osd++) {
2194 if (!SlObjectMember(ptr, sld))
continue;
2211 for (i = sd; i->
save.
cmd != SL_END; i++) {
2212 length += SlCalcObjMemberLength(
object, &i->
save);
2216 for (i = sd; i->
save.
cmd != SL_END; i++) {
2218 SlObjectMember(ptr, &i->
save);
2222 static void Load_OPTS()
2232 static void Load_PATS()
2240 static void Check_PATS()
2245 static void Save_PATS()
2262 extern const ChunkHandler _setting_chunk_handlers[] = {
2263 {
'OPTS', NULL, Load_OPTS, NULL, NULL, CH_RIFF},
2264 {
'PATS', Save_PATS, Load_PATS, NULL, Check_PATS, CH_RIFF |
CH_LAST},
2267 static bool IsSignedVarMemType(VarType vt)