aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/console.cpp27
-rw-r--r--engines/sci/console.h1
-rw-r--r--engines/sci/engine/kernel.cpp14
-rw-r--r--engines/sci/engine/kernel.h7
-rw-r--r--engines/sci/engine/vm.cpp34
5 files changed, 81 insertions, 2 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index c2db56c40a..6bb2c52d84 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -168,6 +168,7 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
DCmd_Register("disasm_addr", WRAP_METHOD(Console, cmdDisassembleAddress));
DCmd_Register("send", WRAP_METHOD(Console, cmdSend));
DCmd_Register("go", WRAP_METHOD(Console, cmdGo));
+ DCmd_Register("logkernel", WRAP_METHOD(Console, cmdLogKernel));
// Breakpoints
DCmd_Register("bp_list", WRAP_METHOD(Console, cmdBreakpointList));
DCmd_Register("bplist", WRAP_METHOD(Console, cmdBreakpointList)); // alias
@@ -374,6 +375,7 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" disasm_addr - Disassembles one or more commands\n");
DebugPrintf(" send - Sends a message to an object\n");
DebugPrintf(" go - Executes the script\n");
+ DebugPrintf(" logkernel - Logs kernel calls\n");
DebugPrintf("\n");
DebugPrintf("Breakpoints:\n");
DebugPrintf(" bp_list / bplist / bl - Lists the current breakpoints\n");
@@ -2690,6 +2692,31 @@ bool Console::cmdGo(int argc, const char **argv) {
return Cmd_Exit(argc, argv);
}
+bool Console::cmdLogKernel(int argc, const char **argv) {
+ if (argc < 3) {
+ DebugPrintf("Logs calls to specified kernel function.\n");
+ DebugPrintf("Usage: %s <kernel-function> <on/off>\n", argv[0]);
+ DebugPrintf("Example: %s StrCpy on\n", argv[0]);
+ return true;
+ }
+
+ bool logging;
+ if (strcmp(argv[2], "on") == 0)
+ logging = true;
+ else if (strcmp(argv[2], "off") == 0)
+ logging = false;
+ else {
+ DebugPrintf("2nd parameter must be either on or off\n");
+ return true;
+ }
+
+ if (g_sci->getKernel()->debugSetFunctionLogging(argv[1], logging))
+ DebugPrintf("Logging %s for k%s\n", logging ? "enabled" : "disabled", argv[1]);
+ else
+ DebugPrintf("Unknown kernel function %s\n", argv[1]);
+ return true;
+}
+
bool Console::cmdBreakpointList(int argc, const char **argv) {
int i = 0;
int bpdata;
diff --git a/engines/sci/console.h b/engines/sci/console.h
index cb96944e01..234272bbab 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -130,6 +130,7 @@ private:
bool cmdDisassembleAddress(int argc, const char **argv);
bool cmdSend(int argc, const char **argv);
bool cmdGo(int argc, const char **argv);
+ bool cmdLogKernel(int argc, const char **argv);
// Breakpoints
bool cmdBreakpointList(int argc, const char **argv);
bool cmdBreakpointDelete(int argc, const char **argv);
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index d7f45323aa..de64c1ea0b 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -544,7 +544,7 @@ void Kernel::mapFunctions() {
_kernelFuncs[id].workarounds = NULL;
_kernelFuncs[id].subFunctions = NULL;
_kernelFuncs[id].subFunctionCount = 0;
- _kernelFuncs[id].debugCalls = false;
+ _kernelFuncs[id].debugLogging = false;
if (kernelName.empty()) {
// No name was given -> must be an unknown opcode
warning("Kernel function %x unknown", id);
@@ -650,6 +650,18 @@ void Kernel::mapFunctions() {
return;
}
+bool Kernel::debugSetFunctionLogging(const char *kernelName, bool logging) {
+ for (uint id = 0; id < _kernelFuncs.size(); id++) {
+ if (_kernelFuncs[id].name) {
+ if (strcmp(kernelName, _kernelFuncs[id].name) == 0) {
+ _kernelFuncs[id].debugLogging = logging;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void Kernel::setDefaultKernelNames() {
_kernelNames = Common::StringArray(s_defaultKernelNames, ARRAYSIZE(s_defaultKernelNames));
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 8467a640af..19cf11affa 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -135,7 +135,7 @@ struct KernelFunction {
const SciWorkaroundEntry *workarounds;
const KernelSubFunction *subFunctions;
uint16 subFunctionCount;
- bool debugCalls;
+ bool debugLogging;
};
class Kernel {
@@ -216,6 +216,11 @@ public:
*/
void loadKernelNames(GameFeatures *features);
+ /**
+ * Sets debugCalls flag for a kernel function
+ */
+ bool debugSetFunctionLogging(const char *kernelName, bool debugCalls);
+
private:
/**
* Sets the default kernel function names, based on the SCI version used.
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 4cd5fc224f..88d47cb22d 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -642,6 +642,38 @@ static void addKernelCallToExecStack(EngineState *s, int kernelCallNr, int argc,
xstack->type = EXEC_STACK_TYPE_KERNEL;
}
+static void logKernelCall(const KernelFunction *kernelCall, EngineState *s, int argc, reg_t *argv) {
+ Kernel *kernel = g_sci->getKernel();
+ printf("k%s: ", kernelCall->name);
+ for (int parmNr = 0; parmNr < argc; parmNr++) {
+ if (parmNr)
+ printf(", ");
+ uint16 regType = kernel->findRegType(argv[parmNr]);
+ if (regType & SIG_TYPE_NULL)
+ printf("NULL");
+ else if (regType & SIG_TYPE_UNINITIALIZED)
+ printf("UNINIT");
+ else if (regType & SIG_IS_INVALID)
+ printf("INVALID");
+ else if (regType & SIG_TYPE_INTEGER)
+ printf("%04x", argv[parmNr].offset);
+ else {
+ printf("%04x:%04x", PRINT_REG(argv[parmNr]));
+ switch (regType) {
+ case SIG_TYPE_OBJECT:
+ printf(" (%s)", s->_segMan->getObjectName(argv[parmNr]));
+ break;
+ case SIG_TYPE_REFERENCE:
+ printf(" ('%s')", s->_segMan->getString(argv[parmNr]).c_str());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ printf("\n");
+}
+
static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
Kernel *kernel = g_sci->getKernel();
@@ -676,6 +708,8 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
// Call kernel function
if (!kernelCall.subFunctionCount) {
+ if (kernelCall.debugLogging)
+ logKernelCall(&kernelCall, s, argc, argv);
addKernelCallToExecStack(s, kernelCallNr, argc, argv);
s->r_acc = kernelCall.function(s, argc, argv);
} else {