aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/engine/script_patches.cpp104
1 files changed, 68 insertions, 36 deletions
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 810e47b379..9f52d5083e 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -39,6 +39,7 @@ namespace Sci {
struct SciScriptSignature {
uint16 scriptNr;
const char *description;
+ int16 applyCount;
uint32 magicDWord;
int magicOffset;
const byte *data;
@@ -114,9 +115,9 @@ const uint16 ecoquest1PatchStayAndHelp[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
+// script, description, magic DWORD, adjust
const SciScriptSignature ecoquest1Signatures[] = {
- { 660, "CD: bad messagebox and freeze", PATCH_MAGICDWORD(0x38, 0x22, 0x01, 0x78), -17, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp },
+ { 660, "CD: bad messagebox and freeze", 1, PATCH_MAGICDWORD(0x38, 0x22, 0x01, 0x78), -17, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -176,9 +177,9 @@ const uint16 ecoquest2PatchEcorder[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
+// script, description, magic DWORD, adjust
const SciScriptSignature ecoquest2Signatures[] = {
- { 50, "initial text not removed on ecorder", PATCH_MAGICDWORD(0x39, 0x64, 0x39, 0x7d), -8, ecoquest2SignatureEcorder, ecoquest2PatchEcorder },
+ { 50, "initial text not removed on ecorder", 1, PATCH_MAGICDWORD(0x39, 0x64, 0x39, 0x7d), -8, ecoquest2SignatureEcorder, ecoquest2PatchEcorder },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -208,6 +209,33 @@ const uint16 freddypharkasPatchScoreDisposal[] = {
PATCH_END
};
+// script 235 of freddy pharkas rm235::init and sEnterFrom500::changeState
+// disable icon 7+8 of iconbar (CD only). When picking up the cannister after
+// placing it down, the scripts will disable all the other icons. This results
+// in IconBar::disable doing endless loops even in sierra sci, because there
+// is no enabled icon left. We remove disabling of icon 8 (which is help),
+// this fixes the issue.
+const byte freddypharkasSignatureCannisterHang[] = {
+ 12,
+ 0x38, 0xf1, 0x00, // pushi f1 (selector disable)
+ 0x7a, // push2
+ 0x39, 0x07, // pushi 07
+ 0x39, 0x08, // pushi 08
+ 0x81, 0x45, // lag 45
+ 0x4a, 0x08, // send 08 - call IconBar::disable(7, 8)
+ 0
+};
+
+const uint16 freddypharkasPatchCannisterHang[] = {
+ PATCH_ADDTOOFFSET | +3,
+ 0x78, // push1
+ PATCH_ADDTOOFFSET | +2,
+ 0x33, 0x00, // ldi 00 (waste 2 bytes)
+ PATCH_ADDTOOFFSET | +3,
+ 0x06, // send 06 - call IconBar::disable(7)
+ PATCH_END
+};
+
// script 215 of freddy pharkas lowerLadder::doit and highLadder::doit actually
// process keyboard-presses when the ladder is on the screen in that room.
// They strangely also call kGetEvent. Because the main User::doit also calls
@@ -242,12 +270,11 @@ const uint16 freddypharkasPatchLadderEvent[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
+// script, description, magic DWORD, adjust
const SciScriptSignature freddypharkasSignatures[] = {
- { 0, "CD: score early disposal", PATCH_MAGICDWORD(0x39, 0x0d, 0x43, 0x75), -3, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal },
- // this is not a typo, both lowerLadder::doit and highLadder::doit have the same event code
- { 320, "lower ladder event issue", PATCH_MAGICDWORD(0x6d, 0x76, 0x38, 0xf5), -1, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent },
- { 320, "high ladder event issue", PATCH_MAGICDWORD(0x6d, 0x76, 0x38, 0xf5), -1, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent },
+ { 0, "CD: score early disposal", 1, PATCH_MAGICDWORD(0x39, 0x0d, 0x43, 0x75), -3, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal },
+ { 235, "CD: cannister pickup hang", 3, PATCH_MAGICDWORD(0x39, 0x07, 0x39, 0x08), -4, freddypharkasSignatureCannisterHang, freddypharkasPatchCannisterHang },
+ { 320, "ladder event issue", 2, PATCH_MAGICDWORD(0x6d, 0x76, 0x38, 0xf5), -1, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -317,11 +344,11 @@ const uint16 gk1PatchDay5PhoneFreeze[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
+// script, description, magic DWORD, adjust
const SciScriptSignature gk1Signatures[] = {
- { 212, "day 5 phone freeze", PATCH_MAGICDWORD(0x35, 0x03, 0x65, 0x1a), 0, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
- { 230, "day 6 police beignet timer issue", PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -16, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
- { 230, "day 6 police sleep timer issue", PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -5, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
+ { 212, "day 5 phone freeze", 1, PATCH_MAGICDWORD(0x35, 0x03, 0x65, 0x1a), 0, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
+ { 230, "day 6 police beignet timer issue", 1, PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -16, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
+ { 230, "day 6 police sleep timer issue", 1, PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -5, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -439,9 +466,9 @@ const uint16 kq5PatchCdHarpyVolume[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
+// script, description, magic DWORD, adjust
const SciScriptSignature kq5Signatures[] = {
- { 0, "CD: harpy volume change", PATCH_MAGICDWORD(0x80, 0x91, 0x01, 0x18), 0, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
+ { 0, "CD: harpy volume change", 1, PATCH_MAGICDWORD(0x80, 0x91, 0x01, 0x18), 0, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -490,9 +517,9 @@ const uint16 larry6PatchDeathDialog[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
+// script, description, magic DWORD, adjust
const SciScriptSignature larry6Signatures[] = {
- { 82, "death dialog memory corruption", PATCH_MAGICDWORD(0x3e, 0x33, 0x01, 0x35), 0, larry6SignatureDeathDialog, larry6PatchDeathDialog },
+ { 82, "death dialog memory corruption", 1, PATCH_MAGICDWORD(0x3e, 0x33, 0x01, 0x35), 0, larry6SignatureDeathDialog, larry6PatchDeathDialog },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -521,9 +548,9 @@ const uint16 laurabow2PatchPaintingClosing[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
+// script, description, magic DWORD, adjust
const SciScriptSignature laurabow2Signatures[] = {
- { 560, "painting closing immediately", PATCH_MAGICDWORD(0x36, 0x81, 0x0b, 0x1c), -2, laurabow2SignaturePaintingClosing, laurabow2PatchPaintingClosing },
+ { 560, "painting closing immediately", 1, PATCH_MAGICDWORD(0x36, 0x81, 0x0b, 0x1c), -2, laurabow2SignaturePaintingClosing, laurabow2PatchPaintingClosing },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -563,11 +590,11 @@ const uint16 mothergoose256PatchSaveLimit[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
+// script, description, magic DWORD, adjust
const SciScriptSignature mothergoose256Signatures[] = {
- { 0, "replay save issue", PATCH_MAGICDWORD(0x20, 0x04, 0xa1, 0xb3), -2, mothergoose256SignatureReplay, mothergoose256PatchReplay },
- { 0, "save limit dialog (SCI1.1)", PATCH_MAGICDWORD(0xb3, 0x35, 0x0d, 0x20), -1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
- { 994, "save limit dialog (SCI1)", PATCH_MAGICDWORD(0xb3, 0x35, 0x0d, 0x20), -1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
+ { 0, "replay save issue", 1, PATCH_MAGICDWORD(0x20, 0x04, 0xa1, 0xb3), -2, mothergoose256SignatureReplay, mothergoose256PatchReplay },
+ { 0, "save limit dialog (SCI1.1)", 1, PATCH_MAGICDWORD(0xb3, 0x35, 0x0d, 0x20), -1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
+ { 994, "save limit dialog (SCI1)", 1, PATCH_MAGICDWORD(0xb3, 0x35, 0x0d, 0x20), -1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -620,10 +647,10 @@ const uint16 qfg1vgaPatchFightEvents[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
+// script, description, magic DWORD, adjust
const SciScriptSignature qfg1vgaSignatures[] = {
- { 215, "fight event issue", PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07), -1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
- { 216, "weapon master event issue", PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07), -1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
+ { 215, "fight event issue", 1, PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07), -1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
+ { 216, "weapon master event issue", 1, PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07), -1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -650,9 +677,9 @@ const uint16 sq4FloppyPatchEndlessFlight[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
+// script, description, magic DWORD, adjust
const SciScriptSignature sq4Signatures[] = {
- { 298, "Floppy: endless flight", PATCH_MAGICDWORD(0x67, 0x08, 0x63, 0x44), -3, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight },
+ { 298, "Floppy: endless flight", 1, PATCH_MAGICDWORD(0x67, 0x08, 0x63, 0x44), -3, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -698,9 +725,9 @@ const uint16 sq5PatchScrubbing[] = {
PATCH_END
};
-// script, description, magic DWORD, adjust
+// script, description, magic DWORD, adjust
const SciScriptSignature sq5Signatures[] = {
- { 119, "scrubbing send crash", PATCH_MAGICDWORD(0x18, 0x31, 0x37, 0x78), 0, sq5SignatureScrubbing, sq5PatchScrubbing },
+ { 119, "scrubbing send crash", 1, PATCH_MAGICDWORD(0x18, 0x31, 0x37, 0x78), 0, sq5SignatureScrubbing, sq5PatchScrubbing },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -810,12 +837,17 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin
if (signatureTable) {
while (signatureTable->data) {
if (scriptNr == signatureTable->scriptNr) {
- int32 foundOffset = findSignature(signatureTable, scriptData, scriptSize);
- if (foundOffset != -1) {
- // found, so apply the patch
- warning("matched and patched %s on script %d offset %d", signatureTable->description, scriptNr, foundOffset);
- applyPatch(signatureTable->patch, scriptData, scriptSize, foundOffset);
- }
+ int32 foundOffset = 0;
+ int16 applyCount = signatureTable->applyCount;
+ do {
+ foundOffset = findSignature(signatureTable, scriptData, scriptSize);
+ if (foundOffset != -1) {
+ // found, so apply the patch
+ warning("matched and patched %s on script %d offset %d", signatureTable->description, scriptNr, foundOffset);
+ applyPatch(signatureTable->patch, scriptData, scriptSize, foundOffset);
+ }
+ applyCount--;
+ } while ((foundOffset != -1) && (applyCount));
}
signatureTable++;
}