[Scummvm-git-logs] scummvm-tools master -> 9b0d1f71aa037a535199d0b63eb90701922bd1d0

sdelamarre noreply at scummvm.org
Wed Aug 30 21:30:03 UTC 2023


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

Summary:
70264bfd70 GOB: Fix a crash in degob for some command line args combinations
68396c146e GOB: Display hotspot creation details in degob
9b0d1f71aa GOB: Implement an unpackData() extension used in some games


Commit: 70264bfd70ab84f7cb9943f0c13253d22b320832
    https://github.com/scummvm/scummvm-tools/commit/70264bfd70ab84f7cb9943f0c13253d22b320832
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-08-30T22:55:34+02:00

Commit Message:
GOB: Fix a crash in degob for some command line args combinations

Changed paths:
    engines/gob/degob.cpp


diff --git a/engines/gob/degob.cpp b/engines/gob/degob.cpp
index f0f09bdd..0bc33e66 100644
--- a/engines/gob/degob.cpp
+++ b/engines/gob/degob.cpp
@@ -89,9 +89,11 @@ int main(int argc, char **argv) {
 			n++;
 		}
 
-		if (!strncmp(argv[n], "--lib", 5)) {
-			libMode = true;
-			n++;
+		if (argc > n) {
+			if (!strncmp(argv[n], "--lib", 5)) {
+				libMode = true;
+				n++;
+			}
 		}
 
 		if (argc > n) {


Commit: 68396c146ecd4cfaf8abe084d8c0e00600e9bde7
    https://github.com/scummvm/scummvm-tools/commit/68396c146ecd4cfaf8abe084d8c0e00600e9bde7
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-08-30T23:08:42+02:00

Commit Message:
GOB: Display hotspot creation details in degob

Previously, hotspot creation blocks were represented by a single "hotspots->evaluate()" line without any further details. We now display the hotspot data defined by these blocks (coordinates, type, callbacks offsets...).
As a consequence, functions only reachable as a hotspot callback will now appear in degob output, while they were previously forgotten.

Changed paths:
    engines/gob/degob_script.cpp
    engines/gob/degob_script.h
    engines/gob/degob_script_v1.cpp


diff --git a/engines/gob/degob_script.cpp b/engines/gob/degob_script.cpp
index 20a6a4ff..9d55b309 100644
--- a/engines/gob/degob_script.cpp
+++ b/engines/gob/degob_script.cpp
@@ -239,6 +239,7 @@ uint32 Script::getPos() const { return _ptr - _totData; }
 uint32 Script::lastOffsetPos() const { return _lastOffsetPos - _totData; }
 void Script::updateOffsetPos(uint32 pos) { _lastOffsetPos = _totData + pos; }
 void Script::skip(uint32 off) { seek(off, SEEK_CUR); }
+void Script::skipBlock() {seek(peekUint16(2) + 2, SEEK_CUR);}
 void Script::seek(uint32 off, int whence) {
 	switch (whence) {
 	case SEEK_END:
diff --git a/engines/gob/degob_script.h b/engines/gob/degob_script.h
index 49c450c9..451bf5bf 100644
--- a/engines/gob/degob_script.h
+++ b/engines/gob/degob_script.h
@@ -71,6 +71,7 @@ public:
 	uint32 lastOffsetPos() const;
 	void updateOffsetPos(uint32 pos);
 	void skip(uint32 off);
+	void skipBlock();
 	void seek(uint32 off, int whence = SEEK_SET);
 
 	// Properties getter
@@ -234,6 +235,7 @@ protected:
 
 	// Control functions
 	void o1_callSub(FuncParams &params);
+	void hotspotsEvaluate();
 	void o1_switch(FuncParams &params);
 	void o1_repeatUntil(FuncParams &params);
 	void o1_whileDo(FuncParams &params);
diff --git a/engines/gob/degob_script_v1.cpp b/engines/gob/degob_script_v1.cpp
index cf1e82c9..ed25302f 100644
--- a/engines/gob/degob_script_v1.cpp
+++ b/engines/gob/degob_script_v1.cpp
@@ -740,6 +740,137 @@ void Script_v1::o1_goblinFunc(FuncParams &params) {
 	goblinOpcode(cmd, gobParams);
 }
 
+enum Type {
+	kTypeNone              =  0,
+	kTypeMove              =  1,
+	kTypeClick             =  2,
+	kTypeInput1NoLeave     =  3,
+	kTypeInput1Leave       =  4,
+	kTypeInput2NoLeave     =  5,
+	kTypeInput2Leave       =  6,
+	kTypeInput3NoLeave     =  7,
+	kTypeInput3Leave       =  8,
+	kTypeInputFloatNoLeave =  9,
+	kTypeInputFloatLeave   = 10,
+	kTypeEnable2           = 11,
+	kTypeEnable1           = 12,
+	kTypeClickEnter        = 21
+};
+
+void Script_v1::hotspotsEvaluate()
+{
+	skip(1);
+	byte count = readUint8();
+	printIndent();
+	print("set_hotspot_count(%d);\n", count);
+
+	printIndent();
+	print("set_hotspot_properties(handleMouse=%d, duration=%d, leaveWinIndex=%d, hotspotIndex1=%d, hotspotIndex2=%d, needRecalc=%d)\n",
+		  peekUint8(0),
+		  peekUint8(1),
+		  peekUint8(2),
+		  peekUint8(3),
+		  peekUint8(4),
+		  peekUint8(5) != 0);
+
+	skip(6);
+
+	for (uint16 i = 0; i < count; i++) {
+		printIndent();
+		print("add_hotspot(%d, ", i);
+		byte type = readUint8();
+		print("%d", type);
+		if ((type & 0x40) != 0) {
+			type -= 0x40;
+			print(", %d", readUint8());
+		}
+		if ((type & 0x80) != 0) {
+			// Complex coordinate expressions
+			print(", %d", getPos());
+			print(", %s", readExpr().c_str());
+			print(", %s", readExpr().c_str());
+			print(", %s", readExpr().c_str());
+			print(", %s", readExpr().c_str());
+		} else {
+			// Immediate values
+			print(", %d", readUint16());
+			print(", %d", readUint16());
+			print(", %d", readUint16());
+			print(", %d", readUint16());
+		}
+
+		type &= 0x7F;
+
+		// Evaluate parameters for the new hotspot
+		switch (type) {
+		// TODO: handle kTypeEnable1 and kTypeEnable2 types
+		case kTypeNone:
+			skip(6);
+			print(", %d", getPos());
+			addFuncOffset(getPos());
+			skipBlock();
+			print(", %d", getPos());
+			addFuncOffset(getPos());
+			skipBlock();
+			break;
+
+		case kTypeMove:
+			print(", %d", readUint16());
+			print(", %d", readUint16());
+			print(", %d", readUint16());
+			print(", %d", getPos());
+			addFuncOffset(getPos());
+			skipBlock();
+			print(", %d", getPos());
+			addFuncOffset(getPos());
+			skipBlock();
+			break;
+
+		case kTypeInput1NoLeave:
+		case kTypeInput1Leave:
+		case kTypeInput2NoLeave:
+		case kTypeInput2Leave:
+		case kTypeInput3NoLeave:
+		case kTypeInput3Leave:
+		case kTypeInputFloatNoLeave:
+		case kTypeInputFloatLeave:
+			print(", %d", readUint16());
+			print(", %d", readUint16());
+			print(", %d", readUint8());
+			print(", %d", readUint8());
+			if ((type >= kTypeInput2NoLeave) && (type <= kTypeInput3Leave)) {
+				print(", %d", readUint16());
+				print(", %s", readString());
+			}
+			skipBlock();
+			break;
+
+		case 20:
+		case kTypeClick:
+			print(", %d", readUint16());
+			print(", %d", readUint16());
+			print(", %d", readUint16());
+			print(", 0");
+			print(", %d", getPos());
+			addFuncOffset(getPos());
+			skipBlock();
+			break;
+
+		case kTypeClickEnter:
+			print(", %d", readUint16());
+			print(", %d", readUint16());
+			print(", %d", readUint16() & 3);
+			print(", %d", getPos());
+			addFuncOffset(getPos());
+			skipBlock();
+			print(", 0");
+			break;
+		}
+
+		print(");\n");
+	}
+}
+
 void Script_v1::o1_callSub(FuncParams &params) {
 	uint16 offset = readUint16();
 
@@ -753,8 +884,14 @@ void Script_v1::o1_callSub(FuncParams &params) {
 		print("sub_%d();\n", offset);
 		if (offset >= 128)
 			addFuncOffset(offset);
-	} else if (peekUint8() == 2)
-		print("_hotspots->evaluate()(%d);\n", offset);
+	} else if (peekUint8() == 2) {
+		print("_hotspots->evaluate()(%d) {\n", offset);
+		incIndent();
+		hotspotsEvaluate();
+		decIndent();
+		printIndent();
+		print("}\n");
+	}
 	else
 		print("<Unknown block type %d (%d)>\n", peekUint8(), offset);
 


Commit: 9b0d1f71aa037a535199d0b63eb90701922bd1d0
    https://github.com/scummvm/scummvm-tools/commit/9b0d1f71aa037a535199d0b63eb90701922bd1d0
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-08-30T23:28:15+02:00

Commit Message:
GOB: Implement an unpackData() extension used in some games

This extension allows larger strings to be copied from the LZ77-sliding window when unpacking.

Changed paths:
    engines/gob/extract_gob_stk.cpp


diff --git a/engines/gob/extract_gob_stk.cpp b/engines/gob/extract_gob_stk.cpp
index 8b4217e6..15b29bcd 100644
--- a/engines/gob/extract_gob_stk.cpp
+++ b/engines/gob/extract_gob_stk.cpp
@@ -319,18 +319,33 @@ void ExtractGobStk::extractChunks(Common::Filename &outpath, Common::File &stk)
 byte *ExtractGobStk::unpackData(byte *src, uint32 &size) {
 	uint32 counter;
 	uint16 cmd;
-	byte tmpBuf[4114];
+	byte tmpBuf[4370]; // 4096 + (256 + 18) = 4096 + (max string length)
 	int16 off;
-	byte len;
+	int16 len;
 	uint16 tmpIndex;
 
 	counter = size = READ_LE_UINT32(src);
+	src += 4;
+	uint16 magic1 = READ_LE_UINT16(src);
+	src += 2;
+	uint16 magic2 = READ_LE_UINT16(src);
+	src += 2;
 
-	for (int i = 0; i < 4078; i++)
-		tmpBuf[i] = 0x20;
-	tmpIndex = 4078;
+	int16 extendedLenCmd;
+	if ((magic1 == 0x1234) && (magic2 == 0x5678)) {
+		// Extended format allowing to copy larger strings
+		// from the window (up to 256 + 18 = 274 bytes).
+		extendedLenCmd = 18;
+		tmpIndex = 273;
+	} else {
+		// Standard format allowing to copy short strings
+		// (up to 18 bytes) from the window.
+		extendedLenCmd = 100; // Cannot be matched
+		tmpIndex = 4078;
+		src -= 4;
+	}
 
-	src += 4;
+	memset(tmpBuf, 0x20, tmpIndex); // Fill initial window with spaces
 
 	byte *unpacked = new byte[size];
 	byte *dest = unpacked;
@@ -358,6 +373,11 @@ byte *ExtractGobStk::unpackData(byte *src, uint32 &size) {
 			len = (*src & 0x0F) + 3;
 			src++;
 
+			if (len == extendedLenCmd) {
+				len = *src + 18;
+				src++;
+			}
+
 			for (int i = 0; i < len; i++) {
 				*dest++ = tmpBuf[(off + i) % 4096];
 				if (--counter == 0)




More information about the Scummvm-git-logs mailing list