diff options
-rw-r--r-- | engines/sci/console.cpp | 27 | ||||
-rw-r--r-- | engines/sci/console.h | 1 | ||||
-rw-r--r-- | engines/sci/engine/kernel.cpp | 14 | ||||
-rw-r--r-- | engines/sci/engine/kernel.h | 7 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 34 |
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 { |