diff options
| -rw-r--r-- | engines/sci/engine/script_patches.cpp | 115 | 
1 files changed, 115 insertions, 0 deletions
| diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 2dd3bbbaee..ad9ffb3bcd 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -695,8 +695,123 @@ static const uint16 camelotPatchFatimaRoomMessages[] = {  	PATCH_END  }; +// Sheathing the sword by pressing F8 while entering or exiting a room breaks +//  the game by placing ego in an invalid state that allows walking through +//  obstacles and prevents room changes. This affects rooms that subclass eRoom +//  in areas that allow walking with sword drawn such as the monk's ruins and +//  the desert. This is most likely to occur while battling the monk. +// +// eRoom walks ego in and out of rooms in handsOff mode. It sets ego:illegalBits +//  to 0, enables ignoreActors, and sets a motion that cues when complete to +//  restore ego's properties. Sheathing the sword interrupts the motion, which +//  prevents eRoom:cue, and prematurely restores control to the user with ego in +//  the temporary state. There are almost no restrictions on sheathing because +//  it's used when input is disabled and during several handsOff scenes. +// +// We fix this by preventing sword scripts from starting when an eRoom is in the +//  middle of controlling ego. eRoom tracks this with the comingIn and goingOut +//  properties and we require that both be cleared to execute a sword command. +// +// Applies to: All versions +// Responsible method: ARTHUR:doit +// Fixes bug: #11042 +static const uint16 camelotSignatureSwordSheathing[] = { +	SIG_MAGICDWORD, +	0x89, 0x7d,                         // lsg 7d [ sword-command ] +	0x3c,                               // dup +	0x35, 0x01,                         // ldi 01 +	0x1a,                               // eq? [ sword-command == 1 (draw) ] +	0x30, SIG_UINT16(0x0013),           // bnt 0013 +	0x39, SIG_SELECTOR8(setScript),     // pushi setScript +	0x78,                               // push1 +	0x7a,                               // push2 +	0x38, SIG_UINT16(0x038e),           // pushi 910d +	0x76,                               // push0 +	0x43, 0x02, 0x04,                   // callk ScriptID 04 [ ScriptID 910 0 (DrawSword) ] +	0x36,                               // push +	0x81, 0x00,                         // lag 00 +	0x4a, 0x06,                         // send 06 [ ego setScript: DrawSword ] +	0x32, SIG_UINT16(0x0085),           // jmp 0085 [ end of switch ] +	0x3c,                               // dup +	0x35, 0x02,                         // ldi 02 +	0x1a,                               // eq? [ sword-command == 2 (sheath) ] +	0x30, SIG_UINT16(0x0013),           // bnt 0013 +	0x39, SIG_SELECTOR8(setScript),     // pushi setScript +	0x78,                               // push1 +	0x7a,                               // push2 +	0x38, SIG_UINT16(0x038e),           // pushi 910d +	0x78,                               // push1 +	0x43, 0x02, 0x04,                   // callk ScriptID 04 [ ScriptID 910 1 (SheatheSword) ] +	0x36,                               // push +	0x81, 0x00,                         // lag 00 +	0x4a, 0x06,                         // send 06 [ ego setScript: SheatheSword ] +	0x32, SIG_UINT16(0x006b),           // jmp 006b [ end of switch ] +	0x3c,                               // dup +	0x35, 0x03,                         // ldi 03 +	0x1a,                               // eq? [ sword-command == 3 (parry) ] +	0x30, SIG_UINT16(0x0013),           // bnt 0013 +	0x39, SIG_SELECTOR8(setScript),     // pushi setScript +	0x78,                               // push1 +	0x7a,                               // push2 +	0x38, SIG_UINT16(0x0390),           // pushi 912d +	0x78,                               // push1 +	0x43, 0x02, 0x04,                   // callk ScriptID 04 [ ScriptID 912 1 (DoParry) ] +	SIG_ADDTOOFFSET(+15), +	0x81, 0x7c,                         // lag 7c [ start of sword-command == 0 handler ] +	SIG_ADDTOOFFSET(+72), +	0x3a,                               // toss [ end of switch ] +	SIG_END +}; + +static const uint16 camelotPatchSwordSheathing[] = { +	0x81, 0x7d,                         // lag 7d [ sword-command ] +	0x31, 0x53,                         // bnt 53 [ sword-command == 0 handler ] +	0x39, 0x03,                         // pushi 03 +	0x20,                               // ge? [ 3 >= sword-command ] +	0x31, 0x3e,                         // bnt 3e [ exit if sword-command > 3 ] +	0x7a,                               // push2 +	0x89, 0x02,                         // lsg 02 +	0x38, PATCH_UINT16(0x014b),         // pushi comingIn [ same value in all versions ] +	0x43, 0x07, 0x04,                   // callk RespondsTo 04 [ RespondsTo currentRoom comingIn ] +	0x31, 0x14,                         // bnt 14 [ skip eRoom checks if room isn't an eRoom ] +	0x38, PATCH_UINT16(0x014b),         // pushi comingIn +	0x76,                               // push0 +	0x81, 0x02,                         // lag 02 +	0x4a, 0x04,                         // send 04 [ currentRoom comingIn? ] +	0x2f, 0x29,                         // bt 29   [ skip sword scripts if entering room ] +	0x38, PATCH_UINT16(0x014c),         // pushi goingOut [ same value in all versions ] +	0x76,                               // push0 +	0x81, 0x02,                         // lag 02 +	0x4a, 0x04,                         // send 04 [ currentRoom goingOut? ] +	0x2f, 0x1f,                         // bt 1f   [ skip sword scripts if exiting room ] +	0x39, PATCH_SELECTOR8(setScript),   // pushi setScript +	0x78,                               // push1 +	0x7a,                               // push2 +	0x81, 0x7d,                         // lag 7d +	0x7a,                               // push2 +	0x20,                               // ge? [ 2 >= sword-command ] +	0x31, 0x05,                         // bnt 05 +	0x38, PATCH_UINT16(0x038e),         // pushi 910d +	0x33, 0x03,                         // jmp 03 +	0x38, PATCH_UINT16(0x0390),         // pushi 912d +	0x81, 0x7d,                         // lag 7d +	0x78,                               // push1 +	0x1c,                               // ne? [ sword-command != 1 ] +	0x36,                               // push +	0x43, 0x02, 0x04,                   // callk ScriptID 04 [ ScriptID (sword-command <= 2) ? 910 : 912, (sword-command != 1) ] +	0x36,                               // push +	0x81, 0x00,                         // lag 00 +	0x4a, 0x06,                         // send 06 [ ego setScript: sword-script ] +	0x48,                               // ret +	PATCH_ADDTOOFFSET(+89), +	0x48,                               // ret [ remove toss since dup instructions were removed ] +	PATCH_END +}; + +  //         script, description,                                       signature                             patch  static const SciScriptPatcherEntry camelotSignatures[] = { +	{ true,     0, "fix sword sheathing",                          1, camelotSignatureSwordSheathing,       camelotPatchSwordSheathing },  	{ true,    11, "fix hunter missing points",                    1, camelotSignatureHunterMissingPoints,  camelotPatchHunterMissingPoints },  	{ true,    62, "fix peepingTom Sierra bug",                    1, camelotSignaturePeepingTom,           camelotPatchPeepingTom },  	{ true,    64, "fix Fatima room messages",                     2, camelotSignatureFatimaRoomMessages,   camelotPatchFatimaRoomMessages }, | 
