(svn r1426) -Codechange: cleaned up the reference code in the saveload routines
authortruelight
Sat, 08 Jan 2005 09:48:08 +0000
changeset 938 4f84a0530758
parent 937 a8dfd3eb406f
child 939 68f8d6560c23
(svn r1426) -Codechange: cleaned up the reference code in the saveload routines
-Codechange: removed next_in_chain_old, and saved ->next for Vehicles
(and bumped savegame revision for that to version 4.4)
-Codechange: Added _sl.full_version, which has both major and minor version
engine.c
saveload.c
saveload.h
vehicle.c
vehicle.h
--- a/engine.c	Sat Jan 08 09:40:22 2005 +0000
+++ b/engine.c	Sat Jan 08 09:48:08 2005 +0000
@@ -405,8 +405,8 @@
 						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);
--- a/saveload.c	Sat Jan 08 09:40:22 2005 +0000
+++ b/saveload.c	Sat Jan 08 09:48:08 2005 +0000
@@ -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 @@
 	_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 @@
 		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 @@
 				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 @@
 				// 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;
 			}
 		}
--- a/saveload.h	Sat Jan 08 09:40:22 2005 +0000
+++ b/saveload.h	Sat Jan 08 09:48:08 2005 +0000
@@ -37,6 +37,7 @@
 	byte block_mode;
 	bool error;
 	byte version;
+	uint16 full_version;
 
 	int obj_len;
 	int array_index, last_array_index;
@@ -73,6 +74,7 @@
 	REF_VEHICLE = 1,
 	REF_STATION = 2,
 	REF_TOWN = 3,
+	REF_VEHICLE_OLD = 4,
 };
 
 
--- a/vehicle.c	Sat Jan 08 09:40:22 2005 +0000
+++ b/vehicle.c	Sat Jan 08 09:48:08 2005 +0000
@@ -1788,7 +1788,7 @@
 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 _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 @@
 				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 @@
 	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;
 
--- a/vehicle.h	Sat Jan 08 09:40:22 2005 +0000
+++ b/vehicle.h	Sat Jan 08 09:48:08 2005 +0000
@@ -118,7 +118,6 @@
 	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