(svn r11004) -Codechange: some reworks of the saveload mechanism to be able to save and load private and protected variables in the vehicle struct.

This commit is contained in:
rubidium 2007-08-30 13:09:44 +00:00
parent cb7eaff353
commit 9b65bc430c
8 changed files with 54 additions and 49 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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}

View File

@ -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) {

View File

@ -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;

View File

@ -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