oldloader_sl.cpp

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

Generated on Fri Dec 31 17:15:37 2010 for OpenTTD by  doxygen 1.6.1