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;
188 if (n == maxitems)
return -1;
190 long v = strtol(p, &end, 0);
191 if (p == end)
return -1;
192 if (
sizeof(
int) <
sizeof(
long)) v =
ClampToI32(v);
203 if (n != 0 && !comma)
return -1;
216 static bool LoadIntList(
const char *str,
void *array,
int nelems, VarType type)
222 memset(items, 0,
sizeof(items));
226 if (nitems != nelems)
return false;
233 for (i = 0; i != nitems; i++) ((byte*)array)[i] = items[i];
238 for (i = 0; i != nitems; i++) ((uint16*)array)[i] = items[i];
243 for (i = 0; i != nitems; i++) ((uint32*)array)[i] = items[i];
246 default: NOT_REACHED();
261 static void MakeIntList(
char *buf,
const char *last,
const void *array,
int nelems, VarType type)
264 const byte *p = (
const byte *)array;
266 for (i = 0; i != nelems; i++) {
269 case SLE_VAR_I8: v = *(
const int8 *)p; p += 1;
break;
270 case SLE_VAR_U8: v = *(
const uint8 *)p; p += 1;
break;
271 case SLE_VAR_I16: v = *(
const int16 *)p; p += 2;
break;
272 case SLE_VAR_U16: v = *(
const uint16 *)p; p += 2;
break;
273 case SLE_VAR_I32: v = *(
const int32 *)p; p += 4;
break;
274 case SLE_VAR_U32: v = *(
const uint32 *)p; p += 4;
break;
275 default: NOT_REACHED();
277 buf +=
seprintf(buf, last, (i == 0) ?
"%d" :
",%d", v);
288 static void MakeOneOfMany(
char *buf,
const char *last,
const char *many,
int id)
294 for (; *many !=
'|'; many++) {
304 while (*many !=
'\0' && *many !=
'|' && buf < last) *buf++ = *many++;
316 static void MakeManyOfMany(
char *buf,
const char *last,
const char *many, uint32 x)
322 for (; x != 0; x >>= 1, i++) {
324 while (*many != 0 && *many !=
'|') many++;
327 if (!init) buf +=
seprintf(buf, last,
"|");
330 buf +=
seprintf(buf, last,
"%d", i);
332 memcpy(buf, start, many - start);
337 if (*many ==
'|') many++;
351 const char *str = orig_str == NULL ?
"" : orig_str;
356 size_t val = strtoul(str, &end, 0);
365 ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_TRAILING_CHARACTERS);
377 if (r != (
size_t)-1)
return (
void*)r;
388 if (r != (
size_t)-1)
return (
void*)r;
397 if (strcmp(str,
"true") == 0 || strcmp(str,
"on") == 0 || strcmp(str,
"1") == 0)
return (
void*)
true;
398 if (strcmp(str,
"false") == 0 || strcmp(str,
"off") == 0 || strcmp(str,
"0") == 0)
return (
void*)
false;
462 default: NOT_REACHED();
486 for (; sd->
save.
cmd != SL_END; sd++) {
493 s = strchr(sdb->
name,
'.');
502 item = group->
GetItem(s,
false);
503 if (item == NULL && group != group_def) {
506 item = group_def->
GetItem(s,
false);
511 const char *sc = strchr(s,
'.');
512 if (sc != NULL) item = ini->
GetGroup(s, sc - s)->
GetItem(sc + 1,
false);
530 if (p != NULL)
strecpy((
char*)ptr, (
const char*)p, (
char*)ptr + sld->
length - 1);
536 *(
char**)ptr = p == NULL ? NULL :
stredup((
const char*)p);
539 case SLE_VAR_CHAR:
if (p != NULL) *(
char *)ptr = *(
const char *)p;
break;
541 default: NOT_REACHED();
558 default: NOT_REACHED();
583 for (; sd->
save.
cmd != SL_END; sd++) {
593 s = strchr(sdb->
name,
'.');
598 if (group_def == NULL) group_def = ini->
GetGroup(grpname);
603 item = group->GetItem(s,
true);
606 if (item->
value != NULL) {
619 if (*(
bool*)ptr == (p != NULL))
continue;
624 if (*(byte*)ptr == (byte)(
size_t)p)
continue;
629 if (*(uint16*)ptr == (uint16)(
size_t)p)
continue;
634 if (*(uint32*)ptr == (uint32)(
size_t)p)
continue;
637 default: NOT_REACHED();
658 default: NOT_REACHED();
670 if (*(
char**)ptr == NULL) {
677 case SLE_VAR_CHAR: buf[0] = *(
char*)ptr; buf[1] =
'\0';
break;
678 default: NOT_REACHED();
686 default: NOT_REACHED();
708 if (group == NULL || list == NULL)
return;
712 for (
const IniItem *item = group->
item; item != NULL; item = item->
next) {
713 if (item->name != NULL) *list->
Append() =
stredup(item->name);
730 if (group == NULL || list == NULL)
return;
733 for (
char **iter = list->
Begin(); iter != list->
End(); iter++) {
771 (_game_mode == GM_NORMAL ||
772 (_game_mode == GM_EDITOR && !(this->desc.flags &
SGF_SCENEDIT_TOO))))
return false;
798 if (_game_mode != GM_MENU) {
806 static bool PopulationInLabelActive(int32 p1)
812 static bool RedrawScreen(int32 p1)
831 static bool InvalidateDetailsWindow(int32 p1)
837 static bool StationSpreadChanged(int32 p1)
844 static bool InvalidateBuildIndustryWindow(int32 p1)
850 static bool CloseSignalGUI(int32 p1)
858 static bool InvalidateTownViewWindow(int32 p1)
864 static bool DeleteSelectStationWindow(int32 p1)
870 static bool UpdateConsists(int32 p1)
882 static bool CheckInterval(int32 p1)
884 bool update_vehicles;
888 update_vehicles =
false;
891 update_vehicles =
true;
906 if (update_vehicles) {
912 v->SetServiceIntervalIsPercent(p1 != 0);
917 InvalidateDetailsWindow(0);
922 static bool UpdateInterval(
VehicleType type, int32 p1)
924 bool update_vehicles;
928 update_vehicles =
false;
931 update_vehicles =
true;
936 if (interval != p1)
return false;
938 if (update_vehicles) {
942 v->SetServiceInterval(p1);
947 InvalidateDetailsWindow(0);
952 static bool UpdateIntervalTrains(int32 p1)
957 static bool UpdateIntervalRoadVeh(int32 p1)
959 return UpdateInterval(
VEH_ROAD, p1);
962 static bool UpdateIntervalShips(int32 p1)
964 return UpdateInterval(
VEH_SHIP, p1);
967 static bool UpdateIntervalAircraft(int32 p1)
972 static bool TrainAccelerationModelChanged(int32 p1)
1014 FOR_ALL_ROADVEHICLES(rv) {
1037 FOR_ALL_ROADVEHICLES(rv) {
1044 static bool DragSignalsDensityChanged(int32)
1051 static bool TownFoundingChanged(int32 p1)
1061 static bool InvalidateVehTimetableWindow(int32 p1)
1067 static bool ZoomMinMaxChanged(int32 p1)
1069 extern void ConstrainAllViewportsZoom();
1070 ConstrainAllViewportsZoom();
1096 static bool InvalidateCompanyLiveryWindow(int32 p1)
1099 return RedrawScreen(p1);
1102 static bool InvalidateIndustryViewWindow(int32 p1)
1108 static bool InvalidateAISettingsWindow(int32 p1)
1157 static bool DifficultyNoiseChange(int32 i)
1159 if (_game_mode == GM_NORMAL) {
1169 static bool MaxNoAIsChange(int32 i)
1204 static bool CheckFreeformEdges(int32 p1)
1206 if (_game_mode == GM_MENU)
return true;
1217 FOR_ALL_BASE_STATIONS(st) {
1227 for (uint i = 0; i <
MapMaxX(); i++) {
1233 for (uint i = 1; i <
MapMaxX(); i++) {
1239 for (uint i = 0; i <
MapMaxY(); i++) {
1245 for (uint i = 1; i <
MapMaxY(); i++) {
1252 for (uint i = 0; i <
MapMaxX(); i++) {
1256 for (uint i = 0; i <
MapMaxY(); i++) {
1271 if (_game_mode == GM_MENU)
return true;
1281 static bool ChangeMaxHeightLevel(int32 p1)
1283 if (_game_mode == GM_NORMAL)
return false;
1284 if (_game_mode != GM_EDITOR)
return true;
1302 static bool StationCatchmentChanged(int32 p1)
1308 static bool MaxVehiclesChanged(int32 p1)
1316 #ifdef ENABLE_NETWORK
1318 static bool UpdateClientName(int32 p1)
1324 static bool UpdateServerPassword(int32 p1)
1333 static bool UpdateRconPassword(int32 p1)
1342 static bool UpdateClientConfigValues(int32 p1)
1359 memset(_old_diff_custom, 0,
sizeof(_old_diff_custom));
1374 bool old_diff_custom_used =
false;
1375 for (uint i = 0; i < options_to_load && !old_diff_custom_used; i++) {
1376 old_diff_custom_used = (_old_diff_custom[i] != 0);
1379 if (!old_diff_custom_used)
return;
1382 for (uint i = 0; i < options_to_load; i++) {
1391 static void AILoadConfig(
IniFile *ini,
const char *grpname)
1402 if (group == NULL)
return;
1405 for (item = group->
item; c < MAX_COMPANIES && item != NULL; c++, item = item->next) {
1410 if (strcmp(item->
name,
"none") != 0) {
1411 DEBUG(script, 0,
"The AI by the name '%s' was no longer found, and removed from the list.", item->
name);
1419 static void GameLoadConfig(
IniFile *ini,
const char *grpname)
1428 if (group == NULL)
return;
1431 if (item == NULL)
return;
1437 if (strcmp(item->
name,
"none") != 0) {
1438 DEBUG(script, 0,
"The GameScript by the name '%s' was no longer found, and removed from the list.", item->
name);
1452 if (c >=
'0' && c <=
'9')
return c -
'0';
1453 if (c >=
'A' && c <=
'F')
return c + 10 -
'A';
1454 if (c >=
'a' && c <=
'f')
return c + 10 -
'a';
1468 while (dest_size > 0) {
1471 if (lo < 0)
return false;
1472 *dest++ = (hi << 4) | lo;
1492 if (group == NULL)
return NULL;
1494 for (item = group->
item; item != NULL; item = item->
next) {
1497 uint8 grfid_buf[4], md5sum[16];
1498 char *filename = item->
name;
1499 bool has_grfid =
false;
1500 bool has_md5sum =
false;
1505 filename += 1 + 2 *
lengthof(grfid_buf);
1507 if (has_md5sum) filename += 1 + 2 *
lengthof(md5sum);
1509 uint32 grfid = grfid_buf[0] | (grfid_buf[1] << 8) | (grfid_buf[2] << 16) | (grfid_buf[3] << 24);
1519 if (c == NULL) c =
new GRFConfig(filename);
1535 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_NOT_FOUND);
1537 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNSAFE);
1539 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_SYSTEM);
1541 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_INCOMPATIBLE);
1543 SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN);
1553 bool duplicate =
false;
1554 for (
const GRFConfig *gc = first; gc != NULL; gc = gc->
next) {
1579 static void AISaveConfig(
IniFile *ini,
const char *grpname)
1583 if (group == NULL)
return;
1603 static void GameSaveConfig(
IniFile *ini,
const char *grpname)
1607 if (group == NULL)
return;
1634 seprintf(version,
lastof(version),
"%08X", _openttd_newgrf_version);
1636 const char *
const versions[][2] = {
1637 {
"version_string", _openttd_revision },
1638 {
"version_number", version }
1641 for (uint i = 0; i <
lengthof(versions); i++) {
1647 static void GRFSaveConfig(
IniFile *ini,
const char *grpname,
const GRFConfig *list)
1653 for (c = list; c != NULL; c = c->
next) {
1655 char key[4 * 2 + 1 + 16 * 2 + 1 + MAX_PATH];
1667 static void HandleSettingDescs(
IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list,
bool basic_settings =
true,
bool other_settings =
true)
1669 if (basic_settings) {
1670 proc(ini, (
const SettingDesc*)_misc_settings,
"misc", NULL);
1671 #if defined(WIN32) && !defined(DEDICATED)
1672 proc(ini, (
const SettingDesc*)_win32_settings,
"win32", NULL);
1676 if (other_settings) {
1677 proc(ini, _settings,
"patches", &_settings_newgame);
1678 proc(ini, _currency_settings,
"currency", &_custom_currency);
1679 proc(ini, _company_settings,
"company", &_settings_client.
company);
1681 #ifdef ENABLE_NETWORK
1689 static IniFile *IniLoadConfig()
1702 IniFile *ini = IniLoadConfig();
1711 AILoadConfig(ini,
"ai_players");
1712 GameLoadConfig(ini,
"game_scripts");
1715 IniLoadSettings(ini, _gameopt_settings,
"gameopt", &_settings_newgame);
1732 IniFile *ini = IniLoadConfig();
1742 AISaveConfig(ini,
"ai_players");
1743 GameSaveConfig(ini,
"game_scripts");
1757 IniFile *ini = IniLoadConfig();
1759 for (group = ini->
group; group != NULL; group = group->
next) {
1760 if (strncmp(group->
name,
"preset-", 7) == 0) {
1776 size_t len = strlen(config_name) + 8;
1777 char *section = (
char*)alloca(len);
1778 seprintf(section, section + len - 1,
"preset-%s", config_name);
1780 IniFile *ini = IniLoadConfig();
1795 size_t len = strlen(config_name) + 8;
1796 char *section = (
char*)alloca(len);
1797 seprintf(section, section + len - 1,
"preset-%s", config_name);
1799 IniFile *ini = IniLoadConfig();
1800 GRFSaveConfig(ini, section, config);
1811 size_t len = strlen(config_name) + 8;
1812 char *section = (
char*)alloca(len);
1813 seprintf(section, section + len - 1,
"preset-%s", config_name);
1815 IniFile *ini = IniLoadConfig();
1821 const SettingDesc *GetSettingDescription(uint index)
1823 if (index >=
lengthof(_settings))
return NULL;
1824 return &_settings[index];
1840 const SettingDesc *sd = GetSettingDescription(p1);
1851 int32 newval = (int32)p2;
1894 int32 newval = (int32)p2;
1930 if (_game_mode != GM_MENU) {
1941 if (force_newgame) {
1962 const SettingDesc *sd = &_company_settings[index];
1979 for (sd = _company_settings; sd->
save.
cmd != SL_END; sd++) {
1985 #if defined(ENABLE_NETWORK)
1993 for (sd = _company_settings; sd->
save.
cmd != SL_END; sd++, i++) {
2031 *var = strcmp(value,
"(null)") == 0 ? NULL :
stredup(value);
2053 for (*i = 0, sd = _settings; sd->
save.
cmd != SL_END; sd++, (*i)++) {
2055 if (strcmp(sd->
desc.
name, name) == 0)
return sd;
2059 for (*i = 0, sd = _settings; sd->
save.
cmd != SL_END; sd++, (*i)++) {
2061 const char *short_name = strchr(sd->
desc.
name,
'.');
2062 if (short_name != NULL) {
2064 if (strcmp(short_name, name) == 0)
return sd;
2068 if (strncmp(name,
"company.", 8) == 0) name += 8;
2070 for (*i = 0, sd = _company_settings; sd->
save.
cmd != SL_END; sd++, (*i)++) {
2072 if (strcmp(sd->
desc.
name, name) == 0)
return sd;
2080 void IConsoleSetSetting(
const char *name,
const char *value,
bool force_newgame)
2107 IConsoleError(
"This command/variable is not available during network games.");
2109 IConsoleError(
"This command/variable is only available to a network server.");
2114 void IConsoleSetSetting(
const char *name,
int value)
2139 ptr =
GetVariableAddress((_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game, &sd->
save);
2145 seprintf(value,
lastof(value), (*(
const bool*)ptr != 0) ?
"on" :
"off");
2166 if (prefilter != NULL && strstr(sd->
desc.
name, prefilter) == NULL)
continue;
2171 seprintf(value,
lastof(value), (*(
const bool *)ptr != 0) ?
"on" :
"off");
2191 for (; osd->
save.
cmd != SL_END; osd++) {
2195 if (!SlObjectMember(ptr, sld))
continue;
2212 for (i = sd; i->
save.
cmd != SL_END; i++) {
2213 length += SlCalcObjMemberLength(
object, &i->
save);
2217 for (i = sd; i->
save.
cmd != SL_END; i++) {
2219 SlObjectMember(ptr, &i->
save);
2223 static void Load_OPTS()
2233 static void Load_PATS()
2241 static void Check_PATS()
2246 static void Save_PATS()
2263 extern const ChunkHandler _setting_chunk_handlers[] = {
2264 {
'OPTS', NULL, Load_OPTS, NULL, NULL, CH_RIFF},
2265 {
'PATS', Save_PATS, Load_PATS, NULL, Check_PATS, CH_RIFF |
CH_LAST},
2268 static bool IsSignedVarMemType(VarType vt)