Merge branch 'save_ext' into day_length

# Conflicts:
#	src/saveload/saveload.cpp
This commit is contained in:
Jonathan G Rennison
2016-09-07 21:49:28 +01:00
259 changed files with 16793 additions and 3726 deletions

View File

@@ -248,7 +248,7 @@ static void InitializeWindowsAndCaches()
/* For each company, verify (while loading a scenario) that the inauguration date is the current year and set it
* accordingly if it is not the case. No need to set it on companies that are not been used already,
* thus the MIN_YEAR (which is really nothing more than Zero, initialized value) test */
if (_file_to_saveload.filetype == FT_SCENARIO && c->inaugurated_year != MIN_YEAR) {
if (_file_to_saveload.abstract_ftype == FT_SCENARIO && c->inaugurated_year != MIN_YEAR) {
c->inaugurated_year = _cur_year;
}
}

View File

@@ -16,6 +16,7 @@
#include "../tunnelbridge_map.h"
#include "../tunnelbridge.h"
#include "../station_base.h"
#include "../settings_func.h"
#include "saveload.h"
@@ -486,6 +487,7 @@ static void Load_PLYR()
int index;
while ((index = SlIterateArray()) != -1) {
Company *c = new (index) Company();
SetDefaultCompanySettings(c->index);
SaveLoad_PLYR(c);
_company_colours[index] = (Colours)c->colour;
}
@@ -529,7 +531,25 @@ static void Ptrs_PLYR()
}
}
extern void LoadSettingsPlyx(bool skip);
extern void SaveSettingsPlyx();
static void Load_PLYX()
{
LoadSettingsPlyx(false);
}
static void Check_PLYX()
{
LoadSettingsPlyx(true);
}
static void Save_PLYX()
{
SaveSettingsPlyx();
}
extern const ChunkHandler _company_chunk_handlers[] = {
{ 'PLYR', Save_PLYR, Load_PLYR, Ptrs_PLYR, Check_PLYR, CH_ARRAY | CH_LAST},
{ 'PLYR', Save_PLYR, Load_PLYR, Ptrs_PLYR, Check_PLYR, CH_ARRAY },
{ 'PLYX', Save_PLYX, Load_PLYX, NULL, Check_PLYX, CH_RIFF | CH_LAST},
};

View File

