oldloader_sl.cpp

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

Generated on Sat Apr 17 23:24:52 2010 for OpenTTD by  doxygen 1.6.1