(svn r16338) -Codechange: split loading of references to two phases

In the first phase, indexes are stored. In the second phase, indexes are checked for validity and converted to pointers
This commit is contained in:
smatz 2009-05-17 16:28:29 +00:00
parent 83dc6ef6e6
commit 570af0ce44
29 changed files with 231 additions and 99 deletions

View File

@ -71,7 +71,7 @@ struct CargoPacket : PoolItem<CargoPacket, CargoPacketID, &_CargoPacket_pool> {
*/
#define FOR_ALL_CARGOPACKETS(cp) FOR_ALL_CARGOPACKETS_FROM(cp, 0)
extern void SaveLoad_STNS(Station *st);
extern const struct SaveLoad *GetGoodsDesc();
/**
* Simple collection class for a list of cargo packets
@ -99,7 +99,7 @@ private:
uint days_in_transit; ///< Cache for the number of days in transit
public:
friend void SaveLoad_STNS(Station *st);
friend const struct SaveLoad *GetGoodsDesc();
/** Create the cargo list */
CargoList() { this->InvalidateCache(); }

View File

@ -260,8 +260,8 @@ private:
public:
/** Default constructor producing an invalid order list. */
OrderList()
: first(NULL), num_orders(INVALID_VEH_ORDER_ID), num_vehicles(0), first_shared(NULL),
OrderList(VehicleOrderID num_orders = INVALID_VEH_ORDER_ID)
: first(NULL), num_orders(num_orders), num_vehicles(0), first_shared(NULL),
timetable_duration(0) { }
/** Create an order list with the given order chain for the given vehicle.

View File

@ -102,5 +102,5 @@ static void Save_AIPL()
}
extern const ChunkHandler _ai_chunk_handlers[] = {
{ 'AIPL', Save_AIPL, Load_AIPL, CH_ARRAY | CH_LAST},
{ 'AIPL', Save_AIPL, Load_AIPL, NULL, CH_ARRAY | CH_LAST},
};

View File

@ -52,5 +52,5 @@ static void Load_ANIT()
* the animated tile table.
*/
extern const ChunkHandler _animated_tile_chunk_handlers[] = {
{ 'ANIT', Save_ANIT, Load_ANIT, CH_RIFF | CH_LAST},
{ 'ANIT', Save_ANIT, Load_ANIT, NULL, CH_RIFF | CH_LAST},
};

View File

@ -45,6 +45,15 @@ static void Load_ERNW()
}
}
static void Ptrs_ERNW()
{
EngineRenew *er;
FOR_ALL_ENGINE_RENEWS(er) {
SlObject(er, _engine_renew_desc);
}
}
extern const ChunkHandler _autoreplace_chunk_handlers[] = {
{ 'ERNW', Save_ERNW, Load_ERNW, CH_ARRAY | CH_LAST},
{ 'ERNW', Save_ERNW, Load_ERNW, Ptrs_ERNW, CH_ARRAY | CH_LAST},
};

View File

@ -40,5 +40,5 @@ static void Load_CAPA()
}
extern const ChunkHandler _cargopacket_chunk_handlers[] = {
{ 'CAPA', Save_CAPA, Load_CAPA, CH_ARRAY | CH_LAST},
{ 'CAPA', Save_CAPA, Load_CAPA, NULL, CH_ARRAY | CH_LAST},
};

View File

@ -33,5 +33,5 @@ static void Load_CHTS()
}
extern const ChunkHandler _cheat_chunk_handlers[] = {
{ 'CHTS', Save_CHTS, Load_CHTS, CH_RIFF | CH_LAST}
{ 'CHTS', Save_CHTS, Load_CHTS, NULL, CH_RIFF | CH_LAST},
};

View File

@ -277,6 +277,15 @@ static void Load_PLYR()
}
}
static void Ptrs_PLYR()
{
Company *c;
FOR_ALL_COMPANIES(c) {
SlObject(c, _company_desc);
}
}
extern const ChunkHandler _company_chunk_handlers[] = {
{ 'PLYR', Save_PLYR, Load_PLYR, CH_ARRAY | CH_LAST},
{ 'PLYR', Save_PLYR, Load_PLYR, Ptrs_PLYR, CH_ARRAY | CH_LAST},
};

View File

@ -35,5 +35,5 @@ static void Load_DEPT()
}
extern const ChunkHandler _depot_chunk_handlers[] = {
{ 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY | CH_LAST},
{ 'DEPT', Save_DEPT, Load_DEPT, NULL, CH_ARRAY | CH_LAST},
};

