summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRubidium <rubidium@openttd.org>2021-07-05 20:14:28 +0200
committerrubidium42 <rubidium42@users.noreply.github.com>2021-07-06 21:32:47 +0200
commit7e7a4aad721f89c98a347a4d2104f6a01e8fbcaa (patch)
treefccb8282a0afcb99cef9a47231a37be3518e8bcb
parent25ca6a75bc83df7224f56fc1ab22c4491f77649e (diff)
downloadopenttd-7e7a4aad721f89c98a347a4d2104f6a01e8fbcaa.tar.xz
Codechange: split off the settings saveload code from the main settings handling logic
-rw-r--r--src/saveload/CMakeLists.txt1
-rw-r--r--src/saveload/settings_sl.cpp178
-rw-r--r--src/settings.cpp198
-rw-r--r--src/settings_internal.h10
4 files changed, 204 insertions, 183 deletions
diff --git a/src/saveload/CMakeLists.txt b/src/saveload/CMakeLists.txt
index 5f83309a4..32bcc57ac 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 000000000..2097d8645
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+/** @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<SaveLoad> GetSettingsDesc(const SettingTable &settings, bool is_loading)
+{
+ std::vector<SaveLoad> 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<SaveLoad> 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<SaveLoad> 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 a2ab8ae33..e3741c235 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.
@@ -144,16 +152,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
* @param len length of the string
@@ -832,6 +830,10 @@ const StringSettingDesc *SettingDesc::AsStringSetting() const
return static_cast<const StringSettingDesc *>(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<SaveLoad> GetSettingsDesc(const SettingTable &settings, bool is_loading)
-{
- std::vector<SaveLoad> 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<SaveLoad> 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<SaveLoad> 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 0e6637a5b..304f1393a 100644
--- a/src/settings_internal.h
+++ b/src/settings_internal.h
@@ -302,6 +302,16 @@ struct NullSettingDesc : SettingDesc {
typedef std::variant<IntSettingDesc, BoolSettingDesc, OneOfManySettingDesc, ManyOfManySettingDesc, StringSettingDesc, ListSettingDesc, NullSettingDesc> 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<SaveLoad> &saveloads);
bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame = false);