Merge branch 'save_ext' into day_length
# Conflicts: # src/saveload/saveload.cpp
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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},
|
||||
};
|
||||
|
@@ -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) {
|
||||
|
@@ -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.
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user