[Scummvm-cvs-logs] scummvm master -> eaf6367bb26b95af7e27ebbbb090664a3ad04e65

m-kiewitz m_kiewitz at users.sourceforge.net
Wed Dec 4 21:14:57 CET 2013


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
8bdffcb2fb SCI: script patcher is now a separate class
eaf6367bb2 Merge branch 'master' of github.com:scummvm/scummvm


Commit: 8bdffcb2fb7aefc96aa10fde1bebd372233cac9d
    https://github.com/scummvm/scummvm/commit/8bdffcb2fb7aefc96aa10fde1bebd372233cac9d
Author: Martin Kiewitz (m_kiewitz at users.sourceforge.net)
Date: 2013-12-04T11:42:16-08:00

Commit Message:
SCI: script patcher is now a separate class

Changed paths:
  A engines/sci/engine/script_patches.h
    engines/sci/console.cpp
    engines/sci/engine/savegame.cpp
    engines/sci/engine/script.cpp
    engines/sci/engine/script.h
    engines/sci/engine/script_patches.cpp
    engines/sci/engine/seg_manager.cpp
    engines/sci/engine/seg_manager.h
    engines/sci/sci.cpp
    engines/sci/sci.h



diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 80d8ab8..e7cbde6 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -2980,7 +2980,7 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
 	Script *script;
 	// Create a custom segment manager here, so that the game's segment
 	// manager won't be affected by loading and unloading scripts here.
