diff options
-rw-r--r-- | engines/sci/detection.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kfile.cpp | 12 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 26 |
3 files changed, 33 insertions, 7 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index d3bbedef11..c313a5d237 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -371,7 +371,7 @@ bool SciMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD bool SciMetaEngine::hasFeature(MetaEngineFeature f) const { return (f == kSupportsListSaves) || - //(f == kSupportsLoadingDuringStartup) || + (f == kSupportsLoadingDuringStartup) || (f == kSupportsDeleteSave) || (f == kSavesSupportMetaInfo) || (f == kSavesSupportThumbnail) || diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 1b5b94589a..21674cc94f 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -583,15 +583,19 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { } reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { - Common::String game_id = s->_segMan->getString(argv[0]); + Common::String game_id = !argv[0].isNull() ? s->_segMan->getString(argv[0]) : ""; int savedir_nr = argv[1].toUint16(); debug(3, "kRestoreGame(%s,%d)", game_id.c_str(), savedir_nr); - Common::Array<SavegameDesc> saves; - listSavegames(saves); + if (!argv[0].isNull()) { + Common::Array<SavegameDesc> saves; + listSavegames(saves); - savedir_nr = saves[savedir_nr].id; + savedir_nr = saves[savedir_nr].id; + } else { + // Loading from GMM, no change necessary + } if (savedir_nr > -1) { Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 1b5998617a..b53f3e3aaf 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -25,6 +25,7 @@ #include "common/debug.h" #include "common/stack.h" +#include "common/config-manager.h" #include "sci/sci.h" #include "sci/console.h" @@ -549,6 +550,11 @@ void run_vm(EngineState *s, int restoring) { reg_t r_temp; // Temporary register StackPtr s_temp; // Temporary stack pointer int16 opparams[4]; // opcode parameters + bool loadFromGMM = ConfMan.hasKey("save_slot") ? true : false; + if (loadFromGMM) { + if (ConfMan.getInt("save_slot") < 0) + loadFromGMM = false; // already loaded + } scriptState.restAdjust = s->restAdjust; // &rest adjusts the parameter count by this value @@ -984,8 +990,24 @@ void run_vm(EngineState *s, int restoring) { //warning("callk %s", kfun.orig_name.c_str()); - // Call kernel function - s->r_acc = kfun.fun(s, argc, argv); + // TODO: SCI2/SCI2.1+ equivalent, once saving/loading works in SCI2/SCI2.1+ + if (loadFromGMM && opparams[0] == 0x8) { + // A game is being loaded from GMM, and kDisplay is called, all initialization has taken + // place (i.e. menus have been constructed etc). Therefore, inject a kRestoreGame call + // here, instead of the requested function + int saveSlot = ConfMan.getInt("save_slot"); + ConfMan.setInt("save_slot", -1); // invalidate slot + loadFromGMM = false; + + if (saveSlot < 0) + error("Requested to load invalid save slot"); // should never happen, really + + reg_t argv[2] = { NULL_REG, make_reg(0, saveSlot) }; // special GMM call (argv[0] is NULL) + kRestoreGame(s, 2, argv); + } else { + // Call kernel function + s->r_acc = kfun.fun(s, argc, argv); + } // Remove callk stack frame again s->_executionStack.pop_back(); |