View File

@ -52,7 +52,7 @@ static void Load_ECMY()
}
extern const ChunkHandler _economy_chunk_handlers[] = {
{ 'PRIC', SaveLoad_PRIC, SaveLoad_PRIC, CH_RIFF | CH_AUTO_LENGTH},
{ 'CAPR', SaveLoad_CAPR, SaveLoad_CAPR, CH_RIFF | CH_AUTO_LENGTH},
{ 'ECMY', Save_ECMY, Load_ECMY, CH_RIFF | CH_LAST},
{ 'PRIC', SaveLoad_PRIC, SaveLoad_PRIC, NULL, CH_RIFF | CH_AUTO_LENGTH},
{ 'CAPR', SaveLoad_CAPR, SaveLoad_CAPR, NULL, CH_RIFF | CH_AUTO_LENGTH},
{ 'ECMY', Save_ECMY, Load_ECMY, NULL, CH_RIFF | CH_LAST},
};

View File

@ -143,7 +143,7 @@ static void Load_EIDS()
}
extern const ChunkHandler _engine_chunk_handlers[] = {
{ 'EIDS', Save_EIDS, Load_EIDS, CH_ARRAY },
{ 'ENGN', Save_ENGN, Load_ENGN, CH_ARRAY },
{ 'ENGS', NULL, Load_ENGS, CH_RIFF | CH_LAST },
{ 'EIDS', Save_EIDS, Load_EIDS, NULL, CH_ARRAY },
{ 'ENGN', Save_ENGN, Load_ENGN, NULL, CH_ARRAY },
{ 'ENGS', NULL, Load_ENGS, NULL, CH_RIFF | CH_LAST },
};

View File

@ -162,5 +162,5 @@ static void Save_GLOG()
extern const ChunkHandler _gamelog_chunk_handlers[] = {
{ 'GLOG', Save_GLOG, Load_GLOG, CH_RIFF | CH_LAST }
{ 'GLOG', Save_GLOG, Load_GLOG, NULL, CH_RIFF | CH_LAST }
};

View File

@ -39,5 +39,5 @@ static void Load_GRPS(void)
}
extern const ChunkHandler _group_chunk_handlers[] = {
{ 'GRPS', Save_GRPS, Load_GRPS, CH_ARRAY | CH_LAST},
{ 'GRPS', Save_GRPS, Load_GRPS, NULL, CH_ARRAY | CH_LAST},
};

View File

@ -148,8 +148,17 @@ static void Load_TIDS()
}
}
static void Ptrs_INDY()
{
Industry *i;
FOR_ALL_INDUSTRIES(i) {
SlObject(i, _industry_desc);
}
}
extern const ChunkHandler _industry_chunk_handlers[] = {
{ 'INDY', Save_INDY, Load_INDY, CH_ARRAY},
{ 'IIDS', Save_IIDS, Load_IIDS, CH_ARRAY},
{ 'TIDS', Save_TIDS, Load_TIDS, CH_ARRAY | CH_LAST},
{ 'INDY', Save_INDY, Load_INDY, Ptrs_INDY, CH_ARRAY},
{ 'IIDS', Save_IIDS, Load_IIDS, NULL, CH_ARRAY},
{ 'TIDS', Save_TIDS, Load_TIDS, NULL, CH_ARRAY | CH_LAST},
};

View File

@ -120,6 +120,6 @@ static void Load_RAIL()
}
extern const ChunkHandler _labelmaps_chunk_handlers[] = {
{ 'RAIL', Save_RAIL, Load_RAIL, CH_ARRAY | CH_LAST},
{ 'RAIL', Save_RAIL, Load_RAIL, NULL, CH_ARRAY | CH_LAST},
};

View File

