diff options
author | Colin Snover | 2017-09-14 20:42:42 -0500 |
---|---|---|
committer | Colin Snover | 2017-09-14 20:45:02 -0500 |
commit | 029eeeb803eaef861e74765f69e2fabddf0ec7a7 (patch) | |
tree | 25f5e175f62be21c1ee407bdd8f054e0fd460729 /engines/sci | |
parent | 88420970b78cd8f740c3251d7d6c028c06ef6fc1 (diff) | |
download | scummvm-rg350-029eeeb803eaef861e74765f69e2fabddf0ec7a7.tar.gz scummvm-rg350-029eeeb803eaef861e74765f69e2fabddf0ec7a7.tar.bz2 scummvm-rg350-029eeeb803eaef861e74765f69e2fabddf0ec7a7.zip |
SCI32: Fix Phant2 "auto-save"
The game has a feature where it will automatically create a save
game when you quit the game through the in-game control panel (or
when you die, for some reason).
Unfortunately, due to bad programming, this automatic save would
just overwrite whatever was in save slot 1 (slot 0 in the original
interpreter). Find this attempt to auto-save the game and redirect
it to the auto-save slot. This might not be totally correct, but
it is at least better than destroying a save game.
Fixes Trac#10201.
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/engine/guest_additions.cpp | 11 | ||||
-rw-r--r-- | engines/sci/engine/kfile.cpp | 10 | ||||
-rw-r--r-- | engines/sci/engine/selector.cpp | 1 | ||||
-rw-r--r-- | engines/sci/engine/selector.h | 1 | ||||
-rw-r--r-- | engines/sci/engine/state.cpp | 12 | ||||
-rw-r--r-- | engines/sci/engine/state.h | 5 |
6 files changed, 26 insertions, 14 deletions
diff --git a/engines/sci/engine/guest_additions.cpp b/engines/sci/engine/guest_additions.cpp index 90d797aee9..e74a5d6e3f 100644 --- a/engines/sci/engine/guest_additions.cpp +++ b/engines/sci/engine/guest_additions.cpp @@ -263,15 +263,8 @@ bool GuestAdditions::kGetEventHook() const { // cause loading to fail if the save game contains a saved Robot state, // because the Robot will try to restore itself into a game plane which does // not exist yet - if (g_sci->getGameId() == GID_LIGHTHOUSE) { - Common::List<ExecStack>::const_iterator it; - for (it = _state->_executionStack.begin(); it != _state->_executionStack.end(); ++it) { - const ExecStack &call = *it; - const reg_t gameObject = g_sci->getGameObject(); - if (call.sendp == gameObject && call.debugSelector == SELECTOR(init)) { - return false; - } - } + if (g_sci->getGameId() == GID_LIGHTHOUSE && _state->callInStack(g_sci->getGameObject(), SELECTOR(init))) { + return false; } #endif diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 79e1894532..3b8420849a 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -1227,12 +1227,12 @@ reg_t kSaveGame32(EngineState *s, int argc, reg_t *argv) { saveNo += kSaveIdShift; } - if (g_sci->getGameId() == GID_LIGHTHOUSE && gameName == "rst") { + if (g_sci->getGameId() == GID_PHANTASMAGORIA2 && s->callInStack(g_sci->getGameObject(), SELECTOR(bookMark))) { + saveNo = kAutoSaveId; + } else if (g_sci->getGameId() == GID_LIGHTHOUSE && gameName == "rst") { saveNo = kNewGameId; - } - - // Auto-save system used by QFG4 - if (g_sci->getGameId() == GID_QFG4) { + } else if (g_sci->getGameId() == GID_QFG4) { + // Auto-save system used by QFG4 reg_t autoSaveNameId; SciArray &autoSaveName = *s->_segMan->allocateArray(kArrayTypeString, 0, &autoSaveNameId); MessageTuple autoSaveNameTuple(0, 0, 16, 1); diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index 971802affb..d310b0fafd 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -226,6 +226,7 @@ void Kernel::mapSelectors() { FIND_SELECTOR(scratch); FIND_SELECTOR(num); FIND_SELECTOR(reallyRestore); + FIND_SELECTOR(bookMark); #endif } diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h index e2afa74c7a..977411429a 100644 --- a/engines/sci/engine/selector.h +++ b/engines/sci/engine/selector.h @@ -183,6 +183,7 @@ struct SelectorCache { Selector scratch; // for Phant2 save/load patching Selector num; // for Phant2 restore from launcher Selector reallyRestore; // for Phant2 restore from launcher + Selector bookMark; // for Phant2 auto-save #endif }; diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 7e7be9923c..731f6b7e07 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -423,4 +423,16 @@ SciCallOrigin EngineState::getCurrentCallOrigin() const { return reply; } +bool EngineState::callInStack(const reg_t object, const Selector selector) const { + Common::List<ExecStack>::const_iterator it; + for (it = _executionStack.begin(); it != _executionStack.end(); ++it) { + const ExecStack &call = *it; + if (call.sendp == object && call.debugSelector == selector) { + return true; + } + } + + return false; +} + } // End of namespace Sci diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 57839ab04e..b02ace8aaf 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -224,6 +224,11 @@ public: * Finds and returns the origin of the current call. */ SciCallOrigin getCurrentCallOrigin() const; + + /** + * Determines whether the given object method is in the current stack. + */ + bool callInStack(const reg_t object, const Selector selector) const; }; } // End of namespace Sci |