diff options
-rw-r--r-- | engines/sci/console.cpp | 26 | ||||
-rw-r--r-- | engines/sci/console.h | 3 | ||||
-rw-r--r-- | engines/sci/debug.h | 4 | ||||
-rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 98 |
4 files changed, 74 insertions, 57 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 8ea4315c24..b34b4f44ea 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -156,12 +156,15 @@ Console::Console(SciEngine *engine) : GUI::Debugger() { DCmd_Register("set_acc", WRAP_METHOD(Console, cmdSetAccumulator)); DCmd_Register("backtrace", WRAP_METHOD(Console, cmdBacktrace)); DCmd_Register("bt", WRAP_METHOD(Console, cmdBacktrace)); // alias - DCmd_Register("step", WRAP_METHOD(Console, cmdStep)); - DCmd_Register("s", WRAP_METHOD(Console, cmdStep)); // alias + DCmd_Register("trace", WRAP_METHOD(Console, cmdTrace)); + DCmd_Register("t", WRAP_METHOD(Console, cmdTrace)); // alias + DCmd_Register("s", WRAP_METHOD(Console, cmdTrace)); // alias + DCmd_Register("stepover", WRAP_METHOD(Console, cmdStepOver)); + DCmd_Register("p", WRAP_METHOD(Console, cmdStepOver)); // alias + DCmd_Register("step_ret", WRAP_METHOD(Console, cmdStepRet)); + DCmd_Register("pret", WRAP_METHOD(Console, cmdStepRet)); // alias DCmd_Register("step_event", WRAP_METHOD(Console, cmdStepEvent)); DCmd_Register("se", WRAP_METHOD(Console, cmdStepEvent)); // alias - DCmd_Register("step_ret", WRAP_METHOD(Console, cmdStepRet)); - DCmd_Register("sret", WRAP_METHOD(Console, cmdStepRet)); // alias DCmd_Register("step_global", WRAP_METHOD(Console, cmdStepGlobal)); DCmd_Register("sg", WRAP_METHOD(Console, cmdStepGlobal)); // alias DCmd_Register("step_callk", WRAP_METHOD(Console, cmdStepCallk)); @@ -378,9 +381,10 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" dissect_script - Examines a script\n"); DebugPrintf(" set_acc - Sets the accumulator\n"); DebugPrintf(" backtrace / bt - Dumps the send/self/super/call/calle/callb stack\n"); - DebugPrintf(" step / s - Executes one operation (no parameters) or several operations (specified as a parameter) \n"); + DebugPrintf(" trace / t / s - Executes one operation (no parameters) or several operations (specified as a parameter) \n"); + DebugPrintf(" stepover / p - Executes one operation, skips over call/send\n"); + DebugPrintf(" step_ret / pret - Steps forward until ret is called on the current execution stack level.\n"); DebugPrintf(" step_event / se - Steps forward until a SCI event is received.\n"); - DebugPrintf(" step_ret / sret - Steps forward until ret is called on the current execution stack level.\n"); DebugPrintf(" step_global / sg - Steps until the global variable with the specified index is modified.\n"); DebugPrintf(" step_callk / snk - Steps forward until it hits the next callk operation, or a specific callk (specified as a parameter)\n"); DebugPrintf(" disasm - Disassembles a method by name\n"); @@ -2405,7 +2409,7 @@ bool Console::cmdBacktrace(int argc, const char **argv) { return true; } -bool Console::cmdStep(int argc, const char **argv) { +bool Console::cmdTrace(int argc, const char **argv) { if (argc == 2 && atoi(argv[1]) > 0) g_debugState.runningStep = atoi(argv[1]) - 1; g_debugState.debugging = true; @@ -2413,6 +2417,14 @@ bool Console::cmdStep(int argc, const char **argv) { return false; } +bool Console::cmdStepOver(int argc, const char **argv) { + g_debugState.seeking = kDebugSeekStepOver; + g_debugState.seekLevel = _engine->_gamestate->_executionStack.size(); + g_debugState.debugging = true; + + return false; +} + bool Console::cmdStepEvent(int argc, const char **argv) { g_debugState.stopOnEvent = true; g_debugState.debugging = true; diff --git a/engines/sci/console.h b/engines/sci/console.h index e353958a0d..f8a2768f35 100644 --- a/engines/sci/console.h +++ b/engines/sci/console.h @@ -120,7 +120,8 @@ private: bool cmdDissectScript(int argc, const char **argv); bool cmdSetAccumulator(int argc, const char **argv); bool cmdBacktrace(int argc, const char **argv); - bool cmdStep(int argc, const char **argv); + bool cmdTrace(int argc, const char **argv); + bool cmdStepOver(int argc, const char **argv); bool cmdStepEvent(int argc, const char **argv); bool cmdStepRet(int argc, const char **argv); bool cmdStepGlobal(int argc, const char **argv); diff --git a/engines/sci/debug.h b/engines/sci/debug.h index 8383722956..d381e55dc8 100644 --- a/engines/sci/debug.h +++ b/engines/sci/debug.h @@ -57,8 +57,8 @@ enum DebugSeeking { kDebugSeekCallk = 1, // Step forward until callk is found kDebugSeekLevelRet = 2, // Step forward until returned from this level kDebugSeekSpecialCallk = 3, // Step forward until a /special/ callk is found - kDebugSeekSO = 4, // Step forward until specified PC (after the send command) and stack depth - kDebugSeekGlobal = 5 // Step forward until one specified global variable is modified + kDebugSeekGlobal = 4, // Step forward until one specified global variable is modified + kDebugSeekStepOver = 5 // Step forward until we reach same stack-level again }; struct DebugState { diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index d829b01c31..b8a0987865 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -296,55 +296,59 @@ void script_debug(EngineState *s) { #endif if (g_debugState.seeking && !g_debugState.breakpointWasHit) { // Are we looking for something special? - SegmentObj *mobj = s->_segMan->getSegment(s->xs->addr.pc.segment, SEG_TYPE_SCRIPT); - - if (mobj) { - Script *scr = (Script *)mobj; - byte *code_buf = scr->_buf; - int code_buf_size = scr->getBufSize(); - int opcode = s->xs->addr.pc.offset >= code_buf_size ? 0 : code_buf[s->xs->addr.pc.offset]; - int op = opcode >> 1; - int paramb1 = s->xs->addr.pc.offset + 1 >= code_buf_size ? 0 : code_buf[s->xs->addr.pc.offset + 1]; - int paramf1 = (opcode & 1) ? paramb1 : (s->xs->addr.pc.offset + 2 >= code_buf_size ? 0 : (int16)READ_SCI11ENDIAN_UINT16(code_buf + s->xs->addr.pc.offset + 1)); - - switch (g_debugState.seeking) { - case kDebugSeekSpecialCallk: - if (paramb1 != g_debugState.seekSpecial) - return; - - case kDebugSeekCallk: - if (op != op_callk) - return; - break; - - case kDebugSeekLevelRet: - if ((op != op_ret) || (g_debugState.seekLevel < (int)s->_executionStack.size()-1)) - return; - break; - - case kDebugSeekGlobal: - if (op < op_sag) - return; - if ((op & 0x3) > 1) - return; // param or temp - if ((op & 0x3) && s->_executionStack.back().local_segment > 0) - return; // locals and not running in script.000 - if (paramf1 != g_debugState.seekSpecial) - return; // CORRECT global? - break; - - case kDebugSeekSO: - // FIXME: Unhandled? - break; - - case kDebugSeekNothing: - // We seek nothing, so just continue - break; - } - + if (g_debugState.seeking == kDebugSeekStepOver) { + // are we above seek-level? resume then + if (g_debugState.seekLevel < (int)s->_executionStack.size()) + return; g_debugState.seeking = kDebugSeekNothing; - // OK, found whatever we were looking for } + + if (g_debugState.seeking != kDebugSeekNothing) { + SegmentObj *mobj = s->_segMan->getSegment(s->xs->addr.pc.segment, SEG_TYPE_SCRIPT); + + if (mobj) { + Script *scr = (Script *)mobj; + byte *code_buf = scr->_buf; + int code_buf_size = scr->getBufSize(); + int opcode = s->xs->addr.pc.offset >= code_buf_size ? 0 : code_buf[s->xs->addr.pc.offset]; + int op = opcode >> 1; + int paramb1 = s->xs->addr.pc.offset + 1 >= code_buf_size ? 0 : code_buf[s->xs->addr.pc.offset + 1]; + int paramf1 = (opcode & 1) ? paramb1 : (s->xs->addr.pc.offset + 2 >= code_buf_size ? 0 : (int16)READ_SCI11ENDIAN_UINT16(code_buf + s->xs->addr.pc.offset + 1)); + + switch (g_debugState.seeking) { + case kDebugSeekSpecialCallk: + if (paramb1 != g_debugState.seekSpecial) + return; + + case kDebugSeekCallk: + if (op != op_callk) + return; + break; + + case kDebugSeekLevelRet: + if ((op != op_ret) || (g_debugState.seekLevel < (int)s->_executionStack.size()-1)) + return; + break; + + case kDebugSeekGlobal: + if (op < op_sag) + return; + if ((op & 0x3) > 1) + return; // param or temp + if ((op & 0x3) && s->_executionStack.back().local_segment > 0) + return; // locals and not running in script.000 + if (paramf1 != g_debugState.seekSpecial) + return; // CORRECT global? + break; + + default: + break; + } + + g_debugState.seeking = kDebugSeekNothing; + } + } + // OK, found whatever we were looking for } printf("Step #%d\n", s->scriptStepCounter); |