[Scummvm-git-logs] scummvm master -> efddaf84ebc138cad41f7f13f3cc6545b8954940

bgK bastien.bouclet at gmail.com
Fri Aug 11 19:06:25 CEST 2017


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:
ee588a8c33 MOHAWK: Riven: Patch an invalid card change when entering Gehn's office
efddaf84eb MOHAWK: Riven: b_Data1.mhk is not required to play the CD version


Commit: ee588a8c33b3f75c9ee64ca28ef5010e292b2458
    https://github.com/scummvm/scummvm/commit/ee588a8c33b3f75c9ee64ca28ef5010e292b2458
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-08-11T19:05:55+02:00

Commit Message:
MOHAWK: Riven: Patch an invalid card change when entering Gehn's office

Fixes #10118.

Changed paths:
    engines/mohawk/riven_card.cpp
    engines/mohawk/riven_scripts.cpp
    engines/mohawk/riven_scripts.h


diff --git a/engines/mohawk/riven_card.cpp b/engines/mohawk/riven_card.cpp
index 3aab79d..feea22a 100644
--- a/engines/mohawk/riven_card.cpp
+++ b/engines/mohawk/riven_card.cpp
@@ -130,13 +130,7 @@ void RivenCard::applyPatches(uint16 id) {
 				forwardEnabled.index
 		};
 
-		// Script data is expected to be in big endian
-		for (uint i = 0; i < ARRAYSIZE(patchData); i++) {
-			patchData[i] = TO_BE_16(patchData[i]);
-		}
-
-		Common::MemoryReadStream patchStream((const byte *)(patchData), ARRAYSIZE(patchData) * sizeof(uint16));
-		RivenScriptPtr patchScript = _vm->_scriptMan->readScript(&patchStream);
+		RivenScriptPtr patchScript = _vm->_scriptMan->readScriptFromData(patchData, ARRAYSIZE(patchData));
 
 		// Append the patch to the existing script
 		RivenScriptPtr loadScript = getScript(kCardLoadScript);
@@ -145,6 +139,111 @@ void RivenCard::applyPatches(uint16 id) {
 		debugC(kRivenDebugPatches, "Applied fix always enabled forward hotspot in card %x", globalId);
 	}
 