@@ -116,9 +116,7 @@ void SlXvSetCurrentState()
*/
void SlXvCheckSpecialSavegameVersions()
{
extern uint16 _sl_version;
// TODO: check for savegame versions
// Checks for special savegame versions go here
}
/**
@@ -165,7 +163,6 @@ static void Save_SLXI()
SlXvSetCurrentState();
static const SaveLoad _xlsi_sub_chunk_desc[] = {
SLE_VAR(SlxiSubChunkInfo, save_version, SLE_UINT16),
SLE_STR(SlxiSubChunkInfo, name, SLE_STR, 0),
SLE_END()
};
@@ -179,9 +176,9 @@ static void Save_SLXI()
chunk_counts.resize(XSLFI_SIZE);
const SlxiSubChunkInfo *info = _sl_xv_sub_chunk_infos;
for (; info->index != XSLFI_NULL; ++info) {
if (info->save_version > 0) {
if (_sl_xv_feature_versions[info->index] > 0) {
item_count++;
length += 4;
length += 6;
length += SlCalcObjLength(info, _xlsi_sub_chunk_desc);
if (info->save_proc) {
uint32 extra_data_length = info->save_proc(info, true);
@@ -209,7 +206,8 @@ static void Save_SLXI()
// write data
info = _sl_xv_sub_chunk_infos;
for (; info->index != XSLFI_NULL; ++info) {
if (info->save_version > 0) {
uint16 save_version = _sl_xv_feature_versions[info->index];
if (save_version > 0) {
SlxiSubChunkFlags flags = info->flags;
assert(!(flags & (XSCF_EXTRA_DATA_PRESENT | XSCF_CHUNK_ID_LIST_PRESENT)));
uint32 extra_data_length = extra_data_lengths[info->index];
@@ -217,6 +215,7 @@ static void Save_SLXI()
if (extra_data_length > 0) flags |= XSCF_EXTRA_DATA_PRESENT;
if (chunk_count > 0) flags |= XSCF_CHUNK_ID_LIST_PRESENT;
SlWriteUint32(flags);
SlWriteUint16(save_version);
SlObject(const_cast<SlxiSubChunkInfo *>(info), _xlsi_sub_chunk_desc);
if (extra_data_length > 0) {

View File

@@ -264,12 +264,14 @@
* 191 26646
* 192 26700
* 193 26802
* 194 26881 1.5.x
* 194 26881 1.5.x, 1.6.0
* 195 27572 1.6.x
*/
extern const uint16 SAVEGAME_VERSION = 194; ///< Current savegame version of OpenTTD.
extern const uint16 SAVEGAME_VERSION = 195; ///< Current savegame version of OpenTTD.
const uint16 SAVEGAME_VERSION_EXT = 0x8000; ///< Savegame extension indicator mask
SavegameType _savegame_type; ///< type of savegame we are loading
FileToSaveLoad _file_to_saveload; ///< File to save or load in the openttd loop.
uint32 _ttdp_version; ///< version of TTDP savegame (if applicable)
uint16 _sl_version; ///< the major savegame version identifier
@@ -564,7 +566,7 @@ void NORETURN SlError(StringID string, const char *extra_msg, bool already_mallo
/**
* As SlError, except that it takes a format string and additional parameters
*/
void CDECL NORETURN SlErrorFmt(StringID string, const char *msg, ...)
void NORETURN CDECL SlErrorFmt(StringID string, const char *msg, ...)
{
va_list va;
va_start(va, msg);
@@ -588,7 +590,7 @@ void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced)
/**
* As SlErrorCorruptFmt, except that it takes a format string and additional parameters
*/
void CDECL NORETURN SlErrorCorruptFmt(const char *msg, ...)
void NORETURN CDECL SlErrorCorruptFmt(const char *msg, ...)
{
va_list va;
va_start(va, msg);
@@ -888,9 +890,20 @@ void SlSetLength(size_t length)
case CH_RIFF:
/* Ugly encoding of >16M RIFF chunks
* The lower 24 bits are normal
* The uppermost 4 bits are bits 24:27 */
assert(length < (1 << 28));
* The uppermost 4 bits are bits 24:27
*
* If we have more than 28 bits, use an extra uint32 and
* signal this using the extended chunk header */
assert(length < (1LL << 32));
if (length >= (1 << 28)) {
/* write out extended chunk header */
SlWriteByte(CH_EXT_HDR);
SlWriteUint32(static_cast<uint32>(SLCEHF_BIG_RIFF));
}
SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
if (length >= (1 << 28)) {
SlWriteUint32(length >> 28);
}
break;
case CH_ARRAY:
assert(_sl.last_array_index <= _sl.array_index);
@@ -1661,6 +1674,16 @@ void SlAutolength(AutolengthProc *proc, void *arg)
if (offs != _sl.dumper->GetSize()) SlErrorCorrupt("Invalid chunk size");
}
/*
* Notes on extended chunk header:
*
* If the chunk type is CH_EXT_HDR (15), then a u32 flags field follows.
* This flag field may define additional fields which follow the flags field in future.
* The standard chunk header follows, though it my be modified by the flags field.
* At present SLCEHF_BIG_RIFF increases the RIFF size limit to a theoretical 60 bits,
* by adding a further u32 field for the high bits after the existing RIFF size field.
*/
/**
* Load a chunk of data (eg vehicles, stations, etc.)
* @param ch The chunkhandler that will be used for the operation
@@ -1674,6 +1697,15 @@ static void SlLoadChunk(const ChunkHandler *ch)
_sl.block_mode = m;
_sl.obj_len = 0;
SaveLoadChunkExtHeaderFlags ext_flags = static_cast<SaveLoadChunkExtHeaderFlags>(0);
if ((m & 0xF) == CH_EXT_HDR) {
ext_flags = static_cast<SaveLoadChunkExtHeaderFlags>(SlReadUint32());
/* read in real header */
m = SlReadByte();
_sl.block_mode = m;
}
switch (m) {
case CH_ARRAY:
_sl.array_index = 0;
@@ -1689,6 +1721,10 @@ static void SlLoadChunk(const ChunkHandler *ch)
/* Read length */
len = (SlReadByte() << 16) | ((m >> 4) << 24);
len += SlReadUint16();
if (ext_flags & SLCEHF_BIG_RIFF) {
len |= SlReadUint32() << 28;
}
_sl.obj_len = len;
endoffs = _sl.reader->GetSize() + len;
ch->load_proc();
@@ -1714,9 +1750,21 @@ static void SlLoadCheckChunk(const ChunkHandler *ch)
_sl.block_mode = m;
_sl.obj_len = 0;
SaveLoadChunkExtHeaderFlags ext_flags = static_cast<SaveLoadChunkExtHeaderFlags>(0);
if ((m & 0xF) == CH_EXT_HDR) {
ext_flags = static_cast<SaveLoadChunkExtHeaderFlags>(SlReadUint32());
/* read in real header */
m = SlReadByte();
_sl.block_mode = m;
}
switch (m) {
case CH_ARRAY:
_sl.array_index = 0;
if (ext_flags) {
SlErrorCorruptFmt("CH_ARRAY does not take chunk header extension flags: 0x%X", ext_flags);
}
if (ch && ch->load_check_proc) {
ch->load_check_proc();
} else {
@@ -1724,6 +1772,9 @@ static void SlLoadCheckChunk(const ChunkHandler *ch)
}
break;
case CH_SPARSE_ARRAY:
if (ext_flags) {
SlErrorCorruptFmt("CH_SPARSE_ARRAY does not take chunk header extension flags: 0x%X", ext_flags);
}
if (ch && ch->load_check_proc) {
ch->load_check_proc();
} else {
@@ -1732,9 +1783,19 @@ static void SlLoadCheckChunk(const ChunkHandler *ch)
break;
default:
if ((m & 0xF) == CH_RIFF) {
if (ext_flags != (ext_flags & SLCEHF_BIG_RIFF)) {
SlErrorCorruptFmt("Unknown chunk header extension flags for CH_RIFF: 0x%X", ext_flags);
}
/* Read length */
len = (SlReadByte() << 16) | ((m >> 4) << 24);
len += SlReadUint16();
if (ext_flags & SLCEHF_BIG_RIFF) {
uint64 full_len = len | (static_cast<uint64>(SlReadUint32()) << 28);
if (full_len >= (1LL << 32)) {
SlErrorCorrupt("Chunk size too large: " OTTD_PRINTFHEX64, full_len);
}
len = static_cast<size_t>(full_len);
}
_sl.obj_len = len;
endoffs = _sl.reader->GetSize() + len;
if (ch && ch->load_check_proc) {
@@ -2478,7 +2539,7 @@ static void SaveFileStart()
{
_sl.ff_state = _fast_forward;
_fast_forward = 0;
if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
SetMouseCursorBusy(true);
InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_START);
_sl.saveinprogress = true;
@@ -2488,7 +2549,7 @@ static void SaveFileStart()
static void SaveFileDone()
{
if (_game_mode != GM_MENU) _fast_forward = _sl.ff_state;
if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
SetMouseCursorBusy(false);
InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_FINISH);
_sl.saveinprogress = false;
@@ -2808,10 +2869,10 @@ SaveOrLoadResult LoadWithFilter(LoadFilter *reader)
* @param threaded True when threaded saving is allowed
* @return Return the result of the action. #SL_OK, #SL_ERROR, or #SL_REINIT ("unload" the game)
*/
SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, bool threaded)
SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
{
/* An instance of saving is already active, so don't go saving again */
if (_sl.saveinprogress && mode == SL_SAVE && threaded) {
if (_sl.saveinprogress && fop == SLO_SAVE && dft == DFT_GAME_FILE && threaded) {
/* if not an autosave, but a user action, show error message */
if (!_do_autosave) ShowErrorMessage(STR_ERROR_SAVE_STILL_IN_PROGRESS, INVALID_STRING_ID, WL_ERROR);
return SL_OK;
@@ -2820,7 +2881,7 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, boo
try {
/* Load a TTDLX or TTDPatch game */
if (mode == SL_OLD_LOAD) {
if (fop == SLO_LOAD && dft == DFT_OLD_GAME_FILE) {
InitializeGame(256, 256, true, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused
/* TTD/TTO savegames have no NewGRFs, TTDP savegame have them
@@ -2843,25 +2904,35 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, boo
return SL_OK;
}
switch (mode) {
case SL_LOAD_CHECK: _sl.action = SLA_LOAD_CHECK; break;
case SL_LOAD: _sl.action = SLA_LOAD; break;
case SL_SAVE: _sl.action = SLA_SAVE; break;
assert(dft == DFT_GAME_FILE);
switch (fop) {
case SLO_CHECK:
_sl.action = SLA_LOAD_CHECK;
break;
case SLO_LOAD:
_sl.action = SLA_LOAD;
break;
case SLO_SAVE:
_sl.action = SLA_SAVE;
break;
default: NOT_REACHED();
}
FILE *fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
FILE *fh = (fop == SLO_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
/* Make it a little easier to load savegames from the console */
if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", SAVE_DIR);
if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", BASE_DIR);
if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", SCENARIO_DIR);
if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", SAVE_DIR);
if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", BASE_DIR);
if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", SCENARIO_DIR);
if (fh == NULL) {
SlError(mode == SL_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
SlError(fop == SLO_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
}
if (mode == SL_SAVE) { // SAVE game
if (fop == SLO_SAVE) { // SAVE game
DEBUG(desync, 1, "save: %08x; %02x; %02X; %s", _date, _date_fract, _tick_skip_counter, filename);
if (_network_server || !_settings_client.gui.threaded_saves) threaded = false;
@@ -2869,24 +2940,25 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, boo
}
/* LOAD game */
assert(mode == SL_LOAD || mode == SL_LOAD_CHECK);
assert(fop == SLO_LOAD || fop == SLO_CHECK);
DEBUG(desync, 1, "load: %s", filename);
return DoLoad(new FileReader(fh), mode == SL_LOAD_CHECK);
return DoLoad(new FileReader(fh), fop == SLO_CHECK);
} catch (...) {
/* This code may be executed both for old and new save games. */
ClearSaveLoadState();
/* Skip the "colour" character */
if (mode != SL_LOAD_CHECK) DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
if (fop != SLO_CHECK) DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
/* A saver/loader exception!! reinitialize all variables to prevent crash! */
return (mode == SL_LOAD || mode == SL_OLD_LOAD) ? SL_REINIT : SL_ERROR;
return (fop == SLO_LOAD) ? SL_REINIT : SL_ERROR;
}
}
/** Do a save when exiting the game (_settings_client.gui.autosave_on_exit) */
void DoExitSave()
{
SaveOrLoad("exit.sav", SL_SAVE, AUTOSAVE_DIR);
SaveOrLoad("exit.sav", SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR);
}
/**
@@ -2924,6 +2996,53 @@ void GenerateDefaultSaveName(char *buf, const char *last)
SanitizeFilename(buf);
}
/**
* Set the mode and file type of the file to save or load based on the type of file entry at the file system.
* @param ft Type of file entry of the file system.
*/
void FileToSaveLoad::SetMode(FiosType ft)
{
this->SetMode(SLO_LOAD, GetAbstractFileType(ft), GetDetailedFileType(ft));
}
/**
* Set the mode and file type of the file to save or load.
* @param fop File operation being performed.
* @param aft Abstract file type.
* @param dft Detailed file type.
*/
void FileToSaveLoad::SetMode(SaveLoadOperation fop, AbstractFileType aft, DetailedFileType dft)
{
if (aft == FT_INVALID || aft == FT_NONE) {
this->file_op = SLO_INVALID;
this->detail_ftype = DFT_INVALID;
this->abstract_ftype = FT_INVALID;
return;
}
this->file_op = fop;
this->detail_ftype = dft;
this->abstract_ftype = aft;
}
/**
* Set the name of the file.
* @param name Name of the file.
*/
void FileToSaveLoad::SetName(const char *name)
{
strecpy(this->name, name, lastof(this->name));
}
/**
* Set the title of the file.
* @param title Title of the file.
*/
void FileToSaveLoad::SetTitle(const char *title)
{
strecpy(this->title, title, lastof(this->title));
}
#if 0
/**
* Function to get the type of the savegame by looking at the file header.

View File

@@ -25,15 +25,18 @@ enum SaveOrLoadResult {
SL_REINIT = 2, ///< error that was caught in the middle of updating game state, need to clear it. (can only happen during load)
};
/** Save or load mode. @see SaveOrLoad */
enum SaveOrLoadMode {
SL_INVALID = -1, ///< Invalid mode.
SL_LOAD = 0, ///< Load game.
SL_SAVE = 1, ///< Save game.
SL_OLD_LOAD = 2, ///< Load old game.
SL_PNG = 3, ///< Load PNG file (height map).
SL_BMP = 4, ///< Load BMP file (height map).
SL_LOAD_CHECK = 5, ///< Load for game preview.
/** Deals with the type of the savegame, independent of extension */
struct FileToSaveLoad {
SaveLoadOperation file_op; ///< File operation to perform.
DetailedFileType detail_ftype; ///< Concrete file type (PNG, BMP, old save, etc).
AbstractFileType abstract_ftype; ///< Abstract type of file (scenario, heightmap, etc).
char name[MAX_PATH]; ///< Name of the file.
char title[255]; ///< Internal name of the game.
void SetMode(FiosType ft);
void SetMode(SaveLoadOperation fop, AbstractFileType aft, DetailedFileType dft);
void SetName(const char *name);
void SetTitle(const char *title);
};
/** Types of save games. */
@@ -46,10 +49,12 @@ enum SavegameType {
SGT_INVALID = 0xFF, ///< broken savegame (used internally)
};
extern FileToSaveLoad _file_to_saveload;
void GenerateDefaultSaveName(char *buf, const char *last);
void SetSaveLoadError(uint16 str);
const char *GetSaveLoadErrorString();
SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, bool threaded = true);
SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded = true);
void WaitTillSaved();
void ProcessAsyncSaveFinish();
void DoExitSave();
@@ -99,10 +104,17 @@ enum ChunkType {
CH_ARRAY = 1,
CH_SPARSE_ARRAY = 2,
CH_TYPE_MASK = 3,
CH_EXT_HDR = 15, ///< Extended chunk header
CH_LAST = 8, ///< Last chunk in this array.
CH_AUTO_LENGTH = 16,
};
/** Flags for chunk extended headers */
enum SaveLoadChunkExtHeaderFlags {
SLCEHF_BIG_RIFF = 1 << 0, ///< This block uses a 60-bit RIFF chunk size
};
DECLARE_ENUM_AS_BIT_SET(SaveLoadChunkExtHeaderFlags)
/**
* VarTypes is the general bitmasked magic type that tells us
* certain characteristics about the variable it refers to. For example
@@ -234,7 +246,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @note In general, it is better to use one of the SLE_* macros below.
*/
#define SLE_GENERAL_X(cmd, base, variable, type, length, from, to, extver) {false, cmd, type, length, from, to, (void*)cpp_offsetof(base, variable), cpp_sizeof(base, variable), extver}
#define SLE_GENERAL(cmd, base, variable, type, length, from, to) SLE_GENERAL_X(cmd, base, variable, type, length, from, to, {})
#define SLE_GENERAL(cmd, base, variable, type, length, from, to) SLE_GENERAL_X(cmd, base, variable, type, length, from, to, SlXvFeatureTest())
/**
* Storage of a variable in some savegame versions.
@@ -246,7 +258,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLE_CONDVAR_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_VAR, base, variable, type, 0, from, to, extver)
#define SLE_CONDVAR(base, variable, type, from, to) SLE_CONDVAR_X(base, variable, type, from, to, {})
#define SLE_CONDVAR(base, variable, type, from, to) SLE_CONDVAR_X(base, variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a reference in some savegame versions.
@@ -258,7 +270,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLE_CONDREF_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_REF, base, variable, type, 0, from, to, extver)
#define SLE_CONDREF(base, variable, type, from, to) SLE_CONDREF_X(base, variable, type, from, to, {})
#define SLE_CONDREF(base, variable, type, from, to) SLE_CONDREF_X(base, variable, type, from, to, SlXvFeatureTest())
/**
* Storage of an array in some savegame versions.
@@ -271,7 +283,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLE_CONDARR_X(base, variable, type, length, from, to, extver) SLE_GENERAL_X(SL_ARR, base, variable, type, length, from, to, extver)
#define SLE_CONDARR(base, variable, type, length, from, to) SLE_CONDARR_X(base, variable, type, length, from, to, {})
#define SLE_CONDARR(base, variable, type, length, from, to) SLE_CONDARR_X(base, variable, type, length, from, to, SlXvFeatureTest())
/**
* Storage of a string in some savegame versions.
@@ -284,7 +296,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLE_CONDSTR_X(base, variable, type, length, from, to, extver) SLE_GENERAL_X(SL_STR, base, variable, type, length, from, to, extver)
#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_CONDSTR_X(base, variable, type, length, from, to, {})
#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_CONDSTR_X(base, variable, type, length, from, to, SlXvFeatureTest())
/**
* Storage of a list in some savegame versions.
@@ -296,7 +308,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLE_CONDLST_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_LST, base, variable, type, 0, from, to, extver)
#define SLE_CONDLST(base, variable, type, from, to) SLE_CONDLST_X(base, variable, type, from, to, {})
#define SLE_CONDLST(base, variable, type, from, to) SLE_CONDLST_X(base, variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a variable in every version of a savegame.
@@ -354,16 +366,16 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have empty space
*/
#define SLE_CONDNULL_X(length, from, to, extver) SLE_CONDARR_X(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, extver)
#define SLE_CONDNULL(length, from, to) SLE_CONDNULL_X(length, from, to, {})
#define SLE_CONDNULL(length, from, to) SLE_CONDNULL_X(length, from, to, SlXvFeatureTest())
/** 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)
#define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0, {}}
#define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0, {}}
#define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0, SlXvFeatureTest()}
#define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0, SlXvFeatureTest()}
/** End marker of a struct/class save or load. */
#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL, 0, {}}
#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL, 0, SlXvFeatureTest()}
/**
* Storage of global simple variables, references (pointers), and arrays.
@@ -376,7 +388,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @note In general, it is better to use one of the SLEG_* macros below.
*/
#define SLEG_GENERAL_X(cmd, variable, type, length, from, to, extver) {true, cmd, type, length, from, to, (void*)&variable, sizeof(variable), extver}
#define SLEG_GENERAL(cmd, variable, type, length, from, to) SLEG_GENERAL_X(cmd, variable, type, length, from, to, {})
#define SLEG_GENERAL(cmd, variable, type, length, from, to) SLEG_GENERAL_X(cmd, variable, type, length, from, to, SlXvFeatureTest())
/**
* Storage of a global variable in some savegame versions.
@@ -387,7 +399,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLEG_CONDVAR_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_VAR, variable, type, 0, from, to, extver)
#define SLEG_CONDVAR(variable, type, from, to) SLEG_CONDVAR_X(variable, type, from, to, {})
#define SLEG_CONDVAR(variable, type, from, to) SLEG_CONDVAR_X(variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a global reference in some savegame versions.
@@ -398,7 +410,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLEG_CONDREF_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_REF, variable, type, 0, from, to, extver)
#define SLEG_CONDREF(variable, type, from, to) SLEG_CONDREF_X(variable, type, from, to, {})
#define SLEG_CONDREF(variable, type, from, to) SLEG_CONDREF_X(variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a global array in some savegame versions.
@@ -410,7 +422,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLEG_CONDARR_X(variable, type, length, from, to, extver) SLEG_GENERAL_X(SL_ARR, variable, type, length, from, to, extver)
#define SLEG_CONDARR(variable, type, length, from, to) SLEG_CONDARR_X(variable, type, length, from, to, {})
#define SLEG_CONDARR(variable, type, length, from, to) SLEG_CONDARR_X(variable, type, length, from, to, SlXvFeatureTest())
/**
* Storage of a global string in some savegame versions.
@@ -422,7 +434,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLEG_CONDSTR_X(variable, type, length, from, to, extver) SLEG_GENERAL_X(SL_STR, variable, type, length, from, to, extver)
#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_CONDSTR_X(variable, type, length, from, to, {})
#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_CONDSTR_X(variable, type, length, from, to, SlXvFeatureTest())
/**
* Storage of a global list in some savegame versions.
@@ -433,7 +445,7 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLEG_CONDLST_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_LST, variable, type, 0, from, to, extver)
#define SLEG_CONDLST(variable, type, from, to) SLEG_CONDLST_X(variable, type, from, to, {})
#define SLEG_CONDLST(variable, type, from, to) SLEG_CONDLST_X(variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a global variable in every savegame version.
@@ -477,10 +489,10 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param to Last savegame version that has the empty space.
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have empty space
*/
#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL, {}}
#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL, SlXvFeatureTest()}
/** End marker of global variables save or load. */
#define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL, 0, {}}
#define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL, 0, SlXvFeatureTest()}
/**
* Checks whether the savegame is below \a major.\a minor.
@@ -624,8 +636,8 @@ void SlObject(void *object, const SaveLoad *sld);
bool SlObjectMember(void *object, const SaveLoad *sld);
void NORETURN SlError(StringID string, const char *extra_msg = NULL, bool already_malloced = false);
void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced = false);
void CDECL NORETURN SlErrorFmt(StringID string, const char *msg, ...) WARN_FORMAT(2, 3);
void CDECL NORETURN SlErrorCorruptFmt(const char *msg, ...) WARN_FORMAT(1, 2);
void NORETURN CDECL SlErrorFmt(StringID string, const char *msg, ...) WARN_FORMAT(2, 3);
void NORETURN CDECL SlErrorCorruptFmt(const char *msg, ...) WARN_FORMAT(1, 2);
bool SaveloadCrashWithMissingNewGRFs();

View File

@@ -60,7 +60,7 @@ static void Load_SIGN()
}
/* Signs placed in scenario editor shall now be OWNER_DEITY */
if (IsSavegameVersionBefore(171) && si->owner == OWNER_NONE && _saveload_mode == SLD_LOAD_SCENARIO) {
if (IsSavegameVersionBefore(171) && si->owner == OWNER_NONE && _file_to_saveload.abstract_ftype == FT_SCENARIO) {
si->owner = OWNER_DEITY;
}
}