summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine.c4
-rw-r--r--saveload.c82
-rw-r--r--saveload.h2
-rw-r--r--vehicle.c7
-rw-r--r--vehicle.h1
5 files changed, 66 insertions, 30 deletions
diff --git a/engine.c b/engine.c
index 12d1c7d80..749bb9b4a 100644
--- a/engine.c
+++ b/engine.c
@@ -405,8 +405,8 @@ ResolveVehicleSpriteGroup(struct SpriteGroup *spritegroup, struct Vehicle *veh,
veh_prop(0x57, veh->profit_last_year & 0xFF);
veh_prop(0x58, veh->profit_last_year);
veh_prop(0x59, veh->profit_last_year & 0xFF);
- veh_prop(0x5A, veh->next_in_chain_old);
- veh_prop(0x5B, veh->next_in_chain_old & 0xFF);
+/* veh_prop(0x5A, veh->next_in_chain_old);
+ veh_prop(0x5B, veh->next_in_chain_old & 0xFF);*/
veh_prop(0x5C, veh->value);
veh_prop(0x5D, veh->value & 0xFFFFFF);
veh_prop(0x5E, veh->value & 0xFFFF);
diff --git a/saveload.c b/saveload.c
index 4d2631b5c..b99796256 100644
--- a/saveload.c
+++ b/saveload.c
@@ -8,7 +8,7 @@
enum {
SAVEGAME_MAJOR_VERSION = 4,
- SAVEGAME_MINOR_VERSION = 3,
+ SAVEGAME_MINOR_VERSION = 4,
SAVEGAME_LOADABLE_VERSION = (SAVEGAME_MAJOR_VERSION << 8) + SAVEGAME_MINOR_VERSION
};
@@ -897,29 +897,63 @@ static const byte * const _desc_includes[] = {
_common_veh_desc
};
-typedef struct {
- void *base;
- size_t size;
-} ReferenceSetup;
-
-// used to translate "pointers"
-static const ReferenceSetup _ref_setup[] = {
- {_order_array,sizeof(_order_array[0])},
- {_vehicles,sizeof(_vehicles[0])},
- {_stations,sizeof(_stations[0])},
- {_towns,sizeof(_towns[0])},
-};
-
+/* We can't save pointers to a savegame, so this functions get's
+ the index of the item, and if not available, it hussles with
+ pointers (looks really bad :()
+ Remember that a NULL item has value 0, and all
+ indexes have + 1, so vehicle 0 is saved as index 1. */
static uint ReferenceToInt(void *v, uint t)
{
- if (v == NULL) return 0;
- return ((byte*)v - (byte*)_ref_setup[t].base) / _ref_setup[t].size + 1;
+ if (v == NULL)
+ return 0;
+
+ switch (t) {
+ case REF_VEHICLE_OLD: // Old vehicles we save as new onces
+ case REF_VEHICLE: return ((Vehicle *)v)->index + 1;
+ case REF_STATION: return ((Station *)v)->index + 1;
+ case REF_TOWN: return ((Town *)v)->index + 1;
+
+ case REF_SCHEDULE:
+ return ((byte*)v - (byte*)_order_array) / sizeof(_order_array[0]) + 1;
+
+ default:
+ NOT_REACHED();
+ }
+
+ return 0;
}
void *IntToReference(uint r, uint t)
{
- if (r == 0) return NULL;
- return (byte*)_ref_setup[t].base + (r-1) * _ref_setup[t].size;
+ /* From version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE, and should be loaded
+ like that */
+ if (t == REF_VEHICLE_OLD &&
+ _sl.full_version >= 0x404)
+ t = REF_VEHICLE;
+
+ if (t != REF_VEHICLE_OLD && r == 0)
+ return NULL;
+
+ switch (t) {
+ case REF_VEHICLE: return GetVehicle(r - 1);
+ case REF_STATION: return GetStation(r - 1);
+ case REF_TOWN: return GetTown(r - 1);
+
+ case REF_SCHEDULE:
+ return (byte*)_order_array + (r - 1) * sizeof(_order_array[0]);
+
+ case REF_VEHICLE_OLD: {
+ /* Old vehicles were saved differently: invalid vehicle was 0xFFFF,
+ and the index was not - 1.. correct for this */
+ if (r == INVALID_VEHICLE)
+ return NULL;
+ return GetVehicle(r);
+ }
+ default:
+ NOT_REACHED();
+ }
+
+ return NULL;
}
typedef struct {
@@ -1029,7 +1063,7 @@ int SaveOrLoad(const char *filename, int mode)
if (!fmt->init_write()) goto init_err;
hdr[0] = fmt->tag;
- hdr[1] = TO_BE32((SAVEGAME_MAJOR_VERSION<<16) + (SAVEGAME_MINOR_VERSION << 8));
+ hdr[1] = TO_BE32((SAVEGAME_MAJOR_VERSION << 16) + (SAVEGAME_MINOR_VERSION << 8));
if (fwrite(hdr, sizeof(hdr), 1, _sl.fh) != 1) SlError("file write failed");
_sl.version = SAVEGAME_MAJOR_VERSION;
@@ -1054,6 +1088,7 @@ init_err:
printf("Unknown savegame type, trying to load it as the buggy format.\n");
rewind(_sl.fh);
_sl.version = 0;
+ _sl.full_version = 0;
version = 0;
fmt = _saveload_formats + 0; // lzo
break;
@@ -1062,9 +1097,12 @@ init_err:
// check version number
version = TO_BE32(hdr[1]) >> 8;
- // incompatible version?
- if (version > SAVEGAME_LOADABLE_VERSION) goto read_err;
- _sl.version = (version>>8);
+ /* Is the version higher than the current? */
+ if (version > SAVEGAME_LOADABLE_VERSION)
+ goto read_err;
+
+ _sl.version = (version >> 8);
+ _sl.full_version = version;
break;
}
}
diff --git a/saveload.h b/saveload.h
index d9ba00765..ab5a15cf5 100644
--- a/saveload.h
+++ b/saveload.h
@@ -37,6 +37,7 @@ typedef struct {
byte block_mode;
bool error;
byte version;
+ uint16 full_version;
int obj_len;
int array_index, last_array_index;
@@ -73,6 +74,7 @@ enum {
REF_VEHICLE = 1,
REF_STATION = 2,
REF_TOWN = 3,
+ REF_VEHICLE_OLD = 4,
};
diff --git a/vehicle.c b/vehicle.c
index 4d3692ee7..7b59272aa 100644
--- a/vehicle.c
+++ b/vehicle.c
@@ -1788,7 +1788,7 @@ restart:
const byte _common_veh_desc[] = {
SLE_VAR(Vehicle,subtype, SLE_UINT8),
- SLE_VAR(Vehicle,next_in_chain_old, SLE_UINT16),
+ SLE_REF(Vehicle,next, REF_VEHICLE_OLD),
SLE_VAR(Vehicle,string_id, SLE_STRINGID),
SLE_VAR(Vehicle,unitnumber, SLE_UINT8),
SLE_VAR(Vehicle,owner, SLE_UINT8),
@@ -1964,7 +1964,7 @@ static const byte _special_desc[] = {
static const byte _disaster_desc[] = {
SLE_WRITEBYTE(Vehicle,type,VEH_Disaster, 5),
- SLE_VAR(Vehicle,next_in_chain_old,SLE_UINT16),
+ SLE_REF(Vehicle,next, REF_VEHICLE_OLD),
SLE_VAR(Vehicle,subtype, SLE_UINT8),
SLE_VAR(Vehicle,tile, SLE_UINT16),
@@ -2024,7 +2024,6 @@ static void Save_VEHS()
v->last_station_visited = 0xFF;
SlSetArrayIndex(v->index);
- v->next_in_chain_old = v->next ? v->next->index : INVALID_VEHICLE;
SlObject(v, _veh_descs[v->type - 0x10]);
}
}
@@ -2039,9 +2038,7 @@ static void Load_VEHS()
while ((index = SlIterateArray()) != -1) {
Vehicle *v = GetVehicle(index);
- v->next_in_chain_old = INVALID_VEHICLE;
SlObject(v, _veh_descs[SlReadByte()]);
- v->next = (v->next_in_chain_old == INVALID_VEHICLE) ? NULL : GetVehicle(v->next_in_chain_old);
if (v->type == VEH_Train)
v->u.rail.first_engine = 0xffff;
diff --git a/vehicle.h b/vehicle.h
index 29bf42362..b5d564368 100644
--- a/vehicle.h
+++ b/vehicle.h
@@ -118,7 +118,6 @@ struct Vehicle {
byte subtype; // subtype (for trains, 0 == loco, 4 wagon ??)
uint16 index; // NOSAVE: Index in vehicle array
- uint16 next_in_chain_old; // Next vehicle index for chained vehicles
Vehicle *next; // next