OpenTTD Source: src/saveload/settings_sl.cpp Source File

OpenTTD Source 15.3

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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "../stdafx.h"
11
12#include "saveload.h"
13#include "compat/settings_sl_compat.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
26 void PrepareOldDiffCustom()
27{
28 _old_diff_custom.fill(0);
29}
30
37 void 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++]);
68 sd->AsIntSetting()->MakeValueValidAndWrite(savegame ? &_settings_game : &_settings_newgame, value);
69 }
70}
71
78 static 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) {
86 if (IsSavegameVersionBefore(SLV_TABLE_CHUNKS)) {
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
105 static void LoadSettings(const SettingTable &settings, void *object, const SaveLoadCompatTable &slct)
106{
107 const std::vector<SaveLoad> slt = SlCompatTableHeader(GetSettingsDesc(settings, true), slct);
108
109 if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
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;
117 if (sd->flags.Test(SettingFlag::NoNetworkSync) && _networking && !_network_server) continue;
118 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) 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
133 static 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
143 struct OPTSChunkHandler : ChunkHandler {
144 OPTSChunkHandler() : ChunkHandler('OPTS', CH_READONLY) {}
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 */
151 PrepareOldDiffCustom();
152 LoadSettings(_old_gameopt_settings, &_settings_game, _gameopt_sl_compat);
153 HandleOldDiffCustom(true);
154 }
155};
156
157 struct PATSChunkHandler : ChunkHandler {
158 PATSChunkHandler() : ChunkHandler('PATS', CH_TABLE) {}
159
160 void Load() const override
161 {
162 LoadSettings(GetSaveLoadSettingTable(), &_settings_game, _settings_sl_compat);
163 }
164
165 void LoadCheck(size_t) const override
166 {
167 GameSettings settings{};
168 LoadSettings(GetSaveLoadSettingTable(), &settings, _settings_sl_compat);
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 {
176 SaveSettings(GetSaveLoadSettingTable(), &_settings_game);
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);
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
_load_check_data
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
Definition fios_gui.cpp:41
settings
fluid_settings_t * settings
FluidSynth settings handle.
Definition fluidsynth.cpp:25
_networking
bool _networking
are we in networking mode?
Definition network.cpp:67
_network_server
bool _network_server
network-server is active
Definition network.cpp:68
SlCompatTableHeader
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
Definition saveload.cpp:2037
SlIterateArray
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition saveload.cpp:677
SlErrorCorrupt
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
Definition saveload.cpp:369
SlObject
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
Definition saveload.cpp:1846
SlTableHeader
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
Definition saveload.cpp:1899
saveload.h
Functions/types related to saving and loading games.
SLE_VAR_NULL
@ SLE_VAR_NULL
useful to write zeros in savegame.
Definition saveload.h:667
ChunkHandlerRef
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:524
GetVarFileType
constexpr VarType GetVarFileType(VarType type)
Get the FileType of a setting.
Definition saveload.h:777
ChunkHandlerTable
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:527
SlIsObjectCurrentlyValid
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:1305
SaveLoadCompatTable
std::span< const struct SaveLoadCompat > SaveLoadCompatTable
A table of SaveLoadCompat entries.
Definition saveload.h:533
IsSavegameVersionBefore
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1278
SLV_4
@ 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
@ SLV_RIFF_TO_ARRAY
294 PR#9375 Changed many CH_RIFF chunks to CH_ARRAY chunks.
Definition saveload.h:332
SLV_TABLE_CHUNKS
@ SLV_TABLE_CHUNKS
295 PR#9322 Introduction of CH_TABLE and CH_SPARSE_TABLE.
Definition saveload.h:334
CH_READONLY
@ CH_READONLY
Chunk is never saved.
Definition saveload.h:474
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
GetSaveLoadSettingTable
SettingTable GetSaveLoadSettingTable()
Create a single table with all settings that should be stored/loaded in the savegame.
Definition settings.cpp:1678
_settings_newgame
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
GetSettingFromName
static const SettingDesc * GetSettingFromName(std::string_view name, const SettingTable &settings)
Given a name of setting, return a setting description from the table.
Definition settings.cpp:1640
SettingFlag::NotInSave
@ NotInSave
Do not save with savegame, basically client-based.
SettingFlag::NoNetworkSync
@ NoNetworkSync
Do not synchronize over network (but it is saved if SettingFlag::NotInSave is not set).
GetSettingDesc
static constexpr const SettingDesc * GetSettingDesc(const SettingVariant &desc)
Helper to convert the type of the iterated settings description to a pointer to it.
Definition settings_internal.h:384
HandleOldDiffCustom
void HandleOldDiffCustom(bool savegame)
Reading of the old diff_custom array and transforming it to the new format.
Definition settings_sl.cpp:37
LoadSettings
static void LoadSettings(const SettingTable &settings, void *object, const SaveLoadCompatTable &slct)
Save and load handler for settings.
Definition settings_sl.cpp:105
GetSettingsDesc
static std::vector< SaveLoad > GetSettingsDesc(const SettingTable &settings, bool is_loading)
Get the SaveLoad description for the SettingTable.
Definition settings_sl.cpp:78
PrepareOldDiffCustom
void PrepareOldDiffCustom()
Prepare for reading and old diff_custom by zero-ing the memory.
Definition settings_sl.cpp:26
SaveSettings
static void SaveSettings(const SettingTable &settings, void *object)
Save and load handler for settings.
Definition settings_sl.cpp:133
settings_sl_compat.h
Loading of settings chunks before table headers were added.
_gameopt_sl_compat
const SaveLoadCompat _gameopt_sl_compat[]
Original field order for _gameopt.
Definition settings_sl_compat.h:16
_settings_sl_compat
const SaveLoadCompat _settings_sl_compat[]
Original field order for _settings.
Definition settings_sl_compat.h:30
ChunkHandler
Handlers and description of chunk.
Definition saveload.h:478
GameSettings
All settings together for the game.
Definition settings_type.h:632
IntSettingDesc
Base integer type, including boolean, settings.
Definition settings_internal.h:148
IntSettingDesc::MakeValueValidAndWrite
void MakeValueValidAndWrite(const void *object, int32_t value) const
Make the value valid and then write it to the setting.
Definition settings.cpp:487
IntSettingDesc::Read
int32_t Read(const void *object) const
Read the integer from the the actual setting.
Definition settings.cpp:567
LoadCheckData::starting_year
TimerGameCalendar::Year starting_year
Starting date.
Definition fios.h:43
LoadCheckData::landscape
LandscapeType landscape
Landscape type.
Definition fios.h:42
OPTSChunkHandler
Definition settings_sl.cpp:143
OPTSChunkHandler::Load
void Load() const override
Load the chunk.
Definition settings_sl.cpp:146
PATSChunkHandler
Definition settings_sl.cpp:157
PATSChunkHandler::Load
void Load() const override
Load the chunk.
Definition settings_sl.cpp:160
PATSChunkHandler::LoadCheck
void LoadCheck(size_t) const override
Load the chunk for game preview.
Definition settings_sl.cpp:165
PATSChunkHandler::Save
void Save() const override
Save the chunk.
Definition settings_sl.cpp:174
SaveLoad::length
uint16_t length
(Conditional) length of the variable (eg. arrays) (max array size is 65536 elements).
Definition saveload.h:736
SaveLoad::version_to
SaveLoadVersion version_to
Save/load the variable before this savegame version.
Definition saveload.h:738
SaveLoad::cmd
SaveLoadType cmd
The action to take with the saved/loaded type, All types need different action.
Definition saveload.h:734
SaveLoad::conv
VarType conv
Type of the variable to be saved; this field combines both FileVarType and MemVarType.
Definition saveload.h:735
SaveLoad::version_from
SaveLoadVersion version_from
Save/load the variable starting from this savegame version.
Definition saveload.h:737
SettingDesc
Properties of config file settings.
Definition settings_internal.h:71
SettingDesc::flags
SettingFlags flags
Handles how a setting would show up in the GUI (text/currency, etc.).
Definition settings_internal.h:76
SettingDesc::GetName
constexpr const std::string & GetName() const
Get the name of this setting.
Definition settings_internal.h:87
SettingDesc::save
SaveLoad save
Internal structure (going to savegame, parts to config).
Definition settings_internal.h:78
SettingDesc::IsIntSetting
virtual bool IsIntSetting() const
Check whether this setting is an integer type setting.
Definition settings_internal.h:96
SettingDesc::AsIntSetting
const struct IntSettingDesc * AsIntSetting() const
Get the setting description of this setting as an integer setting.
Definition settings.cpp:921