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