diff options
| -rw-r--r-- | engines/sci/engine/script_patches.cpp | 120 | 
1 files changed, 120 insertions, 0 deletions
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 107fe18ab8..5597f170a6 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -127,6 +127,7 @@ static const char *const selectorNameTable[] = {  	"get",          // Torin, GK1  	"newRoom",      // GK1  	"normalize",    // GK1 +	"signal",       // GK1  	"set",          // Torin  	"clear",        // Torin  	"masterVolume", // SCI2 master volume reset @@ -203,6 +204,7 @@ enum ScriptPatcherSelectors {  	SELECTOR_get,  	SELECTOR_newRoom,  	SELECTOR_normalize, +	SELECTOR_signal,  	SELECTOR_set,  	SELECTOR_clear,  	SELECTOR_masterVolume, @@ -1598,6 +1600,122 @@ static const uint16 gk1ShowMagentiaItemPatch[] = {  	PATCH_END  }; +// The day 5 snake attack has speed, audio, and graphics problems. +//  These occur in all versions and also in Sierra's interpreter. +// +// Gabriel automatically walks cautiously in the darkened museum while looking +//  around and saying lines, then a snake drops on him. Depending on the game's +//  speed setting, the audio for "Why is it so dark in here?" is interrupted as +//  much as halfway through by the next line, "Dr. John, hello?". The cautious +//  walk animation runs at game speed, which can be fast, then abruptly changes +//  to 10 (33%) when the snake drops, which looks off. Ego doesn't even reach +//  the snake and instead stops short and warps 17 pixels to the right when the +//  drop animation starts. +// +// We fix all of this. Initializing ego's speed to 10 solves the interrupted +//  speech and inconsistent speed. It feels like this was the intended pacing. +//  The snake-warping isn't a speed issue, ego's animation frames for this +//  scene simply fall short of the snake's location. To fix that we start ego +//  a little farther in the room and increase ego's final position so that he +//  ends up directly under the snake and transitions to the drop animation +//  smoothly. Finally, we initialize ego on the room's first cycle instead of +//  second so that ego doesn't materialize after the room is already displayed. +// +// This patch works with pc floppy and cd even though they have different +//  snakeAttack scripts. Floppy doesn't have speech to interrupt but it +//  has the same issues. +// +// Applies to: All PC Floppy and CD versions. TODO: Test Mac, should apply +// Responsible method: snakeAttack:changeState +// Fixes bug #10793 +static const uint16 gk1Day5SnakeAttackSignature1[] = { +	0x65, 0x1a,                         // aTop cycles +	0x32, SIG_ADDTOOFFSET(+2),          // jmp [ end of method ] +	0x3c,                               // dup +	0x35, 0x01,                         // ldi 1 +	SIG_MAGICDWORD, +	0x1a,                               // eq? +	0x30, SIG_UINT16(0x0048),           // bnt 0048 [ state 2 ] +	0x35, 0x01,                         // ldi 1 [ free bytes ] +	0x39, SIG_SELECTOR8(view),          // pushi view +	0x78,                               // push1 +	0x38, SIG_UINT16(0x0107),           // pushi 0107 +	0x38, SIG_SELECTOR16(setCel),       // pushi setCel +	0x78,                               // push1 +	0x76,                               // push0 +	0x38, SIG_SELECTOR16(setLoop),      // pushi setLoop +	0x78,                               // push1 +	0x76,                               // push0 +	0x39, SIG_SELECTOR8(signal),        // pushi signal +	0x78,                               // push1 +	0x39, SIG_SELECTOR8(signal),        // pushi signal +	0x76,                               // push0 +	0x81, 0x00,                         // lag 00 +	0x4a, SIG_UINT16(0x0004),           // send 4 [ GKEgo:signal? ] +	SIG_ADDTOOFFSET(+18), +	0x39, 0x64,                         // pushi 64 [ initial x ] +	SIG_END +}; + +static const uint16 gk1Day5SnakeAttackPatch1[] = { +	0x39, PATCH_SELECTOR8(view),        // pushi view [ begin initializing ego in state 0 ] +	0x78,                               // push1 +	0x33, 0x07,                         // jmp 07 [ continue initializing ego in state 0 ] +	0x3c,                               // dup +	0x18,                               // not [ acc = 1 ] +	0x1a,                               // eq? +	0x65, 0x1a,                         // aTop cycles [ just set cycles to 1 in state 1 ] +	0x33, 0x48,                         // jmp 47 [ state 2 ] +	0x38, PATCH_UINT16(0x0107),         // pushi 0107 +	0x39, PATCH_SELECTOR8(cel),         // pushi cel +	0x78,                               // push1 +	0x76,                               // push0 +	0x38, PATCH_SELECTOR16(setLoop),    // pushi setLoop +	0x78,                               // push1 +	0x76,                               // push0 +	0x39, PATCH_SELECTOR8(signal),      // pushi signal +	0x78,                               // push1 +	0x38, PATCH_SELECTOR16(cycleSpeed), // pushi cycleSpeed +	0x78,                               // push1 +	0x39, 0x0a,                         // pushi 0a +	PATCH_ADDTOOFFSET(+5), +	0x4a, PATCH_UINT16(0x000a),         // send a [ GKEgo:signal?, cycleSpeed = a ] +	PATCH_ADDTOOFFSET(+18), +	0x39, 0x70,                         // pushi 70 [ new initial x ] +	PATCH_END +}; + +// this just changes ego's second x coordinate but unfortunately that promotes it to 16 bits +static const uint16 gk1Day5SnakeAttackSignature2[] = { +	SIG_MAGICDWORD, +	0x39, 0x7a,                         // push 7a [ x for second walking loop ] +	0x39, 0x7c,                         // push 7c +	0x38, SIG_SELECTOR16(setCycle),     // pushi setCycle +	0x7a,                               // push2 +	0x51, 0x18,                         // class End +	0x36,                               // push +	0x7c,                               // pushSelf +	0x81, 0x00,                         // lag 00 +	0x4a, SIG_UINT16(0x0022),           // send 22 +	0x32, SIG_ADDTOOFFSET(+2),          // jmp [ end of method ] +	SIG_END +}; + +static const uint16 gk1Day5SnakeAttackPatch2[] = { +	0x38, PATCH_UINT16(0x008b),         // push 008b [ new x for second walking loop ] +	0x39, 0x7c,                         // push 7c +	0x38, PATCH_SELECTOR16(setCycle),   // pushi setCycle +	0x7a,                               // push2 +	0x51, 0x18,                         // class End +	0x36,                               // push +	0x7c,                               // pushSelf +	0x81, 0x00,                         // lag 00 +	0x4a, PATCH_UINT16(0x0022),         // send 22 +	0x3a,                               // toss +	0x48,                               // ret +	PATCH_END +}; +  // When entering the police station (room 230) sGabeEnters sets ego speed  //  to 4 for the door animation but fails to restore it to the game speed  //  by calling GKEgo:normalize. This leaves ego at 75% speed until doing @@ -1884,6 +2002,8 @@ static const SciScriptPatcherEntry gk1Signatures[] = {  	{  true,   230, "fix police station ego speed (version 2)",    1, gk1PoliceEgoSpeedFixV2Signature,  gk1PoliceEgoSpeedFixV2Patch },  	{  true,   240, "fix day 5 mosely veve missing points",        1, gk1Day5MoselyVevePointsSignature, gk1Day5MoselyVevePointsPatch },  	{  true,   250, "fix ego speed when exiting drug store",       1, gk1DrugStoreEgoSpeedFixSignature, gk1DrugStoreEgoSpeedFixPatch }, +	{  true,   260, "fix day 5 snake attack (1/2)",                1, gk1Day5SnakeAttackSignature1,     gk1Day5SnakeAttackPatch1 }, +	{  true,   260, "fix day 5 snake attack (2/2)",                1, gk1Day5SnakeAttackSignature2,     gk1Day5SnakeAttackPatch2 },  	{  true,   280, "fix pathfinding in Madame Cazanoux's house",  1, gk1CazanouxPathfindingSignature,  gk1CazanouxPathfindingPatch },  	{  true,   290, "fix magentia missing message",                1, gk1ShowMagentiaItemSignature,     gk1ShowMagentiaItemPatch },  	{  true,   380, "fix ego flicker in Gran's chair",             1, gk1GranChairFlickerSignature,     gk1GranChairFlickerPatch },  | 
