diff options
| -rw-r--r-- | engines/sci/engine/selector.cpp | 1 | ||||
| -rw-r--r-- | engines/sci/engine/selector.h | 2 | ||||
| -rw-r--r-- | engines/sci/engine/state.cpp | 14 | ||||
| -rw-r--r-- | engines/sci/engine/state.h | 2 | ||||
| -rw-r--r-- | engines/sci/engine/vm.cpp | 50 | ||||
| -rw-r--r-- | 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<ExecStack>::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<ExecStack>::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();  | 
