Fix some daylength issues, possible division by zero in main menu.
[openttd-joker.git] / src / saveload / oldloader_sl.cpp
blobecbc135f8635304bd51fba8e199d6bf7f9f368da
1 /* $Id$ */
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 */
10 /** @file oldloader_sl.cpp Chunks and fix-ups for TTO/TTD/TTDP savegames. TTO loader code is based on SVXConverter by Roman Vetter. */
12 #include "../stdafx.h"
13 #include "../town.h"
14 #include "../industry.h"
15 #include "../company_func.h"
16 #include "../aircraft.h"
17 #include "../roadveh.h"
18 #include "../ship.h"
19 #include "../train.h"
20 #include "../signs_base.h"
21 #include "../station_base.h"
22 #include "../subsidy_base.h"
23 #include "../debug.h"
24 #include "../depot_base.h"
25 #include "../date_func.h"
26 #include "../vehicle_func.h"
27 #include "../effectvehicle_base.h"
28 #include "../engine_func.h"
29 #include "../company_base.h"
30 #include "../disaster_vehicle.h"
31 #include "saveload_internal.h"
32 #include "oldloader.h"
34 #include "table/strings.h"
35 #include "../table/engines.h"
36 #include "../table/townname.h"
38 #include "../safeguards.h"
40 static bool _read_ttdpatch_flags; ///< Have we (tried to) read TTDPatch extra flags?
41 static uint16 _old_extra_chunk_nums; ///< Number of extra TTDPatch chunks
42 static byte _old_vehicle_multiplier; ///< TTDPatch vehicle multiplier
44 static uint8 *_old_map3;
46 void FixOldMapArray()
48 /* TTO/TTD/TTDP savegames could have buoys at tile 0
49 * (without assigned station struct) */
50 MemSetT(&_m[0], 0);
51 SetTileType(0, MP_WATER);
52 SetTileOwner(0, OWNER_WATER);
55 static void FixTTDMapArray()
57 /* _old_map3 is moved to _m::m3 and _m::m4 */
58 for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) {
59 _m[t].m3 = _old_map3[t * 2];
60 _m[t].m4 = _old_map3[t * 2 + 1];
63 for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) {
64 switch (GetTileType(t)) {
65 case MP_STATION:
66 _m[t].m4 = 0; // We do not understand this TTDP station mapping (yet)
67 switch (_m[t].m5) {
68 /* We have drive through stops at a totally different place */
69 case 0x53: case 0x54: _m[t].m5 += 170 - 0x53; break; // Bus drive through
70 case 0x57: case 0x58: _m[t].m5 += 168 - 0x57; break; // Truck drive through
71 case 0x55: case 0x56: _m[t].m5 += 170 - 0x55; break; // Bus tram stop
72 case 0x59: case 0x5A: _m[t].m5 += 168 - 0x59; break; // Truck tram stop
73 default: break;
75 break;
77 case MP_RAILWAY:
78 /* We save presignals different from TTDPatch, convert them */
79 if (GB(_m[t].m5, 6, 2) == 1) { // RAIL_TILE_SIGNALS
80 /* This byte is always zero in TTD for this type of tile */
81 if (_m[t].m4) { // Convert the presignals to our own format
82 _m[t].m4 = (_m[t].m4 >> 1) & 7;
85 /* TTDPatch stores PBS things in L6 and all elsewhere; so we'll just
86 * clear it for ourselves and let OTTD's rebuild PBS itself */
87 _m[t].m4 &= 0xF; // Only keep the lower four bits; upper four is PBS
88 break;
90 case MP_WATER:
91 /* if water class == 3, make river there */
92 if (GB(_m[t].m3, 0, 2) == 3) {
93 SetTileType(t, MP_WATER);
94 SetTileOwner(t, OWNER_WATER);
95 _m[t].m2 = 0;
96 _m[t].m3 = 2; // WATER_CLASS_RIVER
97 _m[t].m4 = Random();
98 _m[t].m5 = 0;
100 break;
102 default:
103 break;
107 FixOldMapArray();
110 static void FixTTDDepots()
112 const Depot *d;
113 FOR_ALL_DEPOTS_FROM(d, 252) {
114 if (!IsDepotTile(d->xy) || GetDepotIndex(d->xy) != d->index) {
115 /** Workaround for SVXConverter bug, depots 252-255 could be invalid */
116 delete d;
121 #define FIXNUM(x, y, z) (((((x) << 16) / (y)) + 1) << z)
123 static uint32 RemapOldTownName(uint32 townnameparts, byte old_town_name_type)
125 switch (old_town_name_type) {
126 case 0: case 3: // English, American
127 /* Already OK */
128 return townnameparts;
130 case 1: // French
131 /* For some reason 86 needs to be subtracted from townnameparts
132 * 0000 0000 0000 0000 0000 0000 1111 1111 */
133 return FIXNUM(townnameparts - 86, lengthof(_name_french_real), 0);
135 case 2: // German
136 DEBUG(misc, 0, "German Townnames are buggy (%d)", townnameparts);
137 return townnameparts;
139 case 4: // Latin-American
140 /* 0000 0000 0000 0000 0000 0000 1111 1111 */
141 return FIXNUM(townnameparts, lengthof(_name_spanish_real), 0);
143 case 5: // Silly
144 /* NUM_SILLY_1 - lower 16 bits
145 * NUM_SILLY_2 - upper 16 bits without leading 1 (first 8 bytes)
146 * 1000 0000 2222 2222 0000 0000 1111 1111 */
147 return FIXNUM(townnameparts, lengthof(_name_silly_1), 0) | FIXNUM(GB(townnameparts, 16, 8), lengthof(_name_silly_2), 16);
149 return 0;
152 #undef FIXNUM
154 static void FixOldTowns()
156 Town *town;
158 /* Convert town-names if needed */
159 FOR_ALL_TOWNS(town) {
160 if (IsInsideMM(town->townnametype, 0x20C1, 0x20C3)) {
161 town->townnametype = SPECSTR_TOWNNAME_ENGLISH + _settings_game.game_creation.town_name;
162 town->townnameparts = RemapOldTownName(town->townnameparts, _settings_game.game_creation.town_name);
167 static StringID *_old_vehicle_names;
170 * Convert the old style vehicles into something that resembles
171 * the old new style savegames. Then #AfterLoadGame can handle
172 * the rest of the conversion.
174 void FixOldVehicles()
176 Vehicle *v;
178 FOR_ALL_VEHICLES(v) {
179 if ((size_t)v->next == 0xFFFF) {
180 v->next = NULL;
181 } else {
182 v->next = Vehicle::GetIfValid((size_t)v->next);
185 /* For some reason we need to correct for this */
186 switch (v->spritenum) {
187 case 0xfd: break;
188 case 0xff: v->spritenum = 0xfe; break;
189 default: v->spritenum >>= 1; break;
192 /* Vehicle-subtype is different in TTD(Patch) */
193 if (v->type == VEH_EFFECT) v->subtype = v->subtype >> 1;
195 v->name = CopyFromOldName(_old_vehicle_names[v->index]);
197 /* We haven't used this bit for stations for ages */
198 if (v->type == VEH_ROAD) {
199 RoadVehicle *rv = RoadVehicle::From(v);
200 if (rv->state != RVSB_IN_DEPOT && rv->state != RVSB_WORMHOLE) {
201 ClrBit(rv->state, 2);
202 if (IsTileType(rv->tile, MP_STATION) && _m[rv->tile].m5 >= 168) {
203 /* Update the vehicle's road state to show we're in a drive through road stop. */
204 SetBit(rv->state, RVS_IN_DT_ROAD_STOP);
209 /* The subtype should be 0, but it sometimes isn't :( */
210 if (v->type == VEH_ROAD || v->type == VEH_SHIP) v->subtype = 0;
212 /* Sometimes primary vehicles would have a nothing (invalid) order
213 * or vehicles that could not have an order would still have a
214 * (loading) order which causes assertions and the like later on.
216 if (!IsCompanyBuildableVehicleType(v) ||
217 (v->IsPrimaryVehicle() && v->current_order.IsType(OT_NOTHING))) {
218 v->current_order.MakeDummy();
221 /* Shared orders are fixed in AfterLoadVehicles now */
225 static bool FixTTOMapArray()
227 for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) {
228 TileType tt = GetTileType(t);
229 if (tt == 11) {
230 /* TTO has a different way of storing monorail.
231 * Instead of using bits in m3 it uses a different tile type. */
232 _m[t].m3 = 1; // rail type = monorail (in TTD)
233 SetTileType(t, MP_RAILWAY);
234 _m[t].m2 = 1; // set monorail ground to RAIL_GROUND_GRASS
235 tt = MP_RAILWAY;
238 switch (tt) {
239 case MP_CLEAR:
240 break;
242 case MP_RAILWAY:
243 switch (GB(_m[t].m5, 6, 2)) {
244 case 0: // RAIL_TILE_NORMAL
245 break;
246 case 1: // RAIL_TILE_SIGNALS
247 _m[t].m4 = (~_m[t].m5 & 1) << 2; // signal variant (present only in OTTD)
248 SB(_m[t].m2, 6, 2, GB(_m[t].m5, 3, 2)); // signal status
249 _m[t].m3 |= 0xC0; // both signals are present
250 _m[t].m5 = HasBit(_m[t].m5, 5) ? 2 : 1; // track direction (only X or Y)
251 _m[t].m5 |= 0x40; // RAIL_TILE_SIGNALS
252 break;
253 case 3: // RAIL_TILE_DEPOT
254 _m[t].m2 = 0;
255 break;
256 default:
257 return false;
259 break;
261 case MP_ROAD: // road (depot) or level crossing
262 switch (GB(_m[t].m5, 4, 4)) {
263 case 0: // ROAD_TILE_NORMAL
264 if (_m[t].m2 == 4) _m[t].m2 = 5; // 'small trees' -> ROADSIDE_TREES
265 break;
266 case 1: // ROAD_TILE_CROSSING (there aren't monorail crossings in TTO)
267 _m[t].m3 = _m[t].m1; // set owner of road = owner of rail
268 break;
269 case 2: // ROAD_TILE_DEPOT
270 break;
271 default:
272 return false;
274 break;
276 case MP_HOUSE:
277 _m[t].m3 = _m[t].m2 & 0xC0; // construction stage
278 _m[t].m2 &= 0x3F; // building type
279 if (_m[t].m2 >= 5) _m[t].m2++; // skip "large office block on snow"
280 break;
282 case MP_TREES:
283 _m[t].m3 = GB(_m[t].m5, 3, 3); // type of trees
284 _m[t].m5 &= 0xC7; // number of trees and growth status
285 break;
287 case MP_STATION:
288 _m[t].m3 = (_m[t].m5 >= 0x08 && _m[t].m5 <= 0x0F) ? 1 : 0; // monorail -> 1, others 0 (rail, road, airport, dock)
289 if (_m[t].m5 >= 8) _m[t].m5 -= 8; // shift for monorail
290 if (_m[t].m5 >= 0x42) _m[t].m5++; // skip heliport
291 break;
293 case MP_WATER:
294 _m[t].m3 = _m[t].m2 = 0;
295 break;
297 case MP_VOID:
298 _m[t].m2 = _m[t].m3 = _m[t].m5 = 0;
299 break;
301 case MP_INDUSTRY:
302 _m[t].m3 = 0;
303 switch (_m[t].m5) {
304 case 0x24: // farm silo
305 _m[t].m5 = 0x25;
306 break;
307 case 0x25: case 0x27: // farm
308 case 0x28: case 0x29: case 0x2A: case 0x2B: // factory
309 _m[t].m5--;
310 break;
311 default:
312 if (_m[t].m5 >= 0x2C) _m[t].m5 += 3; // iron ore mine, steel mill or bank
313 break;
315 break;
317 case MP_TUNNELBRIDGE:
318 if (HasBit(_m[t].m5, 7)) { // bridge
319 byte m5 = _m[t].m5;
320 _m[t].m5 = m5 & 0xE1; // copy bits 7..5, 1
321 if (GB(m5, 1, 2) == 1) _m[t].m5 |= 0x02; // road bridge
322 if (GB(m5, 1, 2) == 3) _m[t].m2 |= 0xA0; // monorail bridge -> tubular, steel bridge
323 if (!HasBit(m5, 6)) { // bridge head
324 _m[t].m3 = (GB(m5, 1, 2) == 3) ? 1 : 0; // track subtype (1 for monorail, 0 for others)
325 } else { // middle bridge part
326 _m[t].m3 = HasBit(m5, 2) ? 0x10 : 0; // track subtype on bridge
327 if (GB(m5, 3, 2) == 3) _m[t].m3 |= 1; // track subtype under bridge
328 if (GB(m5, 3, 2) == 1) _m[t].m5 |= 0x08; // set for road/water under (0 for rail/clear)
330 } else { // tunnel entrance/exit
331 _m[t].m2 = 0;
332 _m[t].m3 = HasBit(_m[t].m5, 3); // monorail
333 _m[t].m5 &= HasBit(_m[t].m5, 3) ? 0x03 : 0x07 ; // direction, transport type (== 0 for rail)
335 break;
337 case MP_OBJECT:
338 _m[t].m2 = 0;
339 _m[t].m3 = 0;
340 break;
342 default:
343 return false;
348 FixOldMapArray();
350 return true;
353 static Engine *_old_engines;
355 static bool FixTTOEngines()
357 /** TTD->TTO remapping of engines; 255 means there is no equivalent. SVXConverter uses (almost) the same table. */
358 static const EngineID ttd_to_tto[] = {
359 0, 255, 255, 255, 255, 255, 255, 255, 5, 7, 8, 9, 10, 11, 12, 13,
360 255, 255, 255, 255, 255, 255, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
361 25, 26, 27, 29, 28, 30, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
362 255, 255, 255, 255, 255, 255, 255, 31, 255, 32, 33, 34, 35, 36, 37, 38,
363 39, 40, 41, 42, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
364 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
365 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
366 255, 255, 255, 255, 44, 45, 46, 255, 255, 255, 255, 47, 48, 255, 49, 50,
367 255, 255, 255, 255, 51, 52, 255, 53, 54, 255, 55, 56, 255, 57, 59, 255,
368 58, 60, 255, 61, 62, 255, 63, 64, 255, 65, 66, 255, 255, 255, 255, 255,
369 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
370 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
371 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 67, 68, 69, 70,
372 71, 255, 255, 76, 77, 255, 255, 78, 79, 80, 81, 82, 83, 84, 85, 86,
373 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 255,
374 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 102, 255, 255
377 /** TTO->TTD remapping of engines. SVXConverter uses the same table. */
378 static const EngineID tto_to_ttd[] = {
379 0, 0, 8, 8, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 15, 22,
380 23, 24, 25, 26, 27, 29, 28, 30, 31, 32, 33, 34, 35, 36, 37, 55,
381 57, 59, 58, 60, 61, 62, 63, 64, 65, 66, 67, 116, 116, 117, 118, 123,
382 124, 126, 127, 132, 133, 135, 136, 138, 139, 141, 142, 144, 145, 147, 148, 150,
383 151, 153, 154, 204, 205, 206, 207, 208, 211, 212, 211, 212, 211, 212, 215, 216,
384 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
385 233, 234, 235, 236, 237, 238, 253
388 Vehicle *v;
389 FOR_ALL_VEHICLES(v) {
390 if (v->engine_type >= lengthof(tto_to_ttd)) return false;
391 v->engine_type = tto_to_ttd[v->engine_type];
394 /* Load the default engine set. Many of them will be overridden later */
395 uint j = 0;
396 for (uint i = 0; i < lengthof(_orig_rail_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_TRAIN, i);
397 for (uint i = 0; i < lengthof(_orig_road_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_ROAD, i);
398 for (uint i = 0; i < lengthof(_orig_ship_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_SHIP, i);
399 for (uint i = 0; i < lengthof(_orig_aircraft_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_AIRCRAFT, i);
401 Date aging_date = min(_date + DAYS_TILL_ORIGINAL_BASE_YEAR, ConvertYMDToDate(2050, 0, 1));
403 for (EngineID i = 0; i < 256; i++) {
404 int oi = ttd_to_tto[i];
405 Engine *e = GetTempDataEngine(i);
407 if (oi == 255) {
408 /* Default engine is used */
409 _date += DAYS_TILL_ORIGINAL_BASE_YEAR;
410 StartupOneEngine(e, aging_date);
411 e->intro_date -= DAYS_TILL_ORIGINAL_BASE_YEAR;
412 _date -= DAYS_TILL_ORIGINAL_BASE_YEAR;
414 /* Make sure for example monorail and maglev are available when they should be */
415 if (_date >= e->intro_date && HasBit(e->info.climates, 0)) {
416 e->flags |= ENGINE_AVAILABLE;
417 e->company_avail = (CompanyMask)0xFF;
418 e->age = _date > e->intro_date ? (_date - e->intro_date) / 30 : 0;
420 } else {
421 /* Using data from TTO savegame */
422 Engine *oe = &_old_engines[oi];
424 e->intro_date = oe->intro_date;
425 e->age = oe->age;
426 e->reliability = oe->reliability;
427 e->reliability_spd_dec = oe->reliability_spd_dec;
428 e->reliability_start = oe->reliability_start;
429 e->reliability_max = oe->reliability_max;
430 e->reliability_final = oe->reliability_final;
431 e->duration_phase_1 = oe->duration_phase_1;
432 e->duration_phase_2 = oe->duration_phase_2;
433 e->duration_phase_3 = oe->duration_phase_3;
434 e->flags = oe->flags;
436 e->company_avail = 0;
438 /* One or more engines were remapped to this one. Make this engine available
439 * if at least one of them was available. */
440 for (uint j = 0; j < lengthof(tto_to_ttd); j++) {
441 if (tto_to_ttd[j] == i && _old_engines[j].company_avail != 0) {
442 e->company_avail = (CompanyMask)0xFF;
443 e->flags |= ENGINE_AVAILABLE;
444 break;
448 e->info.climates = 1;
451 e->preview_company = INVALID_COMPANY;
452 e->preview_asked = (CompanyMask)-1;
453 e->preview_wait = 0;
454 e->name = NULL;
457 return true;
460 static void FixTTOCompanies()
462 Company *c;
463 FOR_ALL_COMPANIES(c) {
464 c->cur_economy.company_value = CalculateCompanyValue(c); // company value history is zeroed
468 static inline byte RemapTTOColour(byte tto)
470 /** Lossy remapping of TTO colours to TTD colours. SVXConverter uses the same conversion. */
471 static const byte tto_colour_remap[] = {
472 COLOUR_DARK_BLUE, COLOUR_GREY, COLOUR_YELLOW, COLOUR_RED,
473 COLOUR_PURPLE, COLOUR_DARK_GREEN, COLOUR_ORANGE, COLOUR_PALE_GREEN,
474 COLOUR_BLUE, COLOUR_GREEN, COLOUR_CREAM, COLOUR_BROWN,
475 COLOUR_WHITE, COLOUR_LIGHT_BLUE, COLOUR_MAUVE, COLOUR_PINK
478 if ((size_t)tto >= lengthof(tto_colour_remap)) return COLOUR_GREY; // this shouldn't happen
480 return tto_colour_remap[tto];
483 static inline uint RemapTownIndex(uint x)
485 return _savegame_type == SGT_TTO ? (x - 0x264) / 78 : (x - 0x264) / 94;
488 static inline uint RemapOrderIndex(uint x)
490 return _savegame_type == SGT_TTO ? (x - 0x1AC4) / 2 : (x - 0x1C18) / 2;
493 extern TileIndex *_animated_tile_list;
494 extern uint _animated_tile_count;
495 extern char *_old_name_array;
497 static uint32 _old_town_index;
498 static uint16 _old_string_id;
499 static uint16 _old_string_id_2;
501 static void ReadTTDPatchFlags()
503 if (_read_ttdpatch_flags) return;
505 _read_ttdpatch_flags = true;
507 /* Set default values */
508 _old_vehicle_multiplier = 1;
509 _ttdp_version = 0;
510 _old_extra_chunk_nums = 0;
511 _bump_assert_value = 0;
513 if (_savegame_type == SGT_TTO) return;
515 /* TTDPatch misuses _old_map3 for flags.. read them! */
516 _old_vehicle_multiplier = _old_map3[0];
517 /* Somehow.... there was an error in some savegames, so 0 becomes 1
518 * and 1 becomes 2. The rest of the values are okay */
519 if (_old_vehicle_multiplier < 2) _old_vehicle_multiplier++;
521 _old_vehicle_names = MallocT<StringID>(_old_vehicle_multiplier * 850);
523 /* TTDPatch increases the Vehicle-part in the middle of the game,
524 * so if the multiplier is anything else but 1, the assert fails..
525 * bump the assert value so it doesn't!
526 * (1 multiplier == 850 vehicles
527 * 1 vehicle == 128 bytes */
528 _bump_assert_value = (_old_vehicle_multiplier - 1) * 850 * 128;
530 for (uint i = 0; i < 17; i++) { // check tile 0, too
531 if (_old_map3[i] != 0) _savegame_type = SGT_TTDP1;
534 /* Check if we have a modern TTDPatch savegame (has extra data all around) */
535 if (memcmp(&_old_map3[0x1FFFA], "TTDp", 4) == 0) _savegame_type = SGT_TTDP2;
537 _old_extra_chunk_nums = _old_map3[_savegame_type == SGT_TTDP2 ? 0x1FFFE : 0x2];
539 /* Clean the misused places */
540 for (uint i = 0; i < 17; i++) _old_map3[i] = 0;
541 for (uint i = 0x1FE00; i < 0x20000; i++) _old_map3[i] = 0;
543 if (_savegame_type == SGT_TTDP2) DEBUG(oldloader, 2, "Found TTDPatch game");
545 DEBUG(oldloader, 3, "Vehicle-multiplier is set to %d (%d vehicles)", _old_vehicle_multiplier, _old_vehicle_multiplier * 850);
548 static const OldChunks town_chunk[] = {
549 OCL_SVAR( OC_TILE, Town, xy ),
550 OCL_NULL( 2 ), ///< population, no longer in use
551 OCL_SVAR( OC_UINT16, Town, townnametype ),
552 OCL_SVAR( OC_UINT32, Town, townnameparts ),
553 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Town, grow_counter ),
554 OCL_NULL( 1 ), ///< sort_index, no longer in use
555 OCL_NULL( 4 ), ///< sign-coordinates, no longer in use
556 OCL_NULL( 2 ), ///< namewidth, no longer in use
557 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Town, flags ),
558 OCL_NULL( 10 ), ///< radius, no longer in use
560 OCL_SVAR( OC_INT16, Town, ratings[0] ),
561 OCL_SVAR( OC_INT16, Town, ratings[1] ),
562 OCL_SVAR( OC_INT16, Town, ratings[2] ),
563 OCL_SVAR( OC_INT16, Town, ratings[3] ),
564 OCL_SVAR( OC_INT16, Town, ratings[4] ),
565 OCL_SVAR( OC_INT16, Town, ratings[5] ),
566 OCL_SVAR( OC_INT16, Town, ratings[6] ),
567 OCL_SVAR( OC_INT16, Town, ratings[7] ),
569 OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, have_ratings ),
570 OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, statues ),
571 OCL_NULL( 2 ), ///< num_houses, no longer in use
572 OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Town, time_until_rebuild ),
573 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Town, growth_rate ),
575 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].new_max ),
576 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].new_max ),
577 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].new_act ),
578 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].new_act ),
579 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].old_max ),
580 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].old_max ),
581 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].old_act ),
582 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].old_act ),
584 OCL_NULL( 2 ), ///< pct_pass_transported / pct_mail_transported, now computed on the fly
586 OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_FOOD].new_act ),
587 OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_WATER].new_act ),
588 OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_FOOD].old_act ),
589 OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_WATER].old_act ),
591 OCL_SVAR( OC_UINT8, Town, road_build_months ),
592 OCL_SVAR( OC_UINT8, Town, fund_buildings_months ),
594 OCL_CNULL( OC_TTD, 8 ), ///< some junk at the end of the record
596 OCL_END()
599 static bool LoadOldTown(LoadgameState *ls, int num)
601 Town *t = new (num) Town();
602 if (!LoadChunk(ls, t, town_chunk)) return false;
604 if (t->xy != 0) {
605 if (_savegame_type == SGT_TTO) {
606 /* 0x10B6 is auto-generated name, others are custom names */
607 t->townnametype = t->townnametype == 0x10B6 ? 0x20C1 : t->townnametype + 0x2A00;
609 } else {
610 delete t;
613 return true;
616 static uint16 _old_order;
617 static const OldChunks order_chunk[] = {
618 OCL_VAR ( OC_UINT16, 1, &_old_order ),
619 OCL_END()
622 static bool LoadOldOrder(LoadgameState *ls, int num)
624 if (!LoadChunk(ls, NULL, order_chunk)) return false;
626 Order *o = new (num) Order();
627 o->AssignOrder(UnpackOldOrder(_old_order));
629 if (o->IsType(OT_NOTHING)) {
630 delete o;
631 } else {
632 /* Relink the orders to each other (in the orders for one vehicle are behind each other,
633 * with an invalid order (OT_NOTHING) as indication that it is the last order */
634 Order *prev = Order::GetIfValid(num - 1);
635 if (prev != NULL) prev->next = o;
638 return true;
641 static bool LoadOldAnimTileList(LoadgameState *ls, int num)
643 /* This is slightly hackish - we must load a chunk into an array whose
644 * address isn't static, but instead pointed to by _animated_tile_list.
645 * To achieve that, create an OldChunks list on the stack on the fly.
646 * The list cannot be static because the value of _animated_tile_list
647 * can change between calls. */
649 const OldChunks anim_chunk[] = {
650 OCL_VAR ( OC_TILE, 256, _animated_tile_list ),
651 OCL_END ()
654 if (!LoadChunk(ls, NULL, anim_chunk)) return false;
656 /* Update the animated tile counter by counting till the first zero in the array */
657 for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
658 if (_animated_tile_list[_animated_tile_count] == 0) break;
661 return true;
664 static const OldChunks depot_chunk[] = {
665 OCL_SVAR( OC_TILE, Depot, xy ),
666 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
667 OCL_END()
670 static bool LoadOldDepot(LoadgameState *ls, int num)
672 Depot *d = new (num) Depot();
673 if (!LoadChunk(ls, d, depot_chunk)) return false;
675 if (d->xy != 0) {
676 /* In some cases, there could be depots referencing invalid town. */
677 Town *t = Town::GetIfValid(RemapTownIndex(_old_town_index));
678 if (t == NULL) t = Town::GetRandom();
679 d->town = t;
680 } else {
681 delete d;
684 return true;
687 static StationID _current_station_id;
688 static uint16 _waiting_acceptance;
689 static uint8 _cargo_source;
690 static uint8 _cargo_days;
692 static const OldChunks goods_chunk[] = {
693 OCL_VAR ( OC_UINT16, 1, &_waiting_acceptance ),
694 OCL_SVAR( OC_UINT8, GoodsEntry, time_since_pickup ),
695 OCL_SVAR( OC_UINT8, GoodsEntry, rating ),
696 OCL_VAR ( OC_UINT8, 1, &_cargo_source ),
697 OCL_VAR ( OC_UINT8, 1, &_cargo_days ),
698 OCL_SVAR( OC_UINT8, GoodsEntry, last_speed ),
699 OCL_SVAR( OC_UINT8, GoodsEntry, last_age ),
701 OCL_END()
704 static bool LoadOldGood(LoadgameState *ls, int num)
706 /* for TTO games, 12th (num == 11) goods entry is created in the Station constructor */
707 if (_savegame_type == SGT_TTO && num == 11) return true;
709 Station *st = Station::Get(_current_station_id);
710 GoodsEntry *ge = &st->goods[num];
712 if (!LoadChunk(ls, ge, goods_chunk)) return false;
714 SB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
715 SB(ge->status, GoodsEntry::GES_RATING, 1, _cargo_source != 0xFF);
716 if (GB(_waiting_acceptance, 0, 12) != 0 && CargoPacket::CanAllocateItem()) {
717 ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, 0, 0),
718 INVALID_STATION);
721 return true;
724 static const OldChunks station_chunk[] = {
725 OCL_SVAR( OC_TILE, Station, xy ),
726 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
728 OCL_NULL( 4 ), ///< bus/lorry tile
729 OCL_SVAR( OC_TILE, Station, train_station.tile ),
730 OCL_SVAR( OC_TILE, Station, airport.tile ),
731 OCL_SVAR( OC_TILE, Station, dock_station.tile),
732 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Station, train_station.w ),
734 OCL_NULL( 1 ), ///< sort-index, no longer in use
735 OCL_NULL( 2 ), ///< sign-width, no longer in use
737 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
739 OCL_NULL( 4 ), ///< sign left/top, no longer in use
741 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Station, had_vehicle_of_type ),
743 OCL_CHUNK( 12, LoadOldGood ),
745 OCL_SVAR( OC_UINT8, Station, time_since_load ),
746 OCL_SVAR( OC_UINT8, Station, time_since_unload ),
747 OCL_SVAR( OC_UINT8, Station, delete_ctr ),
748 OCL_SVAR( OC_UINT8, Station, owner ),
749 OCL_SVAR( OC_UINT8, Station, facilities ),
750 OCL_SVAR( OC_TTD | OC_UINT8, Station, airport.type ),
751 OCL_SVAR( OC_TTO | OC_FILE_U16 | OC_VAR_U64, Station, airport.flags ),
752 OCL_NULL( 3 ), ///< bus/truck status, blocked months, no longer in use
753 OCL_CNULL( OC_TTD, 1 ), ///< unknown
754 OCL_SVAR( OC_TTD | OC_FILE_U16 | OC_VAR_U64, Station, airport.flags ),
755 OCL_CNULL( OC_TTD, 2 ), ///< last_vehicle. now last_vehicle_type
756 OCL_CNULL( OC_TTD, 4 ), ///< junk at end of chunk
758 OCL_END()
761 static bool LoadOldStation(LoadgameState *ls, int num)
763 Station *st = new (num) Station();
764 _current_station_id = num;
766 if (!LoadChunk(ls, st, station_chunk)) return false;
768 if (st->xy != 0) {
769 st->town = Town::Get(RemapTownIndex(_old_town_index));
771 if (_savegame_type == SGT_TTO) {
772 if (IsInsideBS(_old_string_id, 0x180F, 32)) {
773 st->string_id = STR_SV_STNAME + (_old_string_id - 0x180F); // automatic name
774 } else {
775 st->string_id = _old_string_id + 0x2800; // custom name
778 if (HasBit(st->airport.flags, 8)) {
779 st->airport.type = 1; // large airport
780 } else if (HasBit(st->airport.flags, 6)) {
781 st->airport.type = 3; // oil rig
782 } else {
783 st->airport.type = 0; // small airport
785 } else {
786 st->string_id = RemapOldStringID(_old_string_id);
788 } else {
789 delete st;
792 return true;
795 static const OldChunks industry_chunk[] = {
796 OCL_SVAR( OC_TILE, Industry, location.tile ),
797 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
798 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Industry, location.w ),
799 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Industry, location.h ),
800 OCL_NULL( 2 ), ///< used to be industry's produced_cargo
802 OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced_cargo_waiting[0] ),
803 OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced_cargo_waiting[1] ),
804 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced_cargo_waiting[0] ),
805 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced_cargo_waiting[1] ),
807 OCL_SVAR( OC_UINT8, Industry, production_rate[0] ),
808 OCL_SVAR( OC_UINT8, Industry, production_rate[1] ),
810 OCL_NULL( 3 ), ///< used to be industry's accepts_cargo
812 OCL_SVAR( OC_UINT8, Industry, prod_level ),
814 OCL_SVAR( OC_UINT16, Industry, this_month_production[0] ),
815 OCL_SVAR( OC_UINT16, Industry, this_month_production[1] ),
816 OCL_SVAR( OC_UINT16, Industry, this_month_transported[0] ),
817 OCL_SVAR( OC_UINT16, Industry, this_month_transported[1] ),
819 OCL_SVAR( OC_UINT8, Industry, last_month_pct_transported[0] ),
820 OCL_SVAR( OC_UINT8, Industry, last_month_pct_transported[1] ),
822 OCL_SVAR( OC_UINT16, Industry, last_month_production[0] ),
823 OCL_SVAR( OC_UINT16, Industry, last_month_production[1] ),
824 OCL_SVAR( OC_UINT16, Industry, last_month_transported[0] ),
825 OCL_SVAR( OC_UINT16, Industry, last_month_transported[1] ),
827 OCL_SVAR( OC_UINT8, Industry, type ),
828 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, counter ),
829 OCL_SVAR( OC_UINT8, Industry, owner ),
830 OCL_SVAR( OC_UINT8, Industry, random_colour ),
831 OCL_SVAR( OC_TTD | OC_FILE_U8 | OC_VAR_I32, Industry, last_prod_year ),
832 OCL_SVAR( OC_TTD | OC_UINT16, Industry, counter ),
833 OCL_SVAR( OC_TTD | OC_UINT8, Industry, was_cargo_delivered ),
835 OCL_CNULL( OC_TTD, 9 ), ///< Random junk at the end of this chunk
837 OCL_END()
840 static bool LoadOldIndustry(LoadgameState *ls, int num)
842 Industry *i = new (num) Industry();
843 if (!LoadChunk(ls, i, industry_chunk)) return false;
845 if (i->location.tile != 0) {
846 i->town = Town::Get(RemapTownIndex(_old_town_index));
848 if (_savegame_type == SGT_TTO) {
849 if (i->type > 0x06) i->type++; // Printing Works were added
850 if (i->type == 0x0A) i->type = 0x12; // Iron Ore Mine has different ID
852 i->last_prod_year = _cur_date_ymd.year;
854 i->random_colour = RemapTTOColour(i->random_colour);
857 Industry::IncIndustryTypeCount(i->type);
858 } else {
859 delete i;
862 return true;
865 static CompanyID _current_company_id;
866 static int32 _old_yearly;
868 static const OldChunks _company_yearly_chunk[] = {
869 OCL_VAR( OC_INT32, 1, &_old_yearly ),
870 OCL_END()
873 static bool LoadOldCompanyYearly(LoadgameState *ls, int num)
875 Company *c = Company::Get(_current_company_id);
877 for (uint i = 0; i < 13; i++) {
878 if (_savegame_type == SGT_TTO && i == 6) {
879 _old_yearly = 0; // property maintenance
880 } else {
881 if (!LoadChunk(ls, NULL, _company_yearly_chunk)) return false;
884 c->yearly_expenses[num][i] = _old_yearly;
887 return true;
890 static const OldChunks _company_economy_chunk[] = {
891 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, income ),
892 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, expenses ),
893 OCL_SVAR( OC_INT32, CompanyEconomyEntry, delivered_cargo[NUM_CARGO - 1] ),
894 OCL_SVAR( OC_INT32, CompanyEconomyEntry, performance_history ),
895 OCL_SVAR( OC_TTD | OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, company_value ),
897 OCL_END()
900 static bool LoadOldCompanyEconomy(LoadgameState *ls, int num)
902 Company *c = Company::Get(_current_company_id);
904 if (!LoadChunk(ls, &c->cur_economy, _company_economy_chunk)) return false;
906 /* Don't ask, but the number in TTD(Patch) are inversed to OpenTTD */
907 c->cur_economy.income = -c->cur_economy.income;
908 c->cur_economy.expenses = -c->cur_economy.expenses;
910 for (uint i = 0; i < 24; i++) {
911 if (!LoadChunk(ls, &c->old_economy[i], _company_economy_chunk)) return false;
913 c->old_economy[i].income = -c->old_economy[i].income;
914 c->old_economy[i].expenses = -c->old_economy[i].expenses;
917 return true;
920 static const OldChunks _company_chunk[] = {
921 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
922 OCL_SVAR( OC_UINT32, Company, name_2 ),
923 OCL_SVAR( OC_UINT32, Company, face ),
924 OCL_VAR ( OC_UINT16, 1, &_old_string_id_2 ),
925 OCL_SVAR( OC_UINT32, Company, president_name_2 ),
927 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, money ),
928 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, current_loan ),
930 OCL_SVAR( OC_UINT8, Company, colour ),
931 OCL_SVAR( OC_UINT8, Company, money_fraction ),
932 OCL_SVAR( OC_UINT8, Company, months_of_bankruptcy ),
933 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Company, bankrupt_asked ),
934 OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Company, bankrupt_value ),
935 OCL_SVAR( OC_UINT16, Company, bankrupt_timeout ),
937 OCL_CNULL( OC_TTD, 4 ), // cargo_types
938 OCL_CNULL( OC_TTO, 2 ), // cargo_types
940 OCL_CHUNK( 3, LoadOldCompanyYearly ),
941 OCL_CHUNK( 1, LoadOldCompanyEconomy ),
943 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Company, inaugurated_year),
944 OCL_SVAR( OC_TILE, Company, last_build_coordinate ),
945 OCL_SVAR( OC_UINT8, Company, num_valid_stat_ent ),
947 OCL_NULL( 230 ), // Old AI
949 OCL_SVAR( OC_UINT8, Company, block_preview ),
950 OCL_CNULL( OC_TTD, 1 ), // Old AI
951 OCL_SVAR( OC_TTD | OC_UINT8, Company, avail_railtypes ),
952 OCL_SVAR( OC_TILE, Company, location_of_HQ ),
953 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[0] ),
954 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[1] ),
955 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[2] ),
956 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[3] ),
958 OCL_CNULL( OC_TTD, 8 ), ///< junk at end of chunk
960 OCL_END()
963 static bool LoadOldCompany(LoadgameState *ls, int num)
965 Company *c = new (num) Company();
967 _current_company_id = (CompanyID)num;
969 if (!LoadChunk(ls, c, _company_chunk)) return false;
971 if (_old_string_id == 0) {
972 delete c;
973 return true;
976 if (_savegame_type == SGT_TTO) {
977 /* adjust manager's face */
978 if (HasBit(c->face, 27) && GB(c->face, 26, 1) == GB(c->face, 19, 1)) {
979 /* if face would be black in TTD, adjust tie colour and thereby face colour */
980 ClrBit(c->face, 27);
983 /* Company name */
984 if (_old_string_id == 0 || _old_string_id == 0x4C00) {
985 _old_string_id = STR_SV_UNNAMED; // "Unnamed"
986 } else if (GB(_old_string_id, 8, 8) == 0x52) {
987 _old_string_id += 0x2A00; // Custom name
988 } else {
989 _old_string_id = RemapOldStringID(_old_string_id += 0x240D); // Automatic name
991 c->name_1 = _old_string_id;
993 /* Manager name */
994 switch (_old_string_id_2) {
995 case 0x4CDA: _old_string_id_2 = SPECSTR_PRESIDENT_NAME; break; // automatic name
996 case 0x0006: _old_string_id_2 = STR_SV_EMPTY; break; // empty name
997 default: _old_string_id_2 = _old_string_id_2 + 0x2A00; break; // custom name
999 c->president_name_1 = _old_string_id_2;
1001 c->colour = RemapTTOColour(c->colour);
1003 if (num != 0) c->is_ai = true;
1004 } else {
1005 c->name_1 = RemapOldStringID(_old_string_id);
1006 c->president_name_1 = RemapOldStringID(_old_string_id_2);
1008 if (num == 0) {
1009 /* If the first company has no name, make sure we call it UNNAMED */
1010 if (c->name_1 == 0) {
1011 c->name_1 = STR_SV_UNNAMED;
1013 } else {
1014 /* Beside some multiplayer maps (1 on 1), which we don't official support,
1015 * all other companies are an AI.. mark them as such */
1016 c->is_ai = true;
1019 /* Sometimes it is better to not ask.. in old scenarios, the money
1020 * was always 893288 pounds. In the newer versions this is correct,
1021 * but correct for those oldies
1022 * Ps: this also means that if you had exact 893288 pounds, you will go back
1023 * to 100000.. this is a very VERY small chance ;) */
1024 if (c->money == 893288) c->money = c->current_loan = 100000;
1027 _company_colours[num] = (Colours)c->colour;
1028 c->inaugurated_year -= ORIGINAL_BASE_YEAR;
1030 return true;
1033 static uint32 _old_order_ptr;
1034 static uint16 _old_next_ptr;
1035 static VehicleID _current_vehicle_id;
1037 static const OldChunks vehicle_train_chunk[] = {
1038 OCL_SVAR( OC_UINT8, Train, track ),
1039 OCL_SVAR( OC_UINT8, Train, force_proceed ),
1040 OCL_SVAR( OC_UINT16, Train, crash_anim_pos ),
1041 OCL_SVAR( OC_UINT8, Train, railtype ),
1043 OCL_NULL( 5 ), ///< Junk
1045 OCL_END()
1048 static const OldChunks vehicle_road_chunk[] = {
1049 OCL_SVAR( OC_UINT8, RoadVehicle, state ),
1050 OCL_SVAR( OC_UINT8, RoadVehicle, frame ),
1051 OCL_SVAR( OC_UINT16, RoadVehicle, blocked_ctr ),
1052 OCL_SVAR( OC_UINT8, RoadVehicle, overtaking ),
1053 OCL_SVAR( OC_UINT8, RoadVehicle, overtaking_ctr ),
1054 OCL_SVAR( OC_UINT16, RoadVehicle, crashed_ctr ),
1055 OCL_SVAR( OC_UINT8, RoadVehicle, reverse_ctr ),
1057 OCL_NULL( 1 ), ///< Junk
1059 OCL_END()
1062 static const OldChunks vehicle_ship_chunk[] = {
1063 OCL_SVAR( OC_UINT8, Ship, state ),
1065 OCL_NULL( 9 ), ///< Junk
1067 OCL_END()
1070 static const OldChunks vehicle_air_chunk[] = {
1071 OCL_SVAR( OC_UINT8, Aircraft, pos ),
1072 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Aircraft, targetairport ),
1073 OCL_SVAR( OC_UINT16, Aircraft, crashed_counter ),
1074 OCL_SVAR( OC_UINT8, Aircraft, state ),
1076 OCL_NULL( 5 ), ///< Junk
1078 OCL_END()
1081 static const OldChunks vehicle_effect_chunk[] = {
1082 OCL_SVAR( OC_UINT16, EffectVehicle, animation_state ),
1083 OCL_SVAR( OC_UINT8, EffectVehicle, animation_substate ),
1085 OCL_NULL( 7 ), // Junk
1087 OCL_END()
1090 static const OldChunks vehicle_disaster_chunk[] = {
1091 OCL_SVAR( OC_UINT16, DisasterVehicle, image_override ),
1092 OCL_SVAR( OC_UINT16, DisasterVehicle, big_ufo_destroyer_target ),
1094 OCL_NULL( 6 ), ///< Junk
1096 OCL_END()
1099 static const OldChunks vehicle_empty_chunk[] = {
1100 OCL_NULL( 10 ), ///< Junk
1102 OCL_END()
1105 static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
1107 Vehicle *v = Vehicle::GetIfValid(_current_vehicle_id);
1108 uint temp = ls->total_read;
1109 bool res;
1111 if (v == NULL) {
1112 res = LoadChunk(ls, NULL, vehicle_empty_chunk);
1113 } else {
1114 switch (v->type) {
1115 default: SlErrorCorrupt("Invalid vehicle type");
1116 case VEH_TRAIN : res = LoadChunk(ls, v, vehicle_train_chunk); break;
1117 case VEH_ROAD : res = LoadChunk(ls, v, vehicle_road_chunk); break;
1118 case VEH_SHIP : res = LoadChunk(ls, v, vehicle_ship_chunk); break;
1119 case VEH_AIRCRAFT: res = LoadChunk(ls, v, vehicle_air_chunk); break;
1120 case VEH_EFFECT : res = LoadChunk(ls, v, vehicle_effect_chunk); break;
1121 case VEH_DISASTER: res = LoadChunk(ls, v, vehicle_disaster_chunk); break;
1125 /* This chunk size should always be 10 bytes */
1126 if (ls->total_read - temp != 10) {
1127 DEBUG(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
1128 return false;
1131 return res;
1134 static uint16 _cargo_count;
1136 static const OldChunks vehicle_chunk[] = {
1137 OCL_SVAR( OC_UINT8, Vehicle, subtype ),
1139 OCL_NULL( 2 ), ///< Hash, calculated automatically
1140 OCL_NULL( 2 ), ///< Index, calculated automatically
1142 OCL_VAR ( OC_UINT32, 1, &_old_order_ptr ),
1143 OCL_VAR ( OC_UINT16, 1, &_old_order ),
1145 OCL_NULL ( 1 ), ///< num_orders, now calculated
1146 OCL_SVAR( OC_UINT8, Vehicle, cur_implicit_order_index ),
1147 OCL_SVAR( OC_TILE, Vehicle, dest_tile ),
1148 OCL_SVAR( OC_UINT16, Vehicle, load_unload_ticks ),
1149 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
1150 OCL_SVAR( OC_UINT16, Vehicle, service_interval ),
1151 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, last_station_visited ),
1152 OCL_SVAR( OC_TTD | OC_UINT8, Vehicle, tick_counter ),
1153 OCL_CNULL( OC_TTD, 2 ), ///< max_speed, now it is calculated.
1154 OCL_CNULL( OC_TTO, 1 ), ///< max_speed, now it is calculated.
1156 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, x_pos ),
1157 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ),
1158 OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, z_pos ),
1159 OCL_SVAR( OC_UINT8, Vehicle, direction ),
1160 OCL_NULL( 2 ), ///< x_offs and y_offs, calculated automatically
1161 OCL_NULL( 2 ), ///< x_extent and y_extent, calculated automatically
1162 OCL_NULL( 1 ), ///< z_extent, calculated automatically
1164 OCL_SVAR( OC_UINT8, Vehicle, owner ),
1165 OCL_SVAR( OC_TILE, Vehicle, tile ),
1166 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, sprite_seq.seq[0].sprite ),
1168 OCL_NULL( 8 ), ///< Vehicle sprite box, calculated automatically
1170 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Vehicle, vehstatus ),
1171 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cur_speed ),
1172 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cur_speed ),
1173 OCL_SVAR( OC_UINT8, Vehicle, subspeed ),
1174 OCL_SVAR( OC_UINT8, Vehicle, acceleration ),
1175 OCL_SVAR( OC_UINT8, Vehicle, progress ),
1177 OCL_SVAR( OC_UINT8, Vehicle, cargo_type ),
1178 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cargo_cap ),
1179 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cargo_cap ),
1180 OCL_VAR ( OC_TTD | OC_UINT16, 1, &_cargo_count ),
1181 OCL_VAR ( OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_cargo_count ),
1182 OCL_VAR ( OC_UINT8, 1, &_cargo_source ),
1183 OCL_VAR ( OC_UINT8, 1, &_cargo_days ),
1185 OCL_SVAR( OC_TTO | OC_UINT8, Vehicle, tick_counter ),
1187 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, age ),
1188 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, max_age ),
1189 OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, build_year ),
1190 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, unitnumber ),
1192 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, engine_type ),
1193 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, engine_type ),
1195 OCL_SVAR( OC_UINT8, Vehicle, spritenum ),
1196 OCL_SVAR( OC_UINT8, Vehicle, day_counter ),
1198 OCL_SVAR( OC_UINT8, Vehicle, breakdowns_since_last_service ),
1199 OCL_SVAR( OC_UINT8, Vehicle, breakdown_ctr ),
1200 OCL_SVAR( OC_UINT8, Vehicle, breakdown_delay ),
1201 OCL_SVAR( OC_UINT8, Vehicle, breakdown_chance ),
1203 OCL_CNULL( OC_TTO, 1 ),
1205 OCL_SVAR( OC_UINT16, Vehicle, reliability ),
1206 OCL_SVAR( OC_UINT16, Vehicle, reliability_spd_dec ),
1208 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_this_year ),
1209 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_last_year ),
1211 OCL_VAR ( OC_UINT16, 1, &_old_next_ptr ),
1213 OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Vehicle, value ),
1215 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
1217 OCL_CHUNK( 1, LoadOldVehicleUnion ),
1219 OCL_CNULL( OC_TTO, 24 ), ///< junk
1220 OCL_CNULL( OC_TTD, 20 ), ///< junk at end of struct (TTDPatch has some data in it)
1222 OCL_END()
1226 * Load the vehicles of an old style savegame.
1227 * @param ls State (buffer) of the currently loaded game.
1228 * @param num The number of vehicles to load.
1229 * @return True iff loading went without problems.
1231 bool LoadOldVehicle(LoadgameState *ls, int num)
1233 /* Read the TTDPatch flags, because we need some info from it */
1234 ReadTTDPatchFlags();
1236 for (uint i = 0; i < _old_vehicle_multiplier; i++) {
1237 _current_vehicle_id = num * _old_vehicle_multiplier + i;
1239 Vehicle *v;
1241 if (_savegame_type == SGT_TTO) {
1242 uint type = ReadByte(ls);
1243 switch (type) {
1244 default: return false;
1245 case 0x00 /* VEH_INVALID */: v = NULL; break;
1246 case 0x25 /* MONORAIL */:
1247 case 0x20 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break;
1248 case 0x21 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break;
1249 case 0x22 /* VEH_SHIP */: v = new (_current_vehicle_id) Ship(); break;
1250 case 0x23 /* VEH_AIRCRAFT */: v = new (_current_vehicle_id) Aircraft(); break;
1251 case 0x24 /* VEH_EFFECT */: v = new (_current_vehicle_id) EffectVehicle(); break;
1252 case 0x26 /* VEH_DISASTER */: v = new (_current_vehicle_id) DisasterVehicle(); break;
1255 if (!LoadChunk(ls, v, vehicle_chunk)) return false;
1256 if (v == NULL) continue;
1257 v->refit_cap = v->cargo_cap;
1259 SpriteID sprite = v->sprite_seq.seq[0].sprite;
1260 /* no need to override other sprites */
1261 if (IsInsideMM(sprite, 1460, 1465)) {
1262 sprite += 580; // aircraft smoke puff
1263 } else if (IsInsideMM(sprite, 2096, 2115)) {
1264 sprite += 977; // special effects part 1
1265 } else if (IsInsideMM(sprite, 2396, 2436)) {
1266 sprite += 1305; // special effects part 2
1267 } else if (IsInsideMM(sprite, 2516, 2539)) {
1268 sprite += 1385; // rotor or disaster-related vehicles
1270 v->sprite_seq.seq[0].sprite = sprite;
1271 v->UpdateSpriteSeqBound();
1273 switch (v->type) {
1274 case VEH_TRAIN: {
1275 static const byte spriteset_rail[] = {
1276 0, 2, 4, 4, 8, 10, 12, 14, 16, 18, 20, 22, 40, 42, 44, 46,
1277 48, 52, 54, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 120, 122,
1278 124, 126, 128, 130, 132, 134, 136, 138, 140
1280 if (v->spritenum / 2 >= lengthof(spriteset_rail)) return false;
1281 v->spritenum = spriteset_rail[v->spritenum / 2]; // adjust railway sprite set offset
1282 Train::From(v)->railtype = type == 0x25 ? 1 : 0; // monorail / rail
1283 break;
1286 case VEH_ROAD:
1287 if (v->spritenum >= 22) v->spritenum += 12;
1288 break;
1290 case VEH_SHIP:
1291 v->spritenum += 2;
1293 switch (v->spritenum) {
1294 case 2: // oil tanker && cargo type != oil
1295 if (v->cargo_type != CT_OIL) v->spritenum = 0; // make it a coal/goods ship
1296 break;
1297 case 4: // passenger ship && cargo type == mail
1298 if (v->cargo_type == CT_MAIL) v->spritenum = 0; // make it a mail ship
1299 break;
1300 default:
1301 break;
1303 break;
1305 default:
1306 break;
1309 switch (_old_string_id) {
1310 case 0x0000: break; // empty (invalid vehicles)
1311 case 0x0006: _old_string_id = STR_SV_EMPTY; break; // empty (special vehicles)
1312 case 0x8495: _old_string_id = STR_SV_TRAIN_NAME; break; // "Train X"
1313 case 0x8842: _old_string_id = STR_SV_ROAD_VEHICLE_NAME; break; // "Road Vehicle X"
1314 case 0x8C3B: _old_string_id = STR_SV_SHIP_NAME; break; // "Ship X"
1315 case 0x9047: _old_string_id = STR_SV_AIRCRAFT_NAME; break; // "Aircraft X"
1316 default: _old_string_id += 0x2A00; break; // custom name
1319 _old_vehicle_names[_current_vehicle_id] = _old_string_id;
1320 } else {
1321 /* Read the vehicle type and allocate the right vehicle */
1322 switch (ReadByte(ls)) {
1323 default: SlErrorCorrupt("Invalid vehicle type");
1324 case 0x00 /* VEH_INVALID */: v = NULL; break;
1325 case 0x10 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break;
1326 case 0x11 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break;
1327 case 0x12 /* VEH_SHIP */: v = new (_current_vehicle_id) Ship(); break;
1328 case 0x13 /* VEH_AIRCRAFT*/: v = new (_current_vehicle_id) Aircraft(); break;
1329 case 0x14 /* VEH_EFFECT */: v = new (_current_vehicle_id) EffectVehicle(); break;
1330 case 0x15 /* VEH_DISASTER*/: v = new (_current_vehicle_id) DisasterVehicle(); break;
1333 if (!LoadChunk(ls, v, vehicle_chunk)) return false;
1334 if (v == NULL) continue;
1336 _old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
1338 /* This should be consistent, else we have a big problem... */
1339 if (v->index != _current_vehicle_id) {
1340 DEBUG(oldloader, 0, "Loading failed - vehicle-array is invalid");
1341 return false;
1345 if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
1346 uint max = _savegame_type == SGT_TTO ? 3000 : 5000;
1347 uint old_id = RemapOrderIndex(_old_order_ptr);
1348 if (old_id < max) v->orders.old = Order::Get(old_id); // don't accept orders > max number of orders
1350 v->current_order.AssignOrder(UnpackOldOrder(_old_order));
1352 v->next = (Vehicle *)(size_t)_old_next_ptr;
1354 if (_cargo_count != 0 && CargoPacket::CanAllocateItem()) {
1355 StationID source = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
1356 TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : 0;
1357 v->cargo.Append(new CargoPacket(_cargo_count, _cargo_days, source, source_xy, source_xy));
1361 return true;
1364 static const OldChunks sign_chunk[] = {
1365 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
1366 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, x ),
1367 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, y ),
1368 OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, Sign, z ),
1370 OCL_NULL( 6 ), ///< Width of sign, no longer in use
1372 OCL_END()
1375 static bool LoadOldSign(LoadgameState *ls, int num)
1377 Sign *si = new (num) Sign();
1378 if (!LoadChunk(ls, si, sign_chunk)) return false;
1380 if (_old_string_id != 0) {
1381 if (_savegame_type == SGT_TTO) {
1382 if (_old_string_id != 0x140A) si->name = CopyFromOldName(_old_string_id + 0x2A00);
1383 } else {
1384 si->name = CopyFromOldName(RemapOldStringID(_old_string_id));
1386 si->owner = OWNER_NONE;
1387 } else {
1388 delete si;
1391 return true;
1394 static const OldChunks engine_chunk[] = {
1395 OCL_SVAR( OC_UINT16, Engine, company_avail ),
1396 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, intro_date ),
1397 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, age ),
1398 OCL_SVAR( OC_UINT16, Engine, reliability ),
1399 OCL_SVAR( OC_UINT16, Engine, reliability_spd_dec ),
1400 OCL_SVAR( OC_UINT16, Engine, reliability_start ),
1401 OCL_SVAR( OC_UINT16, Engine, reliability_max ),
1402 OCL_SVAR( OC_UINT16, Engine, reliability_final ),
1403 OCL_SVAR( OC_UINT16, Engine, duration_phase_1 ),
1404 OCL_SVAR( OC_UINT16, Engine, duration_phase_2 ),
1405 OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
1407 OCL_NULL( 1 ), // lifelength
1408 OCL_SVAR( OC_UINT8, Engine, flags ),
1409 OCL_NULL( 1 ), // preview_company_rank
1410 OCL_SVAR( OC_UINT8, Engine, preview_wait ),
1412 OCL_CNULL( OC_TTD, 2 ), ///< railtype + junk
1414 OCL_END()
1417 static bool LoadOldEngine(LoadgameState *ls, int num)
1419 Engine *e = _savegame_type == SGT_TTO ? &_old_engines[num] : GetTempDataEngine(num);
1420 return LoadChunk(ls, e, engine_chunk);
1423 static bool LoadOldEngineName(LoadgameState *ls, int num)
1425 Engine *e = GetTempDataEngine(num);
1426 e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
1427 return true;
1430 static const OldChunks subsidy_chunk[] = {
1431 OCL_SVAR( OC_UINT8, Subsidy, cargo_type ),
1432 OCL_SVAR( OC_UINT8, Subsidy, remaining ),
1433 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, src ),
1434 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, dst ),
1436 OCL_END()
1439 static bool LoadOldSubsidy(LoadgameState *ls, int num)
1441 Subsidy *s = new (num) Subsidy();
1442 bool ret = LoadChunk(ls, s, subsidy_chunk);
1443 if (s->cargo_type == CT_INVALID) delete s;
1444 return ret;
1447 static const OldChunks game_difficulty_chunk[] = {
1448 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, max_no_competitors ),
1449 OCL_NULL( 2), // competitor_start_time
1450 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, number_towns ),
1451 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, industry_density ),
1452 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, DifficultySettings, max_loan ),
1453 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, initial_interest ),
1454 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, vehicle_costs ),
1455 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, competitor_speed ),
1456 OCL_NULL( 2), // competitor_intelligence
1457 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, vehicle_breakdowns ),
1458 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, subsidy_multiplier ),
1459 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, construction_cost ),
1460 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, terrain_type ),
1461 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, quantity_sea_lakes ),
1462 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, economy ),
1463 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, line_reverse_mode ),
1464 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, disasters ),
1465 OCL_END()
1468 static bool LoadOldGameDifficulty(LoadgameState *ls, int num)
1470 bool ret = LoadChunk(ls, &_settings_game.difficulty, game_difficulty_chunk);
1471 _settings_game.difficulty.max_loan *= 1000;
1472 return ret;
1476 static bool LoadOldMapPart1(LoadgameState *ls, int num)
1478 if (_savegame_type == SGT_TTO) {
1479 MemSetT(_m, 0, OLD_MAP_SIZE);
1480 MemSetT(_me, 0, OLD_MAP_SIZE);
1483 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
1484 _m[i].m1 = ReadByte(ls);
1486 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
1487 _m[i].m2 = ReadByte(ls);
1490 if (_savegame_type != SGT_TTO) {
1491 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
1492 _old_map3[i * 2] = ReadByte(ls);
1493 _old_map3[i * 2 + 1] = ReadByte(ls);
1495 for (uint i = 0; i < OLD_MAP_SIZE / 4; i++) {
1496 byte b = ReadByte(ls);
1497 _me[i * 4 + 0].m6 = GB(b, 0, 2);
1498 _me[i * 4 + 1].m6 = GB(b, 2, 2);
1499 _me[i * 4 + 2].m6 = GB(b, 4, 2);
1500 _me[i * 4 + 3].m6 = GB(b, 6, 2);
1504 return true;
1507 static bool LoadOldMapPart2(LoadgameState *ls, int num)
1509 uint i;
1511 for (i = 0; i < OLD_MAP_SIZE; i++) {
1512 _m[i].type = ReadByte(ls);
1514 for (i = 0; i < OLD_MAP_SIZE; i++) {
1515 _m[i].m5 = ReadByte(ls);
1518 return true;
1521 static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num)
1523 ReadTTDPatchFlags();
1525 DEBUG(oldloader, 2, "Found %d extra chunk(s)", _old_extra_chunk_nums);
1527 for (int i = 0; i != _old_extra_chunk_nums; i++) {
1528 uint16 id = ReadUint16(ls);
1529 uint32 len = ReadUint32(ls);
1531 switch (id) {
1532 /* List of GRFIDs, used in the savegame. 0x8004 is the new ID
1533 * They are saved in a 'GRFID:4 active:1' format, 5 bytes for each entry */
1534 case 0x2:
1535 case 0x8004: {
1536 /* Skip the first element: TTDP hack for the Action D special variables (FFFF0000 01) */
1537 ReadUint32(ls); ReadByte(ls); len -= 5;
1539 ClearGRFConfigList(&_grfconfig);
1540 while (len != 0) {
1541 uint32 grfid = ReadUint32(ls);
1543 if (ReadByte(ls) == 1) {
1544 GRFConfig *c = new GRFConfig("TTDP game, no information");
1545 c->ident.grfid = grfid;
1547 AppendToGRFConfigList(&_grfconfig, c);
1548 DEBUG(oldloader, 3, "TTDPatch game using GRF file with GRFID %0X", BSWAP32(c->ident.grfid));
1550 len -= 5;
1553 /* Append static NewGRF configuration */
1554 AppendStaticGRFConfigs(&_grfconfig);
1555 break;
1558 /* TTDPatch version and configuration */
1559 case 0x3:
1560 _ttdp_version = ReadUint32(ls);
1561 DEBUG(oldloader, 3, "Game saved with TTDPatch version %d.%d.%d r%d",
1562 GB(_ttdp_version, 24, 8), GB(_ttdp_version, 20, 4), GB(_ttdp_version, 16, 4), GB(_ttdp_version, 0, 16));
1563 len -= 4;
1564 while (len-- != 0) ReadByte(ls); // skip the configuration
1565 break;
1567 default:
1568 DEBUG(oldloader, 4, "Skipping unknown extra chunk %X", id);
1569 while (len-- != 0) ReadByte(ls);
1570 break;
1574 return true;
1577 extern TileIndex _cur_tileloop_tile;
1578 extern uint16 _disaster_delay;
1579 extern byte _trees_tick_ctr;
1580 extern byte _age_cargo_skip_counter; // From misc_sl.cpp
1581 extern uint8 _old_diff_level;
1582 extern uint8 _old_units;
1583 static const OldChunks main_chunk[] = {
1584 OCL_ASSERT( OC_TTD, 0 ),
1585 OCL_ASSERT( OC_TTO, 0 ),
1586 OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_date ),
1587 OCL_VAR ( OC_UINT16, 1, &_date_fract ),
1588 OCL_NULL( 600 ), ///< TextEffects
1589 OCL_VAR ( OC_UINT32, 2, &_random.state ),
1591 OCL_ASSERT( OC_TTD, 0x264 ),
1592 OCL_ASSERT( OC_TTO, 0x264 ),
1594 OCL_CCHUNK( OC_TTD, 70, LoadOldTown ),
1595 OCL_CCHUNK( OC_TTO, 80, LoadOldTown ),
1597 OCL_ASSERT( OC_TTD, 0x1C18 ),
1598 OCL_ASSERT( OC_TTO, 0x1AC4 ),
1600 OCL_CCHUNK( OC_TTD, 5000, LoadOldOrder ),
1601 OCL_CCHUNK( OC_TTO, 3000, LoadOldOrder ),
1603 OCL_ASSERT( OC_TTD, 0x4328 ),
1604 OCL_ASSERT( OC_TTO, 0x3234 ),
1606 OCL_CHUNK( 1, LoadOldAnimTileList ),
1607 OCL_NULL( 4 ), ///< old end-of-order-list-pointer, no longer in use
1609 OCL_ASSERT( OC_TTO, 0x3438 ),
1611 OCL_CCHUNK( OC_TTD, 255, LoadOldDepot ),
1612 OCL_CCHUNK( OC_TTO, 252, LoadOldDepot ),
1614 OCL_ASSERT( OC_TTD, 0x4B26 ),
1615 OCL_ASSERT( OC_TTO, 0x3A20 ),
1617 OCL_NULL( 4 ), ///< town counter, no longer in use
1618 OCL_NULL( 2 ), ///< timer_counter, no longer in use
1619 OCL_NULL( 2 ), ///< land_code, no longer in use
1621 OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ),
1622 OCL_VAR ( OC_UINT16, 1, &_tick_counter ),
1623 OCL_VAR ( OC_TILE, 1, &_cur_tileloop_tile ),
1625 OCL_ASSERT( OC_TTO, 0x3A2E ),
1627 OCL_CNULL( OC_TTO, 48 * 6 ), ///< prices
1628 OCL_CNULL( OC_TTD, 49 * 6 ), ///< prices
1630 OCL_ASSERT( OC_TTO, 0x3B4E ),
1632 OCL_CNULL( OC_TTO, 11 * 8 ), ///< cargo payment rates
1633 OCL_CNULL( OC_TTD, 12 * 8 ), ///< cargo payment rates
1635 OCL_ASSERT( OC_TTD, 0x4CBA ),
1636 OCL_ASSERT( OC_TTO, 0x3BA6 ),
1638 OCL_CHUNK( 1, LoadOldMapPart1 ),
1640 OCL_ASSERT( OC_TTD, 0x48CBA ),
1641 OCL_ASSERT( OC_TTO, 0x23BA6 ),
1643 OCL_CCHUNK( OC_TTD, 250, LoadOldStation ),
1644 OCL_CCHUNK( OC_TTO, 200, LoadOldStation ),
1646 OCL_ASSERT( OC_TTO, 0x29E16 ),
1648 OCL_CCHUNK( OC_TTD, 90, LoadOldIndustry ),
1649 OCL_CCHUNK( OC_TTO, 100, LoadOldIndustry ),
1651 OCL_ASSERT( OC_TTO, 0x2ADB6 ),
1653 OCL_CHUNK( 8, LoadOldCompany ),
1655 OCL_ASSERT( OC_TTD, 0x547F2 ),
1656 OCL_ASSERT( OC_TTO, 0x2C746 ),
1658 OCL_CCHUNK( OC_TTD, 850, LoadOldVehicle ),
1659 OCL_CCHUNK( OC_TTO, 800, LoadOldVehicle ),
1661 OCL_ASSERT( OC_TTD, 0x6F0F2 ),
1662 OCL_ASSERT( OC_TTO, 0x45746 ),
1664 OCL_VAR ( OC_TTD | OC_UINT8 | OC_DEREFERENCE_POINTER, 32 * 500, &_old_name_array ),
1665 OCL_VAR ( OC_TTO | OC_UINT8 | OC_DEREFERENCE_POINTER, 24 * 200, &_old_name_array ),
1667 OCL_ASSERT( OC_TTO, 0x46A06 ),
1669 OCL_NULL( 0x2000 ), ///< Old hash-table, no longer in use
1671 OCL_CHUNK( 40, LoadOldSign ),
1673 OCL_ASSERT( OC_TTO, 0x48C36 ),
1675 OCL_CCHUNK( OC_TTD, 256, LoadOldEngine ),
1676 OCL_CCHUNK( OC_TTO, 103, LoadOldEngine ),
1678 OCL_ASSERT( OC_TTO, 0x496AC ),
1680 OCL_NULL ( 2 ), // _vehicle_id_ctr_day
1682 OCL_CHUNK( 8, LoadOldSubsidy ),
1684 OCL_ASSERT( OC_TTO, 0x496CE ),
1686 OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_next_competitor_start ),
1688 OCL_CNULL( OC_TTO, 2 ), ///< available monorail bitmask
1690 OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_x ),
1691 OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_y ),
1692 OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_saved_scrollpos_zoom ),
1694 OCL_NULL( 4 ), ///< max_loan
1695 OCL_VAR ( OC_FILE_U32 | OC_VAR_I64, 1, &_economy.old_max_loan_unround ),
1696 OCL_VAR ( OC_INT16, 1, &_economy.fluct ),
1698 OCL_VAR ( OC_UINT16, 1, &_disaster_delay ),
1700 OCL_ASSERT( OC_TTO, 0x496E4 ),
1702 OCL_CNULL( OC_TTD, 144 ), ///< cargo-stuff
1704 OCL_CCHUNK( OC_TTD, 256, LoadOldEngineName ),
1706 OCL_CNULL( OC_TTD, 144 ), ///< AI cargo-stuff
1707 OCL_NULL( 2 ), ///< Company indexes of companies, no longer in use
1708 OCL_NULL( 1 ), ///< Station tick counter, no longer in use
1710 OCL_VAR ( OC_UINT8, 1, &_settings_game.locale.currency ),
1711 OCL_VAR ( OC_UINT8, 1, &_old_units ),
1712 OCL_VAR ( OC_FILE_U8 | OC_VAR_U32, 1, &_cur_company_tick_index ),
1714 OCL_NULL( 2 ), ///< Date stuff, calculated automatically
1715 OCL_NULL( 8 ), ///< Company colours, calculated automatically
1717 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount ),
1718 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount_pr ),
1719 OCL_VAR ( OC_UINT8, 1, &_economy.interest_rate ),
1720 OCL_NULL( 1 ), // available airports
1721 OCL_VAR ( OC_UINT8, 1, &_settings_game.vehicle.road_side ),
1722 OCL_VAR ( OC_UINT8, 1, &_settings_game.game_creation.town_name ),
1724 OCL_CHUNK( 1, LoadOldGameDifficulty ),
1726 OCL_ASSERT( OC_TTD, 0x77130 ),
1728 OCL_VAR ( OC_UINT8, 1, &_old_diff_level ),
1730 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.landscape ),
1731 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_trees_tick_ctr ),
1733 OCL_CNULL( OC_TTD, 1 ), ///< Custom vehicle types yes/no, no longer used
1734 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.snow_line_height ),
1736 OCL_CNULL( OC_TTD, 32 ), ///< new_industry_randtable, no longer used (because of new design)
1737 OCL_CNULL( OC_TTD, 36 ), ///< cargo-stuff
1739 OCL_ASSERT( OC_TTD, 0x77179 ),
1740 OCL_ASSERT( OC_TTO, 0x4971D ),
1742 OCL_CHUNK( 1, LoadOldMapPart2 ),
1744 OCL_ASSERT( OC_TTD, 0x97179 ),
1745 OCL_ASSERT( OC_TTO, 0x6971D ),
1747 /* Below any (if available) extra chunks from TTDPatch can follow */
1748 OCL_CHUNK(1, LoadTTDPatchExtraChunks),
1750 OCL_END()
1753 bool LoadTTDMain(LoadgameState *ls)
1755 DEBUG(oldloader, 3, "Reading main chunk...");
1757 _read_ttdpatch_flags = false;
1759 /* Load the biggest chunk */
1760 SmallStackSafeStackAlloc<byte, OLD_MAP_SIZE * 2> map3;
1761 _old_map3 = map3.data;
1762 _old_vehicle_names = NULL;
1763 try {
1764 if (!LoadChunk(ls, NULL, main_chunk)) {
1765 DEBUG(oldloader, 0, "Loading failed");
1766 free(_old_vehicle_names);
1767 return false;
1769 } catch (...) {
1770 free(_old_vehicle_names);
1771 throw;
1774 DEBUG(oldloader, 3, "Done, converting game data...");
1776 FixTTDMapArray();
1777 FixTTDDepots();
1779 /* Fix some general stuff */
1780 _settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
1782 /* Fix the game to be compatible with OpenTTD */
1783 FixOldTowns();
1784 FixOldVehicles();
1786 /* We have a new difficulty setting */
1787 _settings_game.difficulty.town_council_tolerance = Clamp(_old_diff_level, 0, 2);
1789 DEBUG(oldloader, 3, "Finished converting game data");
1790 DEBUG(oldloader, 1, "TTD(Patch) savegame successfully converted");
1792 free(_old_vehicle_names);
1794 return true;
1797 bool LoadTTOMain(LoadgameState *ls)
1799 DEBUG(oldloader, 3, "Reading main chunk...");
1801 _read_ttdpatch_flags = false;
1803 SmallStackSafeStackAlloc<byte, 103 * sizeof(Engine)> engines; // we don't want to call Engine constructor here
1804 _old_engines = (Engine *)engines.data;
1805 SmallStackSafeStackAlloc<StringID, 800> vehnames;
1806 _old_vehicle_names = vehnames.data;
1808 /* Load the biggest chunk */
1809 if (!LoadChunk(ls, NULL, main_chunk)) {
1810 DEBUG(oldloader, 0, "Loading failed");
1811 return false;
1813 DEBUG(oldloader, 3, "Done, converting game data...");
1815 if (_settings_game.game_creation.town_name != 0) _settings_game.game_creation.town_name++;
1817 _settings_game.game_creation.landscape = 0;
1818 _trees_tick_ctr = 0xFF;
1820 if (!FixTTOMapArray() || !FixTTOEngines()) {
1821 DEBUG(oldloader, 0, "Conversion failed");
1822 return false;
1825 FixOldTowns();
1826 FixOldVehicles();
1827 FixTTOCompanies();
1829 /* We have a new difficulty setting */
1830 _settings_game.difficulty.town_council_tolerance = Clamp(_old_diff_level, 0, 2);
1832 /* SVXConverter about cargo payment rates correction:
1833 * "increase them to compensate for the faster time advance in TTD compared to TTO
1834 * which otherwise would cause much less income while the annual running costs of
1835 * the vehicles stay the same" */
1836 _economy.inflation_payment = min(_economy.inflation_payment * 124 / 74, MAX_INFLATION);
1838 DEBUG(oldloader, 3, "Finished converting game data");
1839 DEBUG(oldloader, 1, "TTO savegame successfully converted");
1841 return true;