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)