diff options
| author | md5 | 2011-02-28 00:15:47 +0200 | 
|---|---|---|
| committer | md5 | 2011-02-28 00:15:47 +0200 | 
| commit | 4d3392343675faec3b2427a7cd2d19ddce69884b (patch) | |
| tree | 8c2aeab5e0a547bac014b1047bb5e62864bb0f1b | |
| parent | d90c7a831457ee01f501d564e628fa88374f0419 (diff) | |
| download | scummvm-rg350-4d3392343675faec3b2427a7cd2d19ddce69884b.tar.gz scummvm-rg350-4d3392343675faec3b2427a7cd2d19ddce69884b.tar.bz2 scummvm-rg350-4d3392343675faec3b2427a7cd2d19ddce69884b.zip | |
SCI: Cleanup of the save/load dialog patching code and the lofs type detection code
| -rw-r--r-- | engines/sci/engine/features.cpp | 20 | ||||
| -rw-r--r-- | engines/sci/sci.cpp | 81 | ||||
| -rw-r--r-- | engines/sci/sci.h | 2 | 
3 files changed, 35 insertions, 68 deletions
| diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp index 206624f87e..964097f57d 100644 --- a/engines/sci/engine/features.cpp +++ b/engines/sci/engine/features.cpp @@ -285,20 +285,16 @@ SciVersion GameFeatures::detectLofsType() {  		}  		// Find a function of the "Game" object (which is the game super class) which invokes lofsa/lofss -		reg_t gameSuperClass = g_sci->getGameSuperClassAddress(); +		const Object *gameObject = _segMan->getObject(g_sci->getGameObject()); +		const Object *gameSuperObject = _segMan->getObject(gameObject->getSuperClassSelector());  		bool found = false; -		if (!gameSuperClass.isNull()) { -			Common::String gameSuperClassName = _segMan->getObjectName(gameSuperClass); -			const Object *gameSuperObject = _segMan->getObject(gameSuperClass); +		if (gameSuperObject) { +			Common::String gameSuperClassName = _segMan->getObjectName(gameObject->getSuperClassSelector()); -			if (gameSuperObject) { -				for (uint m = 0; m < gameSuperObject->getMethodCount(); m++) { -					found = autoDetectLofsType(gameSuperClassName, m); -					if (found) -						break; -				} -			} else { -				warning("detectLofsType(): Could not get superclass object"); +			for (uint m = 0; m < gameSuperObject->getMethodCount(); m++) { +				found = autoDetectLofsType(gameSuperClassName, m); +				if (found) +					break;  			}  		} else {  			warning("detectLofsType(): Could not find superclass of game object"); diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index b460b06662..4155fd2a1f 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -213,7 +213,6 @@ Common::Error SciEngine::run() {  	// Add the after market GM patches for the specified game, if they exist  	_resMan->addNewGMPatch(_gameId);  	_gameObjectAddress = _resMan->findGameObject(); -	_gameSuperClassAddress = NULL_REG;  	SegManager *segMan = new SegManager(_resMan); @@ -250,7 +249,6 @@ Common::Error SciEngine::run() {  		warning("Could not get game object, aborting...");  		return Common::kUnknownError;  	} -	_gameSuperClassAddress = gameObject->getSuperClassSelector();  	script_adjust_opcode_formats(); @@ -441,19 +439,24 @@ static byte patchGameRestoreSaveSci2[] = {  	0x48,              // ret  }; +static void patchGameSaveRestoreCode(SegManager *segMan, reg_t methodAddress, byte id) { +	Script *script = segMan->getScript(methodAddress.segment); +	byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.offset)); +	if (getSciVersion() <= SCI_VERSION_1_1) +		memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave)); +	else if (getSciVersion() == SCI_VERSION_2) +		memcpy(patchPtr, patchGameRestoreSaveSci2, sizeof(patchGameRestoreSaveSci2)); +	// TODO: SCI21/SCI3 +	patchPtr[8] = id; +} +  void SciEngine::patchGameSaveRestore() {  	SegManager *segMan = _gamestate->_segMan;  	const Object *gameObject = segMan->getObject(_gameObjectAddress); -	const uint16 gameMethodCount = gameObject->getMethodCount(); -	const Object *gameSuperObject = segMan->getObject(_gameSuperClassAddress); +	const Object *gameSuperObject = segMan->getObject(gameObject->getSuperClassSelector());  	if (!gameSuperObject)  		gameSuperObject = gameObject;	// happens in KQ5CD, when loading saved games before r54510 -	const uint16 gameSuperMethodCount = gameSuperObject->getMethodCount(); -	reg_t methodAddress; -	const uint16 kernelCount = _kernel->getKernelNamesSize(); -	const byte *scriptRestorePtr = NULL;  	byte kernelIdRestore = 0; -	const byte *scriptSavePtr = NULL;  	byte kernelIdSave = 0;  	// This feature is currently not supported in SCI21 or SCI3 @@ -473,7 +476,8 @@ void SciEngine::patchGameSaveRestore() {  	if (ConfMan.getBool("sci_originalsaveload"))  		return; -	for (uint16 kernelNr = 0; kernelNr < kernelCount; kernelNr++) { +	uint16 kernelNamesSize = _kernel->getKernelNamesSize(); +	for (uint16 kernelNr = 0; kernelNr < kernelNamesSize; kernelNr++) {  		Common::String kernelName = _kernel->getKernelName(kernelNr);  		if (kernelName == "RestoreGame")  			kernelIdRestore = kernelNr; @@ -481,61 +485,30 @@ void SciEngine::patchGameSaveRestore() {  			kernelIdSave = kernelNr;  	} -	// Search for gameobject-superclass ::restore -	for (uint16 methodNr = 0; methodNr < gameSuperMethodCount; methodNr++) { +	// Search for gameobject superclass ::restore +	uint16 gameSuperObjectMethodCount = gameSuperObject->getMethodCount(); +	for (uint16 methodNr = 0; methodNr < gameSuperObjectMethodCount; methodNr++) {  		uint16 selectorId = gameSuperObject->getFuncSelector(methodNr);  		Common::String methodName = _kernel->getSelectorName(selectorId); -		if (methodName == "restore") { -			methodAddress = gameSuperObject->getFunction(methodNr); -			Script *script = segMan->getScript(methodAddress.segment); -			scriptRestorePtr = script->getBuf(methodAddress.offset); -		} -		if (methodName == "save") { -			methodAddress = gameSuperObject->getFunction(methodNr); -			Script *script = segMan->getScript(methodAddress.segment); -			scriptSavePtr = script->getBuf(methodAddress.offset); +		if (methodName == "restore") +			patchGameSaveRestoreCode(segMan, gameSuperObject->getFunction(methodNr), kernelIdRestore); +		else if (methodName == "save") { +			if (_gameId != GID_FAIRYTALES)	// Fairy Tales saves automatically without a dialog +				patchGameSaveRestoreCode(segMan, gameSuperObject->getFunction(methodNr), kernelIdSave);  		}  	} -	// Search for gameobject ::save, if there is one patch that one instead -	for (uint16 methodNr = 0; methodNr < gameMethodCount; methodNr++) { +	// Search for gameobject ::save, if there is one patch that one too +	uint16 gameObjectMethodCount = gameObject->getMethodCount(); +	for (uint16 methodNr = 0; methodNr < gameObjectMethodCount; methodNr++) {  		uint16 selectorId = gameObject->getFuncSelector(methodNr);  		Common::String methodName = _kernel->getSelectorName(selectorId);  		if (methodName == "save") { -			methodAddress = gameObject->getFunction(methodNr); -			Script *script = segMan->getScript(methodAddress.segment); -			scriptSavePtr = script->getBuf(methodAddress.offset); +			if (_gameId != GID_FAIRYTALES)	// Fairy Tales saves automatically without a dialog +				patchGameSaveRestoreCode(segMan, gameObject->getFunction(methodNr), kernelIdSave);  			break;  		}  	} - -	switch (_gameId) { -	case GID_FAIRYTALES: // fairy tales automatically saves w/o dialog -		scriptSavePtr = NULL; -	default: -		break; -	} - -	if (scriptRestorePtr) { -		// Now patch in our code -		byte *patchPtr = const_cast<byte *>(scriptRestorePtr); -		if (getSciVersion() <= SCI_VERSION_1_1) -			memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave)); -		else if (getSciVersion() == SCI_VERSION_2) -			memcpy(patchPtr, patchGameRestoreSaveSci2, sizeof(patchGameRestoreSaveSci2)); -		// TODO: SCI21/SCI3 -		patchPtr[8] = kernelIdRestore; -	} -	if (scriptSavePtr) { -		// Now patch in our code -		byte *patchPtr = const_cast<byte *>(scriptSavePtr); -		if (getSciVersion() <= SCI_VERSION_1_1) -			memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave)); -		else if (getSciVersion() == SCI_VERSION_2) -			memcpy(patchPtr, patchGameRestoreSaveSci2, sizeof(patchGameRestoreSaveSci2)); -		// TODO: SCI21/SCI3 -		patchPtr[8] = kernelIdSave; -	}  }  bool SciEngine::initGame() { diff --git a/engines/sci/sci.h b/engines/sci/sci.h index 72fbe0c71f..aea5712ace 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -246,7 +246,6 @@ public:  	inline Vocabulary *getVocabulary() const { return _vocabulary; }  	inline EventManager *getEventManager() const { return _eventMan; }  	inline reg_t getGameObject() const { return _gameObjectAddress; } -	inline reg_t getGameSuperClassAddress() const { return _gameSuperClassAddress; }  	Common::RandomSource &getRNG() { return _rng; } @@ -375,7 +374,6 @@ private:  	int16 _vocabularyLanguage;  	EventManager *_eventMan;  	reg_t _gameObjectAddress; /**< Pointer to the game object */ -	reg_t _gameSuperClassAddress; // Address of the super class of the game object  	Console *_console;  	Common::RandomSource _rng;  	Common::MacResManager _macExecutable; | 
