[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