Saveload: Improve SpringPP savegame detection
Trunk savegames will soon reach the range of versions used by SpringPP
This commit is contained in:
@@ -51,6 +51,7 @@
|
|||||||
uint16 _sl_xv_feature_versions[XSLFI_SIZE]; ///< array of all known feature types and their current versions
|
uint16 _sl_xv_feature_versions[XSLFI_SIZE]; ///< array of all known feature types and their current versions
|
||||||
bool _sl_is_ext_version; ///< is this an extended savegame version, with more info in the SLXI chunk?
|
bool _sl_is_ext_version; ///< is this an extended savegame version, with more info in the SLXI chunk?
|
||||||
bool _sl_is_faked_ext; ///< is this a faked extended savegame version, with no SLXI chunk? See: SlXvCheckSpecialSavegameVersions.
|
bool _sl_is_faked_ext; ///< is this a faked extended savegame version, with no SLXI chunk? See: SlXvCheckSpecialSavegameVersions.
|
||||||
|
bool _sl_maybe_springpp; ///< is this possibly a SpringPP savegame?
|
||||||
std::vector<uint32> _sl_xv_discardable_chunk_ids; ///< list of chunks IDs which we can discard if no chunk loader exists
|
std::vector<uint32> _sl_xv_discardable_chunk_ids; ///< list of chunks IDs which we can discard if no chunk loader exists
|
||||||
|
|
||||||
static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version of SLXI chunk
|
static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version of SLXI chunk
|
||||||
@@ -174,6 +175,7 @@ void SlXvResetState()
|
|||||||
{
|
{
|
||||||
_sl_is_ext_version = false;
|
_sl_is_ext_version = false;
|
||||||
_sl_is_faked_ext = false;
|
_sl_is_faked_ext = false;
|
||||||
|
_sl_maybe_springpp = false;
|
||||||
_sl_xv_discardable_chunk_ids.clear();
|
_sl_xv_discardable_chunk_ids.clear();
|
||||||
memset(_sl_xv_feature_versions, 0, sizeof(_sl_xv_feature_versions));
|
memset(_sl_xv_feature_versions, 0, sizeof(_sl_xv_feature_versions));
|
||||||
}
|
}
|
||||||
@@ -198,7 +200,7 @@ void SlXvSetCurrentState()
|
|||||||
/**
|
/**
|
||||||
* Check for "special" savegame versions (i.e. known patchpacks) and set correct savegame version, settings, etc.
|
* Check for "special" savegame versions (i.e. known patchpacks) and set correct savegame version, settings, etc.
|
||||||
*/
|
*/
|
||||||
void SlXvCheckSpecialSavegameVersions()
|
bool SlXvCheckSpecialSavegameVersions()
|
||||||
{
|
{
|
||||||
// Checks for special savegame versions go here
|
// Checks for special savegame versions go here
|
||||||
extern SaveLoadVersion _sl_version;
|
extern SaveLoadVersion _sl_version;
|
||||||
@@ -208,19 +210,32 @@ void SlXvCheckSpecialSavegameVersions()
|
|||||||
_sl_version = SLV_194;
|
_sl_version = SLV_194;
|
||||||
_sl_is_faked_ext = true;
|
_sl_is_faked_ext = true;
|
||||||
_sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 1;
|
_sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 1;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (_sl_version == SL_TRACE_RESTRICT_2001) {
|
if (_sl_version == SL_TRACE_RESTRICT_2001) {
|
||||||
DEBUG(sl, 1, "Loading a trace restrict patch savegame version %d as version 195", _sl_version);
|
DEBUG(sl, 1, "Loading a trace restrict patch savegame version %d as version 195", _sl_version);
|
||||||
_sl_version = SLV_195;
|
_sl_version = SLV_195;
|
||||||
_sl_is_faked_ext = true;
|
_sl_is_faked_ext = true;
|
||||||
_sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 6;
|
_sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 6;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (_sl_version == SL_TRACE_RESTRICT_2002) {
|
if (_sl_version == SL_TRACE_RESTRICT_2002) {
|
||||||
DEBUG(sl, 1, "Loading a trace restrict patch savegame version %d as version 196", _sl_version);
|
DEBUG(sl, 1, "Loading a trace restrict patch savegame version %d as version 196", _sl_version);
|
||||||
_sl_version = SLV_196;
|
_sl_version = SLV_196;
|
||||||
_sl_is_faked_ext = true;
|
_sl_is_faked_ext = true;
|
||||||
_sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 6;
|
_sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 6;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
if (_sl_version >= SL_SPRING_2013_v2_0_102 && _sl_version <= SL_SPRING_2013_v2_4) { /* 220 - 227 */
|
||||||
|
_sl_maybe_springpp = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlXvSpringPPSpecialSavegameVersions()
|
||||||
|
{
|
||||||
|
extern SaveLoadVersion _sl_version;
|
||||||
|
|
||||||
if (_sl_version == SL_SPRING_2013_v2_0_102) { /* 220 */
|
if (_sl_version == SL_SPRING_2013_v2_0_102) { /* 220 */
|
||||||
DEBUG(sl, 1, "Loading a SpringPP 2013 v2.0.102 savegame version %d as version 187", _sl_version);
|
DEBUG(sl, 1, "Loading a SpringPP 2013 v2.0.102 savegame version %d as version 187", _sl_version);
|
||||||
|
@@ -172,7 +172,7 @@ void SlXvResetState();
|
|||||||
|
|
||||||
void SlXvSetCurrentState();
|
void SlXvSetCurrentState();
|
||||||
|
|
||||||
void SlXvCheckSpecialSavegameVersions();
|
bool SlXvCheckSpecialSavegameVersions();
|
||||||
|
|
||||||
bool SlXvIsChunkDiscardable(uint32 id);
|
bool SlXvIsChunkDiscardable(uint32 id);
|
||||||
|
|
||||||
|
@@ -83,6 +83,7 @@ char _savegame_format[8]; ///< how to compress savegames
|
|||||||
bool _do_autosave; ///< are we doing an autosave at the moment?
|
bool _do_autosave; ///< are we doing an autosave at the moment?
|
||||||
|
|
||||||
extern bool _sl_is_ext_version;
|
extern bool _sl_is_ext_version;
|
||||||
|
extern bool _sl_maybe_springpp;
|
||||||
|
|
||||||
/** What are we currently doing? */
|
/** What are we currently doing? */
|
||||||
enum SaveLoadAction {
|
enum SaveLoadAction {
|
||||||
@@ -1990,6 +1991,19 @@ void SlAutolength(AutolengthProc *proc, void *arg)
|
|||||||
* by adding a further u32 field for the high bits after the existing RIFF size field.
|
* by adding a further u32 field for the high bits after the existing RIFF size field.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
inline void SlRIFFSpringPPCheck(size_t len)
|
||||||
|
{
|
||||||
|
if (_sl_maybe_springpp) {
|
||||||
|
_sl_maybe_springpp = false;
|
||||||
|
if (len == 0) {
|
||||||
|
extern void SlXvSpringPPSpecialSavegameVersions();
|
||||||
|
SlXvSpringPPSpecialSavegameVersions();
|
||||||
|
} else if (_sl_version > SAVEGAME_VERSION) {
|
||||||
|
SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a chunk of data (eg vehicles, stations, etc.)
|
* Load a chunk of data (eg vehicles, stations, etc.)
|
||||||
* @param ch The chunkhandler that will be used for the operation
|
* @param ch The chunkhandler that will be used for the operation
|
||||||
@@ -2027,6 +2041,7 @@ static void SlLoadChunk(const ChunkHandler *ch)
|
|||||||
/* Read length */
|
/* Read length */
|
||||||
len = (SlReadByte() << 16) | ((m >> 4) << 24);
|
len = (SlReadByte() << 16) | ((m >> 4) << 24);
|
||||||
len += SlReadUint16();
|
len += SlReadUint16();
|
||||||
|
SlRIFFSpringPPCheck(len);
|
||||||
if (SlXvIsFeaturePresent(XSLFI_RIFF_HEADER_60_BIT)) {
|
if (SlXvIsFeaturePresent(XSLFI_RIFF_HEADER_60_BIT)) {
|
||||||
if (len != 0) {
|
if (len != 0) {
|
||||||
SlErrorCorrupt("RIFF chunk too large");
|
SlErrorCorrupt("RIFF chunk too large");
|
||||||
@@ -2101,6 +2116,7 @@ static void SlLoadCheckChunk(const ChunkHandler *ch)
|
|||||||
/* Read length */
|
/* Read length */
|
||||||
len = (SlReadByte() << 16) | ((m >> 4) << 24);
|
len = (SlReadByte() << 16) | ((m >> 4) << 24);
|
||||||
len += SlReadUint16();
|
len += SlReadUint16();
|
||||||
|
SlRIFFSpringPPCheck(len);
|
||||||
if (SlXvIsFeaturePresent(XSLFI_RIFF_HEADER_60_BIT)) {
|
if (SlXvIsFeaturePresent(XSLFI_RIFF_HEADER_60_BIT)) {
|
||||||
if (len != 0) {
|
if (len != 0) {
|
||||||
SlErrorCorrupt("RIFF chunk too large");
|
SlErrorCorrupt("RIFF chunk too large");
|
||||||
@@ -3134,17 +3150,18 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
|
|||||||
* Therefore it is loaded, but never saved (or, it saves a 0 in any scenario). */
|
* Therefore it is loaded, but never saved (or, it saves a 0 in any scenario). */
|
||||||
_sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
|
_sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
|
||||||
|
|
||||||
|
bool special_version = false;
|
||||||
if (_sl_version & SAVEGAME_VERSION_EXT) {
|
if (_sl_version & SAVEGAME_VERSION_EXT) {
|
||||||
_sl_version = (SaveLoadVersion)(_sl_version & ~SAVEGAME_VERSION_EXT);
|
_sl_version = (SaveLoadVersion)(_sl_version & ~SAVEGAME_VERSION_EXT);
|
||||||
_sl_is_ext_version = true;
|
_sl_is_ext_version = true;
|
||||||
} else {
|
} else {
|
||||||
SlXvCheckSpecialSavegameVersions();
|
special_version = SlXvCheckSpecialSavegameVersions();
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(sl, 1, "Loading savegame version %d%s", _sl_version, _sl_is_ext_version ? " (extended)" : "");
|
DEBUG(sl, 1, "Loading savegame version %d%s%s", _sl_version, _sl_is_ext_version ? " (extended)" : "", _sl_maybe_springpp ? " which might be SpringPP" : "");
|
||||||
|
|
||||||
/* Is the version higher than the current? */
|
/* Is the version higher than the current? */
|
||||||
if (_sl_version > SAVEGAME_VERSION) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
|
if (_sl_version > SAVEGAME_VERSION && !special_version) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user