-	SegManager *customSegMan = new SegManager(_engine->getResMan());
+	SegManager *customSegMan = new SegManager(_engine->getResMan(), _engine->getScriptPatcher());
 
 	Common::List<ResourceId>::iterator itr;
 	for (itr = resources.begin(); itr != resources.end(); ++itr) {
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index c60b50a..fbbab6b 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -484,7 +484,7 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) {
 	s.syncAsSint32LE(_nr);
 
 	if (s.isLoading())
-		load(_nr, g_sci->getResMan());
+		load(_nr, g_sci->getResMan(), g_sci->getScriptPatcher());
 	s.skip(4, VER(14), VER(22));		// OBSOLETE: Used to be _bufSize
 	s.skip(4, VER(14), VER(22));		// OBSOLETE: Used to be _scriptSize
 	s.skip(4, VER(14), VER(22));		// OBSOLETE: Used to be _heapSize
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 6616a0e..c661a00 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -32,7 +32,8 @@
 
 namespace Sci {
 
-Script::Script() : SegmentObj(SEG_TYPE_SCRIPT), _buf(NULL) {
+Script::Script()
+	: SegmentObj(SEG_TYPE_SCRIPT), _buf(NULL) {
 	freeScript();
 }
 
@@ -65,7 +66,7 @@ void Script::freeScript() {
 	_objects.clear();
 }
 
-void Script::load(int script_nr, ResourceManager *resMan) {
+void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher) {
 	freeScript();
 
 	Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, script_nr), 0);
@@ -136,7 +137,7 @@ void Script::load(int script_nr, ResourceManager *resMan) {
 	memcpy(_buf, script->data, script->size);
 
 	// Check scripts for matching signatures and patch those, if found
-	patcherProcessScript(_nr, _buf, script->size);
+	scriptPatcher->processScript(_nr, _buf, script->size);
 
 	if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) {
 		Resource *heap = resMan->findResource(ResourceId(kResourceTypeHeap, _nr), 0);
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index 6a27dc7..9e01615 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -25,6 +25,7 @@
 
 #include "common/str.h"
 #include "sci/engine/segment.h"
+#include "sci/engine/script_patches.h"
 
 namespace Sci {
 
@@ -96,13 +97,7 @@ public:
 	~Script();
 
 	void freeScript();
-	void load(int script_nr, ResourceManager *resMan);
-
-	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);
+	void load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher);
 
 	virtual bool isValidOffset(uint16 offset) const;
 	virtual SegmentRef dereference(reg_t pointer);
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 6293fb4..5370c59 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -25,6 +25,7 @@
 #include "sci/engine/script.h"
 #include "sci/engine/state.h"
 #include "sci/engine/features.h"
+#include "sci/engine/script_patches.h"
 
 #include "common/util.h"
 
@@ -76,72 +77,27 @@ namespace Sci {
 //        You have to use the exact same order in both the table and the enum, otherwise
 //        it won't work.
 
-#define SIG_END               0xFFFF
-#define SIG_MISMATCH          0xFFFE
-#define SIG_COMMANDMASK       0xF000
-#define SIG_VALUEMASK         0x0FFF
-#define SIG_BYTEMASK          0x00FF
-#define SIG_MAGICDWORD        0xF000
-#define SIG_ADDTOOFFSET       0xE000
-#define SIG_SELECTOR16        0x9000
-#define SIG_SELECTOR8         0x8000
-#define SIG_UINT16            0x1000
-#define SIG_BYTE              0x0000
-
-#define PATCH_END                   SIG_END
-#define PATCH_COMMANDMASK           SIG_COMMANDMASK
-#define PATCH_VALUEMASK             SIG_VALUEMASK
-#define PATCH_BYTEMASK              SIG_BYTEMASK
-#define PATCH_ADDTOOFFSET           SIG_ADDTOOFFSET
-#define PATCH_GETORIGINALBYTE       0xD000
-#define PATCH_GETORIGINALBYTEADJUST 0xC000
-#define PATCH_SELECTOR16            SIG_SELECTOR16
-#define PATCH_SELECTOR8             SIG_SELECTOR8
-#define PATCH_UINT16                SIG_UINT16
-#define PATCH_BYTE                  SIG_BYTE
-
-// defines maximum scratch area for getting original bytes from unpatched script data
-#define PATCH_VALUELIMIT      4096
-
-struct SciScriptPatcherEntry {
-	bool active;
-	uint16 scriptNr;
-	const char *description;
-	int16 applyCount;
-	uint32 magicDWord;
-	int magicOffset;
-	const uint16 *signatureData;
-	const uint16 *patchData;
-};
-
-#define SCI_SIGNATUREENTRY_TERMINATOR { false, 0, NULL, 0, 0, 0, NULL, NULL }
-
-struct SciScriptPatcherSelector {
-	const char *name;
-	int16 id;
-};
-
-SciScriptPatcherSelector selectorTable[] = {
-	{ "cycles",            -1, }, // system selector
-	{ "seconds",           -1, }, // system selector
-	{ "init",              -1, }, // system selector
-	{ "dispose",           -1, }, // system selector
-	{ "new",               -1, }, // system selector
-	{ "curEvent",          -1, }, // system selector
-	{ "disable",           -1, }, // system selector
-	{ "show",              -1, }, // system selector
-	{ "x",                 -1, }, // system selector
-	{ "cel",               -1, }, // system selector
-	{ "setMotion",         -1, }, // system selector
-	{ "deskSarg",          -1, }, // Gabriel Knight
-	{ "localize",          -1, }, // Freddy Pharkas
-	{ "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 }
+static const char *selectorNameTable[] = {
+	"cycles",       // system selector
+	"seconds",      // system selector
+	"init",         // system selector
+	"dispose",      // system selector
+	"new",          // system selector
+	"curEvent",     // system selector
+	"disable",      // system selector
+	"show",         // system selector
+	"x",            // system selector
+	"cel",          // system selector
+	"setMotion",    // system selector
+	"deskSarg",     // Gabriel Knight
+	"localize",     // Freddy Pharkas
+	"put",          // Police Quest 1 VGA
+	"solvePuzzle",  // Quest For Glory 3
+	"timesShownID", // Space Quest 1 VGA
+	"startText",    // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
+	"startAudio",   // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
+	"modNum",       // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
+	NULL
 };
 
 enum ScriptPatcherSelectors {
@@ -209,9 +165,9 @@ const uint16 camelotPatchPeepingTom[] = {
 	PATCH_END
 };
 
-//         script, description,                                            signature                   patch
+//         script, description,                                       signature                   patch
 SciScriptPatcherEntry camelotSignatures[] = {
-	{  true,   62, "fix peepingTom Sierra bug",                    1, 0, 0, camelotSignaturePeepingTom, camelotPatchPeepingTom },
+	{ true,    62, "fix peepingTom Sierra bug",                    1, camelotSignaturePeepingTom, camelotPatchPeepingTom },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -278,9 +234,9 @@ const uint16 ecoquest1PatchStayAndHelp[] = {
 	PATCH_END
 };
 
-//          script, description,                                            signature                      patch
+//          script, description,                                      signature                      patch
 SciScriptPatcherEntry ecoquest1Signatures[] = {
-	{  true,   660, "CD: bad messagebox and freeze",               1, 0, 0, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp },
+	{  true,   660, "CD: bad messagebox and freeze",               1, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -403,10 +359,10 @@ const uint16 ecoquest2PatchEcorderTutorial[] = {
 	PATCH_END
 };
 
-//          script, description,                                            signature                          patch
+//          script, description,                                      signature                          patch
 SciScriptPatcherEntry ecoquest2Signatures[] = {
-	{  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 },
+	{  true,    50, "initial text not removed on ecorder",         1, ecoquest2SignatureEcorder,         ecoquest2PatchEcorder },
+	{  true,   333, "initial text not removed on ecorder tutorial",1, ecoquest2SignatureEcorderTutorial, ecoquest2PatchEcorderTutorial },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -433,9 +389,9 @@ const uint16 fanmadePatchInfiniteLoop[] = {
 	PATCH_END
 };
 
-//          script, description,                                            signature                     patch
+//          script, description,                                      signature                     patch
 SciScriptPatcherEntry fanmadeSignatures[] = {
-	{  true,   999, "infinite loop on typo",                       1, 0, 0, fanmadeSignatureInfiniteLoop, fanmadePatchInfiniteLoop },
+	{  true,   999, "infinite loop on typo",                       1, fanmadeSignatureInfiniteLoop, fanmadePatchInfiniteLoop },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -556,10 +512,10 @@ const uint16 freddypharkasPatchMacInventory[] = {
 
 //          script, description,                                            signature                            patch
 SciScriptPatcherEntry freddypharkasSignatures[] = {
-	{  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 },
+	{  true,     0, "CD: score early disposal",                    1, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal },
+	{  true,    15, "Mac: broken inventory",                       1, freddypharkasSignatureMacInventory,  freddypharkasPatchMacInventory },
+	{  true,   235, "CD: canister pickup hang",                    3, freddypharkasSignatureCanisterHang,  freddypharkasPatchCanisterHang },
+	{  true,   320, "ladder event issue",                          2, freddypharkasSignatureLadderEvent,   freddypharkasPatchLadderEvent },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -697,10 +653,10 @@ const uint16 gk1PatchInterrogationBug[] = {
 
 //          script, description,                                            signature                     patch
 SciScriptPatcherEntry gk1Signatures[] = {
-	{  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 },
+	{  true,    51, "interrogation bug",                           1, gk1SignatureInterrogationBug, gk1PatchInterrogationBug },
+	{  true,   212, "day 5 phone freeze",                          1, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
+	{  true,   230, "day 6 police beignet timer issue",            1, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
+	{  true,   230, "day 6 police sleep timer issue",              1, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -821,9 +777,9 @@ const uint16 kq5PatchWinGMSignals[] = {
 
 //          script, description,                                            signature                  patch
 SciScriptPatcherEntry kq5Signatures[] = {
-	{  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 },
+	{  true,     0, "CD: harpy volume change",                     1, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
+	{  true,   200, "CD: witch cage init",                         1, kq5SignatureWitchCageInit, kq5PatchWitchCageInit },
+	{ false,   124, "Win: GM Music signal checks",                 4, kq5SignatureWinGMSignals, kq5PatchWinGMSignals },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1019,19 +975,19 @@ const uint16 kq6laurabow2CDPatchAudioTextSupport5[] = {
 	PATCH_END
 };
 
-//          script, description,                                            signature                     patch
+//          script, description,                                      signature                     patch
 SciScriptPatcherEntry kq6Signatures[] = {
-	{  true,   481, "duplicate baby cry",                          1, 0, 0, kq6SignatureDuplicateBabyCry, kq6PatchDuplicateBabyCry },
-	{  true,   907, "inventory stack fix",                         1, 0, 0, kq6SignatureInventoryStackFix, kq6PatchInventoryStackFix },
+	{  true,   481, "duplicate baby cry",                          1, kq6SignatureDuplicateBabyCry, kq6PatchDuplicateBabyCry },
+	{  true,   907, "inventory stack fix",                         1, 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 },
+	{ false,   924, "CD: audio + text support 1",                  1, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
+	{ false,   924, "CD: audio + text support 2",                  1, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
+	{ false,   924, "CD: audio + text support 3",                  1, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 },
+	{ false,   928, "CD: audio + text support 4",                  1, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 },
+	{ false,   928, "CD: audio + text support 5",                  2, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1075,9 +1031,9 @@ const uint16 longbowPatchShowHandCode[] = {
 	PATCH_END
 };
 
-//          script, description,                                            signature                     patch
+//          script, description,                                      signature                     patch
 SciScriptPatcherEntry longbowSignatures[] = {
-	{  true,   210, "hand code crash",                             5, 0, 0, longbowSignatureShowHandCode, longbowPatchShowHandCode },
+	{  true,   210, "hand code crash",                             5, longbowSignatureShowHandCode, longbowPatchShowHandCode },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1119,7 +1075,7 @@ const uint16 larry2PatchWearParachutePoints[] = {
 
 //          script, description,                                            signature                           patch
 SciScriptPatcherEntry larry2Signatures[] = {
-	{  true,    63, "plane: no points for wearing plane",          1, 0, 0, larry2SignatureWearParachutePoints, larry2PatchWearParachutePoints },
+	{  true,    63, "plane: no points for wearing plane",          1, larry2SignatureWearParachutePoints, larry2PatchWearParachutePoints },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1148,7 +1104,7 @@ const uint16 larry5PatchGermanEndingPattiTalker[] = {
 
 //          script, description,                                            signature                               patch
 SciScriptPatcherEntry larry5Signatures[] = {
-	{  true,   380, "German-only: Enlarge Patti Textbox",          1, 0, 0, larry5SignatureGermanEndingPattiTalker, larry5PatchGermanEndingPattiTalker },
+	{  true,   380, "German-only: Enlarge Patti Textbox",          1, larry5SignatureGermanEndingPattiTalker, larry5PatchGermanEndingPattiTalker },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1199,7 +1155,7 @@ const uint16 larry6PatchDeathDialog[] = {
 
 //          script, description,                                            signature                   patch
 SciScriptPatcherEntry larry6Signatures[] = {
-	{  true,    82, "death dialog memory corruption",              1, 0, 0, larry6SignatureDeathDialog, larry6PatchDeathDialog },
+	{  true,    82, "death dialog memory corruption",              1, larry6SignatureDeathDialog, larry6PatchDeathDialog },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1323,14 +1279,14 @@ const uint16 laurabow2CDPatchFixProblematicIconBar[] = {
 
 //          script, description,                                            signature                                  patch
 SciScriptPatcherEntry laurabow2Signatures[] = {
-	{  true,   560, "CD: painting closing immediately",            1, 0, 0, laurabow2CDSignaturePaintingClosing,       laurabow2CDPatchPaintingClosing },
-	{  true,     0, "CD: fix problematic icon bar",                1, 0, 0, laurabow2CDSignatureFixProblematicIconBar, laurabow2CDPatchFixProblematicIconBar },
+	{  true,   560, "CD: painting closing immediately",            1, laurabow2CDSignaturePaintingClosing,       laurabow2CDPatchPaintingClosing },
+	{  true,     0, "CD: fix problematic icon bar",                1, 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 },
+	{ false,   924, "CD: audio + text support 1",                  1, kq6laurabow2CDSignatureAudioTextSupport1,  kq6laurabow2CDPatchAudioTextSupport1 },
+	{ false,   924, "CD: audio + text support 2",                  1, kq6laurabow2CDSignatureAudioTextSupport2,  kq6laurabow2CDPatchAudioTextSupport2 },
+	{ false,   924, "CD: audio + text support 3",                  1, kq6laurabow2CDSignatureAudioTextSupport3,  kq6laurabow2CDPatchAudioTextSupport3 },
+	{ false,   928, "CD: audio + text support 4",                  1, kq6laurabow2CDSignatureAudioTextSupport4,  kq6laurabow2CDPatchAudioTextSupport4 },
+	{ false,   928, "CD: audio + text support 5",                  2, kq6laurabow2CDSignatureAudioTextSupport5,  kq6laurabow2CDPatchAudioTextSupport5 },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1370,9 +1326,9 @@ const uint16 mothergoose256PatchSaveLimit[] = {
 
 //          script, description,                                            signature                         patch
 SciScriptPatcherEntry mothergoose256Signatures[] = {
-	{  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 },
+	{  true,     0, "replay save issue",                           1, mothergoose256SignatureReplay,    mothergoose256PatchReplay },
+	{  true,     0, "save limit dialog (SCI1.1)",                  1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
+	{  true,   994, "save limit dialog (SCI1)",                    1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1435,7 +1391,7 @@ const uint16 pq1vgaPatchPutGunInLockerBug[] = {
 
 //          script, description,                                            signature                         patch
 SciScriptPatcherEntry pq1vgaSignatures[] = {
-	{  true,   341, "put gun in locker bug",                       1, 0, 0, pq1vgaSignaturePutGunInLockerBug, pq1vgaPatchPutGunInLockerBug },
+	{  true,   341, "put gun in locker bug",                       1, pq1vgaSignaturePutGunInLockerBug, pq1vgaPatchPutGunInLockerBug },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1633,14 +1589,14 @@ const uint16 qfg1vgaPatchFunnyRoomFix[] = {
 
 //          script, description,                                            signature                            patch
 SciScriptPatcherEntry qfg1vgaSignatures[] = {
-	{  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 },
+	{  true,   215, "fight event issue",                           1, qfg1vgaSignatureFightEvents,         qfg1vgaPatchFightEvents },
+	{  true,   216, "weapon master event issue",                   1, qfg1vgaSignatureFightEvents,         qfg1vgaPatchFightEvents },
+	{  true,   814, "window text temp space",                      1, qfg1vgaSignatureTempSpace,           qfg1vgaPatchTempSpace },
+	{  true,   814, "dialog header offset",                        3, qfg1vgaSignatureDialogHeader,        qfg1vgaPatchDialogHeader },
+	{  true,   331, "moving to crusher",                           1, qfg1vgaSignatureMoveToCrusher,       qfg1vgaPatchMoveToCrusher },
+	{  true,    41, "moving to castle gate",                       1, qfg1vgaSignatureMoveToCastleGate,    qfg1vgaPatchMoveToCastleGate },
+	{  true,   210, "cheetaur description fixed",                  1, qfg1vgaSignatureCheetaurDescription, qfg1vgaPatchCheetaurDescription },
+	{  true,    96, "funny room script bug fixed",                 1, qfg1vgaSignatureFunnyRoomFix,        qfg1vgaPatchFunnyRoomFix },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1678,7 +1634,7 @@ const uint16 qfg2PatchImportDialog[] = {
 
 //          script, description,                                            signature                  patch
 SciScriptPatcherEntry qfg2Signatures[] = {
-	{  true,   944, "import dialog continuous calls",              1, 0, 0, qfg2SignatureImportDialog, qfg2PatchImportDialog },
+	{  true,   944, "import dialog continuous calls",              1, qfg2SignatureImportDialog, qfg2PatchImportDialog },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1749,8 +1705,8 @@ const uint16 qfg3PatchWooDialog[] = {
 
 //          script, description,                                            signature                  patch
 SciScriptPatcherEntry qfg3Signatures[] = {
-	{  true,   944, "import dialog continuous calls",              1, 0, 0, qfg3SignatureImportDialog, qfg3PatchImportDialog },
-	{  true,   440, "dialog crash when asking about Woo",          1, 0, 0, qfg3SignatureWooDialog,    qfg3PatchWooDialog },
+	{  true,   944, "import dialog continuous calls",              1, qfg3SignatureImportDialog, qfg3PatchImportDialog },
+	{  true,   440, "dialog crash when asking about Woo",          1, qfg3SignatureWooDialog,    qfg3PatchWooDialog },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1870,10 +1826,10 @@ const uint16 sq4CdPatchTextOptions[] = {
 
 //          script, description,                                            signature                        patch
 SciScriptPatcherEntry sq4Signatures[] = {
-	{  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 },
+	{  true,   298, "Floppy: endless flight",                      1, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight },
+	{  true,   818, "CD: Speech and subtitles option",             1, sq4CdSignatureTextOptions,       sq4CdPatchTextOptions },
+	{  true,     0, "CD: Babble icon speech and subtitles fix",    1, sq4CdSignatureBabbleIcon,        sq4CdPatchBabbleIcon },
+	{  true,   818, "CD: Speech and subtitles option button",      1, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -1947,8 +1903,8 @@ const uint16 sq1vgaPatchEgoShowsCard[] = {
 
 //          script, description,                                            signature                                   patch
 SciScriptPatcherEntry sq1vgaSignatures[] = {
-	{  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 },
+	{  true,    45, "Ulence Flats: timepod graphic glitch",        1, sq1vgaSignatureUlenceFlatsTimepodGfxGlitch, sq1vgaPatchUlenceFlatsTimepodGfxGlitch },
+	{  true,    58, "Sarien armory droid zapping ego first time",  1, sq1vgaSignatureEgoShowsCard,                sq1vgaPatchEgoShowsCard },
 	SCI_SIGNATUREENTRY_TERMINATOR};
 
 // ===========================================================================
@@ -2005,13 +1961,31 @@ const uint16 sq5PatchToolboxFix[] = {
 
 //          script, description,                                            signature                        patch
 SciScriptPatcherEntry sq5Signatures[] = {
-	{  true,   226, "toolbox fix",                                 1, 0, 0, sq5SignatureToolboxFix,          sq5PatchToolboxFix },
+	{  true,   226, "toolbox fix",                                 1, sq5SignatureToolboxFix,          sq5PatchToolboxFix },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
+// =================================================================================
+
+ScriptPatcher::ScriptPatcher() {
+	int selectorCount = ARRAYSIZE(selectorNameTable);
+	int selectorNr;
+
+	// Allocate table for selector-IDs and initialize that table as well
+	_selectorIdTable = new Selector[ selectorCount ];
+	for (selectorNr = 0; selectorNr < selectorCount; selectorNr++)
+		_selectorIdTable[selectorNr] = -1;
+		
+	_runtimeTable = NULL;
+}
+
+ScriptPatcher::~ScriptPatcher() {
+	delete[] _runtimeTable;
+	delete[] _selectorIdTable;
+}
 
 // will actually patch previously found signature area
-void Script::patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, const bool isMacSci11) {
+void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, const bool isMacSci11) {
 	const uint16 *patchData = patchEntry->patchData;
 	byte orgData[PATCH_VALUELIMIT];
 	int32 offset = signatureOffset;
@@ -2067,7 +2041,7 @@ void Script::patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc
 				break;
 			}
 			case PATCH_SELECTOR16: {
-				patchSelector = selectorTable[patchValue].id;
+				patchSelector = _selectorIdTable[patchValue];
 				byte1 = patchSelector & 0xFF;
 				byte2 = patchSelector >> 8;
 				break;
@@ -2086,7 +2060,7 @@ void Script::patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc
 			break;
 		}
 		case PATCH_SELECTOR8: {
-			patchSelector = selectorTable[patchValue].id;
+			patchSelector = _selectorIdTable[patchValue];
 			if (patchSelector & 0xFF00)
 				error("Script-Patcher: 8 bit selector required, game uses 16 bit selector");
 			scriptData[offset] = patchSelector & 0xFF;
@@ -2103,18 +2077,18 @@ void Script::patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc
 }
 
 // will return -1 if no match was found, otherwise an offset to the start of the signature match
-int32 Script::patcherFindSignature(const SciScriptPatcherEntry *patchEntry, const byte *scriptData, const uint32 scriptSize, const bool isMacSci11) {
+int32 ScriptPatcher::findSignature(const SciScriptPatcherEntry *patchEntry, SciScriptPatcherRuntimeEntry *runtimeEntry, const byte *scriptData, const uint32 scriptSize, const bool isMacSci11) {
 	if (scriptSize < 4) // we need to find a DWORD, so less than 4 bytes is not okay
 		return -1;
 
-	const uint32 magicDWord = patchEntry->magicDWord; // is platform-specific BE/LE form, so that the later match will work
+	const uint32 magicDWord = runtimeEntry->magicDWord; // is platform-specific BE/LE form, so that the later match will work
 	const uint32 searchLimit = scriptSize - 3;
 	uint32 DWordOffset = 0;
 	// first search for the magic DWORD
 	while (DWordOffset < searchLimit) {
 		if (magicDWord == READ_UINT32(scriptData + DWordOffset)) {
 			// magic DWORD found, check if actual signature matches
-			uint32 offset = DWordOffset + patchEntry->magicOffset;
+			uint32 offset = DWordOffset + runtimeEntry->magicOffset;
 			uint32 byteOffset = offset;
 			const uint16 *signatureData = patchEntry->signatureData;
 			uint16 sigSelector = 0;
@@ -2145,7 +2119,7 @@ int32 Script::patcherFindSignature(const SciScriptPatcherEntry *patchEntry, cons
 							break;
 						}
 						case SIG_SELECTOR16: {
-							sigSelector = selectorTable[sigValue].id;
+							sigSelector = _selectorIdTable[sigValue];
 							byte1 = sigSelector & 0xFF;
 							byte2 = sigSelector >> 8;
 							break;
@@ -2169,7 +2143,7 @@ int32 Script::patcherFindSignature(const SciScriptPatcherEntry *patchEntry, cons
 				}
 				case SIG_SELECTOR8: {
 					if (byteOffset < scriptSize) {
-						sigSelector = selectorTable[sigValue].id;
+						sigSelector = _selectorIdTable[sigValue];
 						if (sigSelector & 0xFF00)
 							error("Script-Patcher: 8 bit selector required, game uses 16 bit selector\nFaulty patch: '%s'", patchEntry->description);
 						if (scriptData[byteOffset] != (sigSelector & 0xFF))
@@ -2208,9 +2182,10 @@ int32 Script::patcherFindSignature(const SciScriptPatcherEntry *patchEntry, cons
 
 // This method calculates the magic DWORD for each entry in the signature table
 //  and it also initializes the selector table for selectors used in the signatures/patches of the current game
-void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacSci11) {
+void ScriptPatcher::initSignature(SciScriptPatcherEntry *patchTable, bool isMacSci11) {
 	SciScriptPatcherEntry *curEntry = patchTable;
-	SciScriptPatcherSelector *curSelector = NULL;
+	SciScriptPatcherRuntimeEntry *curRuntimeEntry;
+	Selector curSelector = -1;
 	int step;
 	int magicOffset;
 	byte magicDWord[4];
@@ -2221,10 +2196,24 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS
     uint32 curValue;
     byte byte1;
     byte byte2;
+    int patchEntryCount = 0;
+    
+    // Count entries and allocate runtime data
+    while (curEntry->signatureData) {
+		patchEntryCount++; curEntry++;
+    }
+    _runtimeTable = new SciScriptPatcherRuntimeEntry[patchEntryCount];
+    memset(_runtimeTable, 0, sizeof(SciScriptPatcherRuntimeEntry) * patchEntryCount);
 
+	curEntry = patchTable;
+	curRuntimeEntry = _runtimeTable;
     while (curEntry->signatureData) {
 		// process signature
 		memset(magicDWord, 0, sizeof(magicDWord));
+		
+		curRuntimeEntry->active = curEntry->defaultActive;
+		curRuntimeEntry->magicDWord = 0;
+		curRuntimeEntry->magicOffset = 0;
 
 		for (step = 0; step < 2; step++) {
 			switch (step) {
@@ -2240,10 +2229,10 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS
 				switch (curCommand) {
 				case SIG_MAGICDWORD: {
 					if (step == 0) {
-						if ((curEntry->magicDWord) || (magicDWordLeft))
+						if ((curRuntimeEntry->magicDWord) || (magicDWordLeft))
 							error("Script-Patcher: Magic-DWORD specified multiple times in signature\nFaulty patch: '%s'", curEntry->description);
 						magicDWordLeft = 4;
-						curEntry->magicOffset = magicOffset;
+						curRuntimeEntry->magicOffset = magicOffset;
 					}
 					break;
 				}
@@ -2271,15 +2260,17 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS
 						break;
 					}
 					case SIG_SELECTOR16: {
-						curSelector = &selectorTable[curValue];
-						if (curSelector->id == -1)
-							curSelector->id = g_sci->getKernel()->findSelector(curSelector->name);
+						curSelector = _selectorIdTable[curValue];
+						if (curSelector == -1) {
+							curSelector = g_sci->getKernel()->findSelector(selectorNameTable[curValue]);
+							_selectorIdTable[curValue] = curSelector;
+						}
 						if (!isMacSci11) {
-							byte1 = curSelector->id & 0x00FF;
-							byte2 = curSelector->id >> 8;
+							byte1 = curSelector & 0x00FF;
+							byte2 = curSelector >> 8;
 						} else {
-							byte1 = curSelector->id >> 8;
-							byte2 = curSelector->id & 0x00FF;
+							byte1 = curSelector >> 8;
+							byte2 = curSelector & 0x00FF;
 						}
 						break;
 					}
@@ -2294,7 +2285,7 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS
 							magicDWordLeft--;
 						}
 						if (!magicDWordLeft) {
-							curEntry->magicDWord = READ_LE_UINT32(magicDWord);
+							curRuntimeEntry->magicDWord = READ_LE_UINT32(magicDWord);
 						}
 					}
 					break;
@@ -2302,15 +2293,16 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS
 				case SIG_BYTE:
 				case SIG_SELECTOR8: {
 					if (curCommand == SIG_SELECTOR8) {
-						curSelector = &selectorTable[curValue];
-						if (curSelector->id == -1) {
-							curSelector->id = g_sci->getKernel()->findSelector(curSelector->name);
-							if (curSelector->id != -1) {
-								if (curSelector->id & 0xFF00)
+						curSelector = _selectorIdTable[curValue];
+						if (curSelector == -1) {
+							curSelector = g_sci->getKernel()->findSelector(selectorNameTable[curValue]);
+							_selectorIdTable[curValue] = curSelector;
+							if (curSelector != -1) {
+								if (curSelector & 0xFF00)
 									error("Script-Patcher: 8 bit selector required, game uses 16 bit selector\nFaulty patch: '%s'", curEntry->description);
 							}
 						}
-						curValue = curSelector->id;
+						curValue = curSelector;
 					}
 					magicOffset--;
 					if (magicDWordLeft) {
@@ -2318,7 +2310,7 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS
 						magicDWord[4 - magicDWordLeft] = (byte)curValue;
 						magicDWordLeft--;
 						if (!magicDWordLeft) {
-							curEntry->magicDWord = READ_LE_UINT32(magicDWord);
+							curRuntimeEntry->magicDWord = READ_LE_UINT32(magicDWord);
 						}
 					}
 				}
@@ -2329,35 +2321,38 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS
 		}
 		if (magicDWordLeft)
 			error("Script-Patcher: Magic-DWORD beyond End-Of-Signature\nFaulty patch: '%s'", curEntry->description);
-		if (!curEntry->magicDWord)
+		if (!curRuntimeEntry->magicDWord)
 			error("Script-Patcher: Magic-DWORD not specified in signature\nFaulty patch: '%s'", curEntry->description);
     
-		curEntry++;
+		curEntry++; curRuntimeEntry++;
     }
 }
 
 // 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) {
+void ScriptPatcher::enablePatch(SciScriptPatcherEntry *patchTable, const char *searchDescription) {
 	SciScriptPatcherEntry *curEntry = patchTable;
+	SciScriptPatcherRuntimeEntry *runtimeEntry = _runtimeTable;
 	int searchDescriptionLen = strlen( searchDescription );
 	int matchCount = 0;
 	
     while (curEntry->signatureData) {
 		if (strncmp(curEntry->description, searchDescription, searchDescriptionLen) == 0) {
 			// match found, enable patch
-			curEntry->active = true;
+			runtimeEntry->active = true;
 			matchCount++;
 		}
-		curEntry++;
+		curEntry++; runtimeEntry++;
     }
     
     if (!matchCount)
 		error("Script-Patcher: no patch found to enable");
 }
 
-void Script::patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) {
+void ScriptPatcher::processScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) {
 	SciScriptPatcherEntry *signatureTable = NULL;
+	SciScriptPatcherEntry *curEntry = NULL;
+	SciScriptPatcherRuntimeEntry *curRuntimeEntry = NULL;
 	const Sci::SciGameId gameId = g_sci->getGameId();
 
 	switch (gameId) {
@@ -2431,48 +2426,51 @@ void Script::patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint3
 	if (signatureTable) {
 		bool isMacSci11 = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1);
 
-		if (!signatureTable->magicDWord) {
+		if (!_runtimeTable) {
 			// 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);
+			initSignature(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");
+					enablePatch(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");
+					enablePatch(signatureTable, "CD: audio + text support");
 				}
 				break;
 			default:
 				break;
 			}
 		}
+
+		curEntry = signatureTable;
+		curRuntimeEntry = _runtimeTable;
 	
-		while (signatureTable->signatureData) {
-			if ( (scriptNr == signatureTable->scriptNr) && (signatureTable->active) ) {
+		while (curEntry->signatureData) {
+			if ( (scriptNr == curEntry->scriptNr) && (curRuntimeEntry->active) ) {
 				int32 foundOffset = 0;
-				int16 applyCount = signatureTable->applyCount;
+				int16 applyCount = curEntry->applyCount;
 				do {
-					foundOffset = patcherFindSignature(signatureTable, scriptData, scriptSize, isMacSci11);
+					foundOffset = findSignature(curEntry, curRuntimeEntry, scriptData, scriptSize, isMacSci11);
 					if (foundOffset != -1) {
 						// found, so apply the patch
-						debugC(kDebugLevelScriptPatcher, "Script-Patcher: '%s' on script %d offset %d", signatureTable->description, scriptNr, foundOffset);
-						patcherApplyPatch(signatureTable, scriptData, scriptSize, foundOffset, isMacSci11);
+						debugC(kDebugLevelScriptPatcher, "Script-Patcher: '%s' on script %d offset %d", curEntry->description, scriptNr, foundOffset);
+						applyPatch(curEntry, scriptData, scriptSize, foundOffset, isMacSci11);
 					}
 					applyCount--;
 				} while ((foundOffset != -1) && (applyCount));
 			}
-			signatureTable++;
+			curEntry++; curRuntimeEntry++;
 		}
 	}
 }
diff --git a/engines/sci/engine/script_patches.h b/engines/sci/engine/script_patches.h
new file mode 100644
index 0000000..77cb2c7
--- /dev/null
+++ b/engines/sci/engine/script_patches.h
@@ -0,0 +1,100 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SCI_ENGINE_SCRIPT_PATCHES_H
+#define SCI_ENGINE_SCRIPT_PATCHES_H
+
+#include "sci/sci.h"
+
+namespace Sci {
+
+#define SIG_END               0xFFFF
+#define SIG_MISMATCH          0xFFFE
+#define SIG_COMMANDMASK       0xF000
+#define SIG_VALUEMASK         0x0FFF
+#define SIG_BYTEMASK          0x00FF
+#define SIG_MAGICDWORD        0xF000
+#define SIG_ADDTOOFFSET       0xE000
+#define SIG_SELECTOR16        0x9000
+#define SIG_SELECTOR8         0x8000
+#define SIG_UINT16            0x1000
+#define SIG_BYTE              0x0000
+
+#define PATCH_END                   SIG_END
+#define PATCH_COMMANDMASK           SIG_COMMANDMASK
+#define PATCH_VALUEMASK             SIG_VALUEMASK
+#define PATCH_BYTEMASK              SIG_BYTEMASK
+#define PATCH_ADDTOOFFSET           SIG_ADDTOOFFSET
+#define PATCH_GETORIGINALBYTE       0xD000
+#define PATCH_GETORIGINALBYTEADJUST 0xC000
+#define PATCH_SELECTOR16            SIG_SELECTOR16
+#define PATCH_SELECTOR8             SIG_SELECTOR8
+#define PATCH_UINT16                SIG_UINT16
+#define PATCH_BYTE                  SIG_BYTE
+
+// defines maximum scratch area for getting original bytes from unpatched script data
+#define PATCH_VALUELIMIT      4096
+
+struct SciScriptPatcherEntry {
+	bool defaultActive;
+//	bool active;
+	uint16 scriptNr;
+	const char *description;
+	int16 applyCount;
+//	uint32 magicDWord;
+//	int magicOffset;
+	const uint16 *signatureData;
+	const uint16 *patchData;
+};
+
+//#define SCI_SIGNATUREENTRY_TERMINATOR { false, 0, NULL, 0, 0, 0, NULL, NULL }
+#define SCI_SIGNATUREENTRY_TERMINATOR { false, 0, NULL, 0, NULL, NULL }
+
+struct SciScriptPatcherRuntimeEntry {
+	bool active;
+	uint32 magicDWord;
+	int magicOffset;
+};
+
+/**
+ * ScriptPatcher class, handles on-the-fly patching of script data
+ */
+class ScriptPatcher {
+public:
+	ScriptPatcher();
+	~ScriptPatcher();
+
+	void processScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize);
+
+private:
+	void initSignature(SciScriptPatcherEntry *patchTable, bool isMacSci11);
+	void enablePatch(SciScriptPatcherEntry *patchTable, const char *searchDescription);
+	int32 findSignature(const SciScriptPatcherEntry *patchEntry, SciScriptPatcherRuntimeEntry *runtimeEntry, const byte *scriptData, const uint32 scriptSize, bool isMacSci11);
+	void applyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, bool isMacSci11);
+	
+	Selector *_selectorIdTable;
+	SciScriptPatcherRuntimeEntry *_runtimeTable;
+};
+
+} // End of namespace Sci
+
+#endif // SCI_ENGINE_WORKAROUNDS_H
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index a059bee..161a4f5 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -28,7 +28,8 @@
 namespace Sci {
 
 
-SegManager::SegManager(ResourceManager *resMan) {
+SegManager::SegManager(ResourceManager *resMan, ScriptPatcher *scriptPatcher)
+	: _resMan(resMan), _scriptPatcher(scriptPatcher) {
 	_heap.push_back(0);
 
 	_clonesSegId = 0;
@@ -44,8 +45,6 @@ SegManager::SegManager(ResourceManager *resMan) {
 	_stringSegId = 0;
 #endif
 
-	_resMan = resMan;
-
 	createClassTable();
 }
 
@@ -983,7 +982,7 @@ int SegManager::instantiateScript(int scriptNum) {
 		scr = allocateScript(scriptNum, &segmentId);
 	}
 
-	scr->load(scriptNum, _resMan);
+	scr->load(scriptNum, _resMan, _scriptPatcher);
 	scr->initializeLocals(this);
 	scr->initializeClasses(this);
 	scr->initializeObjects(this, segmentId);
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 074d3f6..b73399d 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -49,7 +49,7 @@ public:
 	/**
 	 * Initialize the segment manager.
 	 */
-	SegManager(ResourceManager *resMan);
+	SegManager(ResourceManager *resMan, ScriptPatcher *scriptPatcher);
 
 	/**
 	 * Deallocate all memory associated with the segment manager.
@@ -448,6 +448,7 @@ private:
 	Common::HashMap<int, SegmentId> _scriptSegMap;
 
 	ResourceManager *_resMan;
+	ScriptPatcher *_scriptPatcher;
 
 	SegmentId _clonesSegId; ///< ID of the (a) clones segment
 	SegmentId _listsSegId; ///< ID of the (a) list segment
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 065565d..69a7c0b 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -38,6 +38,7 @@
 #include "sci/engine/state.h"
 #include "sci/engine/kernel.h"
 #include "sci/engine/script.h"	// for script_adjust_opcode_formats
+#include "sci/engine/script_patches.h"
 #include "sci/engine/selector.h"	// for SELECTOR
 
 #include "sci/sound/audio.h"
@@ -184,6 +185,7 @@ SciEngine::~SciEngine() {
 
 	delete[] _opcode_formats;
 
+	delete _scriptPatcher;
 	delete _resMan;	// should be deleted last
 	g_sci = 0;
 }
@@ -217,8 +219,9 @@ Common::Error SciEngine::run() {
 	// Add the after market GM patches for the specified game, if they exist
 	_resMan->addNewGMPatch(_gameId);
 	_gameObjectAddress = _resMan->findGameObject();
-
-	SegManager *segMan = new SegManager(_resMan);
+	
+	_scriptPatcher = new ScriptPatcher();
+	SegManager *segMan = new SegManager(_resMan, _scriptPatcher);
 
 	// Initialize the game screen
 	_gfxScreen = new GfxScreen(_resMan);
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index c91606f..418f8c5 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -55,6 +55,7 @@ class AudioPlayer;
 class SoundCommandParser;
 class EventManager;
 class SegManager;
+class ScriptPatcher;
 
 class GfxAnimate;
 class GfxCache;
@@ -269,6 +270,7 @@ public:
 	bool hasMacIconBar() const;
 
 	inline ResourceManager *getResMan() const { return _resMan; }
+	inline ScriptPatcher *getScriptPatcher() const { return _scriptPatcher; }
 	inline Kernel *getKernel() const { return _kernel; }
 	inline EngineState *getEngineState() const { return _gamestate; }
 	inline Vocabulary *getVocabulary() const { return _vocabulary; }
@@ -400,6 +402,7 @@ private:
 	const ADGameDescription *_gameDescription;
 	const SciGameId _gameId;
 	ResourceManager *_resMan; /**< The resource manager */
+	ScriptPatcher *_scriptPatcher; /**< The script patcher */
 	EngineState *_gamestate;
 	Kernel *_kernel;
 	Vocabulary *_vocabulary;


Commit: eaf6367bb26b95af7e27ebbbb090664a3ad04e65
    https://github.com/scummvm/scummvm/commit/eaf6367bb26b95af7e27ebbbb090664a3ad04e65
Author: Martin Kiewitz (m_kiewitz at users.sourceforge.net)
Date: 2013-12-04T11:42:50-08:00

Commit Message:
Merge branch 'master' of github.com:scummvm/scummvm

Changed paths:
  A backends/platform/symbian/help/Custom.xml
  A backends/platform/symbian/help/ScummVM.rtf
  A backends/platform/symbian/help/ScummVM.xml
  A backends/platform/symbian/help/build_help.mk
  A backends/platform/symbian/mmp/scummvm_avalanche.mmp.in
  A backends/platform/symbian/mmp/scummvm_dreamweb.mmp.in
  A backends/platform/symbian/mmp/scummvm_fullpipe.mmp.in
  A backends/platform/symbian/mmp/scummvm_mortevielle.mmp.in
  A backends/platform/symbian/mmp/scummvm_neverhood.mmp.in
  A backends/platform/symbian/mmp/scummvm_sword25.mmp.in
  A backends/platform/symbian/mmp/scummvm_testbed.mmp.in
  A backends/platform/symbian/mmp/scummvm_zvision.mmp.in
  A common/ustr.cpp
  A common/ustr.h
  A engines/agi/configure.engine
  A engines/agos/configure.engine
  A engines/avalanche/configure.engine
  A engines/avalanche/nim.cpp
  A engines/avalanche/nim.h
  A engines/cge/configure.engine
  A engines/cine/configure.engine
  A engines/composer/configure.engine
  A engines/cruise/configure.engine
  A engines/draci/configure.engine
  A engines/drascula/configure.engine
  A engines/dreamweb/configure.engine
  A engines/fullpipe/configure.engine
  A engines/gob/configure.engine
  A engines/groovie/configure.engine
  A engines/hopkins/configure.engine
  A engines/hugo/configure.engine
  A engines/kyra/configure.engine
  A engines/lastexpress/configure.engine
  A engines/lure/configure.engine
  A engines/made/configure.engine
  A engines/mohawk/configure.engine
  A engines/mortevielle/configure.engine
  A engines/neverhood/configure.engine
  A engines/parallaction/configure.engine
  A engines/pegasus/configure.engine
  A engines/queen/configure.engine
  A engines/saga/configure.engine
  A engines/sci/configure.engine
  A engines/scumm/configure.engine
  A engines/sky/configure.engine
  A engines/sword1/configure.engine
  A engines/sword2/configure.engine
  A engines/sword25/configure.engine
  A engines/teenagent/configure.engine
  A engines/testbed/configure.engine
  A engines/tinsel/configure.engine
  A engines/toltecs/configure.engine
  A engines/tony/configure.engine
  A engines/toon/configure.engine
  A engines/touche/configure.engine
  A engines/tsage/configure.engine
  A engines/tucker/configure.engine
  A engines/wintermute/configure.engine
  A engines/zvision/configure.engine
  R engines/configure.engines
  R engines/engines.mk
  R engines/plugins_table.h
    .gitignore
    Makefile
    Makefile.common
    backends/platform/symbian/AdaptAllMMPs.pl
    backends/platform/symbian/BuildPackageUpload_AllVersions.pl
    backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
    backends/platform/symbian/README
    backends/platform/symbian/S60v3/BLD.INF.in
    backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg
    backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3_split.pkg
    backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg
    backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3_split.pkg
    backends/platform/symbian/mmp/scummvm_base.mmp.in
    backends/platform/symbian/mmp/scummvm_kyra.mmp.in
    backends/platform/symbian/mmp/scummvm_mohawk.mmp.in
    backends/platform/symbian/mmp/scummvm_sci.mmp.in
    backends/platform/symbian/src/SymbianOS.cpp
    backends/platform/symbian/src/portdefs.h
    common/module.mk
    common/str.h
    configure
    devtools/create_project/codeblocks.cpp
    devtools/create_project/config.h
    devtools/create_project/create_project.cpp
    devtools/create_project/create_project.h
    devtools/create_project/msbuild.cpp
    devtools/create_project/visualstudio.cpp
    devtools/create_project/xcode.cpp
    engines/agos/icons.cpp
    engines/avalanche/animation.cpp
    engines/avalanche/animation.h
    engines/avalanche/avalanche.cpp
    engines/avalanche/avalanche.h
    engines/avalanche/avalot.cpp
    engines/avalanche/avalot.h
    engines/avalanche/background.cpp
    engines/avalanche/console.cpp
    engines/avalanche/detection.cpp
    engines/avalanche/dialogs.cpp
    engines/avalanche/enums.h
    engines/avalanche/graphics.cpp
    engines/avalanche/menu.cpp
    engines/avalanche/module.mk
    engines/avalanche/parser.cpp
    engines/avalanche/parser.h
    engines/avalanche/timer.cpp
    engines/draci/barchive.cpp
    engines/draci/game.cpp
    engines/draci/script.cpp
    engines/fullpipe/behavior.cpp
    engines/fullpipe/behavior.h
    engines/fullpipe/constants.h
    engines/fullpipe/fullpipe.h
    engines/fullpipe/gfx.cpp
    engines/fullpipe/init.cpp
    engines/fullpipe/motion.cpp
    engines/fullpipe/objectnames.h
    engines/fullpipe/scenes.cpp
    engines/fullpipe/scenes.h
    engines/fullpipe/scenes/scene04.cpp
    engines/fullpipe/sound.cpp
    engines/fullpipe/statics.cpp
    engines/fullpipe/utils.cpp
    engines/groovie/font.cpp
    engines/groovie/font.h
    engines/hopkins/events.cpp
    engines/hopkins/graphics.cpp
    engines/hopkins/talk.cpp
    engines/lastexpress/entities/entity.h
    engines/lastexpress/entities/servers0.cpp
    engines/lastexpress/entities/verges.cpp
    engines/lastexpress/game/entities.h
    engines/lastexpress/game/logic.cpp
    engines/lastexpress/game/logic.h
    engines/lastexpress/game/object.cpp
    engines/lastexpress/game/savegame.h
    engines/lastexpress/game/state.h
    engines/made/detection.cpp
    engines/made/screenfx.cpp
    engines/made/sound.cpp
    engines/neverhood/detection.cpp
    engines/neverhood/gamemodule.cpp
    engines/parallaction/exec.h
    engines/parallaction/gui_ns.cpp
    engines/parallaction/input.h
    engines/parallaction/objects.h
    engines/parallaction/parallaction.h
    engines/parallaction/parser.h
    engines/parallaction/sound.h
    engines/pegasus/timers.cpp
    engines/saga/saga.h
    engines/sci/detection_tables.h
    engines/sci/engine/kfile.cpp
    engines/sci/engine/savegame.cpp
    engines/sci/engine/seg_manager.h
    engines/sci/resource.h
    engines/sci/sound/soundcmd.cpp
    engines/scumm/detection.cpp
    engines/scumm/saveload.cpp
    engines/scumm/scumm.h
    engines/sword25/gfx/image/art.cpp
    engines/sword25/gfx/renderobjectmanager.cpp
    engines/sword25/util/lua/lopcodes.cpp
    engines/sword25/util/lua/lua.h
    engines/tinsel/music.cpp
    engines/toltecs/render.cpp
    engines/toltecs/saveload.cpp
    engines/toltecs/screen.cpp
    engines/toltecs/script.cpp
    engines/toltecs/toltecs.cpp
    engines/tony/mpal/mpal.cpp
    engines/tsage/blue_force/blueforce_logic.cpp
    engines/tsage/blue_force/blueforce_logic.h
    engines/tsage/blue_force/blueforce_scenes3.cpp
    engines/tsage/blue_force/blueforce_scenes3.h
    engines/tsage/blue_force/blueforce_scenes4.cpp
    engines/tsage/blue_force/blueforce_scenes4.h
    engines/tsage/blue_force/blueforce_scenes5.cpp
    engines/tsage/blue_force/blueforce_scenes5.h
    engines/tsage/blue_force/blueforce_scenes7.cpp
    engines/tsage/blue_force/blueforce_scenes8.cpp
    engines/tsage/blue_force/blueforce_scenes8.h
    engines/tsage/blue_force/blueforce_scenes9.cpp
    engines/tsage/converse.cpp
    engines/tsage/core.cpp
    engines/tsage/core.h
    engines/tsage/debugger.cpp
    engines/tsage/debugger.h
    engines/tsage/detection_tables.h
    engines/tsage/events.cpp
    engines/tsage/globals.cpp
    engines/tsage/globals.h
    engines/tsage/graphics.cpp
    engines/tsage/graphics.h
    engines/tsage/ringworld/ringworld_scenes1.h
    engines/tsage/ringworld/ringworld_scenes10.cpp
    engines/tsage/ringworld2/ringworld2_dialogs.cpp
    engines/tsage/ringworld2/ringworld2_dialogs.h
    engines/tsage/ringworld2/ringworld2_logic.cpp
    engines/tsage/ringworld2/ringworld2_logic.h
    engines/tsage/ringworld2/ringworld2_scenes0.cpp
    engines/tsage/ringworld2/ringworld2_scenes1.cpp
    engines/tsage/ringworld2/ringworld2_scenes1.h
    engines/tsage/ringworld2/ringworld2_scenes3.cpp
    engines/tsage/ringworld2/ringworld2_scenes3.h
    engines/tsage/saveload.h
    engines/tsage/sound.cpp
    engines/tsage/sound.h
    engines/wintermute/base/base_file_manager.cpp
    engines/wintermute/base/font/base_font_truetype.cpp
    engines/wintermute/base/font/base_font_truetype.h
    engines/wintermute/base/scriptables/script_ext_string.cpp
    engines/wintermute/dctypes.h
    engines/wintermute/utils/string_util.cpp
    engines/wintermute/utils/string_util.h
    graphics/font.cpp
    graphics/font.h
    graphics/fonts/bdf.cpp
    graphics/fonts/bdf.h
    graphics/fonts/ttf.cpp
    graphics/fonts/winfont.cpp
    graphics/fonts/winfont.h
    graphics/surface.h
    gui/widgets/editable.cpp
    gui/widgets/editable.h
    gui/widgets/edittext.cpp
    gui/widgets/list.cpp
    ports.mk
    video/avi_decoder.cpp
    video/avi_decoder.h
    video/codecs/mpeg.h









More information about the Scummvm-git-logs mailing list