@ -236,13 +236,13 @@ static void Save_MAP7()
}
extern const ChunkHandler _map_chunk_handlers[] = {
{ 'MAPS', Save_MAPS, Load_MAPS, CH_RIFF },
{ 'MAPT', Save_MAPT, Load_MAPT, CH_RIFF },
{ 'MAPO', Save_MAP1, Load_MAP1, CH_RIFF },
{ 'MAP2', Save_MAP2, Load_MAP2, CH_RIFF },
{ 'M3LO', Save_MAP3, Load_MAP3, CH_RIFF },
{ 'M3HI', Save_MAP4, Load_MAP4, CH_RIFF },
{ 'MAP5', Save_MAP5, Load_MAP5, CH_RIFF },
{ 'MAPE', Save_MAP6, Load_MAP6, CH_RIFF },
{ 'MAP7', Save_MAP7, Load_MAP7, CH_RIFF | CH_LAST },
{ 'MAPS', Save_MAPS, Load_MAPS, NULL, CH_RIFF },
{ 'MAPT', Save_MAPT, Load_MAPT, NULL, CH_RIFF },
{ 'MAPO', Save_MAP1, Load_MAP1, NULL, CH_RIFF },
{ 'MAP2', Save_MAP2, Load_MAP2, NULL, CH_RIFF },
{ 'M3LO', Save_MAP3, Load_MAP3, NULL, CH_RIFF },
{ 'M3HI', Save_MAP4, Load_MAP4, NULL, CH_RIFF },
{ 'MAP5', Save_MAP5, Load_MAP5, NULL, CH_RIFF },
{ 'MAPE', Save_MAP6, Load_MAP6, NULL, CH_RIFF },
{ 'MAP7', Save_MAP7, Load_MAP7, NULL, CH_RIFF | CH_LAST },
};

View File

@ -102,6 +102,6 @@ static void SaveLoad_VIEW()
}
extern const ChunkHandler _misc_chunk_handlers[] = {
{ 'DATE', SaveLoad_DATE, SaveLoad_DATE, CH_RIFF},
{ 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, CH_RIFF | CH_LAST},
{ 'DATE', SaveLoad_DATE, SaveLoad_DATE, NULL, CH_RIFF},
{ 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, NULL, CH_RIFF | CH_LAST},
};

View File

@ -48,5 +48,5 @@ static void Load_NGRF()
}
extern const ChunkHandler _newgrf_chunk_handlers[] = {
{ 'NGRF', Save_NGRF, Load_NGRF, CH_ARRAY | CH_LAST }
{ 'NGRF', Save_NGRF, Load_NGRF, NULL, CH_ARRAY | CH_LAST }
};

View File

