aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Brown2002-12-16 06:21:08 +0000
committerJames Brown2002-12-16 06:21:08 +0000
commite9898096653965b5cee0d73b4c802f19b07ab57a (patch)
tree0021a1d802e83910a07ac5f3a8fcb0e6441faef0
parent932bfdeed7e1c9c0cbe59a5a77970c316912bf93 (diff)
downloadscummvm-rg350-e9898096653965b5cee0d73b4c802f19b07ab57a.tar.gz
scummvm-rg350-e9898096653965b5cee0d73b4c802f19b07ab57a.tar.bz2
scummvm-rg350-e9898096653965b5cee0d73b4c802f19b07ab57a.zip
New debugger core. Doesn't really have anything implemented yet, but is far more expandable and userfriendly than our previous.
Enable experimental console debugger by default, as I havn't written the text console code yet :) svn-id: r5990
-rw-r--r--gui/console.cpp2
-rw-r--r--scumm/debugger.cpp240
-rw-r--r--scumm/debugger.h72
-rw-r--r--scumm/module.mk3
-rw-r--r--scumm/scummvm.cpp7
5 files changed, 316 insertions, 8 deletions
diff --git a/gui/console.cpp b/gui/console.cpp
index ef8aa12a26..1e3c2c1226 100644
--- a/gui/console.cpp
+++ b/gui/console.cpp
@@ -37,7 +37,7 @@ This code is not finished, so please don't complain :-)
*/
-#define PROMPT "$ "
+#define PROMPT ") "
/* TODO:
* - it is very inefficient to redraw the full thingy when just one char is added/removed.
diff --git a/scumm/debugger.cpp b/scumm/debugger.cpp
new file mode 100644
index 0000000000..50c69495e0
--- /dev/null
+++ b/scumm/debugger.cpp
@@ -0,0 +1,240 @@
+#include "stdafx.h"
+#include "scumm.h"
+#include "sound.h"
+#include "actor.h"
+#include "debugger.h"
+#include "common/util.h"
+
+// The new debugger doesn't actually have the guts for text console coded yet ;)
+
+#define USE_CONSOLE
+
+// Choose between text console or ScummConsole
+#ifdef USE_CONSOLE
+ #include "gui/console.h"
+ #define Debug_Printf _s->_debuggerDialog->printf
+#else
+ #define Debug_Printf printf
+#endif
+
+// Initialisation Functions
+void ScummDebugger::attach(Scumm *s)
+{
+ if (_s)
+ detach();
+
+ _s = s;
+ s->_debugger = this;
+ _frame_countdown = 1;
+ _detach_now = false;
+
+ if (_dvar_count < 1) { // We need to register our variables
+ DVar_Register("debug_countdown", &_frame_countdown, DVAR_INT, 0);
+
+ DVar_Register("scumm_speed", &_s->_fastMode, DVAR_INT, 0);
+ DVar_Register("scumm_room", &_s->_currentRoom, DVAR_INT, 0);
+ DVar_Register("scumm_roomresource", &_s->_roomResource, DVAR_INT, 0);
+ DVar_Register("scumm_vars", &_s->_vars, DVAR_INTARRAY, _s->_numVariables);
+
+ DVar_Register("scumm_gamename", &_s->_game_name, DVAR_STRING, 0);
+ DVar_Register("scumm_exename", &_s->_exe_name, DVAR_STRING, 0);
+ DVar_Register("scumm_gameid", &_s->_gameId, DVAR_INT, 0);
+ }
+
+ if (_dcmd_count < 1) { // We need to register our commands
+ DCmd_Register("exit", &ScummDebugger::Cmd_Exit);
+ DCmd_Register("quit", &ScummDebugger::Cmd_Exit);
+ }
+}
+
+void ScummDebugger::detach()
+{
+#ifdef USE_CONSOLE
+ if (_s->_debuggerDialog)
+ _s->_debuggerDialog->setInputeCallback(0, 0);
+#endif
+
+ _s->_debugger = NULL;
+ _s = NULL;
+ _detach_now = false;
+}
+
+
+// Temporary execution handler
+void ScummDebugger::on_frame() {
+ if (_frame_countdown == 0)
+ return;
+ --_frame_countdown;
+
+ if (!_frame_countdown) {
+ // Pause sound output
+ bool old_soundsPaused = _s->_sound->_soundsPaused;
+ _s->_sound->pauseSounds(true);
+
+ // Enter debugger
+ enter();
+
+ _s->_sound->pauseSounds(old_soundsPaused); // Resume previous sound state
+
+ if (_detach_now) // Detach if we're finished with the debugger
+ detach();
+ }
+}
+
+// Console handler
+#ifdef USE_CONSOLE
+bool ScummDebugger::debuggerInputCallback(ConsoleDialog *console, const char *input, void *refCon)
+{
+ ScummDebugger *debugger = (ScummDebugger *)refCon;
+
+ return debugger->RunCommand((char*)input);
+}
+#endif
+
+///////////////////////////////////////////////////
+// Now the fun stuff:
+
+// Command/Variable registration functions
+void ScummDebugger::DVar_Register(char *varname, void *pointer, int type, int optional) {
+ strcpy(_dvars[_dvar_count].name, varname);
+ _dvars[_dvar_count].type = type;
+ _dvars[_dvar_count].variable = pointer;
+ _dvars[_dvar_count].optional = optional;
+
+ _dvar_count++;
+}
+
+void ScummDebugger::DCmd_Register(char *cmdname, DebugProc pointer) {
+ strcpy(_dcmds[_dcmd_count].name, cmdname);
+ _dcmds[_dcmd_count].function = pointer;
+
+ _dcmd_count++;
+}
+
+// Main Debugger Loop
+void ScummDebugger::enter()
+{
+#ifdef USE_CONSOLE
+ if (!_s->_debuggerDialog) {
+ _s->_debuggerDialog = new ConsoleDialog(_s->_newgui);
+ Debug_Printf("Debugger started, type 'exit' to return to the game\n");
+ }
+
+ _s->_debuggerDialog->setInputeCallback(debuggerInputCallback, this);
+ _s->_debuggerDialog->runModal();
+#else
+ printf("Debugger entered, please switch to this console for input.\n");
+// while(1) {
+// ;
+// }
+#endif
+}
+
+// Command execution loop
+bool ScummDebugger::RunCommand(char *input) {
+ int i = 0, num_parms = 0;
+ char parm[255][255];
+
+ // Parse out any params
+ char *tok = strtok(input, " ");
+ if (tok) {
+ do {
+ strcpy(parm[num_parms++], tok);
+ } while ((tok = strtok(NULL, " ")) != NULL);
+ } else
+ strcpy(parm[0], input);
+
+ for(i=0;i<_dcmd_count;i++) {
+ if (!strcmp(_dcmds[i].name, parm[0])) {
+ DebugProc cmd;
+
+ cmd = _dcmds[i].function;
+ return (this->*cmd)();
+ }
+ }
+
+ // It's not a command, so things get a little tricky for variables. Do fuzzy matching to ignore things like subscripts.
+ for(i=0;i<_dvar_count;i++) {
+ if (!strncmp(_dvars[i].name, parm[0], strlen(_dvars[i].name))) {
+ if (num_parms > 1) {
+ // Alright, we need to check the TYPE of the variable to deref and stuff... the array stuff is a bit ugly :)
+ switch(_dvars[i].type) {
+ // Integer
+ case DVAR_INT:
+ *(int *)_dvars[i].variable = atoi(parm[1]);
+ Debug_Printf("(int)%s = %d\n", parm[0], *(int *)_dvars[i].variable);
+ break;
+
+ // Integer Array
+ case DVAR_INTARRAY: {
+ char *chr = strchr(parm[0], '[');
+ if (!chr) {
+ Debug_Printf("You must access this array as %s[element]\n", parm[0]);
+ } else {
+ int element = atoi(chr+1);
+ int16 *var = *(int16 **)_dvars[i].variable;
+ if (element > _dvars[i].optional) {
+ Debug_Printf("%s is out of range (array is %d elements big)\n", parm[0], _dvars[i].optional);
+ } else {
+ var[element] = atoi(parm[1]);
+ Debug_Printf("(int)%s = %d\n", parm[0], var[element]);
+
+ }
+ }
+ }
+ break;
+
+ default:
+ Debug_Printf("Failed to set variable %s to %s - unknown type\n", _dvars[i].name, parm[1]);
+ break;
+ }
+ } else {
+ // And again, type-dependent prints/defrefs. The array one is still ugly.
+ switch(_dvars[i].type) {
+ // Integer
+ case DVAR_INT:
+ Debug_Printf("(int)%s = %d\n", parm[0], *(int *)_dvars[i].variable);
+ break;
+
+ // Integer array
+ case DVAR_INTARRAY: {
+ char *chr = strchr(parm[0], '[');
+ if (!chr) {
+ Debug_Printf("You must access this array as %s[element]\n", parm[0]);
+ } else {
+ int element = atoi(chr+1);
+ int16 *var = *(int16 **)_dvars[i].variable;
+ if (element > _dvars[i].optional) {
+ Debug_Printf("%s is out of range (array is %d elements big)\n", parm[0], _dvars[i].optional);
+ } else {
+ Debug_Printf("(int)%s = %d\n", parm[0], var[element]);
+
+ }
+ }
+ }
+ break;
+
+ // String
+ case DVAR_STRING:
+ Debug_Printf("(string)%s = %s\n", parm[0], *(char **)_dvars[i].variable);
+ break;
+
+ default:
+ Debug_Printf("%s = (unknown type)\n", parm[0]);
+ break;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ Debug_Printf("Unknown command or variable\n");
+ return true;
+}
+
+// Commands
+bool ScummDebugger::Cmd_Exit() {
+ _detach_now = true;
+ return false;
+}
diff --git a/scumm/debugger.h b/scumm/debugger.h
new file mode 100644
index 0000000000..7029b441e5
--- /dev/null
+++ b/scumm/debugger.h
@@ -0,0 +1,72 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+class Scumm;
+typedef bool (ScummDebugger::*DebugProc)();
+
+enum {
+ DVAR_INT,
+ DVAR_BOOL,
+ DVAR_INTARRAY,
+ DVAR_STRING
+};
+
+struct DVar {
+ char name[30];
+ void *variable;
+ int type, optional;
+};
+
+struct DCmd {
+ char name[30];
+ DebugProc function;
+};
+
+class ScummDebugger {
+public:
+ void on_frame();
+ void attach(Scumm *s);
+
+protected:
+ Scumm *_s;
+ int _frame_countdown, _dvar_count, _dcmd_count;
+ DVar _dvars[255];
+ DCmd _dcmds[255];
+ bool _detach_now;
+
+ void enter();
+ void detach();
+
+ void DVar_Register(char *varname, void *pointer, int type, int optional);
+ void DCmd_Register(char *cmdname, DebugProc pointer);
+ bool RunCommand(char *input);
+
+ // Commands
+ bool Cmd_Exit();
+
+#ifdef USE_CONSOLE
+ static bool ScummDebugger::debuggerInputCallback(ConsoleDialog *console, const char *input, void *refCon);
+#endif
+};
+
+#endif
diff --git a/scumm/module.mk b/scumm/module.mk
index b7caaf620b..57266d38ec 100644
--- a/scumm/module.mk
+++ b/scumm/module.mk
@@ -6,8 +6,7 @@ SCUMM_OBJS = \
scumm/boxes.o \
scumm/bundle.o \
scumm/costume.o \
- scumm/debug.o \
- scumm/debugrl.o \
+ scumm/debugger.o \
scumm/dialogs.o \
scumm/gfx.o \
scumm/imuse.o \
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index b9d7e19e66..59f68e691c 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -46,6 +46,7 @@ extern void drawError(char*);
// Use g_scumm from error() ONLY
Scumm *g_scumm = 0;
+ScummDebugger g_debugger;
extern NewGui *g_gui;
@@ -1003,9 +1004,7 @@ void Scumm::saveloadDialog()
void Scumm::debuggerDialog()
{
- if (!_debuggerDialog)
- _debuggerDialog = new ConsoleDialog(_newgui);
- runDialog(_debuggerDialog);
+ g_debugger.attach(this);
}
void Scumm::optionsDialog()
@@ -1374,8 +1373,6 @@ void NORETURN CDECL error(const char *s, ...)
exit(1);
}
-ScummDebugger g_debugger;
-
void Scumm::waitForTimer(int msec_delay) {
OSystem::Event event;
uint32 start_time;