OpenTTD Source  20241108-master-g80f628063a
misc_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"
13 #include "compat/misc_sl_compat.h"
14 
15 #include "../timer/timer_game_calendar.h"
16 #include "../timer/timer_game_economy.h"
17 #include "../zoom_func.h"
18 #include "../window_gui.h"
19 #include "../window_func.h"
20 #include "../viewport_func.h"
21 #include "../gfx_func.h"
22 #include "../core/random_func.hpp"
23 #include "../fios.h"
24 #include "../timer/timer.h"
25 #include "../timer/timer_game_tick.h"
26 
27 #include "../safeguards.h"
28 
29 extern TileIndex _cur_tileloop_tile;
30 extern uint16_t _disaster_delay;
31 extern uint8_t _trees_tick_ctr;
32 
33 /* Keep track of current game position */
34 int _saved_scrollpos_x;
35 int _saved_scrollpos_y;
36 ZoomLevel _saved_scrollpos_zoom;
37 
38 void SaveViewportBeforeSaveGame()
39 {
40  /* Don't use GetMainWindow() in case the window does not exist. */
41  const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
42  if (w == nullptr || w->viewport == nullptr) {
43  /* Ensure saved position is clearly invalid. */
44  _saved_scrollpos_x = INT_MAX;
45  _saved_scrollpos_y = INT_MAX;
46  _saved_scrollpos_zoom = ZOOM_LVL_END;
47  } else {
48  _saved_scrollpos_x = w->viewport->scrollpos_x;
49  _saved_scrollpos_y = w->viewport->scrollpos_y;
50  _saved_scrollpos_zoom = w->viewport->zoom;
51  }
52 }
53 
54 void ResetViewportAfterLoadGame()
55 {
56  Window *w = GetMainWindow();
57 
58  w->viewport->scrollpos_x = _saved_scrollpos_x;
59  w->viewport->scrollpos_y = _saved_scrollpos_y;
60  w->viewport->dest_scrollpos_x = _saved_scrollpos_x;
61  w->viewport->dest_scrollpos_y = _saved_scrollpos_y;
62 
63  Viewport *vp = w->viewport;
64  vp->zoom = std::min(_saved_scrollpos_zoom, ZOOM_LVL_MAX);
65  vp->virtual_width = ScaleByZoom(vp->width, vp->zoom);
66  vp->virtual_height = ScaleByZoom(vp->height, vp->zoom);
67 
68  /* If zoom_max is ZOOM_LVL_MIN then the setting has not been loaded yet, therefore all levels are allowed. */
70  /* Ensure zoom level is allowed */
73  }
74 
75  DoZoomInOutWindow(ZOOM_NONE, w); // update button status
77 }
78 
81 
82 static const SaveLoad _date_desc[] = {
83  SLEG_CONDVAR("date", TimerGameCalendar::date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
85  SLEG_VAR("date_fract", TimerGameCalendar::date_fract, SLE_UINT16),
86  SLEG_CONDVAR("tick_counter", TimerGameTick::counter, SLE_FILE_U16 | SLE_VAR_U64, SL_MIN_VERSION, SLV_U64_TICK_COUNTER),
89  SLEG_CONDVAR("economy_date_fract", TimerGameEconomy::date_fract, SLE_UINT16, SLV_ECONOMY_DATE, SL_MAX_VERSION),
91  SLEG_CONDVAR("age_cargo_skip_counter", _age_cargo_skip_counter, SLE_UINT8, SL_MIN_VERSION, SLV_162),
92  SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
93  SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION),
94  SLEG_VAR("next_disaster_start", _disaster_delay, SLE_UINT16),
95  SLEG_VAR("random_state[0]", _random.state[0], SLE_UINT32),
96  SLEG_VAR("random_state[1]", _random.state[1], SLE_UINT32),
97  SLEG_VAR("company_tick_counter", _cur_company_tick_index, SLE_FILE_U8 | SLE_VAR_U32),
98  SLEG_VAR("trees_tick_counter", _trees_tick_ctr, SLE_UINT8),
99  SLEG_CONDVAR("pause_mode", _pause_mode, SLE_UINT8, SLV_4, SL_MAX_VERSION),
101  /* For older savegames, we load the current value as the "period"; afterload will set the "fired" and "elapsed". */
102  SLEG_CONDVAR("next_competitor_start", _new_competitor_timeout.period.value, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_109),
103  SLEG_CONDVAR("next_competitor_start", _new_competitor_timeout.period.value, SLE_UINT32, SLV_109, SLV_AI_START_DATE),
104  SLEG_CONDVAR("competitors_interval", _new_competitor_timeout.period.value, SLE_UINT32, SLV_AI_START_DATE, SL_MAX_VERSION),
105  SLEG_CONDVAR("competitors_interval_elapsed", _new_competitor_timeout.storage.elapsed, SLE_UINT32, SLV_AI_START_DATE, SL_MAX_VERSION),
106  SLEG_CONDVAR("competitors_interval_fired", _new_competitor_timeout.fired, SLE_BOOL, SLV_AI_START_DATE, SL_MAX_VERSION),
107 };
108 
109 static const SaveLoad _date_check_desc[] = {
110  SLEG_CONDVAR("date", _load_check_data.current_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
111  SLEG_CONDVAR("date", _load_check_data.current_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
112 };
113 
114 /* Save load date related variables as well as persistent tick counters
115  * XXX: currently some unrelated stuff is just put here */
117  DATEChunkHandler() : ChunkHandler('DATE', CH_TABLE) {}
118 
119  void Save() const override
120  {
121  SlTableHeader(_date_desc);
122 
123  SlSetArrayIndex(0);
124  SlGlobList(_date_desc);
125  }
126 
127  void LoadCommon(const SaveLoadTable &slt, const SaveLoadCompatTable &slct) const
128  {
129  const std::vector<SaveLoad> oslt = SlCompatTableHeader(slt, slct);
130 
132  SlGlobList(oslt);
133  if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many DATE entries");
134  }
135 
136  void Load() const override
137  {
138  this->LoadCommon(_date_desc, _date_sl_compat);
139  }
140 
141 
142  void LoadCheck(size_t) const override
143  {
144  this->LoadCommon(_date_check_desc, _date_check_sl_compat);
145 
148  }
149  }
150 };
151 
152 static const SaveLoad _view_desc[] = {
153  SLEG_CONDVAR("x", _saved_scrollpos_x, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
154  SLEG_CONDVAR("x", _saved_scrollpos_x, SLE_INT32, SLV_6, SL_MAX_VERSION),
155  SLEG_CONDVAR("y", _saved_scrollpos_y, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
156  SLEG_CONDVAR("y", _saved_scrollpos_y, SLE_INT32, SLV_6, SL_MAX_VERSION),
157  SLEG_VAR("zoom", _saved_scrollpos_zoom, SLE_UINT8),
158 };
159 
161  VIEWChunkHandler() : ChunkHandler('VIEW', CH_TABLE) {}
162 
163  void Save() const override
164  {
165  SlTableHeader(_view_desc);
166 
167  SlSetArrayIndex(0);
168  SlGlobList(_view_desc);
169  }
170 
171  void Load() const override
172  {
173  const std::vector<SaveLoad> slt = SlCompatTableHeader(_view_desc, _view_sl_compat);
174 
176  SlGlobList(slt);
177  if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many DATE entries");
178  }
179 };
180 
181 static const DATEChunkHandler DATE;
182 static const VIEWChunkHandler VIEW;
183 static const ChunkHandlerRef misc_chunk_handlers[] = {
184  DATE,
185  VIEW,
186 };
187 
188 extern const ChunkHandlerTable _misc_chunk_handlers(misc_chunk_handlers);
A timeout timer will fire once after the interval.
Definition: timer.h:116
static uint16_t sub_date_fract
Subpart of date_fract that we use when calendar days are slower than economy days.
static Date date
Current date in days (day counter).
static DateFract date_fract
Fractional part of the day.
static constexpr TimerGame< struct Calendar >::Date DAYS_TILL_ORIGINAL_BASE_YEAR
The date of the first day of the original base year.
static Date date
Current date in days (day counter).
static DateFract date_fract
Fractional part of the day.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
uint _cur_company_tick_index
used to generate a name for one company that doesn't have a name yet per tick
Definition: company_cmd.cpp:56
TimeoutTimer< TimerGameTick > _new_competitor_timeout({ TimerGameTick::Priority::COMPETITOR_TIMEOUT, 0 }, []() { if(_game_mode==GM_MENU||!AI::CanStartNew()) return;if(_networking &&Company::GetNumItems() >=_settings_client.network.max_companies) return;uint8_t n=0;for(const Company *c :Company::Iterate()) { if(c->is_ai) n++;} if(n >=_settings_game.difficulty.max_no_competitors) return;Command< CMD_COMPANY_CTRL >::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);})
Start a new competitor company if possible.
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
Definition: fios_gui.cpp:41
PauseMode _pause_mode
The current pause mode.
Definition: gfx.cpp:50
GameSessionStats _game_session_stats
Statistics about the current session.
Definition: gfx.cpp:51
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition: gfx.cpp:1529
bool DoZoomInOutWindow(ZoomStateChange how, Window *w)
Zooms a viewport in a window in or out.
Definition: main_gui.cpp:93
uint16_t _disaster_delay
Delay counter for considering the next disaster.
uint8_t _age_cargo_skip_counter
Skip aging of cargo? Used before savegame version 162.
Definition: misc_sl.cpp:79
uint8_t _trees_tick_ctr
Determines when to consider building more trees.
Definition: tree_cmd.cpp:55
Loading for misc chunks before table headers were added.
const SaveLoadCompat _date_check_sl_compat[]
Original field order for _date_check_desc.
const SaveLoadCompat _date_sl_compat[]
Original field order for _date_desc.
const SaveLoadCompat _view_sl_compat[]
Original field order for _view_desc.
Randomizer _random
Random used in the game state calculations.
Definition: random_func.cpp:37
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition: saveload.cpp:658
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
Definition: saveload.cpp:351
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
Definition: saveload.cpp:1888
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
Definition: saveload.cpp:1750
void SlGlobList(const SaveLoadTable &slt)
Save or Load (a list of) global variables.
Definition: saveload.cpp:1942
Functions/types related to saving and loading games.
#define SLEG_CONDSSTR(name, variable, type, from, to)
Storage of a global std::string in some savegame versions.
Definition: saveload.h:1105
#define SLEG_CONDVAR(name, variable, type, from, to)
Storage of a global variable in some savegame versions.
Definition: saveload.h:1074
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition: saveload.h:505
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition: saveload.h:508
#define SLEG_VAR(name, variable, type)
Storage of a global variable in every savegame version.
Definition: saveload.h:1151
std::span< const struct SaveLoadCompat > SaveLoadCompatTable
A table of SaveLoadCompat entries.
Definition: saveload.h:514
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition: saveload.h:1227
@ SLV_AI_START_DATE
309 PR#10653 Removal of individual AI start dates and added a generic one.
Definition: saveload.h:350
@ 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_6
6.0 1721 6.1 1768
Definition: saveload.h:46
@ SLV_SAVEGAME_ID
313 PR#10719 Add an unique ID to every savegame (used to deduplicate surveys).
Definition: saveload.h:355
@ SLV_CALENDAR_SUB_DATE_FRACT
328 PR#11428 Add sub_date_fract to measure calendar days.
Definition: saveload.h:373
@ SLV_RIFF_TO_ARRAY
294 PR#9375 Changed many CH_RIFF chunks to CH_ARRAY chunks.
Definition: saveload.h:332
@ SL_MAX_VERSION
Highest possible saveload version.
Definition: saveload.h:395
@ SL_MIN_VERSION
First savegame version.
Definition: saveload.h:31
@ SLV_ECONOMY_DATE
326 PR#10700 Split calendar and economy timers and dates.
Definition: saveload.h:371
@ SLV_109
109 15075
Definition: saveload.h:173
@ SLV_162
162 22713
Definition: saveload.h:237
@ SLV_31
31 5999
Definition: saveload.h:80
@ SLV_U64_TICK_COUNTER
300 PR#10035 Make tick counter 64bit to avoid wrapping.
Definition: saveload.h:340
std::span< const struct SaveLoad > SaveLoadTable
A table of SaveLoad entries.
Definition: saveload.h:511
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:56
Handlers and description of chunk.
Definition: saveload.h:459
GUISettings gui
settings related to the GUI
void Save() const override
Save the chunk.
Definition: misc_sl.cpp:119
void Load() const override
Load the chunk.
Definition: misc_sl.cpp:136
void LoadCheck(size_t) const override
Load the chunk for game preview.
Definition: misc_sl.cpp:142
ZoomLevel zoom_min
minimum zoom out level
ZoomLevel zoom_max
maximum zoom out level
std::string savegame_id
Unique ID of the savegame.
Definition: openttd.h:57
uint32_t state[2]
The state of the randomizer.
Definition: random_func.hpp:29
SaveLoad type struct.
Definition: saveload.h:711
void Save() const override
Save the chunk.
Definition: misc_sl.cpp:163
void Load() const override
Load the chunk.
Definition: misc_sl.cpp:171
int32_t dest_scrollpos_y
Current destination y coordinate to display (virtual screen coordinate of topleft corner of the viewp...
Definition: window_gui.h:257
int32_t scrollpos_y
Currently shown y coordinate (virtual screen coordinate of topleft corner of the viewport).
Definition: window_gui.h:255
int32_t dest_scrollpos_x
Current destination x coordinate to display (virtual screen coordinate of topleft corner of the viewp...
Definition: window_gui.h:256
int32_t scrollpos_x
Currently shown x coordinate (virtual screen coordinate of topleft corner of the viewport).
Definition: window_gui.h:254
Data structure for viewport, display of a part of the world.
Definition: viewport_type.h:22
int width
Screen width of the viewport.
Definition: viewport_type.h:25
ZoomLevel zoom
The zoom level of the viewport.
Definition: viewport_type.h:33
int virtual_width
width << zoom
Definition: viewport_type.h:30
int height
Screen height of the viewport.
Definition: viewport_type.h:26
int virtual_height
height << zoom
Definition: viewport_type.h:31
Data structure for an opened window.
Definition: window_gui.h:273
ViewportData * viewport
Pointer to viewport data, if present.
Definition: window_gui.h:318
@ ZOOM_IN
Zoom in (get more detailed view).
Definition: viewport_type.h:77
@ ZOOM_NONE
Hack, used to update the button status.
Definition: viewport_type.h:79
@ ZOOM_OUT
Zoom out (get helicopter view).
Definition: viewport_type.h:78
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition: window.cpp:1098
Window * GetMainWindow()
Get the main window, i.e.
Definition: window.cpp:1127
@ WC_MAIN_WINDOW
Main window; Window numbers:
Definition: window_type.h:51
int ScaleByZoom(int value, ZoomLevel zoom)
Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_MIN) When shifting right,...
Definition: zoom_func.h:22
ZoomLevel
All zoom levels we know.
Definition: zoom_type.h:16
@ ZOOM_LVL_MAX
Maximum zoom level.
Definition: zoom_type.h:42
@ ZOOM_LVL_END
End for iteration.
Definition: zoom_type.h:25
@ ZOOM_LVL_MIN
Minimum zoom level.
Definition: zoom_type.h:41