diff options
Diffstat (limited to 'src/saveload')
-rw-r--r-- | src/saveload/afterload.cpp | 2 | ||||
-rw-r--r-- | src/saveload/oldloader.cpp | 4 | ||||
-rw-r--r-- | src/saveload/oldloader_sl.cpp | 55 | ||||
-rw-r--r-- | src/saveload/order_sl.cpp | 27 | ||||
-rw-r--r-- | src/saveload/saveload.cpp | 18 | ||||
-rw-r--r-- | src/saveload/strings_sl.cpp | 1 | ||||
-rw-r--r-- | src/saveload/town_sl.cpp | 6 | ||||
-rw-r--r-- | src/saveload/vehicle_sl.cpp | 4 |
8 files changed, 64 insertions, 53 deletions
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index e350b343e..f32af8537 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1457,7 +1457,7 @@ bool AfterLoadGame() Vehicle *v; FOR_ALL_VEHICLES(v) { - if (v->orders.list != NULL && v->orders.list->GetFirstOrder() != NULL && !v->orders.list->GetFirstOrder()->IsValid()) { + if (v->orders.list != NULL && v->orders.list->GetFirstOrder() != NULL && v->orders.list->GetFirstOrder()->IsType(OT_NOTHING)) { v->orders.list->FreeChain(); v->orders.list = NULL; } diff --git a/src/saveload/oldloader.cpp b/src/saveload/oldloader.cpp index 1feb3e4fa..25589a03c 100644 --- a/src/saveload/oldloader.cpp +++ b/src/saveload/oldloader.cpp @@ -148,8 +148,8 @@ bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks) default: NOT_REACHED(); } - /* Sanity check */ - assert(base_ptr != NULL || chunk->ptr != NULL); + /* When both pointers are NULL, we are just skipping data */ + if (base_ptr == NULL && chunk->ptr == NULL) continue; /* Writing to the var: bits 8 to 15 have the VAR type */ if (chunk->ptr == NULL) ptr = base_ptr + chunk->offset; diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index ca63e7c1e..5e6202401 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -160,6 +160,8 @@ void FixOldVehicles() Vehicle *v; FOR_ALL_VEHICLES(v) { + if (v->next != NULL) v->next = Vehicle::Get((size_t)v->next); + /* For some reason we need to correct for this */ switch (v->spritenum) { case 0xfd: break; @@ -578,7 +580,7 @@ static bool LoadOldTown(LoadgameState *ls, int num) t->townnametype = t->townnametype == 0x10B6 ? 0x20C1 : t->townnametype + 0x2A00; } } else { - t->xy = INVALID_TILE; + delete t; } return true; @@ -594,12 +596,15 @@ static bool LoadOldOrder(LoadgameState *ls, int num) { if (!LoadChunk(ls, NULL, order_chunk)) return false; - new (num) Order(UnpackOldOrder(_old_order)); + Order *o = new (num) Order(UnpackOldOrder(_old_order)); - /* Relink the orders to eachother (in the orders for one vehicle are behind eachother, - * with an invalid order (OT_NOTHING) as indication that it is the last order */ - if (num > 0 && Order::Get(num)->IsValid()) { - Order::Get(num - 1)->next = Order::Get(num); + if (o->IsType(OT_NOTHING)) { + delete o; + } else { + /* Relink the orders to eachother (in the orders for one vehicle are behind eachother, + * with an invalid order (OT_NOTHING) as indication that it is the last order */ + Order *prev = Order::GetIfValid(num - 1); + if (prev != NULL) prev->next = o; } return true; @@ -642,7 +647,7 @@ static bool LoadOldDepot(LoadgameState *ls, int num) if (d->xy != 0) { d->town_index = RemapTownIndex(_old_town_index); } else { - d->xy = INVALID_TILE; + delete d; } return true; @@ -823,7 +828,7 @@ static bool LoadOldStation(LoadgameState *ls, int num) st->string_id = RemapOldStringID(_old_string_id); } } else { - st->xy = INVALID_TILE; + delete st; } return true; @@ -895,7 +900,7 @@ static bool LoadOldIndustry(LoadgameState *ls, int num) IncIndustryTypeCount(i->type); } else { - i->xy = INVALID_TILE; + delete i; } return true; @@ -1142,19 +1147,22 @@ static const OldChunks vehicle_empty_chunk[] = { static bool LoadOldVehicleUnion(LoadgameState *ls, int num) { - Vehicle *v = Vehicle::Get(_current_vehicle_id); + Vehicle *v = Vehicle::GetIfValid(_current_vehicle_id); uint temp = ls->total_read; bool res; - switch (v->type) { - default: NOT_REACHED(); - case VEH_INVALID : res = LoadChunk(ls, NULL, vehicle_empty_chunk); break; - case VEH_TRAIN : res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break; - case VEH_ROAD : res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break; - case VEH_SHIP : res = LoadChunk(ls, &v->u.ship, vehicle_ship_chunk); break; - case VEH_AIRCRAFT: res = LoadChunk(ls, &v->u.air, vehicle_air_chunk); break; - case VEH_EFFECT : res = LoadChunk(ls, &v->u.effect, vehicle_effect_chunk); break; - case VEH_DISASTER: res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break; + if (v == NULL) { + res = LoadChunk(ls, NULL, vehicle_empty_chunk); + } else { + switch (v->type) { + default: NOT_REACHED(); + case VEH_TRAIN : res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break; + case VEH_ROAD : res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break; + case VEH_SHIP : res = LoadChunk(ls, &v->u.ship, vehicle_ship_chunk); break; + case VEH_AIRCRAFT: res = LoadChunk(ls, &v->u.air, vehicle_air_chunk); break; + case VEH_EFFECT : res = LoadChunk(ls, &v->u.effect, vehicle_effect_chunk); break; + case VEH_DISASTER: res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break; + } } /* This chunk size should always be 10 bytes */ @@ -1271,7 +1279,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) uint type = ReadByte(ls); switch (type) { default: return false; - case 0x00 /* VEH_INVALID */: v = new (_current_vehicle_id) InvalidVehicle(); break; + case 0x00 /* VEH_INVALID */: v = NULL; break; case 0x25 /* MONORAIL */: case 0x20 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break; case 0x21 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break; @@ -1282,6 +1290,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) } if (!LoadChunk(ls, v, vehicle_chunk)) return false; + if (v == NULL) continue; SpriteID sprite = v->cur_image; /* no need to override other sprites */ @@ -1347,7 +1356,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) /* Read the vehicle type and allocate the right vehicle */ switch (ReadByte(ls)) { default: NOT_REACHED(); - case 0x00 /* VEH_INVALID */: v = new (_current_vehicle_id) InvalidVehicle(); break; + case 0x00 /* VEH_INVALID */: v = NULL; break; case 0x10 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break; case 0x11 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break; case 0x12 /* VEH_SHIP */: v = new (_current_vehicle_id) Ship(); break; @@ -1355,7 +1364,9 @@ bool LoadOldVehicle(LoadgameState *ls, int num) case 0x14 /* VEH_EFFECT */: v = new (_current_vehicle_id) EffectVehicle(); break; case 0x15 /* VEH_DISASTER*/: v = new (_current_vehicle_id) DisasterVehicle(); break; } + if (!LoadChunk(ls, v, vehicle_chunk)) return false; + if (v == NULL) continue; _old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id); @@ -1373,7 +1384,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) } v->current_order.AssignOrder(UnpackOldOrder(_old_order)); - if (_old_next_ptr != 0xFFFF) v->next = Vehicle::GetPoolSize() <= _old_next_ptr ? new (_old_next_ptr) InvalidVehicle() : Vehicle::Get(_old_next_ptr); + if (_old_next_ptr != 0xFFFF) v->next = (Vehicle *)_old_next_ptr; if (_cargo_count != 0) { CargoPacket *cp = new CargoPacket((_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, _cargo_count); diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index 6325b3cca..d9283a2be 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -81,7 +81,7 @@ Order UnpackOldOrder(uint16 packed) * Sanity check * TTD stores invalid orders as OT_NOTHING with non-zero flags/station */ - if (!order.IsValid() && packed != 0) order.MakeDummy(); + if (order.IsType(OT_NOTHING) && packed != 0) order.MakeDummy(); return order; } @@ -123,7 +123,6 @@ static void Load_ORDR() /* Version older than 5.2 did not have a ->next pointer. Convert them * (in the old days, the orderlist was 5000 items big) */ size_t len = SlGetFieldLength(); - uint i; if (CheckSavegameVersion(5)) { /* Pre-version 5 had an other layout for orders @@ -133,9 +132,9 @@ static void Load_ORDR() SlArray(orders, len, SLE_UINT16); - for (i = 0; i < len; ++i) { - Order *order = new (i) Order(); - order->AssignOrder(UnpackVersion4Order(orders[i])); + for (size_t i = 0; i < len; ++i) { + Order *o = new (i) Order(); + o->AssignOrder(UnpackVersion4Order(orders[i])); } free(orders); @@ -145,7 +144,7 @@ static void Load_ORDR() SlArray(orders, len, SLE_UINT32); - for (i = 0; i < len; ++i) { + for (size_t i = 0; i < len; ++i) { new (i) Order(orders[i]); } @@ -153,12 +152,17 @@ static void Load_ORDR() } /* Update all the next pointer */ - for (i = 1; i < len; ++i) { + Order *o; + FOR_ALL_ORDERS(o) { + /* Delete invalid orders */ + if (o->IsType(OT_NOTHING)) { + delete o; + continue; + } /* The orders were built like this: - * While the order is valid, set the previous will get it's next pointer set - * We start with index 1 because no order will have the first in it's next pointer */ - if (Order::Get(i)->IsValid()) - Order::Get(i - 1)->next = Order::Get(i); + * While the order is valid, set the previous will get its next pointer set */ + Order *prev = Order::GetIfValid(order_index - 1); + if (prev != NULL) prev->next = o; } } else { int index; @@ -172,6 +176,7 @@ static void Load_ORDR() static void Ptrs_ORDR() { + /* Orders from old savegames have pointers corrected in Load_ORDR */ if (CheckSavegameVersionOldStyle(5, 2)) return; Order *o; diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 9389bdab2..9735970d9 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -739,8 +739,8 @@ void SlArray(void *array, size_t length, VarType conv) } -static uint ReferenceToInt(const void *obj, SLRefType rt); -static void *IntToReference(uint index, SLRefType rt); +static size_t ReferenceToInt(const void *obj, SLRefType rt); +static void *IntToReference(size_t index, SLRefType rt); /** @@ -782,15 +782,15 @@ void SlList(void *list, SLRefType conv) PtrList::iterator iter; for (iter = l->begin(); iter != l->end(); ++iter) { void *ptr = *iter; - SlWriteUint32(ReferenceToInt(ptr, conv)); + SlWriteUint32((uint32)ReferenceToInt(ptr, conv)); } break; } case SLA_LOAD: { - uint length = CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32(); + size_t length = CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32(); /* Load each reference and push to the end of the list */ - for (uint i = 0; i < length; i++) { + for (size_t i = 0; i < length; i++) { size_t data = CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32(); l->push_back((void *)data); } @@ -899,10 +899,10 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld) case SL_REF: // Reference variable, translate switch (_sl.action) { case SLA_SAVE: - SlWriteUint32(ReferenceToInt(*(void **)ptr, (SLRefType)conv)); + SlWriteUint32((uint32)ReferenceToInt(*(void **)ptr, (SLRefType)conv)); break; case SLA_LOAD: - *(size_t *)ptr = (size_t)(CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32()); + *(size_t *)ptr = CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32(); break; case SLA_PTRS: *(void **)ptr = IntToReference(*(size_t *)ptr, (SLRefType)conv); @@ -1470,7 +1470,7 @@ static const ChunkHandler * const _chunk_handlers[] = { * @param rt SLRefType type of the object the index is being sought of * @return Return the pointer converted to an index of the type pointed to */ -static uint ReferenceToInt(const void *obj, SLRefType rt) +static size_t ReferenceToInt(const void *obj, SLRefType rt) { assert(_sl.action == SLA_SAVE); @@ -1505,7 +1505,7 @@ static uint ReferenceToInt(const void *obj, SLRefType rt) assert_compile(sizeof(size_t) <= sizeof(void *)); -static void *IntToReference(uint index, SLRefType rt) +static void *IntToReference(size_t index, SLRefType rt) { assert(_sl.action == SLA_PTRS); diff --git a/src/saveload/strings_sl.cpp b/src/saveload/strings_sl.cpp index 6813c2c06..c39a036c9 100644 --- a/src/saveload/strings_sl.cpp +++ b/src/saveload/strings_sl.cpp @@ -4,6 +4,7 @@ #include "../stdafx.h" #include "../core/alloc_func.hpp" +#include "../core/math_func.hpp" #include "../string_func.h" #include "saveload_internal.h" diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 584727918..2528be2a6 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -10,8 +10,6 @@ #include "saveload.h" -extern uint _total_towns; - /** * Check and update town and house values. * @@ -181,13 +179,9 @@ static void Load_TOWN() { int index; - _total_towns = 0; - while ((index = SlIterateArray()) != -1) { Town *t = new (index) Town(); SlObject(t, _town_desc); - - _total_towns++; } } diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index ae904dbd5..a44bb6960 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -208,7 +208,7 @@ void UpdateOldAircraft() */ static void CheckValidVehicles() { - uint total_engines = Engine::GetPoolSize(); + size_t total_engines = Engine::GetPoolSize(); EngineID first_engine[4] = { INVALID_ENGINE, INVALID_ENGINE, INVALID_ENGINE, INVALID_ENGINE }; Engine *e; @@ -282,7 +282,7 @@ void AfterLoadVehicles(bool part_of_load) } } else { // OrderList was saved as such, only recalculate not saved values if (v->PreviousShared() == NULL) { - new (v->orders.list) OrderList(v->orders.list->GetFirstOrder(), v); + v->orders.list->Initialize(v->orders.list->first, v); } } } |