oldloader_sl.cpp

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

Generated on Mon Dec 14 21:00:02 2009 for OpenTTD by  doxygen 1.5.6