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

bluegr md5 at scummvm.org
Sat Mar 12 22:50:07 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:
5dce3235e9 SCI: Some changes to the "dissassemble" command
fa10ee66e4 SCI: Added proper fix for bug #3048054 - "LONGBOW: crash when opening hand code"


Commit: 5dce3235e97758a76bac899d80e8166dcf33986d
    https://github.com/scummvm/scummvm/commit/5dce3235e97758a76bac899d80e8166dcf33986d
Author: md5 (md5 at scummvm.org)
Date: 2011-03-12T13:45:36-08:00

Commit Message:
SCI: Some changes to the "dissassemble" command

Fixed a bug (the "bwt" and "bc" options were inversed) and added the
ability to skip a defined number of ret calls, useful when a function
continues after a ret call

Changed paths:
    engines/sci/console.cpp



diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index aaf79da..6a64f19 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -2601,12 +2601,14 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
 		DebugPrintf("Valid options are:\n");
 		DebugPrintf(" bwt  : Print byte/word tag\n");
 		DebugPrintf(" bc   : Print bytecode\n");
+		DebugPrintf(" rX   : Continue after X ret opcodes before stopping decompilation\n");
 		return true;
 	}
 
 	reg_t objAddr = NULL_REG;
 	bool printBytecode = false;
 	bool printBWTag = false;
