oldloader_sl.cpp

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