00001
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
00038
00039 MemSetT(&_m[0], 0);
00040 SetTileType(0, MP_WATER);
00041 SetTileOwner(0, OWNER_WATER);
00042 }
00043
00044 static void FixTTDMapArray()
00045 {
00046
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;
00056 switch (_m[t].m5) {
00057
00058 case 0x53: case 0x54: _m[t].m5 += 170 - 0x53; break;
00059 case 0x57: case 0x58: _m[t].m5 += 168 - 0x57; break;
00060 case 0x55: case 0x56: _m[t].m5 += 170 - 0x55; break;
00061 case 0x59: case 0x5A: _m[t].m5 += 168 - 0x59; break;
00062 default: break;
00063 }
00064 break;
00065
00066 case MP_RAILWAY:
00067
00068 if (GB(_m[t].m5, 6, 2) == 1) {
00069
00070 if (_m[t].m4) {
00071 _m[t].m4 = (_m[t].m4 >> 1) & 7;
00072 }
00073 }
00074
00075
00076 _m[t].m4 &= 0xF;
00077 break;
00078
00079 case MP_WATER:
00080
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;
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:
00116
00117 return townnameparts;
00118
00119 case 1:
00120
00121
00122 return FIXNUM(townnameparts - 86, lengthof(_name_french_real), 0);
00123
00124 case 2:
00125 DEBUG(misc, 0, "German Townnames are buggy (%d)", townnameparts);
00126 return townnameparts;
00127
00128 case 4:
00129
00130 return FIXNUM(townnameparts, lengthof(_name_spanish_real), 0);
00131
00132 case 5:
00133
00134
00135
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
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
00164 switch (v->spritenum) {
00165 case 0xfd: break;
00166 case 0xff: v->spritenum = 0xfe; break;
00167 default: v->spritenum >>= 1; break;
00168 }
00169
00170
00171 if (v->type == VEH_EFFECT) v->subtype = v->subtype >> 1;
00172
00173 v->name = CopyFromOldName(_old_vehicle_names[v->index]);
00174
00175
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
00183 if (v->type == VEH_ROAD || v->type == VEH_SHIP) v->subtype = 0;
00184
00185
00186
00187
00188
00189 if (!IsCompanyBuildableVehicleType(v) ||
00190 (v->IsPrimaryVehicle() && v->current_order.IsType(OT_NOTHING))) {
00191 v->current_order.MakeDummy();
00192 }
00193
00194
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:
00209 if (tt == 11) {
00210 _m[t].m3 = 1;
00211 _m[t].type_height &= 0x1F;
00212 _m[t].m2 = 1;
00213 }
00214 switch (GB(_m[t].m5, 6, 2)) {
00215 case 0:
00216 break;
00217 case 1:
00218 _m[t].m4 = (~_m[t].m5 & 1) << 2;
00219 SB(_m[t].m2, 6, 2, GB(_m[t].m5, 3, 2));
00220 _m[t].m3 |= 0xC0;
00221 _m[t].m5 = HasBit(_m[t].m5, 5) ? 2 : 1;
00222 _m[t].m5 |= 0x40;
00223 break;
00224 case 3:
00225 _m[t].m2 = 0;
00226 break;
00227 default:
00228 return false;
00229 }
00230 break;
00231
00232 case MP_ROAD:
00233 switch (GB(_m[t].m5, 4, 4)) {
00234 case 0:
00235 if (_m[t].m2 == 4) _m[t].m2 = 5;
00236 break;
00237 case 1:
00238 _m[t].m3 = _m[t].m1;
00239 break;
00240 case 2:
00241 break;
00242 default:
00243 return false;
00244 }
00245 break;
00246
00247 case MP_HOUSE:
00248 _m[t].m3 = _m[t].m2 & 0xC0;
00249 _m[t].m2 &= 0x3F;
00250 if (_m[t].m2 >= 5) _m[t].m2++;
00251 break;
00252
00253 case MP_TREES:
00254 _m[t].m3 = GB(_m[t].m5, 3, 3);
00255 _m[t].m5 &= 0xC7;
00256 break;
00257
00258 case MP_STATION:
00259 _m[t].m3 = (_m[t].m5 >= 0x08 && _m[t].m5 <= 0x0F) ? 1 : 0;
00260 if (_m[t].m5 >= 8) _m[t].m5 -= 8;
00261 if (_m[t].m5 >= 0x42) _m[t].m5++;
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:
00276 _m[t].m5 = 0x25;
00277 break;
00278 case 0x25: case 0x27:
00279 case 0x28: case 0x29: case 0x2A: case 0x2B:
00280 _m[t].m5--;
00281 break;
00282 default:
00283 if (_m[t].m5 >= 0x2C) _m[t].m5 += 3;
00284 break;
00285 }
00286 break;
00287
00288 case MP_TUNNELBRIDGE:
00289 if (HasBit(_m[t].m5, 7)) {
00290 byte m5 = _m[t].m5;
00291 _m[t].m5 = m5 & 0xE1;
00292 if (GB(m5, 1, 2) == 1) _m[t].m5 |= 0x02;
00293 if (GB(m5, 1, 2) == 3) _m[t].m2 |= 0xA0;
00294 if (!HasBit(m5, 6)) {
00295 _m[t].m3 = (GB(m5, 1, 2) == 3) ? 1 : 0;
00296 } else {
00297 _m[t].m3 = HasBit(m5, 2) ? 0x10 : 0;
00298 if (GB(m5, 3, 2) == 3) _m[t].m3 |= 1;
00299 if (GB(m5, 3, 2) == 1) _m[t].m5 |= 0x08;
00300 }
00301 } else {
00302 _m[t].m2 = 0;
00303 _m[t].m3 = HasBit(_m[t].m5, 3);
00304 _m[t].m5 &= HasBit(_m[t].m5, 3) ? 0x03 : 0x07 ;
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
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
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
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
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
00411
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);
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;
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
00486 _old_vehicle_multiplier = _old_map3[0];
00487
00488
00489 if (_old_vehicle_multiplier < 2) _old_vehicle_multiplier++;
00490
00491 _old_vehicle_names = MallocT<StringID>(_old_vehicle_multiplier * 850);
00492
00493
00494
00495
00496
00497
00498 _bump_assert_value = (_old_vehicle_multiplier - 1) * 850 * 128;
00499
00500 for (uint i = 0; i < 17; i++) {
00501 if (_old_map3[i] != 0) _savegame_type = SGT_TTDP1;
00502 }
00503
00504
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
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
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
00601
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
00612
00613
00614
00615
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
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
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
00673 if (num == 15) _old_price = ClampToI32(((Money)_old_price) * 20 / 3);
00674 if (num == 17) _old_price = ClampToI32(((Money)_old_price) * 10);
00675 }
00676
00677
00678
00679
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) {
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
00706
00707
00708
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
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);
00812 } else {
00813 st->string_id = _old_string_id + 0x2800;
00814 }
00815
00816 if (HasBit(st->airport_flags, 8)) {
00817 st->airport_type = 1;
00818 } else if (HasBit(st->airport_flags, 6)) {
00819 st->airport_type = 3;
00820 } else {
00821 st->airport_type = 0;
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++;
00888 if (i->type == 0x0A) i->type = 0x12;
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;
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
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 ),
00988
00989 OCL_SVAR( OC_UINT8, Company, block_preview ),
00990 OCL_CNULL( OC_TTD, 1 ),
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
01018 if (HasBit(c->face, 27) && GB(c->face, 26, 1) == GB(c->face, 19, 1)) {
01019
01020 ClrBit(c->face, 27);
01021 }
01022
01023
01024 if (_old_string_id == 0 || _old_string_id == 0x4C00) {
01025 _old_string_id = STR_SV_UNNAMED;
01026 } else if (GB(_old_string_id, 8, 8) == 0x52) {
01027 _old_string_id += 0x2A00;
01028 } else {
01029 _old_string_id = RemapOldStringID(_old_string_id += 0x240D);
01030 }
01031 c->name_1 = _old_string_id;
01032
01033
01034 switch (_old_string_id_2) {
01035 case 0x4CDA: _old_string_id_2 = SPECSTR_PRESIDENT_NAME; break;
01036 case 0x0006: _old_string_id_2 = STR_SV_EMPTY; break;
01037 default: _old_string_id_2 = _old_string_id_2 + 0x2A00; break;
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
01050 if (c->name_1 == 0)
01051 c->name_1 = STR_SV_UNNAMED;
01052 } else {
01053
01054
01055 c->is_ai = true;
01056 }
01057
01058
01059
01060
01061
01062
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 ),
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
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
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 : v = new (_current_vehicle_id) InvalidVehicle(); break;
01276 case 0x25 :
01277 case 0x20 : v = new (_current_vehicle_id) Train(); break;
01278 case 0x21 : v = new (_current_vehicle_id) RoadVehicle(); break;
01279 case 0x22 : v = new (_current_vehicle_id) Ship(); break;
01280 case 0x23 : v = new (_current_vehicle_id) Aircraft(); break;
01281 case 0x24 : v = new (_current_vehicle_id) EffectVehicle(); break;
01282 case 0x26 : 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
01289 if (IsInsideMM(sprite, 1460, 1465)) {
01290 sprite += 580;
01291 } else if (IsInsideMM(sprite, 2096, 2115)) {
01292 sprite += 977;
01293 } else if (IsInsideMM(sprite, 2396, 2436)) {
01294 sprite += 1305;
01295 } else if (IsInsideMM(sprite, 2516, 2539)) {
01296 sprite += 1385;
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];
01309 v->u.rail.railtype = type == 0x25 ? 1 : 0;
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:
01322 if (v->cargo_type != CT_OIL) v->spritenum = 0;
01323 break;
01324 case 4:
01325 if (v->cargo_type == CT_MAIL) v->spritenum = 0;
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;
01338 case 0x0006: _old_string_id = STR_SV_EMPTY; break;
01339 case 0x8495: _old_string_id = STR_SV_TRAIN_NAME; break;
01340 case 0x8842: _old_string_id = STR_SV_ROADVEH_NAME; break;
01341 case 0x8C3B: _old_string_id = STR_SV_SHIP_NAME; break;
01342 case 0x9047: _old_string_id = STR_SV_AIRCRAFT_NAME; break;
01343 default: _old_string_id += 0x2A00; break;
01344 }
01345
01346 _old_vehicle_names[_current_vehicle_id] = _old_string_id;
01347 } else {
01348
01349 switch (ReadByte(ls)) {
01350 default: NOT_REACHED();
01351 case 0x00 : v = new (_current_vehicle_id) InvalidVehicle(); break;
01352 case 0x10 : v = new (_current_vehicle_id) Train(); break;
01353 case 0x11 : v = new (_current_vehicle_id) RoadVehicle(); break;
01354 case 0x12 : v = new (_current_vehicle_id) Ship(); break;
01355 case 0x13 : v = new (_current_vehicle_id) Aircraft(); break;
01356 case 0x14 : v = new (_current_vehicle_id) EffectVehicle(); break;
01357 case 0x15 : 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
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);
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),
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),
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
01553
01554 case 0x2:
01555 case 0x8004: {
01556
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
01575 AppendStaticGRFConfigs(&_grfconfig);
01576 } break;
01577
01578
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);
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 ),
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
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
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
01787 _settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
01788
01789
01790 FixOldTowns();
01791 FixOldVehicles();
01792
01793
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;
01809 _old_engines = (Engine *)engines.data;
01810 SmallStackSafeStackAlloc<StringID, 800> vehnames;
01811 _old_vehicle_names = vehnames.data;
01812
01813
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
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 }