[Scummvm-cvs-logs] SF.net SVN: scummvm:[51795] scummvm/trunk/engines/sci

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Fri Aug 6 20:54:58 CEST 2010


Revision: 51795
          http://scummvm.svn.sourceforge.net/scummvm/?rev=51795&view=rev
Author:   m_kiewitz
Date:     2010-08-06 18:54:58 +0000 (Fri, 06 Aug 2010)

Log Message:
-----------
SCI: adding script patching

including a patch for hoyle 4 and commenting out the workaround code inside kDisposeWindow

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/script.cpp
    scummvm/trunk/engines/sci/engine/script.h
    scummvm/trunk/engines/sci/graphics/ports.cpp

Modified: scummvm/trunk/engines/sci/engine/script.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/script.cpp	2010-08-06 18:10:53 UTC (rev 51794)
+++ scummvm/trunk/engines/sci/engine/script.cpp	2010-08-06 18:54:58 UTC (rev 51795)
@@ -119,6 +119,13 @@
 //  - then another counter of bytes (0 for EOS)
 //  - if not EOS, an adjust offset and the actual bytes
 //  - rinse and repeat
+
+
+// this here gets called on entry and when going out of game windows
+//  uEvt::port will not get changed after kDisposeWindow but a bit later, so
+//  we would get an invalid port handle to a kSetPort call. We just patch in
+//  resetting of the port selector. We destroy the stop/fade code in there,
+//  it seems it isn't used at all in the game.
 const byte hoyle4SignaturePortFix[] = {
 	28,
 	0x39, 0x09,        // pushi 09
@@ -132,14 +139,22 @@
 	0x38, 0xbc, 0x02,  // pushi 02bc
 	0x38, 0x20, 0x03,  // pushi 0320
 	0x46,              // calle [xxxx] [xxxx] [xx]
-	13, +5,            // [skip 5 bytes]
+	43, +5,            // [skip 5 bytes]
 	0x30, 0x27, 0x00,  // bnt 0027 -> end of routine
 	0x87, 0x00,        // lap 00
 	0x30, 0x19, 0x00,  // bnt 0019 -> fade out
 	0x87, 0x01,        // lap 01
 	0x30, 0x14, 0x00,  // bnt 0014 -> fade out
-	// [...]
-	10, +20,           // [skip 20 bytes]
+	0x38, 0xa7, 0x00,  // pushi 00a7
+	0x76,              // push0
+	0x80, 0x29, 0x01,  // lag 0129
+	0x4a, 0x04,        // send 04 (song::stop)
+	0x39, 0x27,        // pushi 27
+	0x78,              // push1
+	0x8f, 0x01,        // lsp 01
+	0x51, 0x54,        // class 54
+	0x4a, 0x06,        // send 06 (PlaySong::play)
+	0x33, 0x09,        // jmp 09 -> end of routine
 	0x38, 0xaa, 0x00,  // pushi 00aa
 	0x76,              // push0
 	0x80, 0x29, 0x01,  // lag 0129
@@ -148,8 +163,23 @@
 	0
 };
 
-const int16 hoyle4PatchPortFix[] = {
-	0
+#define PATCH_END             0xFFFF
+#define PATCH_ADDTOOFFSET     0x8000
+#define PATCH_GETORIGINALBYTE 0x4000
+
+const uint16 hoyle4PatchPortFix[] = {
+	PATCH_ADDTOOFFSET | +33,
+	0x38, 0x31, 0x01,  // pushi 0131 (selector curEvent)
+	0x76,              // push0
+	0x80, 0x50, 0x00,  // lag 0050 (global var 80h, "User")
+	0x4a, 0x04,        // send 04 (read User::curEvent)
+
+	0x38, 0x93, 0x00,  // pushi 0093 (selector port)
+	0x78,              // push1
+	0x78,              // push1
+	0x4a, 0x06,        // send 06 (write 0 to that object::port)
+	0x48,              // ret
+	PATCH_END
 };
 
 //    script, description,                                   magic DWORD,                adjust
@@ -158,6 +188,25 @@
     {      0, NULL,                                          0,                              0, NULL,                     NULL }
 };
 
