aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
authorColin Snover2017-09-14 20:42:42 -0500
committerColin Snover2017-09-14 20:45:02 -0500
commit029eeeb803eaef861e74765f69e2fabddf0ec7a7 (patch)
tree25f5e175f62be21c1ee407bdd8f054e0fd460729 /engines/sci/engine
parent88420970b78cd8f740c3251d7d6c028c06ef6fc1 (diff)
downloadscummvm-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/engine')
-rw-r--r--engines/sci/engine/guest_additions.cpp11
-rw-r--r--engines/sci/engine/kfile.cpp10
-rw-r--r--engines/sci/engine/selector.cpp1
-rw-r--r--engines/sci/engine/selector.h1
-rw-r--r--engines/sci/engine/state.cpp12
-rw-r--r--engines/sci/engine/state.h5
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