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/>.
10 /** @file map_sl.cpp Code handling saving and loading of map */
12 #include "../stdafx.h"
13 #include "../core/bitmath_func.hpp"
14 #include "../core/random_func.hpp"
17 #include "../landscape_type.h"
18 #include "../signal_type.h"
19 #include "../map/ground.h"
20 #include "../map/water.h"
21 #include "../map/station.h"
23 #include "saveload_buffer.h"
27 OLD_MP_CLEAR
, ///< A tile without any structures, i.e. grass, docks, farm fields etc.
28 OLD_MP_RAILWAY
, ///< A railway
29 OLD_MP_ROAD
, ///< A tile with road (or tram tracks)
30 OLD_MP_HOUSE
, ///< A house by a town
31 OLD_MP_TREES
, ///< Tile got trees
32 OLD_MP_STATION
, ///< A tile of a station
33 OLD_MP_WATER
, ///< Water tile
34 OLD_MP_VOID
, ///< Invisible tiles at the SW and SE border
35 OLD_MP_INDUSTRY
, ///< Part of an industry
36 OLD_MP_TUNNELBRIDGE
, ///< Tunnel entry/exit and bridge heads
37 OLD_MP_OBJECT
, ///< Contains objects such as transmitters and owned land
40 static inline OldTileType
GetOldTileType(TileIndex tile
)
42 assert(tile
< MapSize());
43 return (OldTileType
)GB(_mth
[tile
], 4, 4);
46 static inline bool IsOldTileType(TileIndex tile
, OldTileType type
)
48 return GetOldTileType(tile
) == type
;
51 static inline void SetOldTileType(TileIndex tile
, OldTileType type
)
53 SB(_mth
[tile
], 4, 4, type
);
56 static inline uint
OldTileHeight(TileIndex tile
)
58 assert(tile
< MapSize());
59 return GB(_mth
[tile
], 0, 4);
62 static bool IsOldTileFlat(TileIndex tile
)
64 assert(tile
< MapSize());
66 if (TileX(tile
) == MapMaxX() || TileY(tile
) == MapMaxY() ||
67 TileX(tile
) == 0 || TileY(tile
) == 0) {
71 uint h
= OldTileHeight(tile
);
72 if (OldTileHeight(tile
+ TileDiffXY(1, 0)) != h
) return false;
73 if (OldTileHeight(tile
+ TileDiffXY(0, 1)) != h
) return false;
74 if (OldTileHeight(tile
+ TileDiffXY(1, 1)) != h
) return false;
81 * Fix map array after loading an old savegame
83 void AfterLoadMap(const SavegameTypeVersion
*stv
)
85 TileIndex map_size
= MapSize();
87 /* in legacy version 2.1 of the savegame, town owner was unified. */
88 if (IsOTTDSavegameVersionBefore(stv
, 2, 1)) {
89 for (TileIndex tile
= 0; tile
< map_size
; tile
++) {
90 switch (GetOldTileType(tile
)) {
92 if (GB(_mc
[tile
].m5
, 4, 2) == 1 && HasBit(_mc
[tile
].m3
, 7)) {
93 _mc
[tile
].m3
= OWNER_TOWN
;
97 case OLD_MP_TUNNELBRIDGE
:
98 if (_mc
[tile
].m1
& 0x80) SB(_mc
[tile
].m1
, 0, 5, OWNER_TOWN
);
106 /* In legacy version 6.1 we put the town index in the map-array. To do this, we need
107 * to use m2 (16bit big), so we need to clean m2, and that is where this is
109 if (IsOTTDSavegameVersionBefore(stv
, 6, 1)) {
110 for (TileIndex t
= 0; t
< map_size
; t
++) {
111 switch (GetOldTileType(t
)) {
113 _mc
[t
].m4
= _mc
[t
].m2
;
118 _mc
[t
].m4
|= (_mc
[t
].m2
<< 4);
127 /* From legacy version 15, we moved a semaphore bit from bit 2 to bit 3 in m4, making
128 * room for PBS. Now in version 21 move it back :P. */
129 if (IsOTTDSavegameVersionBefore(stv
, 21) && !IsOTTDSavegameVersionBefore(stv
, 15)) {
130 for (TileIndex t
= 0; t
< map_size
; t
++) {
131 switch (GetOldTileType(t
)) {
133 if (GB(_mc
[t
].m5
, 6, 2) == 1) {
134 /* convert PBS signals to combo-signals */
135 if (HasBit(_mc
[t
].m2
, 2)) SB(_mc
[t
].m2
, 0, 3, 3);
137 /* move the signal variant back */
138 SB(_mc
[t
].m2
, 3, 1, HasBit(_mc
[t
].m2
, 3) ? SIG_SEMAPHORE
: SIG_ELECTRIC
);
139 ClrBit(_mc
[t
].m2
, 3);
142 /* Clear PBS reservation on track */
143 if (GB(_mc
[t
].m5
, 6, 2) != 3) {
144 SB(_mc
[t
].m4
, 4, 4, 0);
146 ClrBit(_mc
[t
].m3
, 6);
150 case OLD_MP_STATION
: // Clear PBS reservation on station
151 ClrBit(_mc
[t
].m3
, 6);
159 if (IsOTTDSavegameVersionBefore(stv
, 48)) {
160 for (TileIndex t
= 0; t
< map_size
; t
++) {
161 switch (GetOldTileType(t
)) {
163 if (!HasBit(_mc
[t
].m5
, 7)) {
164 /* Swap ground type and signal type for plain rail tiles, so the
165 * ground type uses the same bits as for depots and waypoints. */
166 uint tmp
= GB(_mc
[t
].m4
, 0, 4);
167 SB(_mc
[t
].m4
, 0, 4, GB(_mc
[t
].m2
, 0, 4));
168 SB(_mc
[t
].m2
, 0, 4, tmp
);
169 } else if (HasBit(_mc
[t
].m5
, 2)) {
170 /* Split waypoint and depot rail type and remove the subtype. */
171 ClrBit(_mc
[t
].m5
, 2);
172 ClrBit(_mc
[t
].m5
, 6);
177 /* Swap m3 and m4, so the track type for rail crossings is the
178 * same as for normal rail. */
179 Swap(_mc
[t
].m3
, _mc
[t
].m4
);
187 /* From legacy version 53, the map array was changed for house tiles to allow
188 * space for newhouses grf features. A new byte, m7, was also added. */
189 if (IsOTTDSavegameVersionBefore(stv
, 53)) {
190 for (TileIndex t
= 0; t
< map_size
; t
++) {
191 if (IsOldTileType(t
, OLD_MP_HOUSE
)) {
192 if (GB(_mc
[t
].m3
, 6, 2) != TOWN_HOUSE_COMPLETED
) {
193 /* Move the construction stage from m3[7..6] to m5[5..4].
194 * The construction counter does not have to move. */
195 SB(_mc
[t
].m5
, 3, 2, GB(_mc
[t
].m3
, 6, 2));
196 SB(_mc
[t
].m3
, 6, 2, 0);
198 /* The "lift has destination" bit has been moved from
200 SB(_mc
[t
].m7
, 0, 1, HasBit(_mc
[t
].m5
, 7));
201 ClrBit(_mc
[t
].m5
, 7);
203 /* The "lift is moving" bit has been removed, as it does
204 * the same job as the "lift has destination" bit. */
205 ClrBit(_mc
[t
].m1
, 7);
207 /* The position of the lift goes from m1[7..0] to m0[7..2],
208 * making m1 totally free, now. The lift position does not
209 * have to be a full byte since the maximum value is 36. */
210 SB(_mc
[t
].m0
, 2, 6, GB(_mc
[t
].m1
, 0, 6 ));
219 if (IsOTTDSavegameVersionBefore(stv
, 64)) {
220 /* Since now we allow different signal types and variants on a single tile.
221 * Move signal states to m4 to make room and clone the signal type/variant. */
222 for (TileIndex t
= 0; t
< map_size
; t
++) {
223 if (IsOldTileType(t
, OLD_MP_RAILWAY
) && GB(_mc
[t
].m5
, 6, 2) == 1) {
224 /* move signal states */
225 SB(_mc
[t
].m4
, 4, 4, GB(_mc
[t
].m2
, 4, 4));
226 /* clone signal type and variant */
227 SB(_mc
[t
].m2
, 4, 3, GB(_mc
[t
].m2
, 0, 3));
228 ClrBit(_mc
[t
].m2
, 7);
233 if (IsOTTDSavegameVersionBefore(stv
, 72)) {
234 /* Locks in very old savegames had OWNER_WATER as owner */
235 for (TileIndex t
= 0; t
< map_size
; t
++) {
236 switch (GetOldTileType(t
)) {
240 if (GB(_mc
[t
].m5
, 4, 4) == 1 && GB(_mc
[t
].m1
, 0, 5) == OWNER_WATER
) SB(_mc
[t
].m1
, 0, 5, OWNER_NONE
);
243 case OLD_MP_STATION
: {
244 if (HasBit(_mc
[t
].m0
, 3)) SetBit(_mc
[t
].m0
, 2);
245 byte gfx
= _mc
[t
].m5
;
247 if ( IsInsideMM(gfx
, 0, 8)) { // Rail station
250 } else if (IsInsideMM(gfx
, 8, 67)) { // Airport
253 } else if (IsInsideMM(gfx
, 67, 71)) { // Truck
255 _mc
[t
].m5
= gfx
- 67;
256 } else if (IsInsideMM(gfx
, 71, 75)) { // Bus
258 _mc
[t
].m5
= gfx
- 71;
259 } else if (gfx
== 75) { // Oil rig
261 _mc
[t
].m5
= gfx
- 75;
262 } else if (IsInsideMM(gfx
, 76, 82)) { // Dock
264 _mc
[t
].m5
= gfx
- 76;
265 } else if (gfx
== 82) { // Buoy
267 _mc
[t
].m5
= gfx
- 82;
268 } else if (IsInsideMM(gfx
, 83, 168)) { // Extended airport
270 _mc
[t
].m5
= gfx
- 83 + 67 - 8;
271 } else if (IsInsideMM(gfx
, 168, 170)) { // Drive through truck
273 _mc
[t
].m5
= gfx
- 168 + GFX_ROAD_DT_OFFSET
;
274 } else if (IsInsideMM(gfx
, 170, 172)) { // Drive through bus
276 _mc
[t
].m5
= gfx
- 170 + GFX_ROAD_DT_OFFSET
;
278 throw SlCorrupt("Invalid station tile");
280 SB(_mc
[t
].m0
, 3, 3, st
);
287 /* Before legacy version 81, the density of grass was always stored as zero, and
288 * grassy trees were always drawn fully grassy. Furthermore, trees on rough
289 * land used to have zero density, now they have full density. Therefore,
290 * make all grassy/rough land trees have a density of 3. */
291 if (IsOTTDSavegameVersionBefore(stv
, 81)) {
292 for (TileIndex t
= 0; t
< map_size
; t
++) {
293 if (GetOldTileType(t
) == OLD_MP_TREES
) {
294 uint groundType
= GB(_mc
[t
].m2
, 4, 2);
295 if (groundType
!= 2) SB(_mc
[t
].m2
, 6, 2, 3);
300 /* The void tiles on the southern border used to belong to a wrong class (pre 4.3).
301 * This problem appears in savegame version 21 too, see r3455. But after loading the
302 * savegame and saving again, the buggy map array could be converted to new savegame
303 * version. It didn't show up before r12070. */
304 if (IsOTTDSavegameVersionBefore(stv
, 87)) {
307 for (t
= MapMaxX(); t
< map_size
- 1; t
+= MapSizeX()) {
308 _mth
[t
] = OLD_MP_VOID
<< 4;
309 memset(&_mc
[t
], 0, sizeof(_mc
[t
]));
312 for (t
= MapSizeX() * MapMaxY(); t
< map_size
; t
++) {
313 _mth
[t
] = OLD_MP_VOID
<< 4;
314 memset(&_mc
[t
], 0, sizeof(_mc
[t
]));
318 if (IsOTTDSavegameVersionBefore(stv
, 114)) {
319 bool old_bridge
= IsOTTDSavegameVersionBefore(stv
, 42);
320 bool add_roadtypes
= IsOTTDSavegameVersionBefore(stv
, 61);
322 for (TileIndex t
= 0; t
< map_size
; t
++) {
323 switch (GetOldTileType(t
)) {
328 if (old_bridge
) SB(_mc
[t
].m0
, 6, 2, 0);
333 SB(_mc
[t
].m5
, 6, 2, GB(_mc
[t
].m5
, 4, 2));
334 SB(_mc
[t
].m7
, 6, 2, 1);
336 SB(_mc
[t
].m7
, 6, 2, GB(_mc
[t
].m7
, 5, 3));
338 SB(_mc
[t
].m7
, 5, 1, GB(_mc
[t
].m3
, 7, 1)); // snow/desert
339 switch (GB(_mc
[t
].m5
, 6, 2)) {
340 default: throw SlCorrupt("Invalid road tile type");
343 SB(_mc
[t
].m0
, 2, 4, 0);
345 SB(_mc
[t
].m5
, 0, 4, GB(_mc
[t
].m4
, 0, 4)); // road bits
347 SB(_mc
[t
].m7
, 0, 4, GB(_mc
[t
].m3
, 0, 4)); // road works
348 SB(_mc
[t
].m0
, 3, 3, GB(_mc
[t
].m3
, 4, 3)); // ground
349 SB(_mc
[t
].m3
, 0, 4, add_roadtypes
? 0 : GB(_mc
[t
].m4
, 4, 4)); // tram bits
350 SB(_mc
[t
].m3
, 4, 4, GB(_mc
[t
].m5
, 0, 4)); // tram owner
354 SB(_mc
[t
].m7
, 0, 5, GB(_mc
[t
].m4
, 0, 5)); // road owner
355 SB(_mc
[t
].m0
, 3, 3, GB(_mc
[t
].m3
, 4, 3)); // ground
356 SB(_mc
[t
].m3
, 4, 4, GB(_mc
[t
].m5
, 0, 4)); // tram owner
357 SB(_mc
[t
].m5
, 0, 1, add_roadtypes
? GB(_mc
[t
].m5
, 3, 1) : GB(_mc
[t
].m4
, 6, 1)); // road axis
358 SB(_mc
[t
].m5
, 5, 1, add_roadtypes
? GB(_mc
[t
].m5
, 2, 1) : GB(_mc
[t
].m4
, 5, 1)); // crossing state
365 if (old_bridge
) SB(_mc
[t
].m0
, 6, 2, 0);
369 if (GB(_mc
[t
].m0
, 4, 2) != 1) break;
371 SB(_mc
[t
].m7
, 6, 2, add_roadtypes
? 1 : GB(_mc
[t
].m3
, 0, 3));
372 SB(_mc
[t
].m7
, 0, 5, HasBit(_mc
[t
].m0
, 2) ? OWNER_TOWN
: (Owner
)GB(_mc
[t
].m1
, 0, 5));
373 SB(_mc
[t
].m3
, 4, 4, _mc
[t
].m1
);
377 case OLD_MP_TUNNELBRIDGE
: {
378 if (!old_bridge
|| !HasBit(_mc
[t
].m5
, 7) || !HasBit(_mc
[t
].m5
, 6)) {
379 if (((old_bridge
&& HasBit(_mc
[t
].m5
, 7)) ? GB(_mc
[t
].m5
, 1, 2) : GB(_mc
[t
].m5
, 2, 2)) == 1) {
380 /* Middle part of "old" bridges */
381 SB(_mc
[t
].m7
, 6, 2, add_roadtypes
? 1 : GB(_mc
[t
].m3
, 0, 3));
383 Owner o
= (Owner
)GB(_mc
[t
].m1
, 0, 5);
384 SB(_mc
[t
].m7
, 0, 5, o
); // road owner
385 SB(_mc
[t
].m3
, 4, 4, o
== OWNER_NONE
? OWNER_TOWN
: o
); // tram owner
387 SB(_mc
[t
].m0
, 2, 4, GB(_mc
[t
].m2
, 4, 4)); // bridge type
388 SB(_mc
[t
].m7
, 5, 1, GB(_mc
[t
].m4
, 7, 1)); // snow/desert
392 if (old_bridge
) SB(_mc
[t
].m0
, 6, 2, 0);
395 if (!old_bridge
|| !HasBit(_mc
[t
].m5
, 7)) break;
397 Axis axis
= (Axis
)GB(_mc
[t
].m5
, 0, 1);
399 if (HasBit(_mc
[t
].m5
, 6)) { // middle part
400 if (HasBit(_mc
[t
].m5
, 5)) { // transport route under bridge?
401 if (GB(_mc
[t
].m5
, 3, 2) == 0) {
402 SetOldTileType(t
, OLD_MP_RAILWAY
);
404 SB(_mc
[t
].m3
, 4, 4, 0);
405 _mc
[t
].m5
= axis
== AXIS_X
? TRACK_BIT_Y
: TRACK_BIT_X
;
406 _mc
[t
].m4
= _mc
[t
].m7
= 0;
408 SetOldTileType(t
, OLD_MP_ROAD
);
409 _mc
[t
].m2
= INVALID_TOWN
;
410 _mc
[t
].m3
= _mc
[t
].m4
= 0;
411 SB(_mc
[t
].m3
, 4, 4, OWNER_TOWN
);
412 _mc
[t
].m5
= axis
== AXIS_X
? ROAD_Y
: ROAD_X
;
415 } else if (GB(_mc
[t
].m5
, 3, 2) == 0) {
416 SetOldTileType(t
, OLD_MP_CLEAR
);
417 _mc
[t
].m1
= OWNER_NONE
;
419 _mc
[t
].m3
= _mc
[t
].m4
= _mc
[t
].m7
= 0;
421 } else if (!IsOldTileFlat(t
)) {
422 SetOldTileType(t
, OLD_MP_WATER
);
423 SB(_mc
[t
].m1
, 0, 5, OWNER_WATER
);
424 SB(_mc
[t
].m1
, 5, 2, WATER_CLASS_SEA
);
426 _mc
[t
].m3
= _mc
[t
].m4
= _mc
[t
].m7
= 0;
428 } else if (GB(_mc
[t
].m1
, 0, 5) == OWNER_WATER
) {
429 SetOldTileType(t
, OLD_MP_WATER
);
430 SB(_mc
[t
].m1
, 0, 5, OWNER_WATER
);
431 SB(_mc
[t
].m1
, 5, 2, WATER_CLASS_SEA
);
433 _mc
[t
].m3
= _mc
[t
].m4
= _mc
[t
].m5
= _mc
[t
].m7
= 0;
435 SetOldTileType(t
, OLD_MP_WATER
);
436 SB(_mc
[t
].m1
, 5, 2, WATER_CLASS_CANAL
);
438 _mc
[t
].m3
= _mc
[t
].m5
= _mc
[t
].m7
= 0;
439 _mc
[t
].m4
= Random();
441 SB(_mc
[t
].m0
, 2, 6, (1 << 4) << axis
);
443 DiagDirection dir
= AxisToDiagDir(axis
);
444 if (HasBit(_mc
[t
].m5
, 5)) dir
= ReverseDiagDir(dir
);
445 TransportType type
= (TransportType
)GB(_mc
[t
].m5
, 1, 2);
447 _mc
[t
].m5
= 1 << 7 | type
<< 2 | dir
;
458 /* From legacy version 82, old style canals (above sealevel (0), WATER owner) are no longer supported.
459 Replace the owner for those by OWNER_NONE. */
460 if (IsOTTDSavegameVersionBefore(stv
, 82)) {
461 for (TileIndex t
= 0; t
< map_size
; t
++) {
462 if (IsOldTileType(t
, OLD_MP_WATER
) &&
464 GB(_mc
[t
].m1
, 0, 5) == OWNER_WATER
&&
465 OldTileHeight(t
) != 0) {
466 SB(_mc
[t
].m1
, 0, 5, OWNER_NONE
);
472 * Add the 'previous' owner to the ship depots so we can reset it with
473 * the correct values when it gets destroyed. This prevents that
474 * someone can remove canals owned by somebody else and it prevents
475 * making floods using the removal of ship depots.
477 if (IsOTTDSavegameVersionBefore(stv
, 83)) {
478 for (TileIndex t
= 0; t
< map_size
; t
++) {
479 if (IsOldTileType(t
, OLD_MP_WATER
) && GB(_mc
[t
].m5
, 4, 4) == 8) {
480 _mc
[t
].m4
= (OldTileHeight(t
) == 0) ? OWNER_WATER
: OWNER_NONE
;
485 /* The water class was moved/unified. */
486 if (IsOTTDSavegameVersionBefore(stv
, 146)) {
487 for (TileIndex t
= 0; t
< map_size
; t
++) {
488 switch (GetOldTileType(t
)) {
490 switch (GB(_mc
[t
].m0
, 3, 3)) {
494 SB(_mc
[t
].m1
, 5, 2, GB(_mc
[t
].m3
, 0, 2));
495 SB(_mc
[t
].m3
, 0, 2, 0);
499 SB(_mc
[t
].m1
, 5, 2, WATER_CLASS_INVALID
);
505 SB(_mc
[t
].m1
, 5, 2, GB(_mc
[t
].m3
, 0, 2));
506 SB(_mc
[t
].m3
, 0, 2, 0);
510 SB(_mc
[t
].m1
, 5, 2, WATER_CLASS_INVALID
);
514 /* No water class. */
520 if (IsOTTDSavegameVersionBefore(stv
, 86)) {
521 for (TileIndex t
= 0; t
< map_size
; t
++) {
522 /* Move river flag and update canals to use water class */
523 if (IsOldTileType(t
, OLD_MP_WATER
) && GB(_mc
[t
].m1
, 5, 2) != WATER_CLASS_RIVER
) {
524 if (_mc
[t
].m5
== 0) {
525 if (GB(_mc
[t
].m1
, 0, 5) == OWNER_WATER
) {
526 SB(_mc
[t
].m1
, 5, 2, WATER_CLASS_SEA
);
529 SB(_mc
[t
].m1
, 5, 2, WATER_CLASS_CANAL
);
530 _mc
[t
].m4
= Random();
533 _mc
[t
].m3
= _mc
[t
].m5
= _mc
[t
].m7
= 0;
534 SB(_mc
[t
].m0
, 2, 4, 0);
535 } else if (GB(_mc
[t
].m5
, 4, 4) == 8) {
536 Owner o
= (Owner
)_mc
[t
].m4
; // Original water owner
537 SB(_mc
[t
].m1
, 5, 2, o
== OWNER_WATER
? WATER_CLASS_SEA
: WATER_CLASS_CANAL
);
543 /* Move the signal variant back up one bit for PBS. We don't convert the old PBS
544 * format here, as an old layout wouldn't work properly anyway. To be safe, we
545 * clear any possible PBS reservations as well. */
546 if (IsOTTDSavegameVersionBefore(stv
, 100)) {
547 for (TileIndex t
= 0; t
< map_size
; t
++) {
548 switch (GetOldTileType(t
)) {
550 if (GB(_mc
[t
].m5
, 6, 2) == 1) {
551 /* move the signal variant */
552 SB(_mc
[t
].m2
, 3, 1, HasBit(_mc
[t
].m2
, 2) ? SIG_SEMAPHORE
: SIG_ELECTRIC
);
553 SB(_mc
[t
].m2
, 7, 1, HasBit(_mc
[t
].m2
, 6) ? SIG_SEMAPHORE
: SIG_ELECTRIC
);
554 ClrBit(_mc
[t
].m2
, 2);
555 ClrBit(_mc
[t
].m2
, 6);
558 /* Clear PBS reservation on track */
559 if (GB(_mc
[t
].m5
, 6, 2) == 3) {
560 ClrBit(_mc
[t
].m5
, 4);
562 SB(_mc
[t
].m2
, 8, 4, 0);
566 case OLD_MP_ROAD
: // Clear PBS reservation on crossing
567 if (GB(_mc
[t
].m5
, 6, 2) == 1) ClrBit(_mc
[t
].m5
, 4);
570 case OLD_MP_STATION
: // Clear PBS reservation on station
571 if (GB(_mc
[t
].m0
, 3, 3) == 0 || GB(_mc
[t
].m0
, 3, 3) == 7) ClrBit(_mc
[t
].m0
, 2);
574 case OLD_MP_TUNNELBRIDGE
: // Clear PBS reservation on tunnels/bridges
575 if (GB(_mc
[t
].m5
, 2, 2) == 0) ClrBit(_mc
[t
].m5
, 4);
583 if (IsOTTDSavegameVersionBefore(stv
, 112)) {
584 for (TileIndex t
= 0; t
< map_size
; t
++) {
585 /* Check for HQ bit being set, instead of using map accessor,
586 * since we've already changed it code-wise */
587 if (IsOldTileType(t
, OLD_MP_OBJECT
) && HasBit(_mc
[t
].m5
, 7)) {
588 /* Move size and part identification of HQ out of the m5 attribute,
589 * on new locations */
590 _mc
[t
].m3
= GB(_mc
[t
].m5
, 0, 5);
596 /* The bits for the tree ground and tree density have
597 * been swapped (m2 bits 7..6 and 5..4. */
598 if (IsOTTDSavegameVersionBefore(stv
, 135)) {
599 for (TileIndex t
= 0; t
< map_size
; t
++) {
600 if (IsOldTileType(t
, OLD_MP_CLEAR
)) {
601 if (GB(_mc
[t
].m5
, 2, 3) == 4) {
602 SB(_mc
[t
].m5
, 2, 6, 0);
603 SetBit(_mc
[t
].m3
, 4);
605 ClrBit(_mc
[t
].m3
, 4);
607 } else if (IsOldTileType(t
, OLD_MP_TREES
)) {
608 uint density
= GB(_mc
[t
].m2
, 6, 2);
609 uint ground
= GB(_mc
[t
].m2
, 4, 2);
610 uint counter
= GB(_mc
[t
].m2
, 0, 4);
611 _mc
[t
].m2
= ground
<< 6 | density
<< 4 | counter
;
616 /* Reset tropic zone for VOID tiles, they shall not have any. */
617 if (IsOTTDSavegameVersionBefore(stv
, 141)) {
618 for (TileIndex t
= 0; t
< map_size
; t
++) {
619 if (IsOldTileType(t
, OLD_MP_VOID
)) SB(_mc
[t
].m0
, 0, 2, 0);
623 if (IsOTTDSavegameVersionBefore(stv
, 144)) {
624 for (TileIndex t
= 0; t
< map_size
; t
++) {
625 if (!IsOldTileType(t
, OLD_MP_OBJECT
)) continue;
627 /* Reordering/generalisation of the object bits. */
628 bool is_hq
= _mc
[t
].m5
== 4;
629 SB(_mc
[t
].m0
, 2, 4, is_hq
? GB(_mc
[t
].m3
, 2, 3) : 0);
630 _mc
[t
].m3
= is_hq
? GB(_mc
[t
].m3
, 1, 1) | GB(_mc
[t
].m3
, 0, 1) << 4 : 0;
632 /* Make sure those bits are clear as well! */
638 if (IsOTTDSavegameVersionBefore(stv
, 147)) {
639 /* Move the animation frame to the same location (m7) for all objects. */
640 for (TileIndex t
= 0; t
< map_size
; t
++) {
641 switch (GetOldTileType(t
)) {
643 /* This needs GRF knowledge, so it is done in AfterLoadGame */
646 case OLD_MP_INDUSTRY
:
647 Swap(_mc
[t
].m3
, _mc
[t
].m7
);
651 /* hack: temporarily store offset in m4;
652 * it will be used (and removed) in AfterLoadGame */
653 _mc
[t
].m4
= _mc
[t
].m3
;
655 /* move the animation state. */
656 _mc
[t
].m7
= GB(_mc
[t
].m0
, 2, 4);
657 SB(_mc
[t
].m0
, 2, 4, 0);
662 /* For stations/airports it's already at m7 */
668 if (IsOTTDSavegameVersionBefore(stv
, 164)) {
669 /* We store 4 fences in the field tiles instead of only SE and SW. */
670 for (TileIndex t
= 0; t
< map_size
; t
++) {
671 if (!IsOldTileType(t
, OLD_MP_CLEAR
) && !IsOldTileType(t
, OLD_MP_TREES
)) continue;
672 if (IsOldTileType(t
, OLD_MP_CLEAR
) && !HasBit(_mc
[t
].m3
, 4) && GB(_mc
[t
].m5
, 2, 3) == 3) continue;
674 uint fence
= GB(_mc
[t
].m4
, 5, 3);
676 TileIndex neighbour
= TILE_ADDXY(t
, 1, 0);
677 if (IsOldTileType(neighbour
, OLD_MP_CLEAR
) && !HasBit(_mc
[neighbour
].m3
, 4) && GB(_mc
[neighbour
].m5
, 2, 3) == 3) {
678 SB(_mc
[neighbour
].m3
, 5, 3, fence
);
682 fence
= GB(_mc
[t
].m4
, 2, 3);
684 TileIndex neighbour
= TILE_ADDXY(t
, 0, 1);
685 if (IsOldTileType(neighbour
, OLD_MP_CLEAR
) && !HasBit(_mc
[neighbour
].m3
, 4) && GB(_mc
[neighbour
].m5
, 2, 3) == 3) {
686 SB(_mc
[neighbour
].m0
, 2, 3, fence
);
690 SB(_mc
[t
].m4
, 2, 3, 0);
691 SB(_mc
[t
].m4
, 5, 3, 0);
695 /* Switch to the new map array */
696 if (IsFullSavegameVersionBefore(stv
, 1)) {
697 for (TileIndex t
= 0; t
< map_size
; t
++) {
698 uint zone
= GB(_mc
[t
].m0
, 0, 2);
700 switch (GetOldTileType(t
)) {
702 uint fence_nw
= GB(_mc
[t
].m0
, 2, 3);
703 _mc
[t
].m0
= GB(_mc
[t
].m0
, 6, 2) | (TT_GROUND
<< 4);
704 uint ground
= GB(_mc
[t
].m5
, 2, 3);
706 SB(_mc
[t
].m1
, 6, 2, TT_GROUND_FIELDS
);
707 uint counter
= GB(_mc
[t
].m5
, 5, 3);
708 SB(_mc
[t
].m5
, 2, 3, fence_nw
);
709 SB(_mc
[t
].m5
, 5, 3, GB(_mc
[t
].m3
, 5, 3));
710 SB(_mc
[t
].m3
, 4, 4, GB(_mc
[t
].m3
, 0, 4));
711 SB(_mc
[t
].m3
, 0, 4, counter
);
713 SB(_mc
[t
].m1
, 6, 2, TT_GROUND_CLEAR
);
714 _mc
[t
].m4
= GB(_mc
[t
].m5
, 0, 2);
715 if (HasBit(_mc
[t
].m3
, 4)) {
717 case 1: ground
= GROUND_SNOW_ROUGH
; break;
718 case 2: ground
= GROUND_SNOW_ROCKS
; break;
719 default: ground
= GROUND_SNOW
; break;
723 default: ground
= GROUND_GRASS
; break;
724 case 1: ground
= GROUND_ROUGH
; break;
725 case 2: ground
= GROUND_ROCKS
; break;
726 case 4: ground
= GROUND_SNOW
; break;
727 case 5: ground
= GROUND_DESERT
; break;
730 SB(_mc
[t
].m3
, 4, 4, ground
);
731 SB(_mc
[t
].m3
, 0, 4, GB(_mc
[t
].m5
, 5, 3));
738 case OLD_MP_RAILWAY
: {
739 uint ground
= GB(_mc
[t
].m4
, 0, 4);
740 if (!HasBit(_mc
[t
].m5
, 7)) { // track
741 _mc
[t
].m0
= GB(_mc
[t
].m0
, 6, 2) | (TT_RAILWAY
<< 4);
742 SB(_mc
[t
].m1
, 6, 2, TT_TRACK
);
743 if (HasBit(_mc
[t
].m5
, 6)) { // with signals
744 _mc
[t
].m7
= GB(_mc
[t
].m4
, 4, 2) | (GB(_mc
[t
].m3
, 4, 2) << 2) | (GB(_mc
[t
].m2
, 4, 3) << 4) | (GB(_mc
[t
].m2
, 7, 1) << 7);
745 _mc
[t
].m4
= GB(_mc
[t
].m4
, 6, 2) | (GB(_mc
[t
].m3
, 6, 2) << 2) | (GB(_mc
[t
].m2
, 0, 3) << 4) | (GB(_mc
[t
].m2
, 3, 1) << 7);
747 _mc
[t
].m4
= _mc
[t
].m7
= 0;
749 SB(_mc
[t
].m3
, 4, 4, ground
);
750 SB(_mc
[t
].m2
, 0, 8, GB(_mc
[t
].m5
, 0, 6));
751 } else if (HasBit(_mc
[t
].m5
, 6)) { // depot
752 _mc
[t
].m0
= GB(_mc
[t
].m0
, 6, 2) | (TT_MISC
<< 4);
753 SB(_mc
[t
].m1
, 6, 2, TT_MISC_DEPOT
);
754 ClrBit(_mc
[t
].m1
, 5);
755 SB(_mc
[t
].m3
, 4, 4, ground
== 12 ? 1 : 0);
757 _mc
[t
].m4
= _mc
[t
].m7
= 0;
758 } else { // old waypoint
759 if (!IsOTTDSavegameVersionBefore(stv
, 123)) {
760 throw SlCorrupt("Invalid rail tile type");
762 /* temporary hack; AfterLoadGame will fix this */
763 _mc
[t
].m0
= GB(_mc
[t
].m5
, 4, 1) | (STATION_WAYPOINT
<< 1) | (TT_STATION
<< 4);
769 uint roadside
= GB(_mc
[t
].m0
, 3, 3);
770 _mc
[t
].m0
= GB(_mc
[t
].m0
, 6, 2);
771 switch (GB(_mc
[t
].m5
, 6, 2)) {
772 case 0: { // normal road
773 _mc
[t
].m0
|= (TT_ROAD
<< 4);
774 SB(_mc
[t
].m1
, 6, 2, TT_TRACK
);
775 _mc
[t
].m4
= GB(_mc
[t
].m5
, 0, 4) | (GB(_mc
[t
].m3
, 0, 4) << 4);
776 SB(_mc
[t
].m5
, 0, 4, GB(_mc
[t
].m3
, 4, 4));
777 _mc
[t
].m3
= (GB(_mc
[t
].m5
, 4, 2) << 6) | (GB(_mc
[t
].m7
, 5, 1) << 4);
778 SB(_mc
[t
].m5
, 4, 4, roadside
);
782 case 1: // level crossing
783 _mc
[t
].m0
|= (TT_MISC
<< 4);
784 SB(_mc
[t
].m1
, 6, 2, TT_MISC_CROSSING
);
785 SB(_mc
[t
].m3
, 4, 4, GB(_mc
[t
].m7
, 5, 1));
786 SB(_mc
[t
].m4
, 5, 1, GB(_mc
[t
].m5
, 0, 1));
787 SB(_mc
[t
].m4
, 6, 1, GB(_mc
[t
].m5
, 5, 1));
788 SB(_mc
[t
].m4
, 7, 1, GB(_mc
[t
].m5
, 4, 1));
789 _mc
[t
].m5
= GB(_mc
[t
].m3
, 4, 4) | (roadside
<< 4);
792 case 2: // road depot
793 _mc
[t
].m0
|= (TT_MISC
<< 4);
794 SB(_mc
[t
].m1
, 6, 2, TT_MISC_DEPOT
);
795 SetBit(_mc
[t
].m1
, 5);
796 _mc
[t
].m3
= GB(_mc
[t
].m7
, 5, 1) << 4;
806 uint random
= _mc
[t
].m1
;
807 _mc
[t
].m1
= GB(_mc
[t
].m0
, 2, 6) | (_mc
[t
].m3
& 0xC0);
808 _mc
[t
].m0
= GB(_mc
[t
].m3
, 0, 6) | 0xC0;
814 _mc
[t
].m0
= TT_GROUND
<< 4;
815 SB(_mc
[t
].m1
, 6, 2, TT_GROUND_TREES
);
816 _mc
[t
].m7
= _mc
[t
].m3
;
817 switch (GB(_mc
[t
].m2
, 6, 3)) {
818 case 0: _mc
[t
].m3
= GROUND_GRASS
<< 4; break;
819 case 1: _mc
[t
].m3
= GROUND_ROUGH
<< 4; break;
820 case 2: _mc
[t
].m3
= _settings_game
.game_creation
.landscape
== LT_TROPIC
? GROUND_DESERT
<< 4 : GROUND_SNOW
<< 4; break;
821 case 3: _mc
[t
].m3
= GROUND_SHORE
<< 4; break;
822 case 4: _mc
[t
].m3
= GROUND_SNOW_ROUGH
<< 4; break;
824 SB(_mc
[t
].m3
, 0, 4, GB(_mc
[t
].m2
, 0, 4));
825 _mc
[t
].m4
= GB(_mc
[t
].m2
, 4, 2);
829 case OLD_MP_STATION
: {
830 uint type
= GB(_mc
[t
].m0
, 2, 4);
831 if ((type
== STATION_WAYPOINT
) && IsOTTDSavegameVersionBefore(stv
, 123)) {
832 throw SlCorrupt("Invalid station type");
834 _mc
[t
].m0
= type
| (TT_STATION
<< 4);
839 _mc
[t
].m0
= GB(_mc
[t
].m0
, 6, 2) | (TT_WATER
<< 4);
840 _mc
[t
].m3
= _mc
[t
].m4
;
845 _mc
[t
].m0
= TT_GROUND
<< 4;
846 _mc
[t
].m1
= TT_GROUND_VOID
<< 6;
848 _mc
[t
].m3
= _mc
[t
].m4
= _mc
[t
].m5
= _mc
[t
].m7
= 0;
851 case OLD_MP_INDUSTRY
:
852 _mc
[t
].m0
= GB(_mc
[t
].m0
, 3, 3) | (GB(_mc
[t
].m0
, 2, 1) << 3) | 0x80;
855 case OLD_MP_TUNNELBRIDGE
:
856 if (HasBit(_mc
[t
].m5
, 7)) { // bridge
857 uint type
= GB(_mc
[t
].m0
, 2, 4);
858 switch (GB(_mc
[t
].m5
, 2, 2)) {
860 _mc
[t
].m0
= GB(_mc
[t
].m0
, 6, 2) | (TT_RAILWAY
<< 4);
861 SB(_mc
[t
].m1
, 6, 2, TT_BRIDGE
);
862 SB(_mc
[t
].m2
, 12, 4, type
);
863 SB(_mc
[t
].m3
, 4, 2, GB(_mc
[t
].m7
, 5, 1));
864 SB(_mc
[t
].m3
, 6, 2, GB(_mc
[t
].m5
, 0, 2));
867 _mc
[t
].m0
= GB(_mc
[t
].m0
, 6, 2) | (TT_ROAD
<< 4);
868 SB(_mc
[t
].m1
, 6, 2, TT_BRIDGE
);
869 if (HasBit(_mc
[t
].m7
, 6)) SB(_mc
[t
].m1
, 0, 5, GB(_mc
[t
].m7
, 0, 5));
870 uint tram
= GB(_mc
[t
].m3
, 4, 4);
871 _mc
[t
].m3
= (GB(_mc
[t
].m5
, 0, 2) << 6) | (GB(_mc
[t
].m7
, 5, 1) << 4);
873 SB(_mc
[t
].m7
, 0, 4, type
);
876 _mc
[t
].m0
= GB(_mc
[t
].m0
, 6, 2) | (TT_MISC
<< 4);
877 SB(_mc
[t
].m1
, 6, 2, TT_MISC_AQUEDUCT
);
878 _mc
[t
].m3
= (GB(_mc
[t
].m5
, 0, 2) << 6) | (GB(_mc
[t
].m7
, 5, 1) << 4);
882 throw SlCorrupt("Invalid bridge transport type");
885 _mc
[t
].m0
= GB(_mc
[t
].m0
, 6, 2) | (TT_MISC
<< 4);
886 SB(_mc
[t
].m1
, 6, 2, TT_MISC_TUNNEL
);
887 uint tram
= GB(_mc
[t
].m3
, 4, 4);
888 SB(_mc
[t
].m3
, 4, 2, GB(_mc
[t
].m7
, 5, 1));
889 SB(_mc
[t
].m3
, 6, 2, GB(_mc
[t
].m5
, 0, 2));
890 SB(_mc
[t
].m5
, 6, 2, GB(_mc
[t
].m5
, 2, 2));
891 SB(_mc
[t
].m5
, 0, 4, tram
);
896 _mc
[t
].m0
= GB(_mc
[t
].m0
, 6, 2) | (TT_OBJECT
<< 4);
900 throw SlCorrupt("Invalid tile type");
903 SB(_mth
[t
], 4, 4, zone
<< 2);
907 /* Add second railtype to rail tiles */
908 if (IsFullSavegameVersionBefore(stv
, 3)) {
909 for (TileIndex t
= 0; t
< map_size
; t
++) {
910 if (IsTileTypeSubtype(t
, TT_RAILWAY
, TT_TRACK
)) {
911 SB(_mc
[t
].m5
, 0, 4, GB(_mc
[t
].m3
, 0, 4));
916 /* Add road layout to road bridgeheads */
917 if (IsFullSavegameVersionBefore(stv
, 7)) {
918 for (TileIndex t
= 0; t
< map_size
; t
++) {
919 if (IsTileTypeSubtype(t
, TT_ROAD
, TT_BRIDGE
)) {
920 RoadBits bits
= AxisToRoadBits(DiagDirToAxis((DiagDirection
)GB(_mc
[t
].m3
, 6, 2)));
921 SB(_mc
[t
].m4
, 0, 4, HasBit(_mc
[t
].m7
, 6) ? bits
: 0);
922 SB(_mc
[t
].m4
, 4, 4, HasBit(_mc
[t
].m7
, 7) ? bits
: 0);
927 /* Add track layout to rail bridgeheads */
928 if (IsFullSavegameVersionBefore(stv
, 8)) {
929 for (TileIndex t
= 0; t
< map_size
; t
++) {
930 if (IsTileTypeSubtype(t
, TT_RAILWAY
, TT_BRIDGE
)) {
931 Track track
= DiagDirToDiagTrack((DiagDirection
)GB(_mc
[t
].m3
, 6, 2));
932 bool reserved
= HasBit(_mc
[t
].m5
, 4);
933 SB(_mc
[t
].m2
, 0, 6, TrackToTrackBits(track
));
934 SB(_mc
[t
].m2
, 6, 1, reserved
? 1 : 0);
935 SB(_mc
[t
].m2
, 8, 4, reserved
? (track
+ 1) : 0);
936 SB(_mc
[t
].m5
, 4, 4, 0);
937 _mc
[t
].m4
= _mc
[t
].m7
= 0;
942 /* Split tunnelhead/tunnel PBS reservation */
943 if (IsFullSavegameVersionBefore(stv
, 9)) {
944 for (TileIndex t
= 0; t
< map_size
; t
++) {
945 if (IsTileTypeSubtype(t
, TT_MISC
, TT_MISC_TUNNEL
) && GB(_mc
[t
].m5
, 6, 2) == 0) {
946 if (HasBit(_mc
[t
].m5
, 4)) {
947 SetBit(_mc
[t
].m5
, 5);
949 ClrBit(_mc
[t
].m5
, 5);
955 /* Roadworks now count down, not up */
956 if (IsFullSavegameVersionBefore(stv
, 12)) {
957 for (TileIndex t
= 0; t
< map_size
; t
++) {
958 if (IsTileTypeSubtype(t
, TT_ROAD
, TT_TRACK
)) {
959 uint roadside
= GB(_mc
[t
].m5
, 4, 3);
961 SB(_mc
[t
].m5
, 4, 3, roadside
- 5);
962 SB(_mc
[t
].m7
, 0, 4, 0xF - GB(_mc
[t
].m7
, 0, 4));
968 /* Store direction for ship depots */
969 if (IsFullSavegameVersionBefore(stv
, 14)) {
970 for (TileIndex t
= 0; t
< map_size
; t
++) {
971 if (IsTileType(t
, TT_WATER
) && GB(_mc
[t
].m5
, 4, 4) == 8) {
972 DiagDirection dir
= AxisToDiagDir((Axis
)GB(_mc
[t
].m5
, 1, 1));
973 SB(_mc
[t
].m5
, 0, 2, HasBit(_mc
[t
].m5
, 0) ? dir
: ReverseDiagDir(dir
));
984 static const SaveLoad _map_dimensions
[] = {
985 SLE_VAR(MapDim
, x
, SLE_UINT32
, 0, , 6, ),
986 SLE_VAR(MapDim
, y
, SLE_UINT32
, 0, , 6, ),
990 static void Save_MAPS(SaveDumper
*dumper
)
993 map_dim
.x
= MapSizeX();
994 map_dim
.y
= MapSizeY();
995 dumper
->WriteRIFFObject(&map_dim
, _map_dimensions
);
998 static void Load_MAPS(LoadBuffer
*reader
)
1001 reader
->ReadObject(&map_dim
, _map_dimensions
);
1002 AllocateMap(map_dim
.x
, map_dim
.y
);
1005 static void Check_MAPS(LoadBuffer
*reader
)
1008 reader
->ReadObject(&map_dim
, _map_dimensions
);
1009 _load_check_data
.map_size_x
= map_dim
.x
;
1010 _load_check_data
.map_size_y
= map_dim
.y
;
1013 static const uint MAP_SL_BUF_SIZE
= 4096;
1015 static void Load_MAPT(LoadBuffer
*reader
)
1017 reader
->CopyBytes(_mth
, MapSize());
1020 static void Save_MAPT(SaveDumper
*dumper
)
1022 TileIndex size
= MapSize();
1024 dumper
->WriteRIFFSize(size
);
1025 dumper
->CopyBytes(_mth
, size
);
1028 static void Load_MAP1(LoadBuffer
*reader
)
1030 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1031 TileIndex size
= MapSize();
1033 for (TileIndex i
= 0; i
!= size
;) {
1034 reader
->ReadArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1035 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) _mc
[i
++].m1
= buf
[j
];
1039 static void Save_MAP1(SaveDumper
*dumper
)
1041 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1042 TileIndex size
= MapSize();
1044 dumper
->WriteRIFFSize(size
);
1045 for (TileIndex i
= 0; i
!= size
;) {
1046 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) buf
[j
] = _mc
[i
++].m1
;
1047 dumper
->WriteArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1051 static void Load_MAP2(LoadBuffer
*reader
)
1053 SmallStackSafeStackAlloc
<uint16
, MAP_SL_BUF_SIZE
> buf
;
1054 TileIndex size
= MapSize();
1056 for (TileIndex i
= 0; i
!= size
;) {
1057 reader
->ReadArray(buf
, MAP_SL_BUF_SIZE
,
1058 /* In those versions the m2 was 8 bits */
1059 reader
->IsOTTDVersionBefore(5) ? SLE_FILE_U8
| SLE_VAR_U16
: SLE_UINT16
1061 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) _mc
[i
++].m2
= buf
[j
];
1065 static void Save_MAP2(SaveDumper
*dumper
)
1067 SmallStackSafeStackAlloc
<uint16
, MAP_SL_BUF_SIZE
> buf
;
1068 TileIndex size
= MapSize();
1070 dumper
->WriteRIFFSize(size
* sizeof(uint16
));
1071 for (TileIndex i
= 0; i
!= size
;) {
1072 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) buf
[j
] = _mc
[i
++].m2
;
1073 dumper
->WriteArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT16
);
1077 static void Load_MAP3(LoadBuffer
*reader
)
1079 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1080 TileIndex size
= MapSize();
1082 for (TileIndex i
= 0; i
!= size
;) {
1083 reader
->ReadArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1084 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) _mc
[i
++].m3
= buf
[j
];
1088 static void Save_MAP3(SaveDumper
*dumper
)
1090 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1091 TileIndex size
= MapSize();
1093 dumper
->WriteRIFFSize(size
);
1094 for (TileIndex i
= 0; i
!= size
;) {
1095 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) buf
[j
] = _mc
[i
++].m3
;
1096 dumper
->WriteArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1100 static void Load_MAP4(LoadBuffer
*reader
)
1102 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1103 TileIndex size
= MapSize();
1105 for (TileIndex i
= 0; i
!= size
;) {
1106 reader
->ReadArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1107 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) _mc
[i
++].m4
= buf
[j
];
1111 static void Save_MAP4(SaveDumper
*dumper
)
1113 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1114 TileIndex size
= MapSize();
1116 dumper
->WriteRIFFSize(size
);
1117 for (TileIndex i
= 0; i
!= size
;) {
1118 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) buf
[j
] = _mc
[i
++].m4
;
1119 dumper
->WriteArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1123 static void Load_MAP5(LoadBuffer
*reader
)
1125 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1126 TileIndex size
= MapSize();
1128 for (TileIndex i
= 0; i
!= size
;) {
1129 reader
->ReadArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1130 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) _mc
[i
++].m5
= buf
[j
];
1134 static void Save_MAP5(SaveDumper
*dumper
)
1136 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1137 TileIndex size
= MapSize();
1139 dumper
->WriteRIFFSize(size
);
1140 for (TileIndex i
= 0; i
!= size
;) {
1141 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) buf
[j
] = _mc
[i
++].m5
;
1142 dumper
->WriteArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1146 static void Load_MAP0(LoadBuffer
*reader
)
1148 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1149 TileIndex size
= MapSize();
1151 if (reader
->IsOTTDVersionBefore(42)) {
1152 for (TileIndex i
= 0; i
!= size
;) {
1153 /* 1024, otherwise we overflow on 64x64 maps! */
1154 reader
->ReadArray(buf
, 1024, SLE_UINT8
);
1155 for (uint j
= 0; j
!= 1024; j
++) {
1156 _mc
[i
++].m0
= GB(buf
[j
], 0, 2);
1157 _mc
[i
++].m0
= GB(buf
[j
], 2, 2);
1158 _mc
[i
++].m0
= GB(buf
[j
], 4, 2);
1159 _mc
[i
++].m0
= GB(buf
[j
], 6, 2);
1163 for (TileIndex i
= 0; i
!= size
;) {
1164 reader
->ReadArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1165 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) _mc
[i
++].m0
= buf
[j
];
1170 static void Save_MAP0(SaveDumper
*dumper
)
1172 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1173 TileIndex size
= MapSize();
1175 dumper
->WriteRIFFSize(size
);
1176 for (TileIndex i
= 0; i
!= size
;) {
1177 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) buf
[j
] = _mc
[i
++].m0
;
1178 dumper
->WriteArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1182 static void Load_MAP7(LoadBuffer
*reader
)
1184 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1185 TileIndex size
= MapSize();
1187 for (TileIndex i
= 0; i
!= size
;) {
1188 reader
->ReadArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1189 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) _mc
[i
++].m7
= buf
[j
];
1193 static void Save_MAP7(SaveDumper
*dumper
)
1195 SmallStackSafeStackAlloc
<byte
, MAP_SL_BUF_SIZE
> buf
;
1196 TileIndex size
= MapSize();
1198 dumper
->WriteRIFFSize(size
);
1199 for (TileIndex i
= 0; i
!= size
;) {
1200 for (uint j
= 0; j
!= MAP_SL_BUF_SIZE
; j
++) buf
[j
] = _mc
[i
++].m7
;
1201 dumper
->WriteArray(buf
, MAP_SL_BUF_SIZE
, SLE_UINT8
);
1205 extern const ChunkHandler _map_chunk_handlers
[] = {
1206 { 'MAPS', Save_MAPS
, Load_MAPS
, NULL
, Check_MAPS
, CH_RIFF
},
1207 { 'MAPT', Save_MAPT
, Load_MAPT
, NULL
, NULL
, CH_RIFF
},
1208 { 'MAPO', Save_MAP1
, Load_MAP1
, NULL
, NULL
, CH_RIFF
},
1209 { 'MAP2', Save_MAP2
, Load_MAP2
, NULL
, NULL
, CH_RIFF
},
1210 { 'M3LO', Save_MAP3
, Load_MAP3
, NULL
, NULL
, CH_RIFF
},
1211 { 'M3HI', Save_MAP4
, Load_MAP4
, NULL
, NULL
, CH_RIFF
},
1212 { 'MAP5', Save_MAP5
, Load_MAP5
, NULL
, NULL
, CH_RIFF
},
1213 { 'MAPE', Save_MAP0
, Load_MAP0
, NULL
, NULL
, CH_RIFF
},
1214 { 'MAP7', Save_MAP7
, Load_MAP7
, NULL
, NULL
, CH_RIFF
| CH_LAST
},