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

OpenTTD Source 13.1

map_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/map_sl_compat.h"
14
15 #include "../map_func.h"
16 #include "../core/bitmath_func.hpp"
17 #include "../fios.h"
18 #include <array>
19
20 #include "../safeguards.h"
21
22 static uint32 _map_dim_x;
23 static uint32 _map_dim_y;
24
25 static const SaveLoad _map_desc[] = {
26 SLEG_CONDVAR("dim_x", _map_dim_x, SLE_UINT32, SLV_6, SL_MAX_VERSION),
27 SLEG_CONDVAR("dim_y", _map_dim_y, SLE_UINT32, SLV_6, SL_MAX_VERSION),
28 };
29
30 struct MAPSChunkHandler : ChunkHandler {
31 MAPSChunkHandler() : ChunkHandler('MAPS', CH_TABLE) {}
32
33 void Save() const override
34 {
35 SlTableHeader(_map_desc);
36
37 _map_dim_x = MapSizeX();
38 _map_dim_y = MapSizeY();
39
40 SlSetArrayIndex(0);
41 SlGlobList(_map_desc);
42 }
43
44 void Load() const override
45 {
46 const std::vector<SaveLoad> slt = SlCompatTableHeader(_map_desc, _map_sl_compat);
47
48 if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
49 SlGlobList(slt);
50 if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many MAPS entries");
51
52 AllocateMap(_map_dim_x, _map_dim_y);
53 }
54
55 void LoadCheck(size_t) const override
56 {
57 const std::vector<SaveLoad> slt = SlCompatTableHeader(_map_desc, _map_sl_compat);
58
59 if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
60 SlGlobList(slt);
61 if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many MAPS entries");
62
63 _load_check_data.map_size_x = _map_dim_x;
64 _load_check_data.map_size_y = _map_dim_y;
65 }
66 };
67
68 static const uint MAP_SL_BUF_SIZE = 4096;
69
70 struct MAPTChunkHandler : ChunkHandler {
71 MAPTChunkHandler() : ChunkHandler('MAPT', CH_RIFF) {}
72
73 void Load() const override
74 {
75 std::array<byte, MAP_SL_BUF_SIZE> buf;
76 TileIndex size = MapSize();
77
78 for (TileIndex i = 0; i != size;) {
79 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
80 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type = buf[j];
81 }
82 }
83
84 void Save() const override
85 {
86 std::array<byte, MAP_SL_BUF_SIZE> buf;
87 TileIndex size = MapSize();
88
89 SlSetLength(size);
90 for (TileIndex i = 0; i != size;) {
91 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type;
92 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
93 }
94 }
95 };
96
97 struct MAPHChunkHandler : ChunkHandler {
98 MAPHChunkHandler() : ChunkHandler('MAPH', CH_RIFF) {}
99
100 void Load() const override
101 {
102 std::array<byte, MAP_SL_BUF_SIZE> buf;
103 TileIndex size = MapSize();
104
105 for (TileIndex i = 0; i != size;) {
106 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
107 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].height = buf[j];
108 }
109 }
110
111 void Save() const override
112 {
113 std::array<byte, MAP_SL_BUF_SIZE> buf;
114 TileIndex size = MapSize();
115
116 SlSetLength(size);
117 for (TileIndex i = 0; i != size;) {
118 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].height;
119 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
120 }
121 }
122 };
123
124 struct MAPOChunkHandler : ChunkHandler {
125 MAPOChunkHandler() : ChunkHandler('MAPO', CH_RIFF) {}
126
127 void Load() const override
128 {
129 std::array<byte, MAP_SL_BUF_SIZE> buf;
130 TileIndex size = MapSize();
131
132 for (TileIndex i = 0; i != size;) {
133 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
134 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
135 }
136 }
137
138 void Save() const override
139 {
140 std::array<byte, MAP_SL_BUF_SIZE> buf;
141 TileIndex size = MapSize();
142
143 SlSetLength(size);
144 for (TileIndex i = 0; i != size;) {
145 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1;
146 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
147 }
148 }
149 };
150
151 struct MAP2ChunkHandler : ChunkHandler {
152 MAP2ChunkHandler() : ChunkHandler('MAP2', CH_RIFF) {}
153
154 void Load() const override
155 {
156 std::array<uint16, MAP_SL_BUF_SIZE> buf;
157 TileIndex size = MapSize();
158
159 for (TileIndex i = 0; i != size;) {
160 SlCopy(buf.data(), MAP_SL_BUF_SIZE,
161 /* In those versions the m2 was 8 bits */
162 IsSavegameVersionBefore(SLV_5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
163 );
164 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
165 }
166 }
167
168 void Save() const override
169 {
170 std::array<uint16, MAP_SL_BUF_SIZE> buf;
171 TileIndex size = MapSize();
172
173 SlSetLength(size * sizeof(uint16));
174 for (TileIndex i = 0; i != size;) {
175 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2;
176 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
177 }
178 }
179 };
180
181 struct M3LOChunkHandler : ChunkHandler {
182 M3LOChunkHandler() : ChunkHandler('M3LO', CH_RIFF) {}
183
184 void Load() const override
185 {
186 std::array<byte, MAP_SL_BUF_SIZE> buf;
187 TileIndex size = MapSize();
188
189 for (TileIndex i = 0; i != size;) {
190 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
191 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
192 }
193 }
194
195 void Save() const override
196 {
197 std::array<byte, MAP_SL_BUF_SIZE> buf;
198 TileIndex size = MapSize();
199
200 SlSetLength(size);
201 for (TileIndex i = 0; i != size;) {
202 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3;
203 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
204 }
205 }
206 };
207
208 struct M3HIChunkHandler : ChunkHandler {
209 M3HIChunkHandler() : ChunkHandler('M3HI', CH_RIFF) {}
210
211 void Load() const override
212 {
213 std::array<byte, MAP_SL_BUF_SIZE> buf;
214 TileIndex size = MapSize();
215
216 for (TileIndex i = 0; i != size;) {
217 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
218 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
219 }
220 }
221
222 void Save() const override
223 {
224 std::array<byte, MAP_SL_BUF_SIZE> buf;
225 TileIndex size = MapSize();
226
227 SlSetLength(size);
228 for (TileIndex i = 0; i != size;) {
229 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4;
230 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
231 }
232 }
233 };
234
235 struct MAP5ChunkHandler : ChunkHandler {
236 MAP5ChunkHandler() : ChunkHandler('MAP5', CH_RIFF) {}
237
238 void Load() const override
239 {
240 std::array<byte, MAP_SL_BUF_SIZE> buf;
241 TileIndex size = MapSize();
242
243 for (TileIndex i = 0; i != size;) {
244 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
245 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
246 }
247 }
248
249 void Save() const override
250 {
251 std::array<byte, MAP_SL_BUF_SIZE> buf;
252 TileIndex size = MapSize();
253
254 SlSetLength(size);
255 for (TileIndex i = 0; i != size;) {
256 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5;
257 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
258 }
259 }
260 };
261
262 struct MAPEChunkHandler : ChunkHandler {
263 MAPEChunkHandler() : ChunkHandler('MAPE', CH_RIFF) {}
264
265 void Load() const override
266 {
267 std::array<byte, MAP_SL_BUF_SIZE> buf;
268 TileIndex size = MapSize();
269
270 if (IsSavegameVersionBefore(SLV_42)) {
271 for (TileIndex i = 0; i != size;) {
272 /* 1024, otherwise we overflow on 64x64 maps! */
273 SlCopy(buf.data(), 1024, SLE_UINT8);
274 for (uint j = 0; j != 1024; j++) {
275 _me[i++].m6 = GB(buf[j], 0, 2);
276 _me[i++].m6 = GB(buf[j], 2, 2);
277 _me[i++].m6 = GB(buf[j], 4, 2);
278 _me[i++].m6 = GB(buf[j], 6, 2);
279 }
280 }
281 } else {
282 for (TileIndex i = 0; i != size;) {
283 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
284 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m6 = buf[j];
285 }
286 }
287 }
288
289 void Save() const override
290 {
291 std::array<byte, MAP_SL_BUF_SIZE> buf;
292 TileIndex size = MapSize();
293
294 SlSetLength(size);
295 for (TileIndex i = 0; i != size;) {
296 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m6;
297 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
298 }
299 }
300 };
301
302 struct MAP7ChunkHandler : ChunkHandler {
303 MAP7ChunkHandler() : ChunkHandler('MAP7', CH_RIFF) {}
304
305 void Load() const override
306 {
307 std::array<byte, MAP_SL_BUF_SIZE> buf;
308 TileIndex size = MapSize();
309
310 for (TileIndex i = 0; i != size;) {
311 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
312 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
313 }
314 }
315
316 void Save() const override
317 {
318 std::array<byte, MAP_SL_BUF_SIZE> buf;
319 TileIndex size = MapSize();
320
321 SlSetLength(size);
322 for (TileIndex i = 0; i != size;) {
323 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7;
324 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
325 }
326 }
327 };
328
329 struct MAP8ChunkHandler : ChunkHandler {
330 MAP8ChunkHandler() : ChunkHandler('MAP8', CH_RIFF) {}
331
332 void Load() const override
333 {
334 std::array<uint16, MAP_SL_BUF_SIZE> buf;
335 TileIndex size = MapSize();
336
337 for (TileIndex i = 0; i != size;) {
338 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
339 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j];
340 }
341 }
342
343 void Save() const override
344 {
345 std::array<uint16, MAP_SL_BUF_SIZE> buf;
346 TileIndex size = MapSize();
347
348 SlSetLength(size * sizeof(uint16));
349 for (TileIndex i = 0; i != size;) {
350 for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m8;
351 SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
352 }
353 }
354 };
355
356 static const MAPSChunkHandler MAPS;
357 static const MAPTChunkHandler MAPT;
358 static const MAPHChunkHandler MAPH;
359 static const MAPOChunkHandler MAPO;
360 static const MAP2ChunkHandler MAP2;
361 static const M3LOChunkHandler M3LO;
362 static const M3HIChunkHandler M3HI;
363 static const MAP5ChunkHandler MAP5;
364 static const MAPEChunkHandler MAPE;
365 static const MAP7ChunkHandler MAP7;
366 static const MAP8ChunkHandler MAP8;
367 static const ChunkHandlerRef map_chunk_handlers[] = {
368 MAPS,
369 MAPT,
370 MAPH,
371 MAPO,
372 MAP2,
373 M3LO,
374 M3HI,
375 MAP5,
376 MAPE,
377 MAP7,
378 MAP8,
379 };
380
381 extern const ChunkHandlerTable _map_chunk_handlers(map_chunk_handlers);
MAPHChunkHandler::Load
void Load() const override
Load the chunk.
Definition: map_sl.cpp:100
SLV_RIFF_TO_ARRAY
@ SLV_RIFF_TO_ARRAY
294 PR#9375 Changed many CH_RIFF chunks to CH_ARRAY chunks.
Definition: saveload.h:336
GB
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Definition: bitmath_func.hpp:32
MAPOChunkHandler::Save
void Save() const override
Save the chunk.
Definition: map_sl.cpp:138
ChunkHandlerRef
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition: saveload.h:449
SlCopy
void SlCopy(void *object, size_t length, VarType conv)
Copy a list of SL_VARs to/from a savegame.
Definition: saveload.cpp:1152
MAP5ChunkHandler::Load
void Load() const override
Load the chunk.
Definition: map_sl.cpp:238
MAPSChunkHandler::LoadCheck
void LoadCheck(size_t) const override
Load the chunk for game preview.
Definition: map_sl.cpp:55
_load_check_data
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
Definition: fios_gui.cpp:39
MAPSChunkHandler::Save
void Save() const override
Save the chunk.
Definition: map_sl.cpp:33
_me
TileExtended * _me
Extended Tiles of the map.
Definition: map.cpp:31
TileIndex
The index/ID of a Tile.
Definition: tile_type.h:85
MAPSChunkHandler::Load
void Load() const override
Load the chunk.
Definition: map_sl.cpp:44
MAP5ChunkHandler::Save
void Save() const override
Save the chunk.
Definition: map_sl.cpp:249
saveload.h
ChunkHandler::type
ChunkType type
Type of the chunk.
Definition: saveload.h:414
MAPOChunkHandler
Definition: map_sl.cpp:124
MAP8ChunkHandler
Definition: map_sl.cpp:329
MAP2ChunkHandler::Load
void Load() const override
Load the chunk.
Definition: map_sl.cpp:154
ChunkHandler
Handlers and description of chunk.
Definition: saveload.h:412
SlSetLength
void SlSetLength(size_t length)
Sets the length of either a RIFF object or the number of items in an array.
Definition: saveload.cpp:724
MAP8ChunkHandler::Save
void Save() const override
Save the chunk.
Definition: map_sl.cpp:343
M3HIChunkHandler
Definition: map_sl.cpp:208
MAP7ChunkHandler
Definition: map_sl.cpp:302
SlGlobList
void SlGlobList(const SaveLoadTable &slt)
Save or Load (a list of) global variables.
Definition: saveload.cpp:2084
MapSizeX
static uint MapSizeX()
Get the size of the map along the X.
Definition: map_func.h:72
MAPHChunkHandler::Save
void Save() const override
Save the chunk.
Definition: map_sl.cpp:111
SLV_5
@ SLV_5
5.0 1429 5.1 1440 5.2 1525 0.3.6
Definition: saveload.h:47
TileExtended::m6
byte m6
General purpose.
Definition: map_type.h:34
M3HIChunkHandler::Load
void Load() const override
Load the chunk.
Definition: map_sl.cpp:211
MapSize
static uint MapSize()
Get the size of the map.
Definition: map_func.h:92
MAPTChunkHandler
Definition: map_sl.cpp:70
MAP2ChunkHandler
Definition: map_sl.cpp:151
span
A trimmed down version of what std::span will be in C++20.
Definition: span_type.hpp:60
MAP2ChunkHandler::Save
void Save() const override
Save the chunk.
Definition: map_sl.cpp:168
M3LOChunkHandler::Save
void Save() const override
Save the chunk.
Definition: map_sl.cpp:195
MAP7ChunkHandler::Save
void Save() const override
Save the chunk.
Definition: map_sl.cpp:316
_map_sl_compat
const SaveLoadCompat _map_sl_compat[]
Original field order for _map_desc.
Definition: map_sl_compat.h:16
MAPSChunkHandler
Definition: map_sl.cpp:30
M3HIChunkHandler::Save
void Save() const override
Save the chunk.
Definition: map_sl.cpp:222
MAP7ChunkHandler::Load
void Load() const override
Load the chunk.
Definition: map_sl.cpp:305
IsSavegameVersionBefore
static bool IsSavegameVersionBefore(SaveLoadVersion major, byte minor=0)
Checks whether the savegame is below major.
Definition: saveload.h:1030
MapSizeY
static uint MapSizeY()
Get the size of the map along the Y.
Definition: map_func.h:82
MAP8ChunkHandler::Load
void Load() const override
Load the chunk.
Definition: map_sl.cpp:332
SLV_42
@ SLV_42
42 7573
Definition: saveload.h:97
SL_MAX_VERSION
@ SL_MAX_VERSION
Highest possible saveload version.
Definition: saveload.h:348
MAPEChunkHandler
Definition: map_sl.cpp:262
SLEG_CONDVAR
#define SLEG_CONDVAR(name, variable, type, from, to)
Storage of a global variable in some savegame versions.
Definition: saveload.h:855
SLV_6
@ SLV_6
6.0 1721 6.1 1768
Definition: saveload.h:50
SlErrorCorrupt
void NORETURN SlErrorCorrupt(const char *msg)
Error handler for corrupt savegames.
Definition: saveload.cpp:365
MAPTChunkHandler::Save
void Save() const override
Save the chunk.
Definition: map_sl.cpp:84
MAPEChunkHandler::Save
void Save() const override
Save the chunk.
Definition: map_sl.cpp:289
MAPEChunkHandler::Load
void Load() const override
Load the chunk.
Definition: map_sl.cpp:265
M3LOChunkHandler::Load
void Load() const override
Load the chunk.
Definition: map_sl.cpp:184
SlCompatTableHeader
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
Definition: saveload.cpp:2030
MAPOChunkHandler::Load
void Load() const override
Load the chunk.
Definition: map_sl.cpp:127
MAP5ChunkHandler
Definition: map_sl.cpp:235
SlTableHeader
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
Definition: saveload.cpp:1892
SaveLoad
SaveLoad type struct.
Definition: saveload.h:659
AllocateMap
void AllocateMap(uint size_x, uint size_y)
(Re)allocates a map with the given dimension
Definition: map.cpp:39
_m
Tile * _m
Tiles of the map.
Definition: map.cpp:30
SlIterateArray
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition: saveload.cpp:671
M3LOChunkHandler
Definition: map_sl.cpp:181
map_sl_compat.h
MAPHChunkHandler
Definition: map_sl.cpp:97
MAPTChunkHandler::Load
void Load() const override
Load the chunk.
Definition: map_sl.cpp:73