diff options
author | Colin Snover | 2017-05-12 23:35:02 -0500 |
---|---|---|
committer | Colin Snover | 2017-05-13 22:46:25 -0500 |
commit | 1911b19e154b4e946d29dbf143b18cb6c9e4b660 (patch) | |
tree | 0985f13635dea33872e45082ea7a1819254e407e | |
parent | 262ef4de61727ebe6ede497f871ef858253c9956 (diff) | |
download | scummvm-rg350-1911b19e154b4e946d29dbf143b18cb6c9e4b660.tar.gz scummvm-rg350-1911b19e154b4e946d29dbf143b18cb6c9e4b660.tar.bz2 scummvm-rg350-1911b19e154b4e946d29dbf143b18cb6c9e4b660.zip |
SCI32: Make sure all save game validity checks are in kCheckSaveGame32
Save game metadata validity checks in SCI32 should all exist within
kCheckSaveGame32 since this allows most games to recover
successfully from an attempt to load an invalid save game. If
gamestate_restore fails, the game will usually crash because the
engine is left in an inconsistent state (game scripts have cleaned
up objects in preparation for a game load that is no longer
happening).
-rw-r--r-- | engines/sci/engine/file.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/file.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/kfile.cpp | 15 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 35 |
4 files changed, 38 insertions, 16 deletions
diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp index 91cf189d0a..2128433b90 100644 --- a/engines/sci/engine/file.cpp +++ b/engines/sci/engine/file.cpp @@ -357,6 +357,8 @@ bool fillSavegameDesc(const Common::String &filename, SavegameDesc *desc) { desc->time = meta.saveTime; desc->version = meta.version; desc->gameVersion = meta.gameVersion; + desc->script0Size = meta.script0Size; + desc->gameObjectOffset = meta.gameObjectOffset; #ifdef ENABLE_SCI32 if (g_sci->getGameId() == GID_SHIVERS) { desc->lowScore = meta.lowScore; diff --git a/engines/sci/engine/file.h b/engines/sci/engine/file.h index 1c9a092063..fee628aad5 100644 --- a/engines/sci/engine/file.h +++ b/engines/sci/engine/file.h @@ -64,6 +64,8 @@ struct SavegameDesc { int version; char name[SCI_MAX_SAVENAME_LENGTH]; Common::String gameVersion; + uint32 script0Size; + uint32 gameObjectOffset; #ifdef ENABLE_SCI32 // Used by Shivers 1 uint16 lowScore; diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index e386b1315d..fd6fab6506 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -1328,6 +1328,21 @@ reg_t kCheckSaveGame32(EngineState *s, int argc, reg_t *argv) { return NULL_REG; } + if (save.gameObjectOffset > 0 && save.script0Size > 0) { + Resource *script0 = g_sci->getResMan()->findResource(ResourceId(kResourceTypeScript, 0), false); + assert(script0); + + if (save.script0Size != script0->size()) { + warning("Save game was created for a game with a script 0 size of %u, but the current game script 0 size is %u", save.script0Size, script0->size()); + return NULL_REG; + } + + if (save.gameObjectOffset != g_sci->getGameObject().getOffset()) { + warning("Save game was created for a game with the main game object at offset %u, but the current main game object offset is %u", save.gameObjectOffset, g_sci->getGameObject().getOffset()); + return NULL_REG; + } + } + return TRUE_REG; } diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 5172de3f43..dce6430946 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -1257,26 +1257,29 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { return; } - if ((meta.version < MINIMUM_SAVEGAME_VERSION) || (meta.version > CURRENT_SAVEGAME_VERSION)) { - if (meta.version < MINIMUM_SAVEGAME_VERSION) { - showScummVMDialog(_("The format of this saved game is obsolete, unable to load it")); - } else { - Common::String msg = Common::String::format(_("Savegame version is %d, maximum supported is %0d"), meta.version, CURRENT_SAVEGAME_VERSION); - showScummVMDialog(msg); - } - - s->r_acc = TRUE_REG; // signal failure - return; - } - - if (meta.gameObjectOffset > 0 && meta.script0Size > 0) { - Resource *script0 = g_sci->getResMan()->findResource(ResourceId(kResourceTypeScript, 0), false); - if (script0->size() != meta.script0Size || g_sci->getGameObject().getOffset() != meta.gameObjectOffset) { - showScummVMDialog(_("This saved game was created with a different version of the game, unable to load it")); + // In SCI32 these checks are all in kCheckSaveGame32 + if (getSciVersion() < SCI_VERSION_2) { + if ((meta.version < MINIMUM_SAVEGAME_VERSION) || (meta.version > CURRENT_SAVEGAME_VERSION)) { + if (meta.version < MINIMUM_SAVEGAME_VERSION) { + showScummVMDialog(_("The format of this saved game is obsolete, unable to load it")); + } else { + Common::String msg = Common::String::format(_("Savegame version is %d, maximum supported is %0d"), meta.version, CURRENT_SAVEGAME_VERSION); + showScummVMDialog(msg); + } s->r_acc = TRUE_REG; // signal failure return; } + + if (meta.gameObjectOffset > 0 && meta.script0Size > 0) { + Resource *script0 = g_sci->getResMan()->findResource(ResourceId(kResourceTypeScript, 0), false); + if (script0->size() != meta.script0Size || g_sci->getGameObject().getOffset() != meta.gameObjectOffset) { + showScummVMDialog(_("This saved game was created with a different version of the game, unable to load it")); + + s->r_acc = TRUE_REG; // signal failure + return; + } + } } // We don't need the thumbnail here, so just read it and discard it |