Changeset - r25596:7bf7822e5659
src/saveload/ai_sl.cpp
Show inline comments
 
@@ -99,27 +99,29 @@ static void Load_AIPL()
 
				/* Make sure the AI doesn't get the saveload data, as it was not the
 
				 *  writer of the saveload data in the first place */
 
				_ai_saveload_version = -1;
 
			}
 
		}
 

	
 
		config->StringToSettings(_ai_saveload_settings);
 

	
 
		/* Start the AI directly if it was active in the savegame */
 
		if (Company::IsValidAiID(index)) {
 
			AI::StartNew(index, false);
 
			AI::Load(index, _ai_saveload_version);
 
		}
 
	}
 
}
 

	
 
static void Save_AIPL()
 
{
 
	for (int i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
 
		SlSetArrayIndex(i);
 
		SlAutolength((AutolengthProc *)SaveReal_AIPL, &i);
 
	}
 
}
 

	
 
extern const ChunkHandler _ai_chunk_handlers[] = {
 
	{ 'AIPL', Save_AIPL, Load_AIPL, nullptr, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler ai_chunk_handlers[] = {
 
	{ 'AIPL', Save_AIPL, Load_AIPL, nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _ai_chunk_handlers(ai_chunk_handlers);
src/saveload/airport_sl.cpp
Show inline comments
 
@@ -13,28 +13,30 @@
 
#include "newgrf_sl.h"
 

	
 
#include "../safeguards.h"
 

	
 
static void Save_APID()
 
{
 
	Save_NewGRFMapping(_airport_mngr);
 
}
 

	
 
static void Load_APID()
 
{
 
	Load_NewGRFMapping(_airport_mngr);
 
}
 

	
 
static void Save_ATID()
 
{
 
	Save_NewGRFMapping(_airporttile_mngr);
 
}
 

	
 
static void Load_ATID()
 
{
 
	Load_NewGRFMapping(_airporttile_mngr);
 
}
 

	
 
extern const ChunkHandler _airport_chunk_handlers[] = {
 
static const ChunkHandler airport_chunk_handlers[] = {
 
	{ 'ATID', Save_ATID, Load_ATID, nullptr, nullptr, CH_ARRAY },
 
	{ 'APID', Save_APID, Load_APID, nullptr, nullptr, CH_ARRAY | CH_LAST },
 
	{ 'APID', Save_APID, Load_APID, nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _airport_chunk_handlers(airport_chunk_handlers);
src/saveload/animated_tile_sl.cpp
Show inline comments
 
@@ -34,27 +34,29 @@ static void Load_ANIT()
 
{
 
	/* Before version 80 we did NOT have a variable length animated tile table */
 
	if (IsSavegameVersionBefore(SLV_80)) {
 
		/* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
 
		TileIndex anim_list[256];
 
		SlArray(anim_list, 256, IsSavegameVersionBefore(SLV_6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
 

	
 
		for (int i = 0; i < 256; i++) {
 
			if (anim_list[i] == 0) break;
 
			_animated_tiles.push_back(anim_list[i]);
 
		}
 
		return;
 
	}
 

	
 
	uint count = (uint)SlGetFieldLength() / sizeof(_animated_tiles.front());
 
	_animated_tiles.clear();
 
	_animated_tiles.resize(_animated_tiles.size() + count);
 
	SlArray(_animated_tiles.data(), count, SLE_UINT32);
 
}
 

	
 
/**
 
 * "Definition" imported by the saveload code to be able to load and save
 
 * the animated tile table.
 
 */
 
extern const ChunkHandler _animated_tile_chunk_handlers[] = {
 
	{ 'ANIT', Save_ANIT, Load_ANIT, nullptr, nullptr, CH_RIFF | CH_LAST},
 
static const ChunkHandler animated_tile_chunk_handlers[] = {
 
	{ 'ANIT', Save_ANIT, Load_ANIT, nullptr, nullptr, CH_RIFF },
 
};
 

	
 
extern const ChunkHandlerTable _animated_tile_chunk_handlers(animated_tile_chunk_handlers);
src/saveload/autoreplace_sl.cpp
Show inline comments
 
@@ -34,27 +34,29 @@ static void Save_ERNW()
 
static void Load_ERNW()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		EngineRenew *er = new (index) EngineRenew();
 
		SlObject(er, _engine_renew_desc);
 

	
 
		/* Advanced vehicle lists, ungrouped vehicles got added */
 
		if (IsSavegameVersionBefore(SLV_60)) {
 
			er->group_id = ALL_GROUP;
 
		} else if (IsSavegameVersionBefore(SLV_71)) {
 
			if (er->group_id == DEFAULT_GROUP) er->group_id = ALL_GROUP;
 
		}
 
	}
 
}
 

	
 
static void Ptrs_ERNW()
 
{
 
	for (EngineRenew *er : EngineRenew::Iterate()) {
 
		SlObject(er, _engine_renew_desc);
 
	}
 
}
 

	
 
extern const ChunkHandler _autoreplace_chunk_handlers[] = {
 
	{ 'ERNW', Save_ERNW, Load_ERNW, Ptrs_ERNW, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler autoreplace_chunk_handlers[] = {
 
	{ 'ERNW', Save_ERNW, Load_ERNW, Ptrs_ERNW, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _autoreplace_chunk_handlers(autoreplace_chunk_handlers);
src/saveload/cargomonitor_sl.cpp
Show inline comments
 
@@ -96,28 +96,30 @@ static void SavePickup()
 
		i++;
 
		iter++;
 
	}
 
}
 

	
 
/** Load the #_cargo_pickups monitoring map. */
 
static void LoadPickup()
 
{
 
	TempStorage storage;
 
	bool fix = IsSavegameVersionBefore(SLV_FIX_CARGO_MONITOR);
 

	
 
	ClearCargoPickupMonitoring();
 
	for (;;) {
 
		if (SlIterateArray() < 0) break;
 
		SlObject(&storage, _cargomonitor_pair_desc);
 

	
 
		if (fix) storage.number = FixupCargoMonitor(storage.number);
 

	
 
		std::pair<CargoMonitorID, uint32> p(storage.number, storage.amount);
 
		_cargo_pickups.insert(p);
 
	}
 
}
 

	
 
/** Chunk definition of the cargomonitoring maps. */
 
extern const ChunkHandler _cargomonitor_chunk_handlers[] = {
 
static const ChunkHandler cargomonitor_chunk_handlers[] = {
 
	{ 'CMDL', SaveDelivery, LoadDelivery, nullptr, nullptr, CH_ARRAY},
 
	{ 'CMPU', SavePickup,   LoadPickup,   nullptr, nullptr, CH_ARRAY | CH_LAST},
 
	{ 'CMPU', SavePickup,   LoadPickup,   nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _cargomonitor_chunk_handlers(cargomonitor_chunk_handlers);
src/saveload/cargopacket_sl.cpp
Show inline comments
 
@@ -105,27 +105,29 @@ SaveLoadTable GetCargoPacketDesc()
 
 * Save the cargo packets.
 
 */
 
static void Save_CAPA()
 
{
 
	for (CargoPacket *cp : CargoPacket::Iterate()) {
 
		SlSetArrayIndex(cp->index);
 
		SlObject(cp, GetCargoPacketDesc());
 
	}
 
}
 

	
 
/**
 
 * Load the cargo packets.
 
 */
 
static void Load_CAPA()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		CargoPacket *cp = new (index) CargoPacket();
 
		SlObject(cp, GetCargoPacketDesc());
 
	}
 
}
 

	
 
/** Chunk handlers related to cargo packets. */
 
extern const ChunkHandler _cargopacket_chunk_handlers[] = {
 
	{ 'CAPA', Save_CAPA, Load_CAPA, nullptr, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler cargopacket_chunk_handlers[] = {
 
	{ 'CAPA', Save_CAPA, Load_CAPA, nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _cargopacket_chunk_handlers(cargopacket_chunk_handlers);
src/saveload/cheat_sl.cpp
Show inline comments
 
@@ -27,27 +27,29 @@ static void Save_CHTS()
 
	SlSetLength(count * 2);
 
	for (; cht != cht_last; cht++) {
 
		SlWriteByte(cht->been_used);
 
		SlWriteByte(cht->value);
 
	}
 
}
 

	
 
/**
 
 * Load the cheat values.
 
 */
 
static void Load_CHTS()
 
{
 
	Cheat *cht = (Cheat*)&_cheats;
 
	size_t count = SlGetFieldLength() / 2;
 
	/* Cannot use lengthof because _cheats is of type Cheats, not Cheat */
 
	if (count > sizeof(_cheats) / sizeof(Cheat)) SlErrorCorrupt("Too many cheat values");
 

	
 
	for (uint i = 0; i < count; i++) {
 
		cht[i].been_used = (SlReadByte() != 0);
 
		cht[i].value     = (SlReadByte() != 0);
 
	}
 
}
 

	
 
/** Chunk handlers related to cheats. */
 
extern const ChunkHandler _cheat_chunk_handlers[] = {
 
	{ 'CHTS', Save_CHTS, Load_CHTS, nullptr, nullptr, CH_RIFF | CH_LAST},
 
static const ChunkHandler cheat_chunk_handlers[] = {
 
	{ 'CHTS', Save_CHTS, Load_CHTS, nullptr, nullptr, CH_RIFF },
 
};
 

	
 
extern const ChunkHandlerTable _cheat_chunk_handlers(cheat_chunk_handlers);
src/saveload/company_sl.cpp
Show inline comments
 
@@ -506,27 +506,29 @@ static void Check_PLYR()
 
			if (GetStringTab(cprops->president_name_1) == TEXT_TAB_OLD_CUSTOM) {
 
				cprops->president_name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
 
			}
 
		}
 

	
 
		if (cprops->name.empty() && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) &&
 
				cprops->name_1 != STR_GAME_SAVELOAD_NOT_AVAILABLE && cprops->name_1 != STR_SV_UNNAMED &&
 
				cprops->name_1 != SPECSTR_ANDCO_NAME && cprops->name_1 != SPECSTR_PRESIDENT_NAME &&
 
				cprops->name_1 != SPECSTR_SILLY_NAME) {
 
			cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
 
		}
 

	
 
		if (!_load_check_data.companies.Insert(index, cprops)) delete cprops;
 
	}
 
}
 

	
 
static void Ptrs_PLYR()
 
{
 
	for (Company *c : Company::Iterate()) {
 
		SlObject(c, _company_settings_desc);
 
	}
 
}
 

	
 

	
 
extern const ChunkHandler _company_chunk_handlers[] = {
 
	{ 'PLYR', Save_PLYR, Load_PLYR, Ptrs_PLYR, Check_PLYR, CH_ARRAY | CH_LAST},
 
static const ChunkHandler company_chunk_handlers[] = {
 
	{ 'PLYR', Save_PLYR, Load_PLYR, Ptrs_PLYR, Check_PLYR, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _company_chunk_handlers(company_chunk_handlers);
src/saveload/depot_sl.cpp
Show inline comments
 
@@ -35,27 +35,29 @@ static void Save_DEPT()
 
	}
 
}
 

	
 
static void Load_DEPT()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		Depot *depot = new (index) Depot();
 
		SlObject(depot, _depot_desc);
 

	
 
		/* Set the town 'pointer' so we can restore it later. */
 
		if (IsSavegameVersionBefore(SLV_141)) depot->town = (Town *)(size_t)_town_index;
 
	}
 
}
 

	
 
static void Ptrs_DEPT()
 
{
 
	for (Depot *depot : Depot::Iterate()) {
 
		SlObject(depot, _depot_desc);
 
		if (IsSavegameVersionBefore(SLV_141)) depot->town = Town::Get((size_t)depot->town);
 
	}
 
}
 

	
 
extern const ChunkHandler _depot_chunk_handlers[] = {
 
	{ 'DEPT', Save_DEPT, Load_DEPT, Ptrs_DEPT, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler depot_chunk_handlers[] = {
 
	{ 'DEPT', Save_DEPT, Load_DEPT, Ptrs_DEPT, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _depot_chunk_handlers(depot_chunk_handlers);
src/saveload/economy_sl.cpp
Show inline comments
 
@@ -73,30 +73,32 @@ static void Save_CAPY()
 
	for (CargoPayment *cp : CargoPayment::Iterate()) {
 
		SlSetArrayIndex(cp->index);
 
		SlObject(cp, _cargopayment_desc);
 
	}
 
}
 

	
 
static void Load_CAPY()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		CargoPayment *cp = new (index) CargoPayment();
 
		SlObject(cp, _cargopayment_desc);
 
	}
 
}
 

	
 
static void Ptrs_CAPY()
 
{
 
	for (CargoPayment *cp : CargoPayment::Iterate()) {
 
		SlObject(cp, _cargopayment_desc);
 
	}
 
}
 

	
 

	
 
extern const ChunkHandler _economy_chunk_handlers[] = {
 
static const ChunkHandler economy_chunk_handlers[] = {
 
	{ 'CAPY', Save_CAPY,     Load_CAPY,     Ptrs_CAPY, nullptr, CH_ARRAY},
 
	{ 'PRIC', nullptr,       Load_PRIC,     nullptr,   nullptr, CH_RIFF },
 
	{ 'CAPR', nullptr,       Load_CAPR,     nullptr,   nullptr, CH_RIFF },
 
	{ 'ECMY', Save_ECMY,     Load_ECMY,     nullptr,   nullptr, CH_RIFF | CH_LAST},
 
	{ 'ECMY', Save_ECMY, Load_ECMY, nullptr,   nullptr, CH_RIFF  },
 
};
 

	
 
extern const ChunkHandlerTable _economy_chunk_handlers(economy_chunk_handlers);
src/saveload/engine_sl.cpp
Show inline comments
 
@@ -172,29 +172,31 @@ static const SaveLoad _engine_id_mapping
 
	SLE_VAR(EngineIDMapping, type,          SLE_UINT8),
 
	SLE_VAR(EngineIDMapping, substitute_id, SLE_UINT8),
 
};
 

	
 
static void Save_EIDS()
 
{
 
	uint index = 0;
 
	for (EngineIDMapping &eid : _engine_mngr) {
 
		SlSetArrayIndex(index);
 
		SlObject(&eid, _engine_id_mapping_desc);
 
		index++;
 
	}
 
}
 

	
 
static void Load_EIDS()
 
{
 
	_engine_mngr.clear();
 

	
 
	while (SlIterateArray() != -1) {
 
		EngineIDMapping *eid = &_engine_mngr.emplace_back();
 
		SlObject(eid, _engine_id_mapping_desc);
 
	}
 
}
 

	
 
extern const ChunkHandler _engine_chunk_handlers[] = {
 
static const ChunkHandler engine_chunk_handlers[] = {
 
	{ 'EIDS', Save_EIDS, Load_EIDS, nullptr, nullptr, CH_ARRAY          },
 
	{ 'ENGN', Save_ENGN, Load_ENGN, nullptr, nullptr, CH_ARRAY          },
 
	{ 'ENGS', nullptr,   Load_ENGS, nullptr, nullptr, CH_RIFF | CH_LAST },
 
	{ 'ENGS', nullptr,   Load_ENGS, nullptr, nullptr, CH_RIFF  },
 
};
 

	
 
extern const ChunkHandlerTable _engine_chunk_handlers(engine_chunk_handlers);
src/saveload/game_sl.cpp
Show inline comments
 
@@ -152,28 +152,30 @@ static void Load_GSTR()
 
		_current_data->raw_strings.push_back(std::move(ls));
 
	}
 

	
 
	/* If there were no strings in the savegame, set GameStrings to nullptr */
 
	if (_current_data->raw_strings.size() == 0) {
 
		delete _current_data;
 
		_current_data = nullptr;
 
		return;
 
	}
 

	
 
	_current_data->Compile();
 
	ReconsiderGameScriptLanguage();
 
}
 

	
 
static void Save_GSTR()
 
{
 
	if (_current_data == nullptr) return;
 

	
 
	for (uint i = 0; i < _current_data->raw_strings.size(); i++) {
 
		SlSetArrayIndex(i);
 
		SlAutolength((AutolengthProc *)SaveReal_GSTR, &_current_data->raw_strings[i]);
 
	}
 
}
 

	
 
extern const ChunkHandler _game_chunk_handlers[] = {
 
static const ChunkHandler game_chunk_handlers[] = {
 
	{ 'GSTR', Save_GSTR, Load_GSTR, nullptr, nullptr, CH_ARRAY },
 
	{ 'GSDT', Save_GSDT, Load_GSDT, nullptr, nullptr, CH_ARRAY | CH_LAST},
 
	{ 'GSDT', Save_GSDT, Load_GSDT, nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _game_chunk_handlers(game_chunk_handlers);
src/saveload/gamelog_sl.cpp
Show inline comments
 
@@ -147,27 +147,29 @@ static void Save_GLOG()
 
		SlWriteByte(la->at);
 
		SlObject(la, _glog_action_desc);
 

	
 
		const LoggedChange *lcend = &la->change[la->changes];
 
		for (LoggedChange *lc = la->change; lc != lcend; lc++) {
 
			SlWriteByte(lc->ct);
 
			assert((uint)lc->ct < GLCT_END);
 
			SlObject(lc, _glog_desc[lc->ct]);
 
		}
 
		SlWriteByte(GLCT_NONE);
 
	}
 
	SlWriteByte(GLAT_NONE);
 
}
 

	
 
static void Load_GLOG()
 
{
 
	Load_GLOG_common(_gamelog_action, _gamelog_actions);
 
}
 

	
 
static void Check_GLOG()
 
{
 
	Load_GLOG_common(_load_check_data.gamelog_action, _load_check_data.gamelog_actions);
 
}
 

	
 
extern const ChunkHandler _gamelog_chunk_handlers[] = {
 
	{ 'GLOG', Save_GLOG, Load_GLOG, nullptr, Check_GLOG, CH_RIFF | CH_LAST }
 
static const ChunkHandler gamelog_chunk_handlers[] = {
 
	{ 'GLOG', Save_GLOG, Load_GLOG, nullptr, Check_GLOG, CH_RIFF }
 
};
 

	
 
extern const ChunkHandlerTable _gamelog_chunk_handlers(gamelog_chunk_handlers);
src/saveload/goal_sl.cpp
Show inline comments
 
@@ -19,27 +19,29 @@ static const SaveLoad _goals_desc[] = {
 
	    SLE_VAR(Goal, type,      SLE_FILE_U16 | SLE_VAR_U8),
 
	    SLE_VAR(Goal, dst,       SLE_UINT32),
 
	    SLE_STR(Goal, text,      SLE_STR | SLF_ALLOW_CONTROL, 0),
 
	SLE_CONDSTR(Goal, progress,  SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_182, SL_MAX_VERSION),
 
	SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION),
 
};
 

	
 
static void Save_GOAL()
 
{
 
	for (Goal *s : Goal::Iterate()) {
 
		SlSetArrayIndex(s->index);
 
		SlObject(s, _goals_desc);
 
	}
 
}
 

	
 
static void Load_GOAL()
 
{
 
	int index;
 
	while ((index = SlIterateArray()) != -1) {
 
		Goal *s = new (index) Goal();
 
		SlObject(s, _goals_desc);
 
	}
 
}
 

	
 
extern const ChunkHandler _goal_chunk_handlers[] = {
 
	{ 'GOAL', Save_GOAL, Load_GOAL, nullptr, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler goal_chunk_handlers[] = {
 
	{ 'GOAL', Save_GOAL, Load_GOAL, nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _goal_chunk_handlers(goal_chunk_handlers);
src/saveload/group_sl.cpp
Show inline comments
 
@@ -34,27 +34,29 @@ static void Save_GRPS()
 
		SlSetArrayIndex(g->index);
 
		SlObject(g, _group_desc);
 
	}
 
}
 

	
 

	
 
static void Load_GRPS()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		Group *g = new (index) Group();
 
		SlObject(g, _group_desc);
 

	
 
		if (IsSavegameVersionBefore(SLV_189)) g->parent = INVALID_GROUP;
 

	
 
		if (IsSavegameVersionBefore(SLV_GROUP_LIVERIES)) {
 
	                const Company *c = Company::Get(g->owner);
 
	                g->livery.colour1 = c->livery[LS_DEFAULT].colour1;
 
	                g->livery.colour2 = c->livery[LS_DEFAULT].colour2;
 
		}
 
	}
 
}
 

	
 
extern const ChunkHandler _group_chunk_handlers[] = {
 
	{ 'GRPS', Save_GRPS, Load_GRPS, nullptr, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler group_chunk_handlers[] = {
 
	{ 'GRPS', Save_GRPS, Load_GRPS, nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _group_chunk_handlers(group_chunk_handlers);
src/saveload/industry_sl.cpp
Show inline comments
 
@@ -155,31 +155,33 @@ static const SaveLoad _industrytype_buil
 
};
 

	
 
/** Save industry-type build data. */
 
static void Save_ITBL()
 
{
 
	for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
 
		SlSetArrayIndex(i);
 
		SlObject(_industry_builder.builddata + i, _industrytype_builder_desc);
 
	}
 
}
 

	
 
/** Load industry-type build data. */
 
static void Load_ITBL()
 
{
 
	for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
 
		_industry_builder.builddata[it].Reset();
 
	}
 
	int index;
 
	while ((index = SlIterateArray()) != -1) {
 
		if ((uint)index >= NUM_INDUSTRYTYPES) SlErrorCorrupt("Too many industry builder datas");
 
		SlObject(_industry_builder.builddata + index, _industrytype_builder_desc);
 
	}
 
}
 

	
 
extern const ChunkHandler _industry_chunk_handlers[] = {
 
static const ChunkHandler industry_chunk_handlers[] = {
 
	{ 'INDY', Save_INDY,     Load_INDY,     Ptrs_INDY, nullptr, CH_ARRAY},
 
	{ 'IIDS', Save_IIDS,     Load_IIDS,     nullptr,   nullptr, CH_ARRAY},
 
	{ 'TIDS', Save_TIDS,     Load_TIDS,     nullptr,   nullptr, CH_ARRAY},
 
	{ 'IBLD', LoadSave_IBLD, LoadSave_IBLD, nullptr,   nullptr, CH_RIFF},
 
	{ 'ITBL', Save_ITBL,     Load_ITBL,     nullptr,   nullptr, CH_ARRAY | CH_LAST},
 
	{ 'ITBL', Save_ITBL,     Load_ITBL,     nullptr,   nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _industry_chunk_handlers(industry_chunk_handlers);
src/saveload/labelmaps_sl.cpp
Show inline comments
 
@@ -100,28 +100,30 @@ static const SaveLoad _label_object_desc
 
static void Save_RAIL()
 
{
 
	LabelObject lo;
 

	
 
	for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) {
 
		lo.label = GetRailTypeInfo(r)->label;
 

	
 
		SlSetArrayIndex(r);
 
		SlObject(&lo, _label_object_desc);
 
	}
 
}
 

	
 
static void Load_RAIL()
 
{
 
	ResetLabelMaps();
 

	
 
	LabelObject lo;
 

	
 
	while (SlIterateArray() != -1) {
 
		SlObject(&lo, _label_object_desc);
 
		_railtype_list.push_back((RailTypeLabel)lo.label);
 
	}
 
}
 

	
 
extern const ChunkHandler _labelmaps_chunk_handlers[] = {
 
	{ 'RAIL', Save_RAIL, Load_RAIL, nullptr, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler labelmaps_chunk_handlers[] = {
 
	{ 'RAIL', Save_RAIL, Load_RAIL, nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _labelmaps_chunk_handlers(labelmaps_chunk_handlers);
 

	
src/saveload/linkgraph_sl.cpp
Show inline comments
 
@@ -259,29 +259,31 @@ static void Save_LGRP()
 
static void Save_LGRJ()
 
{
 
	for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
 
		SlSetArrayIndex(lgj->index);
 
		SlAutolength((AutolengthProc*)DoSave_LGRJ, lgj);
 
	}
 
}
 

	
 
/**
 
 * Save the link graph schedule.
 
 */
 
static void Save_LGRS()
 
{
 
	SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
 
}
 

	
 
/**
 
 * Substitute pointers in link graph schedule.
 
 */
 
static void Ptrs_LGRS()
 
{
 
	SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
 
}
 

	
 
extern const ChunkHandler _linkgraph_chunk_handlers[] = {
 
static const ChunkHandler linkgraph_chunk_handlers[] = {
 
	{ 'LGRP', Save_LGRP, Load_LGRP, nullptr,   nullptr, CH_ARRAY },
 
	{ 'LGRJ', Save_LGRJ, Load_LGRJ, nullptr,   nullptr, CH_ARRAY },
 
	{ 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_LAST  }
 
	{ 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_RIFF  }
 
};
 

	
 
extern const ChunkHandlerTable _linkgraph_chunk_handlers(linkgraph_chunk_handlers);
src/saveload/map_sl.cpp
Show inline comments
 
@@ -273,37 +273,39 @@ static void Save_MAP7()
 
static void Load_MAP8()
 
{
 
	std::array<uint16, MAP_SL_BUF_SIZE> buf;
 
	TileIndex size = MapSize();
 

	
 
	for (TileIndex i = 0; i != size;) {
 
		SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
 
		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j];
 
	}
 
}
 

	
 
static void Save_MAP8()
 
{
 
	std::array<uint16, MAP_SL_BUF_SIZE> buf;
 
	TileIndex size = MapSize();
 

	
 
	SlSetLength(size * sizeof(uint16));
 
	for (TileIndex i = 0; i != size;) {
 
		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m8;
 
		SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
 
	}
 
}
 

	
 

	
 
extern const ChunkHandler _map_chunk_handlers[] = {
 
static const ChunkHandler map_chunk_handlers[] = {
 
	{ 'MAPS', Save_MAPS, Load_MAPS, nullptr, Check_MAPS, CH_RIFF },
 
	{ 'MAPT', Save_MAPT, Load_MAPT, nullptr, nullptr,    CH_RIFF },
 
	{ 'MAPH', Save_MAPH, Load_MAPH, nullptr, nullptr,    CH_RIFF },
 
	{ 'MAPO', Save_MAP1, Load_MAP1, nullptr, nullptr,    CH_RIFF },
 
	{ 'MAP2', Save_MAP2, Load_MAP2, nullptr, nullptr,    CH_RIFF },
 
	{ 'M3LO', Save_MAP3, Load_MAP3, nullptr, nullptr,    CH_RIFF },
 
	{ 'M3HI', Save_MAP4, Load_MAP4, nullptr, nullptr,    CH_RIFF },
 
	{ 'MAP5', Save_MAP5, Load_MAP5, nullptr, nullptr,    CH_RIFF },
 
	{ 'MAPE', Save_MAP6, Load_MAP6, nullptr, nullptr,    CH_RIFF },
 
	{ 'MAP7', Save_MAP7, Load_MAP7, nullptr, nullptr,    CH_RIFF },
 
	{ 'MAP8', Save_MAP8, Load_MAP8, nullptr, nullptr,    CH_RIFF | CH_LAST },
 
	{ 'MAP8', Save_MAP8, Load_MAP8, nullptr, nullptr,    CH_RIFF },
 
};
 

	
 
extern const ChunkHandlerTable _map_chunk_handlers(map_chunk_handlers);
src/saveload/misc_sl.cpp
Show inline comments
 
@@ -124,28 +124,30 @@ static void SaveLoad_DATE()
 
}
 

	
 
static void Check_DATE()
 
{
 
	SlGlobList(_date_check_desc);
 
	if (IsSavegameVersionBefore(SLV_31)) {
 
		_load_check_data.current_date += DAYS_TILL_ORIGINAL_BASE_YEAR;
 
	}
 
}
 

	
 

	
 
static const SaveLoad _view_desc[] = {
 
	SLEG_CONDVAR(_saved_scrollpos_x,    SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
 
	SLEG_CONDVAR(_saved_scrollpos_x,    SLE_INT32,                  SLV_6, SL_MAX_VERSION),
 
	SLEG_CONDVAR(_saved_scrollpos_y,    SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
 
	SLEG_CONDVAR(_saved_scrollpos_y,    SLE_INT32,                  SLV_6, SL_MAX_VERSION),
 
	    SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8),
 
};
 

	
 
static void SaveLoad_VIEW()
 
{
 
	SlGlobList(_view_desc);
 
}
 

	
 
extern const ChunkHandler _misc_chunk_handlers[] = {
 
static const ChunkHandler misc_chunk_handlers[] = {
 
	{ 'DATE', SaveLoad_DATE, SaveLoad_DATE, nullptr, Check_DATE, CH_RIFF},
 
	{ 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, nullptr, nullptr,    CH_RIFF | CH_LAST},
 
	{ 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, nullptr, nullptr,    CH_RIFF },
 
};
 

	
 
extern const ChunkHandlerTable _misc_chunk_handlers(misc_chunk_handlers);
src/saveload/newgrf_sl.cpp
Show inline comments
 
@@ -90,27 +90,29 @@ static void Load_NGRF_common(GRFConfig *
 
	}
 
}
 

	
 
static void Load_NGRF()
 
{
 
	Load_NGRF_common(_grfconfig);
 

	
 
	if (_game_mode == GM_MENU) {
 
		/* Intro game must not have NewGRF. */
 
		if (_grfconfig != nullptr) SlErrorCorrupt("The intro game must not use NewGRF");
 

	
 
		/* Activate intro NewGRFs (townnames) */
 
		ResetGRFConfig(false);
 
	} else {
 
		/* Append static NewGRF configuration */
 
		AppendStaticGRFConfigs(&_grfconfig);
 
	}
 
}
 

	
 
static void Check_NGRF()
 
{
 
	Load_NGRF_common(_load_check_data.grfconfig);
 
}
 

	
 
extern const ChunkHandler _newgrf_chunk_handlers[] = {
 
	{ 'NGRF', Save_NGRF, Load_NGRF, nullptr, Check_NGRF, CH_ARRAY | CH_LAST }
 
static const ChunkHandler newgrf_chunk_handlers[] = {
 
	{ 'NGRF', Save_NGRF, Load_NGRF, nullptr, Check_NGRF, CH_ARRAY }
 
};
 

	
 
extern const ChunkHandlerTable _newgrf_chunk_handlers(newgrf_chunk_handlers);
src/saveload/object_sl.cpp
Show inline comments
 
@@ -45,28 +45,30 @@ static void Load_OBJS()
 
	}
 
}
 

	
 
static void Ptrs_OBJS()
 
{
 
	for (Object *o : Object::Iterate()) {
 
		SlObject(o, _object_desc);
 
		if (IsSavegameVersionBefore(SLV_148) && !IsTileType(o->location.tile, MP_OBJECT)) {
 
			/* Due to a small bug stale objects could remain. */
 
			delete o;
 
		}
 
	}
 
}
 

	
 
static void Save_OBID()
 
{
 
	Save_NewGRFMapping(_object_mngr);
 
}
 

	
 
static void Load_OBID()
 
{
 
	Load_NewGRFMapping(_object_mngr);
 
}
 

	
 
extern const ChunkHandler _object_chunk_handlers[] = {
 
static const ChunkHandler object_chunk_handlers[] = {
 
	{ 'OBID', Save_OBID, Load_OBID, nullptr,   nullptr, CH_ARRAY },
 
	{ 'OBJS', Save_OBJS, Load_OBJS, Ptrs_OBJS, nullptr, CH_ARRAY | CH_LAST},
 
	{ 'OBJS', Save_OBJS, Load_OBJS, Ptrs_OBJS, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _object_chunk_handlers(object_chunk_handlers);
src/saveload/order_sl.cpp
Show inline comments
 
@@ -265,29 +265,31 @@ static void Save_BKOR()
 
	for (OrderBackup *ob : OrderBackup::Iterate()) {
 
		SlSetArrayIndex(ob->index);
 
		SlObject(ob, GetOrderBackupDescription());
 
	}
 
}
 

	
 
void Load_BKOR()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		/* set num_orders to 0 so it's a valid OrderList */
 
		OrderBackup *ob = new (index) OrderBackup();
 
		SlObject(ob, GetOrderBackupDescription());
 
	}
 
}
 

	
 
static void Ptrs_BKOR()
 
{
 
	for (OrderBackup *ob : OrderBackup::Iterate()) {
 
		SlObject(ob, GetOrderBackupDescription());
 
	}
 
}
 

	
 
extern const ChunkHandler _order_chunk_handlers[] = {
 
static const ChunkHandler order_chunk_handlers[] = {
 
	{ 'BKOR', Save_BKOR, Load_BKOR, Ptrs_BKOR, nullptr, CH_ARRAY},
 
	{ 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, nullptr, CH_ARRAY},
 
	{ 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, nullptr, CH_ARRAY | CH_LAST},
 
	{ 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _order_chunk_handlers(order_chunk_handlers);
src/saveload/saveload.cpp
Show inline comments
 
@@ -193,143 +193,149 @@ struct MemoryDumper {
 
struct SaveLoadParams {
 
	SaveLoadAction action;               ///< are we doing a save or a load atm.
 
	NeedLength need_length;              ///< working in NeedLength (Autolength) mode?
 
	byte block_mode;                     ///< ???
 
	bool error;                          ///< did an error occur or not
 

	
 
	size_t obj_len;                      ///< the length of the current object we are busy with
 
	int array_index, last_array_index;   ///< in the case of an array, the current and last positions
 

	
 
	MemoryDumper *dumper;                ///< Memory dumper to write the savegame to.
 
	SaveFilter *sf;                      ///< Filter to write the savegame to.
 

	
 
	ReadBuffer *reader;                  ///< Savegame reading buffer.
 
	LoadFilter *lf;                      ///< Filter to read the savegame from.
 

	
 
	StringID error_str;                  ///< the translatable error message to show
 
	char *extra_msg;                     ///< the error message
 

	
 
	uint16 game_speed;                   ///< The game speed when saving started.
 
	bool saveinprogress;                 ///< Whether there is currently a save in progress.
 
};
 

	
 
static SaveLoadParams _sl; ///< Parameters used for/at saveload.
 

	
 
/* these define the chunks */
 
extern const ChunkHandler _gamelog_chunk_handlers[];
 
extern const ChunkHandler _map_chunk_handlers[];
 
extern const ChunkHandler _misc_chunk_handlers[];
 
extern const ChunkHandler _name_chunk_handlers[];
 
extern const ChunkHandler _cheat_chunk_handlers[] ;
 
extern const ChunkHandler _setting_chunk_handlers[];
 
extern const ChunkHandler _company_chunk_handlers[];
 
extern const ChunkHandler _engine_chunk_handlers[];
 
extern const ChunkHandler _veh_chunk_handlers[];
 
extern const ChunkHandler _waypoint_chunk_handlers[];
 
extern const ChunkHandler _depot_chunk_handlers[];
 
extern const ChunkHandler _order_chunk_handlers[];
 
extern const ChunkHandler _town_chunk_handlers[];
 
extern const ChunkHandler _sign_chunk_handlers[];
 
extern const ChunkHandler _station_chunk_handlers[];
 
extern const ChunkHandler _industry_chunk_handlers[];
 
extern const ChunkHandler _economy_chunk_handlers[];
 
extern const ChunkHandler _subsidy_chunk_handlers[];
 
extern const ChunkHandler _cargomonitor_chunk_handlers[];
 
extern const ChunkHandler _goal_chunk_handlers[];
 
extern const ChunkHandler _story_page_chunk_handlers[];
 
extern const ChunkHandler _ai_chunk_handlers[];
 
extern const ChunkHandler _game_chunk_handlers[];
 
extern const ChunkHandler _animated_tile_chunk_handlers[];
 
extern const ChunkHandler _newgrf_chunk_handlers[];
 
extern const ChunkHandler _group_chunk_handlers[];
 
extern const ChunkHandler _cargopacket_chunk_handlers[];
 
extern const ChunkHandler _autoreplace_chunk_handlers[];
 
extern const ChunkHandler _labelmaps_chunk_handlers[];
 
extern const ChunkHandler _linkgraph_chunk_handlers[];
 
extern const ChunkHandler _airport_chunk_handlers[];
 
extern const ChunkHandler _object_chunk_handlers[];
 
extern const ChunkHandler _persistent_storage_chunk_handlers[];
 

	
 
/** Array of all chunks in a savegame, \c nullptr terminated. */
 
static const ChunkHandler * const _chunk_handlers[] = {
 
static const std::vector<ChunkHandler> &ChunkHandlers()
 
{
 
	/* These define the chunks */
 
	extern const ChunkHandlerTable _gamelog_chunk_handlers;
 
	extern const ChunkHandlerTable _map_chunk_handlers;
 
	extern const ChunkHandlerTable _misc_chunk_handlers;
 
	extern const ChunkHandlerTable _name_chunk_handlers;
 
	extern const ChunkHandlerTable _cheat_chunk_handlers;
 
	extern const ChunkHandlerTable _setting_chunk_handlers;
 
	extern const ChunkHandlerTable _company_chunk_handlers;
 
	extern const ChunkHandlerTable _engine_chunk_handlers;
 
	extern const ChunkHandlerTable _veh_chunk_handlers;
 
	extern const ChunkHandlerTable _waypoint_chunk_handlers;
 
	extern const ChunkHandlerTable _depot_chunk_handlers;
 
	extern const ChunkHandlerTable _order_chunk_handlers;
 
	extern const ChunkHandlerTable _town_chunk_handlers;
 
	extern const ChunkHandlerTable _sign_chunk_handlers;
 
	extern const ChunkHandlerTable _station_chunk_handlers;
 
	extern const ChunkHandlerTable _industry_chunk_handlers;
 
	extern const ChunkHandlerTable _economy_chunk_handlers;
 
	extern const ChunkHandlerTable _subsidy_chunk_handlers;
 
	extern const ChunkHandlerTable _cargomonitor_chunk_handlers;
 
	extern const ChunkHandlerTable _goal_chunk_handlers;
 
	extern const ChunkHandlerTable _story_page_chunk_handlers;
 
	extern const ChunkHandlerTable _ai_chunk_handlers;
 
	extern const ChunkHandlerTable _game_chunk_handlers;
 
	extern const ChunkHandlerTable _animated_tile_chunk_handlers;
 
	extern const ChunkHandlerTable _newgrf_chunk_handlers;
 
	extern const ChunkHandlerTable _group_chunk_handlers;
 
	extern const ChunkHandlerTable _cargopacket_chunk_handlers;
 
	extern const ChunkHandlerTable _autoreplace_chunk_handlers;
 
	extern const ChunkHandlerTable _labelmaps_chunk_handlers;
 
	extern const ChunkHandlerTable _linkgraph_chunk_handlers;
 
	extern const ChunkHandlerTable _airport_chunk_handlers;
 
	extern const ChunkHandlerTable _object_chunk_handlers;
 
	extern const ChunkHandlerTable _persistent_storage_chunk_handlers;
 

	
 
	/** List of all chunks in a savegame. */
 
	static const ChunkHandlerTable _chunk_handler_tables[] = {
 
	_gamelog_chunk_handlers,
 
	_map_chunk_handlers,
 
	_misc_chunk_handlers,
 
	_name_chunk_handlers,
 
	_cheat_chunk_handlers,
 
	_setting_chunk_handlers,
 
	_veh_chunk_handlers,
 
	_waypoint_chunk_handlers,
 
	_depot_chunk_handlers,
 
	_order_chunk_handlers,
 
	_industry_chunk_handlers,
 
	_economy_chunk_handlers,
 
	_subsidy_chunk_handlers,
 
	_cargomonitor_chunk_handlers,
 
	_goal_chunk_handlers,
 
	_story_page_chunk_handlers,
 
	_engine_chunk_handlers,
 
	_town_chunk_handlers,
 
	_sign_chunk_handlers,
 
	_station_chunk_handlers,
 
	_company_chunk_handlers,
 
	_ai_chunk_handlers,
 
	_game_chunk_handlers,
 
	_animated_tile_chunk_handlers,
 
	_newgrf_chunk_handlers,
 
	_group_chunk_handlers,
 
	_cargopacket_chunk_handlers,
 
	_autoreplace_chunk_handlers,
 
	_labelmaps_chunk_handlers,
 
	_linkgraph_chunk_handlers,
 
	_airport_chunk_handlers,
 
	_object_chunk_handlers,
 
	_persistent_storage_chunk_handlers,
 
	nullptr,
 
};
 

	
 
/**
 
 * Iterate over all chunk handlers.
 
 * @param ch the chunk handler iterator
 
 */
 
#define FOR_ALL_CHUNK_HANDLERS(ch) \
 
	for (const ChunkHandler * const *chsc = _chunk_handlers; *chsc != nullptr; chsc++) \
 
		for (const ChunkHandler *ch = *chsc; ch != nullptr; ch = (ch->flags & CH_LAST) ? nullptr : ch + 1)
 
	static std::vector<ChunkHandler> _chunk_handlers;
 

	
 
	if (_chunk_handlers.empty()) {
 
		for (auto &chunk_handler_table : _chunk_handler_tables) {
 
			for (auto &chunk_handler : chunk_handler_table) {
 
				_chunk_handlers.push_back(chunk_handler);
 
			}
 
		}
 
	}
 

	
 
	return _chunk_handlers;
 
}
 

	
 
/** Null all pointers (convert index -> nullptr) */
 
static void SlNullPointers()
 
{
 
	_sl.action = SLA_NULL;
 

	
 
	/* We don't want any savegame conversion code to run
 
	 * during NULLing; especially those that try to get
 
	 * pointers from other pools. */
 
	_sl_version = SAVEGAME_VERSION;
 

	
 
	FOR_ALL_CHUNK_HANDLERS(ch) {
 
		if (ch->ptrs_proc != nullptr) {
 
			DEBUG(sl, 3, "Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
 
			ch->ptrs_proc();
 
	for (auto &ch : ChunkHandlers()) {
 
		if (ch.ptrs_proc != nullptr) {
 
			DEBUG(sl, 3, "Nulling pointers for %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
 
			ch.ptrs_proc();
 
		}
 
	}
 

	
 
	assert(_sl.action == SLA_NULL);
 
}
 

	
 
/**
 
 * Error handler. Sets everything up to show an error message and to clean
 
 * up the mess of a partial savegame load.
 
 * @param string The translatable error message to show.
 
 * @param extra_msg An extra error message coming from one of the APIs.
 
 * @note This function does never return as it throws an exception to
 
 *       break out of all the saveload code.
 
 */
 
void NORETURN SlError(StringID string, const char *extra_msg)
 
{
 
	/* Distinguish between loading into _load_check_data vs. normal save/load. */
 
	if (_sl.action == SLA_LOAD_CHECK) {
 
		_load_check_data.error = string;
 
		free(_load_check_data.error_data);
 
		_load_check_data.error_data = (extra_msg == nullptr) ? nullptr : stredup(extra_msg);
 
	} else {
 
		_sl.error_str = string;
 
		free(_sl.extra_msg);
 
@@ -1633,231 +1639,231 @@ void SlAutolength(AutolengthProc *proc, 
 

	
 
	assert(_sl.action == SLA_SAVE);
 

	
 
	/* Tell it to calculate the length */
 
	_sl.need_length = NL_CALCLENGTH;
 
	_sl.obj_len = 0;
 
	proc(arg);
 

	
 
	/* Setup length */
 
	_sl.need_length = NL_WANTLENGTH;
 
	SlSetLength(_sl.obj_len);
 

	
 
	offs = _sl.dumper->GetSize() + _sl.obj_len;
 

	
 
	/* And write the stuff */
 
	proc(arg);
 

	
 
	if (offs != _sl.dumper->GetSize()) SlErrorCorrupt("Invalid chunk size");
 
}
 

	
 
/**
 
 * Load a chunk of data (eg vehicles, stations, etc.)
 
 * @param ch The chunkhandler that will be used for the operation
 
 */
 
static void SlLoadChunk(const ChunkHandler *ch)
 
static void SlLoadChunk(const ChunkHandler &ch)
 
{
 
	byte m = SlReadByte();
 
	size_t len;
 
	size_t endoffs;
 

	
 
	_sl.block_mode = m;
 
	_sl.obj_len = 0;
 

	
 
	switch (m) {
 
		case CH_ARRAY:
 
			_sl.array_index = 0;
 
			ch->load_proc();
 
			ch.load_proc();
 
			if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
 
			break;
 
		case CH_SPARSE_ARRAY:
 
			ch->load_proc();
 
			ch.load_proc();
 
			if (_next_offs != 0) SlErrorCorrupt("Invalid array length");
 
			break;
 
		default:
 
			if ((m & 0xF) == CH_RIFF) {
 
				/* Read length */
 
				len = (SlReadByte() << 16) | ((m >> 4) << 24);
 
				len += SlReadUint16();
 
				_sl.obj_len = len;
 
				endoffs = _sl.reader->GetSize() + len;
 
				ch->load_proc();
 
				ch.load_proc();
 
				if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
 
			} else {
 
				SlErrorCorrupt("Invalid chunk type");
 
			}
 
			break;
 
	}
 
}
 

	
 
/**
 
 * Load a chunk of data for checking savegames.
 
 * If the chunkhandler is nullptr, the chunk is skipped.
 
 * @param ch The chunkhandler that will be used for the operation
 
 */
 
static void SlLoadCheckChunk(const ChunkHandler *ch)
 
static void SlLoadCheckChunk(const ChunkHandler &ch)
 
{
 
	byte m = SlReadByte();
 
	size_t len;
 
	size_t endoffs;
 

	
 
	_sl.block_mode = m;
 
	_sl.obj_len = 0;
 

	
 
	switch (m) {
 
		case CH_ARRAY:
 
			_sl.array_index = 0;
 
			if (ch->load_check_proc) {
 
				ch->load_check_proc();
 
			if (ch.load_check_proc) {
 
				ch.load_check_proc();
 
			} else {
 
				SlSkipArray();
 
			}
 
			break;
 
		case CH_SPARSE_ARRAY:
 
			if (ch->load_check_proc) {
 
				ch->load_check_proc();
 
			if (ch.load_check_proc) {
 
				ch.load_check_proc();
 
			} else {
 
				SlSkipArray();
 
			}
 
			break;
 
		default:
 
			if ((m & 0xF) == CH_RIFF) {
 
				/* Read length */
 
				len = (SlReadByte() << 16) | ((m >> 4) << 24);
 
				len += SlReadUint16();
 
				_sl.obj_len = len;
 
				endoffs = _sl.reader->GetSize() + len;
 
				if (ch->load_check_proc) {
 
					ch->load_check_proc();
 
				if (ch.load_check_proc) {
 
					ch.load_check_proc();
 
				} else {
 
					SlSkipBytes(len);
 
				}
 
				if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
 
			} else {
 
				SlErrorCorrupt("Invalid chunk type");
 
			}
 
			break;
 
	}
 
}
 

	
 
/**
 
 * Save a chunk of data (eg. vehicles, stations, etc.). Each chunk is
 
 * prefixed by an ID identifying it, followed by data, and terminator where appropriate
 
 * @param ch The chunkhandler that will be used for the operation
 
 */
 
static void SlSaveChunk(const ChunkHandler *ch)
 
static void SlSaveChunk(const ChunkHandler &ch)
 
{
 
	ChunkSaveLoadProc *proc = ch->save_proc;
 
	ChunkSaveLoadProc *proc = ch.save_proc;
 

	
 
	/* Don't save any chunk information if there is no save handler. */
 
	if (proc == nullptr) return;
 

	
 
	SlWriteUint32(ch->id);
 
	DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
 

	
 
	_sl.block_mode = ch->flags & CH_TYPE_MASK;
 
	switch (ch->flags & CH_TYPE_MASK) {
 
	SlWriteUint32(ch.id);
 
	DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
 

	
 
	_sl.block_mode = ch.type;
 
	switch (ch.type) {
 
		case CH_RIFF:
 
			_sl.need_length = NL_WANTLENGTH;
 
			proc();
 
			break;
 
		case CH_ARRAY:
 
			_sl.last_array_index = 0;
 
			SlWriteByte(CH_ARRAY);
 
			proc();
 
			SlWriteArrayLength(0); // Terminate arrays
 
			break;
 
		case CH_SPARSE_ARRAY:
 
			SlWriteByte(CH_SPARSE_ARRAY);
 
			proc();
 
			SlWriteArrayLength(0); // Terminate arrays
 
			break;
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/** Save all chunks */
 
static void SlSaveChunks()
 
{
 
	FOR_ALL_CHUNK_HANDLERS(ch) {
 
	for (auto &ch : ChunkHandlers()) {
 
		SlSaveChunk(ch);
 
	}
 

	
 
	/* Terminator */
 
	SlWriteUint32(0);
 
}
 

	
 
/**
 
 * Find the ChunkHandler that will be used for processing the found
 
 * chunk in the savegame or in memory
 
 * @param id the chunk in question
 
 * @return returns the appropriate chunkhandler
 
 */
 
static const ChunkHandler *SlFindChunkHandler(uint32 id)
 
{
 
	FOR_ALL_CHUNK_HANDLERS(ch) if (ch->id == id) return ch;
 
	for (auto &ch : ChunkHandlers()) if (ch.id == id) return &ch;
 
	return nullptr;
 
}
 

	
 
/** Load all chunks */
 
static void SlLoadChunks()
 
{
 
	uint32 id;
 
	const ChunkHandler *ch;
 

	
 
	for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
 
		DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
 

	
 
		ch = SlFindChunkHandler(id);
 
		if (ch == nullptr) SlErrorCorrupt("Unknown chunk type");
 
		SlLoadChunk(ch);
 
		SlLoadChunk(*ch);
 
	}
 
}
 

	
 
/** Load all chunks for savegame checking */
 
static void SlLoadCheckChunks()
 
{
 
	uint32 id;
 
	const ChunkHandler *ch;
 

	
 
	for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
 
		DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
 

	
 
		ch = SlFindChunkHandler(id);
 
		if (ch == nullptr) SlErrorCorrupt("Unknown chunk type");
 
		SlLoadCheckChunk(ch);
 
		SlLoadCheckChunk(*ch);
 
	}
 
}
 

	
 
/** Fix all pointers (convert index -> pointer) */
 
static void SlFixPointers()
 
{
 
	_sl.action = SLA_PTRS;
 

	
 
	FOR_ALL_CHUNK_HANDLERS(ch) {
 
		if (ch->ptrs_proc != nullptr) {
 
			DEBUG(sl, 3, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
 
			ch->ptrs_proc();
 
	for (auto &ch : ChunkHandlers()) {
 
		if (ch.ptrs_proc != nullptr) {
 
			DEBUG(sl, 3, "Fixing pointers for %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
 
			ch.ptrs_proc();
 
		}
 
	}
 

	
 
	assert(_sl.action == SLA_PTRS);
 
}
 

	
 

	
 
/** Yes, simply reading from a file. */
 
struct FileReader : LoadFilter {
 
	FILE *file; ///< The file to read from.
 
	long begin; ///< The begin of the file.
 

	
 
	/**
 
	 * Create the file reader, so it reads from a specific file.
 
	 * @param file The file to read from.
 
	 */
 
	FileReader(FILE *file) : LoadFilter(nullptr), file(file), begin(ftell(file))
 
	{
 
	}
 

	
 
	/** Make sure everything is cleaned up. */
 
	~FileReader()
 
	{
 
		if (this->file != nullptr) fclose(this->file);
src/saveload/saveload.h
Show inline comments
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file saveload.h Functions/types related to saving and loading games. */
 

	
 
#ifndef SAVELOAD_H
 
#define SAVELOAD_H
 

	
 
#include "../fileio_type.h"
 
#include "../strings_type.h"
 
#include "../core/span_type.hpp"
 
#include <string>
 
#include <vector>
 

	
 
/** SaveLoad versions
 
 * Previous savegame versions, the trunk revision where they were
 
 * introduced and the released version that had that particular
 
 * savegame version.
 
 * Up to savegame version 18 there is a minor version as well.
 
 *
 
 * Older entries keep their original numbering.
 
 *
 
 * Newer entries should use a descriptive labels, numeric version
 
 * and PR can be added to comment.
 
 *
 
 * Note that this list must not be reordered.
 
 */
 
enum SaveLoadVersion : uint16 {
 
	SL_MIN_VERSION,                         ///< First savegame version
 

	
 
	SLV_1,                                  ///<   1.0         0.1.x, 0.2.x
 
	SLV_2,                                  /**<   2.0         0.3.0
 
	                                         *     2.1         0.3.1, 0.3.2 */
 
	SLV_3,                                  ///<   3.x         lost
 
	SLV_4,                                  /**<   4.0     1
 
	                                         *     4.1   122   0.3.3, 0.3.4
 
	                                         *     4.2  1222   0.3.5
 
@@ -357,83 +358,84 @@ enum SavegameType {
 
	SGT_TTD,    ///< TTD  savegame (can be detected incorrectly)
 
	SGT_TTDP1,  ///< TTDP savegame ( -//- ) (data at NW border)
 
	SGT_TTDP2,  ///< TTDP savegame in new format (data at SE border)
 
	SGT_OTTD,   ///< OTTD savegame
 
	SGT_TTO,    ///< TTO savegame
 
	SGT_INVALID = 0xFF, ///< broken savegame (used internally)
 
};
 

	
 
extern FileToSaveLoad _file_to_saveload;
 

	
 
void GenerateDefaultSaveName(char *buf, const char *last);
 
void SetSaveLoadError(StringID str);
 
const char *GetSaveLoadErrorString();
 
SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded = true);
 
void WaitTillSaved();
 
void ProcessAsyncSaveFinish();
 
void DoExitSave();
 

	
 
SaveOrLoadResult SaveWithFilter(struct SaveFilter *writer, bool threaded);
 
SaveOrLoadResult LoadWithFilter(struct LoadFilter *reader);
 

	
 
typedef void ChunkSaveLoadProc();
 
typedef void AutolengthProc(void *arg);
 

	
 
/** Type of a chunk. */
 
enum ChunkType {
 
	CH_RIFF = 0,
 
	CH_ARRAY = 1,
 
	CH_SPARSE_ARRAY = 2,
 
};
 

	
 
/** Handlers and description of chunk. */
 
struct ChunkHandler {
 
	uint32 id;                          ///< Unique ID (4 letters).
 
	ChunkSaveLoadProc *save_proc;       ///< Save procedure of the chunk.
 
	ChunkSaveLoadProc *load_proc;       ///< Load procedure of the chunk.
 
	ChunkSaveLoadProc *ptrs_proc;       ///< Manipulate pointers in the chunk.
 
	ChunkSaveLoadProc *load_check_proc; ///< Load procedure for game preview.
 
	uint32 flags;                       ///< Flags of the chunk. @see ChunkType
 
	ChunkType type;                     ///< Type of the chunk. @see ChunkType
 
};
 

	
 
/** A table of ChunkHandler entries. */
 
using ChunkHandlerTable = span<const ChunkHandler>;
 

	
 
/** Type of reference (#SLE_REF, #SLE_CONDREF). */
 
enum SLRefType {
 
	REF_ORDER          =  0, ///< Load/save a reference to an order.
 
	REF_VEHICLE        =  1, ///< Load/save a reference to a vehicle.
 
	REF_STATION        =  2, ///< Load/save a reference to a station.
 
	REF_TOWN           =  3, ///< Load/save a reference to a town.
 
	REF_VEHICLE_OLD    =  4, ///< Load/save an old-style reference to a vehicle (for pre-4.4 savegames).
 
	REF_ROADSTOPS      =  5, ///< Load/save a reference to a bus/truck stop.
 
	REF_ENGINE_RENEWS  =  6, ///< Load/save a reference to an engine renewal (autoreplace).
 
	REF_CARGO_PACKET   =  7, ///< Load/save a reference to a cargo packet.
 
	REF_ORDERLIST      =  8, ///< Load/save a reference to an orderlist.
 
	REF_STORAGE        =  9, ///< Load/save a reference to a persistent storage.
 
	REF_LINK_GRAPH     = 10, ///< Load/save a reference to a link graph.
 
	REF_LINK_GRAPH_JOB = 11, ///< Load/save a reference to a link graph job.
 
};
 

	
 
/** Flags of a chunk. */
 
enum ChunkType {
 
	CH_RIFF         =  0,
 
	CH_ARRAY        =  1,
 
	CH_SPARSE_ARRAY =  2,
 
	CH_TYPE_MASK    =  3,
 
	CH_LAST         =  8, ///< Last chunk in this array.
 
};
 

	
 
/**
 
 * VarTypes is the general bitmasked magic type that tells us
 
 * certain characteristics about the variable it refers to. For example
 
 * SLE_FILE_* gives the size(type) as it would be in the savegame and
 
 * SLE_VAR_* the size(type) as it is in memory during runtime. These are
 
 * the first 8 bits (0-3 SLE_FILE, 4-7 SLE_VAR).
 
 * Bits 8-15 are reserved for various flags as explained below
 
 */
 
enum VarTypes {
 
	/* 4 bits allocated a maximum of 16 types for NumberType */
 
	SLE_FILE_I8       = 0,
 
	SLE_FILE_U8       = 1,
 
	SLE_FILE_I16      = 2,
 
	SLE_FILE_U16      = 3,
 
	SLE_FILE_I32      = 4,
 
	SLE_FILE_U32      = 5,
 
	SLE_FILE_I64      = 6,
 
	SLE_FILE_U64      = 7,
 
	SLE_FILE_STRINGID = 8, ///< StringID offset into strings-array
 
	SLE_FILE_STRING   = 9,
 
	/* 6 more possible file-primitives */
 

	
 
	/* 4 bits allocated a maximum of 16 types for NumberType */
 
	SLE_VAR_BL    =  0 << 4,
src/saveload/signs_sl.cpp
Show inline comments
 
@@ -41,27 +41,29 @@ static void Save_SIGN()
 
static void Load_SIGN()
 
{
 
	int index;
 
	while ((index = SlIterateArray()) != -1) {
 
		Sign *si = new (index) Sign();
 
		SlObject(si, _sign_desc);
 
		/* Before version 6.1, signs didn't have owner.
 
		 * Before version 83, invalid signs were determined by si->str == 0.
 
		 * Before version 103, owner could be a bankrupted company.
 
		 *  - we can't use IsValidCompany() now, so this is fixed in AfterLoadGame()
 
		 * All signs that were saved are valid (including those with just 'Sign' and INVALID_OWNER).
 
		 *  - so set owner to OWNER_NONE if needed (signs from pre-version 6.1 would be lost) */
 
		if (IsSavegameVersionBefore(SLV_6, 1) || (IsSavegameVersionBefore(SLV_83) && si->owner == INVALID_OWNER)) {
 
			si->owner = OWNER_NONE;
 
		}
 

	
 
		/* Signs placed in scenario editor shall now be OWNER_DEITY */
 
		if (IsSavegameVersionBefore(SLV_171) && si->owner == OWNER_NONE && _file_to_saveload.abstract_ftype == FT_SCENARIO) {
 
			si->owner = OWNER_DEITY;
 
		}
 
	}
 
}
 

	
 
/** Chunk handlers related to signs. */
 
extern const ChunkHandler _sign_chunk_handlers[] = {
 
	{ 'SIGN', Save_SIGN, Load_SIGN, nullptr, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler sign_chunk_handlers[] = {
 
	{ 'SIGN', Save_SIGN, Load_SIGN, nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _sign_chunk_handlers(sign_chunk_handlers);
src/saveload/station_sl.cpp
Show inline comments
 
@@ -592,29 +592,31 @@ static void Save_ROADSTOP()
 
	for (RoadStop *rs : RoadStop::Iterate()) {
 
		SlSetArrayIndex(rs->index);
 
		SlObject(rs, _roadstop_desc);
 
	}
 
}
 

	
 
static void Load_ROADSTOP()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		RoadStop *rs = new (index) RoadStop(INVALID_TILE);
 

	
 
		SlObject(rs, _roadstop_desc);
 
	}
 
}
 

	
 
static void Ptrs_ROADSTOP()
 
{
 
	for (RoadStop *rs : RoadStop::Iterate()) {
 
		SlObject(rs, _roadstop_desc);
 
	}
 
}
 

	
 
extern const ChunkHandler _station_chunk_handlers[] = {
 
static const ChunkHandler station_chunk_handlers[] = {
 
	{ 'STNS', nullptr,       Load_STNS,     Ptrs_STNS,     nullptr, CH_ARRAY },
 
	{ 'STNN', Save_STNN,     Load_STNN,     Ptrs_STNN,     nullptr, CH_ARRAY },
 
	{ 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, nullptr, CH_ARRAY | CH_LAST},
 
	{ 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _station_chunk_handlers(station_chunk_handlers);
src/saveload/storage_sl.cpp
Show inline comments
 
@@ -23,27 +23,29 @@ static const SaveLoad _storage_desc[] = 
 
/** Load persistent storage data. */
 
static void Load_PSAC()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		assert(PersistentStorage::CanAllocateItem());
 
		PersistentStorage *ps = new (index) PersistentStorage(0, 0, 0);
 
		SlObject(ps, _storage_desc);
 
	}
 
}
 

	
 
/** Save persistent storage data. */
 
static void Save_PSAC()
 
{
 
	/* Write the industries */
 
	for (PersistentStorage *ps : PersistentStorage::Iterate()) {
 
		ps->ClearChanges();
 
		SlSetArrayIndex(ps->index);
 
		SlObject(ps, _storage_desc);
 
	}
 
}
 

	
 
/** Chunk handler for persistent storages. */
 
extern const ChunkHandler _persistent_storage_chunk_handlers[] = {
 
	{ 'PSAC', Save_PSAC, Load_PSAC, nullptr, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler persistent_storage_chunk_handlers[] = {
 
	{ 'PSAC', Save_PSAC, Load_PSAC, nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _persistent_storage_chunk_handlers(persistent_storage_chunk_handlers);
src/saveload/story_sl.cpp
Show inline comments
 
@@ -74,28 +74,30 @@ static void Save_STORY_PAGE()
 
{
 
	for (StoryPage *s : StoryPage::Iterate()) {
 
		SlSetArrayIndex(s->index);
 
		SlObject(s, _story_pages_desc);
 
	}
 
}
 

	
 
static void Load_STORY_PAGE()
 
{
 
	int index;
 
	uint32 max_sort_value = 0;
 
	while ((index = SlIterateArray()) != -1) {
 
		StoryPage *s = new (index) StoryPage();
 
		SlObject(s, _story_pages_desc);
 
		if (s->sort_value > max_sort_value) {
 
			max_sort_value = s->sort_value;
 
		}
 
	}
 
	/* Update the next sort value, so that the next
 
	 * created page is shown after all existing pages.
 
	 */
 
	_story_page_next_sort_value = max_sort_value + 1;
 
}
 

	
 
extern const ChunkHandler _story_page_chunk_handlers[] = {
 
static const ChunkHandler story_page_chunk_handlers[] = {
 
	{ 'STPE', Save_STORY_PAGE_ELEMENT, Load_STORY_PAGE_ELEMENT, nullptr, nullptr, CH_ARRAY},
 
	{ 'STPA', Save_STORY_PAGE,         Load_STORY_PAGE,         nullptr, nullptr, CH_ARRAY | CH_LAST},
 
	{ 'STPA', Save_STORY_PAGE,         Load_STORY_PAGE,         nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _story_page_chunk_handlers(story_page_chunk_handlers);
src/saveload/strings_sl.cpp
Show inline comments
 
@@ -110,27 +110,29 @@ void ResetOldNames()
 
void InitializeOldNames()
 
{
 
	free(_old_name_array);
 
	_old_name_array = CallocT<char>(NUM_OLD_STRINGS * LEN_OLD_STRINGS); // 200 * 24 would be enough for TTO savegames
 
}
 

	
 
/**
 
 * Load the NAME chunk.
 
 */
 
static void Load_NAME()
 
{
 
	int index;
 

	
 
	while ((index = SlIterateArray()) != -1) {
 
		if (index >= NUM_OLD_STRINGS) SlErrorCorrupt("Invalid old name index");
 
		if (SlGetFieldLength() > (uint)LEN_OLD_STRINGS) SlErrorCorrupt("Invalid old name length");
 

	
 
		SlArray(&_old_name_array[LEN_OLD_STRINGS * index], SlGetFieldLength(), SLE_UINT8);
 
		/* Make sure the old name is null terminated */
 
		_old_name_array[LEN_OLD_STRINGS * index + LEN_OLD_STRINGS - 1] = '\0';
 
	}
 
}
 

	
 
/** Chunk handlers related to strings. */
 
extern const ChunkHandler _name_chunk_handlers[] = {
 
	{ 'NAME', nullptr, Load_NAME, nullptr, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler name_chunk_handlers[] = {
 
	{ 'NAME', nullptr, Load_NAME, nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _name_chunk_handlers(name_chunk_handlers);
src/saveload/subsidy_sl.cpp
Show inline comments
 
@@ -22,27 +22,29 @@ static const SaveLoad _subsidies_desc[] 
 
	SLE_CONDVAR(Subsidy, dst_type,   SLE_UINT8,                 SLV_125, SL_MAX_VERSION),
 
	SLE_CONDVAR(Subsidy, src,        SLE_FILE_U8 | SLE_VAR_U16,   SL_MIN_VERSION, SLV_5),
 
	SLE_CONDVAR(Subsidy, src,        SLE_UINT16,                  SLV_5, SL_MAX_VERSION),
 
	SLE_CONDVAR(Subsidy, dst,        SLE_FILE_U8 | SLE_VAR_U16,   SL_MIN_VERSION, SLV_5),
 
	SLE_CONDVAR(Subsidy, dst,        SLE_UINT16,                  SLV_5, SL_MAX_VERSION),
 
};
 

	
 
static void Save_SUBS()
 
{
 
	for (Subsidy *s : Subsidy::Iterate()) {
 
		SlSetArrayIndex(s->index);
 
		SlObject(s, _subsidies_desc);
 
	}
 
}
 

	
 
static void Load_SUBS()
 
{
 
	int index;
 
	while ((index = SlIterateArray()) != -1) {
 
		Subsidy *s = new (index) Subsidy();
 
		SlObject(s, _subsidies_desc);
 
	}
 
}
 

	
 
extern const ChunkHandler _subsidy_chunk_handlers[] = {
 
	{ 'SUBS', Save_SUBS, Load_SUBS, nullptr, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler subsidy_chunk_handlers[] = {
 
	{ 'SUBS', Save_SUBS, Load_SUBS, nullptr, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _subsidy_chunk_handlers(subsidy_chunk_handlers);
src/saveload/town_sl.cpp
Show inline comments
 
@@ -275,28 +275,30 @@ static void Load_TOWN()
 
		if (!IsSavegameVersionBefore(SLV_166) && IsSavegameVersionBefore(SLV_REMOVE_TOWN_CARGO_CACHE)) {
 
			/* Discard now unused acceptance matrix. */
 
			AcceptanceMatrix dummy;
 
			SlObject(&dummy, GetTileMatrixDesc());
 
			if (dummy.area.w != 0) {
 
				uint arr_len = dummy.area.w / AcceptanceMatrix::GRID * dummy.area.h / AcceptanceMatrix::GRID;
 
				SlSkipBytes(4 * arr_len);
 
			}
 
		}
 
	}
 
}
 

	
 
/** Fix pointers when loading town data. */
 
static void Ptrs_TOWN()
 
{
 
	/* Don't run when savegame version lower than 161. */
 
	if (IsSavegameVersionBefore(SLV_161)) return;
 

	
 
	for (Town *t : Town::Iterate()) {
 
		SlObject(t, _town_desc);
 
	}
 
}
 

	
 
/** Chunk handler for towns. */
 
extern const ChunkHandler _town_chunk_handlers[] = {
 
static const ChunkHandler town_chunk_handlers[] = {
 
	{ 'HIDS', Save_HIDS, Load_HIDS, nullptr,   nullptr, CH_ARRAY },
 
	{ 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, nullptr, CH_ARRAY | CH_LAST},
 
	{ 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _town_chunk_handlers(town_chunk_handlers);
src/saveload/vehicle_sl.cpp
Show inline comments
 
@@ -910,27 +910,29 @@ void Load_VEHS()
 
			v->last_station_visited = INVALID_STATION;
 
		}
 

	
 
		if (IsSavegameVersionBefore(SLV_182)) v->last_loading_station = INVALID_STATION;
 

	
 
		if (IsSavegameVersionBefore(SLV_5)) {
 
			/* Convert the current_order.type (which is a mix of type and flags, because
 
			 *  in those versions, they both were 4 bits big) to type and flags */
 
			v->current_order.flags = GB(v->current_order.type, 4, 4);
 
			v->current_order.type &= 0x0F;
 
		}
 

	
 
		/* Advanced vehicle lists got added */
 
		if (IsSavegameVersionBefore(SLV_60)) v->group_id = DEFAULT_GROUP;
 
	}
 
}
 

	
 
static void Ptrs_VEHS()
 
{
 
	for (Vehicle *v : Vehicle::Iterate()) {
 
		SlObject(v, GetVehicleDescription(v->type));
 
	}
 
}
 

	
 
extern const ChunkHandler _veh_chunk_handlers[] = {
 
	{ 'VEHS', Save_VEHS, Load_VEHS, Ptrs_VEHS, nullptr, CH_SPARSE_ARRAY | CH_LAST},
 
static const ChunkHandler veh_chunk_handlers[] = {
 
	{ 'VEHS', Save_VEHS, Load_VEHS, Ptrs_VEHS, nullptr, CH_SPARSE_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _veh_chunk_handlers(veh_chunk_handlers);
src/saveload/waypoint_sl.cpp
Show inline comments
 
@@ -203,27 +203,29 @@ static void Ptrs_WAYP()
 
		SlObject(&wp, _old_waypoint_desc);
 

	
 
		if (IsSavegameVersionBefore(SLV_12)) {
 
			wp.town_cn = (wp.string_id & 0xC000) == 0xC000 ? (wp.string_id >> 8) & 0x3F : 0;
 
			wp.town = ClosestTownFromTile(wp.xy, UINT_MAX);
 
		} else if (IsSavegameVersionBefore(SLV_122)) {
 
			/* Only for versions 12 .. 122 */
 
			if (!Town::IsValidID(wp.town_index)) {
 
				/* Upon a corrupted waypoint we'll likely get here. The next step will be to
 
				 * loop over all Ptrs procs to nullptr the pointers. However, we don't know
 
				 * whether we're in the nullptr or "normal" Ptrs proc. So just clear the list
 
				 * of old waypoints we constructed and then this waypoint (and the other
 
				 * possibly corrupt ones) will not be queried in the nullptr Ptrs proc run. */
 
				_old_waypoints.clear();
 
				SlErrorCorrupt("Referencing invalid Town");
 
			}
 
			wp.town = Town::Get(wp.town_index);
 
		}
 
		if (IsSavegameVersionBefore(SLV_84)) {
 
			wp.name = CopyFromOldName(wp.string_id);
 
		}
 
	}
 
}
 

	
 
extern const ChunkHandler _waypoint_chunk_handlers[] = {
 
	{ 'CHKP', nullptr, Load_WAYP, Ptrs_WAYP, nullptr, CH_ARRAY | CH_LAST},
 
static const ChunkHandler waypoint_chunk_handlers[] = {
 
	{ 'CHKP', nullptr, Load_WAYP, Ptrs_WAYP, nullptr, CH_ARRAY },
 
};
 

	
 
extern const ChunkHandlerTable _waypoint_chunk_handlers(waypoint_chunk_handlers);
src/settings.cpp
Show inline comments
 
@@ -2064,40 +2064,42 @@ static void Load_OPTS()
 
	 * autosave-frequency stays when joining a network-server */
 
	PrepareOldDiffCustom();
 
	LoadSettings(_gameopt_settings, &_settings_game);
 
	HandleOldDiffCustom(true);
 
}
 

	
 
static void Load_PATS()
 
{
 
	/* Copy over default setting since some might not get loaded in
 
	 * a networking environment. This ensures for example that the local
 
	 * currency setting stays when joining a network-server */
 
	LoadSettings(_settings, &_settings_game);
 
}
 

	
 
static void Check_PATS()
 
{
 
	LoadSettings(_settings, &_load_check_data.settings);
 
}
 

	
 
static void Save_PATS()
 
{
 
	SaveSettings(_settings, &_settings_game);
 
}
 

	
 
extern const ChunkHandler _setting_chunk_handlers[] = {
 
static const ChunkHandler setting_chunk_handlers[] = {
 
	{ 'OPTS', nullptr,      Load_OPTS, nullptr, nullptr,       CH_RIFF},
 
	{ 'PATS', Save_PATS, Load_PATS, nullptr, Check_PATS, CH_RIFF | CH_LAST},
 
	{ 'PATS', Save_PATS, Load_PATS, nullptr, Check_PATS, CH_RIFF },
 
};
 

	
 
extern const ChunkHandlerTable _setting_chunk_handlers(setting_chunk_handlers);
 

	
 
static bool IsSignedVarMemType(VarType vt)
 
{
 
	switch (GetVarMemType(vt)) {
 
		case SLE_VAR_I8:
 
		case SLE_VAR_I16:
 
		case SLE_VAR_I32:
 
		case SLE_VAR_I64:
 
			return true;
 
	}
 
	return false;
 
}
0 comments (0 inline, 0 general)