+	int ignoreXret = 0;
 
 	if (parse_reg_t(_engine->_gamestate, argv[1], &objAddr, false)) {
 		DebugPrintf("Invalid address passed.\n");
@@ -2616,7 +2618,7 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
 
 	const Object *obj = _engine->_gamestate->_segMan->getObject(objAddr);
 	int selectorId = _engine->getKernel()->findSelector(argv[2]);
-	reg_t addr;
+	reg_t addr = NULL_REG;
 
 	if (!obj) {
 		DebugPrintf("Not an object.");
@@ -2635,13 +2637,20 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
 
 	for (int i = 3; i < argc; i++) {
 		if (!scumm_stricmp(argv[i], "bwt"))
-			printBytecode = true;
-		else if (!scumm_stricmp(argv[i], "bc"))
 			printBWTag = true;
+		else if (!scumm_stricmp(argv[i], "bc"))
+			printBytecode = true;
+		else if (argv[i][0] == 'r')
+			ignoreXret = atoi(argv[i] + 1);
 	}
 
 	do {
+		reg_t prevAddr = addr;
 		addr = disassemble(_engine->_gamestate, addr, printBWTag, printBytecode);
+		if (addr.isNull() && ignoreXret) {
+			addr = prevAddr + 1;	// skip past the ret
+			ignoreXret--;
+		}
 	} while (addr.offset > 0);
 
 	return true;


Commit: fa10ee66e46be4a08743f920ec50f11df1017a12
    https://github.com/scummvm/scummvm/commit/fa10ee66e46be4a08743f920ec50f11df1017a12
Author: md5 (md5 at scummvm.org)
Date: 2011-03-12T13:48:56-08:00

Commit Message:
SCI: Added proper fix for bug #3048054 - "LONGBOW: crash when opening hand code"

This was caused by a buggy script, most probably the result of an
incorrect copy/paste while processing the original script. Fixed with a
script patch.

Changed paths:
    engines/sci/engine/kernel_tables.h
    engines/sci/engine/script_patches.cpp
    engines/sci/engine/workarounds.cpp
    engines/sci/engine/workarounds.h



diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 614d1b1..b262906 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -434,7 +434,7 @@ static SciKernelMapEntry s_kernelMap[] = {
 	{ MAP_CALL(Sort),              SIG_EVERYWHERE,           "ooo",                   NULL,            NULL },
 	{ MAP_CALL(Sqrt),              SIG_EVERYWHERE,           "i",                     NULL,            NULL },
 	{ MAP_CALL(StrAt),             SIG_EVERYWHERE,           "ri(i)",                 NULL,            kStrAt_workarounds },
-	{ MAP_CALL(StrCat),            SIG_EVERYWHERE,           "rr",                    NULL,            kStrCat_workarounds },
+	{ MAP_CALL(StrCat),            SIG_EVERYWHERE,           "rr",                    NULL,            NULL },
 	{ MAP_CALL(StrCmp),            SIG_EVERYWHERE,           "rr(i)",                 NULL,            NULL },
 	{ MAP_CALL(StrCpy),            SIG_EVERYWHERE,           "r[r0](i)",              NULL,            NULL },
 	{ MAP_CALL(StrEnd),            SIG_EVERYWHERE,           "r",                     NULL,            NULL },
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index f69b6a7..d292c4a 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -571,6 +571,52 @@ const SciScriptSignature kq6Signatures[] = {
 };
 
 // ===========================================================================
+// Script 210 in the German version of Longbow handles the case where Robin
+// hands out the scroll to Marion and then types his name using the hand code.
+// The German version script contains a typo (probably a copy/paste error),
+// and the function that is used to show each letter is called twice. The
+// second time that the function is called, the second parameter passed to
+// the function is undefined, thus kStrCat() that is called inside the function
+// reads a random pointer and crashes. We patch all of the 5 function calls
+// (one for each letter typed from "R", "O", "B", "I", "N") so that they are
+// the same as the English version. Fixes bug #3048054.
+const byte longbowSignatureShowHandCode[] = {
+	3,
+	0x78,                   // push1
+	0x78,                   // push1
+	0x72,                   // lofsa
+	+2, 2,                  // skip 2 bytes, offset of lofsa (the letter typed)
+	0x36,                   // push
+	0x40,                   // call
+	+2, 3,                  // skip 2 bytes, offset of call
+	0x02,                   // perform the call above with 2 parameters
+	0x36,                   // push
+	0x40,                   // call
+	+2, 8,                  // skip 2 bytes, offset of call
+	0x02,                   // perform the call above with 2 parameters
+	0x38, 0x1c, 0x01,       // pushi 011c (setMotion)
+	0x39, 0x04,             // pushi 04 (x)
+	0x51, 0x1e,             // class MoveTo
+	0
+};
+
+const uint16 longbowPatchShowHandCode[] = {
+	0x39, 0x01,             // pushi 1 (combine the two push1's in one, like in the English version)
+	PATCH_ADDTOOFFSET | +3, // leave the lofsa call untouched
+	// The following will remove the duplicate call
+	0x32, 0x02, 0x00,       // jmp 02 - skip 2 bytes (the remainder of the first call)
+	0x48,                   // ret (dummy, should never be reached)
+	0x48,                   // ret (dummy, should never be reached)
+	PATCH_END
+};
+
+//    script, description,                                      magic DWORD,                                  adjust
+const SciScriptSignature longbowSignatures[] = {
+	{    210, "hand code crash",                             5, PATCH_MAGICDWORD(0x02, 0x38, 0x1c, 0x01),   -14, longbowSignatureShowHandCode, longbowPatchShowHandCode },
+	SCI_SIGNATUREENTRY_TERMINATOR
+};
+
+// ===========================================================================
 // this is called on every death dialog. Problem is at least the german
 //  version of lsl6 gets title text that is far too long for the
 //  available temp space resulting in temp space corruption
@@ -1111,6 +1157,9 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin
 	case GID_LAURABOW2:
 		signatureTable = laurabow2Signatures;
 		break;
+	case GID_LONGBOW:
+		signatureTable = longbowSignatures;
+		break;
 	case GID_LSL6:
 		signatureTable = larry6Signatures;
 		break;
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index fb6c0e4..17c9f9f 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -368,12 +368,6 @@ const SciWorkaroundEntry kStrAt_workarounds[] = {
 };
 
 //    gameID,           room,script,lvl,          object-name, method-name,    call,index,                workaround
-const SciWorkaroundEntry kStrCat_workarounds[] = {
-	{ GID_LONGBOW,       210,   210,  0,         "giveScroll", "changeState",0x3294,    0, { WORKAROUND_FAKE,      0 } }, // German version, when handing the scroll with the druid hand code to Marion - bug #3048054
-	SCI_WORKAROUNDENTRY_TERMINATOR
-};
-
-//    gameID,           room,script,lvl,          object-name, method-name,    call,index,                workaround
 const SciWorkaroundEntry kStrLen_workarounds[] = {
 	{ GID_QFG2,          210,     2,  0,                   "", "export 21",   0xdeb,    0, { WORKAROUND_FAKE,      0 } }, // When saying something incorrect at the WIT, an integer is passed instead of a reference - bug #3100292
 	SCI_WORKAROUNDENTRY_TERMINATOR
diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h
index 7ab73cd..c7721aa 100644
--- a/engines/sci/engine/workarounds.h
+++ b/engines/sci/engine/workarounds.h
@@ -95,7 +95,6 @@ extern const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[];
 extern const SciWorkaroundEntry kSetCursor_workarounds[];
 extern const SciWorkaroundEntry kSetPort_workarounds[];
 extern const SciWorkaroundEntry kStrAt_workarounds[];
-extern const SciWorkaroundEntry kStrCat_workarounds[];
 extern const SciWorkaroundEntry kStrLen_workarounds[];
 extern const SciWorkaroundEntry kUnLoad_workarounds[];
 






More information about the Scummvm-git-logs mailing list