summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2007-08-30 13:09:44 +0000
committerrubidium <rubidium@openttd.org>2007-08-30 13:09:44 +0000
commit9b65bc430cc4e59cba2e7ad09c2fcc0448e22781 (patch)
tree6e679af8466e541ec086d1aba2cb7f6f89e4ad69
parentcb7eaff3534c1d18c9c8bc06be04ceb437d97765 (diff)
downloadopenttd-9b65bc430cc4e59cba2e7ad09c2fcc0448e22781.tar.xz
(svn r11004) -Codechange: some reworks of the saveload mechanism to be able to save and load private and protected variables in the vehicle struct.
-rw-r--r--src/aircraft_cmd.cpp6
-rw-r--r--src/disaster_cmd.cpp14
-rw-r--r--src/oldloader.cpp2
-rw-r--r--src/saveload.cpp18
-rw-r--r--src/saveload.h20
-rw-r--r--src/train_cmd.cpp10
-rw-r--r--src/vehicle.cpp26
-rw-r--r--src/vehicle.h7
8 files changed, 54 insertions, 49 deletions
diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp
index 24c2a6110..4f6098d79 100644
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -405,7 +405,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
v->u.air.state = HANGAR;
v->u.air.previous_pos = v->u.air.pos;
v->u.air.targetairport = GetStationIndex(tile);
- v->next = u;
+ v->SetNext(u);
v->service_interval = _patches.servint_aircraft;
@@ -429,8 +429,6 @@ CommandCost CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (v->subtype == AIR_HELICOPTER) {
Vehicle *w = vl[2];
- u->next = w;
-
w = new (w) Aircraft();
w->direction = DIR_N;
w->owner = _current_player;
@@ -445,6 +443,8 @@ CommandCost CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
/* Use rotor's air.state to store the rotor animation frame */
w->u.air.state = HRS_ROTOR_STOPPED;
w->UpdateDeltaXY(INVALID_DIR);
+
+ u->SetNext(w);
VehiclePositionChanged(w);
}
diff --git a/src/disaster_cmd.cpp b/src/disaster_cmd.cpp
index a88a1bfe8..7034a16e0 100644
--- a/src/disaster_cmd.cpp
+++ b/src/disaster_cmd.cpp
@@ -611,7 +611,7 @@ static void DisasterTick_Big_Ufo(Vehicle *v)
w = new DisasterVehicle();
if (w == NULL) return;
- u->next = w;
+ u->SetNext(w);
InitializeDisasterVehicle(w, -6 * TILE_SIZE, v->y_pos, 0, DIR_SW, ST_Big_Ufo_Destroyer_Shadow);
w->vehstatus |= VS_SHADOW;
} else if (v->current_order.dest == 0) {
@@ -782,7 +782,7 @@ static void Disaster_Zeppeliner_Init()
/* Allocate shadow too? */
u = new DisasterVehicle();
if (u != NULL) {
- v->next = u;
+ v->SetNext(u);
InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Zeppeliner_Shadow);
u->vehstatus |= VS_SHADOW;
}
@@ -807,7 +807,7 @@ static void Disaster_Small_Ufo_Init()
/* Allocate shadow too? */
u = new DisasterVehicle();
if (u != NULL) {
- v->next = u;
+ v->SetNext(u);
InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Small_Ufo_Shadow);
u->vehstatus |= VS_SHADOW;
}
@@ -843,7 +843,7 @@ static void Disaster_Airplane_Init()
u = new DisasterVehicle();
if (u != NULL) {
- v->next = u;
+ v->SetNext(u);
InitializeDisasterVehicle(u, x, y, 0, DIR_SE, ST_Airplane_Shadow);
u->vehstatus |= VS_SHADOW;
}
@@ -878,13 +878,13 @@ static void Disaster_Helicopter_Init()
u = new DisasterVehicle();
if (u != NULL) {
- v->next = u;
+ v->SetNext(u);
InitializeDisasterVehicle(u, x, y, 0, DIR_SW, ST_Helicopter_Shadow);
u->vehstatus |= VS_SHADOW;
w = new DisasterVehicle();
if (w != NULL) {
- u->next = w;
+ u->SetNext(w);
InitializeDisasterVehicle(w, x, y, 140, DIR_SW, ST_Helicopter_Rotors);
}
}
@@ -910,7 +910,7 @@ static void Disaster_Big_Ufo_Init()
/* Allocate shadow too? */
u = new DisasterVehicle();
if (u != NULL) {
- v->next = u;
+ v->SetNext(u);
InitializeDisasterVehicle(u, x, y, 0, DIR_NW, ST_Big_Ufo_Shadow);
u->vehstatus |= VS_SHADOW;
}
diff --git a/src/oldloader.cpp b/src/oldloader.cpp
index 5eba924ca..b43011cf4 100644
--- a/src/oldloader.cpp
+++ b/src/oldloader.cpp
@@ -1206,7 +1206,7 @@ static bool LoadOldVehicle(LoadgameState *ls, int num)
default: v->spritenum >>= 1; break;
}
- if (_old_next_ptr != 0xFFFF) v->next = GetVehicle(_old_next_ptr);
+ if (_old_next_ptr != 0xFFFF) v->SetNext(GetVehicle(_old_next_ptr));
v->string_id = RemapOldStringID(_old_string_id);
diff --git a/src/saveload.cpp b/src/saveload.cpp
index 3a5fbdc7b..68b4fa808 100644
--- a/src/saveload.cpp
+++ b/src/saveload.cpp
@@ -52,7 +52,6 @@ static struct {
ReaderProc *read_bytes; ///< savegame loader function
const ChunkHandler* const *chs; ///< the chunk of data that is being processed atm (vehicles, signs, etc.)
- const SaveLoad* const *includes; ///< the internal layouf of the given chunk
/* When saving/loading savegames, they are always saved to a temporary memory-place
* to be flushed to file (save) or to final place (load) when full. */
@@ -755,7 +754,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
}
break;
case SL_WRITEBYTE: return 1; // a byte is logically of size 1
- case SL_INCLUDE: return SlCalcObjLength(object, _sl.includes[sld->version_from]);
+ case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
default: NOT_REACHED();
}
return 0;
@@ -804,11 +803,9 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
}
break;
- /* SL_INCLUDE loads common code for a type
- * XXX - variable renaming abuse
- * include_index: common code to include from _desc_includes[], abused by sld->version_from */
- case SL_INCLUDE:
- SlObject(ptr, _sl.includes[sld->version_from]);
+ /* SL_VEH_INCLUDE loads common code for vehicles */
+ case SL_VEH_INCLUDE:
+ SlObject(ptr, GetVehicleDescription(VEH_END));
break;
default: NOT_REACHED();
}
@@ -1281,12 +1278,6 @@ static const ChunkHandler * const _chunk_handlers[] = {
NULL,
};
-/* used to include a vehicle desc in another desc. */
-extern const SaveLoad _common_veh_desc[];
-static const SaveLoad* const _desc_includes[] = {
- _common_veh_desc
-};
-
/**
* Pointers cannot be saved to a savegame, so this functions gets
* the index of the item, and if not available, it hussles with
@@ -1628,7 +1619,6 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
_sl.bufe = _sl.bufp = NULL;
_sl.offs_base = 0;
_sl.save = (mode != 0);
- _sl.includes = _desc_includes;
_sl.chs = _chunk_handlers;
/* General tactic is to first save the game to memory, then use an available writer
diff --git a/src/saveload.h b/src/saveload.h
index c215a83ef..793b63dba 100644
--- a/src/saveload.h
+++ b/src/saveload.h
@@ -160,15 +160,15 @@ enum VarTypes {
typedef uint32 VarType;
enum SaveLoadTypes {
- SL_VAR = 0,
- SL_REF = 1,
- SL_ARR = 2,
- SL_STR = 3,
- SL_LST = 4,
+ SL_VAR = 0,
+ SL_REF = 1,
+ SL_ARR = 2,
+ SL_STR = 3,
+ SL_LST = 4,
// non-normal save-load types
- SL_WRITEBYTE = 8,
- SL_INCLUDE = 9,
- SL_END = 15
+ SL_WRITEBYTE = 8,
+ SL_VEH_INCLUDE = 9,
+ SL_END = 15
};
typedef byte SaveLoadType;
@@ -209,8 +209,6 @@ typedef SaveLoad SaveLoadGlobVarList;
/* Translate values ingame to different values in the savegame and vv */
#define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value)
-/* Load common code and put it into each struct (currently only for vehicles */
-#define SLE_INCLUDE(base, variable, include_index) SLE_GENERAL(SL_INCLUDE, base, variable, 0, 0, include_index, 0)
/* The same as the ones at the top, only the offset is given directly; used for unions */
#define SLE_GENERALX(cmd, offset, type, param1, param2) {false, cmd, type, 0, param1, param2, (void*)(offset)}
@@ -221,7 +219,7 @@ typedef SaveLoad SaveLoadGlobVarList;
#define SLE_REFX(offset, type) SLE_CONDREFX(offset, type, 0, SL_MAX_VERSION)
#define SLE_WRITEBYTEX(offset, something) SLE_GENERALX(SL_WRITEBYTE, offset, 0, something, 0)
-#define SLE_INCLUDEX(offset, type) SLE_GENERALX(SL_INCLUDE, offset, type, 0, SL_MAX_VERSION)
+#define SLE_VEH_INCLUDEX() SLE_GENERALX(SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION)
/* End marker */
#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL}
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index 2733a7c92..97c29a630 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -558,7 +558,7 @@ static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 fla
SetTrainWagon(v);
if (u != NULL) {
- u->next = v;
+ u->SetNext(v);
} else {
SetFreeWagon(v);
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
@@ -636,7 +636,7 @@ static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool buildin
u->cargo_subtype = v->cargo_subtype;
u->cargo_cap = v->cargo_cap;
u->u.rail.railtype = v->u.rail.railtype;
- if (building) v->next = u;
+ if (building) v->SetNext(u);
u->engine_type = v->engine_type;
u->build_year = v->build_year;
if (building) v->value >>= 1;
@@ -840,7 +840,7 @@ static Vehicle *UnlinkWagon(Vehicle *v, Vehicle *first)
Vehicle *u;
for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
- GetLastEnginePart(u)->next = GetNextVehicle(v);
+ GetLastEnginePart(u)->SetNext(GetNextVehicle(v));
v->first = NULL; // we shouldn't point to the old first, since the vehicle isn't in that chain anymore
return first;
}
@@ -1041,7 +1041,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p
if (src != src_head) {
Vehicle *v = src_head;
while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
- GetLastEnginePart(v)->next = NULL;
+ GetLastEnginePart(v)->SetNext(NULL);
} else {
InvalidateWindowData(WC_VEHICLE_DEPOT, src_head->tile); // We removed a line
src_head = NULL;
@@ -1051,7 +1051,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p
if (src_head == dst_head) dst_head = NULL;
/* unlink single wagon from linked list */
src_head = UnlinkWagon(src, src_head);
- GetLastEnginePart(src)->next = NULL;
+ GetLastEnginePart(src)->SetNext(NULL);
}
if (dst == NULL) {
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index c28a2b9c4..9a2afd4fe 100644
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -2724,8 +2724,15 @@ static uint16 _cargo_paid_for;
static Money _cargo_feeder_share;
static uint32 _cargo_loaded_at_xy;
+/**
+ * Make it possible to make the saveload tables "friends" of other classes.
+ * @param vt the vehicle type. Can be VEH_END for the common vehicle description data
+ * @return the saveload description
+ */
+const SaveLoad *GetVehicleDescription(VehicleType vt)
+{
/** Save and load of vehicles */
-extern const SaveLoad _common_veh_desc[] = {
+static const SaveLoad _common_veh_desc[] = {
SLE_VAR(Vehicle, subtype, SLE_UINT8),
SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
@@ -2848,7 +2855,7 @@ extern const SaveLoad _common_veh_desc[] = {
static const SaveLoad _train_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN),
- SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+ SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype), SLE_UINT8),
@@ -2866,7 +2873,7 @@ static const SaveLoad _train_desc[] = {
static const SaveLoad _roadveh_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_ROAD),
- SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+ SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr), SLE_UINT16),
@@ -2886,7 +2893,7 @@ static const SaveLoad _roadveh_desc[] = {
static const SaveLoad _ship_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
- SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+ SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state), SLE_UINT8),
/* reserve extra space in savegame here. (currently 16 bytes) */
@@ -2897,7 +2904,7 @@ static const SaveLoad _ship_desc[] = {
static const SaveLoad _aircraft_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT),
- SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+ SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos), SLE_UINT8),
@@ -2988,8 +2995,12 @@ static const SaveLoad *_veh_descs[] = {
_aircraft_desc,
_special_desc,
_disaster_desc,
+ _common_veh_desc,
};
+ return _veh_descs[vt];
+}
+
/** Will be called when the vehicles need to be saved. */
static void Save_VEHS()
{
@@ -2997,7 +3008,7 @@ static void Save_VEHS()
/* Write the vehicles */
FOR_ALL_VEHICLES(v) {
SlSetArrayIndex(v->index);
- SlObject(v, _veh_descs[v->type]);
+ SlObject(v, GetVehicleDescription(v->type));
}
}
@@ -3024,7 +3035,7 @@ static void Load_VEHS()
default: NOT_REACHED();
}
- SlObject(v, _veh_descs[vtype]);
+ SlObject(v, GetVehicleDescription(vtype));
if (_cargo_count != 0 && IsPlayerBuildableVehicleType(v)) {
/* Don't construct the packet with station here, because that'll fail with old savegames */
@@ -3157,7 +3168,6 @@ void Vehicle::HandleLoading(bool mode)
InvalidateVehicleOrder(this);
}
-
void SpecialVehicle::UpdateDeltaXY(Direction direction)
{
this->x_offs = 0;
diff --git a/src/vehicle.h b/src/vehicle.h
index e2041229f..ea75423c1 100644
--- a/src/vehicle.h
+++ b/src/vehicle.h
@@ -218,11 +218,18 @@ struct VehicleShip {
struct Vehicle;
DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
+struct SaveLoad;
+extern const SaveLoad *GetVehicleDescription(VehicleType vt);
+
struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool> {
VehicleTypeByte type; ///< Type of vehicle
byte subtype; // subtype (Filled with values from EffectVehicles/TrainSubTypes/AircraftSubTypes)
+private:
Vehicle *next; // pointer to the next vehicle in the chain
+public:
+ friend const SaveLoad *GetVehicleDescription(VehicleType vt); // So we can use private/protected variables in the saveload code
+
Vehicle *first; // NOSAVE: pointer to the first vehicle in the chain
Vehicle *depot_list; // NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace