# oldloader_sl.cpp

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #include "../stdafx.h"
    00013 #include "../town.h"
    00014 #include "../industry.h"
    00015 #include "../company_func.h"
    00016 #include "../aircraft.h"
    00017 #include "../roadveh.h"
    00018 #include "../ship.h"
    00019 #include "../train.h"
    00020 #include "../signs_base.h"
    00021 #include "../station_base.h"
    00022 #include "../subsidy_base.h"
    00023 #include "../debug.h"
    00024 #include "../depot_base.h"
    00025 #include "../date_func.h"
    00026 #include "../vehicle_func.h"
    00027 #include "../effectvehicle_base.h"
    00028 #include "../engine_func.h"
    00029 #include "../company_base.h"
    00030 #include "saveload_internal.h"
    00031 #include "oldloader.h"
    00032
    00033 #include "table/strings.h"
    00034 #include "../table/engines.h"
    00035 #include "../table/townname.h"
    00036
    00037 static bool _read_ttdpatch_flags;
    00038 static uint16 _old_extra_chunk_nums;
    00039 static byte _old_vehicle_multiplier;
    00040
    00041 static uint8 *_old_map3;
    00042
    00043 void FixOldMapArray()
    00044 {
    00045   /* TTO/TTD/TTDP savegames could have buoys at tile 0
    00046    * (without assigned station struct) */
    00047   MemSetT(&_m[0], 0);
    00048   SetTileType(0, MP_WATER);
    00049   SetTileOwner(0, OWNER_WATER);
    00050 }
    00051
    00052 static void FixTTDMapArray()
    00053 {
    00054   /* _old_map3 is moved to _m::m3 and _m::m4 */
    00055   for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) {
    00056     _m[t].m3 = _old_map3[t * 2];
    00057     _m[t].m4 = _old_map3[t * 2 + 1];
    00058   }
    00059
    00060   for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) {
    00061     switch (GetTileType(t)) {
    00062       case MP_STATION:
    00063         _m[t].m4 = 0; // We do not understand this TTDP station mapping (yet)
    00064         switch (_m[t].m5) {
    00065           /* We have drive through stops at a totally different place */
    00066           case 0x53: case 0x54: _m[t].m5 += 170 - 0x53; break; // Bus drive through
    00067           case 0x57: case 0x58: _m[t].m5 += 168 - 0x57; break; // Truck drive through
    00068           case 0x55: case 0x56: _m[t].m5 += 170 - 0x55; break; // Bus tram stop
    00069           case 0x59: case 0x5A: _m[t].m5 += 168 - 0x59; break; // Truck tram stop
    00070           default: break;
    00071         }
    00072         break;
    00073
    00074       case MP_RAILWAY:
    00075         /* We save presignals different from TTDPatch, convert them */
    00076         if (GB(_m[t].m5, 6, 2) == 1) { // RAIL_TILE_SIGNALS
    00077           /* This byte is always zero in TTD for this type of tile */
    00078           if (_m[t].m4) { // Convert the presignals to our own format
    00079             _m[t].m4 = (_m[t].m4 >> 1) & 7;
    00080           }
    00081         }
    00082         /* TTDPatch stores PBS things in L6 and all elsewhere; so we'll just
    00083          * clear it for ourselves and let OTTD's rebuild PBS itself */
    00084         _m[t].m4 &= 0xF; // Only keep the lower four bits; upper four is PBS
    00085         break;
    00086
    00087       case MP_WATER:
    00088         /* if water class == 3, make river there */
    00089         if (GB(_m[t].m3, 0, 2) == 3) {
    00090           SetTileType(t, MP_WATER);
    00091           SetTileOwner(t, OWNER_WATER);
    00092           _m[t].m2 = 0;
    00093           _m[t].m3 = 2; // WATER_CLASS_RIVER
    00094           _m[t].m4 = Random();
    00095           _m[t].m5 = 0;
    00096         }
    00097         break;
    00098
    00099       default:
    00100         break;
    00101     }
    00102   }
    00103
    00104   FixOldMapArray();
    00105 }
    00106
    00107 static void FixTTDDepots()
    00108 {
    00109   const Depot *d;
    00110   FOR_ALL_DEPOTS_FROM(d, 252) {
    00111     if (!IsDepotTile(d->xy) || GetDepotIndex(d->xy) != d->index) {
    00113       delete d;
    00114     }
    00115   }
    00116 }
    00117
    00118 #define FIXNUM(x, y, z) (((((x) << 16) / (y)) + 1) << z)
    00119
    00120 static uint32 RemapOldTownName(uint32 townnameparts, byte old_town_name_type)
    00121 {
    00122   switch (old_town_name_type) {
    00123     case 0: case 3: // English, American
    00124       /* Already OK */
    00125       return townnameparts;
    00126
    00127     case 1: // French
    00128       /* For some reason 86 needs to be subtracted from townnameparts
    00129        * 0000 0000 0000 0000 0000 0000 1111 1111 */
    00130       return FIXNUM(townnameparts - 86, lengthof(_name_french_real), 0);
    00131
    00132     case 2: // German
    00133       DEBUG(misc, 0, "German Townnames are buggy (%d)", townnameparts);
    00134       return townnameparts;
    00135
    00136     case 4: // Latin-American
    00137       /* 0000 0000 0000 0000 0000 0000 1111 1111 */
    00138       return FIXNUM(townnameparts, lengthof(_name_spanish_real), 0);
    00139
    00140     case 5: // Silly
    00141       /* NUM_SILLY_1 - lower 16 bits
    00142        * NUM_SILLY_2 - upper 16 bits without leading 1 (first 8 bytes)
    00143        * 1000 0000 2222 2222 0000 0000 1111 1111 */
    00144       return FIXNUM(townnameparts, lengthof(_name_silly_1), 0) | FIXNUM(GB(townnameparts, 16, 8), lengthof(_name_silly_2), 16);
    00145   }
    00146   return 0;
    00147 }
    00148
    00149 #undef FIXNUM
    00150
    00151 static void FixOldTowns()
    00152 {
    00153   Town *town;
    00154
    00155   /* Convert town-names if needed */
    00156   FOR_ALL_TOWNS(town) {
    00157     if (IsInsideMM(town->townnametype, 0x20C1, 0x20C3)) {
    00158       town->townnametype = SPECSTR_TOWNNAME_ENGLISH + _settings_game.game_creation.town_name;
    00159       town->townnameparts = RemapOldTownName(town->townnameparts, _settings_game.game_creation.town_name);
    00160     }
    00161   }
    00162 }
    00163
    00164 static StringID *_old_vehicle_names;
    00165
    00171 void FixOldVehicles()
    00172 {
    00173   Vehicle *v;
    00174
    00175   FOR_ALL_VEHICLES(v) {
    00176     if ((size_t)v->next == 0xFFFF) {
    00177       v->next = NULL;
    00178     } else {
    00179       v->next = Vehicle::GetIfValid((size_t)v->next);
    00180     }
    00181
    00182     /* For some reason we need to correct for this */
    00183     switch (v->spritenum) {
    00184       case 0xfd: break;
    00185       case 0xff: v->spritenum = 0xfe; break;
    00186       default:   v->spritenum >>= 1; break;
    00187     }
    00188
    00189     /* Vehicle-subtype is different in TTD(Patch) */
    00190     if (v->type == VEH_EFFECT) v->subtype = v->subtype >> 1;
    00191
    00192     v->name = CopyFromOldName(_old_vehicle_names[v->index]);
    00193
    00194     /* We haven't used this bit for stations for ages */
    00195     if (v->type == VEH_ROAD) {
    00196       RoadVehicle *rv = RoadVehicle::From(v);
    00197       if (rv->state != RVSB_IN_DEPOT && rv->state != RVSB_WORMHOLE) {
    00198         ClrBit(rv->state, 2);
    00199         if (IsTileType(rv->tile, MP_STATION) && _m[rv->tile].m5 >= 168) {
    00200           /* Update the vehicle's road state to show we're in a drive through road stop. */
    00201           SetBit(rv->state, RVS_IN_DT_ROAD_STOP);
    00202         }
    00203       }
    00204     }
    00205
    00206     /* The subtype should be 0, but it sometimes isn't :( */
    00207     if (v->type == VEH_ROAD || v->type == VEH_SHIP) v->subtype = 0;
    00208
    00209     /* Sometimes primary vehicles would have a nothing (invalid) order
    00210      * or vehicles that could not have an order would still have a
    00211      * (loading) order which causes assertions and the like later on.
    00212      */
    00213     if (!IsCompanyBuildableVehicleType(v) ||
    00214         (v->IsPrimaryVehicle() && v->current_order.IsType(OT_NOTHING))) {
    00215       v->current_order.MakeDummy();
    00216     }
    00217
    00218     /* Shared orders are fixed in AfterLoadVehicles now */
    00219   }
    00220 }
    00221
    00222 static bool FixTTOMapArray()
    00223 {
    00224   for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) {
    00225     TileType tt = GetTileType(t);
    00226     if (tt == 11) {
    00227       /* TTO has a different way of storing monorail.
    00228        * Instead of using bits in m3 it uses a different tile type. */
    00229       _m[t].m3 = 1; // rail type = monorail (in TTD)
    00230       SetTileType(t, MP_RAILWAY);
    00231       _m[t].m2 = 1; // set monorail ground to RAIL_GROUND_GRASS
    00232       tt = MP_RAILWAY;
    00233     }
    00234
    00235     switch (tt) {
    00236       case MP_CLEAR:
    00237         break;
    00238
    00239       case MP_RAILWAY:
    00240         switch (GB(_m[t].m5, 6, 2)) {
    00241           case 0: // RAIL_TILE_NORMAL
    00242             break;
    00243           case 1: // RAIL_TILE_SIGNALS
    00244             _m[t].m4 = (~_m[t].m5 & 1) << 2;        // signal variant (present only in OTTD)
    00245             SB(_m[t].m2, 6, 2, GB(_m[t].m5, 3, 2)); // signal status
    00246             _m[t].m3 |= 0xC0;                       // both signals are present
    00247             _m[t].m5 = HasBit(_m[t].m5, 5) ? 2 : 1; // track direction (only X or Y)
    00248             _m[t].m5 |= 0x40;                       // RAIL_TILE_SIGNALS
    00249             break;
    00250           case 3: // RAIL_TILE_DEPOT
    00251             _m[t].m2 = 0;
    00252             break;
    00253           default:
    00254             return false;
    00255         }
    00256         break;
    00257
    00258       case MP_ROAD: // road (depot) or level crossing
    00259         switch (GB(_m[t].m5, 4, 4)) {
    00260           case 0: // ROAD_TILE_NORMAL
    00261             if (_m[t].m2 == 4) _m[t].m2 = 5; // 'small trees' -> ROADSIDE_TREES
    00262             break;
    00263           case 1: // ROAD_TILE_CROSSING (there aren't monorail crossings in TTO)
    00264             _m[t].m3 = _m[t].m1; // set owner of road = owner of rail
    00265             break;
    00266           case 2: // ROAD_TILE_DEPOT
    00267             break;
    00268           default:
    00269             return false;
    00270         }
    00271         break;
    00272
    00273       case MP_HOUSE:
    00274         _m[t].m3 = _m[t].m2 & 0xC0;    // construction stage
    00275         _m[t].m2 &= 0x3F;              // building type
    00276         if (_m[t].m2 >= 5) _m[t].m2++; // skip "large office block on snow"
    00277         break;
    00278
    00279       case MP_TREES:
    00280         _m[t].m3 = GB(_m[t].m5, 3, 3); // type of trees
    00281         _m[t].m5 &= 0xC7;              // number of trees and growth status
    00282         break;
    00283
    00284       case MP_STATION:
    00285         _m[t].m3 = (_m[t].m5 >= 0x08 && _m[t].m5 <= 0x0F) ? 1 : 0; // monorail -> 1, others 0 (rail, road, airport, dock)
    00286         if (_m[t].m5 >= 8) _m[t].m5 -= 8; // shift for monorail
    00287         if (_m[t].m5 >= 0x42) _m[t].m5++; // skip heliport
    00288         break;
    00289
    00290       case MP_WATER:
    00291         _m[t].m3 = _m[t].m2 = 0;
    00292         break;
    00293
    00294       case MP_VOID:
    00295         _m[t].m2 = _m[t].m3 = _m[t].m5 = 0;
    00296         break;
    00297
    00298       case MP_INDUSTRY:
    00299         _m[t].m3 = 0;
    00300         switch (_m[t].m5) {
    00301           case 0x24: // farm silo
    00302             _m[t].m5 = 0x25;
    00303             break;
    00304           case 0x25: case 0x27: // farm
    00305           case 0x28: case 0x29: case 0x2A: case 0x2B: // factory
    00306             _m[t].m5--;
    00307             break;
    00308           default:
    00309             if (_m[t].m5 >= 0x2C) _m[t].m5 += 3; // iron ore mine, steel mill or bank
    00310             break;
    00311         }
    00312         break;
    00313
    00314       case MP_TUNNELBRIDGE:
    00315         if (HasBit(_m[t].m5, 7)) { // bridge
    00316           byte m5 = _m[t].m5;
    00317           _m[t].m5 = m5 & 0xE1; // copy bits 7..5, 1
    00318           if (GB(m5, 1, 2) == 1) _m[t].m5 |= 0x02; // road bridge
    00319           if (GB(m5, 1, 2) == 3) _m[t].m2 |= 0xA0; // monorail bridge -> tubular, steel bridge
    00320           if (!HasBit(m5, 6)) { // bridge head
    00321             _m[t].m3 = (GB(m5, 1, 2) == 3) ? 1 : 0; // track subtype (1 for monorail, 0 for others)
    00322           } else { // middle bridge part
    00323             _m[t].m3 = HasBit(m5, 2) ? 0x10 : 0;  // track subtype on bridge
    00324             if (GB(m5, 3, 2) == 3) _m[t].m3 |= 1; // track subtype under bridge
    00325             if (GB(m5, 3, 2) == 1) _m[t].m5 |= 0x08; // set for road/water under (0 for rail/clear)
    00326           }
    00327         } else { // tunnel entrance/exit
    00328           _m[t].m2 = 0;
    00329           _m[t].m3 = HasBit(_m[t].m5, 3); // monorail
    00330           _m[t].m5 &= HasBit(_m[t].m5, 3) ? 0x03 : 0x07 ; // direction, transport type (== 0 for rail)
    00331         }
    00332         break;
    00333
    00334       case MP_OBJECT:
    00335         _m[t].m2 = 0;
    00336         _m[t].m3 = 0;
    00337         break;
    00338
    00339       default:
    00340         return false;
    00341
    00342     }
    00343   }
    00344
    00345   FixOldMapArray();
    00346
    00347   return true;
    00348 }
    00349
    00350 static Engine *_old_engines;
    00351
    00352 static bool FixTTOEngines()
    00353 {
    00355   static const EngineID ttd_to_tto[] = {
    00356       0, 255, 255, 255, 255, 255, 255, 255,   5,   7,   8,   9,  10,  11,  12,  13,
    00357     255, 255, 255, 255, 255, 255,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
    00358     25,   26,  27,  29,  28,  30, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    00359     255, 255, 255, 255, 255, 255, 255,  31, 255,  32,  33,  34,  35,  36,  37,  38,
    00360      39,  40,  41,  42, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    00361     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    00362     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    00363     255, 255, 255, 255,  44,  45,  46, 255, 255, 255, 255,  47,  48, 255,  49,  50,
    00364     255, 255, 255, 255,  51,  52, 255,  53,  54, 255,  55,  56, 255,  57,  59, 255,
    00365      58,  60, 255,  61,  62, 255,  63,  64, 255,  65,  66, 255, 255, 255, 255, 255,
    00366     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    00367     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    00368     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,  67,  68,  69,  70,
    00369      71, 255, 255,  76,  77, 255, 255,  78,  79,  80,  81,  82,  83,  84,  85,  86,
    00370      87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99, 100, 101, 255,
    00371     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 102, 255, 255
    00372   };
    00373
    00375   static const EngineID tto_to_ttd[] = {
    00376       0,   0,   8,   8,   8,   8,   8,   9,  10,  11,  12,  13,  14,  15,  15,  22,
    00377      23,  24,  25,  26,  27,  29,  28,  30,  31,  32,  33,  34,  35,  36,  37,  55,
    00378      57,  59,  58,  60,  61,  62,  63,  64,  65,  66,  67, 116, 116, 117, 118, 123,
    00379     124, 126, 127, 132, 133, 135, 136, 138, 139, 141, 142, 144, 145, 147, 148, 150,
    00380     151, 153, 154, 204, 205, 206, 207, 208, 211, 212, 211, 212, 211, 212, 215, 216,
    00381     217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
    00382     233, 234, 235, 236, 237, 238, 253
    00383   };
    00384
    00385   Vehicle *v;
    00386   FOR_ALL_VEHICLES(v) {
    00387     if (v->engine_type >= lengthof(tto_to_ttd)) return false;
    00388     v->engine_type = tto_to_ttd[v->engine_type];
    00389   }
    00390
    00391   /* Load the default engine set. Many of them will be overridden later */
    00392   uint j = 0;
    00393   for (uint i = 0; i < lengthof(_orig_rail_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_TRAIN, i);
    00394   for (uint i = 0; i < lengthof(_orig_road_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_ROAD, i);
    00395   for (uint i = 0; i < lengthof(_orig_ship_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_SHIP, i);
    00396   for (uint i = 0; i < lengthof(_orig_aircraft_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_AIRCRAFT, i);
    00397
    00398   Date aging_date = min(_date + DAYS_TILL_ORIGINAL_BASE_YEAR, ConvertYMDToDate(2050, 0, 1));
    00399
    00400   for (EngineID i = 0; i < 256; i++) {
    00401     int oi = ttd_to_tto[i];
    00402     Engine *e = GetTempDataEngine(i);
    00403
    00404     if (oi == 255) {
    00405       /* Default engine is used */
    00406       _date += DAYS_TILL_ORIGINAL_BASE_YEAR;
    00407       StartupOneEngine(e, aging_date);
    00408       e->intro_date -= DAYS_TILL_ORIGINAL_BASE_YEAR;
    00409       _date -= DAYS_TILL_ORIGINAL_BASE_YEAR;
    00410
    00411       /* Make sure for example monorail and maglev are available when they should be */
    00412       if (_date >= e->intro_date && HasBit(e->info.climates, 0)) {
    00413         e->flags |= ENGINE_AVAILABLE;
    00414         e->company_avail = (CompanyMask)0xFF;
    00415         e->age = _date > e->intro_date ? (_date - e->intro_date) / 30 : 0;
    00416       }
    00417     } else {
    00418       /* Using data from TTO savegame */
    00419       Engine *oe = &_old_engines[oi];
    00420
    00421       e->intro_date          = oe->intro_date;
    00422       e->age                 = oe->age;
    00423       e->reliability         = oe->reliability;
    00424       e->reliability_spd_dec = oe->reliability_spd_dec;
    00425       e->reliability_start   = oe->reliability_start;
    00426       e->reliability_max     = oe->reliability_max;
    00427       e->reliability_final   = oe->reliability_final;
    00428       e->duration_phase_1    = oe->duration_phase_1;
    00429       e->duration_phase_2    = oe->duration_phase_2;
    00430       e->duration_phase_3    = oe->duration_phase_3;
    00431       e->flags               = oe->flags;
    00432
    00433       e->company_avail = 0;
    00434
    00435       /* One or more engines were remapped to this one. Make this engine available
    00436        * if at least one of them was available. */
    00437       for (uint j = 0; j < lengthof(tto_to_ttd); j++) {
    00438         if (tto_to_ttd[j] == i && _old_engines[j].company_avail != 0) {
    00439           e->company_avail = (CompanyMask)0xFF;
    00440           e->flags |= ENGINE_AVAILABLE;
    00441           break;
    00442         }
    00443       }
    00444
    00445       e->info.climates = 1;
    00446     }
    00447
    00448     e->preview_company = INVALID_COMPANY;
    00449     e->preview_asked = (CompanyMask)-1;
    00450     e->preview_wait = 0;
    00451     e->name = NULL;
    00452   }
    00453
    00454   return true;
    00455 }
    00456
    00457 static void FixTTOCompanies()
    00458 {
    00459   Company *c;
    00460   FOR_ALL_COMPANIES(c) {
    00461     c->cur_economy.company_value = CalculateCompanyValue(c); // company value history is zeroed
    00462   }
    00463 }
    00464
    00465 static inline byte RemapTTOColour(byte tto)
    00466 {
    00468   static const byte tto_colour_remap[] = {
    00469     COLOUR_DARK_BLUE,  COLOUR_GREY,       COLOUR_YELLOW,     COLOUR_RED,
    00470     COLOUR_PURPLE,     COLOUR_DARK_GREEN, COLOUR_ORANGE,     COLOUR_PALE_GREEN,
    00471     COLOUR_BLUE,       COLOUR_GREEN,      COLOUR_CREAM,      COLOUR_BROWN,
    00472     COLOUR_WHITE,      COLOUR_LIGHT_BLUE, COLOUR_MAUVE,      COLOUR_PINK
    00473   };
    00474
    00475   if ((size_t)tto >= lengthof(tto_colour_remap)) return COLOUR_GREY; // this shouldn't happen
    00476
    00477   return tto_colour_remap[tto];
    00478 }
    00479
    00480 static inline uint RemapTownIndex(uint x)
    00481 {
    00482   return _savegame_type == SGT_TTO ? (x - 0x264) / 78 : (x - 0x264) / 94;
    00483 }
    00484
    00485 static inline uint RemapOrderIndex(uint x)
    00486 {
    00487   return _savegame_type == SGT_TTO ? (x - 0x1AC4) / 2 : (x - 0x1C18) / 2;
    00488 }
    00489
    00490 extern TileIndex *_animated_tile_list;
    00491 extern uint _animated_tile_count;
    00492 extern char *_old_name_array;
    00493
    00494 static uint32 _old_town_index;
    00495 static uint16 _old_string_id;
    00496 static uint16 _old_string_id_2;
    00497
    00498 static void ReadTTDPatchFlags()
    00499 {
    00500   if (_read_ttdpatch_flags) return;
    00501
    00502   _read_ttdpatch_flags = true;
    00503
    00504   /* Set default values */
    00505   _old_vehicle_multiplier = 1;
    00506   _ttdp_version = 0;
    00507   _old_extra_chunk_nums = 0;
    00508   _bump_assert_value = 0;
    00509
    00510   if (_savegame_type == SGT_TTO) return;
    00511
    00512   /* TTDPatch misuses _old_map3 for flags.. read them! */
    00513   _old_vehicle_multiplier = _old_map3[0];
    00514   /* Somehow.... there was an error in some savegames, so 0 becomes 1
    00515    * and 1 becomes 2. The rest of the values are okay */
    00516   if (_old_vehicle_multiplier < 2) _old_vehicle_multiplier++;
    00517
    00518   _old_vehicle_names = MallocT<StringID>(_old_vehicle_multiplier * 850);
    00519
    00520   /* TTDPatch increases the Vehicle-part in the middle of the game,
    00521    * so if the multiplier is anything else but 1, the assert fails..
    00522    * bump the assert value so it doesn't!
    00523    * (1 multiplier == 850 vehicles
    00524    * 1 vehicle   == 128 bytes */
    00525   _bump_assert_value = (_old_vehicle_multiplier - 1) * 850 * 128;
    00526
    00527   for (uint i = 0; i < 17; i++) { // check tile 0, too
    00528     if (_old_map3[i] != 0) _savegame_type = SGT_TTDP1;
    00529   }
    00530
    00531   /* Check if we have a modern TTDPatch savegame (has extra data all around) */
    00532   if (memcmp(&_old_map3[0x1FFFA], "TTDp", 4) == 0) _savegame_type = SGT_TTDP2;
    00533
    00534   _old_extra_chunk_nums = _old_map3[_savegame_type == SGT_TTDP2 ? 0x1FFFE : 0x2];
    00535
    00536   /* Clean the misused places */
    00537   for (uint i = 0;       i < 17;      i++) _old_map3[i] = 0;
    00538   for (uint i = 0x1FE00; i < 0x20000; i++) _old_map3[i] = 0;
    00539
    00540   if (_savegame_type == SGT_TTDP2) DEBUG(oldloader, 2, "Found TTDPatch game");
    00541
    00542   DEBUG(oldloader, 3, "Vehicle-multiplier is set to %d (%d vehicles)", _old_vehicle_multiplier, _old_vehicle_multiplier * 850);
    00543 }
    00544
    00545 static const OldChunks town_chunk[] = {
    00546   OCL_SVAR(   OC_TILE, Town, xy ),
    00547   OCL_NULL( 2 ),
    00548   OCL_SVAR( OC_UINT16, Town, townnametype ),
    00549   OCL_SVAR( OC_UINT32, Town, townnameparts ),
    00550   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Town, grow_counter ),
    00551   OCL_NULL( 1 ),
    00552   OCL_NULL( 4 ),
    00553   OCL_NULL( 2 ),
    00554   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, Town, flags ),
    00555   OCL_NULL( 10 ),
    00556
    00557   OCL_SVAR( OC_INT16, Town, ratings[0] ),
    00558   OCL_SVAR( OC_INT16, Town, ratings[1] ),
    00559   OCL_SVAR( OC_INT16, Town, ratings[2] ),
    00560   OCL_SVAR( OC_INT16, Town, ratings[3] ),
    00561   OCL_SVAR( OC_INT16, Town, ratings[4] ),
    00562   OCL_SVAR( OC_INT16, Town, ratings[5] ),
    00563   OCL_SVAR( OC_INT16, Town, ratings[6] ),
    00564   OCL_SVAR( OC_INT16, Town, ratings[7] ),
    00565
    00566   OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, have_ratings ),
    00567   OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, statues ),
    00568   OCL_NULL( 2 ),
    00569   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Town, time_until_rebuild ),
    00570   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Town, growth_rate ),
    00571
    00572   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].new_max ),
    00573   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].new_max ),
    00574   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].new_act ),
    00575   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].new_act ),
    00576   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].old_max ),
    00577   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].old_max ),
    00578   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].old_act ),
    00579   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].old_act ),
    00580
    00581   OCL_NULL( 2 ),
    00582
    00583   OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_FOOD].new_act ),
    00584   OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_WATER].new_act ),
    00585   OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_FOOD].old_act ),
    00586   OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_WATER].old_act ),
    00587
    00588   OCL_SVAR(  OC_UINT8, Town, road_build_months ),
    00589   OCL_SVAR(  OC_UINT8, Town, fund_buildings_months ),
    00590
    00591   OCL_CNULL( OC_TTD, 8 ),
    00592
    00593   OCL_END()
    00594 };
    00595
    00596 static bool LoadOldTown(LoadgameState *ls, int num)
    00597 {
    00598   Town *t = new (num) Town();
    00599   if (!LoadChunk(ls, t, town_chunk)) return false;
    00600
    00601   if (t->xy != 0) {
    00602     if (_savegame_type == SGT_TTO) {
    00603       /* 0x10B6 is auto-generated name, others are custom names */
    00604       t->townnametype = t->townnametype == 0x10B6 ? 0x20C1 : t->townnametype + 0x2A00;
    00605     }
    00606   } else {
    00607     delete t;
    00608   }
    00609
    00610   return true;
    00611 }
    00612
    00613 static uint16 _old_order;
    00614 static const OldChunks order_chunk[] = {
    00615   OCL_VAR ( OC_UINT16,   1, &_old_order ),
    00616   OCL_END()
    00617 };
    00618
    00619 static bool LoadOldOrder(LoadgameState *ls, int num)
    00620 {
    00621   if (!LoadChunk(ls, NULL, order_chunk)) return false;
    00622
    00623   Order *o = new (num) Order();
    00624   o->AssignOrder(UnpackOldOrder(_old_order));
    00625
    00626   if (o->IsType(OT_NOTHING)) {
    00627     delete o;
    00628   } else {
    00629     /* Relink the orders to each other (in the orders for one vehicle are behind each other,
    00630      * with an invalid order (OT_NOTHING) as indication that it is the last order */
    00631     Order *prev = Order::GetIfValid(num - 1);
    00632     if (prev != NULL) prev->next = o;
    00633   }
    00634
    00635   return true;
    00636 }
    00637
    00638 static bool LoadOldAnimTileList(LoadgameState *ls, int num)
    00639 {
    00640   /* This is slightly hackish - we must load a chunk into an array whose
    00641    * address isn't static, but instead pointed to by _animated_tile_list.
    00642    * To achieve that, create an OldChunks list on the stack on the fly.
    00643    * The list cannot be static because the value of _animated_tile_list
    00644    * can change between calls. */
    00645
    00646   const OldChunks anim_chunk[] = {
    00647     OCL_VAR (   OC_TILE, 256, _animated_tile_list ),
    00648     OCL_END ()
    00649   };
    00650
    00651   if (!LoadChunk(ls, NULL, anim_chunk)) return false;
    00652
    00653   /* Update the animated tile counter by counting till the first zero in the array */
    00654   for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
    00655     if (_animated_tile_list[_animated_tile_count] == 0) break;
    00656   }
    00657
    00658   return true;
    00659 }
    00660
    00661 static const OldChunks depot_chunk[] = {
    00662   OCL_SVAR(   OC_TILE, Depot, xy ),
    00663   OCL_VAR ( OC_UINT32,                1, &_old_town_index ),
    00664   OCL_END()
    00665 };
    00666
    00667 static bool LoadOldDepot(LoadgameState *ls, int num)
    00668 {
    00669   Depot *d = new (num) Depot();
    00670   if (!LoadChunk(ls, d, depot_chunk)) return false;
    00671
    00672   if (d->xy != 0) {
    00673     /* In some cases, there could be depots referencing invalid town. */
    00674     Town *t = Town::GetIfValid(RemapTownIndex(_old_town_index));
    00675     if (t == NULL) t = Town::GetRandom();
    00676     d->town = t;
    00677   } else {
    00678     delete d;
    00679   }
    00680
    00681   return true;
    00682 }
    00683
    00684 static StationID _current_station_id;
    00685 static uint16 _waiting_acceptance;
    00686 static uint8  _cargo_source;
    00687 static uint8  _cargo_days;
    00688
    00689 static const OldChunks goods_chunk[] = {
    00690   OCL_VAR ( OC_UINT16, 1,          &_waiting_acceptance ),
    00691   OCL_SVAR(  OC_UINT8, GoodsEntry, time_since_pickup ),
    00692   OCL_SVAR(  OC_UINT8, GoodsEntry, rating ),
    00693   OCL_VAR (  OC_UINT8, 1,          &_cargo_source ),
    00694   OCL_VAR (  OC_UINT8, 1,          &_cargo_days ),
    00695   OCL_SVAR(  OC_UINT8, GoodsEntry, last_speed ),
    00696   OCL_SVAR(  OC_UINT8, GoodsEntry, last_age ),
    00697
    00698   OCL_END()
    00699 };
    00700
    00701 static bool LoadOldGood(LoadgameState *ls, int num)
    00702 {
    00703   /* for TTO games, 12th (num == 11) goods entry is created in the Station constructor */
    00704   if (_savegame_type == SGT_TTO && num == 11) return true;
    00705
    00706   Station *st = Station::Get(_current_station_id);
    00707   GoodsEntry *ge = &st->goods[num];
    00708
    00709   if (!LoadChunk(ls, ge, goods_chunk)) return false;
    00710
    00711   SB(ge->acceptance_pickup, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
    00712   SB(ge->acceptance_pickup, GoodsEntry::GES_PICKUP, 1, _cargo_source != 0xFF);
    00713   if (GB(_waiting_acceptance, 0, 12) != 0 && CargoPacket::CanAllocateItem()) {
    00714     ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, 0, 0),
    00715         INVALID_STATION);
    00716   }
    00717
    00718   return true;
    00719 }
    00720
    00721 static const OldChunks station_chunk[] = {
    00722   OCL_SVAR(   OC_TILE, Station, xy ),
    00723   OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
    00724
    00725   OCL_NULL( 4 ),
    00726   OCL_SVAR(   OC_TILE, Station, train_station.tile ),
    00727   OCL_SVAR(   OC_TILE, Station, airport.tile ),
    00728   OCL_SVAR(   OC_TILE, Station, dock_tile ),
    00729   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Station, train_station.w ),
    00730
    00731   OCL_NULL( 1 ),
    00732   OCL_NULL( 2 ),
    00733
    00734   OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
    00735
    00736   OCL_NULL( 4 ),
    00737
    00738   OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Station, had_vehicle_of_type ),
    00739
    00740   OCL_CHUNK( 12, LoadOldGood ),
    00741
    00742   OCL_SVAR(  OC_UINT8, Station, time_since_load ),
    00743   OCL_SVAR(  OC_UINT8, Station, time_since_unload ),
    00744   OCL_SVAR(  OC_UINT8, Station, delete_ctr ),
    00745   OCL_SVAR(  OC_UINT8, Station, owner ),
    00746   OCL_SVAR(  OC_UINT8, Station, facilities ),
    00747   OCL_SVAR( OC_TTD | OC_UINT8, Station, airport.type ),
    00748   OCL_SVAR( OC_TTO | OC_FILE_U16 | OC_VAR_U64, Station, airport.flags ),
    00749   OCL_NULL( 3 ),
    00750   OCL_CNULL( OC_TTD, 1 ),
    00751   OCL_SVAR( OC_TTD | OC_FILE_U16 | OC_VAR_U64, Station, airport.flags ),
    00752   OCL_CNULL( OC_TTD, 2 ),
    00753   OCL_CNULL( OC_TTD, 4 ),
    00754
    00755   OCL_END()
    00756 };
    00757
    00758 static bool LoadOldStation(LoadgameState *ls, int num)
    00759 {
    00760   Station *st = new (num) Station();
    00761   _current_station_id = num;
    00762
    00763   if (!LoadChunk(ls, st, station_chunk)) return false;
    00764
    00765   if (st->xy != 0) {
    00766     st->town = Town::Get(RemapTownIndex(_old_town_index));
    00767
    00768     if (_savegame_type == SGT_TTO) {
    00769       if (IsInsideBS(_old_string_id, 0x180F, 32)) {
    00770         st->string_id = STR_SV_STNAME + (_old_string_id - 0x180F); // automatic name
    00771       } else {
    00772         st->string_id = _old_string_id + 0x2800; // custom name
    00773       }
    00774
    00775       if (HasBit(st->airport.flags, 8)) {
    00776         st->airport.type = 1; // large airport
    00777       } else if (HasBit(st->airport.flags, 6)) {
    00778         st->airport.type = 3; // oil rig
    00779       } else {
    00780         st->airport.type = 0; // small airport
    00781       }
    00782     } else {
    00783       st->string_id = RemapOldStringID(_old_string_id);
    00784     }
    00785   } else {
    00786     delete st;
    00787   }
    00788
    00789   return true;
    00790 }
    00791
    00792 static const OldChunks industry_chunk[] = {
    00793   OCL_SVAR(   OC_TILE, Industry, location.tile ),
    00794   OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
    00795   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Industry, location.w ),
    00796   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Industry, location.h ),
    00797   OCL_NULL( 2 ),
    00798
    00799   OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced_cargo_waiting[0] ),
    00800   OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced_cargo_waiting[1] ),
    00801   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced_cargo_waiting[0] ),
    00802   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced_cargo_waiting[1] ),
    00803
    00804   OCL_SVAR(  OC_UINT8, Industry, production_rate[0] ),
    00805   OCL_SVAR(  OC_UINT8, Industry, production_rate[1] ),
    00806
    00807   OCL_NULL( 3 ),
    00808
    00809   OCL_SVAR(  OC_UINT8, Industry, prod_level ),
    00810
    00811   OCL_SVAR( OC_UINT16, Industry, this_month_production[0] ),
    00812   OCL_SVAR( OC_UINT16, Industry, this_month_production[1] ),
    00813   OCL_SVAR( OC_UINT16, Industry, this_month_transported[0] ),
    00814   OCL_SVAR( OC_UINT16, Industry, this_month_transported[1] ),
    00815
    00816   OCL_SVAR(  OC_UINT8, Industry, last_month_pct_transported[0] ),
    00817   OCL_SVAR(  OC_UINT8, Industry, last_month_pct_transported[1] ),
    00818
    00819   OCL_SVAR( OC_UINT16, Industry, last_month_production[0] ),
    00820   OCL_SVAR( OC_UINT16, Industry, last_month_production[1] ),
    00821   OCL_SVAR( OC_UINT16, Industry, last_month_transported[0] ),
    00822   OCL_SVAR( OC_UINT16, Industry, last_month_transported[1] ),
    00823
    00824   OCL_SVAR(  OC_UINT8, Industry, type ),
    00825   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, counter ),
    00826   OCL_SVAR(  OC_UINT8, Industry, owner ),
    00827   OCL_SVAR(  OC_UINT8, Industry, random_colour ),
    00828   OCL_SVAR( OC_TTD | OC_FILE_U8 | OC_VAR_I32, Industry, last_prod_year ),
    00829   OCL_SVAR( OC_TTD | OC_UINT16, Industry, counter ),
    00830   OCL_SVAR( OC_TTD | OC_UINT8, Industry, was_cargo_delivered ),
    00831
    00832   OCL_CNULL( OC_TTD, 9 ),
    00833
    00834   OCL_END()
    00835 };
    00836
    00837 static bool LoadOldIndustry(LoadgameState *ls, int num)
    00838 {
    00839   Industry *i = new (num) Industry();
    00840   if (!LoadChunk(ls, i, industry_chunk)) return false;
    00841
    00842   if (i->location.tile != 0) {
    00843     i->town = Town::Get(RemapTownIndex(_old_town_index));
    00844
    00845     if (_savegame_type == SGT_TTO) {
    00846       if (i->type > 0x06) i->type++; // Printing Works were added
    00847       if (i->type == 0x0A) i->type = 0x12; // Iron Ore Mine has different ID
    00848
    00849       YearMonthDay ymd;
    00850       ConvertDateToYMD(_date, &ymd);
    00851       i->last_prod_year = ymd.year;
    00852
    00853       i->random_colour = RemapTTOColour(i->random_colour);
    00854     }
    00855
    00856     Industry::IncIndustryTypeCount(i->type);
    00857   } else {
    00858     delete i;
    00859   }
    00860
    00861   return true;
    00862 }
    00863
    00864 static CompanyID _current_company_id;
    00865 static int32 _old_yearly;
    00866
    00867 static const OldChunks _company_yearly_chunk[] = {
    00868   OCL_VAR(  OC_INT32,   1, &_old_yearly ),
    00869   OCL_END()
    00870 };
    00871
    00872 static bool LoadOldCompanyYearly(LoadgameState *ls, int num)
    00873 {
    00874   Company *c = Company::Get(_current_company_id);
    00875
    00876   for (uint i = 0; i < 13; i++) {
    00877     if (_savegame_type == SGT_TTO && i == 6) {
    00878       _old_yearly = 0; // property maintenance
    00879     } else {
    00880       if (!LoadChunk(ls, NULL, _company_yearly_chunk)) return false;
    00881     }
    00882
    00883     c->yearly_expenses[num][i] = _old_yearly;
    00884   }
    00885
    00886   return true;
    00887 }
    00888
    00889 static const OldChunks _company_economy_chunk[] = {
    00890   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, income ),
    00891   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, expenses ),
    00892   OCL_SVAR( OC_INT32,                 CompanyEconomyEntry, delivered_cargo[NUM_CARGO - 1] ),
    00893   OCL_SVAR( OC_INT32,                 CompanyEconomyEntry, performance_history ),
    00894   OCL_SVAR( OC_TTD | OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, company_value ),
    00895
    00896   OCL_END()
    00897 };
    00898
    00899 static bool LoadOldCompanyEconomy(LoadgameState *ls, int num)
    00900 {
    00901   Company *c = Company::Get(_current_company_id);
    00902
    00903   if (!LoadChunk(ls, &c->cur_economy, _company_economy_chunk)) return false;
    00904
    00905   /* Don't ask, but the number in TTD(Patch) are inversed to OpenTTD */
    00906   c->cur_economy.income   = -c->cur_economy.income;
    00907   c->cur_economy.expenses = -c->cur_economy.expenses;
    00908
    00909   for (uint i = 0; i < 24; i++) {
    00910     if (!LoadChunk(ls, &c->old_economy[i], _company_economy_chunk)) return false;
    00911
    00912     c->old_economy[i].income   = -c->old_economy[i].income;
    00913     c->old_economy[i].expenses = -c->old_economy[i].expenses;
    00914   }
    00915
    00916   return true;
    00917 }
    00918
    00919 static const OldChunks _company_chunk[] = {
    00920   OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
    00921   OCL_SVAR( OC_UINT32, Company, name_2 ),
    00922   OCL_SVAR( OC_UINT32, Company, face ),
    00923   OCL_VAR ( OC_UINT16,   1, &_old_string_id_2 ),
    00924   OCL_SVAR( OC_UINT32, Company, president_name_2 ),
    00925
    00926   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, money ),
    00927   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, current_loan ),
    00928
    00929   OCL_SVAR(  OC_UINT8, Company, colour ),
    00930   OCL_SVAR(  OC_UINT8, Company, money_fraction ),
    00931   OCL_SVAR(  OC_UINT8, Company, months_of_bankruptcy ),
    00932   OCL_SVAR( OC_FILE_U8  | OC_VAR_U16, Company, bankrupt_asked ),
    00933   OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Company, bankrupt_value ),
    00934   OCL_SVAR( OC_UINT16, Company, bankrupt_timeout ),
    00935
    00936   OCL_CNULL( OC_TTD, 4 ), // cargo_types
    00937   OCL_CNULL( OC_TTO, 2 ), // cargo_types
    00938
    00939   OCL_CHUNK( 3, LoadOldCompanyYearly ),
    00940   OCL_CHUNK( 1, LoadOldCompanyEconomy ),
    00941
    00942   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Company, inaugurated_year),
    00943   OCL_SVAR(                  OC_TILE, Company, last_build_coordinate ),
    00944   OCL_SVAR(                 OC_UINT8, Company, num_valid_stat_ent ),
    00945
    00946   OCL_NULL( 230 ),         // Old AI
    00947
    00948   OCL_SVAR(  OC_UINT8, Company, block_preview ),
    00949   OCL_CNULL( OC_TTD, 1 ),           // Old AI
    00950   OCL_SVAR( OC_TTD | OC_UINT8, Company, avail_railtypes ),
    00951   OCL_SVAR(   OC_TILE, Company, location_of_HQ ),
    00952   OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[0] ),
    00953   OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[1] ),
    00954   OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[2] ),
    00955   OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[3] ),
    00956
    00957   OCL_CNULL( OC_TTD, 8 ),
    00958
    00959   OCL_END()
    00960 };
    00961
    00962 static bool LoadOldCompany(LoadgameState *ls, int num)
    00963 {
    00964   Company *c = new (num) Company();
    00965
    00966   _current_company_id = (CompanyID)num;
    00967
    00968   if (!LoadChunk(ls, c, _company_chunk)) return false;
    00969
    00970   if (_old_string_id == 0) {
    00971     delete c;
    00972     return true;
    00973   }
    00974
    00975   if (_savegame_type == SGT_TTO) {
    00976     /* adjust manager's face */
    00977     if (HasBit(c->face, 27) && GB(c->face, 26, 1) == GB(c->face, 19, 1)) {
    00978       /* if face would be black in TTD, adjust tie colour and thereby face colour */
    00979       ClrBit(c->face, 27);
    00980     }
    00981
    00982     /* Company name */
    00983     if (_old_string_id == 0 || _old_string_id == 0x4C00) {
    00984       _old_string_id = STR_SV_UNNAMED; // "Unnamed"
    00985     } else if (GB(_old_string_id, 8, 8) == 0x52) {
    00986       _old_string_id += 0x2A00; // Custom name
    00987     } else {
    00988       _old_string_id = RemapOldStringID(_old_string_id += 0x240D); // Automatic name
    00989     }
    00990     c->name_1 = _old_string_id;
    00991
    00992     /* Manager name */
    00993     switch (_old_string_id_2) {
    00994       case 0x4CDA: _old_string_id_2 = SPECSTR_PRESIDENT_NAME;    break; // automatic name
    00995       case 0x0006: _old_string_id_2 = STR_SV_EMPTY;              break; // empty name
    00996       default:     _old_string_id_2 = _old_string_id_2 + 0x2A00; break; // custom name
    00997     }
    00998     c->president_name_1 = _old_string_id_2;
    00999
    01000     c->colour = RemapTTOColour(c->colour);
    01001
    01002     if (num != 0) c->is_ai = true;
    01003   } else {
    01004     c->name_1 = RemapOldStringID(_old_string_id);
    01005     c->president_name_1 = RemapOldStringID(_old_string_id_2);
    01006
    01007     if (num == 0) {
    01008       /* If the first company has no name, make sure we call it UNNAMED */
    01009       if (c->name_1 == 0) {
    01010         c->name_1 = STR_SV_UNNAMED;
    01011       }
    01012     } else {
    01013       /* Beside some multiplayer maps (1 on 1), which we don't official support,
    01014        * all other companies are an AI.. mark them as such */
    01015       c->is_ai = true;
    01016     }
    01017
    01018     /* Sometimes it is better to not ask.. in old scenarios, the money
    01019      * was always 893288 pounds. In the newer versions this is correct,
    01020      * but correct for those oldies
    01021      * Ps: this also means that if you had exact 893288 pounds, you will go back
    01022      * to 100000.. this is a very VERY small chance ;) */
    01023     if (c->money == 893288) c->money = c->current_loan = 100000;
    01024   }
    01025
    01026   _company_colours[num] = (Colours)c->colour;
    01027   c->inaugurated_year -= ORIGINAL_BASE_YEAR;
    01028
    01029   return true;
    01030 }
    01031
    01032 static uint32 _old_order_ptr;
    01033 static uint16 _old_next_ptr;
    01034 static VehicleID _current_vehicle_id;
    01035
    01036 static const OldChunks vehicle_train_chunk[] = {
    01037   OCL_SVAR(  OC_UINT8, Train, track ),
    01038   OCL_SVAR(  OC_UINT8, Train, force_proceed ),
    01039   OCL_SVAR( OC_UINT16, Train, crash_anim_pos ),
    01040   OCL_SVAR(  OC_UINT8, Train, railtype ),
    01041
    01042   OCL_NULL( 5 ),
    01043
    01044   OCL_END()
    01045 };
    01046
    01047 static const OldChunks vehicle_road_chunk[] = {
    01048   OCL_SVAR(  OC_UINT8, RoadVehicle, state ),
    01049   OCL_SVAR(  OC_UINT8, RoadVehicle, frame ),
    01050   OCL_SVAR( OC_UINT16, RoadVehicle, blocked_ctr ),
    01051   OCL_SVAR(  OC_UINT8, RoadVehicle, overtaking ),
    01052   OCL_SVAR(  OC_UINT8, RoadVehicle, overtaking_ctr ),
    01053   OCL_SVAR( OC_UINT16, RoadVehicle, crashed_ctr ),
    01054   OCL_SVAR(  OC_UINT8, RoadVehicle, reverse_ctr ),
    01055
    01056   OCL_NULL( 1 ),
    01057
    01058   OCL_END()
    01059 };
    01060
    01061 static const OldChunks vehicle_ship_chunk[] = {
    01062   OCL_SVAR(  OC_UINT8, Ship, state ),
    01063
    01064   OCL_NULL( 9 ),
    01065
    01066   OCL_END()
    01067 };
    01068
    01069 static const OldChunks vehicle_air_chunk[] = {
    01070   OCL_SVAR(  OC_UINT8, Aircraft, pos ),
    01071   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Aircraft, targetairport ),
    01072   OCL_SVAR( OC_UINT16, Aircraft, crashed_counter ),
    01073   OCL_SVAR(  OC_UINT8, Aircraft, state ),
    01074
    01075   OCL_NULL( 5 ),
    01076
    01077   OCL_END()
    01078 };
    01079
    01080 static const OldChunks vehicle_effect_chunk[] = {
    01081   OCL_SVAR( OC_UINT16, EffectVehicle, animation_state ),
    01082   OCL_SVAR(  OC_UINT8, EffectVehicle, animation_substate ),
    01083
    01084   OCL_NULL( 7 ), // Junk
    01085
    01086   OCL_END()
    01087 };
    01088
    01089 static const OldChunks vehicle_disaster_chunk[] = {
    01090   OCL_SVAR( OC_UINT16, DisasterVehicle, image_override ),
    01091   OCL_SVAR( OC_UINT16, DisasterVehicle, big_ufo_destroyer_target ),
    01092
    01093   OCL_NULL( 6 ),
    01094
    01095   OCL_END()
    01096 };
    01097
    01098 static const OldChunks vehicle_empty_chunk[] = {
    01099   OCL_NULL( 10 ),
    01100
    01101   OCL_END()
    01102 };
    01103
    01104 static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
    01105 {
    01106   Vehicle *v = Vehicle::GetIfValid(_current_vehicle_id);
    01107   uint temp = ls->total_read;
    01108   bool res;
    01109
    01110   if (v == NULL) {
    01111     res = LoadChunk(ls, NULL, vehicle_empty_chunk);
    01112   } else {
    01113     switch (v->type) {
    01114       default: SlErrorCorrupt("Invalid vehicle type");
    01115       case VEH_TRAIN   : res = LoadChunk(ls, v, vehicle_train_chunk);    break;
    01116       case VEH_ROAD    : res = LoadChunk(ls, v, vehicle_road_chunk);     break;
    01117       case VEH_SHIP    : res = LoadChunk(ls, v, vehicle_ship_chunk);     break;
    01118       case VEH_AIRCRAFT: res = LoadChunk(ls, v, vehicle_air_chunk);      break;
    01119       case VEH_EFFECT  : res = LoadChunk(ls, v, vehicle_effect_chunk);   break;
    01120       case VEH_DISASTER: res = LoadChunk(ls, v, vehicle_disaster_chunk); break;
    01121     }
    01122   }
    01123
    01124   /* This chunk size should always be 10 bytes */
    01125   if (ls->total_read - temp != 10) {
    01126     DEBUG(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
    01127     return false;
    01128   }
    01129
    01130   return res;
    01131 }
    01132
    01133 static uint16 _cargo_count;
    01134
    01135 static const OldChunks vehicle_chunk[] = {
    01136   OCL_SVAR(  OC_UINT8, Vehicle, subtype ),
    01137
    01138   OCL_NULL( 2 ),
    01139   OCL_NULL( 2 ),
    01140
    01141   OCL_VAR ( OC_UINT32,   1, &_old_order_ptr ),
    01142   OCL_VAR ( OC_UINT16,   1, &_old_order ),
    01143
    01144   OCL_NULL ( 1 ),
    01145   OCL_SVAR(  OC_UINT8, Vehicle, cur_implicit_order_index ),
    01146   OCL_SVAR(   OC_TILE, Vehicle, dest_tile ),
    01147   OCL_SVAR( OC_UINT16, Vehicle, load_unload_ticks ),
    01148   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
    01149   OCL_SVAR( OC_UINT16, Vehicle, service_interval ),
    01150   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, last_station_visited ),
    01151   OCL_SVAR( OC_TTD | OC_UINT8, Vehicle, tick_counter ),
    01152   OCL_CNULL( OC_TTD, 2 ),
    01153   OCL_CNULL( OC_TTO, 1 ),
    01154
    01155   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, x_pos ),
    01156   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ),
    01157   OCL_SVAR( OC_FILE_U8  | OC_VAR_I32, Vehicle, z_pos ),
    01158   OCL_SVAR(  OC_UINT8, Vehicle, direction ),
    01159   OCL_NULL( 2 ),
    01160   OCL_NULL( 2 ),
    01161   OCL_NULL( 1 ),
    01162
    01163   OCL_SVAR(  OC_UINT8, Vehicle, owner ),
    01164   OCL_SVAR(   OC_TILE, Vehicle, tile ),
    01165   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, cur_image ),
    01166
    01167   OCL_NULL( 8 ),
    01168
    01169   OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Vehicle, vehstatus ),
    01170   OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cur_speed ),
    01171   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cur_speed ),
    01172   OCL_SVAR(  OC_UINT8, Vehicle, subspeed ),
    01173   OCL_SVAR(  OC_UINT8, Vehicle, acceleration ),
    01174   OCL_SVAR(  OC_UINT8, Vehicle, progress ),
    01175
    01176   OCL_SVAR(  OC_UINT8, Vehicle, cargo_type ),
    01177   OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cargo_cap ),
    01178   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cargo_cap ),
    01179   OCL_VAR ( OC_TTD | OC_UINT16, 1, &_cargo_count ),
    01180   OCL_VAR ( OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_cargo_count ),
    01181   OCL_VAR (  OC_UINT8, 1,       &_cargo_source ),
    01182   OCL_VAR (  OC_UINT8, 1,       &_cargo_days ),
    01183
    01184   OCL_SVAR( OC_TTO | OC_UINT8, Vehicle, tick_counter ),
    01185
    01186   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, age ),
    01187   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, max_age ),
    01188   OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, build_year ),
    01189   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, unitnumber ),
    01190
    01191   OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, engine_type ),
    01192   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, engine_type ),
    01193
    01194   OCL_SVAR(  OC_UINT8, Vehicle, spritenum ),
    01195   OCL_SVAR(  OC_UINT8, Vehicle, day_counter ),
    01196
    01197   OCL_SVAR(  OC_UINT8, Vehicle, breakdowns_since_last_service ),
    01198   OCL_SVAR(  OC_UINT8, Vehicle, breakdown_ctr ),
    01199   OCL_SVAR(  OC_UINT8, Vehicle, breakdown_delay ),
    01200   OCL_SVAR(  OC_UINT8, Vehicle, breakdown_chance ),
    01201
    01202   OCL_CNULL( OC_TTO, 1 ),
    01203
    01204   OCL_SVAR( OC_UINT16, Vehicle, reliability ),
    01205   OCL_SVAR( OC_UINT16, Vehicle, reliability_spd_dec ),
    01206
    01207   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_this_year ),
    01208   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_last_year ),
    01209
    01210   OCL_VAR ( OC_UINT16,   1, &_old_next_ptr ),
    01211
    01212   OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Vehicle, value ),
    01213
    01214   OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
    01215
    01216   OCL_CHUNK( 1, LoadOldVehicleUnion ),
    01217
    01218   OCL_CNULL( OC_TTO, 24 ),
    01219   OCL_CNULL( OC_TTD, 20 ),
    01220
    01221   OCL_END()
    01222 };
    01223
    01230 bool LoadOldVehicle(LoadgameState *ls, int num)
    01231 {
    01232   /* Read the TTDPatch flags, because we need some info from it */
    01233   ReadTTDPatchFlags();
    01234
    01235   for (uint i = 0; i < _old_vehicle_multiplier; i++) {
    01236     _current_vehicle_id = num * _old_vehicle_multiplier + i;
    01237
    01238     Vehicle *v;
    01239
    01240     if (_savegame_type == SGT_TTO) {
    01241       uint type = ReadByte(ls);
    01242       switch (type) {
    01243         default: return false;
    01244         case 0x00 /* VEH_INVALID  */: v = NULL;                                        break;
    01245         case 0x25 /* MONORAIL     */:
    01246         case 0x20 /* VEH_TRAIN    */: v = new (_current_vehicle_id) Train();           break;
    01247         case 0x21 /* VEH_ROAD     */: v = new (_current_vehicle_id) RoadVehicle();     break;
    01248         case 0x22 /* VEH_SHIP     */: v = new (_current_vehicle_id) Ship();            break;
    01249         case 0x23 /* VEH_AIRCRAFT */: v = new (_current_vehicle_id) Aircraft();        break;
    01250         case 0x24 /* VEH_EFFECT   */: v = new (_current_vehicle_id) EffectVehicle();   break;
    01251         case 0x26 /* VEH_DISASTER */: v = new (_current_vehicle_id) DisasterVehicle(); break;
    01252       }
    01253
    01254       if (!LoadChunk(ls, v, vehicle_chunk)) return false;
    01255       if (v == NULL) continue;
    01256       v->refit_cap = v->cargo_cap;
    01257
    01258       SpriteID sprite = v->cur_image;
    01259       /* no need to override other sprites */
    01260       if (IsInsideMM(sprite, 1460, 1465)) {
    01261         sprite += 580; // aircraft smoke puff
    01262       } else if (IsInsideMM(sprite, 2096, 2115)) {
    01263         sprite += 977; // special effects part 1
    01264       } else if (IsInsideMM(sprite, 2396, 2436)) {
    01265         sprite += 1305; // special effects part 2
    01266       } else if (IsInsideMM(sprite, 2516, 2539)) {
    01267         sprite += 1385; // rotor or disaster-related vehicles
    01268       }
    01269       v->cur_image = sprite;
    01270
    01271       switch (v->type) {
    01272         case VEH_TRAIN: {
    01273           static const byte spriteset_rail[] = {
    01274               0,   2,   4,   4,   8,  10,  12,  14,  16,  18,  20,  22,  40,  42,  44,  46,
    01275              48,  52,  54,  66,  68,  70,  72,  74,  76,  78,  80,  82,  84,  86, 120, 122,
    01276             124, 126, 128, 130, 132, 134, 136, 138, 140
    01277           };
    01278           if (v->spritenum / 2 >= lengthof(spriteset_rail)) return false;
    01279           v->spritenum = spriteset_rail[v->spritenum / 2]; // adjust railway sprite set offset
    01280           Train::From(v)->railtype = type == 0x25 ? 1 : 0; // monorail / rail
    01281           break;
    01282         }
    01283
    01284         case VEH_ROAD:
    01285           if (v->spritenum >= 22) v->spritenum += 12;
    01286           break;
    01287
    01288         case VEH_SHIP:
    01289           v->spritenum += 2;
    01290
    01291           switch (v->spritenum) {
    01292             case 2: // oil tanker && cargo type != oil
    01293               if (v->cargo_type != CT_OIL) v->spritenum = 0; // make it a coal/goods ship
    01294               break;
    01295             case 4: // passenger ship && cargo type == mail
    01296               if (v->cargo_type == CT_MAIL) v->spritenum = 0; // make it a mail ship
    01297               break;
    01298             default:
    01299               break;
    01300           }
    01301           break;
    01302
    01303         default:
    01304           break;
    01305       }
    01306
    01307       switch (_old_string_id) {
    01308         case 0x0000: break; // empty (invalid vehicles)
    01309         case 0x0006: _old_string_id  = STR_SV_EMPTY;              break; // empty (special vehicles)
    01310         case 0x8495: _old_string_id  = STR_SV_TRAIN_NAME;         break; // "Train X"
    01311         case 0x8842: _old_string_id  = STR_SV_ROAD_VEHICLE_NAME;  break; // "Road Vehicle X"
    01312         case 0x8C3B: _old_string_id  = STR_SV_SHIP_NAME;          break; // "Ship X"
    01313         case 0x9047: _old_string_id  = STR_SV_AIRCRAFT_NAME;      break; // "Aircraft X"
    01314         default:     _old_string_id += 0x2A00;                    break; // custom name
    01315       }
    01316
    01317       _old_vehicle_names[_current_vehicle_id] = _old_string_id;
    01318     } else {
    01319       /* Read the vehicle type and allocate the right vehicle */
    01320       switch (ReadByte(ls)) {
    01321         default: SlErrorCorrupt("Invalid vehicle type");
    01322         case 0x00 /* VEH_INVALID */: v = NULL;                                        break;
    01323         case 0x10 /* VEH_TRAIN   */: v = new (_current_vehicle_id) Train();           break;
    01324         case 0x11 /* VEH_ROAD    */: v = new (_current_vehicle_id) RoadVehicle();     break;
    01325         case 0x12 /* VEH_SHIP    */: v = new (_current_vehicle_id) Ship();            break;
    01326         case 0x13 /* VEH_AIRCRAFT*/: v = new (_current_vehicle_id) Aircraft();        break;
    01327         case 0x14 /* VEH_EFFECT  */: v = new (_current_vehicle_id) EffectVehicle();   break;
    01328         case 0x15 /* VEH_DISASTER*/: v = new (_current_vehicle_id) DisasterVehicle(); break;
    01329       }
    01330
    01331       if (!LoadChunk(ls, v, vehicle_chunk)) return false;
    01332       if (v == NULL) continue;
    01333
    01334       _old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
    01335
    01336       /* This should be consistent, else we have a big problem... */
    01337       if (v->index != _current_vehicle_id) {
    01338         DEBUG(oldloader, 0, "Loading failed - vehicle-array is invalid");
    01339         return false;
    01340       }
    01341     }
    01342
    01343     if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
    01344       uint max = _savegame_type == SGT_TTO ? 3000 : 5000;
    01345       uint old_id = RemapOrderIndex(_old_order_ptr);
    01346       if (old_id < max) v->orders.old = Order::Get(old_id); // don't accept orders > max number of orders
    01347     }
    01348     v->current_order.AssignOrder(UnpackOldOrder(_old_order));
    01349
    01350     v->next = (Vehicle *)(size_t)_old_next_ptr;
    01351
    01352     if (_cargo_count != 0 && CargoPacket::CanAllocateItem()) {
    01353       StationID source =    (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
    01354       TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : 0;
    01355       v->cargo.Append(new CargoPacket(_cargo_count, _cargo_days, source, source_xy, source_xy));
    01356     }
    01357   }
    01358
    01359   return true;
    01360 }
    01361
    01362 static const OldChunks sign_chunk[] = {
    01363   OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
    01364   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, x ),
    01365   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, y ),
    01366   OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, Sign, z ),
    01367
    01368   OCL_NULL( 6 ),
    01369
    01370   OCL_END()
    01371 };
    01372
    01373 static bool LoadOldSign(LoadgameState *ls, int num)
    01374 {
    01375   Sign *si = new (num) Sign();
    01376   if (!LoadChunk(ls, si, sign_chunk)) return false;
    01377
    01378   if (_old_string_id != 0) {
    01379     if (_savegame_type == SGT_TTO) {
    01380       if (_old_string_id != 0x140A) si->name = CopyFromOldName(_old_string_id + 0x2A00);
    01381     } else {
    01382       si->name = CopyFromOldName(RemapOldStringID(_old_string_id));
    01383     }
    01384     si->owner = OWNER_NONE;
    01385   } else {
    01386     delete si;
    01387   }
    01388
    01389   return true;
    01390 }
    01391
    01392 static const OldChunks engine_chunk[] = {
    01393   OCL_SVAR( OC_UINT16, Engine, company_avail ),
    01394   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, intro_date ),
    01395   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, age ),
    01396   OCL_SVAR( OC_UINT16, Engine, reliability ),
    01397   OCL_SVAR( OC_UINT16, Engine, reliability_spd_dec ),
    01398   OCL_SVAR( OC_UINT16, Engine, reliability_start ),
    01399   OCL_SVAR( OC_UINT16, Engine, reliability_max ),
    01400   OCL_SVAR( OC_UINT16, Engine, reliability_final ),
    01401   OCL_SVAR( OC_UINT16, Engine, duration_phase_1 ),
    01402   OCL_SVAR( OC_UINT16, Engine, duration_phase_2 ),
    01403   OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
    01404
    01405   OCL_NULL( 1 ), // lifelength
    01406   OCL_SVAR(  OC_UINT8, Engine, flags ),
    01407   OCL_NULL( 1 ), // preview_company_rank
    01408   OCL_SVAR(  OC_UINT8, Engine, preview_wait ),
    01409
    01410   OCL_CNULL( OC_TTD, 2 ),
    01411
    01412   OCL_END()
    01413 };
    01414
    01415 static bool LoadOldEngine(LoadgameState *ls, int num)
    01416 {
    01417   Engine *e = _savegame_type == SGT_TTO ? &_old_engines[num] : GetTempDataEngine(num);
    01418   return LoadChunk(ls, e, engine_chunk);
    01419 }
    01420
    01421 static bool LoadOldEngineName(LoadgameState *ls, int num)
    01422 {
    01423   Engine *e = GetTempDataEngine(num);
    01424   e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
    01425   return true;
    01426 }
    01427
    01428 static const OldChunks subsidy_chunk[] = {
    01429   OCL_SVAR(  OC_UINT8, Subsidy, cargo_type ),
    01430   OCL_SVAR(  OC_UINT8, Subsidy, remaining ),
    01431   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, src ),
    01432   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, dst ),
    01433
    01434   OCL_END()
    01435 };
    01436
    01437 static bool LoadOldSubsidy(LoadgameState *ls, int num)
    01438 {
    01439   Subsidy *s = new (num) Subsidy();
    01440   bool ret = LoadChunk(ls, s, subsidy_chunk);
    01441   if (s->cargo_type == CT_INVALID) delete s;
    01442   return ret;
    01443 }
    01444
    01445 static const OldChunks game_difficulty_chunk[] = {
    01446   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, max_no_competitors ),
    01447   OCL_NULL( 2), // competitor_start_time
    01448   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, number_towns ),
    01449   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, industry_density ),
    01450   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, DifficultySettings, max_loan ),
    01451   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, initial_interest ),
    01452   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, vehicle_costs ),
    01453   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, competitor_speed ),
    01454   OCL_NULL( 2), // competitor_intelligence
    01455   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, vehicle_breakdowns ),
    01456   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, subsidy_multiplier ),
    01457   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, construction_cost ),
    01458   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, terrain_type ),
    01459   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, quantity_sea_lakes ),
    01460   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, economy ),
    01461   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, line_reverse_mode ),
    01462   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, disasters ),
    01463   OCL_END()
    01464 };
    01465
    01466 static bool LoadOldGameDifficulty(LoadgameState *ls, int num)
    01467 {
    01468   bool ret = LoadChunk(ls, &_settings_game.difficulty, game_difficulty_chunk);
    01469   _settings_game.difficulty.max_loan *= 1000;
    01470   return ret;
    01471 }
    01472
    01473
    01474 static bool LoadOldMapPart1(LoadgameState *ls, int num)
    01475 {
    01476   if (_savegame_type == SGT_TTO) {
    01477     MemSetT(_m, 0, OLD_MAP_SIZE);
    01478     MemSetT(_me, 0, OLD_MAP_SIZE);
    01479   }
    01480
    01481   for (uint i = 0; i < OLD_MAP_SIZE; i++) {
    01482     _m[i].m1 = ReadByte(ls);
    01483   }
    01484   for (uint i = 0; i < OLD_MAP_SIZE; i++) {
    01485     _m[i].m2 = ReadByte(ls);
    01486   }
    01487
    01488   if (_savegame_type != SGT_TTO) {
    01489     for (uint i = 0; i < OLD_MAP_SIZE; i++) {
    01490       _old_map3[i * 2] = ReadByte(ls);
    01491       _old_map3[i * 2 + 1] = ReadByte(ls);
    01492     }
    01493     for (uint i = 0; i < OLD_MAP_SIZE / 4; i++) {
    01494       byte b = ReadByte(ls);
    01495       _m[i * 4 + 0].m6 = GB(b, 0, 2);
    01496       _m[i * 4 + 1].m6 = GB(b, 2, 2);
    01497       _m[i * 4 + 2].m6 = GB(b, 4, 2);
    01498       _m[i * 4 + 3].m6 = GB(b, 6, 2);
    01499     }
    01500   }
    01501
    01502   return true;
    01503 }
    01504
    01505 static bool LoadOldMapPart2(LoadgameState *ls, int num)
    01506 {
    01507   uint i;
    01508
    01509   for (i = 0; i < OLD_MAP_SIZE; i++) {
    01510     _m[i].type_height = ReadByte(ls);
    01511   }
    01512   for (i = 0; i < OLD_MAP_SIZE; i++) {
    01513     _m[i].m5 = ReadByte(ls);
    01514   }
    01515
    01516   return true;
    01517 }
    01518
    01519 static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num)
    01520 {
    01521   ReadTTDPatchFlags();
    01522
    01523   DEBUG(oldloader, 2, "Found %d extra chunk(s)", _old_extra_chunk_nums);
    01524
    01525   for (int i = 0; i != _old_extra_chunk_nums; i++) {
    01526     uint16 id = ReadUint16(ls);
    01527     uint32 len = ReadUint32(ls);
    01528
    01529     switch (id) {
    01530       /* List of GRFIDs, used in the savegame. 0x8004 is the new ID
    01531        * They are saved in a 'GRFID:4 active:1' format, 5 bytes for each entry */
    01532       case 0x2:
    01533       case 0x8004: {
    01534         /* Skip the first element: TTDP hack for the Action D special variables (FFFF0000 01) */
    01535         ReadUint32(ls); ReadByte(ls); len -= 5;
    01536
    01537         ClearGRFConfigList(&_grfconfig);
    01538         while (len != 0) {
    01539           uint32 grfid = ReadUint32(ls);
    01540
    01541           if (ReadByte(ls) == 1) {
    01542             GRFConfig *c = new GRFConfig("TTDP game, no information");
    01543             c->ident.grfid = grfid;
    01544
    01545             AppendToGRFConfigList(&_grfconfig, c);
    01546             DEBUG(oldloader, 3, "TTDPatch game using GRF file with GRFID %0X", BSWAP32(c->ident.grfid));
    01547           }
    01548           len -= 5;
    01549         }
    01550
    01551         /* Append static NewGRF configuration */
    01552         AppendStaticGRFConfigs(&_grfconfig);
    01553         break;
    01554       }
    01555
    01556       /* TTDPatch version and configuration */
    01557       case 0x3:
    01558         _ttdp_version = ReadUint32(ls);
    01559         DEBUG(oldloader, 3, "Game saved with TTDPatch version %d.%d.%d r%d",
    01560           GB(_ttdp_version, 24, 8), GB(_ttdp_version, 20, 4), GB(_ttdp_version, 16, 4), GB(_ttdp_version, 0, 16));
    01561         len -= 4;
    01562         while (len-- != 0) ReadByte(ls); // skip the configuration
    01563         break;
    01564
    01565       default:
    01566         DEBUG(oldloader, 4, "Skipping unknown extra chunk %X", id);
    01567         while (len-- != 0) ReadByte(ls);
    01568         break;
    01569     }
    01570   }
    01571
    01572   return true;
    01573 }
    01574
    01575 extern TileIndex _cur_tileloop_tile;
    01576 extern uint16 _disaster_delay;
    01577 extern byte _trees_tick_ctr;
    01578 extern byte _age_cargo_skip_counter; // From misc_sl.cpp
    01579 extern uint8 _old_diff_level;
    01580 static const OldChunks main_chunk[] = {
    01581   OCL_ASSERT( OC_TTD, 0 ),
    01582   OCL_ASSERT( OC_TTO, 0 ),
    01583   OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_date ),
    01584   OCL_VAR ( OC_UINT16,   1, &_date_fract ),
    01585   OCL_NULL( 600 ),
    01586   OCL_VAR ( OC_UINT32,   2, &_random.state ),
    01587
    01588   OCL_ASSERT( OC_TTD, 0x264 ),
    01589   OCL_ASSERT( OC_TTO, 0x264 ),
    01590
    01591   OCL_CCHUNK( OC_TTD, 70, LoadOldTown ),
    01592   OCL_CCHUNK( OC_TTO, 80, LoadOldTown ),
    01593
    01594   OCL_ASSERT( OC_TTD, 0x1C18 ),
    01595   OCL_ASSERT( OC_TTO, 0x1AC4 ),
    01596
    01597   OCL_CCHUNK( OC_TTD, 5000, LoadOldOrder ),
    01598   OCL_CCHUNK( OC_TTO, 3000, LoadOldOrder ),
    01599
    01600   OCL_ASSERT( OC_TTD, 0x4328 ),
    01601   OCL_ASSERT( OC_TTO, 0x3234 ),
    01602
    01603   OCL_CHUNK( 1, LoadOldAnimTileList ),
    01604   OCL_NULL( 4 ),
    01605
    01606   OCL_ASSERT( OC_TTO, 0x3438 ),
    01607
    01608   OCL_CCHUNK( OC_TTD, 255, LoadOldDepot ),
    01609   OCL_CCHUNK( OC_TTO, 252, LoadOldDepot ),
    01610
    01611   OCL_ASSERT( OC_TTD, 0x4B26 ),
    01612   OCL_ASSERT( OC_TTO, 0x3A20 ),
    01613
    01614   OCL_NULL( 4 ),
    01615   OCL_NULL( 2 ),
    01616   OCL_NULL( 2 ),
    01617
    01618   OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ),
    01619   OCL_VAR ( OC_UINT16,   1, &_tick_counter ),
    01620   OCL_VAR (   OC_TILE,   1, &_cur_tileloop_tile ),
    01621
    01622   OCL_ASSERT( OC_TTO, 0x3A2E ),
    01623
    01624   OCL_CNULL( OC_TTO, 48 * 6 ),
    01625   OCL_CNULL( OC_TTD, 49 * 6 ),
    01626
    01627   OCL_ASSERT( OC_TTO, 0x3B4E ),
    01628
    01629   OCL_CNULL( OC_TTO, 11 * 8 ),
    01630   OCL_CNULL( OC_TTD, 12 * 8 ),
    01631
    01632   OCL_ASSERT( OC_TTD, 0x4CBA ),
    01633   OCL_ASSERT( OC_TTO, 0x3BA6 ),
    01634
    01635   OCL_CHUNK( 1, LoadOldMapPart1 ),
    01636
    01637   OCL_ASSERT( OC_TTD, 0x48CBA ),
    01638   OCL_ASSERT( OC_TTO, 0x23BA6 ),
    01639
    01640   OCL_CCHUNK( OC_TTD, 250, LoadOldStation ),
    01641   OCL_CCHUNK( OC_TTO, 200, LoadOldStation ),
    01642
    01643   OCL_ASSERT( OC_TTO, 0x29E16 ),
    01644
    01645   OCL_CCHUNK( OC_TTD, 90, LoadOldIndustry ),
    01646   OCL_CCHUNK( OC_TTO, 100, LoadOldIndustry ),
    01647
    01648   OCL_ASSERT( OC_TTO, 0x2ADB6 ),
    01649
    01650   OCL_CHUNK(  8, LoadOldCompany ),
    01651
    01652   OCL_ASSERT( OC_TTD, 0x547F2 ),
    01653   OCL_ASSERT( OC_TTO, 0x2C746 ),
    01654
    01655   OCL_CCHUNK( OC_TTD, 850, LoadOldVehicle ),
    01656   OCL_CCHUNK( OC_TTO, 800, LoadOldVehicle ),
    01657
    01658   OCL_ASSERT( OC_TTD, 0x6F0F2 ),
    01659   OCL_ASSERT( OC_TTO, 0x45746 ),
    01660
    01661   OCL_VAR ( OC_TTD | OC_UINT8 | OC_DEREFERENCE_POINTER, 32 * 500, &_old_name_array ),
    01662   OCL_VAR ( OC_TTO | OC_UINT8 | OC_DEREFERENCE_POINTER, 24 * 200, &_old_name_array ),
    01663
    01664   OCL_ASSERT( OC_TTO, 0x46A06 ),
    01665
    01666   OCL_NULL( 0x2000 ),
    01667
    01668   OCL_CHUNK( 40, LoadOldSign ),
    01669
    01670   OCL_ASSERT( OC_TTO, 0x48C36 ),
    01671
    01672   OCL_CCHUNK( OC_TTD, 256, LoadOldEngine ),
    01673   OCL_CCHUNK( OC_TTO, 103, LoadOldEngine ),
    01674
    01675   OCL_ASSERT( OC_TTO, 0x496AC ),
    01676
    01677   OCL_NULL ( 2 ), // _vehicle_id_ctr_day
    01678
    01679   OCL_CHUNK(  8, LoadOldSubsidy ),
    01680
    01681   OCL_ASSERT( OC_TTO, 0x496CE ),
    01682
    01683   OCL_VAR ( OC_FILE_U16 | OC_VAR_U32,   1, &_next_competitor_start ),
    01684
    01685   OCL_CNULL( OC_TTO, 2 ),
    01686
    01687   OCL_VAR ( OC_FILE_I16 | OC_VAR_I32,   1, &_saved_scrollpos_x ),
    01688   OCL_VAR ( OC_FILE_I16 | OC_VAR_I32,   1, &_saved_scrollpos_y ),
    01689   OCL_VAR ( OC_FILE_U16 | OC_VAR_U8,    1, &_saved_scrollpos_zoom ),
    01690
    01691   OCL_NULL( 4 ),
    01692   OCL_VAR ( OC_FILE_U32 | OC_VAR_I64,   1, &_economy.old_max_loan_unround ),
    01693   OCL_VAR (  OC_INT16,    1, &_economy.fluct ),
    01694
    01695   OCL_VAR ( OC_UINT16,    1, &_disaster_delay ),
    01696
    01697   OCL_ASSERT( OC_TTO, 0x496E4 ),
    01698
    01699   OCL_CNULL( OC_TTD, 144 ),
    01700
    01701   OCL_CCHUNK( OC_TTD, 256, LoadOldEngineName ),
    01702
    01703   OCL_CNULL( OC_TTD, 144 ),
    01704   OCL_NULL( 2 ),
    01705   OCL_NULL( 1 ),
    01706
    01707   OCL_VAR (  OC_UINT8,    1, &_settings_game.locale.currency ),
    01708   OCL_VAR (  OC_UINT8,    1, &_settings_game.locale.units ),
    01709   OCL_VAR ( OC_FILE_U8 | OC_VAR_U32,    1, &_cur_company_tick_index ),
    01710
    01711   OCL_NULL( 2 ),
    01712   OCL_NULL( 8 ),
    01713
    01714   OCL_VAR (  OC_UINT8,    1, &_economy.infl_amount ),
    01715   OCL_VAR (  OC_UINT8,    1, &_economy.infl_amount_pr ),
    01716   OCL_VAR (  OC_UINT8,    1, &_economy.interest_rate ),
    01717   OCL_NULL( 1 ), // available airports
    01718   OCL_VAR (  OC_UINT8,    1, &_settings_game.vehicle.road_side ),
    01719   OCL_VAR (  OC_UINT8,    1, &_settings_game.game_creation.town_name ),
    01720
    01721   OCL_CHUNK( 1, LoadOldGameDifficulty ),
    01722
    01723   OCL_ASSERT( OC_TTD, 0x77130 ),
    01724
    01725   OCL_VAR (  OC_UINT8,    1, &_old_diff_level ),
    01726
    01727   OCL_VAR ( OC_TTD | OC_UINT8,    1, &_settings_game.game_creation.landscape ),
    01728   OCL_VAR ( OC_TTD | OC_UINT8,    1, &_trees_tick_ctr ),
    01729
    01730   OCL_CNULL( OC_TTD, 1 ),
    01731   OCL_VAR ( OC_TTD | OC_UINT8,    1, &_settings_game.game_creation.snow_line_height ),
    01732
    01733   OCL_CNULL( OC_TTD, 32 ),
    01734   OCL_CNULL( OC_TTD, 36 ),
    01735
    01736   OCL_ASSERT( OC_TTD, 0x77179 ),
    01737   OCL_ASSERT( OC_TTO, 0x4971D ),
    01738
    01739   OCL_CHUNK( 1, LoadOldMapPart2 ),
    01740
    01741   OCL_ASSERT( OC_TTD, 0x97179 ),
    01742   OCL_ASSERT( OC_TTO, 0x6971D ),
    01743
    01744   /* Below any (if available) extra chunks from TTDPatch can follow */
    01745   OCL_CHUNK(1, LoadTTDPatchExtraChunks),
    01746
    01747   OCL_END()
    01748 };
    01749
    01750 bool LoadTTDMain(LoadgameState *ls)
    01751 {
    01752   DEBUG(oldloader, 3, "Reading main chunk...");
    01753
    01754   _read_ttdpatch_flags = false;
    01755
    01756   /* Load the biggest chunk */
    01757   SmallStackSafeStackAlloc<byte, OLD_MAP_SIZE * 2> map3;
    01758   _old_map3 = map3.data;
    01759   _old_vehicle_names = NULL;
    01760   try {
    01761     if (!LoadChunk(ls, NULL, main_chunk)) {
    01762       DEBUG(oldloader, 0, "Loading failed");
    01763       free(_old_vehicle_names);
    01764       return false;
    01765     }
    01766   } catch (...) {
    01767     free(_old_vehicle_names);
    01768     throw;
    01769   }
    01770
    01771   DEBUG(oldloader, 3, "Done, converting game data...");
    01772
    01773   FixTTDMapArray();
    01774   FixTTDDepots();
    01775
    01776   /* Fix some general stuff */
    01777   _settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
    01778
    01779   /* Fix the game to be compatible with OpenTTD */
    01780   FixOldTowns();
    01781   FixOldVehicles();
    01782
    01783   /* We have a new difficulty setting */
    01784   _settings_game.difficulty.town_council_tolerance = Clamp(_old_diff_level, 0, 2);
    01785
    01786   DEBUG(oldloader, 3, "Finished converting game data");
    01787   DEBUG(oldloader, 1, "TTD(Patch) savegame successfully converted");
    01788
    01789   free(_old_vehicle_names);
    01790
    01791   return true;
    01792 }
    01793
    01794 bool LoadTTOMain(LoadgameState *ls)
    01795 {
    01796   DEBUG(oldloader, 3, "Reading main chunk...");
    01797
    01798   _read_ttdpatch_flags = false;
    01799
    01800   SmallStackSafeStackAlloc<byte, 103 * sizeof(Engine)> engines; // we don't want to call Engine constructor here
    01801   _old_engines = (Engine *)engines.data;
    01802   SmallStackSafeStackAlloc<StringID, 800> vehnames;
    01803   _old_vehicle_names = vehnames.data;
    01804
    01805   /* Load the biggest chunk */
    01806   if (!LoadChunk(ls, NULL, main_chunk)) {
    01807     DEBUG(oldloader, 0, "Loading failed");
    01808     return false;
    01809   }
    01810   DEBUG(oldloader, 3, "Done, converting game data...");
    01811
    01812   if (_settings_game.game_creation.town_name != 0) _settings_game.game_creation.town_name++;
    01813
    01814   _settings_game.game_creation.landscape = 0;
    01815   _trees_tick_ctr = 0xFF;
    01816
    01817   if (!FixTTOMapArray() || !FixTTOEngines()) {
    01818     DEBUG(oldloader, 0, "Conversion failed");
    01819     return false;
    01820   }
    01821
    01822   FixOldTowns();
    01823   FixOldVehicles();
    01824   FixTTOCompanies();
    01825
    01826   /* We have a new difficulty setting */
    01827   _settings_game.difficulty.town_council_tolerance = Clamp(_old_diff_level, 0, 2);
    01828
    01829   /* SVXConverter about cargo payment rates correction:
    01830    * "increase them to compensate for the faster time advance in TTD compared to TTO
    01831    * which otherwise would cause much less income while the annual running costs of
    01832    * the vehicles stay the same" */
    01833   _economy.inflation_payment = min(_economy.inflation_payment * 124 / 74, MAX_INFLATION);
    01834
    01835   DEBUG(oldloader, 3, "Finished converting game data");
    01836   DEBUG(oldloader, 1, "TTO savegame successfully converted");
    01837
    01838   return true;
    01839 }