@ -121,7 +121,7 @@ static void Load_ORDR()
{
if (CheckSavegameVersionOldStyle(5, 2)) {
/* Version older than 5.2 did not have a ->next pointer. Convert them
(in the old days, the orderlist was 5000 items big) */
* (in the old days, the orderlist was 5000 items big) */
size_t len = SlGetFieldLength();
uint i;
@ -170,6 +170,17 @@ static void Load_ORDR()
}
}
static void Ptrs_ORDR()
{
if (CheckSavegameVersionOldStyle(5, 2)) return;
Order *o;
FOR_ALL_ORDERS(o) {
SlObject(o, GetOrderDescription());
}
}
const SaveLoad *GetOrderListDescription()
{
static const SaveLoad _orderlist_desc[] = {
@ -195,12 +206,23 @@ static void Load_ORDL()
int index;
while ((index = SlIterateArray()) != -1) {
OrderList *list = new (index) OrderList();
/* set num_orders to 0 so it's a valid OrderList */
OrderList *list = new (index) OrderList(0);
SlObject(list, GetOrderListDescription());
}
}
static void Ptrs_ORDL()
{
OrderList *list;
FOR_ALL_ORDER_LISTS(list) {
SlObject(list, GetOrderListDescription());
}
}
extern const ChunkHandler _order_chunk_handlers[] = {
{ 'ORDR', Save_ORDR, Load_ORDR, CH_ARRAY},
{ 'ORDL', Save_ORDL, Load_ORDL, CH_ARRAY | CH_LAST},
{ 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, CH_ARRAY},
{ 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, CH_ARRAY | CH_LAST},
};

View File

@ -56,6 +56,7 @@ typedef size_t ReaderProc();
enum SaveLoadAction {
SLA_LOAD, ///< loading
SLA_SAVE, ///< saving
SLA_PTRS, ///< fixing pointers
};
enum NeedLength {
@ -564,6 +565,7 @@ static void SlSaveLoadConv(void *ptr, VarType conv)
WriteValue(ptr, conv, x);
break;
}
case SLA_PTRS: break;
default: NOT_REACHED();
}
}
@ -671,6 +673,7 @@ static void SlString(void *ptr, size_t length, VarType conv)
str_validate((char *)ptr, (char *)ptr + len);
break;
}
case SLA_PTRS: break;
default: NOT_REACHED();
}
}
@ -693,6 +696,8 @@ static inline size_t SlCalcArrayLen(size_t length, VarType conv)
*/
void SlArray(void *array, size_t length, VarType conv)
{
if (_sl.action == SLA_PTRS) return;
/* Automatically calculate the length? */
if (_sl.need_length != NL_NONE) {
SlSetLength(SlCalcArrayLen(length, conv));
@ -767,13 +772,14 @@ void SlList(void *list, SLRefType conv)
if (_sl.need_length == NL_CALCLENGTH) return;
}
std::list<void *> *l = (std::list<void *> *) list;
typedef std::list<void *> PtrList;
PtrList *l = (PtrList *)list;
switch (_sl.action) {
case SLA_SAVE: {
SlWriteUint32((uint32)l->size());
std::list<void *>::iterator iter;
PtrList::iterator iter;
for (iter = l->begin(); iter != l->end(); ++iter) {
void *ptr = *iter;
SlWriteUint32(ReferenceToInt(ptr, conv));
@ -785,7 +791,18 @@ void SlList(void *list, SLRefType conv)
/* Load each reference and push to the end of the list */
for (uint i = 0; i < length; i++) {
void *ptr = IntToReference(CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32(), conv);
size_t data = CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32();
l->push_back((void *)data);
}
break;
}
case SLA_PTRS: {
PtrList temp = *l;
l->clear();
PtrList::iterator iter;
for (iter = temp.begin(); iter != temp.end(); ++iter) {
void *ptr = IntToReference((size_t)*iter, conv);
l->push_back(ptr);
}
break;
@ -885,7 +902,10 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
SlWriteUint32(ReferenceToInt(*(void **)ptr, (SLRefType)conv));
break;
case SLA_LOAD:
*(void **)ptr = IntToReference(CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32(), (SLRefType)conv);
*(size_t *)ptr = (size_t)(CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32());
break;
case SLA_PTRS:
*(void **)ptr = IntToReference(*(size_t *)ptr, (SLRefType)conv);
break;
default: NOT_REACHED();
}
@ -906,6 +926,7 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
switch (_sl.action) {
case SLA_SAVE: SlWriteByte(sld->version_to); break;
case SLA_LOAD: *(byte *)ptr = sld->version_from; break;
case SLA_PTRS: break;
default: NOT_REACHED();
}
break;
@ -1116,6 +1137,33 @@ static void SlLoadChunks()
}
}
/** Fix all pointers (convert index -> pointer) */
static void SlFixPointers()
{
const ChunkHandler *ch;
const ChunkHandler * const *chsc;
_sl.action = SLA_PTRS;
DEBUG(sl, 1, "Fixing pointers");
for (chsc = _sl.chs; (ch = *chsc++) != NULL;) {
while (true) {
if (ch->ptrs_proc != NULL) {
DEBUG(sl, 2, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
ch->ptrs_proc();
}
if (ch->flags & CH_LAST)
break;
ch++;
}
}
DEBUG(sl, 1, "All pointers fixed");
assert(_sl.action == SLA_PTRS);
}
/*******************************************
********** START OF LZO CODE **************
*******************************************/
@ -1424,6 +1472,8 @@ static const ChunkHandler * const _chunk_handlers[] = {
*/
static uint ReferenceToInt(const void *obj, SLRefType rt)
{
assert(_sl.action == SLA_SAVE);
if (obj == NULL) return 0;
switch (rt) {
@ -1452,8 +1502,13 @@ static uint ReferenceToInt(const void *obj, SLRefType rt)
* @param rt SLRefType type of the object the pointer is sought of
* @return Return the index converted to a pointer of any type
*/
assert_compile(sizeof(size_t) <= sizeof(void *));
static void *IntToReference(uint index, SLRefType rt)
{
assert(_sl.action == SLA_PTRS);
/* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
* and should be loaded like that */
if (rt == REF_VEHICLE_OLD && !CheckSavegameVersionOldStyle(4, 4)) {
@ -1461,59 +1516,50 @@ static void *IntToReference(uint index, SLRefType rt)
}
/* No need to look up NULL pointers, just return immediately */
if (rt != REF_VEHICLE_OLD && index == 0) {
return NULL;
}
if (index == (rt == REF_VEHICLE_OLD ? 0xFFFF : 0)) return NULL;
index--; // correct for the NULL index
/* Correct index. Old vehicles were saved differently:
* invalid vehicle was 0xFFFF, now we use 0x0000 for everything invalid. */
if (rt != REF_VEHICLE_OLD) index--;
switch (rt) {
case REF_ORDERLIST:
if (_OrderList_pool.AddBlockIfNeeded(index)) return OrderList::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "OrderList index out of range");
if (OrderList::IsValidID(index)) return OrderList::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid OrderList");
case REF_ORDER:
if (_Order_pool.AddBlockIfNeeded(index)) return Order::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Order index out of range");
case REF_VEHICLE:
if (_Vehicle_pool.AddBlockIfNeeded(index)) return Vehicle::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Vehicle index out of range");
case REF_STATION:
if (_Station_pool.AddBlockIfNeeded(index)) return Station::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Station index out of range");
case REF_TOWN:
if (_Town_pool.AddBlockIfNeeded(index)) return Town::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Town index out of range");
case REF_ROADSTOPS:
if (_RoadStop_pool.AddBlockIfNeeded(index)) return RoadStop::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "RoadStop index out of range");
case REF_ENGINE_RENEWS:
if (_EngineRenew_pool.AddBlockIfNeeded(index)) return EngineRenew::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "EngineRenew index out of range");
case REF_CARGO_PACKET:
if (_CargoPacket_pool.AddBlockIfNeeded(index)) return CargoPacket::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "CargoPacket index out of range");
if (Order::IsValidID(index)) return Order::Get(index);
/* in old versions, invalid order was used to mark end of order list */
if (CheckSavegameVersionOldStyle(5, 2)) return NULL;
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid Order");
case REF_VEHICLE_OLD:
/* Old vehicles were saved differently:
* invalid vehicle was 0xFFFF,
* and the index was not - 1.. correct for this */
index++;
if (index == INVALID_VEHICLE) return NULL;
case REF_VEHICLE:
if (Vehicle::IsValidID(index)) return Vehicle::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid Vehicle");
if (_Vehicle_pool.AddBlockIfNeeded(index)) return Vehicle::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Vehicle index out of range");
case REF_STATION:
if (Station::IsValidID(index)) return Station::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid Station");
case REF_TOWN:
if (Town::IsValidID(index)) return Town::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid Town");
case REF_ROADSTOPS:
if (RoadStop::IsValidID(index)) return RoadStop::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid RoadStop");
case REF_ENGINE_RENEWS:
if (EngineRenew::IsValidID(index)) return EngineRenew::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid EngineRenew");
case REF_CARGO_PACKET:
if (CargoPacket::IsValidID(index)) return CargoPacket::Get(index);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid CargoPacket");
default: NOT_REACHED();
}
return NULL;
}
/** The format for a reader/writer type of a savegame */
@ -1852,6 +1898,7 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
GamelogReset();
SlLoadChunks();
SlFixPointers();
fmt->uninit_read();
fclose(_sl.fh);

View File

@ -52,6 +52,7 @@ struct ChunkHandler {
uint32 id;
ChunkSaveLoadProc *save_proc;
ChunkSaveLoadProc *load_proc;
ChunkSaveLoadProc *ptrs_proc;
uint32 flags;
};

View File

@ -51,5 +51,5 @@ static void Load_SIGN()
}
extern const ChunkHandler _sign_chunk_handlers[] = {
{ 'SIGN', Save_SIGN, Load_SIGN, CH_ARRAY | CH_LAST},
{ 'SIGN', Save_SIGN, Load_SIGN, NULL, CH_ARRAY | CH_LAST},
};

