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

bluegr bluegr at gmail.com
Sat Aug 7 08:57:53 UTC 2021


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

Summary:
8e8e3225da SCUMM: Add missing Lemonhead lines in English CD Monkey Island 1
30ce02e9e3 SCUMM: Simplify MI1 cannibal patch
4bcfd4aa3b SCUMM: Prepare for translated versions of the MI1 cannibal patch
f1e07f96b7 SCUMM: Add missing space.
b5d7ec68ef SCUMM: Minor cleanup


Commit: 8e8e3225dac33554b27d24b51f892e69b84a4af9
    https://github.com/scummvm/scummvm/commit/8e8e3225dac33554b27d24b51f892e69b84a4af9
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-08-07T11:57:48+03:00

Commit Message:
SCUMM: Add missing Lemonhead lines in English CD Monkey Island 1

Apparently these were lost when the game was converted from floppy to CD
version. Not just in the English version, but that's all I have. We
should come up with a way to make it easy to add other languages,
though.

Changed paths:
    engines/scumm/resource.cpp
    engines/scumm/script_v5.cpp
    engines/scumm/scumm.h
    engines/scumm/scumm_v5.h


diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index d7c10ee856..fd91d10984 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -1726,6 +1726,16 @@ void ScummEngine::applyWorkaroundIfNeeded(ResType type, int idx) {
 		delete[] patchedScript;
 	} else
 
+	// For some reason, the CD version of Monkey Island 1 removes some of
+	// the text when giving the wimpy idol to the cannibals. It looks like
+	// a mistake, because one of the text that is printed is immediately
+	// overwritten. This probably affects all CD versions, so we just have
+	// to add further patches as they are reported.
+
+	if (_game.id == GID_MONKEY && type == rtRoom && idx == 25) {
+		tryPatchMI1CannibalScript(getResourceAddress(type, idx), size);
+	} else
+
 	// There is a cracked version of Maniac Mansion v2 that attempts to
 	// remove the security door copy protection. With it, any code is
 	// accepted as long as you get the last digit wrong. Unfortunately,
@@ -1771,5 +1781,72 @@ bool ScummEngine::verifyMI2MacBootScript(byte *buf, int size) {
 	return true;
 }
 
+bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
+	assert(_game.id == GID_MONKEY);
+
+	int expectedSize = -1;
+	int scriptOffset = -1;
+	int scriptLength = -1;
+	Common::String expectedMd5;
+	int patchOffset = -1;
+	int patchLength = -1;
+
+	switch (_language) {
+	case Common::EN_ANY:
+		expectedSize = 82906;
+		scriptOffset = 73883;
+		scriptLength = 607;
+		expectedMd5 = "98b1126a836ef5bfefff10b605b20555";
+		patchOffset = 167;
+		patchLength = 126;
+		break;
+	default:
+		return false;
+	}
+
+	if (size == expectedSize) {
+		// There isn't enough space in the script for the revised
+		// texts, so these abbreviations will be expanded in
+		// decodeParseString().
+		const byte patchData[] = {
+			0x14, 0x03, 0x0F,       // print(3,[Text("/LMH.001/");
+			0x2F, 0x4C, 0x4D, 0x48,
+			0x2E, 0x30, 0x30, 0x31,
+			0x2F, 0x00,
+			0xAE, 0x02,             // WaitForMessage();
+			0x14, 0x03, 0x0F,       // print(3,[Text("/LMH.001/");
+			0x2F, 0x4C, 0x4D, 0x48,
+			0x2E, 0x30, 0x30, 0x32,
+			0x2F,			// No terminating 0x00!
+		};
+
+		byte *scriptPtr = buf + scriptOffset;
+
+		// Check that the data is a local script.
+		if (READ_BE_UINT32(scriptPtr) != MKTAG('L','S','C','R'))
+			return false;
+
+		// Check that the first instruction to be patched is o5_print
+		if (scriptPtr[patchOffset] != 0x14)
+			return false;
+
+		// Check that the MD5 sum matches a known patchable script.
+		Common::MemoryReadStream stream(buf + scriptOffset, scriptLength);
+		Common::String md5 = Common::computeStreamMD5AsString(stream);
+
+		if (md5 != expectedMd5)
+			return false;
+
+		// Pad the rest of the replaced script part with spaces before
+		// terminating the string.
+
+		memcpy(scriptPtr + patchOffset, patchData, sizeof(patchData));
+		memset(scriptPtr + patchOffset + sizeof(patchData), 32, patchLength - sizeof(patchData) - 1);
+		scriptPtr[patchOffset + patchLength - 1] = 0;
+	}
+
+	return true;
+}
+
 
 } // End of namespace Scumm
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index e4b4e8c571..b86deb8222 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -2777,6 +2777,8 @@ void ScummEngine_v5::decodeParseString() {
 					strcpy(tmpBuf + diff, "5000");
 					strcpy(tmpBuf + diff + 4, tmp + sizeof("NCREDIT-NOTE-AMOUNT") - 1);
 					printString(textSlot, (byte *)tmpBuf);
+				} if (_game.id == GID_MONKEY && _roomResource == 25 && vm.slot[_currentScript].number == 205) {
+					printPatchedMI1CannibalString(textSlot, _scriptPointer);
 				} else {
 					printString(textSlot, _scriptPointer);
 				}
