# oldloader_sl.cpp

Go to the documentation of this file.

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