# 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_rank = 0;
    00449     e->preview_wait = 0;
    00450     e->name = NULL;
    00451   }
    00452
    00453   return true;
    00454 }
    00455
    00456 static void FixTTOCompanies()
    00457 {
    00458   Company *c;
    00459   FOR_ALL_COMPANIES(c) {
    00460     c->cur_economy.company_value = CalculateCompanyValue(c); // company value history is zeroed
    00461   }
    00462 }
    00463
    00464 static inline byte RemapTTOColour(byte tto)
    00465 {
    00467   static const byte tto_colour_remap[] = {
    00468     COLOUR_DARK_BLUE,  COLOUR_GREY,       COLOUR_YELLOW,     COLOUR_RED,
    00469     COLOUR_PURPLE,     COLOUR_DARK_GREEN, COLOUR_ORANGE,     COLOUR_PALE_GREEN,
    00470     COLOUR_BLUE,       COLOUR_GREEN,      COLOUR_CREAM,      COLOUR_BROWN,
    00471     COLOUR_WHITE,      COLOUR_LIGHT_BLUE, COLOUR_MAUVE,      COLOUR_PINK
    00472   };
    00473
    00474   if ((size_t)tto >= lengthof(tto_colour_remap)) return COLOUR_GREY; // this shouldn't happen
    00475
    00476   return tto_colour_remap[tto];
    00477 }
    00478
    00479 static inline uint RemapTownIndex(uint x)
    00480 {
    00481   return _savegame_type == SGT_TTO ? (x - 0x264) / 78 : (x - 0x264) / 94;
    00482 }
    00483
    00484 static inline uint RemapOrderIndex(uint x)
    00485 {
    00486   return _savegame_type == SGT_TTO ? (x - 0x1AC4) / 2 : (x - 0x1C18) / 2;
    00487 }
    00488
    00489 extern TileIndex *_animated_tile_list;
    00490 extern uint _animated_tile_count;
    00491 extern char *_old_name_array;
    00492
    00493 static uint32 _old_town_index;
    00494 static uint16 _old_string_id;
    00495 static uint16 _old_string_id_2;
    00496
    00497 static void ReadTTDPatchFlags()
    00498 {
    00499   if (_read_ttdpatch_flags) return;
    00500
    00501   _read_ttdpatch_flags = true;
    00502
    00503   /* Set default values */
    00504   _old_vehicle_multiplier = 1;
    00505   _ttdp_version = 0;
    00506   _old_extra_chunk_nums = 0;
    00507   _bump_assert_value = 0;
    00508
    00509   if (_savegame_type == SGT_TTO) return;
    00510
    00511   /* TTDPatch misuses _old_map3 for flags.. read them! */
    00512   _old_vehicle_multiplier = _old_map3[0];
    00513   /* Somehow.... there was an error in some savegames, so 0 becomes 1
    00514    * and 1 becomes 2. The rest of the values are okay */
    00515   if (_old_vehicle_multiplier < 2) _old_vehicle_multiplier++;
    00516
    00517   _old_vehicle_names = MallocT<StringID>(_old_vehicle_multiplier * 850);
    00518
    00519   /* TTDPatch increases the Vehicle-part in the middle of the game,
    00520    * so if the multiplier is anything else but 1, the assert fails..
    00521    * bump the assert value so it doesn't!
    00522    * (1 multiplier == 850 vehicles
    00523    * 1 vehicle   == 128 bytes */
    00524   _bump_assert_value = (_old_vehicle_multiplier - 1) * 850 * 128;
    00525
    00526   for (uint i = 0; i < 17; i++) { // check tile 0, too
    00527     if (_old_map3[i] != 0) _savegame_type = SGT_TTDP1;
    00528   }
    00529
    00530   /* Check if we have a modern TTDPatch savegame (has extra data all around) */
    00531   if (memcmp(&_old_map3[0x1FFFA], "TTDp", 4) == 0) _savegame_type = SGT_TTDP2;
    00532
    00533   _old_extra_chunk_nums = _old_map3[_savegame_type == SGT_TTDP2 ? 0x1FFFE : 0x2];
    00534
    00535   /* Clean the misused places */
    00536   for (uint i = 0;       i < 17;      i++) _old_map3[i] = 0;
    00537   for (uint i = 0x1FE00; i < 0x20000; i++) _old_map3[i] = 0;
    00538
    00539   if (_savegame_type == SGT_TTDP2) DEBUG(oldloader, 2, "Found TTDPatch game");
    00540
    00541   DEBUG(oldloader, 3, "Vehicle-multiplier is set to %d (%d vehicles)", _old_vehicle_multiplier, _old_vehicle_multiplier * 850);
    00542 }
    00543
    00544 static const OldChunks town_chunk[] = {
    00545   OCL_SVAR(   OC_TILE, Town, xy ),
    00546   OCL_NULL( 2 ),
    00547   OCL_SVAR( OC_UINT16, Town, townnametype ),
    00548   OCL_SVAR( OC_UINT32, Town, townnameparts ),
    00549   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Town, grow_counter ),
    00550   OCL_NULL( 1 ),
    00551   OCL_NULL( 4 ),
    00552   OCL_NULL( 2 ),
    00553   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, Town, flags ),
    00554   OCL_NULL( 10 ),
    00555
    00556   OCL_SVAR( OC_INT16, Town, ratings[0] ),
    00557   OCL_SVAR( OC_INT16, Town, ratings[1] ),
    00558   OCL_SVAR( OC_INT16, Town, ratings[2] ),
    00559   OCL_SVAR( OC_INT16, Town, ratings[3] ),
    00560   OCL_SVAR( OC_INT16, Town, ratings[4] ),
    00561   OCL_SVAR( OC_INT16, Town, ratings[5] ),
    00562   OCL_SVAR( OC_INT16, Town, ratings[6] ),
    00563   OCL_SVAR( OC_INT16, Town, ratings[7] ),
    00564
    00565   OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, have_ratings ),
    00566   OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, statues ),
    00567   OCL_NULL( 2 ),
    00568   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Town, time_until_rebuild ),
    00569   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Town, growth_rate ),
    00570
    00571   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].new_max ),
    00572   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].new_max ),
    00573   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].new_act ),
    00574   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].new_act ),
    00575   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].old_max ),
    00576   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].old_max ),
    00577   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].old_act ),
    00578   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].old_act ),
    00579
    00580   OCL_NULL( 2 ),
    00581
    00582   OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_FOOD].new_act ),
    00583   OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_WATER].new_act ),
    00584   OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_FOOD].old_act ),
    00585   OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_WATER].old_act ),
    00586
    00587   OCL_SVAR(  OC_UINT8, Town, road_build_months ),
    00588   OCL_SVAR(  OC_UINT8, Town, fund_buildings_months ),
    00589
    00590   OCL_CNULL( OC_TTD, 8 ),
    00591
    00592   OCL_END()
    00593 };
    00594
    00595 static bool LoadOldTown(LoadgameState *ls, int num)
    00596 {
    00597   Town *t = new (num) Town();
    00598   if (!LoadChunk(ls, t, town_chunk)) return false;
    00599
    00600   if (t->xy != 0) {
    00601     if (_savegame_type == SGT_TTO) {
    00602       /* 0x10B6 is auto-generated name, others are custom names */
    00603       t->townnametype = t->townnametype == 0x10B6 ? 0x20C1 : t->townnametype + 0x2A00;
    00604     }
    00605   } else {
    00606     delete t;
    00607   }
    00608
    00609   return true;
    00610 }
    00611
    00612 static uint16 _old_order;
    00613 static const OldChunks order_chunk[] = {
    00614   OCL_VAR ( OC_UINT16,   1, &_old_order ),
    00615   OCL_END()
    00616 };
    00617
    00618 static bool LoadOldOrder(LoadgameState *ls, int num)
    00619 {
    00620   if (!LoadChunk(ls, NULL, order_chunk)) return false;
    00621
    00622   Order *o = new (num) Order();
    00623   o->AssignOrder(UnpackOldOrder(_old_order));
    00624
    00625   if (o->IsType(OT_NOTHING)) {
    00626     delete o;
    00627   } else {
    00628     /* Relink the orders to eachother (in the orders for one vehicle are behind eachother,
    00629      * with an invalid order (OT_NOTHING) as indication that it is the last order */
    00630     Order *prev = Order::GetIfValid(num - 1);
    00631     if (prev != NULL) prev->next = o;
    00632   }
    00633
    00634   return true;
    00635 }
    00636
    00637 static bool LoadOldAnimTileList(LoadgameState *ls, int num)
    00638 {
    00639   /* This is sligthly hackish - we must load a chunk into an array whose
    00640    * address isn't static, but instead pointed to by _animated_tile_list.
    00641    * To achieve that, create an OldChunks list on the stack on the fly.
    00642    * The list cannot be static because the value of _animated_tile_list
    00643    * can change between calls. */
    00644
    00645   const OldChunks anim_chunk[] = {
    00646     OCL_VAR (   OC_TILE, 256, _animated_tile_list ),
    00647     OCL_END ()
    00648   };
    00649
    00650   if (!LoadChunk(ls, NULL, anim_chunk)) return false;
    00651
    00652   /* Update the animated tile counter by counting till the first zero in the array */
    00653   for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
    00654     if (_animated_tile_list[_animated_tile_count] == 0) break;
    00655   }
    00656
    00657   return true;
    00658 }
    00659
    00660 static const OldChunks depot_chunk[] = {
    00661   OCL_SVAR(   OC_TILE, Depot, xy ),
    00662   OCL_VAR ( OC_UINT32,                1, &_old_town_index ),
    00663   OCL_END()
    00664 };
    00665
    00666 static bool LoadOldDepot(LoadgameState *ls, int num)
    00667 {
    00668   Depot *d = new (num) Depot();
    00669   if (!LoadChunk(ls, d, depot_chunk)) return false;
    00670
    00671   if (d->xy != 0) {
    00672     /* In some cases, there could be depots referencing invalid town. */
    00673     Town *t = Town::GetIfValid(RemapTownIndex(_old_town_index));
    00674     if (t == NULL) t = Town::GetRandom();
    00675     d->town = t;
    00676   } else {
    00677     delete d;
    00678   }
    00679
    00680   return true;
    00681 }
    00682
    00683 static StationID _current_station_id;
    00684 static uint16 _waiting_acceptance;
    00685 static uint8  _cargo_source;
    00686 static uint8  _cargo_days;
    00687
    00688 static const OldChunks goods_chunk[] = {
    00689   OCL_VAR ( OC_UINT16, 1,          &_waiting_acceptance ),
    00690   OCL_SVAR(  OC_UINT8, GoodsEntry, time_since_pickup ),
    00691   OCL_SVAR(  OC_UINT8, GoodsEntry, rating ),
    00692   OCL_VAR (  OC_UINT8, 1,          &_cargo_source ),
    00693   OCL_VAR (  OC_UINT8, 1,          &_cargo_days ),
    00694   OCL_SVAR(  OC_UINT8, GoodsEntry, last_speed ),
    00695   OCL_SVAR(  OC_UINT8, GoodsEntry, last_age ),
    00696
    00697   OCL_END()
    00698 };
    00699
    00700 static bool LoadOldGood(LoadgameState *ls, int num)
    00701 {
    00702   /* for TTO games, 12th (num == 11) goods entry is created in the Station constructor */
    00703   if (_savegame_type == SGT_TTO && num == 11) return true;
    00704
    00705   Station *st = Station::Get(_current_station_id);
    00706   GoodsEntry *ge = &st->goods[num];
    00707
    00708   if (!LoadChunk(ls, ge, goods_chunk)) return false;
    00709
    00710   SB(ge->acceptance_pickup, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
    00711   SB(ge->acceptance_pickup, GoodsEntry::GES_PICKUP, 1, _cargo_source != 0xFF);
    00712   if (GB(_waiting_acceptance, 0, 12) != 0 && CargoPacket::CanAllocateItem()) {
    00713     ge->cargo.Append(INVALID_STATION, new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, 0, 0));
    00714   }
    00715
    00716   return true;
    00717 }
    00718
    00719 static const OldChunks station_chunk[] = {
    00720   OCL_SVAR(   OC_TILE, Station, xy ),
    00721   OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
    00722
    00723   OCL_NULL( 4 ),
    00724   OCL_SVAR(   OC_TILE, Station, train_station.tile ),
    00725   OCL_SVAR(   OC_TILE, Station, airport.tile ),
    00726   OCL_SVAR(   OC_TILE, Station, dock_tile ),
    00727   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Station, train_station.w ),
    00728
    00729   OCL_NULL( 1 ),
    00730   OCL_NULL( 2 ),
    00731
    00732   OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
    00733
    00734   OCL_NULL( 4 ),
    00735
    00736   OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Station, had_vehicle_of_type ),
    00737
    00738   OCL_CHUNK( 12, LoadOldGood ),
    00739
    00740   OCL_SVAR(  OC_UINT8, Station, time_since_load ),
    00741   OCL_SVAR(  OC_UINT8, Station, time_since_unload ),
    00742   OCL_SVAR(  OC_UINT8, Station, delete_ctr ),
    00743   OCL_SVAR(  OC_UINT8, Station, owner ),
    00744   OCL_SVAR(  OC_UINT8, Station, facilities ),
    00745   OCL_SVAR( OC_TTD | OC_UINT8, Station, airport.type ),
    00746   OCL_SVAR( OC_TTO | OC_FILE_U16 | OC_VAR_U64, Station, airport.flags ),
    00747   OCL_NULL( 3 ),
    00748   OCL_CNULL( OC_TTD, 1 ),
    00749   OCL_SVAR( OC_TTD | OC_FILE_U16 | OC_VAR_U64, Station, airport.flags ),
    00750   OCL_CNULL( OC_TTD, 2 ),
    00751   OCL_CNULL( OC_TTD, 4 ),
    00752
    00753   OCL_END()
    00754 };
    00755
    00756 static bool LoadOldStation(LoadgameState *ls, int num)
    00757 {
    00758   Station *st = new (num) Station();
    00759   _current_station_id = num;
    00760
    00761   if (!LoadChunk(ls, st, station_chunk)) return false;
    00762
    00763   if (st->xy != 0) {
    00764     st->town = Town::Get(RemapTownIndex(_old_town_index));
    00765
    00766     if (_savegame_type == SGT_TTO) {
    00767       if (IsInsideBS(_old_string_id, 0x180F, 32)) {
    00768         st->string_id = STR_SV_STNAME + (_old_string_id - 0x180F); // automatic name
    00769       } else {
    00770         st->string_id = _old_string_id + 0x2800; // custom name
    00771       }
    00772
    00773       if (HasBit(st->airport.flags, 8)) {
    00774         st->airport.type = 1; // large airport
    00775       } else if (HasBit(st->airport.flags, 6)) {
    00776         st->airport.type = 3; // oil rig
    00777       } else {
    00778         st->airport.type = 0; // small airport
    00779       }
    00780     } else {
    00781       st->string_id = RemapOldStringID(_old_string_id);
    00782     }
    00783   } else {
    00784     delete st;
    00785   }
    00786
    00787   return true;
    00788 }
    00789
    00790 static const OldChunks industry_chunk[] = {
    00791   OCL_SVAR(   OC_TILE, Industry, location.tile ),
    00792   OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
    00793   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Industry, location.w ),
    00794   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Industry, location.h ),
    00795   OCL_NULL( 2 ),
    00796
    00797   OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced_cargo_waiting[0] ),
    00798   OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced_cargo_waiting[1] ),
    00799   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced_cargo_waiting[0] ),
    00800   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced_cargo_waiting[1] ),
    00801
    00802   OCL_SVAR(  OC_UINT8, Industry, production_rate[0] ),
    00803   OCL_SVAR(  OC_UINT8, Industry, production_rate[1] ),
    00804
    00805   OCL_NULL( 3 ),
    00806
    00807   OCL_SVAR(  OC_UINT8, Industry, prod_level ),
    00808
    00809   OCL_SVAR( OC_UINT16, Industry, this_month_production[0] ),
    00810   OCL_SVAR( OC_UINT16, Industry, this_month_production[1] ),
    00811   OCL_SVAR( OC_UINT16, Industry, this_month_transported[0] ),
    00812   OCL_SVAR( OC_UINT16, Industry, this_month_transported[1] ),
    00813
    00814   OCL_SVAR(  OC_UINT8, Industry, last_month_pct_transported[0] ),
    00815   OCL_SVAR(  OC_UINT8, Industry, last_month_pct_transported[1] ),
    00816
    00817   OCL_SVAR( OC_UINT16, Industry, last_month_production[0] ),
    00818   OCL_SVAR( OC_UINT16, Industry, last_month_production[1] ),
    00819   OCL_SVAR( OC_UINT16, Industry, last_month_transported[0] ),
    00820   OCL_SVAR( OC_UINT16, Industry, last_month_transported[1] ),
    00821
    00822   OCL_SVAR(  OC_UINT8, Industry, type ),
    00823   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, counter ),
    00824   OCL_SVAR(  OC_UINT8, Industry, owner ),
    00825   OCL_SVAR(  OC_UINT8, Industry, random_colour ),
    00826   OCL_SVAR( OC_TTD | OC_FILE_U8 | OC_VAR_I32, Industry, last_prod_year ),
    00827   OCL_SVAR( OC_TTD | OC_UINT16, Industry, counter ),
    00828   OCL_SVAR( OC_TTD | OC_UINT8, Industry, was_cargo_delivered ),
    00829
    00830   OCL_CNULL( OC_TTD, 9 ),
    00831
    00832   OCL_END()
    00833 };
    00834
    00835 static bool LoadOldIndustry(LoadgameState *ls, int num)
    00836 {
    00837   Industry *i = new (num) Industry();
    00838   if (!LoadChunk(ls, i, industry_chunk)) return false;
    00839
    00840   if (i->location.tile != 0) {
    00841     i->town = Town::Get(RemapTownIndex(_old_town_index));
    00842
    00843     if (_savegame_type == SGT_TTO) {
    00844       if (i->type > 0x06) i->type++; // Printing Works were added
    00845       if (i->type == 0x0A) i->type = 0x12; // Iron Ore Mine has different ID
    00846
    00847       YearMonthDay ymd;
    00848       ConvertDateToYMD(_date, &ymd);
    00849       i->last_prod_year = ymd.year;
    00850
    00851       i->random_colour = RemapTTOColour(i->random_colour);
    00852     }
    00853
    00854     Industry::IncIndustryTypeCount(i->type);
    00855   } else {
    00856     delete i;
    00857   }
    00858
    00859   return true;
    00860 }
    00861
    00862 static CompanyID _current_company_id;
    00863 static int32 _old_yearly;
    00864
    00865 static const OldChunks _company_yearly_chunk[] = {
    00866   OCL_VAR(  OC_INT32,   1, &_old_yearly ),
    00867   OCL_END()
    00868 };
    00869
    00870 static bool LoadOldCompanyYearly(LoadgameState *ls, int num)
    00871 {
    00872   Company *c = Company::Get(_current_company_id);
    00873
    00874   for (uint i = 0; i < 13; i++) {
    00875     if (_savegame_type == SGT_TTO && i == 6) {
    00876       _old_yearly = 0; // property maintenance
    00877     } else {
    00878       if (!LoadChunk(ls, NULL, _company_yearly_chunk)) return false;
    00879     }
    00880
    00881     c->yearly_expenses[num][i] = _old_yearly;
    00882   }
    00883
    00884   return true;
    00885 }
    00886
    00887 static const OldChunks _company_economy_chunk[] = {
    00888   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, income ),
    00889   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, expenses ),
    00890   OCL_SVAR( OC_INT32,                 CompanyEconomyEntry, delivered_cargo[NUM_CARGO - 1] ),
    00891   OCL_SVAR( OC_INT32,                 CompanyEconomyEntry, performance_history ),
    00892   OCL_SVAR( OC_TTD | OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, company_value ),
    00893
    00894   OCL_END()
    00895 };
    00896
    00897 static bool LoadOldCompanyEconomy(LoadgameState *ls, int num)
    00898 {
    00899   Company *c = Company::Get(_current_company_id);
    00900
    00901   if (!LoadChunk(ls, &c->cur_economy, _company_economy_chunk)) return false;
    00902
    00903   /* Don't ask, but the number in TTD(Patch) are inversed to OpenTTD */
    00904   c->cur_economy.income   = -c->cur_economy.income;
    00905   c->cur_economy.expenses = -c->cur_economy.expenses;
    00906
    00907   for (uint i = 0; i < 24; i++) {
    00908     if (!LoadChunk(ls, &c->old_economy[i], _company_economy_chunk)) return false;
    00909
    00910     c->old_economy[i].income   = -c->old_economy[i].income;
    00911     c->old_economy[i].expenses = -c->old_economy[i].expenses;
    00912   }
    00913
    00914   return true;
    00915 }
    00916
    00917 static const OldChunks _company_chunk[] = {
    00918   OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
    00919   OCL_SVAR( OC_UINT32, Company, name_2 ),
    00920   OCL_SVAR( OC_UINT32, Company, face ),
    00921   OCL_VAR ( OC_UINT16,   1, &_old_string_id_2 ),
    00922   OCL_SVAR( OC_UINT32, Company, president_name_2 ),
    00923
    00924   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, money ),
    00925   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, current_loan ),
    00926
    00927   OCL_SVAR(  OC_UINT8, Company, colour ),
    00928   OCL_SVAR(  OC_UINT8, Company, money_fraction ),
    00929   OCL_SVAR(  OC_UINT8, Company, months_of_bankruptcy ),
    00930   OCL_SVAR( OC_FILE_U8  | OC_VAR_U16, Company, bankrupt_asked ),
    00931   OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Company, bankrupt_value ),
    00932   OCL_SVAR( OC_UINT16, Company, bankrupt_timeout ),
    00933
    00934   OCL_CNULL( OC_TTD, 4 ), // cargo_types
    00935   OCL_CNULL( OC_TTO, 2 ), // cargo_types
    00936
    00937   OCL_CHUNK( 3, LoadOldCompanyYearly ),
    00938   OCL_CHUNK( 1, LoadOldCompanyEconomy ),
    00939
    00940   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Company, inaugurated_year),
    00941   OCL_SVAR(                  OC_TILE, Company, last_build_coordinate ),
    00942   OCL_SVAR(                 OC_UINT8, Company, num_valid_stat_ent ),
    00943
    00944   OCL_NULL( 230 ),         // Old AI
    00945
    00946   OCL_SVAR(  OC_UINT8, Company, block_preview ),
    00947   OCL_CNULL( OC_TTD, 1 ),           // Old AI
    00948   OCL_SVAR( OC_TTD | OC_UINT8, Company, avail_railtypes ),
    00949   OCL_SVAR(   OC_TILE, Company, location_of_HQ ),
    00950   OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[0] ),
    00951   OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[1] ),
    00952   OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[2] ),
    00953   OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[3] ),
    00954
    00955   OCL_CNULL( OC_TTD, 8 ),
    00956
    00957   OCL_END()
    00958 };
    00959
    00960 static bool LoadOldCompany(LoadgameState *ls, int num)
    00961 {
    00962   Company *c = new (num) Company();
    00963
    00964   _current_company_id = (CompanyID)num;
    00965
    00966   if (!LoadChunk(ls, c, _company_chunk)) return false;
    00967
    00968   if (_old_string_id == 0) {
    00969     delete c;
    00970     return true;
    00971   }
    00972
    00973   if (_savegame_type == SGT_TTO) {
    00974     /* adjust manager's face */
    00975     if (HasBit(c->face, 27) && GB(c->face, 26, 1) == GB(c->face, 19, 1)) {
    00976       /* if face would be black in TTD, adjust tie colour and thereby face colour */
    00977       ClrBit(c->face, 27);
    00978     }
    00979
    00980     /* Company name */
    00981     if (_old_string_id == 0 || _old_string_id == 0x4C00) {
    00982       _old_string_id = STR_SV_UNNAMED; // "Unnamed"
    00983     } else if (GB(_old_string_id, 8, 8) == 0x52) {
    00984       _old_string_id += 0x2A00; // Custom name
    00985     } else {
    00986       _old_string_id = RemapOldStringID(_old_string_id += 0x240D); // Automatic name
    00987     }
    00988     c->name_1 = _old_string_id;
    00989
    00990     /* Manager name */
    00991     switch (_old_string_id_2) {
    00992       case 0x4CDA: _old_string_id_2 = SPECSTR_PRESIDENT_NAME;    break; // automatic name
    00993       case 0x0006: _old_string_id_2 = STR_SV_EMPTY;              break; // empty name
    00994       default:     _old_string_id_2 = _old_string_id_2 + 0x2A00; break; // custom name
    00995     }
    00996     c->president_name_1 = _old_string_id_2;
    00997
    00998     c->colour = RemapTTOColour(c->colour);
    00999
    01000     if (num != 0) c->is_ai = true;
    01001   } else {
    01002     c->name_1 = RemapOldStringID(_old_string_id);
    01003     c->president_name_1 = RemapOldStringID(_old_string_id_2);
    01004
    01005     if (num == 0) {
    01006       /* If the first company has no name, make sure we call it UNNAMED */
    01007       if (c->name_1 == 0) {
    01008         c->name_1 = STR_SV_UNNAMED;
    01009       }
    01010     } else {
    01011       /* Beside some multiplayer maps (1 on 1), which we don't official support,
    01012        * all other companies are an AI.. mark them as such */
    01013       c->is_ai = true;
    01014     }
    01015
    01016     /* Sometimes it is better to not ask.. in old scenarios, the money
    01017      * was always 893288 pounds. In the newer versions this is correct,
    01018      * but correct for those oldies
    01019      * Ps: this also means that if you had exact 893288 pounds, you will go back
    01020      * to 100000.. this is a very VERY small chance ;) */
    01021     if (c->money == 893288) c->money = c->current_loan = 100000;
    01022   }
    01023
    01024   _company_colours[num] = (Colours)c->colour;
    01025   c->inaugurated_year -= ORIGINAL_BASE_YEAR;
    01026
    01027   return true;
    01028 }
    01029
    01030 static uint32 _old_order_ptr;
    01031 static uint16 _old_next_ptr;
    01032 static VehicleID _current_vehicle_id;
    01033
    01034 static const OldChunks vehicle_train_chunk[] = {
    01035   OCL_SVAR(  OC_UINT8, Train, track ),
    01036   OCL_SVAR(  OC_UINT8, Train, force_proceed ),
    01037   OCL_SVAR( OC_UINT16, Train, crash_anim_pos ),
    01038   OCL_SVAR(  OC_UINT8, Train, railtype ),
    01039
    01040   OCL_NULL( 5 ),
    01041
    01042   OCL_END()
    01043 };
    01044
    01045 static const OldChunks vehicle_road_chunk[] = {
    01046   OCL_SVAR(  OC_UINT8, RoadVehicle, state ),
    01047   OCL_SVAR(  OC_UINT8, RoadVehicle, frame ),
    01048   OCL_SVAR( OC_UINT16, RoadVehicle, blocked_ctr ),
    01049   OCL_SVAR(  OC_UINT8, RoadVehicle, overtaking ),
    01050   OCL_SVAR(  OC_UINT8, RoadVehicle, overtaking_ctr ),
    01051   OCL_SVAR( OC_UINT16, RoadVehicle, crashed_ctr ),
    01052   OCL_SVAR(  OC_UINT8, RoadVehicle, reverse_ctr ),
    01053
    01054   OCL_NULL( 1 ),
    01055
    01056   OCL_END()
    01057 };
    01058
    01059 static const OldChunks vehicle_ship_chunk[] = {
    01060   OCL_SVAR(  OC_UINT8, Ship, state ),
    01061
    01062   OCL_NULL( 9 ),
    01063
    01064   OCL_END()
    01065 };
    01066
    01067 static const OldChunks vehicle_air_chunk[] = {
    01068   OCL_SVAR(  OC_UINT8, Aircraft, pos ),
    01069   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Aircraft, targetairport ),
    01070   OCL_SVAR( OC_UINT16, Aircraft, crashed_counter ),
    01071   OCL_SVAR(  OC_UINT8, Aircraft, state ),
    01072
    01073   OCL_NULL( 5 ),
    01074
    01075   OCL_END()
    01076 };
    01077
    01078 static const OldChunks vehicle_effect_chunk[] = {
    01079   OCL_SVAR( OC_UINT16, EffectVehicle, animation_state ),
    01080   OCL_SVAR(  OC_UINT8, EffectVehicle, animation_substate ),
    01081
    01082   OCL_NULL( 7 ), // Junk
    01083
    01084   OCL_END()
    01085 };
    01086
    01087 static const OldChunks vehicle_disaster_chunk[] = {
    01088   OCL_SVAR( OC_UINT16, DisasterVehicle, image_override ),
    01089   OCL_SVAR( OC_UINT16, DisasterVehicle, big_ufo_destroyer_target ),
    01090
    01091   OCL_NULL( 6 ),
    01092
    01093   OCL_END()
    01094 };
    01095
    01096 static const OldChunks vehicle_empty_chunk[] = {
    01097   OCL_NULL( 10 ),
    01098
    01099   OCL_END()
    01100 };
    01101
    01102 static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
    01103 {
    01104   Vehicle *v = Vehicle::GetIfValid(_current_vehicle_id);
    01105   uint temp = ls->total_read;
    01106   bool res;
    01107
    01108   if (v == NULL) {
    01109     res = LoadChunk(ls, NULL, vehicle_empty_chunk);
    01110   } else {
    01111     switch (v->type) {
    01112       default: SlErrorCorrupt("Invalid vehicle type");
    01113       case VEH_TRAIN   : res = LoadChunk(ls, v, vehicle_train_chunk);    break;
    01114       case VEH_ROAD    : res = LoadChunk(ls, v, vehicle_road_chunk);     break;
    01115       case VEH_SHIP    : res = LoadChunk(ls, v, vehicle_ship_chunk);     break;
    01116       case VEH_AIRCRAFT: res = LoadChunk(ls, v, vehicle_air_chunk);      break;
    01117       case VEH_EFFECT  : res = LoadChunk(ls, v, vehicle_effect_chunk);   break;
    01118       case VEH_DISASTER: res = LoadChunk(ls, v, vehicle_disaster_chunk); break;
    01119     }
    01120   }
    01121
    01122   /* This chunk size should always be 10 bytes */
    01123   if (ls->total_read - temp != 10) {
    01124     DEBUG(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
    01125     return false;
    01126   }
    01127
    01128   return res;
    01129 }
    01130
    01131 static uint16 _cargo_count;
    01132
    01133 static const OldChunks vehicle_chunk[] = {
    01134   OCL_SVAR(  OC_UINT8, Vehicle, subtype ),
    01135
    01136   OCL_NULL( 2 ),
    01137   OCL_NULL( 2 ),
    01138
    01139   OCL_VAR ( OC_UINT32,   1, &_old_order_ptr ),
    01140   OCL_VAR ( OC_UINT16,   1, &_old_order ),
    01141
    01142   OCL_NULL ( 1 ),
    01143   OCL_SVAR(  OC_UINT8, Vehicle, cur_implicit_order_index ),
    01144   OCL_SVAR(   OC_TILE, Vehicle, dest_tile ),
    01145   OCL_SVAR( OC_UINT16, Vehicle, load_unload_ticks ),
    01146   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
    01147   OCL_SVAR( OC_UINT16, Vehicle, service_interval ),
    01148   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, last_station_visited ),
    01149   OCL_SVAR( OC_TTD | OC_UINT8, Vehicle, tick_counter ),
    01150   OCL_CNULL( OC_TTD, 2 ),
    01151   OCL_CNULL( OC_TTO, 1 ),
    01152
    01153   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, x_pos ),
    01154   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ),
    01155   OCL_SVAR( OC_FILE_U8  | OC_VAR_I32, Vehicle, z_pos ),
    01156   OCL_SVAR(  OC_UINT8, Vehicle, direction ),
    01157   OCL_NULL( 2 ),
    01158   OCL_NULL( 2 ),
    01159   OCL_NULL( 1 ),
    01160
    01161   OCL_SVAR(  OC_UINT8, Vehicle, owner ),
    01162   OCL_SVAR(   OC_TILE, Vehicle, tile ),
    01163   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, cur_image ),
    01164
    01165   OCL_NULL( 8 ),
    01166
    01167   OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Vehicle, vehstatus ),
    01168   OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cur_speed ),
    01169   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cur_speed ),
    01170   OCL_SVAR(  OC_UINT8, Vehicle, subspeed ),
    01171   OCL_SVAR(  OC_UINT8, Vehicle, acceleration ),
    01172   OCL_SVAR(  OC_UINT8, Vehicle, progress ),
    01173
    01174   OCL_SVAR(  OC_UINT8, Vehicle, cargo_type ),
    01175   OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cargo_cap ),
    01176   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cargo_cap ),
    01177   OCL_VAR ( OC_TTD | OC_UINT16, 1, &_cargo_count ),
    01178   OCL_VAR ( OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_cargo_count ),
    01179   OCL_VAR (  OC_UINT8, 1,       &_cargo_source ),
    01180   OCL_VAR (  OC_UINT8, 1,       &_cargo_days ),
    01181
    01182   OCL_SVAR( OC_TTO | OC_UINT8, Vehicle, tick_counter ),
    01183
    01184   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, age ),
    01185   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, max_age ),
    01186   OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, build_year ),
    01187   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, unitnumber ),
    01188
    01189   OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, engine_type ),
    01190   OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, engine_type ),
    01191
    01192   OCL_SVAR(  OC_UINT8, Vehicle, spritenum ),
    01193   OCL_SVAR(  OC_UINT8, Vehicle, day_counter ),
    01194
    01195   OCL_SVAR(  OC_UINT8, Vehicle, breakdowns_since_last_service ),
    01196   OCL_SVAR(  OC_UINT8, Vehicle, breakdown_ctr ),
    01197   OCL_SVAR(  OC_UINT8, Vehicle, breakdown_delay ),
    01198   OCL_SVAR(  OC_UINT8, Vehicle, breakdown_chance ),
    01199
    01200   OCL_CNULL( OC_TTO, 1 ),
    01201
    01202   OCL_SVAR( OC_UINT16, Vehicle, reliability ),
    01203   OCL_SVAR( OC_UINT16, Vehicle, reliability_spd_dec ),
    01204
    01205   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_this_year ),
    01206   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_last_year ),
    01207
    01208   OCL_VAR ( OC_UINT16,   1, &_old_next_ptr ),
    01209
    01210   OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Vehicle, value ),
    01211
    01212   OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
    01213
    01214   OCL_CHUNK( 1, LoadOldVehicleUnion ),
    01215
    01216   OCL_CNULL( OC_TTO, 24 ),
    01217   OCL_CNULL( OC_TTD, 20 ),
    01218
    01219   OCL_END()
    01220 };
    01221
    01228 bool LoadOldVehicle(LoadgameState *ls, int num)
    01229 {
    01230   /* Read the TTDPatch flags, because we need some info from it */
    01231   ReadTTDPatchFlags();
    01232
    01233   for (uint i = 0; i < _old_vehicle_multiplier; i++) {
    01234     _current_vehicle_id = num * _old_vehicle_multiplier + i;
    01235
    01236     Vehicle *v;
    01237
    01238     if (_savegame_type == SGT_TTO) {
    01239       uint type = ReadByte(ls);
    01240       switch (type) {
    01241         default: return false;
    01242         case 0x00 /* VEH_INVALID  */: v = NULL;                                        break;
    01243         case 0x25 /* MONORAIL     */:
    01244         case 0x20 /* VEH_TRAIN    */: v = new (_current_vehicle_id) Train();           break;
    01245         case 0x21 /* VEH_ROAD     */: v = new (_current_vehicle_id) RoadVehicle();     break;
    01246         case 0x22 /* VEH_SHIP     */: v = new (_current_vehicle_id) Ship();            break;
    01247         case 0x23 /* VEH_AIRCRAFT */: v = new (_current_vehicle_id) Aircraft();        break;
    01248         case 0x24 /* VEH_EFFECT   */: v = new (_current_vehicle_id) EffectVehicle();   break;
    01249         case 0x26 /* VEH_DISASTER */: v = new (_current_vehicle_id) DisasterVehicle(); break;
    01250       }
    01251
    01252       if (!LoadChunk(ls, v, vehicle_chunk)) return false;
    01253       if (v == NULL) continue;
    01254
    01255       SpriteID sprite = v->cur_image;
    01256       /* no need to override other sprites */
    01257       if (IsInsideMM(sprite, 1460, 1465)) {
    01258         sprite += 580; // aircraft smoke puff
    01259       } else if (IsInsideMM(sprite, 2096, 2115)) {
    01260         sprite += 977; // special effects part 1
    01261       } else if (IsInsideMM(sprite, 2396, 2436)) {
    01262         sprite += 1305; // special effects part 2
    01263       } else if (IsInsideMM(sprite, 2516, 2539)) {
    01264         sprite += 1385; // rotor or disaster-related vehicles
    01265       }
    01266       v->cur_image = sprite;
    01267
    01268       switch (v->type) {
    01269         case VEH_TRAIN: {
    01270           static const byte spriteset_rail[] = {
    01271               0,   2,   4,   4,   8,  10,  12,  14,  16,  18,  20,  22,  40,  42,  44,  46,
    01272              48,  52,  54,  66,  68,  70,  72,  74,  76,  78,  80,  82,  84,  86, 120, 122,
    01273             124, 126, 128, 130, 132, 134, 136, 138, 140
    01274           };
    01275           if (v->spritenum / 2 >= lengthof(spriteset_rail)) return false;
    01276           v->spritenum = spriteset_rail[v->spritenum / 2]; // adjust railway sprite set offset
    01277           Train::From(v)->railtype = type == 0x25 ? 1 : 0; // monorail / rail
    01278           break;
    01279         }
    01280
    01281         case VEH_ROAD:
    01282           if (v->spritenum >= 22) v->spritenum += 12;
    01283           break;
    01284
    01285         case VEH_SHIP:
    01286           v->spritenum += 2;
    01287
    01288           switch (v->spritenum) {
    01289             case 2: // oil tanker && cargo type != oil
    01290               if (v->cargo_type != CT_OIL) v->spritenum = 0; // make it a coal/goods ship
    01291               break;
    01292             case 4: // passenger ship && cargo type == mail
    01293               if (v->cargo_type == CT_MAIL) v->spritenum = 0; // make it a mail ship
    01294               break;
    01295             default:
    01296               break;
    01297           }
    01298           break;
    01299
    01300         default:
    01301           break;
    01302       }
    01303
    01304       switch (_old_string_id) {
    01305         case 0x0000: break; // empty (invalid vehicles)
    01306         case 0x0006: _old_string_id  = STR_SV_EMPTY;              break; // empty (special vehicles)
    01307         case 0x8495: _old_string_id  = STR_SV_TRAIN_NAME;         break; // "Train X"
    01308         case 0x8842: _old_string_id  = STR_SV_ROAD_VEHICLE_NAME;  break; // "Road Vehicle X"
    01309         case 0x8C3B: _old_string_id  = STR_SV_SHIP_NAME;          break; // "Ship X"
    01310         case 0x9047: _old_string_id  = STR_SV_AIRCRAFT_NAME;      break; // "Aircraft X"
    01311         default:     _old_string_id += 0x2A00;                    break; // custom name
    01312       }
    01313
    01314       _old_vehicle_names[_current_vehicle_id] = _old_string_id;
    01315     } else {
    01316       /* Read the vehicle type and allocate the right vehicle */
    01317       switch (ReadByte(ls)) {
    01318         default: SlErrorCorrupt("Invalid vehicle type");
    01319         case 0x00 /* VEH_INVALID */: v = NULL;                                        break;
    01320         case 0x10 /* VEH_TRAIN   */: v = new (_current_vehicle_id) Train();           break;
    01321         case 0x11 /* VEH_ROAD    */: v = new (_current_vehicle_id) RoadVehicle();     break;
    01322         case 0x12 /* VEH_SHIP    */: v = new (_current_vehicle_id) Ship();            break;
    01323         case 0x13 /* VEH_AIRCRAFT*/: v = new (_current_vehicle_id) Aircraft();        break;
    01324         case 0x14 /* VEH_EFFECT  */: v = new (_current_vehicle_id) EffectVehicle();   break;
    01325         case 0x15 /* VEH_DISASTER*/: v = new (_current_vehicle_id) DisasterVehicle(); break;
    01326       }
    01327
    01328       if (!LoadChunk(ls, v, vehicle_chunk)) return false;
    01329       if (v == NULL) continue;
    01330
    01331       _old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
    01332
    01333       /* This should be consistent, else we have a big problem... */
    01334       if (v->index != _current_vehicle_id) {
    01335         DEBUG(oldloader, 0, "Loading failed - vehicle-array is invalid");
    01336         return false;
    01337       }
    01338     }
    01339
    01340     if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
    01341       uint max = _savegame_type == SGT_TTO ? 3000 : 5000;
    01342       uint old_id = RemapOrderIndex(_old_order_ptr);
    01343       if (old_id < max) v->orders.old = Order::Get(old_id); // don't accept orders > max number of orders
    01344     }
    01345     v->current_order.AssignOrder(UnpackOldOrder(_old_order));
    01346
    01347     v->next = (Vehicle *)(size_t)_old_next_ptr;
    01348
    01349     if (_cargo_count != 0 && CargoPacket::CanAllocateItem()) {
    01350       StationID source =    (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
    01351       TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : 0;
    01352       v->cargo.Append(new CargoPacket(_cargo_count, _cargo_days, source, source_xy, source_xy));
    01353     }
    01354   }
    01355
    01356   return true;
    01357 }
    01358
    01359 static const OldChunks sign_chunk[] = {
    01360   OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
    01361   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, x ),
    01362   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, y ),
    01363   OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, Sign, z ),
    01364
    01365   OCL_NULL( 6 ),
    01366
    01367   OCL_END()
    01368 };
    01369
    01370 static bool LoadOldSign(LoadgameState *ls, int num)
    01371 {
    01372   Sign *si = new (num) Sign();
    01373   if (!LoadChunk(ls, si, sign_chunk)) return false;
    01374
    01375   if (_old_string_id != 0) {
    01376     if (_savegame_type == SGT_TTO) {
    01377       if (_old_string_id != 0x140A) si->name = CopyFromOldName(_old_string_id + 0x2A00);
    01378     } else {
    01379       si->name = CopyFromOldName(RemapOldStringID(_old_string_id));
    01380     }
    01381     si->owner = OWNER_NONE;
    01382   } else {
    01383     delete si;
    01384   }
    01385
    01386   return true;
    01387 }
    01388
    01389 static const OldChunks engine_chunk[] = {
    01390   OCL_SVAR( OC_UINT16, Engine, company_avail ),
    01391   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, intro_date ),
    01392   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, age ),
    01393   OCL_SVAR( OC_UINT16, Engine, reliability ),
    01394   OCL_SVAR( OC_UINT16, Engine, reliability_spd_dec ),
    01395   OCL_SVAR( OC_UINT16, Engine, reliability_start ),
    01396   OCL_SVAR( OC_UINT16, Engine, reliability_max ),
    01397   OCL_SVAR( OC_UINT16, Engine, reliability_final ),
    01398   OCL_SVAR( OC_UINT16, Engine, duration_phase_1 ),
    01399   OCL_SVAR( OC_UINT16, Engine, duration_phase_2 ),
    01400   OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
    01401
    01402   OCL_NULL( 1 ), // lifelength
    01403   OCL_SVAR(  OC_UINT8, Engine, flags ),
    01404   OCL_SVAR(  OC_UINT8, Engine, preview_company_rank ),
    01405   OCL_SVAR(  OC_UINT8, Engine, preview_wait ),
    01406
    01407   OCL_CNULL( OC_TTD, 2 ),
    01408
    01409   OCL_END()
    01410 };
    01411
    01412 static bool LoadOldEngine(LoadgameState *ls, int num)
    01413 {
    01414   Engine *e = _savegame_type == SGT_TTO ? &_old_engines[num] : GetTempDataEngine(num);
    01415   return LoadChunk(ls, e, engine_chunk);
    01416 }
    01417
    01418 static bool LoadOldEngineName(LoadgameState *ls, int num)
    01419 {
    01420   Engine *e = GetTempDataEngine(num);
    01421   e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
    01422   return true;
    01423 }
    01424
    01425 static const OldChunks subsidy_chunk[] = {
    01426   OCL_SVAR(  OC_UINT8, Subsidy, cargo_type ),
    01427   OCL_SVAR(  OC_UINT8, Subsidy, remaining ),
    01428   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, src ),
    01429   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, dst ),
    01430
    01431   OCL_END()
    01432 };
    01433
    01434 static bool LoadOldSubsidy(LoadgameState *ls, int num)
    01435 {
    01436   Subsidy *s = new (num) Subsidy();
    01437   bool ret = LoadChunk(ls, s, subsidy_chunk);
    01438   if (s->cargo_type == CT_INVALID) delete s;
    01439   return ret;
    01440 }
    01441
    01442 static const OldChunks game_difficulty_chunk[] = {
    01443   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, max_no_competitors ),
    01444   OCL_NULL( 2), // competitor_start_time
    01445   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, number_towns ),
    01446   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, industry_density ),
    01447   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, DifficultySettings, max_loan ),
    01448   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, initial_interest ),
    01449   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, vehicle_costs ),
    01450   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, competitor_speed ),
    01451   OCL_NULL( 2), // competitor_intelligence
    01452   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, vehicle_breakdowns ),
    01453   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, subsidy_multiplier ),
    01454   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, construction_cost ),
    01455   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, terrain_type ),
    01456   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, quantity_sea_lakes ),
    01457   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, economy ),
    01458   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, line_reverse_mode ),
    01459   OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, disasters ),
    01460   OCL_END()
    01461 };
    01462
    01463 static bool LoadOldGameDifficulty(LoadgameState *ls, int num)
    01464 {
    01465   bool ret = LoadChunk(ls, &_settings_game.difficulty, game_difficulty_chunk);
    01466   _settings_game.difficulty.max_loan *= 1000;
    01467   return ret;
    01468 }
    01469
    01470
    01471 static bool LoadOldMapPart1(LoadgameState *ls, int num)
    01472 {
    01473   if (_savegame_type == SGT_TTO) {
    01474     MemSetT(_m, 0, OLD_MAP_SIZE);
    01475     MemSetT(_me, 0, OLD_MAP_SIZE);
    01476   }
    01477
    01478   for (uint i = 0; i < OLD_MAP_SIZE; i++) {
    01479     _m[i].m1 = ReadByte(ls);
    01480   }
    01481   for (uint i = 0; i < OLD_MAP_SIZE; i++) {
    01482     _m[i].m2 = ReadByte(ls);
    01483   }
    01484
    01485   if (_savegame_type != SGT_TTO) {
    01486     for (uint i = 0; i < OLD_MAP_SIZE; i++) {
    01487       _old_map3[i * 2] = ReadByte(ls);
    01488       _old_map3[i * 2 + 1] = ReadByte(ls);
    01489     }
    01490     for (uint i = 0; i < OLD_MAP_SIZE / 4; i++) {
    01491       byte b = ReadByte(ls);
    01492       _m[i * 4 + 0].m6 = GB(b, 0, 2);
    01493       _m[i * 4 + 1].m6 = GB(b, 2, 2);
    01494       _m[i * 4 + 2].m6 = GB(b, 4, 2);
    01495       _m[i * 4 + 3].m6 = GB(b, 6, 2);
    01496     }
    01497   }
    01498
    01499   return true;
    01500 }
    01501
    01502 static bool LoadOldMapPart2(LoadgameState *ls, int num)
    01503 {
    01504   uint i;
    01505
    01506   for (i = 0; i < OLD_MAP_SIZE; i++) {
    01507     _m[i].type_height = ReadByte(ls);
    01508   }
    01509   for (i = 0; i < OLD_MAP_SIZE; i++) {
    01510     _m[i].m5 = ReadByte(ls);
    01511   }
    01512
    01513   return true;
    01514 }
    01515
    01516 static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num)
    01517 {
    01518   ReadTTDPatchFlags();
    01519
    01520   DEBUG(oldloader, 2, "Found %d extra chunk(s)", _old_extra_chunk_nums);
    01521
    01522   for (int i = 0; i != _old_extra_chunk_nums; i++) {
    01523     uint16 id = ReadUint16(ls);
    01524     uint32 len = ReadUint32(ls);
    01525
    01526     switch (id) {
    01527       /* List of GRFIDs, used in the savegame. 0x8004 is the new ID
    01528        * They are saved in a 'GRFID:4 active:1' format, 5 bytes for each entry */
    01529       case 0x2:
    01530       case 0x8004: {
    01531         /* Skip the first element: TTDP hack for the Action D special variables (FFFF0000 01) */
    01532         ReadUint32(ls); ReadByte(ls); len -= 5;
    01533
    01534         ClearGRFConfigList(&_grfconfig);
    01535         while (len != 0) {
    01536           uint32 grfid = ReadUint32(ls);
    01537
    01538           if (ReadByte(ls) == 1) {
    01539             GRFConfig *c = new GRFConfig("TTDP game, no information");
    01540             c->ident.grfid = grfid;
    01541
    01542             AppendToGRFConfigList(&_grfconfig, c);
    01543             DEBUG(oldloader, 3, "TTDPatch game using GRF file with GRFID %0X", BSWAP32(c->ident.grfid));
    01544           }
    01545           len -= 5;
    01546         }
    01547
    01548         /* Append static NewGRF configuration */
    01549         AppendStaticGRFConfigs(&_grfconfig);
    01550         break;
    01551       }
    01552
    01553       /* TTDPatch version and configuration */
    01554       case 0x3:
    01555         _ttdp_version = ReadUint32(ls);
    01556         DEBUG(oldloader, 3, "Game saved with TTDPatch version %d.%d.%d r%d",
    01557           GB(_ttdp_version, 24, 8), GB(_ttdp_version, 20, 4), GB(_ttdp_version, 16, 4), GB(_ttdp_version, 0, 16));
    01558         len -= 4;
    01559         while (len-- != 0) ReadByte(ls); // skip the configuration
    01560         break;
    01561
    01562       default:
    01563         DEBUG(oldloader, 4, "Skipping unknown extra chunk %X", id);
    01564         while (len-- != 0) ReadByte(ls);
    01565         break;
    01566     }
    01567   }
    01568
    01569   return true;
    01570 }
    01571
    01572 extern TileIndex _cur_tileloop_tile;
    01573 extern uint16 _disaster_delay;
    01574 extern byte _trees_tick_ctr;
    01575 extern byte _age_cargo_skip_counter; // From misc_sl.cpp
    01576 static const OldChunks main_chunk[] = {
    01577   OCL_ASSERT( OC_TTD, 0 ),
    01578   OCL_ASSERT( OC_TTO, 0 ),
    01579   OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_date ),
    01580   OCL_VAR ( OC_UINT16,   1, &_date_fract ),
    01581   OCL_NULL( 600 ),
    01582   OCL_VAR ( OC_UINT32,   2, &_random.state ),
    01583
    01584   OCL_ASSERT( OC_TTD, 0x264 ),
    01585   OCL_ASSERT( OC_TTO, 0x264 ),
    01586
    01587   OCL_CCHUNK( OC_TTD, 70, LoadOldTown ),
    01588   OCL_CCHUNK( OC_TTO, 80, LoadOldTown ),
    01589
    01590   OCL_ASSERT( OC_TTD, 0x1C18 ),
    01591   OCL_ASSERT( OC_TTO, 0x1AC4 ),
    01592
    01593   OCL_CCHUNK( OC_TTD, 5000, LoadOldOrder ),
    01594   OCL_CCHUNK( OC_TTO, 3000, LoadOldOrder ),
    01595
    01596   OCL_ASSERT( OC_TTD, 0x4328 ),
    01597   OCL_ASSERT( OC_TTO, 0x3234 ),
    01598
    01599   OCL_CHUNK( 1, LoadOldAnimTileList ),
    01600   OCL_NULL( 4 ),
    01601
    01602   OCL_ASSERT( OC_TTO, 0x3438 ),
    01603
    01604   OCL_CCHUNK( OC_TTD, 255, LoadOldDepot ),
    01605   OCL_CCHUNK( OC_TTO, 252, LoadOldDepot ),
    01606
    01607   OCL_ASSERT( OC_TTD, 0x4B26 ),
    01608   OCL_ASSERT( OC_TTO, 0x3A20 ),
    01609
    01610   OCL_NULL( 4 ),
    01611   OCL_NULL( 2 ),
    01612   OCL_NULL( 2 ),
    01613
    01614   OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ),
    01615   OCL_VAR ( OC_UINT16,   1, &_tick_counter ),
    01616   OCL_VAR (   OC_TILE,   1, &_cur_tileloop_tile ),
    01617
    01618   OCL_ASSERT( OC_TTO, 0x3A2E ),
    01619
    01620   OCL_CNULL( OC_TTO, 48 * 6 ),
    01621   OCL_CNULL( OC_TTD, 49 * 6 ),
    01622
    01623   OCL_ASSERT( OC_TTO, 0x3B4E ),
    01624
    01625   OCL_CNULL( OC_TTO, 11 * 8 ),
    01626   OCL_CNULL( OC_TTD, 12 * 8 ),
    01627
    01628   OCL_ASSERT( OC_TTD, 0x4CBA ),
    01629   OCL_ASSERT( OC_TTO, 0x3BA6 ),
    01630
    01631   OCL_CHUNK( 1, LoadOldMapPart1 ),
    01632
    01633   OCL_ASSERT( OC_TTD, 0x48CBA ),
    01634   OCL_ASSERT( OC_TTO, 0x23BA6 ),
    01635
    01636   OCL_CCHUNK( OC_TTD, 250, LoadOldStation ),
    01637   OCL_CCHUNK( OC_TTO, 200, LoadOldStation ),
    01638
    01639   OCL_ASSERT( OC_TTO, 0x29E16 ),
    01640
    01641   OCL_CCHUNK( OC_TTD, 90, LoadOldIndustry ),
    01642   OCL_CCHUNK( OC_TTO, 100, LoadOldIndustry ),
    01643
    01644   OCL_ASSERT( OC_TTO, 0x2ADB6 ),
    01645
    01646   OCL_CHUNK(  8, LoadOldCompany ),
    01647
    01648   OCL_ASSERT( OC_TTD, 0x547F2 ),
    01649   OCL_ASSERT( OC_TTO, 0x2C746 ),
    01650
    01651   OCL_CCHUNK( OC_TTD, 850, LoadOldVehicle ),
    01652   OCL_CCHUNK( OC_TTO, 800, LoadOldVehicle ),
    01653
    01654   OCL_ASSERT( OC_TTD, 0x6F0F2 ),
    01655   OCL_ASSERT( OC_TTO, 0x45746 ),
    01656
    01657   OCL_VAR ( OC_TTD | OC_UINT8 | OC_DEREFERENCE_POINTER, 32 * 500, &_old_name_array ),
    01658   OCL_VAR ( OC_TTO | OC_UINT8 | OC_DEREFERENCE_POINTER, 24 * 200, &_old_name_array ),
    01659
    01660   OCL_ASSERT( OC_TTO, 0x46A06 ),
    01661
    01662   OCL_NULL( 0x2000 ),
    01663
    01664   OCL_CHUNK( 40, LoadOldSign ),
    01665
    01666   OCL_ASSERT( OC_TTO, 0x48C36 ),
    01667
    01668   OCL_CCHUNK( OC_TTD, 256, LoadOldEngine ),
    01669   OCL_CCHUNK( OC_TTO, 103, LoadOldEngine ),
    01670
    01671   OCL_ASSERT( OC_TTO, 0x496AC ),
    01672
    01673   OCL_NULL ( 2 ), // _vehicle_id_ctr_day
    01674
    01675   OCL_CHUNK(  8, LoadOldSubsidy ),
    01676
    01677   OCL_ASSERT( OC_TTO, 0x496CE ),
    01678
    01679   OCL_VAR ( OC_FILE_U16 | OC_VAR_U32,   1, &_next_competitor_start ),
    01680
    01681   OCL_CNULL( OC_TTO, 2 ),
    01682
    01683   OCL_VAR ( OC_FILE_I16 | OC_VAR_I32,   1, &_saved_scrollpos_x ),
    01684   OCL_VAR ( OC_FILE_I16 | OC_VAR_I32,   1, &_saved_scrollpos_y ),
    01685   OCL_VAR ( OC_FILE_U16 | OC_VAR_U8,    1, &_saved_scrollpos_zoom ),
    01686
    01687   OCL_NULL( 4 ),
    01688   OCL_VAR ( OC_FILE_U32 | OC_VAR_I64,   1, &_economy.old_max_loan_unround ),
    01689   OCL_VAR (  OC_INT16,    1, &_economy.fluct ),
    01690
    01691   OCL_VAR ( OC_UINT16,    1, &_disaster_delay ),
    01692
    01693   OCL_ASSERT( OC_TTO, 0x496E4 ),
    01694
    01695   OCL_CNULL( OC_TTD, 144 ),
    01696
    01697   OCL_CCHUNK( OC_TTD, 256, LoadOldEngineName ),
    01698
    01699   OCL_CNULL( OC_TTD, 144 ),
    01700   OCL_NULL( 2 ),
    01701   OCL_NULL( 1 ),
    01702
    01703   OCL_VAR (  OC_UINT8,    1, &_settings_game.locale.currency ),
    01704   OCL_VAR (  OC_UINT8,    1, &_settings_game.locale.units ),
    01705   OCL_VAR ( OC_FILE_U8 | OC_VAR_U32,    1, &_cur_company_tick_index ),
    01706
    01707   OCL_NULL( 2 ),
    01708   OCL_NULL( 8 ),
    01709
    01710   OCL_VAR (  OC_UINT8,    1, &_economy.infl_amount ),
    01711   OCL_VAR (  OC_UINT8,    1, &_economy.infl_amount_pr ),
    01712   OCL_VAR (  OC_UINT8,    1, &_economy.interest_rate ),
    01713   OCL_NULL( 1 ), // available airports
    01714   OCL_VAR (  OC_UINT8,    1, &_settings_game.vehicle.road_side ),
    01715   OCL_VAR (  OC_UINT8,    1, &_settings_game.game_creation.town_name ),
    01716
    01717   OCL_CHUNK( 1, LoadOldGameDifficulty ),
    01718
    01719   OCL_ASSERT( OC_TTD, 0x77130 ),
    01720
    01721   OCL_VAR (  OC_UINT8,    1, &_settings_game.difficulty.diff_level ),
    01722
    01723   OCL_VAR ( OC_TTD | OC_UINT8,    1, &_settings_game.game_creation.landscape ),
    01724   OCL_VAR ( OC_TTD | OC_UINT8,    1, &_trees_tick_ctr ),
    01725
    01726   OCL_CNULL( OC_TTD, 1 ),
    01727   OCL_VAR ( OC_TTD | OC_UINT8,    1, &_settings_game.game_creation.snow_line_height ),
    01728
    01729   OCL_CNULL( OC_TTD, 32 ),
    01730   OCL_CNULL( OC_TTD, 36 ),
    01731
    01732   OCL_ASSERT( OC_TTD, 0x77179 ),
    01733   OCL_ASSERT( OC_TTO, 0x4971D ),
    01734
    01735   OCL_CHUNK( 1, LoadOldMapPart2 ),
    01736
    01737   OCL_ASSERT( OC_TTD, 0x97179 ),
    01738   OCL_ASSERT( OC_TTO, 0x6971D ),
    01739
    01740   /* Below any (if available) extra chunks from TTDPatch can follow */
    01741   OCL_CHUNK(1, LoadTTDPatchExtraChunks),
    01742
    01743   OCL_END()
    01744 };
    01745
    01746 bool LoadTTDMain(LoadgameState *ls)
    01747 {
    01748   DEBUG(oldloader, 3, "Reading main chunk...");
    01749
    01750   _read_ttdpatch_flags = false;
    01751
    01752   /* Load the biggest chunk */
    01753   SmallStackSafeStackAlloc<byte, OLD_MAP_SIZE * 2> map3;
    01754   _old_map3 = map3.data;
    01755   _old_vehicle_names = NULL;
    01756   try {
    01757     if (!LoadChunk(ls, NULL, main_chunk)) {
    01758       DEBUG(oldloader, 0, "Loading failed");
    01759       free(_old_vehicle_names);
    01760       return false;
    01761     }
    01762   } catch (...) {
    01763     free(_old_vehicle_names);
    01764     throw;
    01765   }
    01766
    01767   DEBUG(oldloader, 3, "Done, converting game data...");
    01768
    01769   FixTTDMapArray();
    01770   FixTTDDepots();
    01771
    01772   /* Fix some general stuff */
    01773   _settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
    01774
    01775   /* Fix the game to be compatible with OpenTTD */
    01776   FixOldTowns();
    01777   FixOldVehicles();
    01778
    01779   /* We have a new difficulty setting */
    01780   _settings_game.difficulty.town_council_tolerance = Clamp(_settings_game.difficulty.diff_level, 0, 2);
    01781
    01782   DEBUG(oldloader, 3, "Finished converting game data");
    01783   DEBUG(oldloader, 1, "TTD(Patch) savegame successfully converted");
    01784
    01785   free(_old_vehicle_names);
    01786
    01787   return true;
    01788 }
    01789
    01790 bool LoadTTOMain(LoadgameState *ls)
    01791 {
    01792   DEBUG(oldloader, 3, "Reading main chunk...");
    01793
    01794   _read_ttdpatch_flags = false;
    01795
    01796   SmallStackSafeStackAlloc<byte, 103 * sizeof(Engine)> engines; // we don't want to call Engine constructor here
    01797   _old_engines = (Engine *)engines.data;
    01798   SmallStackSafeStackAlloc<StringID, 800> vehnames;
    01799   _old_vehicle_names = vehnames.data;
    01800
    01801   /* Load the biggest chunk */
    01802   if (!LoadChunk(ls, NULL, main_chunk)) {
    01803     DEBUG(oldloader, 0, "Loading failed");
    01804     return false;
    01805   }
    01806   DEBUG(oldloader, 3, "Done, converting game data...");
    01807
    01808   if (_settings_game.game_creation.town_name != 0) _settings_game.game_creation.town_name++;
    01809
    01810   _settings_game.game_creation.landscape = 0;
    01811   _trees_tick_ctr = 0xFF;
    01812
    01813   if (!FixTTOMapArray() || !FixTTOEngines()) {
    01814     DEBUG(oldloader, 0, "Conversion failed");
    01815     return false;
    01816   }
    01817
    01818   FixOldTowns();
    01819   FixOldVehicles();
    01820   FixTTOCompanies();
    01821
    01822   /* We have a new difficulty setting */
    01823   _settings_game.difficulty.town_council_tolerance = Clamp(_settings_game.difficulty.diff_level, 0, 2);
    01824
    01825   /* SVXConverter about cargo payment rates correction:
    01826    * "increase them to compensate for the faster time advance in TTD compared to TTO
    01827    * which otherwise would cause much less income while the annual running costs of
    01828    * the vehicles stay the same" */
    01829   _economy.inflation_payment = min(_economy.inflation_payment * 124 / 74, MAX_INFLATION);
    01830
    01831   DEBUG(oldloader, 3, "Finished converting game data");
    01832   DEBUG(oldloader, 1, "TTO savegame successfully converted");
    01833
    01834   return true;
    01835 }