+// will actually patch previously found signature area
+void Script::applyPatch(const uint16 *patch, byte *scriptData, const uint32 scriptSize, int32 signatureOffset) {
+	int32 offset = signatureOffset;
+	uint16 patchWord = *patch;
+
+	while (patchWord != PATCH_END) {
+		if (patchWord & PATCH_ADDTOOFFSET) {
+			offset += patchWord & ~PATCH_ADDTOOFFSET;
+		} else if (patchWord & PATCH_GETORIGINALBYTE) {
+			// TODO: implement this
+		} else {
+			scriptData[offset] = patchWord & 0xFF;
+			offset++;
+		}
+		patch++;
+		patchWord = *patch;
+	}	
+}
+
 // will return -1 if no match was found, otherwise an offset to the start of the signature match
 int32 Script::findSignature(const SciScriptSignature *signature, const byte *scriptData, const uint32 scriptSize) {
 	if (scriptSize < 4) // we need to find a DWORD, so less than 4 bytes is not okay
@@ -196,7 +245,7 @@
 	return -1;
 }
 
-void Script::matchSignatureAndPatch(uint16 scriptNr, const byte *scriptData, const uint32 scriptSize) {
+void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) {
 	if (g_sci->getGameId() == GID_HOYLE4) {
 		const SciScriptSignature *signatureTable = hoyle4Signatures;
 		while (signatureTable->data) {
@@ -204,6 +253,7 @@
 			if (foundOffset != -1) {
 				// found, so apply the patch
 				warning("matched %s on script %d offset %d", signatureTable->description, scriptNr, foundOffset);
+				applyPatch(signatureTable->patch, scriptData, scriptSize, foundOffset);
 			}
 			signatureTable++;
 		}

Modified: scummvm/trunk/engines/sci/engine/script.h
===================================================================
--- scummvm/trunk/engines/sci/engine/script.h	2010-08-06 18:10:53 UTC (rev 51794)
+++ scummvm/trunk/engines/sci/engine/script.h	2010-08-06 18:54:58 UTC (rev 51795)
@@ -37,7 +37,7 @@
 	uint32 magicDWord;
 	int magicOffset;
 	const byte *data;
-	const int16 *patch;
+	const uint16 *patch;
 };
 
 struct EngineState;
@@ -109,8 +109,9 @@
 	void init(int script_nr, ResourceManager *resMan);
 	void load(ResourceManager *resMan);
 
-	void matchSignatureAndPatch(uint16 scriptNr, const byte *scriptData, const uint32 scriptSize);
+	void matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uint32 scriptSize);
 	int32 findSignature(const SciScriptSignature *signature, const byte *scriptData, const uint32 scriptSize);
+	void applyPatch(const uint16 *patch, byte *scriptData, const uint32 scriptSize, int32 signatureOffset);
 
 	virtual bool isValidOffset(uint16 offset) const;
 	virtual SegmentRef dereference(reg_t pointer);

Modified: scummvm/trunk/engines/sci/graphics/ports.cpp
===================================================================
--- scummvm/trunk/engines/sci/graphics/ports.cpp	2010-08-06 18:10:53 UTC (rev 51794)
+++ scummvm/trunk/engines/sci/graphics/ports.cpp	2010-08-06 18:54:58 UTC (rev 51795)
@@ -250,10 +250,10 @@
 		//  and iconReplay
 		//  or inside GameControls::hide (script 978) which is called to
 		//  actually remove the window
-		reg_t eventObject = _segMan->findObjectByName("uEvt");
-		if (!eventObject.isNull()) {
-			writeSelectorValue(_segMan, eventObject, SELECTOR(port), 0);
-		}
+		//reg_t eventObject = _segMan->findObjectByName("uEvt");
+		//if (!eventObject.isNull()) {
+		//	writeSelectorValue(_segMan, eventObject, SELECTOR(port), 0);
+		//}
 	}
 }
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list