View File

@ -118,10 +118,9 @@ static const SaveLoad _station_speclist_desc[] = {
SLE_END()
};
void SaveLoad_STNS(Station *st)
const SaveLoad *GetGoodsDesc()
{
static const SaveLoad _goods_desc[] = {
static const SaveLoad goods_desc[] = {
SLEG_CONDVAR( _waiting_acceptance, SLE_UINT16, 0, 67),
SLE_CONDVAR(GoodsEntry, acceptance_pickup, SLE_UINT8, 68, SL_MAX_VERSION),
SLE_CONDNULL(2, 51, 67),
@ -140,7 +139,12 @@ void SaveLoad_STNS(Station *st)
SLE_END()
};
return goods_desc;
}
static void SaveLoad_STNS(Station *st)
{
SlObject(st, _station_desc);
_waiting_acceptance = 0;
@ -148,7 +152,7 @@ void SaveLoad_STNS(Station *st)
uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
for (CargoID i = 0; i < num_cargo; i++) {
GoodsEntry *ge = &st->goods[i];
SlObject(ge, _goods_desc);
SlObject(ge, GetGoodsDesc());
if (CheckSavegameVersion(68)) {
SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
if (GB(_waiting_acceptance, 0, 12) != 0) {
@ -197,6 +201,21 @@ static void Load_STNS()
}
}
void Ptrs_STNS()
{
Station *st;
FOR_ALL_STATIONS(st) {
if (!CheckSavegameVersion(68)) {
for (CargoID i = 0; i < NUM_CARGO; i++) {
GoodsEntry *ge = &st->goods[i];
SlObject(ge, GetGoodsDesc());
}
}
SlObject(st, _station_desc);
}
}
static void Save_ROADSTOP()
{
RoadStop *rs;
@ -218,7 +237,15 @@ static void Load_ROADSTOP()
}
}
static void Ptrs_ROADSTOP()
{
RoadStop *rs;
FOR_ALL_ROADSTOPS(rs) {
SlObject(rs, _roadstop_desc);
}
}
extern const ChunkHandler _station_chunk_handlers[] = {
{ 'STNS', Save_STNS, Load_STNS, CH_ARRAY },
{ 'ROAD', Save_ROADSTOP, Load_ROADSTOP, CH_ARRAY | CH_LAST},
{ 'STNS', Save_STNS, Load_STNS, Ptrs_STNS, CH_ARRAY },
{ 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, CH_ARRAY | CH_LAST},
};

View File

@ -119,5 +119,5 @@ static void Load_NAME()
}
extern const ChunkHandler _name_chunk_handlers[] = {
{ 'NAME', NULL, Load_NAME, CH_ARRAY | CH_LAST},
{ 'NAME', NULL, Load_NAME, NULL, CH_ARRAY | CH_LAST},
};

View File

@ -39,5 +39,5 @@ void Load_SUBS()
}
extern const ChunkHandler _subsidy_chunk_handlers[] = {
{ 'SUBS', Save_SUBS, Load_SUBS, CH_ARRAY | CH_LAST},
{ 'SUBS', Save_SUBS, Load_SUBS, NULL, CH_ARRAY | CH_LAST},
};