@@ -2810,4 +2812,26 @@ void ScummEngine_v5::decodeParseString() {
 	_string[textSlot].saveDefault();
 }
 
+void ScummEngine_v5::printPatchedMI1CannibalString(int textSlot, const byte *ptr) {
+	const char *msg = (const char *)ptr;
+
+#define MSG_WAIT "\xFF\x03"
+
+	if (strncmp((const char *)ptr, "/LMH.001/", 9) == 0) {
+		msg =
+"Oooh, that's nice." MSG_WAIT
+"Simple.  Just like one of mine." MSG_WAIT
+"And little.  Like mine.";
+	} else if (strncmp((const char *)ptr, "/LMH.002/", 9) == 0) {
+		msg =
+"And it says, `Made by Lemonhead`^" MSG_WAIT
+"^just like one of mine!" MSG_WAIT
+"We should take this to the Great Monkey.";
+	}
+
+#undef MSG_WAIT
+
+	printString(textSlot, (const byte *)msg);
+}
+
 } // End of namespace Scumm
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 3a94797583..3b3e30fb6e 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -701,6 +701,8 @@ public:
 	void applyWorkaroundIfNeeded(ResType type, int idx);
 	bool verifyMI2MacBootScript();
 	bool verifyMI2MacBootScript(byte *buf, int size);
+	bool tryPatchMI1CannibalScript(byte *buf, int size);
+
 	int getResourceDataSize(const byte *ptr) const;
 	void dumpResource(const char *tag, int index, const byte *ptr, int length = -1);
 
diff --git a/engines/scumm/scumm_v5.h b/engines/scumm/scumm_v5.h
index 4def0e3455..d516938309 100644
--- a/engines/scumm/scumm_v5.h
+++ b/engines/scumm/scumm_v5.h
@@ -65,6 +65,7 @@ protected:
 	void setupScummVars() override;
 	void resetScummVars() override;
 	virtual void decodeParseString();
+	void printPatchedMI1CannibalString(int textSlot, const byte *ptr);
 
 	void saveLoadWithSerializer(Common::Serializer &s) override;
 


Commit: 30ce02e9e34d9a2d02f20cabebd1f7b868f7d031
    https://github.com/scummvm/scummvm/commit/30ce02e9e34d9a2d02f20cabebd1f7b868f7d031
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-08-07T11:57:48+03:00

Commit Message:
SCUMM: Simplify MI1 cannibal patch

