From a42251fc72d2196c26abfcc77c7fe0277798d3d4 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Mon, 28 Jun 2021 15:35:00 +0200 Subject: [PATCH 01/42] Codechange: move network-related settings out of settings.ini This to prepare the code to split up network-related settings into private / secrets / generic. --- src/settings.cpp | 43 ++- src/table/settings/CMakeLists.txt | 1 + src/table/settings/network_settings.ini | 331 ++++++++++++++++++++++++ src/table/settings/settings.ini | 296 --------------------- 4 files changed, 365 insertions(+), 306 deletions(-) create mode 100644 src/table/settings/network_settings.ini diff --git a/src/settings.cpp b/src/settings.cpp index a7a50db11c..71531b261b 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -89,6 +89,21 @@ static ErrorList _settings_error_list; ///< Errors while loading minimal setting typedef span SettingTable; +/** + * List of all the setting tables. + * + * There are a few tables that are special and not processed like the rest: + * - _currency_settings + * - _misc_settings + * - _company_settings + * - _win32_settings + * As such, they are not part of this list. + */ +static const SettingTable _setting_tables[] = { + _settings, + _network_settings, +}; + typedef void SettingDescProc(IniFile *ini, const SettingTable &desc, const char *grpname, void *object, bool only_startup); typedef void SettingDescProcList(IniFile *ini, const char *grpname, StringList &list); @@ -1542,7 +1557,11 @@ static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescP proc(ini, _win32_settings, "win32", nullptr, only_startup); #endif /* _WIN32 */ - proc(ini, _settings, "patches", &_settings_newgame, only_startup); + for (auto &table : _setting_tables) { + /* The name "patches" is a fallback, as every setting should sets its own group. */ + proc(ini, table, "patches", &_settings_newgame, only_startup); + } + proc(ini, _currency_settings,"currency", &_custom_currency, only_startup); proc(ini, _company_settings, "company", &_settings_client.company, only_startup); @@ -1773,8 +1792,10 @@ static const SettingDesc *GetCompanySettingFromName(std::string_view name) */ const SettingDesc *GetSettingFromName(const std::string_view name) { - auto sd = GetSettingFromName(name, _settings); - if (sd != nullptr) return sd; + for (auto &table : _setting_tables) { + auto sd = GetSettingFromName(name, table); + if (sd != nullptr) return sd; + } return GetCompanySettingFromName(name); } @@ -2016,13 +2037,15 @@ void IConsoleListSettings(const char *prefilter) { IConsolePrint(CC_HELP, "All settings with their current value:"); - for (auto &desc : _settings) { - const SettingDesc *sd = GetSettingDesc(desc); - if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; - if (prefilter != nullptr && sd->name.find(prefilter) == std::string::npos) continue; - char value[80]; - sd->FormatValue(value, lastof(value), &GetGameSettings()); - IConsolePrint(CC_DEFAULT, "{} = {}", sd->name, value); + for (auto &table : _setting_tables) { + for (auto &desc : table) { + const SettingDesc *sd = GetSettingDesc(desc); + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; + if (prefilter != nullptr && sd->name.find(prefilter) == std::string::npos) continue; + char value[80]; + sd->FormatValue(value, lastof(value), &GetGameSettings()); + IConsolePrint(CC_DEFAULT, "{} = {}", sd->name, value); + } } IConsolePrint(CC_HELP, "Use 'setting' command to change a value."); diff --git a/src/table/settings/CMakeLists.txt b/src/table/settings/CMakeLists.txt index b1503145fd..802b6b42da 100644 --- a/src/table/settings/CMakeLists.txt +++ b/src/table/settings/CMakeLists.txt @@ -6,6 +6,7 @@ set(TABLE_INI_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/currency_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/gameopt_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/misc_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/network_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/win32_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/window_settings.ini diff --git a/src/table/settings/network_settings.ini b/src/table/settings/network_settings.ini new file mode 100644 index 0000000000..5d33773c83 --- /dev/null +++ b/src/table/settings/network_settings.ini @@ -0,0 +1,331 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; Network settings as stored in the main configuration file ("openttd.cfg"). + +[pre-amble] +static bool ReplaceAsteriskWithEmptyPassword(std::string &newval); +static void UpdateClientConfigValues(); + +static const SettingVariant _network_settings[] = { +[post-amble] +}; +[templates] +SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTC_SSTR = SDTC_SSTR( $var, $type, $flags, $def, $length, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTC_VAR = SDTC_VAR( $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDTC_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +[SDTC_VAR] +var = network.sync_freq +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NOT_IN_CONFIG | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 100 +min = 0 +max = 100 +cat = SC_EXPERT + +[SDTC_VAR] +var = network.frame_freq +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NOT_IN_CONFIG | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 0 +min = 0 +max = 100 +cat = SC_EXPERT + +[SDTC_VAR] +var = network.commands_per_frame +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 2 +min = 1 +max = 65535 +cat = SC_EXPERT + +[SDTC_VAR] +var = network.max_commands_in_queue +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 16 +min = 1 +max = 65535 +cat = SC_EXPERT + +[SDTC_VAR] +var = network.bytes_per_frame +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 8 +min = 1 +max = 65535 +cat = SC_EXPERT + +[SDTC_VAR] +var = network.bytes_per_frame_burst +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 256 +min = 1 +max = 65535 +cat = SC_EXPERT + +[SDTC_VAR] +var = network.max_init_time +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 100 +min = 0 +max = 32000 +cat = SC_EXPERT + +[SDTC_VAR] +var = network.max_join_time +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 500 +min = 0 +max = 32000 + +[SDTC_VAR] +var = network.max_download_time +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 1000 +min = 0 +max = 32000 + +[SDTC_VAR] +var = network.max_password_time +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 2000 +min = 0 +max = 32000 + +[SDTC_VAR] +var = network.max_lag_time +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 500 +min = 0 +max = 32000 + +[SDTC_BOOL] +var = network.pause_on_join +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = true + +[SDTC_VAR] +var = network.server_port +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = NETWORK_DEFAULT_PORT +min = 0 +max = 65535 +cat = SC_EXPERT + +[SDTC_VAR] +var = network.server_admin_port +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = NETWORK_ADMIN_PORT +min = 0 +max = 65535 +cat = SC_EXPERT + +[SDTC_BOOL] +var = network.server_admin_chat +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = true +cat = SC_EXPERT + +[SDTC_BOOL] +var = network.server_advertise +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = false + +[SDTC_SSTR] +var = network.client_name +type = SLE_STR +length = NETWORK_CLIENT_NAME_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = nullptr +pre_cb = NetworkValidateClientName +post_cb = NetworkUpdateClientName +cat = SC_BASIC + +[SDTC_SSTR] +var = network.server_password +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = nullptr +pre_cb = ReplaceAsteriskWithEmptyPassword +post_cb = [](auto) { NetworkServerUpdateGameInfo(); } +cat = SC_BASIC + +[SDTC_SSTR] +var = network.rcon_password +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = nullptr +pre_cb = ReplaceAsteriskWithEmptyPassword +cat = SC_BASIC + +[SDTC_SSTR] +var = network.admin_password +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = nullptr +cat = SC_BASIC + +[SDTC_SSTR] +var = network.default_company_pass +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = nullptr + +[SDTC_SSTR] +var = network.server_name +type = SLE_STR +length = NETWORK_NAME_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = nullptr +pre_cb = NetworkValidateServerName +post_cb = [](auto) { UpdateClientConfigValues(); } +cat = SC_BASIC + +[SDTC_SSTR] +var = network.connect_to_ip +type = SLE_STR +length = 0 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = nullptr + +[SDTC_SSTR] +var = network.network_id +type = SLE_STR +length = NETWORK_SERVER_ID_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = nullptr + +[SDTC_BOOL] +var = network.autoclean_companies +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = false + +[SDTC_VAR] +var = network.autoclean_unprotected +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NETWORK_ONLY +def = 12 +min = 0 +max = 240 + +[SDTC_VAR] +var = network.autoclean_protected +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NETWORK_ONLY +def = 36 +min = 0 +max = 240 + +[SDTC_VAR] +var = network.autoclean_novehicles +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NETWORK_ONLY +def = 0 +min = 0 +max = 240 + +[SDTC_VAR] +var = network.max_companies +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 15 +min = 1 +max = MAX_COMPANIES +post_cb = [](auto) { UpdateClientConfigValues(); } +cat = SC_BASIC + +[SDTC_VAR] +var = network.max_clients +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 25 +min = 2 +max = MAX_CLIENTS +post_cb = [](auto) { UpdateClientConfigValues(); } +cat = SC_BASIC + +[SDTC_VAR] +var = network.max_spectators +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 15 +min = 0 +max = MAX_CLIENTS +post_cb = [](auto) { UpdateClientConfigValues(); } +cat = SC_BASIC + +[SDTC_VAR] +var = network.restart_game_year +type = SLE_INT32 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NETWORK_ONLY +def = 0 +min = MIN_YEAR +max = MAX_YEAR +interval = 1 + +[SDTC_VAR] +var = network.min_active_clients +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = 0 +min = 0 +max = MAX_CLIENTS + +[SDTC_BOOL] +var = network.reload_cfg +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = false +cat = SC_EXPERT + +[SDTC_SSTR] +var = network.last_joined +type = SLE_STR +length = 0 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = """" +cat = SC_EXPERT + +[SDTC_BOOL] +var = network.no_http_content_downloads +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +cat = SC_EXPERT diff --git a/src/table/settings/settings.ini b/src/table/settings/settings.ini index 5e352ff3c7..601493a7e9 100644 --- a/src/table/settings/settings.ini +++ b/src/table/settings/settings.ini @@ -35,9 +35,6 @@ static void SpriteZoomMinChanged(int32 new_value); static void MaxVehiclesChanged(int32 new_value); static void InvalidateShipPathCache(int32 new_value); -static bool ReplaceAsteriskWithEmptyPassword(std::string &newval); -static void UpdateClientConfigValues(); - /* End - Callback Functions for the various settings */ /* Some settings do not need to be synchronised when playing in multiplayer. @@ -3550,296 +3547,3 @@ def = 20 min = 1 max = 65535 cat = SC_EXPERT - -[SDTC_VAR] -var = network.sync_freq -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NOT_IN_CONFIG | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 100 -min = 0 -max = 100 -cat = SC_EXPERT - -[SDTC_VAR] -var = network.frame_freq -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NOT_IN_CONFIG | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 0 -min = 0 -max = 100 -cat = SC_EXPERT - -[SDTC_VAR] -var = network.commands_per_frame -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 2 -min = 1 -max = 65535 -cat = SC_EXPERT - -[SDTC_VAR] -var = network.max_commands_in_queue -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 16 -min = 1 -max = 65535 -cat = SC_EXPERT - -[SDTC_VAR] -var = network.bytes_per_frame -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 8 -min = 1 -max = 65535 -cat = SC_EXPERT - -[SDTC_VAR] -var = network.bytes_per_frame_burst -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 256 -min = 1 -max = 65535 -cat = SC_EXPERT - -[SDTC_VAR] -var = network.max_init_time -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 100 -min = 0 -max = 32000 -cat = SC_EXPERT - -[SDTC_VAR] -var = network.max_join_time -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 500 -min = 0 -max = 32000 - -[SDTC_VAR] -var = network.max_download_time -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 1000 -min = 0 -max = 32000 - -[SDTC_VAR] -var = network.max_password_time -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 2000 -min = 0 -max = 32000 - -[SDTC_VAR] -var = network.max_lag_time -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 500 -min = 0 -max = 32000 - -[SDTC_BOOL] -var = network.pause_on_join -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = true - -[SDTC_VAR] -var = network.server_port -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = NETWORK_DEFAULT_PORT -min = 0 -max = 65535 -cat = SC_EXPERT - -[SDTC_VAR] -var = network.server_admin_port -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = NETWORK_ADMIN_PORT -min = 0 -max = 65535 -cat = SC_EXPERT - -[SDTC_BOOL] -var = network.server_admin_chat -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = true -cat = SC_EXPERT - -[SDTC_BOOL] -var = network.server_advertise -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = false - -[SDTC_SSTR] -var = network.client_name -type = SLE_STR -length = NETWORK_CLIENT_NAME_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = nullptr -pre_cb = NetworkValidateClientName -post_cb = NetworkUpdateClientName -cat = SC_BASIC - -[SDTC_SSTR] -var = network.server_password -type = SLE_STR -length = NETWORK_PASSWORD_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = nullptr -pre_cb = ReplaceAsteriskWithEmptyPassword -post_cb = [](auto) { NetworkServerUpdateGameInfo(); } -cat = SC_BASIC - -[SDTC_SSTR] -var = network.rcon_password -type = SLE_STR -length = NETWORK_PASSWORD_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = nullptr -pre_cb = ReplaceAsteriskWithEmptyPassword -cat = SC_BASIC - -[SDTC_SSTR] -var = network.admin_password -type = SLE_STR -length = NETWORK_PASSWORD_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = nullptr -cat = SC_BASIC - -[SDTC_SSTR] -var = network.default_company_pass -type = SLE_STR -length = NETWORK_PASSWORD_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = nullptr - -[SDTC_SSTR] -var = network.server_name -type = SLE_STR -length = NETWORK_NAME_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = nullptr -pre_cb = NetworkValidateServerName -post_cb = [](auto) { UpdateClientConfigValues(); } -cat = SC_BASIC - -[SDTC_SSTR] -var = network.connect_to_ip -type = SLE_STR -length = 0 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = nullptr - -[SDTC_SSTR] -var = network.network_id -type = SLE_STR -length = NETWORK_SERVER_ID_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = nullptr - -[SDTC_BOOL] -var = network.autoclean_companies -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = false - -[SDTC_VAR] -var = network.autoclean_unprotected -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NETWORK_ONLY -def = 12 -min = 0 -max = 240 - -[SDTC_VAR] -var = network.autoclean_protected -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NETWORK_ONLY -def = 36 -min = 0 -max = 240 - -[SDTC_VAR] -var = network.autoclean_novehicles -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NETWORK_ONLY -def = 0 -min = 0 -max = 240 - -[SDTC_VAR] -var = network.max_companies -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 15 -min = 1 -max = MAX_COMPANIES -post_cb = [](auto) { UpdateClientConfigValues(); } -cat = SC_BASIC - -[SDTC_VAR] -var = network.max_clients -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 25 -min = 2 -max = MAX_CLIENTS -post_cb = [](auto) { UpdateClientConfigValues(); } -cat = SC_BASIC - -[SDTC_VAR] -var = network.max_spectators -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 15 -min = 0 -max = MAX_CLIENTS -post_cb = [](auto) { UpdateClientConfigValues(); } -cat = SC_BASIC - -[SDTC_VAR] -var = network.restart_game_year -type = SLE_INT32 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NETWORK_ONLY -def = 0 -min = MIN_YEAR -max = MAX_YEAR -interval = 1 - -[SDTC_VAR] -var = network.min_active_clients -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = 0 -min = 0 -max = MAX_CLIENTS - -[SDTC_BOOL] -var = network.reload_cfg -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = false -cat = SC_EXPERT - -[SDTC_SSTR] -var = network.last_joined -type = SLE_STR -length = 0 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = """" -cat = SC_EXPERT - -[SDTC_BOOL] -var = network.no_http_content_downloads -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -cat = SC_EXPERT From 66dc0ce1965bd033b6b52712c3db7a768ff2fba9 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 1 Jul 2021 19:59:13 +0200 Subject: [PATCH 02/42] Codechange: C++-ify the usage of IniFile in settings.cpp Instead of creating the object on heap and use a pointer, create the object on stack and use a guaranteed-not-null pointer. The size of IniFile doesn't warrent the forcing to heap. Additionally, use a subclass instead of a function to do some initial bookkeeping on an IniFile meant to read a configuration. --- src/settings.cpp | 134 +++++++++++++++++++++----------------------- src/settings_func.h | 4 +- src/window.cpp | 12 ++-- 3 files changed, 72 insertions(+), 78 deletions(-) diff --git a/src/settings.cpp b/src/settings.cpp index 71531b261b..2a8c5b6cce 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -104,11 +104,31 @@ static const SettingTable _setting_tables[] = { _network_settings, }; -typedef void SettingDescProc(IniFile *ini, const SettingTable &desc, const char *grpname, void *object, bool only_startup); -typedef void SettingDescProcList(IniFile *ini, const char *grpname, StringList &list); +typedef void SettingDescProc(IniFile &ini, const SettingTable &desc, const char *grpname, void *object, bool only_startup); +typedef void SettingDescProcList(IniFile &ini, const char *grpname, StringList &list); static bool IsSignedVarMemType(VarType vt); +/** + * IniFile to store a configuration. + */ +class ConfigIniFile : public IniFile { +private: + inline static const char * const list_group_names[] = { + "bans", + "newgrf", + "servers", + "server_bind_addresses", + nullptr, + }; + +public: + ConfigIniFile(const std::string &filename) : IniFile(list_group_names) + { + this->LoadFromDisk(filename, NO_DIRECTORY); + } +}; + /** * Helper to convert the type of the iterated settings description to a pointer to it. * @param desc The type of the iterator of the value in SettingTable. @@ -119,17 +139,6 @@ static constexpr const SettingDesc *GetSettingDesc(const SettingVariant &desc) return std::visit([](auto&& arg) -> const SettingDesc * { return &arg; }, desc); } -/** - * Groups in openttd.cfg that are actually lists. - */ -static const char * const _list_group_names[] = { - "bans", - "newgrf", - "servers", - "server_bind_addresses", - nullptr -}; - /** * Find the index value of a ONEofMANY type in a string separated by | * @param str the current value of the setting for which a value needs found @@ -532,10 +541,10 @@ const std::string &StringSettingDesc::Read(const void *object) const * @param object pointer to the object been loaded * @param only_startup load only the startup settings set */ -static void IniLoadSettings(IniFile *ini, const SettingTable &settings_table, const char *grpname, void *object, bool only_startup) +static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, const char *grpname, void *object, bool only_startup) { IniGroup *group; - IniGroup *group_def = ini->GetGroup(grpname); + IniGroup *group_def = ini.GetGroup(grpname); for (auto &desc : settings_table) { const SettingDesc *sd = GetSettingDesc(desc); @@ -546,7 +555,7 @@ static void IniLoadSettings(IniFile *ini, const SettingTable &settings_table, co std::string s{ sd->name }; auto sc = s.find('.'); if (sc != std::string::npos) { - group = ini->GetGroup(s.substr(0, sc)); + group = ini.GetGroup(s.substr(0, sc)); s = s.substr(sc + 1); } else { group = group_def; @@ -562,7 +571,7 @@ static void IniLoadSettings(IniFile *ini, const SettingTable &settings_table, co /* For settings.xx.zz.yy load the settings from [zz] yy = ? in case the previous * did not exist (e.g. loading old config files with a [yapf] section */ sc = s.find('.'); - if (sc != std::string::npos) item = ini->GetGroup(s.substr(0, sc))->GetItem(s.substr(sc + 1), false); + if (sc != std::string::npos) item = ini.GetGroup(s.substr(0, sc))->GetItem(s.substr(sc + 1), false); } sd->ParseValue(item, object); @@ -608,7 +617,7 @@ void ListSettingDesc::ParseValue(const IniItem *item, void *object) const * values are reloaded when saving). If settings indeed have changed, we get * these and save them. */ -static void IniSaveSettings(IniFile *ini, const SettingTable &settings_table, const char *grpname, void *object, bool) +static void IniSaveSettings(IniFile &ini, const SettingTable &settings_table, const char *grpname, void *object, bool) { IniGroup *group_def = nullptr, *group; IniItem *item; @@ -625,10 +634,10 @@ static void IniSaveSettings(IniFile *ini, const SettingTable &settings_table, co std::string s{ sd->name }; auto sc = s.find('.'); if (sc != std::string::npos) { - group = ini->GetGroup(s.substr(0, sc)); + group = ini.GetGroup(s.substr(0, sc)); s = s.substr(sc + 1); } else { - if (group_def == nullptr) group_def = ini->GetGroup(grpname); + if (group_def == nullptr) group_def = ini.GetGroup(grpname); group = group_def; } @@ -706,9 +715,9 @@ bool ListSettingDesc::IsSameValue(const IniItem *item, void *object) const * @param grpname character string identifying the section-header of the ini file that will be parsed * @param list new list with entries of the given section */ -static void IniLoadSettingList(IniFile *ini, const char *grpname, StringList &list) +static void IniLoadSettingList(IniFile &ini, const char *grpname, StringList &list) { - IniGroup *group = ini->GetGroup(grpname); + IniGroup *group = ini.GetGroup(grpname); if (group == nullptr) return; @@ -728,9 +737,9 @@ static void IniLoadSettingList(IniFile *ini, const char *grpname, StringList &li * @param list pointer to an string(pointer) array that will be used as the * source to be saved into the relevant ini section */ -static void IniSaveSettingList(IniFile *ini, const char *grpname, StringList &list) +static void IniSaveSettingList(IniFile &ini, const char *grpname, StringList &list) { - IniGroup *group = ini->GetGroup(grpname); + IniGroup *group = ini.GetGroup(grpname); if (group == nullptr) return; group->Clear(); @@ -746,7 +755,7 @@ static void IniSaveSettingList(IniFile *ini, const char *grpname, StringList &li * @param grpname character string identifying the section-header of the ini file that will be parsed * @param desc Destination WindowDesc */ -void IniLoadWindowSettings(IniFile *ini, const char *grpname, void *desc) +void IniLoadWindowSettings(IniFile &ini, const char *grpname, void *desc) { IniLoadSettings(ini, _window_settings, grpname, desc, false); } @@ -757,7 +766,7 @@ void IniLoadWindowSettings(IniFile *ini, const char *grpname, void *desc) * @param grpname character string identifying the section-header of the ini file * @param desc Source WindowDesc */ -void IniSaveWindowSettings(IniFile *ini, const char *grpname, void *desc) +void IniSaveWindowSettings(IniFile &ini, const char *grpname, void *desc) { IniSaveSettings(ini, _window_settings, grpname, desc, false); } @@ -1276,9 +1285,9 @@ static void HandleOldDiffCustom(bool savegame) } } -static void AILoadConfig(IniFile *ini, const char *grpname) +static void AILoadConfig(IniFile &ini, const char *grpname) { - IniGroup *group = ini->GetGroup(grpname); + IniGroup *group = ini.GetGroup(grpname); IniItem *item; /* Clean any configured AI */ @@ -1304,9 +1313,9 @@ static void AILoadConfig(IniFile *ini, const char *grpname) } } -static void GameLoadConfig(IniFile *ini, const char *grpname) +static void GameLoadConfig(IniFile &ini, const char *grpname) { - IniGroup *group = ini->GetGroup(grpname); + IniGroup *group = ini.GetGroup(grpname); IniItem *item; /* Clean any configured GameScript */ @@ -1370,9 +1379,9 @@ static bool DecodeHexText(const char *pos, uint8 *dest, size_t dest_size) * @param grpname Group name containing the configuration of the GRF. * @param is_static GRF is static. */ -static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_static) +static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_static) { - IniGroup *group = ini->GetGroup(grpname); + IniGroup *group = ini.GetGroup(grpname); IniItem *item; GRFConfig *first = nullptr; GRFConfig **curr = &first; @@ -1464,9 +1473,9 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati return first; } -static void AISaveConfig(IniFile *ini, const char *grpname) +static void AISaveConfig(IniFile &ini, const char *grpname) { - IniGroup *group = ini->GetGroup(grpname); + IniGroup *group = ini.GetGroup(grpname); if (group == nullptr) return; group->Clear(); @@ -1487,9 +1496,9 @@ static void AISaveConfig(IniFile *ini, const char *grpname) } } -static void GameSaveConfig(IniFile *ini, const char *grpname) +static void GameSaveConfig(IniFile &ini, const char *grpname) { - IniGroup *group = ini->GetGroup(grpname); + IniGroup *group = ini.GetGroup(grpname); if (group == nullptr) return; group->Clear(); @@ -1512,9 +1521,9 @@ static void GameSaveConfig(IniFile *ini, const char *grpname) * Save the version of OpenTTD to the ini file. * @param ini the ini to write to */ -static void SaveVersionInConfig(IniFile *ini) +static void SaveVersionInConfig(IniFile &ini) { - IniGroup *group = ini->GetGroup("version"); + IniGroup *group = ini.GetGroup("version"); char version[9]; seprintf(version, lastof(version), "%08X", _openttd_newgrf_version); @@ -1530,10 +1539,10 @@ static void SaveVersionInConfig(IniFile *ini) } /* Save a GRF configuration to the given group name */ -static void GRFSaveConfig(IniFile *ini, const char *grpname, const GRFConfig *list) +static void GRFSaveConfig(IniFile &ini, const char *grpname, const GRFConfig *list) { - ini->RemoveGroup(grpname); - IniGroup *group = ini->GetGroup(grpname); + ini.RemoveGroup(grpname); + IniGroup *group = ini.GetGroup(grpname); const GRFConfig *c; for (c = list; c != nullptr; c = c->next) { @@ -1550,7 +1559,7 @@ static void GRFSaveConfig(IniFile *ini, const char *grpname, const GRFConfig *li } /* Common handler for saving/loading variables to the configuration file */ -static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list, bool only_startup = false) +static void HandleSettingDescs(IniFile &ini, SettingDescProc *proc, SettingDescProcList *proc_list, bool only_startup = false) { proc(ini, _misc_settings, "misc", nullptr, only_startup); #if defined(_WIN32) && !defined(DEDICATED) @@ -1572,20 +1581,13 @@ static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescP } } -static IniFile *IniLoadConfig() -{ - IniFile *ini = new IniFile(_list_group_names); - ini->LoadFromDisk(_config_file, NO_DIRECTORY); - return ini; -} - /** * Load the values from the configuration files * @param startup Load the minimal amount of the configuration to "bootstrap" the blitter and such. */ void LoadFromConfig(bool startup) { - IniFile *ini = IniLoadConfig(); + ConfigIniFile ini(_config_file); if (!startup) ResetCurrencies(false); // Initialize the array of currencies, without preserving the custom one /* Load basic settings only during bootstrap, load other settings not during bootstrap */ @@ -1608,19 +1610,17 @@ void LoadFromConfig(bool startup) ScheduleErrorMessage(_settings_error_list); if (FindWindowById(WC_ERRMSG, 0) == nullptr) ShowFirstError(); } - - delete ini; } /** Save the values to the configuration file */ void SaveToConfig() { - IniFile *ini = IniLoadConfig(); + ConfigIniFile ini(_config_file); /* Remove some obsolete groups. These have all been loaded into other groups. */ - ini->RemoveGroup("patches"); - ini->RemoveGroup("yapf"); - ini->RemoveGroup("gameopt"); + ini.RemoveGroup("patches"); + ini.RemoveGroup("yapf"); + ini.RemoveGroup("gameopt"); HandleSettingDescs(ini, IniSaveSettings, IniSaveSettingList); GRFSaveConfig(ini, "newgrf", _grfconfig_newgame); @@ -1628,8 +1628,7 @@ void SaveToConfig() AISaveConfig(ini, "ai_players"); GameSaveConfig(ini, "game_scripts"); SaveVersionInConfig(ini); - ini->SaveToDisk(_config_file); - delete ini; + ini.SaveToDisk(_config_file); } /** @@ -1640,8 +1639,8 @@ StringList GetGRFPresetList() { StringList list; - std::unique_ptr ini(IniLoadConfig()); - for (IniGroup *group = ini->group; group != nullptr; group = group->next) { + ConfigIniFile ini(_config_file); + for (IniGroup *group = ini.group; group != nullptr; group = group->next) { if (group->name.compare(0, 7, "preset-") == 0) { list.push_back(group->name.substr(7)); } @@ -1662,9 +1661,8 @@ GRFConfig *LoadGRFPresetFromConfig(const char *config_name) char *section = (char*)alloca(len); seprintf(section, section + len - 1, "preset-%s", config_name); - IniFile *ini = IniLoadConfig(); + ConfigIniFile ini(_config_file); GRFConfig *config = GRFLoadConfig(ini, section, false); - delete ini; return config; } @@ -1681,10 +1679,9 @@ void SaveGRFPresetToConfig(const char *config_name, GRFConfig *config) char *section = (char*)alloca(len); seprintf(section, section + len - 1, "preset-%s", config_name); - IniFile *ini = IniLoadConfig(); + ConfigIniFile ini(_config_file); GRFSaveConfig(ini, section, config); - ini->SaveToDisk(_config_file); - delete ini; + ini.SaveToDisk(_config_file); } /** @@ -1697,10 +1694,9 @@ void DeleteGRFPresetFromConfig(const char *config_name) char *section = (char*)alloca(len); seprintf(section, section + len - 1, "preset-%s", config_name); - IniFile *ini = IniLoadConfig(); - ini->RemoveGroup(section); - ini->SaveToDisk(_config_file); - delete ini; + ConfigIniFile ini(_config_file); + ini.RemoveGroup(section); + ini.SaveToDisk(_config_file); } /** diff --git a/src/settings_func.h b/src/settings_func.h index d1ecdbac1d..9f56b6de14 100644 --- a/src/settings_func.h +++ b/src/settings_func.h @@ -24,8 +24,8 @@ void IConsoleListSettings(const char *prefilter); void LoadFromConfig(bool minimal = false); void SaveToConfig(); -void IniLoadWindowSettings(IniFile *ini, const char *grpname, void *desc); -void IniSaveWindowSettings(IniFile *ini, const char *grpname, void *desc); +void IniLoadWindowSettings(IniFile &ini, const char *grpname, void *desc); +void IniSaveWindowSettings(IniFile &ini, const char *grpname, void *desc); StringList GetGRFPresetList(); struct GRFConfig *LoadGRFPresetFromConfig(const char *config_name); diff --git a/src/window.cpp b/src/window.cpp index ef15a3ed20..1c2a305ba8 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -153,13 +153,12 @@ int16 WindowDesc::GetDefaultHeight() const */ void WindowDesc::LoadFromConfig() { - IniFile *ini = new IniFile(); - ini->LoadFromDisk(_windows_file, NO_DIRECTORY); + IniFile ini; + ini.LoadFromDisk(_windows_file, NO_DIRECTORY); for (WindowDesc *wd : *_window_descs) { if (wd->ini_key == nullptr) continue; IniLoadWindowSettings(ini, wd->ini_key, wd); } - delete ini; } /** @@ -179,14 +178,13 @@ void WindowDesc::SaveToConfig() /* Sort the stuff to get a nice ini file on first write */ std::sort(_window_descs->begin(), _window_descs->end(), DescSorter); - IniFile *ini = new IniFile(); - ini->LoadFromDisk(_windows_file, NO_DIRECTORY); + IniFile ini; + ini.LoadFromDisk(_windows_file, NO_DIRECTORY); for (WindowDesc *wd : *_window_descs) { if (wd->ini_key == nullptr) continue; IniSaveWindowSettings(ini, wd->ini_key, wd); } - ini->SaveToDisk(_windows_file); - delete ini; + ini.SaveToDisk(_windows_file); } /** From 4f3bf84af4eb03936c0242871d7fb5b3b3214e2d Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 1 Jul 2021 20:06:04 +0200 Subject: [PATCH 03/42] Codechange: simplify SaveVersionInConfig() Clearly someone really wanted to generalize the function, but in reality it makes it a lot longer than needed. Let's keep it simple. --- src/settings.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/settings.cpp b/src/settings.cpp index 2a8c5b6cce..db84b0ca7a 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1524,18 +1524,8 @@ static void GameSaveConfig(IniFile &ini, const char *grpname) static void SaveVersionInConfig(IniFile &ini) { IniGroup *group = ini.GetGroup("version"); - - char version[9]; - seprintf(version, lastof(version), "%08X", _openttd_newgrf_version); - - const char * const versions[][2] = { - { "version_string", _openttd_revision }, - { "version_number", version } - }; - - for (uint i = 0; i < lengthof(versions); i++) { - group->GetItem(versions[i][0], true)->SetValue(versions[i][1]); - } + group->GetItem("version_string", true)->SetValue(_openttd_revision); + group->GetItem("version_number", true)->SetValue(fmt::format("{:08X}", _openttd_newgrf_version)); } /* Save a GRF configuration to the given group name */ From 75b6051b7ae3aade1f06c8eb2bb915add4f317d1 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Mon, 28 Jun 2021 16:39:48 +0200 Subject: [PATCH 04/42] Change: move sensitive information to secrets.cfg and private information to private.cfg We often ask people for their openttd.cfg, which now includes their passwords, usernames, etc. It is easy for people to overlook this, unwillingly sharing information they shouldn't. By splitting this information over either private.cfg or secrets.cfg, we make it more obvious they shouldn't be sharing those files, and hint to what is inside them. --- src/fileio.cpp | 4 + src/ini_load.cpp | 23 ++ src/ini_type.h | 1 + src/settings.cpp | 232 ++++++++++++++---- src/table/settings/CMakeLists.txt | 2 + .../settings/network_private_settings.ini | 68 +++++ .../settings/network_secrets_settings.ini | 76 ++++++ src/table/settings/network_settings.ini | 78 ------ 8 files changed, 361 insertions(+), 123 deletions(-) create mode 100644 src/table/settings/network_private_settings.ini create mode 100644 src/table/settings/network_secrets_settings.ini diff --git a/src/fileio.cpp b/src/fileio.cpp index fe9c947dff..c000362eff 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -1027,6 +1027,10 @@ void DeterminePaths(const char *exe, bool only_local_path) _hotkeys_file = config_dir + "hotkeys.cfg"; extern std::string _windows_file; _windows_file = config_dir + "windows.cfg"; + extern std::string _private_file; + _private_file = config_dir + "private.cfg"; + extern std::string _secrets_file; + _secrets_file = config_dir + "secrets.cfg"; #ifdef USE_XDG if (config_dir == config_home) { diff --git a/src/ini_load.cpp b/src/ini_load.cpp index 308f822be8..0663ef1e48 100644 --- a/src/ini_load.cpp +++ b/src/ini_load.cpp @@ -100,6 +100,29 @@ IniItem *IniGroup::GetItem(const std::string &name, bool create) return new IniItem(this, name); } +/** + * Remove the item with the given name. + * @param name Name of the item to remove. + */ +void IniGroup::RemoveItem(const std::string &name) +{ + IniItem **prev = &this->item; + + for (IniItem *item = this->item; item != nullptr; prev = &item->next, item = item->next) { + if (item->name != name) continue; + + *prev = item->next; + if (this->last_item == &this->item) { + this->last_item = &item->next; + } + + item->next = nullptr; + delete item; + + return; + } +} + /** * Clear all items in the group */ diff --git a/src/ini_type.h b/src/ini_type.h index 882ccc7896..607e8940b4 100644 --- a/src/ini_type.h +++ b/src/ini_type.h @@ -47,6 +47,7 @@ struct IniGroup { ~IniGroup(); IniItem *GetItem(const std::string &name, bool create); + void RemoveItem(const std::string &name); void Clear(); }; diff --git a/src/settings.cpp b/src/settings.cpp index db84b0ca7a..9847a0ff93 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -23,6 +23,7 @@ #include "stdafx.h" #include +#include #include #include "currency.h" #include "screenshot.h" @@ -81,8 +82,10 @@ ClientSettings _settings_client; GameSettings _settings_game; ///< Game settings of a running game or the scenario editor. GameSettings _settings_newgame; ///< Game settings for new games (updated from the intro screen). -VehicleDefaultSettings _old_vds; ///< Used for loading default vehicles settings from old savegames -std::string _config_file; ///< Configuration file of OpenTTD +VehicleDefaultSettings _old_vds; ///< Used for loading default vehicles settings from old savegames. +std::string _config_file; ///< Configuration file of OpenTTD. +std::string _private_file; ///< Private configuration file of OpenTTD. +std::string _secrets_file; ///< Secrets configuration file of OpenTTD. typedef std::list ErrorList; static ErrorList _settings_error_list; ///< Errors while loading minimal settings. @@ -90,7 +93,7 @@ static ErrorList _settings_error_list; ///< Errors while loading minimal setting typedef span SettingTable; /** - * List of all the setting tables. + * List of all the generic setting tables. * * There are a few tables that are special and not processed like the rest: * - _currency_settings @@ -99,11 +102,25 @@ typedef span SettingTable; * - _win32_settings * As such, they are not part of this list. */ -static const SettingTable _setting_tables[] = { +static const SettingTable _generic_setting_tables[] = { _settings, _network_settings, }; +/** + * List of all the private setting tables. + */ +static const SettingTable _private_setting_tables[] = { + _network_private_settings, +}; + +/** + * List of all the secrets setting tables. + */ +static const SettingTable _secrets_setting_tables[] = { + _network_secrets_settings, +}; + typedef void SettingDescProc(IniFile &ini, const SettingTable &desc, const char *grpname, void *object, bool only_startup); typedef void SettingDescProcList(IniFile &ini, const char *grpname, StringList &list); @@ -129,6 +146,22 @@ public: } }; +/** + * Ini-file versions. + * + * Sometimes we move settings between different ini-files, as we need to know + * when we have to load/remove it from the old versus reading it from the new + * location. These versions assist with situations like that. + */ +enum IniFileVersion : uint32 { + IFV_0, ///< 0 All versions prior to introduction. + IFV_PRIVATE_SECRETS, ///< 1 PR#9298 Moving of settings from openttd.cfg to private.cfg / secrets.cfg. + + IFV_MAX_VERSION, ///< Highest possible ini-file version. +}; + +const uint16 INIFILE_VERSION = (IniFileVersion)(IFV_MAX_VERSION - 1); ///< Current ini-file version of OpenTTD. + /** * Helper to convert the type of the iterated settings description to a pointer to it. * @param desc The type of the iterator of the value in SettingTable. @@ -1473,6 +1506,20 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati return first; } +static IniFileVersion LoadVersionFromConfig(IniFile &ini) +{ + IniGroup *group = ini.GetGroup("version"); + + auto version_number = group->GetItem("ini_version", false); + /* Older ini-file versions don't have this key yet. */ + if (version_number == nullptr || !version_number->value.has_value()) return IFV_0; + + uint32 version = 0; + std::from_chars(version_number->value->data(), version_number->value->data() + version_number->value->size(), version); + + return static_cast(version); +} + static void AISaveConfig(IniFile &ini, const char *grpname) { IniGroup *group = ini.GetGroup(grpname); @@ -1526,6 +1573,7 @@ static void SaveVersionInConfig(IniFile &ini) IniGroup *group = ini.GetGroup("version"); group->GetItem("version_string", true)->SetValue(_openttd_revision); group->GetItem("version_number", true)->SetValue(fmt::format("{:08X}", _openttd_newgrf_version)); + group->GetItem("ini_version", true)->SetValue(std::to_string(INIFILE_VERSION)); } /* Save a GRF configuration to the given group name */ @@ -1549,25 +1597,58 @@ static void GRFSaveConfig(IniFile &ini, const char *grpname, const GRFConfig *li } /* Common handler for saving/loading variables to the configuration file */ -static void HandleSettingDescs(IniFile &ini, SettingDescProc *proc, SettingDescProcList *proc_list, bool only_startup = false) +static void HandleSettingDescs(IniFile &generic_ini, IniFile &private_ini, IniFile &secrets_ini, SettingDescProc *proc, SettingDescProcList *proc_list, bool only_startup = false) { - proc(ini, _misc_settings, "misc", nullptr, only_startup); + proc(generic_ini, _misc_settings, "misc", nullptr, only_startup); #if defined(_WIN32) && !defined(DEDICATED) - proc(ini, _win32_settings, "win32", nullptr, only_startup); + proc(generic_ini, _win32_settings, "win32", nullptr, only_startup); #endif /* _WIN32 */ - for (auto &table : _setting_tables) { - /* The name "patches" is a fallback, as every setting should sets its own group. */ - proc(ini, table, "patches", &_settings_newgame, only_startup); + /* The name "patches" is a fallback, as every setting should sets its own group. */ + + for (auto &table : _generic_setting_tables) { + proc(generic_ini, table, "patches", &_settings_newgame, only_startup); + } + for (auto &table : _private_setting_tables) { + proc(private_ini, table, "patches", &_settings_newgame, only_startup); + } + for (auto &table : _secrets_setting_tables) { + proc(secrets_ini, table, "patches", &_settings_newgame, only_startup); } - proc(ini, _currency_settings,"currency", &_custom_currency, only_startup); - proc(ini, _company_settings, "company", &_settings_client.company, only_startup); + proc(generic_ini, _currency_settings, "currency", &_custom_currency, only_startup); + proc(generic_ini, _company_settings, "company", &_settings_client.company, only_startup); if (!only_startup) { - proc_list(ini, "server_bind_addresses", _network_bind_list); - proc_list(ini, "servers", _network_host_list); - proc_list(ini, "bans", _network_ban_list); + proc_list(private_ini, "server_bind_addresses", _network_bind_list); + proc_list(private_ini, "servers", _network_host_list); + proc_list(private_ini, "bans", _network_ban_list); + } +} + +/** + * Remove all entries from a settings table from an ini-file. + * + * This is only useful if those entries are moved to another file, and you + * want to clean up what is left behind. + * + * @param ini The ini file to remove the entries from. + * @param table The table to look for entries to remove. + */ +static void RemoveEntriesFromIni(IniFile &ini, const SettingTable &table) +{ + for (auto &desc : table) { + const SettingDesc *sd = GetSettingDesc(desc); + + /* For settings.xx.yy load the settings from [xx] yy = ? */ + std::string s{ sd->name }; + auto sc = s.find('.'); + if (sc == std::string::npos) continue; + + IniGroup *group = ini.GetGroup(s.substr(0, sc)); + s = s.substr(sc + 1); + + group->RemoveItem(s); } } @@ -1577,20 +1658,30 @@ static void HandleSettingDescs(IniFile &ini, SettingDescProc *proc, SettingDescP */ void LoadFromConfig(bool startup) { - ConfigIniFile ini(_config_file); + ConfigIniFile generic_ini(_config_file); + ConfigIniFile private_ini(_private_file); + ConfigIniFile secrets_ini(_secrets_file); + if (!startup) ResetCurrencies(false); // Initialize the array of currencies, without preserving the custom one - /* Load basic settings only during bootstrap, load other settings not during bootstrap */ - HandleSettingDescs(ini, IniLoadSettings, IniLoadSettingList, startup); + IniFileVersion generic_version = LoadVersionFromConfig(generic_ini); + /* Before the split of private/secrets, we have to look in the generic for these settings. */ + if (generic_version < IFV_PRIVATE_SECRETS) { + HandleSettingDescs(generic_ini, generic_ini, generic_ini, IniLoadSettings, IniLoadSettingList, startup); + } else { + HandleSettingDescs(generic_ini, private_ini, secrets_ini, IniLoadSettings, IniLoadSettingList, startup); + } + + /* Load basic settings only during bootstrap, load other settings not during bootstrap */ if (!startup) { - _grfconfig_newgame = GRFLoadConfig(ini, "newgrf", false); - _grfconfig_static = GRFLoadConfig(ini, "newgrf-static", true); - AILoadConfig(ini, "ai_players"); - GameLoadConfig(ini, "game_scripts"); + _grfconfig_newgame = GRFLoadConfig(generic_ini, "newgrf", false); + _grfconfig_static = GRFLoadConfig(generic_ini, "newgrf-static", true); + AILoadConfig(generic_ini, "ai_players"); + GameLoadConfig(generic_ini, "game_scripts"); PrepareOldDiffCustom(); - IniLoadSettings(ini, _gameopt_settings, "gameopt", &_settings_newgame, false); + IniLoadSettings(generic_ini, _gameopt_settings, "gameopt", &_settings_newgame, false); HandleOldDiffCustom(false); ValidateSettings(); @@ -1605,20 +1696,52 @@ void LoadFromConfig(bool startup) /** Save the values to the configuration file */ void SaveToConfig() { - ConfigIniFile ini(_config_file); + ConfigIniFile generic_ini(_config_file); + ConfigIniFile private_ini(_private_file); + ConfigIniFile secrets_ini(_secrets_file); - /* Remove some obsolete groups. These have all been loaded into other groups. */ - ini.RemoveGroup("patches"); - ini.RemoveGroup("yapf"); - ini.RemoveGroup("gameopt"); + IniFileVersion generic_version = LoadVersionFromConfig(generic_ini); - HandleSettingDescs(ini, IniSaveSettings, IniSaveSettingList); - GRFSaveConfig(ini, "newgrf", _grfconfig_newgame); - GRFSaveConfig(ini, "newgrf-static", _grfconfig_static); - AISaveConfig(ini, "ai_players"); - GameSaveConfig(ini, "game_scripts"); - SaveVersionInConfig(ini); - ini.SaveToDisk(_config_file); + /* If we newly create the private/secrets file, add a dummy group on top + * just so we can add a comment before it (that is how IniFile works). + * This to explain what the file is about. After doing it once, never touch + * it again, as otherwise we might be reverting user changes. */ + if (!private_ini.GetGroup("private", false)) private_ini.GetGroup("private")->comment = "; This file possibly contains private information which can identify you as person.\n"; + if (!secrets_ini.GetGroup("secrets", false)) secrets_ini.GetGroup("secrets")->comment = "; Do not share this file with others, not even if they claim to be technical support.\n; This file contains saved passwords and other secrets that should remain private to you!\n"; + + if (generic_version == IFV_0) { + /* Remove some obsolete groups. These have all been loaded into other groups. */ + generic_ini.RemoveGroup("patches"); + generic_ini.RemoveGroup("yapf"); + generic_ini.RemoveGroup("gameopt"); + + /* Remove all settings from the generic ini that are now in the private ini. */ + generic_ini.RemoveGroup("server_bind_addresses"); + generic_ini.RemoveGroup("servers"); + generic_ini.RemoveGroup("bans"); + for (auto &table : _private_setting_tables) { + RemoveEntriesFromIni(generic_ini, table); + } + + /* Remove all settings from the generic ini that are now in the secrets ini. */ + for (auto &table : _secrets_setting_tables) { + RemoveEntriesFromIni(generic_ini, table); + } + } + + HandleSettingDescs(generic_ini, private_ini, secrets_ini, IniSaveSettings, IniSaveSettingList); + GRFSaveConfig(generic_ini, "newgrf", _grfconfig_newgame); + GRFSaveConfig(generic_ini, "newgrf-static", _grfconfig_static); + AISaveConfig(generic_ini, "ai_players"); + GameSaveConfig(generic_ini, "game_scripts"); + + SaveVersionInConfig(generic_ini); + SaveVersionInConfig(private_ini); + SaveVersionInConfig(secrets_ini); + + generic_ini.SaveToDisk(_config_file); + private_ini.SaveToDisk(_private_file); + secrets_ini.SaveToDisk(_secrets_file); } /** @@ -1778,7 +1901,15 @@ static const SettingDesc *GetCompanySettingFromName(std::string_view name) */ const SettingDesc *GetSettingFromName(const std::string_view name) { - for (auto &table : _setting_tables) { + for (auto &table : _generic_setting_tables) { + auto sd = GetSettingFromName(name, table); + if (sd != nullptr) return sd; + } + for (auto &table : _private_setting_tables) { + auto sd = GetSettingFromName(name, table); + if (sd != nullptr) return sd; + } + for (auto &table : _secrets_setting_tables) { auto sd = GetSettingFromName(name, table); if (sd != nullptr) return sd; } @@ -2014,6 +2145,18 @@ void IConsoleGetSetting(const char *name, bool force_newgame) } } +static void IConsoleListSettingsTable(const SettingTable &table, const char *prefilter) +{ + for (auto &desc : table) { + const SettingDesc *sd = GetSettingDesc(desc); + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; + if (prefilter != nullptr && sd->name.find(prefilter) == std::string::npos) continue; + char value[80]; + sd->FormatValue(value, lastof(value), &GetGameSettings()); + IConsolePrint(CC_DEFAULT, "{} = {}", sd->name, value); + } +} + /** * List all settings and their value to the console * @@ -2023,15 +2166,14 @@ void IConsoleListSettings(const char *prefilter) { IConsolePrint(CC_HELP, "All settings with their current value:"); - for (auto &table : _setting_tables) { - for (auto &desc : table) { - const SettingDesc *sd = GetSettingDesc(desc); - if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; - if (prefilter != nullptr && sd->name.find(prefilter) == std::string::npos) continue; - char value[80]; - sd->FormatValue(value, lastof(value), &GetGameSettings()); - IConsolePrint(CC_DEFAULT, "{} = {}", sd->name, value); - } + for (auto &table : _generic_setting_tables) { + IConsoleListSettingsTable(table, prefilter); + } + for (auto &table : _private_setting_tables) { + IConsoleListSettingsTable(table, prefilter); + } + for (auto &table : _secrets_setting_tables) { + IConsoleListSettingsTable(table, prefilter); } IConsolePrint(CC_HELP, "Use 'setting' command to change a value."); diff --git a/src/table/settings/CMakeLists.txt b/src/table/settings/CMakeLists.txt index 802b6b42da..f4d3c209ed 100644 --- a/src/table/settings/CMakeLists.txt +++ b/src/table/settings/CMakeLists.txt @@ -7,6 +7,8 @@ set(TABLE_INI_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/gameopt_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/misc_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/network_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/network_private_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/network_secrets_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/win32_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/window_settings.ini diff --git a/src/table/settings/network_private_settings.ini b/src/table/settings/network_private_settings.ini new file mode 100644 index 0000000000..76fbd373ae --- /dev/null +++ b/src/table/settings/network_private_settings.ini @@ -0,0 +1,68 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; Network settings as stored in the private configuration file ("private.cfg"). + +[pre-amble] +static const SettingVariant _network_private_settings[] = { +[post-amble] +}; +[templates] +SDTC_SSTR = SDTC_SSTR( $var, $type, $flags, $def, $length, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + + +[SDTC_SSTR] +var = network.client_name +type = SLE_STR +length = NETWORK_CLIENT_NAME_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = nullptr +pre_cb = NetworkValidateClientName +post_cb = NetworkUpdateClientName +cat = SC_BASIC + +[SDTC_SSTR] +var = network.server_name +type = SLE_STR +length = NETWORK_NAME_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = nullptr +pre_cb = NetworkValidateServerName +post_cb = [](auto) { UpdateClientConfigValues(); } +cat = SC_BASIC + +[SDTC_SSTR] +var = network.connect_to_ip +type = SLE_STR +length = 0 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = nullptr + +[SDTC_SSTR] +var = network.last_joined +type = SLE_STR +length = 0 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = """" +cat = SC_EXPERT diff --git a/src/table/settings/network_secrets_settings.ini b/src/table/settings/network_secrets_settings.ini new file mode 100644 index 0000000000..a408bad409 --- /dev/null +++ b/src/table/settings/network_secrets_settings.ini @@ -0,0 +1,76 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; Network settings as stored in the secrets configuration file ("secrets.cfg"). + +[pre-amble] +static bool ReplaceAsteriskWithEmptyPassword(std::string &newval); + +static const SettingVariant _network_secrets_settings[] = { +[post-amble] +}; +[templates] +SDTC_SSTR = SDTC_SSTR( $var, $type, $flags, $def, $length, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + + +[SDTC_SSTR] +var = network.server_password +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = nullptr +pre_cb = ReplaceAsteriskWithEmptyPassword +post_cb = [](auto) { NetworkServerUpdateGameInfo(); } +cat = SC_BASIC + +[SDTC_SSTR] +var = network.rcon_password +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = nullptr +pre_cb = ReplaceAsteriskWithEmptyPassword +cat = SC_BASIC + +[SDTC_SSTR] +var = network.admin_password +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = nullptr +cat = SC_BASIC + +[SDTC_SSTR] +var = network.default_company_pass +type = SLE_STR +length = NETWORK_PASSWORD_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = nullptr + +[SDTC_SSTR] +var = network.network_id +type = SLE_STR +length = NETWORK_SERVER_ID_LENGTH +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY +def = nullptr diff --git a/src/table/settings/network_settings.ini b/src/table/settings/network_settings.ini index 5d33773c83..1317edbc72 100644 --- a/src/table/settings/network_settings.ini +++ b/src/table/settings/network_settings.ini @@ -7,7 +7,6 @@ ; Network settings as stored in the main configuration file ("openttd.cfg"). [pre-amble] -static bool ReplaceAsteriskWithEmptyPassword(std::string &newval); static void UpdateClientConfigValues(); static const SettingVariant _network_settings[] = { @@ -15,7 +14,6 @@ static const SettingVariant _network_settings[] = { }; [templates] SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDTC_SSTR = SDTC_SSTR( $var, $type, $flags, $def, $length, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), SDTC_VAR = SDTC_VAR( $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), [validation] @@ -166,74 +164,6 @@ var = network.server_advertise flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY def = false -[SDTC_SSTR] -var = network.client_name -type = SLE_STR -length = NETWORK_CLIENT_NAME_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = nullptr -pre_cb = NetworkValidateClientName -post_cb = NetworkUpdateClientName -cat = SC_BASIC - -[SDTC_SSTR] -var = network.server_password -type = SLE_STR -length = NETWORK_PASSWORD_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = nullptr -pre_cb = ReplaceAsteriskWithEmptyPassword -post_cb = [](auto) { NetworkServerUpdateGameInfo(); } -cat = SC_BASIC - -[SDTC_SSTR] -var = network.rcon_password -type = SLE_STR -length = NETWORK_PASSWORD_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = nullptr -pre_cb = ReplaceAsteriskWithEmptyPassword -cat = SC_BASIC - -[SDTC_SSTR] -var = network.admin_password -type = SLE_STR -length = NETWORK_PASSWORD_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = nullptr -cat = SC_BASIC - -[SDTC_SSTR] -var = network.default_company_pass -type = SLE_STR -length = NETWORK_PASSWORD_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = nullptr - -[SDTC_SSTR] -var = network.server_name -type = SLE_STR -length = NETWORK_NAME_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = nullptr -pre_cb = NetworkValidateServerName -post_cb = [](auto) { UpdateClientConfigValues(); } -cat = SC_BASIC - -[SDTC_SSTR] -var = network.connect_to_ip -type = SLE_STR -length = 0 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = nullptr - -[SDTC_SSTR] -var = network.network_id -type = SLE_STR -length = NETWORK_SERVER_ID_LENGTH -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY -def = nullptr - [SDTC_BOOL] var = network.autoclean_companies flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY @@ -316,14 +246,6 @@ flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY def = false cat = SC_EXPERT -[SDTC_SSTR] -var = network.last_joined -type = SLE_STR -length = 0 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = """" -cat = SC_EXPERT - [SDTC_BOOL] var = network.no_http_content_downloads flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC From 513641f9baaa732ab8000bc452a26284ae601f32 Mon Sep 17 00:00:00 2001 From: translators Date: Fri, 2 Jul 2021 18:50:57 +0000 Subject: [PATCH 05/42] Update: Translations from eints english (us): 1 change by 2TallTyler german: 1 change by Wuzzy2 dutch: 1 change by Afoklala --- src/lang/dutch.txt | 1 + src/lang/english_US.txt | 1 + src/lang/german.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index c4cff623c3..2b7d3068df 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -2152,6 +2152,7 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nieuw bedrijf) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Een nieuw bedrijf maken en meedoen STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Dit ben jij STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Dit is de host van het spel +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klant{P "" en} / {NUM} bedrij{P f ven} STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Eruit schoppen STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Bannen diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 7550f8314e..2833bdacee 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -2152,6 +2152,7 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(New company) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Create a new company and join it STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}This is you STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}This is the host of the game +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} compan{P y ies} STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Kick STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Ban diff --git a/src/lang/german.txt b/src/lang/german.txt index 5a3c015542..718dbe07e3 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -2153,6 +2153,7 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Neue Firma) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Eine neue Firma gründen und beitreten STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Das sind Sie STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Dies ist der Host des Spiels +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} Client{P "" s} / {NUM} Firm{P a en} STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Hinauswerfen STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Bannen From 7dd5fd6ed497e1da40c13075d6e37b54ab12a082 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Mon, 14 Jun 2021 10:05:30 +0200 Subject: [PATCH 06/42] Feature: framework to make savegames self-descriptive We won't be able to make it fully self-descriptive (looking at you MAP-chunks), but anything else can. With this framework, we can add headers for each chunk explaining how each chunk looks like in detail. They also will all be tables, making it a lot easier to read in external tooling, and opening the way to consider a database (like SQLite) to use as savegame format. Lastly, with the headers in the savegame, you can freely add fields without needing a savegame version bump; older versions of OpenTTD will simply ignore the new field. This also means we can remove all the SLE_CONDNULL, as they are irrelevant. The next few commits will start using this framework. --- src/core/span_type.hpp | 2 + src/saveload/ai_sl.cpp | 8 +- src/saveload/animated_tile_sl.cpp | 2 +- src/saveload/cheat_sl.cpp | 1 - src/saveload/company_sl.cpp | 12 +- src/saveload/depot_sl.cpp | 2 +- src/saveload/game_sl.cpp | 14 +- src/saveload/gamelog_sl.cpp | 26 +- src/saveload/industry_sl.cpp | 4 +- src/saveload/linkgraph_sl.cpp | 8 +- src/saveload/map_sl.cpp | 4 +- src/saveload/misc_sl.cpp | 44 ++-- src/saveload/saveload.cpp | 423 +++++++++++++++++++++++++++--- src/saveload/saveload.h | 154 ++++++++--- src/saveload/station_sl.cpp | 42 +-- src/saveload/town_sl.cpp | 6 +- src/saveload/vehicle_sl.cpp | 40 +-- src/script/script_instance.cpp | 2 +- src/settings.cpp | 2 +- src/table/settings.h.preamble | 12 +- 20 files changed, 620 insertions(+), 188 deletions(-) diff --git a/src/core/span_type.hpp b/src/core/span_type.hpp index 394b9ef38c..03bc678b7e 100644 --- a/src/core/span_type.hpp +++ b/src/core/span_type.hpp @@ -73,6 +73,8 @@ public: typedef size_t size_type; typedef std::ptrdiff_t difference_type; + constexpr span() noexcept : first(nullptr), last(nullptr) {} + constexpr span(pointer data_in, size_t size_in) : first(data_in), last(data_in + size_in) {} template::value), int>::type = 0> diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp index 49221ef300..1c44ef7323 100644 --- a/src/saveload/ai_sl.cpp +++ b/src/saveload/ai_sl.cpp @@ -26,10 +26,10 @@ static std::string _ai_saveload_settings; static bool _ai_saveload_is_random; static const SaveLoad _ai_company[] = { - SLEG_SSTR(_ai_saveload_name, SLE_STR), - SLEG_SSTR(_ai_saveload_settings, SLE_STR), - SLEG_CONDVAR(_ai_saveload_version, SLE_UINT32, SLV_108, SL_MAX_VERSION), - SLEG_CONDVAR(_ai_saveload_is_random, SLE_BOOL, SLV_136, SL_MAX_VERSION), + SLEG_SSTR("name", _ai_saveload_name, SLE_STR), + SLEG_SSTR("settings", _ai_saveload_settings, SLE_STR), + SLEG_CONDVAR("version", _ai_saveload_version, SLE_UINT32, SLV_108, SL_MAX_VERSION), + SLEG_CONDVAR("is_random", _ai_saveload_is_random, SLE_BOOL, SLV_136, SL_MAX_VERSION), }; static void SaveReal_AIPL(int *index_ptr) diff --git a/src/saveload/animated_tile_sl.cpp b/src/saveload/animated_tile_sl.cpp index 7f05eaeeb7..2e0666d4a2 100644 --- a/src/saveload/animated_tile_sl.cpp +++ b/src/saveload/animated_tile_sl.cpp @@ -19,7 +19,7 @@ extern std::vector _animated_tiles; static const SaveLoad _animated_tile_desc[] = { - SLEG_VECTOR(_animated_tiles, SLE_UINT32), + SLEG_VECTOR("tiles", _animated_tiles, SLE_UINT32), }; /** diff --git a/src/saveload/cheat_sl.cpp b/src/saveload/cheat_sl.cpp index 51df50314e..6c6bab4ddb 100644 --- a/src/saveload/cheat_sl.cpp +++ b/src/saveload/cheat_sl.cpp @@ -74,7 +74,6 @@ static void Load_CHTS() if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many CHTS entries"); } -/** Chunk handlers related to cheats. */ static const ChunkHandler cheat_chunk_handlers[] = { { 'CHTS', Save_CHTS, Load_CHTS, nullptr, nullptr, CH_ARRAY }, }; diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 880fc9e891..7abec80418 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -294,7 +294,7 @@ public: SLE_CONDNULL(32, SL_MIN_VERSION, SLV_107), SLE_CONDNULL(64, SLV_2, SLV_107), - SLEG_STRUCTLIST(SlCompanyOldAIBuildRec), + SLEG_STRUCTLIST("build_rec", SlCompanyOldAIBuildRec), }; void GenericSaveLoad(CompanyProperties *c) const @@ -513,11 +513,11 @@ static const SaveLoad _company_desc[] = { SLE_CONDVAR(CompanyProperties, terraform_limit, SLE_UINT32, SLV_156, SL_MAX_VERSION), SLE_CONDVAR(CompanyProperties, clear_limit, SLE_UINT32, SLV_156, SL_MAX_VERSION), SLE_CONDVAR(CompanyProperties, tree_limit, SLE_UINT32, SLV_175, SL_MAX_VERSION), - SLEG_STRUCT(SlCompanySettings), - SLEG_CONDSTRUCT(SlCompanyOldAI, SL_MIN_VERSION, SLV_107), - SLEG_STRUCT(SlCompanyEconomy), - SLEG_STRUCTLIST(SlCompanyOldEconomy), - SLEG_CONDSTRUCTLIST(SlCompanyLiveries, SLV_34, SL_MAX_VERSION), + SLEG_STRUCT("settings", SlCompanySettings), + SLEG_CONDSTRUCT("old_ai", SlCompanyOldAI, SL_MIN_VERSION, SLV_107), + SLEG_STRUCT("cur_economy", SlCompanyEconomy), + SLEG_STRUCTLIST("old_economy", SlCompanyOldEconomy), + SLEG_CONDSTRUCTLIST("liveries", SlCompanyLiveries, SLV_34, SL_MAX_VERSION), }; static void Save_PLYR() diff --git a/src/saveload/depot_sl.cpp b/src/saveload/depot_sl.cpp index da195416bd..6af08e718d 100644 --- a/src/saveload/depot_sl.cpp +++ b/src/saveload/depot_sl.cpp @@ -20,7 +20,7 @@ static TownID _town_index; static const SaveLoad _depot_desc[] = { SLE_CONDVAR(Depot, xy, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), SLE_CONDVAR(Depot, xy, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLEG_CONDVAR(_town_index, SLE_UINT16, SL_MIN_VERSION, SLV_141), + SLEG_CONDVAR("town_index", _town_index, SLE_UINT16, SL_MIN_VERSION, SLV_141), SLE_CONDREF(Depot, town, REF_TOWN, SLV_141, SL_MAX_VERSION), SLE_CONDVAR(Depot, town_cn, SLE_UINT16, SLV_141, SL_MAX_VERSION), SLE_CONDSSTR(Depot, name, SLE_STR, SLV_141, SL_MAX_VERSION), diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index 48281ed665..1ef513c635 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -26,10 +26,10 @@ static std::string _game_saveload_settings; static bool _game_saveload_is_random; static const SaveLoad _game_script[] = { - SLEG_SSTR(_game_saveload_name, SLE_STR), - SLEG_SSTR(_game_saveload_settings, SLE_STR), - SLEG_VAR(_game_saveload_version, SLE_UINT32), - SLEG_VAR(_game_saveload_is_random, SLE_BOOL), + SLEG_SSTR("name", _game_saveload_name, SLE_STR), + SLEG_SSTR("settings", _game_saveload_settings, SLE_STR), + SLEG_VAR("version", _game_saveload_version, SLE_UINT32), + SLEG_VAR("is_random", _game_saveload_is_random, SLE_BOOL), }; static void SaveReal_GSDT(int *index_ptr) @@ -116,7 +116,7 @@ static uint32 _game_saveload_strings; class SlGameLanguageString : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { - SLEG_SSTR(_game_saveload_string, SLE_STR | SLF_ALLOW_CONTROL), + SLEG_SSTR("string", _game_saveload_string, SLE_STR | SLF_ALLOW_CONTROL), }; void Save(LanguageStrings *ls) const override @@ -142,8 +142,8 @@ public: static const SaveLoad _game_language_desc[] = { SLE_SSTR(LanguageStrings, language, SLE_STR), - SLEG_CONDVAR(_game_saveload_strings, SLE_UINT32, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH), - SLEG_STRUCTLIST(SlGameLanguageString), + SLEG_CONDVAR("count", _game_saveload_strings, SLE_UINT32, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH), + SLEG_STRUCTLIST("strings", SlGameLanguageString), }; static void Load_GSTR() diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index 9f7f4f140d..f76718d42a 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.cpp @@ -204,7 +204,7 @@ class SlGamelogEmergency : public DefaultSaveLoadHandlerGetSize() + length; + if (_sl.expect_table_header) { + _sl.expect_table_header = false; + return INT32_MAX; + } + switch (_sl.block_mode) { + case CH_SPARSE_TABLE: case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break; + case CH_TABLE: case CH_ARRAY: index = _sl.array_index++; break; default: Debug(sl, 0, "SlIterateArray error"); @@ -687,6 +729,12 @@ void SlSetLength(size_t length) switch (_sl.need_length) { case NL_WANTLENGTH: _sl.need_length = NL_NONE; + if ((_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE) && _sl.expect_table_header) { + _sl.expect_table_header = false; + SlWriteArrayLength(length + 1); + break; + } + switch (_sl.block_mode) { case CH_RIFF: /* Ugly encoding of >16M RIFF chunks @@ -695,6 +743,7 @@ void SlSetLength(size_t length) assert(length < (1 << 28)); SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28))); break; + case CH_TABLE: case CH_ARRAY: assert(_sl.last_array_index <= _sl.array_index); while (++_sl.last_array_index <= _sl.array_index) { @@ -702,6 +751,7 @@ void SlSetLength(size_t length) } SlWriteArrayLength(length + 1); break; + case CH_SPARSE_TABLE: case CH_SPARSE_ARRAY: SlWriteArrayLength(length + 1 + SlGetArrayLength(_sl.array_index)); // Also include length of sparse index. SlWriteSparseIndex(_sl.array_index); @@ -1142,7 +1192,15 @@ static void SlArray(void *array, size_t length, VarType conv) case SLA_LOAD: { if (!IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH)) { size_t sv_length = SlReadArrayLength(); - if (sv_length != length) SlErrorCorrupt("Fixed-length array is of wrong length"); + if (GetVarMemType(conv) == SLE_VAR_NULL) { + /* We don't know this field, so we assume the length in the savegame is correct. */ + length = sv_length; + } else if (sv_length != length) { + /* If the SLE_ARR changes size, a savegame bump is required + * and the developer should have written conversion lines. + * Error out to make this more visible. */ + SlErrorCorrupt("Fixed-length array is of wrong length"); + } } SlCopyInternal(array, length, conv); @@ -1501,6 +1559,34 @@ static inline bool SlIsObjectValidInSavegame(const SaveLoad &sld) return (_sl_version >= sld.version_from && _sl_version < sld.version_to); } +/** + * Calculate the size of the table header. + * @param slt The SaveLoad table with objects to save/load. + * @return size of given object. + */ +static size_t SlCalcTableHeader(const SaveLoadTable &slt) +{ + size_t length = 0; + + for (auto &sld : slt) { + if (!SlIsObjectValidInSavegame(sld)) continue; + + length += SlCalcConvFileLen(SLE_UINT8); + length += SlCalcStdStringLen(&sld.name); + } + + length += SlCalcConvFileLen(SLE_UINT8); // End-of-list entry. + + for (auto &sld : slt) { + if (!SlIsObjectValidInSavegame(sld)) continue; + if (sld.cmd == SL_STRUCTLIST || sld.cmd == SL_STRUCT) { + length += SlCalcTableHeader(sld.handler->GetDescription()); + } + } + + return length; +} + /** * Calculate the size of an object. * @param object to be measured. @@ -1764,6 +1850,233 @@ void SlObject(void *object, const SaveLoadTable &slt) } } +/** + * Handler that is assigned when there is a struct read in the savegame which + * is not known to the code. This means we are going to skip it. + */ +class SlSkipHandler : public SaveLoadHandler { + void Save(void *object) const override + { + NOT_REACHED(); + } + + void Load(void *object) const override + { + size_t length = SlGetStructListLength(UINT32_MAX); + for (; length > 0; length--) { + SlObject(object, this->GetLoadDescription()); + } + } + + void LoadCheck(void *object) const override + { + this->Load(object); + } + + virtual SaveLoadTable GetDescription() const override + { + return {}; + } + + virtual SaveLoadCompatTable GetCompatDescription() const override + { + NOT_REACHED(); + } +}; + +/** + * Save or Load a table header. + * @note a table-header can never contain more than 65535 fields. + * @param slt The SaveLoad table with objects to save/load. + * @return When loading, the ordered SaveLoad array to use; otherwise an empty list. + */ +std::vector SlTableHeader(const SaveLoadTable &slt) +{ + /* You can only use SlTableHeader if you are a CH_TABLE. */ + assert(_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE); + + switch (_sl.action) { + case SLA_LOAD_CHECK: + case SLA_LOAD: { + std::vector saveloads; + + /* Build a key lookup mapping based on the available fields. */ + std::map key_lookup; + for (auto &sld : slt) { + if (!SlIsObjectValidInSavegame(sld)) continue; + + /* Check that there is only one active SaveLoad for a given name. */ + assert(key_lookup.find(sld.name) == key_lookup.end()); + key_lookup[sld.name] = &sld; + } + + while (true) { + uint8 type; + SlSaveLoadConv(&type, SLE_UINT8); + if (type == SLE_FILE_END) break; + + std::string key; + SlStdString(&key, SLE_STR); + + auto sld_it = key_lookup.find(key); + if (sld_it == key_lookup.end()) { + Debug(sl, 2, "Field '{}' of type 0x{:02x} not found, skipping", key, type); + + std::shared_ptr handler = nullptr; + SaveLoadType slt; + switch (type & SLE_FILE_TYPE_MASK) { + case SLE_FILE_STRING: + /* Strings are always marked with SLE_FILE_HAS_LENGTH_FIELD, as they are a list of chars. */ + slt = SL_STR; + break; + + case SLE_FILE_STRUCT: + /* Structs are always marked with SLE_FILE_HAS_LENGTH_FIELD as SL_STRUCT is seen as a list of 0/1 in length. */ + slt = SL_STRUCTLIST; + handler = std::make_shared(); + break; + + default: + slt = (type & SLE_FILE_HAS_LENGTH_FIELD) ? SL_ARR : SL_VAR; + break; + } + + /* We don't know this field, so read to nothing. */ + saveloads.push_back({key, slt, ((VarType)type & SLE_FILE_TYPE_MASK) | SLE_VAR_NULL, 1, SL_MIN_VERSION, SL_MAX_VERSION, 0, nullptr, 0, handler}); + continue; + } + + /* Validate the type of the field. If it is changed, the + * savegame should have been bumped so we know how to do the + * conversion. If this error triggers, that clearly didn't + * happen and this is a friendly poke to the developer to bump + * the savegame version and add conversion code. */ + uint8 correct_type = GetSavegameFileType(*sld_it->second); + if (correct_type != type) { + Debug(sl, 1, "Field type for '{}' was expected to be 0x{:02x} but 0x{:02x} was found", key, correct_type, type); + SlErrorCorrupt("Field type is different than expected"); + } + saveloads.push_back(*sld_it->second); + } + + for (auto &sld : saveloads) { + if (sld.cmd == SL_STRUCTLIST || sld.cmd == SL_STRUCT) { + sld.handler->load_description = SlTableHeader(sld.handler->GetDescription()); + } + } + + return saveloads; + } + + case SLA_SAVE: { + /* Automatically calculate the length? */ + if (_sl.need_length != NL_NONE) { + SlSetLength(SlCalcTableHeader(slt)); + if (_sl.need_length == NL_CALCLENGTH) break; + } + + for (auto &sld : slt) { + if (!SlIsObjectValidInSavegame(sld)) continue; + /* Make sure we are not storing empty keys. */ + assert(!sld.name.empty()); + + uint8 type = GetSavegameFileType(sld); + assert(type != SLE_FILE_END); + + SlSaveLoadConv(&type, SLE_UINT8); + SlStdString(const_cast(&sld.name), SLE_STR); + } + + /* Add an end-of-header marker. */ + uint8 type = SLE_FILE_END; + SlSaveLoadConv(&type, SLE_UINT8); + + /* After the table, write down any sub-tables we might have. */ + for (auto &sld : slt) { + if (!SlIsObjectValidInSavegame(sld)) continue; + if (sld.cmd == SL_STRUCTLIST || sld.cmd == SL_STRUCT) { + /* SlCalcTableHeader already looks in sub-lists, so avoid the length being added twice. */ + NeedLength old_need_length = _sl.need_length; + _sl.need_length = NL_NONE; + + SlTableHeader(sld.handler->GetDescription()); + + _sl.need_length = old_need_length; + } + } + + break; + } + + default: NOT_REACHED(); + } + + return std::vector(); +} + +/** + * Load a table header in a savegame compatible way. If the savegame was made + * before table headers were added, it will fall back to the + * SaveLoadCompatTable for the order of fields while loading. + * + * @note You only have to call this function if the chunk existed as a + * non-table type before converting it to a table. New chunks created as + * table can call SlTableHeader() directly. + * + * @param slt The SaveLoad table with objects to save/load. + * @param slct The SaveLoadCompat table the original order of the fields. + * @return When loading, the ordered SaveLoad array to use; otherwise an empty list. + */ +std::vector SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct) +{ + assert(_sl.action == SLA_LOAD || _sl.action == SLA_LOAD_CHECK); + /* CH_TABLE / CH_SPARSE_TABLE always have a header. */ + if (_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE) return SlTableHeader(slt); + + std::vector saveloads; + + /* Build a key lookup mapping based on the available fields. */ + std::map> key_lookup; + for (auto &sld : slt) { + /* All entries should have a name; otherwise the entry should just be removed. */ + assert(!sld.name.empty()); + + key_lookup[sld.name].push_back(&sld); + } + + for (auto &slc : slct) { + if (slc.name.empty()) { + /* In old savegames there can be data we no longer care for. We + * skip this by simply reading the amount of bytes indicated and + * send those to /dev/null. */ + saveloads.push_back({"", SL_NULL, SLE_FILE_U8 | SLE_VAR_NULL, slc.length, slc.version_from, slc.version_to, 0, nullptr, 0, nullptr}); + } else { + auto sld_it = key_lookup.find(slc.name); + /* If this branch triggers, it means that an entry in the + * SaveLoadCompat list is not mentioned in the SaveLoad list. Did + * you rename a field in one and not in the other? */ + if (sld_it == key_lookup.end()) { + /* This isn't an assert, as that leaves no information what + * field was to blame. This way at least we have breadcrumbs. */ + Debug(sl, 0, "internal error: saveload compatibility field '{}' not found", slc.name); + SlErrorCorrupt("Internal error with savegame compatibility"); + } + for (auto &sld : sld_it->second) { + saveloads.push_back(*sld); + } + } + } + + for (auto &sld : saveloads) { + if (!SlIsObjectValidInSavegame(sld)) continue; + if (sld.cmd == SL_STRUCTLIST || sld.cmd == SL_STRUCT) { + sld.handler->load_description = SlCompatTableHeader(sld.handler->GetDescription(), sld.handler->GetCompatDescription()); + } + } + + return saveloads; +} + /** * Save or Load (a list of) global variables. * @param slt The SaveLoad table with objects to save/load. @@ -1811,33 +2124,43 @@ static void SlLoadChunk(const ChunkHandler &ch) size_t len; size_t endoffs; - _sl.block_mode = m; + _sl.block_mode = m & CH_TYPE_MASK; _sl.obj_len = 0; + _sl.expect_table_header = (_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE); - switch (m) { + /* The header should always be at the start. Read the length; the + * load_proc() should as first action process the header. */ + if (_sl.expect_table_header) { + SlIterateArray(); + } + + switch (_sl.block_mode) { + case CH_TABLE: case CH_ARRAY: _sl.array_index = 0; ch.load_proc(); if (_next_offs != 0) SlErrorCorrupt("Invalid array length"); break; + case CH_SPARSE_TABLE: case CH_SPARSE_ARRAY: ch.load_proc(); if (_next_offs != 0) SlErrorCorrupt("Invalid array length"); break; + case CH_RIFF: + /* Read length */ + len = (SlReadByte() << 16) | ((m >> 4) << 24); + len += SlReadUint16(); + _sl.obj_len = len; + endoffs = _sl.reader->GetSize() + len; + ch.load_proc(); + if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size"); + break; default: - if ((m & 0xF) == CH_RIFF) { - /* Read length */ - len = (SlReadByte() << 16) | ((m >> 4) << 24); - len += SlReadUint16(); - _sl.obj_len = len; - endoffs = _sl.reader->GetSize() + len; - ch.load_proc(); - if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size"); - } else { - SlErrorCorrupt("Invalid chunk type"); - } + SlErrorCorrupt("Invalid chunk type"); break; } + + if (_sl.expect_table_header) SlErrorCorrupt("Table chunk without header"); } /** @@ -1851,43 +2174,54 @@ static void SlLoadCheckChunk(const ChunkHandler &ch) size_t len; size_t endoffs; - _sl.block_mode = m; + _sl.block_mode = m & CH_TYPE_MASK; _sl.obj_len = 0; + _sl.expect_table_header = (_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE); - switch (m) { + /* The header should always be at the start. Read the length; the + * load_check_proc() should as first action process the header. */ + if (_sl.expect_table_header && ch.load_check_proc != nullptr) { + /* If load_check_proc() is nullptr, SlSkipArray() will already skip the header. */ + SlIterateArray(); + } + + switch (_sl.block_mode) { + case CH_TABLE: case CH_ARRAY: _sl.array_index = 0; - if (ch.load_check_proc) { + if (ch.load_check_proc != nullptr) { ch.load_check_proc(); } else { SlSkipArray(); } break; + case CH_SPARSE_TABLE: case CH_SPARSE_ARRAY: - if (ch.load_check_proc) { + if (ch.load_check_proc != nullptr) { ch.load_check_proc(); } else { SlSkipArray(); } break; + case CH_RIFF: + /* Read length */ + len = (SlReadByte() << 16) | ((m >> 4) << 24); + len += SlReadUint16(); + _sl.obj_len = len; + endoffs = _sl.reader->GetSize() + len; + if (ch.load_check_proc) { + ch.load_check_proc(); + } else { + SlSkipBytes(len); + } + if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size"); + break; default: - if ((m & 0xF) == CH_RIFF) { - /* Read length */ - len = (SlReadByte() << 16) | ((m >> 4) << 24); - len += SlReadUint16(); - _sl.obj_len = len; - endoffs = _sl.reader->GetSize() + len; - if (ch.load_check_proc) { - ch.load_check_proc(); - } else { - SlSkipBytes(len); - } - if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size"); - } else { - SlErrorCorrupt("Invalid chunk type"); - } + SlErrorCorrupt("Invalid chunk type"); break; } + + if (_sl.expect_table_header) SlErrorCorrupt("Table chunk without header"); } /** @@ -1906,24 +2240,31 @@ static void SlSaveChunk(const ChunkHandler &ch) Debug(sl, 2, "Saving chunk {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id); _sl.block_mode = ch.type; - switch (ch.type) { + _sl.expect_table_header = (_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE); + + _sl.need_length = (_sl.expect_table_header || _sl.block_mode == CH_RIFF) ? NL_WANTLENGTH : NL_NONE; + + switch (_sl.block_mode) { case CH_RIFF: - _sl.need_length = NL_WANTLENGTH; proc(); break; + case CH_TABLE: case CH_ARRAY: _sl.last_array_index = 0; - SlWriteByte(CH_ARRAY); + SlWriteByte(_sl.block_mode); proc(); SlWriteArrayLength(0); // Terminate arrays break; + case CH_SPARSE_TABLE: case CH_SPARSE_ARRAY: - SlWriteByte(CH_SPARSE_ARRAY); + SlWriteByte(_sl.block_mode); proc(); SlWriteArrayLength(0); // Terminate arrays break; default: NOT_REACHED(); } + + if (_sl.expect_table_header) SlErrorCorrupt("Table chunk without header"); } /** Save all chunks */ @@ -3068,3 +3409,9 @@ void FileToSaveLoad::SetTitle(const char *title) { strecpy(this->title, title, lastof(this->title)); } + +SaveLoadTable SaveLoadHandler::GetLoadDescription() const +{ + assert(this->load_description.has_value()); + return *this->load_description; +} diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 0ce46cbe98..b6e843c991 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -13,6 +13,7 @@ #include "../fileio_type.h" #include "../strings_type.h" #include "../core/span_type.hpp" +#include #include #include @@ -333,6 +334,8 @@ enum SaveLoadVersion : uint16 { SLV_SAVELOAD_LIST_LENGTH, ///< 293 PR#9374 Consistency in list length with SL_STRUCT / SL_STRUCTLIST / SL_DEQUE / SL_REFLIST. SLV_RIFF_TO_ARRAY, ///< 294 PR#9375 Changed many CH_RIFF chunks to CH_ARRAY chunks. + SLV_TABLE_CHUNKS, ///< 295 PR#9322 Introduction of CH_TABLE and CH_SPARSE_TABLE. + SL_MAX_VERSION, ///< Highest possible saveload version }; @@ -388,6 +391,10 @@ enum ChunkType { CH_RIFF = 0, CH_ARRAY = 1, CH_SPARSE_ARRAY = 2, + CH_TABLE = 3, + CH_SPARSE_TABLE = 4, + + CH_TYPE_MASK = 0xf, ///< All ChunkType values have to be within this mask. CH_READONLY, ///< Chunk is never saved. }; @@ -407,9 +414,14 @@ using ChunkHandlerTable = span; /** A table of SaveLoad entries. */ using SaveLoadTable = span; +/** A table of SaveLoadCompat entries. */ +using SaveLoadCompatTable = span; + /** Handler for saving/loading an object to/from disk. */ class SaveLoadHandler { public: + std::optional> load_description; + virtual ~SaveLoadHandler() {} /** @@ -440,6 +452,18 @@ public: * Get the description of the fields in the savegame. */ virtual SaveLoadTable GetDescription() const = 0; + + /** + * Get the pre-header description of the fields in the savegame. + */ + virtual SaveLoadCompatTable GetCompatDescription() const { return {}; } + + /** + * Get the description for how to load the chunk. Depending on the + * savegame version this can either use the headers in the savegame or + * fall back to backwards compatibility and uses hard-coded headers. + */ + SaveLoadTable GetLoadDescription() const; }; /** @@ -496,18 +520,24 @@ enum SLRefType { * Bits 8-15 are reserved for various flags as explained below */ enum VarTypes { - /* 4 bits allocated a maximum of 16 types for NumberType */ - SLE_FILE_I8 = 0, - SLE_FILE_U8 = 1, - SLE_FILE_I16 = 2, - SLE_FILE_U16 = 3, - SLE_FILE_I32 = 4, - SLE_FILE_U32 = 5, - SLE_FILE_I64 = 6, - SLE_FILE_U64 = 7, - SLE_FILE_STRINGID = 8, ///< StringID offset into strings-array - SLE_FILE_STRING = 9, - /* 6 more possible file-primitives */ + /* 4 bits allocated a maximum of 16 types for NumberType. + * NOTE: the SLE_FILE_NNN values are stored in the savegame! */ + SLE_FILE_END = 0, ///< Used to mark end-of-header in tables. + SLE_FILE_I8 = 1, + SLE_FILE_U8 = 2, + SLE_FILE_I16 = 3, + SLE_FILE_U16 = 4, + SLE_FILE_I32 = 5, + SLE_FILE_U32 = 6, + SLE_FILE_I64 = 7, + SLE_FILE_U64 = 8, + SLE_FILE_STRINGID = 9, ///< StringID offset into strings-array + SLE_FILE_STRING = 10, + SLE_FILE_STRUCT = 11, + /* 4 more possible file-primitives */ + + SLE_FILE_TYPE_MASK = 0xf, ///< Mask to get the file-type (and not any flags). + SLE_FILE_HAS_LENGTH_FIELD = 1 << 4, ///< Bit stored in savegame to indicate field has a length field for each entry. /* 4 bits allocated a maximum of 16 types for NumberType */ SLE_VAR_BL = 0 << 4, @@ -586,6 +616,7 @@ typedef void *SaveLoadAddrProc(void *base, size_t extra); /** SaveLoad type struct. Do NOT use this directly but use the SLE_ macros defined just below! */ struct SaveLoad { + std::string name; ///< Name of this field (optional, used for tables). SaveLoadType cmd; ///< the action to take with the saved/loaded type, All types need different action VarType conv; ///< type of the variable to be saved, int uint16 length; ///< (conditional) length of the variable (eg. arrays) (max array size is 65536 elements) @@ -594,7 +625,22 @@ struct SaveLoad { size_t size; ///< the sizeof size. SaveLoadAddrProc *address_proc; ///< callback proc the get the actual variable address in memory size_t extra_data; ///< extra data for the callback proc - SaveLoadHandler *handler; ///< Custom handler for Save/Load procs. + std::shared_ptr handler; ///< Custom handler for Save/Load procs. +}; + +/** + * SaveLoad information for backwards compatibility. + * + * At SLV_SETTINGS_NAME a new method of keeping track of fields in a savegame + * was added, where the order of fields is no longer important. For older + * savegames we still need to know the correct order. This struct is the glue + * to make that happen. + */ +struct SaveLoadCompat { + std::string name; ///< Name of the field. + uint16 length; ///< Length of the NULL field. + SaveLoadVersion version_from; ///< Save/load the variable starting from this savegame version. + SaveLoadVersion version_to; ///< Save/load the variable until this savegame version. }; /** @@ -608,7 +654,7 @@ struct SaveLoad { * @param extra Extra data to pass to the address callback function. * @note In general, it is better to use one of the SLE_* macros below. */ -#define SLE_GENERAL(cmd, base, variable, type, length, from, to, extra) SaveLoad {cmd, type, length, from, to, cpp_sizeof(base, variable), [] (void *b, size_t) -> void * { assert(b != nullptr); return const_cast(static_cast(std::addressof(static_cast(b)->variable))); }, extra, nullptr} +#define SLE_GENERAL(cmd, base, variable, type, length, from, to, extra) SaveLoad {#variable, cmd, type, length, from, to, cpp_sizeof(base, variable), [] (void *b, size_t) -> void * { assert(b != nullptr); return const_cast(static_cast(std::addressof(static_cast(b)->variable))); }, extra, nullptr} /** * Storage of a variable in some savegame versions. @@ -744,7 +790,7 @@ struct SaveLoad { * @param from First savegame version that has the empty space. * @param to Last savegame version that has the empty space. */ -#define SLE_CONDNULL(length, from, to) SaveLoad {SL_NULL, SLE_FILE_U8 | SLE_VAR_NULL, length, from, to, 0, nullptr, 0, nullptr} +#define SLE_CONDNULL(length, from, to) SaveLoad {"", SL_NULL, SLE_FILE_U8 | SLE_VAR_NULL, length, from, to, 0, nullptr, 0, nullptr} /** * Only write byte during saving; never read it during loading. @@ -760,6 +806,7 @@ struct SaveLoad { /** * Storage of global simple variables, references (pointers), and arrays. + * @param name The name of the field. * @param cmd Load/save type. @see SaveLoadType * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. @@ -768,149 +815,167 @@ struct SaveLoad { * @param extra Extra data to pass to the address callback function. * @note In general, it is better to use one of the SLEG_* macros below. */ -#define SLEG_GENERAL(cmd, variable, type, length, from, to, extra) SaveLoad {cmd, type, length, from, to, sizeof(variable), [] (void *, size_t) -> void * { return static_cast(std::addressof(variable)); }, extra, nullptr} +#define SLEG_GENERAL(name, cmd, variable, type, length, from, to, extra) SaveLoad {name, cmd, type, length, from, to, sizeof(variable), [] (void *, size_t) -> void * { return static_cast(std::addressof(variable)); }, extra, nullptr} /** * Storage of a global variable in some savegame versions. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the field. * @param to Last savegame version that has the field. */ -#define SLEG_CONDVAR(variable, type, from, to) SLEG_GENERAL(SL_VAR, variable, type, 0, from, to, 0) +#define SLEG_CONDVAR(name, variable, type, from, to) SLEG_GENERAL(name, SL_VAR, variable, type, 0, from, to, 0) /** * Storage of a global reference in some savegame versions. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the field. * @param to Last savegame version that has the field. */ -#define SLEG_CONDREF(variable, type, from, to) SLEG_GENERAL(SL_REF, variable, type, 0, from, to, 0) +#define SLEG_CONDREF(name, variable, type, from, to) SLEG_GENERAL(name, SL_REF, variable, type, 0, from, to, 0) /** * Storage of a global fixed-size array of #SL_VAR elements in some savegame versions. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. * @param length Number of elements in the array. * @param from First savegame version that has the array. * @param to Last savegame version that has the array. */ -#define SLEG_CONDARR(variable, type, length, from, to) SLEG_GENERAL(SL_ARR, variable, type, length, from, to, 0) +#define SLEG_CONDARR(name, variable, type, length, from, to) SLEG_GENERAL(name, SL_ARR, variable, type, length, from, to, 0) /** * Storage of a global string in some savegame versions. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. * @param length Number of elements in the string (only used for fixed size buffers). * @param from First savegame version that has the string. * @param to Last savegame version that has the string. */ -#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_GENERAL(SL_STR, variable, type, length, from, to, 0) +#define SLEG_CONDSTR(name, variable, type, length, from, to) SLEG_GENERAL(name, SL_STR, variable, type, length, from, to, 0) /** * Storage of a global \c std::string in some savegame versions. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the string. * @param to Last savegame version that has the string. */ -#define SLEG_CONDSSTR(variable, type, from, to) SLEG_GENERAL(SL_STDSTR, variable, type, 0, from, to, 0) +#define SLEG_CONDSSTR(name, variable, type, from, to) SLEG_GENERAL(name, SL_STDSTR, variable, type, 0, from, to, 0) /** * Storage of a structs in some savegame versions. + * @param name The name of the field. * @param handler SaveLoadHandler for the structs. * @param from First savegame version that has the struct. * @param to Last savegame version that has the struct. */ -#define SLEG_CONDSTRUCT(handler, from, to) SaveLoad {SL_STRUCT, 0, 0, from, to, 0, nullptr, 0, new handler()} +#define SLEG_CONDSTRUCT(name, handler, from, to) SaveLoad {name, SL_STRUCT, 0, 0, from, to, 0, nullptr, 0, std::make_shared()} /** * Storage of a global reference list in some savegame versions. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the list. * @param to Last savegame version that has the list. */ -#define SLEG_CONDREFLIST(variable, type, from, to) SLEG_GENERAL(SL_REFLIST, variable, type, 0, from, to, 0) +#define SLEG_CONDREFLIST(name, variable, type, from, to) SLEG_GENERAL(name, SL_REFLIST, variable, type, 0, from, to, 0) /** * Storage of a global vector of #SL_VAR elements in some savegame versions. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the list. * @param to Last savegame version that has the list. */ -#define SLEG_CONDVECTOR(variable, type, from, to) SLEG_GENERAL(SL_VECTOR, variable, type, 0, from, to, 0) +#define SLEG_CONDVECTOR(name, variable, type, from, to) SLEG_GENERAL(name, SL_VECTOR, variable, type, 0, from, to, 0) /** * Storage of a list of structs in some savegame versions. + * @param name The name of the field. * @param handler SaveLoadHandler for the list of structs. * @param from First savegame version that has the list. * @param to Last savegame version that has the list. */ -#define SLEG_CONDSTRUCTLIST(handler, from, to) SaveLoad {SL_STRUCTLIST, 0, 0, from, to, 0, nullptr, 0, new handler()} +#define SLEG_CONDSTRUCTLIST(name, handler, from, to) SaveLoad {name, SL_STRUCTLIST, 0, 0, from, to, 0, nullptr, 0, std::make_shared()} /** * Storage of a global variable in every savegame version. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. */ -#define SLEG_VAR(variable, type) SLEG_CONDVAR(variable, type, SL_MIN_VERSION, SL_MAX_VERSION) +#define SLEG_VAR(name, variable, type) SLEG_CONDVAR(name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION) /** * Storage of a global reference in every savegame version. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. */ -#define SLEG_REF(variable, type) SLEG_CONDREF(variable, type, SL_MIN_VERSION, SL_MAX_VERSION) +#define SLEG_REF(name, variable, type) SLEG_CONDREF(name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION) /** * Storage of a global fixed-size array of #SL_VAR elements in every savegame version. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. */ -#define SLEG_ARR(variable, type) SLEG_CONDARR(variable, type, lengthof(variable), SL_MIN_VERSION, SL_MAX_VERSION) +#define SLEG_ARR(name, variable, type) SLEG_CONDARR(name, variable, type, lengthof(variable), SL_MIN_VERSION, SL_MAX_VERSION) /** * Storage of a global string in every savegame version. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. */ -#define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, sizeof(variable), SL_MIN_VERSION, SL_MAX_VERSION) +#define SLEG_STR(name, variable, type) SLEG_CONDSTR(name, variable, type, sizeof(variable), SL_MIN_VERSION, SL_MAX_VERSION) /** * Storage of a global \c std::string in every savegame version. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. */ -#define SLEG_SSTR(variable, type) SLEG_CONDSSTR(variable, type, SL_MIN_VERSION, SL_MAX_VERSION) +#define SLEG_SSTR(name, variable, type) SLEG_CONDSSTR(name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION) /** * Storage of a structs in every savegame version. + * @param name The name of the field. * @param handler SaveLoadHandler for the structs. */ -#define SLEG_STRUCT(handler) SLEG_CONDSTRUCT(handler, SL_MIN_VERSION, SL_MAX_VERSION) +#define SLEG_STRUCT(name, handler) SLEG_CONDSTRUCT(name, handler, SL_MIN_VERSION, SL_MAX_VERSION) /** * Storage of a global reference list in every savegame version. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. */ -#define SLEG_REFLIST(variable, type) SLEG_CONDREFLIST(variable, type, SL_MIN_VERSION, SL_MAX_VERSION) +#define SLEG_REFLIST(name, variable, type) SLEG_CONDREFLIST(name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION) /** * Storage of a global vector of #SL_VAR elements in every savegame version. + * @param name The name of the field. * @param variable Name of the global variable. * @param type Storage of the data in memory and in the savegame. */ -#define SLEG_VECTOR(variable, type) SLEG_CONDVECTOR(variable, type, SL_MIN_VERSION, SL_MAX_VERSION) +#define SLEG_VECTOR(name, variable, type) SLEG_CONDVECTOR(name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION) /** * Storage of a list of structs in every savegame version. + * @param name The name of the field. * @param handler SaveLoadHandler for the list of structs. */ -#define SLEG_STRUCTLIST(handler) SLEG_CONDSTRUCTLIST(handler, SL_MIN_VERSION, SL_MAX_VERSION) +#define SLEG_STRUCTLIST(name, handler) SLEG_CONDSTRUCTLIST(name, handler, SL_MIN_VERSION, SL_MAX_VERSION) /** * Empty global space in some savegame versions. @@ -918,7 +983,24 @@ struct SaveLoad { * @param from First savegame version that has the empty space. * @param to Last savegame version that has the empty space. */ -#define SLEG_CONDNULL(length, from, to) SaveLoad {SL_NULL, SLE_FILE_U8 | SLE_VAR_NULL, length, from, to, 0, nullptr, 0, nullptr} +#define SLEG_CONDNULL(length, from, to) SaveLoad {"", SL_NULL, SLE_FILE_U8 | SLE_VAR_NULL, length, from, to, 0, nullptr, 0, nullptr} + +/** + * Field name where the real SaveLoad can be located. + * @param name The name of the field. + */ +#define SLC_VAR(name) {name, 0, SL_MIN_VERSION, SL_MAX_VERSION} + +/** + * Empty space in every savegame version. + * @param length Length of the empty space. + * @param from First savegame version that has the empty space. + * @param to Last savegame version that has the empty space. + */ +#define SLC_NULL(length, from, to) {{}, length, from, to} + +/** End marker of compat variables save or load. */ +#define SLC_END() {{}, 0, SL_MIN_VERSION, SL_MIN_VERSION} /** * Checks whether the savegame is below \a major.\a minor. @@ -1029,6 +1111,8 @@ void SlWriteByte(byte b); void SlGlobList(const SaveLoadTable &slt); void SlCopy(void *object, size_t length, VarType conv); +std::vector SlTableHeader(const SaveLoadTable &slt); +std::vector SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct); void SlObject(void *object, const SaveLoadTable &slt); void NORETURN SlError(StringID string, const char *extra_msg = nullptr); void NORETURN SlErrorCorrupt(const char *msg); diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index a536c02db4..5b99b09f7d 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -331,29 +331,29 @@ public: inline #endif static const SaveLoad description[] = { - SLEG_CONDVAR( _waiting_acceptance, SLE_UINT16, SL_MIN_VERSION, SLV_68), + SLEG_CONDVAR("waiting_acceptance", _waiting_acceptance, SLE_UINT16, SL_MIN_VERSION, SLV_68), SLE_CONDVAR(GoodsEntry, status, SLE_UINT8, SLV_68, SL_MAX_VERSION), SLE_CONDNULL(2, SLV_51, SLV_68), SLE_VAR(GoodsEntry, time_since_pickup, SLE_UINT8), SLE_VAR(GoodsEntry, rating, SLE_UINT8), - SLEG_CONDVAR( _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_7), - SLEG_CONDVAR( _cargo_source, SLE_UINT16, SLV_7, SLV_68), - SLEG_CONDVAR( _cargo_source_xy, SLE_UINT32, SLV_44, SLV_68), - SLEG_CONDVAR( _cargo_days, SLE_UINT8, SL_MIN_VERSION, SLV_68), + SLEG_CONDVAR("cargo_source", _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_7), + SLEG_CONDVAR("cargo_source", _cargo_source, SLE_UINT16, SLV_7, SLV_68), + SLEG_CONDVAR("cargo_source_xy", _cargo_source_xy, SLE_UINT32, SLV_44, SLV_68), + SLEG_CONDVAR("cargo_days", _cargo_days, SLE_UINT8, SL_MIN_VERSION, SLV_68), SLE_VAR(GoodsEntry, last_speed, SLE_UINT8), SLE_VAR(GoodsEntry, last_age, SLE_UINT8), - SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, SLV_14, SLV_65), - SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, SLV_65, SLV_68), + SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, SLV_14, SLV_65), + SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_INT64, SLV_65, SLV_68), SLE_CONDVAR(GoodsEntry, amount_fract, SLE_UINT8, SLV_150, SL_MAX_VERSION), - SLEG_CONDREFLIST( _packets, REF_CARGO_PACKET, SLV_68, SLV_183), - SLEG_CONDVAR( _old_num_dests, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH), + SLEG_CONDREFLIST("packets", _packets, REF_CARGO_PACKET, SLV_68, SLV_183), + SLEG_CONDVAR("old_num_dests", _old_num_dests, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH), SLE_CONDVAR(GoodsEntry, cargo.reserved_count, SLE_UINT, SLV_181, SL_MAX_VERSION), SLE_CONDVAR(GoodsEntry, link_graph, SLE_UINT16, SLV_183, SL_MAX_VERSION), SLE_CONDVAR(GoodsEntry, node, SLE_UINT16, SLV_183, SL_MAX_VERSION), - SLEG_CONDVAR( _old_num_flows, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH), + SLEG_CONDVAR("old_num_flows", _old_num_flows, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH), SLE_CONDVAR(GoodsEntry, max_waiting_cargo, SLE_UINT32, SLV_183, SL_MAX_VERSION), - SLEG_CONDSTRUCTLIST(SlStationFlow, SLV_183, SL_MAX_VERSION), - SLEG_CONDSTRUCTLIST(SlStationCargo, SLV_183, SL_MAX_VERSION), + SLEG_CONDSTRUCTLIST("flow", SlStationFlow, SLV_183, SL_MAX_VERSION), + SLEG_CONDSTRUCTLIST("cargo", SlStationCargo, SLV_183, SL_MAX_VERSION), }; #if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916) return description; @@ -497,8 +497,8 @@ static const SaveLoad _old_station_desc[] = { /* reserve extra space in savegame here. (currently 32 bytes) */ SLE_CONDNULL(32, SLV_2, SL_MAX_VERSION), - SLEG_STRUCTLIST(SlStationGoods), - SLEG_CONDSTRUCTLIST(SlStationSpecList, SLV_27, SL_MAX_VERSION), + SLEG_STRUCTLIST("goods", SlStationGoods), + SLEG_CONDSTRUCTLIST("speclist", SlStationSpecList, SLV_27, SL_MAX_VERSION), }; static void Load_STNS() @@ -566,7 +566,7 @@ public: class SlStationNormal : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { - SLEG_STRUCT(SlStationBase), + SLEG_STRUCT("base", SlStationBase), SLE_VAR(Station, train_station.tile, SLE_UINT32), SLE_VAR(Station, train_station.w, SLE_FILE_U8 | SLE_VAR_U16), SLE_VAR(Station, train_station.h, SLE_FILE_U8 | SLE_VAR_U16), @@ -587,7 +587,7 @@ public: SLE_CONDVAR(Station, airport.layout, SLE_UINT8, SLV_145, SL_MAX_VERSION), SLE_VAR(Station, airport.flags, SLE_UINT64), SLE_CONDVAR(Station, airport.rotation, SLE_UINT8, SLV_145, SL_MAX_VERSION), - SLEG_CONDARR(_old_st_persistent_storage.storage, SLE_UINT32, 16, SLV_145, SLV_161), + SLEG_CONDARR("storage", _old_st_persistent_storage.storage, SLE_UINT32, 16, SLV_145, SLV_161), SLE_CONDREF(Station, airport.psa, REF_STORAGE, SLV_161, SL_MAX_VERSION), SLE_VAR(Station, indtype, SLE_UINT8), @@ -599,7 +599,7 @@ public: SLE_REFLIST(Station, loading_vehicles, REF_VEHICLE), SLE_CONDVAR(Station, always_accepted, SLE_FILE_U32 | SLE_VAR_U64, SLV_127, SLV_EXTEND_CARGOTYPES), SLE_CONDVAR(Station, always_accepted, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), - SLEG_STRUCTLIST(SlStationGoods), + SLEG_STRUCTLIST("goods", SlStationGoods), }; void GenericSaveLoad(BaseStation *bst) const @@ -616,7 +616,7 @@ public: class SlStationWaypoint : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { - SLEG_STRUCT(SlStationBase), + SLEG_STRUCT("base", SlStationBase), SLE_VAR(Waypoint, town_cn, SLE_UINT16), SLE_CONDVAR(Waypoint, train_station.tile, SLE_UINT32, SLV_124, SL_MAX_VERSION), @@ -637,9 +637,9 @@ public: static const SaveLoad _station_desc[] = { SLE_SAVEBYTE(BaseStation, facilities), - SLEG_STRUCT(SlStationNormal), - SLEG_STRUCT(SlStationWaypoint), - SLEG_CONDSTRUCTLIST(SlStationSpecList, SLV_27, SL_MAX_VERSION), + SLEG_STRUCT("normal", SlStationNormal), + SLEG_STRUCT("waypoint", SlStationWaypoint), + SLEG_CONDSTRUCTLIST("speclist", SlStationSpecList, SLV_27, SL_MAX_VERSION), }; static void Save_STNN() diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 38c000e3b9..c653db53a7 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -278,9 +278,9 @@ static const SaveLoad _town_desc[] = { SLE_CONDNULL(8, SLV_EXTEND_CARGOTYPES, SLV_REMOVE_TOWN_CARGO_CACHE), ///< cargo_produced, no longer in use SLE_CONDNULL(30, SLV_2, SLV_REMOVE_TOWN_CARGO_CACHE), ///< old reserved space - SLEG_CONDSTRUCTLIST(SlTownSupplied, SLV_165, SL_MAX_VERSION), - SLEG_CONDSTRUCTLIST(SlTownReceived, SLV_165, SL_MAX_VERSION), - SLEG_CONDSTRUCTLIST(SlTownAcceptanceMatrix, SLV_166, SLV_REMOVE_TOWN_CARGO_CACHE), + SLEG_CONDSTRUCTLIST("supplied", SlTownSupplied, SLV_165, SL_MAX_VERSION), + SLEG_CONDSTRUCTLIST("received", SlTownReceived, SLV_165, SL_MAX_VERSION), + SLEG_CONDSTRUCTLIST("acceptance_matrix", SlTownAcceptanceMatrix, SLV_166, SLV_REMOVE_TOWN_CARGO_CACHE), }; static void Save_HIDS() diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index ffa0206771..b2d9972fee 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -626,14 +626,14 @@ public: SLE_VAR(Vehicle, cargo_type, SLE_UINT8), SLE_CONDVAR(Vehicle, cargo_subtype, SLE_UINT8, SLV_35, SL_MAX_VERSION), - SLEG_CONDVAR( _cargo_days, SLE_UINT8, SL_MIN_VERSION, SLV_68), - SLEG_CONDVAR( _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_7), - SLEG_CONDVAR( _cargo_source, SLE_UINT16, SLV_7, SLV_68), - SLEG_CONDVAR( _cargo_source_xy, SLE_UINT32, SLV_44, SLV_68), + SLEG_CONDVAR("cargo_days", _cargo_days, SLE_UINT8, SL_MIN_VERSION, SLV_68), + SLEG_CONDVAR("cargo_source", _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_7), + SLEG_CONDVAR("cargo_source", _cargo_source, SLE_UINT16, SLV_7, SLV_68), + SLEG_CONDVAR("cargo_source_xy", _cargo_source_xy, SLE_UINT32, SLV_44, SLV_68), SLE_VAR(Vehicle, cargo_cap, SLE_UINT16), SLE_CONDVAR(Vehicle, refit_cap, SLE_UINT16, SLV_182, SL_MAX_VERSION), - SLEG_CONDVAR( _cargo_count, SLE_UINT16, SL_MIN_VERSION, SLV_68), - SLE_CONDREFLIST(Vehicle, cargo.packets, REF_CARGO_PACKET, SLV_68, SL_MAX_VERSION), + SLEG_CONDVAR("cargo_count", _cargo_count, SLE_UINT16, SL_MIN_VERSION, SLV_68), + SLE_CONDREFLIST(Vehicle, cargo.packets, REF_CARGO_PACKET, SLV_68, SL_MAX_VERSION), SLE_CONDARR(Vehicle, cargo.action_counts, SLE_UINT, VehicleCargoList::NUM_MOVE_TO_ACTION, SLV_181, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, cargo_age_counter, SLE_UINT16, SLV_162, SL_MAX_VERSION), @@ -689,7 +689,7 @@ public: SLE_CONDVAR(Vehicle, build_year, SLE_INT32, SLV_31, SL_MAX_VERSION), SLE_VAR(Vehicle, load_unload_ticks, SLE_UINT16), - SLEG_CONDVAR( _cargo_paid_for, SLE_UINT16, SLV_45, SL_MAX_VERSION), + SLEG_CONDVAR("cargo_paid_for", _cargo_paid_for, SLE_UINT16, SLV_45, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, vehicle_flags, SLE_FILE_U8 | SLE_VAR_U16, SLV_40, SLV_180), SLE_CONDVAR(Vehicle, vehicle_flags, SLE_UINT16, SLV_180, SL_MAX_VERSION), @@ -697,9 +697,9 @@ public: SLE_CONDVAR(Vehicle, profit_this_year, SLE_INT64, SLV_65, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, profit_last_year, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), SLE_CONDVAR(Vehicle, profit_last_year, SLE_INT64, SLV_65, SL_MAX_VERSION), - SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_I32 | SLE_VAR_I64, SLV_51, SLV_65), - SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, SLV_65, SLV_68), - SLEG_CONDVAR( _cargo_loaded_at_xy, SLE_UINT32, SLV_51, SLV_68), + SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_FILE_I32 | SLE_VAR_I64, SLV_51, SLV_65), + SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_INT64, SLV_65, SLV_68), + SLEG_CONDVAR("cargo_loaded_at_xy", _cargo_loaded_at_xy, SLE_UINT32, SLV_51, SLV_68), SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), SLE_CONDVAR(Vehicle, value, SLE_INT64, SLV_65, SL_MAX_VERSION), @@ -735,7 +735,7 @@ public: class SlVehicleTrain : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { - SLEG_STRUCT(SlVehicleCommon), + SLEG_STRUCT("common", SlVehicleCommon), SLE_VAR(Train, crash_anim_pos, SLE_UINT16), SLE_VAR(Train, force_proceed, SLE_UINT8), SLE_VAR(Train, railtype, SLE_UINT8), @@ -766,7 +766,7 @@ public: class SlVehicleRoadVeh : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { - SLEG_STRUCT(SlVehicleCommon), + SLEG_STRUCT("common", SlVehicleCommon), SLE_VAR(RoadVehicle, state, SLE_UINT8), SLE_VAR(RoadVehicle, frame, SLE_UINT8), SLE_VAR(RoadVehicle, blocked_ctr, SLE_UINT16), @@ -798,7 +798,7 @@ public: class SlVehicleShip : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { - SLEG_STRUCT(SlVehicleCommon), + SLEG_STRUCT("common", SlVehicleCommon), SLE_VAR(Ship, state, SLE_UINT8), SLE_CONDDEQUE(Ship, path, SLE_UINT8, SLV_SHIP_PATH_CACHE, SL_MAX_VERSION), SLE_CONDVAR(Ship, rotation, SLE_UINT8, SLV_SHIP_ROTATION, SL_MAX_VERSION), @@ -820,7 +820,7 @@ public: class SlVehicleAircraft : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { - SLEG_STRUCT(SlVehicleCommon), + SLEG_STRUCT("common", SlVehicleCommon), SLE_VAR(Aircraft, crashed_counter, SLE_UINT16), SLE_VAR(Aircraft, pos, SLE_UINT8), @@ -955,12 +955,12 @@ public: const static SaveLoad _vehicle_desc[] = { SLE_SAVEBYTE(Vehicle, type), - SLEG_STRUCT(SlVehicleTrain), - SLEG_STRUCT(SlVehicleRoadVeh), - SLEG_STRUCT(SlVehicleShip), - SLEG_STRUCT(SlVehicleAircraft), - SLEG_STRUCT(SlVehicleEffect), - SLEG_STRUCT(SlVehicleDisaster), + SLEG_STRUCT("train", SlVehicleTrain), + SLEG_STRUCT("roadveh", SlVehicleRoadVeh), + SLEG_STRUCT("ship", SlVehicleShip), + SLEG_STRUCT("aircraft", SlVehicleAircraft), + SLEG_STRUCT("effect", SlVehicleEffect), + SLEG_STRUCT("disaster", SlVehicleDisaster), }; /** Will be called when the vehicles need to be saved. */ diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp index 2665a86846..1d57383a9f 100644 --- a/src/script/script_instance.cpp +++ b/src/script/script_instance.cpp @@ -345,7 +345,7 @@ static byte _script_sl_byte; ///< Used as source/target by the script saveload c /** SaveLoad array that saves/loads exactly one byte. */ static const SaveLoad _script_byte[] = { - SLEG_VAR(_script_sl_byte, SLE_UINT8), + SLEG_VAR("type", _script_sl_byte, SLE_UINT8), }; /* static */ bool ScriptInstance::SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test) diff --git a/src/settings.cpp b/src/settings.cpp index 9847a0ff93..6368dea113 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -2194,7 +2194,7 @@ static std::vector GetSettingsDesc(const SettingTable &settings, bool if (is_loading && (sd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) { /* We don't want to read this setting, so we do need to skip over it. */ - saveloads.push_back({sd->save.cmd, GetVarFileType(sd->save.conv) | SLE_VAR_NULL, sd->save.length, sd->save.version_from, sd->save.version_to, 0, nullptr, 0, nullptr}); + saveloads.push_back({sd->name, sd->save.cmd, GetVarFileType(sd->save.conv) | SLE_VAR_NULL, sd->save.length, sd->save.version_from, sd->save.version_to, 0, nullptr, 0, nullptr}); continue; } diff --git a/src/table/settings.h.preamble b/src/table/settings.h.preamble index 5fd1a9bac6..9641c24cea 100644 --- a/src/table/settings.h.preamble +++ b/src/table/settings.h.preamble @@ -59,22 +59,22 @@ static size_t ConvertLandscape(const char *value); /* Macros for various objects to go in the configuration file. * This section is for global variables */ #define SDTG_VAR(name, type, flags, var, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, cat, extra, startup)\ - NSD(Int, SLEG_GENERAL(SL_VAR, var, type, 1, from, to, extra), name, flags, startup, def, min, max, interval, str, strhelp, strval, cat, pre_check, post_callback) + NSD(Int, SLEG_GENERAL(#var, SL_VAR, var, type, 1, from, to, extra), name, flags, startup, def, min, max, interval, str, strhelp, strval, cat, pre_check, post_callback) #define SDTG_BOOL(name, flags, var, def, str, strhelp, strval, pre_check, post_callback, from, to, cat, extra, startup)\ - NSD(Bool, SLEG_GENERAL(SL_VAR, var, SLE_BOOL, 1, from, to, extra), name, flags, startup, def, str, strhelp, strval, cat, pre_check, post_callback) + NSD(Bool, SLEG_GENERAL(#var, SL_VAR, var, SLE_BOOL, 1, from, to, extra), name, flags, startup, def, str, strhelp, strval, cat, pre_check, post_callback) #define SDTG_LIST(name, type, flags, var, def, length, from, to, cat, extra, startup)\ - NSD(List, SLEG_GENERAL(SL_ARR, var, type, length, from, to, extra), name, flags, startup, def) + NSD(List, SLEG_GENERAL(#var, SL_ARR, var, type, length, from, to, extra), name, flags, startup, def) #define SDTG_SSTR(name, type, flags, var, def, max_length, pre_check, post_callback, from, to, cat, extra, startup)\ - NSD(String, SLEG_GENERAL(SL_STDSTR, var, type, sizeof(var), from, to, extra), name, flags, startup, def, max_length, pre_check, post_callback) + NSD(String, SLEG_GENERAL(#var, SL_STDSTR, var, type, sizeof(var), from, to, extra), name, flags, startup, def, max_length, pre_check, post_callback) #define SDTG_OMANY(name, type, flags, var, def, max, full, str, strhelp, strval, pre_check, post_callback, from, to, cat, extra, startup)\ - NSD(OneOfMany, SLEG_GENERAL(SL_VAR, var, type, 1, from, to, extra), name, flags, startup, def, max, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr) + NSD(OneOfMany, SLEG_GENERAL(#var, SL_VAR, var, type, 1, from, to, extra), name, flags, startup, def, max, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr) #define SDTG_MMANY(name, type, flags, var, def, full, str, strhelp, strval, pre_check, post_callback, from, to, cat, extra, startup)\ - NSD(ManyOfMany, SLEG_GENERAL(SL_VAR, var, type, 1, from, to, extra), name, flags, startup, def, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr) + NSD(ManyOfMany, SLEG_GENERAL(#var, SL_VAR, var, type, 1, from, to, extra), name, flags, startup, def, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr) #define SDTG_NULL(length, from, to)\ NSD(Null, SLEG_NULL(length, from, to)) From cdb3dd0493749dd5c62378f318ea61bcb85f988f Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 30 May 2021 15:59:40 +0200 Subject: [PATCH 07/42] Add: store headers for most savegame chunks When a header is added, the chunk changes from CH_ARRAY type to CH_TABLE type. --- src/saveload/CMakeLists.txt | 2 + src/saveload/ai_sl.cpp | 17 +- src/saveload/airport_sl.cpp | 4 +- src/saveload/animated_tile_sl.cpp | 18 +- src/saveload/autoreplace_sl.cpp | 12 +- src/saveload/cargomonitor_sl.cpp | 22 +- src/saveload/cargopacket_sl.cpp | 18 +- src/saveload/cheat_sl.cpp | 41 +-- src/saveload/compat/CMakeLists.txt | 26 ++ src/saveload/compat/ai_sl_compat.h | 23 ++ src/saveload/compat/animated_tile_sl_compat.h | 20 ++ src/saveload/compat/autoreplace_sl_compat.h | 24 ++ src/saveload/compat/cargomonitor_sl_compat.h | 21 ++ src/saveload/compat/cargopacket_sl_compat.h | 28 ++ src/saveload/compat/cheat_sl_compat.h | 41 +++ src/saveload/compat/depot_sl_compat.h | 25 ++ src/saveload/compat/economy_sl_compat.h | 38 +++ src/saveload/compat/engine_sl_compat.h | 48 ++++ src/saveload/compat/game_sl_compat.h | 23 ++ src/saveload/compat/goal_sl_compat.h | 25 ++ src/saveload/compat/group_sl_compat.h | 28 ++ src/saveload/compat/industry_sl_compat.h | 72 +++++ src/saveload/compat/labelmaps_sl_compat.h | 20 ++ src/saveload/compat/map_sl_compat.h | 21 ++ src/saveload/compat/misc_sl_compat.h | 68 +++++ src/saveload/compat/newgrf_sl_compat.h | 33 +++ src/saveload/compat/object_sl_compat.h | 27 ++ src/saveload/compat/order_sl_compat.h | 52 ++++ src/saveload/compat/settings_sl_compat.h | 266 ++++++++++++++++++ src/saveload/compat/signs_sl_compat.h | 24 ++ src/saveload/compat/station_sl_compat.h | 29 ++ src/saveload/compat/storage_sl_compat.h | 21 ++ src/saveload/compat/story_sl_compat.h | 32 +++ src/saveload/compat/subsidy_sl_compat.h | 26 ++ src/saveload/depot_sl.cpp | 14 +- src/saveload/economy_sl.cpp | 24 +- src/saveload/engine_sl.cpp | 26 +- src/saveload/game_sl.cpp | 17 +- src/saveload/goal_sl.cpp | 10 +- src/saveload/group_sl.cpp | 16 +- src/saveload/industry_sl.cpp | 37 ++- src/saveload/labelmaps_sl.cpp | 14 +- src/saveload/map_sl.cpp | 18 +- src/saveload/misc_sl.cpp | 59 ++-- src/saveload/newgrf_sl.cpp | 18 +- src/saveload/object_sl.cpp | 16 +- src/saveload/order_sl.cpp | 46 +-- src/saveload/signs_sl.cpp | 15 +- src/saveload/station_sl.cpp | 23 +- src/saveload/storage_sl.cpp | 14 +- src/saveload/story_sl.cpp | 20 +- src/saveload/strings_sl.cpp | 1 - src/saveload/subsidy_sl.cpp | 12 +- src/saveload/town_sl.cpp | 3 +- src/settings.cpp | 30 +- src/table/settings/gameopt_settings.ini | 9 - src/table/settings/settings.ini | 62 ---- 57 files changed, 1410 insertions(+), 289 deletions(-) create mode 100644 src/saveload/compat/CMakeLists.txt create mode 100644 src/saveload/compat/ai_sl_compat.h create mode 100644 src/saveload/compat/animated_tile_sl_compat.h create mode 100644 src/saveload/compat/autoreplace_sl_compat.h create mode 100644 src/saveload/compat/cargomonitor_sl_compat.h create mode 100644 src/saveload/compat/cargopacket_sl_compat.h create mode 100644 src/saveload/compat/cheat_sl_compat.h create mode 100644 src/saveload/compat/depot_sl_compat.h create mode 100644 src/saveload/compat/economy_sl_compat.h create mode 100644 src/saveload/compat/engine_sl_compat.h create mode 100644 src/saveload/compat/game_sl_compat.h create mode 100644 src/saveload/compat/goal_sl_compat.h create mode 100644 src/saveload/compat/group_sl_compat.h create mode 100644 src/saveload/compat/industry_sl_compat.h create mode 100644 src/saveload/compat/labelmaps_sl_compat.h create mode 100644 src/saveload/compat/map_sl_compat.h create mode 100644 src/saveload/compat/misc_sl_compat.h create mode 100644 src/saveload/compat/newgrf_sl_compat.h create mode 100644 src/saveload/compat/object_sl_compat.h create mode 100644 src/saveload/compat/order_sl_compat.h create mode 100644 src/saveload/compat/settings_sl_compat.h create mode 100644 src/saveload/compat/signs_sl_compat.h create mode 100644 src/saveload/compat/station_sl_compat.h create mode 100644 src/saveload/compat/storage_sl_compat.h create mode 100644 src/saveload/compat/story_sl_compat.h create mode 100644 src/saveload/compat/subsidy_sl_compat.h diff --git a/src/saveload/CMakeLists.txt b/src/saveload/CMakeLists.txt index 52f103fa7e..5f83309a40 100644 --- a/src/saveload/CMakeLists.txt +++ b/src/saveload/CMakeLists.txt @@ -1,3 +1,5 @@ +add_subdirectory(compat) + add_files( afterload.cpp ai_sl.cpp diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp index 1c44ef7323..047a08d5b8 100644 --- a/src/saveload/ai_sl.cpp +++ b/src/saveload/ai_sl.cpp @@ -8,9 +8,12 @@ /** @file ai_sl.cpp Handles the saveload part of the AIs */ #include "../stdafx.h" -#include "../company_base.h" #include "../debug.h" + #include "saveload.h" +#include "compat/ai_sl_compat.h" + +#include "../company_base.h" #include "../string_func.h" #include "../ai/ai.hpp" @@ -25,7 +28,7 @@ static int _ai_saveload_version; static std::string _ai_saveload_settings; static bool _ai_saveload_is_random; -static const SaveLoad _ai_company[] = { +static const SaveLoad _ai_company_desc[] = { SLEG_SSTR("name", _ai_saveload_name, SLE_STR), SLEG_SSTR("settings", _ai_saveload_settings, SLE_STR), SLEG_CONDVAR("version", _ai_saveload_version, SLE_UINT32, SLV_108, SL_MAX_VERSION), @@ -49,13 +52,15 @@ static void SaveReal_AIPL(int *index_ptr) _ai_saveload_is_random = config->IsRandom(); _ai_saveload_settings = config->SettingsToString(); - SlObject(nullptr, _ai_company); + SlObject(nullptr, _ai_company_desc); /* If the AI was active, store its data too */ if (Company::IsValidAiID(index)) AI::Save(index); } static void Load_AIPL() { + const std::vector slt = SlCompatTableHeader(_ai_company_desc, _ai_company_sl_compat); + /* Free all current data */ for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(nullptr); @@ -67,7 +72,7 @@ static void Load_AIPL() _ai_saveload_is_random = false; _ai_saveload_version = -1; - SlObject(nullptr, _ai_company); + SlObject(nullptr, slt); if (_networking && !_network_server) { if (Company::IsValidAiID(index)) AIInstance::LoadEmpty(); @@ -114,6 +119,8 @@ static void Load_AIPL() static void Save_AIPL() { + SlTableHeader(_ai_company_desc); + for (int i = COMPANY_FIRST; i < MAX_COMPANIES; i++) { SlSetArrayIndex(i); SlAutolength((AutolengthProc *)SaveReal_AIPL, &i); @@ -121,7 +128,7 @@ static void Save_AIPL() } static const ChunkHandler ai_chunk_handlers[] = { - { 'AIPL', Save_AIPL, Load_AIPL, nullptr, nullptr, CH_ARRAY }, + { 'AIPL', Save_AIPL, Load_AIPL, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _ai_chunk_handlers(ai_chunk_handlers); diff --git a/src/saveload/airport_sl.cpp b/src/saveload/airport_sl.cpp index 114e5672ab..6862fc1330 100644 --- a/src/saveload/airport_sl.cpp +++ b/src/saveload/airport_sl.cpp @@ -35,8 +35,8 @@ static void Load_ATID() } static const ChunkHandler airport_chunk_handlers[] = { - { 'ATID', Save_ATID, Load_ATID, nullptr, nullptr, CH_ARRAY }, - { 'APID', Save_APID, Load_APID, nullptr, nullptr, CH_ARRAY }, + { 'ATID', Save_ATID, Load_ATID, nullptr, nullptr, CH_TABLE }, + { 'APID', Save_APID, Load_APID, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _airport_chunk_handlers(airport_chunk_handlers); diff --git a/src/saveload/animated_tile_sl.cpp b/src/saveload/animated_tile_sl.cpp index 2e0666d4a2..50fe05df2b 100644 --- a/src/saveload/animated_tile_sl.cpp +++ b/src/saveload/animated_tile_sl.cpp @@ -8,12 +8,14 @@ /** @file animated_tile_sl.cpp Code handling saving and loading of animated tiles */ #include "../stdafx.h" + +#include "saveload.h" +#include "compat/animated_tile_sl_compat.h" + #include "../tile_type.h" #include "../core/alloc_func.hpp" #include "../core/smallvec_type.hpp" -#include "saveload.h" - #include "../safeguards.h" extern std::vector _animated_tiles; @@ -27,6 +29,8 @@ static const SaveLoad _animated_tile_desc[] = { */ static void Save_ANIT() { + SlTableHeader(_animated_tile_desc); + SlSetArrayIndex(0); SlGlobList(_animated_tile_desc); } @@ -57,17 +61,15 @@ static void Load_ANIT() return; } + const std::vector slt = SlCompatTableHeader(_animated_tile_desc, _animated_tile_sl_compat); + if (SlIterateArray() == -1) return; - SlGlobList(_animated_tile_desc); + SlGlobList(slt); if (SlIterateArray() != -1) SlErrorCorrupt("Too many ANIT entries"); } -/** - * "Definition" imported by the saveload code to be able to load and save - * the animated tile table. - */ static const ChunkHandler animated_tile_chunk_handlers[] = { - { 'ANIT', Save_ANIT, Load_ANIT, nullptr, nullptr, CH_ARRAY }, + { 'ANIT', Save_ANIT, Load_ANIT, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _animated_tile_chunk_handlers(animated_tile_chunk_handlers); diff --git a/src/saveload/autoreplace_sl.cpp b/src/saveload/autoreplace_sl.cpp index f54866c107..2c848c96d2 100644 --- a/src/saveload/autoreplace_sl.cpp +++ b/src/saveload/autoreplace_sl.cpp @@ -8,9 +8,11 @@ /** @file autoreplace_sl.cpp Code handling saving and loading of autoreplace rules */ #include "../stdafx.h" -#include "../autoreplace_base.h" #include "saveload.h" +#include "compat/autoreplace_sl_compat.h" + +#include "../autoreplace_base.h" #include "../safeguards.h" @@ -25,6 +27,8 @@ static const SaveLoad _engine_renew_desc[] = { static void Save_ERNW() { + SlTableHeader(_engine_renew_desc); + for (EngineRenew *er : EngineRenew::Iterate()) { SlSetArrayIndex(er->index); SlObject(er, _engine_renew_desc); @@ -33,11 +37,13 @@ static void Save_ERNW() static void Load_ERNW() { + const std::vector slt = SlCompatTableHeader(_engine_renew_desc, _engine_renew_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { EngineRenew *er = new (index) EngineRenew(); - SlObject(er, _engine_renew_desc); + SlObject(er, slt); /* Advanced vehicle lists, ungrouped vehicles got added */ if (IsSavegameVersionBefore(SLV_60)) { @@ -56,7 +62,7 @@ static void Ptrs_ERNW() } static const ChunkHandler autoreplace_chunk_handlers[] = { - { 'ERNW', Save_ERNW, Load_ERNW, Ptrs_ERNW, nullptr, CH_ARRAY }, + { 'ERNW', Save_ERNW, Load_ERNW, Ptrs_ERNW, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _autoreplace_chunk_handlers(autoreplace_chunk_handlers); diff --git a/src/saveload/cargomonitor_sl.cpp b/src/saveload/cargomonitor_sl.cpp index abb0d59b99..e00d383329 100644 --- a/src/saveload/cargomonitor_sl.cpp +++ b/src/saveload/cargomonitor_sl.cpp @@ -8,9 +8,11 @@ /** @file cargomonitor_sl.cpp Code handling saving and loading of Cargo monitoring. */ #include "../stdafx.h" -#include "../cargomonitor.h" #include "saveload.h" +#include "compat/cargomonitor_sl_compat.h" + +#include "../cargomonitor.h" #include "../safeguards.h" @@ -44,6 +46,8 @@ static CargoMonitorID FixupCargoMonitor(CargoMonitorID number) /** Save the #_cargo_deliveries monitoring map. */ static void SaveDelivery() { + SlTableHeader(_cargomonitor_pair_desc); + TempStorage storage; int i = 0; @@ -63,13 +67,15 @@ static void SaveDelivery() /** Load the #_cargo_deliveries monitoring map. */ static void LoadDelivery() { + const std::vector slt = SlCompatTableHeader(_cargomonitor_pair_desc, _cargomonitor_pair_sl_compat); + TempStorage storage; bool fix = IsSavegameVersionBefore(SLV_FIX_CARGO_MONITOR); ClearCargoDeliveryMonitoring(); for (;;) { if (SlIterateArray() < 0) break; - SlObject(&storage, _cargomonitor_pair_desc); + SlObject(&storage, slt); if (fix) storage.number = FixupCargoMonitor(storage.number); @@ -82,6 +88,8 @@ static void LoadDelivery() /** Save the #_cargo_pickups monitoring map. */ static void SavePickup() { + SlTableHeader(_cargomonitor_pair_desc); + TempStorage storage; int i = 0; @@ -101,13 +109,15 @@ static void SavePickup() /** Load the #_cargo_pickups monitoring map. */ static void LoadPickup() { + const std::vector slt = SlCompatTableHeader(_cargomonitor_pair_desc, _cargomonitor_pair_sl_compat); + TempStorage storage; bool fix = IsSavegameVersionBefore(SLV_FIX_CARGO_MONITOR); ClearCargoPickupMonitoring(); for (;;) { if (SlIterateArray() < 0) break; - SlObject(&storage, _cargomonitor_pair_desc); + SlObject(&storage, slt); if (fix) storage.number = FixupCargoMonitor(storage.number); @@ -117,9 +127,9 @@ static void LoadPickup() } /** Chunk definition of the cargomonitoring maps. */ -static const ChunkHandler cargomonitor_chunk_handlers[] = { - { 'CMDL', SaveDelivery, LoadDelivery, nullptr, nullptr, CH_ARRAY }, - { 'CMPU', SavePickup, LoadPickup, nullptr, nullptr, CH_ARRAY }, +extern const ChunkHandler cargomonitor_chunk_handlers[] = { + { 'CMDL', SaveDelivery, LoadDelivery, nullptr, nullptr, CH_TABLE }, + { 'CMPU', SavePickup, LoadPickup, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _cargomonitor_chunk_handlers(cargomonitor_chunk_handlers); diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp index 96c96cabcb..def62a7b9d 100644 --- a/src/saveload/cargopacket_sl.cpp +++ b/src/saveload/cargopacket_sl.cpp @@ -8,10 +8,12 @@ /** @file cargopacket_sl.cpp Code handling saving and loading of cargo packets */ #include "../stdafx.h" -#include "../vehicle_base.h" -#include "../station_base.h" #include "saveload.h" +#include "compat/cargopacket_sl_compat.h" + +#include "../vehicle_base.h" +#include "../station_base.h" #include "../safeguards.h" @@ -94,9 +96,6 @@ SaveLoadTable GetCargoPacketDesc() SLE_VAR(CargoPacket, feeder_share, SLE_INT64), SLE_CONDVAR(CargoPacket, source_type, SLE_UINT8, SLV_125, SL_MAX_VERSION), SLE_CONDVAR(CargoPacket, source_id, SLE_UINT16, SLV_125, SL_MAX_VERSION), - - /* Used to be paid_for, but that got changed. */ - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_121), }; return _cargopacket_desc; } @@ -106,6 +105,8 @@ SaveLoadTable GetCargoPacketDesc() */ static void Save_CAPA() { + SlTableHeader(GetCargoPacketDesc()); + for (CargoPacket *cp : CargoPacket::Iterate()) { SlSetArrayIndex(cp->index); SlObject(cp, GetCargoPacketDesc()); @@ -117,17 +118,18 @@ static void Save_CAPA() */ static void Load_CAPA() { + const std::vector slt = SlCompatTableHeader(GetCargoPacketDesc(), _cargopacket_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { CargoPacket *cp = new (index) CargoPacket(); - SlObject(cp, GetCargoPacketDesc()); + SlObject(cp, slt); } } -/** Chunk handlers related to cargo packets. */ static const ChunkHandler cargopacket_chunk_handlers[] = { - { 'CAPA', Save_CAPA, Load_CAPA, nullptr, nullptr, CH_ARRAY }, + { 'CAPA', Save_CAPA, Load_CAPA, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _cargopacket_chunk_handlers(cargopacket_chunk_handlers); diff --git a/src/saveload/cheat_sl.cpp b/src/saveload/cheat_sl.cpp index 6c6bab4ddb..cef8b7e903 100644 --- a/src/saveload/cheat_sl.cpp +++ b/src/saveload/cheat_sl.cpp @@ -8,9 +8,11 @@ /** @file cheat_sl.cpp Code handling saving and loading of cheats */ #include "../stdafx.h" -#include "../cheat_type.h" #include "saveload.h" +#include "compat/cheat_sl_compat.h" + +#include "../cheat_type.h" #include "../safeguards.h" @@ -23,18 +25,12 @@ static const SaveLoad _cheats_desc[] = { SLE_VAR(Cheats, money.value, SLE_BOOL), SLE_VAR(Cheats, crossing_tunnels.been_used, SLE_BOOL), SLE_VAR(Cheats, crossing_tunnels.value, SLE_BOOL), - SLE_NULL(1), - SLE_NULL(1), // Needs to be two NULL fields. See Load_CHTS(). SLE_VAR(Cheats, no_jetcrash.been_used, SLE_BOOL), SLE_VAR(Cheats, no_jetcrash.value, SLE_BOOL), - SLE_NULL(1), - SLE_NULL(1), // Needs to be two NULL fields. See Load_CHTS(). SLE_VAR(Cheats, change_date.been_used, SLE_BOOL), SLE_VAR(Cheats, change_date.value, SLE_BOOL), SLE_VAR(Cheats, setup_prod.been_used, SLE_BOOL), SLE_VAR(Cheats, setup_prod.value, SLE_BOOL), - SLE_NULL(1), - SLE_NULL(1), // Needs to be two NULL fields. See Load_CHTS(). SLE_VAR(Cheats, edit_max_hl.been_used, SLE_BOOL), SLE_VAR(Cheats, edit_max_hl.value, SLE_BOOL), }; @@ -44,9 +40,9 @@ static const SaveLoad _cheats_desc[] = { */ static void Save_CHTS() { - SlSetArrayIndex(0); + SlTableHeader(_cheats_desc); - SlSetLength(std::size(_cheats_desc)); + SlSetArrayIndex(0); SlObject(&_cheats, _cheats_desc); } @@ -55,18 +51,23 @@ static void Save_CHTS() */ static void Load_CHTS() { - size_t count = SlGetFieldLength(); - std::vector slt; + std::vector slt = SlCompatTableHeader(_cheats_desc, _cheats_sl_compat); - /* Cheats were added over the years without a savegame bump. They are - * stored as 2 SLE_BOOLs per entry. "count" indicates how many SLE_BOOLs - * are stored for this savegame. So read only "count" SLE_BOOLs (and in - * result "count / 2" cheats). */ - for (auto &sld : _cheats_desc) { - count--; - slt.push_back(sld); + if (IsSavegameVersionBefore(SLV_TABLE_CHUNKS)) { + size_t count = SlGetFieldLength(); + std::vector oslt; - if (count == 0) break; + /* Cheats were added over the years without a savegame bump. They are + * stored as 2 SLE_BOOLs per entry. "count" indicates how many SLE_BOOLs + * are stored for this savegame. So read only "count" SLE_BOOLs (and in + * result "count / 2" cheats). */ + for (auto &sld : slt) { + count--; + oslt.push_back(sld); + + if (count == 0) break; + } + slt = oslt; } if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; @@ -75,7 +76,7 @@ static void Load_CHTS() } static const ChunkHandler cheat_chunk_handlers[] = { - { 'CHTS', Save_CHTS, Load_CHTS, nullptr, nullptr, CH_ARRAY }, + { 'CHTS', Save_CHTS, Load_CHTS, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _cheat_chunk_handlers(cheat_chunk_handlers); diff --git a/src/saveload/compat/CMakeLists.txt b/src/saveload/compat/CMakeLists.txt new file mode 100644 index 0000000000..1737f9493a --- /dev/null +++ b/src/saveload/compat/CMakeLists.txt @@ -0,0 +1,26 @@ +add_files( + ai_sl_compat.h + autoreplace_sl_compat.h + cargomonitor_sl_compat.h + cargopacket_sl_compat.h + cheat_sl_compat.h + depot_sl_compat.h + economy_sl_compat.h + engine_sl_compat.h + game_sl_compat.h + goal_sl_compat.h + group_sl_compat.h + industry_sl_compat.h + labelmaps_sl_compat.h + map_sl_compat.h + misc_sl_compat.h + newgrf_sl_compat.h + object_sl_compat.h + order_sl_compat.h + settings_sl_compat.h + signs_sl_compat.h + station_sl_compat.h + storage_sl_compat.h + story_sl_compat.h + subsidy_sl_compat.h +) diff --git a/src/saveload/compat/ai_sl_compat.h b/src/saveload/compat/ai_sl_compat.h new file mode 100644 index 0000000000..dba2855a19 --- /dev/null +++ b/src/saveload/compat/ai_sl_compat.h @@ -0,0 +1,23 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file ai_sl_compat.h Loading for ai chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_AI_H +#define SAVELOAD_COMPAT_AI_H + +#include "../saveload.h" + +/** Original field order for _ai_company_desc. */ +const SaveLoadCompat _ai_company_sl_compat[] = { + SLC_VAR("name"), + SLC_VAR("settings"), + SLC_VAR("version"), + SLC_VAR("is_random"), +}; + +#endif /* SAVELOAD_COMPAT_AI_H */ diff --git a/src/saveload/compat/animated_tile_sl_compat.h b/src/saveload/compat/animated_tile_sl_compat.h new file mode 100644 index 0000000000..1fcea5818a --- /dev/null +++ b/src/saveload/compat/animated_tile_sl_compat.h @@ -0,0 +1,20 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file animated_tile_sl_compat.h Loading for animated_tile chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_ANIMATED_TILE_H +#define SAVELOAD_COMPAT_ANIMATED_TILE_H + +#include "../saveload.h" + +/** Original field order for _animated_tile_desc. */ +const SaveLoadCompat _animated_tile_sl_compat[] = { + SLC_VAR("tiles"), +}; + +#endif /* SAVELOAD_COMPAT_ANIMATED_TILE_H */ diff --git a/src/saveload/compat/autoreplace_sl_compat.h b/src/saveload/compat/autoreplace_sl_compat.h new file mode 100644 index 0000000000..abb4b0e28d --- /dev/null +++ b/src/saveload/compat/autoreplace_sl_compat.h @@ -0,0 +1,24 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file autoreplace_sl_compat.h Loading for autoreplace chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_AUTOREPLACE_H +#define SAVELOAD_COMPAT_AUTOREPLACE_H + +#include "../saveload.h" + +/** Original field order for _engine_renew_desc. */ +const SaveLoadCompat _engine_renew_sl_compat[] = { + SLC_VAR("from"), + SLC_VAR("to"), + SLC_VAR("next"), + SLC_VAR("group_id"), + SLC_VAR("replace_when_old"), +}; + +#endif /* SAVELOAD_COMPAT_AUTOREPLACE_H */ diff --git a/src/saveload/compat/cargomonitor_sl_compat.h b/src/saveload/compat/cargomonitor_sl_compat.h new file mode 100644 index 0000000000..2bb1e999ad --- /dev/null +++ b/src/saveload/compat/cargomonitor_sl_compat.h @@ -0,0 +1,21 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file cargomonitor_sl_compat.h Loading for cargomonitor chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_CARGOMONITOR_H +#define SAVELOAD_COMPAT_CARGOMONITOR_H + +#include "../saveload.h" + +/** Original field order for _cargomonitor_pair_desc. */ +const SaveLoadCompat _cargomonitor_pair_sl_compat[] = { + SLC_VAR("number"), + SLC_VAR("amount"), +}; + +#endif /* SAVELOAD_COMPAT_CARGOMONITOR_H */ diff --git a/src/saveload/compat/cargopacket_sl_compat.h b/src/saveload/compat/cargopacket_sl_compat.h new file mode 100644 index 0000000000..eee308bcb0 --- /dev/null +++ b/src/saveload/compat/cargopacket_sl_compat.h @@ -0,0 +1,28 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file cargopacket_sl_compat.h Loading for cargopacket chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_CARGOPACKET_H +#define SAVELOAD_COMPAT_CARGOPACKET_H + +#include "../saveload.h" + +/** Original field order for _cargopacket_desc. */ +const SaveLoadCompat _cargopacket_sl_compat[] = { + SLC_VAR("source"), + SLC_VAR("source_xy"), + SLC_VAR("loaded_at_xy"), + SLC_VAR("count"), + SLC_VAR("days_in_transit"), + SLC_VAR("feeder_share"), + SLC_VAR("source_type"), + SLC_VAR("source_id"), + SLC_NULL(1, SL_MIN_VERSION, SLV_121), +}; + +#endif /* SAVELOAD_COMPAT_CARGOPACKET_H */ diff --git a/src/saveload/compat/cheat_sl_compat.h b/src/saveload/compat/cheat_sl_compat.h new file mode 100644 index 0000000000..f3c7560976 --- /dev/null +++ b/src/saveload/compat/cheat_sl_compat.h @@ -0,0 +1,41 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file cheat_sl_compat.h Loading for cheat chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_CHEAT_H +#define SAVELOAD_COMPAT_CHEAT_H + +#include "../saveload.h" + +/** Original field order for _cheats_desc. */ +const SaveLoadCompat _cheats_sl_compat[] = { + SLC_VAR("magic_bulldozer.been_used"), + SLC_VAR("magic_bulldozer.value"), + SLC_VAR("switch_company.been_used"), + SLC_VAR("switch_company.value"), + SLC_VAR("money.been_used"), + SLC_VAR("money.value"), + SLC_VAR("crossing_tunnels.been_used"), + SLC_VAR("crossing_tunnels.value"), + SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS), + SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS), // Need to be two NULL fields. See Load_CHTS(). + SLC_VAR("no_jetcrash.been_used"), + SLC_VAR("no_jetcrash.value"), + SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS), + SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS), // Need to be two NULL fields. See Load_CHTS(). + SLC_VAR("change_date.been_used"), + SLC_VAR("change_date.value"), + SLC_VAR("setup_prod.been_used"), + SLC_VAR("setup_prod.value"), + SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS), + SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS), // Need to be two NULL fields. See Load_CHTS(). + SLC_VAR("edit_max_hl.been_used"), + SLC_VAR("edit_max_hl.value"), +}; + +#endif /* SAVELOAD_COMPAT_CHEAT_H */ diff --git a/src/saveload/compat/depot_sl_compat.h b/src/saveload/compat/depot_sl_compat.h new file mode 100644 index 0000000000..8fcf4b6861 --- /dev/null +++ b/src/saveload/compat/depot_sl_compat.h @@ -0,0 +1,25 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file depot_sl_compat.h Loading for depot chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_DEPOT_H +#define SAVELOAD_COMPAT_DEPOT_H + +#include "../saveload.h" + +/** Original field order for _depot_desc. */ +const SaveLoadCompat _depot_sl_compat[] = { + SLC_VAR("xy"), + SLC_VAR("town_index"), + SLC_VAR("town"), + SLC_VAR("town_cn"), + SLC_VAR("name"), + SLC_VAR("build_date"), +}; + +#endif /* SAVELOAD_COMPAT_DEPOT_H */ diff --git a/src/saveload/compat/economy_sl_compat.h b/src/saveload/compat/economy_sl_compat.h new file mode 100644 index 0000000000..560673a0d0 --- /dev/null +++ b/src/saveload/compat/economy_sl_compat.h @@ -0,0 +1,38 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file economy_sl_compat.h Loading for economy chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_ECONOMY_H +#define SAVELOAD_COMPAT_ECONOMY_H + +#include "../saveload.h" + +/** Original field order for _economy_desc. */ +const SaveLoadCompat _economy_sl_compat[] = { + SLC_NULL(4, SL_MIN_VERSION, SLV_65), + SLC_NULL(8, SLV_65, SLV_144), + SLC_VAR("old_max_loan_unround"), + SLC_VAR("old_max_loan_unround_fract"), + SLC_VAR("inflation_prices"), + SLC_VAR("inflation_payment"), + SLC_VAR("fluct"), + SLC_VAR("interest_rate"), + SLC_VAR("infl_amount"), + SLC_VAR("infl_amount_pr"), + SLC_VAR("industry_daily_change_counter"), +}; + +/** Original field order for _cargopayment_desc. */ +const SaveLoadCompat _cargopayment_sl_compat[] = { + SLC_VAR("front"), + SLC_VAR("route_profit"), + SLC_VAR("visual_profit"), + SLC_VAR("visual_transfer"), +}; + +#endif /* SAVELOAD_COMPAT_ECONOMY_H */ diff --git a/src/saveload/compat/engine_sl_compat.h b/src/saveload/compat/engine_sl_compat.h new file mode 100644 index 0000000000..68a839bef1 --- /dev/null +++ b/src/saveload/compat/engine_sl_compat.h @@ -0,0 +1,48 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file engine_sl_compat.h Loading for engine chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_ENGINE_H +#define SAVELOAD_COMPAT_ENGINE_H + +#include "../saveload.h" + +/** Original field order for _engine_desc. */ +const SaveLoadCompat _engine_sl_compat[] = { + SLC_VAR("intro_date"), + SLC_VAR("age"), + SLC_VAR("reliability"), + SLC_VAR("reliability_spd_dec"), + SLC_VAR("reliability_start"), + SLC_VAR("reliability_max"), + SLC_VAR("reliability_final"), + SLC_VAR("duration_phase_1"), + SLC_VAR("duration_phase_2"), + SLC_VAR("duration_phase_3"), + SLC_NULL(1, SL_MIN_VERSION, SLV_121), + SLC_VAR("flags"), + SLC_NULL(1, SL_MIN_VERSION, SLV_179), + SLC_VAR("preview_asked"), + SLC_VAR("preview_company"), + SLC_VAR("preview_wait"), + SLC_NULL(1, SL_MIN_VERSION, SLV_45), + SLC_VAR("company_avail"), + SLC_VAR("company_hidden"), + SLC_VAR("name"), + SLC_NULL(16, SLV_2, SLV_144), +}; + +/** Original field order for _engine_id_mapping_desc. */ +const SaveLoadCompat _engine_id_mapping_sl_compat[] = { + SLC_VAR("grfid"), + SLC_VAR("internal_id"), + SLC_VAR("type"), + SLC_VAR("substitute_id"), +}; + +#endif /* SAVELOAD_COMPAT_ENGINE_H */ diff --git a/src/saveload/compat/game_sl_compat.h b/src/saveload/compat/game_sl_compat.h new file mode 100644 index 0000000000..204504e3b2 --- /dev/null +++ b/src/saveload/compat/game_sl_compat.h @@ -0,0 +1,23 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file game_sl_compat.h Loading for game chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_GAME_H +#define SAVELOAD_COMPAT_GAME_H + +#include "../saveload.h" + +/** Original field order for _game_script_desc. */ +const SaveLoadCompat _game_script_sl_compat[] = { + SLC_VAR("name"), + SLC_VAR("settings"), + SLC_VAR("version"), + SLC_VAR("is_random"), +}; + +#endif /* SAVELOAD_COMPAT_GAME_H */ diff --git a/src/saveload/compat/goal_sl_compat.h b/src/saveload/compat/goal_sl_compat.h new file mode 100644 index 0000000000..5dc205462c --- /dev/null +++ b/src/saveload/compat/goal_sl_compat.h @@ -0,0 +1,25 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file goal_sl_compat.h Loading of goal chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_GOAL_H +#define SAVELOAD_COMPAT_GOAL_H + +#include "../saveload.h" + +/** Original field order for _goals_desc. */ +const SaveLoadCompat _goals_sl_compat[] = { + SLC_VAR("company"), + SLC_VAR("type"), + SLC_VAR("dst"), + SLC_VAR("text"), + SLC_VAR("progress"), + SLC_VAR("completed"), +}; + +#endif /* SAVELOAD_COMPAT_GOAL_H */ diff --git a/src/saveload/compat/group_sl_compat.h b/src/saveload/compat/group_sl_compat.h new file mode 100644 index 0000000000..50021079f2 --- /dev/null +++ b/src/saveload/compat/group_sl_compat.h @@ -0,0 +1,28 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file group_sl_compat.h Loading of group chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_GROUP_H +#define SAVELOAD_COMPAT_GROUP_H + +#include "../saveload.h" + +/** Original field order for _group_desc. */ +const SaveLoadCompat _group_sl_compat[] = { + SLC_VAR("name"), + SLC_NULL(2, SL_MIN_VERSION, SLV_164), + SLC_VAR("owner"), + SLC_VAR("vehicle_type"), + SLC_VAR("flags"), + SLC_VAR("livery.in_use"), + SLC_VAR("livery.colour1"), + SLC_VAR("livery.colour2"), + SLC_VAR("parent"), +}; + +#endif /* SAVELOAD_COMPAT_GROUP_H */ diff --git a/src/saveload/compat/industry_sl_compat.h b/src/saveload/compat/industry_sl_compat.h new file mode 100644 index 0000000000..990cc64d54 --- /dev/null +++ b/src/saveload/compat/industry_sl_compat.h @@ -0,0 +1,72 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file industry_sl_compat.h Loading of industry chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_INDUSTRY_H +#define SAVELOAD_COMPAT_INDUSTRY_H + +#include "../saveload.h" + +/** Original field order for _industry_desc. */ +const SaveLoadCompat _industry_sl_compat[] = { + SLC_VAR("location.tile"), + SLC_VAR("location.w"), + SLC_VAR("location.h"), + SLC_VAR("town"), + SLC_VAR("neutral_station"), + SLC_NULL(2, SL_MIN_VERSION, SLV_61), + SLC_VAR("produced_cargo"), + SLC_VAR("incoming_cargo_waiting"), + SLC_VAR("produced_cargo_waiting"), + SLC_VAR("production_rate"), + SLC_NULL(3, SL_MIN_VERSION, SLV_61), + SLC_VAR("accepts_cargo"), + SLC_VAR("prod_level"), + SLC_VAR("this_month_production"), + SLC_VAR("this_month_transported"), + SLC_VAR("last_month_pct_transported"), + SLC_VAR("last_month_production"), + SLC_VAR("last_month_transported"), + SLC_VAR("counter"), + SLC_VAR("type"), + SLC_VAR("owner"), + SLC_VAR("random_colour"), + SLC_VAR("last_prod_year"), + SLC_VAR("was_cargo_delivered"), + SLC_VAR("ctlflags"), + SLC_VAR("founder"), + SLC_VAR("construction_date"), + SLC_VAR("construction_type"), + SLC_VAR("last_cargo_accepted_at[0]"), + SLC_VAR("last_cargo_accepted_at"), + SLC_VAR("selected_layout"), + SLC_VAR("exclusive_supplier"), + SLC_VAR("exclusive_consumer"), + SLC_VAR("storage"), + SLC_VAR("psa"), + SLC_NULL(1, SLV_82, SLV_197), + SLC_VAR("random"), + SLC_VAR("text"), + SLC_NULL(32, SLV_2, SLV_144), +}; + +/** Original field order for _industry_builder_desc. */ +const SaveLoadCompat _industry_builder_sl_compat[] = { + SLC_VAR("wanted_inds"), +}; + +/** Original field order for _industrytype_builder_desc. */ +const SaveLoadCompat _industrytype_builder_sl_compat[] = { + SLC_VAR("probability"), + SLC_VAR("min_number"), + SLC_VAR("target_count"), + SLC_VAR("max_wait"), + SLC_VAR("wait_count"), +}; + +#endif /* SAVELOAD_COMPAT_INDUSTRY_H */ diff --git a/src/saveload/compat/labelmaps_sl_compat.h b/src/saveload/compat/labelmaps_sl_compat.h new file mode 100644 index 0000000000..8664cec19d --- /dev/null +++ b/src/saveload/compat/labelmaps_sl_compat.h @@ -0,0 +1,20 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file labelmaps_sl_compat.h Loading of labelmaps chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_LABELMAPS_H +#define SAVELOAD_COMPAT_LABELMAPS_H + +#include "../saveload.h" + +/** Original field order for _label_object_desc. */ +const SaveLoadCompat _label_object_sl_compat[] = { + SLC_VAR("label"), +}; + +#endif /* SAVELOAD_COMPAT_LABELMAPS_H */ diff --git a/src/saveload/compat/map_sl_compat.h b/src/saveload/compat/map_sl_compat.h new file mode 100644 index 0000000000..84cfb28652 --- /dev/null +++ b/src/saveload/compat/map_sl_compat.h @@ -0,0 +1,21 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file map_sl_compat.h Loading for map chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_MAP_H +#define SAVELOAD_COMPAT_MAP_H + +#include "../saveload.h" + +/** Original field order for _map_desc. */ +const SaveLoadCompat _map_sl_compat[] = { + SLC_VAR("dim_x"), + SLC_VAR("dim_y"), +}; + +#endif /* SAVELOAD_COMPAT_MAP_H */ diff --git a/src/saveload/compat/misc_sl_compat.h b/src/saveload/compat/misc_sl_compat.h new file mode 100644 index 0000000000..02d26002a5 --- /dev/null +++ b/src/saveload/compat/misc_sl_compat.h @@ -0,0 +1,68 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file misc_sl_compat.h Loading for misc chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_MISC_H +#define SAVELOAD_COMPAT_MISC_H + +#include "../saveload.h" + +/** Original field order for _date_desc. */ +const SaveLoadCompat _date_sl_compat[] = { + SLC_VAR("date"), + SLC_VAR("date_fract"), + SLC_VAR("tick_counter"), + SLC_NULL(2, SL_MIN_VERSION, SLV_157), + SLC_VAR("age_cargo_skip_counter"), + SLC_NULL(1, SL_MIN_VERSION, SLV_46), + SLC_VAR("cur_tileloop_tile"), + SLC_VAR("next_disaster_start"), + SLC_NULL(2, SL_MIN_VERSION, SLV_120), + SLC_VAR("random_state[0]"), + SLC_VAR("random_state[1]"), + SLC_NULL(1, SL_MIN_VERSION, SLV_10), + SLC_NULL(4, SLV_10, SLV_120), + SLC_VAR("company_tick_counter"), + SLC_VAR("next_competitor_start"), + SLC_VAR("trees_tick_counter"), + SLC_VAR("pause_mode"), + SLC_NULL(4, SLV_11, SLV_120), +}; + +/** Original field order for _date_check_desc. */ +const SaveLoadCompat _date_check_sl_compat[] = { + SLC_VAR("date"), + SLC_NULL(2, SL_MIN_VERSION, SL_MAX_VERSION), // date_fract + SLC_NULL(2, SL_MIN_VERSION, SL_MAX_VERSION), // tick_counter + SLC_NULL(2, SL_MIN_VERSION, SLV_157), + SLC_NULL(1, SL_MIN_VERSION, SLV_162), // age_cargo_skip_counter + SLC_NULL(1, SL_MIN_VERSION, SLV_46), + SLC_NULL(2, SL_MIN_VERSION, SLV_6), // cur_tileloop_tile + SLC_NULL(4, SLV_6, SL_MAX_VERSION), // cur_tileloop_tile + SLC_NULL(2, SL_MIN_VERSION, SL_MAX_VERSION), // disaster_delay + SLC_NULL(2, SL_MIN_VERSION, SLV_120), + SLC_NULL(4, SL_MIN_VERSION, SL_MAX_VERSION), // random.state[0] + SLC_NULL(4, SL_MIN_VERSION, SL_MAX_VERSION), // random.state[1] + SLC_NULL(1, SL_MIN_VERSION, SLV_10), + SLC_NULL(4, SLV_10, SLV_120), + SLC_NULL(1, SL_MIN_VERSION, SL_MAX_VERSION), // cur_company_tick_index + SLC_NULL(2, SL_MIN_VERSION, SLV_109), // next_competitor_start + SLC_NULL(4, SLV_109, SL_MAX_VERSION), // next_competitor_start + SLC_NULL(1, SL_MIN_VERSION, SL_MAX_VERSION), // trees_tick_ctr + SLC_NULL(1, SLV_4, SL_MAX_VERSION), // pause_mode + SLC_NULL(4, SLV_11, SLV_120), +}; + +/** Original field order for _view_desc. */ +const SaveLoadCompat _view_sl_compat[] = { + SLC_VAR("x"), + SLC_VAR("y"), + SLC_VAR("zoom"), +}; + +#endif /* SAVELOAD_COMPAT_MISC_H */ diff --git a/src/saveload/compat/newgrf_sl_compat.h b/src/saveload/compat/newgrf_sl_compat.h new file mode 100644 index 0000000000..8a1803946f --- /dev/null +++ b/src/saveload/compat/newgrf_sl_compat.h @@ -0,0 +1,33 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file newgrf_sl_compat.h Loading of newgrf chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_NEWGRF_H +#define SAVELOAD_COMPAT_NEWGRF_H + +#include "../saveload.h" + +/** Original field order for _newgrf_mapping_desc. */ +const SaveLoadCompat _newgrf_mapping_sl_compat[] = { + SLC_VAR("grfid"), + SLC_VAR("entity_id"), + SLC_VAR("substitute_id"), +}; + +/** Original field order for _newgrf_desc. */ +const SaveLoadCompat _grfconfig_sl_compat[] = { + SLC_VAR("filename"), + SLC_VAR("ident.grfid"), + SLC_VAR("ident.md5sum"), + SLC_VAR("version"), + SLC_VAR("param"), + SLC_VAR("num_params"), + SLC_VAR("palette"), +}; + +#endif /* SAVELOAD_COMPAT_NEWGRF_H */ diff --git a/src/saveload/compat/object_sl_compat.h b/src/saveload/compat/object_sl_compat.h new file mode 100644 index 0000000000..a4a9fca6a8 --- /dev/null +++ b/src/saveload/compat/object_sl_compat.h @@ -0,0 +1,27 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file object_sl_compat.h Loading of object chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_OBJECT_H +#define SAVELOAD_COMPAT_OBJECT_H + +#include "../saveload.h" + +/** Original field order for _object_desc. */ +const SaveLoadCompat _object_sl_compat[] = { + SLC_VAR("location.tile"), + SLC_VAR("location.w"), + SLC_VAR("location.h"), + SLC_VAR("town"), + SLC_VAR("build_date"), + SLC_VAR("colour"), + SLC_VAR("view"), + SLC_VAR("type"), +}; + +#endif /* SAVELOAD_COMPAT_OBJECT_H */ diff --git a/src/saveload/compat/order_sl_compat.h b/src/saveload/compat/order_sl_compat.h new file mode 100644 index 0000000000..62c879cf13 --- /dev/null +++ b/src/saveload/compat/order_sl_compat.h @@ -0,0 +1,52 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file order_sl_compat.h Loading of order chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_ORDER_H +#define SAVELOAD_COMPAT_ORDER_H + +#include "../saveload.h" + +/** Original field order for _order_desc. */ +const SaveLoadCompat _order_sl_compat[] = { + SLC_VAR("type"), + SLC_VAR("flags"), + SLC_VAR("dest"), + SLC_VAR("next"), + SLC_VAR("refit_cargo"), + SLC_NULL(1, SLV_36, SLV_182), + SLC_VAR("wait_time"), + SLC_VAR("travel_time"), + SLC_VAR("max_speed"), + SLC_NULL(10, SLV_5, SLV_36), +}; + +/** Original field order for _orderlist_desc. */ +const SaveLoadCompat _orderlist_sl_compat[] = { + SLC_VAR("first"), +}; + +/** Original field order for _order_backup_desc. */ +const SaveLoadCompat _order_backup_sl_compat[] = { + SLC_VAR("user"), + SLC_VAR("tile"), + SLC_VAR("group"), + SLC_VAR("service_interval"), + SLC_VAR("name"), + SLC_NULL(2, SL_MIN_VERSION, SLV_192), + SLC_VAR("clone"), + SLC_VAR("cur_real_order_index"), + SLC_VAR("cur_implicit_order_index"), + SLC_VAR("current_order_time"), + SLC_VAR("lateness_counter"), + SLC_VAR("timetable_start"), + SLC_VAR("vehicle_flags"), + SLC_VAR("orders"), +}; + +#endif /* SAVELOAD_COMPAT_ORDER_H */ diff --git a/src/saveload/compat/settings_sl_compat.h b/src/saveload/compat/settings_sl_compat.h new file mode 100644 index 0000000000..081779bf5b --- /dev/null +++ b/src/saveload/compat/settings_sl_compat.h @@ -0,0 +1,266 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file settings_sl_compat.h Loading of settings chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_SETTINGS_H +#define SAVELOAD_COMPAT_SETTINGS_H + +#include "../saveload.h" + +/** Original field order for _gameopt. */ +const SaveLoadCompat _gameopt_sl_compat[] = { + SLC_VAR("diff_custom"), + SLC_VAR("diff_level"), + SLC_VAR("locale.currency"), + SLC_VAR("units"), + SLC_VAR("game_creation.town_name"), + SLC_VAR("game_creation.landscape"), + SLC_VAR("game_creation.snow_line_height"), + SLC_NULL(1, SLV_22, SLV_165), + SLC_NULL(1, SL_MIN_VERSION, SLV_23), + SLC_VAR("vehicle.road_side"), +}; + +/** Original field order for _settings. */ +const SaveLoadCompat _settings_sl_compat[] = { + SLC_VAR("difficulty.max_no_competitors"), + SLC_NULL(1, SLV_97, SLV_110), + SLC_VAR("difficulty.number_towns"), + SLC_VAR("difficulty.industry_density"), + SLC_VAR("difficulty.max_loan"), + SLC_VAR("difficulty.initial_interest"), + SLC_VAR("difficulty.vehicle_costs"), + SLC_VAR("difficulty.competitor_speed"), + SLC_NULL(1, SLV_97, SLV_110), + SLC_VAR("difficulty.vehicle_breakdowns"), + SLC_VAR("difficulty.subsidy_multiplier"), + SLC_VAR("difficulty.subsidy_duration"), + SLC_VAR("difficulty.construction_cost"), + SLC_VAR("difficulty.terrain_type"), + SLC_VAR("difficulty.quantity_sea_lakes"), + SLC_VAR("difficulty.economy"), + SLC_VAR("difficulty.line_reverse_mode"), + SLC_VAR("difficulty.disasters"), + SLC_VAR("difficulty.town_council_tolerance"), + SLC_VAR("diff_level"), + SLC_VAR("game_creation.town_name"), + SLC_VAR("game_creation.landscape"), + SLC_NULL(1, SLV_97, SLV_164), + SLC_VAR("vehicle.road_side"), + SLC_VAR("construction.map_height_limit"), + SLC_VAR("game_creation.heightmap_height"), + SLC_VAR("construction.build_on_slopes"), + SLC_VAR("construction.command_pause_level"), + SLC_VAR("construction.terraform_per_64k_frames"), + SLC_VAR("construction.terraform_frame_burst"), + SLC_VAR("construction.clear_per_64k_frames"), + SLC_VAR("construction.clear_frame_burst"), + SLC_VAR("construction.tree_per_64k_frames"), + SLC_VAR("construction.tree_frame_burst"), + SLC_VAR("construction.autoslope"), + SLC_VAR("construction.extra_dynamite"), + SLC_VAR("construction.max_bridge_length"), + SLC_VAR("construction.max_bridge_height"), + SLC_VAR("construction.max_tunnel_length"), + SLC_NULL(1, SL_MIN_VERSION, SLV_159), + SLC_VAR("construction.train_signal_side"), + SLC_VAR("station.never_expire_airports"), + SLC_VAR("economy.town_layout"), + SLC_VAR("economy.allow_town_roads"), + SLC_VAR("economy.found_town"), + SLC_VAR("economy.allow_town_level_crossings"), + SLC_VAR("economy.town_cargogen_mode"), + SLC_VAR("linkgraph.recalc_interval"), + SLC_VAR("linkgraph.recalc_time"), + SLC_VAR("linkgraph.distribution_pax"), + SLC_VAR("linkgraph.distribution_mail"), + SLC_VAR("linkgraph.distribution_armoured"), + SLC_VAR("linkgraph.distribution_default"), + SLC_VAR("linkgraph.accuracy"), + SLC_VAR("linkgraph.demand_distance"), + SLC_VAR("linkgraph.demand_size"), + SLC_VAR("linkgraph.short_path_saturation"), + SLC_VAR("vehicle.train_acceleration_model"), + SLC_VAR("vehicle.roadveh_acceleration_model"), + SLC_VAR("vehicle.train_slope_steepness"), + SLC_VAR("vehicle.roadveh_slope_steepness"), + SLC_VAR("pf.forbid_90_deg"), + SLC_VAR("vehicle.max_train_length"), + SLC_NULL(1, SL_MIN_VERSION, SLV_159), + SLC_VAR("vehicle.smoke_amount"), + SLC_NULL(1, SL_MIN_VERSION, SLV_159), + SLC_VAR("pf.roadveh_queue"), + SLC_VAR("pf.new_pathfinding_all"), + SLC_VAR("pf.yapf.ship_use_yapf"), + SLC_VAR("pf.yapf.road_use_yapf"), + SLC_VAR("pf.yapf.rail_use_yapf"), + SLC_VAR("pf.pathfinder_for_trains"), + SLC_VAR("pf.pathfinder_for_roadvehs"), + SLC_VAR("pf.pathfinder_for_ships"), + SLC_VAR("vehicle.never_expire_vehicles"), + SLC_VAR("vehicle.max_trains"), + SLC_VAR("vehicle.max_roadveh"), + SLC_VAR("vehicle.max_aircraft"), + SLC_VAR("vehicle.max_ships"), + SLC_VAR("_old_vds.servint_ispercent"), + SLC_VAR("_old_vds.servint_trains"), + SLC_VAR("_old_vds.servint_roadveh"), + SLC_VAR("_old_vds.servint_ships"), + SLC_VAR("_old_vds.servint_aircraft"), + SLC_VAR("order.no_servicing_if_no_breakdowns"), + SLC_VAR("vehicle.wagon_speed_limits"), + SLC_VAR("vehicle.disable_elrails"), + SLC_VAR("vehicle.freight_trains"), + SLC_NULL(1, SLV_67, SLV_159), + SLC_VAR("vehicle.plane_speed"), + SLC_VAR("vehicle.dynamic_engines"), + SLC_VAR("vehicle.plane_crashes"), + SLC_NULL(1, SL_MIN_VERSION, SLV_159), + SLC_VAR("gui.sg_full_load_any"), + SLC_VAR("order.improved_load"), + SLC_VAR("order.selectgoods"), + SLC_VAR("gui.sg_new_nonstop"), + SLC_NULL(1, SL_MIN_VERSION, SLV_159), + SLC_VAR("station.station_spread"), + SLC_VAR("order.serviceathelipad"), + SLC_VAR("station.modified_catchment"), + SLC_VAR("station.serve_neutral_industries"), + SLC_VAR("order.gradual_loading"), + SLC_VAR("construction.road_stop_on_town_road"), + SLC_VAR("construction.road_stop_on_competitor_road"), + SLC_VAR("station.adjacent_stations"), + SLC_VAR("economy.station_noise_level"), + SLC_VAR("station.distant_join_stations"), + SLC_VAR("economy.inflation"), + SLC_VAR("construction.raw_industry_construction"), + SLC_VAR("construction.industry_platform"), + SLC_VAR("economy.multiple_industry_per_town"), + SLC_NULL(1, SL_MIN_VERSION, SLV_141), + SLC_VAR("economy.bribe"), + SLC_VAR("economy.exclusive_rights"), + SLC_VAR("economy.fund_buildings"), + SLC_VAR("economy.fund_roads"), + SLC_VAR("economy.give_money"), + SLC_VAR("game_creation.snow_line_height"), + SLC_VAR("game_creation.snow_coverage"), + SLC_VAR("game_creation.desert_coverage"), + SLC_NULL(4, SL_MIN_VERSION, SLV_144), + SLC_VAR("game_creation.starting_year"), + SLC_NULL(4, SL_MIN_VERSION, SLV_105), + SLC_VAR("game_creation.ending_year"), + SLC_VAR("economy.type"), + SLC_VAR("economy.allow_shares"), + SLC_VAR("economy.min_years_for_shares"), + SLC_VAR("economy.feeder_payment_share"), + SLC_VAR("economy.town_growth_rate"), + SLC_VAR("economy.larger_towns"), + SLC_VAR("economy.initial_city_size"), + SLC_VAR("economy.mod_road_rebuild"), + SLC_NULL(1, SL_MIN_VERSION, SLV_107), + SLC_VAR("script.settings_profile"), + SLC_VAR("ai.ai_in_multiplayer"), + SLC_VAR("ai.ai_disable_veh_train"), + SLC_VAR("ai.ai_disable_veh_roadveh"), + SLC_VAR("ai.ai_disable_veh_aircraft"), + SLC_VAR("ai.ai_disable_veh_ship"), + SLC_VAR("script.script_max_opcode_till_suspend"), + SLC_VAR("script.script_max_memory_megabytes"), + SLC_VAR("vehicle.extend_vehicle_life"), + SLC_VAR("economy.dist_local_authority"), + SLC_VAR("pf.reverse_at_signals"), + SLC_VAR("pf.wait_oneway_signal"), + SLC_VAR("pf.wait_twoway_signal"), + SLC_VAR("economy.town_noise_population[0]"), + SLC_VAR("economy.town_noise_population[1]"), + SLC_VAR("economy.town_noise_population[2]"), + SLC_VAR("economy.infrastructure_maintenance"), + SLC_VAR("pf.wait_for_pbs_path"), + SLC_VAR("pf.reserve_paths"), + SLC_VAR("pf.path_backoff_interval"), + SLC_NULL(3, SL_MIN_VERSION, SLV_REMOVE_OPF), + SLC_VAR("pf.npf.npf_max_search_nodes"), + SLC_VAR("pf.npf.npf_rail_firstred_penalty"), + SLC_VAR("pf.npf.npf_rail_firstred_exit_penalty"), + SLC_VAR("pf.npf.npf_rail_lastred_penalty"), + SLC_VAR("pf.npf.npf_rail_station_penalty"), + SLC_VAR("pf.npf.npf_rail_slope_penalty"), + SLC_VAR("pf.npf.npf_rail_curve_penalty"), + SLC_VAR("pf.npf.npf_rail_depot_reverse_penalty"), + SLC_VAR("pf.npf.npf_rail_pbs_cross_penalty"), + SLC_VAR("pf.npf.npf_rail_pbs_signal_back_penalty"), + SLC_VAR("pf.npf.npf_buoy_penalty"), + SLC_VAR("pf.npf.npf_water_curve_penalty"), + SLC_VAR("pf.npf.npf_road_curve_penalty"), + SLC_VAR("pf.npf.npf_crossing_penalty"), + SLC_VAR("pf.npf.npf_road_drive_through_penalty"), + SLC_VAR("pf.npf.npf_road_dt_occupied_penalty"), + SLC_VAR("pf.npf.npf_road_bay_occupied_penalty"), + SLC_VAR("pf.npf.maximum_go_to_depot_penalty"), + SLC_VAR("pf.yapf.disable_node_optimization"), + SLC_VAR("pf.yapf.max_search_nodes"), + SLC_VAR("pf.yapf.rail_firstred_twoway_eol"), + SLC_VAR("pf.yapf.rail_firstred_penalty"), + SLC_VAR("pf.yapf.rail_firstred_exit_penalty"), + SLC_VAR("pf.yapf.rail_lastred_penalty"), + SLC_VAR("pf.yapf.rail_lastred_exit_penalty"), + SLC_VAR("pf.yapf.rail_station_penalty"), + SLC_VAR("pf.yapf.rail_slope_penalty"), + SLC_VAR("pf.yapf.rail_curve45_penalty"), + SLC_VAR("pf.yapf.rail_curve90_penalty"), + SLC_VAR("pf.yapf.rail_depot_reverse_penalty"), + SLC_VAR("pf.yapf.rail_crossing_penalty"), + SLC_VAR("pf.yapf.rail_look_ahead_max_signals"), + SLC_VAR("pf.yapf.rail_look_ahead_signal_p0"), + SLC_VAR("pf.yapf.rail_look_ahead_signal_p1"), + SLC_VAR("pf.yapf.rail_look_ahead_signal_p2"), + SLC_VAR("pf.yapf.rail_pbs_cross_penalty"), + SLC_VAR("pf.yapf.rail_pbs_station_penalty"), + SLC_VAR("pf.yapf.rail_pbs_signal_back_penalty"), + SLC_VAR("pf.yapf.rail_doubleslip_penalty"), + SLC_VAR("pf.yapf.rail_longer_platform_penalty"), + SLC_VAR("pf.yapf.rail_longer_platform_per_tile_penalty"), + SLC_VAR("pf.yapf.rail_shorter_platform_penalty"), + SLC_VAR("pf.yapf.rail_shorter_platform_per_tile_penalty"), + SLC_VAR("pf.yapf.road_slope_penalty"), + SLC_VAR("pf.yapf.road_curve_penalty"), + SLC_VAR("pf.yapf.road_crossing_penalty"), + SLC_VAR("pf.yapf.road_stop_penalty"), + SLC_VAR("pf.yapf.road_stop_occupied_penalty"), + SLC_VAR("pf.yapf.road_stop_bay_occupied_penalty"), + SLC_VAR("pf.yapf.maximum_go_to_depot_penalty"), + SLC_VAR("pf.yapf.ship_curve45_penalty"), + SLC_VAR("pf.yapf.ship_curve90_penalty"), + SLC_VAR("game_creation.land_generator"), + SLC_VAR("game_creation.oil_refinery_limit"), + SLC_VAR("game_creation.tgen_smoothness"), + SLC_VAR("game_creation.variety"), + SLC_VAR("game_creation.generation_seed"), + SLC_VAR("game_creation.tree_placer"), + SLC_VAR("construction.freeform_edges"), + SLC_VAR("game_creation.water_borders"), + SLC_VAR("game_creation.custom_town_number"), + SLC_VAR("construction.extra_tree_placement"), + SLC_VAR("game_creation.custom_terrain_type"), + SLC_VAR("game_creation.custom_sea_level"), + SLC_VAR("game_creation.min_river_length"), + SLC_VAR("game_creation.river_route_random"), + SLC_VAR("game_creation.amount_of_rivers"), + SLC_VAR("locale.currency"), + SLC_VAR("units"), + SLC_VAR("locale.units_velocity"), + SLC_VAR("locale.units_power"), + SLC_VAR("locale.units_weight"), + SLC_VAR("locale.units_volume"), + SLC_VAR("locale.units_force"), + SLC_VAR("locale.units_height"), + SLC_VAR("locale.digit_group_separator"), + SLC_VAR("locale.digit_group_separator_currency"), + SLC_VAR("locale.digit_decimal_separator"), +}; + +#endif /* SAVELOAD_COMPAT_SETTINGS_H */ diff --git a/src/saveload/compat/signs_sl_compat.h b/src/saveload/compat/signs_sl_compat.h new file mode 100644 index 0000000000..80bc707893 --- /dev/null +++ b/src/saveload/compat/signs_sl_compat.h @@ -0,0 +1,24 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file signs_sl_compat.h Loading of signs chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_SIGNS_H +#define SAVELOAD_COMPAT_SIGNS_H + +#include "../saveload.h" + +/** Original field order for _sign_desc. */ +const SaveLoadCompat _sign_sl_compat[] = { + SLC_VAR("name"), + SLC_VAR("x"), + SLC_VAR("y"), + SLC_VAR("owner"), + SLC_VAR("z"), +}; + +#endif /* SAVELOAD_COMPAT_SIGNS_H */ diff --git a/src/saveload/compat/station_sl_compat.h b/src/saveload/compat/station_sl_compat.h new file mode 100644 index 0000000000..397e1660fb --- /dev/null +++ b/src/saveload/compat/station_sl_compat.h @@ -0,0 +1,29 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file station_sl_compat.h Loading of station chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_STATION_H +#define SAVELOAD_COMPAT_STATION_H + +#include "../saveload.h" + +/** Original field order for _roadstop_desc. */ +const SaveLoadCompat _roadstop_sl_compat[] = { + SLC_VAR("xy"), + SLC_NULL(1, SL_MIN_VERSION, SLV_45), + SLC_VAR("status"), + SLC_NULL(4, SL_MIN_VERSION, SLV_9), + SLC_NULL(2, SL_MIN_VERSION, SLV_45), + SLC_NULL(1, SL_MIN_VERSION, SLV_26), + SLC_VAR("next"), + SLC_NULL(2, SL_MIN_VERSION, SLV_45), + SLC_NULL(4, SL_MIN_VERSION, SLV_25), + SLC_NULL(1, SLV_25, SLV_26), +}; + +#endif /* SAVELOAD_COMPAT_STATION_H */ diff --git a/src/saveload/compat/storage_sl_compat.h b/src/saveload/compat/storage_sl_compat.h new file mode 100644 index 0000000000..f4f6d0d9a6 --- /dev/null +++ b/src/saveload/compat/storage_sl_compat.h @@ -0,0 +1,21 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file storage_sl_compat.h Loading of storage chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_STORAGE_H +#define SAVELOAD_COMPAT_STORAGE_H + +#include "../saveload.h" + +/** Original field order for _storage_desc. */ +const SaveLoadCompat _storage_sl_compat[] = { + SLC_VAR("grfid"), + SLC_VAR("storage"), +}; + +#endif /* SAVELOAD_COMPAT_STORAGE_H */ diff --git a/src/saveload/compat/story_sl_compat.h b/src/saveload/compat/story_sl_compat.h new file mode 100644 index 0000000000..519ca2bf18 --- /dev/null +++ b/src/saveload/compat/story_sl_compat.h @@ -0,0 +1,32 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file story_sl_compat.h Loading for story chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_STORE_H +#define SAVELOAD_COMPAT_STORE_H + +#include "../saveload.h" + +/** Original field order for _story_page_elements_desc. */ +const SaveLoadCompat _story_page_elements_sl_compat[] = { + SLC_VAR("sort_value"), + SLC_VAR("page"), + SLC_VAR("type"), + SLC_VAR("referenced_id"), + SLC_VAR("text"), +}; + +/** Original field order for _story_pages_desc. */ +const SaveLoadCompat _story_pages_sl_compat[] = { + SLC_VAR("sort_value"), + SLC_VAR("date"), + SLC_VAR("company"), + SLC_VAR("title"), +}; + +#endif /* SAVELOAD_COMPAT_STORE_H */ diff --git a/src/saveload/compat/subsidy_sl_compat.h b/src/saveload/compat/subsidy_sl_compat.h new file mode 100644 index 0000000000..7ae758318d --- /dev/null +++ b/src/saveload/compat/subsidy_sl_compat.h @@ -0,0 +1,26 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file subsidy_sl_compat.h Loading of subsidy chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_SUBSIDY_H +#define SAVELOAD_COMPAT_SUBSIDY_H + +#include "../saveload.h" + +/** Original field order for _subsidies_desc. */ +const SaveLoadCompat _subsidies_sl_compat[] = { + SLC_VAR("cargo_type"), + SLC_VAR("remaining"), + SLC_VAR("awarded"), + SLC_VAR("src_type"), + SLC_VAR("dst_type"), + SLC_VAR("src"), + SLC_VAR("dst"), +}; + +#endif /* SAVELOAD_COMPAT_SUBSIDY_H */ diff --git a/src/saveload/depot_sl.cpp b/src/saveload/depot_sl.cpp index 6af08e718d..c1252562a5 100644 --- a/src/saveload/depot_sl.cpp +++ b/src/saveload/depot_sl.cpp @@ -8,10 +8,12 @@ /** @file depot_sl.cpp Code handling saving and loading of depots */ #include "../stdafx.h" -#include "../depot_base.h" -#include "../town.h" #include "saveload.h" +#include "compat/depot_sl_compat.h" + +#include "../depot_base.h" +#include "../town.h" #include "../safeguards.h" @@ -29,6 +31,8 @@ static const SaveLoad _depot_desc[] = { static void Save_DEPT() { + SlTableHeader(_depot_desc); + for (Depot *depot : Depot::Iterate()) { SlSetArrayIndex(depot->index); SlObject(depot, _depot_desc); @@ -37,11 +41,13 @@ static void Save_DEPT() static void Load_DEPT() { + const std::vector slt = SlCompatTableHeader(_depot_desc, _depot_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { Depot *depot = new (index) Depot(); - SlObject(depot, _depot_desc); + SlObject(depot, slt); /* Set the town 'pointer' so we can restore it later. */ if (IsSavegameVersionBefore(SLV_141)) depot->town = (Town *)(size_t)_town_index; @@ -57,7 +63,7 @@ static void Ptrs_DEPT() } static const ChunkHandler depot_chunk_handlers[] = { - { 'DEPT', Save_DEPT, Load_DEPT, Ptrs_DEPT, nullptr, CH_ARRAY }, + { 'DEPT', Save_DEPT, Load_DEPT, Ptrs_DEPT, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _depot_chunk_handlers(depot_chunk_handlers); diff --git a/src/saveload/economy_sl.cpp b/src/saveload/economy_sl.cpp index d8624f5d66..4d7890b4b1 100644 --- a/src/saveload/economy_sl.cpp +++ b/src/saveload/economy_sl.cpp @@ -8,10 +8,12 @@ /** @file economy_sl.cpp Code handling saving and loading of economy data */ #include "../stdafx.h" -#include "../economy_func.h" -#include "../economy_base.h" #include "saveload.h" +#include "compat/economy_sl_compat.h" + +#include "../economy_func.h" +#include "../economy_base.h" #include "../safeguards.h" @@ -34,8 +36,6 @@ static void Load_CAPR() } static const SaveLoad _economy_desc[] = { - SLE_CONDNULL(4, SL_MIN_VERSION, SLV_65), // max_loan - SLE_CONDNULL(8, SLV_65, SLV_144), // max_loan SLE_CONDVAR(Economy, old_max_loan_unround, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), SLE_CONDVAR(Economy, old_max_loan_unround, SLE_INT64, SLV_65, SLV_126), SLE_CONDVAR(Economy, old_max_loan_unround_fract, SLE_UINT16, SLV_70, SLV_126), @@ -51,6 +51,8 @@ static const SaveLoad _economy_desc[] = { /** Economy variables */ static void Save_ECMY() { + SlTableHeader(_economy_desc); + SlSetArrayIndex(0); SlObject(&_economy, _economy_desc); } @@ -58,8 +60,10 @@ static void Save_ECMY() /** Economy variables */ static void Load_ECMY() { + const std::vector slt = SlCompatTableHeader(_economy_desc, _economy_sl_compat); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlObject(&_economy, _economy_desc); + SlObject(&_economy, slt); if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many ECMY entries"); StartupIndustryDailyChanges(IsSavegameVersionBefore(SLV_102)); // old savegames will need to be initialized @@ -74,6 +78,8 @@ static const SaveLoad _cargopayment_desc[] = { static void Save_CAPY() { + SlTableHeader(_cargopayment_desc); + for (CargoPayment *cp : CargoPayment::Iterate()) { SlSetArrayIndex(cp->index); SlObject(cp, _cargopayment_desc); @@ -82,11 +88,13 @@ static void Save_CAPY() static void Load_CAPY() { + const std::vector slt = SlCompatTableHeader(_cargopayment_desc, _cargopayment_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { CargoPayment *cp = new (index) CargoPayment(); - SlObject(cp, _cargopayment_desc); + SlObject(cp, slt); } } @@ -99,10 +107,10 @@ static void Ptrs_CAPY() static const ChunkHandler economy_chunk_handlers[] = { - { 'CAPY', Save_CAPY, Load_CAPY, Ptrs_CAPY, nullptr, CH_ARRAY }, + { 'CAPY', Save_CAPY, Load_CAPY, Ptrs_CAPY, nullptr, CH_TABLE }, { 'PRIC', nullptr, Load_PRIC, nullptr, nullptr, CH_READONLY }, { 'CAPR', nullptr, Load_CAPR, nullptr, nullptr, CH_READONLY }, - { 'ECMY', Save_ECMY, Load_ECMY, nullptr, nullptr, CH_ARRAY }, + { 'ECMY', Save_ECMY, Load_ECMY, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _economy_chunk_handlers(economy_chunk_handlers); diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp index 12670449e8..109d90434d 100644 --- a/src/saveload/engine_sl.cpp +++ b/src/saveload/engine_sl.cpp @@ -8,6 +8,10 @@ /** @file engine_sl.cpp Code handling saving and loading of engines */ #include "../stdafx.h" + +#include "saveload.h" +#include "compat/engine_sl_compat.h" + #include "saveload_internal.h" #include "../engine_base.h" #include "../string_func.h" @@ -28,20 +32,14 @@ static const SaveLoad _engine_desc[] = { SLE_VAR(Engine, duration_phase_1, SLE_UINT16), SLE_VAR(Engine, duration_phase_2, SLE_UINT16), SLE_VAR(Engine, duration_phase_3, SLE_UINT16), - - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_121), SLE_VAR(Engine, flags, SLE_UINT8), - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_179), // old preview_company_rank SLE_CONDVAR(Engine, preview_asked, SLE_UINT16, SLV_179, SL_MAX_VERSION), SLE_CONDVAR(Engine, preview_company, SLE_UINT8, SLV_179, SL_MAX_VERSION), SLE_VAR(Engine, preview_wait, SLE_UINT8), - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_45), SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), SLE_CONDVAR(Engine, company_avail, SLE_UINT16, SLV_104, SL_MAX_VERSION), SLE_CONDVAR(Engine, company_hidden, SLE_UINT16, SLV_193, SL_MAX_VERSION), SLE_CONDSSTR(Engine, name, SLE_STR, SLV_84, SL_MAX_VERSION), - - SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space }; static std::vector _temp_engine; @@ -84,6 +82,8 @@ Engine *GetTempDataEngine(EngineID index) static void Save_ENGN() { + SlTableHeader(_engine_desc); + for (Engine *e : Engine::Iterate()) { SlSetArrayIndex(e->index); SlObject(e, _engine_desc); @@ -92,13 +92,15 @@ static void Save_ENGN() static void Load_ENGN() { + const std::vector slt = SlCompatTableHeader(_engine_desc, _engine_sl_compat); + /* As engine data is loaded before engines are initialized we need to load * this information into a temporary array. This is then copied into the * engine pool after processing NewGRFs by CopyTempEngineData(). */ int index; while ((index = SlIterateArray()) != -1) { Engine *e = GetTempDataEngine(index); - SlObject(e, _engine_desc); + SlObject(e, slt); if (IsSavegameVersionBefore(SLV_179)) { /* preview_company_rank was replaced with preview_company and preview_asked. @@ -175,6 +177,8 @@ static const SaveLoad _engine_id_mapping_desc[] = { static void Save_EIDS() { + SlTableHeader(_engine_id_mapping_desc); + uint index = 0; for (EngineIDMapping &eid : _engine_mngr) { SlSetArrayIndex(index); @@ -185,17 +189,19 @@ static void Save_EIDS() static void Load_EIDS() { + const std::vector slt = SlCompatTableHeader(_engine_id_mapping_desc, _engine_id_mapping_sl_compat); + _engine_mngr.clear(); while (SlIterateArray() != -1) { EngineIDMapping *eid = &_engine_mngr.emplace_back(); - SlObject(eid, _engine_id_mapping_desc); + SlObject(eid, slt); } } static const ChunkHandler engine_chunk_handlers[] = { - { 'EIDS', Save_EIDS, Load_EIDS, nullptr, nullptr, CH_ARRAY }, - { 'ENGN', Save_ENGN, Load_ENGN, nullptr, nullptr, CH_ARRAY }, + { 'EIDS', Save_EIDS, Load_EIDS, nullptr, nullptr, CH_TABLE }, + { 'ENGN', Save_ENGN, Load_ENGN, nullptr, nullptr, CH_TABLE }, { 'ENGS', nullptr, Load_ENGS, nullptr, nullptr, CH_READONLY }, }; diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index 1ef513c635..059e173336 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -9,9 +9,11 @@ #include "../stdafx.h" #include "../debug.h" -#include "saveload.h" -#include "../string_func.h" +#include "saveload.h" +#include "compat/game_sl_compat.h" + +#include "../string_func.h" #include "../game/game.hpp" #include "../game/game_config.hpp" #include "../network/network.h" @@ -25,7 +27,7 @@ static int _game_saveload_version; static std::string _game_saveload_settings; static bool _game_saveload_is_random; -static const SaveLoad _game_script[] = { +static const SaveLoad _game_script_desc[] = { SLEG_SSTR("name", _game_saveload_name, SLE_STR), SLEG_SSTR("settings", _game_saveload_settings, SLE_STR), SLEG_VAR("version", _game_saveload_version, SLE_UINT32), @@ -48,19 +50,21 @@ static void SaveReal_GSDT(int *index_ptr) _game_saveload_is_random = config->IsRandom(); _game_saveload_settings = config->SettingsToString(); - SlObject(nullptr, _game_script); + SlObject(nullptr, _game_script_desc); Game::Save(); } static void Load_GSDT() { + const std::vector slt = SlCompatTableHeader(_game_script_desc, _game_script_sl_compat); + /* Free all current data */ GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME)->Change(nullptr); if (SlIterateArray() == -1) return; _game_saveload_version = -1; - SlObject(nullptr, _game_script); + SlObject(nullptr, slt); if (_networking && !_network_server) { GameInstance::LoadEmpty(); @@ -104,6 +108,7 @@ static void Load_GSDT() static void Save_GSDT() { + SlTableHeader(_game_script_desc); SlSetArrayIndex(0); SlAutolength((AutolengthProc *)SaveReal_GSDT, nullptr); } @@ -180,7 +185,7 @@ static void Save_GSTR() static const ChunkHandler game_chunk_handlers[] = { { 'GSTR', Save_GSTR, Load_GSTR, nullptr, nullptr, CH_ARRAY }, - { 'GSDT', Save_GSDT, Load_GSDT, nullptr, nullptr, CH_ARRAY }, + { 'GSDT', Save_GSDT, Load_GSDT, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _game_chunk_handlers(game_chunk_handlers); diff --git a/src/saveload/goal_sl.cpp b/src/saveload/goal_sl.cpp index 2f66797594..68ba3597a2 100644 --- a/src/saveload/goal_sl.cpp +++ b/src/saveload/goal_sl.cpp @@ -8,9 +8,11 @@ /** @file goal_sl.cpp Code handling saving and loading of goals */ #include "../stdafx.h" -#include "../goal_base.h" #include "saveload.h" +#include "compat/goal_sl_compat.h" + +#include "../goal_base.h" #include "../safeguards.h" @@ -25,6 +27,8 @@ static const SaveLoad _goals_desc[] = { static void Save_GOAL() { + SlTableHeader(_goals_desc); + for (Goal *s : Goal::Iterate()) { SlSetArrayIndex(s->index); SlObject(s, _goals_desc); @@ -33,6 +37,8 @@ static void Save_GOAL() static void Load_GOAL() { + const std::vector slt = SlCompatTableHeader(_goals_desc, _goals_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { Goal *s = new (index) Goal(); @@ -41,7 +47,7 @@ static void Load_GOAL() } static const ChunkHandler goal_chunk_handlers[] = { - { 'GOAL', Save_GOAL, Load_GOAL, nullptr, nullptr, CH_ARRAY }, + { 'GOAL', Save_GOAL, Load_GOAL, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _goal_chunk_handlers(goal_chunk_handlers); diff --git a/src/saveload/group_sl.cpp b/src/saveload/group_sl.cpp index f41091611c..77ab23bd86 100644 --- a/src/saveload/group_sl.cpp +++ b/src/saveload/group_sl.cpp @@ -12,13 +12,13 @@ #include "../company_base.h" #include "saveload.h" +#include "compat/group_sl_compat.h" #include "../safeguards.h" static const SaveLoad _group_desc[] = { SLE_CONDVAR(Group, name, SLE_NAME, SL_MIN_VERSION, SLV_84), SLE_CONDSSTR(Group, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_164), // num_vehicle SLE_VAR(Group, owner, SLE_UINT8), SLE_VAR(Group, vehicle_type, SLE_UINT8), SLE_VAR(Group, flags, SLE_UINT8), @@ -30,6 +30,8 @@ static const SaveLoad _group_desc[] = { static void Save_GRPS() { + SlTableHeader(_group_desc); + for (Group *g : Group::Iterate()) { SlSetArrayIndex(g->index); SlObject(g, _group_desc); @@ -39,24 +41,26 @@ static void Save_GRPS() static void Load_GRPS() { + const std::vector slt = SlCompatTableHeader(_group_desc, _group_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { Group *g = new (index) Group(); - SlObject(g, _group_desc); + SlObject(g, slt); if (IsSavegameVersionBefore(SLV_189)) g->parent = INVALID_GROUP; if (IsSavegameVersionBefore(SLV_GROUP_LIVERIES)) { - const Company *c = Company::Get(g->owner); - g->livery.colour1 = c->livery[LS_DEFAULT].colour1; - g->livery.colour2 = c->livery[LS_DEFAULT].colour2; + const Company *c = Company::Get(g->owner); + g->livery.colour1 = c->livery[LS_DEFAULT].colour1; + g->livery.colour2 = c->livery[LS_DEFAULT].colour2; } } } static const ChunkHandler group_chunk_handlers[] = { - { 'GRPS', Save_GRPS, Load_GRPS, nullptr, nullptr, CH_ARRAY }, + { 'GRPS', Save_GRPS, Load_GRPS, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _group_chunk_handlers(group_chunk_handlers); diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index 139a5c1afb..1be1ad2195 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -8,9 +8,11 @@ /** @file industry_sl.cpp Code handling saving and loading of industries */ #include "../stdafx.h" -#include "../industry.h" #include "saveload.h" +#include "compat/industry_sl_compat.h" + +#include "../industry.h" #include "newgrf_sl.h" #include "../safeguards.h" @@ -24,7 +26,6 @@ static const SaveLoad _industry_desc[] = { SLE_VAR(Industry, location.h, SLE_FILE_U8 | SLE_VAR_U16), SLE_REF(Industry, town, REF_TOWN), SLE_CONDREF(Industry, neutral_station, REF_STATION, SLV_SERVE_NEUTRAL_INDUSTRIES, SL_MAX_VERSION), - SLE_CONDNULL( 2, SL_MIN_VERSION, SLV_61), ///< used to be industry's produced_cargo SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, SLV_78, SLV_EXTEND_INDUSTRY_CARGO_SLOTS), SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION), SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, SLV_70, SLV_EXTEND_INDUSTRY_CARGO_SLOTS), @@ -33,7 +34,6 @@ static const SaveLoad _industry_desc[] = { SLE_CONDARR(Industry, produced_cargo_waiting, SLE_UINT16, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION), SLE_CONDARR(Industry, production_rate, SLE_UINT8, 2, SL_MIN_VERSION, SLV_EXTEND_INDUSTRY_CARGO_SLOTS), SLE_CONDARR(Industry, production_rate, SLE_UINT8, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION), - SLE_CONDNULL( 3, SL_MIN_VERSION, SLV_61), ///< used to be industry's accepts_cargo SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 3, SLV_78, SLV_EXTEND_INDUSTRY_CARGO_SLOTS), SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION), SLE_VAR(Industry, prod_level, SLE_UINT8), @@ -70,15 +70,14 @@ static const SaveLoad _industry_desc[] = { SLEG_CONDARR("storage", _old_ind_persistent_storage.storage, SLE_UINT32, 16, SLV_76, SLV_161), SLE_CONDREF(Industry, psa, REF_STORAGE, SLV_161, SL_MAX_VERSION), - SLE_CONDNULL(1, SLV_82, SLV_197), // random_triggers SLE_CONDVAR(Industry, random, SLE_UINT16, SLV_82, SL_MAX_VERSION), SLE_CONDSSTR(Industry, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_INDUSTRY_TEXT, SL_MAX_VERSION), - - SLE_CONDNULL(32, SLV_2, SLV_144), // old reserved space }; static void Save_INDY() { + SlTableHeader(_industry_desc); + /* Write the industries */ for (Industry *ind : Industry::Iterate()) { SlSetArrayIndex(ind->index); @@ -98,13 +97,15 @@ static void Save_TIDS() static void Load_INDY() { + const std::vector slt = SlCompatTableHeader(_industry_desc, _industry_sl_compat); + int index; Industry::ResetIndustryCounts(); while ((index = SlIterateArray()) != -1) { Industry *i = new (index) Industry(); - SlObject(i, _industry_desc); + SlObject(i, slt); /* Before savegame version 161, persistent storages were not stored in a pool. */ if (IsSavegameVersionBefore(SLV_161) && !IsSavegameVersionBefore(SLV_76)) { @@ -142,6 +143,8 @@ static const SaveLoad _industry_builder_desc[] = { /** Save industry builder. */ static void Save_IBLD() { + SlTableHeader(_industry_builder_desc); + SlSetArrayIndex(0); SlGlobList(_industry_builder_desc); } @@ -149,8 +152,10 @@ static void Save_IBLD() /** Load industry builder. */ static void Load_IBLD() { + const std::vector slt = SlCompatTableHeader(_industry_builder_desc, _industry_builder_sl_compat); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlGlobList(_industry_builder_desc); + SlGlobList(slt); if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many IBLD entries"); } @@ -166,6 +171,8 @@ static const SaveLoad _industrytype_builder_desc[] = { /** Save industry-type build data. */ static void Save_ITBL() { + SlTableHeader(_industrytype_builder_desc); + for (int i = 0; i < NUM_INDUSTRYTYPES; i++) { SlSetArrayIndex(i); SlObject(_industry_builder.builddata + i, _industrytype_builder_desc); @@ -175,22 +182,24 @@ static void Save_ITBL() /** Load industry-type build data. */ static void Load_ITBL() { + const std::vector slt = SlCompatTableHeader(_industrytype_builder_desc, _industrytype_builder_sl_compat); + for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) { _industry_builder.builddata[it].Reset(); } int index; while ((index = SlIterateArray()) != -1) { if ((uint)index >= NUM_INDUSTRYTYPES) SlErrorCorrupt("Too many industry builder datas"); - SlObject(_industry_builder.builddata + index, _industrytype_builder_desc); + SlObject(_industry_builder.builddata + index, slt); } } static const ChunkHandler industry_chunk_handlers[] = { - { 'INDY', Save_INDY, Load_INDY, Ptrs_INDY, nullptr, CH_ARRAY }, - { 'IIDS', Save_IIDS, Load_IIDS, nullptr, nullptr, CH_ARRAY }, - { 'TIDS', Save_TIDS, Load_TIDS, nullptr, nullptr, CH_ARRAY }, - { 'IBLD', Save_IBLD, Load_IBLD, nullptr, nullptr, CH_ARRAY }, - { 'ITBL', Save_ITBL, Load_ITBL, nullptr, nullptr, CH_ARRAY }, + { 'INDY', Save_INDY, Load_INDY, Ptrs_INDY, nullptr, CH_TABLE }, + { 'IIDS', Save_IIDS, Load_IIDS, nullptr, nullptr, CH_TABLE }, + { 'TIDS', Save_TIDS, Load_TIDS, nullptr, nullptr, CH_TABLE }, + { 'IBLD', Save_IBLD, Load_IBLD, nullptr, nullptr, CH_TABLE }, + { 'ITBL', Save_ITBL, Load_ITBL, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _industry_chunk_handlers(industry_chunk_handlers); diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp index 5a7d6fae98..6b8509b53e 100644 --- a/src/saveload/labelmaps_sl.cpp +++ b/src/saveload/labelmaps_sl.cpp @@ -8,11 +8,13 @@ /** @file labelmaps_sl.cpp Code handling saving and loading of rail type label mappings */ #include "../stdafx.h" -#include "../station_map.h" -#include "../tunnelbridge_map.h" #include "saveload.h" +#include "compat/labelmaps_sl_compat.h" + #include "saveload_internal.h" +#include "../station_map.h" +#include "../tunnelbridge_map.h" #include "../safeguards.h" @@ -99,6 +101,8 @@ static const SaveLoad _label_object_desc[] = { static void Save_RAIL() { + SlTableHeader(_label_object_desc); + LabelObject lo; for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { @@ -111,18 +115,20 @@ static void Save_RAIL() static void Load_RAIL() { + const std::vector slt = SlCompatTableHeader(_label_object_desc, _label_object_sl_compat); + ResetLabelMaps(); LabelObject lo; while (SlIterateArray() != -1) { - SlObject(&lo, _label_object_desc); + SlObject(&lo, slt); _railtype_list.push_back((RailTypeLabel)lo.label); } } static const ChunkHandler labelmaps_chunk_handlers[] = { - { 'RAIL', Save_RAIL, Load_RAIL, nullptr, nullptr, CH_ARRAY }, + { 'RAIL', Save_RAIL, Load_RAIL, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _labelmaps_chunk_handlers(labelmaps_chunk_handlers); diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index 476a9a89ab..e55ac665aa 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -8,13 +8,15 @@ /** @file map_sl.cpp Code handling saving and loading of map */ #include "../stdafx.h" + +#include "saveload.h" +#include "compat/map_sl_compat.h" + #include "../map_func.h" #include "../core/bitmath_func.hpp" #include "../fios.h" #include -#include "saveload.h" - #include "../safeguards.h" static uint32 _map_dim_x; @@ -27,6 +29,8 @@ static const SaveLoad _map_desc[] = { static void Save_MAPS() { + SlTableHeader(_map_desc); + _map_dim_x = MapSizeX(); _map_dim_y = MapSizeY(); @@ -36,8 +40,10 @@ static void Save_MAPS() static void Load_MAPS() { + const std::vector slt = SlCompatTableHeader(_map_desc, _map_sl_compat); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlGlobList(_map_desc); + SlGlobList(slt); if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many MAPS entries"); AllocateMap(_map_dim_x, _map_dim_y); @@ -45,8 +51,10 @@ static void Load_MAPS() static void Check_MAPS() { + const std::vector slt = SlCompatTableHeader(_map_desc, _map_sl_compat); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlGlobList(_map_desc); + SlGlobList(slt); if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many MAPS entries"); _load_check_data.map_size_x = _map_dim_x; @@ -303,7 +311,7 @@ static void Save_MAP8() static const ChunkHandler map_chunk_handlers[] = { - { 'MAPS', Save_MAPS, Load_MAPS, nullptr, Check_MAPS, CH_ARRAY }, + { 'MAPS', Save_MAPS, Load_MAPS, nullptr, Check_MAPS, CH_TABLE }, { 'MAPT', Save_MAPT, Load_MAPT, nullptr, nullptr, CH_RIFF }, { 'MAPH', Save_MAPH, Load_MAPH, nullptr, nullptr, CH_RIFF }, { 'MAPO', Save_MAP1, Load_MAP1, nullptr, nullptr, CH_RIFF }, diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index eb227e3363..35b59a0212 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -8,6 +8,10 @@ /** @file misc_sl.cpp Saving and loading of things that didn't fit anywhere else */ #include "../stdafx.h" + +#include "saveload.h" +#include "compat/misc_sl_compat.h" + #include "../date_func.h" #include "../zoom_func.h" #include "../window_gui.h" @@ -17,8 +21,6 @@ #include "../core/random_func.hpp" #include "../fios.h" -#include "saveload.h" - #include "../safeguards.h" extern TileIndex _cur_tileloop_tile; @@ -72,73 +74,52 @@ static const SaveLoad _date_desc[] = { SLEG_CONDVAR("date", _date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), SLEG_CONDVAR("date", _date, SLE_INT32, SLV_31, SL_MAX_VERSION), SLEG_VAR("date_fract", _date_fract, SLE_UINT16), - SLEG_VAR("tick_counter", _tick_counter, SLE_UINT16), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_157), // _vehicle_id_ctr_day + SLEG_VAR("tick_counter", _tick_counter, SLE_UINT16), SLEG_CONDVAR("age_cargo_skip_counter", _age_cargo_skip_counter, SLE_UINT8, SL_MIN_VERSION, SLV_162), - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_46), SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLEG_VAR("next_disaster_start", _disaster_delay, SLE_UINT16), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_120), + SLEG_VAR("next_disaster_start", _disaster_delay, SLE_UINT16), SLEG_VAR("random_state[0]", _random.state[0], SLE_UINT32), SLEG_VAR("random_state[1]", _random.state[1], SLE_UINT32), - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_10), - SLE_CONDNULL(4, SLV_10, SLV_120), - SLEG_VAR("company_tick_counter", _cur_company_tick_index, SLE_FILE_U8 | SLE_VAR_U32), + SLEG_VAR("company_tick_counter", _cur_company_tick_index, SLE_FILE_U8 | SLE_VAR_U32), SLEG_CONDVAR("next_competitor_start", _next_competitor_start, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_109), SLEG_CONDVAR("next_competitor_start", _next_competitor_start, SLE_UINT32, SLV_109, SL_MAX_VERSION), SLEG_VAR("trees_tick_counter", _trees_tick_ctr, SLE_UINT8), SLEG_CONDVAR("pause_mode", _pause_mode, SLE_UINT8, SLV_4, SL_MAX_VERSION), - SLE_CONDNULL(4, SLV_11, SLV_120), }; static const SaveLoad _date_check_desc[] = { SLEG_CONDVAR("date", _load_check_data.current_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), SLEG_CONDVAR("date", _load_check_data.current_date, SLE_INT32, SLV_31, SL_MAX_VERSION), - SLE_NULL(2), // _date_fract - SLE_NULL(2), // _tick_counter - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_157), // _vehicle_id_ctr_day - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_162), // _age_cargo_skip_counter - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_46), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), // _cur_tileloop_tile - SLE_CONDNULL(4, SLV_6, SL_MAX_VERSION), // _cur_tileloop_tile - SLE_NULL(2), // _disaster_delay - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_120), - SLE_NULL(4), // _random.state[0] - SLE_NULL(4), // _random.state[1] - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_10), - SLE_CONDNULL(4, SLV_10, SLV_120), - SLE_NULL(1), // _cur_company_tick_index - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_109), // _next_competitor_start - SLE_CONDNULL(4, SLV_109, SL_MAX_VERSION), // _next_competitor_start - SLE_NULL(1), // _trees_tick_ctr - SLE_CONDNULL(1, SLV_4, SL_MAX_VERSION), // _pause_mode - SLE_CONDNULL(4, SLV_11, SLV_120), }; /* Save load date related variables as well as persistent tick counters * XXX: currently some unrelated stuff is just put here */ static void Save_DATE() { + SlTableHeader(_date_desc); + SlSetArrayIndex(0); SlGlobList(_date_desc); } -static void Load_DATE_common(const SaveLoadTable &slt) +static void Load_DATE_common(const SaveLoadTable &slt, const SaveLoadCompatTable &slct) { + const std::vector oslt = SlCompatTableHeader(slt, slct); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlGlobList(slt); + SlGlobList(oslt); if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many DATE entries"); } static void Load_DATE() { - Load_DATE_common(_date_desc); + Load_DATE_common(_date_desc, _date_sl_compat); } static void Check_DATE() { - Load_DATE_common(_date_check_desc); + Load_DATE_common(_date_check_desc, _date_check_sl_compat); if (IsSavegameVersionBefore(SLV_31)) { _load_check_data.current_date += DAYS_TILL_ORIGINAL_BASE_YEAR; @@ -156,20 +137,24 @@ static const SaveLoad _view_desc[] = { static void Save_VIEW() { + SlTableHeader(_view_desc); + SlSetArrayIndex(0); SlGlobList(_view_desc); } static void Load_VIEW() { + const std::vector slt = SlCompatTableHeader(_view_desc, _view_sl_compat); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlGlobList(_view_desc); + SlGlobList(slt); if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many DATE entries"); } static const ChunkHandler misc_chunk_handlers[] = { - { 'DATE', Save_DATE, Load_DATE, nullptr, Check_DATE, CH_ARRAY }, - { 'VIEW', Save_VIEW, Load_VIEW, nullptr, nullptr, CH_ARRAY }, + { 'DATE', Save_DATE, Load_DATE, nullptr, Check_DATE, CH_TABLE }, + { 'VIEW', Save_VIEW, Load_VIEW, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _misc_chunk_handlers(misc_chunk_handlers); diff --git a/src/saveload/newgrf_sl.cpp b/src/saveload/newgrf_sl.cpp index f92da0db31..20b6585622 100644 --- a/src/saveload/newgrf_sl.cpp +++ b/src/saveload/newgrf_sl.cpp @@ -8,10 +8,12 @@ /** @file newgrf_sl.cpp Code handling saving and loading of newgrf config */ #include "../stdafx.h" -#include "../fios.h" #include "saveload.h" +#include "compat/newgrf_sl_compat.h" + #include "newgrf_sl.h" +#include "../fios.h" #include "../safeguards.h" @@ -28,6 +30,8 @@ static const SaveLoad _newgrf_mapping_desc[] = { */ void Save_NewGRFMapping(const OverrideManagerBase &mapping) { + SlTableHeader(_newgrf_mapping_desc); + for (uint i = 0; i < mapping.GetMaxMapping(); i++) { if (mapping.mapping_ID[i].grfid == 0 && mapping.mapping_ID[i].entity_id == 0) continue; @@ -42,6 +46,8 @@ void Save_NewGRFMapping(const OverrideManagerBase &mapping) */ void Load_NewGRFMapping(OverrideManagerBase &mapping) { + const std::vector slt = SlCompatTableHeader(_newgrf_mapping_desc, _newgrf_mapping_sl_compat); + /* Clear the current mapping stored. * This will create the manager if ever it is not yet done */ mapping.ResetMapping(); @@ -51,7 +57,7 @@ void Load_NewGRFMapping(OverrideManagerBase &mapping) int index; while ((index = SlIterateArray()) != -1) { if ((uint)index >= max_id) SlErrorCorrupt("Too many NewGRF entity mappings"); - SlObject(&mapping.mapping_ID[index], _newgrf_mapping_desc); + SlObject(&mapping.mapping_ID[index], slt); } } @@ -69,6 +75,8 @@ static const SaveLoad _grfconfig_desc[] = { static void Save_NGRF() { + SlTableHeader(_grfconfig_desc); + int index = 0; for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { @@ -81,10 +89,12 @@ static void Save_NGRF() static void Load_NGRF_common(GRFConfig *&grfconfig) { + const std::vector slt = SlCompatTableHeader(_grfconfig_desc, _grfconfig_sl_compat); + ClearGRFConfigList(&grfconfig); while (SlIterateArray() != -1) { GRFConfig *c = new GRFConfig(); - SlObject(c, _grfconfig_desc); + SlObject(c, slt); if (IsSavegameVersionBefore(SLV_101)) c->SetSuitablePalette(); AppendToGRFConfigList(&grfconfig, c); } @@ -112,7 +122,7 @@ static void Check_NGRF() } static const ChunkHandler newgrf_chunk_handlers[] = { - { 'NGRF', Save_NGRF, Load_NGRF, nullptr, Check_NGRF, CH_ARRAY } + { 'NGRF', Save_NGRF, Load_NGRF, nullptr, Check_NGRF, CH_TABLE } }; extern const ChunkHandlerTable _newgrf_chunk_handlers(newgrf_chunk_handlers); diff --git a/src/saveload/object_sl.cpp b/src/saveload/object_sl.cpp index dcf5fd65cb..57e34af3a4 100644 --- a/src/saveload/object_sl.cpp +++ b/src/saveload/object_sl.cpp @@ -8,10 +8,12 @@ /** @file object_sl.cpp Code handling saving and loading of objects */ #include "../stdafx.h" -#include "../object_base.h" -#include "../object_map.h" #include "saveload.h" +#include "compat/object_sl_compat.h" + +#include "../object_base.h" +#include "../object_map.h" #include "newgrf_sl.h" #include "../safeguards.h" @@ -29,6 +31,8 @@ static const SaveLoad _object_desc[] = { static void Save_OBJS() { + SlTableHeader(_object_desc); + /* Write the objects */ for (Object *o : Object::Iterate()) { SlSetArrayIndex(o->index); @@ -38,10 +42,12 @@ static void Save_OBJS() static void Load_OBJS() { + const std::vector slt = SlCompatTableHeader(_object_desc, _object_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { Object *o = new (index) Object(); - SlObject(o, _object_desc); + SlObject(o, slt); } } @@ -67,8 +73,8 @@ static void Load_OBID() } static const ChunkHandler object_chunk_handlers[] = { - { 'OBID', Save_OBID, Load_OBID, nullptr, nullptr, CH_ARRAY }, - { 'OBJS', Save_OBJS, Load_OBJS, Ptrs_OBJS, nullptr, CH_ARRAY }, + { 'OBID', Save_OBID, Load_OBID, nullptr, nullptr, CH_TABLE }, + { 'OBJS', Save_OBJS, Load_OBJS, Ptrs_OBJS, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _object_chunk_handlers(object_chunk_handlers); diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index 81e485606e..4d9bf3d8f9 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -8,12 +8,15 @@ /** @file order_sl.cpp Code handling saving and loading of orders */ #include "../stdafx.h" + +#include "saveload.h" +#include "compat/order_sl_compat.h" + +#include "saveload_internal.h" #include "../order_backup.h" #include "../settings_type.h" #include "../network/network.h" -#include "saveload_internal.h" - #include "../safeguards.h" /** @@ -107,14 +110,9 @@ SaveLoadTable GetOrderDescription() SLE_VAR(Order, dest, SLE_UINT16), SLE_REF(Order, next, REF_ORDER), SLE_CONDVAR(Order, refit_cargo, SLE_UINT8, SLV_36, SL_MAX_VERSION), - SLE_CONDNULL(1, SLV_36, SLV_182), // refit_subtype SLE_CONDVAR(Order, wait_time, SLE_UINT16, SLV_67, SL_MAX_VERSION), SLE_CONDVAR(Order, travel_time, SLE_UINT16, SLV_67, SL_MAX_VERSION), SLE_CONDVAR(Order, max_speed, SLE_UINT16, SLV_172, SL_MAX_VERSION), - - /* Leftover from the minor savegame version stuff - * We will never use those free bytes, but we have to keep this line to allow loading of old savegames */ - SLE_CONDNULL(10, SLV_5, SLV_36), }; return _order_desc; @@ -122,9 +120,12 @@ SaveLoadTable GetOrderDescription() static void Save_ORDR() { + const SaveLoadTable slt = GetOrderDescription(); + SlTableHeader(slt); + for (Order *order : Order::Iterate()) { SlSetArrayIndex(order->index); - SlObject(order, GetOrderDescription()); + SlObject(order, slt); } } @@ -176,11 +177,13 @@ static void Load_ORDR() if (prev != nullptr) prev->next = o; } } else { + const std::vector slt = SlCompatTableHeader(GetOrderDescription(), _order_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { Order *order = new (index) Order(); - SlObject(order, GetOrderDescription()); + SlObject(order, slt); } } } @@ -206,20 +209,25 @@ SaveLoadTable GetOrderListDescription() static void Save_ORDL() { + const SaveLoadTable slt = GetOrderListDescription(); + SlTableHeader(slt); + for (OrderList *list : OrderList::Iterate()) { SlSetArrayIndex(list->index); - SlObject(list, GetOrderListDescription()); + SlObject(list, slt); } } static void Load_ORDL() { + const std::vector slt = SlCompatTableHeader(GetOrderListDescription(), _orderlist_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { /* set num_orders to 0 so it's a valid OrderList */ OrderList *list = new (index) OrderList(0); - SlObject(list, GetOrderListDescription()); + SlObject(list, slt); } } @@ -240,7 +248,6 @@ SaveLoadTable GetOrderBackupDescription() SLE_CONDVAR(OrderBackup, service_interval, SLE_FILE_U32 | SLE_VAR_U16, SL_MIN_VERSION, SLV_192), SLE_CONDVAR(OrderBackup, service_interval, SLE_UINT16, SLV_192, SL_MAX_VERSION), SLE_SSTR(OrderBackup, name, SLE_STR), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_192), // clone (2 bytes of pointer, i.e. garbage) SLE_CONDREF(OrderBackup, clone, REF_VEHICLE, SLV_192, SL_MAX_VERSION), SLE_VAR(OrderBackup, cur_real_order_index, SLE_UINT8), SLE_CONDVAR(OrderBackup, cur_implicit_order_index, SLE_UINT8, SLV_176, SL_MAX_VERSION), @@ -257,6 +264,9 @@ SaveLoadTable GetOrderBackupDescription() static void Save_BKOR() { + const SaveLoadTable slt = GetOrderBackupDescription(); + SlTableHeader(slt); + /* We only save this when we're a network server * as we want this information on our clients. For * normal games this information isn't needed. */ @@ -264,18 +274,20 @@ static void Save_BKOR() for (OrderBackup *ob : OrderBackup::Iterate()) { SlSetArrayIndex(ob->index); - SlObject(ob, GetOrderBackupDescription()); + SlObject(ob, slt); } } void Load_BKOR() { + const std::vector slt = SlCompatTableHeader(GetOrderBackupDescription(), _order_backup_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { /* set num_orders to 0 so it's a valid OrderList */ OrderBackup *ob = new (index) OrderBackup(); - SlObject(ob, GetOrderBackupDescription()); + SlObject(ob, slt); } } @@ -287,9 +299,9 @@ static void Ptrs_BKOR() } static const ChunkHandler order_chunk_handlers[] = { - { 'BKOR', Save_BKOR, Load_BKOR, Ptrs_BKOR, nullptr, CH_ARRAY }, - { 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, nullptr, CH_ARRAY }, - { 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, nullptr, CH_ARRAY }, + { 'BKOR', Save_BKOR, Load_BKOR, Ptrs_BKOR, nullptr, CH_TABLE }, + { 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, nullptr, CH_TABLE }, + { 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _order_chunk_handlers(order_chunk_handlers); diff --git a/src/saveload/signs_sl.cpp b/src/saveload/signs_sl.cpp index 388a92af92..4479ff63d6 100644 --- a/src/saveload/signs_sl.cpp +++ b/src/saveload/signs_sl.cpp @@ -8,10 +8,12 @@ /** @file signs_sl.cpp Code handling saving and loading of economy data */ #include "../stdafx.h" -#include "../signs_base.h" -#include "../fios.h" #include "saveload.h" +#include "compat/signs_sl_compat.h" + +#include "../signs_base.h" +#include "../fios.h" #include "../safeguards.h" @@ -31,6 +33,8 @@ static const SaveLoad _sign_desc[] = { /** Save all signs */ static void Save_SIGN() { + SlTableHeader(_sign_desc); + for (Sign *si : Sign::Iterate()) { SlSetArrayIndex(si->index); SlObject(si, _sign_desc); @@ -40,10 +44,12 @@ static void Save_SIGN() /** Load all signs */ static void Load_SIGN() { + const std::vector slt = SlCompatTableHeader(_sign_desc, _sign_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { Sign *si = new (index) Sign(); - SlObject(si, _sign_desc); + SlObject(si, slt); /* Before version 6.1, signs didn't have owner. * Before version 83, invalid signs were determined by si->str == 0. * Before version 103, owner could be a bankrupted company. @@ -61,9 +67,8 @@ static void Load_SIGN() } } -/** Chunk handlers related to signs. */ static const ChunkHandler sign_chunk_handlers[] = { - { 'SIGN', Save_SIGN, Load_SIGN, nullptr, nullptr, CH_ARRAY }, + { 'SIGN', Save_SIGN, Load_SIGN, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _sign_chunk_handlers(sign_chunk_handlers); diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 5b99b09f7d..ebf2c94f4e 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -8,13 +8,16 @@ /** @file station_sl.cpp Code handling saving and loading of stations. */ #include "../stdafx.h" + +#include "saveload.h" +#include "compat/station_sl_compat.h" + #include "../station_base.h" #include "../waypoint_base.h" #include "../roadstop_base.h" #include "../vehicle_base.h" #include "../newgrf_station.h" -#include "saveload.h" #include "table/strings.h" #include "../safeguards.h" @@ -142,18 +145,8 @@ void AfterLoadRoadStops() static const SaveLoad _roadstop_desc[] = { SLE_VAR(RoadStop, xy, SLE_UINT32), - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_45), SLE_VAR(RoadStop, status, SLE_UINT8), - /* Index was saved in some versions, but this is not needed */ - SLE_CONDNULL(4, SL_MIN_VERSION, SLV_9), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_45), - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_26), - SLE_REF(RoadStop, next, REF_ROADSTOPS), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_45), - - SLE_CONDNULL(4, SL_MIN_VERSION, SLV_25), - SLE_CONDNULL(1, SLV_25, SLV_26), }; static uint16 _waiting_acceptance; @@ -678,6 +671,8 @@ static void Ptrs_STNN() static void Save_ROADSTOP() { + SlTableHeader(_roadstop_desc); + for (RoadStop *rs : RoadStop::Iterate()) { SlSetArrayIndex(rs->index); SlObject(rs, _roadstop_desc); @@ -686,12 +681,14 @@ static void Save_ROADSTOP() static void Load_ROADSTOP() { + const std::vector slt = SlCompatTableHeader(_roadstop_desc, _roadstop_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { RoadStop *rs = new (index) RoadStop(INVALID_TILE); - SlObject(rs, _roadstop_desc); + SlObject(rs, slt); } } @@ -705,7 +702,7 @@ static void Ptrs_ROADSTOP() static const ChunkHandler station_chunk_handlers[] = { { 'STNS', nullptr, Load_STNS, Ptrs_STNS, nullptr, CH_READONLY }, { 'STNN', Save_STNN, Load_STNN, Ptrs_STNN, nullptr, CH_ARRAY }, - { 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, nullptr, CH_ARRAY }, + { 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _station_chunk_handlers(station_chunk_handlers); diff --git a/src/saveload/storage_sl.cpp b/src/saveload/storage_sl.cpp index 50f858f116..4838e9f12a 100644 --- a/src/saveload/storage_sl.cpp +++ b/src/saveload/storage_sl.cpp @@ -8,8 +8,11 @@ /** @file storage_sl.cpp Code handling saving and loading of persistent storages. */ #include "../stdafx.h" -#include "../newgrf_storage.h" + #include "saveload.h" +#include "compat/storage_sl_compat.h" + +#include "../newgrf_storage.h" #include "../safeguards.h" @@ -23,18 +26,22 @@ static const SaveLoad _storage_desc[] = { /** Load persistent storage data. */ static void Load_PSAC() { + const std::vector slt = SlCompatTableHeader(_storage_desc, _storage_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { assert(PersistentStorage::CanAllocateItem()); PersistentStorage *ps = new (index) PersistentStorage(0, 0, 0); - SlObject(ps, _storage_desc); + SlObject(ps, slt); } } /** Save persistent storage data. */ static void Save_PSAC() { + SlTableHeader(_storage_desc); + /* Write the industries */ for (PersistentStorage *ps : PersistentStorage::Iterate()) { ps->ClearChanges(); @@ -43,9 +50,8 @@ static void Save_PSAC() } } -/** Chunk handler for persistent storages. */ static const ChunkHandler persistent_storage_chunk_handlers[] = { - { 'PSAC', Save_PSAC, Load_PSAC, nullptr, nullptr, CH_ARRAY }, + { 'PSAC', Save_PSAC, Load_PSAC, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _persistent_storage_chunk_handlers(persistent_storage_chunk_handlers); diff --git a/src/saveload/story_sl.cpp b/src/saveload/story_sl.cpp index df5b1406f0..9dabd5cbf7 100644 --- a/src/saveload/story_sl.cpp +++ b/src/saveload/story_sl.cpp @@ -8,9 +8,11 @@ /** @file story_sl.cpp Code handling saving and loading of story pages */ #include "../stdafx.h" -#include "../story_base.h" #include "saveload.h" +#include "compat/story_sl_compat.h" + +#include "../story_base.h" #include "../safeguards.h" @@ -38,6 +40,8 @@ static const SaveLoad _story_page_elements_desc[] = { static void Save_STORY_PAGE_ELEMENT() { + SlTableHeader(_story_page_elements_desc); + for (StoryPageElement *s : StoryPageElement::Iterate()) { SlSetArrayIndex(s->index); SlObject(s, _story_page_elements_desc); @@ -46,11 +50,13 @@ static void Save_STORY_PAGE_ELEMENT() static void Load_STORY_PAGE_ELEMENT() { + const std::vector slt = SlCompatTableHeader(_story_page_elements_desc, _story_page_elements_sl_compat); + int index; uint32 max_sort_value = 0; while ((index = SlIterateArray()) != -1) { StoryPageElement *s = new (index) StoryPageElement(); - SlObject(s, _story_page_elements_desc); + SlObject(s, slt); if (s->sort_value > max_sort_value) { max_sort_value = s->sort_value; } @@ -72,6 +78,8 @@ static const SaveLoad _story_pages_desc[] = { static void Save_STORY_PAGE() { + SlTableHeader(_story_pages_desc); + for (StoryPage *s : StoryPage::Iterate()) { SlSetArrayIndex(s->index); SlObject(s, _story_pages_desc); @@ -80,11 +88,13 @@ static void Save_STORY_PAGE() static void Load_STORY_PAGE() { + const std::vector slt = SlCompatTableHeader(_story_pages_desc, _story_pages_sl_compat); + int index; uint32 max_sort_value = 0; while ((index = SlIterateArray()) != -1) { StoryPage *s = new (index) StoryPage(); - SlObject(s, _story_pages_desc); + SlObject(s, slt); if (s->sort_value > max_sort_value) { max_sort_value = s->sort_value; } @@ -96,8 +106,8 @@ static void Load_STORY_PAGE() } static const ChunkHandler story_page_chunk_handlers[] = { - { 'STPE', Save_STORY_PAGE_ELEMENT, Load_STORY_PAGE_ELEMENT, nullptr, nullptr, CH_ARRAY }, - { 'STPA', Save_STORY_PAGE, Load_STORY_PAGE, nullptr, nullptr, CH_ARRAY }, + { 'STPE', Save_STORY_PAGE_ELEMENT, Load_STORY_PAGE_ELEMENT, nullptr, nullptr, CH_TABLE }, + { 'STPA', Save_STORY_PAGE, Load_STORY_PAGE, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _story_page_chunk_handlers(story_page_chunk_handlers); diff --git a/src/saveload/strings_sl.cpp b/src/saveload/strings_sl.cpp index 784d89d8fd..70d001e73b 100644 --- a/src/saveload/strings_sl.cpp +++ b/src/saveload/strings_sl.cpp @@ -130,7 +130,6 @@ static void Load_NAME() } } -/** Chunk handlers related to strings. */ static const ChunkHandler name_chunk_handlers[] = { { 'NAME', nullptr, Load_NAME, nullptr, nullptr, CH_READONLY }, }; diff --git a/src/saveload/subsidy_sl.cpp b/src/saveload/subsidy_sl.cpp index 9ed65a04ec..0a9c25ebd2 100644 --- a/src/saveload/subsidy_sl.cpp +++ b/src/saveload/subsidy_sl.cpp @@ -8,9 +8,11 @@ /** @file subsidy_sl.cpp Code handling saving and loading of subsidies */ #include "../stdafx.h" -#include "../subsidy_base.h" #include "saveload.h" +#include "compat/subsidy_sl_compat.h" + +#include "../subsidy_base.h" #include "../safeguards.h" @@ -29,6 +31,8 @@ static const SaveLoad _subsidies_desc[] = { static void Save_SUBS() { + SlTableHeader(_subsidies_desc); + for (Subsidy *s : Subsidy::Iterate()) { SlSetArrayIndex(s->index); SlObject(s, _subsidies_desc); @@ -37,15 +41,17 @@ static void Save_SUBS() static void Load_SUBS() { + const std::vector slt = SlCompatTableHeader(_subsidies_desc, _subsidies_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { Subsidy *s = new (index) Subsidy(); - SlObject(s, _subsidies_desc); + SlObject(s, slt); } } static const ChunkHandler subsidy_chunk_handlers[] = { - { 'SUBS', Save_SUBS, Load_SUBS, nullptr, nullptr, CH_ARRAY }, + { 'SUBS', Save_SUBS, Load_SUBS, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _subsidy_chunk_handlers(subsidy_chunk_handlers); diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index c653db53a7..faca4180c0 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -325,9 +325,8 @@ static void Ptrs_TOWN() } } -/** Chunk handler for towns. */ static const ChunkHandler town_chunk_handlers[] = { - { 'HIDS', Save_HIDS, Load_HIDS, nullptr, nullptr, CH_ARRAY }, + { 'HIDS', Save_HIDS, Load_HIDS, nullptr, nullptr, CH_TABLE }, { 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, nullptr, CH_ARRAY }, }; diff --git a/src/settings.cpp b/src/settings.cpp index 6368dea113..837c6ae024 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -67,6 +67,8 @@ #include "strings_func.h" #include "vehicle_func.h" +#include "saveload/compat/settings_sl_compat.h" + #include "void_map.h" #include "station_base.h" @@ -2193,27 +2195,31 @@ static std::vector GetSettingsDesc(const SettingTable &settings, bool if (sd->flags & SF_NOT_IN_SAVE) continue; if (is_loading && (sd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) { - /* We don't want to read this setting, so we do need to skip over it. */ - saveloads.push_back({sd->name, sd->save.cmd, GetVarFileType(sd->save.conv) | SLE_VAR_NULL, sd->save.length, sd->save.version_from, sd->save.version_to, 0, nullptr, 0, nullptr}); + if (IsSavegameVersionBefore(SLV_TABLE_CHUNKS)) { + /* We don't want to read this setting, so we do need to skip over it. */ + saveloads.push_back({sd->name, sd->save.cmd, GetVarFileType(sd->save.conv) | SLE_VAR_NULL, sd->save.length, sd->save.version_from, sd->save.version_to, 0, nullptr, 0, nullptr}); + } continue; } - saveloads.push_back(sd->save); + SaveLoad sv = sd->save; + /* Replace the name with the actual name of the setting. */ + if (!sd->name.empty()) sv.name = sd->name; + saveloads.push_back(sv); } return saveloads; } - /** * Save and load handler for settings * @param settings SettingDesc struct containing all information * @param object can be either nullptr in which case we load global variables or * a pointer to a struct which is getting saved */ -static void LoadSettings(const SettingTable &settings, void *object) +static void LoadSettings(const SettingTable &settings, void *object, const SaveLoadCompatTable &slct) { - const std::vector slt = GetSettingsDesc(settings, true); + const std::vector slt = SlCompatTableHeader(GetSettingsDesc(settings, true), slct); if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; SlObject(object, slt); @@ -2243,6 +2249,8 @@ static void SaveSettings(const SettingTable &settings, void *object) { const std::vector slt = GetSettingsDesc(settings, false); + SlTableHeader(slt); + SlSetArrayIndex(0); SlObject(object, slt); } @@ -2253,7 +2261,7 @@ static void Load_OPTS() * a networking environment. This ensures for example that the local * autosave-frequency stays when joining a network-server */ PrepareOldDiffCustom(); - LoadSettings(_gameopt_settings, &_settings_game); + LoadSettings(_gameopt_settings, &_settings_game, _gameopt_sl_compat); HandleOldDiffCustom(true); } @@ -2262,12 +2270,12 @@ static void Load_PATS() /* Copy over default setting since some might not get loaded in * a networking environment. This ensures for example that the local * currency setting stays when joining a network-server */ - LoadSettings(_settings, &_settings_game); + LoadSettings(_settings, &_settings_game, _settings_sl_compat); } static void Check_PATS() { - LoadSettings(_settings, &_load_check_data.settings); + LoadSettings(_settings, &_load_check_data.settings, _settings_sl_compat); } static void Save_PATS() @@ -2276,8 +2284,8 @@ static void Save_PATS() } static const ChunkHandler setting_chunk_handlers[] = { - { 'OPTS', nullptr, Load_OPTS, nullptr, nullptr, CH_READONLY }, - { 'PATS', Save_PATS, Load_PATS, nullptr, Check_PATS, CH_ARRAY }, + { 'OPTS', nullptr, Load_OPTS, nullptr, nullptr, CH_READONLY }, + { 'PATS', Save_PATS, Load_PATS, nullptr, Check_PATS, CH_TABLE }, }; extern const ChunkHandlerTable _setting_chunk_handlers(setting_chunk_handlers); diff --git a/src/table/settings/gameopt_settings.ini b/src/table/settings/gameopt_settings.ini index 4474006236..a30400e85b 100644 --- a/src/table/settings/gameopt_settings.ini +++ b/src/table/settings/gameopt_settings.ini @@ -158,15 +158,6 @@ min = MIN_SNOWLINE_HEIGHT * TILE_HEIGHT max = UINT8_MAX to = SLV_22 -[SDT_NULL] -length = 1 -from = SLV_22 -to = SLV_165 - -[SDT_NULL] -length = 1 -to = SLV_23 - [SDTC_OMANY] var = gui.autosave type = SLE_UINT8 diff --git a/src/table/settings/settings.ini b/src/table/settings/settings.ini index 601493a7e9..fae6e5636a 100644 --- a/src/table/settings/settings.ini +++ b/src/table/settings/settings.ini @@ -62,7 +62,6 @@ SDT_BOOL = SDT_BOOL(GameSettings, $var, $flags, $def, SDT_OMANY = SDT_OMANY(GameSettings, $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $load, $cat, $extra, $startup), SDT_SSTR = SDT_SSTR(GameSettings, $var, $type, $flags, $def, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDT_NULL = SDT_NULL( $length, $from, $to), [validation] SDTG_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); @@ -355,12 +354,6 @@ strhelp = STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT strval = STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE cat = SC_BASIC -; Snow line (or snow_line_height * TILE_HEIGHT) -[SDT_NULL] -length = 1 -from = SLV_97 -to = SLV_164 - [SDT_OMANY] var = vehicle.road_side type = SLE_UINT8 @@ -536,11 +529,6 @@ str = STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH strhelp = STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT strval = STR_CONFIG_SETTING_TILE_LENGTH -# construction.longbridges -[SDT_NULL] -length = 1 -to = SLV_159 - [SDT_VAR] var = construction.train_signal_side type = SLE_UINT8 @@ -843,11 +831,6 @@ strhelp = STR_CONFIG_SETTING_TRAIN_LENGTH_HELPTEXT strval = STR_CONFIG_SETTING_TILE_LENGTH cat = SC_BASIC -; vehicle.mammoth_trains -[SDT_NULL] -length = 1 -to = SLV_159 - [SDT_VAR] var = vehicle.smoke_amount type = SLE_UINT8 @@ -860,11 +843,6 @@ str = STR_CONFIG_SETTING_SMOKE_AMOUNT strhelp = STR_CONFIG_SETTING_SMOKE_AMOUNT_HELPTEXT strval = STR_CONFIG_SETTING_NONE -; order.gotodepot -[SDT_NULL] -length = 1 -to = SLV_159 - ; path finder [SDT_BOOL] @@ -1083,12 +1061,6 @@ strhelp = STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT strval = STR_JUST_COMMA post_cb = UpdateConsists -; order.timetabling -[SDT_NULL] -length = 1 -from = SLV_67 -to = SLV_159 - [SDT_VAR] var = vehicle.plane_speed type = SLE_UINT8 @@ -1123,11 +1095,6 @@ strhelp = STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT strval = STR_CONFIG_SETTING_PLANE_CRASHES_NONE cat = SC_BASIC -; station.join_stations -[SDT_NULL] -length = 1 -to = SLV_159 - [SDTC_BOOL] var = gui.sg_full_load_any from = SLV_22 @@ -1151,11 +1118,6 @@ from = SLV_22 to = SLV_93 def = false -; station.nonuniform_stations -[SDT_NULL] -length = 1 -to = SLV_159 - [SDT_VAR] var = station.station_spread type = SLE_UINT8 @@ -1277,10 +1239,6 @@ def = false str = STR_CONFIG_SETTING_MULTIPINDTOWN strhelp = STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT -[SDT_NULL] -length = 1 -to = SLV_141 - [SDT_BOOL] var = economy.bribe def = true @@ -1365,10 +1323,6 @@ strhelp = STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT strval = STR_CONFIG_SETTING_DESERT_COVERAGE_VALUE cat = SC_BASIC -[SDT_NULL] -length = 4 -to = SLV_144 - [SDT_VAR] var = game_creation.starting_year type = SLE_INT32 @@ -1380,10 +1334,6 @@ str = STR_CONFIG_SETTING_STARTING_YEAR strval = STR_JUST_INT cat = SC_BASIC -[SDT_NULL] -length = 4 -to = SLV_105 - [SDT_VAR] var = game_creation.ending_year type = SLE_INT32 @@ -1486,11 +1436,6 @@ from = SLV_77 def = true cat = SC_EXPERT -; previously ai-new setting. -[SDT_NULL] -length = 1 -to = SLV_107 - [SDT_OMANY] var = script.settings_profile type = SLE_UINT8 @@ -1665,13 +1610,6 @@ min = 1 max = 255 cat = SC_EXPERT -## -; Used to be pf.opf.pf_maxlength & pf.opf.pf_maxdepth -[SDT_NULL] -length = 3 -to = SLV_REMOVE_OPF - -## [SDT_VAR] var = pf.npf.npf_max_search_nodes type = SLE_UINT From 3826703bc3807c8af7372b550760fcd8286b9a6c Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Mon, 7 Jun 2021 11:35:21 +0200 Subject: [PATCH 08/42] Add: store headers for chunks with SL_STRUCTLIST --- src/saveload/company_sl.cpp | 127 ++++++------- src/saveload/compat/CMakeLists.txt | 3 + src/saveload/compat/company_sl_compat.h | 129 ++++++++++++++ src/saveload/compat/game_sl_compat.h | 12 ++ src/saveload/compat/gamelog_sl_compat.h | 105 +++++++++++ src/saveload/compat/linkgraph_sl_compat.h | 66 +++++++ src/saveload/compat/station_sl_compat.h | 152 ++++++++++++++++ src/saveload/compat/town_sl_compat.h | 87 +++++++++ src/saveload/compat/vehicle_sl_compat.h | 207 ++++++++++++++++++++++ src/saveload/game_sl.cpp | 11 +- src/saveload/gamelog_sl.cpp | 165 +++++++++++------ src/saveload/linkgraph_sl.cpp | 43 +++-- src/saveload/saveload.h | 3 +- src/saveload/station_sl.cpp | 88 +++++---- src/saveload/town_sl.cpp | 59 +++--- src/saveload/vehicle_sl.cpp | 163 ++++++++++------- 16 files changed, 1149 insertions(+), 271 deletions(-) create mode 100644 src/saveload/compat/company_sl_compat.h create mode 100644 src/saveload/compat/gamelog_sl_compat.h create mode 100644 src/saveload/compat/linkgraph_sl_compat.h create mode 100644 src/saveload/compat/town_sl_compat.h create mode 100644 src/saveload/compat/vehicle_sl_compat.h diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 7abec80418..27fb2cf375 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -8,6 +8,10 @@ /** @file company_sl.cpp Code handling saving and loading of company data */ #include "../stdafx.h" + +#include "saveload.h" +#include "compat/company_sl_compat.h" + #include "../company_func.h" #include "../company_manager_face.h" #include "../fios.h" @@ -16,8 +20,6 @@ #include "../station_base.h" #include "../strings_func.h" -#include "saveload.h" - #include "table/strings.h" #include "../safeguards.h" @@ -243,79 +245,44 @@ struct CompanyOldAI { class SlCompanyOldAIBuildRec : public DefaultSaveLoadHandler { public: - inline static const SaveLoad description[] = { - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), - SLE_CONDNULL(4, SLV_6, SLV_107), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), - SLE_CONDNULL(4, SLV_6, SLV_107), - SLE_CONDNULL(8, SL_MIN_VERSION, SLV_107), - }; + inline static const SaveLoad description[] = {{}}; // Needed to keep DefaultSaveLoadHandler happy. + inline const static SaveLoadCompatTable compat_description = _company_old_ai_buildrec_compat; - void GenericSaveLoad(CompanyOldAI *old_ai) const + SaveLoadTable GetDescription() const override { return {}; } + + void Load(CompanyOldAI *old_ai) const override { for (int i = 0; i != old_ai->num_build_rec; i++) { - SlObject(nullptr, this->GetDescription()); + SlObject(nullptr, this->GetLoadDescription()); } } - // No Save(); this is for backwards compatibility. - void Load(CompanyOldAI *old_ai) const override { this->GenericSaveLoad(old_ai); } - void LoadCheck(CompanyOldAI *old_ai) const override { this->GenericSaveLoad(old_ai); } - void FixPointers(CompanyOldAI *old_ai) const override { this->GenericSaveLoad(old_ai); } + void LoadCheck(CompanyOldAI *old_ai) const override { this->Load(old_ai); } }; class SlCompanyOldAI : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_107), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_13), - SLE_CONDNULL(4, SLV_13, SLV_107), - SLE_CONDNULL(8, SL_MIN_VERSION, SLV_107), - SLE_CONDVAR(CompanyOldAI, num_build_rec, SLE_UINT8, SL_MIN_VERSION, SLV_107), - SLE_CONDNULL(3, SL_MIN_VERSION, SLV_107), - - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), - SLE_CONDNULL(4, SLV_6, SLV_107), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), - SLE_CONDNULL(4, SLV_6, SLV_107), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_107), - - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), - SLE_CONDNULL(4, SLV_6, SLV_107), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), - SLE_CONDNULL(4, SLV_6, SLV_107), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_107), - - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_69), - SLE_CONDNULL(4, SLV_69, SLV_107), - - SLE_CONDNULL(18, SL_MIN_VERSION, SLV_107), - SLE_CONDNULL(20, SL_MIN_VERSION, SLV_107), - SLE_CONDNULL(32, SL_MIN_VERSION, SLV_107), - - SLE_CONDNULL(64, SLV_2, SLV_107), - SLEG_STRUCTLIST("build_rec", SlCompanyOldAIBuildRec), + SLE_CONDVAR(CompanyOldAI, num_build_rec, SLE_UINT8, SL_MIN_VERSION, SLV_107), + SLEG_STRUCTLIST("buildrec", SlCompanyOldAIBuildRec), }; + inline const static SaveLoadCompatTable compat_description = _company_old_ai_compat; - void GenericSaveLoad(CompanyProperties *c) const + void Load(CompanyProperties *c) const override { if (!c->is_ai) return; CompanyOldAI old_ai; - SlObject(&old_ai, this->GetDescription()); + SlObject(&old_ai, this->GetLoadDescription()); } - // No Save(); this is for backwards compatibility. - void Load(CompanyProperties *c) const override { this->GenericSaveLoad(c); } - void LoadCheck(CompanyProperties *c) const override { this->GenericSaveLoad(c); } - void FixPointers(CompanyProperties *c) const override { this->GenericSaveLoad(c); } + void LoadCheck(CompanyProperties *c) const override { this->Load(c); } }; class SlCompanySettings : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { /* Engine renewal settings */ - SLE_CONDNULL(512, SLV_16, SLV_19), SLE_CONDREF(CompanyProperties, engine_renew_list, REF_ENGINE_RENEWS, SLV_19, SL_MAX_VERSION), SLE_CONDVAR(CompanyProperties, settings.engine_renew, SLE_BOOL, SLV_16, SL_MAX_VERSION), SLE_CONDVAR(CompanyProperties, settings.engine_renew_months, SLE_INT16, SLV_16, SL_MAX_VERSION), @@ -328,19 +295,25 @@ public: SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_roadveh, SLE_UINT16, SLV_120, SL_MAX_VERSION), SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_aircraft, SLE_UINT16, SLV_120, SL_MAX_VERSION), SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_ships, SLE_UINT16, SLV_120, SL_MAX_VERSION), - - SLE_CONDNULL(63, SLV_2, SLV_144), // old reserved space }; + inline const static SaveLoadCompatTable compat_description = _company_settings_compat; - void GenericSaveLoad(CompanyProperties *c) const + void Save(CompanyProperties *c) const override { SlObject(c, this->GetDescription()); } - void Save(CompanyProperties *c) const override { this->GenericSaveLoad(c); } - void Load(CompanyProperties *c) const override { this->GenericSaveLoad(c); } - void LoadCheck(CompanyProperties *c) const override { this->GenericSaveLoad(c); } - void FixPointers(CompanyProperties *c) const override { this->GenericSaveLoad(c); } + void Load(CompanyProperties *c) const override + { + SlObject(c, this->GetLoadDescription()); + } + + void FixPointers(CompanyProperties *c) const override + { + SlObject(c, this->GetDescription()); + } + + void LoadCheck(CompanyProperties *c) const override { this->Load(c); } }; class SlCompanyEconomy : public DefaultSaveLoadHandler { @@ -358,16 +331,24 @@ public: SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32), }; + inline const static SaveLoadCompatTable compat_description = _company_economy_compat; - void GenericSaveLoad(CompanyProperties *c) const + void Save(CompanyProperties *c) const override { SlObject(&c->cur_economy, this->GetDescription()); } - void Save(CompanyProperties *c) const override { this->GenericSaveLoad(c); } - void Load(CompanyProperties *c) const override { this->GenericSaveLoad(c); } - void LoadCheck(CompanyProperties *c) const override { this->GenericSaveLoad(c); } - void FixPointers(CompanyProperties *c) const override { this->GenericSaveLoad(c); } + void Load(CompanyProperties *c) const override + { + SlObject(&c->cur_economy, this->GetLoadDescription()); + } + + void FixPointers(CompanyProperties *c) const override + { + SlObject(&c->cur_economy, this->GetDescription()); + } + + void LoadCheck(CompanyProperties *c) const override { this->Load(c); } }; class SlCompanyOldEconomy : public SlCompanyEconomy { @@ -388,7 +369,7 @@ public: if (c->num_valid_stat_ent > lengthof(c->old_economy)) SlErrorCorrupt("Too many old economy entries"); for (int i = 0; i < c->num_valid_stat_ent; i++) { - SlObject(&c->old_economy[i], this->GetDescription()); + SlObject(&c->old_economy[i], this->GetLoadDescription()); } } @@ -402,6 +383,7 @@ public: SLE_CONDVAR(Livery, colour1, SLE_UINT8, SLV_34, SL_MAX_VERSION), SLE_CONDVAR(Livery, colour2, SLE_UINT8, SLV_34, SL_MAX_VERSION), }; + inline const static SaveLoadCompatTable compat_description = _company_liveries_compat; /** * Get the number of liveries used by this savegame version. @@ -430,7 +412,7 @@ public: bool update_in_use = IsSavegameVersionBefore(SLV_GROUP_LIVERIES); for (size_t i = 0; i < num_liveries; i++) { - SlObject(&c->livery[i], this->GetDescription()); + SlObject(&c->livery[i], this->GetLoadDescription()); if (update_in_use && i != LS_DEFAULT) { if (c->livery[i].in_use == 0) { c->livery[i].colour1 = c->livery[LS_DEFAULT].colour1; @@ -479,11 +461,8 @@ static const SaveLoad _company_desc[] = { SLE_VAR(CompanyProperties, colour, SLE_UINT8), SLE_VAR(CompanyProperties, money_fraction, SLE_UINT8), - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_58), ///< avail_railtypes SLE_VAR(CompanyProperties, block_preview, SLE_UINT8), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_94), ///< cargo_types - SLE_CONDNULL(4, SLV_94, SLV_170), ///< cargo_types SLE_CONDVAR(CompanyProperties, location_of_HQ, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), SLE_CONDVAR(CompanyProperties, location_of_HQ, SLE_UINT32, SLV_6, SL_MAX_VERSION), SLE_CONDVAR(CompanyProperties, last_build_coordinate, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), @@ -507,8 +486,6 @@ static const SaveLoad _company_desc[] = { SLE_CONDARR(CompanyProperties, yearly_expenses, SLE_INT64, 3 * 13, SLV_2, SL_MAX_VERSION), SLE_CONDVAR(CompanyProperties, is_ai, SLE_BOOL, SLV_2, SL_MAX_VERSION), - SLE_CONDNULL(1, SLV_107, SLV_112), ///< is_noai - SLE_CONDNULL(1, SLV_4, SLV_100), SLE_CONDVAR(CompanyProperties, terraform_limit, SLE_UINT32, SLV_156, SL_MAX_VERSION), SLE_CONDVAR(CompanyProperties, clear_limit, SLE_UINT32, SLV_156, SL_MAX_VERSION), @@ -522,6 +499,8 @@ static const SaveLoad _company_desc[] = { static void Save_PLYR() { + SlTableHeader(_company_desc); + for (Company *c : Company::Iterate()) { SlSetArrayIndex(c->index); SlObject(c, _company_desc); @@ -530,20 +509,24 @@ static void Save_PLYR() static void Load_PLYR() { + const std::vector slt = SlCompatTableHeader(_company_desc, _company_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { Company *c = new (index) Company(); - SlObject(c, _company_desc); + SlObject(c, slt); _company_colours[index] = (Colours)c->colour; } } static void Check_PLYR() { + const std::vector slt = SlCompatTableHeader(_company_desc, _company_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { CompanyProperties *cprops = new CompanyProperties(); - SlObject(cprops, _company_desc); + SlObject(cprops, slt); /* We do not load old custom names */ if (IsSavegameVersionBefore(SLV_84)) { @@ -576,7 +559,7 @@ static void Ptrs_PLYR() static const ChunkHandler company_chunk_handlers[] = { - { 'PLYR', Save_PLYR, Load_PLYR, Ptrs_PLYR, Check_PLYR, CH_ARRAY }, + { 'PLYR', Save_PLYR, Load_PLYR, Ptrs_PLYR, Check_PLYR, CH_TABLE }, }; extern const ChunkHandlerTable _company_chunk_handlers(company_chunk_handlers); diff --git a/src/saveload/compat/CMakeLists.txt b/src/saveload/compat/CMakeLists.txt index 1737f9493a..dc7c57e5c8 100644 --- a/src/saveload/compat/CMakeLists.txt +++ b/src/saveload/compat/CMakeLists.txt @@ -4,6 +4,7 @@ add_files( cargomonitor_sl_compat.h cargopacket_sl_compat.h cheat_sl_compat.h + company_sl_compat.h depot_sl_compat.h economy_sl_compat.h engine_sl_compat.h @@ -23,4 +24,6 @@ add_files( storage_sl_compat.h story_sl_compat.h subsidy_sl_compat.h + town_sl_compat.h + vehicle_sl_compat.h ) diff --git a/src/saveload/compat/company_sl_compat.h b/src/saveload/compat/company_sl_compat.h new file mode 100644 index 0000000000..9da01d3a47 --- /dev/null +++ b/src/saveload/compat/company_sl_compat.h @@ -0,0 +1,129 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file company_sl_compat.h Loading of company chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_COMPANY_H +#define SAVELOAD_COMPAT_COMPANY_H + +#include "../saveload.h" + +/** Original field order for SlCompanyOldAIBuildRec. */ +const SaveLoadCompat _company_old_ai_buildrec_compat[] = { + SLC_NULL(2, SL_MIN_VERSION, SLV_6), + SLC_NULL(4, SLV_6, SLV_107), + SLC_NULL(2, SL_MIN_VERSION, SLV_6), + SLC_NULL(4, SLV_6, SLV_107), + SLC_NULL(8, SL_MIN_VERSION, SLV_107), +}; + +/** Original field order for SlCompanyOldAI. */ +const SaveLoadCompat _company_old_ai_compat[] = { + SLC_NULL(2, SL_MIN_VERSION, SLV_107), + SLC_NULL(2, SL_MIN_VERSION, SLV_13), + SLC_NULL(4, SLV_13, SLV_107), + SLC_NULL(8, SL_MIN_VERSION, SLV_107), + SLC_VAR("num_build_rec"), + SLC_NULL(3, SL_MIN_VERSION, SLV_107), + + SLC_NULL(2, SL_MIN_VERSION, SLV_6), + SLC_NULL(4, SLV_6, SLV_107), + SLC_NULL(2, SL_MIN_VERSION, SLV_6), + SLC_NULL(4, SLV_6, SLV_107), + SLC_NULL(2, SL_MIN_VERSION, SLV_107), + + SLC_NULL(2, SL_MIN_VERSION, SLV_6), + SLC_NULL(4, SLV_6, SLV_107), + SLC_NULL(2, SL_MIN_VERSION, SLV_6), + SLC_NULL(4, SLV_6, SLV_107), + SLC_NULL(2, SL_MIN_VERSION, SLV_107), + + SLC_NULL(2, SL_MIN_VERSION, SLV_69), + SLC_NULL(4, SLV_69, SLV_107), + + SLC_NULL(18, SL_MIN_VERSION, SLV_107), + SLC_NULL(20, SL_MIN_VERSION, SLV_107), + SLC_NULL(32, SL_MIN_VERSION, SLV_107), + + SLC_NULL(64, SLV_2, SLV_107), + SLC_VAR("buildrec"), +}; + +/** Original field order for SlCompanySettings. */ +const SaveLoadCompat _company_settings_compat[] = { + SLC_NULL(512, SLV_16, SLV_19), + SLC_VAR("engine_renew_list"), + SLC_VAR("settings.engine_renew"), + SLC_VAR("settings.engine_renew_months"), + SLC_VAR("settings.engine_renew_money"), + SLC_VAR("settings.renew_keep_length"), + SLC_VAR("settings.vehicle.servint_ispercent"), + SLC_VAR("settings.vehicle.servint_trains"), + SLC_VAR("settings.vehicle.servint_roadveh"), + SLC_VAR("settings.vehicle.servint_aircraft"), + SLC_VAR("settings.vehicle.servint_ships"), + SLC_NULL(63, SLV_2, SLV_144), +}; + +/** Original field order for SlCompanyEconomy. */ +const SaveLoadCompat _company_economy_compat[] = { + SLC_VAR("income"), + SLC_VAR("expenses"), + SLC_VAR("company_value"), + SLC_VAR("delivered_cargo[NUM_CARGO - 1]"), + SLC_VAR("delivered_cargo"), + SLC_VAR("performance_history"), +}; + +/** Original field order for SlCompanyLiveries. */ +const SaveLoadCompat _company_liveries_compat[] = { + SLC_VAR("in_use"), + SLC_VAR("colour1"), + SLC_VAR("colour2"), +}; + +/** Original field order for company_desc. */ +const SaveLoadCompat _company_sl_compat[] = { + SLC_VAR("name_2"), + SLC_VAR("name_1"), + SLC_VAR("name"), + SLC_VAR("president_name_1"), + SLC_VAR("president_name_2"), + SLC_VAR("president_name"), + SLC_VAR("face"), + SLC_VAR("money"), + SLC_VAR("current_loan"), + SLC_VAR("colour"), + SLC_VAR("money_fraction"), + SLC_NULL(1, SL_MIN_VERSION, SLV_58), + SLC_VAR("block_preview"), + SLC_NULL(2, SL_MIN_VERSION, SLV_94), + SLC_NULL(4, SLV_94, SLV_170), + SLC_VAR("location_of_HQ"), + SLC_VAR("last_build_coordinate"), + SLC_VAR("inaugurated_year"), + SLC_VAR("share_owners"), + SLC_VAR("num_valid_stat_ent"), + SLC_VAR("months_of_bankruptcy"), + SLC_VAR("bankrupt_asked"), + SLC_VAR("bankrupt_timeout"), + SLC_VAR("bankrupt_value"), + SLC_VAR("yearly_expenses"), + SLC_VAR("is_ai"), + SLC_NULL(1, SLV_107, SLV_112), + SLC_NULL(1, SLV_4, SLV_100), + SLC_VAR("terraform_limit"), + SLC_VAR("clear_limit"), + SLC_VAR("tree_limit"), + SLC_VAR("settings"), + SLC_VAR("old_ai"), + SLC_VAR("cur_economy"), + SLC_VAR("old_economy"), + SLC_VAR("liveries"), +}; + +#endif /* SAVELOAD_COMPAT_COMPANY_H */ diff --git a/src/saveload/compat/game_sl_compat.h b/src/saveload/compat/game_sl_compat.h index 204504e3b2..cc05913d6d 100644 --- a/src/saveload/compat/game_sl_compat.h +++ b/src/saveload/compat/game_sl_compat.h @@ -20,4 +20,16 @@ const SaveLoadCompat _game_script_sl_compat[] = { SLC_VAR("is_random"), }; +/** Original field order for SlGameLanguageString. */ +const SaveLoadCompat _game_language_string_sl_compat[] = { + SLC_VAR("string"), +}; + +/** Original field order for _game_language_desc. */ +const SaveLoadCompat _game_language_sl_compat[] = { + SLC_VAR("language"), + SLC_VAR("count"), + SLC_VAR("strings"), +}; + #endif /* SAVELOAD_COMPAT_GAME_H */ diff --git a/src/saveload/compat/gamelog_sl_compat.h b/src/saveload/compat/gamelog_sl_compat.h new file mode 100644 index 0000000000..f1298bf929 --- /dev/null +++ b/src/saveload/compat/gamelog_sl_compat.h @@ -0,0 +1,105 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file gamelog_sl_compat.h Loading for gamelog chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_GAMELOG_H +#define SAVELOAD_COMPAT_GAMELOG_H + +#include "../saveload.h" + +/** Original field order for SlGamelogMode. */ +const SaveLoadCompat _gamelog_mode_sl_compat[] = { + SLC_VAR("mode.mode"), + SLC_VAR("mode.landscape"), +}; + +/** Original field order for SlGamelogRevision. */ +const SaveLoadCompat _gamelog_revision_sl_compat[] = { + SLC_VAR("revision.text"), + SLC_VAR("revision.newgrf"), + SLC_VAR("revision.slver"), + SLC_VAR("revision.modified"), +}; + +/** Original field order for SlGamelogOldver. */ +const SaveLoadCompat _gamelog_oldver_sl_compat[] = { + SLC_VAR("oldver.type"), + SLC_VAR("oldver.version"), +}; + +/** Original field order for SlGamelogSetting. */ +const SaveLoadCompat _gamelog_setting_sl_compat[] = { + SLC_VAR("setting.name"), + SLC_VAR("setting.oldval"), + SLC_VAR("setting.newval"), +}; + +/** Original field order for SlGamelogGrfadd. */ +const SaveLoadCompat _gamelog_grfadd_sl_compat[] = { + SLC_VAR("grfadd.grfid"), + SLC_VAR("grfadd.md5sum"), +}; + +/** Original field order for SlGamelogGrfrem. */ +const SaveLoadCompat _gamelog_grfrem_sl_compat[] = { + SLC_VAR("grfrem.grfid"), +}; + +/** Original field order for SlGamelogGrfcompat. */ +const SaveLoadCompat _gamelog_grfcompat_sl_compat[] = { + SLC_VAR("grfcompat.grfid"), + SLC_VAR("grfcompat.md5sum"), +}; + +/** Original field order for SlGamelogGrfparam. */ +const SaveLoadCompat _gamelog_grfparam_sl_compat[] = { + SLC_VAR("grfparam.grfid"), +}; + +/** Original field order for SlGamelogGrfmove. */ +const SaveLoadCompat _gamelog_grfmove_sl_compat[] = { + SLC_VAR("grfmove.grfid"), + SLC_VAR("grfmove.offset"), +}; + +/** Original field order for SlGamelogGrfbug. */ +const SaveLoadCompat _gamelog_grfbug_sl_compat[] = { + SLC_VAR("grfbug.data"), + SLC_VAR("grfbug.grfid"), + SLC_VAR("grfbug.bug"), +}; + +/** Original field order for SlGamelogEmergency. */ +const SaveLoadCompat _gamelog_emergency_sl_compat[] = { + SLC_VAR("is_emergency_save"), +}; + +/** Original field order for SlGamelogAction. */ +const SaveLoadCompat _gamelog_action_sl_compat[] = { + SLC_VAR("ct"), + SLC_VAR("mode"), + SLC_VAR("revision"), + SLC_VAR("oldver"), + SLC_VAR("setting"), + SLC_VAR("grfadd"), + SLC_VAR("grfrem"), + SLC_VAR("grfcompat"), + SLC_VAR("grfparam"), + SLC_VAR("grfmove"), + SLC_VAR("grfbug"), + SLC_VAR("emergency"), +}; + +/** Original field order for _gamelog_desc. */ +const SaveLoadCompat _gamelog_sl_compat[] = { + SLC_VAR("at"), + SLC_VAR("tick"), + SLC_VAR("action"), +}; + +#endif /* SAVELOAD_COMPAT_GAMELOG_H */ diff --git a/src/saveload/compat/linkgraph_sl_compat.h b/src/saveload/compat/linkgraph_sl_compat.h new file mode 100644 index 0000000000..eb455da8fc --- /dev/null +++ b/src/saveload/compat/linkgraph_sl_compat.h @@ -0,0 +1,66 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file linkgraph_sl_compat.h Loading of linkgraph chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_LINKGRAPH_H +#define SAVELOAD_COMPAT_LINKGRAPH_H + +#include "../saveload.h" + +/** Original field order for SlLinkgraphEdge. */ +const SaveLoadCompat _linkgraph_edge_sl_compat[] = { + SLC_NULL(4, SL_MIN_VERSION, SLV_191), + SLC_VAR("capacity"), + SLC_VAR("usage"), + SLC_VAR("last_unrestricted_update"), + SLC_VAR("last_restricted_update"), + SLC_VAR("next_edge"), +}; + +/** Original field order for SlLinkgraphNode. */ +const SaveLoadCompat _linkgraph_node_sl_compat[] = { + SLC_VAR("xy"), + SLC_VAR("supply"), + SLC_VAR("demand"), + SLC_VAR("station"), + SLC_VAR("last_update"), + SLC_VAR("edges"), +}; + +/** Original field order for link_graph_desc. */ +const SaveLoadCompat _linkgraph_sl_compat[] = { + SLC_VAR("last_compression"), + SLC_VAR("num_nodes"), + SLC_VAR("cargo"), + SLC_VAR("nodes"), +}; + +/** Original field order for job_desc. */ +const SaveLoadCompat _linkgraph_job_sl_compat[] = { + SLC_VAR("linkgraph.recalc_interval"), + SLC_VAR("linkgraph.recalc_time"), + SLC_VAR("linkgraph.distribution_pax"), + SLC_VAR("linkgraph.distribution_mail"), + SLC_VAR("linkgraph.distribution_armoured"), + SLC_VAR("linkgraph.distribution_default"), + SLC_VAR("linkgraph.accuracy"), + SLC_VAR("linkgraph.demand_distance"), + SLC_VAR("linkgraph.demand_size"), + SLC_VAR("linkgraph.short_path_saturation"), + SLC_VAR("join_date"), + SLC_VAR("link_graph.index"), + SLC_VAR("linkgraph"), +}; + +/** Original field order for schedule_desc. */ +const SaveLoadCompat _linkgraph_schedule_sl_compat[] = { + SLC_VAR("schedule"), + SLC_VAR("running"), +}; + +#endif /* SAVELOAD_COMPAT_LINKGRAPH_H */ diff --git a/src/saveload/compat/station_sl_compat.h b/src/saveload/compat/station_sl_compat.h index 397e1660fb..1c24a8d5d9 100644 --- a/src/saveload/compat/station_sl_compat.h +++ b/src/saveload/compat/station_sl_compat.h @@ -26,4 +26,156 @@ const SaveLoadCompat _roadstop_sl_compat[] = { SLC_NULL(1, SLV_25, SLV_26), }; +/** Original field order for SlStationSpecList. */ +const SaveLoadCompat _station_spec_list_sl_compat[] = { + SLC_VAR("grfid"), + SLC_VAR("localidx"), +}; + +/** Original field order for SlStationCargo. */ +const SaveLoadCompat _station_cargo_sl_compat[] = { + SLC_VAR("first"), + SLC_VAR("second"), +}; + +/** Original field order for SlStationFlow. */ +const SaveLoadCompat _station_flow_sl_compat[] = { + SLC_VAR("source"), + SLC_VAR("via"), + SLC_VAR("share"), + SLC_VAR("restricted"), +}; + +/** Original field order for SlStationGoods. */ +const SaveLoadCompat _station_goods_sl_compat[] = { + SLC_VAR("waiting_acceptance"), + SLC_VAR("status"), + SLC_NULL(2, SLV_51, SLV_68), + SLC_VAR("time_since_pickup"), + SLC_VAR("rating"), + SLC_VAR("cargo_source"), + SLC_VAR("cargo_source_xy"), + SLC_VAR("cargo_days"), + SLC_VAR("last_speed"), + SLC_VAR("last_age"), + SLC_VAR("cargo_feeder_share"), + SLC_VAR("amount_fract"), + SLC_VAR("packets"), + SLC_VAR("old_num_dests"), + SLC_VAR("cargo.reserved_count"), + SLC_VAR("link_graph"), + SLC_VAR("node"), + SLC_VAR("old_num_flows"), + SLC_VAR("max_waiting_cargo"), + SLC_VAR("flow"), + SLC_VAR("cargo"), +}; + +/** Original field order for SlStationBase. */ +const SaveLoadCompat _station_base_sl_compat[] = { + SLC_VAR("xy"), + SLC_VAR("town"), + SLC_VAR("string_id"), + SLC_VAR("name"), + SLC_VAR("delete_ctr"), + SLC_VAR("owner"), + SLC_VAR("facilities"), + SLC_VAR("build_date"), + SLC_VAR("random_bits"), + SLC_VAR("waiting_triggers"), + SLC_VAR("num_specs"), +}; + +/** Original field order for SlStationNormal. */ +const SaveLoadCompat _station_normal_sl_compat[] = { + SLC_VAR("base"), + SLC_VAR("train_station.tile"), + SLC_VAR("train_station.w"), + SLC_VAR("train_station.h"), + SLC_VAR("bus_stops"), + SLC_VAR("truck_stops"), + SLC_NULL(4, SL_MIN_VERSION, SLV_MULTITILE_DOCKS), + SLC_VAR("ship_station.tile"), + SLC_VAR("ship_station.w"), + SLC_VAR("ship_station.h"), + SLC_VAR("docking_station.tile"), + SLC_VAR("docking_station.w"), + SLC_VAR("docking_station.h"), + SLC_VAR("airport.tile"), + SLC_VAR("airport.w"), + SLC_VAR("airport.h"), + SLC_VAR("airport.type"), + SLC_VAR("airport.layout"), + SLC_VAR("airport.flags"), + SLC_VAR("airport.rotation"), + SLC_VAR("storage"), + SLC_VAR("airport.psa"), + SLC_VAR("indtype"), + SLC_VAR("time_since_load"), + SLC_VAR("time_since_unload"), + SLC_VAR("last_vehicle_type"), + SLC_VAR("had_vehicle_of_type"), + SLC_VAR("loading_vehicles"), + SLC_VAR("always_accepted"), + SLC_VAR("goods"), +}; + +/** Original field order for SlStationWaypoint. */ +const SaveLoadCompat _station_waypoint_sl_compat[] = { + SLC_VAR("base"), + SLC_VAR("town_cn"), + SLC_VAR("train_station.tile"), + SLC_VAR("train_station.w"), + SLC_VAR("train_station.h"), +}; + +/** Original field order for _station_desc. */ +const SaveLoadCompat _station_sl_compat[] = { + SLC_VAR("facilities"), + SLC_VAR("normal"), + SLC_VAR("waypoint"), + SLC_VAR("speclist"), +}; + +/** Original field order for _old_station_desc. */ +const SaveLoadCompat _old_station_sl_compat[] = { + SLC_VAR("xy"), + SLC_NULL(4, SL_MIN_VERSION, SLV_6), + SLC_VAR("train_station.tile"), + SLC_VAR("airport.tile"), + SLC_NULL(2, SL_MIN_VERSION, SLV_6), + SLC_NULL(4, SLV_6, SLV_MULTITILE_DOCKS), + SLC_VAR("town"), + SLC_VAR("train_station.w"), + SLC_VAR("train_station.h"), + SLC_NULL(1, SL_MIN_VERSION, SLV_4), + SLC_VAR("string_id"), + SLC_VAR("name"), + SLC_VAR("indtype"), + SLC_VAR("had_vehicle_of_type"), + SLC_VAR("time_since_load"), + SLC_VAR("time_since_unload"), + SLC_VAR("delete_ctr"), + SLC_VAR("owner"), + SLC_VAR("facilities"), + SLC_VAR("airport.type"), + SLC_NULL(2, SL_MIN_VERSION, SLV_6), + SLC_NULL(1, SL_MIN_VERSION, SLV_5), + SLC_VAR("airport.flags"), + SLC_NULL(2, SL_MIN_VERSION, SLV_26), + SLC_VAR("last_vehicle_type"), + SLC_NULL(2, SLV_3, SLV_26), + SLC_VAR("build_date"), + SLC_VAR("bus_stops"), + SLC_VAR("truck_stops"), + SLC_VAR("random_bits"), + SLC_VAR("waiting_triggers"), + SLC_VAR("num_specs"), + SLC_VAR("loading_vehicles"), + SLC_NULL(32, SLV_2, SL_MAX_VERSION), + SLC_VAR("goods"), + SLC_VAR("speclist"), + +}; + #endif /* SAVELOAD_COMPAT_STATION_H */ diff --git a/src/saveload/compat/town_sl_compat.h b/src/saveload/compat/town_sl_compat.h new file mode 100644 index 0000000000..34a4141028 --- /dev/null +++ b/src/saveload/compat/town_sl_compat.h @@ -0,0 +1,87 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file town_sl_compat.h Loading of town chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_TOWN_H +#define SAVELOAD_COMPAT_TOWN_H + +#include "../saveload.h" + +/** Original field order for SlTownSupplied. */ +const SaveLoadCompat _town_supplied_sl_compat[] = { + SLC_VAR("old_max"), + SLC_VAR("new_max"), + SLC_VAR("old_act"), + SLC_VAR("new_act"), +}; + +/** Original field order for SlTownReceived. */ +const SaveLoadCompat _town_received_sl_compat[] = { + SLC_VAR("old_max"), + SLC_VAR("new_max"), + SLC_VAR("old_act"), + SLC_VAR("new_act"), +}; + +/** Original field order for SlTownAcceptanceMatrix. */ +const SaveLoadCompat _town_acceptance_matrix_sl_compat[] = { + SLC_VAR("area.tile"), + SLC_VAR("area.w"), + SLC_VAR("area.h"), +}; + +/** Original field order for town_desc. */ +const SaveLoadCompat _town_sl_compat[] = { + SLC_VAR("xy"), + SLC_NULL(2, SL_MIN_VERSION, SLV_3), + SLC_NULL(4, SLV_3, SLV_85), + SLC_NULL(2, SL_MIN_VERSION, SLV_92), + SLC_VAR("townnamegrfid"), + SLC_VAR("townnametype"), + SLC_VAR("townnameparts"), + SLC_VAR("name"), + SLC_VAR("flags"), + SLC_VAR("statues"), + SLC_NULL(1, SL_MIN_VERSION, SLV_2), + SLC_VAR("have_ratings"), + SLC_VAR("ratings"), + SLC_VAR("unwanted"), + SLC_VAR("supplied[CT_PASSENGERS].old_max"), + SLC_VAR("supplied[CT_MAIL].old_max"), + SLC_VAR("supplied[CT_PASSENGERS].new_max"), + SLC_VAR("supplied[CT_MAIL].new_max"), + SLC_VAR("supplied[CT_PASSENGERS].old_act"), + SLC_VAR("supplied[CT_MAIL].old_act"), + SLC_VAR("supplied[CT_PASSENGERS].new_act"), + SLC_VAR("supplied[CT_MAIL].new_act"), + SLC_NULL(2, SL_MIN_VERSION, SLV_164), + SLC_VAR("received[TE_FOOD].old_act"), + SLC_VAR("received[TE_WATER].old_act"), + SLC_VAR("received[TE_FOOD].new_act"), + SLC_VAR("received[TE_WATER].new_act"), + SLC_VAR("goal"), + SLC_VAR("text"), + SLC_VAR("time_until_rebuild"), + SLC_VAR("grow_counter"), + SLC_VAR("growth_rate"), + SLC_VAR("fund_buildings_months"), + SLC_VAR("road_build_months"), + SLC_VAR("exclusivity"), + SLC_VAR("exclusive_counter"), + SLC_VAR("larger_town"), + SLC_VAR("layout"), + SLC_VAR("psa_list"), + SLC_NULL(4, SLV_166, SLV_EXTEND_CARGOTYPES), + SLC_NULL(8, SLV_EXTEND_CARGOTYPES, SLV_REMOVE_TOWN_CARGO_CACHE), + SLC_NULL(30, SLV_2, SLV_REMOVE_TOWN_CARGO_CACHE), + SLC_VAR("supplied"), + SLC_VAR("received"), + SLC_VAR("acceptance_matrix"), +}; + +#endif /* SAVELOAD_COMPAT_TOWN_H */ diff --git a/src/saveload/compat/vehicle_sl_compat.h b/src/saveload/compat/vehicle_sl_compat.h new file mode 100644 index 0000000000..524ff1a3ba --- /dev/null +++ b/src/saveload/compat/vehicle_sl_compat.h @@ -0,0 +1,207 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file vehicle_sl_compat.h Loading of vehicle chunks before table headers were added. */ + +#ifndef SAVELOAD_COMPAT_VEHICLE_H +#define SAVELOAD_COMPAT_VEHICLE_H + +#include "../saveload.h" + +/** Original field order for SlVehicleCommon. */ +const SaveLoadCompat _vehicle_common_sl_compat[] = { + SLC_VAR("subtype"), + SLC_VAR("next"), + SLC_VAR("name"), + SLC_VAR("unitnumber"), + SLC_VAR("owner"), + SLC_VAR("tile"), + SLC_VAR("dest_tile"), + SLC_VAR("x_pos"), + SLC_VAR("y_pos"), + SLC_VAR("z_pos"), + SLC_VAR("direction"), + SLC_NULL(2, SL_MIN_VERSION, SLV_58), + SLC_VAR("spritenum"), + SLC_NULL(5, SL_MIN_VERSION, SLV_58), + SLC_VAR("engine_type"), + SLC_NULL(2, SL_MIN_VERSION, SLV_152), + SLC_VAR("cur_speed"), + SLC_VAR("subspeed"), + SLC_VAR("acceleration"), + SLC_VAR("motion_counter"), + SLC_VAR("progress"), + SLC_VAR("vehstatus"), + SLC_VAR("last_station_visited"), + SLC_VAR("last_loading_station"), + SLC_VAR("cargo_type"), + SLC_VAR("cargo_subtype"), + SLC_VAR("cargo_days"), + SLC_VAR("cargo_source"), + SLC_VAR("cargo_source_xy"), + SLC_VAR("cargo_cap"), + SLC_VAR("refit_cap"), + SLC_VAR("cargo_count"), + SLC_VAR("cargo.packets"), + SLC_VAR("cargo.action_counts"), + SLC_VAR("cargo_age_counter"), + SLC_VAR("day_counter"), + SLC_VAR("tick_counter"), + SLC_VAR("running_ticks"), + SLC_VAR("cur_implicit_order_index"), + SLC_VAR("cur_real_order_index"), + SLC_NULL(1, SL_MIN_VERSION, SLV_105), + SLC_VAR("current_order.type"), + SLC_VAR("current_order.flags"), + SLC_VAR("current_order.dest"), + SLC_VAR("current_order.refit_cargo"), + SLC_NULL(1, SLV_36, SLV_182), + SLC_VAR("current_order.wait_time"), + SLC_VAR("current_order.travel_time"), + SLC_VAR("current_order.max_speed"), + SLC_VAR("timetable_start"), + SLC_VAR("orders"), + SLC_VAR("age"), + SLC_VAR("max_age"), + SLC_VAR("date_of_last_service"), + SLC_VAR("service_interval"), + SLC_VAR("reliability"), + SLC_VAR("reliability_spd_dec"), + SLC_VAR("breakdown_ctr"), + SLC_VAR("breakdown_delay"), + SLC_VAR("breakdowns_since_last_service"), + SLC_VAR("breakdown_chance"), + SLC_VAR("build_year"), + SLC_VAR("load_unload_ticks"), + SLC_VAR("cargo_paid_for"), + SLC_VAR("vehicle_flags"), + SLC_VAR("profit_this_year"), + SLC_VAR("profit_last_year"), + SLC_VAR("cargo_feeder_share"), + SLC_VAR("cargo_loaded_at_xy"), + SLC_VAR("value"), + SLC_VAR("random_bits"), + SLC_VAR("waiting_triggers"), + SLC_VAR("next_shared"), + SLC_NULL(2, SLV_2, SLV_69), + SLC_NULL(4, SLV_69, SLV_101), + SLC_VAR("group_id"), + SLC_VAR("current_order_time"), + SLC_VAR("lateness_counter"), + SLC_NULL(10, SLV_2, SLV_144), +}; + +/** Original field order for SlVehicleTrain. */ +const SaveLoadCompat _vehicle_train_sl_compat[] = { + SLC_VAR("common"), + SLC_VAR("crash_anim_pos"), + SLC_VAR("force_proceed"), + SLC_VAR("railtype"), + SLC_VAR("track"), + SLC_VAR("flags"), + SLC_NULL(2, SLV_2, SLV_60), + SLC_VAR("wait_counter"), + SLC_NULL(2, SLV_2, SLV_20), + SLC_VAR("gv_flags"), + SLC_NULL(11, SLV_2, SLV_144), +}; + +/** Original field order for SlVehicleRoadVeh. */ +const SaveLoadCompat _vehicle_roadveh_sl_compat[] = { + SLC_VAR("common"), + SLC_VAR("state"), + SLC_VAR("frame"), + SLC_VAR("blocked_ctr"), + SLC_VAR("overtaking"), + SLC_VAR("overtaking_ctr"), + SLC_VAR("crashed_ctr"), + SLC_VAR("reverse_ctr"), + SLC_VAR("path.td"), + SLC_VAR("path.tile"), + SLC_NULL(2, SLV_6, SLV_69), + SLC_VAR("gv_flags"), + SLC_NULL(4, SLV_69, SLV_131), + SLC_NULL(2, SLV_6, SLV_131), + SLC_NULL(16, SLV_2, SLV_144), +}; + +/** Original field order for SlVehicleShip. */ +const SaveLoadCompat _vehicle_ship_sl_compat[] = { + SLC_VAR("common"), + SLC_VAR("state"), + SLC_VAR("path"), + SLC_VAR("rotation"), + SLC_NULL(16, SLV_2, SLV_144), +}; + +/** Original field order for SlVehicleAircraft. */ +const SaveLoadCompat _vehicle_aircraft_sl_compat[] = { + SLC_VAR("common"), + SLC_VAR("crashed_counter"), + SLC_VAR("pos"), + SLC_VAR("targetairport"), + SLC_VAR("state"), + SLC_VAR("previous_pos"), + SLC_VAR("last_direction"), + SLC_VAR("number_consecutive_turns"), + SLC_VAR("turn_counter"), + SLC_VAR("flags"), + SLC_NULL(13, SLV_2, SLV_144), +}; + +/** Original field order for SlVehicleEffect. */ +const SaveLoadCompat _vehicle_effect_sl_compat[] = { + SLC_VAR("subtype"), + SLC_VAR("tile"), + SLC_VAR("x_pos"), + SLC_VAR("y_pos"), + SLC_VAR("z_pos"), + SLC_VAR("sprite_cache.sprite_seq.seq[0].sprite"), + SLC_NULL(5, SL_MIN_VERSION, SLV_59), + SLC_VAR("progress"), + SLC_VAR("vehstatus"), + SLC_VAR("animation_state"), + SLC_VAR("animation_substate"), + SLC_VAR("spritenum"), + SLC_NULL(15, SLV_2, SLV_144), +}; + +/** Original field order for SlVehicleDisaster. */ +const SaveLoadCompat _vehicle_disaster_sl_compat[] = { + SLC_VAR("next"), + SLC_VAR("subtype"), + SLC_VAR("tile"), + SLC_VAR("dest_tile"), + SLC_VAR("x_pos"), + SLC_VAR("y_pos"), + SLC_VAR("z_pos"), + SLC_VAR("direction"), + SLC_NULL(5, SL_MIN_VERSION, SLV_58), + SLC_VAR("owner"), + SLC_VAR("vehstatus"), + SLC_VAR("current_order.dest"), + SLC_VAR("sprite_cache.sprite_seq.seq[0].sprite"), + SLC_VAR("age"), + SLC_VAR("tick_counter"), + SLC_VAR("image_override"), + SLC_VAR("big_ufo_destroyer_target"), + SLC_VAR("flags"), + SLC_NULL(16, SLV_2, SLV_144), +}; + +/** Original field order for vehicle_desc. */ +const SaveLoadCompat _vehicle_sl_compat[] = { + SLC_VAR("type"), + SLC_VAR("train"), + SLC_VAR("roadveh"), + SLC_VAR("ship"), + SLC_VAR("aircraft"), + SLC_VAR("effect"), + SLC_VAR("disaster"), +}; + +#endif /* SAVELOAD_COMPAT_VEHICLE_H */ diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index 059e173336..f0083cb882 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -123,6 +123,7 @@ public: inline static const SaveLoad description[] = { SLEG_SSTR("string", _game_saveload_string, SLE_STR | SLF_ALLOW_CONTROL), }; + inline const static SaveLoadCompatTable compat_description = _game_language_string_sl_compat; void Save(LanguageStrings *ls) const override { @@ -139,7 +140,7 @@ public: uint32 length = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? _game_saveload_strings : (uint32)SlGetStructListLength(UINT32_MAX); for (uint32 i = 0; i < length; i++) { - SlObject(nullptr, this->GetDescription()); + SlObject(nullptr, this->GetLoadDescription()); ls->lines.emplace_back(_game_saveload_string); } } @@ -153,12 +154,14 @@ static const SaveLoad _game_language_desc[] = { static void Load_GSTR() { + const std::vector slt = SlCompatTableHeader(_game_language_desc, _game_language_sl_compat); + delete _current_data; _current_data = new GameStrings(); while (SlIterateArray() != -1) { LanguageStrings ls; - SlObject(&ls, _game_language_desc); + SlObject(&ls, slt); _current_data->raw_strings.push_back(std::move(ls)); } @@ -175,6 +178,8 @@ static void Load_GSTR() static void Save_GSTR() { + SlTableHeader(_game_language_desc); + if (_current_data == nullptr) return; for (uint i = 0; i < _current_data->raw_strings.size(); i++) { @@ -184,7 +189,7 @@ static void Save_GSTR() } static const ChunkHandler game_chunk_handlers[] = { - { 'GSTR', Save_GSTR, Load_GSTR, nullptr, nullptr, CH_ARRAY }, + { 'GSTR', Save_GSTR, Load_GSTR, nullptr, nullptr, CH_TABLE }, { 'GSDT', Save_GSDT, Load_GSDT, nullptr, nullptr, CH_TABLE }, }; diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index f76718d42a..8cc81c8cf7 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.cpp @@ -8,10 +8,12 @@ /** @file gamelog_sl.cpp Code handling saving and loading of gamelog data */ #include "../stdafx.h" -#include "../gamelog_internal.h" -#include "../fios.h" #include "saveload.h" +#include "compat/gamelog_sl_compat.h" + +#include "../gamelog_internal.h" +#include "../fios.h" #include "../safeguards.h" @@ -22,16 +24,21 @@ public: SLE_VAR(LoggedChange, mode.mode, SLE_UINT8), SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_mode_sl_compat; - void GenericSaveLoad(LoggedChange *lc) const + void Save(LoggedChange *lc) const override { if (lc->ct != GLCT_MODE) return; SlObject(lc, this->GetDescription()); } - void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } + void Load(LoggedChange *lc) const override + { + if (lc->ct != GLCT_MODE) return; + SlObject(lc, this->GetLoadDescription()); + } + + void LoadCheck(LoggedChange *lc) const override { this->Load(lc); } }; class SlGamelogRevision : public DefaultSaveLoadHandler { @@ -42,16 +49,21 @@ public: SLE_VAR(LoggedChange, revision.slver, SLE_UINT16), SLE_VAR(LoggedChange, revision.modified, SLE_UINT8), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_revision_sl_compat; - void GenericSaveLoad(LoggedChange *lc) const + void Save(LoggedChange *lc) const override { if (lc->ct != GLCT_REVISION) return; SlObject(lc, this->GetDescription()); } - void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } + void Load(LoggedChange *lc) const override + { + if (lc->ct != GLCT_REVISION) return; + SlObject(lc, this->GetLoadDescription()); + } + + void LoadCheck(LoggedChange *lc) const override { this->Load(lc); } }; class SlGamelogOldver : public DefaultSaveLoadHandler { @@ -60,16 +72,21 @@ public: SLE_VAR(LoggedChange, oldver.type, SLE_UINT32), SLE_VAR(LoggedChange, oldver.version, SLE_UINT32), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_oldver_sl_compat; - void GenericSaveLoad(LoggedChange *lc) const + void Save(LoggedChange *lc) const override { if (lc->ct != GLCT_OLDVER) return; SlObject(lc, this->GetDescription()); } - void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } + void Load(LoggedChange *lc) const override + { + if (lc->ct != GLCT_OLDVER) return; + SlObject(lc, this->GetLoadDescription()); + } + + void LoadCheck(LoggedChange *lc) const override { this->Load(lc); } }; class SlGamelogSetting : public DefaultSaveLoadHandler { @@ -79,16 +96,21 @@ public: SLE_VAR(LoggedChange, setting.oldval, SLE_INT32), SLE_VAR(LoggedChange, setting.newval, SLE_INT32), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_setting_sl_compat; - void GenericSaveLoad(LoggedChange *lc) const + void Save(LoggedChange *lc) const override { if (lc->ct != GLCT_SETTING) return; SlObject(lc, this->GetDescription()); } - void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } + void Load(LoggedChange *lc) const override + { + if (lc->ct != GLCT_SETTING) return; + SlObject(lc, this->GetLoadDescription()); + } + + void LoadCheck(LoggedChange *lc) const override { this->Load(lc); } }; class SlGamelogGrfadd : public DefaultSaveLoadHandler { @@ -97,16 +119,21 @@ public: SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ), SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_grfadd_sl_compat; - void GenericSaveLoad(LoggedChange *lc) const + void Save(LoggedChange *lc) const override { if (lc->ct != GLCT_GRFADD) return; SlObject(lc, this->GetDescription()); } - void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } + void Load(LoggedChange *lc) const override + { + if (lc->ct != GLCT_GRFADD) return; + SlObject(lc, this->GetLoadDescription()); + } + + void LoadCheck(LoggedChange *lc) const override { this->Load(lc); } }; class SlGamelogGrfrem : public DefaultSaveLoadHandler { @@ -114,16 +141,21 @@ public: inline static const SaveLoad description[] = { SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_grfrem_sl_compat; - void GenericSaveLoad(LoggedChange *lc) const + void Save(LoggedChange *lc) const override { if (lc->ct != GLCT_GRFREM) return; SlObject(lc, this->GetDescription()); } - void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } + void Load(LoggedChange *lc) const override + { + if (lc->ct != GLCT_GRFREM) return; + SlObject(lc, this->GetLoadDescription()); + } + + void LoadCheck(LoggedChange *lc) const override { this->Load(lc); } }; class SlGamelogGrfcompat : public DefaultSaveLoadHandler { @@ -132,16 +164,21 @@ public: SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ), SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_grfcompat_sl_compat; - void GenericSaveLoad(LoggedChange *lc) const + void Save(LoggedChange *lc) const override { if (lc->ct != GLCT_GRFCOMPAT) return; SlObject(lc, this->GetDescription()); } - void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } + void Load(LoggedChange *lc) const override + { + if (lc->ct != GLCT_GRFCOMPAT) return; + SlObject(lc, this->GetLoadDescription()); + } + + void LoadCheck(LoggedChange *lc) const override { this->Load(lc); } }; class SlGamelogGrfparam : public DefaultSaveLoadHandler { @@ -149,16 +186,21 @@ public: inline static const SaveLoad description[] = { SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_grfparam_sl_compat; - void GenericSaveLoad(LoggedChange *lc) const + void Save(LoggedChange *lc) const override { if (lc->ct != GLCT_GRFPARAM) return; SlObject(lc, this->GetDescription()); } - void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } + void Load(LoggedChange *lc) const override + { + if (lc->ct != GLCT_GRFPARAM) return; + SlObject(lc, this->GetLoadDescription()); + } + + void LoadCheck(LoggedChange *lc) const override { this->Load(lc); } }; class SlGamelogGrfmove : public DefaultSaveLoadHandler { @@ -167,16 +209,21 @@ public: SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32), SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_grfmove_sl_compat; - void GenericSaveLoad(LoggedChange *lc) const + void Save(LoggedChange *lc) const override { if (lc->ct != GLCT_GRFMOVE) return; SlObject(lc, this->GetDescription()); } - void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } + void Load(LoggedChange *lc) const override + { + if (lc->ct != GLCT_GRFMOVE) return; + SlObject(lc, this->GetLoadDescription()); + } + + void LoadCheck(LoggedChange *lc) const override { this->Load(lc); } }; class SlGamelogGrfbug : public DefaultSaveLoadHandler { @@ -186,16 +233,21 @@ public: SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32), SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_grfbug_sl_compat; - void GenericSaveLoad(LoggedChange *lc) const + void Save(LoggedChange *lc) const override { if (lc->ct != GLCT_GRFBUG) return; SlObject(lc, this->GetDescription()); } - void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } + void Load(LoggedChange *lc) const override + { + if (lc->ct != GLCT_GRFBUG) return; + SlObject(lc, this->GetLoadDescription()); + } + + void LoadCheck(LoggedChange *lc) const override { this->Load(lc); } }; static bool _is_emergency_save = true; @@ -206,8 +258,9 @@ public: inline static const SaveLoad description[] = { SLEG_CONDVAR("is_emergency_save", _is_emergency_save, SLE_BOOL, SLV_RIFF_TO_ARRAY, SL_MAX_VERSION), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_emergency_sl_compat; - void GenericSaveLoad(LoggedChange *lc) const + void Save(LoggedChange *lc) const override { if (lc->ct != GLCT_EMERGENCY) return; @@ -215,9 +268,14 @@ public: SlObject(lc, this->GetDescription()); } - void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } - void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); } + void Load(LoggedChange *lc) const override + { + if (lc->ct != GLCT_EMERGENCY) return; + + SlObject(lc, this->GetLoadDescription()); + } + + void LoadCheck(LoggedChange *lc) const override { this->Load(lc); } }; class SlGamelogAction : public DefaultSaveLoadHandler { @@ -236,6 +294,7 @@ public: SLEG_STRUCT("grfbug", SlGamelogGrfbug), SLEG_STRUCT("emergency", SlGamelogEmergency), }; + inline const static SaveLoadCompatTable compat_description = _gamelog_action_sl_compat; void Save(LoggedAction *la) const override { @@ -262,7 +321,7 @@ public: memset(lc, 0, sizeof(*lc)); lc->ct = ct; - SlObject(lc, this->GetDescription()); + SlObject(lc, this->GetLoadDescription()); } return; } @@ -275,7 +334,7 @@ public: memset(lc, 0, sizeof(*lc)); lc->ct = (GamelogChangeType)SlReadByte(); - SlObject(lc, this->GetDescription()); + SlObject(lc, this->GetLoadDescription()); } } @@ -293,6 +352,8 @@ static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_action assert(gamelog_action == nullptr); assert(gamelog_actions == 0); + const std::vector slt = SlCompatTableHeader(_gamelog_desc, _gamelog_sl_compat); + if (IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY)) { byte type; while ((type = SlReadByte()) != GLAT_NONE) { @@ -303,7 +364,7 @@ static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_action memset(la, 0, sizeof(*la)); la->at = (GamelogActionType)type; - SlObject(la, _gamelog_desc); + SlObject(la, slt); } return; } @@ -313,12 +374,14 @@ static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_action LoggedAction *la = &gamelog_action[gamelog_actions++]; memset(la, 0, sizeof(*la)); - SlObject(la, _gamelog_desc); + SlObject(la, slt); } } static void Save_GLOG() { + SlTableHeader(_gamelog_desc); + const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; uint i = 0; @@ -339,7 +402,7 @@ static void Check_GLOG() } static const ChunkHandler gamelog_chunk_handlers[] = { - { 'GLOG', Save_GLOG, Load_GLOG, nullptr, Check_GLOG, CH_ARRAY } + { 'GLOG', Save_GLOG, Load_GLOG, nullptr, Check_GLOG, CH_TABLE } }; extern const ChunkHandlerTable _gamelog_chunk_handlers(gamelog_chunk_handlers); diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index 5456fb33ef..952ae1de3f 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -8,12 +8,15 @@ /** @file linkgraph_sl.cpp Code handling saving and loading of link graphs */ #include "../stdafx.h" + +#include "saveload.h" +#include "compat/linkgraph_sl_compat.h" + #include "../linkgraph/linkgraph.h" #include "../linkgraph/linkgraphjob.h" #include "../linkgraph/linkgraphschedule.h" #include "../network/network.h" #include "../settings_internal.h" -#include "saveload.h" #include "../safeguards.h" @@ -27,13 +30,13 @@ static NodeID _linkgraph_from; ///< Contains the current "from" node being saved class SlLinkgraphEdge : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { - SLE_CONDNULL(4, SL_MIN_VERSION, SLV_191), // distance SLE_VAR(Edge, capacity, SLE_UINT32), SLE_VAR(Edge, usage, SLE_UINT32), SLE_VAR(Edge, last_unrestricted_update, SLE_INT32), SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION), SLE_VAR(Edge, next_edge, SLE_UINT16), }; + inline const static SaveLoadCompatTable compat_description = _linkgraph_edge_sl_compat; void Save(Node *bn) const override { @@ -55,7 +58,7 @@ public: if (IsSavegameVersionBefore(SLV_191)) { /* We used to save the full matrix ... */ for (NodeID to = 0; to < max_size; ++to) { - SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetDescription()); + SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetLoadDescription()); } return; } @@ -68,7 +71,7 @@ public: used_size--; if (to >= max_size) SlErrorCorrupt("Link graph structure overflow"); - SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetDescription()); + SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetLoadDescription()); } if (!IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) && used_size > 0) SlErrorCorrupt("Corrupted link graph"); @@ -85,6 +88,7 @@ public: SLE_VAR(Node, last_update, SLE_INT32), SLEG_STRUCTLIST("edges", SlLinkgraphEdge), }; + inline const static SaveLoadCompatTable compat_description = _linkgraph_node_sl_compat; void Save(LinkGraph *lg) const override { @@ -105,7 +109,7 @@ public: lg->Init(length); for (NodeID from = 0; from < length; ++from) { _linkgraph_from = from; - SlObject(&lg->nodes[from], this->GetDescription()); + SlObject(&lg->nodes[from], this->GetLoadDescription()); } } }; @@ -136,15 +140,16 @@ class SlLinkgraphJobProxy : public DefaultSaveLoadHandler(&lgj->Graph()), GetLinkGraphDesc()); + SlObject(const_cast(&lgj->Graph()), this->GetDescription()); } void Load(LinkGraphJob *lgj) const override { - SlObject(const_cast(&lgj->Graph()), GetLinkGraphDesc()); + SlObject(const_cast(&lgj->Graph()), this->GetLoadDescription()); } }; @@ -241,6 +246,8 @@ void AfterLoadLinkGraphs() */ static void Save_LGRP() { + SlTableHeader(GetLinkGraphDesc()); + for (LinkGraph *lg : LinkGraph::Iterate()) { SlSetArrayIndex(lg->index); SlObject(lg, GetLinkGraphDesc()); @@ -252,10 +259,12 @@ static void Save_LGRP() */ static void Load_LGRP() { + const std::vector slt = SlCompatTableHeader(GetLinkGraphDesc(), _linkgraph_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { LinkGraph *lg = new (index) LinkGraph(); - SlObject(lg, GetLinkGraphDesc()); + SlObject(lg, slt); } } @@ -264,6 +273,8 @@ static void Load_LGRP() */ static void Save_LGRJ() { + SlTableHeader(GetLinkGraphJobDesc()); + for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) { SlSetArrayIndex(lgj->index); SlObject(lgj, GetLinkGraphJobDesc()); @@ -275,10 +286,12 @@ static void Save_LGRJ() */ static void Load_LGRJ() { + const std::vector slt = SlCompatTableHeader(GetLinkGraphJobDesc(), _linkgraph_job_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { LinkGraphJob *lgj = new (index) LinkGraphJob(); - SlObject(lgj, GetLinkGraphJobDesc()); + SlObject(lgj, slt); } } @@ -287,6 +300,8 @@ static void Load_LGRJ() */ static void Save_LGRS() { + SlTableHeader(GetLinkGraphScheduleDesc()); + SlSetArrayIndex(0); SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc()); } @@ -296,8 +311,10 @@ static void Save_LGRS() */ static void Load_LGRS() { + const std::vector slt = SlCompatTableHeader(GetLinkGraphScheduleDesc(), _linkgraph_schedule_sl_compat); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc()); + SlObject(&LinkGraphSchedule::instance, slt); if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many LGRS entries"); } @@ -310,9 +327,9 @@ static void Ptrs_LGRS() } static const ChunkHandler linkgraph_chunk_handlers[] = { - { 'LGRP', Save_LGRP, Load_LGRP, nullptr, nullptr, CH_ARRAY }, - { 'LGRJ', Save_LGRJ, Load_LGRJ, nullptr, nullptr, CH_ARRAY }, - { 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_ARRAY }, + { 'LGRP', Save_LGRP, Load_LGRP, nullptr, nullptr, CH_TABLE }, + { 'LGRJ', Save_LGRJ, Load_LGRJ, nullptr, nullptr, CH_TABLE }, + { 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _linkgraph_chunk_handlers(linkgraph_chunk_handlers); diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index b6e843c991..a238d8c1b3 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -456,7 +456,7 @@ public: /** * Get the pre-header description of the fields in the savegame. */ - virtual SaveLoadCompatTable GetCompatDescription() const { return {}; } + virtual SaveLoadCompatTable GetCompatDescription() const = 0; /** * Get the description for how to load the chunk. Depending on the @@ -481,6 +481,7 @@ template class DefaultSaveLoadHandler : public SaveLoadHandler { public: SaveLoadTable GetDescription() const override { return static_cast(this)->description; } + SaveLoadCompatTable GetCompatDescription() const override { return static_cast(this)->compat_description; } virtual void Save(TObject *object) const {} void Save(void *object) const override { this->Save(static_cast(object)); } diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index ebf2c94f4e..d9978cd6f1 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -199,6 +199,7 @@ public: SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION), SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, SLV_27, SL_MAX_VERSION), }; + inline const static SaveLoadCompatTable compat_description = _station_spec_list_sl_compat; void Save(BaseStation *bst) const override { @@ -218,7 +219,7 @@ public: /* Allocate speclist memory when loading a game */ bst->speclist = CallocT(bst->num_specs); for (uint i = 0; i < bst->num_specs; i++) { - SlObject(&bst->speclist[i], this->GetDescription()); + SlObject(&bst->speclist[i], this->GetLoadDescription()); } } } @@ -230,6 +231,7 @@ public: SLE_VAR(StationCargoPair, first, SLE_UINT16), SLE_REFLIST(StationCargoPair, second, REF_CARGO_PACKET), }; + inline const static SaveLoadCompatTable compat_description = _station_cargo_sl_compat; void Save(GoodsEntry *ge) const override { @@ -245,7 +247,7 @@ public: StationCargoPair pair; for (uint j = 0; j < num_dests; ++j) { - SlObject(&pair, this->GetDescription()); + SlObject(&pair, this->GetLoadDescription()); const_cast(*(ge->cargo.Packets()))[pair.first].swap(pair.second); assert(pair.second.empty()); } @@ -267,6 +269,7 @@ public: SLE_VAR(FlowSaveLoad, share, SLE_UINT32), SLE_CONDVAR(FlowSaveLoad, restricted, SLE_BOOL, SLV_187, SL_MAX_VERSION), }; + inline const static SaveLoadCompatTable compat_description = _station_flow_sl_compat; void Save(GoodsEntry *ge) const override { @@ -300,7 +303,7 @@ public: FlowStat *fs = nullptr; StationID prev_source = INVALID_STATION; for (uint32 j = 0; j < num_flows; ++j) { - SlObject(&flow, this->GetDescription()); + SlObject(&flow, this->GetLoadDescription()); if (fs == nullptr || prev_source != flow.source) { fs = &(ge->flows.insert(std::make_pair(flow.source, FlowStat(flow.via, flow.share, flow.restricted))).first->second); } else { @@ -326,7 +329,6 @@ public: static const SaveLoad description[] = { SLEG_CONDVAR("waiting_acceptance", _waiting_acceptance, SLE_UINT16, SL_MIN_VERSION, SLV_68), SLE_CONDVAR(GoodsEntry, status, SLE_UINT8, SLV_68, SL_MAX_VERSION), - SLE_CONDNULL(2, SLV_51, SLV_68), SLE_VAR(GoodsEntry, time_since_pickup, SLE_UINT8), SLE_VAR(GoodsEntry, rating, SLE_UINT8), SLEG_CONDVAR("cargo_source", _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_7), @@ -352,6 +354,7 @@ public: return description; } #endif + inline const static SaveLoadCompatTable compat_description = _station_goods_sl_compat; /** * Get the number of cargoes used by this savegame version. @@ -392,7 +395,7 @@ public: size_t num_cargo = this->GetNumCargo(); for (CargoID i = 0; i < num_cargo; i++) { GoodsEntry *ge = &st->goods[i]; - SlObject(ge, this->GetDescription()); + SlObject(ge, this->GetLoadDescription()); if (IsSavegameVersionBefore(SLV_183)) { SwapPackets(ge); } @@ -438,19 +441,14 @@ public: static const SaveLoad _old_station_desc[] = { SLE_CONDVAR(Station, xy, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), SLE_CONDVAR(Station, xy, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLE_CONDNULL(4, SL_MIN_VERSION, SLV_6), ///< bus/lorry tile SLE_CONDVAR(Station, train_station.tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), SLE_CONDVAR(Station, train_station.tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), SLE_CONDVAR(Station, airport.tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), SLE_CONDVAR(Station, airport.tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), - SLE_CONDNULL(4, SLV_6, SLV_MULTITILE_DOCKS), SLE_REF(Station, town, REF_TOWN), SLE_VAR(Station, train_station.w, SLE_FILE_U8 | SLE_VAR_U16), SLE_CONDVAR(Station, train_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_2, SL_MAX_VERSION), - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_4), ///< alpha_order - SLE_VAR(Station, string_id, SLE_STRINGID), SLE_CONDSSTR(Station, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), SLE_CONDVAR(Station, indtype, SLE_UINT8, SLV_103, SL_MAX_VERSION), @@ -463,18 +461,12 @@ static const SaveLoad _old_station_desc[] = { SLE_VAR(Station, owner, SLE_UINT8), SLE_VAR(Station, facilities, SLE_UINT8), SLE_VAR(Station, airport.type, SLE_UINT8), - - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), ///< Truck/bus stop status - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_5), ///< Blocked months - SLE_CONDVAR(Station, airport.flags, SLE_VAR_U64 | SLE_FILE_U16, SL_MIN_VERSION, SLV_3), SLE_CONDVAR(Station, airport.flags, SLE_VAR_U64 | SLE_FILE_U32, SLV_3, SLV_46), SLE_CONDVAR(Station, airport.flags, SLE_UINT64, SLV_46, SL_MAX_VERSION), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_26), ///< last-vehicle SLE_CONDVAR(Station, last_vehicle_type, SLE_UINT8, SLV_26, SL_MAX_VERSION), - SLE_CONDNULL(2, SLV_3, SLV_26), ///< custom station class and id SLE_CONDVAR(Station, build_date, SLE_FILE_U16 | SLE_VAR_I32, SLV_3, SLV_31), SLE_CONDVAR(Station, build_date, SLE_INT32, SLV_31, SL_MAX_VERSION), @@ -488,14 +480,14 @@ static const SaveLoad _old_station_desc[] = { SLE_CONDREFLIST(Station, loading_vehicles, REF_VEHICLE, SLV_57, SL_MAX_VERSION), - /* reserve extra space in savegame here. (currently 32 bytes) */ - SLE_CONDNULL(32, SLV_2, SL_MAX_VERSION), SLEG_STRUCTLIST("goods", SlStationGoods), SLEG_CONDSTRUCTLIST("speclist", SlStationSpecList, SLV_27, SL_MAX_VERSION), }; static void Load_STNS() { + const std::vector slt = SlCompatTableHeader(_old_station_desc, _old_station_sl_compat); + _cargo_source_xy = 0; _cargo_days = 0; _cargo_feeder_share = 0; @@ -505,7 +497,7 @@ static void Load_STNS() Station *st = new (index) Station(); _waiting_acceptance = 0; - SlObject(st, _old_station_desc); + SlObject(st, slt); } } @@ -542,15 +534,22 @@ public: SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8), SLE_CONDVAR(BaseStation, num_specs, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH), }; + inline const static SaveLoadCompatTable compat_description = _station_base_sl_compat; - void GenericSaveLoad(BaseStation *bst) const + void Save(BaseStation *bst) const override { SlObject(bst, this->GetDescription()); } - void Save(BaseStation *bst) const override { this->GenericSaveLoad(bst); } - void Load(BaseStation *bst) const override { this->GenericSaveLoad(bst); } - void FixPointers(BaseStation *bst) const override { this->GenericSaveLoad(bst); } + void Load(BaseStation *bst) const override + { + SlObject(bst, this->GetLoadDescription()); + } + + void FixPointers(BaseStation *bst) const override + { + SlObject(bst, this->GetDescription()); + } }; /** @@ -566,7 +565,6 @@ public: SLE_REF(Station, bus_stops, REF_ROADSTOPS), SLE_REF(Station, truck_stops, REF_ROADSTOPS), - SLE_CONDNULL(4, SL_MIN_VERSION, SLV_MULTITILE_DOCKS), SLE_CONDVAR(Station, ship_station.tile, SLE_UINT32, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), SLE_CONDVAR(Station, ship_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), SLE_CONDVAR(Station, ship_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), @@ -594,16 +592,25 @@ public: SLE_CONDVAR(Station, always_accepted, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), SLEG_STRUCTLIST("goods", SlStationGoods), }; + inline const static SaveLoadCompatTable compat_description = _station_normal_sl_compat; - void GenericSaveLoad(BaseStation *bst) const + void Save(BaseStation *bst) const { if ((bst->facilities & FACIL_WAYPOINT) != 0) return; SlObject(bst, this->GetDescription()); } - void Save(BaseStation *bst) const override { this->GenericSaveLoad(bst); } - void Load(BaseStation *bst) const override { this->GenericSaveLoad(bst); } - void FixPointers(BaseStation *bst) const override { this->GenericSaveLoad(bst); } + void Load(BaseStation *bst) const + { + if ((bst->facilities & FACIL_WAYPOINT) != 0) return; + SlObject(bst, this->GetLoadDescription()); + } + + void FixPointers(BaseStation *bst) const + { + if ((bst->facilities & FACIL_WAYPOINT) != 0) return; + SlObject(bst, this->GetDescription()); + } }; class SlStationWaypoint : public DefaultSaveLoadHandler { @@ -616,16 +623,25 @@ public: SLE_CONDVAR(Waypoint, train_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION), SLE_CONDVAR(Waypoint, train_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION), }; + inline const static SaveLoadCompatTable compat_description = _station_waypoint_sl_compat; - void GenericSaveLoad(BaseStation *bst) const + void Save(BaseStation *bst) const { if ((bst->facilities & FACIL_WAYPOINT) == 0) return; SlObject(bst, this->GetDescription()); } - void Save(BaseStation *bst) const override { this->GenericSaveLoad(bst); } - void Load(BaseStation *bst) const override { this->GenericSaveLoad(bst); } - void FixPointers(BaseStation *bst) const override { this->GenericSaveLoad(bst); } + void Load(BaseStation *bst) const + { + if ((bst->facilities & FACIL_WAYPOINT) == 0) return; + SlObject(bst, this->GetLoadDescription()); + } + + void FixPointers(BaseStation *bst) const + { + if ((bst->facilities & FACIL_WAYPOINT) == 0) return; + SlObject(bst, this->GetDescription()); + } }; static const SaveLoad _station_desc[] = { @@ -637,6 +653,8 @@ static const SaveLoad _station_desc[] = { static void Save_STNN() { + SlTableHeader(_station_desc); + /* Write the stations */ for (BaseStation *st : BaseStation::Iterate()) { SlSetArrayIndex(st->index); @@ -646,6 +664,8 @@ static void Save_STNN() static void Load_STNN() { + const std::vector slt = SlCompatTableHeader(_station_desc, _station_sl_compat); + _old_num_flows = 0; int index; @@ -653,7 +673,7 @@ static void Load_STNN() bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0; BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station(); - SlObject(bst, _station_desc); + SlObject(bst, slt); } } @@ -701,7 +721,7 @@ static void Ptrs_ROADSTOP() static const ChunkHandler station_chunk_handlers[] = { { 'STNS', nullptr, Load_STNS, Ptrs_STNS, nullptr, CH_READONLY }, - { 'STNN', Save_STNN, Load_STNN, Ptrs_STNN, nullptr, CH_ARRAY }, + { 'STNN', Save_STNN, Load_STNN, Ptrs_STNN, nullptr, CH_TABLE }, { 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, nullptr, CH_TABLE }, }; diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index faca4180c0..c5b5b0080e 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -8,6 +8,11 @@ /** @file town_sl.cpp Code handling saving and loading of towns and houses */ #include "../stdafx.h" + +#include "saveload.h" +#include "compat/town_sl_compat.h" + +#include "newgrf_sl.h" #include "../newgrf_house.h" #include "../town.h" #include "../landscape.h" @@ -15,9 +20,6 @@ #include "../strings_func.h" #include "../tilematrix_type.hpp" -#include "saveload.h" -#include "newgrf_sl.h" - #include "../safeguards.h" typedef TileMatrix AcceptanceMatrix; @@ -121,6 +123,7 @@ public: SLE_CONDVAR(TransportedCargoStat, old_act, SLE_UINT32, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat, new_act, SLE_UINT32, SLV_165, SL_MAX_VERSION), }; + inline const static SaveLoadCompatTable compat_description = _town_supplied_sl_compat; /** * Get the number of cargoes used by this savegame version. @@ -146,7 +149,7 @@ public: { size_t num_cargo = this->GetNumCargo(); for (CargoID i = 0; i < num_cargo; i++) { - SlObject(&t->supplied[i], this->GetDescription()); + SlObject(&t->supplied[i], this->GetLoadDescription()); } } }; @@ -159,6 +162,7 @@ public: SLE_CONDVAR(TransportedCargoStat, old_act, SLE_UINT16, SLV_165, SL_MAX_VERSION), SLE_CONDVAR(TransportedCargoStat, new_act, SLE_UINT16, SLV_165, SL_MAX_VERSION), }; + inline const static SaveLoadCompatTable compat_description = _town_received_sl_compat; void Save(Town *t) const override { @@ -172,7 +176,7 @@ public: { size_t length = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? (size_t)TE_END : SlGetStructListLength(TE_END); for (size_t i = 0; i < length; i++) { - SlObject(&t->received[i], this->GetDescription()); + SlObject(&t->received[i], this->GetLoadDescription()); } } }; @@ -184,12 +188,13 @@ public: SLE_VAR(AcceptanceMatrix, area.w, SLE_UINT16), SLE_VAR(AcceptanceMatrix, area.h, SLE_UINT16), }; + inline const static SaveLoadCompatTable compat_description = _town_acceptance_matrix_sl_compat; void Load(Town *t) const override { /* Discard now unused acceptance matrix. */ AcceptanceMatrix dummy; - SlObject(&dummy, this->GetDescription()); + SlObject(&dummy, this->GetLoadDescription()); if (dummy.area.w != 0) { uint arr_len = dummy.area.w / AcceptanceMatrix::GRID * dummy.area.h / AcceptanceMatrix::GRID; SlSkipBytes(4 * arr_len); @@ -201,10 +206,6 @@ static const SaveLoad _town_desc[] = { SLE_CONDVAR(Town, xy, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), SLE_CONDVAR(Town, xy, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_3), ///< population, no longer in use - SLE_CONDNULL(4, SLV_3, SLV_85), ///< population, no longer in use - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_92), ///< num_houses, no longer in use - SLE_CONDVAR(Town, townnamegrfid, SLE_UINT32, SLV_66, SL_MAX_VERSION), SLE_VAR(Town, townnametype, SLE_UINT16), SLE_VAR(Town, townnameparts, SLE_UINT32), @@ -214,36 +215,30 @@ static const SaveLoad _town_desc[] = { SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), SLE_CONDVAR(Town, statues, SLE_UINT16, SLV_104, SL_MAX_VERSION), - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_2), ///< sort_index, no longer in use - SLE_CONDVAR(Town, have_ratings, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), SLE_CONDVAR(Town, have_ratings, SLE_UINT16, SLV_104, SL_MAX_VERSION), SLE_CONDARR(Town, ratings, SLE_INT16, 8, SL_MIN_VERSION, SLV_104), SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, SLV_104, SL_MAX_VERSION), - /* failed bribe attempts are stored since savegame format 4 */ SLE_CONDARR(Town, unwanted, SLE_INT8, 8, SLV_4, SLV_104), SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, SLV_104, SL_MAX_VERSION), SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), - SLE_CONDVAR(Town, supplied[CT_MAIL].old_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), - SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), - SLE_CONDVAR(Town, supplied[CT_MAIL].new_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), - SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), - SLE_CONDVAR(Town, supplied[CT_MAIL].old_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), - SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), - SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), - SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_max, SLE_UINT32, SLV_9, SLV_165), + SLE_CONDVAR(Town, supplied[CT_MAIL].old_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), SLE_CONDVAR(Town, supplied[CT_MAIL].old_max, SLE_UINT32, SLV_9, SLV_165), + SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_max, SLE_UINT32, SLV_9, SLV_165), + SLE_CONDVAR(Town, supplied[CT_MAIL].new_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), SLE_CONDVAR(Town, supplied[CT_MAIL].new_max, SLE_UINT32, SLV_9, SLV_165), + SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_act, SLE_UINT32, SLV_9, SLV_165), + SLE_CONDVAR(Town, supplied[CT_MAIL].old_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), SLE_CONDVAR(Town, supplied[CT_MAIL].old_act, SLE_UINT32, SLV_9, SLV_165), + SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_act, SLE_UINT32, SLV_9, SLV_165), + SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_UINT32, SLV_9, SLV_165), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_164), ///< pct_pass_transported / pct_mail_transported, now computed on the fly - SLE_CONDVAR(Town, received[TE_FOOD].old_act, SLE_UINT16, SL_MIN_VERSION, SLV_165), SLE_CONDVAR(Town, received[TE_WATER].old_act, SLE_UINT16, SL_MIN_VERSION, SLV_165), SLE_CONDVAR(Town, received[TE_FOOD].new_act, SLE_UINT16, SL_MIN_VERSION, SLV_165), @@ -254,12 +249,10 @@ static const SaveLoad _town_desc[] = { SLE_CONDSSTR(Town, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_168, SL_MAX_VERSION), SLE_CONDVAR(Town, time_until_rebuild, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_54), - SLE_CONDVAR(Town, grow_counter, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_54), - SLE_CONDVAR(Town, growth_rate, SLE_FILE_U8 | SLE_VAR_I16, SL_MIN_VERSION, SLV_54), - SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT16, SLV_54, SL_MAX_VERSION), + SLE_CONDVAR(Town, grow_counter, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_54), SLE_CONDVAR(Town, grow_counter, SLE_UINT16, SLV_54, SL_MAX_VERSION), - + SLE_CONDVAR(Town, growth_rate, SLE_FILE_U8 | SLE_VAR_I16, SL_MIN_VERSION, SLV_54), SLE_CONDVAR(Town, growth_rate, SLE_FILE_I16 | SLE_VAR_U16, SLV_54, SLV_165), SLE_CONDVAR(Town, growth_rate, SLE_UINT16, SLV_165, SL_MAX_VERSION), @@ -274,10 +267,6 @@ static const SaveLoad _town_desc[] = { SLE_CONDREFLIST(Town, psa_list, REF_STORAGE, SLV_161, SL_MAX_VERSION), - SLE_CONDNULL(4, SLV_166, SLV_EXTEND_CARGOTYPES), ///< cargo_produced, no longer in use - SLE_CONDNULL(8, SLV_EXTEND_CARGOTYPES, SLV_REMOVE_TOWN_CARGO_CACHE), ///< cargo_produced, no longer in use - SLE_CONDNULL(30, SLV_2, SLV_REMOVE_TOWN_CARGO_CACHE), ///< old reserved space - SLEG_CONDSTRUCTLIST("supplied", SlTownSupplied, SLV_165, SL_MAX_VERSION), SLEG_CONDSTRUCTLIST("received", SlTownReceived, SLV_165, SL_MAX_VERSION), SLEG_CONDSTRUCTLIST("acceptance_matrix", SlTownAcceptanceMatrix, SLV_166, SLV_REMOVE_TOWN_CARGO_CACHE), @@ -295,6 +284,8 @@ static void Load_HIDS() static void Save_TOWN() { + SlTableHeader(_town_desc); + for (Town *t : Town::Iterate()) { SlSetArrayIndex(t->index); SlObject(t, _town_desc); @@ -303,11 +294,13 @@ static void Save_TOWN() static void Load_TOWN() { + const std::vector slt = SlCompatTableHeader(_town_desc, _town_sl_compat); + int index; while ((index = SlIterateArray()) != -1) { Town *t = new (index) Town(); - SlObject(t, _town_desc); + SlObject(t, slt); if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GetStringTab(t->townnametype) != TEXT_TAB_OLD_CUSTOM) { SlErrorCorrupt("Invalid town name generator"); @@ -327,7 +320,7 @@ static void Ptrs_TOWN() static const ChunkHandler town_chunk_handlers[] = { { 'HIDS', Save_HIDS, Load_HIDS, nullptr, nullptr, CH_TABLE }, - { 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, nullptr, CH_ARRAY }, + { 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _town_chunk_handlers(town_chunk_handlers); diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index b2d9972fee..962f5f99a6 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -8,6 +8,10 @@ /** @file vehicle_sl.cpp Code handling saving and loading of vehicles */ #include "../stdafx.h" + +#include "saveload.h" +#include "compat/vehicle_sl_compat.h" + #include "../vehicle_func.h" #include "../train.h" #include "../roadveh.h" @@ -19,8 +23,6 @@ #include "../company_func.h" #include "../disaster_vehicle.h" -#include "saveload.h" - #include #include "../safeguards.h" @@ -607,12 +609,8 @@ public: SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, SLV_164, SL_MAX_VERSION), SLE_VAR(Vehicle, direction, SLE_UINT8), - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_58), SLE_VAR(Vehicle, spritenum, SLE_UINT8), - SLE_CONDNULL(5, SL_MIN_VERSION, SLV_58), SLE_VAR(Vehicle, engine_type, SLE_UINT16), - - SLE_CONDNULL(2, SL_MIN_VERSION, SLV_152), SLE_VAR(Vehicle, cur_speed, SLE_UINT16), SLE_VAR(Vehicle, subspeed, SLE_UINT8), SLE_VAR(Vehicle, acceleration, SLE_UINT8), @@ -643,8 +641,6 @@ public: SLE_VAR(Vehicle, cur_implicit_order_index, SLE_UINT8), SLE_CONDVAR(Vehicle, cur_real_order_index, SLE_UINT8, SLV_158, SL_MAX_VERSION), - /* num_orders is now part of OrderList and is not saved but counted */ - SLE_CONDNULL(1, SL_MIN_VERSION, SLV_105), /* This next line is for version 4 and prior compatibility.. it temporarily reads type and flags (which were both 4 bits) into type. Later on this is @@ -659,7 +655,6 @@ public: /* Refit in current order */ SLE_CONDVAR(Vehicle, current_order.refit_cargo, SLE_UINT8, SLV_36, SL_MAX_VERSION), - SLE_CONDNULL(1, SLV_36, SLV_182), // refit_subtype /* Timetable in current order */ SLE_CONDVAR(Vehicle, current_order.wait_time, SLE_UINT16, SLV_67, SL_MAX_VERSION), @@ -707,29 +702,31 @@ public: SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, SLV_2, SL_MAX_VERSION), SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, SLV_2, SL_MAX_VERSION), - SLE_CONDNULL(2, SLV_2, SLV_69), - SLE_CONDNULL(4, SLV_69, SLV_101), - SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, SLV_60, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, SLV_67, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, SLV_67, SL_MAX_VERSION), - - SLE_CONDNULL(10, SLV_2, SLV_144), // old reserved space }; #if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916) return description; } #endif + inline const static SaveLoadCompatTable compat_description = _vehicle_common_sl_compat; - void GenericSaveLoad(Vehicle *v) const + void Save(Vehicle *v) const override { SlObject(v, this->GetDescription()); } - void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } - void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } - void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override + { + SlObject(v, this->GetLoadDescription()); + } + + void FixPointers(Vehicle *v) const override + { + SlObject(v, this->GetDescription()); + } }; class SlVehicleTrain : public DefaultSaveLoadHandler { @@ -743,24 +740,28 @@ public: SLE_CONDVAR(Train, flags, SLE_FILE_U8 | SLE_VAR_U16, SLV_2, SLV_100), SLE_CONDVAR(Train, flags, SLE_UINT16, SLV_100, SL_MAX_VERSION), - SLE_CONDNULL(2, SLV_2, SLV_60), - SLE_CONDVAR(Train, wait_counter, SLE_UINT16, SLV_136, SL_MAX_VERSION), - - SLE_CONDNULL(2, SLV_2, SLV_20), SLE_CONDVAR(Train, gv_flags, SLE_UINT16, SLV_139, SL_MAX_VERSION), - SLE_CONDNULL(11, SLV_2, SLV_144), // old reserved space }; + inline const static SaveLoadCompatTable compat_description = _vehicle_train_sl_compat; - void GenericSaveLoad(Vehicle *v) const + void Save(Vehicle *v) const override { if (v->type != VEH_TRAIN) return; SlObject(v, this->GetDescription()); } - void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } - void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } - void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override + { + if (v->type != VEH_TRAIN) return; + SlObject(v, this->GetLoadDescription()); + } + + void FixPointers(Vehicle *v) const override + { + if (v->type != VEH_TRAIN) return; + SlObject(v, this->GetDescription()); + } }; class SlVehicleRoadVeh : public DefaultSaveLoadHandler { @@ -776,23 +777,27 @@ public: SLE_VAR(RoadVehicle, reverse_ctr, SLE_UINT8), SLE_CONDDEQUE(RoadVehicle, path.td, SLE_UINT8, SLV_ROADVEH_PATH_CACHE, SL_MAX_VERSION), SLE_CONDDEQUE(RoadVehicle, path.tile, SLE_UINT32, SLV_ROADVEH_PATH_CACHE, SL_MAX_VERSION), - - SLE_CONDNULL(2, SLV_6, SLV_69), SLE_CONDVAR(RoadVehicle, gv_flags, SLE_UINT16, SLV_139, SL_MAX_VERSION), - SLE_CONDNULL(4, SLV_69, SLV_131), - SLE_CONDNULL(2, SLV_6, SLV_131), - SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space }; + inline const static SaveLoadCompatTable compat_description = _vehicle_roadveh_sl_compat; - void GenericSaveLoad(Vehicle *v) const + void Save(Vehicle *v) const override { if (v->type != VEH_ROAD) return; SlObject(v, this->GetDescription()); } - void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } - void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } - void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override + { + if (v->type != VEH_ROAD) return; + SlObject(v, this->GetLoadDescription()); + } + + void FixPointers(Vehicle *v) const override + { + if (v->type != VEH_ROAD) return; + SlObject(v, this->GetDescription()); + } }; class SlVehicleShip : public DefaultSaveLoadHandler { @@ -802,19 +807,26 @@ public: SLE_VAR(Ship, state, SLE_UINT8), SLE_CONDDEQUE(Ship, path, SLE_UINT8, SLV_SHIP_PATH_CACHE, SL_MAX_VERSION), SLE_CONDVAR(Ship, rotation, SLE_UINT8, SLV_SHIP_ROTATION, SL_MAX_VERSION), - - SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space }; + inline const static SaveLoadCompatTable compat_description = _vehicle_ship_sl_compat; - void GenericSaveLoad(Vehicle *v) const + void Save(Vehicle *v) const override { if (v->type != VEH_SHIP) return; SlObject(v, this->GetDescription()); } - void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } - void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } - void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override + { + if (v->type != VEH_SHIP) return; + SlObject(v, this->GetLoadDescription()); + } + + void FixPointers(Vehicle *v) const override + { + if (v->type != VEH_SHIP) return; + SlObject(v, this->GetDescription()); + } }; class SlVehicleAircraft : public DefaultSaveLoadHandler { @@ -835,19 +847,26 @@ public: SLE_CONDVAR(Aircraft, turn_counter, SLE_UINT8, SLV_136, SL_MAX_VERSION), SLE_CONDVAR(Aircraft, flags, SLE_UINT8, SLV_167, SL_MAX_VERSION), - - SLE_CONDNULL(13, SLV_2, SLV_144), // old reserved space }; + inline const static SaveLoadCompatTable compat_description = _vehicle_aircraft_sl_compat; - void GenericSaveLoad(Vehicle *v) const + void Save(Vehicle *v) const override { if (v->type != VEH_AIRCRAFT) return; SlObject(v, this->GetDescription()); } - void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } - void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } - void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override + { + if (v->type != VEH_AIRCRAFT) return; + SlObject(v, this->GetLoadDescription()); + } + + void FixPointers(Vehicle *v) const override + { + if (v->type != VEH_AIRCRAFT) return; + SlObject(v, this->GetDescription()); + } }; class SlVehicleEffect : public DefaultSaveLoadHandler { @@ -866,7 +885,6 @@ public: SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, SLV_164, SL_MAX_VERSION), SLE_VAR(Vehicle, sprite_cache.sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32), - SLE_CONDNULL(5, SL_MIN_VERSION, SLV_59), SLE_VAR(Vehicle, progress, SLE_UINT8), SLE_VAR(Vehicle, vehstatus, SLE_UINT8), @@ -874,19 +892,26 @@ public: SLE_VAR(EffectVehicle, animation_substate, SLE_UINT8), SLE_CONDVAR(Vehicle, spritenum, SLE_UINT8, SLV_2, SL_MAX_VERSION), - - SLE_CONDNULL(15, SLV_2, SLV_144), // old reserved space }; + inline const static SaveLoadCompatTable compat_description = _vehicle_effect_sl_compat; - void GenericSaveLoad(Vehicle *v) const + void Save(Vehicle *v) const override { if (v->type != VEH_EFFECT) return; SlObject(v, this->GetDescription()); } - void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } - void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } - void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override + { + if (v->type != VEH_EFFECT) return; + SlObject(v, this->GetLoadDescription()); + } + + void FixPointers(Vehicle *v) const override + { + if (v->type != VEH_EFFECT) return; + SlObject(v, this->GetDescription()); + } }; class SlVehicleDisaster : public DefaultSaveLoadHandler { @@ -918,7 +943,6 @@ public: SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, SLV_164, SL_MAX_VERSION), SLE_VAR(Vehicle, direction, SLE_UINT8), - SLE_CONDNULL(5, SL_MIN_VERSION, SLV_58), SLE_VAR(Vehicle, owner, SLE_UINT8), SLE_VAR(Vehicle, vehstatus, SLE_UINT8), SLE_CONDVAR(Vehicle, current_order.dest, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5), @@ -934,23 +958,30 @@ public: SLE_CONDVAR(DisasterVehicle, big_ufo_destroyer_target, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_191), SLE_CONDVAR(DisasterVehicle, big_ufo_destroyer_target, SLE_UINT32, SLV_191, SL_MAX_VERSION), SLE_CONDVAR(DisasterVehicle, flags, SLE_UINT8, SLV_194, SL_MAX_VERSION), - - SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space }; #if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916) return description; } #endif + inline const static SaveLoadCompatTable compat_description = _vehicle_disaster_sl_compat; - void GenericSaveLoad(Vehicle *v) const + void Save(Vehicle *v) const override { if (v->type != VEH_DISASTER) return; SlObject(v, this->GetDescription()); } - void Save(Vehicle *v) const override { this->GenericSaveLoad(v); } - void Load(Vehicle *v) const override { this->GenericSaveLoad(v); } - void FixPointers(Vehicle *v) const override { this->GenericSaveLoad(v); } + void Load(Vehicle *v) const override + { + if (v->type != VEH_DISASTER) return; + SlObject(v, this->GetLoadDescription()); + } + + void FixPointers(Vehicle *v) const override + { + if (v->type != VEH_DISASTER) return; + SlObject(v, this->GetDescription()); + } }; const static SaveLoad _vehicle_desc[] = { @@ -966,6 +997,8 @@ const static SaveLoad _vehicle_desc[] = { /** Will be called when the vehicles need to be saved. */ static void Save_VEHS() { + SlTableHeader(_vehicle_desc); + /* Write the vehicles */ for (Vehicle *v : Vehicle::Iterate()) { SlSetArrayIndex(v->index); @@ -976,6 +1009,8 @@ static void Save_VEHS() /** Will be called when vehicles need to be loaded. */ void Load_VEHS() { + const std::vector slt = SlCompatTableHeader(_vehicle_desc, _vehicle_sl_compat); + int index; _cargo_count = 0; @@ -995,7 +1030,7 @@ void Load_VEHS() default: SlErrorCorrupt("Invalid vehicle type"); } - SlObject(v, _vehicle_desc); + SlObject(v, slt); if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v) && CargoPacket::CanAllocateItem()) { /* Don't construct the packet with station here, because that'll fail with old savegames */ @@ -1030,7 +1065,7 @@ void Ptrs_VEHS() } static const ChunkHandler veh_chunk_handlers[] = { - { 'VEHS', Save_VEHS, Load_VEHS, Ptrs_VEHS, nullptr, CH_SPARSE_ARRAY }, + { 'VEHS', Save_VEHS, Load_VEHS, Ptrs_VEHS, nullptr, CH_SPARSE_TABLE }, }; extern const ChunkHandlerTable _veh_chunk_handlers(veh_chunk_handlers); From 1ed240590799d0a2b724b226a512906908057e79 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Tue, 15 Jun 2021 13:31:51 +0200 Subject: [PATCH 09/42] Cleanup: remove SLE_NULL and friends We no longer need them. If you want to remove a field .. just remove it! Because of the headers in the savegame, on loading, it will do the right thing and skip the field. Do remember to bump the savegame version, as otherwise older clients can still load the game, but will reset the field you have removed .. that might be unintentially. --- src/saveload/saveload.h | 22 ---------------------- src/table/settings.h.preamble | 10 +--------- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index a238d8c1b3..77588a9f85 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -779,20 +779,6 @@ struct SaveLoadCompat { */ #define SLE_REFLIST(base, variable, type) SLE_CONDREFLIST(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION) -/** - * Empty space in every savegame version. - * @param length Length of the empty space. - */ -#define SLE_NULL(length) SLE_CONDNULL(length, SL_MIN_VERSION, SL_MAX_VERSION) - -/** - * Empty space in some savegame versions. - * @param length Length of the empty space. - * @param from First savegame version that has the empty space. - * @param to Last savegame version that has the empty space. - */ -#define SLE_CONDNULL(length, from, to) SaveLoad {"", SL_NULL, SLE_FILE_U8 | SLE_VAR_NULL, length, from, to, 0, nullptr, 0, nullptr} - /** * Only write byte during saving; never read it during loading. * When using SLE_SAVEBYTE you will have to read this byte before the table @@ -978,14 +964,6 @@ struct SaveLoadCompat { */ #define SLEG_STRUCTLIST(name, handler) SLEG_CONDSTRUCTLIST(name, handler, SL_MIN_VERSION, SL_MAX_VERSION) -/** - * Empty global space in some savegame versions. - * @param length Length of the empty space. - * @param from First savegame version that has the empty space. - * @param to Last savegame version that has the empty space. - */ -#define SLEG_CONDNULL(length, from, to) SaveLoad {"", SL_NULL, SLE_FILE_U8 | SLE_VAR_NULL, length, from, to, 0, nullptr, 0, nullptr} - /** * Field name where the real SaveLoad can be located. * @param name The name of the field. diff --git a/src/table/settings.h.preamble b/src/table/settings.h.preamble index 9641c24cea..032714bafe 100644 --- a/src/table/settings.h.preamble +++ b/src/table/settings.h.preamble @@ -43,9 +43,7 @@ static size_t ConvertLandscape(const char *value); * These are actually normal numbers, only bitmasked. In MMANY several bits can * be set, in the other only one. * If nothing fits you, you can use the GENERAL macros, but it exposes the - * internal structure somewhat so it needs a little looking. There are _NULL() - * macros as well, these fill up space so you can add more settings there (in - * place) and you DON'T have to increase the savegame version. + * internal structure somewhat so it needs a little looking. * * While reading values from openttd.cfg, some values may not be converted * properly, for any kind of reasons. In order to allow a process of self-cleaning @@ -76,9 +74,6 @@ static size_t ConvertLandscape(const char *value); #define SDTG_MMANY(name, type, flags, var, def, full, str, strhelp, strval, pre_check, post_callback, from, to, cat, extra, startup)\ NSD(ManyOfMany, SLEG_GENERAL(#var, SL_VAR, var, type, 1, from, to, extra), name, flags, startup, def, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr) -#define SDTG_NULL(length, from, to)\ - NSD(Null, SLEG_NULL(length, from, to)) - /* Macros for various objects to go in the configuration file. * This section is for structures where their various members are saved */ #define SDT_VAR(base, var, type, flags, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, cat, extra, startup)\ @@ -99,9 +94,6 @@ static size_t ConvertLandscape(const char *value); #define SDT_MMANY(base, var, type, flags, def, full, str, pre_check, post_callback, strhelp, strval, from, to, cat, extra, startup)\ NSD(ManyOfMany, SLE_GENERAL(SL_VAR, base, var, type, 1, from, to, extra), #var, flags, startup, def, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr) -#define SDT_NULL(length, from, to)\ - NSD(Null, SLE_CONDNULL(length, from, to)) - #define SDTC_VAR(var, type, flags, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, cat, extra, startup)\ SDTG_VAR(#var, type, flags, _settings_client.var, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, cat, extra, startup) From 9643a1b80ac9d5c2e3b2781e7536de874ee3f2bb Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Tue, 15 Jun 2021 14:54:10 +0200 Subject: [PATCH 10/42] Doc: explain the binary structure of our (new) savegames --- docs/savegame_format.md | 175 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 docs/savegame_format.md diff --git a/docs/savegame_format.md b/docs/savegame_format.md new file mode 100644 index 0000000000..e4e2e40005 --- /dev/null +++ b/docs/savegame_format.md @@ -0,0 +1,175 @@ +# OpenTTD's Savegame Format + +Last updated: 2021-06-15 + +## Outer container + +Savegames for OpenTTD start with an outer container, to contain the compressed data for the rest of the savegame. + +`[0..3]` - The first four bytes indicate what compression is used. +In ASCII, these values are possible: + +- `OTTD` - Compressed with LZO (deprecated, only really old savegames would use this). +- `OTTN` - No compression. +- `OTTZ` - Compressed with zlib. +- `OTTX` - Compressed with LZMA. + +`[4..5]` - The next two bytes indicate which savegame version used. + +`[6..7]` - The next two bytes can be ignored, and were only used in really old savegames. + +`[8..N]` - Next follows a binary blob which is compressed with the indicated compression algorithm. + +The rest of this document talks about this decompressed blob of data. + +## Data types + +The savegame is written in Big Endian, so when we talk about a 16-bit unsigned integer (`uint16`), we mean it is stored in Big Endian. + +The following types are valid: + +- `1` - `int8` / `SLE_FILE_I8` -8-bit signed integer +- `2` - `uint8` / `SLE_FILE_U8` - 8-bit unsigned integer +- `3` - `int16` / `SLE_FILE_I16` - 16-bit signed integer +- `4` - `uint16` / `SLE_FILE_U16` - 16-bit unsigned integer +- `5` - `int32` / `SLE_FILE_I32` - 32-bit signed integer +- `6` - `uint32` / `SLE_FILE_U32` - 32-bit unsigned integer +- `7` - `int64` / `SLE_FILE_I64` - 64-bit signed integer +- `8` - `uint64` / `SLE_FILE_U64` - 64-bit unsigned integer +- `9` - `StringID` / `SLE_FILE_STRINGID` - a StringID inside the OpenTTD's string table +- `10` - `str` / `SLE_FILE_STRING` - a string (prefixed with a length-field) +- `11` - `struct` / `SLE_FILE_STRUCT` - a struct + +### Gamma value + +There is also a field-type called `gamma`. +This is most often used for length-fields, and uses as few bytes as possible to store an integer. +For values <= 127, it uses a single byte. +For values > 127, it uses two bytes and sets the highest bit to high. +For values > 32767, it uses three bytes and sets the two highest bits to high. +And this continues till the value fits. +In a more visual approach: +``` + 0xxxxxxx + 10xxxxxx xxxxxxxx + 110xxxxx xxxxxxxx xxxxxxxx + 1110xxxx xxxxxxxx xxxxxxxx xxxxxxxx + 11110--- xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx +``` + +## Chunks + +Savegames for OpenTTD store their data in chunks. +Each chunk contains data for a certain part of the game, for example "Companies", "Vehicles", etc. + +`[0..3]` - Each chunk starts with four bytes to indicate the tag. +If the tag is `\x00\x00\x00\x00` it means the end of the savegame is reached. +An example of a valid tag is `PLYR` when looking at it via ASCII, which contains the information of all the companies. + +`[4..4]` - Next follows a byte where the lower 4 bits contain the type. +The possible valid types are: + +- `0` - `CH_RIFF` - This chunk is a binary blob. +- `1` - `CH_ARRAY` - This chunk is a list of items. +- `2` - `CH_SPARSE_ARRAY` - This chunk is a list of items. +- `3` - `CH_TABLE` - This chunk is self-describing list of items. +- `4` - `CH_SPARSE_TABLE` - This chunk is self-describing list of items. + +Now per type the format is (slightly) different. + +### CH_RIFF + +(since savegame version 295, this chunk type is only used for MAP-chunks, containing bit-information about each tile on the map) + +A `CH_RIFF` starts with an `uint24` which together with the upper-bits of the type defines the length of the chunk. +In pseudo-code: + +``` +type = read uint8 +if type == 0 + length = read uint24 + length |= ((type >> 4) << 24) +``` + +The next `length` bytes are part of the chunk. +What those bytes mean depends on the tag of the chunk; further details per chunk can be found in the source-code. + +### CH_ARRAY / CH_SPARSE_ARRAY + +(this chunk type is deprecated since savegame version 295 and is no longer in use) + +`[0..G1]` - A `CH_ARRAY` / `CH_SPARSE_ARRAY` starts with a `gamma`, indicating the size of the next item plus one. +If this size value is zero, it indicates the end of the list. +This indicates the full length of the next item minus one. +In psuedo-code: + +``` +loop + size = read gamma - 1 + if size == -1 + break loop + read bytes +``` + +`[]` - For `CH_ARRAY` there is an implicit index. +The loop starts at zero, and every iteration adds one to the index. +For entries in the game that were not allocated, the `size` will be zero. + +`[G1+1..G2]` - For `CH_SPARSE_ARRAY` there is an explicit index. +The `gamma` following the size indicates the index. + +The content of the item is a binary blob, and similar to `CH_RIFF`, it depends on the tag of the chunk what it means. +Please check the source-code for further details. + +### CH_TABLE / CH_SPARSE_TABLE + +(this chunk type only exists since savegame version 295) + +Both `CH_TABLE` and `CH_SPARSE_TABLE` are very similar to `CH_ARRAY` / `CH_SPARSE_ARRAY` respectively. +The only change is that the chunk starts with a header. +This header describes the chunk in details; with the header you know the meaning of each byte in the binary blob that follows. + +`[0..G]` - The header starts with a `gamma` to indicate the size of all the headers in this chunk plus one. +If this size value is zero, it means there is no header, which should never be the case. + +Next follows a list of `(type, key)` pairs: + +- `[0..0]` - Type of the field. +- `[1..G]` - `gamma` to indicate length of key. +- `[G+1..N]` - Key (in UTF-8) of the field. + +If at any point `type` is zero, the list stops (and no `key` follows). + +The `type`'s lower 4 bits indicate the data-type (see chapter above). +The `type`'s 5th bit (so `0x10`) indicates if the field is a list, and if this field in every record starts with a `gamma` to indicate how many times the `type` is repeated. + +If the `type` indicates either a `struct` or `str`, the `0x10` flag is also always set. + +As the savegame format allows (list of) structs in structs, if any `struct` type is found, this header will be followed by a header of that struct. +This nesting of structs is stored depth-first, so given this table: + +``` +type | key +----------------- +uint8 | counter +struct | substruct1 +struct | substruct2 +``` + +With `substruct1` being like: + +``` +type | key +----------------- +uint8 | counter +struct | substruct3 +``` + +The headers will be, in order: `table`, `substruct1`, `substruct3`, `substruct2`, each ending with a `type` is zero field. + +After reading all the fields of all the headers, there is a list of records. +To read this, see `CH_ARRAY` / `CH_SPARSE_ARRAY` for details. + +As each `type` has a well defined length, you can read the records even without knowing anything about the chunk-tag yourself. + +Do remember, that if the `type` had the `0x10` flag active, the field in the record first has a `gamma` to indicate how many times that `type` is repeated. From 4e645ce749904f736ccf2b5b9d400240ea420833 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Fri, 18 Jun 2021 13:27:59 +0200 Subject: [PATCH 11/42] Codechange: using "until" in function names can be confusing IsSavegameVersionUntil() did a [0, N] check, not [0, N) as the name suggests. Until can be a confusing word, where people consider it to be including the upperbound. Dictionary states it means "before", excluding the upperbound. There are long debates about who is right. So, simply remove away from this ambiguity, and call it "before" and "before or at". This makes the world easier for everyone. --- src/saveload/afterload.cpp | 2 +- src/saveload/saveload.h | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 83f3c6fc65..df1b4e44f1 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3106,7 +3106,7 @@ bool AfterLoadGame() } } - if (IsSavegameVersionUntil(SLV_ENDING_YEAR)) { + if (IsSavegameVersionBeforeOrAt(SLV_ENDING_YEAR)) { /* Update station docking tiles. Was only needed for pre-SLV_MULTITLE_DOCKS * savegames, but a bug in docking tiles touched all savegames between * SLV_MULTITILE_DOCKS and SLV_ENDING_YEAR. */ diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 77588a9f85..e4318c0114 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -618,14 +618,14 @@ typedef void *SaveLoadAddrProc(void *base, size_t extra); /** SaveLoad type struct. Do NOT use this directly but use the SLE_ macros defined just below! */ struct SaveLoad { std::string name; ///< Name of this field (optional, used for tables). - SaveLoadType cmd; ///< the action to take with the saved/loaded type, All types need different action - VarType conv; ///< type of the variable to be saved, int - uint16 length; ///< (conditional) length of the variable (eg. arrays) (max array size is 65536 elements) - SaveLoadVersion version_from; ///< save/load the variable starting from this savegame version - SaveLoadVersion version_to; ///< save/load the variable until this savegame version - size_t size; ///< the sizeof size. - SaveLoadAddrProc *address_proc; ///< callback proc the get the actual variable address in memory - size_t extra_data; ///< extra data for the callback proc + SaveLoadType cmd; ///< The action to take with the saved/loaded type, All types need different action. + VarType conv; ///< Type of the variable to be saved; this field combines both FileVarType and MemVarType. + uint16 length; ///< (Conditional) length of the variable (eg. arrays) (max array size is 65536 elements). + SaveLoadVersion version_from; ///< Save/load the variable starting from this savegame version. + SaveLoadVersion version_to; ///< Save/load the variable before this savegame version. + size_t size; ///< The sizeof size. + SaveLoadAddrProc *address_proc; ///< Callback proc the get the actual variable address in memory. + size_t extra_data; ///< Extra data for the callback proc. std::shared_ptr handler; ///< Custom handler for Save/Load procs. }; @@ -641,7 +641,7 @@ struct SaveLoadCompat { std::string name; ///< Name of the field. uint16 length; ///< Length of the NULL field. SaveLoadVersion version_from; ///< Save/load the variable starting from this savegame version. - SaveLoadVersion version_to; ///< Save/load the variable until this savegame version. + SaveLoadVersion version_to; ///< Save/load the variable before this savegame version. }; /** @@ -1001,7 +1001,7 @@ static inline bool IsSavegameVersionBefore(SaveLoadVersion major, byte minor = 0 * @param major Major number of the version to check against. * @return Savegame version is at most the specified version. */ -static inline bool IsSavegameVersionUntil(SaveLoadVersion major) +static inline bool IsSavegameVersionBeforeOrAt(SaveLoadVersion major) { extern SaveLoadVersion _sl_version; return _sl_version <= major; From 3e3049fd0e4414225d640a379b894ac72cb119c1 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sat, 19 Jun 2021 11:18:30 +0200 Subject: [PATCH 12/42] Codechange: make savegame-version checks more obvious in SlCompanyLiveries::Load num_liveries indirectly contained the same information, but this makes reading these things pretty difficult. So use IsSavegameVersionBefore() like everywhere else instead. --- src/saveload/company_sl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 27fb2cf375..0738688653 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -423,14 +423,14 @@ public: } } - if (num_liveries < LS_END) { + if (IsSavegameVersionBefore(SLV_85)) { /* We want to insert some liveries somewhere in between. This means some have to be moved. */ memmove(&c->livery[LS_FREIGHT_WAGON], &c->livery[LS_PASSENGER_WAGON_MONORAIL], (LS_END - LS_FREIGHT_WAGON) * sizeof(c->livery[0])); c->livery[LS_PASSENGER_WAGON_MONORAIL] = c->livery[LS_MONORAIL]; c->livery[LS_PASSENGER_WAGON_MAGLEV] = c->livery[LS_MAGLEV]; } - if (num_liveries == LS_END - 4) { + if (IsSavegameVersionBefore(SLV_63)) { /* Copy bus/truck liveries over to trams */ c->livery[LS_PASSENGER_TRAM] = c->livery[LS_BUS]; c->livery[LS_FREIGHT_TRAM] = c->livery[LS_TRUCK]; From 1d9912134df71a0adee5de92b83b9bb361f1f151 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Mon, 28 Jun 2021 12:47:04 +0200 Subject: [PATCH 13/42] Doc: guidelines for network-compatible patch-packs that want to add fields to existing chunks --- docs/savegame_format.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/savegame_format.md b/docs/savegame_format.md index e4e2e40005..d0731cbbaa 100644 --- a/docs/savegame_format.md +++ b/docs/savegame_format.md @@ -173,3 +173,14 @@ To read this, see `CH_ARRAY` / `CH_SPARSE_ARRAY` for details. As each `type` has a well defined length, you can read the records even without knowing anything about the chunk-tag yourself. Do remember, that if the `type` had the `0x10` flag active, the field in the record first has a `gamma` to indicate how many times that `type` is repeated. + +#### Guidelines for network-compatible patch-packs + +For network-compatible patch-packs (client-side patches that can play together with unpatched clients) we advise to prefix the field-name with `__` when introducing new fields to an existing chunk. + +Example: you have an extra setting called `auto_destroy_rivers` you want to store in the savegame for your patched client called `mypp`. +We advise you to call this setting `__mypp_auto_destroy_rivers` in the settings chunk. + +Doing it this way ensures that a savegame created by these patch-packs can still safely be loaded by unpatched clients. +They will simply ignore the field and continue loading the savegame as usual. +The prefix is strongly advised to avoid conflicts with future-settings in an unpatched client or conflicts with other patch-packs. From 979783f90e9c5939e645448cf9aac01f86c37fc9 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Sat, 3 Jul 2021 08:03:33 +0200 Subject: [PATCH 14/42] Codechange: replace InjectDParam/ShiftParameters by setting the right parameter values in the first place --- src/strings.cpp | 19 ------------------- src/strings_func.h | 4 ---- src/subsidy.cpp | 24 ++++++++++++------------ src/subsidy_func.h | 2 +- 4 files changed, 13 insertions(+), 36 deletions(-) diff --git a/src/strings.cpp b/src/strings.cpp index 6e39f77328..423e2ebf09 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -83,16 +83,6 @@ int64 StringParameters::GetInt64(WChar type) return this->data[this->offset++]; } -/** - * Shift all data in the data array by the given amount to make - * room for some extra parameters. - */ -void StringParameters::ShiftParameters(uint amount) -{ - assert(amount <= this->num_param); - MemMoveT(this->data + amount, this->data, this->num_param - amount); -} - /** * Set DParam n to some number that is suitable for string size computations. * @param n Index of the string parameter. @@ -319,15 +309,6 @@ void SetDParamStr(uint n, const std::string &str) SetDParamStr(n, str.c_str()); } -/** - * Shift the string parameters in the global string parameter array by \a amount positions, making room at the beginning. - * @param amount Number of positions to shift. - */ -void InjectDParam(uint amount) -{ - _global_string_params.ShiftParameters(amount); -} - /** * Format a number into a string. * @param buff the buffer to write to diff --git a/src/strings_func.h b/src/strings_func.h index 11f41d7381..e9b9f81598 100644 --- a/src/strings_func.h +++ b/src/strings_func.h @@ -122,8 +122,6 @@ public: return (int32)this->GetInt64(type); } - void ShiftParameters(uint amount); - /** Get a pointer to the current element in the data array. */ uint64 *GetDataPointer() const { @@ -179,8 +177,6 @@ const char *GetStringPtr(StringID string); uint ConvertKmhishSpeedToDisplaySpeed(uint speed); uint ConvertDisplaySpeedToKmhishSpeed(uint speed); -void InjectDParam(uint amount); - /** * Set a string parameter \a v at index \a n in a given array \a s. * @param s Array of string parameters. diff --git a/src/subsidy.cpp b/src/subsidy.cpp index 28cb0d3ccb..0b1c1a721f 100644 --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -47,8 +47,7 @@ void Subsidy::AwardTo(CompanyID company) NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME)); /* Add a news item */ - std::pair reftype = SetupSubsidyDecodeParam(this, SubsidyDecodeParamType::NewsAwarded); - InjectDParam(1); + std::pair reftype = SetupSubsidyDecodeParam(this, SubsidyDecodeParamType::NewsAwarded, 1); SetDParamStr(0, company_name->string); AddNewsItem( @@ -67,9 +66,10 @@ void Subsidy::AwardTo(CompanyID company) * Setup the string parameters for printing the subsidy at the screen, and compute the news reference for the subsidy. * @param s %Subsidy being printed. * @param mode Type of subsidy news message to decide on parameter format. + * @param parameter_offset The location/index in the String DParams to start decoding the subsidy's parameters. Defaults to 0. * @return Reference of the subsidy in the news system. */ -std::pair SetupSubsidyDecodeParam(const Subsidy *s, SubsidyDecodeParamType mode) +std::pair SetupSubsidyDecodeParam(const Subsidy *s, SubsidyDecodeParamType mode, uint parameter_offset) { NewsReferenceType reftype1 = NR_NONE; NewsReferenceType reftype2 = NR_NONE; @@ -77,40 +77,40 @@ std::pair SetupSubsidyDecodeParam(const Su /* Choose whether to use the singular or plural form of the cargo name based on how we're printing the subsidy */ const CargoSpec *cs = CargoSpec::Get(s->cargo_type); if (mode == SubsidyDecodeParamType::Gui || mode == SubsidyDecodeParamType::NewsWithdrawn) { - SetDParam(0, cs->name); + SetDParam(parameter_offset, cs->name); } else { - SetDParam(0, cs->name_single); + SetDParam(parameter_offset, cs->name_single); } switch (s->src_type) { case ST_INDUSTRY: reftype1 = NR_INDUSTRY; - SetDParam(1, STR_INDUSTRY_NAME); + SetDParam(parameter_offset + 1, STR_INDUSTRY_NAME); break; case ST_TOWN: reftype1 = NR_TOWN; - SetDParam(1, STR_TOWN_NAME); + SetDParam(parameter_offset + 1, STR_TOWN_NAME); break; default: NOT_REACHED(); } - SetDParam(2, s->src); + SetDParam(parameter_offset + 2, s->src); switch (s->dst_type) { case ST_INDUSTRY: reftype2 = NR_INDUSTRY; - SetDParam(4, STR_INDUSTRY_NAME); + SetDParam(parameter_offset + 4, STR_INDUSTRY_NAME); break; case ST_TOWN: reftype2 = NR_TOWN; - SetDParam(4, STR_TOWN_NAME); + SetDParam(parameter_offset + 4, STR_TOWN_NAME); break; default: NOT_REACHED(); } - SetDParam(5, s->dst); + SetDParam(parameter_offset + 5, s->dst); /* If the subsidy is being offered or awarded, the news item mentions the subsidy duration. */ if (mode == SubsidyDecodeParamType::NewsOffered || mode == SubsidyDecodeParamType::NewsAwarded) { - SetDParam(7, _settings_game.difficulty.subsidy_duration); + SetDParam(parameter_offset + 7, _settings_game.difficulty.subsidy_duration); } return std::pair(reftype1, reftype2); diff --git a/src/subsidy_func.h b/src/subsidy_func.h index 5cd7a31181..a33c5d8bfa 100644 --- a/src/subsidy_func.h +++ b/src/subsidy_func.h @@ -17,7 +17,7 @@ #include "news_type.h" #include "subsidy_base.h" -std::pair SetupSubsidyDecodeParam(const struct Subsidy *s, SubsidyDecodeParamType mode); +std::pair SetupSubsidyDecodeParam(const struct Subsidy *s, SubsidyDecodeParamType mode, uint parameter_offset = 0); void DeleteSubsidyWith(SourceType type, SourceID index); bool CheckSubsidised(CargoID cargo_type, CompanyID company, SourceType src_type, SourceID src, const Station *st); void RebuildSubsidisedSourceAndDestinationCache(); From d38ad7d80ca592612ce7bc98e770e40ae778fd04 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Sat, 3 Jul 2021 08:12:13 +0200 Subject: [PATCH 15/42] Cleanup: remove declaration of undefined function --- src/subsidy_func.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/subsidy_func.h b/src/subsidy_func.h index a33c5d8bfa..89bf0f1fe2 100644 --- a/src/subsidy_func.h +++ b/src/subsidy_func.h @@ -21,6 +21,5 @@ std::pair SetupSubsidyDecodeParam(const st void DeleteSubsidyWith(SourceType type, SourceID index); bool CheckSubsidised(CargoID cargo_type, CompanyID company, SourceType src_type, SourceID src, const Station *st); void RebuildSubsidisedSourceAndDestinationCache(); -void DeleteSubsidy(struct Subsidy *s); #endif /* SUBSIDY_FUNC_H */ From 0fa200756001078d5222f6e17248d1d67a828c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Sat, 3 Jul 2021 18:26:24 +0200 Subject: [PATCH 16/42] Fix cdb3dd049: GOAL chunk was not using the header for loading (#9409) --- src/saveload/goal_sl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/saveload/goal_sl.cpp b/src/saveload/goal_sl.cpp index 68ba3597a2..7e2cad491e 100644 --- a/src/saveload/goal_sl.cpp +++ b/src/saveload/goal_sl.cpp @@ -42,7 +42,7 @@ static void Load_GOAL() int index; while ((index = SlIterateArray()) != -1) { Goal *s = new (index) Goal(); - SlObject(s, _goals_desc); + SlObject(s, slt); } } From 05bdfadcb67014c4eaf35cc25e698620f9547558 Mon Sep 17 00:00:00 2001 From: translators Date: Sat, 3 Jul 2021 18:49:50 +0000 Subject: [PATCH 17/42] Update: Translations from eints norwegian (bokmal): 1 change by Anolitt japanese: 1 change by scabtert --- src/lang/japanese.txt | 1 + src/lang/norwegian_bokmal.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index ddb3ceb50b..d86b8134a0 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -1198,6 +1198,7 @@ STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :車両故障: { STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT :点検が不十分な車両が故障する頻度を設定します STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER :助成金の乗数: {STRING} STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :助成金対象の路線に対して、通常の輸送相場の何倍が支払われるかを設定します +STR_CONFIG_SETTING_SUBSIDY_DURATION :助成期間: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_COSTS :建設費: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :建設・購入費用のレベルを設定します STR_CONFIG_SETTING_RECESSIONS :景気後退: {STRING} diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 2d14178c1f..796d75ecca 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -2156,6 +2156,7 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nytt firma) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Opprett et nytt firma og bli med i det STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Dette er deg STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Dette er verten for spillet +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" s} / {NUM} firma{P et er} STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Spark STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Utesteng From 10d8c172366999808bf30d8a1b37f07074c93fa9 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 4 Jul 2021 15:57:04 +0200 Subject: [PATCH 18/42] Codechange: Add CMake source group for the saveload compat tables. While at it, fix the not-working OpenGL sub-group. --- cmake/MSVCFilters.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/MSVCFilters.cmake b/cmake/MSVCFilters.cmake index e8026eee3c..db53fc2258 100644 --- a/cmake/MSVCFilters.cmake +++ b/cmake/MSVCFilters.cmake @@ -11,12 +11,13 @@ source_group("Network Core" REGULAR_EXPRESSION "src/network/core/") source_group("OSX" REGULAR_EXPRESSION "src/os/macosx/") source_group("Pathfinder" REGULAR_EXPRESSION "src/pathfinder/") source_group("Save/Load handlers" REGULAR_EXPRESSION "src/saveload/") +source_group("Save/Load handlers\\Compat" REGULAR_EXPRESSION "src/saveload/compat/") source_group("Sound" REGULAR_EXPRESSION "src/sound/") source_group("Sprite loaders" REGULAR_EXPRESSION "src/spriteloader/") source_group("Squirrel" REGULAR_EXPRESSION "src/3rdparty/squirrel/squirrel/") source_group("Tables" REGULAR_EXPRESSION "src/table/") source_group("Video" REGULAR_EXPRESSION "src/video/") -source_group("Video/GL" REGULAR_EXPRESSION "src/3rdparty/opengl/") +source_group("Video\\GL" REGULAR_EXPRESSION "src/3rdparty/opengl/") source_group("Widgets" REGULAR_EXPRESSION "src/widgets/") source_group("Windows files" REGULAR_EXPRESSION "src/os/windows/|\.rc$") From 511c1081af039e1b41b09add27d454f7daeb69b2 Mon Sep 17 00:00:00 2001 From: translators Date: Sun, 4 Jul 2021 18:49:29 +0000 Subject: [PATCH 19/42] Update: Translations from eints catalan: 1 change by J0anJosep --- src/lang/catalan.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 0bf9a01db5..8e2e5b8e4a 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -2153,6 +2153,7 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Companyia nova STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Crea una companyia nova i uniu-vos. STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Aquest ets tu. STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Aquest és l'hoste de la partida. +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} companyi{P a es} STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Treu STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Expulsa From faea943a9bc88a188ad15f65739b5dcfaa238dfe Mon Sep 17 00:00:00 2001 From: translators Date: Mon, 5 Jul 2021 18:50:45 +0000 Subject: [PATCH 20/42] Update: Translations from eints hindi: 26 changes by ritwikraghav14 --- src/lang/hindi.txt | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/lang/hindi.txt b/src/lang/hindi.txt index 1fabeb2892..0a4246e00f 100644 --- a/src/lang/hindi.txt +++ b/src/lang/hindi.txt @@ -62,6 +62,7 @@ STR_COLOUR_RED :लाल # Units used in OpenTTD +STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp @@ -98,9 +99,11 @@ STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :पिछले STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}ध्वनि/संगीत विकल्प # Extra tooltips for the scenario editor toolbar +STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}मानचित्र, नगर निर्देशिका दिखायें ############ range for SE file menu starts STR_SCENEDIT_FILE_MENU_SEPARATOR : +STR_SCENEDIT_FILE_MENU_QUIT :निकास ############ range for SE file menu starts ############ range for settings menu starts @@ -184,6 +187,7 @@ STR_COMPANY_LEAGUE_COMPANY_NAME :{ORANGE}{COMPAN # Performance detail window ############ Those following lines need to be in this order!! STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}वाहन: +STR_PERFORMANCE_DETAIL_CARGO :{BLACK}माल : ############ End of order list # Music window @@ -211,6 +215,7 @@ STR_STATUSBAR_PAUSED_LINK_GRAPH :{ORANGE}* * ठ STR_NEWS_CUSTOM_ITEM :{BIG_FONT}{BLACK}{STRING} +STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL :{BIG_FONT}{BLACK}नागरिक हर्षित हैं . . .{}पहली माल ट्रैम {STATION} पर पहुँची है! @@ -220,6 +225,7 @@ STR_NEWS_COMPANY_LAUNCH_DESCRIPTION :{BIG_FONT}{BLAC +STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH :{BIG_FONT}{BLACK}{STRING}{INDUSTRY} के उत्पादन में {COMMA}% कमी आयी! # Order review system / warnings @@ -238,6 +244,7 @@ STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLAC ############ start of currency region STR_GAME_OPTIONS_CURRENCY_FIM :फिनलैंड मार्का (FIM) +STR_GAME_OPTIONS_CURRENCY_ISK :आइसलैंडिक क्रोना (ISK) STR_GAME_OPTIONS_CURRENCY_HKD :हाँग काँग डॉलर (एचकेडी) ############ end of currency region @@ -338,6 +345,7 @@ STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS :दुर्घ STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :नगर में माल उत्पादन: {STRING} STR_CONFIG_SETTING_SOFT_LIMIT_VALUE :{COMMA} @@ -353,11 +361,13 @@ STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_IN_2X :२x STR_CONFIG_SETTING_INTERFACE_GENERAL :{ORANGE}सामान्य +STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS_HELPTEXT :नौकाओं द्वारा उपयोग किया जाने वाला पथान्वेषी # Config errors # Video initalization errors +STR_VIDEO_DRIVER_ERROR :{WHITE}वीडियो विन्यास में त्रुटि... # Intro window @@ -366,6 +376,7 @@ STR_INTRO_PLAY_HEIGHTMAP :{BLACK}उभ STR_INTRO_TOOLTIP_SCENARIO_EDITOR :{BLACK}अपनी इच्छानुसार एक क्रीड़ा-विश्व/परिदृश्य बनायें +STR_INTRO_TOOLTIP_TEMPERATE :{BLACK}'समशीतोष्ण' जलवायु वाला क्षेत्र चुनें @@ -394,6 +405,7 @@ STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT :{BLACK}{COMMA}x +STR_NETWORK_SERVER_LIST_REFRESH_TOOLTIP :{BLACK}सर्वर की जानकारी अद्यतन करें @@ -508,11 +520,13 @@ STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}नह # Airport construction window +STR_AIRPORT_INTERCONTINENTAL :अंतरमहाद्वीपीय STR_AIRPORT_CLASS_SMALL :लघु विमानतल # Landscaping toolbar +STR_LANDSCAPING_TOOLBAR :{WHITE}भूदृश्य निर्माण # Object construction window @@ -541,6 +555,7 @@ STR_INDUSTRY_CARGOES_SELECT_INDUSTRY :{BLACK}उद STR_LAI_CLEAR_DESCRIPTION_BARE_LAND :रिक्त भूमि +STR_LAI_ROAD_DESCRIPTION_TREE_LINED_ROAD :वृक्ष आच्छादित सड़क # Houses come directly from their building names @@ -591,6 +606,7 @@ STR_GENERATION_PROGRESS_NUM :{BLACK}{NUM} / +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :मूल (D) # NewGRF save preset window @@ -640,6 +656,7 @@ STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}फै # Town local authority window +STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN :लघु विज्ञापन अभियान # Goal window @@ -653,6 +670,7 @@ STR_GOALS_PROGRESS_COMPLETE :{GREEN}{STRING} ############ End of Goal Question button list # Subsidies window +STR_SUBSIDIES_OFFERED_TITLE :{BLACK}इन सेवाओं के लिये अनुदान प्रस्तावित : # Story book window STR_STORY_BOOK_TITLE :{YELLOW}{STRING} @@ -753,6 +771,7 @@ STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}भा STR_BUY_VEHICLE_ROAD_VEHICLE_HIDE_TOGGLE_BUTTON :{BLACK}छिपायें +STR_BUY_VEHICLE_SHIP_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}नौका प्रकार को छिपायें/दिखायें # Depot window @@ -803,6 +822,7 @@ STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE +STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP :{BLACK}वर्तमान ट्रेन व्यवहार - ट्रेन रोकने/चलाने के लिये क्लिक करें # Messages in the start stop button in the vehicle view @@ -823,6 +843,7 @@ STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE # Extra buttons for train details windows +STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE}{BLACK} निर्माण: {LTBLUE}{NUM}{BLACK} मूल्य: {LTBLUE}{CURRENCY_LONG} @@ -1003,6 +1024,7 @@ STR_ERROR_CAN_T_RENAME_SHIP :{WHITE}जह +STR_ERROR_CAN_T_SELL_TRAIN :{WHITE}रेल वाहन नहीं बेच सकते... @@ -1013,6 +1035,7 @@ STR_ERROR_CAN_T_RENAME_SHIP :{WHITE}जह # Order related errors +STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... वाहन सभी स्टेशनों तक नहीं जा सकता # Timetable related errors @@ -1049,10 +1072,12 @@ STR_SV_STNAME_WAYPOINT :{STRING} # Vehicle names STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COAL_CAR :कोयला वाहन STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FRUIT_TRUCK :फल वाहन +STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_X2001_ELECTRIC :'X2001' (विद्युतीय) STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOY_VAN :खिलौनों का डब्बा STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_BUBBLE_VAN :बबल वैन STR_VEHICLE_NAME_ROAD_VEHICLE_PLODDYPHUT_MKIII_BUS :प्लॉडीपीहट एमके३ बस STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_ARMORED_TRUCK :फोस्टर कवचयुक्त ट्रक +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_CANDY_TRUCK :पावरनोट मिष्ठान्न ट्रक STR_VEHICLE_NAME_AIRCRAFT_BAKEWELL_COTSWALD_LB_3 :बेकवेल कॉट्सवॉल्ड एलबी-३ STR_VEHICLE_NAME_AIRCRAFT_BAKEWELL_LUCKETT_LB_9 :बेकवेल लकेट एलबी-९ STR_VEHICLE_NAME_AIRCRAFT_BAKEWELL_LUCKETT_LB80 :बेकवेल लकेट एलबी८० @@ -1090,6 +1115,7 @@ STR_COMPANY_NAME :{COMPANY} STR_COMPANY_NAME_COMPANY_NUM :{COMPANY} {COMPANY_NUM} STR_DEPOT_NAME :{DEPOT} STR_ENGINE_NAME :{ENGINE} +STR_HIDDEN_ENGINE_NAME :{ENGINE} (प्रच्छन्न) STR_GROUP_NAME :{GROUP} STR_INDUSTRY_NAME :{INDUSTRY} STR_PRESIDENT_NAME :{PRESIDENT_NAME} From 8913ae9ba8c37e5724d19cdad93161e939ab5ff6 Mon Sep 17 00:00:00 2001 From: translators Date: Tue, 6 Jul 2021 18:50:32 +0000 Subject: [PATCH 21/42] Update: Translations from eints portuguese (brazilian): 1 change by Vimerum --- src/lang/brazilian_portuguese.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index cc000ef756..74f9276fb1 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -2153,6 +2153,7 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nova empresa) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Cria uma nova empresa e se une a ela STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Esse é você STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Esse é o hospedeiro do jogo +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s} / {NUM} empresa{P "" s} STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Expulsar STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Banir From ddafc0de054eb60bdeac4b1980c9021928b04511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Tue, 6 Jul 2021 21:09:08 +0200 Subject: [PATCH 22/42] Fix 39e90ec: Integers for scripts are 64bit, but saved as 32bit (#9415) --- src/saveload/saveload.h | 1 + src/script/api/script_controller.hpp | 4 ++-- src/script/script_instance.cpp | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index e4318c0114..34dea3cb1d 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -335,6 +335,7 @@ enum SaveLoadVersion : uint16 { SLV_RIFF_TO_ARRAY, ///< 294 PR#9375 Changed many CH_RIFF chunks to CH_ARRAY chunks. SLV_TABLE_CHUNKS, ///< 295 PR#9322 Introduction of CH_TABLE and CH_SPARSE_TABLE. + SLV_SCRIPT_INT64, ///< 296 PR#9415 SQInteger is 64bit but was saved as 32bit. SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/script/api/script_controller.hpp b/src/script/api/script_controller.hpp index c6b07232db..992a9ebf22 100644 --- a/src/script/api/script_controller.hpp +++ b/src/script/api/script_controller.hpp @@ -39,7 +39,7 @@ * data from the loaded game. * - Finally, #Start is called to start execution of the script. * - * See also http://wiki.openttd.org/AI:Save/Load for more details. + * See also https://wiki.openttd.org/en/Development/Script/Save%20and%20Load for more details. * * @api ai game */ @@ -91,7 +91,7 @@ public: * notified of the call. To avoid race-conditions between #Save and the * other script code, change variables directly after a #Sleep, it is * very unlikely, to get interrupted at that point in the execution. - * See also http://wiki.openttd.org/AI:Save/Load for more details. + * See also https://wiki.openttd.org/en/Development/Script/Save%20and%20Load for more details. * * @note No other information is saved than the table returned by #Save. * For example all pending events are lost as soon as the game is loaded. diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp index 1d57383a9f..3f611e66c6 100644 --- a/src/script/script_instance.cpp +++ b/src/script/script_instance.cpp @@ -364,8 +364,8 @@ static const SaveLoad _script_byte[] = { SQInteger res; sq_getinteger(vm, index, &res); if (!test) { - int value = (int)res; - SlCopy(&value, 1, SLE_INT32); + int64 value = (int64)res; + SlCopy(&value, 1, SLE_INT64); } return true; } @@ -564,8 +564,8 @@ bool ScriptInstance::IsPaused() SlObject(nullptr, _script_byte); switch (_script_sl_byte) { case SQSL_INT: { - int value; - SlCopy(&value, 1, SLE_INT32); + int64 value; + SlCopy(&value, 1, IsSavegameVersionBefore(SLV_SCRIPT_INT64) ? SLE_INT32 : SLE_INT64); if (vm != nullptr) sq_pushinteger(vm, (SQInteger)value); return true; } From b4aedc8bee97218febda75889ff2ef50f70a2439 Mon Sep 17 00:00:00 2001 From: glx22 Date: Tue, 6 Jul 2021 03:23:05 +0200 Subject: [PATCH 23/42] Codechange: ensure xxx_setting_tables are initialised after their content --- src/settings.cpp | 54 +++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/src/settings.cpp b/src/settings.cpp index 837c6ae024..64ce478289 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -104,24 +104,36 @@ typedef span SettingTable; * - _win32_settings * As such, they are not part of this list. */ -static const SettingTable _generic_setting_tables[] = { - _settings, - _network_settings, -}; +static auto &GenericSettingTables() +{ + static const SettingTable _generic_setting_tables[] = { + _settings, + _network_settings, + }; + return _generic_setting_tables; +} /** * List of all the private setting tables. */ -static const SettingTable _private_setting_tables[] = { - _network_private_settings, -}; +static auto &PrivateSettingTables() +{ + static const SettingTable _private_setting_tables[] = { + _network_private_settings, + }; + return _private_setting_tables; +} /** * List of all the secrets setting tables. */ -static const SettingTable _secrets_setting_tables[] = { - _network_secrets_settings, -}; +static auto &SecretSettingTables() +{ + static const SettingTable _secrets_setting_tables[] = { + _network_secrets_settings, + }; + return _secrets_setting_tables; +} typedef void SettingDescProc(IniFile &ini, const SettingTable &desc, const char *grpname, void *object, bool only_startup); typedef void SettingDescProcList(IniFile &ini, const char *grpname, StringList &list); @@ -1608,13 +1620,13 @@ static void HandleSettingDescs(IniFile &generic_ini, IniFile &private_ini, IniFi /* The name "patches" is a fallback, as every setting should sets its own group. */ - for (auto &table : _generic_setting_tables) { + for (auto &table : GenericSettingTables()) { proc(generic_ini, table, "patches", &_settings_newgame, only_startup); } - for (auto &table : _private_setting_tables) { + for (auto &table : PrivateSettingTables()) { proc(private_ini, table, "patches", &_settings_newgame, only_startup); } - for (auto &table : _secrets_setting_tables) { + for (auto &table : SecretSettingTables()) { proc(secrets_ini, table, "patches", &_settings_newgame, only_startup); } @@ -1721,12 +1733,12 @@ void SaveToConfig() generic_ini.RemoveGroup("server_bind_addresses"); generic_ini.RemoveGroup("servers"); generic_ini.RemoveGroup("bans"); - for (auto &table : _private_setting_tables) { + for (auto &table : PrivateSettingTables()) { RemoveEntriesFromIni(generic_ini, table); } /* Remove all settings from the generic ini that are now in the secrets ini. */ - for (auto &table : _secrets_setting_tables) { + for (auto &table : SecretSettingTables()) { RemoveEntriesFromIni(generic_ini, table); } } @@ -1903,15 +1915,15 @@ static const SettingDesc *GetCompanySettingFromName(std::string_view name) */ const SettingDesc *GetSettingFromName(const std::string_view name) { - for (auto &table : _generic_setting_tables) { + for (auto &table : GenericSettingTables()) { auto sd = GetSettingFromName(name, table); if (sd != nullptr) return sd; } - for (auto &table : _private_setting_tables) { + for (auto &table : PrivateSettingTables()) { auto sd = GetSettingFromName(name, table); if (sd != nullptr) return sd; } - for (auto &table : _secrets_setting_tables) { + for (auto &table : SecretSettingTables()) { auto sd = GetSettingFromName(name, table); if (sd != nullptr) return sd; } @@ -2168,13 +2180,13 @@ void IConsoleListSettings(const char *prefilter) { IConsolePrint(CC_HELP, "All settings with their current value:"); - for (auto &table : _generic_setting_tables) { + for (auto &table : GenericSettingTables()) { IConsoleListSettingsTable(table, prefilter); } - for (auto &table : _private_setting_tables) { + for (auto &table : PrivateSettingTables()) { IConsoleListSettingsTable(table, prefilter); } - for (auto &table : _secrets_setting_tables) { + for (auto &table : SecretSettingTables()) { IConsoleListSettingsTable(table, prefilter); } From 25ca6a75bc83df7224f56fc1ab22c4491f77649e Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Mon, 5 Jul 2021 17:46:38 +0200 Subject: [PATCH 24/42] Codechange: split off the settings table and all the callbacks from the main settings handling logic --- src/CMakeLists.txt | 2 + src/settings.cpp | 449 +---------------- src/settings_table.cpp | 473 ++++++++++++++++++ src/settings_table.h | 38 ++ src/table/settings/company_settings.ini | 2 +- src/table/settings/currency_settings.ini | 2 +- src/table/settings/gameopt_settings.ini | 7 +- src/table/settings/misc_settings.ini | 2 +- .../settings/network_private_settings.ini | 2 +- .../settings/network_secrets_settings.ini | 2 +- src/table/settings/network_settings.ini | 2 +- src/table/settings/settings.ini | 2 +- src/table/settings/win32_settings.ini | 2 +- src/table/settings/window_settings.ini | 2 +- 14 files changed, 529 insertions(+), 458 deletions(-) create mode 100644 src/settings_table.cpp create mode 100644 src/settings_table.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 801a92cb37..631eaf6dea 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -338,6 +338,8 @@ add_files( settings_gui.cpp settings_gui.h settings_internal.h + settings_table.h + settings_table.cpp settings_type.h ship.h ship_cmd.cpp diff --git a/src/settings.cpp b/src/settings.cpp index 64ce478289..a2ab8ae333 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -22,62 +22,31 @@ */ #include "stdafx.h" -#include #include -#include +#include "settings_table.h" +#include "debug.h" #include "currency.h" -#include "screenshot.h" #include "network/network.h" #include "network/network_func.h" -#include "settings_internal.h" #include "command_func.h" #include "console_func.h" -#include "pathfinder/pathfinder_type.h" #include "genworld.h" -#include "train.h" -#include "news_func.h" #include "window_func.h" -#include "sound_func.h" #include "company_func.h" #include "rev.h" -#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) -#include "fontcache.h" -#endif -#include "textbuf_gui.h" -#include "rail_gui.h" -#include "elrail_func.h" #include "error.h" -#include "town.h" -#include "video/video_driver.hpp" -#include "sound/sound_driver.hpp" -#include "music/music_driver.hpp" -#include "blitter/factory.hpp" -#include "base_media_base.h" #include "gamelog.h" #include "settings_func.h" #include "ini_type.h" #include "ai/ai_config.hpp" -#include "ai/ai.hpp" #include "game/game_config.hpp" -#include "game/game.hpp" -#include "ship.h" -#include "smallmap_gui.h" -#include "roadveh.h" +#include "newgrf_config.h" #include "fios.h" -#include "strings_func.h" -#include "vehicle_func.h" +#include "fileio_func.h" #include "saveload/compat/settings_sl_compat.h" -#include "void_map.h" -#include "station_base.h" - -#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) -#define HAS_TRUETYPE_FONT -#endif - #include "table/strings.h" -#include "table/settings.h" #include "safeguards.h" @@ -92,8 +61,6 @@ std::string _secrets_file; ///< Secrets configuration file of OpenTTD. typedef std::list ErrorList; static ErrorList _settings_error_list; ///< Errors while loading minimal settings. -typedef span SettingTable; - /** * List of all the generic setting tables. * @@ -865,227 +832,6 @@ const StringSettingDesc *SettingDesc::AsStringSetting() const return static_cast(this); } -/* Begin - Callback Functions for the various settings. */ - -/** Reposition the main toolbar as the setting changed. */ -static void v_PositionMainToolbar(int32 new_value) -{ - if (_game_mode != GM_MENU) PositionMainToolbar(nullptr); -} - -/** Reposition the statusbar as the setting changed. */ -static void v_PositionStatusbar(int32 new_value) -{ - if (_game_mode != GM_MENU) { - PositionStatusbar(nullptr); - PositionNewsMessage(nullptr); - PositionNetworkChatWindow(nullptr); - } -} - -/** - * Redraw the smallmap after a colour scheme change. - * @param p1 Callback parameter. - */ -static void RedrawSmallmap(int32 new_value) -{ - BuildLandLegend(); - BuildOwnerLegend(); - SetWindowClassesDirty(WC_SMALLMAP); -} - -static void StationSpreadChanged(int32 p1) -{ - InvalidateWindowData(WC_SELECT_STATION, 0); - InvalidateWindowData(WC_BUILD_STATION, 0); -} - -static void CloseSignalGUI(int32 new_value) -{ - if (new_value == 0) { - CloseWindowByClass(WC_BUILD_SIGNAL); - } -} - -static void UpdateConsists(int32 new_value) -{ - for (Train *t : Train::Iterate()) { - /* Update the consist of all trains so the maximum speed is set correctly. */ - if (t->IsFrontEngine() || t->IsFreeWagon()) t->ConsistChanged(CCF_TRACK); - } - InvalidateWindowClassesData(WC_BUILD_VEHICLE, 0); -} - -/* Check service intervals of vehicles, newvalue is value of % or day based servicing */ -static void UpdateAllServiceInterval(int32 new_value) -{ - bool update_vehicles; - VehicleDefaultSettings *vds; - if (_game_mode == GM_MENU || !Company::IsValidID(_current_company)) { - vds = &_settings_client.company.vehicle; - update_vehicles = false; - } else { - vds = &Company::Get(_current_company)->settings.vehicle; - update_vehicles = true; - } - - if (new_value != 0) { - vds->servint_trains = 50; - vds->servint_roadveh = 50; - vds->servint_aircraft = 50; - vds->servint_ships = 50; - } else { - vds->servint_trains = 150; - vds->servint_roadveh = 150; - vds->servint_aircraft = 100; - vds->servint_ships = 360; - } - - if (update_vehicles) { - const Company *c = Company::Get(_current_company); - for (Vehicle *v : Vehicle::Iterate()) { - if (v->owner == _current_company && v->IsPrimaryVehicle() && !v->ServiceIntervalIsCustom()) { - v->SetServiceInterval(CompanyServiceInterval(c, v->type)); - v->SetServiceIntervalIsPercent(new_value != 0); - } - } - } - - SetWindowClassesDirty(WC_VEHICLE_DETAILS); -} - -static bool CanUpdateServiceInterval(VehicleType type, int32 &new_value) -{ - VehicleDefaultSettings *vds; - if (_game_mode == GM_MENU || !Company::IsValidID(_current_company)) { - vds = &_settings_client.company.vehicle; - } else { - vds = &Company::Get(_current_company)->settings.vehicle; - } - - /* Test if the interval is valid */ - int32 interval = GetServiceIntervalClamped(new_value, vds->servint_ispercent); - return interval == new_value; -} - -static void UpdateServiceInterval(VehicleType type, int32 new_value) -{ - if (_game_mode != GM_MENU && Company::IsValidID(_current_company)) { - for (Vehicle *v : Vehicle::Iterate()) { - if (v->owner == _current_company && v->type == type && v->IsPrimaryVehicle() && !v->ServiceIntervalIsCustom()) { - v->SetServiceInterval(new_value); - } - } - } - - SetWindowClassesDirty(WC_VEHICLE_DETAILS); -} - -static void TrainAccelerationModelChanged(int32 new_value) -{ - for (Train *t : Train::Iterate()) { - if (t->IsFrontEngine()) { - t->tcache.cached_max_curve_speed = t->GetCurveSpeedLimit(); - t->UpdateAcceleration(); - } - } - - /* These windows show acceleration values only when realistic acceleration is on. They must be redrawn after a setting change. */ - SetWindowClassesDirty(WC_ENGINE_PREVIEW); - InvalidateWindowClassesData(WC_BUILD_VEHICLE, 0); - SetWindowClassesDirty(WC_VEHICLE_DETAILS); -} - -/** - * This function updates the train acceleration cache after a steepness change. - * @param new_value Unused new value of setting. - */ -static void TrainSlopeSteepnessChanged(int32 new_value) -{ - for (Train *t : Train::Iterate()) { - if (t->IsFrontEngine()) t->CargoChanged(); - } -} - -/** - * This function updates realistic acceleration caches when the setting "Road vehicle acceleration model" is set. - * @param new_value Unused new value of setting. - */ -static void RoadVehAccelerationModelChanged(int32 new_value) -{ - if (_settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL) { - for (RoadVehicle *rv : RoadVehicle::Iterate()) { - if (rv->IsFrontEngine()) { - rv->CargoChanged(); - } - } - } - - /* These windows show acceleration values only when realistic acceleration is on. They must be redrawn after a setting change. */ - SetWindowClassesDirty(WC_ENGINE_PREVIEW); - InvalidateWindowClassesData(WC_BUILD_VEHICLE, 0); - SetWindowClassesDirty(WC_VEHICLE_DETAILS); -} - -/** - * This function updates the road vehicle acceleration cache after a steepness change. - * @param new_value Unused new value of setting. - */ -static void RoadVehSlopeSteepnessChanged(int32 new_value) -{ - for (RoadVehicle *rv : RoadVehicle::Iterate()) { - if (rv->IsFrontEngine()) rv->CargoChanged(); - } -} - -static void TownFoundingChanged(int32 new_value) -{ - if (_game_mode != GM_EDITOR && _settings_game.economy.found_town == TF_FORBIDDEN) { - CloseWindowById(WC_FOUND_TOWN, 0); - } else { - InvalidateWindowData(WC_FOUND_TOWN, 0); - } -} - -static void ZoomMinMaxChanged(int32 new_value) -{ - extern void ConstrainAllViewportsZoom(); - ConstrainAllViewportsZoom(); - GfxClearSpriteCache(); - if (_settings_client.gui.zoom_min > _gui_zoom) { - /* Restrict GUI zoom if it is no longer available. */ - _gui_zoom = _settings_client.gui.zoom_min; - UpdateCursorSize(); - LoadStringWidthTable(); - } -} - -static void SpriteZoomMinChanged(int32 new_value) -{ - GfxClearSpriteCache(); - /* Force all sprites to redraw at the new chosen zoom level */ - MarkWholeScreenDirty(); -} - -/** - * Update any possible saveload window and delete any newgrf dialogue as - * its widget parts might change. Reinit all windows as it allows access to the - * newgrf debug button. - * @param new_value unused. - */ -static void InvalidateNewGRFChangeWindows(int32 new_value) -{ - InvalidateWindowClassesData(WC_SAVELOAD); - CloseWindowByClass(WC_GAME_OPTIONS); - ReInitAllWindows(_gui_zoom_cfg); -} - -static void InvalidateCompanyLiveryWindow(int32 new_value) -{ - InvalidateWindowClassesData(WC_COMPANY_COLOUR, -1); - ResetVehicleColourMap(); -} - /** Checks if any settings are set to incorrect values, and sets them to correct values in that case. */ static void ValidateSettings() { @@ -1096,193 +842,6 @@ static void ValidateSettings() } } -static void DifficultyNoiseChange(int32 new_value) -{ - if (_game_mode == GM_NORMAL) { - UpdateAirportsNoise(); - if (_settings_game.economy.station_noise_level) { - InvalidateWindowClassesData(WC_TOWN_VIEW, 0); - } - } -} - -static void MaxNoAIsChange(int32 new_value) -{ - if (GetGameSettings().difficulty.max_no_competitors != 0 && - AI::GetInfoList()->size() == 0 && - (!_networking || _network_server)) { - ShowErrorMessage(STR_WARNING_NO_SUITABLE_AI, INVALID_STRING_ID, WL_CRITICAL); - } - - InvalidateWindowClassesData(WC_GAME_OPTIONS, 0); -} - -/** - * Check whether the road side may be changed. - * @param new_value unused - * @return true if the road side may be changed. - */ -static bool CheckRoadSide(int32 &new_value) -{ - extern bool RoadVehiclesAreBuilt(); - return _game_mode == GM_MENU || !RoadVehiclesAreBuilt(); -} - -/** - * Conversion callback for _gameopt_settings_game.landscape - * It converts (or try) between old values and the new ones, - * without losing initial setting of the user - * @param value that was read from config file - * @return the "hopefully" converted value - */ -static size_t ConvertLandscape(const char *value) -{ - /* try with the old values */ - static std::vector _old_landscape_values{"normal", "hilly", "desert", "candy"}; - return OneOfManySettingDesc::ParseSingleValue(value, strlen(value), _old_landscape_values); -} - -static bool CheckFreeformEdges(int32 &new_value) -{ - if (_game_mode == GM_MENU) return true; - if (new_value != 0) { - for (Ship *s : Ship::Iterate()) { - /* Check if there is a ship on the northern border. */ - if (TileX(s->tile) == 0 || TileY(s->tile) == 0) { - ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_EMPTY, INVALID_STRING_ID, WL_ERROR); - return false; - } - } - for (const BaseStation *st : BaseStation::Iterate()) { - /* Check if there is a non-deleted buoy on the northern border. */ - if (st->IsInUse() && (TileX(st->xy) == 0 || TileY(st->xy) == 0)) { - ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_EMPTY, INVALID_STRING_ID, WL_ERROR); - return false; - } - } - } else { - for (uint i = 0; i < MapMaxX(); i++) { - if (TileHeight(TileXY(i, 1)) != 0) { - ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); - return false; - } - } - for (uint i = 1; i < MapMaxX(); i++) { - if (!IsTileType(TileXY(i, MapMaxY() - 1), MP_WATER) || TileHeight(TileXY(1, MapMaxY())) != 0) { - ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); - return false; - } - } - for (uint i = 0; i < MapMaxY(); i++) { - if (TileHeight(TileXY(1, i)) != 0) { - ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); - return false; - } - } - for (uint i = 1; i < MapMaxY(); i++) { - if (!IsTileType(TileXY(MapMaxX() - 1, i), MP_WATER) || TileHeight(TileXY(MapMaxX(), i)) != 0) { - ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); - return false; - } - } - } - return true; -} - -static void UpdateFreeformEdges(int32 new_value) -{ - if (_game_mode == GM_MENU) return; - - if (new_value != 0) { - for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0)); - for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y)); - } else { - /* Make tiles at the border water again. */ - for (uint i = 0; i < MapMaxX(); i++) { - SetTileHeight(TileXY(i, 0), 0); - SetTileType(TileXY(i, 0), MP_WATER); - } - for (uint i = 0; i < MapMaxY(); i++) { - SetTileHeight(TileXY(0, i), 0); - SetTileType(TileXY(0, i), MP_WATER); - } - } - MarkWholeScreenDirty(); -} - -/** - * Changing the setting "allow multiple NewGRF sets" is not allowed - * if there are vehicles. - */ -static bool CheckDynamicEngines(int32 &new_value) -{ - if (_game_mode == GM_MENU) return true; - - if (!EngineOverrideManager::ResetToCurrentNewGRFConfig()) { - ShowErrorMessage(STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES, INVALID_STRING_ID, WL_ERROR); - return false; - } - - return true; -} - -static bool CheckMaxHeightLevel(int32 &new_value) -{ - if (_game_mode == GM_NORMAL) return false; - if (_game_mode != GM_EDITOR) return true; - - /* Check if at least one mountain on the map is higher than the new value. - * If yes, disallow the change. */ - for (TileIndex t = 0; t < MapSize(); t++) { - if ((int32)TileHeight(t) > new_value) { - ShowErrorMessage(STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN, INVALID_STRING_ID, WL_ERROR); - /* Return old, unchanged value */ - return false; - } - } - - return true; -} - -static void StationCatchmentChanged(int32 new_value) -{ - Station::RecomputeCatchmentForAll(); - MarkWholeScreenDirty(); -} - -static void MaxVehiclesChanged(int32 new_value) -{ - InvalidateWindowClassesData(WC_BUILD_TOOLBAR); - MarkWholeScreenDirty(); -} - -static void InvalidateShipPathCache(int32 new_value) -{ - for (Ship *s : Ship::Iterate()) { - s->path.clear(); - } -} - -/** - * Replace a passwords that are a literal asterisk with an empty string. - * @param newval The new string value for this password field. - * @return Always true. - */ -static bool ReplaceAsteriskWithEmptyPassword(std::string &newval) -{ - if (newval.compare("*") == 0) newval.clear(); - return true; -} - -/** Update the game info, and send it to the clients when we are running as a server. */ -static void UpdateClientConfigValues() -{ - NetworkServerUpdateGameInfo(); - if (_network_server) NetworkServerSendConfigUpdate(); -} - -/* End - Callback Functions */ - /** * Prepare for reading and old diff_custom by zero-ing the memory. */ diff --git a/src/settings_table.cpp b/src/settings_table.cpp new file mode 100644 index 0000000000..bc1e588cd6 --- /dev/null +++ b/src/settings_table.cpp @@ -0,0 +1,473 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** + * @file settings_table.cpp The tables of all the settings as well as the implementation of most of their callbacks. + */ + +#include "stdafx.h" +#include "settings_table.h" +#include "currency.h" +#include "screenshot.h" +#include "network/network.h" +#include "network/network_func.h" +#include "pathfinder/pathfinder_type.h" +#include "genworld.h" +#include "train.h" +#include "news_func.h" +#include "window_func.h" +#include "company_func.h" +#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) +#define HAS_TRUETYPE_FONT +#include "fontcache.h" +#endif +#include "textbuf_gui.h" +#include "rail_gui.h" +#include "elrail_func.h" +#include "error.h" +#include "town.h" +#include "video/video_driver.hpp" +#include "sound/sound_driver.hpp" +#include "music/music_driver.hpp" +#include "blitter/factory.hpp" +#include "base_media_base.h" +#include "ai/ai_config.hpp" +#include "ai/ai.hpp" +#include "game/game_config.hpp" +#include "ship.h" +#include "smallmap_gui.h" +#include "roadveh.h" +#include "vehicle_func.h" +#include "void_map.h" + +#include "table/strings.h" +#include "table/settings.h" + +#include "safeguards.h" + +SettingTable _settings{ _settings_table }; +SettingTable _network_settings{ _network_settings_table }; +SettingTable _network_private_settings{ _network_private_settings_table }; +SettingTable _network_secrets_settings{ _network_secrets_settings_table }; + +SettingTable _company_settings{ _company_settings_table }; +SettingTable _currency_settings{ _currency_settings_table }; +SettingTable _gameopt_settings{ _gameopt_settings_table }; +SettingTable _misc_settings{ _misc_settings_table }; +SettingTable _window_settings{ _window_settings_table }; +#if defined(_WIN32) && !defined(DEDICATED) +SettingTable _win32_settings{ _win32_settings_table }; +#endif /* _WIN32 */ + + +/* Begin - Callback Functions for the various settings. */ + +/** Reposition the main toolbar as the setting changed. */ +static void v_PositionMainToolbar(int32 new_value) +{ + if (_game_mode != GM_MENU) PositionMainToolbar(nullptr); +} + +/** Reposition the statusbar as the setting changed. */ +static void v_PositionStatusbar(int32 new_value) +{ + if (_game_mode != GM_MENU) { + PositionStatusbar(nullptr); + PositionNewsMessage(nullptr); + PositionNetworkChatWindow(nullptr); + } +} + +/** + * Redraw the smallmap after a colour scheme change. + * @param p1 Callback parameter. + */ +static void RedrawSmallmap(int32 new_value) +{ + BuildLandLegend(); + BuildOwnerLegend(); + SetWindowClassesDirty(WC_SMALLMAP); +} + +static void StationSpreadChanged(int32 p1) +{ + InvalidateWindowData(WC_SELECT_STATION, 0); + InvalidateWindowData(WC_BUILD_STATION, 0); +} + +static void CloseSignalGUI(int32 new_value) +{ + if (new_value == 0) { + CloseWindowByClass(WC_BUILD_SIGNAL); + } +} + +static void UpdateConsists(int32 new_value) +{ + for (Train *t : Train::Iterate()) { + /* Update the consist of all trains so the maximum speed is set correctly. */ + if (t->IsFrontEngine() || t->IsFreeWagon()) t->ConsistChanged(CCF_TRACK); + } + InvalidateWindowClassesData(WC_BUILD_VEHICLE, 0); +} + +/* Check service intervals of vehicles, newvalue is value of % or day based servicing */ +static void UpdateAllServiceInterval(int32 new_value) +{ + bool update_vehicles; + VehicleDefaultSettings *vds; + if (_game_mode == GM_MENU || !Company::IsValidID(_current_company)) { + vds = &_settings_client.company.vehicle; + update_vehicles = false; + } else { + vds = &Company::Get(_current_company)->settings.vehicle; + update_vehicles = true; + } + + if (new_value != 0) { + vds->servint_trains = 50; + vds->servint_roadveh = 50; + vds->servint_aircraft = 50; + vds->servint_ships = 50; + } else { + vds->servint_trains = 150; + vds->servint_roadveh = 150; + vds->servint_aircraft = 100; + vds->servint_ships = 360; + } + + if (update_vehicles) { + const Company *c = Company::Get(_current_company); + for (Vehicle *v : Vehicle::Iterate()) { + if (v->owner == _current_company && v->IsPrimaryVehicle() && !v->ServiceIntervalIsCustom()) { + v->SetServiceInterval(CompanyServiceInterval(c, v->type)); + v->SetServiceIntervalIsPercent(new_value != 0); + } + } + } + + SetWindowClassesDirty(WC_VEHICLE_DETAILS); +} + +static bool CanUpdateServiceInterval(VehicleType type, int32 &new_value) +{ + VehicleDefaultSettings *vds; + if (_game_mode == GM_MENU || !Company::IsValidID(_current_company)) { + vds = &_settings_client.company.vehicle; + } else { + vds = &Company::Get(_current_company)->settings.vehicle; + } + + /* Test if the interval is valid */ + int32 interval = GetServiceIntervalClamped(new_value, vds->servint_ispercent); + return interval == new_value; +} + +static void UpdateServiceInterval(VehicleType type, int32 new_value) +{ + if (_game_mode != GM_MENU && Company::IsValidID(_current_company)) { + for (Vehicle *v : Vehicle::Iterate()) { + if (v->owner == _current_company && v->type == type && v->IsPrimaryVehicle() && !v->ServiceIntervalIsCustom()) { + v->SetServiceInterval(new_value); + } + } + } + + SetWindowClassesDirty(WC_VEHICLE_DETAILS); +} + +static void TrainAccelerationModelChanged(int32 new_value) +{ + for (Train *t : Train::Iterate()) { + if (t->IsFrontEngine()) { + t->tcache.cached_max_curve_speed = t->GetCurveSpeedLimit(); + t->UpdateAcceleration(); + } + } + + /* These windows show acceleration values only when realistic acceleration is on. They must be redrawn after a setting change. */ + SetWindowClassesDirty(WC_ENGINE_PREVIEW); + InvalidateWindowClassesData(WC_BUILD_VEHICLE, 0); + SetWindowClassesDirty(WC_VEHICLE_DETAILS); +} + +/** + * This function updates the train acceleration cache after a steepness change. + * @param new_value Unused new value of setting. + */ +static void TrainSlopeSteepnessChanged(int32 new_value) +{ + for (Train *t : Train::Iterate()) { + if (t->IsFrontEngine()) t->CargoChanged(); + } +} + +/** + * This function updates realistic acceleration caches when the setting "Road vehicle acceleration model" is set. + * @param new_value Unused new value of setting. + */ +static void RoadVehAccelerationModelChanged(int32 new_value) +{ + if (_settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL) { + for (RoadVehicle *rv : RoadVehicle::Iterate()) { + if (rv->IsFrontEngine()) { + rv->CargoChanged(); + } + } + } + + /* These windows show acceleration values only when realistic acceleration is on. They must be redrawn after a setting change. */ + SetWindowClassesDirty(WC_ENGINE_PREVIEW); + InvalidateWindowClassesData(WC_BUILD_VEHICLE, 0); + SetWindowClassesDirty(WC_VEHICLE_DETAILS); +} + +/** + * This function updates the road vehicle acceleration cache after a steepness change. + * @param new_value Unused new value of setting. + */ +static void RoadVehSlopeSteepnessChanged(int32 new_value) +{ + for (RoadVehicle *rv : RoadVehicle::Iterate()) { + if (rv->IsFrontEngine()) rv->CargoChanged(); + } +} + +static void TownFoundingChanged(int32 new_value) +{ + if (_game_mode != GM_EDITOR && _settings_game.economy.found_town == TF_FORBIDDEN) { + CloseWindowById(WC_FOUND_TOWN, 0); + } else { + InvalidateWindowData(WC_FOUND_TOWN, 0); + } +} + +static void ZoomMinMaxChanged(int32 new_value) +{ + extern void ConstrainAllViewportsZoom(); + ConstrainAllViewportsZoom(); + GfxClearSpriteCache(); + if (_settings_client.gui.zoom_min > _gui_zoom) { + /* Restrict GUI zoom if it is no longer available. */ + _gui_zoom = _settings_client.gui.zoom_min; + UpdateCursorSize(); + LoadStringWidthTable(); + } +} + +static void SpriteZoomMinChanged(int32 new_value) +{ + GfxClearSpriteCache(); + /* Force all sprites to redraw at the new chosen zoom level */ + MarkWholeScreenDirty(); +} + +/** + * Update any possible saveload window and delete any newgrf dialogue as + * its widget parts might change. Reinit all windows as it allows access to the + * newgrf debug button. + * @param new_value unused. + */ +static void InvalidateNewGRFChangeWindows(int32 new_value) +{ + InvalidateWindowClassesData(WC_SAVELOAD); + CloseWindowByClass(WC_GAME_OPTIONS); + ReInitAllWindows(_gui_zoom_cfg); +} + +static void InvalidateCompanyLiveryWindow(int32 new_value) +{ + InvalidateWindowClassesData(WC_COMPANY_COLOUR, -1); + ResetVehicleColourMap(); +} + +static void DifficultyNoiseChange(int32 new_value) +{ + if (_game_mode == GM_NORMAL) { + UpdateAirportsNoise(); + if (_settings_game.economy.station_noise_level) { + InvalidateWindowClassesData(WC_TOWN_VIEW, 0); + } + } +} + +static void MaxNoAIsChange(int32 new_value) +{ + if (GetGameSettings().difficulty.max_no_competitors != 0 && + AI::GetInfoList()->size() == 0 && + (!_networking || _network_server)) { + ShowErrorMessage(STR_WARNING_NO_SUITABLE_AI, INVALID_STRING_ID, WL_CRITICAL); + } + + InvalidateWindowClassesData(WC_GAME_OPTIONS, 0); +} + +/** + * Check whether the road side may be changed. + * @param new_value unused + * @return true if the road side may be changed. + */ +static bool CheckRoadSide(int32 &new_value) +{ + extern bool RoadVehiclesAreBuilt(); + return _game_mode == GM_MENU || !RoadVehiclesAreBuilt(); +} + +/** + * Conversion callback for _gameopt_settings_game.landscape + * It converts (or try) between old values and the new ones, + * without losing initial setting of the user + * @param value that was read from config file + * @return the "hopefully" converted value + */ +static size_t ConvertLandscape(const char *value) +{ + /* try with the old values */ + static std::vector _old_landscape_values{"normal", "hilly", "desert", "candy"}; + return OneOfManySettingDesc::ParseSingleValue(value, strlen(value), _old_landscape_values); +} + +static bool CheckFreeformEdges(int32 &new_value) +{ + if (_game_mode == GM_MENU) return true; + if (new_value != 0) { + for (Ship *s : Ship::Iterate()) { + /* Check if there is a ship on the northern border. */ + if (TileX(s->tile) == 0 || TileY(s->tile) == 0) { + ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_EMPTY, INVALID_STRING_ID, WL_ERROR); + return false; + } + } + for (const BaseStation *st : BaseStation::Iterate()) { + /* Check if there is a non-deleted buoy on the northern border. */ + if (st->IsInUse() && (TileX(st->xy) == 0 || TileY(st->xy) == 0)) { + ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_EMPTY, INVALID_STRING_ID, WL_ERROR); + return false; + } + } + } else { + for (uint i = 0; i < MapMaxX(); i++) { + if (TileHeight(TileXY(i, 1)) != 0) { + ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); + return false; + } + } + for (uint i = 1; i < MapMaxX(); i++) { + if (!IsTileType(TileXY(i, MapMaxY() - 1), MP_WATER) || TileHeight(TileXY(1, MapMaxY())) != 0) { + ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); + return false; + } + } + for (uint i = 0; i < MapMaxY(); i++) { + if (TileHeight(TileXY(1, i)) != 0) { + ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); + return false; + } + } + for (uint i = 1; i < MapMaxY(); i++) { + if (!IsTileType(TileXY(MapMaxX() - 1, i), MP_WATER) || TileHeight(TileXY(MapMaxX(), i)) != 0) { + ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); + return false; + } + } + } + return true; +} + +static void UpdateFreeformEdges(int32 new_value) +{ + if (_game_mode == GM_MENU) return; + + if (new_value != 0) { + for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0)); + for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y)); + } else { + /* Make tiles at the border water again. */ + for (uint i = 0; i < MapMaxX(); i++) { + SetTileHeight(TileXY(i, 0), 0); + SetTileType(TileXY(i, 0), MP_WATER); + } + for (uint i = 0; i < MapMaxY(); i++) { + SetTileHeight(TileXY(0, i), 0); + SetTileType(TileXY(0, i), MP_WATER); + } + } + MarkWholeScreenDirty(); +} + +/** + * Changing the setting "allow multiple NewGRF sets" is not allowed + * if there are vehicles. + */ +static bool CheckDynamicEngines(int32 &new_value) +{ + if (_game_mode == GM_MENU) return true; + + if (!EngineOverrideManager::ResetToCurrentNewGRFConfig()) { + ShowErrorMessage(STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES, INVALID_STRING_ID, WL_ERROR); + return false; + } + + return true; +} + +static bool CheckMaxHeightLevel(int32 &new_value) +{ + if (_game_mode == GM_NORMAL) return false; + if (_game_mode != GM_EDITOR) return true; + + /* Check if at least one mountain on the map is higher than the new value. + * If yes, disallow the change. */ + for (TileIndex t = 0; t < MapSize(); t++) { + if ((int32)TileHeight(t) > new_value) { + ShowErrorMessage(STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN, INVALID_STRING_ID, WL_ERROR); + /* Return old, unchanged value */ + return false; + } + } + + return true; +} + +static void StationCatchmentChanged(int32 new_value) +{ + Station::RecomputeCatchmentForAll(); + MarkWholeScreenDirty(); +} + +static void MaxVehiclesChanged(int32 new_value) +{ + InvalidateWindowClassesData(WC_BUILD_TOOLBAR); + MarkWholeScreenDirty(); +} + +static void InvalidateShipPathCache(int32 new_value) +{ + for (Ship *s : Ship::Iterate()) { + s->path.clear(); + } +} + +/** + * Replace a passwords that are a literal asterisk with an empty string. + * @param newval The new string value for this password field. + * @return Always true. + */ +static bool ReplaceAsteriskWithEmptyPassword(std::string &newval) +{ + if (newval.compare("*") == 0) newval.clear(); + return true; +} + +/** Update the game info, and send it to the clients when we are running as a server. */ +static void UpdateClientConfigValues() +{ + NetworkServerUpdateGameInfo(); + if (_network_server) NetworkServerSendConfigUpdate(); +} + +/* End - Callback Functions */ diff --git a/src/settings_table.h b/src/settings_table.h new file mode 100644 index 0000000000..ace0ec7a2f --- /dev/null +++ b/src/settings_table.h @@ -0,0 +1,38 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** + * @file settings_table.h Definition of the configuration tables of the settings. + */ + +#ifndef SETTINGS_TABLE_H +#define SETTINGS_TABLE_H + +#include +#include "settings_internal.h" + +typedef span SettingTable; + +extern SettingTable _settings; +extern SettingTable _network_settings; +extern SettingTable _network_private_settings; +extern SettingTable _network_secrets_settings; + +extern SettingTable _company_settings; +extern SettingTable _currency_settings; +extern SettingTable _gameopt_settings; +extern SettingTable _misc_settings; +extern SettingTable _window_settings; +#if defined(_WIN32) && !defined(DEDICATED) +extern SettingTable _win32_settings; +#endif /* _WIN32 */ + +static const uint GAME_DIFFICULTY_NUM = 18; +extern const std::array _old_diff_settings; +extern uint16 _old_diff_custom[GAME_DIFFICULTY_NUM]; + +#endif /* SETTINGS_TABLE_H */ diff --git a/src/table/settings/company_settings.ini b/src/table/settings/company_settings.ini index e5019305f7..52920e6e6d 100644 --- a/src/table/settings/company_settings.ini +++ b/src/table/settings/company_settings.ini @@ -12,7 +12,7 @@ static void UpdateAllServiceInterval(int32 new_value); static bool CanUpdateServiceInterval(VehicleType type, int32 &new_value); static void UpdateServiceInterval(VehicleType type, int32 new_value); -static const SettingVariant _company_settings[] = { +static const SettingVariant _company_settings_table[] = { [post-amble] }; [templates] diff --git a/src/table/settings/currency_settings.ini b/src/table/settings/currency_settings.ini index d0950db8e6..03c6425b21 100644 --- a/src/table/settings/currency_settings.ini +++ b/src/table/settings/currency_settings.ini @@ -7,7 +7,7 @@ ; Settings for the in-game custom currency. [pre-amble] -static const SettingVariant _currency_settings[] = { +static const SettingVariant _currency_settings_table[] = { [post-amble] }; [templates] diff --git a/src/table/settings/gameopt_settings.ini b/src/table/settings/gameopt_settings.ini index a30400e85b..83e7c6395a 100644 --- a/src/table/settings/gameopt_settings.ini +++ b/src/table/settings/gameopt_settings.ini @@ -14,9 +14,8 @@ ; be saved in their new place. [pre-amble] -static const uint GAME_DIFFICULTY_NUM = 18; -static const std::array _old_diff_settings{"max_no_competitors", "competitor_start_time", "number_towns", "industry_density", "max_loan", "initial_interest", "vehicle_costs", "competitor_speed", "competitor_intelligence", "vehicle_breakdowns", "subsidy_multiplier", "construction_cost", "terrain_type", "quantity_sea_lakes", "economy", "line_reverse_mode", "disasters", "town_council_tolerance"}; -static uint16 _old_diff_custom[GAME_DIFFICULTY_NUM]; +const std::array _old_diff_settings{"max_no_competitors", "competitor_start_time", "number_towns", "industry_density", "max_loan", "initial_interest", "vehicle_costs", "competitor_speed", "competitor_intelligence", "vehicle_breakdowns", "subsidy_multiplier", "construction_cost", "terrain_type", "quantity_sea_lakes", "economy", "line_reverse_mode", "disasters", "town_council_tolerance"}; +uint16 _old_diff_custom[GAME_DIFFICULTY_NUM]; uint8 _old_diff_level; ///< Old difficulty level from old savegames uint8 _old_units; ///< Old units from old savegames @@ -33,7 +32,7 @@ static std::initializer_list _osk_activation{"disabled", "double", static std::initializer_list _settings_profiles{"easy", "medium", "hard"}; static std::initializer_list _news_display{ "off", "summarized", "full"}; -static const SettingVariant _gameopt_settings[] = { +static const SettingVariant _gameopt_settings_table[] = { /* In version 4 a new difficulty setting has been added to the difficulty settings, * town attitude towards demolishing. Needs special handling because some dimwit thought * it funny to have the GameDifficulty struct be an array while it is a struct of diff --git a/src/table/settings/misc_settings.ini b/src/table/settings/misc_settings.ini index 9f73573b20..daca4a8174 100644 --- a/src/table/settings/misc_settings.ini +++ b/src/table/settings/misc_settings.ini @@ -20,7 +20,7 @@ extern bool _allow_hidpi_window; #define WITHOUT_COCOA #endif -static const SettingVariant _misc_settings[] = { +static const SettingVariant _misc_settings_table[] = { [post-amble] }; [templates] diff --git a/src/table/settings/network_private_settings.ini b/src/table/settings/network_private_settings.ini index 76fbd373ae..cae43330fd 100644 --- a/src/table/settings/network_private_settings.ini +++ b/src/table/settings/network_private_settings.ini @@ -7,7 +7,7 @@ ; Network settings as stored in the private configuration file ("private.cfg"). [pre-amble] -static const SettingVariant _network_private_settings[] = { +static const SettingVariant _network_private_settings_table[] = { [post-amble] }; [templates] diff --git a/src/table/settings/network_secrets_settings.ini b/src/table/settings/network_secrets_settings.ini index a408bad409..fced9240e0 100644 --- a/src/table/settings/network_secrets_settings.ini +++ b/src/table/settings/network_secrets_settings.ini @@ -9,7 +9,7 @@ [pre-amble] static bool ReplaceAsteriskWithEmptyPassword(std::string &newval); -static const SettingVariant _network_secrets_settings[] = { +static const SettingVariant _network_secrets_settings_table[] = { [post-amble] }; [templates] diff --git a/src/table/settings/network_settings.ini b/src/table/settings/network_settings.ini index 1317edbc72..45459b6e1f 100644 --- a/src/table/settings/network_settings.ini +++ b/src/table/settings/network_settings.ini @@ -9,7 +9,7 @@ [pre-amble] static void UpdateClientConfigValues(); -static const SettingVariant _network_settings[] = { +static const SettingVariant _network_settings_table[] = { [post-amble] }; [templates] diff --git a/src/table/settings/settings.ini b/src/table/settings/settings.ini index fae6e5636a..984668e510 100644 --- a/src/table/settings/settings.ini +++ b/src/table/settings/settings.ini @@ -46,7 +46,7 @@ static void InvalidateShipPathCache(int32 new_value); * assigns its own value. If the setting was company-based, that would mean that * vehicles could decide on different moments that they are heading back to a * service depot, causing desyncs on a massive scale. */ -static const SettingVariant _settings[] = { +static const SettingVariant _settings_table[] = { [post-amble] }; [templates] diff --git a/src/table/settings/win32_settings.ini b/src/table/settings/win32_settings.ini index 51b5796294..4256528ddc 100644 --- a/src/table/settings/win32_settings.ini +++ b/src/table/settings/win32_settings.ini @@ -12,7 +12,7 @@ #if defined(_WIN32) && !defined(DEDICATED) extern bool _window_maximize; -static const SettingVariant _win32_settings[] = { +static const SettingVariant _win32_settings_table[] = { [post-amble] }; #endif /* _WIN32 */ diff --git a/src/table/settings/window_settings.ini b/src/table/settings/window_settings.ini index d9327aa92c..aba8d3dbaa 100644 --- a/src/table/settings/window_settings.ini +++ b/src/table/settings/window_settings.ini @@ -9,7 +9,7 @@ [pre-amble] -static const SettingVariant _window_settings[] = { +static const SettingVariant _window_settings_table[] = { [post-amble] }; [templates] From 7e7a4aad721f89c98a347a4d2104f6a01e8fbcaa Mon Sep 17 00:00:00 2001 From: Rubidium Date: Mon, 5 Jul 2021 20:14:28 +0200 Subject: [PATCH 25/42] Codechange: split off the settings saveload code from the main settings handling logic --- src/saveload/CMakeLists.txt | 1 + src/saveload/settings_sl.cpp | 178 +++++++++++++++++++++++++++++++ src/settings.cpp | 198 +++-------------------------------- src/settings_internal.h | 10 ++ 4 files changed, 204 insertions(+), 183 deletions(-) create mode 100644 src/saveload/settings_sl.cpp diff --git a/src/saveload/CMakeLists.txt b/src/saveload/CMakeLists.txt index 5f83309a40..32bcc57ac1 100644 --- a/src/saveload/CMakeLists.txt +++ b/src/saveload/CMakeLists.txt @@ -33,6 +33,7 @@ add_files( saveload.h saveload_filter.h saveload_internal.h + settings_sl.cpp signs_sl.cpp station_sl.cpp storage_sl.cpp diff --git a/src/saveload/settings_sl.cpp b/src/saveload/settings_sl.cpp new file mode 100644 index 0000000000..2097d86454 --- /dev/null +++ b/src/saveload/settings_sl.cpp @@ -0,0 +1,178 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file settings_sl.cpp Handles the saveload part of the settings. */ + +#include "../stdafx.h" + +#include "saveload.h" +#include "compat/settings_sl_compat.h" + +#include "../settings_type.h" +#include "../settings_table.h" +#include "../network/network.h" +#include "../fios.h" + +#include "../safeguards.h" + +/** + * Prepare for reading and old diff_custom by zero-ing the memory. + */ +void PrepareOldDiffCustom() +{ + memset(_old_diff_custom, 0, sizeof(_old_diff_custom)); +} + +/** + * Reading of the old diff_custom array and transforming it to the new format. + * @param savegame is it read from the config or savegame. In the latter case + * we are sure there is an array; in the former case we have + * to check that. + */ +void HandleOldDiffCustom(bool savegame) +{ + /* Savegames before v4 didn't have "town_council_tolerance" in savegame yet. */ + bool has_no_town_council_tolerance = savegame && IsSavegameVersionBefore(SLV_4); + uint options_to_load = GAME_DIFFICULTY_NUM - (has_no_town_council_tolerance ? 1 : 0); + + if (!savegame) { + /* If we did read to old_diff_custom, then at least one value must be non 0. */ + bool old_diff_custom_used = false; + for (uint i = 0; i < options_to_load && !old_diff_custom_used; i++) { + old_diff_custom_used = (_old_diff_custom[i] != 0); + } + + if (!old_diff_custom_used) return; + } + + /* Iterate over all the old difficulty settings, and convert the list-value to the new setting. */ + uint i = 0; + for (const auto &name : _old_diff_settings) { + if (has_no_town_council_tolerance && name == "town_council_tolerance") continue; + + std::string fullname = "difficulty." + name; + const SettingDesc *sd = GetSettingFromName(fullname); + + /* Some settings are no longer in use; skip reading those. */ + if (sd == nullptr) { + i++; + continue; + } + + int32 value = (int32)((name == "max_loan" ? 1000 : 1) * _old_diff_custom[i++]); + sd->AsIntSetting()->MakeValueValidAndWrite(savegame ? &_settings_game : &_settings_newgame, value); + } +} + +/** + * Get the SaveLoad description for the SettingTable. + * @param settings SettingDesc struct containing all information. + * @param is_loading True iff the SaveLoad table is for loading. + * @return Vector with SaveLoad entries for the SettingTable. + */ +static std::vector GetSettingsDesc(const SettingTable &settings, bool is_loading) +{ + std::vector saveloads; + for (auto &desc : settings) { + const SettingDesc *sd = GetSettingDesc(desc); + if (sd->flags & SF_NOT_IN_SAVE) continue; + + if (is_loading && (sd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) { + if (IsSavegameVersionBefore(SLV_TABLE_CHUNKS)) { + /* We don't want to read this setting, so we do need to skip over it. */ + saveloads.push_back({sd->name, sd->save.cmd, GetVarFileType(sd->save.conv) | SLE_VAR_NULL, sd->save.length, sd->save.version_from, sd->save.version_to, 0, nullptr, 0, nullptr}); + } + continue; + } + + SaveLoad sv = sd->save; + /* Replace the name with the actual name of the setting. */ + if (!sd->name.empty()) sv.name = sd->name; + saveloads.push_back(sv); + } + + return saveloads; +} + +/** + * Save and load handler for settings + * @param settings SettingDesc struct containing all information + * @param object can be either nullptr in which case we load global variables or + * a pointer to a struct which is getting saved + */ +static void LoadSettings(const SettingTable &settings, void *object, const SaveLoadCompatTable &slct) +{ + const std::vector slt = SlCompatTableHeader(GetSettingsDesc(settings, true), slct); + + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; + SlObject(object, slt); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many settings entries"); + + /* Ensure all IntSettings are valid (min/max could have changed between versions etc). */ + for (auto &desc : settings) { + const SettingDesc *sd = GetSettingDesc(desc); + if (sd->flags & SF_NOT_IN_SAVE) continue; + if ((sd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) continue; + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; + + if (sd->IsIntSetting()) { + const IntSettingDesc *int_setting = sd->AsIntSetting(); + int_setting->MakeValueValidAndWrite(object, int_setting->Read(object)); + } + } +} + +/** + * Save and load handler for settings + * @param settings SettingDesc struct containing all information + * @param object can be either nullptr in which case we load global variables or + * a pointer to a struct which is getting saved + */ +static void SaveSettings(const SettingTable &settings, void *object) +{ + const std::vector slt = GetSettingsDesc(settings, false); + + SlTableHeader(slt); + + SlSetArrayIndex(0); + SlObject(object, slt); +} + +static void Load_OPTS() +{ + /* Copy over default setting since some might not get loaded in + * a networking environment. This ensures for example that the local + * autosave-frequency stays when joining a network-server */ + PrepareOldDiffCustom(); + LoadSettings(_gameopt_settings, &_settings_game, _gameopt_sl_compat); + HandleOldDiffCustom(true); +} + +static void Load_PATS() +{ + /* Copy over default setting since some might not get loaded in + * a networking environment. This ensures for example that the local + * currency setting stays when joining a network-server */ + LoadSettings(_settings, &_settings_game, _settings_sl_compat); +} + +static void Check_PATS() +{ + LoadSettings(_settings, &_load_check_data.settings, _settings_sl_compat); +} + +static void Save_PATS() +{ + SaveSettings(_settings, &_settings_game); +} + +static const ChunkHandler setting_chunk_handlers[] = { + { 'OPTS', nullptr, Load_OPTS, nullptr, nullptr, CH_READONLY }, + { 'PATS', Save_PATS, Load_PATS, nullptr, Check_PATS, CH_TABLE }, +}; + +extern const ChunkHandlerTable _setting_chunk_handlers(setting_chunk_handlers); diff --git a/src/settings.cpp b/src/settings.cpp index a2ab8ae333..e3741c2356 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -44,8 +44,6 @@ #include "fios.h" #include "fileio_func.h" -#include "saveload/compat/settings_sl_compat.h" - #include "table/strings.h" #include "safeguards.h" @@ -105,7 +103,17 @@ static auto &SecretSettingTables() typedef void SettingDescProc(IniFile &ini, const SettingTable &desc, const char *grpname, void *object, bool only_startup); typedef void SettingDescProcList(IniFile &ini, const char *grpname, StringList &list); -static bool IsSignedVarMemType(VarType vt); +static bool IsSignedVarMemType(VarType vt) +{ + switch (GetVarMemType(vt)) { + case SLE_VAR_I8: + case SLE_VAR_I16: + case SLE_VAR_I32: + case SLE_VAR_I64: + return true; + } + return false; +} /** * IniFile to store a configuration. @@ -143,16 +151,6 @@ enum IniFileVersion : uint32 { const uint16 INIFILE_VERSION = (IniFileVersion)(IFV_MAX_VERSION - 1); ///< Current ini-file version of OpenTTD. -/** - * Helper to convert the type of the iterated settings description to a pointer to it. - * @param desc The type of the iterator of the value in SettingTable. - * @return The actual pointer to SettingDesc. - */ -static constexpr const SettingDesc *GetSettingDesc(const SettingVariant &desc) -{ - return std::visit([](auto&& arg) -> const SettingDesc * { return &arg; }, desc); -} - /** * Find the index value of a ONEofMANY type in a string separated by | * @param str the current value of the setting for which a value needs found @@ -832,6 +830,10 @@ const StringSettingDesc *SettingDesc::AsStringSetting() const return static_cast(this); } +void PrepareOldDiffCustom(); +void HandleOldDiffCustom(bool savegame); + + /** Checks if any settings are set to incorrect values, and sets them to correct values in that case. */ static void ValidateSettings() { @@ -842,55 +844,6 @@ static void ValidateSettings() } } -/** - * Prepare for reading and old diff_custom by zero-ing the memory. - */ -static void PrepareOldDiffCustom() -{ - memset(_old_diff_custom, 0, sizeof(_old_diff_custom)); -} - -/** - * Reading of the old diff_custom array and transforming it to the new format. - * @param savegame is it read from the config or savegame. In the latter case - * we are sure there is an array; in the former case we have - * to check that. - */ -static void HandleOldDiffCustom(bool savegame) -{ - /* Savegames before v4 didn't have "town_council_tolerance" in savegame yet. */ - bool has_no_town_council_tolerance = savegame && IsSavegameVersionBefore(SLV_4); - uint options_to_load = GAME_DIFFICULTY_NUM - (has_no_town_council_tolerance ? 1 : 0); - - if (!savegame) { - /* If we did read to old_diff_custom, then at least one value must be non 0. */ - bool old_diff_custom_used = false; - for (uint i = 0; i < options_to_load && !old_diff_custom_used; i++) { - old_diff_custom_used = (_old_diff_custom[i] != 0); - } - - if (!old_diff_custom_used) return; - } - - /* Iterate over all the old difficulty settings, and convert the list-value to the new setting. */ - uint i = 0; - for (const auto &name : _old_diff_settings) { - if (has_no_town_council_tolerance && name == "town_council_tolerance") continue; - - std::string fullname = "difficulty." + name; - const SettingDesc *sd = GetSettingFromName(fullname); - - /* Some settings are no longer in use; skip reading those. */ - if (sd == nullptr) { - i++; - continue; - } - - int32 value = (int32)((name == "max_loan" ? 1000 : 1) * _old_diff_custom[i++]); - sd->AsIntSetting()->MakeValueValidAndWrite(savegame ? &_settings_game : &_settings_newgame, value); - } -} - static void AILoadConfig(IniFile &ini, const char *grpname) { IniGroup *group = ini.GetGroup(grpname); @@ -1751,124 +1704,3 @@ void IConsoleListSettings(const char *prefilter) IConsolePrint(CC_HELP, "Use 'setting' command to change a value."); } - -/** - * Get the SaveLoad description for the SettingTable. - * @param settings SettingDesc struct containing all information. - * @param is_loading True iff the SaveLoad table is for loading. - * @return Vector with SaveLoad entries for the SettingTable. - */ -static std::vector GetSettingsDesc(const SettingTable &settings, bool is_loading) -{ - std::vector saveloads; - for (auto &desc : settings) { - const SettingDesc *sd = GetSettingDesc(desc); - if (sd->flags & SF_NOT_IN_SAVE) continue; - - if (is_loading && (sd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) { - if (IsSavegameVersionBefore(SLV_TABLE_CHUNKS)) { - /* We don't want to read this setting, so we do need to skip over it. */ - saveloads.push_back({sd->name, sd->save.cmd, GetVarFileType(sd->save.conv) | SLE_VAR_NULL, sd->save.length, sd->save.version_from, sd->save.version_to, 0, nullptr, 0, nullptr}); - } - continue; - } - - SaveLoad sv = sd->save; - /* Replace the name with the actual name of the setting. */ - if (!sd->name.empty()) sv.name = sd->name; - saveloads.push_back(sv); - } - - return saveloads; -} - -/** - * Save and load handler for settings - * @param settings SettingDesc struct containing all information - * @param object can be either nullptr in which case we load global variables or - * a pointer to a struct which is getting saved - */ -static void LoadSettings(const SettingTable &settings, void *object, const SaveLoadCompatTable &slct) -{ - const std::vector slt = SlCompatTableHeader(GetSettingsDesc(settings, true), slct); - - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlObject(object, slt); - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many settings entries"); - - /* Ensure all IntSettings are valid (min/max could have changed between versions etc). */ - for (auto &desc : settings) { - const SettingDesc *sd = GetSettingDesc(desc); - if (sd->flags & SF_NOT_IN_SAVE) continue; - if ((sd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) continue; - if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; - - if (sd->IsIntSetting()) { - const IntSettingDesc *int_setting = sd->AsIntSetting(); - int_setting->MakeValueValidAndWrite(object, int_setting->Read(object)); - } - } -} - -/** - * Save and load handler for settings - * @param settings SettingDesc struct containing all information - * @param object can be either nullptr in which case we load global variables or - * a pointer to a struct which is getting saved - */ -static void SaveSettings(const SettingTable &settings, void *object) -{ - const std::vector slt = GetSettingsDesc(settings, false); - - SlTableHeader(slt); - - SlSetArrayIndex(0); - SlObject(object, slt); -} - -static void Load_OPTS() -{ - /* Copy over default setting since some might not get loaded in - * a networking environment. This ensures for example that the local - * autosave-frequency stays when joining a network-server */ - PrepareOldDiffCustom(); - LoadSettings(_gameopt_settings, &_settings_game, _gameopt_sl_compat); - HandleOldDiffCustom(true); -} - -static void Load_PATS() -{ - /* Copy over default setting since some might not get loaded in - * a networking environment. This ensures for example that the local - * currency setting stays when joining a network-server */ - LoadSettings(_settings, &_settings_game, _settings_sl_compat); -} - -static void Check_PATS() -{ - LoadSettings(_settings, &_load_check_data.settings, _settings_sl_compat); -} - -static void Save_PATS() -{ - SaveSettings(_settings, &_settings_game); -} - -static const ChunkHandler setting_chunk_handlers[] = { - { 'OPTS', nullptr, Load_OPTS, nullptr, nullptr, CH_READONLY }, - { 'PATS', Save_PATS, Load_PATS, nullptr, Check_PATS, CH_TABLE }, -}; - -extern const ChunkHandlerTable _setting_chunk_handlers(setting_chunk_handlers); - -static bool IsSignedVarMemType(VarType vt) -{ - switch (GetVarMemType(vt)) { - case SLE_VAR_I8: - case SLE_VAR_I16: - case SLE_VAR_I32: - case SLE_VAR_I64: - return true; - } - return false; -} diff --git a/src/settings_internal.h b/src/settings_internal.h index 0e6637a5b7..304f1393aa 100644 --- a/src/settings_internal.h +++ b/src/settings_internal.h @@ -302,6 +302,16 @@ struct NullSettingDesc : SettingDesc { typedef std::variant SettingVariant; +/** + * Helper to convert the type of the iterated settings description to a pointer to it. + * @param desc The type of the iterator of the value in SettingTable. + * @return The actual pointer to SettingDesc. + */ +static constexpr const SettingDesc *GetSettingDesc(const SettingVariant &desc) +{ + return std::visit([](auto&& arg) -> const SettingDesc * { return &arg; }, desc); +} + const SettingDesc *GetSettingFromName(const std::string_view name); void GetSettingSaveLoadByPrefix(const std::string_view prefix, std::vector &saveloads); bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame = false); From f371a5ad705e10940612475cc697091914a2c96a Mon Sep 17 00:00:00 2001 From: glx22 Date: Sun, 6 Jun 2021 22:26:38 +0200 Subject: [PATCH 26/42] Codechange: Preparation for ChunkHandler subclassing --- src/saveload/saveload.cpp | 90 +++++++++++++++++++++++++-------------- src/saveload/saveload.h | 41 ++++++++++++++++++ 2 files changed, 99 insertions(+), 32 deletions(-) diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 82e96080eb..69bbc75b1a 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -314,9 +314,9 @@ static void SlNullPointers() _sl_version = SAVEGAME_VERSION; for (auto &ch : ChunkHandlers()) { - if (ch.ptrs_proc != nullptr) { + if (ch.fix_pointers) { Debug(sl, 3, "Nulling pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id); - ch.ptrs_proc(); + ch.FixPointers(); } } @@ -2114,6 +2114,48 @@ void SlAutolength(AutolengthProc *proc, void *arg) if (offs != _sl.dumper->GetSize()) SlErrorCorrupt("Invalid chunk size"); } +void ChunkHandler::Save() const +{ + assert(this->save_proc != nullptr); + this->save_proc(); +} + +void ChunkHandler::Load() const +{ + assert(this->load_proc != nullptr); + this->load_proc(); +} + +void ChunkHandler::FixPointers() const +{ + assert(this->ptrs_proc != nullptr); + this->ptrs_proc(); +} + +void ChunkHandler::LoadCheck(size_t len) const +{ + if (this->load_check) { + assert(this->load_check_proc != nullptr); + this->load_check_proc(); + } else { + switch (_sl.block_mode) { + case CH_TABLE: + case CH_SPARSE_TABLE: + SlTableHeader({}); + FALLTHROUGH; + case CH_ARRAY: + case CH_SPARSE_ARRAY: + SlSkipArray(); + break; + case CH_RIFF: + SlSkipBytes(len); + break; + default: + NOT_REACHED(); + } + } +} + /** * Load a chunk of data (eg vehicles, stations, etc.) * @param ch The chunkhandler that will be used for the operation @@ -2129,7 +2171,7 @@ static void SlLoadChunk(const ChunkHandler &ch) _sl.expect_table_header = (_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE); /* The header should always be at the start. Read the length; the - * load_proc() should as first action process the header. */ + * Load() should as first action process the header. */ if (_sl.expect_table_header) { SlIterateArray(); } @@ -2138,12 +2180,12 @@ static void SlLoadChunk(const ChunkHandler &ch) case CH_TABLE: case CH_ARRAY: _sl.array_index = 0; - ch.load_proc(); + ch.Load(); if (_next_offs != 0) SlErrorCorrupt("Invalid array length"); break; case CH_SPARSE_TABLE: case CH_SPARSE_ARRAY: - ch.load_proc(); + ch.Load(); if (_next_offs != 0) SlErrorCorrupt("Invalid array length"); break; case CH_RIFF: @@ -2152,7 +2194,7 @@ static void SlLoadChunk(const ChunkHandler &ch) len += SlReadUint16(); _sl.obj_len = len; endoffs = _sl.reader->GetSize() + len; - ch.load_proc(); + ch.Load(); if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size"); break; default: @@ -2179,9 +2221,8 @@ static void SlLoadCheckChunk(const ChunkHandler &ch) _sl.expect_table_header = (_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE); /* The header should always be at the start. Read the length; the - * load_check_proc() should as first action process the header. */ - if (_sl.expect_table_header && ch.load_check_proc != nullptr) { - /* If load_check_proc() is nullptr, SlSkipArray() will already skip the header. */ + * LoadCheck() should as first action process the header. */ + if (_sl.expect_table_header) { SlIterateArray(); } @@ -2189,19 +2230,11 @@ static void SlLoadCheckChunk(const ChunkHandler &ch) case CH_TABLE: case CH_ARRAY: _sl.array_index = 0; - if (ch.load_check_proc != nullptr) { - ch.load_check_proc(); - } else { - SlSkipArray(); - } + ch.LoadCheck(); break; case CH_SPARSE_TABLE: case CH_SPARSE_ARRAY: - if (ch.load_check_proc != nullptr) { - ch.load_check_proc(); - } else { - SlSkipArray(); - } + ch.LoadCheck(); break; case CH_RIFF: /* Read length */ @@ -2209,11 +2242,7 @@ static void SlLoadCheckChunk(const ChunkHandler &ch) len += SlReadUint16(); _sl.obj_len = len; endoffs = _sl.reader->GetSize() + len; - if (ch.load_check_proc) { - ch.load_check_proc(); - } else { - SlSkipBytes(len); - } + ch.LoadCheck(len); if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size"); break; default: @@ -2233,9 +2262,6 @@ static void SlSaveChunk(const ChunkHandler &ch) { if (ch.type == CH_READONLY) return; - ChunkSaveLoadProc *proc = ch.save_proc; - assert(proc != nullptr); - SlWriteUint32(ch.id); Debug(sl, 2, "Saving chunk {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id); @@ -2246,19 +2272,19 @@ static void SlSaveChunk(const ChunkHandler &ch) switch (_sl.block_mode) { case CH_RIFF: - proc(); + ch.Save(); break; case CH_TABLE: case CH_ARRAY: _sl.last_array_index = 0; SlWriteByte(_sl.block_mode); - proc(); + ch.Save(); SlWriteArrayLength(0); // Terminate arrays break; case CH_SPARSE_TABLE: case CH_SPARSE_ARRAY: SlWriteByte(_sl.block_mode); - proc(); + ch.Save(); SlWriteArrayLength(0); // Terminate arrays break; default: NOT_REACHED(); @@ -2326,9 +2352,9 @@ static void SlFixPointers() _sl.action = SLA_PTRS; for (auto &ch : ChunkHandlers()) { - if (ch.ptrs_proc != nullptr) { + if (ch.fix_pointers) { Debug(sl, 3, "Fixing pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id); - ch.ptrs_proc(); + ch.FixPointers(); } } diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 34dea3cb1d..381e355e0f 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -407,6 +407,47 @@ struct ChunkHandler { ChunkSaveLoadProc *ptrs_proc; ///< Manipulate pointers in the chunk. ChunkSaveLoadProc *load_check_proc; ///< Load procedure for game preview. ChunkType type; ///< Type of the chunk. @see ChunkType + + bool fix_pointers = false; + bool load_check = false; + + ChunkHandler(uint32 id, ChunkType type) : id(id), type(type) {} + + ChunkHandler(uint32 id, ChunkSaveLoadProc *save_proc, ChunkSaveLoadProc *load_proc, ChunkSaveLoadProc *ptrs_proc, ChunkSaveLoadProc *load_check_proc, ChunkType type) + : id(id), save_proc(save_proc), load_proc(load_proc), ptrs_proc(ptrs_proc), load_check_proc(load_check_proc), type(type) + { + this->fix_pointers = ptrs_proc != nullptr; + this->load_check = load_check_proc != nullptr; + } + + virtual ~ChunkHandler() {} + + /** + * Save the chunk. + * Must be overridden, unless Chunk type is CH_READONLY. + */ + virtual void Save() const; + + /** + * Load the chunk. + * Must be overridden. + */ + virtual void Load() const; + + /** + * Fix the pointers. + * Pointers are saved using the index of the pointed object. + * On load, pointers are filled with indices and need to be fixed to point to the real object. + * Must be overridden if the chunk saves any pointer. + */ + virtual void FixPointers() const; + + /** + * Load the chunk for game preview. + * Default implementation just skips the data. + * @param len Number of bytes to skip. + */ + virtual void LoadCheck(size_t len = 0) const; }; /** A table of ChunkHandler entries. */ From c1a9fe6fbd736c9e3a93314b0721d8f2cb8a2052 Mon Sep 17 00:00:00 2001 From: glx22 Date: Wed, 9 Jun 2021 16:23:35 +0200 Subject: [PATCH 27/42] Codechange: Use static array of references to ChunkHandler --- src/saveload/ai_sl.cpp | 5 +++-- src/saveload/airport_sl.cpp | 8 ++++--- src/saveload/animated_tile_sl.cpp | 5 +++-- src/saveload/autoreplace_sl.cpp | 5 +++-- src/saveload/cargomonitor_sl.cpp | 8 ++++--- src/saveload/cargopacket_sl.cpp | 5 +++-- src/saveload/cheat_sl.cpp | 5 +++-- src/saveload/company_sl.cpp | 6 +++--- src/saveload/depot_sl.cpp | 5 +++-- src/saveload/economy_sl.cpp | 15 +++++++------ src/saveload/engine_sl.cpp | 11 ++++++---- src/saveload/game_sl.cpp | 8 ++++--- src/saveload/gamelog_sl.cpp | 5 +++-- src/saveload/goal_sl.cpp | 5 +++-- src/saveload/group_sl.cpp | 5 +++-- src/saveload/industry_sl.cpp | 17 +++++++++------ src/saveload/labelmaps_sl.cpp | 5 +++-- src/saveload/linkgraph_sl.cpp | 11 ++++++---- src/saveload/map_sl.cpp | 36 ++++++++++++++++++++----------- src/saveload/misc_sl.cpp | 8 ++++--- src/saveload/newgrf_sl.cpp | 5 +++-- src/saveload/object_sl.cpp | 8 ++++--- src/saveload/order_sl.cpp | 11 ++++++---- src/saveload/saveload.cpp | 10 ++++----- src/saveload/saveload.h | 5 ++++- src/saveload/settings_sl.cpp | 8 ++++--- src/saveload/signs_sl.cpp | 5 +++-- src/saveload/station_sl.cpp | 11 ++++++---- src/saveload/storage_sl.cpp | 5 +++-- src/saveload/story_sl.cpp | 8 ++++--- src/saveload/strings_sl.cpp | 5 +++-- src/saveload/subsidy_sl.cpp | 5 +++-- src/saveload/town_sl.cpp | 8 ++++--- src/saveload/vehicle_sl.cpp | 5 +++-- src/saveload/waypoint_sl.cpp | 5 +++-- 35 files changed, 174 insertions(+), 108 deletions(-) diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp index 047a08d5b8..f5cf040a93 100644 --- a/src/saveload/ai_sl.cpp +++ b/src/saveload/ai_sl.cpp @@ -127,8 +127,9 @@ static void Save_AIPL() } } -static const ChunkHandler ai_chunk_handlers[] = { - { 'AIPL', Save_AIPL, Load_AIPL, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler AIPL{ 'AIPL', Save_AIPL, Load_AIPL, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef ai_chunk_handlers[] = { + AIPL, }; extern const ChunkHandlerTable _ai_chunk_handlers(ai_chunk_handlers); diff --git a/src/saveload/airport_sl.cpp b/src/saveload/airport_sl.cpp index 6862fc1330..3ab852150f 100644 --- a/src/saveload/airport_sl.cpp +++ b/src/saveload/airport_sl.cpp @@ -34,9 +34,11 @@ static void Load_ATID() Load_NewGRFMapping(_airporttile_mngr); } -static const ChunkHandler airport_chunk_handlers[] = { - { 'ATID', Save_ATID, Load_ATID, nullptr, nullptr, CH_TABLE }, - { 'APID', Save_APID, Load_APID, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler ATID{ 'ATID', Save_ATID, Load_ATID, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler APID{ 'APID', Save_APID, Load_APID, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef airport_chunk_handlers[] = { + ATID, + APID, }; extern const ChunkHandlerTable _airport_chunk_handlers(airport_chunk_handlers); diff --git a/src/saveload/animated_tile_sl.cpp b/src/saveload/animated_tile_sl.cpp index 50fe05df2b..607c2ed978 100644 --- a/src/saveload/animated_tile_sl.cpp +++ b/src/saveload/animated_tile_sl.cpp @@ -68,8 +68,9 @@ static void Load_ANIT() if (SlIterateArray() != -1) SlErrorCorrupt("Too many ANIT entries"); } -static const ChunkHandler animated_tile_chunk_handlers[] = { - { 'ANIT', Save_ANIT, Load_ANIT, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler ANIT{ 'ANIT', Save_ANIT, Load_ANIT, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef animated_tile_chunk_handlers[] = { + ANIT, }; extern const ChunkHandlerTable _animated_tile_chunk_handlers(animated_tile_chunk_handlers); diff --git a/src/saveload/autoreplace_sl.cpp b/src/saveload/autoreplace_sl.cpp index 2c848c96d2..3882468330 100644 --- a/src/saveload/autoreplace_sl.cpp +++ b/src/saveload/autoreplace_sl.cpp @@ -61,8 +61,9 @@ static void Ptrs_ERNW() } } -static const ChunkHandler autoreplace_chunk_handlers[] = { - { 'ERNW', Save_ERNW, Load_ERNW, Ptrs_ERNW, nullptr, CH_TABLE }, +static const ChunkHandler ERNW{ 'ERNW', Save_ERNW, Load_ERNW, Ptrs_ERNW, nullptr, CH_TABLE }; +static const ChunkHandlerRef autoreplace_chunk_handlers[] = { + ERNW, }; extern const ChunkHandlerTable _autoreplace_chunk_handlers(autoreplace_chunk_handlers); diff --git a/src/saveload/cargomonitor_sl.cpp b/src/saveload/cargomonitor_sl.cpp index e00d383329..b660609b5f 100644 --- a/src/saveload/cargomonitor_sl.cpp +++ b/src/saveload/cargomonitor_sl.cpp @@ -127,9 +127,11 @@ static void LoadPickup() } /** Chunk definition of the cargomonitoring maps. */ -extern const ChunkHandler cargomonitor_chunk_handlers[] = { - { 'CMDL', SaveDelivery, LoadDelivery, nullptr, nullptr, CH_TABLE }, - { 'CMPU', SavePickup, LoadPickup, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler CMDL{ 'CMDL', SaveDelivery, LoadDelivery, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler CMPU{ 'CMPU', SavePickup, LoadPickup, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef cargomonitor_chunk_handlers[] = { + CMDL, + CMPU, }; extern const ChunkHandlerTable _cargomonitor_chunk_handlers(cargomonitor_chunk_handlers); diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp index def62a7b9d..c37d6434be 100644 --- a/src/saveload/cargopacket_sl.cpp +++ b/src/saveload/cargopacket_sl.cpp @@ -128,8 +128,9 @@ static void Load_CAPA() } } -static const ChunkHandler cargopacket_chunk_handlers[] = { - { 'CAPA', Save_CAPA, Load_CAPA, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler CAPA{ 'CAPA', Save_CAPA, Load_CAPA, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef cargopacket_chunk_handlers[] = { + CAPA, }; extern const ChunkHandlerTable _cargopacket_chunk_handlers(cargopacket_chunk_handlers); diff --git a/src/saveload/cheat_sl.cpp b/src/saveload/cheat_sl.cpp index cef8b7e903..f68b5a5a57 100644 --- a/src/saveload/cheat_sl.cpp +++ b/src/saveload/cheat_sl.cpp @@ -75,8 +75,9 @@ static void Load_CHTS() if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many CHTS entries"); } -static const ChunkHandler cheat_chunk_handlers[] = { - { 'CHTS', Save_CHTS, Load_CHTS, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler CHTS{ 'CHTS', Save_CHTS, Load_CHTS, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef cheat_chunk_handlers[] = { + CHTS, }; extern const ChunkHandlerTable _cheat_chunk_handlers(cheat_chunk_handlers); diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 0738688653..b4dfd13507 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -557,9 +557,9 @@ static void Ptrs_PLYR() } } - -static const ChunkHandler company_chunk_handlers[] = { - { 'PLYR', Save_PLYR, Load_PLYR, Ptrs_PLYR, Check_PLYR, CH_TABLE }, +static const ChunkHandler PLYR{ 'PLYR', Save_PLYR, Load_PLYR, Ptrs_PLYR, Check_PLYR, CH_TABLE }; +static const ChunkHandlerRef company_chunk_handlers[] = { + PLYR, }; extern const ChunkHandlerTable _company_chunk_handlers(company_chunk_handlers); diff --git a/src/saveload/depot_sl.cpp b/src/saveload/depot_sl.cpp index c1252562a5..b34108c214 100644 --- a/src/saveload/depot_sl.cpp +++ b/src/saveload/depot_sl.cpp @@ -62,8 +62,9 @@ static void Ptrs_DEPT() } } -static const ChunkHandler depot_chunk_handlers[] = { - { 'DEPT', Save_DEPT, Load_DEPT, Ptrs_DEPT, nullptr, CH_TABLE }, +static const ChunkHandler DEPT{ 'DEPT', Save_DEPT, Load_DEPT, Ptrs_DEPT, nullptr, CH_TABLE }; +static const ChunkHandlerRef depot_chunk_handlers[] = { + DEPT, }; extern const ChunkHandlerTable _depot_chunk_handlers(depot_chunk_handlers); diff --git a/src/saveload/economy_sl.cpp b/src/saveload/economy_sl.cpp index 4d7890b4b1..277901845c 100644 --- a/src/saveload/economy_sl.cpp +++ b/src/saveload/economy_sl.cpp @@ -105,12 +105,15 @@ static void Ptrs_CAPY() } } - -static const ChunkHandler economy_chunk_handlers[] = { - { 'CAPY', Save_CAPY, Load_CAPY, Ptrs_CAPY, nullptr, CH_TABLE }, - { 'PRIC', nullptr, Load_PRIC, nullptr, nullptr, CH_READONLY }, - { 'CAPR', nullptr, Load_CAPR, nullptr, nullptr, CH_READONLY }, - { 'ECMY', Save_ECMY, Load_ECMY, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler CAPY{ 'CAPY', Save_CAPY, Load_CAPY, Ptrs_CAPY, nullptr, CH_TABLE }; +static const ChunkHandler PRIC{ 'PRIC', nullptr, Load_PRIC, nullptr, nullptr, CH_READONLY }; +static const ChunkHandler CAPR{ 'CAPR', nullptr, Load_CAPR, nullptr, nullptr, CH_READONLY }; +static const ChunkHandler ECMY{ 'ECMY', Save_ECMY, Load_ECMY, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef economy_chunk_handlers[] = { + CAPY, + PRIC, + CAPR, + ECMY, }; extern const ChunkHandlerTable _economy_chunk_handlers(economy_chunk_handlers); diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp index 109d90434d..aca046ec12 100644 --- a/src/saveload/engine_sl.cpp +++ b/src/saveload/engine_sl.cpp @@ -199,10 +199,13 @@ static void Load_EIDS() } } -static const ChunkHandler engine_chunk_handlers[] = { - { 'EIDS', Save_EIDS, Load_EIDS, nullptr, nullptr, CH_TABLE }, - { 'ENGN', Save_ENGN, Load_ENGN, nullptr, nullptr, CH_TABLE }, - { 'ENGS', nullptr, Load_ENGS, nullptr, nullptr, CH_READONLY }, +static const ChunkHandler EIDS{ 'EIDS', Save_EIDS, Load_EIDS, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler ENGN{ 'ENGN', Save_ENGN, Load_ENGN, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler ENGS{ 'ENGS', nullptr, Load_ENGS, nullptr, nullptr, CH_READONLY }; +static const ChunkHandlerRef engine_chunk_handlers[] = { + EIDS, + ENGN, + ENGS, }; extern const ChunkHandlerTable _engine_chunk_handlers(engine_chunk_handlers); diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index f0083cb882..e075326ae0 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -188,9 +188,11 @@ static void Save_GSTR() } } -static const ChunkHandler game_chunk_handlers[] = { - { 'GSTR', Save_GSTR, Load_GSTR, nullptr, nullptr, CH_TABLE }, - { 'GSDT', Save_GSDT, Load_GSDT, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler GSTR{ 'GSTR', Save_GSTR, Load_GSTR, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler GSDT{ 'GSDT', Save_GSDT, Load_GSDT, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef game_chunk_handlers[] = { + GSTR, + GSDT, }; extern const ChunkHandlerTable _game_chunk_handlers(game_chunk_handlers); diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index 8cc81c8cf7..d2ca49aed2 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.cpp @@ -401,8 +401,9 @@ static void Check_GLOG() Load_GLOG_common(_load_check_data.gamelog_action, _load_check_data.gamelog_actions); } -static const ChunkHandler gamelog_chunk_handlers[] = { - { 'GLOG', Save_GLOG, Load_GLOG, nullptr, Check_GLOG, CH_TABLE } +static const ChunkHandler GLOG{ 'GLOG', Save_GLOG, Load_GLOG, nullptr, Check_GLOG, CH_TABLE }; +static const ChunkHandlerRef gamelog_chunk_handlers[] = { + GLOG, }; extern const ChunkHandlerTable _gamelog_chunk_handlers(gamelog_chunk_handlers); diff --git a/src/saveload/goal_sl.cpp b/src/saveload/goal_sl.cpp index 7e2cad491e..2dac477d0d 100644 --- a/src/saveload/goal_sl.cpp +++ b/src/saveload/goal_sl.cpp @@ -46,8 +46,9 @@ static void Load_GOAL() } } -static const ChunkHandler goal_chunk_handlers[] = { - { 'GOAL', Save_GOAL, Load_GOAL, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler GOAL{ 'GOAL', Save_GOAL, Load_GOAL, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef goal_chunk_handlers[] = { + GOAL, }; extern const ChunkHandlerTable _goal_chunk_handlers(goal_chunk_handlers); diff --git a/src/saveload/group_sl.cpp b/src/saveload/group_sl.cpp index 77ab23bd86..6c510b6e66 100644 --- a/src/saveload/group_sl.cpp +++ b/src/saveload/group_sl.cpp @@ -59,8 +59,9 @@ static void Load_GRPS() } } -static const ChunkHandler group_chunk_handlers[] = { - { 'GRPS', Save_GRPS, Load_GRPS, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler GRPS{ 'GRPS', Save_GRPS, Load_GRPS, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef group_chunk_handlers[] = { + GRPS, }; extern const ChunkHandlerTable _group_chunk_handlers(group_chunk_handlers); diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index 1be1ad2195..e1d2da93a0 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -194,12 +194,17 @@ static void Load_ITBL() } } -static const ChunkHandler industry_chunk_handlers[] = { - { 'INDY', Save_INDY, Load_INDY, Ptrs_INDY, nullptr, CH_TABLE }, - { 'IIDS', Save_IIDS, Load_IIDS, nullptr, nullptr, CH_TABLE }, - { 'TIDS', Save_TIDS, Load_TIDS, nullptr, nullptr, CH_TABLE }, - { 'IBLD', Save_IBLD, Load_IBLD, nullptr, nullptr, CH_TABLE }, - { 'ITBL', Save_ITBL, Load_ITBL, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler INDY{ 'INDY', Save_INDY, Load_INDY, Ptrs_INDY, nullptr, CH_TABLE }; +static const ChunkHandler IIDS{ 'IIDS', Save_IIDS, Load_IIDS, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler TIDS{ 'TIDS', Save_TIDS, Load_TIDS, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler IBLD{ 'IBLD', Save_IBLD, Load_IBLD, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler ITBL{ 'ITBL', Save_ITBL, Load_ITBL, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef industry_chunk_handlers[] = { + INDY, + IIDS, + TIDS, + IBLD, + ITBL, }; extern const ChunkHandlerTable _industry_chunk_handlers(industry_chunk_handlers); diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp index 6b8509b53e..970985b929 100644 --- a/src/saveload/labelmaps_sl.cpp +++ b/src/saveload/labelmaps_sl.cpp @@ -127,8 +127,9 @@ static void Load_RAIL() } } -static const ChunkHandler labelmaps_chunk_handlers[] = { - { 'RAIL', Save_RAIL, Load_RAIL, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler RAIL{ 'RAIL', Save_RAIL, Load_RAIL, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef labelmaps_chunk_handlers[] = { + RAIL, }; extern const ChunkHandlerTable _labelmaps_chunk_handlers(labelmaps_chunk_handlers); diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index 952ae1de3f..04664bed9f 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -326,10 +326,13 @@ static void Ptrs_LGRS() SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc()); } -static const ChunkHandler linkgraph_chunk_handlers[] = { - { 'LGRP', Save_LGRP, Load_LGRP, nullptr, nullptr, CH_TABLE }, - { 'LGRJ', Save_LGRJ, Load_LGRJ, nullptr, nullptr, CH_TABLE }, - { 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_TABLE }, +static const ChunkHandler LGRP{ 'LGRP', Save_LGRP, Load_LGRP, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler LGRJ{ 'LGRJ', Save_LGRJ, Load_LGRJ, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler LGRS{ 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_TABLE }; +static const ChunkHandlerRef linkgraph_chunk_handlers[] = { + LGRP, + LGRJ, + LGRS, }; extern const ChunkHandlerTable _linkgraph_chunk_handlers(linkgraph_chunk_handlers); diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index e55ac665aa..a6f9448e52 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -309,19 +309,29 @@ static void Save_MAP8() } } - -static const ChunkHandler map_chunk_handlers[] = { - { 'MAPS', Save_MAPS, Load_MAPS, nullptr, Check_MAPS, CH_TABLE }, - { 'MAPT', Save_MAPT, Load_MAPT, nullptr, nullptr, CH_RIFF }, - { 'MAPH', Save_MAPH, Load_MAPH, nullptr, nullptr, CH_RIFF }, - { 'MAPO', Save_MAP1, Load_MAP1, nullptr, nullptr, CH_RIFF }, - { 'MAP2', Save_MAP2, Load_MAP2, nullptr, nullptr, CH_RIFF }, - { 'M3LO', Save_MAP3, Load_MAP3, nullptr, nullptr, CH_RIFF }, - { 'M3HI', Save_MAP4, Load_MAP4, nullptr, nullptr, CH_RIFF }, - { 'MAP5', Save_MAP5, Load_MAP5, nullptr, nullptr, CH_RIFF }, - { 'MAPE', Save_MAP6, Load_MAP6, nullptr, nullptr, CH_RIFF }, - { 'MAP7', Save_MAP7, Load_MAP7, nullptr, nullptr, CH_RIFF }, - { 'MAP8', Save_MAP8, Load_MAP8, nullptr, nullptr, CH_RIFF }, +static const ChunkHandler MAPS{ 'MAPS', Save_MAPS, Load_MAPS, nullptr, Check_MAPS, CH_TABLE }; +static const ChunkHandler MAPT{ 'MAPT', Save_MAPT, Load_MAPT, nullptr, nullptr, CH_RIFF }; +static const ChunkHandler MAPH{ 'MAPH', Save_MAPH, Load_MAPH, nullptr, nullptr, CH_RIFF }; +static const ChunkHandler MAPO{ 'MAPO', Save_MAP1, Load_MAP1, nullptr, nullptr, CH_RIFF }; +static const ChunkHandler MAP2{ 'MAP2', Save_MAP2, Load_MAP2, nullptr, nullptr, CH_RIFF }; +static const ChunkHandler M3LO{ 'M3LO', Save_MAP3, Load_MAP3, nullptr, nullptr, CH_RIFF }; +static const ChunkHandler M3HI{ 'M3HI', Save_MAP4, Load_MAP4, nullptr, nullptr, CH_RIFF }; +static const ChunkHandler MAP5{ 'MAP5', Save_MAP5, Load_MAP5, nullptr, nullptr, CH_RIFF }; +static const ChunkHandler MAPE{ 'MAPE', Save_MAP6, Load_MAP6, nullptr, nullptr, CH_RIFF }; +static const ChunkHandler MAP7{ 'MAP7', Save_MAP7, Load_MAP7, nullptr, nullptr, CH_RIFF }; +static const ChunkHandler MAP8{ 'MAP8', Save_MAP8, Load_MAP8, nullptr, nullptr, CH_RIFF }; +static const ChunkHandlerRef map_chunk_handlers[] = { + MAPS, + MAPT, + MAPH, + MAPO, + MAP2, + M3LO, + M3HI, + MAP5, + MAPE, + MAP7, + MAP8, }; extern const ChunkHandlerTable _map_chunk_handlers(map_chunk_handlers); diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index 35b59a0212..a742090e8d 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -152,9 +152,11 @@ static void Load_VIEW() if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many DATE entries"); } -static const ChunkHandler misc_chunk_handlers[] = { - { 'DATE', Save_DATE, Load_DATE, nullptr, Check_DATE, CH_TABLE }, - { 'VIEW', Save_VIEW, Load_VIEW, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler DATE{ 'DATE', Save_DATE, Load_DATE, nullptr, Check_DATE, CH_TABLE }; +static const ChunkHandler VIEW{ 'VIEW', Save_VIEW, Load_VIEW, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef misc_chunk_handlers[] = { + DATE, + VIEW, }; extern const ChunkHandlerTable _misc_chunk_handlers(misc_chunk_handlers); diff --git a/src/saveload/newgrf_sl.cpp b/src/saveload/newgrf_sl.cpp index 20b6585622..10a65e9362 100644 --- a/src/saveload/newgrf_sl.cpp +++ b/src/saveload/newgrf_sl.cpp @@ -121,8 +121,9 @@ static void Check_NGRF() Load_NGRF_common(_load_check_data.grfconfig); } -static const ChunkHandler newgrf_chunk_handlers[] = { - { 'NGRF', Save_NGRF, Load_NGRF, nullptr, Check_NGRF, CH_TABLE } +static const ChunkHandler NGRF{ 'NGRF', Save_NGRF, Load_NGRF, nullptr, Check_NGRF, CH_TABLE }; +static const ChunkHandlerRef newgrf_chunk_handlers[] = { + NGRF, }; extern const ChunkHandlerTable _newgrf_chunk_handlers(newgrf_chunk_handlers); diff --git a/src/saveload/object_sl.cpp b/src/saveload/object_sl.cpp index 57e34af3a4..b970c39345 100644 --- a/src/saveload/object_sl.cpp +++ b/src/saveload/object_sl.cpp @@ -72,9 +72,11 @@ static void Load_OBID() Load_NewGRFMapping(_object_mngr); } -static const ChunkHandler object_chunk_handlers[] = { - { 'OBID', Save_OBID, Load_OBID, nullptr, nullptr, CH_TABLE }, - { 'OBJS', Save_OBJS, Load_OBJS, Ptrs_OBJS, nullptr, CH_TABLE }, +static const ChunkHandler OBID{ 'OBID', Save_OBID, Load_OBID, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler OBJS{ 'OBJS', Save_OBJS, Load_OBJS, Ptrs_OBJS, nullptr, CH_TABLE }; +static const ChunkHandlerRef object_chunk_handlers[] = { + OBID, + OBJS, }; extern const ChunkHandlerTable _object_chunk_handlers(object_chunk_handlers); diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index 4d9bf3d8f9..797c16d1b0 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -298,10 +298,13 @@ static void Ptrs_BKOR() } } -static const ChunkHandler order_chunk_handlers[] = { - { 'BKOR', Save_BKOR, Load_BKOR, Ptrs_BKOR, nullptr, CH_TABLE }, - { 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, nullptr, CH_TABLE }, - { 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, nullptr, CH_TABLE }, +static const ChunkHandler BKOR{ 'BKOR', Save_BKOR, Load_BKOR, Ptrs_BKOR, nullptr, CH_TABLE }; +static const ChunkHandler ORDR{ 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, nullptr, CH_TABLE }; +static const ChunkHandler ORDL{ 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, nullptr, CH_TABLE }; +static const ChunkHandlerRef order_chunk_handlers[] = { + BKOR, + ORDR, + ORDL, }; extern const ChunkHandlerTable _order_chunk_handlers(order_chunk_handlers); diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 69bbc75b1a..39941c268d 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -216,7 +216,7 @@ struct SaveLoadParams { static SaveLoadParams _sl; ///< Parameters used for/at saveload. -static const std::vector &ChunkHandlers() +static const std::vector &ChunkHandlers() { /* These define the chunks */ extern const ChunkHandlerTable _gamelog_chunk_handlers; @@ -290,7 +290,7 @@ static const std::vector &ChunkHandlers() _persistent_storage_chunk_handlers, }; - static std::vector _chunk_handlers; + static std::vector _chunk_handlers; if (_chunk_handlers.empty()) { for (auto &chunk_handler_table : _chunk_handler_tables) { @@ -313,7 +313,7 @@ static void SlNullPointers() * pointers from other pools. */ _sl_version = SAVEGAME_VERSION; - for (auto &ch : ChunkHandlers()) { + for (const ChunkHandler &ch : ChunkHandlers()) { if (ch.fix_pointers) { Debug(sl, 3, "Nulling pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id); ch.FixPointers(); @@ -2312,7 +2312,7 @@ static void SlSaveChunks() */ static const ChunkHandler *SlFindChunkHandler(uint32 id) { - for (auto &ch : ChunkHandlers()) if (ch.id == id) return &ch; + for (const ChunkHandler &ch : ChunkHandlers()) if (ch.id == id) return &ch; return nullptr; } @@ -2351,7 +2351,7 @@ static void SlFixPointers() { _sl.action = SLA_PTRS; - for (auto &ch : ChunkHandlers()) { + for (const ChunkHandler &ch : ChunkHandlers()) { if (ch.fix_pointers) { Debug(sl, 3, "Fixing pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id); ch.FixPointers(); diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 381e355e0f..2f5ebba1f3 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -450,8 +450,11 @@ struct ChunkHandler { virtual void LoadCheck(size_t len = 0) const; }; +/** A reference to ChunkHandler. */ +using ChunkHandlerRef = std::reference_wrapper; + /** A table of ChunkHandler entries. */ -using ChunkHandlerTable = span; +using ChunkHandlerTable = span; /** A table of SaveLoad entries. */ using SaveLoadTable = span; diff --git a/src/saveload/settings_sl.cpp b/src/saveload/settings_sl.cpp index 2097d86454..fe320db5d1 100644 --- a/src/saveload/settings_sl.cpp +++ b/src/saveload/settings_sl.cpp @@ -170,9 +170,11 @@ static void Save_PATS() SaveSettings(_settings, &_settings_game); } -static const ChunkHandler setting_chunk_handlers[] = { - { 'OPTS', nullptr, Load_OPTS, nullptr, nullptr, CH_READONLY }, - { 'PATS', Save_PATS, Load_PATS, nullptr, Check_PATS, CH_TABLE }, +static const ChunkHandler OPTS{ 'OPTS', nullptr, Load_OPTS, nullptr, nullptr, CH_READONLY }; +static const ChunkHandler PATS{ 'PATS', Save_PATS, Load_PATS, nullptr, Check_PATS, CH_TABLE }; +static const ChunkHandlerRef setting_chunk_handlers[] = { + OPTS, + PATS, }; extern const ChunkHandlerTable _setting_chunk_handlers(setting_chunk_handlers); diff --git a/src/saveload/signs_sl.cpp b/src/saveload/signs_sl.cpp index 4479ff63d6..21cd69f155 100644 --- a/src/saveload/signs_sl.cpp +++ b/src/saveload/signs_sl.cpp @@ -67,8 +67,9 @@ static void Load_SIGN() } } -static const ChunkHandler sign_chunk_handlers[] = { - { 'SIGN', Save_SIGN, Load_SIGN, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler SIGN{ 'SIGN', Save_SIGN, Load_SIGN, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef sign_chunk_handlers[] = { + SIGN, }; extern const ChunkHandlerTable _sign_chunk_handlers(sign_chunk_handlers); diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index d9978cd6f1..5662e4a465 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -719,10 +719,13 @@ static void Ptrs_ROADSTOP() } } -static const ChunkHandler station_chunk_handlers[] = { - { 'STNS', nullptr, Load_STNS, Ptrs_STNS, nullptr, CH_READONLY }, - { 'STNN', Save_STNN, Load_STNN, Ptrs_STNN, nullptr, CH_TABLE }, - { 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, nullptr, CH_TABLE }, +static const ChunkHandler STNS{ 'STNS', nullptr, Load_STNS, Ptrs_STNS, nullptr, CH_READONLY }; +static const ChunkHandler STNN{ 'STNN', Save_STNN, Load_STNN, Ptrs_STNN, nullptr, CH_TABLE }; +static const ChunkHandler ROAD{ 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, nullptr, CH_TABLE }; +static const ChunkHandlerRef station_chunk_handlers[] = { + STNS, + STNN, + ROAD, }; extern const ChunkHandlerTable _station_chunk_handlers(station_chunk_handlers); diff --git a/src/saveload/storage_sl.cpp b/src/saveload/storage_sl.cpp index 4838e9f12a..4a360d58d8 100644 --- a/src/saveload/storage_sl.cpp +++ b/src/saveload/storage_sl.cpp @@ -50,8 +50,9 @@ static void Save_PSAC() } } -static const ChunkHandler persistent_storage_chunk_handlers[] = { - { 'PSAC', Save_PSAC, Load_PSAC, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler PSAC{ 'PSAC', Save_PSAC, Load_PSAC, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef persistent_storage_chunk_handlers[] = { + PSAC, }; extern const ChunkHandlerTable _persistent_storage_chunk_handlers(persistent_storage_chunk_handlers); diff --git a/src/saveload/story_sl.cpp b/src/saveload/story_sl.cpp index 9dabd5cbf7..6371b4162b 100644 --- a/src/saveload/story_sl.cpp +++ b/src/saveload/story_sl.cpp @@ -105,9 +105,11 @@ static void Load_STORY_PAGE() _story_page_next_sort_value = max_sort_value + 1; } -static const ChunkHandler story_page_chunk_handlers[] = { - { 'STPE', Save_STORY_PAGE_ELEMENT, Load_STORY_PAGE_ELEMENT, nullptr, nullptr, CH_TABLE }, - { 'STPA', Save_STORY_PAGE, Load_STORY_PAGE, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler STPE{ 'STPE', Save_STORY_PAGE_ELEMENT, Load_STORY_PAGE_ELEMENT, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler STPA{ 'STPA', Save_STORY_PAGE, Load_STORY_PAGE, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef story_page_chunk_handlers[] = { + STPE, + STPA, }; extern const ChunkHandlerTable _story_page_chunk_handlers(story_page_chunk_handlers); diff --git a/src/saveload/strings_sl.cpp b/src/saveload/strings_sl.cpp index 70d001e73b..7cad1fba6e 100644 --- a/src/saveload/strings_sl.cpp +++ b/src/saveload/strings_sl.cpp @@ -130,8 +130,9 @@ static void Load_NAME() } } -static const ChunkHandler name_chunk_handlers[] = { - { 'NAME', nullptr, Load_NAME, nullptr, nullptr, CH_READONLY }, +static const ChunkHandler NAME{ 'NAME', nullptr, Load_NAME, nullptr, nullptr, CH_READONLY }; +static const ChunkHandlerRef name_chunk_handlers[] = { + NAME, }; extern const ChunkHandlerTable _name_chunk_handlers(name_chunk_handlers); diff --git a/src/saveload/subsidy_sl.cpp b/src/saveload/subsidy_sl.cpp index 0a9c25ebd2..a02c19319f 100644 --- a/src/saveload/subsidy_sl.cpp +++ b/src/saveload/subsidy_sl.cpp @@ -50,8 +50,9 @@ static void Load_SUBS() } } -static const ChunkHandler subsidy_chunk_handlers[] = { - { 'SUBS', Save_SUBS, Load_SUBS, nullptr, nullptr, CH_TABLE }, +static const ChunkHandler SUBS{ 'SUBS', Save_SUBS, Load_SUBS, nullptr, nullptr, CH_TABLE }; +static const ChunkHandlerRef subsidy_chunk_handlers[] = { + SUBS, }; extern const ChunkHandlerTable _subsidy_chunk_handlers(subsidy_chunk_handlers); diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index c5b5b0080e..906940033f 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -318,9 +318,11 @@ static void Ptrs_TOWN() } } -static const ChunkHandler town_chunk_handlers[] = { - { 'HIDS', Save_HIDS, Load_HIDS, nullptr, nullptr, CH_TABLE }, - { 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, nullptr, CH_TABLE }, +static const ChunkHandler HIDS{ 'HIDS', Save_HIDS, Load_HIDS, nullptr, nullptr, CH_TABLE }; +static const ChunkHandler CITY{ 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, nullptr, CH_TABLE }; +static const ChunkHandlerRef town_chunk_handlers[] = { + HIDS, + CITY, }; extern const ChunkHandlerTable _town_chunk_handlers(town_chunk_handlers); diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 962f5f99a6..2be5998f59 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -1064,8 +1064,9 @@ void Ptrs_VEHS() } } -static const ChunkHandler veh_chunk_handlers[] = { - { 'VEHS', Save_VEHS, Load_VEHS, Ptrs_VEHS, nullptr, CH_SPARSE_TABLE }, +static const ChunkHandler VEHS{ 'VEHS', Save_VEHS, Load_VEHS, Ptrs_VEHS, nullptr, CH_SPARSE_TABLE }; +static const ChunkHandlerRef veh_chunk_handlers[] = { + VEHS, }; extern const ChunkHandlerTable _veh_chunk_handlers(veh_chunk_handlers); diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp index 8105cc1901..bf22720fcb 100644 --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.cpp @@ -224,8 +224,9 @@ static void Ptrs_WAYP() } } -static const ChunkHandler waypoint_chunk_handlers[] = { - { 'CHKP', nullptr, Load_WAYP, Ptrs_WAYP, nullptr, CH_READONLY }, +static const ChunkHandler CHKP{ 'CHKP', nullptr, Load_WAYP, Ptrs_WAYP, nullptr, CH_READONLY }; +static const ChunkHandlerRef waypoint_chunk_handlers[] = { + CHKP, }; extern const ChunkHandlerTable _waypoint_chunk_handlers(waypoint_chunk_handlers); From 2c941cd8b3cb1774f4982b86735e276597a91750 Mon Sep 17 00:00:00 2001 From: glx22 Date: Mon, 7 Jun 2021 23:24:37 +0200 Subject: [PATCH 28/42] Codechange: Use ChunkHandlers sub-classes --- src/order_backup.h | 2 +- src/order_base.h | 2 +- src/saveload/ai_sl.cpp | 116 +++--- src/saveload/airport_sl.cpp | 44 ++- src/saveload/animated_tile_sl.cpp | 75 ++-- src/saveload/autoreplace_sl.cpp | 65 ++-- src/saveload/cargomonitor_sl.cpp | 125 +++---- src/saveload/cargopacket_sl.cpp | 42 ++- src/saveload/cheat_sl.cpp | 69 ++-- src/saveload/company_sl.cpp | 105 +++--- src/saveload/depot_sl.cpp | 61 ++-- src/saveload/economy_sl.cpp | 129 ++++--- src/saveload/engine_sl.cpp | 128 ++++--- src/saveload/game_sl.cpp | 166 ++++----- src/saveload/gamelog_sl.cpp | 83 +++-- src/saveload/goal_sl.cpp | 36 +- src/saveload/group_sl.cpp | 58 +-- src/saveload/industry_sl.cpp | 203 ++++++----- src/saveload/labelmaps_sl.cpp | 42 ++- src/saveload/linkgraph_sl.cpp | 133 +++---- src/saveload/map_sl.cpp | 567 ++++++++++++++++-------------- src/saveload/misc_sl.cpp | 99 +++--- src/saveload/newgrf_sl.cpp | 83 +++-- src/saveload/object_sl.cpp | 85 +++-- src/saveload/order_sl.cpp | 277 ++++++++------- src/saveload/settings_sl.cpp | 63 ++-- src/saveload/signs_sl.cpp | 68 ++-- src/saveload/station_sl.cpp | 182 +++++----- src/saveload/storage_sl.cpp | 45 +-- src/saveload/story_sl.cpp | 108 +++--- src/saveload/strings_sl.cpp | 29 +- src/saveload/subsidy_sl.cpp | 36 +- src/saveload/town_sl.cpp | 82 +++-- src/saveload/vehicle_sl.cpp | 131 +++---- src/saveload/waypoint_sl.cpp | 79 +++-- 35 files changed, 1953 insertions(+), 1665 deletions(-) diff --git a/src/order_backup.h b/src/order_backup.h index e1b71a71d7..c92adbb411 100644 --- a/src/order_backup.h +++ b/src/order_backup.h @@ -36,7 +36,7 @@ static const uint32 MAKE_ORDER_BACKUP_FLAG = 1U << 31; struct OrderBackup : OrderBackupPool::PoolItem<&_order_backup_pool>, BaseConsist { private: friend SaveLoadTable GetOrderBackupDescription(); ///< Saving and loading of order backups. - friend void Load_BKOR(); ///< Creating empty orders upon savegame loading. + friend struct BKORChunkHandler; ///< Creating empty orders upon savegame loading. uint32 user; ///< The user that requested the backup. TileIndex tile; ///< Tile of the depot where the order was changed. GroupID group; ///< The group the vehicle was part of. diff --git a/src/order_base.h b/src/order_base.h index 84f5289ec1..a722ef5d45 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -32,7 +32,7 @@ extern OrderListPool _orderlist_pool; */ struct Order : OrderPool::PoolItem<&_order_pool> { private: - friend void Load_VEHS(); ///< Loading of ancient vehicles. + friend struct VEHSChunkHandler; ///< Loading of ancient vehicles. friend SaveLoadTable GetOrderDescription(); ///< Saving and loading of orders. /* So we can use private/protected variables in the saveload code */ friend class SlVehicleCommon; diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp index f5cf040a93..51a67b14aa 100644 --- a/src/saveload/ai_sl.cpp +++ b/src/saveload/ai_sl.cpp @@ -57,77 +57,81 @@ static void SaveReal_AIPL(int *index_ptr) if (Company::IsValidAiID(index)) AI::Save(index); } -static void Load_AIPL() -{ - const std::vector slt = SlCompatTableHeader(_ai_company_desc, _ai_company_sl_compat); +struct AIPLChunkHandler : ChunkHandler { + AIPLChunkHandler() : ChunkHandler('AIPL', CH_TABLE) {} - /* Free all current data */ - for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { - AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(nullptr); - } + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_ai_company_desc, _ai_company_sl_compat); - CompanyID index; - while ((index = (CompanyID)SlIterateArray()) != (CompanyID)-1) { - if (index >= MAX_COMPANIES) SlErrorCorrupt("Too many AI configs"); - - _ai_saveload_is_random = false; - _ai_saveload_version = -1; - SlObject(nullptr, slt); - - if (_networking && !_network_server) { - if (Company::IsValidAiID(index)) AIInstance::LoadEmpty(); - continue; + /* Free all current data */ + for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { + AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(nullptr); } - AIConfig *config = AIConfig::GetConfig(index, AIConfig::SSS_FORCE_GAME); - if (_ai_saveload_name.empty()) { - /* A random AI. */ - config->Change(nullptr, -1, false, true); - } else { - config->Change(_ai_saveload_name.c_str(), _ai_saveload_version, false, _ai_saveload_is_random); - if (!config->HasScript()) { - /* No version of the AI available that can load the data. Try to load the - * latest version of the AI instead. */ - config->Change(_ai_saveload_name.c_str(), -1, false, _ai_saveload_is_random); + CompanyID index; + while ((index = (CompanyID)SlIterateArray()) != (CompanyID)-1) { + if (index >= MAX_COMPANIES) SlErrorCorrupt("Too many AI configs"); + + _ai_saveload_is_random = false; + _ai_saveload_version = -1; + SlObject(nullptr, slt); + + if (_networking && !_network_server) { + if (Company::IsValidAiID(index)) AIInstance::LoadEmpty(); + continue; + } + + AIConfig *config = AIConfig::GetConfig(index, AIConfig::SSS_FORCE_GAME); + if (_ai_saveload_name.empty()) { + /* A random AI. */ + config->Change(nullptr, -1, false, true); + } else { + config->Change(_ai_saveload_name.c_str(), _ai_saveload_version, false, _ai_saveload_is_random); if (!config->HasScript()) { - if (_ai_saveload_name.compare("%_dummy") != 0) { - Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version); - Debug(script, 0, "A random other AI will be loaded in its place."); + /* No version of the AI available that can load the data. Try to load the + * latest version of the AI instead. */ + config->Change(_ai_saveload_name.c_str(), -1, false, _ai_saveload_is_random); + if (!config->HasScript()) { + if (_ai_saveload_name.compare("%_dummy") != 0) { + Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version); + Debug(script, 0, "A random other AI will be loaded in its place."); + } else { + Debug(script, 0, "The savegame had no AIs available at the time of saving."); + Debug(script, 0, "A random available AI will be loaded now."); + } } else { - Debug(script, 0, "The savegame had no AIs available at the time of saving."); - Debug(script, 0, "A random available AI will be loaded now."); + Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version); + Debug(script, 0, "The latest version of that AI has been loaded instead, but it'll not get the savegame data as it's incompatible."); } - } else { - Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version); - Debug(script, 0, "The latest version of that AI has been loaded instead, but it'll not get the savegame data as it's incompatible."); + /* Make sure the AI doesn't get the saveload data, as it was not the + * writer of the saveload data in the first place */ + _ai_saveload_version = -1; } - /* Make sure the AI doesn't get the saveload data, as it was not the - * writer of the saveload data in the first place */ - _ai_saveload_version = -1; + } + + config->StringToSettings(_ai_saveload_settings); + + /* Start the AI directly if it was active in the savegame */ + if (Company::IsValidAiID(index)) { + AI::StartNew(index, false); + AI::Load(index, _ai_saveload_version); } } + } - config->StringToSettings(_ai_saveload_settings); + void Save() const override + { + SlTableHeader(_ai_company_desc); - /* Start the AI directly if it was active in the savegame */ - if (Company::IsValidAiID(index)) { - AI::StartNew(index, false); - AI::Load(index, _ai_saveload_version); + for (int i = COMPANY_FIRST; i < MAX_COMPANIES; i++) { + SlSetArrayIndex(i); + SlAutolength((AutolengthProc *)SaveReal_AIPL, &i); } } -} +}; -static void Save_AIPL() -{ - SlTableHeader(_ai_company_desc); - - for (int i = COMPANY_FIRST; i < MAX_COMPANIES; i++) { - SlSetArrayIndex(i); - SlAutolength((AutolengthProc *)SaveReal_AIPL, &i); - } -} - -static const ChunkHandler AIPL{ 'AIPL', Save_AIPL, Load_AIPL, nullptr, nullptr, CH_TABLE }; +static const AIPLChunkHandler AIPL; static const ChunkHandlerRef ai_chunk_handlers[] = { AIPL, }; diff --git a/src/saveload/airport_sl.cpp b/src/saveload/airport_sl.cpp index 3ab852150f..e762c54d01 100644 --- a/src/saveload/airport_sl.cpp +++ b/src/saveload/airport_sl.cpp @@ -14,28 +14,36 @@ #include "../safeguards.h" -static void Save_APID() -{ - Save_NewGRFMapping(_airport_mngr); -} +struct APIDChunkHandler : ChunkHandler { + APIDChunkHandler() : ChunkHandler('APID', CH_TABLE) {} -static void Load_APID() -{ - Load_NewGRFMapping(_airport_mngr); -} + void Save() const override + { + Save_NewGRFMapping(_airport_mngr); + } -static void Save_ATID() -{ - Save_NewGRFMapping(_airporttile_mngr); -} + void Load() const override + { + Load_NewGRFMapping(_airport_mngr); + } +}; -static void Load_ATID() -{ - Load_NewGRFMapping(_airporttile_mngr); -} +struct ATIDChunkHandler : ChunkHandler { + ATIDChunkHandler() : ChunkHandler('ATID', CH_TABLE) {} -static const ChunkHandler ATID{ 'ATID', Save_ATID, Load_ATID, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler APID{ 'APID', Save_APID, Load_APID, nullptr, nullptr, CH_TABLE }; + void Save() const override + { + Save_NewGRFMapping(_airporttile_mngr); + } + + void Load() const override + { + Load_NewGRFMapping(_airporttile_mngr); + } +}; + +static const ATIDChunkHandler ATID; +static const APIDChunkHandler APID; static const ChunkHandlerRef airport_chunk_handlers[] = { ATID, APID, diff --git a/src/saveload/animated_tile_sl.cpp b/src/saveload/animated_tile_sl.cpp index 607c2ed978..282968f9b4 100644 --- a/src/saveload/animated_tile_sl.cpp +++ b/src/saveload/animated_tile_sl.cpp @@ -24,51 +24,50 @@ static const SaveLoad _animated_tile_desc[] = { SLEG_VECTOR("tiles", _animated_tiles, SLE_UINT32), }; -/** - * Save the ANIT chunk. - */ -static void Save_ANIT() -{ - SlTableHeader(_animated_tile_desc); +struct ANITChunkHandler : ChunkHandler { + ANITChunkHandler() : ChunkHandler('ANIT', CH_TABLE) {} - SlSetArrayIndex(0); - SlGlobList(_animated_tile_desc); -} + void Save() const override + { + SlTableHeader(_animated_tile_desc); -/** - * Load the ANIT chunk; the chunk containing the animated tiles. - */ -static void Load_ANIT() -{ - /* Before version 80 we did NOT have a variable length animated tile table */ - if (IsSavegameVersionBefore(SLV_80)) { - /* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */ - TileIndex anim_list[256]; - SlCopy(anim_list, 256, IsSavegameVersionBefore(SLV_6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32); + SlSetArrayIndex(0); + SlGlobList(_animated_tile_desc); + } - for (int i = 0; i < 256; i++) { - if (anim_list[i] == 0) break; - _animated_tiles.push_back(anim_list[i]); + void Load() const override + { + /* Before version 80 we did NOT have a variable length animated tile table */ + if (IsSavegameVersionBefore(SLV_80)) { + /* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */ + TileIndex anim_list[256]; + SlCopy(anim_list, 256, IsSavegameVersionBefore(SLV_6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32); + + for (int i = 0; i < 256; i++) { + if (anim_list[i] == 0) break; + _animated_tiles.push_back(anim_list[i]); + } + return; } - return; + + if (IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY)) { + size_t count = SlGetFieldLength() / sizeof(_animated_tiles.front()); + _animated_tiles.clear(); + _animated_tiles.resize(_animated_tiles.size() + count); + SlCopy(_animated_tiles.data(), count, SLE_UINT32); + return; + } + + const std::vector slt = SlCompatTableHeader(_animated_tile_desc, _animated_tile_sl_compat); + + if (SlIterateArray() == -1) return; + SlGlobList(slt); + if (SlIterateArray() != -1) SlErrorCorrupt("Too many ANIT entries"); } +}; - if (IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY)) { - size_t count = SlGetFieldLength() / sizeof(_animated_tiles.front()); - _animated_tiles.clear(); - _animated_tiles.resize(_animated_tiles.size() + count); - SlCopy(_animated_tiles.data(), count, SLE_UINT32); - return; - } - const std::vector slt = SlCompatTableHeader(_animated_tile_desc, _animated_tile_sl_compat); - - if (SlIterateArray() == -1) return; - SlGlobList(slt); - if (SlIterateArray() != -1) SlErrorCorrupt("Too many ANIT entries"); -} - -static const ChunkHandler ANIT{ 'ANIT', Save_ANIT, Load_ANIT, nullptr, nullptr, CH_TABLE }; +static const ANITChunkHandler ANIT; static const ChunkHandlerRef animated_tile_chunk_handlers[] = { ANIT, }; diff --git a/src/saveload/autoreplace_sl.cpp b/src/saveload/autoreplace_sl.cpp index 3882468330..6a9dd8f006 100644 --- a/src/saveload/autoreplace_sl.cpp +++ b/src/saveload/autoreplace_sl.cpp @@ -25,43 +25,50 @@ static const SaveLoad _engine_renew_desc[] = { SLE_CONDVAR(EngineRenew, replace_when_old, SLE_BOOL, SLV_175, SL_MAX_VERSION), }; -static void Save_ERNW() -{ - SlTableHeader(_engine_renew_desc); - - for (EngineRenew *er : EngineRenew::Iterate()) { - SlSetArrayIndex(er->index); - SlObject(er, _engine_renew_desc); +struct ERNWChunkHandler : ChunkHandler { + ERNWChunkHandler() : ChunkHandler('ERNW', CH_TABLE) + { + this->fix_pointers = true; } -} -static void Load_ERNW() -{ - const std::vector slt = SlCompatTableHeader(_engine_renew_desc, _engine_renew_sl_compat); + void Save() const override + { + SlTableHeader(_engine_renew_desc); - int index; - - while ((index = SlIterateArray()) != -1) { - EngineRenew *er = new (index) EngineRenew(); - SlObject(er, slt); - - /* Advanced vehicle lists, ungrouped vehicles got added */ - if (IsSavegameVersionBefore(SLV_60)) { - er->group_id = ALL_GROUP; - } else if (IsSavegameVersionBefore(SLV_71)) { - if (er->group_id == DEFAULT_GROUP) er->group_id = ALL_GROUP; + for (EngineRenew *er : EngineRenew::Iterate()) { + SlSetArrayIndex(er->index); + SlObject(er, _engine_renew_desc); } } -} -static void Ptrs_ERNW() -{ - for (EngineRenew *er : EngineRenew::Iterate()) { - SlObject(er, _engine_renew_desc); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_engine_renew_desc, _engine_renew_sl_compat); + + int index; + + while ((index = SlIterateArray()) != -1) { + EngineRenew *er = new (index) EngineRenew(); + SlObject(er, slt); + + /* Advanced vehicle lists, ungrouped vehicles got added */ + if (IsSavegameVersionBefore(SLV_60)) { + er->group_id = ALL_GROUP; + } else if (IsSavegameVersionBefore(SLV_71)) { + if (er->group_id == DEFAULT_GROUP) er->group_id = ALL_GROUP; + } + } } -} -static const ChunkHandler ERNW{ 'ERNW', Save_ERNW, Load_ERNW, Ptrs_ERNW, nullptr, CH_TABLE }; + void FixPointers() const override + { + for (EngineRenew *er : EngineRenew::Iterate()) { + SlObject(er, _engine_renew_desc); + } + } +}; + +static const ERNWChunkHandler ERNW; static const ChunkHandlerRef autoreplace_chunk_handlers[] = { ERNW, }; diff --git a/src/saveload/cargomonitor_sl.cpp b/src/saveload/cargomonitor_sl.cpp index b660609b5f..80b32f16b6 100644 --- a/src/saveload/cargomonitor_sl.cpp +++ b/src/saveload/cargomonitor_sl.cpp @@ -43,92 +43,97 @@ static CargoMonitorID FixupCargoMonitor(CargoMonitorID number) return number; } -/** Save the #_cargo_deliveries monitoring map. */ -static void SaveDelivery() -{ - SlTableHeader(_cargomonitor_pair_desc); +/** #_cargo_deliveries monitoring map. */ +struct CMDLChunkHandler : ChunkHandler { + CMDLChunkHandler() : ChunkHandler('CMDL', CH_TABLE) {} - TempStorage storage; + void Save() const override + { + SlTableHeader(_cargomonitor_pair_desc); - int i = 0; - CargoMonitorMap::const_iterator iter = _cargo_deliveries.begin(); - while (iter != _cargo_deliveries.end()) { - storage.number = iter->first; - storage.amount = iter->second; + TempStorage storage; - SlSetArrayIndex(i); - SlObject(&storage, _cargomonitor_pair_desc); + int i = 0; + CargoMonitorMap::const_iterator iter = _cargo_deliveries.begin(); + while (iter != _cargo_deliveries.end()) { + storage.number = iter->first; + storage.amount = iter->second; - i++; - iter++; + SlSetArrayIndex(i); + SlObject(&storage, _cargomonitor_pair_desc); + + i++; + iter++; + } } -} -/** Load the #_cargo_deliveries monitoring map. */ -static void LoadDelivery() -{ - const std::vector slt = SlCompatTableHeader(_cargomonitor_pair_desc, _cargomonitor_pair_sl_compat); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_cargomonitor_pair_desc, _cargomonitor_pair_sl_compat); - TempStorage storage; - bool fix = IsSavegameVersionBefore(SLV_FIX_CARGO_MONITOR); + TempStorage storage; + bool fix = IsSavegameVersionBefore(SLV_FIX_CARGO_MONITOR); - ClearCargoDeliveryMonitoring(); - for (;;) { - if (SlIterateArray() < 0) break; - SlObject(&storage, slt); + ClearCargoDeliveryMonitoring(); + for (;;) { + if (SlIterateArray() < 0) break; + SlObject(&storage, slt); - if (fix) storage.number = FixupCargoMonitor(storage.number); + if (fix) storage.number = FixupCargoMonitor(storage.number); - std::pair p(storage.number, storage.amount); - _cargo_deliveries.insert(p); + std::pair p(storage.number, storage.amount); + _cargo_deliveries.insert(p); + } } -} +}; +/** #_cargo_pickups monitoring map. */ +struct CMPUChunkHandler : ChunkHandler { + CMPUChunkHandler() : ChunkHandler('CMPU', CH_TABLE) {} -/** Save the #_cargo_pickups monitoring map. */ -static void SavePickup() -{ - SlTableHeader(_cargomonitor_pair_desc); + void Save() const override + { + SlTableHeader(_cargomonitor_pair_desc); - TempStorage storage; + TempStorage storage; - int i = 0; - CargoMonitorMap::const_iterator iter = _cargo_pickups.begin(); - while (iter != _cargo_pickups.end()) { - storage.number = iter->first; - storage.amount = iter->second; + int i = 0; + CargoMonitorMap::const_iterator iter = _cargo_pickups.begin(); + while (iter != _cargo_pickups.end()) { + storage.number = iter->first; + storage.amount = iter->second; - SlSetArrayIndex(i); - SlObject(&storage, _cargomonitor_pair_desc); + SlSetArrayIndex(i); + SlObject(&storage, _cargomonitor_pair_desc); - i++; - iter++; + i++; + iter++; + } } -} -/** Load the #_cargo_pickups monitoring map. */ -static void LoadPickup() -{ - const std::vector slt = SlCompatTableHeader(_cargomonitor_pair_desc, _cargomonitor_pair_sl_compat); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_cargomonitor_pair_desc, _cargomonitor_pair_sl_compat); - TempStorage storage; - bool fix = IsSavegameVersionBefore(SLV_FIX_CARGO_MONITOR); + TempStorage storage; + bool fix = IsSavegameVersionBefore(SLV_FIX_CARGO_MONITOR); - ClearCargoPickupMonitoring(); - for (;;) { - if (SlIterateArray() < 0) break; - SlObject(&storage, slt); + ClearCargoPickupMonitoring(); + for (;;) { + if (SlIterateArray() < 0) break; + SlObject(&storage, slt); - if (fix) storage.number = FixupCargoMonitor(storage.number); + if (fix) storage.number = FixupCargoMonitor(storage.number); - std::pair p(storage.number, storage.amount); - _cargo_pickups.insert(p); + std::pair p(storage.number, storage.amount); + _cargo_pickups.insert(p); + } } -} +}; /** Chunk definition of the cargomonitoring maps. */ -static const ChunkHandler CMDL{ 'CMDL', SaveDelivery, LoadDelivery, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler CMPU{ 'CMPU', SavePickup, LoadPickup, nullptr, nullptr, CH_TABLE }; +static const CMDLChunkHandler CMDL; +static const CMPUChunkHandler CMPU; static const ChunkHandlerRef cargomonitor_chunk_handlers[] = { CMDL, CMPU, diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp index c37d6434be..95b9bec6bf 100644 --- a/src/saveload/cargopacket_sl.cpp +++ b/src/saveload/cargopacket_sl.cpp @@ -100,35 +100,33 @@ SaveLoadTable GetCargoPacketDesc() return _cargopacket_desc; } -/** - * Save the cargo packets. - */ -static void Save_CAPA() -{ - SlTableHeader(GetCargoPacketDesc()); +struct CAPAChunkHandler : ChunkHandler { + CAPAChunkHandler() : ChunkHandler('CAPA', CH_TABLE) {} - for (CargoPacket *cp : CargoPacket::Iterate()) { - SlSetArrayIndex(cp->index); - SlObject(cp, GetCargoPacketDesc()); + void Save() const override + { + SlTableHeader(GetCargoPacketDesc()); + + for (CargoPacket *cp : CargoPacket::Iterate()) { + SlSetArrayIndex(cp->index); + SlObject(cp, GetCargoPacketDesc()); + } } -} -/** - * Load the cargo packets. - */ -static void Load_CAPA() -{ - const std::vector slt = SlCompatTableHeader(GetCargoPacketDesc(), _cargopacket_sl_compat); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(GetCargoPacketDesc(), _cargopacket_sl_compat); - int index; + int index; - while ((index = SlIterateArray()) != -1) { - CargoPacket *cp = new (index) CargoPacket(); - SlObject(cp, slt); + while ((index = SlIterateArray()) != -1) { + CargoPacket *cp = new (index) CargoPacket(); + SlObject(cp, slt); + } } -} +}; -static const ChunkHandler CAPA{ 'CAPA', Save_CAPA, Load_CAPA, nullptr, nullptr, CH_TABLE }; +static const CAPAChunkHandler CAPA; static const ChunkHandlerRef cargopacket_chunk_handlers[] = { CAPA, }; diff --git a/src/saveload/cheat_sl.cpp b/src/saveload/cheat_sl.cpp index f68b5a5a57..939a734aaf 100644 --- a/src/saveload/cheat_sl.cpp +++ b/src/saveload/cheat_sl.cpp @@ -35,47 +35,46 @@ static const SaveLoad _cheats_desc[] = { SLE_VAR(Cheats, edit_max_hl.value, SLE_BOOL), }; -/** - * Save the cheat values. - */ -static void Save_CHTS() -{ - SlTableHeader(_cheats_desc); - SlSetArrayIndex(0); - SlObject(&_cheats, _cheats_desc); -} +struct CHTSChunkHandler : ChunkHandler { + CHTSChunkHandler() : ChunkHandler('CHTS', CH_TABLE) {} -/** - * Load the cheat values. - */ -static void Load_CHTS() -{ - std::vector slt = SlCompatTableHeader(_cheats_desc, _cheats_sl_compat); + void Save() const override + { + SlTableHeader(_cheats_desc); - if (IsSavegameVersionBefore(SLV_TABLE_CHUNKS)) { - size_t count = SlGetFieldLength(); - std::vector oslt; - - /* Cheats were added over the years without a savegame bump. They are - * stored as 2 SLE_BOOLs per entry. "count" indicates how many SLE_BOOLs - * are stored for this savegame. So read only "count" SLE_BOOLs (and in - * result "count / 2" cheats). */ - for (auto &sld : slt) { - count--; - oslt.push_back(sld); - - if (count == 0) break; - } - slt = oslt; + SlSetArrayIndex(0); + SlObject(&_cheats, _cheats_desc); } - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlObject(&_cheats, slt); - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many CHTS entries"); -} + void Load() const override + { + std::vector slt = SlCompatTableHeader(_cheats_desc, _cheats_sl_compat); -static const ChunkHandler CHTS{ 'CHTS', Save_CHTS, Load_CHTS, nullptr, nullptr, CH_TABLE }; + if (IsSavegameVersionBefore(SLV_TABLE_CHUNKS)) { + size_t count = SlGetFieldLength(); + std::vector oslt; + + /* Cheats were added over the years without a savegame bump. They are + * stored as 2 SLE_BOOLs per entry. "count" indicates how many SLE_BOOLs + * are stored for this savegame. So read only "count" SLE_BOOLs (and in + * result "count / 2" cheats). */ + for (auto &sld : slt) { + count--; + oslt.push_back(sld); + + if (count == 0) break; + } + slt = oslt; + } + + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; + SlObject(&_cheats, slt); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many CHTS entries"); + } +}; + +static const CHTSChunkHandler CHTS; static const ChunkHandlerRef cheat_chunk_handlers[] = { CHTS, }; diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index b4dfd13507..fab674f8bf 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -497,67 +497,76 @@ static const SaveLoad _company_desc[] = { SLEG_CONDSTRUCTLIST("liveries", SlCompanyLiveries, SLV_34, SL_MAX_VERSION), }; -static void Save_PLYR() -{ - SlTableHeader(_company_desc); - - for (Company *c : Company::Iterate()) { - SlSetArrayIndex(c->index); - SlObject(c, _company_desc); +struct PLYRChunkHandler : ChunkHandler { + PLYRChunkHandler() : ChunkHandler('PLYR', CH_TABLE) + { + this->load_check = true; + this->fix_pointers = true; } -} -static void Load_PLYR() -{ - const std::vector slt = SlCompatTableHeader(_company_desc, _company_sl_compat); + void Save() const override + { + SlTableHeader(_company_desc); - int index; - while ((index = SlIterateArray()) != -1) { - Company *c = new (index) Company(); - SlObject(c, slt); - _company_colours[index] = (Colours)c->colour; - } -} - -static void Check_PLYR() -{ - const std::vector slt = SlCompatTableHeader(_company_desc, _company_sl_compat); - - int index; - while ((index = SlIterateArray()) != -1) { - CompanyProperties *cprops = new CompanyProperties(); - SlObject(cprops, slt); - - /* We do not load old custom names */ - if (IsSavegameVersionBefore(SLV_84)) { - if (GetStringTab(cprops->name_1) == TEXT_TAB_OLD_CUSTOM) { - cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE; - } - - if (GetStringTab(cprops->president_name_1) == TEXT_TAB_OLD_CUSTOM) { - cprops->president_name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE; - } + for (Company *c : Company::Iterate()) { + SlSetArrayIndex(c->index); + SlObject(c, _company_desc); } + } - if (cprops->name.empty() && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) && + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_company_desc, _company_sl_compat); + + int index; + while ((index = SlIterateArray()) != -1) { + Company *c = new (index) Company(); + SlObject(c, slt); + _company_colours[index] = (Colours)c->colour; + } + } + + + void LoadCheck(size_t) const override + { + const std::vector slt = SlCompatTableHeader(_company_desc, _company_sl_compat); + + int index; + while ((index = SlIterateArray()) != -1) { + CompanyProperties *cprops = new CompanyProperties(); + SlObject(cprops, slt); + + /* We do not load old custom names */ + if (IsSavegameVersionBefore(SLV_84)) { + if (GetStringTab(cprops->name_1) == TEXT_TAB_OLD_CUSTOM) { + cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE; + } + + if (GetStringTab(cprops->president_name_1) == TEXT_TAB_OLD_CUSTOM) { + cprops->president_name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE; + } + } + + if (cprops->name.empty() && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) && cprops->name_1 != STR_GAME_SAVELOAD_NOT_AVAILABLE && cprops->name_1 != STR_SV_UNNAMED && cprops->name_1 != SPECSTR_ANDCO_NAME && cprops->name_1 != SPECSTR_PRESIDENT_NAME && cprops->name_1 != SPECSTR_SILLY_NAME) { - cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE; + cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE; + } + + if (!_load_check_data.companies.Insert(index, cprops)) delete cprops; } - - if (!_load_check_data.companies.Insert(index, cprops)) delete cprops; } -} -static void Ptrs_PLYR() -{ - for (Company *c : Company::Iterate()) { - SlObject(c, _company_desc); + void FixPointers() const override + { + for (Company *c : Company::Iterate()) { + SlObject(c, _company_desc); + } } -} +}; -static const ChunkHandler PLYR{ 'PLYR', Save_PLYR, Load_PLYR, Ptrs_PLYR, Check_PLYR, CH_TABLE }; +static const PLYRChunkHandler PLYR; static const ChunkHandlerRef company_chunk_handlers[] = { PLYR, }; diff --git a/src/saveload/depot_sl.cpp b/src/saveload/depot_sl.cpp index b34108c214..ef0c406e22 100644 --- a/src/saveload/depot_sl.cpp +++ b/src/saveload/depot_sl.cpp @@ -29,40 +29,47 @@ static const SaveLoad _depot_desc[] = { SLE_CONDVAR(Depot, build_date, SLE_INT32, SLV_142, SL_MAX_VERSION), }; -static void Save_DEPT() -{ - SlTableHeader(_depot_desc); - - for (Depot *depot : Depot::Iterate()) { - SlSetArrayIndex(depot->index); - SlObject(depot, _depot_desc); +struct DEPTChunkHandler : ChunkHandler { + DEPTChunkHandler() : ChunkHandler('DEPT', CH_TABLE) + { + this->fix_pointers = true; } -} -static void Load_DEPT() -{ - const std::vector slt = SlCompatTableHeader(_depot_desc, _depot_sl_compat); + void Save() const override + { + SlTableHeader(_depot_desc); - int index; - - while ((index = SlIterateArray()) != -1) { - Depot *depot = new (index) Depot(); - SlObject(depot, slt); - - /* Set the town 'pointer' so we can restore it later. */ - if (IsSavegameVersionBefore(SLV_141)) depot->town = (Town *)(size_t)_town_index; + for (Depot *depot : Depot::Iterate()) { + SlSetArrayIndex(depot->index); + SlObject(depot, _depot_desc); + } } -} -static void Ptrs_DEPT() -{ - for (Depot *depot : Depot::Iterate()) { - SlObject(depot, _depot_desc); - if (IsSavegameVersionBefore(SLV_141)) depot->town = Town::Get((size_t)depot->town); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_depot_desc, _depot_sl_compat); + + int index; + + while ((index = SlIterateArray()) != -1) { + Depot *depot = new (index) Depot(); + SlObject(depot, slt); + + /* Set the town 'pointer' so we can restore it later. */ + if (IsSavegameVersionBefore(SLV_141)) depot->town = (Town *)(size_t)_town_index; + } } -} -static const ChunkHandler DEPT{ 'DEPT', Save_DEPT, Load_DEPT, Ptrs_DEPT, nullptr, CH_TABLE }; + void FixPointers() const override + { + for (Depot *depot : Depot::Iterate()) { + SlObject(depot, _depot_desc); + if (IsSavegameVersionBefore(SLV_141)) depot->town = Town::Get((size_t)depot->town); + } + } +}; + +static const DEPTChunkHandler DEPT; static const ChunkHandlerRef depot_chunk_handlers[] = { DEPT, }; diff --git a/src/saveload/economy_sl.cpp b/src/saveload/economy_sl.cpp index 277901845c..3ce1441eea 100644 --- a/src/saveload/economy_sl.cpp +++ b/src/saveload/economy_sl.cpp @@ -18,22 +18,30 @@ #include "../safeguards.h" /** Prices in pre 126 savegames */ -static void Load_PRIC() -{ - /* Old games store 49 base prices, very old games store them as int32 */ - int vt = IsSavegameVersionBefore(SLV_65) ? SLE_FILE_I32 : SLE_FILE_I64; - SlCopy(nullptr, 49, vt | SLE_VAR_NULL); - SlCopy(nullptr, 49, SLE_FILE_U16 | SLE_VAR_NULL); -} +struct PRICChunkHandler : ChunkHandler { + PRICChunkHandler() : ChunkHandler('PRIC', CH_READONLY) {} + + void Load() const override + { + /* Old games store 49 base prices, very old games store them as int32 */ + int vt = IsSavegameVersionBefore(SLV_65) ? SLE_FILE_I32 : SLE_FILE_I64; + SlCopy(nullptr, 49, vt | SLE_VAR_NULL); + SlCopy(nullptr, 49, SLE_FILE_U16 | SLE_VAR_NULL); + } +}; /** Cargo payment rates in pre 126 savegames */ -static void Load_CAPR() -{ - uint num_cargo = IsSavegameVersionBefore(SLV_55) ? 12 : IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO; - int vt = IsSavegameVersionBefore(SLV_65) ? SLE_FILE_I32 : SLE_FILE_I64; - SlCopy(nullptr, num_cargo, vt | SLE_VAR_NULL); - SlCopy(nullptr, num_cargo, SLE_FILE_U16 | SLE_VAR_NULL); -} +struct CAPRChunkHandler : ChunkHandler { + CAPRChunkHandler() : ChunkHandler('CAPR', CH_READONLY) {} + + void Load() const override + { + uint num_cargo = IsSavegameVersionBefore(SLV_55) ? 12 : IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO; + int vt = IsSavegameVersionBefore(SLV_65) ? SLE_FILE_I32 : SLE_FILE_I64; + SlCopy(nullptr, num_cargo, vt | SLE_VAR_NULL); + SlCopy(nullptr, num_cargo, SLE_FILE_U16 | SLE_VAR_NULL); + } +}; static const SaveLoad _economy_desc[] = { SLE_CONDVAR(Economy, old_max_loan_unround, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), @@ -49,25 +57,29 @@ static const SaveLoad _economy_desc[] = { }; /** Economy variables */ -static void Save_ECMY() -{ - SlTableHeader(_economy_desc); +struct ECMYChunkHandler : ChunkHandler { + ECMYChunkHandler() : ChunkHandler('ECMY', CH_TABLE) {} - SlSetArrayIndex(0); - SlObject(&_economy, _economy_desc); -} + void Save() const override + { + SlTableHeader(_economy_desc); -/** Economy variables */ -static void Load_ECMY() -{ - const std::vector slt = SlCompatTableHeader(_economy_desc, _economy_sl_compat); + SlSetArrayIndex(0); + SlObject(&_economy, _economy_desc); + } - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlObject(&_economy, slt); - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many ECMY entries"); - StartupIndustryDailyChanges(IsSavegameVersionBefore(SLV_102)); // old savegames will need to be initialized -} + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_economy_desc, _economy_sl_compat); + + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; + SlObject(&_economy, slt); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many ECMY entries"); + + StartupIndustryDailyChanges(IsSavegameVersionBefore(SLV_102)); // old savegames will need to be initialized + } +}; static const SaveLoad _cargopayment_desc[] = { SLE_REF(CargoPayment, front, REF_VEHICLE), @@ -76,39 +88,46 @@ static const SaveLoad _cargopayment_desc[] = { SLE_CONDVAR(CargoPayment, visual_transfer, SLE_INT64, SLV_181, SL_MAX_VERSION), }; -static void Save_CAPY() -{ - SlTableHeader(_cargopayment_desc); - - for (CargoPayment *cp : CargoPayment::Iterate()) { - SlSetArrayIndex(cp->index); - SlObject(cp, _cargopayment_desc); +struct CAPYChunkHandler : ChunkHandler { + CAPYChunkHandler() : ChunkHandler('CAPY', CH_TABLE) + { + this->fix_pointers = true; } -} -static void Load_CAPY() -{ - const std::vector slt = SlCompatTableHeader(_cargopayment_desc, _cargopayment_sl_compat); + void Save() const override + { + SlTableHeader(_cargopayment_desc); - int index; - - while ((index = SlIterateArray()) != -1) { - CargoPayment *cp = new (index) CargoPayment(); - SlObject(cp, slt); + for (CargoPayment *cp : CargoPayment::Iterate()) { + SlSetArrayIndex(cp->index); + SlObject(cp, _cargopayment_desc); + } } -} -static void Ptrs_CAPY() -{ - for (CargoPayment *cp : CargoPayment::Iterate()) { - SlObject(cp, _cargopayment_desc); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_cargopayment_desc, _cargopayment_sl_compat); + + int index; + + while ((index = SlIterateArray()) != -1) { + CargoPayment *cp = new (index) CargoPayment(); + SlObject(cp, slt); + } } -} -static const ChunkHandler CAPY{ 'CAPY', Save_CAPY, Load_CAPY, Ptrs_CAPY, nullptr, CH_TABLE }; -static const ChunkHandler PRIC{ 'PRIC', nullptr, Load_PRIC, nullptr, nullptr, CH_READONLY }; -static const ChunkHandler CAPR{ 'CAPR', nullptr, Load_CAPR, nullptr, nullptr, CH_READONLY }; -static const ChunkHandler ECMY{ 'ECMY', Save_ECMY, Load_ECMY, nullptr, nullptr, CH_TABLE }; + void FixPointers() const override + { + for (CargoPayment *cp : CargoPayment::Iterate()) { + SlObject(cp, _cargopayment_desc); + } + } +}; + +static const CAPYChunkHandler CAPY; +static const PRICChunkHandler PRIC; +static const CAPRChunkHandler CAPR; +static const ECMYChunkHandler ECMY; static const ChunkHandlerRef economy_chunk_handlers[] = { CAPY, PRIC, diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp index aca046ec12..39699e04d5 100644 --- a/src/saveload/engine_sl.cpp +++ b/src/saveload/engine_sl.cpp @@ -80,37 +80,41 @@ Engine *GetTempDataEngine(EngineID index) } } -static void Save_ENGN() -{ - SlTableHeader(_engine_desc); +struct ENGNChunkHandler : ChunkHandler { + ENGNChunkHandler() : ChunkHandler('ENGN', CH_TABLE) {} - for (Engine *e : Engine::Iterate()) { - SlSetArrayIndex(e->index); - SlObject(e, _engine_desc); - } -} + void Save() const override + { + SlTableHeader(_engine_desc); -static void Load_ENGN() -{ - const std::vector slt = SlCompatTableHeader(_engine_desc, _engine_sl_compat); - - /* As engine data is loaded before engines are initialized we need to load - * this information into a temporary array. This is then copied into the - * engine pool after processing NewGRFs by CopyTempEngineData(). */ - int index; - while ((index = SlIterateArray()) != -1) { - Engine *e = GetTempDataEngine(index); - SlObject(e, slt); - - if (IsSavegameVersionBefore(SLV_179)) { - /* preview_company_rank was replaced with preview_company and preview_asked. - * Just cancel any previews. */ - e->flags &= ~4; // ENGINE_OFFER_WINDOW_OPEN - e->preview_company = INVALID_COMPANY; - e->preview_asked = (CompanyMask)-1; + for (Engine *e : Engine::Iterate()) { + SlSetArrayIndex(e->index); + SlObject(e, _engine_desc); } } -} + + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_engine_desc, _engine_sl_compat); + + /* As engine data is loaded before engines are initialized we need to load + * this information into a temporary array. This is then copied into the + * engine pool after processing NewGRFs by CopyTempEngineData(). */ + int index; + while ((index = SlIterateArray()) != -1) { + Engine *e = GetTempDataEngine(index); + SlObject(e, slt); + + if (IsSavegameVersionBefore(SLV_179)) { + /* preview_company_rank was replaced with preview_company and preview_asked. + * Just cancel any previews. */ + e->flags &= ~4; // ENGINE_OFFER_WINDOW_OPEN + e->preview_company = INVALID_COMPANY; + e->preview_asked = (CompanyMask)-1; + } + } + } +}; /** * Copy data from temporary engine array into the real engine pool. @@ -152,20 +156,24 @@ void ResetTempEngineData() _temp_engine.clear(); } -static void Load_ENGS() -{ - /* Load old separate String ID list into a temporary array. This - * was always 256 entries. */ - StringID names[256]; +struct ENGSChunkHandler : ChunkHandler { + ENGSChunkHandler() : ChunkHandler('ENGS', CH_READONLY) {} - SlCopy(names, lengthof(names), SLE_STRINGID); + void Load() const override + { + /* Load old separate String ID list into a temporary array. This + * was always 256 entries. */ + StringID names[256]; - /* Copy each string into the temporary engine array. */ - for (EngineID engine = 0; engine < lengthof(names); engine++) { - Engine *e = GetTempDataEngine(engine); - e->name = CopyFromOldName(names[engine]); + SlCopy(names, lengthof(names), SLE_STRINGID); + + /* Copy each string into the temporary engine array. */ + for (EngineID engine = 0; engine < lengthof(names); engine++) { + Engine *e = GetTempDataEngine(engine); + e->name = CopyFromOldName(names[engine]); + } } -} +}; /** Save and load the mapping between the engine id in the pool, and the grf file it came from. */ static const SaveLoad _engine_id_mapping_desc[] = { @@ -175,33 +183,37 @@ static const SaveLoad _engine_id_mapping_desc[] = { SLE_VAR(EngineIDMapping, substitute_id, SLE_UINT8), }; -static void Save_EIDS() -{ - SlTableHeader(_engine_id_mapping_desc); +struct EIDSChunkHandler : ChunkHandler { + EIDSChunkHandler() : ChunkHandler('EIDS', CH_TABLE) {} - uint index = 0; - for (EngineIDMapping &eid : _engine_mngr) { - SlSetArrayIndex(index); - SlObject(&eid, _engine_id_mapping_desc); - index++; + void Save() const override + { + SlTableHeader(_engine_id_mapping_desc); + + uint index = 0; + for (EngineIDMapping &eid : _engine_mngr) { + SlSetArrayIndex(index); + SlObject(&eid, _engine_id_mapping_desc); + index++; + } } -} -static void Load_EIDS() -{ - const std::vector slt = SlCompatTableHeader(_engine_id_mapping_desc, _engine_id_mapping_sl_compat); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_engine_id_mapping_desc, _engine_id_mapping_sl_compat); - _engine_mngr.clear(); + _engine_mngr.clear(); - while (SlIterateArray() != -1) { - EngineIDMapping *eid = &_engine_mngr.emplace_back(); - SlObject(eid, slt); + while (SlIterateArray() != -1) { + EngineIDMapping *eid = &_engine_mngr.emplace_back(); + SlObject(eid, slt); + } } -} +}; -static const ChunkHandler EIDS{ 'EIDS', Save_EIDS, Load_EIDS, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler ENGN{ 'ENGN', Save_ENGN, Load_ENGN, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler ENGS{ 'ENGS', nullptr, Load_ENGS, nullptr, nullptr, CH_READONLY }; +static const EIDSChunkHandler EIDS; +static const ENGNChunkHandler ENGN; +static const ENGSChunkHandler ENGS; static const ChunkHandlerRef engine_chunk_handlers[] = { EIDS, ENGN, diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index e075326ae0..bfd0b910c2 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -54,64 +54,68 @@ static void SaveReal_GSDT(int *index_ptr) Game::Save(); } -static void Load_GSDT() -{ - const std::vector slt = SlCompatTableHeader(_game_script_desc, _game_script_sl_compat); +struct GSDTChunkHandler : ChunkHandler { + GSDTChunkHandler() : ChunkHandler('GSDT', CH_TABLE) {} - /* Free all current data */ - GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME)->Change(nullptr); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_game_script_desc, _game_script_sl_compat); - if (SlIterateArray() == -1) return; + /* Free all current data */ + GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME)->Change(nullptr); - _game_saveload_version = -1; - SlObject(nullptr, slt); + if (SlIterateArray() == -1) return; - if (_networking && !_network_server) { - GameInstance::LoadEmpty(); - if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs"); - return; - } + _game_saveload_version = -1; + SlObject(nullptr, slt); - GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME); - if (!_game_saveload_name.empty()) { - config->Change(_game_saveload_name.c_str(), _game_saveload_version, false, _game_saveload_is_random); - if (!config->HasScript()) { - /* No version of the GameScript available that can load the data. Try to load the - * latest version of the GameScript instead. */ - config->Change(_game_saveload_name.c_str(), -1, false, _game_saveload_is_random); - if (!config->HasScript()) { - if (_game_saveload_name.compare("%_dummy") != 0) { - Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version); - Debug(script, 0, "This game will continue to run without GameScript."); - } else { - Debug(script, 0, "The savegame had no GameScript available at the time of saving."); - Debug(script, 0, "This game will continue to run without GameScript."); - } - } else { - Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version); - Debug(script, 0, "The latest version of that GameScript has been loaded instead, but it'll not get the savegame data as it's incompatible."); - } - /* Make sure the GameScript doesn't get the saveload data, as it was not the - * writer of the saveload data in the first place */ - _game_saveload_version = -1; + if (_networking && !_network_server) { + GameInstance::LoadEmpty(); + if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs"); + return; } + + GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME); + if (!_game_saveload_name.empty()) { + config->Change(_game_saveload_name.c_str(), _game_saveload_version, false, _game_saveload_is_random); + if (!config->HasScript()) { + /* No version of the GameScript available that can load the data. Try to load the + * latest version of the GameScript instead. */ + config->Change(_game_saveload_name.c_str(), -1, false, _game_saveload_is_random); + if (!config->HasScript()) { + if (_game_saveload_name.compare("%_dummy") != 0) { + Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version); + Debug(script, 0, "This game will continue to run without GameScript."); + } else { + Debug(script, 0, "The savegame had no GameScript available at the time of saving."); + Debug(script, 0, "This game will continue to run without GameScript."); + } + } else { + Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version); + Debug(script, 0, "The latest version of that GameScript has been loaded instead, but it'll not get the savegame data as it's incompatible."); + } + /* Make sure the GameScript doesn't get the saveload data, as it was not the + * writer of the saveload data in the first place */ + _game_saveload_version = -1; + } + } + + config->StringToSettings(_game_saveload_settings); + + /* Start the GameScript directly if it was active in the savegame */ + Game::StartNew(); + Game::Load(_game_saveload_version); + + if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs"); } - config->StringToSettings(_game_saveload_settings); - - /* Start the GameScript directly if it was active in the savegame */ - Game::StartNew(); - Game::Load(_game_saveload_version); - - if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs"); -} - -static void Save_GSDT() -{ - SlTableHeader(_game_script_desc); - SlSetArrayIndex(0); - SlAutolength((AutolengthProc *)SaveReal_GSDT, nullptr); -} + void Save() const override + { + SlTableHeader(_game_script_desc); + SlSetArrayIndex(0); + SlAutolength((AutolengthProc *)SaveReal_GSDT, nullptr); + } +}; extern GameStrings *_current_data; @@ -152,44 +156,48 @@ static const SaveLoad _game_language_desc[] = { SLEG_STRUCTLIST("strings", SlGameLanguageString), }; -static void Load_GSTR() -{ - const std::vector slt = SlCompatTableHeader(_game_language_desc, _game_language_sl_compat); +struct GSTRChunkHandler : ChunkHandler { + GSTRChunkHandler() : ChunkHandler('GSTR', CH_TABLE) {} - delete _current_data; - _current_data = new GameStrings(); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_game_language_desc, _game_language_sl_compat); - while (SlIterateArray() != -1) { - LanguageStrings ls; - SlObject(&ls, slt); - _current_data->raw_strings.push_back(std::move(ls)); - } - - /* If there were no strings in the savegame, set GameStrings to nullptr */ - if (_current_data->raw_strings.size() == 0) { delete _current_data; - _current_data = nullptr; - return; + _current_data = new GameStrings(); + + while (SlIterateArray() != -1) { + LanguageStrings ls; + SlObject(&ls, slt); + _current_data->raw_strings.push_back(std::move(ls)); + } + + /* If there were no strings in the savegame, set GameStrings to nullptr */ + if (_current_data->raw_strings.size() == 0) { + delete _current_data; + _current_data = nullptr; + return; + } + + _current_data->Compile(); + ReconsiderGameScriptLanguage(); } - _current_data->Compile(); - ReconsiderGameScriptLanguage(); -} + void Save() const override + { + SlTableHeader(_game_language_desc); -static void Save_GSTR() -{ - SlTableHeader(_game_language_desc); + if (_current_data == nullptr) return; - if (_current_data == nullptr) return; - - for (uint i = 0; i < _current_data->raw_strings.size(); i++) { - SlSetArrayIndex(i); - SlObject(&_current_data->raw_strings[i], _game_language_desc); + for (uint i = 0; i < _current_data->raw_strings.size(); i++) { + SlSetArrayIndex(i); + SlObject(&_current_data->raw_strings[i], _game_language_desc); + } } -} +}; -static const ChunkHandler GSTR{ 'GSTR', Save_GSTR, Load_GSTR, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler GSDT{ 'GSDT', Save_GSDT, Load_GSDT, nullptr, nullptr, CH_TABLE }; +static const GSTRChunkHandler GSTR; +static const GSDTChunkHandler GSDT; static const ChunkHandlerRef game_chunk_handlers[] = { GSTR, GSDT, diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index d2ca49aed2..3d71f2ff9e 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.cpp @@ -347,61 +347,68 @@ static const SaveLoad _gamelog_desc[] = { SLEG_STRUCTLIST("action", SlGamelogAction), }; -static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_actions) -{ - assert(gamelog_action == nullptr); - assert(gamelog_actions == 0); +struct GLOGChunkHandler : ChunkHandler { + GLOGChunkHandler() : ChunkHandler('GLOG', CH_TABLE) + { + this->load_check = true; + } - const std::vector slt = SlCompatTableHeader(_gamelog_desc, _gamelog_sl_compat); + void LoadCommon(LoggedAction *&gamelog_action, uint &gamelog_actions) const + { + assert(gamelog_action == nullptr); + assert(gamelog_actions == 0); - if (IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY)) { - byte type; - while ((type = SlReadByte()) != GLAT_NONE) { - if (type >= GLAT_END) SlErrorCorrupt("Invalid gamelog action type"); + const std::vector slt = SlCompatTableHeader(_gamelog_desc, _gamelog_sl_compat); + if (IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY)) { + byte type; + while ((type = SlReadByte()) != GLAT_NONE) { + if (type >= GLAT_END) SlErrorCorrupt("Invalid gamelog action type"); + + gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1); + LoggedAction *la = &gamelog_action[gamelog_actions++]; + memset(la, 0, sizeof(*la)); + + la->at = (GamelogActionType)type; + SlObject(la, slt); + } + return; + } + + while (SlIterateArray() != -1) { gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1); LoggedAction *la = &gamelog_action[gamelog_actions++]; memset(la, 0, sizeof(*la)); - la->at = (GamelogActionType)type; SlObject(la, slt); } - return; } - while (SlIterateArray() != -1) { - gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1); - LoggedAction *la = &gamelog_action[gamelog_actions++]; - memset(la, 0, sizeof(*la)); + void Save() const override + { + SlTableHeader(_gamelog_desc); - SlObject(la, slt); + const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; + + uint i = 0; + for (LoggedAction *la = _gamelog_action; la != laend; la++, i++) { + SlSetArrayIndex(i); + SlObject(la, _gamelog_desc); + } } -} -static void Save_GLOG() -{ - SlTableHeader(_gamelog_desc); - - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - - uint i = 0; - for (LoggedAction *la = _gamelog_action; la != laend; la++, i++) { - SlSetArrayIndex(i); - SlObject(la, _gamelog_desc); + void Load() const override + { + this->LoadCommon(_gamelog_action, _gamelog_actions); } -} -static void Load_GLOG() -{ - Load_GLOG_common(_gamelog_action, _gamelog_actions); -} + void LoadCheck(size_t) const override + { + this->LoadCommon(_load_check_data.gamelog_action, _load_check_data.gamelog_actions); + } +}; -static void Check_GLOG() -{ - Load_GLOG_common(_load_check_data.gamelog_action, _load_check_data.gamelog_actions); -} - -static const ChunkHandler GLOG{ 'GLOG', Save_GLOG, Load_GLOG, nullptr, Check_GLOG, CH_TABLE }; +static const GLOGChunkHandler GLOG; static const ChunkHandlerRef gamelog_chunk_handlers[] = { GLOG, }; diff --git a/src/saveload/goal_sl.cpp b/src/saveload/goal_sl.cpp index 2dac477d0d..ae6b8577b2 100644 --- a/src/saveload/goal_sl.cpp +++ b/src/saveload/goal_sl.cpp @@ -25,28 +25,32 @@ static const SaveLoad _goals_desc[] = { SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION), }; -static void Save_GOAL() -{ - SlTableHeader(_goals_desc); +struct GOALChunkHandler : ChunkHandler { + GOALChunkHandler() : ChunkHandler('GOAL', CH_TABLE) {} - for (Goal *s : Goal::Iterate()) { - SlSetArrayIndex(s->index); - SlObject(s, _goals_desc); + void Save() const override + { + SlTableHeader(_goals_desc); + + for (Goal *s : Goal::Iterate()) { + SlSetArrayIndex(s->index); + SlObject(s, _goals_desc); + } } -} -static void Load_GOAL() -{ - const std::vector slt = SlCompatTableHeader(_goals_desc, _goals_sl_compat); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_goals_desc, _goals_sl_compat); - int index; - while ((index = SlIterateArray()) != -1) { - Goal *s = new (index) Goal(); - SlObject(s, slt); + int index; + while ((index = SlIterateArray()) != -1) { + Goal *s = new (index) Goal(); + SlObject(s, slt); + } } -} +}; -static const ChunkHandler GOAL{ 'GOAL', Save_GOAL, Load_GOAL, nullptr, nullptr, CH_TABLE }; +static const GOALChunkHandler GOAL; static const ChunkHandlerRef goal_chunk_handlers[] = { GOAL, }; diff --git a/src/saveload/group_sl.cpp b/src/saveload/group_sl.cpp index 6c510b6e66..d286f1f204 100644 --- a/src/saveload/group_sl.cpp +++ b/src/saveload/group_sl.cpp @@ -28,38 +28,42 @@ static const SaveLoad _group_desc[] = { SLE_CONDVAR(Group, parent, SLE_UINT16, SLV_189, SL_MAX_VERSION), }; -static void Save_GRPS() -{ - SlTableHeader(_group_desc); +struct GRPSChunkHandler : ChunkHandler { + GRPSChunkHandler() : ChunkHandler('GRPS', CH_TABLE) {} - for (Group *g : Group::Iterate()) { - SlSetArrayIndex(g->index); - SlObject(g, _group_desc); - } -} + void Save() const override + { + SlTableHeader(_group_desc); - -static void Load_GRPS() -{ - const std::vector slt = SlCompatTableHeader(_group_desc, _group_sl_compat); - - int index; - - while ((index = SlIterateArray()) != -1) { - Group *g = new (index) Group(); - SlObject(g, slt); - - if (IsSavegameVersionBefore(SLV_189)) g->parent = INVALID_GROUP; - - if (IsSavegameVersionBefore(SLV_GROUP_LIVERIES)) { - const Company *c = Company::Get(g->owner); - g->livery.colour1 = c->livery[LS_DEFAULT].colour1; - g->livery.colour2 = c->livery[LS_DEFAULT].colour2; + for (Group *g : Group::Iterate()) { + SlSetArrayIndex(g->index); + SlObject(g, _group_desc); } } -} -static const ChunkHandler GRPS{ 'GRPS', Save_GRPS, Load_GRPS, nullptr, nullptr, CH_TABLE }; + + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_group_desc, _group_sl_compat); + + int index; + + while ((index = SlIterateArray()) != -1) { + Group *g = new (index) Group(); + SlObject(g, slt); + + if (IsSavegameVersionBefore(SLV_189)) g->parent = INVALID_GROUP; + + if (IsSavegameVersionBefore(SLV_GROUP_LIVERIES)) { + const Company *c = Company::Get(g->owner); + g->livery.colour1 = c->livery[LS_DEFAULT].colour1; + g->livery.colour2 = c->livery[LS_DEFAULT].colour2; + } + } + } +}; + +static const GRPSChunkHandler GRPS; static const ChunkHandlerRef group_chunk_handlers[] = { GRPS, }; diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index e1d2da93a0..d70e1a4ee7 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -74,90 +74,108 @@ static const SaveLoad _industry_desc[] = { SLE_CONDSSTR(Industry, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_INDUSTRY_TEXT, SL_MAX_VERSION), }; -static void Save_INDY() -{ - SlTableHeader(_industry_desc); - - /* Write the industries */ - for (Industry *ind : Industry::Iterate()) { - SlSetArrayIndex(ind->index); - SlObject(ind, _industry_desc); +struct INDYChunkHandler : ChunkHandler { + INDYChunkHandler() : ChunkHandler('INDY', CH_TABLE) + { + this->fix_pointers = true; } -} -static void Save_IIDS() -{ - Save_NewGRFMapping(_industry_mngr); -} + void Save() const override + { + SlTableHeader(_industry_desc); -static void Save_TIDS() -{ - Save_NewGRFMapping(_industile_mngr); -} - -static void Load_INDY() -{ - const std::vector slt = SlCompatTableHeader(_industry_desc, _industry_sl_compat); - - int index; - - Industry::ResetIndustryCounts(); - - while ((index = SlIterateArray()) != -1) { - Industry *i = new (index) Industry(); - SlObject(i, slt); - - /* Before savegame version 161, persistent storages were not stored in a pool. */ - if (IsSavegameVersionBefore(SLV_161) && !IsSavegameVersionBefore(SLV_76)) { - /* Store the old persistent storage. The GRFID will be added later. */ - assert(PersistentStorage::CanAllocateItem()); - i->psa = new PersistentStorage(0, 0, 0); - memcpy(i->psa->storage, _old_ind_persistent_storage.storage, sizeof(_old_ind_persistent_storage.storage)); + /* Write the industries */ + for (Industry *ind : Industry::Iterate()) { + SlSetArrayIndex(ind->index); + SlObject(ind, _industry_desc); } - Industry::IncIndustryTypeCount(i->type); } -} -static void Load_IIDS() -{ - Load_NewGRFMapping(_industry_mngr); -} + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_industry_desc, _industry_sl_compat); -static void Load_TIDS() -{ - Load_NewGRFMapping(_industile_mngr); -} + int index; -static void Ptrs_INDY() -{ - for (Industry *i : Industry::Iterate()) { - SlObject(i, _industry_desc); + Industry::ResetIndustryCounts(); + + while ((index = SlIterateArray()) != -1) { + Industry *i = new (index) Industry(); + SlObject(i, slt); + + /* Before savegame version 161, persistent storages were not stored in a pool. */ + if (IsSavegameVersionBefore(SLV_161) && !IsSavegameVersionBefore(SLV_76)) { + /* Store the old persistent storage. The GRFID will be added later. */ + assert(PersistentStorage::CanAllocateItem()); + i->psa = new PersistentStorage(0, 0, 0); + memcpy(i->psa->storage, _old_ind_persistent_storage.storage, sizeof(_old_ind_persistent_storage.storage)); + } + Industry::IncIndustryTypeCount(i->type); + } } -} + + void FixPointers() const override + { + for (Industry *i : Industry::Iterate()) { + SlObject(i, _industry_desc); + } + } +}; + +struct IIDSChunkHandler : ChunkHandler { + IIDSChunkHandler() : ChunkHandler('IIDS', CH_TABLE) {} + + void Save() const override + { + Save_NewGRFMapping(_industry_mngr); + } + + void Load() const override + { + Load_NewGRFMapping(_industry_mngr); + } +}; + +struct TIDSChunkHandler : ChunkHandler { + TIDSChunkHandler() : ChunkHandler('TIDS', CH_TABLE) {} + + void Save() const override + { + Save_NewGRFMapping(_industile_mngr); + } + + void Load() const override + { + Load_NewGRFMapping(_industile_mngr); + } +}; /** Description of the data to save and load in #IndustryBuildData. */ static const SaveLoad _industry_builder_desc[] = { SLEG_VAR("wanted_inds", _industry_builder.wanted_inds, SLE_UINT32), }; -/** Save industry builder. */ -static void Save_IBLD() -{ - SlTableHeader(_industry_builder_desc); +/** Industry builder. */ +struct IBLDChunkHandler : ChunkHandler { + IBLDChunkHandler() : ChunkHandler('IBLD', CH_TABLE) {} - SlSetArrayIndex(0); - SlGlobList(_industry_builder_desc); -} + void Save() const override + { + SlTableHeader(_industry_builder_desc); -/** Load industry builder. */ -static void Load_IBLD() -{ - const std::vector slt = SlCompatTableHeader(_industry_builder_desc, _industry_builder_sl_compat); + SlSetArrayIndex(0); + SlGlobList(_industry_builder_desc); + } - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlGlobList(slt); - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many IBLD entries"); -} + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_industry_builder_desc, _industry_builder_sl_compat); + + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; + SlGlobList(slt); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many IBLD entries"); + } +}; /** Description of the data to save and load in #IndustryTypeBuildData. */ static const SaveLoad _industrytype_builder_desc[] = { @@ -168,37 +186,40 @@ static const SaveLoad _industrytype_builder_desc[] = { SLE_VAR(IndustryTypeBuildData, wait_count, SLE_UINT16), }; -/** Save industry-type build data. */ -static void Save_ITBL() -{ - SlTableHeader(_industrytype_builder_desc); +/** Industry-type build data. */ +struct ITBLChunkHandler : ChunkHandler { + ITBLChunkHandler() : ChunkHandler('ITBL', CH_TABLE) {} - for (int i = 0; i < NUM_INDUSTRYTYPES; i++) { - SlSetArrayIndex(i); - SlObject(_industry_builder.builddata + i, _industrytype_builder_desc); + void Save() const override + { + SlTableHeader(_industrytype_builder_desc); + + for (int i = 0; i < NUM_INDUSTRYTYPES; i++) { + SlSetArrayIndex(i); + SlObject(_industry_builder.builddata + i, _industrytype_builder_desc); + } } -} -/** Load industry-type build data. */ -static void Load_ITBL() -{ - const std::vector slt = SlCompatTableHeader(_industrytype_builder_desc, _industrytype_builder_sl_compat); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_industrytype_builder_desc, _industrytype_builder_sl_compat); - for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) { - _industry_builder.builddata[it].Reset(); + for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) { + _industry_builder.builddata[it].Reset(); + } + int index; + while ((index = SlIterateArray()) != -1) { + if ((uint)index >= NUM_INDUSTRYTYPES) SlErrorCorrupt("Too many industry builder datas"); + SlObject(_industry_builder.builddata + index, slt); + } } - int index; - while ((index = SlIterateArray()) != -1) { - if ((uint)index >= NUM_INDUSTRYTYPES) SlErrorCorrupt("Too many industry builder datas"); - SlObject(_industry_builder.builddata + index, slt); - } -} +}; -static const ChunkHandler INDY{ 'INDY', Save_INDY, Load_INDY, Ptrs_INDY, nullptr, CH_TABLE }; -static const ChunkHandler IIDS{ 'IIDS', Save_IIDS, Load_IIDS, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler TIDS{ 'TIDS', Save_TIDS, Load_TIDS, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler IBLD{ 'IBLD', Save_IBLD, Load_IBLD, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler ITBL{ 'ITBL', Save_ITBL, Load_ITBL, nullptr, nullptr, CH_TABLE }; +static const INDYChunkHandler INDY; +static const IIDSChunkHandler IIDS; +static const TIDSChunkHandler TIDS; +static const IBLDChunkHandler IBLD; +static const ITBLChunkHandler ITBL; static const ChunkHandlerRef industry_chunk_handlers[] = { INDY, IIDS, diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp index 970985b929..432aa9ce48 100644 --- a/src/saveload/labelmaps_sl.cpp +++ b/src/saveload/labelmaps_sl.cpp @@ -99,35 +99,39 @@ static const SaveLoad _label_object_desc[] = { SLE_VAR(LabelObject, label, SLE_UINT32), }; -static void Save_RAIL() -{ - SlTableHeader(_label_object_desc); +struct RAILChunkHandler : ChunkHandler { + RAILChunkHandler() : ChunkHandler('RAIL', CH_TABLE) {} - LabelObject lo; + void Save() const override + { + SlTableHeader(_label_object_desc); - for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { - lo.label = GetRailTypeInfo(r)->label; + LabelObject lo; - SlSetArrayIndex(r); - SlObject(&lo, _label_object_desc); + for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { + lo.label = GetRailTypeInfo(r)->label; + + SlSetArrayIndex(r); + SlObject(&lo, _label_object_desc); + } } -} -static void Load_RAIL() -{ - const std::vector slt = SlCompatTableHeader(_label_object_desc, _label_object_sl_compat); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_label_object_desc, _label_object_sl_compat); - ResetLabelMaps(); + ResetLabelMaps(); - LabelObject lo; + LabelObject lo; - while (SlIterateArray() != -1) { - SlObject(&lo, slt); - _railtype_list.push_back((RailTypeLabel)lo.label); + while (SlIterateArray() != -1) { + SlObject(&lo, slt); + _railtype_list.push_back((RailTypeLabel)lo.label); + } } -} +}; -static const ChunkHandler RAIL{ 'RAIL', Save_RAIL, Load_RAIL, nullptr, nullptr, CH_TABLE }; +static const RAILChunkHandler RAIL; static const ChunkHandlerRef labelmaps_chunk_handlers[] = { RAIL, }; diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index 04664bed9f..70dfb7b39e 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -242,93 +242,96 @@ void AfterLoadLinkGraphs() } /** - * Save all link graphs. + * All link graphs. */ -static void Save_LGRP() -{ - SlTableHeader(GetLinkGraphDesc()); +struct LGRPChunkHandler : ChunkHandler { + LGRPChunkHandler() : ChunkHandler('LGRP', CH_TABLE) {} - for (LinkGraph *lg : LinkGraph::Iterate()) { - SlSetArrayIndex(lg->index); - SlObject(lg, GetLinkGraphDesc()); + void Save() const override + { + SlTableHeader(GetLinkGraphDesc()); + + for (LinkGraph *lg : LinkGraph::Iterate()) { + SlSetArrayIndex(lg->index); + SlObject(lg, GetLinkGraphDesc()); + } } -} -/** - * Load all link graphs. - */ -static void Load_LGRP() -{ - const std::vector slt = SlCompatTableHeader(GetLinkGraphDesc(), _linkgraph_sl_compat); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(GetLinkGraphDesc(), _linkgraph_sl_compat); - int index; - while ((index = SlIterateArray()) != -1) { - LinkGraph *lg = new (index) LinkGraph(); - SlObject(lg, slt); + int index; + while ((index = SlIterateArray()) != -1) { + LinkGraph *lg = new (index) LinkGraph(); + SlObject(lg, slt); + } } -} +}; /** - * Save all link graph jobs. + * All link graph jobs. */ -static void Save_LGRJ() -{ - SlTableHeader(GetLinkGraphJobDesc()); +struct LGRJChunkHandler : ChunkHandler { + LGRJChunkHandler() : ChunkHandler('LGRJ', CH_TABLE) {} - for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) { - SlSetArrayIndex(lgj->index); - SlObject(lgj, GetLinkGraphJobDesc()); + void Save() const override + { + SlTableHeader(GetLinkGraphJobDesc()); + + for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) { + SlSetArrayIndex(lgj->index); + SlObject(lgj, GetLinkGraphJobDesc()); + } } -} -/** - * Load all link graph jobs. - */ -static void Load_LGRJ() -{ - const std::vector slt = SlCompatTableHeader(GetLinkGraphJobDesc(), _linkgraph_job_sl_compat); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(GetLinkGraphJobDesc(), _linkgraph_job_sl_compat); - int index; - while ((index = SlIterateArray()) != -1) { - LinkGraphJob *lgj = new (index) LinkGraphJob(); - SlObject(lgj, slt); + int index; + while ((index = SlIterateArray()) != -1) { + LinkGraphJob *lgj = new (index) LinkGraphJob(); + SlObject(lgj, slt); + } } -} +}; /** - * Save the link graph schedule. + * Link graph schedule. */ -static void Save_LGRS() -{ - SlTableHeader(GetLinkGraphScheduleDesc()); +struct LGRSChunkHandler : ChunkHandler { + LGRSChunkHandler() : ChunkHandler('LGRS', CH_TABLE) + { + this->fix_pointers = true; + } - SlSetArrayIndex(0); - SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc()); -} + void Save() const override + { + SlTableHeader(GetLinkGraphScheduleDesc()); -/** - * Load the link graph schedule. - */ -static void Load_LGRS() -{ - const std::vector slt = SlCompatTableHeader(GetLinkGraphScheduleDesc(), _linkgraph_schedule_sl_compat); + SlSetArrayIndex(0); + SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc()); + } - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlObject(&LinkGraphSchedule::instance, slt); - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many LGRS entries"); -} + void Load() const override + { + const std::vector slt = SlCompatTableHeader(GetLinkGraphScheduleDesc(), _linkgraph_schedule_sl_compat); -/** - * Substitute pointers in link graph schedule. - */ -static void Ptrs_LGRS() -{ - SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc()); -} + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; + SlObject(&LinkGraphSchedule::instance, slt); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many LGRS entries"); + } -static const ChunkHandler LGRP{ 'LGRP', Save_LGRP, Load_LGRP, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler LGRJ{ 'LGRJ', Save_LGRJ, Load_LGRJ, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler LGRS{ 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_TABLE }; + void FixPointers() const override + { + SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc()); + } +}; + +static const LGRPChunkHandler LGRP; +static const LGRJChunkHandler LGRJ; +static const LGRSChunkHandler LGRS; static const ChunkHandlerRef linkgraph_chunk_handlers[] = { LGRP, LGRJ, diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index a6f9448e52..d654f3f6bc 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -27,299 +27,346 @@ static const SaveLoad _map_desc[] = { SLEG_CONDVAR("dim_y", _map_dim_y, SLE_UINT32, SLV_6, SL_MAX_VERSION), }; -static void Save_MAPS() -{ - SlTableHeader(_map_desc); +struct MAPSChunkHandler : ChunkHandler { + MAPSChunkHandler() : ChunkHandler('MAPS', CH_TABLE) + { + this->load_check = true; + } - _map_dim_x = MapSizeX(); - _map_dim_y = MapSizeY(); + void Save() const override + { + SlTableHeader(_map_desc); - SlSetArrayIndex(0); - SlGlobList(_map_desc); -} + _map_dim_x = MapSizeX(); + _map_dim_y = MapSizeY(); -static void Load_MAPS() -{ - const std::vector slt = SlCompatTableHeader(_map_desc, _map_sl_compat); + SlSetArrayIndex(0); + SlGlobList(_map_desc); + } - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlGlobList(slt); - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many MAPS entries"); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_map_desc, _map_sl_compat); - AllocateMap(_map_dim_x, _map_dim_y); -} + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; + SlGlobList(slt); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many MAPS entries"); -static void Check_MAPS() -{ - const std::vector slt = SlCompatTableHeader(_map_desc, _map_sl_compat); + AllocateMap(_map_dim_x, _map_dim_y); + } - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlGlobList(slt); - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many MAPS entries"); + void LoadCheck(size_t) const override + { + const std::vector slt = SlCompatTableHeader(_map_desc, _map_sl_compat); - _load_check_data.map_size_x = _map_dim_x; - _load_check_data.map_size_y = _map_dim_y; -} + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; + SlGlobList(slt); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many MAPS entries"); + + _load_check_data.map_size_x = _map_dim_x; + _load_check_data.map_size_y = _map_dim_y; + } +}; static const uint MAP_SL_BUF_SIZE = 4096; -static void Load_MAPT() -{ - std::array buf; - TileIndex size = MapSize(); +struct MAPTChunkHandler : ChunkHandler { + MAPTChunkHandler() : ChunkHandler('MAPT', CH_RIFF) {} - for (TileIndex i = 0; i != size;) { - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type = buf[j]; - } -} + void Load() const override + { + std::array buf; + TileIndex size = MapSize(); -static void Save_MAPT() -{ - std::array buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type; - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - -static void Load_MAPH() -{ - std::array buf; - TileIndex size = MapSize(); - - for (TileIndex i = 0; i != size;) { - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].height = buf[j]; - } -} - -static void Save_MAPH() -{ - std::array buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].height; - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - -static void Load_MAP1() -{ - std::array buf; - TileIndex size = MapSize(); - - for (TileIndex i = 0; i != size;) { - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j]; - } -} - -static void Save_MAP1() -{ - std::array buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1; - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - -static void Load_MAP2() -{ - std::array buf; - TileIndex size = MapSize(); - - for (TileIndex i = 0; i != size;) { - SlCopy(buf.data(), MAP_SL_BUF_SIZE, - /* In those versions the m2 was 8 bits */ - IsSavegameVersionBefore(SLV_5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16 - ); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j]; - } -} - -static void Save_MAP2() -{ - std::array buf; - TileIndex size = MapSize(); - - SlSetLength(size * sizeof(uint16)); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2; - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); - } -} - -static void Load_MAP3() -{ - std::array buf; - TileIndex size = MapSize(); - - for (TileIndex i = 0; i != size;) { - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j]; - } -} - -static void Save_MAP3() -{ - std::array buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3; - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - -static void Load_MAP4() -{ - std::array buf; - TileIndex size = MapSize(); - - for (TileIndex i = 0; i != size;) { - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j]; - } -} - -static void Save_MAP4() -{ - std::array buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4; - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - -static void Load_MAP5() -{ - std::array buf; - TileIndex size = MapSize(); - - for (TileIndex i = 0; i != size;) { - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j]; - } -} - -static void Save_MAP5() -{ - std::array buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5; - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - -static void Load_MAP6() -{ - std::array buf; - TileIndex size = MapSize(); - - if (IsSavegameVersionBefore(SLV_42)) { - for (TileIndex i = 0; i != size;) { - /* 1024, otherwise we overflow on 64x64 maps! */ - SlCopy(buf.data(), 1024, SLE_UINT8); - for (uint j = 0; j != 1024; j++) { - _me[i++].m6 = GB(buf[j], 0, 2); - _me[i++].m6 = GB(buf[j], 2, 2); - _me[i++].m6 = GB(buf[j], 4, 2); - _me[i++].m6 = GB(buf[j], 6, 2); - } - } - } else { for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m6 = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type = buf[j]; } } -} -static void Save_MAP6() -{ - std::array buf; - TileIndex size = MapSize(); + void Save() const override + { + std::array buf; + TileIndex size = MapSize(); - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m6; - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + SlSetLength(size); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type; + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + } } -} +}; -static void Load_MAP7() -{ - std::array buf; - TileIndex size = MapSize(); +struct MAPHChunkHandler : ChunkHandler { + MAPHChunkHandler() : ChunkHandler('MAPH', CH_RIFF) {} - for (TileIndex i = 0; i != size;) { - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j]; + void Load() const override + { + std::array buf; + TileIndex size = MapSize(); + + for (TileIndex i = 0; i != size;) { + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].height = buf[j]; + } } -} -static void Save_MAP7() -{ - std::array buf; - TileIndex size = MapSize(); + void Save() const override + { + std::array buf; + TileIndex size = MapSize(); - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7; - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + SlSetLength(size); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].height; + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + } } -} +}; -static void Load_MAP8() -{ - std::array buf; - TileIndex size = MapSize(); +struct MAPOChunkHandler : ChunkHandler { + MAPOChunkHandler() : ChunkHandler('MAPO', CH_RIFF) {} - for (TileIndex i = 0; i != size;) { - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j]; + void Load() const override + { + std::array buf; + TileIndex size = MapSize(); + + for (TileIndex i = 0; i != size;) { + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j]; + } } -} -static void Save_MAP8() -{ - std::array buf; - TileIndex size = MapSize(); + void Save() const override + { + std::array buf; + TileIndex size = MapSize(); - SlSetLength(size * sizeof(uint16)); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m8; - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); + SlSetLength(size); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1; + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + } } -} +}; -static const ChunkHandler MAPS{ 'MAPS', Save_MAPS, Load_MAPS, nullptr, Check_MAPS, CH_TABLE }; -static const ChunkHandler MAPT{ 'MAPT', Save_MAPT, Load_MAPT, nullptr, nullptr, CH_RIFF }; -static const ChunkHandler MAPH{ 'MAPH', Save_MAPH, Load_MAPH, nullptr, nullptr, CH_RIFF }; -static const ChunkHandler MAPO{ 'MAPO', Save_MAP1, Load_MAP1, nullptr, nullptr, CH_RIFF }; -static const ChunkHandler MAP2{ 'MAP2', Save_MAP2, Load_MAP2, nullptr, nullptr, CH_RIFF }; -static const ChunkHandler M3LO{ 'M3LO', Save_MAP3, Load_MAP3, nullptr, nullptr, CH_RIFF }; -static const ChunkHandler M3HI{ 'M3HI', Save_MAP4, Load_MAP4, nullptr, nullptr, CH_RIFF }; -static const ChunkHandler MAP5{ 'MAP5', Save_MAP5, Load_MAP5, nullptr, nullptr, CH_RIFF }; -static const ChunkHandler MAPE{ 'MAPE', Save_MAP6, Load_MAP6, nullptr, nullptr, CH_RIFF }; -static const ChunkHandler MAP7{ 'MAP7', Save_MAP7, Load_MAP7, nullptr, nullptr, CH_RIFF }; -static const ChunkHandler MAP8{ 'MAP8', Save_MAP8, Load_MAP8, nullptr, nullptr, CH_RIFF }; +struct MAP2ChunkHandler : ChunkHandler { + MAP2ChunkHandler() : ChunkHandler('MAP2', CH_RIFF) {} + + void Load() const override + { + std::array buf; + TileIndex size = MapSize(); + + for (TileIndex i = 0; i != size;) { + SlCopy(buf.data(), MAP_SL_BUF_SIZE, + /* In those versions the m2 was 8 bits */ + IsSavegameVersionBefore(SLV_5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16 + ); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j]; + } + } + + void Save() const override + { + std::array buf; + TileIndex size = MapSize(); + + SlSetLength(size * sizeof(uint16)); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2; + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); + } + } +}; + +struct M3LOChunkHandler : ChunkHandler { + M3LOChunkHandler() : ChunkHandler('M3LO', CH_RIFF) {} + + void Load() const override + { + std::array buf; + TileIndex size = MapSize(); + + for (TileIndex i = 0; i != size;) { + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j]; + } + } + + void Save() const override + { + std::array buf; + TileIndex size = MapSize(); + + SlSetLength(size); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3; + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + } + } +}; + +struct M3HIChunkHandler : ChunkHandler { + M3HIChunkHandler() : ChunkHandler('M3HI', CH_RIFF) {} + + void Load() const override + { + std::array buf; + TileIndex size = MapSize(); + + for (TileIndex i = 0; i != size;) { + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j]; + } + } + + void Save() const override + { + std::array buf; + TileIndex size = MapSize(); + + SlSetLength(size); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4; + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + } + } +}; + +struct MAP5ChunkHandler : ChunkHandler { + MAP5ChunkHandler() : ChunkHandler('MAP5', CH_RIFF) {} + + void Load() const override + { + std::array buf; + TileIndex size = MapSize(); + + for (TileIndex i = 0; i != size;) { + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j]; + } + } + + void Save() const override + { + std::array buf; + TileIndex size = MapSize(); + + SlSetLength(size); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5; + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + } + } +}; + +struct MAPEChunkHandler : ChunkHandler { + MAPEChunkHandler() : ChunkHandler('MAPE', CH_RIFF) {} + + void Load() const override + { + std::array buf; + TileIndex size = MapSize(); + + if (IsSavegameVersionBefore(SLV_42)) { + for (TileIndex i = 0; i != size;) { + /* 1024, otherwise we overflow on 64x64 maps! */ + SlCopy(buf.data(), 1024, SLE_UINT8); + for (uint j = 0; j != 1024; j++) { + _me[i++].m6 = GB(buf[j], 0, 2); + _me[i++].m6 = GB(buf[j], 2, 2); + _me[i++].m6 = GB(buf[j], 4, 2); + _me[i++].m6 = GB(buf[j], 6, 2); + } + } + } else { + for (TileIndex i = 0; i != size;) { + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m6 = buf[j]; + } + } + } + + void Save() const override + { + std::array buf; + TileIndex size = MapSize(); + + SlSetLength(size); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m6; + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + } + } +}; + +struct MAP7ChunkHandler : ChunkHandler { + MAP7ChunkHandler() : ChunkHandler('MAP7', CH_RIFF) {} + + void Load() const override + { + std::array buf; + TileIndex size = MapSize(); + + for (TileIndex i = 0; i != size;) { + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j]; + } + } + + void Save() const override + { + std::array buf; + TileIndex size = MapSize(); + + SlSetLength(size); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7; + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + } + } +}; + +struct MAP8ChunkHandler : ChunkHandler { + MAP8ChunkHandler() : ChunkHandler('MAP8', CH_RIFF) {} + + void Load() const override + { + std::array buf; + TileIndex size = MapSize(); + + for (TileIndex i = 0; i != size;) { + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j]; + } + } + + void Save() const override + { + std::array buf; + TileIndex size = MapSize(); + + SlSetLength(size * sizeof(uint16)); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m8; + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); + } + } +}; + +static const MAPSChunkHandler MAPS; +static const MAPTChunkHandler MAPT; +static const MAPHChunkHandler MAPH; +static const MAPOChunkHandler MAPO; +static const MAP2ChunkHandler MAP2; +static const M3LOChunkHandler M3LO; +static const M3HIChunkHandler M3HI; +static const MAP5ChunkHandler MAP5; +static const MAPEChunkHandler MAPE; +static const MAP7ChunkHandler MAP7; +static const MAP8ChunkHandler MAP8; static const ChunkHandlerRef map_chunk_handlers[] = { MAPS, MAPT, diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index a742090e8d..a7e00f88c9 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -95,37 +95,44 @@ static const SaveLoad _date_check_desc[] = { /* Save load date related variables as well as persistent tick counters * XXX: currently some unrelated stuff is just put here */ -static void Save_DATE() -{ - SlTableHeader(_date_desc); - - SlSetArrayIndex(0); - SlGlobList(_date_desc); -} - -static void Load_DATE_common(const SaveLoadTable &slt, const SaveLoadCompatTable &slct) -{ - const std::vector oslt = SlCompatTableHeader(slt, slct); - - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlGlobList(oslt); - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many DATE entries"); -} - -static void Load_DATE() -{ - Load_DATE_common(_date_desc, _date_sl_compat); -} - -static void Check_DATE() -{ - Load_DATE_common(_date_check_desc, _date_check_sl_compat); - - if (IsSavegameVersionBefore(SLV_31)) { - _load_check_data.current_date += DAYS_TILL_ORIGINAL_BASE_YEAR; +struct DATEChunkHandler : ChunkHandler { + DATEChunkHandler() : ChunkHandler('DATE', CH_TABLE) + { + this->load_check = true; } -} + void Save() const override + { + SlTableHeader(_date_desc); + + SlSetArrayIndex(0); + SlGlobList(_date_desc); + } + + void LoadCommon(const SaveLoadTable &slt, const SaveLoadCompatTable &slct) const + { + const std::vector oslt = SlCompatTableHeader(slt, slct); + + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; + SlGlobList(oslt); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many DATE entries"); + } + + void Load() const override + { + this->LoadCommon(_date_desc, _date_sl_compat); + } + + + void LoadCheck(size_t) const override + { + this->LoadCommon(_date_check_desc, _date_check_sl_compat); + + if (IsSavegameVersionBefore(SLV_31)) { + _load_check_data.current_date += DAYS_TILL_ORIGINAL_BASE_YEAR; + } + } +}; static const SaveLoad _view_desc[] = { SLEG_CONDVAR("x", _saved_scrollpos_x, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6), @@ -135,25 +142,29 @@ static const SaveLoad _view_desc[] = { SLEG_VAR("zoom", _saved_scrollpos_zoom, SLE_UINT8), }; -static void Save_VIEW() -{ - SlTableHeader(_view_desc); +struct VIEWChunkHandler : ChunkHandler { + VIEWChunkHandler() : ChunkHandler('VIEW', CH_TABLE) {} - SlSetArrayIndex(0); - SlGlobList(_view_desc); -} + void Save() const override + { + SlTableHeader(_view_desc); -static void Load_VIEW() -{ - const std::vector slt = SlCompatTableHeader(_view_desc, _view_sl_compat); + SlSetArrayIndex(0); + SlGlobList(_view_desc); + } - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; - SlGlobList(slt); - if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many DATE entries"); -} + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_view_desc, _view_sl_compat); -static const ChunkHandler DATE{ 'DATE', Save_DATE, Load_DATE, nullptr, Check_DATE, CH_TABLE }; -static const ChunkHandler VIEW{ 'VIEW', Save_VIEW, Load_VIEW, nullptr, nullptr, CH_TABLE }; + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return; + SlGlobList(slt); + if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many DATE entries"); + } +}; + +static const DATEChunkHandler DATE; +static const VIEWChunkHandler VIEW; static const ChunkHandlerRef misc_chunk_handlers[] = { DATE, VIEW, diff --git a/src/saveload/newgrf_sl.cpp b/src/saveload/newgrf_sl.cpp index 10a65e9362..43f0bd01a9 100644 --- a/src/saveload/newgrf_sl.cpp +++ b/src/saveload/newgrf_sl.cpp @@ -73,55 +73,62 @@ static const SaveLoad _grfconfig_desc[] = { }; -static void Save_NGRF() -{ - SlTableHeader(_grfconfig_desc); - - int index = 0; - - for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { - if (HasBit(c->flags, GCF_STATIC)) continue; - SlSetArrayIndex(index++); - SlObject(c, _grfconfig_desc); +struct NGRFChunkHandler : ChunkHandler { + NGRFChunkHandler() : ChunkHandler('NGRF', CH_TABLE) + { + this->load_check = true; } -} + void Save() const override + { + SlTableHeader(_grfconfig_desc); -static void Load_NGRF_common(GRFConfig *&grfconfig) -{ - const std::vector slt = SlCompatTableHeader(_grfconfig_desc, _grfconfig_sl_compat); + int index = 0; - ClearGRFConfigList(&grfconfig); - while (SlIterateArray() != -1) { - GRFConfig *c = new GRFConfig(); - SlObject(c, slt); - if (IsSavegameVersionBefore(SLV_101)) c->SetSuitablePalette(); - AppendToGRFConfigList(&grfconfig, c); + for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { + if (HasBit(c->flags, GCF_STATIC)) continue; + SlSetArrayIndex(index++); + SlObject(c, _grfconfig_desc); + } } -} -static void Load_NGRF() -{ - Load_NGRF_common(_grfconfig); - if (_game_mode == GM_MENU) { - /* Intro game must not have NewGRF. */ - if (_grfconfig != nullptr) SlErrorCorrupt("The intro game must not use NewGRF"); + void LoadCommon(GRFConfig *&grfconfig) const + { + const std::vector slt = SlCompatTableHeader(_grfconfig_desc, _grfconfig_sl_compat); - /* Activate intro NewGRFs (townnames) */ - ResetGRFConfig(false); - } else { - /* Append static NewGRF configuration */ - AppendStaticGRFConfigs(&_grfconfig); + ClearGRFConfigList(&grfconfig); + while (SlIterateArray() != -1) { + GRFConfig *c = new GRFConfig(); + SlObject(c, slt); + if (IsSavegameVersionBefore(SLV_101)) c->SetSuitablePalette(); + AppendToGRFConfigList(&grfconfig, c); + } } -} -static void Check_NGRF() -{ - Load_NGRF_common(_load_check_data.grfconfig); -} + void Load() const override + { + this->LoadCommon(_grfconfig); -static const ChunkHandler NGRF{ 'NGRF', Save_NGRF, Load_NGRF, nullptr, Check_NGRF, CH_TABLE }; + if (_game_mode == GM_MENU) { + /* Intro game must not have NewGRF. */ + if (_grfconfig != nullptr) SlErrorCorrupt("The intro game must not use NewGRF"); + + /* Activate intro NewGRFs (townnames) */ + ResetGRFConfig(false); + } else { + /* Append static NewGRF configuration */ + AppendStaticGRFConfigs(&_grfconfig); + } + } + + void LoadCheck(size_t) const override + { + this->LoadCommon(_load_check_data.grfconfig); + } +}; + +static const NGRFChunkHandler NGRF; static const ChunkHandlerRef newgrf_chunk_handlers[] = { NGRF, }; diff --git a/src/saveload/object_sl.cpp b/src/saveload/object_sl.cpp index b970c39345..fc49970020 100644 --- a/src/saveload/object_sl.cpp +++ b/src/saveload/object_sl.cpp @@ -29,51 +29,62 @@ static const SaveLoad _object_desc[] = { SLE_CONDVAR(Object, type, SLE_UINT16, SLV_186, SL_MAX_VERSION), }; -static void Save_OBJS() -{ - SlTableHeader(_object_desc); - - /* Write the objects */ - for (Object *o : Object::Iterate()) { - SlSetArrayIndex(o->index); - SlObject(o, _object_desc); +struct OBJSChunkHandler : ChunkHandler { + OBJSChunkHandler() : ChunkHandler('OBJS', CH_TABLE) + { + this->fix_pointers = true; } -} -static void Load_OBJS() -{ - const std::vector slt = SlCompatTableHeader(_object_desc, _object_sl_compat); + void Save() const override + { + SlTableHeader(_object_desc); - int index; - while ((index = SlIterateArray()) != -1) { - Object *o = new (index) Object(); - SlObject(o, slt); - } -} - -static void Ptrs_OBJS() -{ - for (Object *o : Object::Iterate()) { - SlObject(o, _object_desc); - if (IsSavegameVersionBefore(SLV_148) && !IsTileType(o->location.tile, MP_OBJECT)) { - /* Due to a small bug stale objects could remain. */ - delete o; + /* Write the objects */ + for (Object *o : Object::Iterate()) { + SlSetArrayIndex(o->index); + SlObject(o, _object_desc); } } -} -static void Save_OBID() -{ - Save_NewGRFMapping(_object_mngr); -} + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_object_desc, _object_sl_compat); -static void Load_OBID() -{ - Load_NewGRFMapping(_object_mngr); -} + int index; + while ((index = SlIterateArray()) != -1) { + Object *o = new (index) Object(); + SlObject(o, slt); + } + } -static const ChunkHandler OBID{ 'OBID', Save_OBID, Load_OBID, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler OBJS{ 'OBJS', Save_OBJS, Load_OBJS, Ptrs_OBJS, nullptr, CH_TABLE }; + void FixPointers() const override + { + for (Object *o : Object::Iterate()) { + SlObject(o, _object_desc); + if (IsSavegameVersionBefore(SLV_148) && !IsTileType(o->location.tile, MP_OBJECT)) { + /* Due to a small bug stale objects could remain. */ + delete o; + } + } + } +}; + +struct OBIDChunkHandler : ChunkHandler { + OBIDChunkHandler() : ChunkHandler('OBID', CH_TABLE) {} + + void Save() const override + { + Save_NewGRFMapping(_object_mngr); + } + + void Load() const override + { + Load_NewGRFMapping(_object_mngr); + } +}; + +static const OBIDChunkHandler OBID; +static const OBJSChunkHandler OBJS; static const ChunkHandlerRef object_chunk_handlers[] = { OBID, OBJS, diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index 797c16d1b0..16ee420137 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -118,85 +118,92 @@ SaveLoadTable GetOrderDescription() return _order_desc; } -static void Save_ORDR() -{ - const SaveLoadTable slt = GetOrderDescription(); - SlTableHeader(slt); - - for (Order *order : Order::Iterate()) { - SlSetArrayIndex(order->index); - SlObject(order, slt); +struct ORDRChunkHandler : ChunkHandler { + ORDRChunkHandler() : ChunkHandler('ORDR', CH_TABLE) + { + this->fix_pointers = true; } -} -static void Load_ORDR() -{ - if (IsSavegameVersionBefore(SLV_5, 2)) { - /* Version older than 5.2 did not have a ->next pointer. Convert them - * (in the old days, the orderlist was 5000 items big) */ - size_t len = SlGetFieldLength(); + void Save() const override + { + const SaveLoadTable slt = GetOrderDescription(); + SlTableHeader(slt); - if (IsSavegameVersionBefore(SLV_5)) { - /* Pre-version 5 had another layout for orders - * (uint16 instead of uint32) */ - len /= sizeof(uint16); - uint16 *orders = MallocT(len + 1); - - SlCopy(orders, len, SLE_UINT16); - - for (size_t i = 0; i < len; ++i) { - Order *o = new (i) Order(); - o->AssignOrder(UnpackVersion4Order(orders[i])); - } - - free(orders); - } else if (IsSavegameVersionBefore(SLV_5, 2)) { - len /= sizeof(uint32); - uint32 *orders = MallocT(len + 1); - - SlCopy(orders, len, SLE_UINT32); - - for (size_t i = 0; i < len; ++i) { - new (i) Order(orders[i]); - } - - free(orders); - } - - /* Update all the next pointer */ - for (Order *o : Order::Iterate()) { - size_t order_index = o->index; - /* Delete invalid orders */ - if (o->IsType(OT_NOTHING)) { - delete o; - continue; - } - /* The orders were built like this: - * While the order is valid, set the previous will get its next pointer set */ - Order *prev = Order::GetIfValid(order_index - 1); - if (prev != nullptr) prev->next = o; - } - } else { - const std::vector slt = SlCompatTableHeader(GetOrderDescription(), _order_sl_compat); - - int index; - - while ((index = SlIterateArray()) != -1) { - Order *order = new (index) Order(); + for (Order *order : Order::Iterate()) { + SlSetArrayIndex(order->index); SlObject(order, slt); } } -} -static void Ptrs_ORDR() -{ - /* Orders from old savegames have pointers corrected in Load_ORDR */ - if (IsSavegameVersionBefore(SLV_5, 2)) return; + void Load() const override + { + if (IsSavegameVersionBefore(SLV_5, 2)) { + /* Version older than 5.2 did not have a ->next pointer. Convert them + * (in the old days, the orderlist was 5000 items big) */ + size_t len = SlGetFieldLength(); - for (Order *o : Order::Iterate()) { - SlObject(o, GetOrderDescription()); + if (IsSavegameVersionBefore(SLV_5)) { + /* Pre-version 5 had another layout for orders + * (uint16 instead of uint32) */ + len /= sizeof(uint16); + uint16 *orders = MallocT(len + 1); + + SlCopy(orders, len, SLE_UINT16); + + for (size_t i = 0; i < len; ++i) { + Order *o = new (i) Order(); + o->AssignOrder(UnpackVersion4Order(orders[i])); + } + + free(orders); + } else if (IsSavegameVersionBefore(SLV_5, 2)) { + len /= sizeof(uint32); + uint32 *orders = MallocT(len + 1); + + SlCopy(orders, len, SLE_UINT32); + + for (size_t i = 0; i < len; ++i) { + new (i) Order(orders[i]); + } + + free(orders); + } + + /* Update all the next pointer */ + for (Order *o : Order::Iterate()) { + size_t order_index = o->index; + /* Delete invalid orders */ + if (o->IsType(OT_NOTHING)) { + delete o; + continue; + } + /* The orders were built like this: + * While the order is valid, set the previous will get its next pointer set */ + Order *prev = Order::GetIfValid(order_index - 1); + if (prev != nullptr) prev->next = o; + } + } else { + const std::vector slt = SlCompatTableHeader(GetOrderDescription(), _order_sl_compat); + + int index; + + while ((index = SlIterateArray()) != -1) { + Order *order = new (index) Order(); + SlObject(order, slt); + } + } } -} + + void FixPointers() const override + { + /* Orders from old savegames have pointers corrected in Load_ORDR */ + if (IsSavegameVersionBefore(SLV_5, 2)) return; + + for (Order *o : Order::Iterate()) { + SlObject(o, GetOrderDescription()); + } + } +}; SaveLoadTable GetOrderListDescription() { @@ -207,37 +214,44 @@ SaveLoadTable GetOrderListDescription() return _orderlist_desc; } -static void Save_ORDL() -{ - const SaveLoadTable slt = GetOrderListDescription(); - SlTableHeader(slt); - - for (OrderList *list : OrderList::Iterate()) { - SlSetArrayIndex(list->index); - SlObject(list, slt); - } -} - -static void Load_ORDL() -{ - const std::vector slt = SlCompatTableHeader(GetOrderListDescription(), _orderlist_sl_compat); - - int index; - - while ((index = SlIterateArray()) != -1) { - /* set num_orders to 0 so it's a valid OrderList */ - OrderList *list = new (index) OrderList(0); - SlObject(list, slt); +struct ORDLChunkHandler : ChunkHandler { + ORDLChunkHandler() : ChunkHandler('ORDL', CH_TABLE) + { + this->fix_pointers = true; } -} + void Save() const override + { + const SaveLoadTable slt = GetOrderListDescription(); + SlTableHeader(slt); -static void Ptrs_ORDL() -{ - for (OrderList *list : OrderList::Iterate()) { - SlObject(list, GetOrderListDescription()); + for (OrderList *list : OrderList::Iterate()) { + SlSetArrayIndex(list->index); + SlObject(list, slt); + } } -} + + void Load() const override + { + const std::vector slt = SlCompatTableHeader(GetOrderListDescription(), _orderlist_sl_compat); + + int index; + + while ((index = SlIterateArray()) != -1) { + /* set num_orders to 0 so it's a valid OrderList */ + OrderList *list = new (index) OrderList(0); + SlObject(list, slt); + } + + } + + void FixPointers() const override + { + for (OrderList *list : OrderList::Iterate()) { + SlObject(list, GetOrderListDescription()); + } + } +}; SaveLoadTable GetOrderBackupDescription() { @@ -262,45 +276,52 @@ SaveLoadTable GetOrderBackupDescription() return _order_backup_desc; } -static void Save_BKOR() -{ - const SaveLoadTable slt = GetOrderBackupDescription(); - SlTableHeader(slt); - - /* We only save this when we're a network server - * as we want this information on our clients. For - * normal games this information isn't needed. */ - if (!_networking || !_network_server) return; - - for (OrderBackup *ob : OrderBackup::Iterate()) { - SlSetArrayIndex(ob->index); - SlObject(ob, slt); +struct BKORChunkHandler : ChunkHandler { + BKORChunkHandler() : ChunkHandler('BKOR', CH_TABLE) + { + this->fix_pointers = true; } -} -void Load_BKOR() -{ - const std::vector slt = SlCompatTableHeader(GetOrderBackupDescription(), _order_backup_sl_compat); + void Save() const override + { + const SaveLoadTable slt = GetOrderBackupDescription(); + SlTableHeader(slt); - int index; + /* We only save this when we're a network server + * as we want this information on our clients. For + * normal games this information isn't needed. */ + if (!_networking || !_network_server) return; - while ((index = SlIterateArray()) != -1) { - /* set num_orders to 0 so it's a valid OrderList */ - OrderBackup *ob = new (index) OrderBackup(); - SlObject(ob, slt); + for (OrderBackup *ob : OrderBackup::Iterate()) { + SlSetArrayIndex(ob->index); + SlObject(ob, slt); + } } -} -static void Ptrs_BKOR() -{ - for (OrderBackup *ob : OrderBackup::Iterate()) { - SlObject(ob, GetOrderBackupDescription()); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(GetOrderBackupDescription(), _order_backup_sl_compat); + + int index; + + while ((index = SlIterateArray()) != -1) { + /* set num_orders to 0 so it's a valid OrderList */ + OrderBackup *ob = new (index) OrderBackup(); + SlObject(ob, slt); + } } -} -static const ChunkHandler BKOR{ 'BKOR', Save_BKOR, Load_BKOR, Ptrs_BKOR, nullptr, CH_TABLE }; -static const ChunkHandler ORDR{ 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, nullptr, CH_TABLE }; -static const ChunkHandler ORDL{ 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, nullptr, CH_TABLE }; + void FixPointers() const override + { + for (OrderBackup *ob : OrderBackup::Iterate()) { + SlObject(ob, GetOrderBackupDescription()); + } + } +}; + +static const BKORChunkHandler BKOR; +static const ORDRChunkHandler ORDR; +static const ORDLChunkHandler ORDL; static const ChunkHandlerRef order_chunk_handlers[] = { BKOR, ORDR, diff --git a/src/saveload/settings_sl.cpp b/src/saveload/settings_sl.cpp index fe320db5d1..53254cde7c 100644 --- a/src/saveload/settings_sl.cpp +++ b/src/saveload/settings_sl.cpp @@ -142,36 +142,47 @@ static void SaveSettings(const SettingTable &settings, void *object) SlObject(object, slt); } -static void Load_OPTS() -{ - /* Copy over default setting since some might not get loaded in - * a networking environment. This ensures for example that the local - * autosave-frequency stays when joining a network-server */ - PrepareOldDiffCustom(); - LoadSettings(_gameopt_settings, &_settings_game, _gameopt_sl_compat); - HandleOldDiffCustom(true); -} +struct OPTSChunkHandler : ChunkHandler { + OPTSChunkHandler() : ChunkHandler('OPTS', CH_READONLY) {} -static void Load_PATS() -{ - /* Copy over default setting since some might not get loaded in - * a networking environment. This ensures for example that the local - * currency setting stays when joining a network-server */ - LoadSettings(_settings, &_settings_game, _settings_sl_compat); -} + void Load() const override + { + /* Copy over default setting since some might not get loaded in + * a networking environment. This ensures for example that the local + * autosave-frequency stays when joining a network-server */ + PrepareOldDiffCustom(); + LoadSettings(_gameopt_settings, &_settings_game, _gameopt_sl_compat); + HandleOldDiffCustom(true); + } +}; -static void Check_PATS() -{ - LoadSettings(_settings, &_load_check_data.settings, _settings_sl_compat); -} +struct PATSChunkHandler : ChunkHandler { + PATSChunkHandler() : ChunkHandler('PATS', CH_TABLE) + { + this->load_check = true; + } -static void Save_PATS() -{ - SaveSettings(_settings, &_settings_game); -} + void Load() const override + { + /* Copy over default setting since some might not get loaded in + * a networking environment. This ensures for example that the local + * currency setting stays when joining a network-server */ + LoadSettings(_settings, &_settings_game, _settings_sl_compat); + } -static const ChunkHandler OPTS{ 'OPTS', nullptr, Load_OPTS, nullptr, nullptr, CH_READONLY }; -static const ChunkHandler PATS{ 'PATS', Save_PATS, Load_PATS, nullptr, Check_PATS, CH_TABLE }; + void LoadCheck(size_t) const override + { + LoadSettings(_settings, &_load_check_data.settings, _settings_sl_compat); + } + + void Save() const override + { + SaveSettings(_settings, &_settings_game); + } +}; + +static const OPTSChunkHandler OPTS; +static const PATSChunkHandler PATS; static const ChunkHandlerRef setting_chunk_handlers[] = { OPTS, PATS, diff --git a/src/saveload/signs_sl.cpp b/src/saveload/signs_sl.cpp index 21cd69f155..336a552f76 100644 --- a/src/saveload/signs_sl.cpp +++ b/src/saveload/signs_sl.cpp @@ -30,44 +30,46 @@ static const SaveLoad _sign_desc[] = { SLE_CONDVAR(Sign, z, SLE_INT32, SLV_164, SL_MAX_VERSION), }; -/** Save all signs */ -static void Save_SIGN() -{ - SlTableHeader(_sign_desc); +struct SIGNChunkHandler : ChunkHandler { + SIGNChunkHandler() : ChunkHandler('SIGN', CH_TABLE) {} - for (Sign *si : Sign::Iterate()) { - SlSetArrayIndex(si->index); - SlObject(si, _sign_desc); - } -} + void Save() const override + { + SlTableHeader(_sign_desc); -/** Load all signs */ -static void Load_SIGN() -{ - const std::vector slt = SlCompatTableHeader(_sign_desc, _sign_sl_compat); - - int index; - while ((index = SlIterateArray()) != -1) { - Sign *si = new (index) Sign(); - SlObject(si, slt); - /* Before version 6.1, signs didn't have owner. - * Before version 83, invalid signs were determined by si->str == 0. - * Before version 103, owner could be a bankrupted company. - * - we can't use IsValidCompany() now, so this is fixed in AfterLoadGame() - * All signs that were saved are valid (including those with just 'Sign' and INVALID_OWNER). - * - so set owner to OWNER_NONE if needed (signs from pre-version 6.1 would be lost) */ - if (IsSavegameVersionBefore(SLV_6, 1) || (IsSavegameVersionBefore(SLV_83) && si->owner == INVALID_OWNER)) { - si->owner = OWNER_NONE; - } - - /* Signs placed in scenario editor shall now be OWNER_DEITY */ - if (IsSavegameVersionBefore(SLV_171) && si->owner == OWNER_NONE && _file_to_saveload.abstract_ftype == FT_SCENARIO) { - si->owner = OWNER_DEITY; + for (Sign *si : Sign::Iterate()) { + SlSetArrayIndex(si->index); + SlObject(si, _sign_desc); } } -} -static const ChunkHandler SIGN{ 'SIGN', Save_SIGN, Load_SIGN, nullptr, nullptr, CH_TABLE }; + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_sign_desc, _sign_sl_compat); + + int index; + while ((index = SlIterateArray()) != -1) { + Sign *si = new (index) Sign(); + SlObject(si, slt); + /* Before version 6.1, signs didn't have owner. + * Before version 83, invalid signs were determined by si->str == 0. + * Before version 103, owner could be a bankrupted company. + * - we can't use IsValidCompany() now, so this is fixed in AfterLoadGame() + * All signs that were saved are valid (including those with just 'Sign' and INVALID_OWNER). + * - so set owner to OWNER_NONE if needed (signs from pre-version 6.1 would be lost) */ + if (IsSavegameVersionBefore(SLV_6, 1) || (IsSavegameVersionBefore(SLV_83) && si->owner == INVALID_OWNER)) { + si->owner = OWNER_NONE; + } + + /* Signs placed in scenario editor shall now be OWNER_DEITY */ + if (IsSavegameVersionBefore(SLV_171) && si->owner == OWNER_NONE && _file_to_saveload.abstract_ftype == FT_SCENARIO) { + si->owner = OWNER_DEITY; + } + } + } +}; + +static const SIGNChunkHandler SIGN; static const ChunkHandlerRef sign_chunk_handlers[] = { SIGN, }; diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 5662e4a465..9c97792cef 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -484,34 +484,41 @@ static const SaveLoad _old_station_desc[] = { SLEG_CONDSTRUCTLIST("speclist", SlStationSpecList, SLV_27, SL_MAX_VERSION), }; -static void Load_STNS() -{ - const std::vector slt = SlCompatTableHeader(_old_station_desc, _old_station_sl_compat); - - _cargo_source_xy = 0; - _cargo_days = 0; - _cargo_feeder_share = 0; - - int index; - while ((index = SlIterateArray()) != -1) { - Station *st = new (index) Station(); - - _waiting_acceptance = 0; - SlObject(st, slt); +struct STNSChunkHandler : ChunkHandler { + STNSChunkHandler() : ChunkHandler('STNS', CH_READONLY) + { + this->fix_pointers = true; } -} -static void Ptrs_STNS() -{ - /* From SLV_123 we store stations in STNN; before that in STNS. So do not - * fix pointers when the version is SLV_123 or up, as that would fix - * pointers twice: once in STNN chunk and once here. */ - if (!IsSavegameVersionBefore(SLV_123)) return; + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_old_station_desc, _old_station_sl_compat); - for (Station *st : Station::Iterate()) { - SlObject(st, _old_station_desc); + _cargo_source_xy = 0; + _cargo_days = 0; + _cargo_feeder_share = 0; + + int index; + while ((index = SlIterateArray()) != -1) { + Station *st = new (index) Station(); + + _waiting_acceptance = 0; + SlObject(st, slt); + } } -} + + void FixPointers() const override + { + /* From SLV_123 we store stations in STNN; before that in STNS. So do not + * fix pointers when the version is SLV_123 or up, as that would fix + * pointers twice: once in STNN chunk and once here. */ + if (!IsSavegameVersionBefore(SLV_123)) return; + + for (Station *st : Station::Iterate()) { + SlObject(st, _old_station_desc); + } + } +}; /** * SaveLoad handler for the BaseStation, which all other stations / waypoints @@ -651,77 +658,92 @@ static const SaveLoad _station_desc[] = { SLEG_CONDSTRUCTLIST("speclist", SlStationSpecList, SLV_27, SL_MAX_VERSION), }; -static void Save_STNN() -{ - SlTableHeader(_station_desc); - - /* Write the stations */ - for (BaseStation *st : BaseStation::Iterate()) { - SlSetArrayIndex(st->index); - SlObject(st, _station_desc); +struct STNNChunkHandler : ChunkHandler { + STNNChunkHandler() : ChunkHandler('STNN', CH_TABLE) + { + this->fix_pointers = true; } -} -static void Load_STNN() -{ - const std::vector slt = SlCompatTableHeader(_station_desc, _station_sl_compat); + void Save() const override + { + SlTableHeader(_station_desc); - _old_num_flows = 0; - - int index; - while ((index = SlIterateArray()) != -1) { - bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0; - - BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station(); - SlObject(bst, slt); + /* Write the stations */ + for (BaseStation *st : BaseStation::Iterate()) { + SlSetArrayIndex(st->index); + SlObject(st, _station_desc); + } } -} -static void Ptrs_STNN() -{ - /* From SLV_123 we store stations in STNN; before that in STNS. So do not - * fix pointers when the version is below SLV_123, as that would fix - * pointers twice: once in STNS chunk and once here. */ - if (IsSavegameVersionBefore(SLV_123)) return; - for (BaseStation *bst : BaseStation::Iterate()) { - SlObject(bst, _station_desc); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_station_desc, _station_sl_compat); + + _old_num_flows = 0; + + int index; + while ((index = SlIterateArray()) != -1) { + bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0; + + BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station(); + SlObject(bst, slt); + } } -} -static void Save_ROADSTOP() -{ - SlTableHeader(_roadstop_desc); + void FixPointers() const override + { + /* From SLV_123 we store stations in STNN; before that in STNS. So do not + * fix pointers when the version is below SLV_123, as that would fix + * pointers twice: once in STNS chunk and once here. */ + if (IsSavegameVersionBefore(SLV_123)) return; - for (RoadStop *rs : RoadStop::Iterate()) { - SlSetArrayIndex(rs->index); - SlObject(rs, _roadstop_desc); + for (BaseStation *bst : BaseStation::Iterate()) { + SlObject(bst, _station_desc); + } } -} +}; -static void Load_ROADSTOP() -{ - const std::vector slt = SlCompatTableHeader(_roadstop_desc, _roadstop_sl_compat); - - int index; - - while ((index = SlIterateArray()) != -1) { - RoadStop *rs = new (index) RoadStop(INVALID_TILE); - - SlObject(rs, slt); +struct ROADChunkHandler : ChunkHandler { + ROADChunkHandler() : ChunkHandler('ROAD', CH_TABLE) + { + this->fix_pointers = true; } -} -static void Ptrs_ROADSTOP() -{ - for (RoadStop *rs : RoadStop::Iterate()) { - SlObject(rs, _roadstop_desc); + void Save() const override + { + SlTableHeader(_roadstop_desc); + + for (RoadStop *rs : RoadStop::Iterate()) { + SlSetArrayIndex(rs->index); + SlObject(rs, _roadstop_desc); + } } -} -static const ChunkHandler STNS{ 'STNS', nullptr, Load_STNS, Ptrs_STNS, nullptr, CH_READONLY }; -static const ChunkHandler STNN{ 'STNN', Save_STNN, Load_STNN, Ptrs_STNN, nullptr, CH_TABLE }; -static const ChunkHandler ROAD{ 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, nullptr, CH_TABLE }; + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_roadstop_desc, _roadstop_sl_compat); + + int index; + + while ((index = SlIterateArray()) != -1) { + RoadStop *rs = new (index) RoadStop(INVALID_TILE); + + SlObject(rs, slt); + } + } + + void FixPointers() const override + { + for (RoadStop *rs : RoadStop::Iterate()) { + SlObject(rs, _roadstop_desc); + } + } +}; + +static const STNSChunkHandler STNS; +static const STNNChunkHandler STNN; +static const ROADChunkHandler ROAD; static const ChunkHandlerRef station_chunk_handlers[] = { STNS, STNN, diff --git a/src/saveload/storage_sl.cpp b/src/saveload/storage_sl.cpp index 4a360d58d8..4db185e9af 100644 --- a/src/saveload/storage_sl.cpp +++ b/src/saveload/storage_sl.cpp @@ -23,34 +23,37 @@ static const SaveLoad _storage_desc[] = { SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION), }; -/** Load persistent storage data. */ -static void Load_PSAC() -{ - const std::vector slt = SlCompatTableHeader(_storage_desc, _storage_sl_compat); +/** Persistent storage data. */ +struct PSACChunkHandler : ChunkHandler { + PSACChunkHandler() : ChunkHandler('PSAC', CH_TABLE) {} - int index; + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_storage_desc, _storage_sl_compat); - while ((index = SlIterateArray()) != -1) { - assert(PersistentStorage::CanAllocateItem()); - PersistentStorage *ps = new (index) PersistentStorage(0, 0, 0); - SlObject(ps, slt); + int index; + + while ((index = SlIterateArray()) != -1) { + assert(PersistentStorage::CanAllocateItem()); + PersistentStorage *ps = new (index) PersistentStorage(0, 0, 0); + SlObject(ps, slt); + } } -} -/** Save persistent storage data. */ -static void Save_PSAC() -{ - SlTableHeader(_storage_desc); + void Save() const override + { + SlTableHeader(_storage_desc); - /* Write the industries */ - for (PersistentStorage *ps : PersistentStorage::Iterate()) { - ps->ClearChanges(); - SlSetArrayIndex(ps->index); - SlObject(ps, _storage_desc); + /* Write the industries */ + for (PersistentStorage *ps : PersistentStorage::Iterate()) { + ps->ClearChanges(); + SlSetArrayIndex(ps->index); + SlObject(ps, _storage_desc); + } } -} +}; -static const ChunkHandler PSAC{ 'PSAC', Save_PSAC, Load_PSAC, nullptr, nullptr, CH_TABLE }; +static const PSACChunkHandler PSAC; static const ChunkHandlerRef persistent_storage_chunk_handlers[] = { PSAC, }; diff --git a/src/saveload/story_sl.cpp b/src/saveload/story_sl.cpp index 6371b4162b..d20bc3b4cd 100644 --- a/src/saveload/story_sl.cpp +++ b/src/saveload/story_sl.cpp @@ -38,34 +38,38 @@ static const SaveLoad _story_page_elements_desc[] = { SLE_STR(StoryPageElement, text, SLE_STR | SLF_ALLOW_CONTROL, 0), }; -static void Save_STORY_PAGE_ELEMENT() -{ - SlTableHeader(_story_page_elements_desc); +struct STPEChunkHandler : ChunkHandler { + STPEChunkHandler() : ChunkHandler('STPE', CH_TABLE) {} - for (StoryPageElement *s : StoryPageElement::Iterate()) { - SlSetArrayIndex(s->index); - SlObject(s, _story_page_elements_desc); - } -} + void Save() const override + { + SlTableHeader(_story_page_elements_desc); -static void Load_STORY_PAGE_ELEMENT() -{ - const std::vector slt = SlCompatTableHeader(_story_page_elements_desc, _story_page_elements_sl_compat); - - int index; - uint32 max_sort_value = 0; - while ((index = SlIterateArray()) != -1) { - StoryPageElement *s = new (index) StoryPageElement(); - SlObject(s, slt); - if (s->sort_value > max_sort_value) { - max_sort_value = s->sort_value; + for (StoryPageElement *s : StoryPageElement::Iterate()) { + SlSetArrayIndex(s->index); + SlObject(s, _story_page_elements_desc); } } - /* Update the next sort value, so that the next - * created page is shown after all existing pages. - */ - _story_page_element_next_sort_value = max_sort_value + 1; -} + + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_story_page_elements_desc, _story_page_elements_sl_compat); + + int index; + uint32 max_sort_value = 0; + while ((index = SlIterateArray()) != -1) { + StoryPageElement *s = new (index) StoryPageElement(); + SlObject(s, slt); + if (s->sort_value > max_sort_value) { + max_sort_value = s->sort_value; + } + } + /* Update the next sort value, so that the next + * created page is shown after all existing pages. + */ + _story_page_element_next_sort_value = max_sort_value + 1; + } +}; static const SaveLoad _story_pages_desc[] = { SLE_CONDVAR(StoryPage, sort_value, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_185), @@ -76,37 +80,41 @@ static const SaveLoad _story_pages_desc[] = { SLE_STR(StoryPage, title, SLE_STR | SLF_ALLOW_CONTROL, 0), }; -static void Save_STORY_PAGE() -{ - SlTableHeader(_story_pages_desc); +struct STPAChunkHandler : ChunkHandler { + STPAChunkHandler() : ChunkHandler('STPA', CH_TABLE) {} - for (StoryPage *s : StoryPage::Iterate()) { - SlSetArrayIndex(s->index); - SlObject(s, _story_pages_desc); - } -} + void Save() const override + { + SlTableHeader(_story_pages_desc); -static void Load_STORY_PAGE() -{ - const std::vector slt = SlCompatTableHeader(_story_pages_desc, _story_pages_sl_compat); - - int index; - uint32 max_sort_value = 0; - while ((index = SlIterateArray()) != -1) { - StoryPage *s = new (index) StoryPage(); - SlObject(s, slt); - if (s->sort_value > max_sort_value) { - max_sort_value = s->sort_value; + for (StoryPage *s : StoryPage::Iterate()) { + SlSetArrayIndex(s->index); + SlObject(s, _story_pages_desc); } } - /* Update the next sort value, so that the next - * created page is shown after all existing pages. - */ - _story_page_next_sort_value = max_sort_value + 1; -} -static const ChunkHandler STPE{ 'STPE', Save_STORY_PAGE_ELEMENT, Load_STORY_PAGE_ELEMENT, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler STPA{ 'STPA', Save_STORY_PAGE, Load_STORY_PAGE, nullptr, nullptr, CH_TABLE }; + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_story_pages_desc, _story_pages_sl_compat); + + int index; + uint32 max_sort_value = 0; + while ((index = SlIterateArray()) != -1) { + StoryPage *s = new (index) StoryPage(); + SlObject(s, slt); + if (s->sort_value > max_sort_value) { + max_sort_value = s->sort_value; + } + } + /* Update the next sort value, so that the next + * created page is shown after all existing pages. + */ + _story_page_next_sort_value = max_sort_value + 1; + } +}; + +static const STPEChunkHandler STPE; +static const STPAChunkHandler STPA; static const ChunkHandlerRef story_page_chunk_handlers[] = { STPE, STPA, diff --git a/src/saveload/strings_sl.cpp b/src/saveload/strings_sl.cpp index 7cad1fba6e..512a743d98 100644 --- a/src/saveload/strings_sl.cpp +++ b/src/saveload/strings_sl.cpp @@ -113,24 +113,25 @@ void InitializeOldNames() _old_name_array = CallocT(NUM_OLD_STRINGS * LEN_OLD_STRINGS); // 200 * 24 would be enough for TTO savegames } -/** - * Load the NAME chunk. - */ -static void Load_NAME() -{ - int index; +struct NAMEChunkHandler : ChunkHandler { + NAMEChunkHandler() : ChunkHandler('NAME', CH_READONLY) {} - while ((index = SlIterateArray()) != -1) { - if (index >= NUM_OLD_STRINGS) SlErrorCorrupt("Invalid old name index"); - if (SlGetFieldLength() > (uint)LEN_OLD_STRINGS) SlErrorCorrupt("Invalid old name length"); + void Load() const override + { + int index; - SlCopy(&_old_name_array[LEN_OLD_STRINGS * index], SlGetFieldLength(), SLE_UINT8); - /* Make sure the old name is null terminated */ - _old_name_array[LEN_OLD_STRINGS * index + LEN_OLD_STRINGS - 1] = '\0'; + while ((index = SlIterateArray()) != -1) { + if (index >= NUM_OLD_STRINGS) SlErrorCorrupt("Invalid old name index"); + if (SlGetFieldLength() > (uint)LEN_OLD_STRINGS) SlErrorCorrupt("Invalid old name length"); + + SlCopy(&_old_name_array[LEN_OLD_STRINGS * index], SlGetFieldLength(), SLE_UINT8); + /* Make sure the old name is null terminated */ + _old_name_array[LEN_OLD_STRINGS * index + LEN_OLD_STRINGS - 1] = '\0'; + } } -} +}; -static const ChunkHandler NAME{ 'NAME', nullptr, Load_NAME, nullptr, nullptr, CH_READONLY }; +static const NAMEChunkHandler NAME; static const ChunkHandlerRef name_chunk_handlers[] = { NAME, }; diff --git a/src/saveload/subsidy_sl.cpp b/src/saveload/subsidy_sl.cpp index a02c19319f..d4a882dad7 100644 --- a/src/saveload/subsidy_sl.cpp +++ b/src/saveload/subsidy_sl.cpp @@ -29,28 +29,32 @@ static const SaveLoad _subsidies_desc[] = { SLE_CONDVAR(Subsidy, dst, SLE_UINT16, SLV_5, SL_MAX_VERSION), }; -static void Save_SUBS() -{ - SlTableHeader(_subsidies_desc); +struct SUBSChunkHandler : ChunkHandler { + SUBSChunkHandler() : ChunkHandler('SUBS', CH_TABLE) {} - for (Subsidy *s : Subsidy::Iterate()) { - SlSetArrayIndex(s->index); - SlObject(s, _subsidies_desc); + void Save() const override + { + SlTableHeader(_subsidies_desc); + + for (Subsidy *s : Subsidy::Iterate()) { + SlSetArrayIndex(s->index); + SlObject(s, _subsidies_desc); + } } -} -static void Load_SUBS() -{ - const std::vector slt = SlCompatTableHeader(_subsidies_desc, _subsidies_sl_compat); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_subsidies_desc, _subsidies_sl_compat); - int index; - while ((index = SlIterateArray()) != -1) { - Subsidy *s = new (index) Subsidy(); - SlObject(s, slt); + int index; + while ((index = SlIterateArray()) != -1) { + Subsidy *s = new (index) Subsidy(); + SlObject(s, slt); + } } -} +}; -static const ChunkHandler SUBS{ 'SUBS', Save_SUBS, Load_SUBS, nullptr, nullptr, CH_TABLE }; +static const SUBSChunkHandler SUBS; static const ChunkHandlerRef subsidy_chunk_handlers[] = { SUBS, }; diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 906940033f..09c575e6a0 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -272,54 +272,64 @@ static const SaveLoad _town_desc[] = { SLEG_CONDSTRUCTLIST("acceptance_matrix", SlTownAcceptanceMatrix, SLV_166, SLV_REMOVE_TOWN_CARGO_CACHE), }; -static void Save_HIDS() -{ - Save_NewGRFMapping(_house_mngr); -} +struct HIDSChunkHandler : ChunkHandler { + HIDSChunkHandler() : ChunkHandler('HIDS', CH_TABLE) {} -static void Load_HIDS() -{ - Load_NewGRFMapping(_house_mngr); -} - -static void Save_TOWN() -{ - SlTableHeader(_town_desc); - - for (Town *t : Town::Iterate()) { - SlSetArrayIndex(t->index); - SlObject(t, _town_desc); + void Save() const override + { + Save_NewGRFMapping(_house_mngr); } -} -static void Load_TOWN() -{ - const std::vector slt = SlCompatTableHeader(_town_desc, _town_sl_compat); + void Load() const override + { + Load_NewGRFMapping(_house_mngr); + } +}; - int index; +struct CITYChunkHandler : ChunkHandler { + CITYChunkHandler() : ChunkHandler('CITY', CH_TABLE) + { + this->fix_pointers = true; + } - while ((index = SlIterateArray()) != -1) { - Town *t = new (index) Town(); - SlObject(t, slt); + void Save() const override + { + SlTableHeader(_town_desc); - if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GetStringTab(t->townnametype) != TEXT_TAB_OLD_CUSTOM) { - SlErrorCorrupt("Invalid town name generator"); + for (Town *t : Town::Iterate()) { + SlSetArrayIndex(t->index); + SlObject(t, _town_desc); } } -} -/** Fix pointers when loading town data. */ -static void Ptrs_TOWN() -{ - if (IsSavegameVersionBefore(SLV_161)) return; + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_town_desc, _town_sl_compat); - for (Town *t : Town::Iterate()) { - SlObject(t, _town_desc); + int index; + + while ((index = SlIterateArray()) != -1) { + Town *t = new (index) Town(); + SlObject(t, slt); + + if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GetStringTab(t->townnametype) != TEXT_TAB_OLD_CUSTOM) { + SlErrorCorrupt("Invalid town name generator"); + } + } } -} -static const ChunkHandler HIDS{ 'HIDS', Save_HIDS, Load_HIDS, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler CITY{ 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, nullptr, CH_TABLE }; + void FixPointers() const override + { + if (IsSavegameVersionBefore(SLV_161)) return; + + for (Town *t : Town::Iterate()) { + SlObject(t, _town_desc); + } + } +}; + +static const HIDSChunkHandler HIDS; +static const CITYChunkHandler CITY; static const ChunkHandlerRef town_chunk_handlers[] = { HIDS, CITY, diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 2be5998f59..24b3a13c9f 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -994,77 +994,82 @@ const static SaveLoad _vehicle_desc[] = { SLEG_STRUCT("disaster", SlVehicleDisaster), }; -/** Will be called when the vehicles need to be saved. */ -static void Save_VEHS() -{ - SlTableHeader(_vehicle_desc); - - /* Write the vehicles */ - for (Vehicle *v : Vehicle::Iterate()) { - SlSetArrayIndex(v->index); - SlObject(v, _vehicle_desc); +struct VEHSChunkHandler : ChunkHandler { + VEHSChunkHandler() : ChunkHandler('VEHS', CH_SPARSE_TABLE) + { + this->fix_pointers = true; } -} -/** Will be called when vehicles need to be loaded. */ -void Load_VEHS() -{ - const std::vector slt = SlCompatTableHeader(_vehicle_desc, _vehicle_sl_compat); + void Save() const override + { + SlTableHeader(_vehicle_desc); - int index; - - _cargo_count = 0; - - while ((index = SlIterateArray()) != -1) { - Vehicle *v; - VehicleType vtype = (VehicleType)SlReadByte(); - - switch (vtype) { - case VEH_TRAIN: v = new (index) Train(); break; - case VEH_ROAD: v = new (index) RoadVehicle(); break; - case VEH_SHIP: v = new (index) Ship(); break; - case VEH_AIRCRAFT: v = new (index) Aircraft(); break; - case VEH_EFFECT: v = new (index) EffectVehicle(); break; - case VEH_DISASTER: v = new (index) DisasterVehicle(); break; - case VEH_INVALID: // Savegame shouldn't contain invalid vehicles - default: SlErrorCorrupt("Invalid vehicle type"); + /* Write the vehicles */ + for (Vehicle *v : Vehicle::Iterate()) { + SlSetArrayIndex(v->index); + SlObject(v, _vehicle_desc); } - - SlObject(v, slt); - - if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v) && CargoPacket::CanAllocateItem()) { - /* Don't construct the packet with station here, because that'll fail with old savegames */ - CargoPacket *cp = new CargoPacket(_cargo_count, _cargo_days, _cargo_source, _cargo_source_xy, _cargo_loaded_at_xy, _cargo_feeder_share); - v->cargo.Append(cp); - } - - /* Old savegames used 'last_station_visited = 0xFF' */ - if (IsSavegameVersionBefore(SLV_5) && v->last_station_visited == 0xFF) { - v->last_station_visited = INVALID_STATION; - } - - if (IsSavegameVersionBefore(SLV_182)) v->last_loading_station = INVALID_STATION; - - if (IsSavegameVersionBefore(SLV_5)) { - /* Convert the current_order.type (which is a mix of type and flags, because - * in those versions, they both were 4 bits big) to type and flags */ - v->current_order.flags = GB(v->current_order.type, 4, 4); - v->current_order.type &= 0x0F; - } - - /* Advanced vehicle lists got added */ - if (IsSavegameVersionBefore(SLV_60)) v->group_id = DEFAULT_GROUP; } -} -void Ptrs_VEHS() -{ - for (Vehicle *v : Vehicle::Iterate()) { - SlObject(v, _vehicle_desc); + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_vehicle_desc, _vehicle_sl_compat); + + int index; + + _cargo_count = 0; + + while ((index = SlIterateArray()) != -1) { + Vehicle *v; + VehicleType vtype = (VehicleType)SlReadByte(); + + switch (vtype) { + case VEH_TRAIN: v = new (index) Train(); break; + case VEH_ROAD: v = new (index) RoadVehicle(); break; + case VEH_SHIP: v = new (index) Ship(); break; + case VEH_AIRCRAFT: v = new (index) Aircraft(); break; + case VEH_EFFECT: v = new (index) EffectVehicle(); break; + case VEH_DISASTER: v = new (index) DisasterVehicle(); break; + case VEH_INVALID: // Savegame shouldn't contain invalid vehicles + default: SlErrorCorrupt("Invalid vehicle type"); + } + + SlObject(v, slt); + + if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v) && CargoPacket::CanAllocateItem()) { + /* Don't construct the packet with station here, because that'll fail with old savegames */ + CargoPacket *cp = new CargoPacket(_cargo_count, _cargo_days, _cargo_source, _cargo_source_xy, _cargo_loaded_at_xy, _cargo_feeder_share); + v->cargo.Append(cp); + } + + /* Old savegames used 'last_station_visited = 0xFF' */ + if (IsSavegameVersionBefore(SLV_5) && v->last_station_visited == 0xFF) { + v->last_station_visited = INVALID_STATION; + } + + if (IsSavegameVersionBefore(SLV_182)) v->last_loading_station = INVALID_STATION; + + if (IsSavegameVersionBefore(SLV_5)) { + /* Convert the current_order.type (which is a mix of type and flags, because + * in those versions, they both were 4 bits big) to type and flags */ + v->current_order.flags = GB(v->current_order.type, 4, 4); + v->current_order.type &= 0x0F; + } + + /* Advanced vehicle lists got added */ + if (IsSavegameVersionBefore(SLV_60)) v->group_id = DEFAULT_GROUP; + } } -} -static const ChunkHandler VEHS{ 'VEHS', Save_VEHS, Load_VEHS, Ptrs_VEHS, nullptr, CH_SPARSE_TABLE }; + void FixPointers() const override + { + for (Vehicle *v : Vehicle::Iterate()) { + SlObject(v, _vehicle_desc); + } + } +}; + +static const VEHSChunkHandler VEHS; static const ChunkHandlerRef veh_chunk_handlers[] = { VEHS, }; diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp index bf22720fcb..739fd5655b 100644 --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.cpp @@ -182,49 +182,56 @@ static const SaveLoad _old_waypoint_desc[] = { SLE_CONDVAR(OldWaypoint, owner, SLE_UINT8, SLV_101, SL_MAX_VERSION), }; -static void Load_WAYP() -{ - /* Precaution for when loading failed and it didn't get cleared */ - ResetOldWaypoints(); - - int index; - - while ((index = SlIterateArray()) != -1) { - OldWaypoint *wp = &_old_waypoints.emplace_back(); - - wp->index = index; - SlObject(wp, _old_waypoint_desc); +struct CHKPChunkHandler : ChunkHandler { + CHKPChunkHandler() : ChunkHandler('CHKP', CH_READONLY) + { + this->fix_pointers = true; } -} -static void Ptrs_WAYP() -{ - for (OldWaypoint &wp : _old_waypoints) { - SlObject(&wp, _old_waypoint_desc); + void Load() const override + { + /* Precaution for when loading failed and it didn't get cleared */ + ResetOldWaypoints(); - if (IsSavegameVersionBefore(SLV_12)) { - wp.town_cn = (wp.string_id & 0xC000) == 0xC000 ? (wp.string_id >> 8) & 0x3F : 0; - wp.town = ClosestTownFromTile(wp.xy, UINT_MAX); - } else if (IsSavegameVersionBefore(SLV_122)) { - /* Only for versions 12 .. 122 */ - if (!Town::IsValidID(wp.town_index)) { - /* Upon a corrupted waypoint we'll likely get here. The next step will be to - * loop over all Ptrs procs to nullptr the pointers. However, we don't know - * whether we're in the nullptr or "normal" Ptrs proc. So just clear the list - * of old waypoints we constructed and then this waypoint (and the other - * possibly corrupt ones) will not be queried in the nullptr Ptrs proc run. */ - _old_waypoints.clear(); - SlErrorCorrupt("Referencing invalid Town"); + int index; + + while ((index = SlIterateArray()) != -1) { + OldWaypoint *wp = &_old_waypoints.emplace_back(); + + wp->index = index; + SlObject(wp, _old_waypoint_desc); + } + } + + void FixPointers() const override + { + for (OldWaypoint &wp : _old_waypoints) { + SlObject(&wp, _old_waypoint_desc); + + if (IsSavegameVersionBefore(SLV_12)) { + wp.town_cn = (wp.string_id & 0xC000) == 0xC000 ? (wp.string_id >> 8) & 0x3F : 0; + wp.town = ClosestTownFromTile(wp.xy, UINT_MAX); + } else if (IsSavegameVersionBefore(SLV_122)) { + /* Only for versions 12 .. 122 */ + if (!Town::IsValidID(wp.town_index)) { + /* Upon a corrupted waypoint we'll likely get here. The next step will be to + * loop over all Ptrs procs to nullptr the pointers. However, we don't know + * whether we're in the nullptr or "normal" Ptrs proc. So just clear the list + * of old waypoints we constructed and then this waypoint (and the other + * possibly corrupt ones) will not be queried in the nullptr Ptrs proc run. */ + _old_waypoints.clear(); + SlErrorCorrupt("Referencing invalid Town"); + } + wp.town = Town::Get(wp.town_index); + } + if (IsSavegameVersionBefore(SLV_84)) { + wp.name = CopyFromOldName(wp.string_id); } - wp.town = Town::Get(wp.town_index); - } - if (IsSavegameVersionBefore(SLV_84)) { - wp.name = CopyFromOldName(wp.string_id); } } -} +}; -static const ChunkHandler CHKP{ 'CHKP', nullptr, Load_WAYP, Ptrs_WAYP, nullptr, CH_READONLY }; +static const CHKPChunkHandler CHKP; static const ChunkHandlerRef waypoint_chunk_handlers[] = { CHKP, }; From 6e627f35ac03008dab7729ad079b79db9df2d68b Mon Sep 17 00:00:00 2001 From: glx22 Date: Thu, 10 Jun 2021 03:21:07 +0200 Subject: [PATCH 29/42] Cleanup: Remove now unneeded ChunkHandler members --- src/saveload/autoreplace_sl.cpp | 5 +-- src/saveload/company_sl.cpp | 6 +--- src/saveload/depot_sl.cpp | 5 +-- src/saveload/economy_sl.cpp | 5 +-- src/saveload/gamelog_sl.cpp | 5 +-- src/saveload/industry_sl.cpp | 5 +-- src/saveload/linkgraph_sl.cpp | 5 +-- src/saveload/map_sl.cpp | 5 +-- src/saveload/misc_sl.cpp | 5 +-- src/saveload/newgrf_sl.cpp | 5 +-- src/saveload/object_sl.cpp | 5 +-- src/saveload/order_sl.cpp | 15 ++------ src/saveload/saveload.cpp | 63 ++++++++++----------------------- src/saveload/saveload.h | 21 ++--------- src/saveload/settings_sl.cpp | 5 +-- src/saveload/station_sl.cpp | 15 ++------ src/saveload/town_sl.cpp | 5 +-- src/saveload/vehicle_sl.cpp | 5 +-- src/saveload/waypoint_sl.cpp | 5 +-- 19 files changed, 42 insertions(+), 148 deletions(-) diff --git a/src/saveload/autoreplace_sl.cpp b/src/saveload/autoreplace_sl.cpp index 6a9dd8f006..6d5e08f119 100644 --- a/src/saveload/autoreplace_sl.cpp +++ b/src/saveload/autoreplace_sl.cpp @@ -26,10 +26,7 @@ static const SaveLoad _engine_renew_desc[] = { }; struct ERNWChunkHandler : ChunkHandler { - ERNWChunkHandler() : ChunkHandler('ERNW', CH_TABLE) - { - this->fix_pointers = true; - } + ERNWChunkHandler() : ChunkHandler('ERNW', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index fab674f8bf..cc8a9f9cb6 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -498,11 +498,7 @@ static const SaveLoad _company_desc[] = { }; struct PLYRChunkHandler : ChunkHandler { - PLYRChunkHandler() : ChunkHandler('PLYR', CH_TABLE) - { - this->load_check = true; - this->fix_pointers = true; - } + PLYRChunkHandler() : ChunkHandler('PLYR', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/depot_sl.cpp b/src/saveload/depot_sl.cpp index ef0c406e22..2a7859211c 100644 --- a/src/saveload/depot_sl.cpp +++ b/src/saveload/depot_sl.cpp @@ -30,10 +30,7 @@ static const SaveLoad _depot_desc[] = { }; struct DEPTChunkHandler : ChunkHandler { - DEPTChunkHandler() : ChunkHandler('DEPT', CH_TABLE) - { - this->fix_pointers = true; - } + DEPTChunkHandler() : ChunkHandler('DEPT', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/economy_sl.cpp b/src/saveload/economy_sl.cpp index 3ce1441eea..4625e831a0 100644 --- a/src/saveload/economy_sl.cpp +++ b/src/saveload/economy_sl.cpp @@ -89,10 +89,7 @@ static const SaveLoad _cargopayment_desc[] = { }; struct CAPYChunkHandler : ChunkHandler { - CAPYChunkHandler() : ChunkHandler('CAPY', CH_TABLE) - { - this->fix_pointers = true; - } + CAPYChunkHandler() : ChunkHandler('CAPY', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index 3d71f2ff9e..89db17424c 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.cpp @@ -348,10 +348,7 @@ static const SaveLoad _gamelog_desc[] = { }; struct GLOGChunkHandler : ChunkHandler { - GLOGChunkHandler() : ChunkHandler('GLOG', CH_TABLE) - { - this->load_check = true; - } + GLOGChunkHandler() : ChunkHandler('GLOG', CH_TABLE) {} void LoadCommon(LoggedAction *&gamelog_action, uint &gamelog_actions) const { diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index d70e1a4ee7..6d1645e39f 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -75,10 +75,7 @@ static const SaveLoad _industry_desc[] = { }; struct INDYChunkHandler : ChunkHandler { - INDYChunkHandler() : ChunkHandler('INDY', CH_TABLE) - { - this->fix_pointers = true; - } + INDYChunkHandler() : ChunkHandler('INDY', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index 70dfb7b39e..e1094326bf 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -301,10 +301,7 @@ struct LGRJChunkHandler : ChunkHandler { * Link graph schedule. */ struct LGRSChunkHandler : ChunkHandler { - LGRSChunkHandler() : ChunkHandler('LGRS', CH_TABLE) - { - this->fix_pointers = true; - } + LGRSChunkHandler() : ChunkHandler('LGRS', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index d654f3f6bc..07a36d6a38 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -28,10 +28,7 @@ static const SaveLoad _map_desc[] = { }; struct MAPSChunkHandler : ChunkHandler { - MAPSChunkHandler() : ChunkHandler('MAPS', CH_TABLE) - { - this->load_check = true; - } + MAPSChunkHandler() : ChunkHandler('MAPS', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index a7e00f88c9..779e100989 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -96,10 +96,7 @@ static const SaveLoad _date_check_desc[] = { /* Save load date related variables as well as persistent tick counters * XXX: currently some unrelated stuff is just put here */ struct DATEChunkHandler : ChunkHandler { - DATEChunkHandler() : ChunkHandler('DATE', CH_TABLE) - { - this->load_check = true; - } + DATEChunkHandler() : ChunkHandler('DATE', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/newgrf_sl.cpp b/src/saveload/newgrf_sl.cpp index 43f0bd01a9..9584d503ea 100644 --- a/src/saveload/newgrf_sl.cpp +++ b/src/saveload/newgrf_sl.cpp @@ -74,10 +74,7 @@ static const SaveLoad _grfconfig_desc[] = { struct NGRFChunkHandler : ChunkHandler { - NGRFChunkHandler() : ChunkHandler('NGRF', CH_TABLE) - { - this->load_check = true; - } + NGRFChunkHandler() : ChunkHandler('NGRF', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/object_sl.cpp b/src/saveload/object_sl.cpp index fc49970020..a61050303b 100644 --- a/src/saveload/object_sl.cpp +++ b/src/saveload/object_sl.cpp @@ -30,10 +30,7 @@ static const SaveLoad _object_desc[] = { }; struct OBJSChunkHandler : ChunkHandler { - OBJSChunkHandler() : ChunkHandler('OBJS', CH_TABLE) - { - this->fix_pointers = true; - } + OBJSChunkHandler() : ChunkHandler('OBJS', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index 16ee420137..9ec0d0e256 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -119,10 +119,7 @@ SaveLoadTable GetOrderDescription() } struct ORDRChunkHandler : ChunkHandler { - ORDRChunkHandler() : ChunkHandler('ORDR', CH_TABLE) - { - this->fix_pointers = true; - } + ORDRChunkHandler() : ChunkHandler('ORDR', CH_TABLE) {} void Save() const override { @@ -215,10 +212,7 @@ SaveLoadTable GetOrderListDescription() } struct ORDLChunkHandler : ChunkHandler { - ORDLChunkHandler() : ChunkHandler('ORDL', CH_TABLE) - { - this->fix_pointers = true; - } + ORDLChunkHandler() : ChunkHandler('ORDL', CH_TABLE) {} void Save() const override { @@ -277,10 +271,7 @@ SaveLoadTable GetOrderBackupDescription() } struct BKORChunkHandler : ChunkHandler { - BKORChunkHandler() : ChunkHandler('BKOR', CH_TABLE) - { - this->fix_pointers = true; - } + BKORChunkHandler() : ChunkHandler('BKOR', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 39941c268d..6e3d8f8e07 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -314,10 +314,8 @@ static void SlNullPointers() _sl_version = SAVEGAME_VERSION; for (const ChunkHandler &ch : ChunkHandlers()) { - if (ch.fix_pointers) { - Debug(sl, 3, "Nulling pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id); - ch.FixPointers(); - } + Debug(sl, 3, "Nulling pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id); + ch.FixPointers(); } assert(_sl.action == SLA_NULL); @@ -2114,45 +2112,22 @@ void SlAutolength(AutolengthProc *proc, void *arg) if (offs != _sl.dumper->GetSize()) SlErrorCorrupt("Invalid chunk size"); } -void ChunkHandler::Save() const -{ - assert(this->save_proc != nullptr); - this->save_proc(); -} - -void ChunkHandler::Load() const -{ - assert(this->load_proc != nullptr); - this->load_proc(); -} - -void ChunkHandler::FixPointers() const -{ - assert(this->ptrs_proc != nullptr); - this->ptrs_proc(); -} - void ChunkHandler::LoadCheck(size_t len) const { - if (this->load_check) { - assert(this->load_check_proc != nullptr); - this->load_check_proc(); - } else { - switch (_sl.block_mode) { - case CH_TABLE: - case CH_SPARSE_TABLE: - SlTableHeader({}); - FALLTHROUGH; - case CH_ARRAY: - case CH_SPARSE_ARRAY: - SlSkipArray(); - break; - case CH_RIFF: - SlSkipBytes(len); - break; - default: - NOT_REACHED(); - } + switch (_sl.block_mode) { + case CH_TABLE: + case CH_SPARSE_TABLE: + SlTableHeader({}); + FALLTHROUGH; + case CH_ARRAY: + case CH_SPARSE_ARRAY: + SlSkipArray(); + break; + case CH_RIFF: + SlSkipBytes(len); + break; + default: + NOT_REACHED(); } } @@ -2352,10 +2327,8 @@ static void SlFixPointers() _sl.action = SLA_PTRS; for (const ChunkHandler &ch : ChunkHandlers()) { - if (ch.fix_pointers) { - Debug(sl, 3, "Fixing pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id); - ch.FixPointers(); - } + Debug(sl, 3, "Fixing pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id); + ch.FixPointers(); } assert(_sl.action == SLA_PTRS); diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 2f5ebba1f3..7fc8027132 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -384,7 +384,6 @@ void DoExitSave(); SaveOrLoadResult SaveWithFilter(struct SaveFilter *writer, bool threaded); SaveOrLoadResult LoadWithFilter(struct LoadFilter *reader); -typedef void ChunkSaveLoadProc(); typedef void AutolengthProc(void *arg); /** Type of a chunk. */ @@ -402,37 +401,23 @@ enum ChunkType { /** Handlers and description of chunk. */ struct ChunkHandler { uint32 id; ///< Unique ID (4 letters). - ChunkSaveLoadProc *save_proc; ///< Save procedure of the chunk. - ChunkSaveLoadProc *load_proc; ///< Load procedure of the chunk. - ChunkSaveLoadProc *ptrs_proc; ///< Manipulate pointers in the chunk. - ChunkSaveLoadProc *load_check_proc; ///< Load procedure for game preview. ChunkType type; ///< Type of the chunk. @see ChunkType - bool fix_pointers = false; - bool load_check = false; - ChunkHandler(uint32 id, ChunkType type) : id(id), type(type) {} - ChunkHandler(uint32 id, ChunkSaveLoadProc *save_proc, ChunkSaveLoadProc *load_proc, ChunkSaveLoadProc *ptrs_proc, ChunkSaveLoadProc *load_check_proc, ChunkType type) - : id(id), save_proc(save_proc), load_proc(load_proc), ptrs_proc(ptrs_proc), load_check_proc(load_check_proc), type(type) - { - this->fix_pointers = ptrs_proc != nullptr; - this->load_check = load_check_proc != nullptr; - } - virtual ~ChunkHandler() {} /** * Save the chunk. * Must be overridden, unless Chunk type is CH_READONLY. */ - virtual void Save() const; + virtual void Save() const { NOT_REACHED(); } /** * Load the chunk. * Must be overridden. */ - virtual void Load() const; + virtual void Load() const = 0; /** * Fix the pointers. @@ -440,7 +425,7 @@ struct ChunkHandler { * On load, pointers are filled with indices and need to be fixed to point to the real object. * Must be overridden if the chunk saves any pointer. */ - virtual void FixPointers() const; + virtual void FixPointers() const {} /** * Load the chunk for game preview. diff --git a/src/saveload/settings_sl.cpp b/src/saveload/settings_sl.cpp index 53254cde7c..59b00e0f09 100644 --- a/src/saveload/settings_sl.cpp +++ b/src/saveload/settings_sl.cpp @@ -157,10 +157,7 @@ struct OPTSChunkHandler : ChunkHandler { }; struct PATSChunkHandler : ChunkHandler { - PATSChunkHandler() : ChunkHandler('PATS', CH_TABLE) - { - this->load_check = true; - } + PATSChunkHandler() : ChunkHandler('PATS', CH_TABLE) {} void Load() const override { diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 9c97792cef..20d70066e9 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -485,10 +485,7 @@ static const SaveLoad _old_station_desc[] = { }; struct STNSChunkHandler : ChunkHandler { - STNSChunkHandler() : ChunkHandler('STNS', CH_READONLY) - { - this->fix_pointers = true; - } + STNSChunkHandler() : ChunkHandler('STNS', CH_READONLY) {} void Load() const override { @@ -659,10 +656,7 @@ static const SaveLoad _station_desc[] = { }; struct STNNChunkHandler : ChunkHandler { - STNNChunkHandler() : ChunkHandler('STNN', CH_TABLE) - { - this->fix_pointers = true; - } + STNNChunkHandler() : ChunkHandler('STNN', CH_TABLE) {} void Save() const override { @@ -705,10 +699,7 @@ struct STNNChunkHandler : ChunkHandler { }; struct ROADChunkHandler : ChunkHandler { - ROADChunkHandler() : ChunkHandler('ROAD', CH_TABLE) - { - this->fix_pointers = true; - } + ROADChunkHandler() : ChunkHandler('ROAD', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 09c575e6a0..edf38178d9 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -287,10 +287,7 @@ struct HIDSChunkHandler : ChunkHandler { }; struct CITYChunkHandler : ChunkHandler { - CITYChunkHandler() : ChunkHandler('CITY', CH_TABLE) - { - this->fix_pointers = true; - } + CITYChunkHandler() : ChunkHandler('CITY', CH_TABLE) {} void Save() const override { diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 24b3a13c9f..85df6efcec 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -995,10 +995,7 @@ const static SaveLoad _vehicle_desc[] = { }; struct VEHSChunkHandler : ChunkHandler { - VEHSChunkHandler() : ChunkHandler('VEHS', CH_SPARSE_TABLE) - { - this->fix_pointers = true; - } + VEHSChunkHandler() : ChunkHandler('VEHS', CH_SPARSE_TABLE) {} void Save() const override { diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp index 739fd5655b..e81148fa5c 100644 --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.cpp @@ -183,10 +183,7 @@ static const SaveLoad _old_waypoint_desc[] = { }; struct CHKPChunkHandler : ChunkHandler { - CHKPChunkHandler() : ChunkHandler('CHKP', CH_READONLY) - { - this->fix_pointers = true; - } + CHKPChunkHandler() : ChunkHandler('CHKP', CH_READONLY) {} void Load() const override { From 7bcc7e11ff367d655b58fdc29bde5174afd49e4b Mon Sep 17 00:00:00 2001 From: glx22 Date: Sun, 4 Jul 2021 22:44:23 +0200 Subject: [PATCH 30/42] Codechange: Use a common sub-class for NewGRFMapping chunks --- src/saveload/airport_sl.cpp | 28 ++++------------------------ src/saveload/industry_sl.cpp | 28 ++++------------------------ src/saveload/newgrf_sl.cpp | 20 +++++++++----------- src/saveload/newgrf_sl.h | 9 +++++++-- src/saveload/object_sl.cpp | 14 ++------------ src/saveload/town_sl.cpp | 14 ++------------ 6 files changed, 28 insertions(+), 85 deletions(-) diff --git a/src/saveload/airport_sl.cpp b/src/saveload/airport_sl.cpp index e762c54d01..d83c45b048 100644 --- a/src/saveload/airport_sl.cpp +++ b/src/saveload/airport_sl.cpp @@ -14,32 +14,12 @@ #include "../safeguards.h" -struct APIDChunkHandler : ChunkHandler { - APIDChunkHandler() : ChunkHandler('APID', CH_TABLE) {} - - void Save() const override - { - Save_NewGRFMapping(_airport_mngr); - } - - void Load() const override - { - Load_NewGRFMapping(_airport_mngr); - } +struct APIDChunkHandler : NewGRFMappingChunkHandler { + APIDChunkHandler() : NewGRFMappingChunkHandler('APID', _airport_mngr) {} }; -struct ATIDChunkHandler : ChunkHandler { - ATIDChunkHandler() : ChunkHandler('ATID', CH_TABLE) {} - - void Save() const override - { - Save_NewGRFMapping(_airporttile_mngr); - } - - void Load() const override - { - Load_NewGRFMapping(_airporttile_mngr); - } +struct ATIDChunkHandler : NewGRFMappingChunkHandler { + ATIDChunkHandler() : NewGRFMappingChunkHandler('ATID', _airporttile_mngr) {} }; static const ATIDChunkHandler ATID; diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index 6d1645e39f..7a941a9c7c 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -119,32 +119,12 @@ struct INDYChunkHandler : ChunkHandler { } }; -struct IIDSChunkHandler : ChunkHandler { - IIDSChunkHandler() : ChunkHandler('IIDS', CH_TABLE) {} - - void Save() const override - { - Save_NewGRFMapping(_industry_mngr); - } - - void Load() const override - { - Load_NewGRFMapping(_industry_mngr); - } +struct IIDSChunkHandler : NewGRFMappingChunkHandler { + IIDSChunkHandler() : NewGRFMappingChunkHandler('IIDS', _industry_mngr) {} }; -struct TIDSChunkHandler : ChunkHandler { - TIDSChunkHandler() : ChunkHandler('TIDS', CH_TABLE) {} - - void Save() const override - { - Save_NewGRFMapping(_industile_mngr); - } - - void Load() const override - { - Load_NewGRFMapping(_industile_mngr); - } +struct TIDSChunkHandler : NewGRFMappingChunkHandler { + TIDSChunkHandler() : NewGRFMappingChunkHandler('TIDS', _industile_mngr) {} }; /** Description of the data to save and load in #IndustryBuildData. */ diff --git a/src/saveload/newgrf_sl.cpp b/src/saveload/newgrf_sl.cpp index 9584d503ea..510ffc156e 100644 --- a/src/saveload/newgrf_sl.cpp +++ b/src/saveload/newgrf_sl.cpp @@ -26,38 +26,36 @@ static const SaveLoad _newgrf_mapping_desc[] = { /** * Save a GRF ID + local id -> OpenTTD's id mapping. - * @param mapping The mapping to save. */ -void Save_NewGRFMapping(const OverrideManagerBase &mapping) +void NewGRFMappingChunkHandler::Save() const { SlTableHeader(_newgrf_mapping_desc); - for (uint i = 0; i < mapping.GetMaxMapping(); i++) { - if (mapping.mapping_ID[i].grfid == 0 && - mapping.mapping_ID[i].entity_id == 0) continue; + for (uint i = 0; i < this->mapping.GetMaxMapping(); i++) { + if (this->mapping.mapping_ID[i].grfid == 0 && + this->mapping.mapping_ID[i].entity_id == 0) continue; SlSetArrayIndex(i); - SlObject(&mapping.mapping_ID[i], _newgrf_mapping_desc); + SlObject(&this->mapping.mapping_ID[i], _newgrf_mapping_desc); } } /** * Load a GRF ID + local id -> OpenTTD's id mapping. - * @param mapping The mapping to load. */ -void Load_NewGRFMapping(OverrideManagerBase &mapping) +void NewGRFMappingChunkHandler::Load() const { const std::vector slt = SlCompatTableHeader(_newgrf_mapping_desc, _newgrf_mapping_sl_compat); /* Clear the current mapping stored. * This will create the manager if ever it is not yet done */ - mapping.ResetMapping(); + this->mapping.ResetMapping(); - uint max_id = mapping.GetMaxMapping(); + uint max_id = this->mapping.GetMaxMapping(); int index; while ((index = SlIterateArray()) != -1) { if ((uint)index >= max_id) SlErrorCorrupt("Too many NewGRF entity mappings"); - SlObject(&mapping.mapping_ID[index], slt); + SlObject(&this->mapping.mapping_ID[index], slt); } } diff --git a/src/saveload/newgrf_sl.h b/src/saveload/newgrf_sl.h index 191046de25..c266d90b17 100644 --- a/src/saveload/newgrf_sl.h +++ b/src/saveload/newgrf_sl.h @@ -12,7 +12,12 @@ #include "../newgrf_commons.h" -void Save_NewGRFMapping(const OverrideManagerBase &mapping); -void Load_NewGRFMapping(OverrideManagerBase &mapping); +struct NewGRFMappingChunkHandler : ChunkHandler { + OverrideManagerBase &mapping; + + NewGRFMappingChunkHandler(uint32 id, OverrideManagerBase &mapping) : ChunkHandler(id, CH_TABLE), mapping(mapping) {} + void Save() const override; + void Load() const override; +}; #endif /* SAVELOAD_NEWGRF_SL_H */ diff --git a/src/saveload/object_sl.cpp b/src/saveload/object_sl.cpp index a61050303b..eea1ec0fcb 100644 --- a/src/saveload/object_sl.cpp +++ b/src/saveload/object_sl.cpp @@ -66,18 +66,8 @@ struct OBJSChunkHandler : ChunkHandler { } }; -struct OBIDChunkHandler : ChunkHandler { - OBIDChunkHandler() : ChunkHandler('OBID', CH_TABLE) {} - - void Save() const override - { - Save_NewGRFMapping(_object_mngr); - } - - void Load() const override - { - Load_NewGRFMapping(_object_mngr); - } +struct OBIDChunkHandler : NewGRFMappingChunkHandler { + OBIDChunkHandler() : NewGRFMappingChunkHandler('OBID', _object_mngr) {} }; static const OBIDChunkHandler OBID; diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index edf38178d9..7b91259171 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -272,18 +272,8 @@ static const SaveLoad _town_desc[] = { SLEG_CONDSTRUCTLIST("acceptance_matrix", SlTownAcceptanceMatrix, SLV_166, SLV_REMOVE_TOWN_CARGO_CACHE), }; -struct HIDSChunkHandler : ChunkHandler { - HIDSChunkHandler() : ChunkHandler('HIDS', CH_TABLE) {} - - void Save() const override - { - Save_NewGRFMapping(_house_mngr); - } - - void Load() const override - { - Load_NewGRFMapping(_house_mngr); - } +struct HIDSChunkHandler : NewGRFMappingChunkHandler { + HIDSChunkHandler() : NewGRFMappingChunkHandler('HIDS', _house_mngr) {} }; struct CITYChunkHandler : ChunkHandler { From a7fabe497cd5b9f3b9e6b813b209d665d808d789 Mon Sep 17 00:00:00 2001 From: translators Date: Wed, 7 Jul 2021 18:51:22 +0000 Subject: [PATCH 31/42] Update: Translations from eints spanish (mexican): 6 changes by absay --- src/lang/spanish_MX.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index 797f4530ce..76e548aca2 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -1720,15 +1720,15 @@ STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :En una distribu STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Modo de distribución para el correo: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :En una distribución 'Simétrica', se envía la misma cantidad de correo entre dos estaciones. En una distribución 'Asimétrica', se pueden enviar cantidades arbitrarias de correo en ambas direcciones. 'Manual' significa que no hay distribución automática para el correo STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Modo de distribución para cargamento de valores: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :El cargamento de valores contiene objetos de valor en el clima Templado, diamantes en el clima Subtropical y oro en el clima Subártico (hay NewGRF para modificar esto). En una distribución 'Simétrica', se envía la misma cantidad de cargamento entre dos estaciones. En una distribución 'Asimétrica', se pueden enviar cantidades arbitrarias de cargamento en ambas direcciones. 'Manual' significa que no hay distribución automática para este cargamento. Se recomienda establecer la distribución en 'Asimétrica' o en 'Manual' al jugar en clima Subártico, pues los bancos no regresarán el oro a sus minas de procedencia. En los climas Templado y Subtropical se puede escoger 'Simétrica', ya que los bancos pueden regresar los objetos de valor a su banco origen. -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modo de distribución para otro cargamento: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :'Asimétrica' significa que se pueden mover cantidades arbitrarias de cargamento en ambas direcciones. 'Manual' significa que no habrá distribución automática para esta clase de cargamento. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :El cargamento de valores contiene objetos de valor en el clima Templado, diamantes en el Subtropical y oro en el Subártico. Algún NewGRF puede modificar esto. En una distribución "Simétrica", se envía la misma cantidad de carga entre dos estaciones. En una distribución "Asimétrica", se envían cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no hay distribución automática para esta carga. Se recomienda la distribución "Asimétrica" o "Manual" al jugar en clima Subártico, ya que los bancos no regresan oro a las minas. En los climas Templado y Subtropical se puede escoger "Simétrica", ya que los bancos pueden regresar algunos objetos de valor a su banco de origen.The ARMOURED cargo class contains valuables in the temperate, diamonds in the subtropical or gold in subarctic climate. NewGRFs may change that. "symmetric" means that roughly the same amount of that cargo will be sent from a station A to a station B as from B to A. "asymmetric" means that arbitrary amounts of that cargo can be sent in either direction. "manual" means that no automatic distribution will take place for that cargo. It is recommended to set this to asymmetric or manual when playing subarctic, as banks won't send any gold back to gold mines. For temperate and subtropical you can also choose symmetric as banks will send valuables back to the origin bank of some load of valuables. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modo de distribución para otra carga: {STRING} +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimétrica" significa que se pueden enviar cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no habrá distribución automática para esta clase de carga. STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisión de la distribución: {STRING} STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Si el valor es alto, se requerirá mayor tiempo para calcular la gráfica de distribución (si se lleva demasiado tiempo, se notará desfase en el juego). Si es muy bajo, la distribución será imprecisa, pudiendo hacer que el cargamento no vaya al lugar indicado STR_CONFIG_SETTING_DEMAND_DISTANCE :Efecto de la distancia en la demanda: {STRING} -STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Con un valor diferente a 0, la distancia entre la estación de origen de cierta carga y una posible estación de destino afectará la cantidad de cargamento que se envíe entre ambas. Cuanto más lejos estén entre sí, menos cargamento se enviará. Cuanto mayor sea el valor de esta opción, menos cargamento se enviará a estaciones distantes en favor de estaciones cercanas -STR_CONFIG_SETTING_DEMAND_SIZE :Cantidad de cargamento a devolver en modo simétrico: {STRING} -STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Establecer un valor menor de 100% hará que la distribución simétrica de cargamento sea más asimétrica. Se enviará menos cargamento de regreso forzosamente si una cantidad determinada es enviada a una estación. Si se fija a 0%, la distribución simétrica será como una distribución asimétrica +STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Con un valor mayor de 0, la distancia entre una estación de origen A y una estación de destino B afectará la cantidad de carga que se envíe desde A a B, enviando menos carga cuanto más lejos est. Cuanto mayor sea el valor de esta opción, menos carga se enviará a estaciones distantes en favor de estaciones cercanas. +STR_CONFIG_SETTING_DEMAND_SIZE :Cantidad de carga en retorno en modo simétrico: {STRING} +STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Con un valor menor de 100% la distribución simétrica de carga será más asimétrica, lo cual obligará a enviar menos carga en retorno en función de la enviada a una estación. Si es 0%, la distribución simétrica igual que la asimétrica. STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Nivel de saturación de rutas cortas antes de cambiar a rutas de mayor capacidad: {STRING} STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Entre dos estaciones usualmente hay más de una ruta posible. Se intentarán saturar las rutas más cortas primero, luego las que les siguen, y así sucesivamente. La saturación está determinada por una estimación de capacidad y uso planificado. Una vez que se hayan saturado todas las rutas, si todavía hay demanda se sobrecargarán los caminos empezando por aquellos de mayor capacidad. El algoritmo no siempre estimará la capacidad de forma precisa. Esta opción permite especificar el porcentaje de saturación que debe tener una ruta en el primer análisis antes de pasar a la siguiente ruta. Ponerlo a menos de 100% permite evitar estaciones sobrecargadas en el caso de que se sobreestimen las capacidades From 852e056d6f47a913ee0e13f1779910e18dbf97b7 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 8 Jul 2021 12:29:16 +0200 Subject: [PATCH 32/42] Fix 9e32c618: network revision was always empty (#9419) Shadowing the variable you intend to write in tends to do that ;) --- src/network/core/game_info.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/core/game_info.cpp b/src/network/core/game_info.cpp index a52de6c18c..b4c487fba8 100644 --- a/src/network/core/game_info.cpp +++ b/src/network/core/game_info.cpp @@ -43,7 +43,7 @@ std::string_view GetNetworkRevisionString() static std::string network_revision; if (network_revision.empty()) { - std::string network_revision = _openttd_revision; + network_revision = _openttd_revision; if (_openttd_revision_tagged) { /* Tagged; do not mangle further, though ensure it's not too long. */ if (network_revision.size() >= NETWORK_REVISION_LENGTH) network_revision.resize(NETWORK_REVISION_LENGTH - 1); From c1f13e03729b0bb13236867a633c446f3cce7b81 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 8 Jul 2021 19:31:00 +0200 Subject: [PATCH 33/42] Fix: reduce the amount of debug messages on -dsl=2 (#9420) LoadCheck makes it sound like something is really broken while loading savegames, while it really is perfectly normal, as most chunks do not implement LoadCheck. --- src/saveload/saveload.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 6e3d8f8e07..74978c4db8 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -1918,7 +1918,8 @@ std::vector SlTableHeader(const SaveLoadTable &slt) auto sld_it = key_lookup.find(key); if (sld_it == key_lookup.end()) { - Debug(sl, 2, "Field '{}' of type 0x{:02x} not found, skipping", key, type); + /* SLA_LOADCHECK triggers this debug statement a lot and is perfectly normal. */ + Debug(sl, _sl.action == SLA_LOAD ? 2 : 6, "Field '{}' of type 0x{:02x} not found, skipping", key, type); std::shared_ptr handler = nullptr; SaveLoadType slt; From a5add82600821d97e2013fa349fe3d81048db750 Mon Sep 17 00:00:00 2001 From: translators Date: Thu, 8 Jul 2021 18:51:52 +0000 Subject: [PATCH 34/42] Update: Translations from eints spanish (mexican): 54 changes by absay --- src/lang/spanish_MX.txt | 107 ++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index 76e548aca2..8de27f0b36 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -412,7 +412,7 @@ STR_FILE_MENU_EXIT :Salir # map menu STR_MAP_MENU_MAP_OF_WORLD :Minimapa completo STR_MAP_MENU_EXTRA_VIEWPORT :Ventana de vista adicional -STR_MAP_MENU_LINGRAPH_LEGEND :Leyenda de flujo de cargamento +STR_MAP_MENU_LINGRAPH_LEGEND :Leyenda de flujo de carga STR_MAP_MENU_SIGN_LIST :Lista de carteles ############ range for town menu starts @@ -427,10 +427,10 @@ STR_SUBSIDIES_MENU_SUBSIDIES :Subsidios ############ range for graph menu starts STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH :Gráfica de utilidades operativas STR_GRAPH_MENU_INCOME_GRAPH :Gráfica de ingresos -STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH :Gráfica de cargamento entregado +STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH :Gráfica de carga entregada STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH :Gráfica de desempeño STR_GRAPH_MENU_COMPANY_VALUE_GRAPH :Gráfica del valor de la empresa -STR_GRAPH_MENU_CARGO_PAYMENT_RATES :Tarifas de pagos por cargamento +STR_GRAPH_MENU_CARGO_PAYMENT_RATES :Tasas de pago por carga ############ range ends here ############ range for company league menu starts @@ -584,18 +584,18 @@ STR_GRAPH_Y_LABEL_NUMBER :{TINY_FONT}{COM STR_GRAPH_OPERATING_PROFIT_CAPTION :{WHITE}Gráfica de utilidad operativa STR_GRAPH_INCOME_CAPTION :{WHITE}Gráfica de ingresos -STR_GRAPH_CARGO_DELIVERED_CAPTION :{WHITE}Unidades de cargamento entregadas +STR_GRAPH_CARGO_DELIVERED_CAPTION :{WHITE}Unidades de carga entregadas STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION :{WHITE}Nivel de desempeño (nivel máximo: 1000) STR_GRAPH_COMPANY_VALUES_CAPTION :{WHITE}Valor de la empresa -STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Tarifas de pago por cargamento +STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Tasas de pago por carga STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL :{TINY_FONT}{BLACK}Días en tránsito -STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Pago por entregar 10 unidades (o 10,000 litros) de cargamento por distancia de 20 casillas +STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Pago por entregar 10 unidades (o 10,000 litros) de carga por distancia de 20 casillas STR_GRAPH_CARGO_ENABLE_ALL :{TINY_FONT}{BLACK}Activar todos STR_GRAPH_CARGO_DISABLE_ALL :{TINY_FONT}{BLACK}Desactivar todos -STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}Mostrar todos los tipos de carga en la gráfica de tarifas de pago por cargamento -STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Ocultar todos los tipos de carga en la gráfica de tarifas de pago por cargamento -STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Mostrar u ocultar gráfica de este tipo de cargamento +STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}Mostrar todos los tipos de carga en la gráfica de tasas de pago +STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Ocultar todos los tipos de carga en la gráfica de tasas de pago +STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Alternar gráfica de este tipo de carga STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLACK}{STRING} STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Mostrar detalles de nivel de desempeño @@ -631,7 +631,7 @@ STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Utilidad STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Ingreso mín.: STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Ingreso máx.: STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Entregado: -STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Cargamento: +STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Carga: STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Dinero: STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Préstamo: STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total: @@ -714,20 +714,20 @@ STR_SMALLMAP_CAPTION :{WHITE}Mapa: {S STR_SMALLMAP_TYPE_CONTOURS :Contornos STR_SMALLMAP_TYPE_VEHICLES :Vehículos STR_SMALLMAP_TYPE_INDUSTRIES :Industrias -STR_SMALLMAP_TYPE_ROUTEMAP :Flujo de cargamento +STR_SMALLMAP_TYPE_ROUTEMAP :Flujo de carga STR_SMALLMAP_TYPE_ROUTES :Rutas STR_SMALLMAP_TYPE_VEGETATION :Vegetación STR_SMALLMAP_TYPE_OWNERS :Propietarios STR_SMALLMAP_TOOLTIP_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Mostrar elevaciones en el mapa STR_SMALLMAP_TOOLTIP_SHOW_VEHICLES_ON_MAP :{BLACK}Mostrar vehículos en el mapa STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP :{BLACK}Mostrar industrias en el mapa -STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP :{BLACK}Mostrar flujo de cargamento en el mapa +STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP :{BLACK}Mostrar flujo de carga en el mapa STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Mostrar rutas de transporte en el mapa STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP :{BLACK}Mostrar vegetación en el mapa STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Mostrar dueños de terreno en el mapa STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Clic en un tipo de industria para mostrarlo u ocultarlo. Ctrl+Clic oculta todos los tipos excepto el elegido. Ctrl+Clic de nuevo en el mismo tipo muestra todos los tipos de industrias STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Clic en una empresa para mostrar u ocultar sus propiedades. Ctrl+Clic oculta todas las empresas excepto la elegida. Ctrl+Clic de nuevo en la misma empresa muestra todas las empresas -STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Clic en un cargamento para mostrar u ocultar sus propiedades. Ctrl+Clic oculta todos los cargamentos excepto el elegido. Ctrl+Clic de nuevo muestra todos los tipos de cargamento +STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Clic en una carga para mostrar u ocultar sus propiedades. Ctrl+Clic oculta todas las cargas excepto la elegida. Ctrl+Clic de nuevo muestra todos los tipos de carga STR_SMALLMAP_LEGENDA_ROADS :{TINY_FONT}{BLACK}Carreteras STR_SMALLMAP_LEGENDA_RAILROADS :{TINY_FONT}{BLACK}Ferrocarriles @@ -773,8 +773,8 @@ STR_SMALLMAP_TOOLTIP_ENABLE_ALL_INDUSTRIES :{BLACK}Mostrar STR_SMALLMAP_TOOLTIP_SHOW_HEIGHT :{BLACK}Mostrar u ocultar elevaciones en el mapa STR_SMALLMAP_TOOLTIP_DISABLE_ALL_COMPANIES :{BLACK}No mostrar propiedades de empresas en el mapa STR_SMALLMAP_TOOLTIP_ENABLE_ALL_COMPANIES :{BLACK}Mostrar todas las propiedades de empresas en el mapa -STR_SMALLMAP_TOOLTIP_DISABLE_ALL_CARGOS :{BLACK}No mostrar ningún cargamento en el mapa -STR_SMALLMAP_TOOLTIP_ENABLE_ALL_CARGOS :{BLACK}Muestra todos los cargamentos en el mapa +STR_SMALLMAP_TOOLTIP_DISABLE_ALL_CARGOS :{BLACK}Ocultar todas las cargas del mapa +STR_SMALLMAP_TOOLTIP_ENABLE_ALL_CARGOS :{BLACK}Mostrar todas las cargas en el mapa # Status bar messages STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS :{BLACK}Mostrar último mensaje o noticia @@ -1298,7 +1298,7 @@ STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT :Las empresas ap STR_CONFIG_SETTING_ALLOW_GIVE_MONEY :Permitir enviar dinero a otras empresas: {STRING} STR_CONFIG_SETTING_ALLOW_GIVE_MONEY_HELPTEXT :Permitir la transferencia de dinero entre empresas en modo multijugador STR_CONFIG_SETTING_FREIGHT_TRAINS :Multiplicador de peso para simular trenes pesados: {STRING} -STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :Establece el impacto de llevar cargamento en los trenes. Un valor mayor exige mayor potencia a los trenes para llevar una carga, sobre todo al subir colinas +STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :Impacto de llevar carga en los trenes. Un valor mayor exige mayor potencia a los trenes para llevar carga, sobre todo al subir colinas STR_CONFIG_SETTING_PLANE_SPEED :Factor de velocidad de aeronaves: {STRING} STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Establece la velocidad relativa de las aeronaves comparada con la de otros vehículos para reducir las utilidades de transportación aérea STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1/{COMMA} @@ -1588,8 +1588,8 @@ STR_CONFIG_SETTING_NEWS_ADVICE :Sugerencias e i STR_CONFIG_SETTING_NEWS_ADVICE_HELPTEXT :Mostrar mensajes sobre vehículos que requieran atención STR_CONFIG_SETTING_NEWS_NEW_VEHICLES :Nuevos vehículos: {STRING} STR_CONFIG_SETTING_NEWS_NEW_VEHICLES_HELPTEXT :Mostrar noticias sobre nuevos tipos de vehículos disponibles -STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE :Cambios en la recepción de cargamento: {STRING} -STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE_HELPTEXT :Mostrar mensajes sobre cambios a la recepción de cargamento en estaciones +STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE :Cambios en la aceptación de carga: {STRING} +STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE_HELPTEXT :Mostrar mensajes de cambios a la aceptación de carga en estaciones STR_CONFIG_SETTING_NEWS_SUBSIDIES :Subsidios: {STRING} STR_CONFIG_SETTING_NEWS_SUBSIDIES_HELPTEXT :Mostrar noticias sobre eventos relacionados con subsidios STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION :Información general: {STRING} @@ -1618,10 +1618,10 @@ STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Estabelcer la e STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Porcentaje de la utilidad total a pagar por transferencias de carga: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Porcentaje de utilidad cedida a los transportes intermedios en sistemas de transferencia de carga, dando un mayor control sobre la utilidad de cada vehículo STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Al arrastrar, colocar señales cada: {STRING} -STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT :Distancia de separación entre señales hasta topar con algún obstáculo (otra señal, un desvío, etc.) al instalarlas mediante arrastre con el ratón +STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT :Distancia de separación entre señales hasta topar con algún obstáculo (otra señal, un desvío, etc.) al colocarlas con arrastre STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE :{COMMA} casilla{P 0 "" s} STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE :Al arrastrar, mantener distancia fija entre señales: {STRING} -STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :Forma en que se instalan señales con Ctrl+Arrastrar. Al desactivarse, se colocan señales cerca de túneles y puentes para evitar tramos largos de vías sin señales. Al activarse, se colocan señales cada tanto de casillas, con lo que alinear señales en vías paralelas es más fácil +STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :Forma en que se colocan las señales con Ctrl+Arrastrar. Al desactivarse, se colocan señales cerca de túneles y puentes para evitar tramos largos sin señales. Al activarse, se colocan señales cada tanto de casillas, con lo que alinear señales en vías paralelas es más fácil STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Señales mecánicas por defecto antes de: {STRING} STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Año a partir del cual se usarán señales eléctricas. Antes de ese año se usarán señales mecánicas, las cuales funcionan igual pero tienen distinto aspecto STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI :Activar interfaz de señales: {STRING} @@ -1655,8 +1655,8 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Los jugadores p STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Prohibido STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Permitido STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Permitido, diseño urbano personalizado -STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Generación de cargamento en pueblios: {STRING} -STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Cantidad de cargamento producido por las casas con relación a la población.{}Crecimiento cuadrado: un pueblo de doble tamaño genera el cuádruple de pasajeros.{}Crecimiento lineal: un pueblo de doble tamaño genera el doble de pasajeros. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Generación de carga en pueblos: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Cantidad de carga producida por las casas con relación a la población.{}Crecimiento cuadrado: un pueblo de doble tamaño genera el cuádruple de pasajeros.{}Crecimiento lineal: un pueblo de doble tamaño genera el doble de pasajeros. STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Cuadrado STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Lineal @@ -1716,15 +1716,15 @@ STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :Manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :Asimétrica STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :Simétrica STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modo de distribución para pasajeros: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :En una distribución 'Simétrica', se envía la misma cantidad de pasajeros entre dos estaciones. En una distribución 'Asimétrica', se pueden enviar cantidades arbitrarias de pasajeros en ambas direcciones. 'Manual' significa que no hay distribución automática para los pasajeros +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :En una distribución "Simétrica" se envía la misma cantidad de pasajeros entre dos estaciones. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de pasajeros en ambas direcciones. "Manual" significa que no hay distribución automática para los pasajeros. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Modo de distribución para el correo: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :En una distribución 'Simétrica', se envía la misma cantidad de correo entre dos estaciones. En una distribución 'Asimétrica', se pueden enviar cantidades arbitrarias de correo en ambas direcciones. 'Manual' significa que no hay distribución automática para el correo +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :En una distribución "Simétrica" se envía la misma cantidad de correo entre dos estaciones. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de correo en ambas direcciones. "Manual" significa que no hay distribución automática para el correo STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Modo de distribución para cargamento de valores: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :El cargamento de valores contiene objetos de valor en el clima Templado, diamantes en el Subtropical y oro en el Subártico. Algún NewGRF puede modificar esto. En una distribución "Simétrica", se envía la misma cantidad de carga entre dos estaciones. En una distribución "Asimétrica", se envían cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no hay distribución automática para esta carga. Se recomienda la distribución "Asimétrica" o "Manual" al jugar en clima Subártico, ya que los bancos no regresan oro a las minas. En los climas Templado y Subtropical se puede escoger "Simétrica", ya que los bancos pueden regresar algunos objetos de valor a su banco de origen.The ARMOURED cargo class contains valuables in the temperate, diamonds in the subtropical or gold in subarctic climate. NewGRFs may change that. "symmetric" means that roughly the same amount of that cargo will be sent from a station A to a station B as from B to A. "asymmetric" means that arbitrary amounts of that cargo can be sent in either direction. "manual" means that no automatic distribution will take place for that cargo. It is recommended to set this to asymmetric or manual when playing subarctic, as banks won't send any gold back to gold mines. For temperate and subtropical you can also choose symmetric as banks will send valuables back to the origin bank of some load of valuables. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modo de distribución para otra carga: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimétrica" significa que se pueden enviar cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no habrá distribución automática para esta clase de carga. STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisión de la distribución: {STRING} -STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Si el valor es alto, se requerirá mayor tiempo para calcular la gráfica de distribución (si se lleva demasiado tiempo, se notará desfase en el juego). Si es muy bajo, la distribución será imprecisa, pudiendo hacer que el cargamento no vaya al lugar indicado +STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Si el valor es alto, se requerirá mayor tiempo para calcular la gráfica de distribución (si se lleva demasiado tiempo, se notará desfase en el juego). Si es muy bajo, la distribución será imprecisa, pudiendo hacer que la carga no vaya al lugar indicado STR_CONFIG_SETTING_DEMAND_DISTANCE :Efecto de la distancia en la demanda: {STRING} STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Con un valor mayor de 0, la distancia entre una estación de origen A y una estación de destino B afectará la cantidad de carga que se envíe desde A a B, enviando menos carga cuanto más lejos est. Cuanto mayor sea el valor de esta opción, menos carga se enviará a estaciones distantes en favor de estaciones cercanas. STR_CONFIG_SETTING_DEMAND_SIZE :Cantidad de carga en retorno en modo simétrico: {STRING} @@ -2153,6 +2153,7 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nueva empresa) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Crear nueva empresa y unirse a ella STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Este eres tú STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Este es el host del juego +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s}/{NUM} empresa{P "" s} STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Expulsar STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Bloquear acceso @@ -2372,7 +2373,7 @@ STR_TRANSPARENT_LOADING_TOOLTIP :{BLACK}Transpar STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Ocultar objetos totalmente # Linkgraph legend window -STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Leyenda de flujo de cargamento +STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Leyenda de flujo de carga STR_LINKGRAPH_LEGEND_ALL :{BLACK}Todas STR_LINKGRAPH_LEGEND_NONE :{BLACK}Ninguna STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Elegir las empresas a mostrar @@ -2667,18 +2668,18 @@ STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_QUERY :{YELLOW}¿Segur # Industry cargoes window STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION :{WHITE}Cadena industrial para la industria de {STRING} -STR_INDUSTRY_CARGOES_CARGO_CAPTION :{WHITE}Cadena industrial para el cargamento de {STRING} +STR_INDUSTRY_CARGOES_CARGO_CAPTION :{WHITE}Cadena industrial para carga de {STRING} STR_INDUSTRY_CARGOES_PRODUCERS :{WHITE}Industrias proveedoras STR_INDUSTRY_CARGOES_CUSTOMERS :{WHITE}Industrias receptoras STR_INDUSTRY_CARGOES_HOUSES :{WHITE}Casas STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP :{BLACK}Clic en la industria para ver sus industrias proveedoras y receptoras -STR_INDUSTRY_CARGOES_CARGO_TOOLTIP :{BLACK}{STRING}{}Clic en el cargamento para ver sus industrias proveedoras y receptoras +STR_INDUSTRY_CARGOES_CARGO_TOOLTIP :{BLACK}{STRING}{}Clic en la carga para ver sus proveedores y clientes STR_INDUSTRY_DISPLAY_CHAIN :{BLACK}Mostrar cadena -STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP :{BLACK}Mostrar las industrias que proveen y aceptan el cargamento +STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP :{BLACK}Mostrar las industrias que proveen y aceptan la carga STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP :{BLACK}Ver en minimapa STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP :{BLACK}Elegir y ver en el minimapa las industrias mostradas en el mapa principal -STR_INDUSTRY_CARGOES_SELECT_CARGO :{BLACK}Elegir cargamento -STR_INDUSTRY_CARGOES_SELECT_CARGO_TOOLTIP :{BLACK}Elegir el tipo de cargamento a mostrar +STR_INDUSTRY_CARGOES_SELECT_CARGO :{BLACK}Elegir carga +STR_INDUSTRY_CARGOES_SELECT_CARGO_TOOLTIP :{BLACK}Elegir el tipo de carga STR_INDUSTRY_CARGOES_SELECT_INDUSTRY :{BLACK}Elegir industria STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP :{BLACK}Elegir la industria a mostrar @@ -2703,7 +2704,7 @@ STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Tipo de STR_LAND_AREA_INFORMATION_AIRPORT_NAME :{BLACK}Nombre del aeropuerto: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Nombre de casilla del aeropuerto: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Cargamento aceptado: {LTBLUE} +STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Carga aceptada: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Tipo de vía: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Tipo de carretera: {LTBLUE}{STRING} @@ -2835,7 +2836,7 @@ STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COM STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! STR_FRAMERATE_GAMELOOP :{BLACK}Bucles de juego totales: -STR_FRAMERATE_GL_ECONOMY :{BLACK} Manejo de cargamento: +STR_FRAMERATE_GL_ECONOMY :{BLACK} Manejo de carga: STR_FRAMERATE_GL_TRAINS :{BLACK} Ticks de trenes: STR_FRAMERATE_GL_ROADVEHS :{BLACK} Ticks de vehículos de carretera: STR_FRAMERATE_GL_SHIPS :{BLACK} Ticks de barcos: @@ -2852,7 +2853,7 @@ STR_FRAMERATE_AI :{BLACK} IA {NUM ############ End of leave-in-this-order ############ Leave those lines in this order!! STR_FRAMETIME_CAPTION_GAMELOOP :Bucle de juego -STR_FRAMETIME_CAPTION_GL_ECONOMY :Manejo de cargamento +STR_FRAMETIME_CAPTION_GL_ECONOMY :Manejo de carga STR_FRAMETIME_CAPTION_GL_TRAINS :Ticks de trenes STR_FRAMETIME_CAPTION_GL_ROADVEHS :Ticks de vehículos de carretera STR_FRAMETIME_CAPTION_GL_SHIPS :Ticks de barcos @@ -3136,15 +3137,15 @@ STR_NEWGRF_BROKEN_CAPACITY :{WHITE}Cambió STR_BROKEN_VEHICLE_LENGTH :{WHITE}Tren {VEHICLE} de {COMPANY} tiene una longitud no válida. Quizá es por problemas de los NewGRF, y puede provocar que el juego falle STR_NEWGRF_BUGGY :{WHITE}El NewGRF '{0:STRING}' da información incorrecta -STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}La información de cargamento o reequipamiento para '{1:ENGINE}' difiere de la lista de compra después de la construcción. Esto puede causar que la renovación y el reemplazo automático no haga el reequipamiento correcta +STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}La información de carga o reequipamiento para '{1:ENGINE}' difiere de la lista de compra después de la construcción. Esto puede causar que la renovación y el reemplazo automático no haga el reequipamiento correcto STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' ha causado un bucle sin fin en la llamada de producción STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}La llamada {1:HEX} devolvió un resultado desconocido o no válido {2:HEX} -STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' retornó un tipo inválido de cargamento en la llamada de producción en {2:HEX} +STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' retornó un tipo inválido de carga en la callback de producción en {2:HEX} # 'User removed essential NewGRFs'-placeholders for stuff without specs -STR_NEWGRF_INVALID_CARGO : +STR_NEWGRF_INVALID_CARGO : STR_NEWGRF_INVALID_CARGO_ABBREV :?? -STR_NEWGRF_INVALID_CARGO_QUANTITY :{COMMA} de +STR_NEWGRF_INVALID_CARGO_QUANTITY :{COMMA} de STR_NEWGRF_INVALID_ENGINE : STR_NEWGRF_INVALID_INDUSTRYTYPE : @@ -3488,7 +3489,7 @@ STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUST STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} y {NUM} más... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nombres de industrias. Clic para centrar la vista en la industria. Ctrl+Clic abre una vista aparte -STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Cargamento aceptado: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Carga aceptada: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Cargemento producido: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Todos los tipos STR_INDUSTRY_DIRECTORY_FILTER_NONE :Ninguno @@ -3960,27 +3961,27 @@ STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}Capacida # Vehicle refit STR_REFIT_CAPTION :{WHITE}{VEHICLE} (reformar) -STR_REFIT_TITLE :{GOLD}Elegir el nuevo tipo de cargamento: +STR_REFIT_TITLE :{GOLD}Elegir el nuevo tipo de carga: STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nueva capacidad: {GOLD}{CARGO_LONG}{}{BLACK}Costo por reformar: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Nueva capacidad: {GOLD}{CARGO_LONG}{}{BLACK}Ingreso al reformar: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Nueva capacidad: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Costo por reformar: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Nueva capacidad: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Ingreso al reformar: {GREEN}{CURRENCY_LONG} STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Elegir los vehículos de ferrocarril a reformar. Arrastrar con el ratón para elegir más de un vehículo. Clic en un espacio vacío para elegir el tren completo. Ctrl+Clic para elegir una unidad del tren y los vagones subsecuentes -STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Elegir el tipo de cargamento para el tren -STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Elegir el tipo de cargamento para el vehículo de carretera -STR_REFIT_SHIP_LIST_TOOLTIP :{BLACK}Elegir el tipo de cargamento para el barco -STR_REFIT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Elegir el tipo de cargamento para la aeronave +STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Elegir el tipo de carga para el tren +STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Elegir el tipo de carga para el vehículo de carretera +STR_REFIT_SHIP_LIST_TOOLTIP :{BLACK}Elegir el tipo de carga para el barco +STR_REFIT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Elegir el tipo de carga para la aeronave STR_REFIT_TRAIN_REFIT_BUTTON :{BLACK}Reformar tren STR_REFIT_ROAD_VEHICLE_REFIT_BUTTON :{BLACK}Reformar vehículo de carretera STR_REFIT_SHIP_REFIT_BUTTON :{BLACK}Reformar barco STR_REFIT_AIRCRAFT_REFIT_BUTTON :{BLACK}Reformar aeronave -STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}Reformar el tren para transportar el cargamento elegido -STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Reformar el vehículo de carretera para transportar el cargamento elegido -STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}Reformar el barco para transportar el cargamento elegido -STR_REFIT_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Reformar la aeronave para transportar el cargamento elegido +STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}Reformar el tren para transportar la carga elegida +STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Reformar el vehículo de carretera para transportar la carga elegida +STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}Reformar el barco para transportar la carga elegida +STR_REFIT_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Reformar la aeronave para transportar la carga elegida # Order view STR_ORDERS_CAPTION :{WHITE}{VEHICLE} (Órdenes) @@ -4017,11 +4018,11 @@ STR_ORDER_DROP_NO_UNLOADING :No descargar STR_ORDER_TOOLTIP_UNLOAD :{BLACK}Cambiar la forma de descarga en la orden resaltada STR_ORDER_REFIT :{BLACK}Reformar -STR_ORDER_REFIT_TOOLTIP :{BLACK}Elegir el tipo de cargamento a reformar en esta orden. Ctrl+Clic para eliminar la orden +STR_ORDER_REFIT_TOOLTIP :{BLACK}Elegir el tipo de carga a reformar en esta orden. Ctrl+Clic para eliminar la orden STR_ORDER_REFIT_AUTO :{BLACK}Reformar en estación -STR_ORDER_REFIT_AUTO_TOOLTIP :{BLACK}Elegir el tipo de cargamento a reformar en esta orden. Ctrl+Clic para eliminar la orden. Reformar solo es posible si el vehículo lo permite -STR_ORDER_DROP_REFIT_AUTO :Cargamento fijo -STR_ORDER_DROP_REFIT_AUTO_ANY :Cargamento disponible +STR_ORDER_REFIT_AUTO_TOOLTIP :{BLACK}Elegir la carga para reequipar en esta orden. Ctrl+Clic para eliminar la orden. Reequipar solo es posible si el vehículo lo permite +STR_ORDER_DROP_REFIT_AUTO :Carga fija +STR_ORDER_DROP_REFIT_AUTO_ANY :Carga disponible STR_ORDER_SERVICE :{BLACK}Mantenimiento STR_ORDER_DROP_GO_ALWAYS_DEPOT :Ir siempre @@ -4125,7 +4126,7 @@ STR_ORDER_NO_UNLOAD_REFIT :(No descargar y STR_ORDER_NO_UNLOAD_FULL_LOAD_REFIT :(No descargar y llenar todo con reforma a {STRING}) STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY_REFIT :(No descargar y llenar cualquiera con reforma a {STRING}) -STR_ORDER_AUTO_REFIT_ANY :cargamento disponible +STR_ORDER_AUTO_REFIT_ANY :carga disponible STR_ORDER_STOP_LOCATION_NEAR_END :[principio] STR_ORDER_STOP_LOCATION_MIDDLE :[centro] From d9ca9ca55571829af88429147e20bf0734e07e2d Mon Sep 17 00:00:00 2001 From: translators Date: Fri, 9 Jul 2021 18:53:08 +0000 Subject: [PATCH 35/42] Update: Translations from eints spanish (mexican): 44 changes by absay italian: 2 changes by CoderLel --- src/lang/italian.txt | 2 + src/lang/spanish_MX.txt | 88 ++++++++++++++++++++--------------------- 2 files changed, 46 insertions(+), 44 deletions(-) diff --git a/src/lang/italian.txt b/src/lang/italian.txt index 6f32a248e1..5c1dd682d7 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -2063,6 +2063,7 @@ STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}Il nome STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Imposta password STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Protegge la partita con una password in modo che non sia accessibile pubblicamente +STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}Visibilità STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} client STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Limite client: STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}Imposta il numero massimo di client. Non tutti i posti dovranno essere occupati @@ -2131,6 +2132,7 @@ STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Elenco dei clie # Network client list +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Sei sicuro di voler eliminare la compagnia '{COMPANY}'? STR_NETWORK_SERVER :Server STR_NETWORK_CLIENT :Client diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index 8de27f0b36..a490db27b3 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -299,10 +299,10 @@ STR_SORT_BY_LENGTH :Longitud STR_SORT_BY_LIFE_TIME :Vida útil restante STR_SORT_BY_TIMETABLE_DELAY :Retraso en itinerario STR_SORT_BY_FACILITY :Tipo de estación -STR_SORT_BY_WAITING_TOTAL :Cargamento total en espera -STR_SORT_BY_WAITING_AVAILABLE :Cargamento disponible en espera +STR_SORT_BY_WAITING_TOTAL :Carga total en espera +STR_SORT_BY_WAITING_AVAILABLE :Carga disponible en espera STR_SORT_BY_RATING_MAX :Valoración más alta de cargamento -STR_SORT_BY_RATING_MIN :Valoración más baja de cargamento +STR_SORT_BY_RATING_MIN :Menor índice de carga STR_SORT_BY_ENGINE_ID :Id. locomotora (orden clásico) STR_SORT_BY_COST :Costo STR_SORT_BY_POWER :Potencia @@ -344,8 +344,8 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Mostrar STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Mostrar lista de vehículos de carretera de la empresa. Ctrl+Clic oculta la lista de grupos STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Mostrar lista de barcos de la empresa. Ctrl+Clic oculta la lista de grupos STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Mostrar lista de aeronaves de la empresa. Ctrl+Clic oculta la lista de grupos -STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Acercar vista -STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Alejar vista +STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Acercar +STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Alejar STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Construir vías férreas STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Construir carreteras STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Construir tranvías @@ -602,7 +602,7 @@ STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Mostrar # Graph key window STR_GRAPH_KEY_CAPTION :{WHITE}Leyenda de gráfica -STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP :{BLACK}Mostrar u ocultar la entrada de la empresa en la gráfica +STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP :{BLACK}Mostrar u ocultar esta empresa en la gráfica # Company league window STR_COMPANY_LEAGUE_TABLE_CAPTION :{WHITE}Tabla de evaluación de empresas @@ -766,7 +766,7 @@ STR_SMALLMAP_LINKSTATS :{TINY_FONT}{STR STR_SMALLMAP_COMPANY :{TINY_FONT}{COMPANY} STR_SMALLMAP_TOWN :{TINY_FONT}{WHITE}{TOWN} STR_SMALLMAP_DISABLE_ALL :{BLACK}Ocultar todo -STR_SMALLMAP_ENABLE_ALL :{BLACK}Ver todo +STR_SMALLMAP_ENABLE_ALL :{BLACK}Mostrar todo STR_SMALLMAP_SHOW_HEIGHT :{BLACK}Mostrar elevación STR_SMALLMAP_TOOLTIP_DISABLE_ALL_INDUSTRIES :{BLACK}No mostrar industrias en el mapa STR_SMALLMAP_TOOLTIP_ENABLE_ALL_INDUSTRIES :{BLACK}Mostrar todas las industrias en el mapa @@ -1019,7 +1019,7 @@ STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Doble STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Cuádruple -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Tamaño de letra +STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Tamaño de tipografía STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Elegir qué tamaño de letra usar en la interfaz STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(detectar) @@ -1230,8 +1230,8 @@ STR_CONFIG_SETTING_CATCHMENT :Permitir cambia STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Las áreas de recolección se adecúan a diferentes tamaños, según los tipos de estaciones y aeropuertos STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Las estaciones privadas pueden dar servicio a industrias con estaciones neutrales: {STRING} STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Al activarse, las industrias con estaciones integradas (ej. plataformas petrolíferas) podrán aceptar carga de estaciones aledañas. Al desactivarse, tales industrias solo recibirán carga en sus propias estaciones y no aceptarán de otras estaciones, ni la estación integrada brindará servicio a nada más que su industria -STR_CONFIG_SETTING_EXTRADYNAMITE :Permitir quitar mayor cantidad de carreteras, puentes y túneles de los pueblos: {STRING} -STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Hacer más fácil eliminar infraestructura y edificios que sean propiedad de los pueblos +STR_CONFIG_SETTING_EXTRADYNAMITE :Permitir mayor eliminación de carreteras, puentes y túneles: {STRING} +STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Hacer más fácil eliminar infraestructura y edificios que sean propiedad de las localidades STR_CONFIG_SETTING_TRAIN_LENGTH :Longitud máxima de trenes: {STRING} STR_CONFIG_SETTING_TRAIN_LENGTH_HELPTEXT :Longitud máxima permitida para los trenes STR_CONFIG_SETTING_TILE_LENGTH :{COMMA} casilla{P 0 "" s} @@ -1265,8 +1265,8 @@ STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NORMAL :Como las demás STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_PROSPECTING :Prospección STR_CONFIG_SETTING_INDUSTRY_PLATFORM :Área plana alrededor de industrias: {STRING} STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :Cantidad de espacio plano alrededor de las industrias. Esto asegura que haya espacio libre alrededor de las industrias para construir vías férreas, etc. -STR_CONFIG_SETTING_MULTIPINDTOWN :Permitir múltiples industrias similares por pueblo: {STRING} -STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :Generalmente, no se permite más de una industria del mismo tipo por pueblo. Con esta opción se permiten múltiples industrias del mismo tipo en el mismo pueblo +STR_CONFIG_SETTING_MULTIPINDTOWN :Permitir varias industrias similares por localidad: {STRING} +STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :En general, una localidad admite un solo tipo de industria a la vez, pero con esta opción varias industrias del mismo tipo en una localidad son posibles STR_CONFIG_SETTING_SIGNALSIDE :Mostrar señales: {STRING} STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :De qué lado de las vías se instalarán las señales STR_CONFIG_SETTING_SIGNALSIDE_LEFT :A la izquierda @@ -1288,9 +1288,9 @@ STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN :Vista principal STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT :Vista principal STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT :Todas las vistas STR_CONFIG_SETTING_BRIBE :Permitir sobornos al ayuntamiento: {STRING} -STR_CONFIG_SETTING_BRIBE_HELPTEXT :Las empresas pueden intentar sobornar a los ayuntamientos, pero si un inspector lo descubre la empresa no podrá realizar actividades en el pueblo seis meses +STR_CONFIG_SETTING_BRIBE_HELPTEXT :Las empresas intentan sobornar a los ayuntamientos. Si un inspector lo descubre, la empresa no podrá operar en la localidad seis meses STR_CONFIG_SETTING_ALLOW_EXCLUSIVE :Permitir adquirir los derechos de transporte exclusivos: {STRING} -STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Si una empresa adquiere los derechos de transporte exclusivos en un pueblo, las estaciones de la competencia, de pasajeros o carga, no recibirán nada todo un año +STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Si una empresa compra los derechos de transporte exclusivos en una localidad, las estaciones de la competencia no recibirán carga nada todo un año STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS :Permitir la construcción de nuevos edificios: {STRING} STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT :Las empresas aportan dinero a los ayuntamientos para que construyan nuevas casas y edificios STR_CONFIG_SETTING_ALLOW_FUND_ROAD :Permitir el pago de la reconstrucción de las carreteras locales: {STRING} @@ -1347,15 +1347,15 @@ STR_CONFIG_SETTING_HOVER_DELAY :Mostrar informa STR_CONFIG_SETTING_HOVER_DELAY_HELPTEXT :Tiempo de retraso para mostrar información de ayuda al posar el ratón en un elemento de la interfaz. Si el valor es 0 los mensajes se muestran con el botón derecho del ratón. STR_CONFIG_SETTING_HOVER_DELAY_VALUE :Posar el ratón {COMMA} milisegundo{P 0 "" s} STR_CONFIG_SETTING_HOVER_DELAY_DISABLED :Botón derecho -STR_CONFIG_SETTING_POPULATION_IN_LABEL :Mostrar población de pueblos: {STRING} -STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Mostrar en el mapa la población de los pueblos junto a sus nombres +STR_CONFIG_SETTING_POPULATION_IN_LABEL :Mostrar población de localidades: {STRING} +STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Mostrar en el mapa la población de las localidades junto a sus nombres STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Grosor de las líneas en las gráficas: {STRING} STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Grosor de las líneas en las gráficas. Una línea fina es más precisa, una línea más gruesa es más fácil de distinguir STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Mostrar el nombre del GRF en la ventana de construcción de vehículo: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Indicar por medio de una línea adicional en la ventana de construcción de vehículo su NewGRF. STR_CONFIG_SETTING_LANDSCAPE :Terreno: {STRING} -STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Los terrenos definen mapas con diferentes tipos de carga y requisitos de crecimiento para los pueblos. Es posible modificarlos empleando NewGRF y scripts de juego +STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Los terrenos definen mapas con diferentes tipos de carga y requisitos de crecimiento de las localidades, los cuales pueden cambiarse con NewGRF y scripts de juego STR_CONFIG_SETTING_LAND_GENERATOR :Generador de terreno: {STRING} STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT :El generador 'Original' depende de los gráficos base y crea formas de terreno fijas. 'TerraGenesis' es un generador basado en Ruido Perlin que permite un mayor control de configuración STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL :Original @@ -1369,7 +1369,7 @@ STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Distancia lími STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Nivel de inicio de nieve: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Controlar la altura donde la nieve empieza en mapas de clima Subártico, lo cual afectará la generación de industrias y los requisitos de crecimiento de pueblos. Este valor se puede cambiar en el Editor de mapas o se calculará según la "Extensión de nieve" STR_CONFIG_SETTING_SNOW_COVERAGE :Extensión de nieve: {STRING} -STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :Controlar la cantidad aproximada de nieve al generar un mapa de clima Subártico, lo cual afectará la generación de industrias y los requisitos de crecimiento de pueblos. La superficie casi al ras del nivel del mar nunca tiene nieve. +STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :Controlar la cantidad aproximada de nieve al generar un mapa de geografía de Subártico, la cual afectará la generación de industrias y los requisitos de crecimiento de las localidades. La superficie casi al ras del nivel del mar nunca tiene nieve STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE :{NUM}% STR_CONFIG_SETTING_DESERT_COVERAGE :Extensión de desierto: {STRING} STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT :Controlar la cantidad aproximada de desierto al generar un mapa de clima tropical, lo cual afectará la generación de industrias también. @@ -1509,7 +1509,7 @@ STR_CONFIG_SETTING_SOUND_DISASTER_HELPTEXT :Reproducir efec STR_CONFIG_SETTING_SOUND_VEHICLE :Vehículos: {STRING} STR_CONFIG_SETTING_SOUND_VEHICLE_HELPTEXT :Reproducir efectos de sonido de vehículos STR_CONFIG_SETTING_SOUND_AMBIENT :Ambiente: {STRING} -STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT :Reproducir sonidos ambientales de terreno, industrias y pueblos +STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT :Reproducir sonidos ambientales de terreno, industrias y localidades STR_CONFIG_SETTING_DISABLE_UNSUITABLE_BUILDING :Deshabilitar construcción de infraestructura cuando no haya vehículos apropiados disponibles: {STRING} STR_CONFIG_SETTING_DISABLE_UNSUITABLE_BUILDING_HELPTEXT :Al activarse, hay infraestructura disponible solo si hay vehículos adecuados, evitando gastos de tiempo y dinero en infraestructura inservible @@ -1525,7 +1525,7 @@ STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :Número máximo STR_CONFIG_SETTING_AI_BUILDS_TRAINS :Desactivar trenes para la computadora: {STRING} STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Activar esta opción para deshabilitar la construcción de trenes por jugadores no humanos STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Desactivar vehículos de carretera para la computadora: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Activar esta opción para deshabilitar la construcción de vehículos de carretera por jugadores no humanos +STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Activar esta opción deshabilita la construcción de vehículos de carretera por jugadores no humanos STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Desactivar aeroplanos para la computadora: {STRING} STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Activar esta opción deshabilita la construcción de aeronaves por jugadores no humanos STR_CONFIG_SETTING_AI_BUILDS_SHIPS :Desactivar barcos para la computadora: {STRING} @@ -1644,12 +1644,12 @@ STR_CONFIG_SETTING_TOWN_LAYOUT_BETTER_ROADS :Mejorado STR_CONFIG_SETTING_TOWN_LAYOUT_2X2_GRID :Rejilla de 2×2 STR_CONFIG_SETTING_TOWN_LAYOUT_3X3_GRID :Rejilla de 3×3 STR_CONFIG_SETTING_TOWN_LAYOUT_RANDOM :Aleatorio -STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :Permitir que los pueblos construyan carreteras: {STRING} -STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Los pueblos podrán construir carreteras para expandirse. Al desactivarse, los ayuntamientos no podrán construir carreteras -STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Permitir a los pueblos construir pasos a nivel: {STRING} -STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Los pueblos podrán construir pasos a nivel -STR_CONFIG_SETTING_NOISE_LEVEL :Permitir a los pueblos controlar el nivel de ruido de los aeropuertos: {STRING} -STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Al desactivarse, puede haber solo dos aeropuertos por pueblo. Al activarse, el número de aeropuertos por pueblo depende de su nivel de ruido permitido, que a su vez depende de la población, el tamaño de los aeropuertos y la distancia +STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :Permitir a las localidades construir carreteras: {STRING} +STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Los ayuntamientos construyen carreteras para que las localidades se expandan. Desactivar para impedirlo +STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Permitir a las localidades construir pasos a nivel: {STRING} +STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Activar esta opción permite a las localidades construir pasos a nivel +STR_CONFIG_SETTING_NOISE_LEVEL :Permitir el ruido de aeropuertos controlado por localidades: {STRING} +STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Al desactivarse, puede haber hasta dos aeropuertos por localidad. Al activarse, el número de aeropuertos por localidad depende de su nivel de ruido permitido, el cual depende de la población, el tamaño de cada aeropuerto y la distancia STR_CONFIG_SETTING_TOWN_FOUNDING :Fundar pueblos: {STRING} STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Los jugadores podrán crear nuevos pueblos durante la partida STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Prohibido @@ -1701,12 +1701,12 @@ STR_CONFIG_SETTING_TOWN_GROWTH_SLOW :Lenta STR_CONFIG_SETTING_TOWN_GROWTH_NORMAL :Normal STR_CONFIG_SETTING_TOWN_GROWTH_FAST :Rápida STR_CONFIG_SETTING_TOWN_GROWTH_VERY_FAST :Muy rápida -STR_CONFIG_SETTING_LARGER_TOWNS :Proporción de pueblos que se convertirán en ciudades: {STRING} -STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :Número de pueblos que se convertirán en ciudades. Las ciudades comienzan siendo más grandes y crecen más rápido +STR_CONFIG_SETTING_LARGER_TOWNS :Proporción de localidades que se convertirán en ciudades: {STRING} +STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :Número de localidades que se convertirán en ciudades, las cuales comienzan siendo más grandes y crecen más rápido STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 de cada {COMMA} STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Ninguno STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicador inicial de tamaño de ciudad: {STRING} -STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Tamaño medio de las ciudades en relación a los pueblos al comienzo de la partida +STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Tamaño medio de las ciudades relativo a las localidades al inicio del juego STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Actualizar la gráfica de distribución cada {STRING}{NBSP}día{P 0:2 "" s} STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Periodo de tiempo entre cálculos consecutivos de la gráfica de distribución. Esta opción se refiere a los cálculos para cada uno de los componentes de la gráfica, por lo cual establecer un valor no quiere decir que la gráfica completa se actualizará tras ese número de días, solo algún componente lo hará. Cuanto menor sea, mayor tiempo de CPU será necesario para calcular la gráfica distribución. Cuanto mayor sea, más tardará la gráfica en adaptarse a nuevas rutas @@ -1720,7 +1720,7 @@ STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :En una distribu STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Modo de distribución para el correo: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :En una distribución "Simétrica" se envía la misma cantidad de correo entre dos estaciones. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de correo en ambas direcciones. "Manual" significa que no hay distribución automática para el correo STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Modo de distribución para cargamento de valores: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :El cargamento de valores contiene objetos de valor en el clima Templado, diamantes en el Subtropical y oro en el Subártico. Algún NewGRF puede modificar esto. En una distribución "Simétrica", se envía la misma cantidad de carga entre dos estaciones. En una distribución "Asimétrica", se envían cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no hay distribución automática para esta carga. Se recomienda la distribución "Asimétrica" o "Manual" al jugar en clima Subártico, ya que los bancos no regresan oro a las minas. En los climas Templado y Subtropical se puede escoger "Simétrica", ya que los bancos pueden regresar algunos objetos de valor a su banco de origen.The ARMOURED cargo class contains valuables in the temperate, diamonds in the subtropical or gold in subarctic climate. NewGRFs may change that. "symmetric" means that roughly the same amount of that cargo will be sent from a station A to a station B as from B to A. "asymmetric" means that arbitrary amounts of that cargo can be sent in either direction. "manual" means that no automatic distribution will take place for that cargo. It is recommended to set this to asymmetric or manual when playing subarctic, as banks won't send any gold back to gold mines. For temperate and subtropical you can also choose symmetric as banks will send valuables back to the origin bank of some load of valuables. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :El cargamento de valores contiene objetos de valor en el clima Templado, diamantes en el Subtropical y oro en el Subártico. Algún NewGRF puede modificar esto. En una distribución "Simétrica", se envía la misma cantidad de carga entre dos estaciones. En una distribución "Asimétrica", se envían cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no hay distribución automática para esta carga. Se recomienda la distribución "Asimétrica" o "Manual" al jugar en clima Subártico, ya que los bancos no regresan oro a las minas. En los climas Templado y Subtropical se puede escoger "Simétrica", ya que los bancos pueden regresar algunos objetos de valor a su banco de origen. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modo de distribución para otra carga: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimétrica" significa que se pueden enviar cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no habrá distribución automática para esta clase de carga. STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisión de la distribución: {STRING} @@ -1730,7 +1730,7 @@ STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Con un valor ma STR_CONFIG_SETTING_DEMAND_SIZE :Cantidad de carga en retorno en modo simétrico: {STRING} STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Con un valor menor de 100% la distribución simétrica de carga será más asimétrica, lo cual obligará a enviar menos carga en retorno en función de la enviada a una estación. Si es 0%, la distribución simétrica igual que la asimétrica. STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Nivel de saturación de rutas cortas antes de cambiar a rutas de mayor capacidad: {STRING} -STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Entre dos estaciones usualmente hay más de una ruta posible. Se intentarán saturar las rutas más cortas primero, luego las que les siguen, y así sucesivamente. La saturación está determinada por una estimación de capacidad y uso planificado. Una vez que se hayan saturado todas las rutas, si todavía hay demanda se sobrecargarán los caminos empezando por aquellos de mayor capacidad. El algoritmo no siempre estimará la capacidad de forma precisa. Esta opción permite especificar el porcentaje de saturación que debe tener una ruta en el primer análisis antes de pasar a la siguiente ruta. Ponerlo a menos de 100% permite evitar estaciones sobrecargadas en el caso de que se sobreestimen las capacidades +STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Entre dos estaciones a veces hay varias rutas. Se intentará saturar la ruta más corta primero, luego la que le sigue, y así sucesivamente. La saturación está determinada por una estimación de capacidad y uso planeado. Al saturarse todas las rutas, si aún hay demanda se sobrecargarán todas, empezando por las de mayor capacidad. El algoritmo no siempre estimará la capacidad de forma precisa. Esta opción permite especificar el porcentaje de saturación que debe tener una ruta más corta en la primera vuelta antes de pasar a la siguiente. Menos de 100% evita estaciones abarrotadas si las capacidades se sobreestiman. STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Unidades de velocidad: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :Cada vez que se muestre una velocidad en la interfaz de usuario, se emplearán las unidades elegidas @@ -1787,7 +1787,7 @@ STR_CONFIG_SETTING_ACCIDENTS :{ORANGE}Desastr STR_CONFIG_SETTING_GENWORLD :{ORANGE}Generación de mapa STR_CONFIG_SETTING_ENVIRONMENT :{ORANGE}Ambiente STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES :{ORANGE}Autoridades -STR_CONFIG_SETTING_ENVIRONMENT_TOWNS :{ORANGE}Pueblos +STR_CONFIG_SETTING_ENVIRONMENT_TOWNS :{ORANGE}Localidades STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Industrias STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distribución de carga STR_CONFIG_SETTING_AI :{ORANGE}Competidores @@ -2674,7 +2674,7 @@ STR_INDUSTRY_CARGOES_CUSTOMERS :{WHITE}Industri STR_INDUSTRY_CARGOES_HOUSES :{WHITE}Casas STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP :{BLACK}Clic en la industria para ver sus industrias proveedoras y receptoras STR_INDUSTRY_CARGOES_CARGO_TOOLTIP :{BLACK}{STRING}{}Clic en la carga para ver sus proveedores y clientes -STR_INDUSTRY_DISPLAY_CHAIN :{BLACK}Mostrar cadena +STR_INDUSTRY_DISPLAY_CHAIN :{BLACK}Mostrar cadena industrial STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP :{BLACK}Mostrar las industrias que proveen y aceptan la carga STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP :{BLACK}Ver en minimapa STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP :{BLACK}Elegir y ver en el minimapa las industrias mostradas en el mapa principal @@ -3184,7 +3184,7 @@ STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (ciudad) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Habitantes: {ORANGE}{COMMA}{BLACK} Casas: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} último mes: {ORANGE}{COMMA}{BLACK} máx.: {ORANGE}{COMMA} -STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Cargamento necesario para crecimiento: +STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Carga necesaria para crecimiento: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} requeridos STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} requerido en invierno STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED_GENERAL :{ORANGE}{STRING}{GREEN} entregado @@ -3306,8 +3306,8 @@ STR_STATION_LIST_STATION :{YELLOW}{STATIO STR_STATION_LIST_WAYPOINT :{YELLOW}{WAYPOINT} STR_STATION_LIST_NONE :{YELLOW}- Ninguna - STR_STATION_LIST_SELECT_ALL_FACILITIES :{BLACK}Elegir todos los tipos de estación -STR_STATION_LIST_SELECT_ALL_TYPES :{BLACK}Elegir todos los tipos de cargamento (incluidos los que no estén en espera) -STR_STATION_LIST_NO_WAITING_CARGO :{BLACK}Ningún tipo de cargamento está esperando +STR_STATION_LIST_SELECT_ALL_TYPES :{BLACK}Elegir todos los tipos de carga (también los que no están en espera) +STR_STATION_LIST_NO_WAITING_CARGO :{BLACK}No hay ninguna carga esperando # Station view window STR_STATION_VIEW_CAPTION :{WHITE}{STATION} {STATION_FEATURES} @@ -3316,7 +3316,7 @@ STR_STATION_VIEW_EN_ROUTE_FROM :{YELLOW}({CARGO STR_STATION_VIEW_RESERVED :{YELLOW}({CARGO_SHORT} reservado para cargar) STR_STATION_VIEW_ACCEPTS_BUTTON :{BLACK}Acepta -STR_STATION_VIEW_ACCEPTS_TOOLTIP :{BLACK}Lista de cargamento aceptado +STR_STATION_VIEW_ACCEPTS_TOOLTIP :{BLACK}Lista de carga aceptada STR_STATION_VIEW_ACCEPTS_CARGO :{BLACK}Acepta: {WHITE}{CARGO_LIST} STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF :{BLACK}Esta estación tiene los derechos exclusivos de transporte en este pueblo. @@ -3842,10 +3842,10 @@ STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}Esto com STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}Forzar al tren a proceder sin esperar a que la señal le ceda vía libre -STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Reformar tren para transportar otro tipo de cargamento -STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Reformar vehículo de carretera para transportar otro tipo de cargamento -STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}Reformar barco para que transporte otro tipo de cargamento -STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Reformar aeronave para llevar otro tipo de cargamento +STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Reformar tren para llevar otro tipo de carga +STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Reformar vehículo de carretera para llevar otro tipo de carga +STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}Reformar barco para llevar otro tipo de carga +STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Reformar aeronave para llevar otro tipo de carga STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}Cambiar dirección del tren STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}Forzar al vehículo a girar en sentido opuesto @@ -3948,14 +3948,14 @@ STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Vacío STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} desde {STATION} STR_VEHICLE_DETAILS_CARGO_FROM_MULT :{LTBLUE}{CARGO_LONG} desde {STATION} (×{NUM}) -STR_VEHICLE_DETAIL_TAB_CARGO :{BLACK}Cargamento +STR_VEHICLE_DETAIL_TAB_CARGO :{BLACK}Carga STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP :{BLACK}Mostrar detalles de mercancía transportada STR_VEHICLE_DETAIL_TAB_INFORMATION :{BLACK}Información STR_VEHICLE_DETAILS_TRAIN_INFORMATION_TOOLTIP :{BLACK}Mostrar detalles de los vehículos STR_VEHICLE_DETAIL_TAB_CAPACITIES :{BLACK}Capacidades STR_VEHICLE_DETAILS_TRAIN_CAPACITIES_TOOLTIP :{BLACK}Mostrar capacidades de cada vehículo del tren -STR_VEHICLE_DETAIL_TAB_TOTAL_CARGO :{BLACK}Cargamento total -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP :{BLACK}Mostrar capacidad total del tren dividida por tipo de cargamento +STR_VEHICLE_DETAIL_TAB_TOTAL_CARGO :{BLACK}Carga total +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP :{BLACK}Mostrar capacidad total del tren dividida por carga STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}Capacidad: {LTBLUE} From 8f5d0ecde39cbaf2ac1a6d27e82239bfc3bf1515 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Fri, 9 Jul 2021 21:16:03 +0200 Subject: [PATCH 36/42] Codechange: split settings.ini over several files (#9421) This reduced the load on compilers, as currently for example MacOS doesn't like the huge settings-tables. Additionally, nobody can find settings, as the list is massive and unordered. By splitting it, it becomes a little bit more sensible. --- src/saveload/linkgraph_sl.cpp | 4 +- src/saveload/settings_sl.cpp | 37 +- src/settings.cpp | 24 +- src/settings_internal.h | 4 +- src/settings_table.cpp | 21 +- src/settings_table.h | 23 +- src/table/settings/CMakeLists.txt | 14 +- src/table/settings/currency_settings.ini | 1 - src/table/settings/difficulty_settings.ini | 286 ++ src/table/settings/economy_settings.ini | 294 ++ src/table/settings/game_settings.ini | 421 ++ src/table/settings/gui_settings.ini | 858 ++++ src/table/settings/linkgraph_settings.ini | 168 + src/table/settings/locale_settings.ini | 177 + src/table/settings/multimedia_settings.ini | 148 + src/table/settings/news_display_settings.ini | 201 + ..._settings.ini => old_gameopt_settings.ini} | 17 +- src/table/settings/pathfinding_settings.ini | 617 +++ src/table/settings/script_settings.ini | 112 + src/table/settings/settings.ini | 3487 ----------------- src/table/settings/world_settings.ini | 545 +++ 21 files changed, 3925 insertions(+), 3534 deletions(-) create mode 100644 src/table/settings/difficulty_settings.ini create mode 100644 src/table/settings/economy_settings.ini create mode 100644 src/table/settings/game_settings.ini create mode 100644 src/table/settings/gui_settings.ini create mode 100644 src/table/settings/linkgraph_settings.ini create mode 100644 src/table/settings/locale_settings.ini create mode 100644 src/table/settings/multimedia_settings.ini create mode 100644 src/table/settings/news_display_settings.ini rename src/table/settings/{gameopt_settings.ini => old_gameopt_settings.ini} (77%) create mode 100644 src/table/settings/pathfinding_settings.ini create mode 100644 src/table/settings/script_settings.ini delete mode 100644 src/table/settings/settings.ini create mode 100644 src/table/settings/world_settings.ini diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index e1094326bf..ae21de4c7b 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -17,6 +17,7 @@ #include "../linkgraph/linkgraphschedule.h" #include "../network/network.h" #include "../settings_internal.h" +#include "../settings_table.h" #include "../safeguards.h" @@ -165,7 +166,6 @@ public: SaveLoadTable GetLinkGraphJobDesc() { static std::vector saveloads; - static const char *prefix = "linkgraph."; static const SaveLoad job_desc[] = { SLE_VAR(LinkGraphJob, join_date, SLE_INT32), @@ -184,7 +184,7 @@ SaveLoadTable GetLinkGraphJobDesc() /* Build the SaveLoad array on first call and don't touch it later on */ if (saveloads.size() == 0) { - GetSettingSaveLoadByPrefix(prefix, saveloads); + GetSaveLoadFromSettingTable(_linkgraph_settings, saveloads); for (auto &sl : saveloads) { sl.address_proc = proc; diff --git a/src/saveload/settings_sl.cpp b/src/saveload/settings_sl.cpp index 59b00e0f09..f19ff910c1 100644 --- a/src/saveload/settings_sl.cpp +++ b/src/saveload/settings_sl.cpp @@ -151,7 +151,7 @@ struct OPTSChunkHandler : ChunkHandler { * a networking environment. This ensures for example that the local * autosave-frequency stays when joining a network-server */ PrepareOldDiffCustom(); - LoadSettings(_gameopt_settings, &_settings_game, _gameopt_sl_compat); + LoadSettings(_old_gameopt_settings, &_settings_game, _gameopt_sl_compat); HandleOldDiffCustom(true); } }; @@ -159,22 +159,51 @@ struct OPTSChunkHandler : ChunkHandler { struct PATSChunkHandler : ChunkHandler { PATSChunkHandler() : ChunkHandler('PATS', CH_TABLE) {} + /** + * Create a single table with all settings that should be stored/loaded + * in the savegame. + */ + SettingTable GetSettingTable() const + { + static const SettingTable saveload_settings_tables[] = { + _difficulty_settings, + _economy_settings, + _game_settings, + _linkgraph_settings, + _locale_settings, + _pathfinding_settings, + _script_settings, + _world_settings, + }; + static std::vector settings_table; + + if (settings_table.empty()) { + for (auto &saveload_settings_table : saveload_settings_tables) { + for (auto &saveload_setting : saveload_settings_table) { + settings_table.push_back(saveload_setting); + } + } + } + + return settings_table; + } + void Load() const override { /* Copy over default setting since some might not get loaded in * a networking environment. This ensures for example that the local * currency setting stays when joining a network-server */ - LoadSettings(_settings, &_settings_game, _settings_sl_compat); + LoadSettings(this->GetSettingTable(), &_settings_game, _settings_sl_compat); } void LoadCheck(size_t) const override { - LoadSettings(_settings, &_load_check_data.settings, _settings_sl_compat); + LoadSettings(this->GetSettingTable(), &_load_check_data.settings, _settings_sl_compat); } void Save() const override { - SaveSettings(_settings, &_settings_game); + SaveSettings(this->GetSettingTable(), &_settings_game); } }; diff --git a/src/settings.cpp b/src/settings.cpp index e3741c2356..09223c585e 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -72,8 +72,18 @@ static ErrorList _settings_error_list; ///< Errors while loading minimal setting static auto &GenericSettingTables() { static const SettingTable _generic_setting_tables[] = { - _settings, + _difficulty_settings, + _economy_settings, + _game_settings, + _gui_settings, + _linkgraph_settings, + _locale_settings, + _multimedia_settings, _network_settings, + _news_display_settings, + _pathfinding_settings, + _script_settings, + _world_settings, }; return _generic_setting_tables; } @@ -1207,7 +1217,7 @@ void LoadFromConfig(bool startup) GameLoadConfig(generic_ini, "game_scripts"); PrepareOldDiffCustom(); - IniLoadSettings(generic_ini, _gameopt_settings, "gameopt", &_settings_newgame, false); + IniLoadSettings(generic_ini, _old_gameopt_settings, "gameopt", &_settings_newgame, false); HandleOldDiffCustom(false); ValidateSettings(); @@ -1393,16 +1403,16 @@ static const SettingDesc *GetSettingFromName(const std::string_view name, const } /** - * Get the SaveLoad from all settings matching the prefix. - * @param prefix The prefix to look for. + * Get the SaveLoad for all settings in the settings table. + * @param settings The settings table to get the SaveLoad objects from. * @param saveloads A vector to store the result in. */ -void GetSettingSaveLoadByPrefix(std::string_view prefix, std::vector &saveloads) +void GetSaveLoadFromSettingTable(SettingTable settings, std::vector &saveloads) { - for (auto &desc : _settings) { + for (auto &desc : settings) { const SettingDesc *sd = GetSettingDesc(desc); if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; - if (StrStartsWith(sd->name, prefix)) saveloads.push_back(sd->save); + saveloads.push_back(sd->save); } } diff --git a/src/settings_internal.h b/src/settings_internal.h index 304f1393aa..a9083ce402 100644 --- a/src/settings_internal.h +++ b/src/settings_internal.h @@ -312,8 +312,10 @@ static constexpr const SettingDesc *GetSettingDesc(const SettingVariant &desc) return std::visit([](auto&& arg) -> const SettingDesc * { return &arg; }, desc); } +typedef span SettingTable; + const SettingDesc *GetSettingFromName(const std::string_view name); -void GetSettingSaveLoadByPrefix(const std::string_view prefix, std::vector &saveloads); +void GetSaveLoadFromSettingTable(SettingTable settings, std::vector &saveloads); bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame = false); bool SetSettingValue(const StringSettingDesc *sd, const std::string value, bool force_newgame = false); diff --git a/src/settings_table.cpp b/src/settings_table.cpp index bc1e588cd6..045d8e56c4 100644 --- a/src/settings_table.cpp +++ b/src/settings_table.cpp @@ -49,16 +49,25 @@ #include "safeguards.h" -SettingTable _settings{ _settings_table }; -SettingTable _network_settings{ _network_settings_table }; -SettingTable _network_private_settings{ _network_private_settings_table }; -SettingTable _network_secrets_settings{ _network_secrets_settings_table }; - SettingTable _company_settings{ _company_settings_table }; SettingTable _currency_settings{ _currency_settings_table }; -SettingTable _gameopt_settings{ _gameopt_settings_table }; +SettingTable _difficulty_settings{ _difficulty_settings_table }; +SettingTable _multimedia_settings{ _multimedia_settings_table }; +SettingTable _economy_settings{ _economy_settings_table }; +SettingTable _game_settings{ _game_settings_table }; +SettingTable _gui_settings{ _gui_settings_table }; +SettingTable _linkgraph_settings{ _linkgraph_settings_table }; +SettingTable _locale_settings{ _locale_settings_table }; SettingTable _misc_settings{ _misc_settings_table }; +SettingTable _network_private_settings{ _network_private_settings_table }; +SettingTable _network_secrets_settings{ _network_secrets_settings_table }; +SettingTable _network_settings{ _network_settings_table }; +SettingTable _news_display_settings{ _news_display_settings_table }; +SettingTable _old_gameopt_settings{ _old_gameopt_settings_table }; +SettingTable _pathfinding_settings{ _pathfinding_settings_table }; +SettingTable _script_settings{ _script_settings_table }; SettingTable _window_settings{ _window_settings_table }; +SettingTable _world_settings{ _world_settings_table }; #if defined(_WIN32) && !defined(DEDICATED) SettingTable _win32_settings{ _win32_settings_table }; #endif /* _WIN32 */ diff --git a/src/settings_table.h b/src/settings_table.h index ace0ec7a2f..d662b6a576 100644 --- a/src/settings_table.h +++ b/src/settings_table.h @@ -15,18 +15,25 @@ #include #include "settings_internal.h" -typedef span SettingTable; - -extern SettingTable _settings; -extern SettingTable _network_settings; -extern SettingTable _network_private_settings; -extern SettingTable _network_secrets_settings; - extern SettingTable _company_settings; extern SettingTable _currency_settings; -extern SettingTable _gameopt_settings; +extern SettingTable _difficulty_settings; +extern SettingTable _economy_settings; +extern SettingTable _game_settings; +extern SettingTable _gui_settings; +extern SettingTable _linkgraph_settings; +extern SettingTable _locale_settings; extern SettingTable _misc_settings; +extern SettingTable _multimedia_settings; +extern SettingTable _network_private_settings; +extern SettingTable _network_secrets_settings; +extern SettingTable _network_settings; +extern SettingTable _news_display_settings; +extern SettingTable _old_gameopt_settings; +extern SettingTable _pathfinding_settings; +extern SettingTable _script_settings; extern SettingTable _window_settings; +extern SettingTable _world_settings; #if defined(_WIN32) && !defined(DEDICATED) extern SettingTable _win32_settings; #endif /* _WIN32 */ diff --git a/src/table/settings/CMakeLists.txt b/src/table/settings/CMakeLists.txt index f4d3c209ed..f00c72051a 100644 --- a/src/table/settings/CMakeLists.txt +++ b/src/table/settings/CMakeLists.txt @@ -4,14 +4,24 @@ set(TABLE_BINARY_DIR ${GENERATED_BINARY_DIR}/table) set(TABLE_INI_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/company_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/currency_settings.ini - ${CMAKE_CURRENT_SOURCE_DIR}/gameopt_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/difficulty_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/economy_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/game_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/gui_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/linkgraph_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/locale_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/misc_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/multimedia_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/network_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/network_private_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/network_secrets_settings.ini - ${CMAKE_CURRENT_SOURCE_DIR}/settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/news_display_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/old_gameopt_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/pathfinding_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/script_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/win32_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/window_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/world_settings.ini ) if (HOST_BINARY_DIR) diff --git a/src/table/settings/currency_settings.ini b/src/table/settings/currency_settings.ini index 03c6425b21..4a0e733387 100644 --- a/src/table/settings/currency_settings.ini +++ b/src/table/settings/currency_settings.ini @@ -33,7 +33,6 @@ extra = 0 startup = false - [SDT_VAR] var = rate type = SLE_UINT16 diff --git a/src/table/settings/difficulty_settings.ini b/src/table/settings/difficulty_settings.ini new file mode 100644 index 0000000000..18d2ea7bbb --- /dev/null +++ b/src/table/settings/difficulty_settings.ini @@ -0,0 +1,286 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; Difficulty settings as stored in the main configuration file ("openttd.cfg") +; and in the savegame PATS chunk. + +[pre-amble] +const std::array _old_diff_settings{"max_no_competitors", "competitor_start_time", "number_towns", "industry_density", "max_loan", "initial_interest", "vehicle_costs", "competitor_speed", "competitor_intelligence", "vehicle_breakdowns", "subsidy_multiplier", "construction_cost", "terrain_type", "quantity_sea_lakes", "economy", "line_reverse_mode", "disasters", "town_council_tolerance"}; + +uint16 _old_diff_custom[GAME_DIFFICULTY_NUM]; +uint8 _old_diff_level; ///< Old difficulty level from old savegames + +static void DifficultyNoiseChange(int32 new_value); +static void MaxNoAIsChange(int32 new_value); + +static const SettingVariant _difficulty_settings_table[] = { +[post-amble] +}; +[templates] +SDTG_VAR = SDTG_VAR($name, $type, $flags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDT_BOOL = SDT_BOOL(GameSettings, $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDTG_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); +SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +; Saved settings variables. +; The next 18 entries are important for savegame compatibility. Do NOT remove those. See HandleOldDiffCustom() for more details. +[SDT_VAR] +var = difficulty.max_no_competitors +type = SLE_UINT8 +from = SLV_97 +def = 0 +min = 0 +max = MAX_COMPANIES - 1 +interval = 1 +post_cb = MaxNoAIsChange +cat = SC_BASIC + +[SDT_VAR] +var = difficulty.competitor_start_time +type = SLE_UINT8 +from = SLV_97 +to = SLV_110 +def = 2 +min = 0 +max = 3 + +[SDT_VAR] +var = difficulty.number_towns +type = SLE_UINT8 +from = SLV_97 +flags = SF_NEWGAME_ONLY +def = 2 +min = 0 +max = 4 +interval = 1 +strval = STR_NUM_VERY_LOW +cat = SC_BASIC + +[SDT_VAR] +var = difficulty.industry_density +type = SLE_UINT8 +from = SLV_97 +flags = SF_GUI_DROPDOWN +def = ID_END - 1 +min = 0 +max = ID_END - 1 +interval = 1 +str = STR_CONFIG_SETTING_INDUSTRY_DENSITY +strhelp = STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT +strval = STR_FUNDING_ONLY +cat = SC_BASIC + +[SDT_VAR] +var = difficulty.max_loan +type = SLE_UINT32 +from = SLV_97 +flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO | SF_GUI_CURRENCY +def = 300000 +min = 0 +max = 2000000000 +interval = 50000 +str = STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN +strhelp = STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT +strval = STR_JUST_CURRENCY_LONG +cat = SC_BASIC + +[SDT_VAR] +var = difficulty.initial_interest +type = SLE_UINT8 +from = SLV_97 +flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO +def = 2 +min = 2 +max = 4 +interval = 1 +str = STR_CONFIG_SETTING_INTEREST_RATE +strhelp = STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT +strval = STR_CONFIG_SETTING_PERCENTAGE + +[SDT_VAR] +var = difficulty.vehicle_costs +type = SLE_UINT8 +from = SLV_97 +flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO | SF_GUI_DROPDOWN +def = 0 +min = 0 +max = 2 +interval = 1 +str = STR_CONFIG_SETTING_RUNNING_COSTS +strhelp = STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT +strval = STR_SEA_LEVEL_LOW +cat = SC_BASIC + +[SDT_VAR] +var = difficulty.competitor_speed +type = SLE_UINT8 +from = SLV_97 +flags = SF_GUI_DROPDOWN +def = 2 +min = 0 +max = 4 +interval = 1 +str = STR_CONFIG_SETTING_CONSTRUCTION_SPEED +strhelp = STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT +strval = STR_AI_SPEED_VERY_SLOW +cat = SC_BASIC + +[SDT_VAR] +var = difficulty.competitor_intelligence +type = SLE_UINT8 +from = SLV_97 +to = SLV_110 +def = 0 +min = 0 +max = 2 + +[SDT_VAR] +var = difficulty.vehicle_breakdowns +type = SLE_UINT8 +from = SLV_97 +flags = SF_GUI_DROPDOWN +def = 1 +min = 0 +max = 2 +interval = 1 +str = STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS +strhelp = STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT +strval = STR_DISASTER_NONE +cat = SC_BASIC + +[SDT_VAR] +var = difficulty.subsidy_multiplier +type = SLE_UINT8 +from = SLV_97 +flags = SF_GUI_DROPDOWN +def = 2 +min = 0 +max = 3 +interval = 1 +str = STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER +strhelp = STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT +strval = STR_SUBSIDY_X1_5 + +[SDT_VAR] +var = difficulty.subsidy_duration +type = SLE_UINT16 +from = SLV_CUSTOM_SUBSIDY_DURATION +flags = SF_GUI_0_IS_SPECIAL +def = 1 +min = 0 +max = 5000 +interval = 1 +str = STR_CONFIG_SETTING_SUBSIDY_DURATION +strhelp = STR_CONFIG_SETTING_SUBSIDY_DURATION_HELPTEXT +strval = STR_CONFIG_SETTING_SUBSIDY_DURATION_VALUE + +[SDT_VAR] +var = difficulty.construction_cost +type = SLE_UINT8 +from = SLV_97 +flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO | SF_GUI_DROPDOWN +def = 0 +min = 0 +max = 2 +interval = 1 +str = STR_CONFIG_SETTING_CONSTRUCTION_COSTS +strhelp = STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT +strval = STR_SEA_LEVEL_LOW +cat = SC_BASIC + +[SDT_VAR] +var = difficulty.terrain_type +type = SLE_UINT8 +from = SLV_97 +flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY +def = 1 +min = 0 +max = 5 +interval = 1 +str = STR_CONFIG_SETTING_TERRAIN_TYPE +strhelp = STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT +strval = STR_TERRAIN_TYPE_VERY_FLAT +cat = SC_BASIC + +[SDT_VAR] +var = difficulty.quantity_sea_lakes +type = SLE_UINT8 +from = SLV_97 +flags = SF_NEWGAME_ONLY +def = 0 +min = 0 +max = 4 +interval = 1 +strval = STR_SEA_LEVEL_VERY_LOW +cat = SC_BASIC + +[SDT_BOOL] +var = difficulty.economy +from = SLV_97 +def = false +str = STR_CONFIG_SETTING_RECESSIONS +strhelp = STR_CONFIG_SETTING_RECESSIONS_HELPTEXT + +[SDT_BOOL] +var = difficulty.line_reverse_mode +from = SLV_97 +def = false +str = STR_CONFIG_SETTING_TRAIN_REVERSING +strhelp = STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT + +[SDT_BOOL] +var = difficulty.disasters +from = SLV_97 +def = false +str = STR_CONFIG_SETTING_DISASTERS +strhelp = STR_CONFIG_SETTING_DISASTERS_HELPTEXT +cat = SC_BASIC + +[SDT_VAR] +var = difficulty.town_council_tolerance +type = SLE_UINT8 +from = SLV_97 +flags = SF_GUI_DROPDOWN +def = 0 +min = 0 +max = 2 +interval = 1 +str = STR_CONFIG_SETTING_CITY_APPROVAL +strhelp = STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT +strval = STR_CITY_APPROVAL_PERMISSIVE +post_cb = DifficultyNoiseChange + +[SDTG_VAR] +name = ""diff_level"" +var = _old_diff_level +type = SLE_UINT8 +flags = SF_NOT_IN_CONFIG +from = SLV_97 +to = SLV_178 +def = 3 +min = 0 +max = 3 +cat = SC_BASIC + diff --git a/src/table/settings/economy_settings.ini b/src/table/settings/economy_settings.ini new file mode 100644 index 0000000000..9ffd9edb70 --- /dev/null +++ b/src/table/settings/economy_settings.ini @@ -0,0 +1,294 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; Economy settings as stored in the main configuration file ("openttd.cfg") +; and in the savegame PATS chunk. + +[pre-amble] +static void TownFoundingChanged(int32 new_value); + +static const SettingVariant _economy_settings_table[] = { +[post-amble] +}; +[templates] +SDT_BOOL = SDT_BOOL(GameSettings, $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +[SDT_VAR] +var = economy.town_layout +type = SLE_UINT8 +from = SLV_59 +flags = SF_GUI_DROPDOWN +def = TL_ORIGINAL +min = TL_BEGIN +max = NUM_TLS - 1 +interval = 1 +str = STR_CONFIG_SETTING_TOWN_LAYOUT +strhelp = STR_CONFIG_SETTING_TOWN_LAYOUT_HELPTEXT +strval = STR_CONFIG_SETTING_TOWN_LAYOUT_DEFAULT +post_cb = TownFoundingChanged + +[SDT_BOOL] +var = economy.allow_town_roads +from = SLV_113 +flags = SF_NO_NETWORK +def = true +str = STR_CONFIG_SETTING_ALLOW_TOWN_ROADS +strhelp = STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT + +[SDT_VAR] +var = economy.found_town +type = SLE_UINT8 +from = SLV_128 +flags = SF_GUI_DROPDOWN +def = TF_FORBIDDEN +min = TF_BEGIN +max = TF_END - 1 +interval = 1 +str = STR_CONFIG_SETTING_TOWN_FOUNDING +strhelp = STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT +strval = STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN +post_cb = TownFoundingChanged +cat = SC_BASIC + +[SDT_BOOL] +var = economy.allow_town_level_crossings +from = SLV_143 +flags = SF_NO_NETWORK +def = true +str = STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS +strhelp = STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT + +[SDT_VAR] +var = economy.town_cargogen_mode +type = SLE_UINT8 +from = SLV_TOWN_CARGOGEN +flags = SF_GUI_DROPDOWN +def = TCGM_BITCOUNT +min = TCGM_BEGIN +max = TCGM_END - 1 +interval = 1 +str = STR_CONFIG_SETTING_TOWN_CARGOGENMODE +strhelp = STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT +strval = STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL +cat = SC_ADVANCED + +[SDT_BOOL] +var = economy.station_noise_level +from = SLV_96 +flags = SF_NO_NETWORK +def = false +str = STR_CONFIG_SETTING_NOISE_LEVEL +strhelp = STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT +post_cb = [](auto new_value) { InvalidateWindowClassesData(WC_TOWN_VIEW, new_value); } + +[SDT_BOOL] +var = economy.inflation +flags = SF_NO_NETWORK +def = false +str = STR_CONFIG_SETTING_INFLATION +strhelp = STR_CONFIG_SETTING_INFLATION_HELPTEXT +cat = SC_BASIC + +[SDT_BOOL] +var = economy.multiple_industry_per_town +def = false +str = STR_CONFIG_SETTING_MULTIPINDTOWN +strhelp = STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT + +[SDT_BOOL] +var = economy.bribe +def = true +str = STR_CONFIG_SETTING_BRIBE +strhelp = STR_CONFIG_SETTING_BRIBE_HELPTEXT +post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } +cat = SC_BASIC + +[SDT_BOOL] +var = economy.exclusive_rights +from = SLV_79 +def = true +str = STR_CONFIG_SETTING_ALLOW_EXCLUSIVE +strhelp = STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT +post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } +cat = SC_BASIC + +[SDT_BOOL] +var = economy.fund_buildings +from = SLV_165 +def = true +str = STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS +strhelp = STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT +post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } +cat = SC_BASIC + +[SDT_BOOL] +var = economy.fund_roads +from = SLV_160 +def = true +str = STR_CONFIG_SETTING_ALLOW_FUND_ROAD +strhelp = STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT +post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } +cat = SC_BASIC + +[SDT_BOOL] +var = economy.give_money +from = SLV_79 +def = true +str = STR_CONFIG_SETTING_ALLOW_GIVE_MONEY +strhelp = STR_CONFIG_SETTING_ALLOW_GIVE_MONEY_HELPTEXT +cat = SC_BASIC + +[SDT_VAR] +var = economy.type +type = SLE_UINT8 +flags = SF_GUI_DROPDOWN +def = ET_SMOOTH +min = ET_BEGIN +max = ET_END - 1 +str = STR_CONFIG_SETTING_ECONOMY_TYPE +strhelp = STR_CONFIG_SETTING_ECONOMY_TYPE_HELPTEXT +strval = STR_CONFIG_SETTING_ECONOMY_TYPE_ORIGINAL +post_cb = [](auto) { InvalidateWindowClassesData(WC_INDUSTRY_VIEW); } +cat = SC_BASIC + +[SDT_BOOL] +var = economy.allow_shares +def = false +str = STR_CONFIG_SETTING_ALLOW_SHARES +strhelp = STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT +post_cb = [](auto) { InvalidateWindowClassesData(WC_COMPANY); } + +[SDT_VAR] +var = economy.min_years_for_shares +type = SLE_UINT8 +from = SLV_TRADING_AGE +def = 6 +min = 0 +max = 255 +interval = 1 +str = STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES +strhelp = STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT +strval = STR_JUST_INT +cat = SC_EXPERT + +[SDT_VAR] +var = economy.feeder_payment_share +type = SLE_UINT8 +from = SLV_134 +def = 75 +min = 0 +max = 100 +str = STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE +strhelp = STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT +strval = STR_CONFIG_SETTING_PERCENTAGE +cat = SC_EXPERT + +[SDT_VAR] +var = economy.town_growth_rate +type = SLE_UINT8 +from = SLV_54 +flags = SF_GUI_DROPDOWN +def = 2 +min = 0 +max = 4 +str = STR_CONFIG_SETTING_TOWN_GROWTH +strhelp = STR_CONFIG_SETTING_TOWN_GROWTH_HELPTEXT +strval = STR_CONFIG_SETTING_TOWN_GROWTH_NONE + +[SDT_VAR] +var = economy.larger_towns +type = SLE_UINT8 +from = SLV_54 +flags = SF_GUI_0_IS_SPECIAL +def = 4 +min = 0 +max = 255 +interval = 1 +str = STR_CONFIG_SETTING_LARGER_TOWNS +strhelp = STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT +strval = STR_CONFIG_SETTING_LARGER_TOWNS_VALUE + +[SDT_VAR] +var = economy.initial_city_size +type = SLE_UINT8 +from = SLV_56 +def = 2 +min = 1 +max = 10 +interval = 1 +str = STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER +strhelp = STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT +strval = STR_JUST_COMMA + +[SDT_BOOL] +var = economy.mod_road_rebuild +from = SLV_77 +def = true +cat = SC_EXPERT + +[SDT_VAR] +var = economy.dist_local_authority +type = SLE_UINT8 +def = 20 +min = 5 +max = 60 +cat = SC_EXPERT + +[SDT_VAR] +var = economy.town_noise_population[0] +type = SLE_UINT16 +from = SLV_96 +def = 800 +min = 200 +max = 65535 +cat = SC_EXPERT + +[SDT_VAR] +var = economy.town_noise_population[1] +type = SLE_UINT16 +from = SLV_96 +def = 2000 +min = 400 +max = 65535 +cat = SC_EXPERT + +[SDT_VAR] +var = economy.town_noise_population[2] +type = SLE_UINT16 +from = SLV_96 +def = 4000 +min = 800 +max = 65535 +cat = SC_EXPERT + +[SDT_BOOL] +var = economy.infrastructure_maintenance +from = SLV_166 +def = false +str = STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE +strhelp = STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT +post_cb = [](auto) { InvalidateWindowClassesData(WC_COMPANY_INFRASTRUCTURE); } +cat = SC_BASIC diff --git a/src/table/settings/game_settings.ini b/src/table/settings/game_settings.ini new file mode 100644 index 0000000000..2a51279e5b --- /dev/null +++ b/src/table/settings/game_settings.ini @@ -0,0 +1,421 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; Game settings as stored in the main configuration file ("openttd.cfg") +; and in the savegame PATS chunk. +; Game settings are everything related to vehicles, stations, orders, etc. + +[pre-amble] +static std::initializer_list _roadsides{"left", "right"}; + +static void StationSpreadChanged(int32 new_value); +static void UpdateConsists(int32 new_value); +static void TrainAccelerationModelChanged(int32 new_value); +static void RoadVehAccelerationModelChanged(int32 new_value); +static void TrainSlopeSteepnessChanged(int32 new_value); +static void RoadVehSlopeSteepnessChanged(int32 new_value); +static bool CheckRoadSide(int32 &new_value); +static bool CheckDynamicEngines(int32 &new_value); +static void StationCatchmentChanged(int32 new_value); +static void MaxVehiclesChanged(int32 new_value); + +static const SettingVariant _game_settings_table[] = { +[post-amble] +}; +[templates] +SDTG_BOOL = SDTG_BOOL($name, $flags, $var, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTG_VAR = SDTG_VAR($name, $type, $flags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDT_BOOL = SDT_BOOL(GameSettings, $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDT_OMANY = SDT_OMANY(GameSettings, $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $load, $cat, $extra, $startup), +SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDTG_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); +SDT_OMANY = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); +SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +[SDT_BOOL] +var = order.no_servicing_if_no_breakdowns +def = true +str = STR_CONFIG_SETTING_NOSERVICE +strhelp = STR_CONFIG_SETTING_NOSERVICE_HELPTEXT + +[SDT_BOOL] +var = order.improved_load +flags = SF_NO_NETWORK +def = true +cat = SC_EXPERT + +[SDT_BOOL] +var = order.selectgoods +def = true +cat = SC_EXPERT + +[SDT_BOOL] +var = order.serviceathelipad +def = true +str = STR_CONFIG_SETTING_SERVICEATHELIPAD +strhelp = STR_CONFIG_SETTING_SERVICEATHELIPAD_HELPTEXT +cat = SC_EXPERT + +[SDT_BOOL] +var = order.gradual_loading +from = SLV_40 +flags = SF_NO_NETWORK +def = true +cat = SC_EXPERT + +[SDT_BOOL] +var = station.never_expire_airports +flags = SF_NO_NETWORK +def = false +str = STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS +strhelp = STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT + +[SDT_VAR] +var = station.station_spread +type = SLE_UINT8 +def = 12 +min = 4 +max = 64 +str = STR_CONFIG_SETTING_STATION_SPREAD +strhelp = STR_CONFIG_SETTING_STATION_SPREAD_HELPTEXT +strval = STR_CONFIG_SETTING_TILE_LENGTH +post_cb = StationSpreadChanged +cat = SC_BASIC + +[SDT_BOOL] +var = station.modified_catchment +def = true +str = STR_CONFIG_SETTING_CATCHMENT +strhelp = STR_CONFIG_SETTING_CATCHMENT_HELPTEXT +post_cb = StationCatchmentChanged +cat = SC_EXPERT + +[SDT_BOOL] +var = station.serve_neutral_industries +def = true +from = SLV_SERVE_NEUTRAL_INDUSTRIES +str = STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES +strhelp = STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT +post_cb = StationCatchmentChanged + +[SDT_BOOL] +var = station.adjacent_stations +from = SLV_62 +def = true +cat = SC_EXPERT + +[SDT_BOOL] +var = station.distant_join_stations +from = SLV_106 +def = true +str = STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS +strhelp = STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT +post_cb = [](auto) { CloseWindowById(WC_SELECT_STATION, 0); } + +[SDT_OMANY] +var = vehicle.road_side +type = SLE_UINT8 +from = SLV_97 +flags = SF_GUI_DROPDOWN | SF_NO_NETWORK +def = 1 +max = 1 +full = _roadsides +str = STR_CONFIG_SETTING_ROAD_SIDE +strhelp = STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT +strval = STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT +pre_cb = CheckRoadSide +cat = SC_BASIC + +[SDT_VAR] +var = vehicle.train_acceleration_model +type = SLE_UINT8 +flags = SF_GUI_DROPDOWN +def = 1 +min = 0 +max = 1 +interval = 1 +str = STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL +strhelp = STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL_HELPTEXT +strval = STR_CONFIG_SETTING_ORIGINAL +post_cb = TrainAccelerationModelChanged + +[SDT_VAR] +var = vehicle.roadveh_acceleration_model +type = SLE_UINT8 +from = SLV_139 +flags = SF_GUI_DROPDOWN +def = 1 +min = 0 +max = 1 +interval = 1 +str = STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL +strhelp = STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL_HELPTEXT +strval = STR_CONFIG_SETTING_ORIGINAL +post_cb = RoadVehAccelerationModelChanged + +[SDT_VAR] +var = vehicle.train_slope_steepness +type = SLE_UINT8 +from = SLV_133 +def = 3 +min = 0 +max = 10 +interval = 1 +str = STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS +strhelp = STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT +strval = STR_CONFIG_SETTING_PERCENTAGE +post_cb = TrainSlopeSteepnessChanged +cat = SC_EXPERT + +[SDT_VAR] +var = vehicle.roadveh_slope_steepness +type = SLE_UINT8 +from = SLV_139 +def = 7 +min = 0 +max = 10 +interval = 1 +str = STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS +strhelp = STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT +strval = STR_CONFIG_SETTING_PERCENTAGE +post_cb = RoadVehSlopeSteepnessChanged +cat = SC_EXPERT + +[SDT_VAR] +var = vehicle.max_train_length +type = SLE_UINT8 +from = SLV_159 +def = 7 +min = 1 +max = 64 +interval = 1 +str = STR_CONFIG_SETTING_TRAIN_LENGTH +strhelp = STR_CONFIG_SETTING_TRAIN_LENGTH_HELPTEXT +strval = STR_CONFIG_SETTING_TILE_LENGTH +cat = SC_BASIC + +[SDT_VAR] +var = vehicle.smoke_amount +type = SLE_UINT8 +from = SLV_145 +flags = SF_GUI_DROPDOWN +def = 1 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_SMOKE_AMOUNT +strhelp = STR_CONFIG_SETTING_SMOKE_AMOUNT_HELPTEXT +strval = STR_CONFIG_SETTING_NONE + +[SDT_BOOL] +var = vehicle.never_expire_vehicles +flags = SF_NO_NETWORK +def = false +str = STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES +strhelp = STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT + +[SDT_VAR] +var = vehicle.max_trains +type = SLE_UINT16 +def = 500 +min = 0 +max = 5000 +str = STR_CONFIG_SETTING_MAX_TRAINS +strhelp = STR_CONFIG_SETTING_MAX_TRAINS_HELPTEXT +strval = STR_JUST_COMMA +post_cb = MaxVehiclesChanged +cat = SC_BASIC + +[SDT_VAR] +var = vehicle.max_roadveh +type = SLE_UINT16 +def = 500 +min = 0 +max = 5000 +str = STR_CONFIG_SETTING_MAX_ROAD_VEHICLES +strhelp = STR_CONFIG_SETTING_MAX_ROAD_VEHICLES_HELPTEXT +strval = STR_JUST_COMMA +post_cb = MaxVehiclesChanged +cat = SC_BASIC + +[SDT_VAR] +var = vehicle.max_aircraft +type = SLE_UINT16 +def = 200 +min = 0 +max = 5000 +str = STR_CONFIG_SETTING_MAX_AIRCRAFT +strhelp = STR_CONFIG_SETTING_MAX_AIRCRAFT_HELPTEXT +strval = STR_JUST_COMMA +post_cb = MaxVehiclesChanged +cat = SC_BASIC + +[SDT_VAR] +var = vehicle.max_ships +type = SLE_UINT16 +def = 300 +min = 0 +max = 5000 +str = STR_CONFIG_SETTING_MAX_SHIPS +strhelp = STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT +strval = STR_JUST_COMMA +post_cb = MaxVehiclesChanged +cat = SC_BASIC + +[SDT_BOOL] +var = vehicle.wagon_speed_limits +flags = SF_NO_NETWORK +def = true +str = STR_CONFIG_SETTING_WAGONSPEEDLIMITS +strhelp = STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT +post_cb = UpdateConsists + +[SDT_BOOL] +var = vehicle.disable_elrails +from = SLV_38 +flags = SF_NO_NETWORK +def = false +str = STR_CONFIG_SETTING_DISABLE_ELRAILS +strhelp = STR_CONFIG_SETTING_DISABLE_ELRAILS_HELPTEXT +post_cb = SettingsDisableElrail +cat = SC_EXPERT + +[SDT_VAR] +var = vehicle.freight_trains +type = SLE_UINT8 +from = SLV_39 +flags = SF_NO_NETWORK +def = 1 +min = 1 +max = 255 +interval = 1 +str = STR_CONFIG_SETTING_FREIGHT_TRAINS +strhelp = STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT +strval = STR_JUST_COMMA +post_cb = UpdateConsists + +[SDT_VAR] +var = vehicle.plane_speed +type = SLE_UINT8 +from = SLV_90 +flags = SF_NO_NETWORK +def = 4 +min = 1 +max = 4 +str = STR_CONFIG_SETTING_PLANE_SPEED +strhelp = STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT +strval = STR_CONFIG_SETTING_PLANE_SPEED_VALUE + +[SDT_BOOL] +var = vehicle.dynamic_engines +from = SLV_95 +flags = SF_NO_NETWORK +def = true +pre_cb = CheckDynamicEngines +cat = SC_EXPERT + +[SDT_VAR] +var = vehicle.plane_crashes +type = SLE_UINT8 +from = SLV_138 +flags = SF_GUI_DROPDOWN +def = 2 +min = 0 +max = 2 +interval = 1 +str = STR_CONFIG_SETTING_PLANE_CRASHES +strhelp = STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT +strval = STR_CONFIG_SETTING_PLANE_CRASHES_NONE +cat = SC_BASIC + +[SDT_VAR] +var = vehicle.extend_vehicle_life +type = SLE_UINT8 +def = 0 +min = 0 +max = 100 +cat = SC_EXPERT + +## Old vehicle settings. + +[SDTG_BOOL] +name = """" +flags = SF_NO_NETWORK +var = _old_vds.servint_ispercent +def = false +to = SLV_120 + +[SDTG_VAR] +name = """" +type = SLE_UINT16 +flags = SF_GUI_0_IS_SPECIAL +var = _old_vds.servint_trains +def = 150 +min = 5 +max = 800 +to = SLV_120 + +[SDTG_VAR] +name = """" +type = SLE_UINT16 +flags = SF_GUI_0_IS_SPECIAL +var = _old_vds.servint_roadveh +def = 150 +min = 5 +max = 800 +to = SLV_120 + +[SDTG_VAR] +name = """" +type = SLE_UINT16 +flags = SF_GUI_0_IS_SPECIAL +var = _old_vds.servint_ships +def = 360 +min = 5 +max = 800 +to = SLV_120 + +[SDTG_VAR] +name = """" +type = SLE_UINT16 +flags = SF_GUI_0_IS_SPECIAL +var = _old_vds.servint_aircraft +def = 150 +min = 5 +max = 800 +to = SLV_120 + +## These were once in the "gui" section, but they really are related to orders. + +[SDTC_BOOL] +var = gui.sg_full_load_any +from = SLV_22 +to = SLV_93 +def = true + +[SDTC_BOOL] +var = gui.sg_new_nonstop +from = SLV_22 +to = SLV_93 +def = false diff --git a/src/table/settings/gui_settings.ini b/src/table/settings/gui_settings.ini new file mode 100644 index 0000000000..427402660b --- /dev/null +++ b/src/table/settings/gui_settings.ini @@ -0,0 +1,858 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; GUI settings as stored in the main configuration file ("openttd.cfg"). + +[pre-amble] +static void v_PositionMainToolbar(int32 new_value); +static void v_PositionStatusbar(int32 new_value); +static void RedrawSmallmap(int32 new_value); +static void CloseSignalGUI(int32 new_value); +static void InvalidateCompanyLiveryWindow(int32 new_value); +static void InvalidateNewGRFChangeWindows(int32 new_value); +static void ZoomMinMaxChanged(int32 new_value); +static void SpriteZoomMinChanged(int32 new_value); + +static std::initializer_list _autosave_interval{"off", "monthly", "quarterly", "half year", "yearly"}; +static std::initializer_list _osk_activation{"disabled", "double", "single", "immediately"}; +static std::initializer_list _savegame_date{"long", "short", "iso"}; + +static const SettingVariant _gui_settings_table[] = { +[post-amble] +}; +[templates] +SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTC_VAR = SDTC_VAR( $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDTC_OMANY = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); +SDTC_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +[SDTC_OMANY] +var = gui.autosave +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 4 +full = _autosave_interval +str = STR_CONFIG_SETTING_AUTOSAVE +strhelp = STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT +strval = STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.threaded_saves +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +cat = SC_EXPERT + +[SDTC_OMANY] +var = gui.date_format_in_default_names +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +max = 2 +full = _savegame_date +str = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES +strhelp = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT +strval = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_LONG + +[SDTC_BOOL] +var = gui.show_finances +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_SHOWFINANCES +strhelp = STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT +cat = SC_BASIC + +[SDTC_VAR] +var = gui.auto_scrolling +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 0 +min = 0 +max = 3 +str = STR_CONFIG_SETTING_AUTOSCROLL +strhelp = STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT +strval = STR_CONFIG_SETTING_AUTOSCROLL_DISABLED +cat = SC_BASIC + +[SDTC_VAR] +ifdef = __EMSCRIPTEN__ +var = gui.scroll_mode +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +min = 0 +max = 3 +str = STR_CONFIG_SETTING_SCROLLMODE +strhelp = STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT +strval = STR_CONFIG_SETTING_SCROLLMODE_DEFAULT +cat = SC_BASIC + +[SDTC_VAR] +ifndef = __EMSCRIPTEN__ +var = gui.scroll_mode +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 0 +min = 0 +max = 3 +str = STR_CONFIG_SETTING_SCROLLMODE +strhelp = STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT +strval = STR_CONFIG_SETTING_SCROLLMODE_DEFAULT +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.smooth_scroll +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +str = STR_CONFIG_SETTING_SMOOTH_SCROLLING +strhelp = STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT + +[SDTC_BOOL] +var = gui.right_mouse_wnd_close +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +str = STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE +strhelp = STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT +cat = SC_BASIC + +; We might need to emulate a right mouse button on mac +[SDTC_VAR] +ifdef = __APPLE__ +var = gui.right_mouse_btn_emulation +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 0 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU +strhelp = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT +strval = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.measure_tooltip +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_MEASURE_TOOLTIP +strhelp = STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT +cat = SC_BASIC + +[SDTC_VAR] +var = gui.errmsg_duration +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 5 +min = 0 +max = 20 +str = STR_CONFIG_SETTING_ERRMSG_DURATION +strhelp = STR_CONFIG_SETTING_ERRMSG_DURATION_HELPTEXT +strval = STR_CONFIG_SETTING_ERRMSG_DURATION_VALUE + +[SDTC_VAR] +var = gui.hover_delay_ms +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL +def = 250 +min = 50 +max = 6000 +interval = 50 +str = STR_CONFIG_SETTING_HOVER_DELAY +strhelp = STR_CONFIG_SETTING_HOVER_DELAY_HELPTEXT +strval = STR_CONFIG_SETTING_HOVER_DELAY_VALUE + +[SDTC_OMANY] +var = gui.osk_activation +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +str = STR_CONFIG_SETTING_OSK_ACTIVATION +strhelp = STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT +strval = STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED +flags = SF_GUI_DROPDOWN +full = _osk_activation +def = 1 +min = 0 +max = 3 +cat = SC_BASIC + +[SDTC_VAR] +var = gui.toolbar_pos +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_TOOLBAR_POS +strhelp = STR_CONFIG_SETTING_TOOLBAR_POS_HELPTEXT +strval = STR_CONFIG_SETTING_HORIZONTAL_POS_LEFT +post_cb = v_PositionMainToolbar +cat = SC_BASIC + +[SDTC_VAR] +var = gui.statusbar_pos +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_STATUSBAR_POS +strhelp = STR_CONFIG_SETTING_STATUSBAR_POS_HELPTEXT +strval = STR_CONFIG_SETTING_HORIZONTAL_POS_LEFT +post_cb = v_PositionStatusbar +cat = SC_BASIC + +[SDTC_VAR] +var = gui.window_snap_radius +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL +def = 10 +min = 1 +max = 32 +str = STR_CONFIG_SETTING_SNAP_RADIUS +strhelp = STR_CONFIG_SETTING_SNAP_RADIUS_HELPTEXT +strval = STR_CONFIG_SETTING_SNAP_RADIUS_VALUE +cat = SC_EXPERT + +[SDTC_VAR] +var = gui.window_soft_limit +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL +def = 20 +min = 5 +max = 255 +interval = 1 +str = STR_CONFIG_SETTING_SOFT_LIMIT +strhelp = STR_CONFIG_SETTING_SOFT_LIMIT_HELPTEXT +strval = STR_CONFIG_SETTING_SOFT_LIMIT_VALUE +cat = SC_EXPERT + +[SDTC_VAR] +var = gui.zoom_min +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = ZOOM_LVL_MIN +min = ZOOM_LVL_MIN +max = ZOOM_LVL_OUT_4X +str = STR_CONFIG_SETTING_ZOOM_MIN +strhelp = STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT +strval = STR_CONFIG_SETTING_ZOOM_LVL_MIN +post_cb = ZoomMinMaxChanged +startup = true + +[SDTC_VAR] +var = gui.zoom_max +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = ZOOM_LVL_MAX +min = ZOOM_LVL_OUT_8X +max = ZOOM_LVL_MAX +str = STR_CONFIG_SETTING_ZOOM_MAX +strhelp = STR_CONFIG_SETTING_ZOOM_MAX_HELPTEXT +strval = STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X +post_cb = ZoomMinMaxChanged +startup = true + +[SDTC_VAR] +var = gui.sprite_zoom_min +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = ZOOM_LVL_MIN +min = ZOOM_LVL_MIN +max = ZOOM_LVL_OUT_4X +str = STR_CONFIG_SETTING_SPRITE_ZOOM_MIN +strhelp = STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT +strval = STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_MIN +post_cb = SpriteZoomMinChanged + +[SDTC_BOOL] +var = gui.population_in_label +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_POPULATION_IN_LABEL +strhelp = STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT +post_cb = [](auto) { UpdateAllTownVirtCoords(); } + +[SDTC_BOOL] +var = gui.link_terraform_toolbar +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +str = STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR +strhelp = STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR_HELPTEXT + +[SDTC_VAR] +var = gui.smallmap_land_colour +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 0 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR +strhelp = STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT +strval = STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN +post_cb = RedrawSmallmap + +[SDTC_VAR] +var = gui.liveries +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_LIVERIES +strhelp = STR_CONFIG_SETTING_LIVERIES_HELPTEXT +strval = STR_CONFIG_SETTING_LIVERIES_NONE +post_cb = InvalidateCompanyLiveryWindow + +[SDTC_VAR] +var = gui.starting_colour +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = COLOUR_END +min = 0 +max = COLOUR_END +str = STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR +strhelp = STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT +strval = STR_COLOUR_DARK_BLUE + +[SDTC_BOOL] +var = gui.auto_remove_signals +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +str = STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS +strhelp = STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS_HELPTEXT +cat = SC_ADVANCED + +[SDTC_BOOL] +var = gui.prefer_teamchat +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +str = STR_CONFIG_SETTING_PREFER_TEAMCHAT +strhelp = STR_CONFIG_SETTING_PREFER_TEAMCHAT_HELPTEXT +cat = SC_BASIC + +[SDTC_VAR] +var = gui.scrollwheel_scrolling +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 0 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING +strhelp = STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING_HELPTEXT +strval = STR_CONFIG_SETTING_SCROLLWHEEL_ZOOM +cat = SC_BASIC + +[SDTC_VAR] +var = gui.scrollwheel_multiplier +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 5 +min = 1 +max = 15 +interval = 1 +str = STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER +strhelp = STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER_HELPTEXT +strval = STR_JUST_COMMA +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.pause_on_newgame +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +str = STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME +strhelp = STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT +cat = SC_BASIC + +[SDTC_VAR] +var = gui.advanced_vehicle_list +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS +strhelp = STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT +strval = STR_CONFIG_SETTING_COMPANIES_OFF + +[SDTC_BOOL] +var = gui.timetable_in_ticks +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +str = STR_CONFIG_SETTING_TIMETABLE_IN_TICKS +strhelp = STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT +post_cb = [](auto) { InvalidateWindowClassesData(WC_VEHICLE_TIMETABLE, VIWD_MODIFY_ORDERS); } +cat = SC_EXPERT + +[SDTC_BOOL] +var = gui.timetable_arrival_departure +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE +strhelp = STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT +post_cb = [](auto) { InvalidateWindowClassesData(WC_VEHICLE_TIMETABLE, VIWD_MODIFY_ORDERS); } + +[SDTC_BOOL] +var = gui.quick_goto +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_QUICKGOTO +strhelp = STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT +cat = SC_BASIC + +[SDTC_VAR] +var = gui.loading_indicators +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_LOADING_INDICATORS +strhelp = STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT +strval = STR_CONFIG_SETTING_COMPANIES_OFF +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC + +[SDTC_VAR] +var = gui.default_rail_type +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 0 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE +strhelp = STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT +strval = STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.enable_signal_gui +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI +strhelp = STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI_HELPTEXT +post_cb = CloseSignalGUI +cat = SC_EXPERT + +[SDTC_VAR] +var = gui.coloured_news_year +type = SLE_INT32 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 2000 +min = MIN_YEAR +max = MAX_YEAR +interval = 1 +str = STR_CONFIG_SETTING_COLOURED_NEWS_YEAR +strhelp = STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT +strval = STR_JUST_INT +cat = SC_EXPERT + +[SDTC_VAR] +var = gui.drag_signals_density +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 4 +min = 1 +max = 20 +str = STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY +strhelp = STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT +strval = STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE +post_cb = [](auto) { InvalidateWindowData(WC_BUILD_SIGNAL, 0); } +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.drag_signals_fixed_distance +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +str = STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE +strhelp = STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT +cat = SC_EXPERT + +[SDTC_VAR] +var = gui.semaphore_build_before +type = SLE_INT32 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 1950 +min = MIN_YEAR +max = MAX_YEAR +interval = 1 +str = STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE +strhelp = STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT +strval = STR_JUST_INT +post_cb = ResetSignalVariant + +[SDTC_BOOL] +var = gui.vehicle_income_warn +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_WARN_INCOME_LESS +strhelp = STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT +cat = SC_BASIC + +[SDTC_VAR] +var = gui.order_review_system +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_ORDER_REVIEW +strhelp = STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT +strval = STR_CONFIG_SETTING_ORDER_REVIEW_OFF +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.lost_vehicle_warn +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_WARN_LOST_VEHICLE +strhelp = STR_CONFIG_SETTING_WARN_LOST_VEHICLE_HELPTEXT + +[SDTC_BOOL] +var = gui.new_nonstop +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT +strhelp = STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT +cat = SC_BASIC + +[SDTC_VAR] +var = gui.stop_location +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +min = 0 +max = 2 +interval = 1 +str = STR_CONFIG_SETTING_STOP_LOCATION +strhelp = STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT +strval = STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.keep_all_autosave +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false + +[SDTC_BOOL] +var = gui.autosave_on_exit +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.autosave_on_network_disconnect +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +cat = SC_EXPERT + +[SDTC_VAR] +var = gui.max_num_autosaves +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 16 +min = 0 +max = 255 + +[SDTC_BOOL] +var = gui.auto_euro +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true + +[SDTC_VAR] +var = gui.news_message_timeout +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 2 +min = 1 +max = 255 + +[SDTC_BOOL] +var = gui.show_track_reservation +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION +strhelp = STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION_HELPTEXT +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC + +[SDTC_VAR] +var = gui.default_signal_type +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +min = 0 +max = 2 +interval = 1 +str = STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE +strhelp = STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE_HELPTEXT +strval = STR_CONFIG_SETTING_DEFAULT_SIGNAL_NORMAL +cat = SC_BASIC + +[SDTC_VAR] +var = gui.cycle_signal_types +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +min = 0 +max = 2 +interval = 1 +str = STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES +strhelp = STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT +strval = STR_CONFIG_SETTING_CYCLE_SIGNAL_NORMAL + +[SDTC_VAR] +var = gui.station_numtracks +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 1 +min = 1 +max = 7 + +[SDTC_VAR] +var = gui.station_platlength +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 5 +min = 1 +max = 7 +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.station_dragdrop +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.station_show_coverage +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.persistent_buildingtools +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS +strhelp = STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.expenses_layout +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_EXPENSES_LAYOUT +strhelp = STR_CONFIG_SETTING_EXPENSES_LAYOUT_HELPTEXT +post_cb = [](auto) { MarkWholeScreenDirty(); } + +[SDTC_VAR] +var = gui.station_gui_group_order +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 0 +min = 0 +max = 5 +interval = 1 + +[SDTC_VAR] +var = gui.station_gui_sort_by +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 0 +min = 0 +max = 3 +interval = 1 + +[SDTC_VAR] +var = gui.station_gui_sort_order +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 0 +min = 0 +max = 1 +interval = 1 + +[SDTC_VAR] +var = gui.missing_strings_threshold +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 25 +min = 1 +max = UINT8_MAX +cat = SC_EXPERT + +[SDTC_VAR] +var = gui.graph_line_thickness +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 3 +min = 1 +max = 5 +str = STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS +strhelp = STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT +strval = STR_JUST_COMMA +post_cb = [](auto) { MarkWholeScreenDirty(); } + +[SDTC_BOOL] +var = gui.show_newgrf_name +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +str = STR_CONFIG_SETTING_SHOW_NEWGRF_NAME +strhelp = STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_ADVANCED + +; For the dedicated build we'll enable dates in logs by default. +[SDTC_BOOL] +ifdef = DEDICATED +var = gui.show_date_in_logs +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true + +[SDTC_BOOL] +ifndef = DEDICATED +var = gui.show_date_in_logs +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false + +[SDTC_VAR] +var = gui.settings_restriction_mode +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 0 +min = 0 +max = 2 + +[SDTC_VAR] +var = gui.developer +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 1 +min = 0 +max = 2 +cat = SC_EXPERT + +[SDTC_BOOL] +var = gui.newgrf_developer_tools +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +post_cb = InvalidateNewGRFChangeWindows +cat = SC_EXPERT + +[SDTC_BOOL] +var = gui.ai_developer_tools +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +post_cb = [](auto) { InvalidateWindowClassesData(WC_AI_SETTINGS); } +cat = SC_EXPERT + +[SDTC_BOOL] +var = gui.scenario_developer +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +post_cb = InvalidateNewGRFChangeWindows + +[SDTC_BOOL] +var = gui.newgrf_show_old_versions +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +cat = SC_EXPERT + +[SDTC_VAR] +var = gui.newgrf_default_palette +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +min = 0 +max = 1 +post_cb = UpdateNewGRFConfigPalette +cat = SC_EXPERT + +[SDTC_VAR] +var = gui.console_backlog_timeout +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 100 +min = 10 +max = 65500 + +[SDTC_VAR] +var = gui.console_backlog_length +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 100 +min = 10 +max = 65500 + +[SDTC_VAR] +var = gui.refresh_rate +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 60 +min = 10 +max = 1000 +cat = SC_EXPERT +startup = true + +[SDTC_VAR] +var = gui.fast_forward_speed_limit +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NO_NETWORK +def = 2500 +min = 0 +max = 50000 +interval = 10 +str = STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT +strhelp = STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_HELPTEXT +strval = STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_VAL +cat = SC_BASIC + +[SDTC_VAR] +var = gui.network_chat_box_width_pct +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 40 +min = 10 +max = 100 +cat = SC_EXPERT + +[SDTC_VAR] +var = gui.network_chat_box_height +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 25 +min = 5 +max = 255 +cat = SC_EXPERT + +[SDTC_VAR] +var = gui.network_chat_timeout +type = SLE_UINT16 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 20 +min = 1 +max = 65535 +cat = SC_EXPERT + diff --git a/src/table/settings/linkgraph_settings.ini b/src/table/settings/linkgraph_settings.ini new file mode 100644 index 0000000000..04ef32d621 --- /dev/null +++ b/src/table/settings/linkgraph_settings.ini @@ -0,0 +1,168 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; Linkgraph settings as stored in the main configuration file ("openttd.cfg") +; and in the savegame PATS chunk and in the linkgraph chunks for each job running. + +[pre-amble] +static const SettingVariant _linkgraph_settings_table[] = { +[post-amble] +}; +[templates] +SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +[SDT_VAR] +var = linkgraph.recalc_interval +type = SLE_UINT16 +from = SLV_183 +def = 4 +min = 2 +max = 32 +interval = 2 +str = STR_CONFIG_SETTING_LINKGRAPH_INTERVAL +strval = STR_JUST_COMMA +strhelp = STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT +extra = offsetof(LinkGraphSettings, recalc_interval) + +[SDT_VAR] +var = linkgraph.recalc_time +type = SLE_UINT16 +from = SLV_183 +def = 16 +min = 1 +max = 4096 +interval = 1 +str = STR_CONFIG_SETTING_LINKGRAPH_TIME +strval = STR_JUST_COMMA +strhelp = STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT +extra = offsetof(LinkGraphSettings, recalc_time) + +[SDT_VAR] +var = linkgraph.distribution_pax +type = SLE_UINT8 +from = SLV_183 +flags = SF_GUI_DROPDOWN +def = DT_MANUAL +min = DT_MIN +max = DT_MAX +interval = 1 +str = STR_CONFIG_SETTING_DISTRIBUTION_PAX +strval = STR_CONFIG_SETTING_DISTRIBUTION_MANUAL +strhelp = STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT +extra = offsetof(LinkGraphSettings, distribution_pax) + +[SDT_VAR] +var = linkgraph.distribution_mail +type = SLE_UINT8 +from = SLV_183 +flags = SF_GUI_DROPDOWN +def = DT_MANUAL +min = DT_MIN +max = DT_MAX +interval = 1 +str = STR_CONFIG_SETTING_DISTRIBUTION_MAIL +strval = STR_CONFIG_SETTING_DISTRIBUTION_MANUAL +strhelp = STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT +extra = offsetof(LinkGraphSettings, distribution_mail) + +[SDT_VAR] +var = linkgraph.distribution_armoured +type = SLE_UINT8 +from = SLV_183 +flags = SF_GUI_DROPDOWN +def = DT_MANUAL +min = DT_MIN +max = DT_MAX +interval = 1 +str = STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED +strval = STR_CONFIG_SETTING_DISTRIBUTION_MANUAL +strhelp = STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT +extra = offsetof(LinkGraphSettings, distribution_armoured) + +[SDT_VAR] +var = linkgraph.distribution_default +type = SLE_UINT8 +from = SLV_183 +flags = SF_GUI_DROPDOWN +def = DT_MANUAL +min = DT_BEGIN +max = DT_MAX_NONSYMMETRIC +interval = 1 +str = STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT +strval = STR_CONFIG_SETTING_DISTRIBUTION_MANUAL +strhelp = STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT +extra = offsetof(LinkGraphSettings, distribution_default) + +[SDT_VAR] +var = linkgraph.accuracy +type = SLE_UINT8 +from = SLV_183 +def = 16 +min = 2 +max = 64 +interval = 1 +str = STR_CONFIG_SETTING_LINKGRAPH_ACCURACY +strval = STR_JUST_COMMA +strhelp = STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT +extra = offsetof(LinkGraphSettings, accuracy) + +[SDT_VAR] +var = linkgraph.demand_distance +type = SLE_UINT8 +from = SLV_183 +def = 100 +min = 0 +max = 255 +interval = 5 +str = STR_CONFIG_SETTING_DEMAND_DISTANCE +strval = STR_CONFIG_SETTING_PERCENTAGE +strhelp = STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT +extra = offsetof(LinkGraphSettings, demand_distance) + +[SDT_VAR] +var = linkgraph.demand_size +type = SLE_UINT8 +from = SLV_183 +def = 100 +min = 0 +max = 100 +interval = 5 +str = STR_CONFIG_SETTING_DEMAND_SIZE +strval = STR_CONFIG_SETTING_PERCENTAGE +strhelp = STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT +extra = offsetof(LinkGraphSettings, demand_size) + +[SDT_VAR] +var = linkgraph.short_path_saturation +type = SLE_UINT8 +from = SLV_183 +def = 80 +min = 0 +max = 250 +interval = 5 +str = STR_CONFIG_SETTING_SHORT_PATH_SATURATION +strval = STR_CONFIG_SETTING_PERCENTAGE +strhelp = STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT +extra = offsetof(LinkGraphSettings, short_path_saturation) diff --git a/src/table/settings/locale_settings.ini b/src/table/settings/locale_settings.ini new file mode 100644 index 0000000000..777ae15cf4 --- /dev/null +++ b/src/table/settings/locale_settings.ini @@ -0,0 +1,177 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; Locale settings as stored in the main configuration file ("openttd.cfg") and +; in the savegame PATS chunk. These settings are not sync'd over the network. + +[pre-amble] +uint8 _old_units; ///< Old units from old savegames + +static std::initializer_list _locale_currencies{"GBP", "USD", "EUR", "YEN", "ATS", "BEF", "CHF", "CZK", "DEM", "DKK", "ESP", "FIM", "FRF", "GRD", "HUF", "ISK", "ITL", "NLG", "NOK", "PLN", "RON", "RUR", "SIT", "SEK", "YTL", "SKK", "BRL", "EEK", "custom"}; +static std::initializer_list _locale_units{"imperial", "metric", "si", "gameunits"}; + +static const SettingVariant _locale_settings_table[] = { +[post-amble] +}; +[templates] +SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $var, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDT_OMANY = SDT_OMANY(GameSettings, $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $load, $cat, $extra, $startup), +SDT_SSTR = SDT_SSTR(GameSettings, $var, $type, $flags, $def, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDTG_OMANY = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); +SDT_OMANY = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +[SDT_OMANY] +var = locale.currency +type = SLE_UINT8 +from = SLV_97 +flags = SF_NO_NETWORK_SYNC +def = 0 +max = CURRENCY_END - 1 +full = _locale_currencies +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC + +[SDTG_OMANY] +name = ""units"" +var = _old_units +type = SLE_UINT8 +from = SLV_97 +to = SLV_184 +flags = SF_NOT_IN_CONFIG +def = 1 +max = 2 +full = _locale_units +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC + +[SDT_OMANY] +var = locale.units_velocity +type = SLE_UINT8 +from = SLV_184 +flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 3 +full = _locale_units +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC +str = STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY +strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT +strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL + +[SDT_OMANY] +var = locale.units_power +type = SLE_UINT8 +from = SLV_184 +flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 2 +full = _locale_units +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC +str = STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER +strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_HELPTEXT +strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_IMPERIAL + +[SDT_OMANY] +var = locale.units_weight +type = SLE_UINT8 +from = SLV_184 +flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 2 +full = _locale_units +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC +str = STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT +strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_HELPTEXT +strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_IMPERIAL + +[SDT_OMANY] +var = locale.units_volume +type = SLE_UINT8 +from = SLV_184 +flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 2 +full = _locale_units +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC +str = STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME +strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_HELPTEXT +strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_IMPERIAL + +[SDT_OMANY] +var = locale.units_force +type = SLE_UINT8 +from = SLV_184 +flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +max = 2 +full = _locale_units +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC +str = STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE +strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_HELPTEXT +strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_IMPERIAL + +[SDT_OMANY] +var = locale.units_height +type = SLE_UINT8 +from = SLV_184 +flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 2 +full = _locale_units +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC +str = STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT +strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT +strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL + +[SDT_SSTR] +var = locale.digit_group_separator +type = SLE_STRQ +from = SLV_118 +flags = SF_NO_NETWORK_SYNC +def = nullptr +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC + +[SDT_SSTR] +var = locale.digit_group_separator_currency +type = SLE_STRQ +from = SLV_118 +flags = SF_NO_NETWORK_SYNC +def = nullptr +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC + +[SDT_SSTR] +var = locale.digit_decimal_separator +type = SLE_STRQ +from = SLV_126 +flags = SF_NO_NETWORK_SYNC +def = nullptr +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC diff --git a/src/table/settings/multimedia_settings.ini b/src/table/settings/multimedia_settings.ini new file mode 100644 index 0000000000..14c6b7b302 --- /dev/null +++ b/src/table/settings/multimedia_settings.ini @@ -0,0 +1,148 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; Multimedia (sound / music) settings as stored in the main configuration file ("openttd.cfg"). + +[pre-amble] + +static const SettingVariant _multimedia_settings_table[] = { +[post-amble] +}; +[templates] +SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTC_LIST = SDTC_LIST( $var, $type, $flags, $def, $from, $to, $cat, $extra, $startup), +SDTC_VAR = SDTC_VAR( $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDTC_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +[SDTC_BOOL] +var = sound.news_ticker +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_SOUND_TICKER +strhelp = STR_CONFIG_SETTING_SOUND_TICKER_HELPTEXT + +[SDTC_BOOL] +var = sound.news_full +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_SOUND_NEWS +strhelp = STR_CONFIG_SETTING_SOUND_NEWS_HELPTEXT + +[SDTC_BOOL] +var = sound.new_year +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_SOUND_NEW_YEAR +strhelp = STR_CONFIG_SETTING_SOUND_NEW_YEAR_HELPTEXT + +[SDTC_BOOL] +var = sound.confirm +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_SOUND_CONFIRM +strhelp = STR_CONFIG_SETTING_SOUND_CONFIRM_HELPTEXT + +[SDTC_BOOL] +var = sound.click_beep +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_SOUND_CLICK +strhelp = STR_CONFIG_SETTING_SOUND_CLICK_HELPTEXT + +[SDTC_BOOL] +var = sound.disaster +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_SOUND_DISASTER +strhelp = STR_CONFIG_SETTING_SOUND_DISASTER_HELPTEXT + +[SDTC_BOOL] +var = sound.vehicle +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_SOUND_VEHICLE +strhelp = STR_CONFIG_SETTING_SOUND_VEHICLE_HELPTEXT + +[SDTC_BOOL] +var = sound.ambient +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +str = STR_CONFIG_SETTING_SOUND_AMBIENT +strhelp = STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT + +[SDTC_VAR] +var = music.playlist +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 0 +min = 0 +max = 5 +interval = 1 +cat = SC_BASIC + +[SDTC_VAR] +var = music.music_vol +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 50 +min = 0 +max = 127 +interval = 1 +cat = SC_BASIC + +[SDTC_VAR] +var = music.effect_vol +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 100 +min = 0 +max = 127 +interval = 1 +cat = SC_BASIC + +[SDTC_LIST] +var = music.custom_1 +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = nullptr +cat = SC_BASIC + +[SDTC_LIST] +var = music.custom_2 +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = nullptr +cat = SC_BASIC + +[SDTC_BOOL] +var = music.playing +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +cat = SC_BASIC + +[SDTC_BOOL] +var = music.shuffle +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +cat = SC_BASIC diff --git a/src/table/settings/news_display_settings.ini b/src/table/settings/news_display_settings.ini new file mode 100644 index 0000000000..e3a23d3559 --- /dev/null +++ b/src/table/settings/news_display_settings.ini @@ -0,0 +1,201 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; News display settings as stored in the main configuration file ("openttd.cfg"). + +[pre-amble] +static std::initializer_list _news_display{ "off", "summarized", "full"}; + +static const SettingVariant _news_display_settings_table[] = { +[post-amble] +}; +[templates] +SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDTC_OMANY = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +[SDTC_OMANY] +var = news_display.arrival_player +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN +strhelp = STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.arrival_other +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER +strhelp = STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.accident +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS +strhelp = STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.company_info +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION +strhelp = STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.open +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_INDUSTRY_OPEN +strhelp = STR_CONFIG_SETTING_NEWS_INDUSTRY_OPEN_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.close +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_INDUSTRY_CLOSE +strhelp = STR_CONFIG_SETTING_NEWS_INDUSTRY_CLOSE_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.economy +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES +strhelp = STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.production_player +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY +strhelp = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.production_other +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 0 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER +strhelp = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.production_nobody +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 0 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED +strhelp = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.advice +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_ADVICE +strhelp = STR_CONFIG_SETTING_NEWS_ADVICE_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.new_vehicles +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_NEW_VEHICLES +strhelp = STR_CONFIG_SETTING_NEWS_NEW_VEHICLES_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.acceptance +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE +strhelp = STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.subsidies +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_SUBSIDIES +strhelp = STR_CONFIG_SETTING_NEWS_SUBSIDIES_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + +[SDTC_OMANY] +var = news_display.general +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +max = 2 +full = _news_display +str = STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION +strhelp = STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION_HELPTEXT +strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF + diff --git a/src/table/settings/gameopt_settings.ini b/src/table/settings/old_gameopt_settings.ini similarity index 77% rename from src/table/settings/gameopt_settings.ini rename to src/table/settings/old_gameopt_settings.ini index 83e7c6395a..4e8e467163 100644 --- a/src/table/settings/gameopt_settings.ini +++ b/src/table/settings/old_gameopt_settings.ini @@ -14,25 +14,10 @@ ; be saved in their new place. [pre-amble] -const std::array _old_diff_settings{"max_no_competitors", "competitor_start_time", "number_towns", "industry_density", "max_loan", "initial_interest", "vehicle_costs", "competitor_speed", "competitor_intelligence", "vehicle_breakdowns", "subsidy_multiplier", "construction_cost", "terrain_type", "quantity_sea_lakes", "economy", "line_reverse_mode", "disasters", "town_council_tolerance"}; -uint16 _old_diff_custom[GAME_DIFFICULTY_NUM]; -uint8 _old_diff_level; ///< Old difficulty level from old savegames -uint8 _old_units; ///< Old units from old savegames - -/* Most of these strings are used both for gameopt-backward compatibility - * and the settings tables. The rest is here for consistency. */ -static std::initializer_list _locale_currencies{"GBP", "USD", "EUR", "YEN", "ATS", "BEF", "CHF", "CZK", "DEM", "DKK", "ESP", "FIM", "FRF", "GRD", "HUF", "ISK", "ITL", "NLG", "NOK", "PLN", "RON", "RUR", "SIT", "SEK", "YTL", "SKK", "BRL", "EEK", "custom"}; -static std::initializer_list _locale_units{"imperial", "metric", "si", "gameunits"}; static std::initializer_list _town_names{"english", "french", "german", "american", "latin", "silly", "swedish", "dutch", "finnish", "polish", "slovak", "norwegian", "hungarian", "austrian", "romanian", "czech", "swiss", "danish", "turkish", "italian", "catalan"}; static std::initializer_list _climates{"temperate", "arctic", "tropic", "toyland"}; -static std::initializer_list _autosave_interval{"off", "monthly", "quarterly", "half year", "yearly"}; -static std::initializer_list _roadsides{"left", "right"}; -static std::initializer_list _savegame_date{"long", "short", "iso"}; -static std::initializer_list _osk_activation{"disabled", "double", "single", "immediately"}; -static std::initializer_list _settings_profiles{"easy", "medium", "hard"}; -static std::initializer_list _news_display{ "off", "summarized", "full"}; -static const SettingVariant _gameopt_settings_table[] = { +static const SettingVariant _old_gameopt_settings_table[] = { /* In version 4 a new difficulty setting has been added to the difficulty settings, * town attitude towards demolishing. Needs special handling because some dimwit thought * it funny to have the GameDifficulty struct be an array while it is a struct of diff --git a/src/table/settings/pathfinding_settings.ini b/src/table/settings/pathfinding_settings.ini new file mode 100644 index 0000000000..322090001a --- /dev/null +++ b/src/table/settings/pathfinding_settings.ini @@ -0,0 +1,617 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; Pathfinding settings as stored in the main configuration file ("openttd.cfg") +; and in the savegame PATS chunk. + +[pre-amble] +static void InvalidateShipPathCache(int32 new_value); + +static const SettingVariant _pathfinding_settings_table[] = { +[post-amble] +}; +[templates] +SDT_BOOL = SDT_BOOL(GameSettings, $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +[SDT_BOOL] +var = pf.forbid_90_deg +def = false +str = STR_CONFIG_SETTING_FORBID_90_DEG +strhelp = STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT +post_cb = InvalidateShipPathCache +cat = SC_EXPERT + +[SDT_BOOL] +var = pf.roadveh_queue +def = true +cat = SC_EXPERT + +[SDT_BOOL] +var = pf.new_pathfinding_all +to = SLV_87 +def = false +cat = SC_EXPERT + +[SDT_BOOL] +var = pf.yapf.ship_use_yapf +from = SLV_28 +to = SLV_87 +def = false +cat = SC_EXPERT + +[SDT_BOOL] +var = pf.yapf.road_use_yapf +from = SLV_28 +to = SLV_87 +def = true +cat = SC_EXPERT + +[SDT_BOOL] +var = pf.yapf.rail_use_yapf +from = SLV_28 +to = SLV_87 +def = true +cat = SC_EXPERT + +[SDT_VAR] +var = pf.pathfinder_for_trains +type = SLE_UINT8 +from = SLV_87 +flags = SF_GUI_DROPDOWN +def = 2 +min = 1 +max = 2 +interval = 1 +str = STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS +strhelp = STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS_HELPTEXT +strval = STR_CONFIG_SETTING_PATHFINDER_NPF +cat = SC_EXPERT + +[SDT_VAR] +var = pf.pathfinder_for_roadvehs +type = SLE_UINT8 +from = SLV_87 +flags = SF_GUI_DROPDOWN +def = 2 +min = 1 +max = 2 +interval = 1 +str = STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES +strhelp = STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES_HELPTEXT +strval = STR_CONFIG_SETTING_PATHFINDER_NPF +cat = SC_EXPERT + +[SDT_VAR] +var = pf.pathfinder_for_ships +type = SLE_UINT8 +from = SLV_87 +flags = SF_GUI_DROPDOWN +def = 2 +min = 1 +max = 2 +interval = 1 +str = STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS +strhelp = STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS_HELPTEXT +strval = STR_CONFIG_SETTING_PATHFINDER_NPF +post_cb = InvalidateShipPathCache +cat = SC_EXPERT + +[SDT_BOOL] +var = pf.reverse_at_signals +from = SLV_159 +def = false +str = STR_CONFIG_SETTING_REVERSE_AT_SIGNALS +strhelp = STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT + +[SDT_VAR] +var = pf.wait_oneway_signal +type = SLE_UINT8 +def = 15 +min = 2 +max = 255 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.wait_twoway_signal +type = SLE_UINT8 +def = 41 +min = 2 +max = 255 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.wait_for_pbs_path +type = SLE_UINT8 +from = SLV_100 +def = 30 +min = 2 +max = 255 +cat = SC_EXPERT + +[SDT_BOOL] +var = pf.reserve_paths +from = SLV_100 +def = false +cat = SC_EXPERT + +[SDT_VAR] +var = pf.path_backoff_interval +type = SLE_UINT8 +from = SLV_100 +def = 20 +min = 1 +max = 255 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_max_search_nodes +type = SLE_UINT +def = 10000 +min = 500 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_rail_firstred_penalty +type = SLE_UINT +def = 10 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_rail_firstred_exit_penalty +type = SLE_UINT +def = 100 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_rail_lastred_penalty +type = SLE_UINT +def = 10 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_rail_station_penalty +type = SLE_UINT +def = 1 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_rail_slope_penalty +type = SLE_UINT +def = 1 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_rail_curve_penalty +type = SLE_UINT +def = 1 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_rail_depot_reverse_penalty +type = SLE_UINT +def = 50 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_rail_pbs_cross_penalty +type = SLE_UINT +from = SLV_100 +def = 3 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_rail_pbs_signal_back_penalty +type = SLE_UINT +from = SLV_100 +def = 15 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_buoy_penalty +type = SLE_UINT +def = 2 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_water_curve_penalty +type = SLE_UINT +def = 1 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_road_curve_penalty +type = SLE_UINT +def = 1 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_crossing_penalty +type = SLE_UINT +def = 3 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_road_drive_through_penalty +type = SLE_UINT +from = SLV_47 +def = 8 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_road_dt_occupied_penalty +type = SLE_UINT +from = SLV_130 +def = 8 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.npf_road_bay_occupied_penalty +type = SLE_UINT +from = SLV_130 +def = 15 * NPF_TILE_LENGTH +min = 0 +max = 100000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.npf.maximum_go_to_depot_penalty +type = SLE_UINT +from = SLV_131 +def = 20 * NPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_BOOL] +var = pf.yapf.disable_node_optimization +from = SLV_28 +def = false +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.max_search_nodes +type = SLE_UINT +from = SLV_28 +def = 10000 +min = 500 +max = 1000000 +cat = SC_EXPERT + +[SDT_BOOL] +var = pf.yapf.rail_firstred_twoway_eol +from = SLV_28 +def = false +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_firstred_penalty +type = SLE_UINT +from = SLV_28 +def = 10 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_firstred_exit_penalty +type = SLE_UINT +from = SLV_28 +def = 100 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_lastred_penalty +type = SLE_UINT +from = SLV_28 +def = 10 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_lastred_exit_penalty +type = SLE_UINT +from = SLV_28 +def = 100 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_station_penalty +type = SLE_UINT +from = SLV_28 +def = 10 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_slope_penalty +type = SLE_UINT +from = SLV_28 +def = 2 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_curve45_penalty +type = SLE_UINT +from = SLV_28 +def = 1 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_curve90_penalty +type = SLE_UINT +from = SLV_28 +def = 6 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_depot_reverse_penalty +type = SLE_UINT +from = SLV_28 +def = 50 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_crossing_penalty +type = SLE_UINT +from = SLV_28 +def = 3 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_look_ahead_max_signals +type = SLE_UINT +from = SLV_28 +def = 10 +min = 1 +max = 100 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_look_ahead_signal_p0 +type = SLE_INT +from = SLV_28 +def = 500 +min = -1000000 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_look_ahead_signal_p1 +type = SLE_INT +from = SLV_28 +def = -100 +min = -1000000 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_look_ahead_signal_p2 +type = SLE_INT +from = SLV_28 +def = 5 +min = -1000000 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_pbs_cross_penalty +type = SLE_UINT +from = SLV_100 +def = 3 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_pbs_station_penalty +type = SLE_UINT +from = SLV_100 +def = 8 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_pbs_signal_back_penalty +type = SLE_UINT +from = SLV_100 +def = 15 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_doubleslip_penalty +type = SLE_UINT +from = SLV_100 +def = 1 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_longer_platform_penalty +type = SLE_UINT +from = SLV_33 +def = 8 * YAPF_TILE_LENGTH +min = 0 +max = 20000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_longer_platform_per_tile_penalty +type = SLE_UINT +from = SLV_33 +def = 0 * YAPF_TILE_LENGTH +min = 0 +max = 20000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_shorter_platform_penalty +type = SLE_UINT +from = SLV_33 +def = 40 * YAPF_TILE_LENGTH +min = 0 +max = 20000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.rail_shorter_platform_per_tile_penalty +type = SLE_UINT +from = SLV_33 +def = 0 * YAPF_TILE_LENGTH +min = 0 +max = 20000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.road_slope_penalty +type = SLE_UINT +from = SLV_33 +def = 2 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.road_curve_penalty +type = SLE_UINT +from = SLV_33 +def = 1 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.road_crossing_penalty +type = SLE_UINT +from = SLV_33 +def = 3 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.road_stop_penalty +type = SLE_UINT +from = SLV_47 +def = 8 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.road_stop_occupied_penalty +type = SLE_UINT +from = SLV_130 +def = 8 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.road_stop_bay_occupied_penalty +type = SLE_UINT +from = SLV_130 +def = 15 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.maximum_go_to_depot_penalty +type = SLE_UINT +from = SLV_131 +def = 20 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.ship_curve45_penalty +type = SLE_UINT +from = SLV_SHIP_CURVE_PENALTY +def = 1 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +var = pf.yapf.ship_curve90_penalty +type = SLE_UINT +from = SLV_SHIP_CURVE_PENALTY +def = 6 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT diff --git a/src/table/settings/script_settings.ini b/src/table/settings/script_settings.ini new file mode 100644 index 0000000000..2d3531939c --- /dev/null +++ b/src/table/settings/script_settings.ini @@ -0,0 +1,112 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; Script settings as stored in the main configuration file ("openttd.cfg") +; and in the savegame PATS chunk. + +[pre-amble] +static std::initializer_list _settings_profiles{"easy", "medium", "hard"}; + +static const SettingVariant _script_settings_table[] = { +[post-amble] +}; +[templates] +SDT_BOOL = SDT_BOOL(GameSettings, $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDT_OMANY = SDT_OMANY(GameSettings, $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $load, $cat, $extra, $startup), +SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDT_OMANY = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); +SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +[SDT_OMANY] +var = script.settings_profile +type = SLE_UINT8 +from = SLV_178 +flags = SF_GUI_DROPDOWN +def = SP_EASY +min = SP_EASY +max = SP_HARD +full = _settings_profiles +str = STR_CONFIG_SETTING_AI_PROFILE +strhelp = STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT +strval = STR_CONFIG_SETTING_AI_PROFILE_EASY +cat = SC_BASIC + +[SDT_VAR] +var = script.script_max_opcode_till_suspend +type = SLE_UINT32 +from = SLV_107 +flags = SF_NEWGAME_ONLY +def = 10000 +min = 500 +max = 250000 +interval = 2500 +str = STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES +strhelp = STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT +strval = STR_JUST_COMMA +cat = SC_EXPERT + +[SDT_VAR] +var = script.script_max_memory_megabytes +type = SLE_UINT32 +from = SLV_SCRIPT_MEMLIMIT +flags = SF_NEWGAME_ONLY +def = 1024 +min = 8 +max = 8192 +interval = 8 +str = STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY +strhelp = STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT +strval = STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE +cat = SC_EXPERT + +[SDT_BOOL] +var = ai.ai_in_multiplayer +def = true +str = STR_CONFIG_SETTING_AI_IN_MULTIPLAYER +strhelp = STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT +cat = SC_BASIC + +[SDT_BOOL] +var = ai.ai_disable_veh_train +def = false +str = STR_CONFIG_SETTING_AI_BUILDS_TRAINS +strhelp = STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT + +[SDT_BOOL] +var = ai.ai_disable_veh_roadveh +def = false +str = STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES +strhelp = STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT + +[SDT_BOOL] +var = ai.ai_disable_veh_aircraft +def = false +str = STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT +strhelp = STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT + +[SDT_BOOL] +var = ai.ai_disable_veh_ship +def = false +str = STR_CONFIG_SETTING_AI_BUILDS_SHIPS +strhelp = STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT diff --git a/src/table/settings/settings.ini b/src/table/settings/settings.ini deleted file mode 100644 index 984668e510..0000000000 --- a/src/table/settings/settings.ini +++ /dev/null @@ -1,3487 +0,0 @@ -; This file is part of OpenTTD. -; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. -; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . -; - -; Settings as stored in the main configuration file ("openttd.cfg") and in the -; savegame PATS chunk (if not flagged not to). - -[pre-amble] -/* Begin - Callback Functions for the various settings */ -static void v_PositionMainToolbar(int32 new_value); -static void v_PositionStatusbar(int32 new_value); -static void RedrawSmallmap(int32 new_value); -static void StationSpreadChanged(int32 new_value); -static void CloseSignalGUI(int32 new_value); -static void UpdateConsists(int32 new_value); -static void TrainAccelerationModelChanged(int32 new_value); -static void RoadVehAccelerationModelChanged(int32 new_value); -static void TrainSlopeSteepnessChanged(int32 new_value); -static void RoadVehSlopeSteepnessChanged(int32 new_value); -static void TownFoundingChanged(int32 new_value); -static void DifficultyNoiseChange(int32 new_value); -static void MaxNoAIsChange(int32 new_value); -static bool CheckRoadSide(int32 &new_value); -static bool CheckMaxHeightLevel(int32 &new_value); -static bool CheckFreeformEdges(int32 &new_value); -static void UpdateFreeformEdges(int32 new_value); -static bool CheckDynamicEngines(int32 &new_value); -static void StationCatchmentChanged(int32 new_value); -static void InvalidateCompanyLiveryWindow(int32 new_value); -static void InvalidateNewGRFChangeWindows(int32 new_value); -static void ZoomMinMaxChanged(int32 new_value); -static void SpriteZoomMinChanged(int32 new_value); -static void MaxVehiclesChanged(int32 new_value); -static void InvalidateShipPathCache(int32 new_value); - -/* End - Callback Functions for the various settings */ - -/* Some settings do not need to be synchronised when playing in multiplayer. - * These include for example the GUI settings and will not be saved with the - * savegame. - * It is also a bit tricky since you would think that service_interval - * for example does not need to be synched. Every client assigns the - * service_interval value to the v->service_interval, meaning that every client - * assigns its own value. If the setting was company-based, that would mean that - * vehicles could decide on different moments that they are heading back to a - * service depot, causing desyncs on a massive scale. */ -static const SettingVariant _settings_table[] = { -[post-amble] -}; -[templates] -SDTG_BOOL = SDTG_BOOL($name, $flags, $var, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDTG_VAR = SDTG_VAR($name, $type, $flags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $var, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDTC_LIST = SDTC_LIST( $var, $type, $flags, $def, $from, $to, $cat, $extra, $startup), -SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDTC_SSTR = SDTC_SSTR( $var, $type, $flags, $def, $length, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDTC_VAR = SDTC_VAR( $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDT_BOOL = SDT_BOOL(GameSettings, $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDT_OMANY = SDT_OMANY(GameSettings, $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $load, $cat, $extra, $startup), -SDT_SSTR = SDT_SSTR(GameSettings, $var, $type, $flags, $def, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), - -[validation] -SDTG_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); -SDTG_OMANY = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); -SDTC_OMANY = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); -SDTC_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); -SDT_OMANY = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); -SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); - -[defaults] -flags = SF_NONE -interval = 0 -str = STR_NULL -strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT -strval = STR_NULL -pre_cb = nullptr -post_cb = nullptr -load = nullptr -from = SL_MIN_VERSION -to = SL_MAX_VERSION -cat = SC_ADVANCED -extra = 0 -startup = false - - - -; Saved settings variables. -; The next 18 entries are important for savegame compatibility. Do NOT remove those. See HandleOldDiffCustom() for more details. -[SDT_VAR] -var = difficulty.max_no_competitors -type = SLE_UINT8 -from = SLV_97 -def = 0 -min = 0 -max = MAX_COMPANIES - 1 -interval = 1 -post_cb = MaxNoAIsChange -cat = SC_BASIC - -[SDT_VAR] -var = difficulty.competitor_start_time -type = SLE_UINT8 -from = SLV_97 -to = SLV_110 -def = 2 -min = 0 -max = 3 - -[SDT_VAR] -var = difficulty.number_towns -type = SLE_UINT8 -from = SLV_97 -flags = SF_NEWGAME_ONLY -def = 2 -min = 0 -max = 4 -interval = 1 -strval = STR_NUM_VERY_LOW -cat = SC_BASIC - -[SDT_VAR] -var = difficulty.industry_density -type = SLE_UINT8 -from = SLV_97 -flags = SF_GUI_DROPDOWN -def = ID_END - 1 -min = 0 -max = ID_END - 1 -interval = 1 -str = STR_CONFIG_SETTING_INDUSTRY_DENSITY -strhelp = STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT -strval = STR_FUNDING_ONLY -cat = SC_BASIC - -[SDT_VAR] -var = difficulty.max_loan -type = SLE_UINT32 -from = SLV_97 -flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO | SF_GUI_CURRENCY -def = 300000 -min = 0 -max = 2000000000 -interval = 50000 -str = STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN -strhelp = STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT -strval = STR_JUST_CURRENCY_LONG -cat = SC_BASIC - -[SDT_VAR] -var = difficulty.initial_interest -type = SLE_UINT8 -from = SLV_97 -flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO -def = 2 -min = 2 -max = 4 -interval = 1 -str = STR_CONFIG_SETTING_INTEREST_RATE -strhelp = STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT -strval = STR_CONFIG_SETTING_PERCENTAGE - -[SDT_VAR] -var = difficulty.vehicle_costs -type = SLE_UINT8 -from = SLV_97 -flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO | SF_GUI_DROPDOWN -def = 0 -min = 0 -max = 2 -interval = 1 -str = STR_CONFIG_SETTING_RUNNING_COSTS -strhelp = STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT -strval = STR_SEA_LEVEL_LOW -cat = SC_BASIC - -[SDT_VAR] -var = difficulty.competitor_speed -type = SLE_UINT8 -from = SLV_97 -flags = SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 4 -interval = 1 -str = STR_CONFIG_SETTING_CONSTRUCTION_SPEED -strhelp = STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT -strval = STR_AI_SPEED_VERY_SLOW -cat = SC_BASIC - -[SDT_VAR] -var = difficulty.competitor_intelligence -type = SLE_UINT8 -from = SLV_97 -to = SLV_110 -def = 0 -min = 0 -max = 2 - -[SDT_VAR] -var = difficulty.vehicle_breakdowns -type = SLE_UINT8 -from = SLV_97 -flags = SF_GUI_DROPDOWN -def = 1 -min = 0 -max = 2 -interval = 1 -str = STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS -strhelp = STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT -strval = STR_DISASTER_NONE -cat = SC_BASIC - -[SDT_VAR] -var = difficulty.subsidy_multiplier -type = SLE_UINT8 -from = SLV_97 -flags = SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 3 -interval = 1 -str = STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER -strhelp = STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT -strval = STR_SUBSIDY_X1_5 - -[SDT_VAR] -var = difficulty.subsidy_duration -type = SLE_UINT16 -from = SLV_CUSTOM_SUBSIDY_DURATION -flags = SF_GUI_0_IS_SPECIAL -def = 1 -min = 0 -max = 5000 -interval = 1 -str = STR_CONFIG_SETTING_SUBSIDY_DURATION -strhelp = STR_CONFIG_SETTING_SUBSIDY_DURATION_HELPTEXT -strval = STR_CONFIG_SETTING_SUBSIDY_DURATION_VALUE - -[SDT_VAR] -var = difficulty.construction_cost -type = SLE_UINT8 -from = SLV_97 -flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO | SF_GUI_DROPDOWN -def = 0 -min = 0 -max = 2 -interval = 1 -str = STR_CONFIG_SETTING_CONSTRUCTION_COSTS -strhelp = STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT -strval = STR_SEA_LEVEL_LOW -cat = SC_BASIC - -[SDT_VAR] -var = difficulty.terrain_type -type = SLE_UINT8 -from = SLV_97 -flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY -def = 1 -min = 0 -max = 5 -interval = 1 -str = STR_CONFIG_SETTING_TERRAIN_TYPE -strhelp = STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT -strval = STR_TERRAIN_TYPE_VERY_FLAT -cat = SC_BASIC - -[SDT_VAR] -var = difficulty.quantity_sea_lakes -type = SLE_UINT8 -from = SLV_97 -flags = SF_NEWGAME_ONLY -def = 0 -min = 0 -max = 4 -interval = 1 -strval = STR_SEA_LEVEL_VERY_LOW -cat = SC_BASIC - -[SDT_BOOL] -var = difficulty.economy -from = SLV_97 -def = false -str = STR_CONFIG_SETTING_RECESSIONS -strhelp = STR_CONFIG_SETTING_RECESSIONS_HELPTEXT - -[SDT_BOOL] -var = difficulty.line_reverse_mode -from = SLV_97 -def = false -str = STR_CONFIG_SETTING_TRAIN_REVERSING -strhelp = STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT - -[SDT_BOOL] -var = difficulty.disasters -from = SLV_97 -def = false -str = STR_CONFIG_SETTING_DISASTERS -strhelp = STR_CONFIG_SETTING_DISASTERS_HELPTEXT -cat = SC_BASIC - -[SDT_VAR] -var = difficulty.town_council_tolerance -type = SLE_UINT8 -from = SLV_97 -flags = SF_GUI_DROPDOWN -def = 0 -min = 0 -max = 2 -interval = 1 -str = STR_CONFIG_SETTING_CITY_APPROVAL -strhelp = STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT -strval = STR_CITY_APPROVAL_PERMISSIVE -post_cb = DifficultyNoiseChange - -[SDTG_VAR] -name = ""diff_level"" -var = _old_diff_level -type = SLE_UINT8 -flags = SF_NOT_IN_CONFIG -from = SLV_97 -to = SLV_178 -def = 3 -min = 0 -max = 3 -cat = SC_BASIC - -; There are only 21 predefined town_name values (0-20), but you can have more with newgrf action F so allow -; these bigger values (21-255). Invalid values will fallback to english on use and (undefined string) in GUI. -[SDT_OMANY] -var = game_creation.town_name -type = SLE_UINT8 -from = SLV_97 -flags = SF_NO_NETWORK -def = 0 -max = 255 -full = _town_names -cat = SC_BASIC - -[SDT_OMANY] -var = game_creation.landscape -type = SLE_UINT8 -from = SLV_97 -flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY -def = 0 -max = 3 -full = _climates -load = ConvertLandscape -str = STR_CONFIG_SETTING_LANDSCAPE -strhelp = STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT -strval = STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE -cat = SC_BASIC - -[SDT_OMANY] -var = vehicle.road_side -type = SLE_UINT8 -from = SLV_97 -flags = SF_GUI_DROPDOWN | SF_NO_NETWORK -def = 1 -max = 1 -full = _roadsides -str = STR_CONFIG_SETTING_ROAD_SIDE -strhelp = STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT -strval = STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT -pre_cb = CheckRoadSide -cat = SC_BASIC - -; Construction - -[SDT_VAR] -var = construction.map_height_limit -type = SLE_UINT8 -from = SLV_194 -flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO | SF_GUI_0_IS_SPECIAL -def = 0 -min = MIN_MAP_HEIGHT_LIMIT -max = MAX_MAP_HEIGHT_LIMIT -interval = 1 -str = STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT -strhelp = STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_HELPTEXT -strval = STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_VALUE -pre_cb = CheckMaxHeightLevel -post_cb = [](auto) { InvalidateWindowClassesData(WC_SMALLMAP, 2); } -cat = SC_ADVANCED - -[SDT_VAR] -var = game_creation.heightmap_height -type = SLE_UINT8 -from = SLV_MAPGEN_SETTINGS_REVAMP -flags = SF_NEWGAME_ONLY -def = MAP_HEIGHT_LIMIT_AUTO_MINIMUM -min = MIN_HEIGHTMAP_HEIGHT -max = MAX_MAP_HEIGHT_LIMIT -interval = 1 - -[SDT_BOOL] -var = construction.build_on_slopes -flags = SF_NO_NETWORK -def = true -cat = SC_EXPERT - -[SDT_VAR] -var = construction.command_pause_level -type = SLE_UINT8 -from = SLV_154 -flags = SF_GUI_DROPDOWN | SF_NO_NETWORK -def = 1 -min = 0 -max = 3 -interval = 1 -str = STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL -strhelp = STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_HELPTEXT -strval = STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_NO_ACTIONS - -[SDT_VAR] -var = construction.terraform_per_64k_frames -type = SLE_UINT32 -from = SLV_156 -def = 64 << 16 -min = 0 -max = 1 << 30 -interval = 1 -cat = SC_EXPERT - -[SDT_VAR] -var = construction.terraform_frame_burst -type = SLE_UINT16 -from = SLV_156 -def = 4096 -min = 0 -max = 1 << 15 -interval = 1 -cat = SC_EXPERT - -[SDT_VAR] -var = construction.clear_per_64k_frames -type = SLE_UINT32 -from = SLV_156 -def = 64 << 16 -min = 0 -max = 1 << 30 -interval = 1 -cat = SC_EXPERT - -[SDT_VAR] -var = construction.clear_frame_burst -type = SLE_UINT16 -from = SLV_156 -def = 4096 -min = 0 -max = 1 << 15 -interval = 1 -cat = SC_EXPERT - -[SDT_VAR] -var = construction.tree_per_64k_frames -type = SLE_UINT32 -from = SLV_175 -def = 64 << 16 -min = 0 -max = 1 << 30 -interval = 1 -cat = SC_EXPERT - -[SDT_VAR] -var = construction.tree_frame_burst -type = SLE_UINT16 -from = SLV_175 -def = 4096 -min = 0 -max = 1 << 15 -interval = 1 -cat = SC_EXPERT - -[SDT_BOOL] -var = construction.autoslope -from = SLV_75 -def = true -str = STR_CONFIG_SETTING_AUTOSLOPE -strhelp = STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT -cat = SC_EXPERT - -[SDT_BOOL] -var = construction.extra_dynamite -def = true -str = STR_CONFIG_SETTING_EXTRADYNAMITE -strhelp = STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT - -[SDT_VAR] -var = construction.max_bridge_length -type = SLE_UINT16 -from = SLV_159 -flags = SF_NO_NETWORK -def = 64 -min = 1 -max = MAX_MAP_SIZE -interval = 1 -str = STR_CONFIG_SETTING_MAX_BRIDGE_LENGTH -strhelp = STR_CONFIG_SETTING_MAX_BRIDGE_LENGTH_HELPTEXT -strval = STR_CONFIG_SETTING_TILE_LENGTH - -[SDT_VAR] -var = construction.max_bridge_height -type = SLE_UINT8 -from = SLV_194 -flags = SF_NO_NETWORK -def = 12 -min = 1 -max = MAX_TILE_HEIGHT -interval = 1 -str = STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT -strhelp = STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT_HELPTEXT -strval = STR_JUST_COMMA -cat = SC_EXPERT - -[SDT_VAR] -var = construction.max_tunnel_length -type = SLE_UINT16 -from = SLV_159 -flags = SF_NO_NETWORK -def = 64 -min = 1 -max = MAX_MAP_SIZE -interval = 1 -str = STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH -strhelp = STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT -strval = STR_CONFIG_SETTING_TILE_LENGTH - -[SDT_VAR] -var = construction.train_signal_side -type = SLE_UINT8 -flags = SF_GUI_DROPDOWN | SF_NO_NETWORK -def = 1 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_SIGNALSIDE -strhelp = STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT -strval = STR_CONFIG_SETTING_SIGNALSIDE_LEFT -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC - -[SDT_BOOL] -var = station.never_expire_airports -flags = SF_NO_NETWORK -def = false -str = STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS -strhelp = STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT - -[SDT_VAR] -var = economy.town_layout -type = SLE_UINT8 -from = SLV_59 -flags = SF_GUI_DROPDOWN -def = TL_ORIGINAL -min = TL_BEGIN -max = NUM_TLS - 1 -interval = 1 -str = STR_CONFIG_SETTING_TOWN_LAYOUT -strhelp = STR_CONFIG_SETTING_TOWN_LAYOUT_HELPTEXT -strval = STR_CONFIG_SETTING_TOWN_LAYOUT_DEFAULT -post_cb = TownFoundingChanged - -[SDT_BOOL] -var = economy.allow_town_roads -from = SLV_113 -flags = SF_NO_NETWORK -def = true -str = STR_CONFIG_SETTING_ALLOW_TOWN_ROADS -strhelp = STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT - -[SDT_VAR] -var = economy.found_town -type = SLE_UINT8 -from = SLV_128 -flags = SF_GUI_DROPDOWN -def = TF_FORBIDDEN -min = TF_BEGIN -max = TF_END - 1 -interval = 1 -str = STR_CONFIG_SETTING_TOWN_FOUNDING -strhelp = STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT -strval = STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN -post_cb = TownFoundingChanged -cat = SC_BASIC - -[SDT_BOOL] -var = economy.allow_town_level_crossings -from = SLV_143 -flags = SF_NO_NETWORK -def = true -str = STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS -strhelp = STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT - -[SDT_VAR] -var = economy.town_cargogen_mode -type = SLE_UINT8 -from = SLV_TOWN_CARGOGEN -flags = SF_GUI_DROPDOWN -def = TCGM_BITCOUNT -min = TCGM_BEGIN -max = TCGM_END - 1 -interval = 1 -str = STR_CONFIG_SETTING_TOWN_CARGOGENMODE -strhelp = STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT -strval = STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL -cat = SC_ADVANCED - -; link graph - -[SDT_VAR] -var = linkgraph.recalc_interval -type = SLE_UINT16 -from = SLV_183 -def = 4 -min = 2 -max = 32 -interval = 2 -str = STR_CONFIG_SETTING_LINKGRAPH_INTERVAL -strval = STR_JUST_COMMA -strhelp = STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT -extra = offsetof(LinkGraphSettings, recalc_interval) - -[SDT_VAR] -var = linkgraph.recalc_time -type = SLE_UINT16 -from = SLV_183 -def = 16 -min = 1 -max = 4096 -interval = 1 -str = STR_CONFIG_SETTING_LINKGRAPH_TIME -strval = STR_JUST_COMMA -strhelp = STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT -extra = offsetof(LinkGraphSettings, recalc_time) - - -[SDT_VAR] -var = linkgraph.distribution_pax -type = SLE_UINT8 -from = SLV_183 -flags = SF_GUI_DROPDOWN -def = DT_MANUAL -min = DT_MIN -max = DT_MAX -interval = 1 -str = STR_CONFIG_SETTING_DISTRIBUTION_PAX -strval = STR_CONFIG_SETTING_DISTRIBUTION_MANUAL -strhelp = STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT -extra = offsetof(LinkGraphSettings, distribution_pax) - - -[SDT_VAR] -var = linkgraph.distribution_mail -type = SLE_UINT8 -from = SLV_183 -flags = SF_GUI_DROPDOWN -def = DT_MANUAL -min = DT_MIN -max = DT_MAX -interval = 1 -str = STR_CONFIG_SETTING_DISTRIBUTION_MAIL -strval = STR_CONFIG_SETTING_DISTRIBUTION_MANUAL -strhelp = STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT -extra = offsetof(LinkGraphSettings, distribution_mail) - - -[SDT_VAR] -var = linkgraph.distribution_armoured -type = SLE_UINT8 -from = SLV_183 -flags = SF_GUI_DROPDOWN -def = DT_MANUAL -min = DT_MIN -max = DT_MAX -interval = 1 -str = STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED -strval = STR_CONFIG_SETTING_DISTRIBUTION_MANUAL -strhelp = STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT -extra = offsetof(LinkGraphSettings, distribution_armoured) - - -[SDT_VAR] -var = linkgraph.distribution_default -type = SLE_UINT8 -from = SLV_183 -flags = SF_GUI_DROPDOWN -def = DT_MANUAL -min = DT_BEGIN -max = DT_MAX_NONSYMMETRIC -interval = 1 -str = STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT -strval = STR_CONFIG_SETTING_DISTRIBUTION_MANUAL -strhelp = STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT -extra = offsetof(LinkGraphSettings, distribution_default) - - -[SDT_VAR] -var = linkgraph.accuracy -type = SLE_UINT8 -from = SLV_183 -def = 16 -min = 2 -max = 64 -interval = 1 -str = STR_CONFIG_SETTING_LINKGRAPH_ACCURACY -strval = STR_JUST_COMMA -strhelp = STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT -extra = offsetof(LinkGraphSettings, accuracy) - - -[SDT_VAR] -var = linkgraph.demand_distance -type = SLE_UINT8 -from = SLV_183 -def = 100 -min = 0 -max = 255 -interval = 5 -str = STR_CONFIG_SETTING_DEMAND_DISTANCE -strval = STR_CONFIG_SETTING_PERCENTAGE -strhelp = STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT -extra = offsetof(LinkGraphSettings, demand_distance) - - -[SDT_VAR] -var = linkgraph.demand_size -type = SLE_UINT8 -from = SLV_183 -def = 100 -min = 0 -max = 100 -interval = 5 -str = STR_CONFIG_SETTING_DEMAND_SIZE -strval = STR_CONFIG_SETTING_PERCENTAGE -strhelp = STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT -extra = offsetof(LinkGraphSettings, demand_size) - - -[SDT_VAR] -var = linkgraph.short_path_saturation -type = SLE_UINT8 -from = SLV_183 -def = 80 -min = 0 -max = 250 -interval = 5 -str = STR_CONFIG_SETTING_SHORT_PATH_SATURATION -strval = STR_CONFIG_SETTING_PERCENTAGE -strhelp = STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT -extra = offsetof(LinkGraphSettings, short_path_saturation) - - -; Vehicles - -[SDT_VAR] -var = vehicle.train_acceleration_model -type = SLE_UINT8 -flags = SF_GUI_DROPDOWN -def = 1 -min = 0 -max = 1 -interval = 1 -str = STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL -strhelp = STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL_HELPTEXT -strval = STR_CONFIG_SETTING_ORIGINAL -post_cb = TrainAccelerationModelChanged - -[SDT_VAR] -var = vehicle.roadveh_acceleration_model -type = SLE_UINT8 -from = SLV_139 -flags = SF_GUI_DROPDOWN -def = 1 -min = 0 -max = 1 -interval = 1 -str = STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL -strhelp = STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL_HELPTEXT -strval = STR_CONFIG_SETTING_ORIGINAL -post_cb = RoadVehAccelerationModelChanged - -[SDT_VAR] -var = vehicle.train_slope_steepness -type = SLE_UINT8 -from = SLV_133 -def = 3 -min = 0 -max = 10 -interval = 1 -str = STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS -strhelp = STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT -strval = STR_CONFIG_SETTING_PERCENTAGE -post_cb = TrainSlopeSteepnessChanged -cat = SC_EXPERT - -[SDT_VAR] -var = vehicle.roadveh_slope_steepness -type = SLE_UINT8 -from = SLV_139 -def = 7 -min = 0 -max = 10 -interval = 1 -str = STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS -strhelp = STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT -strval = STR_CONFIG_SETTING_PERCENTAGE -post_cb = RoadVehSlopeSteepnessChanged -cat = SC_EXPERT - -[SDT_BOOL] -var = pf.forbid_90_deg -def = false -str = STR_CONFIG_SETTING_FORBID_90_DEG -strhelp = STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT -post_cb = InvalidateShipPathCache -cat = SC_EXPERT - -[SDT_VAR] -var = vehicle.max_train_length -type = SLE_UINT8 -from = SLV_159 -def = 7 -min = 1 -max = 64 -interval = 1 -str = STR_CONFIG_SETTING_TRAIN_LENGTH -strhelp = STR_CONFIG_SETTING_TRAIN_LENGTH_HELPTEXT -strval = STR_CONFIG_SETTING_TILE_LENGTH -cat = SC_BASIC - -[SDT_VAR] -var = vehicle.smoke_amount -type = SLE_UINT8 -from = SLV_145 -flags = SF_GUI_DROPDOWN -def = 1 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_SMOKE_AMOUNT -strhelp = STR_CONFIG_SETTING_SMOKE_AMOUNT_HELPTEXT -strval = STR_CONFIG_SETTING_NONE - -; path finder - -[SDT_BOOL] -var = pf.roadveh_queue -def = true -cat = SC_EXPERT - -[SDT_BOOL] -var = pf.new_pathfinding_all -to = SLV_87 -def = false -cat = SC_EXPERT - -[SDT_BOOL] -var = pf.yapf.ship_use_yapf -from = SLV_28 -to = SLV_87 -def = false -cat = SC_EXPERT - -[SDT_BOOL] -var = pf.yapf.road_use_yapf -from = SLV_28 -to = SLV_87 -def = true -cat = SC_EXPERT - -[SDT_BOOL] -var = pf.yapf.rail_use_yapf -from = SLV_28 -to = SLV_87 -def = true -cat = SC_EXPERT - -## -[SDT_VAR] -var = pf.pathfinder_for_trains -type = SLE_UINT8 -from = SLV_87 -flags = SF_GUI_DROPDOWN -def = 2 -min = 1 -max = 2 -interval = 1 -str = STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS -strhelp = STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS_HELPTEXT -strval = STR_CONFIG_SETTING_PATHFINDER_NPF -cat = SC_EXPERT - -[SDT_VAR] -var = pf.pathfinder_for_roadvehs -type = SLE_UINT8 -from = SLV_87 -flags = SF_GUI_DROPDOWN -def = 2 -min = 1 -max = 2 -interval = 1 -str = STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES -strhelp = STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES_HELPTEXT -strval = STR_CONFIG_SETTING_PATHFINDER_NPF -cat = SC_EXPERT - -[SDT_VAR] -var = pf.pathfinder_for_ships -type = SLE_UINT8 -from = SLV_87 -flags = SF_GUI_DROPDOWN -def = 2 -min = 1 -max = 2 -interval = 1 -str = STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS -strhelp = STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS_HELPTEXT -strval = STR_CONFIG_SETTING_PATHFINDER_NPF -post_cb = InvalidateShipPathCache -cat = SC_EXPERT - -[SDT_BOOL] -var = vehicle.never_expire_vehicles -flags = SF_NO_NETWORK -def = false -str = STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES -strhelp = STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT - -[SDT_VAR] -var = vehicle.max_trains -type = SLE_UINT16 -def = 500 -min = 0 -max = 5000 -str = STR_CONFIG_SETTING_MAX_TRAINS -strhelp = STR_CONFIG_SETTING_MAX_TRAINS_HELPTEXT -strval = STR_JUST_COMMA -post_cb = MaxVehiclesChanged -cat = SC_BASIC - -[SDT_VAR] -var = vehicle.max_roadveh -type = SLE_UINT16 -def = 500 -min = 0 -max = 5000 -str = STR_CONFIG_SETTING_MAX_ROAD_VEHICLES -strhelp = STR_CONFIG_SETTING_MAX_ROAD_VEHICLES_HELPTEXT -strval = STR_JUST_COMMA -post_cb = MaxVehiclesChanged -cat = SC_BASIC - -[SDT_VAR] -var = vehicle.max_aircraft -type = SLE_UINT16 -def = 200 -min = 0 -max = 5000 -str = STR_CONFIG_SETTING_MAX_AIRCRAFT -strhelp = STR_CONFIG_SETTING_MAX_AIRCRAFT_HELPTEXT -strval = STR_JUST_COMMA -post_cb = MaxVehiclesChanged -cat = SC_BASIC - -[SDT_VAR] -var = vehicle.max_ships -type = SLE_UINT16 -def = 300 -min = 0 -max = 5000 -str = STR_CONFIG_SETTING_MAX_SHIPS -strhelp = STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT -strval = STR_JUST_COMMA -post_cb = MaxVehiclesChanged -cat = SC_BASIC - -[SDTG_BOOL] -name = """" -flags = SF_NO_NETWORK -var = _old_vds.servint_ispercent -def = false -to = SLV_120 - -[SDTG_VAR] -name = """" -type = SLE_UINT16 -flags = SF_GUI_0_IS_SPECIAL -var = _old_vds.servint_trains -def = 150 -min = 5 -max = 800 -to = SLV_120 - -[SDTG_VAR] -name = """" -type = SLE_UINT16 -flags = SF_GUI_0_IS_SPECIAL -var = _old_vds.servint_roadveh -def = 150 -min = 5 -max = 800 -to = SLV_120 - -[SDTG_VAR] -name = """" -type = SLE_UINT16 -flags = SF_GUI_0_IS_SPECIAL -var = _old_vds.servint_ships -def = 360 -min = 5 -max = 800 -to = SLV_120 - -[SDTG_VAR] -name = """" -type = SLE_UINT16 -flags = SF_GUI_0_IS_SPECIAL -var = _old_vds.servint_aircraft -def = 150 -min = 5 -max = 800 -to = SLV_120 - -[SDT_BOOL] -var = order.no_servicing_if_no_breakdowns -def = true -str = STR_CONFIG_SETTING_NOSERVICE -strhelp = STR_CONFIG_SETTING_NOSERVICE_HELPTEXT - -[SDT_BOOL] -var = vehicle.wagon_speed_limits -flags = SF_NO_NETWORK -def = true -str = STR_CONFIG_SETTING_WAGONSPEEDLIMITS -strhelp = STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT -post_cb = UpdateConsists - -[SDT_BOOL] -var = vehicle.disable_elrails -from = SLV_38 -flags = SF_NO_NETWORK -def = false -str = STR_CONFIG_SETTING_DISABLE_ELRAILS -strhelp = STR_CONFIG_SETTING_DISABLE_ELRAILS_HELPTEXT -post_cb = SettingsDisableElrail -cat = SC_EXPERT - -[SDT_VAR] -var = vehicle.freight_trains -type = SLE_UINT8 -from = SLV_39 -flags = SF_NO_NETWORK -def = 1 -min = 1 -max = 255 -interval = 1 -str = STR_CONFIG_SETTING_FREIGHT_TRAINS -strhelp = STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT -strval = STR_JUST_COMMA -post_cb = UpdateConsists - -[SDT_VAR] -var = vehicle.plane_speed -type = SLE_UINT8 -from = SLV_90 -flags = SF_NO_NETWORK -def = 4 -min = 1 -max = 4 -str = STR_CONFIG_SETTING_PLANE_SPEED -strhelp = STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT -strval = STR_CONFIG_SETTING_PLANE_SPEED_VALUE - -[SDT_BOOL] -var = vehicle.dynamic_engines -from = SLV_95 -flags = SF_NO_NETWORK -def = true -pre_cb = CheckDynamicEngines -cat = SC_EXPERT - -[SDT_VAR] -var = vehicle.plane_crashes -type = SLE_UINT8 -from = SLV_138 -flags = SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 2 -interval = 1 -str = STR_CONFIG_SETTING_PLANE_CRASHES -strhelp = STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT -strval = STR_CONFIG_SETTING_PLANE_CRASHES_NONE -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.sg_full_load_any -from = SLV_22 -to = SLV_93 -def = true - -[SDT_BOOL] -var = order.improved_load -flags = SF_NO_NETWORK -def = true -cat = SC_EXPERT - -[SDT_BOOL] -var = order.selectgoods -def = true -cat = SC_EXPERT - -[SDTC_BOOL] -var = gui.sg_new_nonstop -from = SLV_22 -to = SLV_93 -def = false - -[SDT_VAR] -var = station.station_spread -type = SLE_UINT8 -def = 12 -min = 4 -max = 64 -str = STR_CONFIG_SETTING_STATION_SPREAD -strhelp = STR_CONFIG_SETTING_STATION_SPREAD_HELPTEXT -strval = STR_CONFIG_SETTING_TILE_LENGTH -post_cb = StationSpreadChanged -cat = SC_BASIC - -[SDT_BOOL] -var = order.serviceathelipad -def = true -str = STR_CONFIG_SETTING_SERVICEATHELIPAD -strhelp = STR_CONFIG_SETTING_SERVICEATHELIPAD_HELPTEXT -cat = SC_EXPERT - -[SDT_BOOL] -var = station.modified_catchment -def = true -str = STR_CONFIG_SETTING_CATCHMENT -strhelp = STR_CONFIG_SETTING_CATCHMENT_HELPTEXT -post_cb = StationCatchmentChanged -cat = SC_EXPERT - -[SDT_BOOL] -var = station.serve_neutral_industries -def = true -from = SLV_SERVE_NEUTRAL_INDUSTRIES -str = STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES -strhelp = STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT -post_cb = StationCatchmentChanged - -[SDT_BOOL] -var = order.gradual_loading -from = SLV_40 -flags = SF_NO_NETWORK -def = true -cat = SC_EXPERT - -[SDT_BOOL] -var = construction.road_stop_on_town_road -from = SLV_47 -def = true -str = STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD -strhelp = STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT -cat = SC_BASIC - -[SDT_BOOL] -var = construction.road_stop_on_competitor_road -from = SLV_114 -def = true -str = STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD -strhelp = STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT -cat = SC_BASIC - -[SDT_BOOL] -var = station.adjacent_stations -from = SLV_62 -def = true -cat = SC_EXPERT - -[SDT_BOOL] -var = economy.station_noise_level -from = SLV_96 -flags = SF_NO_NETWORK -def = false -str = STR_CONFIG_SETTING_NOISE_LEVEL -strhelp = STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT -post_cb = [](auto new_value) { InvalidateWindowClassesData(WC_TOWN_VIEW, new_value); } - -[SDT_BOOL] -var = station.distant_join_stations -from = SLV_106 -def = true -str = STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS -strhelp = STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT -post_cb = [](auto) { CloseWindowById(WC_SELECT_STATION, 0); } - -## -[SDT_BOOL] -var = economy.inflation -flags = SF_NO_NETWORK -def = false -str = STR_CONFIG_SETTING_INFLATION -strhelp = STR_CONFIG_SETTING_INFLATION_HELPTEXT -cat = SC_BASIC - -[SDT_VAR] -var = construction.raw_industry_construction -type = SLE_UINT8 -flags = SF_GUI_DROPDOWN -def = 0 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD -strhelp = STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT -strval = STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NONE -post_cb = [](auto) { InvalidateWindowData(WC_BUILD_INDUSTRY, 0); } -cat = SC_BASIC - -[SDT_VAR] -var = construction.industry_platform -type = SLE_UINT8 -from = SLV_148 -def = 1 -min = 0 -max = 4 -str = STR_CONFIG_SETTING_INDUSTRY_PLATFORM -strhelp = STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT -strval = STR_CONFIG_SETTING_TILE_LENGTH -cat = SC_EXPERT - -[SDT_BOOL] -var = economy.multiple_industry_per_town -def = false -str = STR_CONFIG_SETTING_MULTIPINDTOWN -strhelp = STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT - -[SDT_BOOL] -var = economy.bribe -def = true -str = STR_CONFIG_SETTING_BRIBE -strhelp = STR_CONFIG_SETTING_BRIBE_HELPTEXT -post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } -cat = SC_BASIC - -[SDT_BOOL] -var = economy.exclusive_rights -from = SLV_79 -def = true -str = STR_CONFIG_SETTING_ALLOW_EXCLUSIVE -strhelp = STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT -post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } -cat = SC_BASIC - -[SDT_BOOL] -var = economy.fund_buildings -from = SLV_165 -def = true -str = STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS -strhelp = STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT -post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } -cat = SC_BASIC - -[SDT_BOOL] -var = economy.fund_roads -from = SLV_160 -def = true -str = STR_CONFIG_SETTING_ALLOW_FUND_ROAD -strhelp = STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT -post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } -cat = SC_BASIC - -[SDT_BOOL] -var = economy.give_money -from = SLV_79 -def = true -str = STR_CONFIG_SETTING_ALLOW_GIVE_MONEY -strhelp = STR_CONFIG_SETTING_ALLOW_GIVE_MONEY_HELPTEXT -cat = SC_BASIC - -[SDT_VAR] -var = game_creation.snow_line_height -type = SLE_UINT8 -flags = SF_SCENEDIT_ONLY -def = DEF_SNOWLINE_HEIGHT -min = MIN_SNOWLINE_HEIGHT -max = MAX_SNOWLINE_HEIGHT -interval = 1 -str = STR_CONFIG_SETTING_SNOWLINE_HEIGHT -strhelp = STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT -strval = STR_JUST_COMMA -cat = SC_BASIC - -[SDT_VAR] -var = game_creation.snow_coverage -type = SLE_UINT8 -from = SLV_MAPGEN_SETTINGS_REVAMP -flags = SF_NEWGAME_ONLY -def = DEF_SNOW_COVERAGE -min = 0 -max = 100 -interval = 10 -str = STR_CONFIG_SETTING_SNOW_COVERAGE -strhelp = STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT -strval = STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE -cat = SC_BASIC - -[SDT_VAR] -var = game_creation.desert_coverage -type = SLE_UINT8 -from = SLV_MAPGEN_SETTINGS_REVAMP -flags = SF_NEWGAME_ONLY -def = DEF_DESERT_COVERAGE -min = 0 -max = 100 -interval = 10 -str = STR_CONFIG_SETTING_DESERT_COVERAGE -strhelp = STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT -strval = STR_CONFIG_SETTING_DESERT_COVERAGE_VALUE -cat = SC_BASIC - -[SDT_VAR] -var = game_creation.starting_year -type = SLE_INT32 -def = DEF_START_YEAR -min = MIN_YEAR -max = MAX_YEAR -interval = 1 -str = STR_CONFIG_SETTING_STARTING_YEAR -strval = STR_JUST_INT -cat = SC_BASIC - -[SDT_VAR] -var = game_creation.ending_year -type = SLE_INT32 -from = SLV_ENDING_YEAR -flags = SF_GUI_0_IS_SPECIAL -def = DEF_END_YEAR -min = MIN_YEAR -max = MAX_YEAR - 1 -interval = 1 -str = STR_CONFIG_SETTING_ENDING_YEAR -strhelp = STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT -strval = STR_CONFIG_SETTING_ENDING_YEAR_VALUE -cat = SC_ADVANCED - -[SDT_VAR] -var = economy.type -type = SLE_UINT8 -flags = SF_GUI_DROPDOWN -def = ET_SMOOTH -min = ET_BEGIN -max = ET_END - 1 -str = STR_CONFIG_SETTING_ECONOMY_TYPE -strhelp = STR_CONFIG_SETTING_ECONOMY_TYPE_HELPTEXT -strval = STR_CONFIG_SETTING_ECONOMY_TYPE_ORIGINAL -post_cb = [](auto) { InvalidateWindowClassesData(WC_INDUSTRY_VIEW); } -cat = SC_BASIC - -[SDT_BOOL] -var = economy.allow_shares -def = false -str = STR_CONFIG_SETTING_ALLOW_SHARES -strhelp = STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT -post_cb = [](auto) { InvalidateWindowClassesData(WC_COMPANY); } - -[SDT_VAR] -var = economy.min_years_for_shares -type = SLE_UINT8 -from = SLV_TRADING_AGE -def = 6 -min = 0 -max = 255 -interval = 1 -str = STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES -strhelp = STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT -strval = STR_JUST_INT -cat = SC_EXPERT - -[SDT_VAR] -var = economy.feeder_payment_share -type = SLE_UINT8 -from = SLV_134 -def = 75 -min = 0 -max = 100 -str = STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE -strhelp = STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT -strval = STR_CONFIG_SETTING_PERCENTAGE -cat = SC_EXPERT - -[SDT_VAR] -var = economy.town_growth_rate -type = SLE_UINT8 -from = SLV_54 -flags = SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 4 -str = STR_CONFIG_SETTING_TOWN_GROWTH -strhelp = STR_CONFIG_SETTING_TOWN_GROWTH_HELPTEXT -strval = STR_CONFIG_SETTING_TOWN_GROWTH_NONE - -[SDT_VAR] -var = economy.larger_towns -type = SLE_UINT8 -from = SLV_54 -flags = SF_GUI_0_IS_SPECIAL -def = 4 -min = 0 -max = 255 -interval = 1 -str = STR_CONFIG_SETTING_LARGER_TOWNS -strhelp = STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT -strval = STR_CONFIG_SETTING_LARGER_TOWNS_VALUE - -[SDT_VAR] -var = economy.initial_city_size -type = SLE_UINT8 -from = SLV_56 -def = 2 -min = 1 -max = 10 -interval = 1 -str = STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER -strhelp = STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT -strval = STR_JUST_COMMA - -[SDT_BOOL] -var = economy.mod_road_rebuild -from = SLV_77 -def = true -cat = SC_EXPERT - -[SDT_OMANY] -var = script.settings_profile -type = SLE_UINT8 -from = SLV_178 -flags = SF_GUI_DROPDOWN -def = SP_EASY -min = SP_EASY -max = SP_HARD -full = _settings_profiles -str = STR_CONFIG_SETTING_AI_PROFILE -strhelp = STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT -strval = STR_CONFIG_SETTING_AI_PROFILE_EASY -cat = SC_BASIC - -[SDT_BOOL] -var = ai.ai_in_multiplayer -def = true -str = STR_CONFIG_SETTING_AI_IN_MULTIPLAYER -strhelp = STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT -cat = SC_BASIC - -[SDT_BOOL] -var = ai.ai_disable_veh_train -def = false -str = STR_CONFIG_SETTING_AI_BUILDS_TRAINS -strhelp = STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT - -[SDT_BOOL] -var = ai.ai_disable_veh_roadveh -def = false -str = STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES -strhelp = STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT - -[SDT_BOOL] -var = ai.ai_disable_veh_aircraft -def = false -str = STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT -strhelp = STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT - -[SDT_BOOL] -var = ai.ai_disable_veh_ship -def = false -str = STR_CONFIG_SETTING_AI_BUILDS_SHIPS -strhelp = STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT - -[SDT_VAR] -var = script.script_max_opcode_till_suspend -type = SLE_UINT32 -from = SLV_107 -flags = SF_NEWGAME_ONLY -def = 10000 -min = 500 -max = 250000 -interval = 2500 -str = STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES -strhelp = STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT -strval = STR_JUST_COMMA -cat = SC_EXPERT - -[SDT_VAR] -var = script.script_max_memory_megabytes -type = SLE_UINT32 -from = SLV_SCRIPT_MEMLIMIT -flags = SF_NEWGAME_ONLY -def = 1024 -min = 8 -max = 8192 -interval = 8 -str = STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY -strhelp = STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT -strval = STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE -cat = SC_EXPERT - -## -[SDT_VAR] -var = vehicle.extend_vehicle_life -type = SLE_UINT8 -def = 0 -min = 0 -max = 100 -cat = SC_EXPERT - -[SDT_VAR] -var = economy.dist_local_authority -type = SLE_UINT8 -def = 20 -min = 5 -max = 60 -cat = SC_EXPERT - -[SDT_BOOL] -var = pf.reverse_at_signals -from = SLV_159 -def = false -str = STR_CONFIG_SETTING_REVERSE_AT_SIGNALS -strhelp = STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT - -[SDT_VAR] -var = pf.wait_oneway_signal -type = SLE_UINT8 -def = 15 -min = 2 -max = 255 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.wait_twoway_signal -type = SLE_UINT8 -def = 41 -min = 2 -max = 255 -cat = SC_EXPERT - -[SDT_VAR] -var = economy.town_noise_population[0] -type = SLE_UINT16 -from = SLV_96 -def = 800 -min = 200 -max = 65535 -cat = SC_EXPERT - -[SDT_VAR] -var = economy.town_noise_population[1] -type = SLE_UINT16 -from = SLV_96 -def = 2000 -min = 400 -max = 65535 -cat = SC_EXPERT - -[SDT_VAR] -var = economy.town_noise_population[2] -type = SLE_UINT16 -from = SLV_96 -def = 4000 -min = 800 -max = 65535 -cat = SC_EXPERT - -[SDT_BOOL] -var = economy.infrastructure_maintenance -from = SLV_166 -def = false -str = STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE -strhelp = STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT -post_cb = [](auto) { InvalidateWindowClassesData(WC_COMPANY_INFRASTRUCTURE); } -cat = SC_BASIC - -## -[SDT_VAR] -var = pf.wait_for_pbs_path -type = SLE_UINT8 -from = SLV_100 -def = 30 -min = 2 -max = 255 -cat = SC_EXPERT - -[SDT_BOOL] -var = pf.reserve_paths -from = SLV_100 -def = false -cat = SC_EXPERT - -[SDT_VAR] -var = pf.path_backoff_interval -type = SLE_UINT8 -from = SLV_100 -def = 20 -min = 1 -max = 255 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_max_search_nodes -type = SLE_UINT -def = 10000 -min = 500 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_rail_firstred_penalty -type = SLE_UINT -def = 10 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_rail_firstred_exit_penalty -type = SLE_UINT -def = 100 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_rail_lastred_penalty -type = SLE_UINT -def = 10 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_rail_station_penalty -type = SLE_UINT -def = 1 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_rail_slope_penalty -type = SLE_UINT -def = 1 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_rail_curve_penalty -type = SLE_UINT -def = 1 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_rail_depot_reverse_penalty -type = SLE_UINT -def = 50 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_rail_pbs_cross_penalty -type = SLE_UINT -from = SLV_100 -def = 3 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_rail_pbs_signal_back_penalty -type = SLE_UINT -from = SLV_100 -def = 15 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_buoy_penalty -type = SLE_UINT -def = 2 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_water_curve_penalty -type = SLE_UINT -def = 1 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_road_curve_penalty -type = SLE_UINT -def = 1 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_crossing_penalty -type = SLE_UINT -def = 3 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_road_drive_through_penalty -type = SLE_UINT -from = SLV_47 -def = 8 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_road_dt_occupied_penalty -type = SLE_UINT -from = SLV_130 -def = 8 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.npf_road_bay_occupied_penalty -type = SLE_UINT -from = SLV_130 -def = 15 * NPF_TILE_LENGTH -min = 0 -max = 100000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.npf.maximum_go_to_depot_penalty -type = SLE_UINT -from = SLV_131 -def = 20 * NPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -## -[SDT_BOOL] -var = pf.yapf.disable_node_optimization -from = SLV_28 -def = false -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.max_search_nodes -type = SLE_UINT -from = SLV_28 -def = 10000 -min = 500 -max = 1000000 -cat = SC_EXPERT - -[SDT_BOOL] -var = pf.yapf.rail_firstred_twoway_eol -from = SLV_28 -def = false -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_firstred_penalty -type = SLE_UINT -from = SLV_28 -def = 10 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_firstred_exit_penalty -type = SLE_UINT -from = SLV_28 -def = 100 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_lastred_penalty -type = SLE_UINT -from = SLV_28 -def = 10 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_lastred_exit_penalty -type = SLE_UINT -from = SLV_28 -def = 100 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_station_penalty -type = SLE_UINT -from = SLV_28 -def = 10 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_slope_penalty -type = SLE_UINT -from = SLV_28 -def = 2 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_curve45_penalty -type = SLE_UINT -from = SLV_28 -def = 1 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_curve90_penalty -type = SLE_UINT -from = SLV_28 -def = 6 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_depot_reverse_penalty -type = SLE_UINT -from = SLV_28 -def = 50 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_crossing_penalty -type = SLE_UINT -from = SLV_28 -def = 3 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_look_ahead_max_signals -type = SLE_UINT -from = SLV_28 -def = 10 -min = 1 -max = 100 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_look_ahead_signal_p0 -type = SLE_INT -from = SLV_28 -def = 500 -min = -1000000 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_look_ahead_signal_p1 -type = SLE_INT -from = SLV_28 -def = -100 -min = -1000000 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_look_ahead_signal_p2 -type = SLE_INT -from = SLV_28 -def = 5 -min = -1000000 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_pbs_cross_penalty -type = SLE_UINT -from = SLV_100 -def = 3 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_pbs_station_penalty -type = SLE_UINT -from = SLV_100 -def = 8 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_pbs_signal_back_penalty -type = SLE_UINT -from = SLV_100 -def = 15 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_doubleslip_penalty -type = SLE_UINT -from = SLV_100 -def = 1 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_longer_platform_penalty -type = SLE_UINT -from = SLV_33 -def = 8 * YAPF_TILE_LENGTH -min = 0 -max = 20000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_longer_platform_per_tile_penalty -type = SLE_UINT -from = SLV_33 -def = 0 * YAPF_TILE_LENGTH -min = 0 -max = 20000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_shorter_platform_penalty -type = SLE_UINT -from = SLV_33 -def = 40 * YAPF_TILE_LENGTH -min = 0 -max = 20000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.rail_shorter_platform_per_tile_penalty -type = SLE_UINT -from = SLV_33 -def = 0 * YAPF_TILE_LENGTH -min = 0 -max = 20000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.road_slope_penalty -type = SLE_UINT -from = SLV_33 -def = 2 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.road_curve_penalty -type = SLE_UINT -from = SLV_33 -def = 1 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.road_crossing_penalty -type = SLE_UINT -from = SLV_33 -def = 3 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.road_stop_penalty -type = SLE_UINT -from = SLV_47 -def = 8 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.road_stop_occupied_penalty -type = SLE_UINT -from = SLV_130 -def = 8 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.road_stop_bay_occupied_penalty -type = SLE_UINT -from = SLV_130 -def = 15 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.maximum_go_to_depot_penalty -type = SLE_UINT -from = SLV_131 -def = 20 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.ship_curve45_penalty -type = SLE_UINT -from = SLV_SHIP_CURVE_PENALTY -def = 1 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -[SDT_VAR] -var = pf.yapf.ship_curve90_penalty -type = SLE_UINT -from = SLV_SHIP_CURVE_PENALTY -def = 6 * YAPF_TILE_LENGTH -min = 0 -max = 1000000 -cat = SC_EXPERT - -## -[SDT_VAR] -var = game_creation.land_generator -type = SLE_UINT8 -from = SLV_30 -flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY -def = 1 -min = 0 -max = 1 -str = STR_CONFIG_SETTING_LAND_GENERATOR -strhelp = STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT -strval = STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL - -[SDT_VAR] -var = game_creation.oil_refinery_limit -type = SLE_UINT8 -from = SLV_30 -def = 32 -min = 12 -max = 128 -str = STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE -strval = STR_CONFIG_SETTING_TILE_LENGTH -strhelp = STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT - -[SDT_VAR] -var = game_creation.tgen_smoothness -type = SLE_UINT8 -from = SLV_30 -flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY -def = 1 -min = TGEN_SMOOTHNESS_BEGIN -max = TGEN_SMOOTHNESS_END - 1 -str = STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN -strhelp = STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT -strval = STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH -cat = SC_BASIC - -[SDT_VAR] -var = game_creation.variety -type = SLE_UINT8 -from = SLV_197 -flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY -def = 0 -min = 0 -max = 5 -str = STR_CONFIG_SETTING_VARIETY -strhelp = STR_CONFIG_SETTING_VARIETY_HELPTEXT -strval = STR_VARIETY_NONE - -[SDT_VAR] -var = game_creation.generation_seed -type = SLE_UINT32 -from = SLV_30 -def = GENERATE_NEW_SEED -min = 0 -max = UINT32_MAX -cat = SC_EXPERT - -[SDT_VAR] -var = game_creation.tree_placer -type = SLE_UINT8 -from = SLV_30 -flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY | SF_SCENEDIT_TOO -def = 2 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_TREE_PLACER -strhelp = STR_CONFIG_SETTING_TREE_PLACER_HELPTEXT -strval = STR_CONFIG_SETTING_TREE_PLACER_NONE -cat = SC_BASIC - -[SDT_VAR] -var = game_creation.heightmap_rotation -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 0 -min = 0 -max = 1 -str = STR_CONFIG_SETTING_HEIGHTMAP_ROTATION -strval = STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE -cat = SC_BASIC - -[SDT_VAR] -var = game_creation.se_flat_world_height -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 1 -min = 0 -max = 15 -str = STR_CONFIG_SETTING_SE_FLAT_WORLD_HEIGHT -strval = STR_JUST_COMMA -cat = SC_BASIC - -## -[SDT_VAR] -var = game_creation.map_x -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 8 -min = MIN_MAP_SIZE_BITS -max = MAX_MAP_SIZE_BITS -cat = SC_BASIC - -[SDT_VAR] -var = game_creation.map_y -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 8 -min = MIN_MAP_SIZE_BITS -max = MAX_MAP_SIZE_BITS -cat = SC_BASIC - -[SDT_BOOL] -var = construction.freeform_edges -from = SLV_111 -def = true -pre_cb = CheckFreeformEdges -post_cb = UpdateFreeformEdges -cat = SC_EXPERT - -[SDT_VAR] -var = game_creation.water_borders -type = SLE_UINT8 -from = SLV_111 -def = 15 -min = 0 -max = 16 - -[SDT_VAR] -var = game_creation.custom_town_number -type = SLE_UINT16 -from = SLV_115 -def = 1 -min = 1 -max = 5000 -cat = SC_BASIC - -[SDT_VAR] -var = construction.extra_tree_placement -type = SLE_UINT8 -from = SLV_132 -flags = SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 3 -str = STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT -strhelp = STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT -strval = STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_SPREAD -cat = SC_BASIC - -[SDT_VAR] -var = game_creation.custom_terrain_type -type = SLE_UINT8 -from = SLV_MAPGEN_SETTINGS_REVAMP -flags = SF_NEWGAME_ONLY -def = MAP_HEIGHT_LIMIT_AUTO_MINIMUM -min = MIN_CUSTOM_TERRAIN_TYPE -max = MAX_MAP_HEIGHT_LIMIT -interval = 1 - -[SDT_VAR] -var = game_creation.custom_sea_level -type = SLE_UINT8 -from = SLV_149 -def = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE -min = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE -max = CUSTOM_SEA_LEVEL_MAX_PERCENTAGE -cat = SC_BASIC - -[SDT_VAR] -var = game_creation.min_river_length -type = SLE_UINT8 -from = SLV_163 -def = 16 -min = 2 -max = 255 -cat = SC_EXPERT - -[SDT_VAR] -var = game_creation.river_route_random -type = SLE_UINT8 -from = SLV_163 -def = 5 -min = 1 -max = 255 -cat = SC_EXPERT - -[SDT_VAR] -var = game_creation.amount_of_rivers -type = SLE_UINT8 -from = SLV_163 -flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY -def = 2 -min = 0 -max = 3 -str = STR_CONFIG_SETTING_RIVER_AMOUNT -strhelp = STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT -strval = STR_RIVERS_NONE - -; locale - -[SDT_OMANY] -var = locale.currency -type = SLE_UINT8 -from = SLV_97 -flags = SF_NO_NETWORK_SYNC -def = 0 -max = CURRENCY_END - 1 -full = _locale_currencies -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC - -[SDTG_OMANY] -name = ""units"" -var = _old_units -type = SLE_UINT8 -from = SLV_97 -to = SLV_184 -flags = SF_NOT_IN_CONFIG -def = 1 -max = 2 -full = _locale_units -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC - -[SDT_OMANY] -var = locale.units_velocity -type = SLE_UINT8 -from = SLV_184 -flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 3 -full = _locale_units -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC -str = STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY -strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT -strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL - -[SDT_OMANY] -var = locale.units_power -type = SLE_UINT8 -from = SLV_184 -flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 2 -full = _locale_units -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC -str = STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER -strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_HELPTEXT -strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_IMPERIAL - -[SDT_OMANY] -var = locale.units_weight -type = SLE_UINT8 -from = SLV_184 -flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 2 -full = _locale_units -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC -str = STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT -strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_HELPTEXT -strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_IMPERIAL - -[SDT_OMANY] -var = locale.units_volume -type = SLE_UINT8 -from = SLV_184 -flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 2 -full = _locale_units -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC -str = STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME -strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_HELPTEXT -strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_IMPERIAL - -[SDT_OMANY] -var = locale.units_force -type = SLE_UINT8 -from = SLV_184 -flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -max = 2 -full = _locale_units -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC -str = STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE -strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_HELPTEXT -strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_IMPERIAL - -[SDT_OMANY] -var = locale.units_height -type = SLE_UINT8 -from = SLV_184 -flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 2 -full = _locale_units -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC -str = STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT -strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT -strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL - -[SDT_SSTR] -var = locale.digit_group_separator -type = SLE_STRQ -from = SLV_118 -flags = SF_NO_NETWORK_SYNC -def = nullptr -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC - -[SDT_SSTR] -var = locale.digit_group_separator_currency -type = SLE_STRQ -from = SLV_118 -flags = SF_NO_NETWORK_SYNC -def = nullptr -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC - -[SDT_SSTR] -var = locale.digit_decimal_separator -type = SLE_STRQ -from = SLV_126 -flags = SF_NO_NETWORK_SYNC -def = nullptr -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC - - -;*************************************************************************** -; Unsaved setting variables. - -[SDTC_OMANY] -var = gui.autosave -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 4 -full = _autosave_interval -str = STR_CONFIG_SETTING_AUTOSAVE -strhelp = STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT -strval = STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.threaded_saves -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -cat = SC_EXPERT - -[SDTC_OMANY] -var = gui.date_format_in_default_names -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -max = 2 -full = _savegame_date -str = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES -strhelp = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT -strval = STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_LONG - -[SDTC_BOOL] -var = gui.show_finances -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_SHOWFINANCES -strhelp = STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT -cat = SC_BASIC - -[SDTC_VAR] -var = gui.auto_scrolling -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 0 -min = 0 -max = 3 -str = STR_CONFIG_SETTING_AUTOSCROLL -strhelp = STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT -strval = STR_CONFIG_SETTING_AUTOSCROLL_DISABLED -cat = SC_BASIC - -[SDTC_VAR] -ifdef = __EMSCRIPTEN__ -var = gui.scroll_mode -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 3 -str = STR_CONFIG_SETTING_SCROLLMODE -strhelp = STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT -strval = STR_CONFIG_SETTING_SCROLLMODE_DEFAULT -cat = SC_BASIC - -[SDTC_VAR] -ifndef = __EMSCRIPTEN__ -var = gui.scroll_mode -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 0 -min = 0 -max = 3 -str = STR_CONFIG_SETTING_SCROLLMODE -strhelp = STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT -strval = STR_CONFIG_SETTING_SCROLLMODE_DEFAULT -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.smooth_scroll -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -str = STR_CONFIG_SETTING_SMOOTH_SCROLLING -strhelp = STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT - -[SDTC_BOOL] -var = gui.right_mouse_wnd_close -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -str = STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE -strhelp = STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT -cat = SC_BASIC - -; We might need to emulate a right mouse button on mac -[SDTC_VAR] -ifdef = __APPLE__ -var = gui.right_mouse_btn_emulation -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 0 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU -strhelp = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT -strval = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.measure_tooltip -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_MEASURE_TOOLTIP -strhelp = STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT -cat = SC_BASIC - -[SDTC_VAR] -var = gui.errmsg_duration -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 5 -min = 0 -max = 20 -str = STR_CONFIG_SETTING_ERRMSG_DURATION -strhelp = STR_CONFIG_SETTING_ERRMSG_DURATION_HELPTEXT -strval = STR_CONFIG_SETTING_ERRMSG_DURATION_VALUE - -[SDTC_VAR] -var = gui.hover_delay_ms -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL -def = 250 -min = 50 -max = 6000 -interval = 50 -str = STR_CONFIG_SETTING_HOVER_DELAY -strhelp = STR_CONFIG_SETTING_HOVER_DELAY_HELPTEXT -strval = STR_CONFIG_SETTING_HOVER_DELAY_VALUE - -[SDTC_OMANY] -var = gui.osk_activation -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -str = STR_CONFIG_SETTING_OSK_ACTIVATION -strhelp = STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT -strval = STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED -flags = SF_GUI_DROPDOWN -full = _osk_activation -def = 1 -min = 0 -max = 3 -cat = SC_BASIC - -[SDTC_VAR] -var = gui.toolbar_pos -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_TOOLBAR_POS -strhelp = STR_CONFIG_SETTING_TOOLBAR_POS_HELPTEXT -strval = STR_CONFIG_SETTING_HORIZONTAL_POS_LEFT -post_cb = v_PositionMainToolbar -cat = SC_BASIC - -[SDTC_VAR] -var = gui.statusbar_pos -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_STATUSBAR_POS -strhelp = STR_CONFIG_SETTING_STATUSBAR_POS_HELPTEXT -strval = STR_CONFIG_SETTING_HORIZONTAL_POS_LEFT -post_cb = v_PositionStatusbar -cat = SC_BASIC - -[SDTC_VAR] -var = gui.window_snap_radius -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL -def = 10 -min = 1 -max = 32 -str = STR_CONFIG_SETTING_SNAP_RADIUS -strhelp = STR_CONFIG_SETTING_SNAP_RADIUS_HELPTEXT -strval = STR_CONFIG_SETTING_SNAP_RADIUS_VALUE -cat = SC_EXPERT - -[SDTC_VAR] -var = gui.window_soft_limit -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL -def = 20 -min = 5 -max = 255 -interval = 1 -str = STR_CONFIG_SETTING_SOFT_LIMIT -strhelp = STR_CONFIG_SETTING_SOFT_LIMIT_HELPTEXT -strval = STR_CONFIG_SETTING_SOFT_LIMIT_VALUE -cat = SC_EXPERT - -[SDTC_VAR] -var = gui.zoom_min -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = ZOOM_LVL_MIN -min = ZOOM_LVL_MIN -max = ZOOM_LVL_OUT_4X -str = STR_CONFIG_SETTING_ZOOM_MIN -strhelp = STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT -strval = STR_CONFIG_SETTING_ZOOM_LVL_MIN -post_cb = ZoomMinMaxChanged -startup = true - -[SDTC_VAR] -var = gui.zoom_max -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = ZOOM_LVL_MAX -min = ZOOM_LVL_OUT_8X -max = ZOOM_LVL_MAX -str = STR_CONFIG_SETTING_ZOOM_MAX -strhelp = STR_CONFIG_SETTING_ZOOM_MAX_HELPTEXT -strval = STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X -post_cb = ZoomMinMaxChanged -startup = true - -[SDTC_VAR] -var = gui.sprite_zoom_min -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = ZOOM_LVL_MIN -min = ZOOM_LVL_MIN -max = ZOOM_LVL_OUT_4X -str = STR_CONFIG_SETTING_SPRITE_ZOOM_MIN -strhelp = STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT -strval = STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_MIN -post_cb = SpriteZoomMinChanged - -[SDTC_BOOL] -var = gui.population_in_label -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_POPULATION_IN_LABEL -strhelp = STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT -post_cb = [](auto) { UpdateAllTownVirtCoords(); } - -[SDTC_BOOL] -var = gui.link_terraform_toolbar -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -str = STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR -strhelp = STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR_HELPTEXT - -[SDTC_VAR] -var = gui.smallmap_land_colour -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 0 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR -strhelp = STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT -strval = STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN -post_cb = RedrawSmallmap - -[SDTC_VAR] -var = gui.liveries -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_LIVERIES -strhelp = STR_CONFIG_SETTING_LIVERIES_HELPTEXT -strval = STR_CONFIG_SETTING_LIVERIES_NONE -post_cb = InvalidateCompanyLiveryWindow - -[SDTC_VAR] -var = gui.starting_colour -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = COLOUR_END -min = 0 -max = COLOUR_END -str = STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR -strhelp = STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT -strval = STR_COLOUR_DARK_BLUE - -[SDTC_BOOL] -var = gui.auto_remove_signals -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -str = STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS -strhelp = STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS_HELPTEXT -cat = SC_ADVANCED - -[SDTC_BOOL] -var = gui.prefer_teamchat -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -str = STR_CONFIG_SETTING_PREFER_TEAMCHAT -strhelp = STR_CONFIG_SETTING_PREFER_TEAMCHAT_HELPTEXT -cat = SC_BASIC - -[SDTC_VAR] -var = gui.scrollwheel_scrolling -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 0 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING -strhelp = STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING_HELPTEXT -strval = STR_CONFIG_SETTING_SCROLLWHEEL_ZOOM -cat = SC_BASIC - -[SDTC_VAR] -var = gui.scrollwheel_multiplier -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 5 -min = 1 -max = 15 -interval = 1 -str = STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER -strhelp = STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER_HELPTEXT -strval = STR_JUST_COMMA -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.pause_on_newgame -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -str = STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME -strhelp = STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT -cat = SC_BASIC - -[SDTC_VAR] -var = gui.advanced_vehicle_list -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS -strhelp = STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT -strval = STR_CONFIG_SETTING_COMPANIES_OFF - -[SDTC_BOOL] -var = gui.timetable_in_ticks -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -str = STR_CONFIG_SETTING_TIMETABLE_IN_TICKS -strhelp = STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT -post_cb = [](auto) { InvalidateWindowClassesData(WC_VEHICLE_TIMETABLE, VIWD_MODIFY_ORDERS); } -cat = SC_EXPERT - -[SDTC_BOOL] -var = gui.timetable_arrival_departure -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE -strhelp = STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT -post_cb = [](auto) { InvalidateWindowClassesData(WC_VEHICLE_TIMETABLE, VIWD_MODIFY_ORDERS); } - -[SDTC_BOOL] -var = gui.quick_goto -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_QUICKGOTO -strhelp = STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT -cat = SC_BASIC - -[SDTC_VAR] -var = gui.loading_indicators -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_LOADING_INDICATORS -strhelp = STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT -strval = STR_CONFIG_SETTING_COMPANIES_OFF -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC - -[SDTC_VAR] -var = gui.default_rail_type -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 0 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE -strhelp = STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT -strval = STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.enable_signal_gui -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI -strhelp = STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI_HELPTEXT -post_cb = CloseSignalGUI -cat = SC_EXPERT - -[SDTC_VAR] -var = gui.coloured_news_year -type = SLE_INT32 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 2000 -min = MIN_YEAR -max = MAX_YEAR -interval = 1 -str = STR_CONFIG_SETTING_COLOURED_NEWS_YEAR -strhelp = STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT -strval = STR_JUST_INT -cat = SC_EXPERT - -[SDTC_VAR] -var = gui.drag_signals_density -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 4 -min = 1 -max = 20 -str = STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY -strhelp = STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT -strval = STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE -post_cb = [](auto) { InvalidateWindowData(WC_BUILD_SIGNAL, 0); } -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.drag_signals_fixed_distance -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -str = STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE -strhelp = STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT -cat = SC_EXPERT - -[SDTC_VAR] -var = gui.semaphore_build_before -type = SLE_INT32 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 1950 -min = MIN_YEAR -max = MAX_YEAR -interval = 1 -str = STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE -strhelp = STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT -strval = STR_JUST_INT -post_cb = ResetSignalVariant - -[SDTC_BOOL] -var = gui.vehicle_income_warn -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_WARN_INCOME_LESS -strhelp = STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT -cat = SC_BASIC - -[SDTC_VAR] -var = gui.order_review_system -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 2 -str = STR_CONFIG_SETTING_ORDER_REVIEW -strhelp = STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT -strval = STR_CONFIG_SETTING_ORDER_REVIEW_OFF -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.lost_vehicle_warn -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_WARN_LOST_VEHICLE -strhelp = STR_CONFIG_SETTING_WARN_LOST_VEHICLE_HELPTEXT - -[SDTC_BOOL] -var = gui.new_nonstop -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT -strhelp = STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT -cat = SC_BASIC - -[SDTC_VAR] -var = gui.stop_location -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 2 -interval = 1 -str = STR_CONFIG_SETTING_STOP_LOCATION -strhelp = STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT -strval = STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.keep_all_autosave -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false - -[SDTC_BOOL] -var = gui.autosave_on_exit -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.autosave_on_network_disconnect -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -cat = SC_EXPERT - -[SDTC_VAR] -var = gui.max_num_autosaves -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 16 -min = 0 -max = 255 - -[SDTC_BOOL] -var = gui.auto_euro -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true - -[SDTC_VAR] -var = gui.news_message_timeout -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 2 -min = 1 -max = 255 - -[SDTC_BOOL] -var = gui.show_track_reservation -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION -strhelp = STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION_HELPTEXT -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_BASIC - -[SDTC_VAR] -var = gui.default_signal_type -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -min = 0 -max = 2 -interval = 1 -str = STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE -strhelp = STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE_HELPTEXT -strval = STR_CONFIG_SETTING_DEFAULT_SIGNAL_NORMAL -cat = SC_BASIC - -[SDTC_VAR] -var = gui.cycle_signal_types -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -min = 0 -max = 2 -interval = 1 -str = STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES -strhelp = STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT -strval = STR_CONFIG_SETTING_CYCLE_SIGNAL_NORMAL - -[SDTC_VAR] -var = gui.station_numtracks -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 1 -min = 1 -max = 7 - -[SDTC_VAR] -var = gui.station_platlength -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 5 -min = 1 -max = 7 -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.station_dragdrop -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.station_show_coverage -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.persistent_buildingtools -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS -strhelp = STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.expenses_layout -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_EXPENSES_LAYOUT -strhelp = STR_CONFIG_SETTING_EXPENSES_LAYOUT_HELPTEXT -post_cb = [](auto) { MarkWholeScreenDirty(); } - -[SDTC_VAR] -var = gui.station_gui_group_order -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 0 -min = 0 -max = 5 -interval = 1 - -[SDTC_VAR] -var = gui.station_gui_sort_by -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 0 -min = 0 -max = 3 -interval = 1 - -[SDTC_VAR] -var = gui.station_gui_sort_order -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 0 -min = 0 -max = 1 -interval = 1 - -[SDTC_VAR] -var = gui.missing_strings_threshold -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 25 -min = 1 -max = UINT8_MAX -cat = SC_EXPERT - -[SDTC_VAR] -var = gui.graph_line_thickness -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 3 -min = 1 -max = 5 -str = STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS -strhelp = STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT -strval = STR_JUST_COMMA -post_cb = [](auto) { MarkWholeScreenDirty(); } - -[SDTC_BOOL] -var = gui.show_newgrf_name -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -str = STR_CONFIG_SETTING_SHOW_NEWGRF_NAME -strhelp = STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT -post_cb = [](auto) { MarkWholeScreenDirty(); } -cat = SC_ADVANCED - -; For the dedicated build we'll enable dates in logs by default. -[SDTC_BOOL] -ifdef = DEDICATED -var = gui.show_date_in_logs -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true - -[SDTC_BOOL] -ifndef = DEDICATED -var = gui.show_date_in_logs -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false - -[SDTC_VAR] -var = gui.settings_restriction_mode -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 0 -min = 0 -max = 2 - -[SDTC_VAR] -var = gui.developer -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 1 -min = 0 -max = 2 -cat = SC_EXPERT - -[SDTC_BOOL] -var = gui.newgrf_developer_tools -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -post_cb = InvalidateNewGRFChangeWindows -cat = SC_EXPERT - -[SDTC_BOOL] -var = gui.ai_developer_tools -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -post_cb = [](auto) { InvalidateWindowClassesData(WC_AI_SETTINGS); } -cat = SC_EXPERT - -[SDTC_BOOL] -var = gui.scenario_developer -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -post_cb = InvalidateNewGRFChangeWindows - -[SDTC_BOOL] -var = gui.newgrf_show_old_versions -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -cat = SC_EXPERT - -[SDTC_VAR] -var = gui.newgrf_default_palette -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -min = 0 -max = 1 -post_cb = UpdateNewGRFConfigPalette -cat = SC_EXPERT - -[SDTC_VAR] -var = gui.console_backlog_timeout -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 100 -min = 10 -max = 65500 - -[SDTC_VAR] -var = gui.console_backlog_length -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 100 -min = 10 -max = 65500 - -[SDTC_VAR] -var = gui.refresh_rate -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 60 -min = 10 -max = 1000 -cat = SC_EXPERT -startup = true - -[SDTC_VAR] -var = gui.fast_forward_speed_limit -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NO_NETWORK -def = 2500 -min = 0 -max = 50000 -interval = 10 -str = STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT -strhelp = STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_HELPTEXT -strval = STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_VAL -cat = SC_BASIC - -[SDTC_BOOL] -var = sound.news_ticker -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_SOUND_TICKER -strhelp = STR_CONFIG_SETTING_SOUND_TICKER_HELPTEXT - -[SDTC_BOOL] -var = sound.news_full -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_SOUND_NEWS -strhelp = STR_CONFIG_SETTING_SOUND_NEWS_HELPTEXT - -[SDTC_BOOL] -var = sound.new_year -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_SOUND_NEW_YEAR -strhelp = STR_CONFIG_SETTING_SOUND_NEW_YEAR_HELPTEXT - -[SDTC_BOOL] -var = sound.confirm -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_SOUND_CONFIRM -strhelp = STR_CONFIG_SETTING_SOUND_CONFIRM_HELPTEXT - -[SDTC_BOOL] -var = sound.click_beep -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_SOUND_CLICK -strhelp = STR_CONFIG_SETTING_SOUND_CLICK_HELPTEXT - -[SDTC_BOOL] -var = sound.disaster -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_SOUND_DISASTER -strhelp = STR_CONFIG_SETTING_SOUND_DISASTER_HELPTEXT - -[SDTC_BOOL] -var = sound.vehicle -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_SOUND_VEHICLE -strhelp = STR_CONFIG_SETTING_SOUND_VEHICLE_HELPTEXT - -[SDTC_BOOL] -var = sound.ambient -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -str = STR_CONFIG_SETTING_SOUND_AMBIENT -strhelp = STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT - -[SDTC_VAR] -var = music.playlist -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 0 -min = 0 -max = 5 -interval = 1 -cat = SC_BASIC - -[SDTC_VAR] -var = music.music_vol -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 50 -min = 0 -max = 127 -interval = 1 -cat = SC_BASIC - -[SDTC_VAR] -var = music.effect_vol -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 100 -min = 0 -max = 127 -interval = 1 -cat = SC_BASIC - -[SDTC_LIST] -var = music.custom_1 -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = nullptr -cat = SC_BASIC - -[SDTC_LIST] -var = music.custom_2 -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = nullptr -cat = SC_BASIC - -[SDTC_BOOL] -var = music.playing -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = true -cat = SC_BASIC - -[SDTC_BOOL] -var = music.shuffle -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -cat = SC_BASIC - -[SDTC_OMANY] -var = news_display.arrival_player -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN -strhelp = STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.arrival_other -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER -strhelp = STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.accident -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS -strhelp = STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.company_info -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION -strhelp = STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.open -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_INDUSTRY_OPEN -strhelp = STR_CONFIG_SETTING_NEWS_INDUSTRY_OPEN_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.close -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_INDUSTRY_CLOSE -strhelp = STR_CONFIG_SETTING_NEWS_INDUSTRY_CLOSE_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.economy -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES -strhelp = STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.production_player -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY -strhelp = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.production_other -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 0 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER -strhelp = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.production_nobody -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 0 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED -strhelp = STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.advice -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_ADVICE -strhelp = STR_CONFIG_SETTING_NEWS_ADVICE_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.new_vehicles -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_NEW_VEHICLES -strhelp = STR_CONFIG_SETTING_NEWS_NEW_VEHICLES_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.acceptance -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE -strhelp = STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.subsidies -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_SUBSIDIES -strhelp = STR_CONFIG_SETTING_NEWS_SUBSIDIES_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_OMANY] -var = news_display.general -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -max = 2 -full = _news_display -str = STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION -strhelp = STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION_HELPTEXT -strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF - -[SDTC_VAR] -var = gui.network_chat_box_width_pct -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 40 -min = 10 -max = 100 -cat = SC_EXPERT - -[SDTC_VAR] -var = gui.network_chat_box_height -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 25 -min = 5 -max = 255 -cat = SC_EXPERT - -[SDTC_VAR] -var = gui.network_chat_timeout -type = SLE_UINT16 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = 20 -min = 1 -max = 65535 -cat = SC_EXPERT diff --git a/src/table/settings/world_settings.ini b/src/table/settings/world_settings.ini new file mode 100644 index 0000000000..5912f89f4c --- /dev/null +++ b/src/table/settings/world_settings.ini @@ -0,0 +1,545 @@ +; This file is part of OpenTTD. +; OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +; OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +; + +; World settings as stored in the main configuration file ("openttd.cfg") +; and in the savegame PATS chunk. +; World settings are everything related to how the world came to be, so +; basically construction and game_creation settings. + +[pre-amble] +static bool CheckMaxHeightLevel(int32 &new_value); +static bool CheckFreeformEdges(int32 &new_value); +static void UpdateFreeformEdges(int32 new_value); + +static const SettingVariant _world_settings_table[] = { +[post-amble] +}; +[templates] +SDT_BOOL = SDT_BOOL(GameSettings, $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDT_OMANY = SDT_OMANY(GameSettings, $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $load, $cat, $extra, $startup), +SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDT_OMANY = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); +SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); + +[defaults] +flags = SF_NONE +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + + +; There are only 21 predefined town_name values (0-20), but you can have more with newgrf action F so allow +; these bigger values (21-255). Invalid values will fallback to english on use and (undefined string) in GUI. +[SDT_OMANY] +var = game_creation.town_name +type = SLE_UINT8 +from = SLV_97 +flags = SF_NO_NETWORK +def = 0 +max = 255 +full = _town_names +cat = SC_BASIC + +[SDT_OMANY] +var = game_creation.landscape +type = SLE_UINT8 +from = SLV_97 +flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY +def = 0 +max = 3 +full = _climates +load = ConvertLandscape +str = STR_CONFIG_SETTING_LANDSCAPE +strhelp = STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT +strval = STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.heightmap_height +type = SLE_UINT8 +from = SLV_MAPGEN_SETTINGS_REVAMP +flags = SF_NEWGAME_ONLY +def = MAP_HEIGHT_LIMIT_AUTO_MINIMUM +min = MIN_HEIGHTMAP_HEIGHT +max = MAX_MAP_HEIGHT_LIMIT +interval = 1 + +[SDT_VAR] +var = game_creation.snow_line_height +type = SLE_UINT8 +flags = SF_SCENEDIT_ONLY +def = DEF_SNOWLINE_HEIGHT +min = MIN_SNOWLINE_HEIGHT +max = MAX_SNOWLINE_HEIGHT +interval = 1 +str = STR_CONFIG_SETTING_SNOWLINE_HEIGHT +strhelp = STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT +strval = STR_JUST_COMMA +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.snow_coverage +type = SLE_UINT8 +from = SLV_MAPGEN_SETTINGS_REVAMP +flags = SF_NEWGAME_ONLY +def = DEF_SNOW_COVERAGE +min = 0 +max = 100 +interval = 10 +str = STR_CONFIG_SETTING_SNOW_COVERAGE +strhelp = STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT +strval = STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.desert_coverage +type = SLE_UINT8 +from = SLV_MAPGEN_SETTINGS_REVAMP +flags = SF_NEWGAME_ONLY +def = DEF_DESERT_COVERAGE +min = 0 +max = 100 +interval = 10 +str = STR_CONFIG_SETTING_DESERT_COVERAGE +strhelp = STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT +strval = STR_CONFIG_SETTING_DESERT_COVERAGE_VALUE +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.starting_year +type = SLE_INT32 +def = DEF_START_YEAR +min = MIN_YEAR +max = MAX_YEAR +interval = 1 +str = STR_CONFIG_SETTING_STARTING_YEAR +strval = STR_JUST_INT +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.ending_year +type = SLE_INT32 +from = SLV_ENDING_YEAR +flags = SF_GUI_0_IS_SPECIAL +def = DEF_END_YEAR +min = MIN_YEAR +max = MAX_YEAR - 1 +interval = 1 +str = STR_CONFIG_SETTING_ENDING_YEAR +strhelp = STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT +strval = STR_CONFIG_SETTING_ENDING_YEAR_VALUE +cat = SC_ADVANCED + +[SDT_VAR] +var = game_creation.land_generator +type = SLE_UINT8 +from = SLV_30 +flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY +def = 1 +min = 0 +max = 1 +str = STR_CONFIG_SETTING_LAND_GENERATOR +strhelp = STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT +strval = STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL + +[SDT_VAR] +var = game_creation.oil_refinery_limit +type = SLE_UINT8 +from = SLV_30 +def = 32 +min = 12 +max = 128 +str = STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE +strval = STR_CONFIG_SETTING_TILE_LENGTH +strhelp = STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT + +[SDT_VAR] +var = game_creation.tgen_smoothness +type = SLE_UINT8 +from = SLV_30 +flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY +def = 1 +min = TGEN_SMOOTHNESS_BEGIN +max = TGEN_SMOOTHNESS_END - 1 +str = STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN +strhelp = STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT +strval = STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.variety +type = SLE_UINT8 +from = SLV_197 +flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY +def = 0 +min = 0 +max = 5 +str = STR_CONFIG_SETTING_VARIETY +strhelp = STR_CONFIG_SETTING_VARIETY_HELPTEXT +strval = STR_VARIETY_NONE + +[SDT_VAR] +var = game_creation.generation_seed +type = SLE_UINT32 +from = SLV_30 +def = GENERATE_NEW_SEED +min = 0 +max = UINT32_MAX +cat = SC_EXPERT + +[SDT_VAR] +var = game_creation.tree_placer +type = SLE_UINT8 +from = SLV_30 +flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY | SF_SCENEDIT_TOO +def = 2 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_TREE_PLACER +strhelp = STR_CONFIG_SETTING_TREE_PLACER_HELPTEXT +strval = STR_CONFIG_SETTING_TREE_PLACER_NONE +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.heightmap_rotation +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 0 +min = 0 +max = 1 +str = STR_CONFIG_SETTING_HEIGHTMAP_ROTATION +strval = STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.se_flat_world_height +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 1 +min = 0 +max = 15 +str = STR_CONFIG_SETTING_SE_FLAT_WORLD_HEIGHT +strval = STR_JUST_COMMA +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.map_x +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 8 +min = MIN_MAP_SIZE_BITS +max = MAX_MAP_SIZE_BITS +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.map_y +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = 8 +min = MIN_MAP_SIZE_BITS +max = MAX_MAP_SIZE_BITS +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.water_borders +type = SLE_UINT8 +from = SLV_111 +def = 15 +min = 0 +max = 16 + +[SDT_VAR] +var = game_creation.custom_town_number +type = SLE_UINT16 +from = SLV_115 +def = 1 +min = 1 +max = 5000 +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.custom_terrain_type +type = SLE_UINT8 +from = SLV_MAPGEN_SETTINGS_REVAMP +flags = SF_NEWGAME_ONLY +def = MAP_HEIGHT_LIMIT_AUTO_MINIMUM +min = MIN_CUSTOM_TERRAIN_TYPE +max = MAX_MAP_HEIGHT_LIMIT +interval = 1 + +[SDT_VAR] +var = game_creation.custom_sea_level +type = SLE_UINT8 +from = SLV_149 +def = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE +min = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE +max = CUSTOM_SEA_LEVEL_MAX_PERCENTAGE +cat = SC_BASIC + +[SDT_VAR] +var = game_creation.min_river_length +type = SLE_UINT8 +from = SLV_163 +def = 16 +min = 2 +max = 255 +cat = SC_EXPERT + +[SDT_VAR] +var = game_creation.river_route_random +type = SLE_UINT8 +from = SLV_163 +def = 5 +min = 1 +max = 255 +cat = SC_EXPERT + +[SDT_VAR] +var = game_creation.amount_of_rivers +type = SLE_UINT8 +from = SLV_163 +flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY +def = 2 +min = 0 +max = 3 +str = STR_CONFIG_SETTING_RIVER_AMOUNT +strhelp = STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT +strval = STR_RIVERS_NONE + +[SDT_VAR] +var = construction.map_height_limit +type = SLE_UINT8 +from = SLV_194 +flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO | SF_GUI_0_IS_SPECIAL +def = 0 +min = MIN_MAP_HEIGHT_LIMIT +max = MAX_MAP_HEIGHT_LIMIT +interval = 1 +str = STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT +strhelp = STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_HELPTEXT +strval = STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_VALUE +pre_cb = CheckMaxHeightLevel +post_cb = [](auto) { InvalidateWindowClassesData(WC_SMALLMAP, 2); } +cat = SC_ADVANCED + +[SDT_BOOL] +var = construction.build_on_slopes +flags = SF_NO_NETWORK +def = true +cat = SC_EXPERT + +[SDT_VAR] +var = construction.command_pause_level +type = SLE_UINT8 +from = SLV_154 +flags = SF_GUI_DROPDOWN | SF_NO_NETWORK +def = 1 +min = 0 +max = 3 +interval = 1 +str = STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL +strhelp = STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_HELPTEXT +strval = STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_NO_ACTIONS + +[SDT_VAR] +var = construction.terraform_per_64k_frames +type = SLE_UINT32 +from = SLV_156 +def = 64 << 16 +min = 0 +max = 1 << 30 +interval = 1 +cat = SC_EXPERT + +[SDT_VAR] +var = construction.terraform_frame_burst +type = SLE_UINT16 +from = SLV_156 +def = 4096 +min = 0 +max = 1 << 15 +interval = 1 +cat = SC_EXPERT + +[SDT_VAR] +var = construction.clear_per_64k_frames +type = SLE_UINT32 +from = SLV_156 +def = 64 << 16 +min = 0 +max = 1 << 30 +interval = 1 +cat = SC_EXPERT + +[SDT_VAR] +var = construction.clear_frame_burst +type = SLE_UINT16 +from = SLV_156 +def = 4096 +min = 0 +max = 1 << 15 +interval = 1 +cat = SC_EXPERT + +[SDT_VAR] +var = construction.tree_per_64k_frames +type = SLE_UINT32 +from = SLV_175 +def = 64 << 16 +min = 0 +max = 1 << 30 +interval = 1 +cat = SC_EXPERT + +[SDT_VAR] +var = construction.tree_frame_burst +type = SLE_UINT16 +from = SLV_175 +def = 4096 +min = 0 +max = 1 << 15 +interval = 1 +cat = SC_EXPERT + +[SDT_BOOL] +var = construction.autoslope +from = SLV_75 +def = true +str = STR_CONFIG_SETTING_AUTOSLOPE +strhelp = STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT +cat = SC_EXPERT + +[SDT_BOOL] +var = construction.extra_dynamite +def = true +str = STR_CONFIG_SETTING_EXTRADYNAMITE +strhelp = STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT + +[SDT_VAR] +var = construction.max_bridge_length +type = SLE_UINT16 +from = SLV_159 +flags = SF_NO_NETWORK +def = 64 +min = 1 +max = MAX_MAP_SIZE +interval = 1 +str = STR_CONFIG_SETTING_MAX_BRIDGE_LENGTH +strhelp = STR_CONFIG_SETTING_MAX_BRIDGE_LENGTH_HELPTEXT +strval = STR_CONFIG_SETTING_TILE_LENGTH + +[SDT_VAR] +var = construction.max_bridge_height +type = SLE_UINT8 +from = SLV_194 +flags = SF_NO_NETWORK +def = 12 +min = 1 +max = MAX_TILE_HEIGHT +interval = 1 +str = STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT +strhelp = STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT_HELPTEXT +strval = STR_JUST_COMMA +cat = SC_EXPERT + +[SDT_VAR] +var = construction.max_tunnel_length +type = SLE_UINT16 +from = SLV_159 +flags = SF_NO_NETWORK +def = 64 +min = 1 +max = MAX_MAP_SIZE +interval = 1 +str = STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH +strhelp = STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT +strval = STR_CONFIG_SETTING_TILE_LENGTH + +[SDT_VAR] +var = construction.train_signal_side +type = SLE_UINT8 +flags = SF_GUI_DROPDOWN | SF_NO_NETWORK +def = 1 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_SIGNALSIDE +strhelp = STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT +strval = STR_CONFIG_SETTING_SIGNALSIDE_LEFT +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC + +[SDT_BOOL] +var = construction.road_stop_on_town_road +from = SLV_47 +def = true +str = STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD +strhelp = STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT +cat = SC_BASIC + +[SDT_BOOL] +var = construction.road_stop_on_competitor_road +from = SLV_114 +def = true +str = STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD +strhelp = STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT +cat = SC_BASIC + +[SDT_VAR] +var = construction.raw_industry_construction +type = SLE_UINT8 +flags = SF_GUI_DROPDOWN +def = 0 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD +strhelp = STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT +strval = STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NONE +post_cb = [](auto) { InvalidateWindowData(WC_BUILD_INDUSTRY, 0); } +cat = SC_BASIC + +[SDT_VAR] +var = construction.industry_platform +type = SLE_UINT8 +from = SLV_148 +def = 1 +min = 0 +max = 4 +str = STR_CONFIG_SETTING_INDUSTRY_PLATFORM +strhelp = STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT +strval = STR_CONFIG_SETTING_TILE_LENGTH +cat = SC_EXPERT + +[SDT_BOOL] +var = construction.freeform_edges +from = SLV_111 +def = true +pre_cb = CheckFreeformEdges +post_cb = UpdateFreeformEdges +cat = SC_EXPERT + +[SDT_VAR] +var = construction.extra_tree_placement +type = SLE_UINT8 +from = SLV_132 +flags = SF_GUI_DROPDOWN +def = 2 +min = 0 +max = 3 +str = STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT +strhelp = STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT +strval = STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_SPREAD +cat = SC_BASIC From 87eb997be0ffb8a62f31ed222e41a10a2622437f Mon Sep 17 00:00:00 2001 From: glx22 Date: Sun, 13 Jun 2021 01:10:57 +0200 Subject: [PATCH 37/42] Codechange: Remove FOR_ALL_TILES_IN_HEIGHT --- src/tgp.cpp | 65 +++++++++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 39 deletions(-) diff --git a/src/tgp.cpp b/src/tgp.cpp index 2c0c479100..511b998e23 100644 --- a/src/tgp.cpp +++ b/src/tgp.cpp @@ -161,11 +161,10 @@ static const int amplitude_decimal_bits = 10; /** Height map - allocated array of heights (MapSizeX() + 1) x (MapSizeY() + 1) */ struct HeightMap { - height_t *h; //< array of heights + std::vector h; //< array of heights /* Even though the sizes are always positive, there are many cases where * X and Y need to be signed integers due to subtractions. */ int dim_x; //< height map size_x MapSizeX() + 1 - int total_size; //< height map total size int size_x; //< MapSizeX() int size_y; //< MapSizeY() @@ -182,7 +181,7 @@ struct HeightMap }; /** Global height map instance */ -static HeightMap _height_map = {nullptr, 0, 0, 0, 0}; +static HeightMap _height_map = { {}, 0, 0, 0 }; /** Conversion: int to height_t */ #define I2H(i) ((i) << height_decimal_bits) @@ -197,10 +196,6 @@ static HeightMap _height_map = {nullptr, 0, 0, 0, 0}; /** Conversion: amplitude_t to height_t */ #define A2H(a) ((a) >> (amplitude_decimal_bits - height_decimal_bits)) - -/** Walk through all items of _height_map.h */ -#define FOR_ALL_TILES_IN_HEIGHT(h) for (h = _height_map.h; h < &_height_map.h[_height_map.total_size]; h++) - /** Maximum number of TGP noise frequencies. */ static const int MAX_TGP_FREQUENCIES = 10; @@ -325,18 +320,15 @@ static inline bool IsValidXY(int x, int y) */ static inline bool AllocHeightMap() { - height_t *h; + assert(_height_map.h.empty()); _height_map.size_x = MapSizeX(); _height_map.size_y = MapSizeY(); /* Allocate memory block for height map row pointers */ - _height_map.total_size = (_height_map.size_x + 1) * (_height_map.size_y + 1); + size_t total_size = (_height_map.size_x + 1) * (_height_map.size_y + 1); _height_map.dim_x = _height_map.size_x + 1; - _height_map.h = CallocT(_height_map.total_size); - - /* Iterate through height map and initialise values. */ - FOR_ALL_TILES_IN_HEIGHT(h) *h = 0; + _height_map.h.resize(total_size); return true; } @@ -344,8 +336,7 @@ static inline bool AllocHeightMap() /** Free height map */ static inline void FreeHeightMap() { - free(_height_map.h); - _height_map.h = nullptr; + _height_map.h.clear(); } /** @@ -369,7 +360,7 @@ static inline height_t RandomHeight(amplitude_t rMax) static void HeightMapGenerate() { /* Trying to apply noise to uninitialized height map */ - assert(_height_map.h != nullptr); + assert(!_height_map.h.empty()); int start = std::max(MAX_TGP_FREQUENCIES - (int)std::min(MapLogX(), MapLogY()), 0); bool first = true; @@ -428,15 +419,15 @@ static void HeightMapGenerate() /** Returns min, max and average height from height map */ static void HeightMapGetMinMaxAvg(height_t *min_ptr, height_t *max_ptr, height_t *avg_ptr) { - height_t h_min, h_max, h_avg, *h; + height_t h_min, h_max, h_avg; int64 h_accu = 0; h_min = h_max = _height_map.height(0, 0); /* Get h_min, h_max and accumulate heights into h_accu */ - FOR_ALL_TILES_IN_HEIGHT(h) { - if (*h < h_min) h_min = *h; - if (*h > h_max) h_max = *h; - h_accu += *h; + for (const height_t &h : _height_map.h) { + if (h < h_min) h_min = h; + if (h > h_max) h_max = h; + h_accu += h; } /* Get average height */ @@ -452,13 +443,12 @@ static void HeightMapGetMinMaxAvg(height_t *min_ptr, height_t *max_ptr, height_t static int *HeightMapMakeHistogram(height_t h_min, height_t h_max, int *hist_buf) { int *hist = hist_buf - h_min; - height_t *h; /* Count the heights and fill the histogram */ - FOR_ALL_TILES_IN_HEIGHT(h) { - assert(*h >= h_min); - assert(*h <= h_max); - hist[*h]++; + for (const height_t &h : _height_map.h){ + assert(h >= h_min); + assert(h <= h_max); + hist[h]++; } return hist; } @@ -466,15 +456,13 @@ static int *HeightMapMakeHistogram(height_t h_min, height_t h_max, int *hist_buf /** Applies sine wave redistribution onto height map */ static void HeightMapSineTransform(height_t h_min, height_t h_max) { - height_t *h; - - FOR_ALL_TILES_IN_HEIGHT(h) { + for (height_t &h : _height_map.h) { double fheight; - if (*h < h_min) continue; + if (h < h_min) continue; /* Transform height into 0..1 space */ - fheight = (double)(*h - h_min) / (double)(h_max - h_min); + fheight = (double)(h - h_min) / (double)(h_max - h_min); /* Apply sine transform depending on landscape type */ switch (_settings_game.game_creation.landscape) { case LT_TOYLAND: @@ -534,9 +522,9 @@ static void HeightMapSineTransform(height_t h_min, height_t h_max) break; } /* Transform it back into h_min..h_max space */ - *h = (height_t)(fheight * (h_max - h_min) + h_min); - if (*h < 0) *h = I2H(0); - if (*h >= h_max) *h = h_max - 1; + h = (height_t)(fheight * (h_max - h_min) + h_min); + if (h < 0) h = I2H(0); + if (h >= h_max) h = h_max - 1; } } @@ -689,7 +677,6 @@ static void HeightMapAdjustWaterLevel(amplitude_t water_percent, height_t h_max_ { height_t h_min, h_max, h_avg, h_water_level; int64 water_tiles, desired_water_tiles; - height_t *h; int *hist; HeightMapGetMinMaxAvg(&h_min, &h_max, &h_avg); @@ -714,12 +701,12 @@ static void HeightMapAdjustWaterLevel(amplitude_t water_percent, height_t h_max_ * values from range: h_water_level..h_max are transformed into 0..h_max_new * where h_max_new is depending on terrain type and map size. */ - FOR_ALL_TILES_IN_HEIGHT(h) { + for (height_t &h : _height_map.h) { /* Transform height from range h_water_level..h_max into 0..h_max_new range */ - *h = (height_t)(((int)h_max_new) * (*h - h_water_level) / (h_max - h_water_level)) + I2H(1); + h = (height_t)(((int)h_max_new) * (h - h_water_level) / (h_max - h_water_level)) + I2H(1); /* Make sure all values are in the proper range (0..h_max_new) */ - if (*h < 0) *h = I2H(0); - if (*h >= h_max_new) *h = h_max_new - 1; + if (h < 0) h = I2H(0); + if (h >= h_max_new) h = h_max_new - 1; } free(hist_buf); From 5844027eb8588197d82fe896f027182621c4f923 Mon Sep 17 00:00:00 2001 From: glx22 Date: Sun, 13 Jun 2021 02:41:41 +0200 Subject: [PATCH 38/42] Codechange: Remove FOR_ALL_SORTED_STANDARD_CARGOSPECS --- src/build_vehicle_gui.cpp | 3 +-- src/cargotype.cpp | 13 ++++++++----- src/cargotype.h | 10 ++-------- src/graph_gui.cpp | 20 +++++++------------- src/industry_gui.cpp | 6 ++---- src/station_gui.cpp | 30 +++++++++++++++--------------- 6 files changed, 35 insertions(+), 47 deletions(-) diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index bdd32dc22a..f88a7ee144 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1186,8 +1186,7 @@ struct BuildVehicleWindow : Window { } /* Collect available cargo types for filtering. */ - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { this->cargo_filter[filter_items] = cs->Index(); this->cargo_filter_texts[filter_items] = cs->name; filter_items++; diff --git a/src/cargotype.cpp b/src/cargotype.cpp index a6ea680d80..e35c94d2fe 100644 --- a/src/cargotype.cpp +++ b/src/cargotype.cpp @@ -149,8 +149,8 @@ SpriteID CargoSpec::GetCargoIcon() const return sprite; } -std::vector _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name. -uint8 _sorted_standard_cargo_specs_size; ///< Number of standard cargo specifications stored in the _sorted_cargo_specs array. +std::vector _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name. +span _sorted_standard_cargo_specs; ///< Standard cargo specifications sorted alphabetically by name. /** Sort cargo specifications by their name. */ static bool CargoSpecNameSorter(const CargoSpec * const &a, const CargoSpec * const &b) @@ -196,13 +196,16 @@ void InitializeSortedCargoSpecs() /* Sort cargo specifications by cargo class and name. */ std::sort(_sorted_cargo_specs.begin(), _sorted_cargo_specs.end(), &CargoSpecClassSorter); + /* Count the number of standard cargos and fill the mask. */ _standard_cargo_mask = 0; - - _sorted_standard_cargo_specs_size = 0; + uint8 nb_standard_cargo = 0; for (const auto &cargo : _sorted_cargo_specs) { if (cargo->classes & CC_SPECIAL) break; - _sorted_standard_cargo_specs_size++; + nb_standard_cargo++; SetBit(_standard_cargo_mask, cargo->Index()); } + + /* _sorted_standard_cargo_specs is a subset of _sorted_cargo_specs. */ + _sorted_standard_cargo_specs = { _sorted_cargo_specs.data(), nb_standard_cargo }; } diff --git a/src/cargotype.h b/src/cargotype.h index e411d53126..c93feea753 100644 --- a/src/cargotype.h +++ b/src/cargotype.h @@ -15,6 +15,7 @@ #include "gfx_type.h" #include "strings_type.h" #include "landscape_type.h" +#include "core/span_type.hpp" #include /** Globally unique label of a cargo type. */ @@ -181,7 +182,7 @@ CargoID GetDefaultCargoID(LandscapeID l, CargoType ct); void InitializeSortedCargoSpecs(); extern std::vector _sorted_cargo_specs; -extern uint8 _sorted_standard_cargo_specs_size; +extern span _sorted_standard_cargo_specs; /** * Does cargo \a c have cargo class \a cc? @@ -196,11 +197,4 @@ static inline bool IsCargoInClass(CargoID c, CargoClass cc) #define FOR_EACH_SET_CARGO_ID(var, cargo_bits) FOR_EACH_SET_BIT_EX(CargoID, var, CargoTypes, cargo_bits) -/** - * Loop header for iterating over 'real' cargoes, sorted by name. Phony cargoes like regearing cargoes are skipped. - * @param var Reference getting the cargospec. - * @see CargoSpec - */ -#define FOR_ALL_SORTED_STANDARD_CARGOSPECS(var) for (uint8 index = 0; index < _sorted_standard_cargo_specs_size && (var = _sorted_cargo_specs[index], true); index++) - #endif /* CARGOTYPE_H */ diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 10433fc093..00e1efd906 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -892,7 +892,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_CPR_MATRIX_SCROLLBAR); - this->vscroll->SetCount(_sorted_standard_cargo_specs_size); + this->vscroll->SetCount(static_cast(_sorted_standard_cargo_specs.size())); /* Initialise the dataset */ this->OnHundredthTick(); @@ -911,8 +911,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { this->excluded_data = 0; int i = 0; - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { if (HasBit(_legend_excluded_cargo, cs->Index())) SetBit(this->excluded_data, i); i++; } @@ -925,8 +924,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { return; } - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { SetDParam(0, cs->name); Dimension d = GetStringBoundingBox(STR_GRAPH_CARGO_PAYMENT_CARGO); d.width += this->legend_width + 4; // colour field @@ -958,8 +956,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { int pos = this->vscroll->GetPosition(); int max = pos + this->vscroll->GetCapacity(); - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { if (pos-- > 0) continue; if (--max < 0) break; @@ -993,8 +990,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { case WID_CPR_DISABLE_CARGOES: { /* Add all cargoes to the excluded lists. */ int i = 0; - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { SetBit(_legend_excluded_cargo, cs->Index()); SetBit(this->excluded_data, i); i++; @@ -1007,8 +1003,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_CPR_MATRIX); if (row >= this->vscroll->GetCount()) return; - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { if (row-- > 0) continue; ToggleBit(_legend_excluded_cargo, cs->Index()); @@ -1047,8 +1042,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { this->UpdateExcludedData(); int i = 0; - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { this->colours[i] = cs->legend_colour; for (uint j = 0; j != 20; j++) { this->cost[i][j] = GetTransportedGoodsIncome(10, 20, j * 4 + 4, cs->Index()); diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 6489399757..5757a30480 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -1375,8 +1375,7 @@ protected: filter_items++; /* Collect available cargo types for filtering. */ - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { this->cargo_filter[filter_items] = cs->Index(); this->cargo_filter_texts[filter_items] = cs->name; filter_items++; @@ -2995,8 +2994,7 @@ struct IndustryCargoesWindow : public Window { case WID_IC_CARGO_DROPDOWN: { DropDownList lst; - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { lst.emplace_back(new DropDownListStringItem(cs->name, cs->Index(), false)); } if (!lst.empty()) { diff --git a/src/station_gui.cpp b/src/station_gui.cpp index a43cc1707c..1b64d8aee9 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -347,10 +347,12 @@ public: this->FinishInitNested(window_number); this->owner = (Owner)this->window_number; - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { - if (!HasBit(this->cargo_filter, cs->Index())) continue; - this->LowerWidget(WID_STL_CARGOSTART + index); + uint8 index = 0; + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { + if (HasBit(this->cargo_filter, cs->Index())) { + this->LowerWidget(WID_STL_CARGOSTART + index); + } + index++; } if (this->cargo_filter == this->cargo_filter_max) this->cargo_filter = _cargo_mask; @@ -396,8 +398,7 @@ public: /* Determine appropriate width for mini station rating graph */ this->rating_width = 0; - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { this->rating_width = std::max(this->rating_width, GetStringBoundingBox(cs->abbrev).width); } /* Approximately match original 16 pixel wide rating bars by multiplying string width by 1.6 */ @@ -465,8 +466,8 @@ public: x += rtl ? -text_spacing : text_spacing; /* show cargo waiting and station ratings */ - for (uint j = 0; j < _sorted_standard_cargo_specs_size; j++) { - CargoID cid = _sorted_cargo_specs[j]->Index(); + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { + CargoID cid = cs->Index(); if (st->goods[cid].cargo.TotalCount() > 0) { /* For RTL we work in exactly the opposite direction. So * decrement the space needed first, then draw to the left @@ -581,7 +582,7 @@ public: break; case WID_STL_CARGOALL: { - for (uint i = 0; i < _sorted_standard_cargo_specs_size; i++) { + for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) { this->LowerWidget(WID_STL_CARGOSTART + i); } this->LowerWidget(WID_STL_NOCARGOWAITING); @@ -607,7 +608,7 @@ public: this->include_empty = !this->include_empty; this->ToggleWidgetLoweredState(WID_STL_NOCARGOWAITING); } else { - for (uint i = 0; i < _sorted_standard_cargo_specs_size; i++) { + for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) { this->RaiseWidget(WID_STL_CARGOSTART + i); } @@ -629,7 +630,7 @@ public: ToggleBit(this->cargo_filter, cs->Index()); this->ToggleWidgetLoweredState(widget); } else { - for (uint i = 0; i < _sorted_standard_cargo_specs_size; i++) { + for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) { this->RaiseWidget(WID_STL_CARGOSTART + i); } this->RaiseWidget(WID_STL_NOCARGOWAITING); @@ -724,7 +725,7 @@ static NWidgetBase *CargoWidgets(int *biggest_index) { NWidgetHorizontal *container = new NWidgetHorizontal(); - for (uint i = 0; i < _sorted_standard_cargo_specs_size; i++) { + for (uint i = 0; i < _sorted_standard_cargo_specs.size(); i++) { NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_GREY, WID_STL_CARGOSTART + i); panel->SetMinimalSize(14, 0); panel->SetMinimalTextLines(1, 0, FS_NORMAL); @@ -733,7 +734,7 @@ static NWidgetBase *CargoWidgets(int *biggest_index) panel->SetDataTip(0, STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE); container->Add(panel); } - *biggest_index = WID_STL_CARGOSTART + _sorted_standard_cargo_specs_size; + *biggest_index = WID_STL_CARGOSTART + static_cast(_sorted_standard_cargo_specs.size()); return container; } @@ -1859,8 +1860,7 @@ struct StationViewWindow : public Window { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_VIEW_SUPPLY_RATINGS_TITLE); y += FONT_HEIGHT_NORMAL; - const CargoSpec *cs; - FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + for (const CargoSpec *cs : _sorted_standard_cargo_specs) { const GoodsEntry *ge = &st->goods[cs->Index()]; if (!ge->HasRating()) continue; From 89ab8b79a51b4963da55dce195ea1ab520c73b50 Mon Sep 17 00:00:00 2001 From: glx22 Date: Sun, 13 Jun 2021 04:18:21 +0200 Subject: [PATCH 39/42] Codechange: Remove FOR_EACH_SET_BIT --- src/core/bitmath_func.hpp | 63 ++++++++++++++++++++++++++++++--------- src/goal_gui.cpp | 3 +- src/newgrf.cpp | 3 +- src/newgrf_station.cpp | 3 +- src/settings.cpp | 3 +- src/station_cmd.cpp | 3 +- src/station_gui.cpp | 3 +- src/town_gui.cpp | 3 +- src/water_cmd.cpp | 6 ++-- 9 files changed, 58 insertions(+), 32 deletions(-) diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index 4af46d3430..917a247daa 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -345,20 +345,55 @@ static inline T ROR(const T x, const uint8 n) ) \ if ((___FESBE_bits & 1) != 0) -/** - * Do an operation for each set set bit in a value. - * - * This macros is used to do an operation for each set - * bit in a variable. The first parameter is a variable - * that is used as the bit position counter. - * The second parameter is an expression of the bits - * we need to iterate over. This expression will be - * evaluated once. - * - * @param bitpos_var The position counter variable. - * @param bitset_value The value which we check for set bits. - */ -#define FOR_EACH_SET_BIT(bitpos_var, bitset_value) FOR_EACH_SET_BIT_EX(uint, bitpos_var, uint, bitset_value) + /** + * Iterable ensemble of each set bit in a value. + * @tparam Tbitpos Type of the position variable. + * @tparam Tbitset Type of the bitset value. +*/ +template +struct SetBitIterator { + struct Iterator { + typedef Tbitpos value_type; + typedef value_type *pointer; + typedef value_type &reference; + typedef size_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + explicit Iterator(Tbitset bitset) : bitset(bitset), bitpos(static_cast(0)) + { + this->Validate(); + } + + bool operator==(const Iterator &other) const + { + return this->bitset == other.bitset && (this->bitset == 0 || this->bitpos == other.bitpos); + } + bool operator!=(const Iterator &other) const { return !(*this == other); } + Tbitpos operator*() const { return this->bitpos; } + Iterator & operator++() { this->Next(); this->Validate(); return *this; } + + private: + Tbitset bitset; + Tbitpos bitpos; + void Validate() + { + while (this->bitset != 0 && (this->bitset & 1) == 0) this->Next(); + } + void Next() + { + this->bitset = static_cast(this->bitset >> 1); + this->bitpos++; + } + }; + + SetBitIterator(Tbitset bitset) : bitset(bitset) {} + Iterator begin() { return Iterator(this->bitset); } + Iterator end() { return Iterator(static_cast(0)); } + bool empty() { return this->begin() == this->end(); } + +private: + Tbitset bitset; +}; #if defined(__APPLE__) /* Make endian swapping use Apple's macros to increase speed diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index 922f5f5d5b..65ed9003b0 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -336,9 +336,8 @@ struct GoalQuestionWindow : public Window { this->question = stredup(question); /* Figure out which buttons we have to enable. */ - uint bit; int n = 0; - FOR_EACH_SET_BIT(bit, button_mask) { + for (uint bit : SetBitIterator(button_mask)) { if (bit >= GOAL_QUESTION_BUTTON_COUNT) break; this->button[n++] = bit; if (n == 3) break; diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 77b4d52a91..15e95e4d2d 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -961,8 +961,7 @@ static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool us static CargoTypes TranslateRefitMask(uint32 refit_mask) { CargoTypes result = 0; - uint8 bit; - FOR_EACH_SET_BIT(bit, refit_mask) { + for (uint8 bit : SetBitIterator(refit_mask)) { CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true); if (cargo != CT_INVALID) SetBit(result, cargo); } diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index a7932ce231..5fd5d6ad3c 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -812,8 +812,7 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID /* Sprite layout which needs preprocessing */ bool separate_ground = HasBit(statspec->flags, SSF_SEPARATE_GROUND); uint32 var10_values = layout->PrepareLayout(total_offset, rti->fallback_railtype, 0, 0, separate_ground); - uint8 var10; - FOR_EACH_SET_BIT(var10, var10_values) { + for (uint8 var10 : SetBitIterator(var10_values)) { uint32 var10_relocation = GetCustomStationRelocation(statspec, nullptr, INVALID_TILE, var10); layout->ProcessRegisters(var10, var10_relocation, separate_ground); } diff --git a/src/settings.cpp b/src/settings.cpp index 09223c585e..97a73dd13b 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -354,9 +354,8 @@ void OneOfManySettingDesc::FormatValue(char *buf, const char *last, const void * void ManyOfManySettingDesc::FormatValue(char *buf, const char *last, const void *object) const { uint bitmask = (uint)this->Read(object); - uint id = 0; bool first = true; - FOR_EACH_SET_BIT(id, bitmask) { + for (uint id : SetBitIterator(bitmask)) { if (!first) buf = strecpy(buf, "|", last); buf = this->FormatSingleValue(buf, last, id); first = false; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 8f26ecf4c0..a58c7b1f26 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2993,8 +2993,7 @@ draw_default_foundation: /* Sprite layout which needs preprocessing */ bool separate_ground = HasBit(statspec->flags, SSF_SEPARATE_GROUND); uint32 var10_values = layout->PrepareLayout(total_offset, rti->fallback_railtype, 0, 0, separate_ground); - uint8 var10; - FOR_EACH_SET_BIT(var10, var10_values) { + for (uint8 var10 : SetBitIterator(var10_values)) { uint32 var10_relocation = GetCustomStationRelocation(statspec, st, ti->tile, var10); layout->ProcessRegisters(var10, var10_relocation, separate_ground); } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 1b64d8aee9..e36978c37c 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -560,8 +560,7 @@ public: ToggleBit(this->facilities, widget - WID_STL_TRAIN); this->ToggleWidgetLoweredState(widget); } else { - uint i; - FOR_EACH_SET_BIT(i, this->facilities) { + for (uint i : SetBitIterator(this->facilities)) { this->RaiseWidget(i + WID_STL_TRAIN); } this->facilities = 1 << (widget - WID_STL_TRAIN); diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 2d7aa8f20f..ec44b246b1 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -84,8 +84,7 @@ private: static int GetNthSetBit(uint32 bits, int n) { if (n >= 0) { - uint i; - FOR_EACH_SET_BIT(i, bits) { + for (uint i : SetBitIterator(bits)) { n--; if (n < 0) return i; } diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index dbb4999a7c..a2bedac845 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -1246,8 +1246,7 @@ void TileLoop_Water(TileIndex tile) case FLOOD_DRYUP: { Slope slope_here = GetFoundationSlope(tile) & ~SLOPE_HALFTILE_MASK & ~SLOPE_STEEP; - uint dir; - FOR_EACH_SET_BIT(dir, _flood_from_dirs[slope_here]) { + for (uint dir : SetBitIterator(_flood_from_dirs[slope_here])) { TileIndex dest = tile + TileOffsByDir((Direction)dir); if (!IsValidTile(dest)) continue; @@ -1285,8 +1284,7 @@ void ConvertGroundTilesIntoWaterTiles() break; default: - uint dir; - FOR_EACH_SET_BIT(dir, _flood_from_dirs[slope & ~SLOPE_STEEP]) { + for (uint dir : SetBitIterator(_flood_from_dirs[slope & ~SLOPE_STEEP])) { TileIndex dest = TileAddByDir(tile, (Direction)dir); Slope slope_dest = GetTileSlope(dest) & ~SLOPE_STEEP; if (slope_dest == SLOPE_FLAT || IsSlopeWithOneCornerRaised(slope_dest)) { From a543a4b7bb0d869800591ec1504b3934b68ecd8f Mon Sep 17 00:00:00 2001 From: glx22 Date: Sun, 13 Jun 2021 04:29:24 +0200 Subject: [PATCH 40/42] Codechange: Remove FOR_EACH_SET_CARGO_ID --- src/cargotype.h | 3 ++- src/economy.cpp | 3 +-- src/linkgraph/linkgraph_gui.cpp | 6 ++---- src/newgrf.cpp | 3 +-- src/station_gui.cpp | 9 +++------ 5 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/cargotype.h b/src/cargotype.h index c93feea753..a398d60795 100644 --- a/src/cargotype.h +++ b/src/cargotype.h @@ -15,6 +15,7 @@ #include "gfx_type.h" #include "strings_type.h" #include "landscape_type.h" +#include "core/bitmath_func.hpp" #include "core/span_type.hpp" #include @@ -195,6 +196,6 @@ static inline bool IsCargoInClass(CargoID c, CargoClass cc) return (CargoSpec::Get(c)->classes & cc) != 0; } -#define FOR_EACH_SET_CARGO_ID(var, cargo_bits) FOR_EACH_SET_BIT_EX(CargoID, var, CargoTypes, cargo_bits) +using SetCargoBitIterator = SetBitIterator; #endif /* CARGOTYPE_H */ diff --git a/src/economy.cpp b/src/economy.cpp index 0c2e73cbdc..c3332c4d12 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1480,9 +1480,8 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station bool is_auto_refit = new_cid == CT_AUTO_REFIT; if (is_auto_refit) { /* Get a refittable cargo type with waiting cargo for next_station or INVALID_STATION. */ - CargoID cid; new_cid = v_start->cargo_type; - FOR_EACH_SET_CARGO_ID(cid, refit_mask) { + for (CargoID cid : SetCargoBitIterator(refit_mask)) { if (st->goods[cid].cargo.HasCargoFor(next_station)) { /* Try to find out if auto-refitting would succeed. In case the refit is allowed, * the returned refit capacity will be greater than zero. */ diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index e0986fdb59..056d958ce8 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -65,8 +65,7 @@ void LinkGraphOverlay::RebuildCache() StationLinkMap &seen_links = this->cached_links[from]; uint supply = 0; - CargoID c; - FOR_EACH_SET_CARGO_ID(c, this->cargo_mask) { + for (CargoID c : SetCargoBitIterator(this->cargo_mask)) { if (!CargoSpec::Get(c)->IsValid()) continue; if (!LinkGraph::IsValidID(sta->goods[c].link_graph)) continue; const LinkGraph &lg = *LinkGraph::Get(sta->goods[c].link_graph); @@ -192,8 +191,7 @@ inline bool LinkGraphOverlay::IsLinkVisible(Point pta, Point ptb, const DrawPixe */ void LinkGraphOverlay::AddLinks(const Station *from, const Station *to) { - CargoID c; - FOR_EACH_SET_CARGO_ID(c, this->cargo_mask) { + for (CargoID c : SetCargoBitIterator(this->cargo_mask)) { if (!CargoSpec::Get(c)->IsValid()) continue; const GoodsEntry &ge = from->goods[c]; if (!LinkGraph::IsValidID(ge.link_graph) || diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 15e95e4d2d..023ad98901 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -8902,8 +8902,7 @@ static void CalculateRefitMasks() if (cargo_map_for_first_refittable != nullptr) { /* Use first refittable cargo from cargo translation table */ byte best_local_slot = 0xFF; - CargoID cargo_type; - FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) { + for (CargoID cargo_type : SetCargoBitIterator(ei->refit_mask)) { byte local_slot = cargo_map_for_first_refittable[cargo_type]; if (local_slot < best_local_slot) { best_local_slot = local_slot; diff --git a/src/station_gui.cpp b/src/station_gui.cpp index e36978c37c..ecc7ea77c3 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -273,8 +273,7 @@ protected: { int diff = 0; - CargoID j; - FOR_EACH_SET_CARGO_ID(j, cargo_filter) { + for (CargoID j : SetCargoBitIterator(cargo_filter)) { diff += a->goods[j].cargo.TotalCount() - b->goods[j].cargo.TotalCount(); } @@ -286,8 +285,7 @@ protected: { int diff = 0; - CargoID j; - FOR_EACH_SET_CARGO_ID(j, cargo_filter) { + for (CargoID j : SetCargoBitIterator(cargo_filter)) { diff += a->goods[j].cargo.AvailableCount() - b->goods[j].cargo.AvailableCount(); } @@ -300,8 +298,7 @@ protected: byte maxr1 = 0; byte maxr2 = 0; - CargoID j; - FOR_EACH_SET_CARGO_ID(j, cargo_filter) { + for (CargoID j : SetCargoBitIterator(cargo_filter)) { if (a->goods[j].HasRating()) maxr1 = std::max(maxr1, a->goods[j].rating); if (b->goods[j].HasRating()) maxr2 = std::max(maxr2, b->goods[j].rating); } From 49b66ea504fafe9b942b35a97c369c4afa054f41 Mon Sep 17 00:00:00 2001 From: glx22 Date: Sun, 13 Jun 2021 05:15:36 +0200 Subject: [PATCH 41/42] Codechange: Remove FOR_EACH_SET_TRACK --- src/elrail.cpp | 3 +-- src/pathfinder/follow_track.hpp | 3 +-- src/pathfinder/npf/npf.cpp | 3 +-- src/track_func.h | 11 +---------- src/train_cmd.cpp | 3 +-- 5 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/elrail.cpp b/src/elrail.cpp index 4959bb2cba..03adb0c8c9 100644 --- a/src/elrail.cpp +++ b/src/elrail.cpp @@ -470,8 +470,7 @@ static void DrawRailCatenaryRailway(const TileInfo *ti) } /* Drawing of pylons is finished, now draw the wires */ - Track t; - FOR_EACH_SET_TRACK(t, wireconfig[TS_HOME]) { + for (Track t : SetTrackBitIterator(wireconfig[TS_HOME])) { SpriteID wire_base = (t == halftile_track) ? wire_halftile : wire_normal; byte PCPconfig = HasBit(PCPstatus, PCPpositions[t][0]) + (HasBit(PCPstatus, PCPpositions[t][1]) << 1); diff --git a/src/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp index 7e5e0e39b7..a9a51da68a 100644 --- a/src/pathfinder/follow_track.hpp +++ b/src/pathfinder/follow_track.hpp @@ -184,8 +184,7 @@ struct CFollowTrackT /* Mask already reserved trackdirs. */ m_new_td_bits &= ~TrackBitsToTrackdirBits(reserved); /* Mask out all trackdirs that conflict with the reservation. */ - Track t; - FOR_EACH_SET_TRACK(t, TrackdirBitsToTrackBits(m_new_td_bits)) { + for (Track t : SetTrackBitIterator(TrackdirBitsToTrackBits(m_new_td_bits))) { if (TracksOverlap(reserved | TrackToTrackBits(t))) m_new_td_bits &= ~TrackToTrackdirBits(t); } if (m_new_td_bits == TRACKDIR_BIT_NONE) { diff --git a/src/pathfinder/npf/npf.cpp b/src/pathfinder/npf/npf.cpp index 5887181851..24803fb31b 100644 --- a/src/pathfinder/npf/npf.cpp +++ b/src/pathfinder/npf/npf.cpp @@ -954,8 +954,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current) TrackBits reserved = GetReservedTrackbits(dst_tile); trackdirbits &= ~TrackBitsToTrackdirBits(reserved); - Track t; - FOR_EACH_SET_TRACK(t, TrackdirBitsToTrackBits(trackdirbits)) { + for (Track t : SetTrackBitIterator(TrackdirBitsToTrackBits(trackdirbits))) { if (TracksOverlap(reserved | TrackToTrackBits(t))) trackdirbits &= ~TrackToTrackdirBits(t); } } diff --git a/src/track_func.h b/src/track_func.h index 1b56668780..6467450646 100644 --- a/src/track_func.h +++ b/src/track_func.h @@ -15,16 +15,7 @@ #include "direction_func.h" #include "slope_func.h" -/** - * Iterate through each set Track in a TrackBits value. - * For more information see FOR_EACH_SET_BIT_EX. - * - * @param var Loop index variable that stores fallowing set track. Must be of type Track. - * @param track_bits The value to iterate through (any expression). - * - * @see FOR_EACH_SET_BIT_EX - */ -#define FOR_EACH_SET_TRACK(var, track_bits) FOR_EACH_SET_BIT_EX(Track, var, TrackBits, track_bits) +using SetTrackBitIterator = SetBitIterator; /** * Checks if a Track is valid. diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 47895122be..17e298c33d 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3485,8 +3485,7 @@ static void DeleteLastWagon(Train *v) /* It is important that these two are the first in the loop, as reservation cannot deal with every trackbit combination */ assert(TRACK_BEGIN == TRACK_X && TRACK_Y == TRACK_BEGIN + 1); - Track t; - FOR_EACH_SET_TRACK(t, remaining_trackbits) TryReserveRailTrack(tile, t); + for (Track t : SetTrackBitIterator(remaining_trackbits)) TryReserveRailTrack(tile, t); } /* check if the wagon was on a road/rail-crossing */ From ce813ce644c58bbf07509eb8c409ec60512deaf0 Mon Sep 17 00:00:00 2001 From: glx22 Date: Sun, 13 Jun 2021 15:47:13 +0200 Subject: [PATCH 42/42] Cleanup: Remove now unused FOR_EACH_SET_BIT_EX macro --- src/core/bitmath_func.hpp | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index 917a247daa..be0d8cd54d 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -320,31 +320,6 @@ static inline T ROR(const T x, const uint8 n) return (T)(x >> n | x << (sizeof(x) * 8 - n)); } -/** - * Do an operation for each set bit in a value. - * - * This macros is used to do an operation for each set - * bit in a variable. The second parameter is a - * variable that is used as the bit position counter. - * The fourth parameter is an expression of the bits - * we need to iterate over. This expression will be - * evaluated once. - * - * @param Tbitpos_type Type of the position counter variable. - * @param bitpos_var The position counter variable. - * @param Tbitset_type Type of the bitset value. - * @param bitset_value The bitset value which we check for bits. - * - * @see FOR_EACH_SET_BIT - */ -#define FOR_EACH_SET_BIT_EX(Tbitpos_type, bitpos_var, Tbitset_type, bitset_value) \ - for ( \ - Tbitset_type ___FESBE_bits = (bitpos_var = (Tbitpos_type)0, bitset_value); \ - ___FESBE_bits != (Tbitset_type)0; \ - ___FESBE_bits = (Tbitset_type)(___FESBE_bits >> 1), bitpos_var++ \ - ) \ - if ((___FESBE_bits & 1) != 0) - /** * Iterable ensemble of each set bit in a value. * @tparam Tbitpos Type of the position variable.