(svn r28004) -Update from Eints:
[openttd.git] / src / saveload / oldloader_sl.cpp
blob0c571668162528f865822e617ee091f8ad3a5149
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_U16, 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_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 YearMonthDay ymd;
853 ConvertDateToYMD(_date, &ymd);
854 i->last_prod_year = ymd.year;
856 i->random_colour = RemapTTOColour(i->random_colour);
859 Industry::IncIndustryTypeCount(i->type);
860 } else {
861 delete i;
864 return true;
867 static CompanyID _current_company_id;
868 static int32 _old_yearly;
870 static const OldChunks _company_yearly_chunk[] = {
871 OCL_VAR( OC_INT32, 1, &_old_yearly ),
872 OCL_END()
875 static bool LoadOldCompanyYearly(LoadgameState *ls, int num)
877 Company *c = Company::Get(_current_company_id);
879 for (uint i = 0; i < 13; i++) {
880 if (_savegame_type == SGT_TTO && i == 6) {
881 _old_yearly = 0; // property maintenance
882 } else {
883 if (!LoadChunk(ls, NULL, _company_yearly_chunk)) return false;
886 c->yearly_expenses[num][i] = _old_yearly;
889 return true;
892 static const OldChunks _company_economy_chunk[] = {
893 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, income ),
894 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, expenses ),
895 OCL_SVAR( OC_INT32, CompanyEconomyEntry, delivered_cargo[NUM_CARGO - 1] ),
896 OCL_SVAR( OC_INT32, CompanyEconomyEntry, performance_history ),
897 OCL_SVAR( OC_TTD | OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, company_value ),
899 OCL_END()
902 static bool LoadOldCompanyEconomy(LoadgameState *ls, int num)
904 Company *c = Company::Get(_current_company_id);
906 if (!LoadChunk(ls, &c->cur_economy, _company_economy_chunk)) return false;
908 /* Don't ask, but the number in TTD(Patch) are inversed to OpenTTD */
909 c->cur_economy.income = -c->cur_economy.income;
910 c->cur_economy.expenses = -c->cur_economy.expenses;
912 for (uint i = 0; i < 24; i++) {
913 if (!LoadChunk(ls, &c->old_economy[i], _company_economy_chunk)) return false;
915 c->old_economy[i].income = -c->old_economy[i].income;
916 c->old_economy[i].expenses = -c->old_economy[i].expenses;
919 return true;
922 static const OldChunks _company_chunk[] = {
923 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
924 OCL_SVAR( OC_UINT32, Company, name_2 ),
925 OCL_SVAR( OC_UINT32, Company, face ),
926 OCL_VAR ( OC_UINT16, 1, &_old_string_id_2 ),
927 OCL_SVAR( OC_UINT32, Company, president_name_2 ),
929 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, money ),
930 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, current_loan ),
932 OCL_SVAR( OC_UINT8, Company, colour ),
933 OCL_SVAR( OC_UINT8, Company, money_fraction ),
934 OCL_SVAR( OC_UINT8, Company, months_of_bankruptcy ),
935 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Company, bankrupt_asked ),
936 OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Company, bankrupt_value ),
937 OCL_SVAR( OC_UINT16, Company, bankrupt_timeout ),
939 OCL_CNULL( OC_TTD, 4 ), // cargo_types
940 OCL_CNULL( OC_TTO, 2 ), // cargo_types
942 OCL_CHUNK( 3, LoadOldCompanyYearly ),
943 OCL_CHUNK( 1, LoadOldCompanyEconomy ),
945 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Company, inaugurated_year),
946 OCL_SVAR( OC_TILE, Company, last_build_coordinate ),
947 OCL_SVAR( OC_UINT8, Company, num_valid_stat_ent ),
949 OCL_NULL( 230 ), // Old AI
951 OCL_SVAR( OC_UINT8, Company, block_preview ),
952 OCL_CNULL( OC_TTD, 1 ), // Old AI
953 OCL_SVAR( OC_TTD | OC_UINT8, Company, avail_railtypes ),
954 OCL_SVAR( OC_TILE, Company, location_of_HQ ),
955 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[0] ),
956 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[1] ),
957 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[2] ),
958 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[3] ),
960 OCL_CNULL( OC_TTD, 8 ), ///< junk at end of chunk
962 OCL_END()
965 static bool LoadOldCompany(LoadgameState *ls, int num)
967 Company *c = new (num) Company();
969 _current_company_id = (CompanyID)num;
971 if (!LoadChunk(ls, c, _company_chunk)) return false;
973 if (_old_string_id == 0) {
974 delete c;
975 return true;
978 if (_savegame_type == SGT_TTO) {
979 /* adjust manager's face */
980 if (HasBit(c->face, 27) && GB(c->face, 26, 1) == GB(c->face, 19, 1)) {
981 /* if face would be black in TTD, adjust tie colour and thereby face colour */
982 ClrBit(c->face, 27);
985 /* Company name */
986 if (_old_string_id == 0 || _old_string_id == 0x4C00) {
987 _old_string_id = STR_SV_UNNAMED; // "Unnamed"
988 } else if (GB(_old_string_id, 8, 8) == 0x52) {
989 _old_string_id += 0x2A00; // Custom name
990 } else {
991 _old_string_id = RemapOldStringID(_old_string_id += 0x240D); // Automatic name
993 c->name_1 = _old_string_id;
995 /* Manager name */
996 switch (_old_string_id_2) {
997 case 0x4CDA: _old_string_id_2 = SPECSTR_PRESIDENT_NAME; break; // automatic name
998 case 0x0006: _old_string_id_2 = STR_SV_EMPTY; break; // empty name
999 default: _old_string_id_2 = _old_string_id_2 + 0x2A00; break; // custom name
1001 c->president_name_1 = _old_string_id_2;
1003 c->colour = RemapTTOColour(c->colour);
1005 if (num != 0) c->is_ai = true;
1006 } else {
1007 c->name_1 = RemapOldStringID(_old_string_id);
1008 c->president_name_1 = RemapOldStringID(_old_string_id_2);
1010 if (num == 0) {
1011 /* If the first company has no name, make sure we call it UNNAMED */
1012 if (c->name_1 == 0) {
1013 c->name_1 = STR_SV_UNNAMED;
1015 } else {
1016 /* Beside some multiplayer maps (1 on 1), which we don't official support,
1017 * all other companies are an AI.. mark them as such */
1018 c->is_ai = true;
1021 /* Sometimes it is better to not ask.. in old scenarios, the money
1022 * was always 893288 pounds. In the newer versions this is correct,
1023 * but correct for those oldies
1024 * Ps: this also means that if you had exact 893288 pounds, you will go back
1025 * to 100000.. this is a very VERY small chance ;) */
1026 if (c->money == 893288) c->money = c->current_loan = 100000;
1029 _company_colours[num] = (Colours)c->colour;
1030 c->inaugurated_year -= ORIGINAL_BASE_YEAR;
1032 return true;
1035 static uint32 _old_order_ptr;
1036 static uint16 _old_next_ptr;
1037 static VehicleID _current_vehicle_id;
1039 static const OldChunks vehicle_train_chunk[] = {
1040 OCL_SVAR( OC_UINT8, Train, track ),
1041 OCL_SVAR( OC_UINT8, Train, force_proceed ),
1042 OCL_SVAR( OC_UINT16, Train, crash_anim_pos ),
1043 OCL_SVAR( OC_UINT8, Train, railtype ),
1045 OCL_NULL( 5 ), ///< Junk
1047 OCL_END()
1050 static const OldChunks vehicle_road_chunk[] = {
1051 OCL_SVAR( OC_UINT8, RoadVehicle, state ),
1052 OCL_SVAR( OC_UINT8, RoadVehicle, frame ),
1053 OCL_SVAR( OC_UINT16, RoadVehicle, blocked_ctr ),
1054 OCL_SVAR( OC_UINT8, RoadVehicle, overtaking ),
1055 OCL_SVAR( OC_UINT8, RoadVehicle, overtaking_ctr ),
1056 OCL_SVAR( OC_UINT16, RoadVehicle, crashed_ctr ),
1057 OCL_SVAR( OC_UINT8, RoadVehicle, reverse_ctr ),
1059 OCL_NULL( 1 ), ///< Junk
1061 OCL_END()
1064 static const OldChunks vehicle_ship_chunk[] = {
1065 OCL_SVAR( OC_UINT8, Ship, state ),
1067 OCL_NULL( 9 ), ///< Junk
1069 OCL_END()
1072 static const OldChunks vehicle_air_chunk[] = {
1073 OCL_SVAR( OC_UINT8, Aircraft, pos ),
1074 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Aircraft, targetairport ),
1075 OCL_SVAR( OC_UINT16, Aircraft, crashed_counter ),
1076 OCL_SVAR( OC_UINT8, Aircraft, state ),
1078 OCL_NULL( 5 ), ///< Junk
1080 OCL_END()
1083 static const OldChunks vehicle_effect_chunk[] = {
1084 OCL_SVAR( OC_UINT16, EffectVehicle, animation_state ),
1085 OCL_SVAR( OC_UINT8, EffectVehicle, animation_substate ),
1087 OCL_NULL( 7 ), // Junk
1089 OCL_END()
1092 static const OldChunks vehicle_disaster_chunk[] = {
1093 OCL_SVAR( OC_UINT16, DisasterVehicle, image_override ),
1094 OCL_SVAR( OC_UINT16, DisasterVehicle, big_ufo_destroyer_target ),
1096 OCL_NULL( 6 ), ///< Junk
1098 OCL_END()
1101 static const OldChunks vehicle_empty_chunk[] = {
1102 OCL_NULL( 10 ), ///< Junk
1104 OCL_END()
1107 static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
1109 Vehicle *v = Vehicle::GetIfValid(_current_vehicle_id);
1110 uint temp = ls->total_read;
1111 bool res;
1113 if (v == NULL) {
1114 res = LoadChunk(ls, NULL, vehicle_empty_chunk);
1115 } else {
1116 switch (v->type) {
1117 default: SlErrorCorrupt("Invalid vehicle type");
1118 case VEH_TRAIN : res = LoadChunk(ls, v, vehicle_train_chunk); break;
1119 case VEH_ROAD : res = LoadChunk(ls, v, vehicle_road_chunk); break;
1120 case VEH_SHIP : res = LoadChunk(ls, v, vehicle_ship_chunk); break;
1121 case VEH_AIRCRAFT: res = LoadChunk(ls, v, vehicle_air_chunk); break;
1122 case VEH_EFFECT : res = LoadChunk(ls, v, vehicle_effect_chunk); break;
1123 case VEH_DISASTER: res = LoadChunk(ls, v, vehicle_disaster_chunk); break;
1127 /* This chunk size should always be 10 bytes */
1128 if (ls->total_read - temp != 10) {
1129 DEBUG(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
1130 return false;
1133 return res;
1136 static uint16 _cargo_count;
1138 static const OldChunks vehicle_chunk[] = {
1139 OCL_SVAR( OC_UINT8, Vehicle, subtype ),
1141 OCL_NULL( 2 ), ///< Hash, calculated automatically
1142 OCL_NULL( 2 ), ///< Index, calculated automatically
1144 OCL_VAR ( OC_UINT32, 1, &_old_order_ptr ),
1145 OCL_VAR ( OC_UINT16, 1, &_old_order ),
1147 OCL_NULL ( 1 ), ///< num_orders, now calculated
1148 OCL_SVAR( OC_UINT8, Vehicle, cur_implicit_order_index ),
1149 OCL_SVAR( OC_TILE, Vehicle, dest_tile ),
1150 OCL_SVAR( OC_UINT16, Vehicle, load_unload_ticks ),
1151 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
1152 OCL_SVAR( OC_UINT16, Vehicle, service_interval ),
1153 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, last_station_visited ),
1154 OCL_SVAR( OC_TTD | OC_UINT8, Vehicle, tick_counter ),
1155 OCL_CNULL( OC_TTD, 2 ), ///< max_speed, now it is calculated.
1156 OCL_CNULL( OC_TTO, 1 ), ///< max_speed, now it is calculated.
1158 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, x_pos ),
1159 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ),
1160 OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, z_pos ),
1161 OCL_SVAR( OC_UINT8, Vehicle, direction ),
1162 OCL_NULL( 2 ), ///< x_offs and y_offs, calculated automatically
1163 OCL_NULL( 2 ), ///< x_extent and y_extent, calculated automatically
1164 OCL_NULL( 1 ), ///< z_extent, calculated automatically
1166 OCL_SVAR( OC_UINT8, Vehicle, owner ),
1167 OCL_SVAR( OC_TILE, Vehicle, tile ),
1168 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, sprite_seq.seq[0].sprite ),
1170 OCL_NULL( 8 ), ///< Vehicle sprite box, calculated automatically
1172 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Vehicle, vehstatus ),
1173 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cur_speed ),
1174 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cur_speed ),
1175 OCL_SVAR( OC_UINT8, Vehicle, subspeed ),
1176 OCL_SVAR( OC_UINT8, Vehicle, acceleration ),
1177 OCL_SVAR( OC_UINT8, Vehicle, progress ),
1179 OCL_SVAR( OC_UINT8, Vehicle, cargo_type ),
1180 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cargo_cap ),
1181 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cargo_cap ),
1182 OCL_VAR ( OC_TTD | OC_UINT16, 1, &_cargo_count ),
1183 OCL_VAR ( OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_cargo_count ),
1184 OCL_VAR ( OC_UINT8, 1, &_cargo_source ),
1185 OCL_VAR ( OC_UINT8, 1, &_cargo_days ),
1187 OCL_SVAR( OC_TTO | OC_UINT8, Vehicle, tick_counter ),
1189 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, age ),
1190 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, max_age ),
1191 OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, build_year ),
1192 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, unitnumber ),
1194 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, engine_type ),
1195 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, engine_type ),
1197 OCL_SVAR( OC_UINT8, Vehicle, spritenum ),
1198 OCL_SVAR( OC_UINT8, Vehicle, day_counter ),
1200 OCL_SVAR( OC_UINT8, Vehicle, breakdowns_since_last_service ),
1201 OCL_SVAR( OC_UINT8, Vehicle, breakdown_ctr ),
1202 OCL_SVAR( OC_UINT8, Vehicle, breakdown_delay ),
1203 OCL_SVAR( OC_UINT8, Vehicle, breakdown_chance ),
1205 OCL_CNULL( OC_TTO, 1 ),
1207 OCL_SVAR( OC_UINT16, Vehicle, reliability ),
1208 OCL_SVAR( OC_UINT16, Vehicle, reliability_spd_dec ),
1210 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_this_year ),
1211 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_last_year ),
1213 OCL_VAR ( OC_UINT16, 1, &_old_next_ptr ),
1215 OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Vehicle, value ),
1217 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
1219 OCL_CHUNK( 1, LoadOldVehicleUnion ),
1221 OCL_CNULL( OC_TTO, 24 ), ///< junk
1222 OCL_CNULL( OC_TTD, 20 ), ///< junk at end of struct (TTDPatch has some data in it)
1224 OCL_END()
1228 * Load the vehicles of an old style savegame.
1229 * @param ls State (buffer) of the currently loaded game.
1230 * @param num The number of vehicles to load.
1231 * @return True iff loading went without problems.
1233 bool LoadOldVehicle(LoadgameState *ls, int num)
1235 /* Read the TTDPatch flags, because we need some info from it */
1236 ReadTTDPatchFlags();
1238 for (uint i = 0; i < _old_vehicle_multiplier; i++) {
1239 _current_vehicle_id = num * _old_vehicle_multiplier + i;
1241 Vehicle *v;
1243 if (_savegame_type == SGT_TTO) {
1244 uint type = ReadByte(ls);
1245 switch (type) {
1246 default: return false;
1247 case 0x00 /* VEH_INVALID */: v = NULL; break;
1248 case 0x25 /* MONORAIL */:
1249 case 0x20 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break;
1250 case 0x21 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break;
1251 case 0x22 /* VEH_SHIP */: v = new (_current_vehicle_id) Ship(); break;
1252 case 0x23 /* VEH_AIRCRAFT */: v = new (_current_vehicle_id) Aircraft(); break;
1253 case 0x24 /* VEH_EFFECT */: v = new (_current_vehicle_id) EffectVehicle(); break;
1254 case 0x26 /* VEH_DISASTER */: v = new (_current_vehicle_id) DisasterVehicle(); break;
1257 if (!LoadChunk(ls, v, vehicle_chunk)) return false;
1258 if (v == NULL) continue;
1259 v->refit_cap = v->cargo_cap;
1261 SpriteID sprite = v->sprite_seq.seq[0].sprite;
1262 /* no need to override other sprites */
1263 if (IsInsideMM(sprite, 1460, 1465)) {
1264 sprite += 580; // aircraft smoke puff
1265 } else if (IsInsideMM(sprite, 2096, 2115)) {
1266 sprite += 977; // special effects part 1
1267 } else if (IsInsideMM(sprite, 2396, 2436)) {
1268 sprite += 1305; // special effects part 2
1269 } else if (IsInsideMM(sprite, 2516, 2539)) {
1270 sprite += 1385; // rotor or disaster-related vehicles
1272 v->sprite_seq.seq[0].sprite = sprite;
1274 switch (v->type) {
1275 case VEH_TRAIN: {
1276 static const byte spriteset_rail[] = {
1277 0, 2, 4, 4, 8, 10, 12, 14, 16, 18, 20, 22, 40, 42, 44, 46,
1278 48, 52, 54, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 120, 122,
1279 124, 126, 128, 130, 132, 134, 136, 138, 140
1281 if (v->spritenum / 2 >= lengthof(spriteset_rail)) return false;
1282 v->spritenum = spriteset_rail[v->spritenum / 2]; // adjust railway sprite set offset
1283 Train::From(v)->railtype = type == 0x25 ? 1 : 0; // monorail / rail
1284 break;
1287 case VEH_ROAD:
1288 if (v->spritenum >= 22) v->spritenum += 12;
1289 break;
1291 case VEH_SHIP:
1292 v->spritenum += 2;
1294 switch (v->spritenum) {
1295 case 2: // oil tanker && cargo type != oil
1296 if (v->cargo_type != CT_OIL) v->spritenum = 0; // make it a coal/goods ship
1297 break;
1298 case 4: // passenger ship && cargo type == mail
1299 if (v->cargo_type == CT_MAIL) v->spritenum = 0; // make it a mail ship
1300 break;
1301 default:
1302 break;
1304 break;
1306 default:
1307 break;
1310 switch (_old_string_id) {
1311 case 0x0000: break; // empty (invalid vehicles)
1312 case 0x0006: _old_string_id = STR_SV_EMPTY; break; // empty (special vehicles)
1313 case 0x8495: _old_string_id = STR_SV_TRAIN_NAME; break; // "Train X"
1314 case 0x8842: _old_string_id = STR_SV_ROAD_VEHICLE_NAME; break; // "Road Vehicle X"
1315 case 0x8C3B: _old_string_id = STR_SV_SHIP_NAME; break; // "Ship X"
1316 case 0x9047: _old_string_id = STR_SV_AIRCRAFT_NAME; break; // "Aircraft X"
1317 default: _old_string_id += 0x2A00; break; // custom name
1320 _old_vehicle_names[_current_vehicle_id] = _old_string_id;
1321 } else {
1322 /* Read the vehicle type and allocate the right vehicle */
1323 switch (ReadByte(ls)) {
1324 default: SlErrorCorrupt("Invalid vehicle type");
1325 case 0x00 /* VEH_INVALID */: v = NULL; break;
1326 case 0x10 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break;
1327 case 0x11 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break;
1328 case 0x12 /* VEH_SHIP */: v = new (_current_vehicle_id) Ship(); break;
1329 case 0x13 /* VEH_AIRCRAFT*/: v = new (_current_vehicle_id) Aircraft(); break;
1330 case 0x14 /* VEH_EFFECT */: v = new (_current_vehicle_id) EffectVehicle(); break;
1331 case 0x15 /* VEH_DISASTER*/: v = new (_current_vehicle_id) DisasterVehicle(); break;
1334 if (!LoadChunk(ls, v, vehicle_chunk)) return false;
1335 if (v == NULL) continue;
1337 _old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
1339 /* This should be consistent, else we have a big problem... */
1340 if (v->index != _current_vehicle_id) {
1341 DEBUG(oldloader, 0, "Loading failed - vehicle-array is invalid");
1342 return false;
1346 if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
1347 uint max = _savegame_type == SGT_TTO ? 3000 : 5000;
1348 uint old_id = RemapOrderIndex(_old_order_ptr);
1349 if (old_id < max) v->orders.old = Order::Get(old_id); // don't accept orders > max number of orders
1351 v->current_order.AssignOrder(UnpackOldOrder(_old_order));
1353 v->next = (Vehicle *)(size_t)_old_next_ptr;
1355 if (_cargo_count != 0 && CargoPacket::CanAllocateItem()) {
1356 StationID source = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
1357 TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : 0;
1358 v->cargo.Append(new CargoPacket(_cargo_count, _cargo_days, source, source_xy, source_xy));
1362 return true;
1365 static const OldChunks sign_chunk[] = {
1366 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
1367 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, x ),
1368 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, y ),
1369 OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, Sign, z ),
1371 OCL_NULL( 6 ), ///< Width of sign, no longer in use
1373 OCL_END()
1376 static bool LoadOldSign(LoadgameState *ls, int num)
1378 Sign *si = new (num) Sign();
1379 if (!LoadChunk(ls, si, sign_chunk)) return false;
1381 if (_old_string_id != 0) {
1382 if (_savegame_type == SGT_TTO) {
1383 if (_old_string_id != 0x140A) si->name = CopyFromOldName(_old_string_id + 0x2A00);
1384 } else {
1385 si->name = CopyFromOldName(RemapOldStringID(_old_string_id));
1387 si->owner = OWNER_NONE;
1388 } else {
1389 delete si;
1392 return true;
1395 static const OldChunks engine_chunk[] = {
1396 OCL_SVAR( OC_UINT16, Engine, company_avail ),
1397 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, intro_date ),
1398 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, age ),
1399 OCL_SVAR( OC_UINT16, Engine, reliability ),
1400 OCL_SVAR( OC_UINT16, Engine, reliability_spd_dec ),
1401 OCL_SVAR( OC_UINT16, Engine, reliability_start ),
1402 OCL_SVAR( OC_UINT16, Engine, reliability_max ),
1403 OCL_SVAR( OC_UINT16, Engine, reliability_final ),
1404 OCL_SVAR( OC_UINT16, Engine, duration_phase_1 ),
1405 OCL_SVAR( OC_UINT16, Engine, duration_phase_2 ),
1406 OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
1408 OCL_NULL( 1 ), // lifelength
1409 OCL_SVAR( OC_UINT8, Engine, flags ),
1410 OCL_NULL( 1 ), // preview_company_rank
1411 OCL_SVAR( OC_UINT8, Engine, preview_wait ),
1413 OCL_CNULL( OC_TTD, 2 ), ///< railtype + junk
1415 OCL_END()
1418 static bool LoadOldEngine(LoadgameState *ls, int num)
1420 Engine *e = _savegame_type == SGT_TTO ? &_old_engines[num] : GetTempDataEngine(num);
1421 return LoadChunk(ls, e, engine_chunk);
1424 static bool LoadOldEngineName(LoadgameState *ls, int num)
1426 Engine *e = GetTempDataEngine(num);
1427 e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
1428 return true;
1431 static const OldChunks subsidy_chunk[] = {
1432 OCL_SVAR( OC_UINT8, Subsidy, cargo_type ),
1433 OCL_SVAR( OC_UINT8, Subsidy, remaining ),
1434 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, src ),
1435 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, dst ),
1437 OCL_END()
1440 static bool LoadOldSubsidy(LoadgameState *ls, int num)
1442 Subsidy *s = new (num) Subsidy();
1443 bool ret = LoadChunk(ls, s, subsidy_chunk);
1444 if (s->cargo_type == CT_INVALID) delete s;
1445 return ret;
1448 static const OldChunks game_difficulty_chunk[] = {
1449 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, max_no_competitors ),
1450 OCL_NULL( 2), // competitor_start_time
1451 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, number_towns ),
1452 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, industry_density ),
1453 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, DifficultySettings, max_loan ),
1454 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, initial_interest ),
1455 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, vehicle_costs ),
1456 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, competitor_speed ),
1457 OCL_NULL( 2), // competitor_intelligence
1458 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, vehicle_breakdowns ),
1459 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, subsidy_multiplier ),
1460 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, construction_cost ),
1461 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, terrain_type ),
1462 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, quantity_sea_lakes ),
1463 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, economy ),
1464 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, line_reverse_mode ),
1465 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, disasters ),
1466 OCL_END()
1469 static bool LoadOldGameDifficulty(LoadgameState *ls, int num)
1471 bool ret = LoadChunk(ls, &_settings_game.difficulty, game_difficulty_chunk);
1472 _settings_game.difficulty.max_loan *= 1000;
1473 return ret;
1477 static bool LoadOldMapPart1(LoadgameState *ls, int num)
1479 if (_savegame_type == SGT_TTO) {
1480 MemSetT(_m, 0, OLD_MAP_SIZE);
1481 MemSetT(_me, 0, OLD_MAP_SIZE);
1484 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
1485 _m[i].m1 = ReadByte(ls);
1487 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
1488 _m[i].m2 = ReadByte(ls);
1491 if (_savegame_type != SGT_TTO) {
1492 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
1493 _old_map3[i * 2] = ReadByte(ls);
1494 _old_map3[i * 2 + 1] = ReadByte(ls);
1496 for (uint i = 0; i < OLD_MAP_SIZE / 4; i++) {
1497 byte b = ReadByte(ls);
1498 _me[i * 4 + 0].m6 = GB(b, 0, 2);
1499 _me[i * 4 + 1].m6 = GB(b, 2, 2);
1500 _me[i * 4 + 2].m6 = GB(b, 4, 2);
1501 _me[i * 4 + 3].m6 = GB(b, 6, 2);
1505 return true;
1508 static bool LoadOldMapPart2(LoadgameState *ls, int num)
1510 uint i;
1512 for (i = 0; i < OLD_MAP_SIZE; i++) {
1513 _m[i].type = ReadByte(ls);
1515 for (i = 0; i < OLD_MAP_SIZE; i++) {
1516 _m[i].m5 = ReadByte(ls);
1519 return true;
1522 static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num)
1524 ReadTTDPatchFlags();
1526 DEBUG(oldloader, 2, "Found %d extra chunk(s)", _old_extra_chunk_nums);
1528 for (int i = 0; i != _old_extra_chunk_nums; i++) {
1529 uint16 id = ReadUint16(ls);
1530 uint32 len = ReadUint32(ls);
1532 switch (id) {
1533 /* List of GRFIDs, used in the savegame. 0x8004 is the new ID
1534 * They are saved in a 'GRFID:4 active:1' format, 5 bytes for each entry */
1535 case 0x2:
1536 case 0x8004: {
1537 /* Skip the first element: TTDP hack for the Action D special variables (FFFF0000 01) */
1538 ReadUint32(ls); ReadByte(ls); len -= 5;
1540 ClearGRFConfigList(&_grfconfig);
1541 while (len != 0) {
1542 uint32 grfid = ReadUint32(ls);
1544 if (ReadByte(ls) == 1) {
1545 GRFConfig *c = new GRFConfig("TTDP game, no information");
1546 c->ident.grfid = grfid;
1548 AppendToGRFConfigList(&_grfconfig, c);
1549 DEBUG(oldloader, 3, "TTDPatch game using GRF file with GRFID %0X", BSWAP32(c->ident.grfid));
1551 len -= 5;
1554 /* Append static NewGRF configuration */
1555 AppendStaticGRFConfigs(&_grfconfig);
1556 break;
1559 /* TTDPatch version and configuration */
1560 case 0x3:
1561 _ttdp_version = ReadUint32(ls);
1562 DEBUG(oldloader, 3, "Game saved with TTDPatch version %d.%d.%d r%d",
1563 GB(_ttdp_version, 24, 8), GB(_ttdp_version, 20, 4), GB(_ttdp_version, 16, 4), GB(_ttdp_version, 0, 16));
1564 len -= 4;
1565 while (len-- != 0) ReadByte(ls); // skip the configuration
1566 break;
1568 default:
1569 DEBUG(oldloader, 4, "Skipping unknown extra chunk %X", id);
1570 while (len-- != 0) ReadByte(ls);
1571 break;
1575 return true;
1578 extern TileIndex _cur_tileloop_tile;
1579 extern uint16 _disaster_delay;
1580 extern byte _trees_tick_ctr;
1581 extern byte _age_cargo_skip_counter; // From misc_sl.cpp
1582 extern uint8 _old_diff_level;
1583 extern uint8 _old_units;
1584 static const OldChunks main_chunk[] = {
1585 OCL_ASSERT( OC_TTD, 0 ),
1586 OCL_ASSERT( OC_TTO, 0 ),
1587 OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_date ),
1588 OCL_VAR ( OC_UINT16, 1, &_date_fract ),
1589 OCL_NULL( 600 ), ///< TextEffects
1590 OCL_VAR ( OC_UINT32, 2, &_random.state ),
1592 OCL_ASSERT( OC_TTD, 0x264 ),
1593 OCL_ASSERT( OC_TTO, 0x264 ),
1595 OCL_CCHUNK( OC_TTD, 70, LoadOldTown ),
1596 OCL_CCHUNK( OC_TTO, 80, LoadOldTown ),
1598 OCL_ASSERT( OC_TTD, 0x1C18 ),
1599 OCL_ASSERT( OC_TTO, 0x1AC4 ),
1601 OCL_CCHUNK( OC_TTD, 5000, LoadOldOrder ),
1602 OCL_CCHUNK( OC_TTO, 3000, LoadOldOrder ),
1604 OCL_ASSERT( OC_TTD, 0x4328 ),
1605 OCL_ASSERT( OC_TTO, 0x3234 ),
1607 OCL_CHUNK( 1, LoadOldAnimTileList ),
1608 OCL_NULL( 4 ), ///< old end-of-order-list-pointer, no longer in use
1610 OCL_ASSERT( OC_TTO, 0x3438 ),
1612 OCL_CCHUNK( OC_TTD, 255, LoadOldDepot ),
1613 OCL_CCHUNK( OC_TTO, 252, LoadOldDepot ),
1615 OCL_ASSERT( OC_TTD, 0x4B26 ),
1616 OCL_ASSERT( OC_TTO, 0x3A20 ),
1618 OCL_NULL( 4 ), ///< town counter, no longer in use
1619 OCL_NULL( 2 ), ///< timer_counter, no longer in use
1620 OCL_NULL( 2 ), ///< land_code, no longer in use
1622 OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ),
1623 OCL_VAR ( OC_UINT16, 1, &_tick_counter ),
1624 OCL_VAR ( OC_TILE, 1, &_cur_tileloop_tile ),
1626 OCL_ASSERT( OC_TTO, 0x3A2E ),
1628 OCL_CNULL( OC_TTO, 48 * 6 ), ///< prices
1629 OCL_CNULL( OC_TTD, 49 * 6 ), ///< prices
1631 OCL_ASSERT( OC_TTO, 0x3B4E ),
1633 OCL_CNULL( OC_TTO, 11 * 8 ), ///< cargo payment rates
1634 OCL_CNULL( OC_TTD, 12 * 8 ), ///< cargo payment rates
1636 OCL_ASSERT( OC_TTD, 0x4CBA ),
1637 OCL_ASSERT( OC_TTO, 0x3BA6 ),
1639 OCL_CHUNK( 1, LoadOldMapPart1 ),
1641 OCL_ASSERT( OC_TTD, 0x48CBA ),
1642 OCL_ASSERT( OC_TTO, 0x23BA6 ),
1644 OCL_CCHUNK( OC_TTD, 250, LoadOldStation ),
1645 OCL_CCHUNK( OC_TTO, 200, LoadOldStation ),
1647 OCL_ASSERT( OC_TTO, 0x29E16 ),
1649 OCL_CCHUNK( OC_TTD, 90, LoadOldIndustry ),
1650 OCL_CCHUNK( OC_TTO, 100, LoadOldIndustry ),
1652 OCL_ASSERT( OC_TTO, 0x2ADB6 ),
1654 OCL_CHUNK( 8, LoadOldCompany ),
1656 OCL_ASSERT( OC_TTD, 0x547F2 ),
1657 OCL_ASSERT( OC_TTO, 0x2C746 ),
1659 OCL_CCHUNK( OC_TTD, 850, LoadOldVehicle ),
1660 OCL_CCHUNK( OC_TTO, 800, LoadOldVehicle ),
1662 OCL_ASSERT( OC_TTD, 0x6F0F2 ),
1663 OCL_ASSERT( OC_TTO, 0x45746 ),
1665 OCL_VAR ( OC_TTD | OC_UINT8 | OC_DEREFERENCE_POINTER, 32 * 500, &_old_name_array ),
1666 OCL_VAR ( OC_TTO | OC_UINT8 | OC_DEREFERENCE_POINTER, 24 * 200, &_old_name_array ),
1668 OCL_ASSERT( OC_TTO, 0x46A06 ),
1670 OCL_NULL( 0x2000 ), ///< Old hash-table, no longer in use
1672 OCL_CHUNK( 40, LoadOldSign ),
1674 OCL_ASSERT( OC_TTO, 0x48C36 ),
1676 OCL_CCHUNK( OC_TTD, 256, LoadOldEngine ),
1677 OCL_CCHUNK( OC_TTO, 103, LoadOldEngine ),
1679 OCL_ASSERT( OC_TTO, 0x496AC ),
1681 OCL_NULL ( 2 ), // _vehicle_id_ctr_day
1683 OCL_CHUNK( 8, LoadOldSubsidy ),
1685 OCL_ASSERT( OC_TTO, 0x496CE ),
1687 OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_next_competitor_start ),
1689 OCL_CNULL( OC_TTO, 2 ), ///< available monorail bitmask
1691 OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_x ),
1692 OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_y ),
1693 OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_saved_scrollpos_zoom ),
1695 OCL_NULL( 4 ), ///< max_loan
1696 OCL_VAR ( OC_FILE_U32 | OC_VAR_I64, 1, &_economy.old_max_loan_unround ),
1697 OCL_VAR ( OC_INT16, 1, &_economy.fluct ),
1699 OCL_VAR ( OC_UINT16, 1, &_disaster_delay ),
1701 OCL_ASSERT( OC_TTO, 0x496E4 ),
1703 OCL_CNULL( OC_TTD, 144 ), ///< cargo-stuff
1705 OCL_CCHUNK( OC_TTD, 256, LoadOldEngineName ),
1707 OCL_CNULL( OC_TTD, 144 ), ///< AI cargo-stuff
1708 OCL_NULL( 2 ), ///< Company indexes of companies, no longer in use
1709 OCL_NULL( 1 ), ///< Station tick counter, no longer in use
1711 OCL_VAR ( OC_UINT8, 1, &_settings_game.locale.currency ),
1712 OCL_VAR ( OC_UINT8, 1, &_old_units ),
1713 OCL_VAR ( OC_FILE_U8 | OC_VAR_U32, 1, &_cur_company_tick_index ),
1715 OCL_NULL( 2 ), ///< Date stuff, calculated automatically
1716 OCL_NULL( 8 ), ///< Company colours, calculated automatically
1718 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount ),
1719 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount_pr ),
1720 OCL_VAR ( OC_UINT8, 1, &_economy.interest_rate ),
1721 OCL_NULL( 1 ), // available airports
1722 OCL_VAR ( OC_UINT8, 1, &_settings_game.vehicle.road_side ),
1723 OCL_VAR ( OC_UINT8, 1, &_settings_game.game_creation.town_name ),
1725 OCL_CHUNK( 1, LoadOldGameDifficulty ),
1727 OCL_ASSERT( OC_TTD, 0x77130 ),
1729 OCL_VAR ( OC_UINT8, 1, &_old_diff_level ),
1731 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.landscape ),
1732 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_trees_tick_ctr ),
1734 OCL_CNULL( OC_TTD, 1 ), ///< Custom vehicle types yes/no, no longer used
1735 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.snow_line_height ),
1737 OCL_CNULL( OC_TTD, 32 ), ///< new_industry_randtable, no longer used (because of new design)
1738 OCL_CNULL( OC_TTD, 36 ), ///< cargo-stuff
1740 OCL_ASSERT( OC_TTD, 0x77179 ),
1741 OCL_ASSERT( OC_TTO, 0x4971D ),
1743 OCL_CHUNK( 1, LoadOldMapPart2 ),
1745 OCL_ASSERT( OC_TTD, 0x97179 ),
1746 OCL_ASSERT( OC_TTO, 0x6971D ),
1748 /* Below any (if available) extra chunks from TTDPatch can follow */
1749 OCL_CHUNK(1, LoadTTDPatchExtraChunks),
1751 OCL_END()
1754 bool LoadTTDMain(LoadgameState *ls)
1756 DEBUG(oldloader, 3, "Reading main chunk...");
1758 _read_ttdpatch_flags = false;
1760 /* Load the biggest chunk */
1761 SmallStackSafeStackAlloc<byte, OLD_MAP_SIZE * 2> map3;
1762 _old_map3 = map3.data;
1763 _old_vehicle_names = NULL;
1764 try {
1765 if (!LoadChunk(ls, NULL, main_chunk)) {
1766 DEBUG(oldloader, 0, "Loading failed");
1767 free(_old_vehicle_names);
1768 return false;
1770 } catch (...) {
1771 free(_old_vehicle_names);
1772 throw;
1775 DEBUG(oldloader, 3, "Done, converting game data...");
1777 FixTTDMapArray();
1778 FixTTDDepots();
1780 /* Fix some general stuff */
1781 _settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
1783 /* Fix the game to be compatible with OpenTTD */
1784 FixOldTowns();
1785 FixOldVehicles();
1787 /* We have a new difficulty setting */
1788 _settings_game.difficulty.town_council_tolerance = Clamp(_old_diff_level, 0, 2);
1790 DEBUG(oldloader, 3, "Finished converting game data");
1791 DEBUG(oldloader, 1, "TTD(Patch) savegame successfully converted");
1793 free(_old_vehicle_names);
1795 return true;
1798 bool LoadTTOMain(LoadgameState *ls)
1800 DEBUG(oldloader, 3, "Reading main chunk...");
1802 _read_ttdpatch_flags = false;
1804 SmallStackSafeStackAlloc<byte, 103 * sizeof(Engine)> engines; // we don't want to call Engine constructor here
1805 _old_engines = (Engine *)engines.data;
1806 SmallStackSafeStackAlloc<StringID, 800> vehnames;
1807 _old_vehicle_names = vehnames.data;
1809 /* Load the biggest chunk */
1810 if (!LoadChunk(ls, NULL, main_chunk)) {
1811 DEBUG(oldloader, 0, "Loading failed");
1812 return false;
1814 DEBUG(oldloader, 3, "Done, converting game data...");
1816 if (_settings_game.game_creation.town_name != 0) _settings_game.game_creation.town_name++;
1818 _settings_game.game_creation.landscape = 0;
1819 _trees_tick_ctr = 0xFF;
1821 if (!FixTTOMapArray() || !FixTTOEngines()) {
1822 DEBUG(oldloader, 0, "Conversion failed");
1823 return false;
1826 FixOldTowns();
1827 FixOldVehicles();
1828 FixTTOCompanies();
1830 /* We have a new difficulty setting */
1831 _settings_game.difficulty.town_council_tolerance = Clamp(_old_diff_level, 0, 2);
1833 /* SVXConverter about cargo payment rates correction:
1834 * "increase them to compensate for the faster time advance in TTD compared to TTO
1835 * which otherwise would cause much less income while the annual running costs of
1836 * the vehicles stay the same" */
1837 _economy.inflation_payment = min(_economy.inflation_payment * 124 / 74, MAX_INFLATION);
1839 DEBUG(oldloader, 3, "Finished converting game data");
1840 DEBUG(oldloader, 1, "TTO savegame successfully converted");
1842 return true;