aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure64
-rw-r--r--gui/debugger.cpp89
-rw-r--r--gui/debugger.h13
3 files changed, 142 insertions, 24 deletions
diff --git a/configure b/configure
index c3dc01d52c..2ad21c58ef 100755
--- a/configure
+++ b/configure
@@ -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