View File

@ -192,6 +192,6 @@ static void Load_TOWN()
}
extern const ChunkHandler _town_chunk_handlers[] = {
{ 'HIDS', Save_HOUSEIDS, Load_HOUSEIDS, CH_ARRAY },
{ 'CITY', Save_TOWN, Load_TOWN, CH_ARRAY | CH_LAST},
{ 'HIDS', Save_HOUSEIDS, Load_HOUSEIDS, NULL, CH_ARRAY },
{ 'CITY', Save_TOWN, Load_TOWN, NULL, CH_ARRAY | CH_LAST},
};

View File

@ -732,6 +732,14 @@ void Load_VEHS()
}
}
void Ptrs_VEHS()
{
Vehicle *v;
FOR_ALL_VEHICLES(v) {
SlObject(v, GetVehicleDescription(v->type));
}
}
extern const ChunkHandler _veh_chunk_handlers[] = {
{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY | CH_LAST},
{ 'VEHS', Save_VEHS, Load_VEHS, Ptrs_VEHS, CH_SPARSE_ARRAY | CH_LAST},
};

View File

@ -92,5 +92,5 @@ static void Load_WAYP()
}
extern const ChunkHandler _waypoint_chunk_handlers[] = {
{ 'CHKP', Save_WAYP, Load_WAYP, CH_ARRAY | CH_LAST},
{ 'CHKP', Save_WAYP, Load_WAYP, NULL, CH_ARRAY | CH_LAST},
};

View File

@ -1704,8 +1704,8 @@ void CheckConfig()
}
extern const ChunkHandler _setting_chunk_handlers[] = {
{ 'OPTS', NULL, Load_OPTS, CH_RIFF},
{ 'PATS', Save_PATS, Load_PATS, CH_RIFF | CH_LAST},
{ 'OPTS', NULL, Load_OPTS, NULL, CH_RIFF},
{ 'PATS', Save_PATS, Load_PATS, NULL, CH_RIFF | CH_LAST},
};
static bool IsSignedVarMemType(VarType vt)