diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index a4db62fbc1..d0fa6b952f 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -51,6 +51,7 @@ 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_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 _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 @@ -174,6 +175,7 @@ void SlXvResetState() { _sl_is_ext_version = false; _sl_is_faked_ext = false; + _sl_maybe_springpp = false; _sl_xv_discardable_chunk_ids.clear(); 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. */ -void SlXvCheckSpecialSavegameVersions() +bool SlXvCheckSpecialSavegameVersions() { // Checks for special savegame versions go here extern SaveLoadVersion _sl_version; @@ -208,19 +210,32 @@ void SlXvCheckSpecialSavegameVersions() _sl_version = SLV_194; _sl_is_faked_ext = true; _sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 1; + return true; } if (_sl_version == SL_TRACE_RESTRICT_2001) { DEBUG(sl, 1, "Loading a trace restrict patch savegame version %d as version 195", _sl_version); _sl_version = SLV_195; _sl_is_faked_ext = true; _sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 6; + return true; } if (_sl_version == SL_TRACE_RESTRICT_2002) { DEBUG(sl, 1, "Loading a trace restrict patch savegame version %d as version 196", _sl_version); _sl_version = SLV_196; _sl_is_faked_ext = true; _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 */ DEBUG(sl, 1, "Loading a SpringPP 2013 v2.0.102 savegame version %d as version 187", _sl_version); diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index a52e0c955a..7ae414f9ab 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -172,7 +172,7 @@ void SlXvResetState(); void SlXvSetCurrentState(); -void SlXvCheckSpecialSavegameVersions(); +bool SlXvCheckSpecialSavegameVersions(); bool SlXvIsChunkDiscardable(uint32 id); diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 7c54824668..d67aa8c10d 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -83,6 +83,7 @@ char _savegame_format[8]; ///< how to compress savegames bool _do_autosave; ///< are we doing an autosave at the moment? extern bool _sl_is_ext_version; +extern bool _sl_maybe_springpp; /** What are we currently doing? */ 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. */ +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.) * @param ch The chunkhandler that will be used for the operation @@ -2027,6 +2041,7 @@ static void SlLoadChunk(const ChunkHandler *ch) /* Read length */ len = (SlReadByte() << 16) | ((m >> 4) << 24); len += SlReadUint16(); + SlRIFFSpringPPCheck(len); if (SlXvIsFeaturePresent(XSLFI_RIFF_HEADER_60_BIT)) { if (len != 0) { SlErrorCorrupt("RIFF chunk too large"); @@ -2101,6 +2116,7 @@ static void SlLoadCheckChunk(const ChunkHandler *ch) /* Read length */ len = (SlReadByte() << 16) | ((m >> 4) << 24); len += SlReadUint16(); + SlRIFFSpringPPCheck(len); if (SlXvIsFeaturePresent(XSLFI_RIFF_HEADER_60_BIT)) { if (len != 0) { 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). */ _sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF; + bool special_version = false; if (_sl_version & SAVEGAME_VERSION_EXT) { _sl_version = (SaveLoadVersion)(_sl_version & ~SAVEGAME_VERSION_EXT); _sl_is_ext_version = true; } 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? */ - 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; }