[Scummvm-cvs-logs] scummvm master -> c7bfbc31e2f23f899dcf884ef9a9ba3a7bd0ebe8

bluegr md5 at scummvm.org
Sun Feb 27 23:19:39 CET 2011


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
4d33923436 SCI: Cleanup of the save/load dialog patching code and the lofs type detection code
c7bfbc31e2 SCI: Fixed bug #3106107 - "QFG3: Crash when saving outside palace"


Commit: 4d3392343675faec3b2427a7cd2d19ddce69884b
    https://github.com/scummvm/scummvm/commit/4d3392343675faec3b2427a7cd2d19ddce69884b
Author: md5 (md5 at scummvm.org)
Date: 2011-02-27T14:15:47-08:00

Commit Message:
SCI: Cleanup of the save/load dialog patching code and the lofs type detection code

Changed paths:
    engines/sci/engine/features.cpp
    engines/sci/sci.cpp
    engines/sci/sci.h



diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp
index 206624f..964097f 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 b460b06..4155fd2 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 72fbe0c..aea5712 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;


Commit: c7bfbc31e2f23f899dcf884ef9a9ba3a7bd0ebe8
    https://github.com/scummvm/scummvm/commit/c7bfbc31e2f23f899dcf884ef9a9ba3a7bd0ebe8
Author: md5 (md5 at scummvm.org)
Date: 2011-02-27T14:18:23-08:00

Commit Message:
SCI: Fixed bug #3106107 - "QFG3: Crash when saving outside palace"

Ignore requests to alter a song's hold value while it's being faded, and reset
a song's hold value when fading starts. This ensures that the song will actually
stop when fading is done and won't keep looping forever.

Changed paths:
    engines/sci/sound/soundcmd.cpp



diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 1e6d0ae..33be8f4 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -318,6 +318,9 @@ reg_t SoundCommandParser::kDoSoundFade(int argc, reg_t *argv, reg_t acc) {
 
 	int volume = musicSlot->volume;
 
+	// Reset hold so that the song can actually stop
+	musicSlot->hold = -1;
+
 	// If sound is not playing currently, set signal directly
 	if (musicSlot->status != kSoundPlaying) {
 		debugC(kDebugLevelSound, "kDoSound(fade): %04x:%04x fading requested, but sound is currently not playing", PRINT_REG(obj));
@@ -531,6 +534,12 @@ reg_t SoundCommandParser::kDoSoundSetHold(int argc, reg_t *argv, reg_t acc) {
 		return acc;
 	}
 
+	// Is the song being faded? If yes, don't set a hold value, otherwise the
+	// song will never actually stop. Fixes bug #3106107.
+	if (musicSlot->fadeStep && argv[1].toSint16() != -1) {
+		warning("kDoSound(setHold): Attempt to set a hold value (%d) to a song being faded, ignoring", argv[1].toSint16());
+		return acc;
+	}
 	// Set the special hold marker ID where the song should be looped at.
 	musicSlot->hold = argv[1].toSint16();
 	return acc;






More information about the Scummvm-git-logs mailing list