[Scummvm-git-logs] scummvm master -> cc696d501951bf8f1e0f3d4c3b587d8e5fe8bc7b

dreammaster noreply at scummvm.org
Mon Oct 28 05:22:52 UTC 2024


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

Summary:
cc696d5019 M4: RIDDLE: Add debugging of (animation) script execution


Commit: cc696d501951bf8f1e0f3d4c3b587d8e5fe8bc7b
    https://github.com/scummvm/scummvm/commit/cc696d501951bf8f1e0f3d4c3b587d8e5fe8bc7b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2024-10-27T22:04:29-07:00

Commit Message:
M4: RIDDLE: Add debugging of (animation) script execution

Changed paths:
    engines/m4/dbg/dbg_wscript.cpp
    engines/m4/dbg/dbg_wscript.h
    engines/m4/detection.cpp
    engines/m4/detection.h
    engines/m4/wscript/ws_cruncher.cpp
    engines/m4/wscript/ws_machine.cpp


diff --git a/engines/m4/dbg/dbg_wscript.cpp b/engines/m4/dbg/dbg_wscript.cpp
index c0b7e0b061d..8851ed8f027 100644
--- a/engines/m4/dbg/dbg_wscript.cpp
+++ b/engines/m4/dbg/dbg_wscript.cpp
@@ -19,10 +19,92 @@
  *
  */
 
+#include "common/debug.h"
 #include "m4/dbg/dbg_wscript.h"