There's enough space to just change the first message and insert the
WaitForMessage(). No need to mess with the second message, since that
one's already correct.

Changed paths:
    engines/scumm/resource.cpp
    engines/scumm/script_v5.cpp


diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index fd91d10984..4786a5695e 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -1784,6 +1784,43 @@ bool ScummEngine::verifyMI2MacBootScript(byte *buf, int size) {
 bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
 	assert(_game.id == GID_MONKEY);
 
+	// The room resource is a collection of resources. We need to know the
+	// offset to the initial LSCR tag of the room-25-205 script, and its
+	// length up to (but not including) the LSCR tag of the next script.
+	// Furthermore we need to know the offset and length of the part of
+	// the script that we are going to replace. As an illustration, this
+	// is what that part of script looks like in the English CD version:
+	//
+	// [009C] (AE) WaitForMessage();
+	// [009E] (14) print(3,[Text("Oooh, that's nice.")]);
+	// [00B4] (14) print(3,[Text("And it says, `Made by Lemonhead`^" +
+	//             wait() + "^just like one of mine!" + wait() +
+	//             "We should take this to the Great Monkey.")]);
+	// [011C] (AE) WaitForMessage();
+	//
+	// What we want to do is make it behave like the script from the VGA
+	// floppy version:
+	//
+	// [009E] (AE) WaitForMessage();
+	// [00A0] (14) print(3,[Text("Oooh, that's nice." + wait() +
+	//             "Simple.  Just like one of mine." + wait() +
+	//             "And little.  Like mine.")]);
+	// [00F0] (AE) WaitForMessage();
+	// [00F2] (14) print(3,[Text("And it says, `Made by Lemonhead`^" +
+	//             wait() + "^just like one of mine!" + wait() +
+	//             "We should take this to the Great Monkey.")]);
+	// [015A] (AE) WaitForMessage();
+	//
+	// So we want to adjust the message, and insert a WaitForMessage().
+	// Unfortunately there isn't enough space to do that, and rather than
+	// modifying the length of the whole resource (which is easy to get
+	// wrong), we insert a placeholder message that gets replaced by
+	// decodeParseString().
+	//
+	// There should be enough space to do this even if we only change the
+	// first message. Any leftover space in the message is padded with
+	// spaces, since I can't find any NOP opcode.
+
 	int expectedSize = -1;
 	int scriptOffset = -1;
 	int scriptLength = -1;
@@ -1798,7 +1835,7 @@ bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
 		scriptLength = 607;
 		expectedMd5 = "98b1126a836ef5bfefff10b605b20555";
 		patchOffset = 167;
-		patchLength = 126;
+		patchLength = 22;
 		break;
 	default:
 		return false;
@@ -1809,15 +1846,9 @@ bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
 		// texts, so these abbreviations will be expanded in
 		// decodeParseString().
 		const byte patchData[] = {
-			0x14, 0x03, 0x0F,       // print(3,[Text("/LMH.001/");
-			0x2F, 0x4C, 0x4D, 0x48,
-			0x2E, 0x30, 0x30, 0x31,
-			0x2F, 0x00,
-			0xAE, 0x02,             // WaitForMessage();
-			0x14, 0x03, 0x0F,       // print(3,[Text("/LMH.001/");
-			0x2F, 0x4C, 0x4D, 0x48,
-			0x2E, 0x30, 0x30, 0x32,
-			0x2F,			// No terminating 0x00!
+			0x14, 0x03, 0x0F,       // print(3,[Text("/LH.1/");
+			0x2F, 0x4C, 0x48, 0x2E,
+			0x31, 0x2F              // No terminating 0x00!
 		};
 
 		byte *scriptPtr = buf + scriptOffset;
@@ -1838,11 +1869,13 @@ bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
 			return false;
 
 		// Pad the rest of the replaced script part with spaces before
-		// terminating the string.
+		// terminating the string. Finally, add WaitForMessage().
 
 		memcpy(scriptPtr + patchOffset, patchData, sizeof(patchData));
-		memset(scriptPtr + patchOffset + sizeof(patchData), 32, patchLength - sizeof(patchData) - 1);
-		scriptPtr[patchOffset + patchLength - 1] = 0;
+		memset(scriptPtr + patchOffset+ sizeof(patchData), 32, patchLength - sizeof(patchData) - 3);
+		scriptPtr[patchOffset + patchLength - 3] = 0;
+		scriptPtr[patchOffset + patchLength - 2] = 0xAE;
+		scriptPtr[patchOffset + patchLength - 1] = 0x02;
 	}
 
 	return true;
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index b86deb8222..ce4099b72d 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -2815,22 +2815,13 @@ void ScummEngine_v5::decodeParseString() {
 void ScummEngine_v5::printPatchedMI1CannibalString(int textSlot, const byte *ptr) {
 	const char *msg = (const char *)ptr;
 
-#define MSG_WAIT "\xFF\x03"
-
-	if (strncmp((const char *)ptr, "/LMH.001/", 9) == 0) {
+	if (strncmp((const char *)ptr, "/LH.1/", 6) == 0) {
 		msg =
-"Oooh, that's nice." MSG_WAIT
-"Simple.  Just like one of mine." MSG_WAIT
+"Oooh, that's nice.\xFF\x03"
+"Simple.  Just like one of mine.\xFF\x03"
 "And little.  Like mine.";
-	} else if (strncmp((const char *)ptr, "/LMH.002/", 9) == 0) {
-		msg =
-"And it says, `Made by Lemonhead`^" MSG_WAIT
-"^just like one of mine!" MSG_WAIT
-"We should take this to the Great Monkey.";
 	}
 
-#undef MSG_WAIT
-
 	printString(textSlot, (const byte *)msg);
 }
 


Commit: 4bcfd4aa3b65b9fcbeef4000def997dfb38a58ae
    https://github.com/scummvm/scummvm/commit/4bcfd4aa3b65b9fcbeef4000def997dfb38a58ae
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-08-07T11:57:48+03:00

Commit Message:
SCUMM: Prepare for translated versions of the MI1 cannibal patch

Changed paths:
    engines/scumm/resource.cpp
    engines/scumm/script_v5.cpp


diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 4786a5695e..6f7bed8f25 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -1827,6 +1827,7 @@ bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
 	Common::String expectedMd5;
 	int patchOffset = -1;
 	int patchLength = -1;
+	char lang[4];
 
 	switch (_language) {
 	case Common::EN_ANY:
@@ -1836,19 +1837,23 @@ bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
 		expectedMd5 = "98b1126a836ef5bfefff10b605b20555";
 		patchOffset = 167;
 		patchLength = 22;
+		strcpy(lang, "ENG");
 		break;
 	default:
 		return false;
 	}
 
+	// Note that the patch will not apply to the "Ultimate Talkie" edition
+	// since that script has been patched to a different length.
+
 	if (size == expectedSize) {
 		// There isn't enough space in the script for the revised
 		// texts, so these abbreviations will be expanded in
 		// decodeParseString().
 		const byte patchData[] = {
-			0x14, 0x03, 0x0F,       // print(3,[Text("/LH.1/");
+			0x14, 0x03, 0x0F,       // print(3,[Text("/LH.$$$/");
 			0x2F, 0x4C, 0x48, 0x2E,
-			0x31, 0x2F              // No terminating 0x00!
+			0x24, 0x24, 0x24, 0x2F  // No terminating 0x00!
 		};
 
 		byte *scriptPtr = buf + scriptOffset;
@@ -1868,10 +1873,15 @@ bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
 		if (md5 != expectedMd5)
 			return false;
 
+		// Insert the script patch and tag it with the appropriate
+		// language.
+
+		memcpy(scriptPtr + patchOffset, patchData, sizeof(patchData));
+		memcpy(scriptPtr + patchOffset + 7, lang, 3);
+
 		// Pad the rest of the replaced script part with spaces before
 		// terminating the string. Finally, add WaitForMessage().
 
-		memcpy(scriptPtr + patchOffset, patchData, sizeof(patchData));
 		memset(scriptPtr + patchOffset+ sizeof(patchData), 32, patchLength - sizeof(patchData) - 3);
 		scriptPtr[patchOffset + patchLength - 3] = 0;
 		scriptPtr[patchOffset + patchLength - 2] = 0xAE;
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index ce4099b72d..b12cf6a24d 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -2815,7 +2815,7 @@ void ScummEngine_v5::decodeParseString() {
 void ScummEngine_v5::printPatchedMI1CannibalString(int textSlot, const byte *ptr) {
 	const char *msg = (const char *)ptr;
 
-	if (strncmp((const char *)ptr, "/LH.1/", 6) == 0) {
+	if (strncmp((const char *)ptr, "/LH.ENG/", 8) == 0) {
 		msg =
 "Oooh, that's nice.\xFF\x03"
 "Simple.  Just like one of mine.\xFF\x03"


Commit: f1e07f96b75964221b71de1406c6d8b79bc9cd23
    https://github.com/scummvm/scummvm/commit/f1e07f96b75964221b71de1406c6d8b79bc9cd23
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-08-07T11:57:48+03:00

Commit Message:
SCUMM: Add missing space.

Changed paths:
    engines/scumm/resource.cpp


diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 6f7bed8f25..baeddce2fd 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -1882,7 +1882,7 @@ bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
 		// Pad the rest of the replaced script part with spaces before
 		// terminating the string. Finally, add WaitForMessage().
 
-		memset(scriptPtr + patchOffset+ sizeof(patchData), 32, patchLength - sizeof(patchData) - 3);
+		memset(scriptPtr + patchOffset + sizeof(patchData), 32, patchLength - sizeof(patchData) - 3);
 		scriptPtr[patchOffset + patchLength - 3] = 0;
 		scriptPtr[patchOffset + patchLength - 2] = 0xAE;
 		scriptPtr[patchOffset + patchLength - 1] = 0x02;


Commit: b5d7ec68ef7f608fc267417ef3445d21ddfaa0d6
    https://github.com/scummvm/scummvm/commit/b5d7ec68ef7f608fc267417ef3445d21ddfaa0d6
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-08-07T11:57:48+03:00

Commit Message:
SCUMM: Minor cleanup

Changed paths:
    engines/scumm/resource.cpp


diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index baeddce2fd..5315b0981b 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -1827,7 +1827,7 @@ bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
 	Common::String expectedMd5;
 	int patchOffset = -1;
 	int patchLength = -1;
-	char lang[4];
+	byte lang[3];
 
 	switch (_language) {
 	case Common::EN_ANY:
@@ -1837,7 +1837,9 @@ bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
 		expectedMd5 = "98b1126a836ef5bfefff10b605b20555";
 		patchOffset = 167;
 		patchLength = 22;
-		strcpy(lang, "ENG");
+		lang[0] = 'E';
+		lang[1] = 'N';
+		lang[2] = 'G';
 		break;
 	default:
 		return false;
@@ -1877,7 +1879,7 @@ bool ScummEngine::tryPatchMI1CannibalScript(byte *buf, int size) {
 		// language.
 
 		memcpy(scriptPtr + patchOffset, patchData, sizeof(patchData));
-		memcpy(scriptPtr + patchOffset + 7, lang, 3);
+		memcpy(scriptPtr + patchOffset + 7, lang, sizeof(lang));
 
 		// Pad the rest of the replaced script part with spaces before
 		// terminating the string. Finally, add WaitForMessage().




More information about the Scummvm-git-logs mailing list