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:
parent
88420970b7
commit
029eeeb803
6 changed files with 26 additions and 14 deletions
|
@ -263,15 +263,8 @@ bool GuestAdditions::kGetEventHook() const {
|
||||||
// cause loading to fail if the save game contains a saved Robot state,
|
// 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
|
// because the Robot will try to restore itself into a game plane which does
|
||||||
// not exist yet
|
// not exist yet
|
||||||
if (g_sci->getGameId() == GID_LIGHTHOUSE) {
|
if (g_sci->getGameId() == GID_LIGHTHOUSE && _state->callInStack(g_sci->getGameObject(), SELECTOR(init))) {
|
||||||
Common::List<ExecStack>::const_iterator it;
|
return false;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1227,12 +1227,12 @@ reg_t kSaveGame32(EngineState *s, int argc, reg_t *argv) {
|
||||||
saveNo += kSaveIdShift;
|
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;
|
saveNo = kNewGameId;
|
||||||
}
|
} else if (g_sci->getGameId() == GID_QFG4) {
|
||||||
|
// Auto-save system used by QFG4
|
||||||
// Auto-save system used by QFG4
|
|
||||||
if (g_sci->getGameId() == GID_QFG4) {
|
|
||||||
reg_t autoSaveNameId;
|
reg_t autoSaveNameId;
|
||||||
SciArray &autoSaveName = *s->_segMan->allocateArray(kArrayTypeString, 0, &autoSaveNameId);
|
SciArray &autoSaveName = *s->_segMan->allocateArray(kArrayTypeString, 0, &autoSaveNameId);
|
||||||
MessageTuple autoSaveNameTuple(0, 0, 16, 1);
|
MessageTuple autoSaveNameTuple(0, 0, 16, 1);
|
||||||
|
|
|
@ -226,6 +226,7 @@ void Kernel::mapSelectors() {
|
||||||
FIND_SELECTOR(scratch);
|
FIND_SELECTOR(scratch);
|
||||||
FIND_SELECTOR(num);
|
FIND_SELECTOR(num);
|
||||||
FIND_SELECTOR(reallyRestore);
|
FIND_SELECTOR(reallyRestore);
|
||||||
|
FIND_SELECTOR(bookMark);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,7 @@ struct SelectorCache {
|
||||||
Selector scratch; // for Phant2 save/load patching
|
Selector scratch; // for Phant2 save/load patching
|
||||||
Selector num; // for Phant2 restore from launcher
|
Selector num; // for Phant2 restore from launcher
|
||||||
Selector reallyRestore; // for Phant2 restore from launcher
|
Selector reallyRestore; // for Phant2 restore from launcher
|
||||||
|
Selector bookMark; // for Phant2 auto-save
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -423,4 +423,16 @@ SciCallOrigin EngineState::getCurrentCallOrigin() const {
|
||||||
return reply;
|
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
|
} // End of namespace Sci
|
||||||
|
|
|
@ -224,6 +224,11 @@ public:
|
||||||
* Finds and returns the origin of the current call.
|
* Finds and returns the origin of the current call.
|
||||||
*/
|
*/
|
||||||
SciCallOrigin getCurrentCallOrigin() const;
|
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
|
} // End of namespace Sci
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue