aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/kernel.cpp12
-rw-r--r--engines/sci/engine/kernel.h4
-rw-r--r--engines/sci/engine/kfile.cpp2
-rw-r--r--engines/sci/engine/savegame.cpp2
-rw-r--r--engines/sci/engine/script.h1
-rw-r--r--engines/sci/engine/script_patches.cpp488
-rw-r--r--engines/sci/engine/seg_manager.h2
-rw-r--r--engines/sci/engine/workarounds.cpp2
8 files changed, 390 insertions, 123 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 8d55790ad2..12746e17d6 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -35,8 +35,6 @@ namespace Sci {
Kernel::Kernel(ResourceManager *resMan, SegManager *segMan)
: _resMan(resMan), _segMan(segMan), _invalid("<invalid>") {
- loadSelectorNames();
- mapSelectors(); // Map a few special selectors for later use
}
Kernel::~Kernel() {
@@ -53,6 +51,11 @@ Kernel::~Kernel() {
}
}
+void Kernel::init() {
+ loadSelectorNames();
+ mapSelectors(); // Map a few special selectors for later use
+}
+
uint Kernel::getSelectorNamesSize() const {
return _selectorNames.size();
}
@@ -104,6 +107,11 @@ int Kernel::findSelector(const char *selectorName) const {
return -1;
}
+// used by Script patcher to figure out, if it's okay to initialize signature/patch-table
+bool Kernel::selectorNamesAvailable() {
+ return !_selectorNames.empty();
+}
+
void Kernel::loadSelectorNames() {
Resource *r = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS), 0);
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 8a021073fc..69c3a6d0c9 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -145,6 +145,8 @@ public:
*/
Kernel(ResourceManager *resMan, SegManager *segMan);
~Kernel();
+
+ void init();
uint getSelectorNamesSize() const;
const Common::String &getSelectorName(uint selector);
@@ -159,6 +161,8 @@ public:
* @return The appropriate selector ID, or -1 on error
*/
int findSelector(const char *selectorName) const;
+
+ bool selectorNamesAvailable();
// Script dissection/dumping functions
void dissectScript(int scriptNumber, Vocabulary *vocab);
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index c6635f2f27..b940eca6f5 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -718,7 +718,7 @@ reg_t kSave(EngineState *s, int argc, reg_t *argv) {
reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) {
Common::String game_id;
- int16 virtualId = argv[1].toSint16();
+ int16 virtualId = argv[1].toSint16();
int16 savegameId = -1;
Common::String game_description;
Common::String version;
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index c60b50a964..6955225fe5 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -465,7 +465,7 @@ void Script::syncStringHeap(Common::Serializer &s) {
break;
} while (1);
- } else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1){
+ } else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1){
// Strings in SCI1.1 come after the object instances
byte *buf = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2;
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index 56a9004226..6a27dc7f64 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -100,6 +100,7 @@ public:
void patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize);
void patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacSci11);
+ void patcherEnablePatch(SciScriptPatcherEntry *patchTable, const char *searchDescription);
int32 patcherFindSignature(const SciScriptPatcherEntry *patchEntry, const byte *scriptData, const uint32 scriptSize, bool isMacSci11);
void patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, bool isMacSci11);
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 4a829c2457..6293fb42ae 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -104,6 +104,7 @@ namespace Sci {
#define PATCH_VALUELIMIT 4096
struct SciScriptPatcherEntry {
+ bool active;
uint16 scriptNr;
const char *description;
int16 applyCount;
@@ -113,7 +114,7 @@ struct SciScriptPatcherEntry {
const uint16 *patchData;
};
-#define SCI_SIGNATUREENTRY_TERMINATOR { 0, NULL, 0, 0, 0, NULL, NULL }
+#define SCI_SIGNATUREENTRY_TERMINATOR { false, 0, NULL, 0, 0, 0, NULL, NULL }
struct SciScriptPatcherSelector {
const char *name;
@@ -137,6 +138,9 @@ SciScriptPatcherSelector selectorTable[] = {
{ "put", -1, }, // Police Quest 1 VGA
{ "solvePuzzle", -1, }, // Quest For Glory 3
{ "timesShownID", -1, }, // Space Quest 1 VGA
+ { "startText", -1, }, // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
+ { "startAudio", -1, }, // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
+ { "modNum", -1, }, // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
{ NULL, -1 }
};
@@ -156,7 +160,10 @@ enum ScriptPatcherSelectors {
SELECTOR_localize,
SELECTOR_put,
SELECTOR_solvePuzzle,
- SELECTOR_timesShownID
+ SELECTOR_timesShownID,
+ SELECTOR_startText,
+ SELECTOR_startAudio,
+ SELECTOR_modNum
};
// ===========================================================================
@@ -178,7 +185,7 @@ enum ScriptPatcherSelectors {
//
// We fix the script by patching in a jump to the proper code inside fawaz::doit.
// Responsible method: fawaz::handleEvent
-// Fixes bug #3614969
+// Fixes bug: #6402
const uint16 camelotSignaturePeepingTom[] = {
0x72, SIG_MAGICDWORD, SIG_UINT16 + 0x7e, 0x07, // lofsa fawaz <-- start of proper initializion code
0xa1, 0xb9, // sag b9h
@@ -202,9 +209,9 @@ const uint16 camelotPatchPeepingTom[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry camelotSignatures[] = {
- { 62, "fix peepingTom Sierra bug", 1, 0, 0, camelotSignaturePeepingTom, camelotPatchPeepingTom },
+ { true, 62, "fix peepingTom Sierra bug", 1, 0, 0, camelotSignaturePeepingTom, camelotPatchPeepingTom },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -216,7 +223,7 @@ SciScriptPatcherEntry camelotSignatures[] = {
// This also happens in sierra sci
// Applies to at least: PC-CD
// Responsible method: stayAndHelp::changeState
-// Fixes bug: #3038387
+// Fixes bug: #5107
const uint16 ecoquest1SignatureStayAndHelp[] = {
0x3f, 0x01, // link 01
0x87, 0x01, // lap param[1]
@@ -271,9 +278,9 @@ const uint16 ecoquest1PatchStayAndHelp[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry ecoquest1Signatures[] = {
- { 660, "CD: bad messagebox and freeze", 1, 0, 0, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp },
+ { true, 660, "CD: bad messagebox and freeze", 1, 0, 0, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -282,7 +289,8 @@ SciScriptPatcherEntry ecoquest1Signatures[] = {
// ecorder. This is done by reusing temp-space, that was filled on state 1.
// this worked in sierra sci just by accident. In our sci, the temp space
// is resetted every time, which means the previous text isn't available
-// anymore. We have to patch the code because of that - bug #3035386
+// anymore. We have to patch the code because of that.
+// Fixes bug: #4993
const uint16 ecoquest2SignatureEcorder[] = {
0x31, 0x22, // bnt [next state]
0x39, 0x0a, // pushi 0a
@@ -334,10 +342,11 @@ const uint16 ecoquest2PatchEcorder[] = {
};
// ===========================================================================
-// Same patch as above for the ecorder introduction. Fixes bug #3092115.
+// Same patch as above for the ecorder introduction.
// Two workarounds are needed for this patch in workarounds.cpp (when calling
// kGraphFillBoxAny and kGraphUpdateBox), as there isn't enough space to patch
// the function otherwise.
+// Fixes bug: #6467
const uint16 ecoquest2SignatureEcorderTutorial[] = {
0x30, SIG_UINT16 + 0x23, 0x00, // bnt [next state]
0x39, 0x0a, // pushi 0a
@@ -394,10 +403,10 @@ const uint16 ecoquest2PatchEcorderTutorial[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry ecoquest2Signatures[] = {
- { 50, "initial text not removed on ecorder", 1, 0, 0, ecoquest2SignatureEcorder, ecoquest2PatchEcorder },
- { 333, "initial text not removed on ecorder tutorial",1, 0, 0, ecoquest2SignatureEcorderTutorial, ecoquest2PatchEcorderTutorial },
+ { true, 50, "initial text not removed on ecorder", 1, 0, 0, ecoquest2SignatureEcorder, ecoquest2PatchEcorder },
+ { true, 333, "initial text not removed on ecorder tutorial",1, 0, 0, ecoquest2SignatureEcorderTutorial, ecoquest2PatchEcorderTutorial },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -406,7 +415,7 @@ SciScriptPatcherEntry ecoquest2Signatures[] = {
// wrong address when an incorrect word is typed, therefore leading to an
// infinite loop. This script bug was not apparent in SSCI, probably because
// event handling was slightly different there, so it was never discovered.
-// Fixes bug #3038870.
+// Fixes bug: #5120
const uint16 fanmadeSignatureInfiniteLoop[] = {
0x38, SIG_UINT16 + 0x4c, 0x00, // pushi 004c
0x39, 0x00, // pushi 00
@@ -424,9 +433,9 @@ const uint16 fanmadePatchInfiniteLoop[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry fanmadeSignatures[] = {
- { 999, "infinite loop on typo", 1, 0, 0, fanmadeSignatureInfiniteLoop, fanmadePatchInfiniteLoop },
+ { true, 999, "infinite loop on typo", 1, 0, 0, fanmadeSignatureInfiniteLoop, fanmadePatchInfiniteLoop },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -545,12 +554,12 @@ const uint16 freddypharkasPatchMacInventory[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry freddypharkasSignatures[] = {
- { 0, "CD: score early disposal", 1, 0, 0, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal },
- { 15, "Mac: broken inventory", 1, 0, 0, freddypharkasSignatureMacInventory, freddypharkasPatchMacInventory },
- { 235, "CD: canister pickup hang", 3, 0, 0, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang },
- { 320, "ladder event issue", 2, 0, 0, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent },
+ { true, 0, "CD: score early disposal", 1, 0, 0, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal },
+ { true, 15, "Mac: broken inventory", 1, 0, 0, freddypharkasSignatureMacInventory, freddypharkasPatchMacInventory },
+ { true, 235, "CD: canister pickup hang", 3, 0, 0, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang },
+ { true, 320, "ladder event issue", 2, 0, 0, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -686,12 +695,12 @@ const uint16 gk1PatchInterrogationBug[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry gk1Signatures[] = {
- { 51, "interrogation bug", 1, 0, 0, gk1SignatureInterrogationBug, gk1PatchInterrogationBug },
- { 212, "day 5 phone freeze", 1, 0, 0, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
- { 230, "day 6 police beignet timer issue", 1, 0, 0, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
- { 230, "day 6 police sleep timer issue", 1, 0, 0, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
+ { true, 51, "interrogation bug", 1, 0, 0, gk1SignatureInterrogationBug, gk1PatchInterrogationBug },
+ { true, 212, "day 5 phone freeze", 1, 0, 0, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
+ { true, 230, "day 6 police beignet timer issue", 1, 0, 0, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
+ { true, 230, "day 6 police sleep timer issue", 1, 0, 0, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -753,12 +762,14 @@ const uint16 kq5PatchCdHarpyVolume[] = {
// Additionally its top,left,bottom,right properties are set to 0 rather
// than the right values. We fix the object by setting the right values.
// If they are all zero, this causes an impossible position check in
-// witch::cantBeHere and an infinite loop when entering room 22 (bug #3034714).
+// witch::cantBeHere and an infinite loop when entering room 22.
//
// This bug is accidentally not triggered in SSCI because the invalid number
// of variables effectively hides witchCage::doit, causing this position check
// to be bypassed entirely.
// See also the warning+comment in Object::initBaseObject
+//
+// Fixes bug: #4964
const uint16 kq5SignatureWitchCageInit[] = {
SIG_UINT16 + 0x00, 0x00, // top
SIG_UINT16 + 0x00, 0x00, // left
@@ -808,17 +819,11 @@ const uint16 kq5PatchWinGMSignals[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry kq5Signatures[] = {
- { 0, "CD: harpy volume change", 1, 0, 0, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
- { 200, "CD: witch cage init", 1, 0, 0, kq5SignatureWitchCageInit, kq5PatchWitchCageInit },
- SCI_SIGNATUREENTRY_TERMINATOR
-};
-
-SciScriptPatcherEntry kq5WinGMSignatures[] = {
- { 0, "CD: harpy volume change", 1, 0, 0, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
- { 200, "CD: witch cage init", 1, 0, 0, kq5SignatureWitchCageInit, kq5PatchWitchCageInit },
- { 124, "Win: GM Music signal checks", 4, 0, 0, kq5SignatureWinGMSignals, kq5PatchWinGMSignals },
+ { true, 0, "CD: harpy volume change", 1, 0, 0, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
+ { true, 200, "CD: witch cage init", 1, 0, 0, kq5SignatureWitchCageInit, kq5PatchWitchCageInit },
+ { false, 124, "Win: GM Music signal checks", 4, 0, 0, kq5SignatureWinGMSignals, kq5PatchWinGMSignals },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -830,7 +835,8 @@ SciScriptPatcherEntry kq5WinGMSignatures[] = {
// sound is played twice, squelching all other sounds. We just rip the
// unnecessary cryMusic::check method out, thereby stopping the sound from
// constantly restarting (since it's being looped anyway), thus the normal
-// game speech can work while the baby cry sound is heard. Fixes bug #3034579.
+// game speech can work while the baby cry sound is heard.
+// Fixes bug: #4955
const uint16 kq6SignatureDuplicateBabyCry[] = {
SIG_MAGICDWORD,
0x83, 0x00, // lal 00
@@ -853,7 +859,7 @@ const uint16 kq6PatchDuplicateBabyCry[] = {
// will be too large. This patch fixes the buggy script.
// Applies to at least: PC-CD, English PC floppy, German PC floppy, English Mac
// Responsible method: KqInv::showSelf
-// Fixes bug: #3293954
+// Fixes bug: #5681
const uint16 kq6SignatureInventoryStackFix[] = {
0x67, 0x30, // pTos state
0x34, SIG_UINT16 + 0x00, 0x20, // ldi 2000
@@ -916,10 +922,116 @@ const uint16 kq6PatchInventoryStackFix[] = {
PATCH_END
};
-// script, description, signature patch
+// Audio + subtitles support - SHARED! - used for King's Quest 6 and Laura Bow 2
+// this patch gets enabled, when the user selects "both" in the ScummVM "Speech + Subtitles" menu
+// We currently use global 98d to hold a kMemory pointer.
+// Patched method: Messager::sayNext / lb2Messager::sayNext (always use text branch)
+const uint16 kq6laurabow2CDSignatureAudioTextSupport1[] = {
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x12, // and
+ SIG_MAGICDWORD,
+ 0x31, 0x13, // bnt [audio call]
+ 0x38, SIG_SELECTOR16 + SELECTOR_modNum, // pushi modNum
+ SIG_END
+};
+
+const uint16 kq6laurabow2CDPatchAudioTextSupport1[] = {
+ PATCH_ADDTOOFFSET +5,
+ 0x33, 0x13, // jmp [audio call]
+ PATCH_END
+};
+
+// Patched method: Messager::sayNext / lb2Messager::sayNext (allocate audio memory)
+const uint16 kq6laurabow2CDSignatureAudioTextSupport2[] = {
+ 0x7a, // push2
+ 0x78, // push1
+ 0x39, 0x0c, // pushi 0c
+ 0x43, SIG_MAGICDWORD, 0x72, 0x04, // kMemory
+ 0xa5, 0xc9, // sat global[c9]
+ SIG_END
+};
+
+const uint16 kq6laurabow2CDPatchAudioTextSupport2[] = {
+ PATCH_ADDTOOFFSET +7,
+ 0xa1, 98, // sag global[98d]
+ PATCH_END
+};
+
+// Patched method: Messager::sayNext / lb2Messager::sayNext (release audio memory)
+const uint16 kq6laurabow2CDSignatureAudioTextSupport3[] = {
+ 0x7a, // push2
+ 0x39, 0x03, // pushi 03
+ SIG_MAGICDWORD,
+ 0x8d, 0xc9, // lst temp[c9]
+ 0x43, 0x72, 0x04, // kMemory
+ SIG_END
+};
+
+const uint16 kq6laurabow2CDPatchAudioTextSupport3[] = {
+ PATCH_ADDTOOFFSET +3,
+ 0x89, 98, // lsg global[98d]
+ PATCH_END
+};
+
+// Patched method: Narrator::say (use audio memory)
+const uint16 kq6laurabow2CDSignatureAudioTextSupport4[] = {
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x01, // ldi 01
+ 0x12, // and
+ 0x31, 0x08, // bnt [skip code]
+ 0x38, SIG_SELECTOR16 + SELECTOR_startText, // pushi startText
+ 0x78, // push1
+ 0x8f, 0x01, // lsp param[1]
+ 0x54, 0x06, // self 06
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x12, // and
+ 0x31, 0x08, // bnt [skip code]
+ SIG_MAGICDWORD,
+ 0x38, SIG_SELECTOR16 + SELECTOR_startAudio, // pushi startAudio
+ 0x78, // push1
+ 0x8f, 0x01, // lsp param[1]
+ 0x54, 0x06, // self 06
+ SIG_END
+};
+
+const uint16 kq6laurabow2CDPatchAudioTextSupport4[] = {
+ PATCH_ADDTOOFFSET +5,
+ 0x18, // not (never jump here)
+ 0x18, // not (never jump here)
+ PATCH_ADDTOOFFSET +19,
+ 0x89, 98, // lsp global[98d]
+ PATCH_END
+};
+
+// Patched method: Talker::display/Narrator::say (remove reset saved mouse cursor code)
+// code would screw over mouse cursor
+const uint16 kq6laurabow2CDSignatureAudioTextSupport5[] = {
+ SIG_MAGICDWORD,
+ 0x35, 0x00, // ldi 00
+ 0x65, 0x82, // aTop saveCursor
+ SIG_END
+};
+
+const uint16 kq6laurabow2CDPatchAudioTextSupport5[] = {
+ 0x18, 0x18, 0x18, 0x18, // waste bytes, do nothing
+ PATCH_END
+};
+
+// script, description, signature patch
SciScriptPatcherEntry kq6Signatures[] = {
- { 481, "duplicate baby cry", 1, 0, 0, kq6SignatureDuplicateBabyCry, kq6PatchDuplicateBabyCry },
- { 907, "inventory stack fix", 1, 0, 0, kq6SignatureInventoryStackFix, kq6PatchInventoryStackFix },
+ { true, 481, "duplicate baby cry", 1, 0, 0, kq6SignatureDuplicateBabyCry, kq6PatchDuplicateBabyCry },
+ { true, 907, "inventory stack fix", 1, 0, 0, kq6SignatureInventoryStackFix, kq6PatchInventoryStackFix },
+ // King's Quest 6 and Laura Bow 2 share basic patches for audio + text support
+ // *** King's Quest 6 audio + text support - CURRENTLY DISABLED ***
+ // TODO: fix window placement (currently part of the text windows go off-screen)
+ // TODO: fix hi-res portraits mode graphic glitches
+ { false, 924, "CD: audio + text support 1", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
+ { false, 924, "CD: audio + text support 2", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
+ { false, 924, "CD: audio + text support 3", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 },
+ { false, 928, "CD: audio + text support 4", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 },
+ { false, 928, "CD: audio + text support 5", 2, 0, 0, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -935,7 +1047,7 @@ SciScriptPatcherEntry kq6Signatures[] = {
// the same as the English version.
// Applies to at least: German floppy
// Responsible method: unknown
-// Fixes bug: #3048054
+// Fixes bug: #5264
const uint16 longbowSignatureShowHandCode[] = {
0x78, // push1
0x78, // push1
@@ -963,9 +1075,9 @@ const uint16 longbowPatchShowHandCode[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry longbowSignatures[] = {
- { 210, "hand code crash", 5, 0, 0, longbowSignatureShowHandCode, longbowPatchShowHandCode },
+ { true, 210, "hand code crash", 5, 0, 0, longbowSignatureShowHandCode, longbowPatchShowHandCode },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -985,7 +1097,7 @@ SciScriptPatcherEntry longbowSignatures[] = {
// We patch the script to use global 90, which seems to be unused in the whole game.
// Applies to at least: English floppy
// Responsible method: rm63Script::handleEvent
-// Fixes bug: #3614419
+// Fixes bug: #6346
const uint16 larry2SignatureWearParachutePoints[] = {
0x35, 0x01, // ldi 01
0xa1, SIG_MAGICDWORD, 0x8e, // sag 8e
@@ -1005,9 +1117,9 @@ const uint16 larry2PatchWearParachutePoints[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry larry2Signatures[] = {
- { 63, "plane: no points for wearing plane", 1, 0, 0, larry2SignatureWearParachutePoints, larry2PatchWearParachutePoints },
+ { true, 63, "plane: no points for wearing plane", 1, 0, 0, larry2SignatureWearParachutePoints, larry2PatchWearParachutePoints },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1034,9 +1146,9 @@ const uint16 larry5PatchGermanEndingPattiTalker[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry larry5Signatures[] = {
- { 380, "German-only: Enlarge Patti Textbox", 1, 0, 0, larry5SignatureGermanEndingPattiTalker, larry5PatchGermanEndingPattiTalker },
+ { true, 380, "German-only: Enlarge Patti Textbox", 1, 0, 0, larry5SignatureGermanEndingPattiTalker, larry5PatchGermanEndingPattiTalker },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1085,42 +1197,140 @@ const uint16 larry6PatchDeathDialog[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry larry6Signatures[] = {
- { 82, "death dialog memory corruption", 1, 0, 0, larry6SignatureDeathDialog, larry6PatchDeathDialog },
+ { true, 82, "death dialog memory corruption", 1, 0, 0, larry6SignatureDeathDialog, larry6PatchDeathDialog },
SCI_SIGNATUREENTRY_TERMINATOR
};
// ===========================================================================
-// rm560::doit was supposed to close the painting, when Heimlich enters the
-// room. The code is buggy. It actually closes the painting, when heimlich
-// is not in the room. We fix that.
-// Applies to at least: English floppy
+// Laura Bow 2
+//
+// Moving away the painting in the room with the hidden safe is problematic
+// for the CD version of the game. safePic::doVerb gets triggered by the mouse-click.
+// This method sets local 0 as signal, which is only meant to get handled, when
+// the player clicks again to move the painting back. This signal is processed by
+// the room doit-script.
+// That doit-script checks safePic::cel to be not equal 0 and would then skip over
+// the "close painting" trigger code. On very fast computers this script may
+// get called too early (which is the case when running under ScummVM and when
+// running the game using Sierra SCI in DOS-Box with cycles 15000) and thinks
+// that it's supposed to move the painting back. Which then results in the painting
+// getting moved to its original position immediately (which means it won't be possible
+// to access the safe behind it).
+//
+// We patch the script, so that we check for cel to be not equal 4 (the final cel) and
+// we also reset the safePic-signal immediately as well.
+//
+// In the floppy version Laura's coordinates are checked directly in rm560::doit
+// and as soon as she moves, the painting will automatically move to its original position.
+// This is not the case for the CD version of the game. The painting will only "move" back,
+// when the player actually exits the room and re-enters.
+//
+// Applies to at least: English PC-CD
// Responsible method: rm560::doit
-const uint16 laurabow2SignaturePaintingClosing[] = {
- 0x4a, 0x04, // send 04 - read aHeimlich::room
+// Fixes bug: #6460
+const uint16 laurabow2CDSignaturePaintingClosing[] = {
+ 0x39, 0x04, // pushi 04 (cel)
+ 0x76, // push0
SIG_MAGICDWORD,
+ 0x7a, // push2
+ 0x38, SIG_UINT16 + 0x31, 0x02, // pushi 0231h (561)
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 561)
+ 0x4a, 0x04, // send 04 (gets safePicture::cel)
+ 0x18, // not
+ 0x31, 0x21, // bnt [exit]
+ 0x38, SIG_UINT16 + 0x83, 0x02, // pushi 0283h
+ 0x76, // push0
+ 0x7a, // push2
+ 0x39, 0x20, // pushi 20
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 32)
+ 0x4a, 0x04, // send 04 (get sHeimlich::room)
0x36, // push
- 0x81, 0x0b, // lag global[11d] -> current room
+ 0x81, 0x0b, // lag global[b] (current room)
0x1c, // ne?
- 0x31, 0x0e, // bnt [don't close]
+ 0x31, 0x0e, // bnt [exit]
0x35, 0x00, // ldi 00
- 0xa3, 0x00, // sal local[0]
- 0x38, SIG_UINT16 + 0x92, 0x00, // pushi 0092
- 0x78, // push1
- 0x72, // lofsa sDumpSafe
+ 0xa3, 0x00, // sal local[0] -> reset safePic signal
SIG_END
};
-const uint16 laurabow2PatchPaintingClosing[] = {
- PATCH_ADDTOOFFSET +6,
- 0x2f, 0x0e, // bt [don't close]
+const uint16 laurabow2CDPatchPaintingClosing[] = {
+ PATCH_ADDTOOFFSET +2,
+ 0x3c, // dup (1 additional byte)
+ 0x76, // push0
+ 0x3c, // dup (1 additional byte)
+ 0xab, 0x00, // ssl local[0] -> reset safePic signal
+ 0x7a, // push2
+ 0x38, PATCH_UINT16 + 0x31, 0x02, // pushi 0231h (561)
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 561)
+ 0x4a, 0x04, // send 04 (gets safePicture::cel)
+ 0x1a, // eq?
+ 0x31, 0x1d, // bnt [exit]
+ 0x38, PATCH_UINT16 + 0x83, 0x02, // pushi 0283h
+ 0x76, // push0
+ 0x7a, // push2
+ 0x39, 0x20, // pushi 20
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 32)
+ 0x4a, 0x04, // send 04 (get sHeimlich::room)
+ 0x36, // push
+ 0x81, 0x0b, // lag global[b] (current room)
+ 0x1a, // eq? (2 opcodes changed, to save 2 bytes)
+ 0x2f, 0x0a, // bt [exit]
PATCH_END
};
-// script, description, signature patch
+// In the CD version the system menu is disabled for certain rooms. LB2::handsOff is called,
+// when leaving the room (and in other cases as well). This method remembers the disabled
+// icons of the icon bar. In the new room LB2::handsOn will get called, which then enables
+// all icons, but also disabled the ones, that were disabled before.
+//
+// Because of this behaviour certain rooms, that should have the system menu enabled, have
+// it disabled, when entering those rooms from rooms, where the menu is supposed to be
+// disabled.
+//
+// We patch this by injecting code into LB2::newRoom (which is called right after a room change)
+// and reset the global variable there, that normally holds the disabled buttons.
+//
+// This patch may cause side-effects and it's difficult to test, because it affects every room
+// in the game. At least for the intro, the speakeasy and plenty of rooms in the beginning it
+// seems to work correctly.
+//
+// Applies to at least: English PC-CD
+// Responsible method: LB2::newRoom, LB2::handsOff, LB2::handsOn
+// Fixes bug: #6440
+const uint16 laurabow2CDSignatureFixProblematicIconBar[] = {
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16 + 0xf1, 0x00, // pushi 00f1 (disable) - hardcoded, we only want to patch the CD version
+ 0x76, // push0
+ 0x81, 0x45, // lag global[45]
+ 0x4a, 0x04, // send 04
+ SIG_END
+};
+
+const uint16 laurabow2CDPatchFixProblematicIconBar[] = {
+ 0x35, 0x00, // ldi 00
+ 0xa1, 0x74, // sag 74h
+ 0x35, 0x00, // ldi 00 (waste bytes)
+ 0x35, 0x00, // ldi 00
+ PATCH_END
+};
+
+
+// script, description, signature patch
SciScriptPatcherEntry laurabow2Signatures[] = {
- { 560, "painting closing immediately", 1, 0, 0, laurabow2SignaturePaintingClosing, laurabow2PatchPaintingClosing },
+ { true, 560, "CD: painting closing immediately", 1, 0, 0, laurabow2CDSignaturePaintingClosing, laurabow2CDPatchPaintingClosing },
+ { true, 0, "CD: fix problematic icon bar", 1, 0, 0, laurabow2CDSignatureFixProblematicIconBar, laurabow2CDPatchFixProblematicIconBar },
+ // King's Quest 6 and Laura Bow 2 share basic patches for audio + text support
+ { false, 924, "CD: audio + text support 1", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
+ { false, 924, "CD: audio + text support 2", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
+ { false, 924, "CD: audio + text support 3", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 },
+ { false, 928, "CD: audio + text support 4", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 },
+ { false, 928, "CD: audio + text support 5", 2, 0, 0, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1158,11 +1368,11 @@ const uint16 mothergoose256PatchSaveLimit[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry mothergoose256Signatures[] = {
- { 0, "replay save issue", 1, 0, 0, mothergoose256SignatureReplay, mothergoose256PatchReplay },
- { 0, "save limit dialog (SCI1.1)", 1, 0, 0, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
- { 994, "save limit dialog (SCI1)", 1, 0, 0, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
+ { true, 0, "replay save issue", 1, 0, 0, mothergoose256SignatureReplay, mothergoose256PatchReplay },
+ { true, 0, "save limit dialog (SCI1.1)", 1, 0, 0, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
+ { true, 994, "save limit dialog (SCI1)", 1, 0, 0, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1178,7 +1388,7 @@ SciScriptPatcherEntry mothergoose256Signatures[] = {
// when the 2 seconds have passed and the locker got closed.
// Applies to at least: English floppy
// Responsible method: putGun::changeState (script 341)
-// Fixes bug: #3036933 / #3303802
+// Fixes bug: #5705 / #6400
const uint16 pq1vgaSignaturePutGunInLockerBug[] = {
0x35, 0x00, // ldi 00
0x1a, // eq?
@@ -1223,9 +1433,9 @@ const uint16 pq1vgaPatchPutGunInLockerBug[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry pq1vgaSignatures[] = {
- { 341, "put gun in locker bug", 1, 0, 0, pq1vgaSignaturePutGunInLockerBug, pq1vgaPatchPutGunInLockerBug },
+ { true, 341, "put gun in locker bug", 1, 0, 0, pq1vgaSignaturePutGunInLockerBug, pq1vgaPatchPutGunInLockerBug },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1287,7 +1497,7 @@ const uint16 qfg1vgaPatchFightEvents[] = {
// window text, which erases the window header text because of its length. To
// fix that, we allocate more temp space and move the pointer used for the
// window header a little bit, wherever it's used in script 814.
-// Fixes bug #3568431.
+// Fixes bug: #6139.
// Patch 1: Increase temp space
const uint16 qfg1vgaSignatureTempSpace[] = {
@@ -1323,7 +1533,7 @@ const uint16 qfg1vgaPatchDialogHeader[] = {
// edge case that can occur when Ego is set to sneak. Normally, when clicking on
// the crusher, ego is supposed to move close to position 79, 165. We change it
// to 85, 165, which is not an edge case thus the freeze is avoided.
-// Fixes bug #3585189.
+// Fixes bug: #6180
const uint16 qfg1vgaSignatureMoveToCrusher[] = {
SIG_MAGICDWORD,
0x51, 0x1f, // class Motion
@@ -1342,7 +1552,8 @@ const uint16 qfg1vgaPatchMoveToCrusher[] = {
// Same pathfinding bug as above, where Ego is set to move to an impossible
// spot when sneaking. In GuardsTrumpet::changeState, we change the final
-// location where Ego is moved from 111, 111 to 114, 114. Fixes bug #3604939.
+// location where Ego is moved from 111, 111 to 114, 114.
+// Fixes bug: #6248
const uint16 qfg1vgaSignatureMoveToCastleGate[] = {
SIG_MAGICDWORD,
0x51, 0x1f, // class MoveTo
@@ -1364,7 +1575,7 @@ const uint16 qfg1vgaPatchMoveToCastleGate[] = {
// The code treats both monster types the same.
// Applies to at least: English floppy
// Responsible method: smallMonster::doVerb
-// Fixes bug #3604943.
+// Fixes bug #6249
const uint16 qfg1vgaSignatureCheetaurDescription[] = {
SIG_MAGICDWORD,
0x34, SIG_UINT16 + 0xb8, 0x01, // ldi 01b8
@@ -1396,7 +1607,7 @@ const uint16 qfg1vgaPatchCheetaurDescription[] = {
// calling goTo6::init, so the whole issue is stopped from happening.
// Applies to at least: English floppy
// Responsible method: happyFace::changeState, door11::doit
-// Fixes bug #3585793
+// Fixes bug #6181
const uint16 qfg1vgaSignatureFunnyRoomFix[] = {
0x65, 0x14, // aTop 14 (state)
0x36, // push
@@ -1420,16 +1631,16 @@ const uint16 qfg1vgaPatchFunnyRoomFix[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry qfg1vgaSignatures[] = {
- { 215, "fight event issue", 1, 0, 0, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
- { 216, "weapon master event issue", 1, 0, 0, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
- { 814, "window text temp space", 1, 0, 0, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace },
- { 814, "dialog header offset", 3, 0, 0, qfg1vgaSignatureDialogHeader, qfg1vgaPatchDialogHeader },
- { 331, "moving to crusher", 1, 0, 0, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher },
- { 41, "moving to castle gate", 1, 0, 0, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate },
- { 210, "cheetaur description fixed", 1, 0, 0, qfg1vgaSignatureCheetaurDescription, qfg1vgaPatchCheetaurDescription },
- { 96, "funny room script bug fixed", 1, 0, 0, qfg1vgaSignatureFunnyRoomFix, qfg1vgaPatchFunnyRoomFix },
+ { true, 215, "fight event issue", 1, 0, 0, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
+ { true, 216, "weapon master event issue", 1, 0, 0, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
+ { true, 814, "window text temp space", 1, 0, 0, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace },
+ { true, 814, "dialog header offset", 3, 0, 0, qfg1vgaSignatureDialogHeader, qfg1vgaPatchDialogHeader },
+ { true, 331, "moving to crusher", 1, 0, 0, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher },
+ { true, 41, "moving to castle gate", 1, 0, 0, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate },
+ { true, 210, "cheetaur description fixed", 1, 0, 0, qfg1vgaSignatureCheetaurDescription, qfg1vgaPatchCheetaurDescription },
+ { true, 96, "funny room script bug fixed", 1, 0, 0, qfg1vgaSignatureFunnyRoomFix, qfg1vgaPatchFunnyRoomFix },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1445,8 +1656,8 @@ SciScriptPatcherEntry qfg1vgaSignatures[] = {
// deleted entries. We don't allow the user to change the directory, thus the
// contents of the file list are constant, so we can avoid the constant file
// and text entry refreshes whenever a button is pressed, and prevent possible
-// crashes because of these constant quick object reallocations. Fixes bug
-// #3037996.
+// crashes because of these constant quick object reallocations.
+// Fixes bug: #5096
const uint16 qfg2SignatureImportDialog[] = {
0x63, SIG_MAGICDWORD, 0x20, // pToa text
0x30, SIG_UINT16 + 0x0b, 0x00, // bnt [next state]
@@ -1465,9 +1676,9 @@ const uint16 qfg2PatchImportDialog[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry qfg2Signatures[] = {
- { 944, "import dialog continuous calls", 1, 0, 0, qfg2SignatureImportDialog, qfg2PatchImportDialog },
+ { true, 944, "import dialog continuous calls", 1, 0, 0, qfg2SignatureImportDialog, qfg2PatchImportDialog },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1494,7 +1705,7 @@ const uint16 qfg3PatchImportDialog[] = {
// ===========================================================================
-// Patch for the Woo dialog option in Uhura's conversation. Bug #3040722
+// Patch for the Woo dialog option in Uhura's conversation.
// Problem: The Woo dialog option (0xffb5) is negative, and therefore
// treated as an option opening a submenu. This leads to uhuraTell::doChild
// being called, which calls hero::solvePuzzle and then proceeds with
@@ -1508,6 +1719,7 @@ const uint16 qfg3PatchImportDialog[] = {
// behaviour.
// Applies to at least: English, German, Italian, French, Spanish Floppy
// Responsible method: unknown
+// Fixes bug: #5172
const uint16 qfg3SignatureWooDialog[] = {
SIG_MAGICDWORD,
0x67, 0x12, // pTos 12 (query)
@@ -1535,10 +1747,10 @@ const uint16 qfg3PatchWooDialog[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry qfg3Signatures[] = {
- { 944, "import dialog continuous calls", 1, 0, 0, qfg3SignatureImportDialog, qfg3PatchImportDialog },
- { 440, "dialog crash when asking about Woo", 1, 0, 0, qfg3SignatureWooDialog, qfg3PatchWooDialog },
+ { true, 944, "import dialog continuous calls", 1, 0, 0, qfg3SignatureImportDialog, qfg3PatchImportDialog },
+ { true, 440, "dialog crash when asking about Woo", 1, 0, 0, qfg3SignatureWooDialog, qfg3PatchWooDialog },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1548,7 +1760,8 @@ SciScriptPatcherEntry qfg3Signatures[] = {
// adds it to nest::x. The problem is that the script also checks if x exceeds
// we never reach that of course, so the pterodactyl-flight will go endlessly
// we could either calculate property count differently somehow fixing this
-// but I think just patching it out is cleaner (bug #3037938)
+// but I think just patching it out is cleaner.
+// Fixes bug: #5093
const uint16 sq4FloppySignatureEndlessFlight[] = {
0x39, 0x04, // pushi 04 (selector x)
SIG_MAGICDWORD,
@@ -1590,7 +1803,7 @@ const uint16 sq4CdPatchTextOptionsButton[] = {
// Patch 2: Adjust a check in babbleIcon::init, which handles the babble icon
// (e.g. the two guys from Andromeda) shown when dying/quitting.
-// Fixes bug #3538418.
+// Fixes bug: #6068
const uint16 sq4CdSignatureBabbleIcon[] = {
SIG_MAGICDWORD,
0x89, 0x5a, // lsg 5a
@@ -1655,12 +1868,12 @@ const uint16 sq4CdPatchTextOptions[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry sq4Signatures[] = {
- { 298, "Floppy: endless flight", 1, 0, 0, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight },
- { 818, "CD: Speech and subtitles option", 1, 0, 0, sq4CdSignatureTextOptions, sq4CdPatchTextOptions },
- { 0, "CD: Babble icon speech and subtitles fix", 1, 0, 0, sq4CdSignatureBabbleIcon, sq4CdPatchBabbleIcon },
- { 818, "CD: Speech and subtitles option button", 1, 0, 0, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton },
+ { true, 298, "Floppy: endless flight", 1, 0, 0, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight },
+ { true, 818, "CD: Speech and subtitles option", 1, 0, 0, sq4CdSignatureTextOptions, sq4CdPatchTextOptions },
+ { true, 0, "CD: Babble icon speech and subtitles fix", 1, 0, 0, sq4CdSignatureBabbleIcon, sq4CdPatchBabbleIcon },
+ { true, 818, "CD: Speech and subtitles option button", 1, 0, 0, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1732,10 +1945,10 @@ const uint16 sq1vgaPatchEgoShowsCard[] = {
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry sq1vgaSignatures[] = {
- { 45, "Ulence Flats: timepod graphic glitch", 1, 0, 0, sq1vgaSignatureUlenceFlatsTimepodGfxGlitch, sq1vgaPatchUlenceFlatsTimepodGfxGlitch },
- { 58, "Sarien armory droid zapping ego first time", 1, 0, 0, sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard },
+ { true, 45, "Ulence Flats: timepod graphic glitch", 1, 0, 0, sq1vgaSignatureUlenceFlatsTimepodGfxGlitch, sq1vgaPatchUlenceFlatsTimepodGfxGlitch },
+ { true, 58, "Sarien armory droid zapping ego first time", 1, 0, 0, sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard },
SCI_SIGNATUREENTRY_TERMINATOR};
// ===========================================================================
@@ -1759,7 +1972,7 @@ SciScriptPatcherEntry sq1vgaSignatures[] = {
// else is done in SCI system scripts and I don't want to touch those.
// Applies to at least: English/German/French PC floppy
// Responsible method: takeTool::changeState
-// Fixes bug #6457
+// Fixes bug: #6457
const uint16 sq5SignatureToolboxFix[] = {
0x31, 0x13, // bnt [check for state 1]
SIG_MAGICDWORD,
@@ -1790,9 +2003,9 @@ const uint16 sq5PatchToolboxFix[] = {
PATCH_END
};
-// script, description, signature patch
+// script, description, signature patch
SciScriptPatcherEntry sq5Signatures[] = {
- { 226, "toolbox fix", 1, 0, 0, sq5SignatureToolboxFix, sq5PatchToolboxFix },
+ { true, 226, "toolbox fix", 1, 0, 0, sq5SignatureToolboxFix, sq5PatchToolboxFix },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -2123,10 +2336,31 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS
}
}
+// This method enables certain patches
+// It's used for patches, which are not meant to get applied all the time
+void Script::patcherEnablePatch(SciScriptPatcherEntry *patchTable, const char *searchDescription) {
+ SciScriptPatcherEntry *curEntry = patchTable;
+ int searchDescriptionLen = strlen( searchDescription );
+ int matchCount = 0;
+
+ while (curEntry->signatureData) {
+ if (strncmp(curEntry->description, searchDescription, searchDescriptionLen) == 0) {
+ // match found, enable patch
+ curEntry->active = true;
+ matchCount++;
+ }
+ curEntry++;
+ }
+
+ if (!matchCount)
+ error("Script-Patcher: no patch found to enable");
+}
+
void Script::patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) {
SciScriptPatcherEntry *signatureTable = NULL;
+ const Sci::SciGameId gameId = g_sci->getGameId();
- switch (g_sci->getGameId()) {
+ switch (gameId) {
case GID_CAMELOT:
signatureTable = camelotSignatures;
break;
@@ -2146,11 +2380,7 @@ void Script::patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint3
signatureTable = gk1Signatures;
break;
case GID_KQ5:
- // See the explanation in the kq5SignatureWinGMSignals comment
- if (g_sci->_features->useAltWinGMSound())
- signatureTable = kq5WinGMSignatures;
- else
- signatureTable = kq5Signatures;
+ signatureTable = kq5Signatures;
break;
case GID_KQ6:
signatureTable = kq6Signatures;
@@ -2202,12 +2432,34 @@ void Script::patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint3
bool isMacSci11 = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1);
if (!signatureTable->magicDWord) {
+ // Abort, in case selectors are not yet initialized (happens for games w/o selector-dictionary)
+ if (!g_sci->getKernel()->selectorNamesAvailable())
+ return;
+
// signature table needs to get initialized (Magic DWORD set, selector table set)
patcherInitSignature(signatureTable, isMacSci11);
+
+ // Do additional game-specific initialization
+ switch (gameId) {
+ case GID_KQ5:
+ if (g_sci->_features->useAltWinGMSound()) {
+ // See the explanation in the kq5SignatureWinGMSignals comment
+ patcherEnablePatch(signatureTable, "Win: GM Music signal checks");
+ }
+ break;
+ case GID_LAURABOW2:
+ if (g_sci->speechAndSubtitlesEnabled()) {
+ // Enables Audio + subtitles patches for Laura Bow 2, when "Text and Speech: Both" is selected
+ patcherEnablePatch(signatureTable, "CD: audio + text support");
+ }
+ break;
+ default:
+ break;
+ }
}
while (signatureTable->signatureData) {
- if (scriptNr == signatureTable->scriptNr) {
+ if ( (scriptNr == signatureTable->scriptNr) && (signatureTable->active) ) {
int32 foundOffset = 0;
int16 applyCount = signatureTable->applyCount;
do {
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 074d3f6b0a..0667b75651 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -224,7 +224,7 @@ public:
* Allocate a fresh chunk of the hunk
* @param[in] size Number of bytes to allocate for the hunk entry
* @param[in] hunk_type A descriptive string for the hunk entry, for
- * debugging purposes
+ * debugging purposes
* @return The offset of the freshly allocated hunk entry
*/
reg_t allocateHunkEntry(const char *hunk_type, int size);
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 6c92f07272..6fdff1ce91 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -110,6 +110,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_KQ6, 520, 520, 0, "rm520", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // going to boiling water trap on beast isle
{ GID_KQ6, -1, 903, 0, "controlWin", "open", -1, 4, { WORKAROUND_FAKE, 0 } }, // when opening the controls window (save, load etc)
{ GID_KQ6, -1, 907, 0, "tomato", "doVerb", -1, 2, { WORKAROUND_FAKE, 0 } }, // when looking at the rotten tomato in the inventory - bug #3059544
+ { GID_KQ6, -1, 928, 0, NULL, "startText", -1, 0, { WORKAROUND_FAKE, 0 } }, // gets caused by Text+Audio support (see script patcher)
{ GID_KQ7, -1, 64996, 0, "User", "handleEvent", -1, 1, { WORKAROUND_FAKE, 0 } }, // called when pushing a keyboard key
{ GID_LAURABOW, 37, 0, 0, "CB1", "doit", -1, 1, { WORKAROUND_FAKE, 0 } }, // when going up the stairs (bug #3037694)
{ GID_LAURABOW, -1, 967, 0, "myIcon", "cycle", -1, 1, { WORKAROUND_FAKE, 0 } }, // having any portrait conversation coming up (initial bug #3034985)
@@ -117,6 +118,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_LAURABOW2, -1, 21, 0, "dropCluesCode", "doit", -1, 1, { WORKAROUND_FAKE, 0x7fff } }, // when asking some questions (e.g. the reporter about the burglary, or the policeman about Ziggy). Must be big, as the game scripts perform lt on it and start deleting journal entries - bugs #3035068, #3036274
{ GID_LAURABOW2, -1, 90, 1, "MuseumActor", "init", -1, 6, { WORKAROUND_FAKE, 0 } }, // Random actors in museum (bug #3041257)
{ GID_LAURABOW2, 240, 240, 0, "sSteveAnimates", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // Steve Dorian's idle animation at the docks - bug #3036291
+ { GID_LAURABOW2, -1, 928, 0, NULL, "startText", -1, 0, { WORKAROUND_FAKE, 0 } }, // gets caused by Text+Audio support (see script patcher)
{ GID_LONGBOW, -1, 0, 0, "Longbow", "restart", -1, 0, { WORKAROUND_FAKE, 0 } }, // When canceling a restart game - bug #3046200
{ GID_LONGBOW, -1, 213, 0, "clear", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // When giving an answer using the druid hand sign code in any room
{ GID_LONGBOW, -1, 213, 0, "letter", "handleEvent", 0xa8, 1, { WORKAROUND_FAKE, 0 } }, // When using the druid hand sign code in any room - bug #3036601