diff options
-rwxr-xr-x | configure | 64 | ||||
-rw-r--r-- | gui/debugger.cpp | 89 | ||||
-rw-r--r-- | gui/debugger.h | 13 |
3 files changed, 142 insertions, 24 deletions
@@ -110,8 +110,10 @@ _alsa=auto _zlib=auto _mpeg2=no _fluidsynth=auto -_mt32emu=yes +_readline=auto # Default option behaviour yes/no +_text_console=no +_mt32emu=yes _build_hq_scalers=yes _build_scalers=yes # Default vkeybd/keymapper options @@ -580,6 +582,7 @@ $engines_help --disable-mt32emu don't enable the integrated MT-32 emulator --disable-hq-scalers exclude HQ2x and HQ3x scalers --disable-scalers exclude scalers + --enable-text-console use text console instead of graphical console Optional Libraries: --with-alsa-prefix=DIR Prefix where alsa is installed (optional) @@ -612,6 +615,9 @@ Optional Libraries: --with-nasm-prefix=DIR Prefix where nasm executable is installed (optional) --disable-nasm disable assembly language optimizations [autodetect] + --with-readline-prefix=DIR Prefix where readline is installed (optional) + --disable-readline disable readline support in text console [autodetect] + Some influential environment variables: LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> @@ -647,6 +653,8 @@ for ac_option in $@; do --disable-nasm) _nasm=no ;; --enable-mpeg2) _mpeg2=yes ;; --disable-fluidsynth) _fluidsynth=no ;; + --enable-readline) _readline=yes ;; + --disable-readline) _readline=no ;; --enable-plugins) _dynamic_modules=yes ;; --default-dynamic) _plugins_default=dynamic ;; --enable-mt32emu) _mt32emu=yes ;; @@ -655,6 +663,8 @@ for ac_option in $@; do --disable-vkeybd) _vkeybd=no ;; --enable-keymapper) _keymapper=yes ;; --disable-keymapper) _keymapper=no ;; + --enable-text-console) _text_console=yes ;; + --disable-text-console) _text_console=no ;; --with-fluidsynth-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` FLUIDSYNTH_CFLAGS="-I$arg/include" @@ -700,6 +710,11 @@ for ac_option in $@; do ZLIB_CFLAGS="-I$arg/include" ZLIB_LIBS="-L$arg/lib" ;; + --with-readline-prefix=*) + arg=`echo $ac_option | cut -d '=' -f 2` + READLINE_CFLAGS="-I$arg/include" + READLINE_LIBS="-L$arg/lib" + ;; --backend=*) _backend=`echo $ac_option | cut -d '=' -f 2` ;; @@ -1802,6 +1817,45 @@ echo "$_fluidsynth" rm -rf $TMPC $TMPO$HOSTEXEEXT $TMPO.dSYM # +# Check for readline if text_console is enabled +# +echocheck "readline" +if test "$_text_console" = yes ; then + if test "$_readline" = auto ; then + _readline=no + cat > $TMPC << EOF +#include <stdio.h> +#include <readline/readline.h> +#include <readline/history.h> + +int main(void) { + char *x = readline(""); +} +EOF + cc_check $LDFLAGS $CXXFLAGS $READLINE_CFLAGS $READLINE_LIBS -lreadline && _readline=yes + fi + echo "$_readline" + rm -rf $TMPC $TMPO$HOSTEXEEXT $TMPO.dSYM +else + _readline=no + echo "skipping (text console disabled)" +fi + +if test "$_readline" = yes ; then + _def_readline='#define USE_READLINE' + LIBS="$LIBS $READLINE_LIBS -lreadline" + INCLUDES="$INCLUDES $READLINE_CFLAGS" +else + _def_readline='#undef USE_READLINE' +fi + +if test "$_text_console" = yes ; then + _def_text_console='#define USE_TEXT_CONSOLE' +else + _def_text_console='#undef USE_TEXT_CONSOLE' +fi + +# # Check for nasm # if test "$_have_x86" = yes ; then @@ -1884,6 +1938,10 @@ if test "$_mt32emu" = yes ; then echo_n ", MT-32 emu" fi +if test "$_text_console" = yes ; then + echo_n ", text console" +fi + if test "$_vkeybd" = yes ; then echo_n ", virtual keyboard" fi @@ -2095,6 +2153,10 @@ $_def_alsa $_def_zlib $_def_mpeg2 $_def_fluidsynth +$_def_readline + +/* Options */ +$_def_text_console $_def_mt32emu /* Plugin settings */ diff --git a/gui/debugger.cpp b/gui/debugger.cpp index dd292a3a8a..a7dd9b2411 100644 --- a/gui/debugger.cpp +++ b/gui/debugger.cpp @@ -27,10 +27,14 @@ #include "common/system.h" #include "gui/debugger.h" -#if USE_CONSOLE +#ifndef USE_TEXT_CONSOLE #include "gui/console.h" +#elif defined(USE_READLINE) + #include <readline/readline.h> + #include <readline/history.h> #endif + namespace GUI { Debugger::Debugger() { @@ -39,7 +43,7 @@ Debugger::Debugger() { _isAttached = false; _errStr = NULL; _firstTime = true; -#if USE_CONSOLE +#ifndef USE_TEXT_CONSOLE _debuggerDialog = new GUI::ConsoleDialog(1.0f, 0.67f); _debuggerDialog->setInputCallback(debuggerInputCallback, this); _debuggerDialog->setCompletionCallback(debuggerCompletionCallback, this); @@ -57,7 +61,7 @@ Debugger::Debugger() { } Debugger::~Debugger() { -#if USE_CONSOLE +#ifndef USE_TEXT_CONSOLE delete _debuggerDialog; #endif } @@ -69,7 +73,7 @@ int Debugger::DebugPrintf(const char *format, ...) { va_start(argptr, format); int count; -#if USE_CONSOLE +#ifndef USE_TEXT_CONSOLE count = _debuggerDialog->vprintf(format, argptr); #else count = ::vprintf(format, argptr); @@ -116,9 +120,21 @@ void Debugger::onFrame() { } } +#if defined(USE_TEXT_CONSOLE) && defined(USE_READLINE) +static Debugger* g_readline_debugger; + +char * readline_completionFunction (const char *text, int state) +{ + return g_readline_debugger->readlineComplete(text, state); +} +#endif + // Main Debugger Loop void Debugger::enter() { -#if USE_CONSOLE + // TODO: Having three I/O methods #ifdef-ed in this file is not the + // cleanest approach to this... + +#ifndef USE_TEXT_CONSOLE if (_firstTime) { DebugPrintf("Debugger started, type 'exit' to return to the game.\n"); DebugPrintf("Type 'help' to see a little list of commands and variables.\n"); @@ -133,18 +149,28 @@ void Debugger::enter() { _debuggerDialog->runModal(); #else - // TODO: compared to the console input, this here is very bare bone. - // For example, no support for tab completion and no history. At least - // we should re-add (optional) support for the readline library. - // Or maybe instead of choosing between a console dialog and stdio, - // we should move that choice into the ConsoleDialog class - that is, - // the console dialog code could be #ifdef'ed to not print to the dialog - // but rather to stdio. This way, we could also reuse the command history - // and tab completion of the console. It would still require a lot of - // work, but at least no dependency on a 3rd party library... - printf("Debugger entered, please switch to this console for input.\n"); +#ifdef USE_READLINE + // TODO: add support for saving/loading history? + + g_readline_debugger = this; + rl_completion_entry_function = &readline_completionFunction; + + char *line_read = 0; + do { + free(line_read); + line_read = readline("debug> "); + + if (line_read && line_read[0]) + add_history(line_read); + + } while (line_read && parseCommand(line_read)); + + free(line_read); + line_read = 0; + +#else int i; char buf[256]; @@ -160,6 +186,7 @@ void Debugger::enter() { if (i == 0) continue; } while (parseCommand(buf)); +#endif #endif } @@ -330,6 +357,30 @@ bool Debugger::tabComplete(const char *input, Common::String &completion) const return true; } +#if defined(USE_TEXT_CONSOLE) && defined(USE_READLINE) +char* Debugger::readlineComplete(const char *input, int state) +{ + static CommandsMap::const_iterator iter; + + // We assume that _cmds isn't changed between calls to readlineComplete, + // unless state is 0. + if (state == 0) { + iter = _cmds.begin(); + } else { + ++iter; + } + + for (; iter != _cmds.end(); ++iter) { + if (iter->_key.hasPrefix(input)) { + char *ret = (char *)malloc(iter->_key.size() + 1); + strcpy(ret, iter->_key.c_str()); + return ret; + } + } + return 0; +} +#endif + // Variable registration function void Debugger::DVar_Register(const Common::String &varname, void *pointer, int type, int optional) { // TODO: Filter out duplicates @@ -361,9 +412,13 @@ bool Debugger::Cmd_Exit(int argc, const char **argv) { // Print a list of all registered commands (and variables, if any), // nicely word-wrapped. bool Debugger::Cmd_Help(int argc, const char **argv) { -#if USE_CONSOLE +#ifndef USE_TEXT_CONSOLE const int charsPerLine = _debuggerDialog->getCharsPerLine(); +#elif defined(USE_READLINE) + int charsPerLine, rows; + rl_get_screen_size(&rows, &charsPerLine); #else + // Can we do better? const int charsPerLine = 80; #endif int width, size; @@ -460,7 +515,7 @@ bool Debugger::Cmd_DebugFlagDisable(int argc, const char **argv) { } // Console handler -#if USE_CONSOLE +#ifndef USE_TEXT_CONSOLE bool Debugger::debuggerInputCallback(GUI::ConsoleDialog *console, const char *input, void *refCon) { Debugger *debugger = (Debugger *)refCon; diff --git a/gui/debugger.h b/gui/debugger.h index 1baf99faeb..81a85a7243 100644 --- a/gui/debugger.h +++ b/gui/debugger.h @@ -32,10 +32,7 @@ namespace GUI { -// Choose between text console or ScummConsole -#define USE_CONSOLE 1 - -#if USE_CONSOLE +#ifndef USE_TEXT_CONSOLE class ConsoleDialog; #endif @@ -86,7 +83,7 @@ private: bool _isAttached; char *_errStr; bool _firstTime; -#if USE_CONSOLE +#ifndef USE_TEXT_CONSOLE GUI::ConsoleDialog *_debuggerDialog; #endif @@ -120,11 +117,15 @@ protected: bool Cmd_DebugFlagEnable(int argc, const char **argv); bool Cmd_DebugFlagDisable(int argc, const char **argv); -#if USE_CONSOLE +#ifndef USE_TEXT_CONSOLE private: static bool debuggerInputCallback(GUI::ConsoleDialog *console, const char *input, void *refCon); static bool debuggerCompletionCallback(GUI::ConsoleDialog *console, const char *input, Common::String &completion, void *refCon); +#elif defined(USE_READLINE) +public: + char* readlineComplete(const char *input, int state); #endif + }; } // End of namespace GUI |