OpenTTD Source 20250529-master-g10c159a79f
settings_sl.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10#include "../stdafx.h"
11
12#include "saveload.h"
14
15#include "../settings_type.h"
16#include "../settings_table.h"
17#include "../settings_internal.h"
18#include "../network/network.h"
19#include "../fios.h"
20
21#include "../safeguards.h"
22
27{
28 _old_diff_custom.fill(0);
29}
30
37void HandleOldDiffCustom(bool savegame)
38{
39 /* Savegames before v4 didn't have "town_council_tolerance" in savegame yet. */
40 bool has_no_town_council_tolerance = savegame && IsSavegameVersionBefore(SLV_4);
41 uint options_to_load = GAME_DIFFICULTY_NUM - (has_no_town_council_tolerance ? 1 : 0);
42
43 if (!savegame) {
44 /* If we did read to old_diff_custom, then at least one value must be non 0. */
45 bool old_diff_custom_used = false;
46 for (uint i = 0; i < options_to_load && !old_diff_custom_used; i++) {
47 old_diff_custom_used = (_old_diff_custom[i] != 0);
48 }
49
50 if (!old_diff_custom_used) return;
51 }
52
53 /* Iterate over all the old difficulty settings, and convert the list-value to the new setting. */
54 uint i = 0;
55 for (const auto &name : _old_diff_settings) {
56 if (has_no_town_council_tolerance && name == "town_council_tolerance") continue;
57
58 std::string fullname = "difficulty." + name;
59 const SettingDesc *sd = GetSettingFromName(fullname);
60
61 /* Some settings are no longer in use; skip reading those. */
62 if (sd == nullptr) {
63 i++;
64 continue;
65 }
66
67 int32_t value = (int32_t)((name == "max_loan" ? 1000 : 1) * _old_diff_custom[i++]);
69 }
70}
71
78static std::vector<SaveLoad> GetSettingsDesc(const SettingTable &settings, bool is_loading)
79{
80 std::vector<SaveLoad> saveloads;
81 for (auto &desc : settings) {
82 const SettingDesc *sd = GetSettingDesc(desc);
83 if (sd->flags.Test(SettingFlag::NotInSave)) continue;
84
85 if (is_loading && sd->flags.Test(SettingFlag::NoNetworkSync) && _networking && !_network_server) {
87 /* We don't want to read this setting, so we do need to skip over it. */
88 saveloads.emplace_back(sd->GetName(), sd->save.cmd, GetVarFileType(sd->save.conv) | SLE_VAR_NULL, sd->save.length, sd->save.version_from, sd->save.version_to, nullptr, 0, nullptr);
89 }
90 continue;
91 }
92
93 saveloads.push_back(sd->save);
94 }
95
96 return saveloads;
97}
98
105static void LoadSettings(const SettingTable &settings, void *object, const SaveLoadCompatTable &slct)
106{
107 const std::vector<SaveLoad> slt = SlCompatTableHeader(GetSettingsDesc(settings, true), slct);
108
110 SlObject(object, slt);
111 if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many settings entries");
112
113 /* Ensure all IntSettings are valid (min/max could have changed between versions etc). */
114 for (auto &desc : settings) {
115 const SettingDesc *sd = GetSettingDesc(desc);
116 if (sd->flags.Test(SettingFlag::NotInSave)) continue;
119
120 if (sd->IsIntSetting()) {
121 const IntSettingDesc *int_setting = sd->AsIntSetting();
122 int_setting->MakeValueValidAndWrite(object, int_setting->Read(object));
123 }
124 }
125}
126
133static void SaveSettings(const SettingTable &settings, void *object)
134{
135 const std::vector<SaveLoad> slt = GetSettingsDesc(settings, false);
136
137 SlTableHeader(slt);
138
139 SlSetArrayIndex(0);
140 SlObject(object, slt);
141}
142
145
146 void Load() const override
147 {
148 /* Copy over default setting since some might not get loaded in
149 * a networking environment. This ensures for example that the local
150 * autosave-frequency stays when joining a network-server */
152 LoadSettings(_old_gameopt_settings, &_settings_game, _gameopt_sl_compat);
154 }
155};
156
158 PATSChunkHandler() : ChunkHandler('PATS', CH_TABLE) {}
159
160 void Load() const override
161 {
163 }
164
165 void LoadCheck(size_t) const override
166 {
169 /* We're only interested in landscape and starting year. */
170 _load_check_data.landscape = settings.game_creation.landscape;
171 _load_check_data.starting_year = settings.game_creation.starting_year;
172 }
173
174 void Save() const override
175 {
177 }
178};
179
180static const OPTSChunkHandler OPTS;
181static const PATSChunkHandler PATS;
182static const ChunkHandlerRef setting_chunk_handlers[] = {
183 OPTS,
184 PATS,
185};
186
187extern const ChunkHandlerTable _setting_chunk_handlers(setting_chunk_handlers);
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
Definition fios_gui.cpp:41
fluid_settings_t * settings
FluidSynth settings handle.
bool _networking
are we in networking mode?
Definition network.cpp:67
bool _network_server
network-server is active
Definition network.cpp:68
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition saveload.cpp:665
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
Definition saveload.cpp:357
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
Functions/types related to saving and loading games.
@ SLE_VAR_NULL
useful to write zeros in savegame.
Definition saveload.h:657
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:514
constexpr VarType GetVarFileType(VarType type)
Get the FileType of a setting.
Definition saveload.h:767
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:517
bool SlIsObjectCurrentlyValid(SaveLoadVersion version_from, SaveLoadVersion version_to)
Checks if some version from/to combination falls within the range of the active savegame version.
Definition saveload.h:1295
std::span< const struct SaveLoadCompat > SaveLoadCompatTable
A table of SaveLoadCompat entries.
Definition saveload.h:523
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1268
@ SLV_4
4.0 1 4.1 122 0.3.3, 0.3.4 4.2 1222 0.3.5 4.3 1417 4.4 1426
Definition saveload.h:37
@ SLV_RIFF_TO_ARRAY
294 PR#9375 Changed many CH_RIFF chunks to CH_ARRAY chunks.
Definition saveload.h:332
@ SLV_TABLE_CHUNKS
295 PR#9322 Introduction of CH_TABLE and CH_SPARSE_TABLE.
Definition saveload.h:334
@ CH_READONLY
Chunk is never saved.
Definition saveload.h:464
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
SettingTable GetSaveLoadSettingTable()
Create a single table with all settings that should be stored/loaded in the savegame.
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
static const SettingDesc * GetSettingFromName(std::string_view name, const SettingTable &settings)
Given a name of setting, return a setting description from the table.
@ NotInSave
Do not save with savegame, basically client-based.
@ NoNetworkSync
Do not synchronize over network (but it is saved if SettingFlag::NotInSave is not set).
static constexpr const SettingDesc * GetSettingDesc(const SettingVariant &desc)
Helper to convert the type of the iterated settings description to a pointer to it.
void HandleOldDiffCustom(bool savegame)
Reading of the old diff_custom array and transforming it to the new format.
static void LoadSettings(const SettingTable &settings, void *object, const SaveLoadCompatTable &slct)
Save and load handler for settings.
static std::vector< SaveLoad > GetSettingsDesc(const SettingTable &settings, bool is_loading)
Get the SaveLoad description for the SettingTable.
void PrepareOldDiffCustom()
Prepare for reading and old diff_custom by zero-ing the memory.
static void SaveSettings(const SettingTable &settings, void *object)
Save and load handler for settings.
Loading of settings chunks before table headers were added.
const SaveLoadCompat _gameopt_sl_compat[]
Original field order for _gameopt.
const SaveLoadCompat _settings_sl_compat[]
Original field order for _settings.
Handlers and description of chunk.
Definition saveload.h:468
All settings together for the game.
Base integer type, including boolean, settings.
void MakeValueValidAndWrite(const void *object, int32_t value) const
Make the value valid and then write it to the setting.
Definition settings.cpp:487
int32_t Read(const void *object) const
Read the integer from the the actual setting.
Definition settings.cpp:567
TimerGameCalendar::Year starting_year
Starting date.
Definition fios.h:43
LandscapeType landscape
Landscape type.
Definition fios.h:42
void Load() const override
Load the chunk.
void Load() const override
Load the chunk.
void LoadCheck(size_t) const override
Load the chunk for game preview.
void Save() const override
Save the chunk.
uint16_t length
(Conditional) length of the variable (eg. arrays) (max array size is 65536 elements).
Definition saveload.h:726
SaveLoadVersion version_to
Save/load the variable before this savegame version.
Definition saveload.h:728
SaveLoadType cmd
The action to take with the saved/loaded type, All types need different action.
Definition saveload.h:724
VarType conv
Type of the variable to be saved; this field combines both FileVarType and MemVarType.
Definition saveload.h:725
SaveLoadVersion version_from
Save/load the variable starting from this savegame version.
Definition saveload.h:727
Properties of config file settings.
SettingFlags flags
Handles how a setting would show up in the GUI (text/currency, etc.).
constexpr const std::string & GetName() const
Get the name of this setting.
SaveLoad save
Internal structure (going to savegame, parts to config).
virtual bool IsIntSetting() const
Check whether this setting is an integer type setting.
const struct IntSettingDesc * AsIntSetting() const
Get the setting description of this setting as an integer setting.
Definition settings.cpp:921