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

Generated on Sat Dec 26 20:06:04 2009 for OpenTTD by  doxygen 1.5.6