From 9b65bc430cc4e59cba2e7ad09c2fcc0448e22781 Mon Sep 17 00:00:00 2001 From: rubidium Date: Thu, 30 Aug 2007 13:09:44 +0000 Subject: [PATCH] (svn r11004) -Codechange: some reworks of the saveload mechanism to be able to save and load private and protected variables in the vehicle struct. --- src/aircraft_cmd.cpp | 6 +++--- src/disaster_cmd.cpp | 14 +++++++------- src/oldloader.cpp | 2 +- src/saveload.cpp | 18 ++++-------------- src/saveload.h | 20 +++++++++----------- src/train_cmd.cpp | 10 +++++----- src/vehicle.cpp | 26 ++++++++++++++++++-------- src/vehicle.h | 7 +++++++ 8 files changed, 54 insertions(+), 49 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 24c2a61101..4f6098d790 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 a88a1bfe84..7034a16e01 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 5eba924cae..b43011cf49 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 3a5fbdc7b4..68b4fa808e 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 c215a83ef5..793b63dba5 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 2733a7c925..97c29a630d 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 c28a2b9c46..9a2afd4fe6 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 e2041229ff..ea75423c15 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 { 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