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

m-kiewitz m_kiewitz at users.sourceforge.net
Sun Mar 19 17:14:44 CET 2017


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

Summary:
c315065503 SCI: Add Colonel's Bequest patch and extend patcher functionality


Commit: c315065503349fdaed038be3469bb0a3ee8a6888
    https://github.com/scummvm/scummvm/commit/c315065503349fdaed038be3469bb0a3ee8a6888
Author: Martin Kiewitz (m_kiewitz at users.sourceforge.net)
Date: 2017-03-19T17:14:33+01:00

Commit Message:
SCI: Add Colonel's Bequest patch and extend patcher functionality

Add Colonel's Bequest patch to fix an issue in room 35.
When you tell Lilly about Gertie in act 2, Lilly will then
walk out of the room. In case Laura (ego) is in her way, the game
will effectively block and will appear frozen.
This also happened, when using the original interpreter.

This also adds a new functionality to the script patcher.
PATCH_GETORIGINALUINT16 is able to get a full UINT16 from
original script data and insert it somewhere else.
PATCH_GETORIGINALBYTE and PATCH_GETORIGINALBYTEADJUST commands
were merged internally and use the same internal command now.
Some script patches were adjusted accordingly.

Thanks again to wjp for helping on the script issue.

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


diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 5f374c2..cf3a981 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -103,6 +103,7 @@ static const char *const selectorNameTable[] = {
 	"modNum",       // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
 	"cycler",       // Space Quest 4 / system selector
 	"setLoop",      // Laura Bow 1 Colonel's Bequest
+	"ignoreActors", // Laura Bow 1 Colonel's Bequest
 #ifdef ENABLE_SCI32
 	"newWith",      // SCI2 array script
 	"scrollSelections", // GK2
@@ -135,7 +136,8 @@ enum ScriptPatcherSelectors {
 	SELECTOR_startAudio,
 	SELECTOR_modNum,
 	SELECTOR_cycler,
-	SELECTOR_setLoop
+	SELECTOR_setLoop,
+	SELECTOR_ignoreActors
 #ifdef ENABLE_SCI32
 	,
 	SELECTOR_newWith,
@@ -554,14 +556,12 @@ static const uint16 freddypharkasSignatureIntroScaling[] = {
 static const uint16 freddypharkasPatchIntroScaling[] = {
 	// remove setLoop(), objects in heap are already prepared, saves 5 bytes
 	0x38,
-	PATCH_GETORIGINALBYTE(+6),
-	PATCH_GETORIGINALBYTE(+7),       // pushi (setStep)
+	PATCH_GETORIGINALUINT16(+6),     // pushi (setStep)
 	0x7a,                            // push2
 	0x39, 0x05,                      // pushi 05
 	0x3c,                            // dup
 	0x72,
-	PATCH_GETORIGINALBYTE(+13),
-	PATCH_GETORIGINALBYTE(+14),      // lofsa (view)
+	PATCH_GETORIGINALUINT16(+13),    // lofsa (view)
 	0x4a, 0x18,                      // send 18 - adjusted
 	0x35, 0x0a,                      // ldi 0a
 	0xa3, 0x02,                      // sal local[2]
@@ -1314,8 +1314,7 @@ static const uint16 kq6PatchInventoryStackFix[] = {
 	0x12,                               // and
 	0x65, 0x30,                         // aTop state
 	0x38,                               // pushi "show"
-	PATCH_GETORIGINALBYTE(+22),
-	PATCH_GETORIGINALBYTE(+23),
+	PATCH_GETORIGINALUINT16(+22),
 	0x78,                               // push1
 	0x87, 0x00,                         // lap param[0]
 	0x31, 0x04,                         // bnt [call show using global 0]
@@ -1600,8 +1599,7 @@ static const uint16 kq6CDPatchAudioTextSupport3[] = {
 	0x65, 0x12,                         // aTop dialog
 	// followed by original addText-calling code
 	0x38,
-	PATCH_GETORIGINALBYTE(+95),
-	PATCH_GETORIGINALBYTE(+96),         // pushi addText
+	PATCH_GETORIGINALUINT16(+95),       // pushi (addText)
 	0x78,                               // push1
 	0x8f, 0x02,                         // lsp param[2]
 	0x59, 0x03,                         // &rest 03
@@ -1949,8 +1947,7 @@ static const uint16 kq7PatchSubtitleFix3[] = {
 	PATCH_ADDTOOFFSET(+2),              // skip over "pToa initialized code"
 	0x2f, 0x0c,                         // bt [skip init code] - saved 1 byte
 	0x38,
-	PATCH_GETORIGINALBYTE(+6),
-	PATCH_GETORIGINALBYTE(+7),          // pushi (init)
+	PATCH_GETORIGINALUINT16(+6),        // pushi (init)
 	0x76,                               // push0
 	0x54, PATCH_UINT16(0x0004),           // self 04
 	// additionally set background color here (5 bytes)
@@ -2488,12 +2485,79 @@ static const uint16 laurabow1PatchArmorOilingArmFix[] = {
 	PATCH_END
 };
 
+// When you tell Lilly about Gertie in room 35, Lilly will then walk to the left and off the screen.
+// In case Laura (ego) is in the way, the whole game will basically block and you won't be able
+// to do anything except saving + restoring the game.
+//
+// If this happened already, the player can enter
+// "send Lillian ignoreActors 1" inside the debugger to fix this situation.
+//
+// This issue is very difficult to solve, because Lilly also walks diagonally after walking to the left right
+// under the kitchen table. This means that even if we added a few more rectangle checks, there could still be
+// spots, where the game would block.
+//
+// Also the mover "PathOut" is used for Lillian instead of the regular "MoveTo", which would avoid other
+// actors by itself.
+//
+// So instead we set Lilly to ignore other actors during that cutscene, which is the least invasive solution.
+//
+// Applies to at least: English PC Floppy, English Amiga Floppy, English Atari ST Floppy
+// Responsible method: goSee::changeState(1) in script 236
+// Fixes bug: (happened during GOG Let's Play)
+static const uint16 laurabow1SignatureTellLillyAboutGerieBlockingFix1[] = {
+	0x7a,                               // puah2
+	SIG_MAGICDWORD,
+	0x38, SIG_UINT16(0x00c1),           // pushi 00C1h
+	0x38, SIG_UINT16(0x008f),           // pushi 008Fh
+	0x38, SIG_SELECTOR16(ignoreActors), // pushi (ignoreActors)
+	0x78,                               // push1
+	0x76,                               // push0
+	SIG_END
+};
+
+static const uint16 laurabow1PatchTellLillyAboutGertieBlockingFix1[] = {
+	PATCH_ADDTOOFFSET(+11),             // skip over until push0
+	0x78,                               // push1 (change push0 to push1)
+	PATCH_END
+};
+
+// a second patch to call Lillian::ignoreActors(1) on goSee::changeState(9) in script 236
+static const uint16 laurabow1SignatureTellLillyAboutGerieBlockingFix2[] = {
+	0x3c,                               // dup
+	0x35, 0x09,                         // ldi 09
+	0x1a,                               // eq?
+	0x30, SIG_UINT16(0x003f),           // bnt [ret]
+	0x39, SIG_ADDTOOFFSET(+1),          // pushi (view)
+	0x78,                               // push1
+	0x38, SIG_UINT16(0x0203),           // pushi 203h (515d)
+	0x38, SIG_ADDTOOFFSET(+2),          // pushi (posn)
+	0x7a,                               // push2
+	0x38, SIG_UINT16(0x00c9),           // pushi C9h (201d)
+	SIG_MAGICDWORD,
+	0x38, SIG_UINT16(0x0084),           // pushi 84h (132d)
+	0x72, SIG_ADDTOOFFSET(+2),          // lofsa Lillian (different offsets for different platforms)
+	0x4a, 0x0e,                         // send 0Eh
+	SIG_END
+};
+
+static const uint16 laurabow1PatchTellLillyAboutGertieBlockingFix2[] = {
+	0x38, PATCH_SELECTOR16(ignoreActors), // pushi (ignoreActors)
+	0x78,                                 // push1
+	0x76,                                 // push0
+	0x33, 0x00,                           // ldi 00 (waste 2 bytes)
+	PATCH_ADDTOOFFSET(+19),               // skip over until send
+	0x4a, 0x14,                           // send 14h
+	PATCH_END
+};
+
 //          script, description,                                      signature                           patch
 static const SciScriptPatcherEntry laurabow1Signatures[] = {
-	{  true,     4, "easter egg view fix",                         1, laurabow1SignatureEasterEggViewFix,  laurabow1PatchEasterEggViewFix },
-	{  true,    37, "armor open visor fix",                        1, laurabow1SignatureArmorOpenVisorFix, laurabow1PatchArmorOpenVisorFix },
-	{  true,    37, "armor move to fix",                           2, laurabow1SignatureArmorMoveToFix,    laurabow1PatchArmorMoveToFix },
-	{  true,    37, "allowing input, after oiling arm",            1, laurabow1SignatureArmorOilingArmFix, laurabow1PatchArmorOilingArmFix },
+	{  true,     4, "easter egg view fix",                      1, laurabow1SignatureEasterEggViewFix,                laurabow1PatchEasterEggViewFix },
+	{  true,    37, "armor open visor fix",                     1, laurabow1SignatureArmorOpenVisorFix,               laurabow1PatchArmorOpenVisorFix },
+	{  true,    37, "armor move to fix",                        2, laurabow1SignatureArmorMoveToFix,                  laurabow1PatchArmorMoveToFix },
+	{  true,    37, "allowing input, after oiling arm",         1, laurabow1SignatureArmorOilingArmFix,               laurabow1PatchArmorOilingArmFix },
+	{  true,   236, "tell Lilly about Gertie blocking fix 1/2", 1, laurabow1SignatureTellLillyAboutGerieBlockingFix1, laurabow1PatchTellLillyAboutGertieBlockingFix1 },
+	{  true,   236, "tell Lilly about Gertie blocking fix 2/2", 1, laurabow1SignatureTellLillyAboutGerieBlockingFix2, laurabow1PatchTellLillyAboutGertieBlockingFix2 },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -2702,9 +2766,7 @@ static const uint16 laurabow2SignatureMuseumPartyFixEnteringSouth2[] = {
 
 static const uint16 laurabow2PatchMuseumPartyFixEnteringSouth2[] = {
 	0x38,                              // pushi
-	PATCH_GETORIGINALBYTEADJUST(96, -1),
-	PATCH_GETORIGINALBYTE(97),         // get handsOff code and subtract 1 from it to get handsOn
-	// we should be able to not care about SCI-platform byte order, because Laura Bow 2 was only released for PC.
+	PATCH_GETORIGINALUINT16ADJUST(+96, -1), // get handsOff code and ubstract 1 from it to get handsOn
 	PATCH_END
 };
 
@@ -4035,8 +4097,7 @@ static const uint16 qfg3PatchMissingPoints1[] = {
 	PATCH_UINT16(0xFFD6),               // -42 "Greet"
 	PATCH_UINT16(0xFFB0),               // -80 "Say Good-bye"
 	PATCH_UINT16(0x03E7),               // 999 END MARKER
-	PATCH_GETORIGINALBYTE(+28),         // local[$aa][0].low
-	PATCH_GETORIGINALBYTE(+29),         // local[$aa][0].high
+	PATCH_GETORIGINALUINT16(+28),       // local[$aa][0]
 	PATCH_END
 };
 
@@ -4937,14 +4998,6 @@ void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc
 			break;
 		}
 		case PATCH_CODE_GETORIGINALBYTE: {
-			// get original byte from script
-			if (patchValue >= orgDataSize)
-				error("Script-Patcher: can not get requested original byte from script");
-			scriptData[offset] = orgData[patchValue];
-			offset++;
-			break;
-		}
-		case PATCH_CODE_GETORIGINALBYTEADJUST: {
 			// get original byte from script and adjust it
 			if (patchValue >= orgDataSize)
 				error("Script-Patcher: can not get requested original byte from script");
@@ -4955,6 +5008,30 @@ void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc
 			offset++;
 			break;
 		}
+		case PATCH_CODE_GETORIGINALUINT16: {
+			// get original byte from script and adjust it
+			if ((patchValue >= orgDataSize) || (((uint32)patchValue + 1) >= orgDataSize))
+				error("Script-Patcher: can not get requested original uint16 from script");
+			uint16 orgUINT16;
+			int16 adjustValue;
+
+			if (!_isMacSci11) {
+				orgUINT16 = orgData[patchValue] | (orgData[patchValue + 1] << 8);
+			} else {
+				orgUINT16 = orgData[patchValue + 1] | (orgData[patchValue] << 8);
+			}
+			patchData++; adjustValue = (int16)(*patchData);
+			orgUINT16 += adjustValue;
+			if (!_isMacSci11) {
+				scriptData[offset] = orgUINT16 & 0xFF;
+				scriptData[offset + 1] = orgUINT16 >> 8;
+			} else {
+				scriptData[offset] = orgUINT16 >> 8;
+				scriptData[offset + 1] = orgUINT16 & 0xFF;
+			}
+			offset += 2;
+			break;
+		}
 		case PATCH_CODE_UINT16:
 		case PATCH_CODE_SELECTOR16: {
 			byte byte1;
@@ -5230,7 +5307,8 @@ void ScriptPatcher::calculateMagicDWordAndVerify(const char *signatureDescriptio
 			}
 			break;
 		}
-		case PATCH_CODE_GETORIGINALBYTEADJUST: {
+		case PATCH_CODE_GETORIGINALBYTE:
+		case PATCH_CODE_GETORIGINALUINT16: {
 			signatureData++; // skip over extra uint16
 			break;
 		}
diff --git a/engines/sci/engine/script_patches.h b/engines/sci/engine/script_patches.h
index f95806a..b5797be 100644
--- a/engines/sci/engine/script_patches.h
+++ b/engines/sci/engine/script_patches.h
@@ -44,23 +44,25 @@ namespace Sci {
 #define SIG_UINT16(_value_)          SIG_CODE_UINT16 | ((_value_) & 0xFF), ((_value_) >> 8)
 #define SIG_CODE_BYTE                0x0000
 
-#define PATCH_END                                            SIG_END
-#define PATCH_COMMANDMASK                                    SIG_COMMANDMASK
-#define PATCH_VALUEMASK                                      SIG_VALUEMASK
-#define PATCH_BYTEMASK                                       SIG_BYTEMASK
-#define PATCH_CODE_ADDTOOFFSET                               SIG_CODE_ADDTOOFFSET
-#define PATCH_ADDTOOFFSET(_offset_)                          SIG_CODE_ADDTOOFFSET | (_offset_)
-#define PATCH_CODE_GETORIGINALBYTE                           0xD000
-#define PATCH_GETORIGINALBYTE(_offset_)                      PATCH_CODE_GETORIGINALBYTE | (_offset_)
-#define PATCH_CODE_GETORIGINALBYTEADJUST                     0xC000
-#define PATCH_GETORIGINALBYTEADJUST(_offset_, _adjustValue_) PATCH_CODE_GETORIGINALBYTEADJUST | (_offset_), (uint16)(_adjustValue_)
-#define PATCH_CODE_SELECTOR16                                SIG_CODE_SELECTOR16
-#define PATCH_SELECTOR16(_selectorID_)                       SIG_CODE_SELECTOR16 | SELECTOR_##_selectorID_
-#define PATCH_CODE_SELECTOR8                                 SIG_CODE_SELECTOR8
-#define PATCH_SELECTOR8(_selectorID_)                        SIG_CODE_SELECTOR8 | SELECTOR_##_selectorID_
-#define PATCH_CODE_UINT16                                    SIG_CODE_UINT16
-#define PATCH_UINT16(_value_)                                SIG_CODE_UINT16 | ((_value_) & 0xFF), ((_value_) >> 8)
-#define PATCH_CODE_BYTE                                      SIG_CODE_BYTE
+#define PATCH_END                                              SIG_END
+#define PATCH_COMMANDMASK                                      SIG_COMMANDMASK
+#define PATCH_VALUEMASK                                        SIG_VALUEMASK
+#define PATCH_BYTEMASK                                         SIG_BYTEMASK
+#define PATCH_CODE_ADDTOOFFSET                                 SIG_CODE_ADDTOOFFSET
+#define PATCH_ADDTOOFFSET(_offset_)                            SIG_CODE_ADDTOOFFSET | (_offset_)
+#define PATCH_CODE_GETORIGINALBYTE                             0xC000
+#define PATCH_GETORIGINALBYTE(_offset_)                        PATCH_CODE_GETORIGINALBYTE | (_offset_), 0
+#define PATCH_GETORIGINALBYTEADJUST(_offset_, _adjustValue_)   PATCH_CODE_GETORIGINALBYTE | (_offset_), (uint16)(_adjustValue_)
+#define PATCH_CODE_GETORIGINALUINT16                           0xD000
+#define PATCH_GETORIGINALUINT16(_offset_)                      PATCH_CODE_GETORIGINALUINT16 | (_offset_), 0
+#define PATCH_GETORIGINALUINT16ADJUST(_offset_, _adjustValue_) PATCH_CODE_GETORIGINALUINT16 | (_offset_), (uint16)(_adjustValue_)
+#define PATCH_CODE_SELECTOR16                                  SIG_CODE_SELECTOR16
+#define PATCH_SELECTOR16(_selectorID_)                         SIG_CODE_SELECTOR16 | SELECTOR_##_selectorID_
+#define PATCH_CODE_SELECTOR8                                   SIG_CODE_SELECTOR8
+#define PATCH_SELECTOR8(_selectorID_)                          SIG_CODE_SELECTOR8 | SELECTOR_##_selectorID_
+#define PATCH_CODE_UINT16                                      SIG_CODE_UINT16
+#define PATCH_UINT16(_value_)                                  SIG_CODE_UINT16 | ((_value_) & 0xFF), ((_value_) >> 8)
+#define PATCH_CODE_BYTE                                        SIG_CODE_BYTE
 
 // defines maximum scratch area for getting original bytes from unpatched script data
 #define PATCH_VALUELIMIT      4096





More information about the Scummvm-git-logs mailing list