# oldloader_sl.cpp

Go to the documentation of this file.

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