oldloader_sl.cpp

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

Generated on Thu Jan 20 22:57:39 2011 for OpenTTD by  doxygen 1.6.1