OpenTTD Source  1.11.2
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 #include "../map_func.h"
12 #include "../core/bitmath_func.hpp"
13 #include "../fios.h"
14 #include <array>
15 
16 #include "saveload.h"
17 
18 #include "../safeguards.h"
19 
20 static uint32 _map_dim_x;
21 static uint32 _map_dim_y;
22 
23 static const SaveLoadGlobVarList _map_dimensions[] = {
24  SLEG_CONDVAR(_map_dim_x, SLE_UINT32, SLV_6, SL_MAX_VERSION),
25  SLEG_CONDVAR(_map_dim_y, SLE_UINT32, SLV_6, SL_MAX_VERSION),
26  SLEG_END()
27 };
28 
29 static void Save_MAPS()
30 {
31  _map_dim_x = MapSizeX();
32  _map_dim_y = MapSizeY();
33  SlGlobList(_map_dimensions);
34 }
35 
36 static void Load_MAPS()
37 {
38  SlGlobList(_map_dimensions);
39  AllocateMap(_map_dim_x, _map_dim_y);
40 }
41 
42 static void Check_MAPS()
43 {
44  SlGlobList(_map_dimensions);
45  _load_check_data.map_size_x = _map_dim_x;
46  _load_check_data.map_size_y = _map_dim_y;
47 }
48 
49 static const uint MAP_SL_BUF_SIZE = 4096;
50 
51 static void Load_MAPT()
52 {
53  std::array<byte, MAP_SL_BUF_SIZE> buf;
54  TileIndex size = MapSize();
55 
56  for (TileIndex i = 0; i != size;) {
57  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
58  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type = buf[j];
59  }
60 }
61 
62 static void Save_MAPT()
63 {
64  std::array<byte, MAP_SL_BUF_SIZE> buf;
65  TileIndex size = MapSize();
66 
67  SlSetLength(size);
68  for (TileIndex i = 0; i != size;) {
69  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type;
70  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
71  }
72 }
73 
74 static void Load_MAPH()
75 {
76  std::array<byte, MAP_SL_BUF_SIZE> buf;
77  TileIndex size = MapSize();
78 
79  for (TileIndex i = 0; i != size;) {
80  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
81  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].height = buf[j];
82  }
83 }
84 
85 static void Save_MAPH()
86 {
87  std::array<byte, MAP_SL_BUF_SIZE> buf;
88  TileIndex size = MapSize();
89 
90  SlSetLength(size);
91  for (TileIndex i = 0; i != size;) {
92  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].height;
93  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
94  }
95 }
96 
97 static void Load_MAP1()
98 {
99  std::array<byte, MAP_SL_BUF_SIZE> buf;
100  TileIndex size = MapSize();
101 
102  for (TileIndex i = 0; i != size;) {
103  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
104  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
105  }
106 }
107 
108 static void Save_MAP1()
109 {
110  std::array<byte, MAP_SL_BUF_SIZE> buf;
111  TileIndex size = MapSize();
112 
113  SlSetLength(size);
114  for (TileIndex i = 0; i != size;) {
115  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1;
116  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
117  }
118 }
119 
120 static void Load_MAP2()
121 {
122  std::array<uint16, MAP_SL_BUF_SIZE> buf;
123  TileIndex size = MapSize();
124 
125  for (TileIndex i = 0; i != size;) {
126  SlArray(buf.data(), MAP_SL_BUF_SIZE,
127  /* In those versions the m2 was 8 bits */
128  IsSavegameVersionBefore(SLV_5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
129  );
130  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
131  }
132 }
133 
134 static void Save_MAP2()
135 {
136  std::array<uint16, MAP_SL_BUF_SIZE> buf;
137  TileIndex size = MapSize();
138 
139  SlSetLength(size * sizeof(uint16));
140  for (TileIndex i = 0; i != size;) {
141  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2;
142  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
143  }
144 }
145 
146 static void Load_MAP3()
147 {
148  std::array<byte, MAP_SL_BUF_SIZE> buf;
149  TileIndex size = MapSize();
150 
151  for (TileIndex i = 0; i != size;) {
152  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
153  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
154  }
155 }
156 
157 static void Save_MAP3()
158 {
159  std::array<byte, MAP_SL_BUF_SIZE> buf;
160  TileIndex size = MapSize();
161 
162  SlSetLength(size);
163  for (TileIndex i = 0; i != size;) {
164  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3;
165  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
166  }
167 }
168 
169 static void Load_MAP4()
170 {
171  std::array<byte, MAP_SL_BUF_SIZE> buf;
172  TileIndex size = MapSize();
173 
174  for (TileIndex i = 0; i != size;) {
175  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
176  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
177  }
178 }
179 
180 static void Save_MAP4()
181 {
182  std::array<byte, MAP_SL_BUF_SIZE> buf;
183  TileIndex size = MapSize();
184 
185  SlSetLength(size);
186  for (TileIndex i = 0; i != size;) {
187  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4;
188  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
189  }
190 }
191 
192 static void Load_MAP5()
193 {
194  std::array<byte, MAP_SL_BUF_SIZE> buf;
195  TileIndex size = MapSize();
196 
197  for (TileIndex i = 0; i != size;) {
198  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
199  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
200  }
201 }
202 
203 static void Save_MAP5()
204 {
205  std::array<byte, MAP_SL_BUF_SIZE> buf;
206  TileIndex size = MapSize();
207 
208  SlSetLength(size);
209  for (TileIndex i = 0; i != size;) {
210  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5;
211  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
212  }
213 }
214 
215 static void Load_MAP6()
216 {
217  std::array<byte, MAP_SL_BUF_SIZE> buf;
218  TileIndex size = MapSize();
219 
221  for (TileIndex i = 0; i != size;) {
222  /* 1024, otherwise we overflow on 64x64 maps! */
223  SlArray(buf.data(), 1024, SLE_UINT8);
224  for (uint j = 0; j != 1024; j++) {
225  _me[i++].m6 = GB(buf[j], 0, 2);
226  _me[i++].m6 = GB(buf[j], 2, 2);
227  _me[i++].m6 = GB(buf[j], 4, 2);
228  _me[i++].m6 = GB(buf[j], 6, 2);
229  }
230  }
231  } else {
232  for (TileIndex i = 0; i != size;) {
233  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
234  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m6 = buf[j];
235  }
236  }
237 }
238 
239 static void Save_MAP6()
240 {
241  std::array<byte, MAP_SL_BUF_SIZE> buf;
242  TileIndex size = MapSize();
243 
244  SlSetLength(size);
245  for (TileIndex i = 0; i != size;) {
246  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m6;
247  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
248  }
249 }
250 
251 static void Load_MAP7()
252 {
253  std::array<byte, MAP_SL_BUF_SIZE> buf;
254  TileIndex size = MapSize();
255 
256  for (TileIndex i = 0; i != size;) {
257  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
258  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
259  }
260 }
261 
262 static void Save_MAP7()
263 {
264  std::array<byte, MAP_SL_BUF_SIZE> buf;
265  TileIndex size = MapSize();
266 
267  SlSetLength(size);
268  for (TileIndex i = 0; i != size;) {
269  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7;
270  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
271  }
272 }
273 
274 static void Load_MAP8()
275 {
276  std::array<uint16, MAP_SL_BUF_SIZE> buf;
277  TileIndex size = MapSize();
278 
279  for (TileIndex i = 0; i != size;) {
280  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
281  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j];
282  }
283 }
284 
285 static void Save_MAP8()
286 {
287  std::array<uint16, MAP_SL_BUF_SIZE> buf;
288  TileIndex size = MapSize();
289 
290  SlSetLength(size * sizeof(uint16));
291  for (TileIndex i = 0; i != size;) {
292  for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m8;
293  SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
294  }
295 }
296 
297 
298 extern const ChunkHandler _map_chunk_handlers[] = {
299  { 'MAPS', Save_MAPS, Load_MAPS, nullptr, Check_MAPS, CH_RIFF },
300  { 'MAPT', Save_MAPT, Load_MAPT, nullptr, nullptr, CH_RIFF },
301  { 'MAPH', Save_MAPH, Load_MAPH, nullptr, nullptr, CH_RIFF },
302  { 'MAPO', Save_MAP1, Load_MAP1, nullptr, nullptr, CH_RIFF },
303  { 'MAP2', Save_MAP2, Load_MAP2, nullptr, nullptr, CH_RIFF },
304  { 'M3LO', Save_MAP3, Load_MAP3, nullptr, nullptr, CH_RIFF },
305  { 'M3HI', Save_MAP4, Load_MAP4, nullptr, nullptr, CH_RIFF },
306  { 'MAP5', Save_MAP5, Load_MAP5, nullptr, nullptr, CH_RIFF },
307  { 'MAPE', Save_MAP6, Load_MAP6, nullptr, nullptr, CH_RIFF },
308  { 'MAP7', Save_MAP7, Load_MAP7, nullptr, nullptr, CH_RIFF },
309  { 'MAP8', Save_MAP8, Load_MAP8, nullptr, nullptr, CH_RIFF | CH_LAST },
310 };
TileIndex
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:83
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
_load_check_data
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
Definition: fios_gui.cpp:38
_me
TileExtended * _me
Extended Tiles of the map.
Definition: map.cpp:31
CH_LAST
@ CH_LAST
Last chunk in this array.
Definition: saveload.h:411
saveload.h
ChunkHandler
Handlers and description of chunk.
Definition: saveload.h:380
SLEG_CONDVAR
#define SLEG_CONDVAR(variable, type, from, to)
Storage of a global variable in some savegame versions.
Definition: saveload.h:708
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:676
MapSizeX
static uint MapSizeX()
Get the size of the map along the X.
Definition: map_func.h:72
SLV_5
@ SLV_5
5.0 1429 5.1 1440 5.2 1525 0.3.6
Definition: saveload.h:43
TileExtended::m6
byte m6
General purpose.
Definition: map_type.h:34
MapSize
static uint MapSize()
Get the size of the map.
Definition: map_func.h:92
IsSavegameVersionBefore
static bool IsSavegameVersionBefore(SaveLoadVersion major, byte minor=0)
Checks whether the savegame is below major.
Definition: saveload.h:816
MapSizeY
static uint MapSizeY()
Get the size of the map along the Y.
Definition: map_func.h:82
SLV_42
@ SLV_42
42 7573
Definition: saveload.h:93
SlGlobList
void SlGlobList(const SaveLoadGlobVarList *sldg)
Save or Load (a list of) global variables.
Definition: saveload.cpp:1630
SL_MAX_VERSION
@ SL_MAX_VERSION
Highest possible saveload version.
Definition: saveload.h:329
SLEG_END
#define SLEG_END()
End marker of global variables save or load.
Definition: saveload.h:808
SLV_6
@ SLV_6
6.0 1721 6.1 1768
Definition: saveload.h:46
SaveLoad
SaveLoad type struct.
Definition: saveload.h:517
SlArray
void SlArray(void *array, size_t length, VarType conv)
Save/Load an array.
Definition: saveload.cpp:1051
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