From 048ceb73d36e4729cb9c8dde292043c32a554234 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sun, 27 Jun 2010 23:20:08 +0000 Subject: SCI: Removed the hack for loading games from the launcher from run_vm(). This is now done on startup. This should fix loading from the launcher for LSL6 svn-id: r50406 --- engines/sci/engine/selector.cpp | 1 + engines/sci/engine/selector.h | 2 ++ engines/sci/engine/state.cpp | 14 +++++++----- engines/sci/engine/state.h | 2 -- engines/sci/engine/vm.cpp | 50 +++++++++++------------------------------ engines/sci/sci.cpp | 27 +++++++++++++++++++--- 6 files changed, 48 insertions(+), 48 deletions(-) diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index 00480743cc..155aa83883 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -161,6 +161,7 @@ void Kernel::mapSelectors() { FIND_SELECTOR(maxScale); FIND_SELECTOR(vanishingX); FIND_SELECTOR(vanishingY); + FIND_SELECTOR(init); FIND_SELECTOR(iconIndex); #ifdef ENABLE_SCI32 diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h index acb7912d8d..1fff7caac8 100644 --- a/engines/sci/engine/selector.h +++ b/engines/sci/engine/selector.h @@ -103,6 +103,8 @@ struct SelectorCache { // perform Selector moveDone; ///< used for DoBresen + Selector init; ///< Used for menu initialization when loading from the launcher + // SCI1 selectors which have been moved a bit in SCI1.1, but otherwise static Selector cantBeHere; ///< Checks for movement avoidance in SCI1+. Replaces canBeHere Selector topString; ///< SCI1 scroll lists use this instead of lsTop diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 4b99097476..9bd8f380a1 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -145,12 +145,14 @@ void EngineState::setRoomNumber(uint16 roomNumber) { } void EngineState::shrinkStackToBase() { - uint size = executionStackBase + 1; - assert(_executionStack.size() >= size); - Common::List::iterator iter = _executionStack.begin(); - for (uint i = 0; i < size; ++i) - ++iter; - _executionStack.erase(iter, _executionStack.end()); + if (_executionStack.size() > 0) { + uint size = executionStackBase + 1; + assert(_executionStack.size() >= size); + Common::List::iterator iter = _executionStack.begin(); + for (uint i = 0; i < size; ++i) + ++iter; + _executionStack.erase(iter, _executionStack.end()); + } } static kLanguage charToLanguage(const char c) { diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index b47b739007..2fcad5b2e4 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -152,8 +152,6 @@ public: SegmentId variablesSegment[4]; ///< Same as above, contains segment IDs int variablesMax[4]; ///< Max. values for all variables - int loadFromLauncher; - AbortGameState abortScriptProcessing; bool gameWasRestarted; diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index a69a142e10..d819db3d08 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -758,48 +758,24 @@ static void callKernelFunc(EngineState *s, int kernelFuncNr, int argc) { xstack->selector = kernelFuncNr; xstack->type = EXEC_STACK_TYPE_KERNEL; - //warning("callk %s", kernelFunc.origName.c_str()); - - // TODO: SCI2.1 equivalent - if (s->loadFromLauncher >= 0 && ( - (kernelFuncNr == 0x8 && getSciVersion() <= SCI_VERSION_1_1) || // DrawPic - (kernelFuncNr == 0x3d && getSciVersion() == SCI_VERSION_2) // GetSaveDir - //(kernelFuncNum == 0x28 && getSciVersion() == SCI_VERSION_2_1) // AddPlane - )) { - - // A game is being loaded from the launcher, and the game is about to draw something on - // screen, hence all initialization has taken place (i.e. menus have been constructed etc). - // Therefore, inject a kRestoreGame call here, instead of the requested function. - // The restore call is injected here mainly for games which have a menu, as the menu is - // constructed when the game starts and is not reconstructed when a saved game is loaded. - int saveSlot = s->loadFromLauncher; - s->loadFromLauncher = -1; // invalidate slot, so that we don't load again - - if (saveSlot < 0) - error("Requested to load invalid save slot"); // should never happen, really - - reg_t restoreArgv[2] = { NULL_REG, make_reg(0, saveSlot) }; // special call (argv[0] is NULL) - kRestoreGame(s, 2, restoreArgv); - } else { - // Call kernel function - s->r_acc = kernelFunc.func(s, argc, argv); + // Call kernel function + s->r_acc = kernelFunc.func(s, argc, argv); #if 0 - // Used for debugging - Common::String debugMsg = kernelFunc.origName + - Common::String::printf("[0x%x]", kernelFuncNum) + - Common::String::printf(", %d params: ", argc) + - " ("; + // Used for debugging + Common::String debugMsg = kernelFunc.origName + + Common::String::printf("[0x%x]", kernelFuncNum) + + Common::String::printf(", %d params: ", argc) + + " ("; - for (int i = 0; i < argc; i++) { - debugMsg += Common::String::printf("%04x:%04x", PRINT_REG(argv[i])); - debugMsg += (i == argc - 1 ? ")" : ", "); - } + for (int i = 0; i < argc; i++) { + debugMsg += Common::String::printf("%04x:%04x", PRINT_REG(argv[i])); + debugMsg += (i == argc - 1 ? ")" : ", "); + } - debugMsg += ", result: " + Common::String::printf("%04x:%04x", PRINT_REG(s->r_acc)); - debug("%s", debugMsg.c_str()); + debugMsg += ", result: " + Common::String::printf("%04x:%04x", PRINT_REG(s->r_acc)); + debug("%s", debugMsg.c_str()); #endif - } // Remove callk stack frame again, if there's still an execution stack if (s->_executionStack.begin() != s->_executionStack.end()) diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 8a41d74b7f..9a80420a12 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -306,9 +306,30 @@ Common::Error SciEngine::run() { // Check whether loading a savestate was requested if (ConfMan.hasKey("save_slot")) { - _gamestate->loadFromLauncher = ConfMan.getInt("save_slot"); - } else { - _gamestate->loadFromLauncher = -1; + reg_t restoreArgv[2] = { NULL_REG, make_reg(0, ConfMan.getInt("save_slot")) }; // special call (argv[0] is NULL) + kRestoreGame(_gamestate, 2, restoreArgv); + + // Initialize the game menu, if there is one. + // This is not done when loading, so we must do it manually. + reg_t menuBarObj = _gamestate->_segMan->findObjectByName("MenuBar"); + if (menuBarObj.isNull()) + menuBarObj = _gamestate->_segMan->findObjectByName("menuBar"); // LSL6 + if (!menuBarObj.isNull()) { + // Game menus are found in SCI0-SCI01 games (but not in demos), which had a selector vocabulary, + // thus the following code should always work (at least theoretically). + // The init selector is being moved around in all games, thus adding it to the list of static + // selectors can be tricky. An alternative way would be to call the first method of the + // MenuBar object (which is init), but this will require refactoring. + if (_kernel->_selectorCache.init != -1) { + // Reset abortScriptProcessing before initializing the game menu, so that the + // VM call performed by invokeSelector will actually run. + _gamestate->abortScriptProcessing = kAbortNone; + invokeSelector(_gamestate, menuBarObj, SELECTOR(init), 0, _gamestate->stack_base); + _gamestate->abortScriptProcessing = kAbortLoadGame; + } else { + warning("Game has a menu but not a selector vocabulary, skipping menu initialization"); + } + } } runGame(); -- cgit v1.2.3