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.
This commit is contained in:
Colin Snover 2017-09-14 20:42:42 -05:00
parent 88420970b7
commit 029eeeb803
6 changed files with 26 additions and 14 deletions

View file

@ -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

View file

@ -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);

View file

@ -226,6 +226,7 @@ void Kernel::mapSelectors() {
FIND_SELECTOR(scratch);
FIND_SELECTOR(num);
FIND_SELECTOR(reallyRestore);
FIND_SELECTOR(bookMark);
#endif
}

View file

@ -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
};

View file

@ -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

View file

@ -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