aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2009-06-03 11:38:12 +0000
committerFilippos Karapetis2009-06-03 11:38:12 +0000
commitcb0aed33037a67c3570059df98ec7bbd167d1703 (patch)
treec2f9b010d8e580594487286b2914fd2fdc924273
parent3c7b434b04240be647d0d10f8e1dcecea95f7aac (diff)
downloadscummvm-rg350-cb0aed33037a67c3570059df98ec7bbd167d1703.tar.gz
scummvm-rg350-cb0aed33037a67c3570059df98ec7bbd167d1703.tar.bz2
scummvm-rg350-cb0aed33037a67c3570059df98ec7bbd167d1703.zip
Moved some more console commands to ScummVM's console
svn-id: r41137
-rw-r--r--engines/sci/console.cpp180
-rw-r--r--engines/sci/console.h5
-rw-r--r--engines/sci/engine/scriptdebug.cpp143
3 files changed, 186 insertions, 142 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 72ec59068a..236f01bb51 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -77,6 +77,7 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
DCmd_Register("parser_nodes", WRAP_METHOD(Console, cmdParserNodes));
DCmd_Register("parser_words", WRAP_METHOD(Console, cmdParserWords));
DCmd_Register("sentence_fragments", WRAP_METHOD(Console, cmdSentenceFragments));
+ DCmd_Register("parse", WRAP_METHOD(Console, cmdParse));
// Resources
DCmd_Register("hexdump", WRAP_METHOD(Console, cmdHexDump));
DCmd_Register("resource_id", WRAP_METHOD(Console, cmdResourceId));
@@ -134,11 +135,15 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
DCmd_Register("registers", WRAP_METHOD(Console, cmdRegisters));
DCmd_Register("dissect_script", WRAP_METHOD(Console, cmdDissectScript));
DCmd_Register("set_acc", WRAP_METHOD(Console, cmdSetAccumulator));
+ // Breakpoints
DCmd_Register("bp_list", WRAP_METHOD(Console, cmdBreakpointList));
DCmd_Register("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete));
+ DCmd_Register("bp_exec_method", WRAP_METHOD(Console, cmdBreakpointExecMethod));
+ DCmd_Register("bp_exec_function", WRAP_METHOD(Console, cmdBreakpointExecFunction));
// VM
DCmd_Register("script_steps", WRAP_METHOD(Console, cmdScriptSteps));
DCmd_Register("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist));
+ DCmd_Register("vm_vars", WRAP_METHOD(Console, cmdVMVars));
DCmd_Register("stack", WRAP_METHOD(Console, cmdStack));
DCmd_Register("value_type", WRAP_METHOD(Console, cmdValueType));
DCmd_Register("view_listnode", WRAP_METHOD(Console, cmdViewListNode));
@@ -188,6 +193,7 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" parser_nodes - Shows the specified number of nodes from the parse node tree\n");
DebugPrintf(" parser_words - Shows the words from the parse node tree\n");
DebugPrintf(" sentence_fragments - Shows the sentence fragments (used to build Parse trees)\n");
+ DebugPrintf(" parse - Parses a sequence of words and prints the resulting parse tree\n");
DebugPrintf("\n");
DebugPrintf("Resources:\n");
DebugPrintf(" hexdump - Dumps the specified resource to standard output\n");
@@ -254,12 +260,17 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" registers - Shows the current register values\n");
DebugPrintf(" dissect_script - Examines a script\n");
DebugPrintf(" set_acc - Sets the accumulator\n");
+ DebugPrintf("\n");
+ DebugPrintf("Breakpoints:\n");
DebugPrintf(" bp_list - Lists the current breakpoints\n");
DebugPrintf(" bp_del - Deletes a breakpoint with the specified index\n");
+ DebugPrintf(" bp_exec_method - Sets a breakpoint on the execution of the specified method\n");
+ DebugPrintf(" bp_exec_function - Sets a breakpoint on the execution of the specified exported function\n");
DebugPrintf("\n");
DebugPrintf("VM:\n");
DebugPrintf(" script_steps - Shows the number of executed SCI operations\n");
DebugPrintf(" vm_varlist - Shows the addresses of variables in the VM\n");
+ DebugPrintf(" vm_vars - Displays or changes variables in the VM\n");
DebugPrintf(" stack - Lists the specified number of stack elements\n");
DebugPrintf(" value_type - Determines the type of a value\n");
DebugPrintf(" view_listnode - Examines the list node at the given address\n");
@@ -726,6 +737,51 @@ bool Console::cmdSentenceFragments(int argc, const char **argv) {
return true;
}
+bool Console::cmdParse(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("Parses a sequence of words with a GNF rule set and prints the resulting parse tree\n");
+ DebugPrintf("Usage: %s <word1> <word2> ... <wordn>\n", argv[0]);
+ return true;
+ }
+
+ ResultWordList words;
+ char *error;
+ char string[1000];
+
+ // Construct the string
+ strcpy(string, argv[2]);
+ for (int i = 2; i < argc; i++) {
+ strcat(string, argv[i]);
+ }
+
+ DebugPrintf("Parsing '%s'\n", string);
+ bool res = g_EngineState->_vocabulary->tokenizeString(words, string, &error);
+ if (res && !words.empty()) {
+ int syntax_fail = 0;
+
+ vocab_synonymize_tokens(words, g_EngineState->_synonyms);
+
+ DebugPrintf("Parsed to the following blocks:\n");
+
+ for (ResultWordList::const_iterator i = words.begin(); i != words.end(); ++i)
+ DebugPrintf(" Type[%04x] Group[%04x]\n", i->_class, i->_group);
+
+ if (g_EngineState->_vocabulary->parseGNF(g_EngineState->parser_nodes, words, true))
+ syntax_fail = 1; // Building a tree failed
+
+ if (syntax_fail)
+ DebugPrintf("Building a tree failed.\n");
+ else
+ vocab_dump_parse_tree("debug-parse-tree", g_EngineState->parser_nodes);
+
+ } else {
+ DebugPrintf("Unknown word: '%s'\n", error);
+ free(error);
+ }
+
+ return true;
+}
+
bool Console::cmdParserNodes(int argc, const char **argv) {
if (argc != 2) {
DebugPrintf("Shows the specified number of nodes from the parse node tree\n");
@@ -1464,6 +1520,63 @@ bool Console::cmdVMVarlist(int argc, const char **argv) {
return true;
}
+bool Console::cmdVMVars(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("Displays or changes variables in the VM\n");
+ DebugPrintf("Usage: %s <type> <varnum> [<value>]\n", argv[0]);
+ DebugPrintf("First parameter is either g(lobal), l(ocal), t(emp) or p(aram).\n");
+ DebugPrintf("Second parameter is the var number\n");
+ DebugPrintf("Third parameter (if specified) is the value to set the variable to, in address form\n");
+ DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ return true;
+ }
+
+ const char *varnames[] = {"global", "local", "temp", "param"};
+ const char *varabbrev = "gltp";
+ const char *vartype_pre = strchr(varabbrev, *argv[1]);
+ int vartype;
+ int idx = atoi(argv[2]);
+
+ if (!vartype_pre) {
+ DebugPrintf("Invalid variable type '%c'\n", *argv[1]);
+ return true;
+ }
+
+ vartype = vartype_pre - varabbrev;
+
+ if (idx < 0) {
+ DebugPrintf("Invalid: negative index\n");
+ return true;
+ }
+
+#if 0
+ // TODO: p_var_max
+ if ((p_var_max) && (p_var_max[vartype] <= idx)) {
+ DebugPrintf("Max. index is %d (0x%x)\n", p_var_max[vartype], p_var_max[vartype]);
+ return true;
+ }
+#endif
+
+ switch (argc) {
+ case 2:
+#if 0
+ // TODO: p_vars
+ DebugPrintf("%s var %d == %04x:%04x\n", varnames[vartype], idx, PRINT_REG(p_vars[vartype][idx]));
+#endif
+ break;
+ case 3:
+#if 0
+ // TODO: p_vars
+ p_vars[vartype][idx] = parse_reg_t(argv[3]);
+#endif
+ break;
+ default:
+ DebugPrintf("Too many arguments\n");
+ }
+
+ return true;
+}
+
bool Console::cmdStack(int argc, const char **argv) {
if (argc != 2) {
DebugPrintf("Lists the specified number of stack elements.\n");
@@ -1697,6 +1810,73 @@ bool Console::cmdBreakpointDelete(int argc, const char **argv) {
return true;
}
+bool Console::cmdBreakpointExecMethod(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Sets a breakpoint on the execution of the specified method.\n");
+ DebugPrintf("Usage: %s <method name>\n", argv[0]);
+ DebugPrintf("Example: %s ego::doit\n", argv[0]);
+ DebugPrintf("May also be used to set a breakpoint that applies whenever an object\n");
+ DebugPrintf("of a specific type is touched: %s foo::\n", argv[0]);
+ return true;
+ }
+
+ /* Note: We can set a breakpoint on a method that has not been loaded yet.
+ Thus, we can't check whether the command argument is a valid method name.
+ A breakpoint set on an invalid method name will just never trigger. */
+ Breakpoint *bp;
+ if (g_EngineState->bp_list) {
+ // List exists, append the breakpoint to the end
+ bp = g_EngineState->bp_list;
+ while (bp->next)
+ bp = bp->next;
+ bp->next = (Breakpoint *)malloc(sizeof(Breakpoint));
+ bp = bp->next;
+ } else {
+ // No list, so create the list head
+ g_EngineState->bp_list = (Breakpoint *)malloc(sizeof(Breakpoint));
+ bp = g_EngineState->bp_list;
+ }
+ bp->next = NULL;
+ bp->type = BREAK_SELECTOR;
+ bp->data.name = (char *)malloc(strlen(argv[1]) + 1);
+ strcpy(bp->data.name, argv[1]);
+ g_EngineState->have_bp |= BREAK_SELECTOR;
+
+ return true;
+}
+
+bool Console::cmdBreakpointExecFunction(int argc, const char **argv) {
+ // TODO/FIXME: Why does this accept 2 parameters (the high and the low part of the address)?"
+ if (argc != 3) {
+ DebugPrintf("Sets a breakpoint on the execution of the specified exported function.\n");
+ DebugPrintf("Usage: %s <addr1> <addr2>\n", argv[0]);
+ return true;
+ }
+
+ /* Note: We can set a breakpoint on a method that has not been loaded yet.
+ Thus, we can't check whether the command argument is a valid method name.
+ A breakpoint set on an invalid method name will just never trigger. */
+ Breakpoint *bp;
+ if (g_EngineState->bp_list) {
+ // List exists, append the breakpoint to the end
+ bp = g_EngineState->bp_list;
+ while (bp->next)
+ bp = bp->next;
+ bp->next = (Breakpoint *)malloc(sizeof(Breakpoint));
+ bp = bp->next;
+ } else {
+ // No list, so create the list head
+ g_EngineState->bp_list = (Breakpoint *)malloc(sizeof(Breakpoint));
+ bp = g_EngineState->bp_list;
+ }
+ bp->next = NULL;
+ bp->type = BREAK_EXPORT;
+ bp->data.address = (atoi(argv[1]) << 16 | atoi(argv[2]));
+ g_EngineState->have_bp |= BREAK_EXPORT;
+
+ return true;
+}
+
bool Console::cmdIsSample(int argc, const char **argv) {
if (argc != 2) {
DebugPrintf("Tests whether a given sound resource is a PCM sample, \n");
diff --git a/engines/sci/console.h b/engines/sci/console.h
index aac86d6e93..4b4b8e618c 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -58,6 +58,7 @@ private:
bool cmdParserNodes(int argc, const char **argv);
bool cmdParserWords(int argc, const char **argv);
bool cmdSentenceFragments(int argc, const char **argv);
+ bool cmdParse(int argc, const char **argv);
// Resources
bool cmdHexDump(int argc, const char **argv);
bool cmdResourceId(int argc, const char **argv);
@@ -115,11 +116,15 @@ private:
bool cmdRegisters(int argc, const char **argv);
bool cmdDissectScript(int argc, const char **argv);
bool cmdSetAccumulator(int argc, const char **argv);
+ // Breakpoints
bool cmdBreakpointList(int argc, const char **argv);
bool cmdBreakpointDelete(int argc, const char **argv);
+ bool cmdBreakpointExecMethod(int argc, const char **argv);
+ bool cmdBreakpointExecFunction(int argc, const char **argv);
// VM
bool cmdScriptSteps(int argc, const char **argv);
bool cmdVMVarlist(int argc, const char **argv);
+ bool cmdVMVars(int argc, const char **argv);
bool cmdStack(int argc, const char **argv);
bool cmdValueType(int argc, const char **argv);
bool cmdViewListNode(int argc, const char **argv);
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 8aa2cd68ed..28821523cd 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -358,47 +358,6 @@ int c_set_parse_nodes(EngineState *s, const Common::Array<cmd_param_t> &cmdParam
return 0;
}
-// parses with a GNF rule set
-
-int c_parse(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
- ResultWordList words;
- char *error;
- const char *string;
-
- if (!s) {
- sciprintf("Not in debug state\n");
- return 1;
- }
-
- string = cmdParams[0].str;
- sciprintf("Parsing '%s'\n", string);
- bool res = s->_vocabulary->tokenizeString(words, string, &error);
- if (res && !words.empty()) {
- int syntax_fail = 0;
-
- vocab_synonymize_tokens(words, s->_synonyms);
-
- sciprintf("Parsed to the following blocks:\n");
-
- for (ResultWordList::const_iterator i = words.begin(); i != words.end(); ++i)
- sciprintf(" Type[%04x] Group[%04x]\n", i->_class, i->_group);
-
- if (s->_vocabulary->parseGNF(s->parser_nodes, words, true))
- syntax_fail = 1; // Building a tree failed
-
- if (syntax_fail)
- sciprintf("Building a tree failed.\n");
- else
- vocab_dump_parse_tree("debug-parse-tree", s->parser_nodes);
-
- } else {
- sciprintf("Unknown word: '%s'\n", error);
- free(error);
- }
-
- return 0;
-}
-
extern const char *selector_name(EngineState *s, int selector);
int prop_ofs_to_id(EngineState *s, int prop_ofs, reg_t objp) {
@@ -678,44 +637,6 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod
return retval;
}
-int c_vmvars(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
- const char *varnames[] = {"global", "local", "temp", "param"};
- const char *varabbrev = "gltp";
- const char *vartype_pre = strchr(varabbrev, *cmdParams[0].str);
- int vartype;
- int idx = cmdParams[1].val;
-
- if (!vartype_pre) {
- sciprintf("Invalid variable type '%c'\n", *cmdParams[0].str);
- return 1;
- }
- vartype = vartype_pre - varabbrev;
-
- if (idx < 0) {
- sciprintf("Invalid: negative index\n");
- return 1;
- }
- if ((p_var_max) && (p_var_max[vartype] <= idx)) {
- sciprintf("Max. index is %d (0x%x)\n", p_var_max[vartype], p_var_max[vartype]);
- return 1;
- }
-
- switch (cmdParams.size()) {
- case 2:
- sciprintf("%s var %d == %04x:%04x\n", varnames[vartype], idx, PRINT_REG(p_vars[vartype][idx]));
- break;
-
- case 3:
- p_vars[vartype][idx] = cmdParams[2].reg;
- break;
-
- default:
- sciprintf("Too many arguments\n");
- }
-
- return 0;
-}
-
static int c_backtrace(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
if (!_debugstate_valid) {
sciprintf("Not in debug state\n");
@@ -824,9 +745,7 @@ static int c_gfx_print_widget(EngineState *s, const Common::Array<cmd_param_t> &
#if 0
// Unreferenced - removed
static int c_gfx_draw_viewobj(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
-#ifdef __GNUC__
-#warning "Re-implement con:gfx_draw_viewobj"
-#endif
+// TODO: Re-implement gfx_draw_viewobj
#if 0
HeapPtr pos = (HeapPtr)(cmdParams[0].val);
int is_view;
@@ -873,15 +792,10 @@ static int c_gfx_draw_viewobj(EngineState *s, const Common::Array<cmd_param_t> &
nsBottom += 10;
gfxop_fill_box(s->gfx_state, gfx_rect(nsLeft, nsTop, nsRight - nsLeft + 1, nsBottom - nsTop + 1), s->ega_colors[2]);
-
gfxop_fill_box(s->gfx_state, gfx_rect(brLeft, brTop, brRight - brLeft + 1, brBottom - brTop + 1), s->ega_colors[1]);
-
gfxop_fill_box(s->gfx_state, gfx_rect(x - 1, y - 1, 3, 3), s->ega_colors[0]);
-
gfxop_fill_box(s->gfx_state, gfx_rect(x - 1, y, 3, 1), s->ega_colors[priority]);
-
gfxop_fill_box(s->gfx_state, gfx_rect(x, y - 1, 1, 3), s->ega_colors[priority]);
-
gfxop_update(s->gfx_state);
return 0;
@@ -1155,54 +1069,6 @@ static void viewobjinfo(EngineState *s, HeapPtr pos) {
// Breakpoint commands
-static Breakpoint *bp_alloc(EngineState *s) {
- Breakpoint *bp;
-
- if (s->bp_list) {
- bp = s->bp_list;
- while (bp->next)
- bp = bp->next;
- bp->next = (Breakpoint *)malloc(sizeof(Breakpoint));
- bp = bp->next;
- } else {
- s->bp_list = (Breakpoint *)malloc(sizeof(Breakpoint));
- bp = s->bp_list;
- }
-
- bp->next = NULL;
-
- return bp;
-}
-
-int c_bpx(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
- Breakpoint *bp;
-
- /* Note: We can set a breakpoint on a method that has not been loaded yet.
- Thus, we can't check whether the command argument is a valid method name.
- A breakpoint set on an invalid method name will just never trigger. */
-
- bp = bp_alloc(s);
-
- bp->type = BREAK_SELECTOR;
- bp->data.name = (char *)malloc(strlen(cmdParams [0].str) + 1);
- strcpy(bp->data.name, cmdParams [0].str);
- s->have_bp |= BREAK_SELECTOR;
-
- return 0;
-}
-
-int c_bpe(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
- Breakpoint *bp;
-
- bp = bp_alloc(s);
-
- bp->type = BREAK_EXPORT;
- bp->data.address = (cmdParams [0].val << 16 | cmdParams [1].val);
- s->have_bp |= BREAK_EXPORT;
-
- return 0;
-}
-
int c_se(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
stop_on_event = 1;
_debugstate_valid = 0;
@@ -1306,7 +1172,6 @@ void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t *
if (_debug_commands_not_hooked) {
_debug_commands_not_hooked = 0;
- con_hook_command(c_vmvars, "vmvars", "!sia*", "Displays or changes variables in the VM\n\nFirst parameter is either g(lobal), l(ocal), t(emp) or p(aram).\nSecond parameter is the var number\nThird parameter (if specified) is the value to set the variable to");
con_hook_command(c_step, "s", "i*", "Executes one or several operations\n\nEXAMPLES\n\n"
" s 4\n\n Execute 4 commands\n\n s\n\n Execute next command");
#if 0
@@ -1326,13 +1191,7 @@ void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t *
con_hook_command(c_se, "se", "", "Steps forward until an SCI event is received.\n");
con_hook_command(c_send, "send", "!asa*", "Sends a message to an object\nExample: send ?fooScript cue");
con_hook_command(c_sret, "sret", "", "Steps forward until ret is called\n on the current execution stack\n level.");
- con_hook_command(c_bpx, "bpx", "s", "Sets a breakpoint on the execution of\n the specified method.\n\n EXAMPLE:\n"
- " bpx ego::doit\n\n May also be used to set a breakpoint\n that applies whenever an object\n"
- " of a specific type is touched:\n bpx foo::\n");
- con_hook_command(c_bpe, "bpe", "ii", "Sets a breakpoint on the execution of specified exported function.\n");
con_hook_command(c_go, "go", "", "Executes the script.\n");
- con_hook_command(c_parse, "parse", "s", "Parses a sequence of words and prints\n the resulting parse tree.\n"
- " The word sequence must be provided as a\n single string.");
con_hook_command(c_set_parse_nodes, "set_parse_nodes", "s*", "Sets the contents of all parse nodes.\n"
" Input token must be separated by\n blanks.");