# oldloader_sl.cpp

Go to the documentation of this file.

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