diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/guest_additions.cpp | 49 | ||||
-rw-r--r-- | engines/sci/engine/guest_additions.h | 11 | ||||
-rw-r--r-- | engines/sci/engine/kernel_tables.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/selector.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/selector.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 1 |
6 files changed, 66 insertions, 1 deletions
diff --git a/engines/sci/engine/guest_additions.cpp b/engines/sci/engine/guest_additions.cpp index 6b9b98d83d..373a1e9c13 100644 --- a/engines/sci/engine/guest_additions.cpp +++ b/engines/sci/engine/guest_additions.cpp @@ -233,6 +233,8 @@ void GuestAdditions::instantiateScriptHook(Script &script, const bool ignoreDela script.getScriptNumber() == 64866) { patchGameSaveRestoreTorin(script); + } else if (g_sci->getGameId() == GID_PHANTASMAGORIA2 && script.getScriptNumber() == 64978) { + patchGameSaveRestorePhant2(script); } else if (script.getScriptNumber() == 64990) { // 64990 is the system script containing SRDialog. This script is used // by the main Game object, but it is not loaded immediately, so we wait @@ -412,7 +414,31 @@ void GuestAdditions::patchGameSaveRestoreTorin(Script &script) const { } } +void GuestAdditions::patchGameSaveRestorePhant2(Script &script) const { + const ObjMap &objects = script.getObjectMap(); + for (ObjMap::const_iterator it = objects.begin(); it != objects.end(); ++it) { + const Object &obj = it->_value; + + if (strncmp(_segMan->derefString(obj.getNameSelector()), "srGetGame", 9) != 0) { + continue; + } + + int methodIndex = obj.funcSelectorPosition(SELECTOR(init)); + if (methodIndex == -1) { + continue; + } + + byte *scriptData = const_cast<byte *>(script.getBuf(obj.getFunction(methodIndex).getOffset())); + memcpy(scriptData, SRDialogPatch, sizeof(SRDialogPatch)); + break; + } +} + reg_t GuestAdditions::kScummVMSaveLoad(EngineState *s, int argc, reg_t *argv) const { + if (g_sci->getGameId() == GID_PHANTASMAGORIA2) { + return promptSaveRestorePhant2(s, argc, argv); + } + if (g_sci->getGameId() == GID_LSL7 || g_sci->getGameId() == GID_TORIN) { return promptSaveRestoreTorin(s, argc, argv); } @@ -446,6 +472,29 @@ reg_t GuestAdditions::promptSaveRestoreTorin(EngineState *s, int argc, reg_t *ar return make_reg(0, saveNo != -1); } +reg_t GuestAdditions::promptSaveRestorePhant2(EngineState *s, int argc, reg_t *argv) const { + assert(argc == 2); + const bool isSave = argv[1].toSint16() == 0; + const int saveNo = runSaveRestore(isSave, argv[0], s->_delayedRestoreGameId); + + // Clear the highlighted state of the button so if the same control panel is + // opened again it does not appear to be opened to the save/load panels + reg_t button; + if (isSave) { + button = _segMan->findObjectByName("saveButton"); + } else { + button = _segMan->findObjectByName("loadButton"); + } + writeSelectorValue(_segMan, button, SELECTOR(cel), 0); + + // This causes the control panel to quit its internal event loop and hide + // itself + const reg_t controlPanel = s->variables[VAR_GLOBAL][kGlobalVarPhant2ControlPanel]; + writeSelector(_segMan, controlPanel, SELECTOR(scratch), TRUE_REG); + + return make_reg(0, saveNo); +} + int GuestAdditions::runSaveRestore(const bool isSave, reg_t outDescription, const int forcedSaveNo) const { int saveNo; Common::String descriptionString; diff --git a/engines/sci/engine/guest_additions.h b/engines/sci/engine/guest_additions.h index 657fa52318..eed1ee3154 100644 --- a/engines/sci/engine/guest_additions.h +++ b/engines/sci/engine/guest_additions.h @@ -188,6 +188,11 @@ private: void patchGameSaveRestoreTorin(Script &script) const; /** + * Patches the ScummVM save/load dialogue into Phant2. + */ + void patchGameSaveRestorePhant2(Script &script) const; + + /** * Prompts for a save game and returns it to game scripts using default * SRDialog game class semantics. */ @@ -200,6 +205,12 @@ private: reg_t promptSaveRestoreTorin(EngineState *s, int argc, reg_t *argv) const; /** + * Prompts for a save game and returns it to game scripts using Phant2's + * custom ControlPanel class semantics. + */ + reg_t promptSaveRestorePhant2(EngineState *s, int argc, reg_t *argv) const; + + /** * Prompts the user to save or load a game. * * @param isSave If true, the prompt is for saving. diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index bd3184a900..c65356470a 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -779,7 +779,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(Said), SIG_EVERYWHERE, "[r0]", NULL, NULL }, #ifdef ENABLE_SCI32 { "SaveGame", kSaveGame32, SIG_THRU_SCI21EARLY, SIGFOR_ALL, "ri[r0][r0]", NULL, NULL }, - { MAP_CALL(ScummVMSaveLoad), SIG_SCI32, SIGFOR_ALL, "([iro])([ro0])", NULL, NULL }, + { MAP_CALL(ScummVMSaveLoad), SIG_SCI32, SIGFOR_ALL, "([iro])([iro])", NULL, NULL }, #endif { MAP_CALL(SaveGame), SIG_SCI16, SIGFOR_ALL, "[r0]i[r0](r0)", NULL, NULL }, { MAP_CALL(ScriptID), SIG_EVERYWHERE, "[io](i)", NULL, NULL }, diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index 889590fc8b..e99f734272 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -222,6 +222,8 @@ void Kernel::mapSelectors() { FIND_SELECTOR(move); FIND_SELECTOR(eachElementDo); FIND_SELECTOR(physicalBar); + FIND_SELECTOR(init); + FIND_SELECTOR(scratch); #endif } diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h index 850a5dc0ec..d26a0d740f 100644 --- a/engines/sci/engine/selector.h +++ b/engines/sci/engine/selector.h @@ -179,6 +179,8 @@ struct SelectorCache { Selector move; // for Phant2 volume sync Selector eachElementDo; // for Phant2 volume sync Selector physicalBar; // for Phant2 volume sync + Selector init; // for Phant2 save/load patching + Selector scratch; // for Phant2 save/load patching #endif }; diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index e92929e7ea..a8ac7b180f 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -170,6 +170,7 @@ enum GlobalVar { // Phant2 labels its volume slider as "music volume" but it is actually // a master volume that affects both music *and* sound effects kGlobalVarPhant2MasterVolume = 236, // 0 to 127 + kGlobalVarPhant2ControlPanel = 250, kGlobalVarShivers1Score = 349 }; |