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