OpenTTD Source 20241224-master-gf74b0cf984
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 "../network/network.h"
18#include "../fios.h"
19
20#include "../safeguards.h"
21
26{
27 memset(_old_diff_custom, 0, sizeof(_old_diff_custom));
28}
29
36void HandleOldDiffCustom(bool savegame)
37{
38 /* Savegames before v4 didn't have "town_council_tolerance" in savegame yet. */
39 bool has_no_town_council_tolerance = savegame && IsSavegameVersionBefore(SLV_4);
40 uint options_to_load = GAME_DIFFICULTY_NUM - (has_no_town_council_tolerance ? 1 : 0);
41
42 if (!savegame) {
43 /* If we did read to old_diff_custom, then at least one value must be non 0. */
44 bool old_diff_custom_used = false;
45 for (uint i = 0; i < options_to_load && !old_diff_custom_used; i++) {
46 old_diff_custom_used = (_old_diff_custom[i] != 0);
47 }
48
49 if (!old_diff_custom_used) return;
50 }
51
52 /* Iterate over all the old difficulty settings, and convert the list-value to the new setting. */
53 uint i = 0;
54 for (const auto &name : _old_diff_settings) {
55 if (has_no_town_council_tolerance && name == "town_council_tolerance") continue;
56
57 std::string fullname = "difficulty." + name;
58 const SettingDesc *sd = GetSettingFromName(fullname);
59
60 /* Some settings are no longer in use; skip reading those. */
61 if (sd == nullptr) {
62 i++;
63 continue;
64 }
65
66 int32_t value = (int32_t)((name == "max_loan" ? 1000 : 1) * _old_diff_custom[i++]);
68 }
69}
70
77static std::vector<SaveLoad> GetSettingsDesc(const SettingTable &settings, bool is_loading)
78{
79 std::vector<SaveLoad> saveloads;
80 for (auto &desc : settings) {
81 const SettingDesc *sd = GetSettingDesc(desc);
82 if (sd->flags & SF_NOT_IN_SAVE) continue;
83
84 if (is_loading && (sd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) {
86 /* We don't want to read this setting, so we do need to skip over it. */
87 saveloads.push_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});
88 }
89 continue;
90 }
91
92 saveloads.push_back(sd->save);
93 }
94
95 return saveloads;
96}
97
104static void LoadSettings(const SettingTable &settings, void *object, const SaveLoadCompatTable &slct)
105{
106 const std::vector<SaveLoad> slt = SlCompatTableHeader(GetSettingsDesc(settings, true), slct);
107
109 SlObject(object, slt);
110 if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many settings entries");
111
112 /* Ensure all IntSettings are valid (min/max could have changed between versions etc). */
113 for (auto &desc : settings) {
114 const SettingDesc *sd = GetSettingDesc(desc);
115 if (sd->flags & SF_NOT_IN_SAVE) continue;
116 if ((sd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) continue;
118
119 if (sd->IsIntSetting()) {
120 const IntSettingDesc *int_setting = sd->AsIntSetting();
121 int_setting->MakeValueValidAndWrite(object, int_setting->Read(object));
122 }
123 }
124}
125
132static void SaveSettings(const SettingTable &settings, void *object)
133{
134 const std::vector<SaveLoad> slt = GetSettingsDesc(settings, false);
135
136 SlTableHeader(slt);
137
138 SlSetArrayIndex(0);
139 SlObject(object, slt);
140}
141
144
145 void Load() const override
146 {
147 /* Copy over default setting since some might not get loaded in
148 * a networking environment. This ensures for example that the local
149 * autosave-frequency stays when joining a network-server */
151 LoadSettings(_old_gameopt_settings, &_settings_game, _gameopt_sl_compat);
153 }
154};
155
157 PATSChunkHandler() : ChunkHandler('PATS', CH_TABLE) {}
158
163 SettingTable GetSettingTable() const
164 {
165 static const SettingTable saveload_settings_tables[] = {
166 _difficulty_settings,
167 _economy_settings,
168 _game_settings,
169 _linkgraph_settings,
170 _locale_settings,
171 _pathfinding_settings,
172 _script_settings,
173 _world_settings,
174 };
175 static std::vector<SettingVariant> settings_table;
176
177 if (settings_table.empty()) {
178 for (auto &saveload_settings_table : saveload_settings_tables) {
179 for (auto &saveload_setting : saveload_settings_table) {
180 settings_table.push_back(saveload_setting);
181 }
182 }
183 }
184
185 return settings_table;
186 }
187
188 void Load() const override
189 {
190 const auto settings_table = this->GetSettingTable();
191
192 /* Reset all settings to their default, so any settings missing in the savegame
193 * are their default, and not "value of last game". AfterLoad might still fix
194 * up values to become non-default, depending on the saveload version. */
195 for (auto &desc : settings_table) {
196 const SettingDesc *sd = GetSettingDesc(desc);
197 if (sd->flags & SF_NOT_IN_SAVE) continue;
198 if ((sd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) continue;
199
201 }
202
204 }
205
206 void LoadCheck(size_t) const override
207 {
209 }
210
211 void Save() const override
212 {
214 }
215};
216
217static const OPTSChunkHandler OPTS;
218static const PATSChunkHandler PATS;
219static const ChunkHandlerRef setting_chunk_handlers[] = {
220 OPTS,
221 PATS,
222};
223
224extern const ChunkHandlerTable _setting_chunk_handlers(setting_chunk_handlers);
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:65
bool _network_server
network-server is active
Definition network.cpp:66
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:659
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
Definition saveload.cpp:351
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:653
@ CH_READONLY
Chunk is never saved.
Definition saveload.h:459
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:509
constexpr VarType GetVarFileType(VarType type)
Get the FileType of a setting.
Definition saveload.h:762
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:512
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:1290
std::span< const struct SaveLoadCompat > SaveLoadCompatTable
A table of SaveLoadCompat entries.
Definition saveload.h:518
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1263
@ 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
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:57
static const SettingDesc * GetSettingFromName(const std::string_view name, const SettingTable &settings)
Given a name of setting, return a setting description from the table.
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:58
@ SF_NOT_IN_SAVE
Do not save with savegame, basically client-based.
@ SF_NO_NETWORK_SYNC
Do not synchronize over network (but it is saved if SF_NOT_IN_SAVE 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:463
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:482
int32_t Read(const void *object) const
Read the integer from the the actual setting.
Definition settings.cpp:561
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.
SettingTable GetSettingTable() const
Create a single table with all settings that should be stored/loaded in the savegame.
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:721
SaveLoadVersion version_to
Save/load the variable before this savegame version.
Definition saveload.h:723
SaveLoadType cmd
The action to take with the saved/loaded type, All types need different action.
Definition saveload.h:719
VarType conv
Type of the variable to be saved; this field combines both FileVarType and MemVarType.
Definition saveload.h:720
SaveLoadVersion version_from
Save/load the variable starting from this savegame version.
Definition saveload.h:722
Properties of config file settings.
virtual void ResetToDefault(void *object) const =0
Reset the setting to its default value.
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:910
SettingFlag flags
Handles how a setting would show up in the GUI (text/currency, etc.).