+	// In Gehn's office, after having encountered him once before and coming back
+	// with the trap book, the draw update script of card 1 tries to switch to
+	// card 2 while still loading card 1. Switching cards is not allowed during
+	// draw update scripts, resulting in an use after free crash.
+	//
+	// Here we backport the fix that has been made in the DVD version to the CD version.
+	//
+	// Script before patch:
+	// == Script 1 ==
+	// type: CardUpdate
+	// switch (agehn) {
+	// case 1:
+	//   switch (atrapbook) {
+	//     case 1:
+	//       obutton = 1;
+	//       transition(16);
+	//       switchCard(2);
+	//       break;
+	//   }
+	// break;
+	// case 2:
+	//   activatePLST(5);
+	//   break;
+	// case 3:
+	//   activatePLST(5);
+	//   break;
+	// }
+	//
+	//
+	// Script after patch:
+	// == Script 1 ==
+	// type: CardUpdate
+	// switch (agehn) {
+	// case 1:
+	//   switch (atrapbook) {
+	//     case 1:
+	//       obutton = 1;
+	//       activatePLST(6);
+	//       break;
+	//   }
+	// break;
+	// case 2:
+	//   activatePLST(5);
+	//   break;
+	// case 3:
+	//   activatePLST(5);
+	//   break;
+	// }
+	//
+	// == Script 2 ==
+	// type: CardEnter
+	// switch (agehn) {
+	// case 1:
+	//   switch (atrapbook) {
+	//     case 1:
+	//       transition(16);
+	//       switchCard(2);
+	//       break;
+	//     }
+	//   break;
+	// }
+	if (globalId == 0x2E76 && !(_vm->getFeatures() & GF_DVD)) {
+		uint16 aGehnVariable = _vm->getStack()->getIdFromName(kVariableNames, "agehn");
+		uint16 aTrapBookVariable = _vm->getStack()->getIdFromName(kVariableNames, "atrapbook");
+		uint16 patchData[] = {
+				1, // Command count in script
+				kRivenCommandSwitch,
+				2, // Unused
+				aGehnVariable,
+				1, // Branches count
+
+				1, // agehn == 1 branch
+				1, // Command count in sub-script
+				kRivenCommandSwitch,
+				2, // Unused
+				aTrapBookVariable,
+				1, // Branches count
+
+				1, // atrapbook == 1 branch
+				2, // Command count in sub-script
+				kRivenCommandTransition,
+				1, // Argument count
+				kRivenTransitionBlend,
+				kRivenCommandChangeCard,
+				1, // Argument count
+				2  // Card id
+		};
+
+		// Add the new script to the list
+		RivenTypedScript patchScript;
+		patchScript.type = kCardEnterScript;
+		patchScript.script = _vm->_scriptMan->readScriptFromData(patchData, ARRAYSIZE(patchData));
+		_scripts.push_back(patchScript);
+
+		// Add a black picture to the card's list to be able to use it in the second part of the patch
+		Picture blackPicture;
+		blackPicture.index = 6;
+		blackPicture.id = 117;
+		blackPicture.rect = Common::Rect(608, 392);
+		_pictureList.push_back(blackPicture);
+
+		debugC(kRivenDebugPatches, "Applied invalid card change during screen update (1/2) to card %x", globalId);
+		// The second part of this patch is in the script patches
+	}
+
 	// Apply script patches
 	for (uint i = 0; i < _scripts.size(); i++) {
 		_scripts[i].script->applyCardPatches(_vm, globalId, _scripts[i].type, 0xFFFF);
@@ -698,7 +797,7 @@ RivenScriptPtr RivenCard::onKeyAction(RivenKeyAction keyAction) {
 	static const char *upNames          [] = { "up",                       nullptr };
 	static const char *downNames        [] = { "down",                     nullptr };
 
-	static const char **hotspotNames;
+	const char **hotspotNames = nullptr;
 	switch (keyAction) {
 		case kKeyActionMoveForward:
 			hotspotNames = forwardNames;
diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp
index 21c18fa..cb040ee 100644
--- a/engines/mohawk/riven_scripts.cpp
+++ b/engines/mohawk/riven_scripts.cpp
@@ -179,6 +179,16 @@ RivenScriptPtr RivenScriptManager::createScriptFromData(uint16 commandCount, ...
 	return readScript(&readStream);
 }
 
+RivenScriptPtr RivenScriptManager::readScriptFromData(uint16 *data, uint16 size) {
+	// Script data is expected to be in big endian
+	for (uint i = 0; i < size; i++) {
+		data[i] = TO_BE_16(data[i]);
+	}
+
+	Common::MemoryReadStream patchStream((const byte *)(data), size * sizeof(uint16));
+	return _vm->_scriptMan->readScript(&patchStream);
+}
+
 RivenScriptPtr RivenScriptManager::createScriptWithCommand(RivenCommand *command) {
 	assert(command);
 
@@ -312,6 +322,29 @@ void RivenScript::applyCardPatches(MohawkEngine_Riven *vm, uint32 cardGlobalId,
 		debugC(kRivenDebugPatches, "Applied missing closing sound patch to card %x", cardGlobalId);
 	}
 
+	// Second part of the patch to fix the invalid card change when entering Gehn's office
+	// The first part is in the card patches.
+	if (cardGlobalId == 0x2E76 && scriptType == kCardUpdateScript && !(vm->getFeatures() & GF_DVD)) {
+		shouldApplyPatches = true;
+
+		for (uint i = 0; i < _commands.size(); i++) {
+			int transitionIndex = -1;
+			if (_commands[i]->getType() == kRivenCommandTransition) {
+				transitionIndex = i;
+			}
+			if (transitionIndex >= 0) {
+				_commands.remove_at(transitionIndex + 1);
+				_commands.remove_at(transitionIndex);
+
+				RivenSimpleCommand::ArgumentArray arguments;
+				arguments.push_back(6);
+				_commands.push_back(RivenCommandPtr(new RivenSimpleCommand(vm, kRivenCommandActivatePLST, arguments)));
+			}
+		}
+
+		debugC(kRivenDebugPatches, "Applied invalid card change during screen update (2/2) to card %x", cardGlobalId);
+	}
+
 	if (shouldApplyPatches) {
 		for (uint i = 0; i < _commands.size(); i++) {
 			_commands[i]->applyCardPatches(cardGlobalId, scriptType, hotspotId);
diff --git a/engines/mohawk/riven_scripts.h b/engines/mohawk/riven_scripts.h
index e77b9ae..25cf363 100644
--- a/engines/mohawk/riven_scripts.h
+++ b/engines/mohawk/riven_scripts.h
@@ -170,6 +170,14 @@ public:
 	/** Read a single script from a stream */
 	RivenScriptPtr readScript(Common::ReadStream *stream);
 
+	/**
+	 * Read a script from an array of uint16
+	 * @param data Script data array. Will be modified.
+	 * @param size Number of uint16 in data
+	 * @return
+	 */
+	RivenScriptPtr readScriptFromData(uint16 *data, uint16 size);
+
 	/** Create a script from the caller provided arguments containing raw data */
 	RivenScriptPtr createScriptFromData(uint16 commandCount, ...);
 


Commit: efddaf84ebc138cad41f7f13f3cc6545b8954940
    https://github.com/scummvm/scummvm/commit/efddaf84ebc138cad41f7f13f3cc6545b8954940
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-08-11T19:05:55+02:00

Commit Message:
MOHAWK: Riven: b_Data1.mhk is not required to play the CD version

Changed paths:
    engines/mohawk/riven.cpp


diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index 6c2b1a2..c7f8d1c 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -390,8 +390,9 @@ bool MohawkEngine_Riven::checkDatafiles() {
 	const char **datafiles = listExpectedDatafiles();
 	for (int i = 0; datafiles[i] != nullptr; i++) {
 		if (!SearchMan.hasFile(datafiles[i])) {
-			if (strcmp(datafiles[i], "j_Data3.mhk") == 0) {
-				// j_Data3.mhk comes from the 1.02 patch. It is not required to play.
+			if (strcmp(datafiles[i], "j_Data3.mhk") == 0
+					|| strcmp(datafiles[i], "b_Data1.mhk") == 0) {
+				// j_Data3.mhk and b_Data1.mhk come from the 1.02 patch. They are not required to play.
 				continue;
 			}
 





More information about the Scummvm-git-logs mailing list