diff options
-rw-r--r-- | engines/sci/detection.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/kevent.cpp | 14 | ||||
-rw-r--r-- | engines/sci/engine/kgraphics.cpp | 7 | ||||
-rw-r--r-- | engines/sci/engine/kvideo.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 17 | ||||
-rw-r--r-- | engines/sci/engine/savegame.h | 4 | ||||
-rw-r--r-- | engines/sci/engine/state.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/state.h | 4 | ||||
-rw-r--r-- | engines/sci/graphics/portrait.cpp | 3 |
9 files changed, 51 insertions, 8 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index e572e8ec7f..604aa476a2 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -791,6 +791,10 @@ void SciMetaEngine::removeSaveState(const char *target, int slot) const { } Common::Error SciEngine::loadGameState(int slot) { + _gamestate->_delayedRestoreGameId = slot; + _gamestate->_delayedRestoreGame = true; + return Common::kNoError; + Common::String fileName = Common::String::format("%s.%03d", _targetName.c_str(), slot); Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); Common::SeekableReadStream *in = saveFileMan->openForLoading(fileName); diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index dfa29bd047..8e16e0a07a 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -24,9 +24,10 @@ #include "sci/sci.h" #include "sci/engine/features.h" -#include "sci/engine/state.h" -#include "sci/engine/selector.h" #include "sci/engine/kernel.h" +#include "sci/engine/savegame.h" +#include "sci/engine/selector.h" +#include "sci/engine/state.h" #include "sci/console.h" #include "sci/debug.h" // for g_debug_simulated_key #include "sci/event.h" @@ -71,13 +72,14 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) { g_debug_simulated_key = 0; return make_reg(0, 1); } - + curEvent = g_sci->getEventManager()->getSciEvent(mask); - // Aborted during getSciEvent (e.g., due to loading a game from the - // ScummVM menu), so return immediately - if (s->abortScriptProcessing) + if (s->_delayedRestoreGame) { + // delayed restore game from ScummVM menu got triggered + gamestate_delayedrestore(s); return NULL_REG; + } // For a real event we use its associated mouse position mousePos = curEvent.mousePos; diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 7d24dd861f..8b790e6a58 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -32,6 +32,7 @@ #include "sci/event.h" #include "sci/resource.h" #include "sci/engine/features.h" +#include "sci/engine/savegame.h" #include "sci/engine/state.h" #include "sci/engine/selector.h" #include "sci/engine/kernel.h" @@ -400,6 +401,12 @@ reg_t kWait(EngineState *s, int argc, reg_t *argv) { s->wait(sleep_time); + if (s->_delayedRestoreGame) { + // delayed restore game from ScummVM menu got triggered + gamestate_delayedrestore(s); + return NULL_REG; + } + return s->r_acc; } diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp index 319469cb08..f925111fc9 100644 --- a/engines/sci/engine/kvideo.cpp +++ b/engines/sci/engine/kvideo.cpp @@ -123,6 +123,8 @@ void playVideo(Video::VideoDecoder *videoDecoder, VideoState videoState) { if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP) skipVideo = true; } + if (g_sci->getEngineState()->_delayedRestoreGame) + skipVideo = true; g_system->delayMillis(10); } diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index d146cba204..d89170ab22 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -20,6 +20,7 @@ * */ +#include "common/savefile.h" #include "common/stream.h" #include "common/system.h" #include "common/func.h" @@ -872,6 +873,22 @@ bool gamestate_save(EngineState *s, Common::WriteStream *fh, const Common::Strin extern void showScummVMDialog(const Common::String &message); +void gamestate_delayedrestore(EngineState *s) { + Common::String fileName = g_sci->getSavegameName(s->_delayedRestoreGameId); + Common::SeekableReadStream *in = g_sci->getSaveFileManager()->openForLoading(fileName); + + if (in) { + // found a savegame file + gamestate_restore(s, in); + delete in; + if (s->r_acc != make_reg(0, 1)) { + return; + } + } + + error("Restoring gamestate '%s' failed", fileName.c_str()); +} + void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { SavegameMetadata meta; diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h index 7f482ed0a1..5512b90fa8 100644 --- a/engines/sci/engine/savegame.h +++ b/engines/sci/engine/savegame.h @@ -74,7 +74,6 @@ struct SavegameMetadata { uint16 script0Size; }; - /** * Saves a game state to the hard disk in a portable way. * @param s The state to save @@ -84,6 +83,9 @@ struct SavegameMetadata { */ bool gamestate_save(EngineState *s, Common::WriteStream *save, const Common::String &savename, const Common::String &version); +// does a delayed saved game restore, used by ScummVM game menu - see detection.cpp / SciEngine::loadGameState() +void gamestate_delayedrestore(EngineState *s); + /** * Restores a game state from a directory. * @param s An older state from the same game diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 527c8f0ae0..417d98e2e2 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -92,6 +92,10 @@ void EngineState::reset(bool isRestoring) { abortScriptProcessing = kAbortNone; } + // reset delayed restore game functionality + _delayedRestoreGame = false; + _delayedRestoreGameId = 0; + executionStackBase = 0; _executionStackPosChanged = false; stack_base = 0; diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index ecc8cb7dfe..e7499e66c9 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -131,6 +131,10 @@ public: VirtualIndexFile *_virtualIndexFile; #endif + // see detection.cpp / SciEngine::loadGameState() + bool _delayedRestoreGame; // boolean, that triggers delayed restore (triggered by ScummVM menu) + int _delayedRestoreGameId; // the saved game id, that it supposed to get restored (triggered by ScummVM menu) + uint _chosenQfGImportItem; // Remembers the item selected in QfG import rooms bool _cursorWorkaroundActive; // Refer to GfxCursor::setPosition() diff --git a/engines/sci/graphics/portrait.cpp b/engines/sci/graphics/portrait.cpp index 3311f47022..cb425f3be9 100644 --- a/engines/sci/graphics/portrait.cpp +++ b/engines/sci/graphics/portrait.cpp @@ -317,7 +317,8 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint curEvent = _event->getSciEvent(SCI_EVENT_ANY); if (curEvent.type == SCI_EVENT_MOUSE_PRESS || (curEvent.type == SCI_EVENT_KEYBOARD && curEvent.data == SCI_KEY_ESC) || - g_sci->getEngineState()->abortScriptProcessing == kAbortQuitGame) + g_sci->getEngineState()->abortScriptProcessing == kAbortQuitGame || + g_sci->getEngineState()->_delayedRestoreGame) userAbort = true; curPosition = _audio->getAudioPosition(); } while ((curPosition != -1) && (curPosition < timerPosition) && (!userAbort)); |