+#include "m4/detection.h"
+#include "m4/vars.h"
 
 namespace M4 {
 
+static const char *IMM_OPCODES[16] = {
+	"NONE",
+	"op_DO_NOTHING",
+	"op_GOTO",
+	"op_JUMP",
+	"op_TERMINATE",
+	"op_START_SEQ",
+	"op_PAUSE_SEQ",
+	"op_RESUME_SEQ",
+	"op_STORE_VAL",
+	"op_SEND_MSG",
+	"op_SEND_GMSG",
+	"op_REPLY_MSG",
+	"op_SYSTEM_MSG",
+	"op_TRIG",
+	"op_TRIG_W",
+	"op_CLEAR_REGS"
+};
+
+static const char *COND_OPCODES[10] = {
+	"op_AFTER",
+	"op_ON_END_SEQ",
+	"op_ON_MSG",
+	"op_ON_P_MSG",
+	"op_SWITCH_LT",
+	"op_SWITCH_LE",
+	"op_SWITCH_EQ",
+	"op_SWITCH_NE",
+	"op_SWITCH_GE",
+	"op_SWITCH_GT"
+};
+
+static const char *PCODE_OPCODES[40] = {
+	"op_END",
+	"op_CLEAR",
+	"op_SET",
+	"op_COMPARE",
+	"op_ADD",
+	"op_SUB",
+	"op_MULT",
+	"op_DIV",
+	"op_AND",
+	"op_OR",
+	"op_NOT",
+	"op_SIN",
+	"op_COS",
+	"op_ABS",
+	"op_MIN",
+	"op_MAX",
+	"op_MOD",
+	"op_FLOOR",
+	"op_ROUND",
+	"op_CEIL",
+	"op_POINT",
+	"op_DIST2D",
+	"op_CRUNCH",
+	"op_BRANCH",
+	"op_SETCEL",
+	"op_SEQ_SEND_MSG",
+	"op_PUSH",
+	"op_POP",
+	"op_JSR",
+	"op_RETURN",
+	"op_GET_CELS_COUNT",
+	"op_GET_CELS_FRAME_RATE",
+	"op_GET_CELS_PIX_SPEED",
+	"op_SET_INDEX",
+	"op_SET_LAYER",
+	"op_SET_DEPTH",
+	"op_SET_DATA",
+	"op_OPEN_STREAM_SS",
+	"op_NEXT_STREAM_SS",
+	"op_CLOSE_STREAM_SS"
+};
+
+static char g_instructionText[256];
+bool g_hasParams;
+bool g_isPcode;
+
 bool dbg_ws_init(bool showTheScreen, Font *useThisFont, frac16 *theGlobals) {
 	return true;
 }
@@ -31,31 +113,63 @@ void dbg_ws_shutdown() {
 	// No implementation
 }
 
-void dbg_ws_update() {
-	// No implementation
+void dbg_SetCurrMachInstr(machine *m, int32 pcOffset, bool isPcode) {
+	if (debugChannelSet(1, kDebugScripts)) {
+		Common::sprintf_s(g_instructionText, "%s (%.4x): ",
+			m ? m->machName : "NONE", pcOffset);
+		g_hasParams = false;
+		g_hasParams = isPcode;
+	}
 }
 
-void dbg_LaunchSequence(Anim8 *myAnim8) {
+void dbg_AddOpcodeToMachineInstr(int instruction) {
+	if (debugChannelSet(1, kDebugScripts)) {
+		if (g_isPcode) {
+			Common::strcat_s(g_instructionText, PCODE_OPCODES[instruction]);
+		} else if (instruction >= 64)
+			Common::strcat_s(g_instructionText, COND_OPCODES[instruction - 64]);
+		else
+			Common::strcat_s(g_instructionText, IMM_OPCODES[instruction]);
+		Common::strcat_s(g_instructionText, " ");
+	}
+}
+
+void dbg_AddParamToCurrMachInstr(const char *param) {
+	if (debugChannelSet(1, kDebugScripts)) {
+		if (g_hasParams)
+			Common::strcat_s(g_instructionText, ", ");
+
+		Common::strcat_s(g_instructionText, param);
+		g_hasParams = true;
+	}
+}
+
+void dbg_EndCurrMachInstr() {
+	debugC(1, kDebugScripts, "%s", g_instructionText);
+}
+
+void dbg_SetCurrSequInstr(Anim8 *myAnim8, int32 compareCCR) {
 	// No implementation
 }
 
-void dbg_DebugWSMach(machine *m, bool debug) {
+
+void dbg_ws_update() {
 	// No implementation
 }
 
-void dbg_DebugNextCycle() {
+void dbg_LaunchSequence(Anim8 *myAnim8) {
 	// No implementation
 }
 
-void dbg_RemoveWSMach(machine *m) {
+void dbg_DebugWSMach(machine *m, bool debug) {
 	// No implementation
 }
 
-void dbg_SetCurrMachInstr(machine *m, int32 pcOffset) {
+void dbg_DebugNextCycle() {
 	// No implementation
 }
 
-void dbg_SetCurrSequInstr(Anim8 *myAnim8, int32 compareCCR) {
+void dbg_RemoveWSMach(machine *m) {
 	// No implementation
 }
 
diff --git a/engines/m4/dbg/dbg_wscript.h b/engines/m4/dbg/dbg_wscript.h
index 971a2a141ef..fe61b18d82c 100644
--- a/engines/m4/dbg/dbg_wscript.h
+++ b/engines/m4/dbg/dbg_wscript.h
@@ -30,17 +30,20 @@
 
 namespace M4 {
 
-bool dbg_ws_init(bool showTheScreen, Font *useThisFont, frac16 *theGlobals);
-void dbg_ws_shutdown();
-void dbg_ws_update();
+extern bool dbg_ws_init(bool showTheScreen, Font *useThisFont, frac16 *theGlobals);
+extern void dbg_ws_shutdown();
+extern void dbg_SetCurrMachInstr(machine *m, int32 pcOffset, bool isPcode);
+extern void dbg_EndCurrMachInstr();
+extern void dbg_AddOpcodeToMachineInstr(int instruction);
+extern void dbg_AddParamToCurrMachInstr(const char *param);
+extern void dbg_ws_update();
 
-void dbg_LaunchSequence(Anim8 *myAnim8);
-void dbg_DebugWSMach(machine *m, bool debug);
-void dbg_DebugNextCycle();
-void dbg_RemoveWSMach(machine *m);
-void dbg_SetCurrMachInstr(machine *m, int32 pcOffset);
-void dbg_SetCurrSequInstr(Anim8 *myAnim8, int32 compareCCR);
-void dbg_WSError(Common::WriteStream *logFile, machine *m, int32 errorType, const char *errDesc, const char *errMsg, int32 pcOffset);
+extern void dbg_LaunchSequence(Anim8 *myAnim8);
+extern void dbg_DebugWSMach(machine *m, bool debug);
+extern void dbg_DebugNextCycle();
+extern void dbg_RemoveWSMach(machine *m);
+extern void dbg_SetCurrSequInstr(Anim8 *myAnim8, int32 compareCCR);
+extern void dbg_WSError(Common::WriteStream *logFile, machine *m, int32 errorType, const char *errDesc, const char *errMsg, int32 pcOffset);
 
 } // namespace M4
 
diff --git a/engines/m4/detection.cpp b/engines/m4/detection.cpp
index 2c26f5b62c7..b9ca6bb013c 100644
--- a/engines/m4/detection.cpp
+++ b/engines/m4/detection.cpp
@@ -29,13 +29,9 @@
 #include "m4/detection_tables.h"
 
 const DebugChannelDef M4MetaEngineDetection::debugFlagList[] = {
-	{ M4::kDebugScript, "script", "Script debug level" },
-	{ M4::kDebugGraphics, "graphics", "Graphics debug level" },
-	{ M4::kDebugConversations, "conversations", "Conversations debugging" },
-	{ M4::kDebugSound, "sound", "Sounds debug level" },
+	{ M4::kDebugScripts, "scripts", "Script debug level" },
+	{ M4::kDebugMessages, "messages", "Messages debug level" },
 	{ M4::kDebugCore, "core", "Core debug level" },
-	{ M4::kDebugWSSequ, "wssequ", "WoodScript sequence debug level" },
-	{ M4::kDebugWSMach, "wsmach", "WoodScript machine debug level" },
 	DEBUG_CHANNEL_END
 };
 
diff --git a/engines/m4/detection.h b/engines/m4/detection.h
index 0f2f2e76bcd..bf463be23f6 100644
--- a/engines/m4/detection.h
+++ b/engines/m4/detection.h
@@ -27,13 +27,9 @@
 namespace M4 {
 
 enum M4DebugChannels {
-	kDebugScript = 1 << 0,
-	kDebugConversations = 1 << 1,
-	kDebugGraphics = 1 << 2,
-	kDebugSound = 1 << 3,
-	kDebugCore = 1 << 4,
-	kDebugWSSequ = 1 << 5,
-	kDebugWSMach = 1 << 6
+	kDebugScripts = 1 << 0,
+	kDebugMessages = 1 << 1,
+	kDebugCore = 1 << 2
 };
 
 enum M4GameType {
@@ -83,7 +79,7 @@ public:
 	}
 
 	const char *getOriginalCopyright() const override {
-		return "M4 (C)";
+		return "M4 (C) 1995-1996 Sanctuary Woods Multimedia Corporation";
 	}
 
 	const DebugChannelDef *getDebugChannels() const override {
diff --git a/engines/m4/wscript/ws_cruncher.cpp b/engines/m4/wscript/ws_cruncher.cpp
index cfd836e1e2d..908dcf60355 100644
--- a/engines/m4/wscript/ws_cruncher.cpp
+++ b/engines/m4/wscript/ws_cruncher.cpp
@@ -391,6 +391,7 @@ static bool ExtractArg(Anim8 *myAnim8, int32 myFormat, int32 myData, frac16 **ar
 	int32 myIndex;
 	Anim8 *parentAnim8;
 	uint32 *dataArray;
+	Common::String param;
 
 	// If the format indicates the argument is a local source (parent, register, or data)
 	if (myFormat == FMT_LOCAL_SRC) {
@@ -402,6 +403,7 @@ static bool ExtractArg(Anim8 *myAnim8, int32 myFormat, int32 myData, frac16 **ar
 		// Find out if the index has been previously stored in a special index register
 		if (myData & REG_SET_IDX_REG) {
 			myIndex = _GWS(indexReg);
+			param = "S";
 		} else {
 			// Else the index is part of the data segment for this arg
 			myIndex = myData & REG_SET_IDX;
@@ -423,6 +425,7 @@ static bool ExtractArg(Anim8 *myAnim8, int32 myFormat, int32 myData, frac16 **ar
 				return false;
 			}
 			*argPtr = &parentAnim8->myRegs[myIndex];
+			param += Common::String::format("PREG %d", myIndex);
 			break;
 
 		case LOCAL_FMT_REG:
@@ -433,6 +436,7 @@ static bool ExtractArg(Anim8 *myAnim8, int32 myFormat, int32 myData, frac16 **ar
 				return false;
 			}
 			*argPtr = &myAnim8->myRegs[myIndex];
+			param = Common::String::format("REG %d", myIndex);
 			break;
 
 		case LOCAL_FMT_DATA:
@@ -448,6 +452,7 @@ static bool ExtractArg(Anim8 *myAnim8, int32 myFormat, int32 myData, frac16 **ar
 			// Copy the data field into dataArg1, and set myArg1 to point to this location
 			*argValue = (int32)FROM_LE_32(dataArray[myIndex]);
 			*argPtr = argValue;
+			param = Common::String::format("DATA %d", myIndex);
 			break;
 		}
 	} else if (myFormat == FMT_GLOBAL_SRC) {
@@ -455,6 +460,7 @@ static bool ExtractArg(Anim8 *myAnim8, int32 myFormat, int32 myData, frac16 **ar
 		// Find out if the index has been previously stored in a special index register
 		if (myData & REG_SET_IDX_REG) {
 			myIndex = _GWS(indexReg);
+			param = "S";
 		} else {
 			// Else the index is part of the data segment for this arg
 			myIndex = myData & REG_SET_IDX;
@@ -462,6 +468,7 @@ static bool ExtractArg(Anim8 *myAnim8, int32 myFormat, int32 myData, frac16 **ar
 
 		// Finally, set myArg1 to point to the location in the ws_globals array, whichever index
 		*argPtr = &(_GWS(ws_globals)[myIndex]);
+		param += Common::String::format("GLOB %d", myIndex);
 	} else {
 		// Else the argument is not a variable, but an actual value
 
@@ -476,8 +483,11 @@ static bool ExtractArg(Anim8 *myAnim8, int32 myFormat, int32 myData, frac16 **ar
 
 		// myArg1 will point to this location
 		*argPtr = argValue;
+		param += Common::String::format("%d", *argValue);
 	}
 
+	dbg_AddParamToCurrMachInstr(param.c_str());
+
 	return true;
 }
 
@@ -497,6 +507,7 @@ int32 ws_PreProcessPcode(uint32 **PC, Anim8 *myAnim8) {
 
 	// Get the instruction number
 	myInstruction = (opCode & OP_INSTR) >> 25;
+	dbg_AddOpcodeToMachineInstr(myInstruction);
 
 	// Get the format for the first arg 
 	myFormat = (opCode & OP_FORMAT1) >> 22;
@@ -1336,7 +1347,6 @@ void (*pCodeJmpTable[])(Anim8 *myAnim8) = {
 
 
 // The guts of the engine.  This proc executes an anim8s program.
-bool CrunchAnim8(Anim8 *myAnim8);
 bool CrunchAnim8(Anim8 *myAnim8) {
 	bool moveTheCel = false;
 	frac16 timeElapsed, percentDist;
@@ -1381,10 +1391,14 @@ bool CrunchAnim8(Anim8 *myAnim8) {
 		oldPC = myPC;
 		_GWS(pcOffsetOld) = myAnim8->pcOffset;
 
+		dbg_SetCurrMachInstr(myAnim8->myMachine, myAnim8->pcOffset, true);
+
 		if ((myInstruction = ws_PreProcessPcode(&myPC, myAnim8)) < 0) {
 			ws_Error(myAnim8->myMachine, ERR_SEQU, 0x025c, nullptr);
 		}
 
+		dbg_EndCurrMachInstr();
+
 		myAnim8->pcOffset += (intptr)myPC - (intptr)oldPC;
 		pCodeJmpTable[myInstruction](myAnim8);
 	}
diff --git a/engines/m4/wscript/ws_machine.cpp b/engines/m4/wscript/ws_machine.cpp
index eef1f9f60ef..593db40f49e 100644
--- a/engines/m4/wscript/ws_machine.cpp
+++ b/engines/m4/wscript/ws_machine.cpp
@@ -30,6 +30,7 @@
 #include "m4/mem/mem.h"
 #include "m4/platform/timer.h"
 #include "m4/vars.h"
+#include "m4/detection.h"
 
 namespace M4 {
 
@@ -523,10 +524,15 @@ static bool op_TRIG_W(machine *m, int32 *pcOffset) {
 	machInstr = (uint32 *)((intptr)(*(m->machHandle)) + (uint32)m->machInstrOffset);
 	myPC = (uint32 *)((intptr)machInstr + *pcOffset);
 	oldPC = myPC;
+
+	dbg_SetCurrMachInstr(m, *pcOffset, false);
+
 	if ((myInstruction = ws_PreProcessPcode(&myPC, m->myAnim8)) < 0) {
 		ws_Error(m, ERR_MACH, 0x0266, "trig_w() failed.");
 	}
 
+	dbg_EndCurrMachInstr();
+
 	// Now find the new pcOffset
 	*pcOffset += (byte *)myPC - (byte *)oldPC;
 
@@ -874,18 +880,20 @@ static int32 StepAt(int32 *pcOffset, machine *m) {
 	machID = m->machID;
 	myAnim8 = m->myAnim8;
 
-	dbg_SetCurrMachInstr(m, *pcOffset);
-
 	// Find the current PC and process it to get the current instruction
 	machInstr = (uint32 *)((intptr)(*(m->machHandle)) + m->machInstrOffset);
 	myPC = (uint32 *)((intptr)(machInstr) + *pcOffset);
 	oldPC = myPC;
 	_GWS(pcOffsetOld) = *pcOffset;
 
+	dbg_SetCurrMachInstr(m, *pcOffset, false);
+
 	if ((myInstruction = ws_PreProcessPcode(&myPC, myAnim8)) < 0) {
 		ws_Error(m, ERR_MACH, 0x0266, nullptr);
 	}
 
+	dbg_EndCurrMachInstr();
+
 	// Now find the new pcOffset
 	*pcOffset += (byte *)myPC - (byte *)oldPC;
 
@@ -1176,6 +1184,10 @@ void sendWSMessage(uint32 msgHash, frac16 msgValue, machine *recvM,
 	bool sendToAll;
 	globalMsgReq *myGlobalMsgs, *tempGlobalMsg;
 
+	debugC(1, kDebugMessages, "Message %xh, %xh, %s, %xh, %s, %d",
+		msgHash, msgValue, recvM ? recvM->machName : "NONE",
+		machHash, sendM ? sendM->machName : "NONE", msgCount);
+
 	// In this case we are sending to a specific machine: recvM
 	if (recvM) {
 		// Search first the regular message list, and if it was not found




More information about the Scummvm-git-logs mailing list