diff options
| -rw-r--r-- | engines/sci/engine/script_patches.cpp | 185 | 
1 files changed, 184 insertions, 1 deletions
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 8fb6e5721b..792a5dd1cd 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -127,7 +127,7 @@ static const char *const selectorNameTable[] = {  	"ignoreActors", // Laura Bow 1 Colonel's Bequest  	"setVol",       // Laura Bow 2 CD  	"at",           // Longbow, QFG4 -	"owner",        // Longbow +	"owner",        // Longbow, QFG4  	"delete",       // EcoQuest 1  	"size",         // EcoQuest 1  	"signal",       // EcoQuest 1, GK1 @@ -168,14 +168,22 @@ static const char *const selectorNameTable[] = {  	"plane",        // RAMA  	"state",        // RAMA  	"getSubscriberObj", // RAMA +	"advanceCurIcon", // QFG4 +	"amount",       // QFG4  	"approachVerbs", // QFG4  	"changeState",  // QFG4  	"cue",          // QFG4 +	"curIcon",      // QFG4 +	"curInvIcon",   // QFG4 +	"getCursor",    // QFG4  	"heading",      // QFG4 +	"hide",         // QFG4  	"moveSpeed",    // QFG4  	"sayMessage",   // QFG4 +	"setCursor",    // QFG4  	"setLooper",    // QFG4  	"setSpeed",     // QFG4 +	"useStamina",   // QFG4  	"value",        // QFG4  #endif  	NULL @@ -269,14 +277,22 @@ enum ScriptPatcherSelectors {  	SELECTOR_plane,  	SELECTOR_state,  	SELECTOR_getSubscriberObj, +	SELECTOR_advanceCurIcon, +	SELECTOR_amount,  	SELECTOR_approachVerbs,  	SELECTOR_changeState,  	SELECTOR_cue, +	SELECTOR_curIcon, +	SELECTOR_curInvIcon, +	SELECTOR_getCursor,  	SELECTOR_heading, +	SELECTOR_hide,  	SELECTOR_moveSpeed,  	SELECTOR_sayMessage, +	SELECTOR_setCursor,  	SELECTOR_setLooper,  	SELECTOR_setSpeed, +	SELECTOR_useStamina,  	SELECTOR_value  #endif  }; @@ -10810,6 +10826,172 @@ static const uint16 qfg4GuildWalkFloppyPatch3[] = {  	PATCH_END                           // (don't end the switch, keep testing cases)  }; +// Rations are not properly decremented by daily scheduled meal consumption. +// Rations are consumed periodically as time advances. If rations are the +// active inventory item when the last of them is eaten, that icon will persist +// in the verb bar. +// +// We make room by consolidating common gloryMessager::say() args in a +// subroutine and cache values with temp variables. We add code to clean up +// the verb bar when rations are exhausted (test if rations were the active +// item, advance the cursor, hide the bar's invItem icon) - similar to the +// localproc in script 16, called by combinable items to remove themselves. +// +// Applies to at least: English CD, English floppy, German floppy +// Responsible method: hero::eatMeal() in script 28 +// Fixes bug: #10772 +static const uint16 qfg4LeftoversSignature[] = { +	0x3f, 0x01,                         // link 1d +	SIG_ADDTOOFFSET(+9),                // ... +	SIG_MAGICDWORD, +	0xe1, 0x88,                         // -ag global[136] (digest a preemptively eaten meal) +	0x35, 0x01,                         // ldi 1d +	SIG_ADDTOOFFSET(+238),              // ... +	0x85, 0x00,                         // lat temp[0] (eaten, unset flags if true) +	SIG_END +}; + +static const uint16 qfg4LeftoversPatch[] = { +	0x3f, 0x03,                         // link 3d (3 temp vars) + +	PATCH_ADDTOOFFSET(+15),             // (cond 1, preemptively eaten meals) +	0x32, PATCH_UINT16(0x00bb),         // jmp 187d [end the cond] + +                                        // (cond 2) +	0x39, PATCH_SELECTOR8(at),          // pushi at +	0x78,                               // push1 +	0x39, 0x04,                         // pushi 4d (itemId 4, theRations) +	0x81, 0x09,                         // lag global[9] (gloryInv) +	0x4a, PATCH_UINT16(0x0006),         // send 6d +	0xa5, 0x01,                         // sat temp[1] (theRations) + +	0x38, PATCH_SELECTOR16(amount),     // pushi amount +	0x76,                               // push0 +	0x4a, PATCH_UINT16(0x0004),         // send 4d (theRations amount:) +	0xa5, 0x02,                         // sat temp[2] (amount) + +	0x31, 0x50,                         // bnt 80d [next condition] + +	0x38, PATCH_SELECTOR16(amount),     // pushi amount +	0x78,                               // push1 +	0xed, 0x02,                         // -st temp[2] (amount) +	0x85, 0x01,                         // lat temp[1] (theRations) +	0x4a, PATCH_UINT16(0x0006),         // send 6d (decrement amount) + +	0x85, 0x02,                         // lat temp[2] (amount) +	0x2f, 0x3b,                         // bt 59d [skip exhausted item removal] + +	0x38, PATCH_SELECTOR16(owner),      // pushi owner +	0x78,                               // push1 +	0x76,                               // push0 +	0x85, 0x01,                         // lat temp[1] (theRations) +	0x4a, PATCH_UINT16(0x0006),         // send 6d + +	0x38, PATCH_SELECTOR16(curInvIcon), // pushi curInvIcon +	0x76,                               // push0 +	0x81, 0x45,                         // lag global[69] (mainIconBar) +	0x4a, PATCH_UINT16(0x0004),         // send 4d +	0x8d, 0x01,                         // lst temp[1] (theRations) +	0x1a,                               // eq? +	0x31, 0x23,                         // bnt 35d [skip icon bar disabling] + +	0x38, PATCH_SELECTOR16(curInvIcon), // pushi curInvIcon +	0x78,                               // push1 +	0x76,                               // push0 +	0x38, PATCH_SELECTOR16(advanceCurIcon), // pushi advanceCurIcon +	0x76,                               // push0 +	0x38, PATCH_SELECTOR16(disable),    // pushi disable +	0x78,                               // push1 +	0x39, 0x06,                         // pushi 6d +	0x81, 0x45,                         // lag global[69] (mainIconBar) +	0x4a, PATCH_UINT16(0x0010),         // send 16d + +	0x38, PATCH_SELECTOR16(hide),       // pushi hide +	0x76,                               // push0 +                                        // +	0x7a,                               // push2 (2 call args) +	0x39, 0x24,                         // pushi 36d +	0x78,                               // push1 +	0x43, 0x02, PATCH_UINT16(0x0004),   // callk ScriptID, 4d (ScriptID 36 1, invItem) +                                        // +	0x4a, PATCH_UINT16(0x0004),         // send 4d (invItem hide:) +                                        // (exhausted item removal end) + +	0x35, 0x01,                         // ldi 1d +	0xa5, 0x00,                         // sat temp[0] (eaten) + +	0x33, 0x54,                         // jmp 84d [end the cond] + +                                        // (cond 3) +	0x78,                               // push1 (1 call arg) +	0x39, 0x03,                         // pushi 3d ("hungry" flag) +	0x45, 0x04, PATCH_UINT16(0x0002),   // callb [export 4 of script 0], 2d (test flag 3) +	0x31, 0x26,                         // bnt 38d [next condition] +                                        // +	0x38, PATCH_SELECTOR16(useStamina), // pushi useStamina +	0x7a,                               // push2 +	0x39, 0x08,                         // pushi 8d +	0x76,                               // push0 +	0x54, PATCH_UINT16(0x0008),         // self 8d (hero useStamina: 8 0) +                                        // +	0x31, 0x09,                         // bnt 9d [hero dies] +	0x78,                               // push1 (1 call arg) +	0x39, 0x05,                         // pushi 5d (say cond:5, "You're starving.") +	0x41, 0x3a, PATCH_UINT16(0x0002),   // call [58], 2d (gloryMessager say: 1 6 5 1 0 28) +	0x33, 0x36,                         // jmp 54d [end the cond] +                                        // +	0x39, 0x04,                         // pushi 4d (4 call args) +	0x39, 0x08,                         // pushi 8d +	0x39, 0x1c,                         // pushi 28d +	0x38, PATCH_UINT16(0x03e3),         // pushi 995d +	0x78,                               // push1 +	0x47, 0x1a, 0x00, PATCH_UINT16(0x0008), // calle [export 0 of script 26], 8d (hero dies) +	0x33, 0x25,                         // jmp 37d [end the cond] + +                                        // (cond 4) +	0x78,                               // push1 (1 call arg) +	0x7a,                               // push2 ("missed meal" flag) +	0x45, 0x04, PATCH_UINT16(0x0002),   // callb [export 4 of script 0], 2d (test flag 2) +	0x31, 0x10,                         // bnt 16d [next condition] +                                        // +	0x78,                               // push1 (1 call arg) +	0x39, 0x03,                         // pushi 3d ("hungry" flag) +	0x45, 0x02, PATCH_UINT16(0x0002),   // callb [export 2 of script 0], 2d (set flag 3) +                                        // +	0x78,                               // push1 (1 call arg) +	0x39, 0x06,                         // pushi 6d (say cond:6, "Really getting hungry.") +	0x41, 0x11, PATCH_UINT16(0x0002),   // call [17], 2d (gloryMessager say: 1 6 6 1 0 28) +	0x33, 0x0d,                         // jmp 13d [end the cond] + +                                        // (cond else) +	0x78,                               // push1 (1 call arg) +	0x7a,                               // push2 ("missed meal" flag) +	0x45, 0x02, PATCH_UINT16(0x0002),   // callb [export 2 of script 0], 2d (set flag 2) +                                        // +	0x78,                               // push1 (1 call arg) +	0x39, 0x04,                         // pushi 4d (say cond:4, "Get food soon.") +	0x41, 0x02, PATCH_UINT16(0x0002),   // call [2], 2d (gloryMessager say: 1 6 4 1 0 28) + +                                        // (cond end) + +	0x33, 0x14,                         // jmp 20d [skip subroutine declaration] +	0x38, PATCH_SELECTOR16(say),        // pushi say +	0x39, 0x06,                         // pushi 6d +	0x78,                               // push1 (noun) +	0x39, 0x06,                         // pushi 6d (verb) +	0x8f, 0x01,                         // lsp param[1] (cond varies) +	0x78,                               // push1 (seq) +	0x76,                               // push0 (caller) +	0x39, 0x1c,                         // pushi 28d (message pool) +	0x81, 0x5b,                         // lag global[91] (gloryMessager say: 1 6 ? 1 0 28) +	0x4a, PATCH_UINT16(0x0010),         // send 16d +	0x48,                               // ret + +	0x33, 0x16,                         // jmp 22d [skip waste bytes] +	0x35, 0x00,                         // ldi 0 (erase 2 bytes to keep disasm aligned) +	PATCH_END +}; +  //          script, description,                                     signature                      patch  static const SciScriptPatcherEntry qfg4Signatures[] = {  	{  true,     0, "prevent autosave from deleting save games",   1, qfg4AutosaveSignature,         qfg4AutosavePatch }, @@ -10822,6 +11004,7 @@ static const SciScriptPatcherEntry qfg4Signatures[] = {  	{  true,    11, "fix trigger after summon staff (1/2)",        1, qfg4TriggerStaffSignature1,    qfg4TriggerStaffPatch1 },  	{  true,    11, "fix trigger after summon staff (2/2)",        1, qfg4TriggerStaffSignature2,    qfg4TriggerStaffPatch2 },  	{  true,    13, "fix spell effect disposal",                   1, qfg4EffectDisposalSignature,   qfg4EffectDisposalPatch }, +	{  true,    28, "fix lingering rations icon after eating",     1, qfg4LeftoversSignature,        qfg4LeftoversPatch },  	{  true,    31, "fix setScaler calls",                         1, qfg4SetScalerSignature,        qfg4SetScalerPatch },  	{  true,    41, "fix conditional void calls",                  3, qfg4ConditionalVoidSignature,  qfg4ConditionalVoidPatch },  	{  true,    83, "fix incorrect array type",                    1, qfg4TrapArrayTypeSignature,    qfg4TrapArrayTypePatch },  | 
