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->preview_company_rank = 0;
00421 e->preview_wait = 0;
00422 e->name = NULL;
00423
00424 e->info.climates = 1;
00425 }
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 new (num) Order(UnpackOldOrder(_old_order));
00598
00599
00600
00601 if (num > 0 && GetOrder(num)->IsValid()) {
00602 GetOrder(num - 1)->next = GetOrder(num);
00603 }
00604
00605 return true;
00606 }
00607
00608 static bool LoadOldAnimTileList(LoadgameState *ls, int num)
00609 {
00610
00611
00612
00613
00614
00615
00616 const OldChunks anim_chunk[] = {
00617 OCL_VAR ( OC_TILE, 256, _animated_tile_list ),
00618 OCL_END ()
00619 };
00620
00621 if (!LoadChunk(ls, NULL, anim_chunk)) return false;
00622
00623
00624 for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
00625 if (_animated_tile_list[_animated_tile_count] == 0) break;
00626 }
00627
00628 return true;
00629 }
00630
00631 static const OldChunks depot_chunk[] = {
00632 OCL_SVAR( OC_TILE, Depot, xy ),
00633 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
00634 OCL_END()
00635 };
00636
00637 static bool LoadOldDepot(LoadgameState *ls, int num)
00638 {
00639 Depot *d = new (num) Depot();
00640 if (!LoadChunk(ls, d, depot_chunk)) return false;
00641
00642 if (d->xy != 0) {
00643 d->town_index = RemapTownIndex(_old_town_index);
00644 } else {
00645 d->xy = INVALID_TILE;
00646 }
00647
00648 return true;
00649 }
00650
00651 static int32 _old_price;
00652 static uint16 _old_price_frac;
00653 static const OldChunks price_chunk[] = {
00654 OCL_VAR ( OC_INT32, 1, &_old_price ),
00655 OCL_VAR ( OC_UINT16, 1, &_old_price_frac ),
00656 OCL_END()
00657 };
00658
00659 static bool LoadOldPrice(LoadgameState *ls, int num)
00660 {
00661 if (_savegame_type == SGT_TTO && num == 25) {
00662
00663 ((Money*)&_price)[25] = ((Money*)&_price)[6];
00664 _price_frac[25] = _price_frac[6];
00665 return true;
00666 }
00667
00668 if (!LoadChunk(ls, NULL, price_chunk)) return false;
00669
00670 if (_savegame_type == SGT_TTO) {
00671
00672 if (num == 15) _old_price = ClampToI32(((Money)_old_price) * 20 / 3);
00673 if (num == 17) _old_price = ClampToI32(((Money)_old_price) * 10);
00674 }
00675
00676
00677
00678
00679 ((Money*)&_price)[num] = _old_price;
00680 _price_frac[num] = _old_price_frac;
00681
00682 return true;
00683 }
00684
00685 static const OldChunks cargo_payment_rate_chunk[] = {
00686 OCL_VAR ( OC_INT32, 1, &_old_price ),
00687 OCL_VAR ( OC_UINT16, 1, &_old_price_frac ),
00688
00689 OCL_NULL( 2 ),
00690 OCL_END()
00691 };
00692
00693 static bool LoadOldCargoPaymentRate(LoadgameState *ls, int num)
00694 {
00695 if (_savegame_type == SGT_TTO && num == 11) {
00696 _cargo_payment_rates[num] = _cargo_payment_rates[9];
00697 _cargo_payment_rates_frac[num] = _cargo_payment_rates_frac[9];
00698 return true;
00699 }
00700
00701 if (!LoadChunk(ls, NULL, cargo_payment_rate_chunk)) return false;
00702
00703 if (_savegame_type == SGT_TTO) {
00704
00705
00706
00707
00708
00709 Money m = ((((Money)_old_price) << 16) + (uint)_old_price_frac) * 124 / 74;
00710
00711 _old_price = m >> 16;
00712 _old_price_frac = GB((int64)m, 0, 16);
00713 }
00714
00715 _cargo_payment_rates[num] = -_old_price;
00716 _cargo_payment_rates_frac[num] = _old_price_frac;
00717
00718 return true;
00719 }
00720
00721 static StationID _current_station_id;
00722 static uint16 _waiting_acceptance;
00723 static uint8 _cargo_source;
00724 static uint8 _cargo_days;
00725
00726 static const OldChunks goods_chunk[] = {
00727 OCL_VAR ( OC_UINT16, 1, &_waiting_acceptance ),
00728 OCL_SVAR( OC_UINT8, GoodsEntry, days_since_pickup ),
00729 OCL_SVAR( OC_UINT8, GoodsEntry, rating ),
00730 OCL_VAR ( OC_UINT8, 1, &_cargo_source ),
00731 OCL_VAR ( OC_UINT8, 1, &_cargo_days ),
00732 OCL_SVAR( OC_UINT8, GoodsEntry, last_speed ),
00733 OCL_SVAR( OC_UINT8, GoodsEntry, last_age ),
00734
00735 OCL_END()
00736 };
00737
00738 static bool LoadOldGood(LoadgameState *ls, int num)
00739 {
00740
00741 if (_savegame_type == SGT_TTO && num == 11) return true;
00742
00743 Station *st = GetStation(_current_station_id);
00744 GoodsEntry *ge = &st->goods[num];
00745
00746 if (!LoadChunk(ls, ge, goods_chunk)) return false;
00747
00748 SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
00749 SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, _cargo_source != 0xFF);
00750 if (GB(_waiting_acceptance, 0, 12) != 0) {
00751 CargoPacket *cp = new CargoPacket();
00752 cp->source = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
00753 cp->count = GB(_waiting_acceptance, 0, 12);
00754 cp->days_in_transit = _cargo_days;
00755 ge->cargo.Append(cp);
00756 }
00757
00758 return true;
00759 }
00760
00761 static const OldChunks station_chunk[] = {
00762 OCL_SVAR( OC_TILE, Station, xy ),
00763 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
00764
00765 OCL_NULL( 4 ),
00766 OCL_SVAR( OC_TILE, Station, train_tile ),
00767 OCL_SVAR( OC_TILE, Station, airport_tile ),
00768 OCL_SVAR( OC_TILE, Station, dock_tile ),
00769 OCL_SVAR( OC_UINT8, Station, trainst_w ),
00770
00771 OCL_NULL( 1 ),
00772 OCL_NULL( 2 ),
00773
00774 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
00775
00776 OCL_NULL( 4 ),
00777
00778 OCL_SVAR( OC_UINT16, Station, had_vehicle_of_type ),
00779
00780 OCL_CHUNK( 12, LoadOldGood ),
00781
00782 OCL_SVAR( OC_UINT8, Station, time_since_load ),
00783 OCL_SVAR( OC_UINT8, Station, time_since_unload ),
00784 OCL_SVAR( OC_UINT8, Station, delete_ctr ),
00785 OCL_SVAR( OC_UINT8, Station, owner ),
00786 OCL_SVAR( OC_UINT8, Station, facilities ),
00787 OCL_SVAR( OC_TTD | OC_UINT8, Station, airport_type ),
00788 OCL_SVAR( OC_TTO | OC_FILE_U16 | OC_VAR_U64, Station, airport_flags ),
00789 OCL_NULL( 3 ),
00790 OCL_CNULL( OC_TTD, 1 ),
00791 OCL_SVAR( OC_TTD | OC_FILE_U16 | OC_VAR_U64, Station, airport_flags ),
00792 OCL_CNULL( OC_TTD, 2 ),
00793 OCL_CNULL( OC_TTD, 4 ),
00794
00795 OCL_END()
00796 };
00797
00798 static bool LoadOldStation(LoadgameState *ls, int num)
00799 {
00800 Station *st = new (num) Station();
00801 _current_station_id = num;
00802
00803 if (!LoadChunk(ls, st, station_chunk)) return false;
00804
00805 if (st->xy != 0) {
00806 st->town = GetTown(RemapTownIndex(_old_town_index));
00807
00808 if (_savegame_type == SGT_TTO) {
00809 if (IsInsideBS(_old_string_id, 0x180F, 32)) {
00810 st->string_id = STR_SV_STNAME + (_old_string_id - 0x180F);
00811 } else {
00812 st->string_id = _old_string_id + 0x2800;
00813 }
00814
00815 if (HasBit(st->airport_flags, 8)) {
00816 st->airport_type = 1;
00817 } else if (HasBit(st->airport_flags, 6)) {
00818 st->airport_type = 3;
00819 } else {
00820 st->airport_type = 0;
00821 }
00822 } else {
00823 st->string_id = RemapOldStringID(_old_string_id);
00824 }
00825 } else {
00826 st->xy = INVALID_TILE;
00827 }
00828
00829 return true;
00830 }
00831
00832 static const OldChunks industry_chunk[] = {
00833 OCL_SVAR( OC_TILE, Industry, xy ),
00834 OCL_VAR ( OC_UINT32, 1, &_old_town_index ),
00835 OCL_SVAR( OC_UINT8, Industry, width ),
00836 OCL_SVAR( OC_UINT8, Industry, height ),
00837 OCL_NULL( 2 ),
00838
00839 OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced_cargo_waiting[0] ),
00840 OCL_SVAR( OC_TTD | OC_UINT16, Industry, produced_cargo_waiting[1] ),
00841 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced_cargo_waiting[0] ),
00842 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, produced_cargo_waiting[1] ),
00843
00844 OCL_SVAR( OC_UINT8, Industry, production_rate[0] ),
00845 OCL_SVAR( OC_UINT8, Industry, production_rate[1] ),
00846
00847 OCL_NULL( 3 ),
00848
00849 OCL_SVAR( OC_UINT8, Industry, prod_level ),
00850
00851 OCL_SVAR( OC_UINT16, Industry, this_month_production[0] ),
00852 OCL_SVAR( OC_UINT16, Industry, this_month_production[1] ),
00853 OCL_SVAR( OC_UINT16, Industry, this_month_transported[0] ),
00854 OCL_SVAR( OC_UINT16, Industry, this_month_transported[1] ),
00855
00856 OCL_SVAR( OC_UINT8, Industry, last_month_pct_transported[0] ),
00857 OCL_SVAR( OC_UINT8, Industry, last_month_pct_transported[1] ),
00858
00859 OCL_SVAR( OC_UINT16, Industry, last_month_production[0] ),
00860 OCL_SVAR( OC_UINT16, Industry, last_month_production[1] ),
00861 OCL_SVAR( OC_UINT16, Industry, last_month_transported[0] ),
00862 OCL_SVAR( OC_UINT16, Industry, last_month_transported[1] ),
00863
00864 OCL_SVAR( OC_UINT8, Industry, type ),
00865 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Industry, counter ),
00866 OCL_SVAR( OC_UINT8, Industry, owner ),
00867 OCL_SVAR( OC_UINT8, Industry, random_colour ),
00868 OCL_SVAR( OC_TTD | OC_FILE_U8 | OC_VAR_I32, Industry, last_prod_year ),
00869 OCL_SVAR( OC_TTD | OC_UINT16, Industry, counter ),
00870 OCL_SVAR( OC_TTD | OC_UINT8, Industry, was_cargo_delivered ),
00871
00872 OCL_CNULL( OC_TTD, 9 ),
00873
00874 OCL_END()
00875 };
00876
00877 static bool LoadOldIndustry(LoadgameState *ls, int num)
00878 {
00879 Industry *i = new (num) Industry();
00880 if (!LoadChunk(ls, i, industry_chunk)) return false;
00881
00882 if (i->xy != 0) {
00883 i->town = GetTown(RemapTownIndex(_old_town_index));
00884
00885 if (_savegame_type == SGT_TTO) {
00886 if (i->type > 0x06) i->type++;
00887 if (i->type == 0x0A) i->type = 0x12;
00888
00889 YearMonthDay ymd;
00890 ConvertDateToYMD(_date, &ymd);
00891 i->last_prod_year = ymd.year;
00892
00893 i->random_colour = RemapTTOColour(i->random_colour);
00894 }
00895
00896 IncIndustryTypeCount(i->type);
00897 } else {
00898 i->xy = INVALID_TILE;
00899 }
00900
00901 return true;
00902 }
00903
00904 static CompanyID _current_company_id;
00905 static int32 _old_yearly;
00906
00907 static const OldChunks _company_yearly_chunk[] = {
00908 OCL_VAR( OC_INT32, 1, &_old_yearly ),
00909 OCL_END()
00910 };
00911
00912 static bool LoadOldCompanyYearly(LoadgameState *ls, int num)
00913 {
00914 Company *c = GetCompany(_current_company_id);
00915
00916 for (uint i = 0; i < 13; i++) {
00917 if (_savegame_type == SGT_TTO && i == 6) {
00918 _old_yearly = 0;
00919 } else {
00920 if (!LoadChunk(ls, NULL, _company_yearly_chunk)) return false;
00921 }
00922
00923 c->yearly_expenses[num][i] = _old_yearly;
00924 }
00925
00926 return true;
00927 }
00928
00929 static const OldChunks _company_economy_chunk[] = {
00930 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, income ),
00931 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, expenses ),
00932 OCL_SVAR( OC_INT32, CompanyEconomyEntry, delivered_cargo ),
00933 OCL_SVAR( OC_INT32, CompanyEconomyEntry, performance_history ),
00934 OCL_SVAR( OC_TTD | OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, company_value ),
00935
00936 OCL_END()
00937 };
00938
00939 static bool LoadOldCompanyEconomy(LoadgameState *ls, int num)
00940 {
00941 Company *c = GetCompany(_current_company_id);
00942
00943 if (!LoadChunk(ls, &c->cur_economy, _company_economy_chunk)) return false;
00944
00945
00946 c->cur_economy.income = -c->cur_economy.income;
00947 c->cur_economy.expenses = -c->cur_economy.expenses;
00948
00949 for (uint i = 0; i < 24; i++) {
00950 if (!LoadChunk(ls, &c->old_economy[i], _company_economy_chunk)) return false;
00951
00952 c->old_economy[i].income = -c->old_economy[i].income;
00953 c->old_economy[i].expenses = -c->old_economy[i].expenses;
00954 }
00955
00956 return true;
00957 }
00958
00959 static const OldChunks _company_chunk[] = {
00960 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
00961 OCL_SVAR( OC_UINT32, Company, name_2 ),
00962 OCL_SVAR( OC_UINT32, Company, face ),
00963 OCL_VAR ( OC_UINT16, 1, &_old_string_id_2 ),
00964 OCL_SVAR( OC_UINT32, Company, president_name_2 ),
00965
00966 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, money ),
00967 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Company, current_loan ),
00968
00969 OCL_SVAR( OC_UINT8, Company, colour ),
00970 OCL_SVAR( OC_UINT8, Company, money_fraction ),
00971 OCL_SVAR( OC_UINT8, Company, quarters_of_bankrupcy ),
00972 OCL_SVAR( OC_UINT8, Company, bankrupt_asked ),
00973 OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Company, bankrupt_value ),
00974 OCL_SVAR( OC_UINT16, Company, bankrupt_timeout ),
00975
00976 OCL_SVAR( OC_TTD | OC_UINT32, Company, cargo_types ),
00977 OCL_SVAR( OC_TTO | OC_FILE_U16 | OC_VAR_U32, Company, cargo_types ),
00978
00979 OCL_CHUNK( 3, LoadOldCompanyYearly ),
00980 OCL_CHUNK( 1, LoadOldCompanyEconomy ),
00981
00982 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Company, inaugurated_year),
00983 OCL_SVAR( OC_TILE, Company, last_build_coordinate ),
00984 OCL_SVAR( OC_UINT8, Company, num_valid_stat_ent ),
00985
00986 OCL_NULL( 230 ),
00987
00988 OCL_SVAR( OC_UINT8, Company, block_preview ),
00989 OCL_CNULL( OC_TTD, 1 ),
00990 OCL_SVAR( OC_TTD | OC_UINT8, Company, avail_railtypes ),
00991 OCL_SVAR( OC_TILE, Company, location_of_HQ ),
00992 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[0] ),
00993 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[1] ),
00994 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[2] ),
00995 OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[3] ),
00996
00997 OCL_CNULL( OC_TTD, 8 ),
00998
00999 OCL_END()
01000 };
01001
01002 static bool LoadOldCompany(LoadgameState *ls, int num)
01003 {
01004 Company *c = new (num) Company();
01005
01006 _current_company_id = (CompanyID)num;
01007
01008 if (!LoadChunk(ls, c, _company_chunk)) return false;
01009
01010 if (_old_string_id == 0) {
01011 delete c;
01012 return true;
01013 }
01014
01015 if (_savegame_type == SGT_TTO) {
01016
01017 if (HasBit(c->face, 27) && GB(c->face, 26, 1) == GB(c->face, 19, 1)) {
01018
01019 ClrBit(c->face, 27);
01020 }
01021
01022
01023 if (_old_string_id == 0 || _old_string_id == 0x4C00) {
01024 _old_string_id = STR_SV_UNNAMED;
01025 } else if (GB(_old_string_id, 8, 8) == 0x52) {
01026 _old_string_id += 0x2A00;
01027 } else {
01028 _old_string_id = RemapOldStringID(_old_string_id += 0x240D);
01029 }
01030 c->name_1 = _old_string_id;
01031
01032
01033 switch (_old_string_id_2) {
01034 case 0x4CDA: _old_string_id_2 = SPECSTR_PRESIDENT_NAME; break;
01035 case 0x0006: _old_string_id_2 = STR_SV_EMPTY; break;
01036 default: _old_string_id_2 = _old_string_id_2 + 0x2A00; break;
01037 }
01038 c->president_name_1 = _old_string_id_2;
01039
01040 c->colour = RemapTTOColour(c->colour);
01041
01042 if (num != 0) c->is_ai = true;
01043 } else {
01044 c->name_1 = RemapOldStringID(_old_string_id);
01045 c->president_name_1 = RemapOldStringID(_old_string_id_2);
01046
01047 if (num == 0) {
01048
01049 if (c->name_1 == 0)
01050 c->name_1 = STR_SV_UNNAMED;
01051 } else {
01052
01053
01054 c->is_ai = true;
01055 }
01056
01057
01058
01059
01060
01061
01062 if (c->money == 893288) c->money = c->current_loan = 100000;
01063 }
01064
01065 _company_colours[num] = (Colours)c->colour;
01066 c->inaugurated_year -= ORIGINAL_BASE_YEAR;
01067
01068 return true;
01069 }
01070
01071 static uint32 _old_order_ptr;
01072 static uint16 _old_next_ptr;
01073 static VehicleID _current_vehicle_id;
01074
01075 static const OldChunks vehicle_train_chunk[] = {
01076 OCL_SVAR( OC_UINT8, VehicleRail, track ),
01077 OCL_SVAR( OC_UINT8, VehicleRail, force_proceed ),
01078 OCL_SVAR( OC_UINT16, VehicleRail, crash_anim_pos ),
01079 OCL_SVAR( OC_UINT8, VehicleRail, railtype ),
01080
01081 OCL_NULL( 5 ),
01082
01083 OCL_END()
01084 };
01085
01086 static const OldChunks vehicle_road_chunk[] = {
01087 OCL_SVAR( OC_UINT8, VehicleRoad, state ),
01088 OCL_SVAR( OC_UINT8, VehicleRoad, frame ),
01089 OCL_SVAR( OC_UINT16, VehicleRoad, blocked_ctr ),
01090 OCL_SVAR( OC_UINT8, VehicleRoad, overtaking ),
01091 OCL_SVAR( OC_UINT8, VehicleRoad, overtaking_ctr ),
01092 OCL_SVAR( OC_UINT16, VehicleRoad, crashed_ctr ),
01093 OCL_SVAR( OC_UINT8, VehicleRoad, reverse_ctr ),
01094
01095 OCL_NULL( 1 ),
01096
01097 OCL_END()
01098 };
01099
01100 static const OldChunks vehicle_ship_chunk[] = {
01101 OCL_SVAR( OC_UINT8, VehicleShip, state ),
01102
01103 OCL_NULL( 9 ),
01104
01105 OCL_END()
01106 };
01107
01108 static const OldChunks vehicle_air_chunk[] = {
01109 OCL_SVAR( OC_UINT8, VehicleAir, pos ),
01110 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, VehicleAir, targetairport ),
01111 OCL_SVAR( OC_UINT16, VehicleAir, crashed_counter ),
01112 OCL_SVAR( OC_UINT8, VehicleAir, state ),
01113
01114 OCL_NULL( 5 ),
01115
01116 OCL_END()
01117 };
01118
01119 static const OldChunks vehicle_effect_chunk[] = {
01120 OCL_SVAR( OC_UINT16, VehicleEffect, animation_state ),
01121 OCL_SVAR( OC_UINT8, VehicleEffect, animation_substate ),
01122
01123 OCL_NULL( 7 ),
01124
01125 OCL_END()
01126 };
01127
01128 static const OldChunks vehicle_disaster_chunk[] = {
01129 OCL_SVAR( OC_UINT16, VehicleDisaster, image_override ),
01130 OCL_SVAR( OC_UINT16, VehicleDisaster, big_ufo_destroyer_target ),
01131
01132 OCL_NULL( 6 ),
01133
01134 OCL_END()
01135 };
01136
01137 static const OldChunks vehicle_empty_chunk[] = {
01138 OCL_NULL( 10 ),
01139
01140 OCL_END()
01141 };
01142
01143 static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
01144 {
01145 Vehicle *v = GetVehicle(_current_vehicle_id);
01146 uint temp = ls->total_read;
01147 bool res;
01148
01149 switch (v->type) {
01150 default: NOT_REACHED();
01151 case VEH_INVALID : res = LoadChunk(ls, NULL, vehicle_empty_chunk); break;
01152 case VEH_TRAIN : res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break;
01153 case VEH_ROAD : res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break;
01154 case VEH_SHIP : res = LoadChunk(ls, &v->u.ship, vehicle_ship_chunk); break;
01155 case VEH_AIRCRAFT: res = LoadChunk(ls, &v->u.air, vehicle_air_chunk); break;
01156 case VEH_EFFECT : res = LoadChunk(ls, &v->u.effect, vehicle_effect_chunk); break;
01157 case VEH_DISASTER: res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break;
01158 }
01159
01160
01161 if (ls->total_read - temp != 10) {
01162 DEBUG(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
01163 return false;
01164 }
01165
01166 return res;
01167 }
01168
01169 static uint16 _cargo_count;
01170
01171 static const OldChunks vehicle_chunk[] = {
01172 OCL_SVAR( OC_UINT8, Vehicle, subtype ),
01173
01174 OCL_NULL( 2 ),
01175 OCL_NULL( 2 ),
01176
01177 OCL_VAR ( OC_UINT32, 1, &_old_order_ptr ),
01178 OCL_VAR ( OC_UINT16, 1, &_old_order ),
01179
01180 OCL_NULL ( 1 ),
01181 OCL_SVAR( OC_UINT8, Vehicle, cur_order_index ),
01182 OCL_SVAR( OC_TILE, Vehicle, dest_tile ),
01183 OCL_SVAR( OC_UINT16, Vehicle, load_unload_time_rem ),
01184 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
01185 OCL_SVAR( OC_UINT16, Vehicle, service_interval ),
01186 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, last_station_visited ),
01187 OCL_SVAR( OC_TTD | OC_UINT8, Vehicle, tick_counter ),
01188 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, max_speed ),
01189 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, max_speed ),
01190
01191 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, x_pos ),
01192 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ),
01193 OCL_SVAR( OC_UINT8, Vehicle, z_pos ),
01194 OCL_SVAR( OC_UINT8, Vehicle, direction ),
01195 OCL_NULL( 2 ),
01196 OCL_NULL( 2 ),
01197 OCL_NULL( 1 ),
01198
01199 OCL_SVAR( OC_UINT8, Vehicle, owner ),
01200 OCL_SVAR( OC_TILE, Vehicle, tile ),
01201 OCL_SVAR( OC_UINT16, Vehicle, cur_image ),
01202
01203 OCL_NULL( 8 ),
01204
01205 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Vehicle, vehstatus ),
01206 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cur_speed ),
01207 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cur_speed ),
01208 OCL_SVAR( OC_UINT8, Vehicle, subspeed ),
01209 OCL_SVAR( OC_UINT8, Vehicle, acceleration ),
01210 OCL_SVAR( OC_UINT8, Vehicle, progress ),
01211
01212 OCL_SVAR( OC_UINT8, Vehicle, cargo_type ),
01213 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, cargo_cap ),
01214 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, cargo_cap ),
01215 OCL_VAR ( OC_TTD | OC_UINT16, 1, &_cargo_count ),
01216 OCL_VAR ( OC_TTO | OC_FILE_U8 | OC_VAR_U16, 1, &_cargo_count ),
01217 OCL_VAR ( OC_UINT8, 1, &_cargo_source ),
01218 OCL_VAR ( OC_UINT8, 1, &_cargo_days ),
01219
01220 OCL_SVAR( OC_TTO | OC_UINT8, Vehicle, tick_counter ),
01221
01222 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, age ),
01223 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, max_age ),
01224 OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, build_year ),
01225 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, unitnumber ),
01226
01227 OCL_SVAR( OC_TTD | OC_UINT16, Vehicle, engine_type ),
01228 OCL_SVAR( OC_TTO | OC_FILE_U8 | OC_VAR_U16, Vehicle, engine_type ),
01229
01230 OCL_SVAR( OC_UINT8, Vehicle, spritenum ),
01231 OCL_SVAR( OC_UINT8, Vehicle, day_counter ),
01232
01233 OCL_SVAR( OC_UINT8, Vehicle, breakdowns_since_last_service ),
01234 OCL_SVAR( OC_UINT8, Vehicle, breakdown_ctr ),
01235 OCL_SVAR( OC_UINT8, Vehicle, breakdown_delay ),
01236 OCL_SVAR( OC_UINT8, Vehicle, breakdown_chance ),
01237
01238 OCL_CNULL( OC_TTO, 1 ),
01239
01240 OCL_SVAR( OC_UINT16, Vehicle, reliability ),
01241 OCL_SVAR( OC_UINT16, Vehicle, reliability_spd_dec ),
01242
01243 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_this_year ),
01244 OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_last_year ),
01245
01246 OCL_VAR ( OC_UINT16, 1, &_old_next_ptr ),
01247
01248 OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Vehicle, value ),
01249
01250 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
01251
01252 OCL_CHUNK( 1, LoadOldVehicleUnion ),
01253
01254 OCL_CNULL( OC_TTO, 24 ),
01255 OCL_CNULL( OC_TTD, 20 ),
01256
01257 OCL_END()
01258 };
01259
01260 bool LoadOldVehicle(LoadgameState *ls, int num)
01261 {
01262
01263 ReadTTDPatchFlags();
01264
01265 for (uint i = 0; i < _old_vehicle_multiplier; i++) {
01266 _current_vehicle_id = num * _old_vehicle_multiplier + i;
01267
01268 Vehicle *v;
01269
01270 if (_savegame_type == SGT_TTO) {
01271 uint type = ReadByte(ls);
01272 switch (type) {
01273 default: return false;
01274 case 0x00 : v = new (_current_vehicle_id) InvalidVehicle(); break;
01275 case 0x25 :
01276 case 0x20 : v = new (_current_vehicle_id) Train(); break;
01277 case 0x21 : v = new (_current_vehicle_id) RoadVehicle(); break;
01278 case 0x22 : v = new (_current_vehicle_id) Ship(); break;
01279 case 0x23 : v = new (_current_vehicle_id) Aircraft(); break;
01280 case 0x24 : v = new (_current_vehicle_id) EffectVehicle(); break;
01281 case 0x26 : v = new (_current_vehicle_id) DisasterVehicle(); break;
01282 }
01283
01284 if (!LoadChunk(ls, v, vehicle_chunk)) return false;
01285
01286 SpriteID sprite = v->cur_image;
01287
01288 if (IsInsideMM(sprite, 1460, 1465)) {
01289 sprite += 580;
01290 } else if (IsInsideMM(sprite, 2096, 2115)) {
01291 sprite += 977;
01292 } else if (IsInsideMM(sprite, 2396, 2436)) {
01293 sprite += 1305;
01294 } else if (IsInsideMM(sprite, 2516, 2539)) {
01295 sprite += 1385;
01296 }
01297 v->cur_image = sprite;
01298
01299 switch (v->type) {
01300 case VEH_TRAIN: {
01301 static const byte spriteset_rail[] = {
01302 0, 2, 4, 4, 8, 10, 12, 14, 16, 18, 20, 22, 40, 42, 44, 46,
01303 48, 52, 54, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 120, 122,
01304 124, 126, 128, 130, 132, 134, 136, 138, 140
01305 };
01306 if (v->spritenum / 2 >= lengthof(spriteset_rail)) return false;
01307 v->spritenum = spriteset_rail[v->spritenum / 2];
01308 v->u.rail.railtype = type == 0x25 ? 1 : 0;
01309 break;
01310 }
01311
01312 case VEH_ROAD:
01313 if (v->spritenum >= 22) v->spritenum += 12;
01314 break;
01315
01316 case VEH_SHIP:
01317 v->spritenum += 2;
01318
01319 switch (v->spritenum) {
01320 case 2:
01321 if (v->cargo_type != CT_OIL) v->spritenum = 0;
01322 break;
01323 case 4:
01324 if (v->cargo_type == CT_MAIL) v->spritenum = 0;
01325 break;
01326 default:
01327 break;
01328 }
01329 break;
01330
01331 default:
01332 break;
01333 }
01334
01335 switch (_old_string_id) {
01336 case 0x0000: break;
01337 case 0x0006: _old_string_id = STR_SV_EMPTY; break;
01338 case 0x8495: _old_string_id = STR_SV_TRAIN_NAME; break;
01339 case 0x8842: _old_string_id = STR_SV_ROADVEH_NAME; break;
01340 case 0x8C3B: _old_string_id = STR_SV_SHIP_NAME; break;
01341 case 0x9047: _old_string_id = STR_SV_AIRCRAFT_NAME; break;
01342 default: _old_string_id += 0x2A00; break;
01343 }
01344
01345 _old_vehicle_names[_current_vehicle_id] = _old_string_id;
01346 } else {
01347
01348 switch (ReadByte(ls)) {
01349 default: NOT_REACHED();
01350 case 0x00 : v = new (_current_vehicle_id) InvalidVehicle(); break;
01351 case 0x10 : v = new (_current_vehicle_id) Train(); break;
01352 case 0x11 : v = new (_current_vehicle_id) RoadVehicle(); break;
01353 case 0x12 : v = new (_current_vehicle_id) Ship(); break;
01354 case 0x13 : v = new (_current_vehicle_id) Aircraft(); break;
01355 case 0x14 : v = new (_current_vehicle_id) EffectVehicle(); break;
01356 case 0x15 : v = new (_current_vehicle_id) DisasterVehicle(); break;
01357 }
01358 if (!LoadChunk(ls, v, vehicle_chunk)) return false;
01359
01360 _old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
01361
01362
01363 if (v->index != _current_vehicle_id) {
01364 DEBUG(oldloader, 0, "Loading failed - vehicle-array is invalid");
01365 return false;
01366 }
01367 }
01368
01369 if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
01370 uint max = _savegame_type == SGT_TTO ? 3000 : 5000;
01371 uint old_id = RemapOrderIndex(_old_order_ptr);
01372 if (old_id < max) v->orders.old = GetOrder(old_id);
01373 }
01374 v->current_order.AssignOrder(UnpackOldOrder(_old_order));
01375
01376 if (_old_next_ptr != 0xFFFF) v->next = GetVehiclePoolSize() <= _old_next_ptr ? new (_old_next_ptr) InvalidVehicle() : GetVehicle(_old_next_ptr);
01377
01378 if (_cargo_count != 0) {
01379 CargoPacket *cp = new CargoPacket((_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, _cargo_count);
01380 cp->days_in_transit = _cargo_days;
01381 v->cargo.Append(cp);
01382 }
01383 }
01384
01385 return true;
01386 }
01387
01388 static const OldChunks sign_chunk[] = {
01389 OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
01390 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, x ),
01391 OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, y ),
01392 OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, Sign, z ),
01393
01394 OCL_NULL( 6 ),
01395
01396 OCL_END()
01397 };
01398
01399 static bool LoadOldSign(LoadgameState *ls, int num)
01400 {
01401 Sign *si = new (num) Sign();
01402 if (!LoadChunk(ls, si, sign_chunk)) return false;
01403
01404 if (_old_string_id != 0) {
01405 if (_savegame_type == SGT_TTO) {
01406 if (_old_string_id != 0x140A) si->name = CopyFromOldName(_old_string_id + 0x2A00);
01407 } else {
01408 si->name = CopyFromOldName(RemapOldStringID(_old_string_id));
01409 }
01410 si->owner = OWNER_NONE;
01411 }
01412
01413 return true;
01414 }
01415
01416 static const OldChunks engine_chunk[] = {
01417 OCL_SVAR( OC_UINT16, Engine, company_avail ),
01418 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, intro_date ),
01419 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, age ),
01420 OCL_SVAR( OC_UINT16, Engine, reliability ),
01421 OCL_SVAR( OC_UINT16, Engine, reliability_spd_dec ),
01422 OCL_SVAR( OC_UINT16, Engine, reliability_start ),
01423 OCL_SVAR( OC_UINT16, Engine, reliability_max ),
01424 OCL_SVAR( OC_UINT16, Engine, reliability_final ),
01425 OCL_SVAR( OC_UINT16, Engine, duration_phase_1 ),
01426 OCL_SVAR( OC_UINT16, Engine, duration_phase_2 ),
01427 OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
01428
01429 OCL_SVAR( OC_UINT8, Engine, lifelength ),
01430 OCL_SVAR( OC_UINT8, Engine, flags ),
01431 OCL_SVAR( OC_UINT8, Engine, preview_company_rank ),
01432 OCL_SVAR( OC_UINT8, Engine, preview_wait ),
01433
01434 OCL_CNULL( OC_TTD, 2 ),
01435
01436 OCL_END()
01437 };
01438
01439 static bool LoadOldEngine(LoadgameState *ls, int num)
01440 {
01441 Engine *e = _savegame_type == SGT_TTO ? &_old_engines[num] : GetTempDataEngine(num);
01442 return LoadChunk(ls, e, engine_chunk);
01443 }
01444
01445 static bool LoadOldEngineName(LoadgameState *ls, int num)
01446 {
01447 Engine *e = GetTempDataEngine(num);
01448 e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
01449 return true;
01450 }
01451
01452 static const OldChunks subsidy_chunk[] = {
01453 OCL_SVAR( OC_UINT8, Subsidy, cargo_type ),
01454 OCL_SVAR( OC_UINT8, Subsidy, age ),
01455 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, from ),
01456 OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Subsidy, to ),
01457
01458 OCL_END()
01459 };
01460
01461 static bool LoadOldSubsidy(LoadgameState *ls, int num)
01462 {
01463 return LoadChunk(ls, &_subsidies[num], subsidy_chunk);
01464 }
01465
01466 static const OldChunks game_difficulty_chunk[] = {
01467 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, max_no_competitors ),
01468 OCL_NULL( 2),
01469 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, number_towns ),
01470 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, number_industries ),
01471 OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, DifficultySettings, max_loan ),
01472 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, initial_interest ),
01473 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, vehicle_costs ),
01474 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, competitor_speed ),
01475 OCL_NULL( 2),
01476 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, vehicle_breakdowns ),
01477 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, subsidy_multiplier ),
01478 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, construction_cost ),
01479 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, terrain_type ),
01480 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, quantity_sea_lakes ),
01481 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, economy ),
01482 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, line_reverse_mode ),
01483 OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, disasters ),
01484 OCL_END()
01485 };
01486
01487 static bool LoadOldGameDifficulty(LoadgameState *ls, int num)
01488 {
01489 bool ret = LoadChunk(ls, &_settings_game.difficulty, game_difficulty_chunk);
01490 _settings_game.difficulty.max_loan *= 1000;
01491 return ret;
01492 }
01493
01494
01495 static bool LoadOldMapPart1(LoadgameState *ls, int num)
01496 {
01497 if (_savegame_type == SGT_TTO) {
01498 MemSetT(_m, 0, OLD_MAP_SIZE);
01499 MemSetT(_me, 0, OLD_MAP_SIZE);
01500 }
01501
01502 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
01503 _m[i].m1 = ReadByte(ls);
01504 }
01505 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
01506 _m[i].m2 = ReadByte(ls);
01507 }
01508
01509 if (_savegame_type != SGT_TTO) {
01510 for (uint i = 0; i < OLD_MAP_SIZE; i++) {
01511 _old_map3[i * 2] = ReadByte(ls);
01512 _old_map3[i * 2 + 1] = ReadByte(ls);
01513 }
01514 for (uint i = 0; i < OLD_MAP_SIZE / 4; i++) {
01515 byte b = ReadByte(ls);
01516 _m[i * 4 + 0].m6 = GB(b, 0, 2);
01517 _m[i * 4 + 1].m6 = GB(b, 2, 2);
01518 _m[i * 4 + 2].m6 = GB(b, 4, 2);
01519 _m[i * 4 + 3].m6 = GB(b, 6, 2);
01520 }
01521 }
01522
01523 return !ls->failed;
01524 }
01525
01526 static bool LoadOldMapPart2(LoadgameState *ls, int num)
01527 {
01528 uint i;
01529
01530 for (i = 0; i < OLD_MAP_SIZE; i++) {
01531 _m[i].type_height = ReadByte(ls);
01532 }
01533 for (i = 0; i < OLD_MAP_SIZE; i++) {
01534 _m[i].m5 = ReadByte(ls);
01535 }
01536
01537 return !ls->failed;
01538 }
01539
01540 static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num)
01541 {
01542 ReadTTDPatchFlags();
01543
01544 DEBUG(oldloader, 2, "Found %d extra chunk(s)", _old_extra_chunk_nums);
01545
01546 for (int i = 0; i != _old_extra_chunk_nums; i++) {
01547 uint16 id = ReadUint16(ls);
01548 uint32 len = ReadUint32(ls);
01549
01550 switch (id) {
01551
01552
01553 case 0x2:
01554 case 0x8004: {
01555
01556 ReadUint32(ls); ReadByte(ls); len -= 5;
01557
01558 ClearGRFConfigList(&_grfconfig);
01559 while (len != 0) {
01560 uint32 grfid = ReadUint32(ls);
01561
01562 if (ReadByte(ls) == 1) {
01563 GRFConfig *c = CallocT<GRFConfig>(1);
01564 c->grfid = grfid;
01565 c->filename = strdup("TTDP game, no information");
01566
01567 AppendToGRFConfigList(&_grfconfig, c);
01568 DEBUG(oldloader, 3, "TTDPatch game using GRF file with GRFID %0X", BSWAP32(c->grfid));
01569 }
01570 len -= 5;
01571 };
01572
01573
01574 AppendStaticGRFConfigs(&_grfconfig);
01575 } break;
01576
01577
01578 case 0x3:
01579 _ttdp_version = ReadUint32(ls);
01580 DEBUG(oldloader, 3, "Game saved with TTDPatch version %d.%d.%d r%d",
01581 GB(_ttdp_version, 24, 8), GB(_ttdp_version, 20, 4), GB(_ttdp_version, 16, 4), GB(_ttdp_version, 0, 16));
01582 len -= 4;
01583 while (len-- != 0) ReadByte(ls);
01584 break;
01585
01586 default:
01587 DEBUG(oldloader, 4, "Skipping unknown extra chunk %X", id);
01588 while (len-- != 0) ReadByte(ls);
01589 break;
01590 }
01591 }
01592
01593 return !ls->failed;
01594 }
01595
01596 extern TileIndex _cur_tileloop_tile;
01597 static const OldChunks main_chunk[] = {
01598 OCL_ASSERT( OC_TTD, 0 ),
01599 OCL_ASSERT( OC_TTO, 0 ),
01600 OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_date ),
01601 OCL_VAR ( OC_UINT16, 1, &_date_fract ),
01602 OCL_NULL( 600 ),
01603 OCL_VAR ( OC_UINT32, 2, &_random.state ),
01604
01605 OCL_ASSERT( OC_TTD, 0x264 ),
01606 OCL_ASSERT( OC_TTO, 0x264 ),
01607
01608 OCL_CCHUNK( OC_TTD, 70, LoadOldTown ),
01609 OCL_CCHUNK( OC_TTO, 80, LoadOldTown ),
01610
01611 OCL_ASSERT( OC_TTD, 0x1C18 ),
01612 OCL_ASSERT( OC_TTO, 0x1AC4 ),
01613
01614 OCL_CCHUNK( OC_TTD, 5000, LoadOldOrder ),
01615 OCL_CCHUNK( OC_TTO, 3000, LoadOldOrder ),
01616
01617 OCL_ASSERT( OC_TTD, 0x4328 ),
01618 OCL_ASSERT( OC_TTO, 0x3234 ),
01619
01620 OCL_CHUNK( 1, LoadOldAnimTileList ),
01621 OCL_NULL( 4 ),
01622
01623 OCL_ASSERT( OC_TTO, 0x3438 ),
01624
01625 OCL_CCHUNK( OC_TTD, 255, LoadOldDepot ),
01626 OCL_CCHUNK( OC_TTO, 252, LoadOldDepot ),
01627
01628 OCL_ASSERT( OC_TTD, 0x4B26 ),
01629 OCL_ASSERT( OC_TTO, 0x3A20 ),
01630
01631 OCL_NULL( 4 ),
01632 OCL_NULL( 2 ),
01633 OCL_NULL( 2 ),
01634
01635 OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ),
01636 OCL_VAR ( OC_UINT16, 1, &_tick_counter ),
01637 OCL_VAR ( OC_TILE, 1, &_cur_tileloop_tile ),
01638
01639 OCL_ASSERT( OC_TTO, 0x3A2E ),
01640
01641 OCL_CHUNK( 49, LoadOldPrice ),
01642
01643 OCL_ASSERT( OC_TTO, 0x3B4E ),
01644
01645 OCL_CHUNK( 12, LoadOldCargoPaymentRate ),
01646
01647 OCL_ASSERT( OC_TTD, 0x4CBA ),
01648 OCL_ASSERT( OC_TTO, 0x3BA6 ),
01649
01650 OCL_CHUNK( 1, LoadOldMapPart1 ),
01651
01652 OCL_ASSERT( OC_TTD, 0x48CBA ),
01653 OCL_ASSERT( OC_TTO, 0x23BA6 ),
01654
01655 OCL_CCHUNK( OC_TTD, 250, LoadOldStation ),
01656 OCL_CCHUNK( OC_TTO, 200, LoadOldStation ),
01657
01658 OCL_ASSERT( OC_TTO, 0x29E16 ),
01659
01660 OCL_CCHUNK( OC_TTD, 90, LoadOldIndustry ),
01661 OCL_CCHUNK( OC_TTO, 100, LoadOldIndustry ),
01662
01663 OCL_ASSERT( OC_TTO, 0x2ADB6 ),
01664
01665 OCL_CHUNK( 8, LoadOldCompany ),
01666
01667 OCL_ASSERT( OC_TTD, 0x547F2 ),
01668 OCL_ASSERT( OC_TTO, 0x2C746 ),
01669
01670 OCL_CCHUNK( OC_TTD, 850, LoadOldVehicle ),
01671 OCL_CCHUNK( OC_TTO, 800, LoadOldVehicle ),
01672
01673 OCL_ASSERT( OC_TTD, 0x6F0F2 ),
01674 OCL_ASSERT( OC_TTO, 0x45746 ),
01675
01676 OCL_VAR ( OC_TTD | OC_UINT8 | OC_DEREFERENCE_POINTER, 32 * 500, &_old_name_array ),
01677 OCL_VAR ( OC_TTO | OC_UINT8 | OC_DEREFERENCE_POINTER, 24 * 200, &_old_name_array ),
01678
01679 OCL_ASSERT( OC_TTO, 0x46A06 ),
01680
01681 OCL_NULL( 0x2000 ),
01682
01683 OCL_CHUNK( 40, LoadOldSign ),
01684
01685 OCL_ASSERT( OC_TTO, 0x48C36 ),
01686
01687 OCL_CCHUNK( OC_TTD, 256, LoadOldEngine ),
01688 OCL_CCHUNK( OC_TTO, 103, LoadOldEngine ),
01689
01690 OCL_ASSERT( OC_TTO, 0x496AC ),
01691
01692 OCL_VAR ( OC_UINT16, 1, &_vehicle_id_ctr_day ),
01693
01694 OCL_CHUNK( 8, LoadOldSubsidy ),
01695
01696 OCL_ASSERT( OC_TTO, 0x496CE ),
01697
01698 OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_next_competitor_start ),
01699
01700 OCL_CNULL( OC_TTO, 2 ),
01701
01702 OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_x ),
01703 OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_y ),
01704 OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_saved_scrollpos_zoom ),
01705
01706 OCL_VAR ( OC_FILE_U32 | OC_VAR_I64, 1, &_economy.max_loan ),
01707 OCL_VAR ( OC_FILE_U32 | OC_VAR_I64, 1, &_economy.max_loan_unround ),
01708 OCL_VAR ( OC_INT16, 1, &_economy.fluct ),
01709
01710 OCL_VAR ( OC_UINT16, 1, &_disaster_delay ),
01711
01712 OCL_ASSERT( OC_TTO, 0x496E4 ),
01713
01714 OCL_CNULL( OC_TTD, 144 ),
01715
01716 OCL_CCHUNK( OC_TTD, 256, LoadOldEngineName ),
01717
01718 OCL_CNULL( OC_TTD, 144 ),
01719 OCL_NULL( 2 ),
01720 OCL_NULL( 1 ),
01721
01722 OCL_VAR ( OC_UINT8, 1, &_settings_game.locale.currency ),
01723 OCL_VAR ( OC_UINT8, 1, &_settings_game.locale.units ),
01724 OCL_VAR ( OC_FILE_U8 | OC_VAR_U32, 1, &_cur_company_tick_index ),
01725
01726 OCL_NULL( 2 ),
01727 OCL_NULL( 8 ),
01728
01729 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount ),
01730 OCL_VAR ( OC_UINT8, 1, &_economy.infl_amount_pr ),
01731 OCL_VAR ( OC_UINT8, 1, &_economy.interest_rate ),
01732 OCL_NULL( 1 ),
01733 OCL_VAR ( OC_UINT8, 1, &_settings_game.vehicle.road_side ),
01734 OCL_VAR ( OC_UINT8, 1, &_settings_game.game_creation.town_name ),
01735
01736 OCL_CHUNK( 1, LoadOldGameDifficulty ),
01737
01738 OCL_ASSERT( OC_TTD, 0x77130 ),
01739
01740 OCL_VAR ( OC_UINT8, 1, &_settings_game.difficulty.diff_level ),
01741
01742 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.landscape ),
01743 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_trees_tick_ctr ),
01744
01745 OCL_CNULL( OC_TTD, 1 ),
01746 OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.snow_line ),
01747
01748 OCL_CNULL( OC_TTD, 32 ),
01749 OCL_CNULL( OC_TTD, 36 ),
01750
01751 OCL_ASSERT( OC_TTD, 0x77179 ),
01752 OCL_ASSERT( OC_TTO, 0x4971D ),
01753
01754 OCL_CHUNK( 1, LoadOldMapPart2 ),
01755
01756 OCL_ASSERT( OC_TTD, 0x97179 ),
01757 OCL_ASSERT( OC_TTO, 0x6971D ),
01758
01759
01760 OCL_CHUNK(1, LoadTTDPatchExtraChunks),
01761
01762 OCL_END()
01763 };
01764
01765 bool LoadTTDMain(LoadgameState *ls)
01766 {
01767 _read_ttdpatch_flags = false;
01768 _ttdp_version = 0;
01769
01770 DEBUG(oldloader, 3, "Reading main chunk...");
01771
01772 SmallStackSafeStackAlloc<byte, OLD_MAP_SIZE * 2> map3;
01773 _old_map3 = map3.data;
01774 _old_vehicle_names = NULL;
01775 if (!LoadChunk(ls, NULL, main_chunk)) {
01776 DEBUG(oldloader, 0, "Loading failed");
01777 free(_old_vehicle_names);
01778 return false;
01779 }
01780 DEBUG(oldloader, 3, "Done, converting game data...");
01781
01782 FixTTDMapArray();
01783 FixTTDDepots();
01784
01785
01786 _settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
01787
01788
01789 FixOldTowns();
01790 FixOldVehicles();
01791
01792
01793 _settings_game.difficulty.town_council_tolerance = Clamp(_settings_game.difficulty.diff_level, 0, 2);
01794
01795 DEBUG(oldloader, 3, "Finished converting game data");
01796 DEBUG(oldloader, 1, "TTD(Patch) savegame successfully converted");
01797
01798 free(_old_vehicle_names);
01799
01800 return true;
01801 }
01802
01803 bool LoadTTOMain(LoadgameState *ls)
01804 {
01805 DEBUG(oldloader, 3, "Reading main chunk...");
01806
01807 SmallStackSafeStackAlloc<byte, 103 * sizeof(Engine)> engines;
01808 _old_engines = (Engine *)engines.data;
01809 SmallStackSafeStackAlloc<StringID, 800> vehnames;
01810 _old_vehicle_names = vehnames.data;
01811
01812
01813 if (!LoadChunk(ls, NULL, main_chunk)) {
01814 DEBUG(oldloader, 0, "Loading failed");
01815 return false;
01816 }
01817 DEBUG(oldloader, 3, "Done, converting game data...");
01818
01819 if (_settings_game.game_creation.town_name != 0) _settings_game.game_creation.town_name++;
01820
01821 _settings_game.game_creation.landscape = 0;
01822 _trees_tick_ctr = 0xFF;
01823
01824 if (!FixTTOMapArray() || !FixTTOEngines()) {
01825 DEBUG(oldloader, 0, "Conversion failed");
01826 return false;
01827 }
01828
01829 FixOldTowns();
01830 FixOldVehicles();
01831 FixTTOCompanies();
01832
01833
01834 _settings_game.difficulty.town_council_tolerance = Clamp(_settings_game.difficulty.diff_level, 0, 2);
01835
01836 DEBUG(oldloader, 3, "Finished converting game data");
01837 DEBUG(oldloader, 1, "TTO savegame successfully converted");
01838
01839 return true;
01840 }