Add optional readline support to the text debugger console.
Make text/graphical console selectable with an option to configure. svn-id: r42787
This commit is contained in:
parent
037c02a1f7
commit
45cde5f642
3 changed files with 142 additions and 24 deletions
64
configure
vendored
64
configure
vendored
|
@ -110,8 +110,10 @@ _alsa=auto
|
||||||
_zlib=auto
|
_zlib=auto
|
||||||
_mpeg2=no
|
_mpeg2=no
|
||||||
_fluidsynth=auto
|
_fluidsynth=auto
|
||||||
_mt32emu=yes
|
_readline=auto
|
||||||
# Default option behaviour yes/no
|
# Default option behaviour yes/no
|
||||||
|
_text_console=no
|
||||||
|
_mt32emu=yes
|
||||||
_build_hq_scalers=yes
|
_build_hq_scalers=yes
|
||||||
_build_scalers=yes
|
_build_scalers=yes
|
||||||
# Default vkeybd/keymapper options
|
# Default vkeybd/keymapper options
|
||||||
|
@ -580,6 +582,7 @@ $engines_help
|
||||||
--disable-mt32emu don't enable the integrated MT-32 emulator
|
--disable-mt32emu don't enable the integrated MT-32 emulator
|
||||||
--disable-hq-scalers exclude HQ2x and HQ3x scalers
|
--disable-hq-scalers exclude HQ2x and HQ3x scalers
|
||||||
--disable-scalers exclude scalers
|
--disable-scalers exclude scalers
|
||||||
|
--enable-text-console use text console instead of graphical console
|
||||||
|
|
||||||
Optional Libraries:
|
Optional Libraries:
|
||||||
--with-alsa-prefix=DIR Prefix where alsa is installed (optional)
|
--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)
|
--with-nasm-prefix=DIR Prefix where nasm executable is installed (optional)
|
||||||
--disable-nasm disable assembly language optimizations [autodetect]
|
--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:
|
Some influential environment variables:
|
||||||
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
|
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
|
||||||
nonstandard directory <lib dir>
|
nonstandard directory <lib dir>
|
||||||
|
@ -647,6 +653,8 @@ for ac_option in $@; do
|
||||||
--disable-nasm) _nasm=no ;;
|
--disable-nasm) _nasm=no ;;
|
||||||
--enable-mpeg2) _mpeg2=yes ;;
|
--enable-mpeg2) _mpeg2=yes ;;
|
||||||
--disable-fluidsynth) _fluidsynth=no ;;
|
--disable-fluidsynth) _fluidsynth=no ;;
|
||||||
|
--enable-readline) _readline=yes ;;
|
||||||
|
--disable-readline) _readline=no ;;
|
||||||
--enable-plugins) _dynamic_modules=yes ;;
|
--enable-plugins) _dynamic_modules=yes ;;
|
||||||
--default-dynamic) _plugins_default=dynamic ;;
|
--default-dynamic) _plugins_default=dynamic ;;
|
||||||
--enable-mt32emu) _mt32emu=yes ;;
|
--enable-mt32emu) _mt32emu=yes ;;
|
||||||
|
@ -655,6 +663,8 @@ for ac_option in $@; do
|
||||||
--disable-vkeybd) _vkeybd=no ;;
|
--disable-vkeybd) _vkeybd=no ;;
|
||||||
--enable-keymapper) _keymapper=yes ;;
|
--enable-keymapper) _keymapper=yes ;;
|
||||||
--disable-keymapper) _keymapper=no ;;
|
--disable-keymapper) _keymapper=no ;;
|
||||||
|
--enable-text-console) _text_console=yes ;;
|
||||||
|
--disable-text-console) _text_console=no ;;
|
||||||
--with-fluidsynth-prefix=*)
|
--with-fluidsynth-prefix=*)
|
||||||
arg=`echo $ac_option | cut -d '=' -f 2`
|
arg=`echo $ac_option | cut -d '=' -f 2`
|
||||||
FLUIDSYNTH_CFLAGS="-I$arg/include"
|
FLUIDSYNTH_CFLAGS="-I$arg/include"
|
||||||
|
@ -700,6 +710,11 @@ for ac_option in $@; do
|
||||||
ZLIB_CFLAGS="-I$arg/include"
|
ZLIB_CFLAGS="-I$arg/include"
|
||||||
ZLIB_LIBS="-L$arg/lib"
|
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=*)
|
||||||
_backend=`echo $ac_option | cut -d '=' -f 2`
|
_backend=`echo $ac_option | cut -d '=' -f 2`
|
||||||
;;
|
;;
|
||||||
|
@ -1801,6 +1816,45 @@ fi
|
||||||
echo "$_fluidsynth"
|
echo "$_fluidsynth"
|
||||||
rm -rf $TMPC $TMPO$HOSTEXEEXT $TMPO.dSYM
|
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
|
# Check for nasm
|
||||||
#
|
#
|
||||||
|
@ -1884,6 +1938,10 @@ if test "$_mt32emu" = yes ; then
|
||||||
echo_n ", MT-32 emu"
|
echo_n ", MT-32 emu"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$_text_console" = yes ; then
|
||||||
|
echo_n ", text console"
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$_vkeybd" = yes ; then
|
if test "$_vkeybd" = yes ; then
|
||||||
echo_n ", virtual keyboard"
|
echo_n ", virtual keyboard"
|
||||||
fi
|
fi
|
||||||
|
@ -2095,6 +2153,10 @@ $_def_alsa
|
||||||
$_def_zlib
|
$_def_zlib
|
||||||
$_def_mpeg2
|
$_def_mpeg2
|
||||||
$_def_fluidsynth
|
$_def_fluidsynth
|
||||||
|
$_def_readline
|
||||||
|
|
||||||
|
/* Options */
|
||||||
|
$_def_text_console
|
||||||
$_def_mt32emu
|
$_def_mt32emu
|
||||||
|
|
||||||
/* Plugin settings */
|
/* Plugin settings */
|
||||||
|
|
|
@ -27,10 +27,14 @@
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
|
|
||||||
#include "gui/debugger.h"
|
#include "gui/debugger.h"
|
||||||
#if USE_CONSOLE
|
#ifndef USE_TEXT_CONSOLE
|
||||||
#include "gui/console.h"
|
#include "gui/console.h"
|
||||||
|
#elif defined(USE_READLINE)
|
||||||
|
#include <readline/readline.h>
|
||||||
|
#include <readline/history.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
Debugger::Debugger() {
|
Debugger::Debugger() {
|
||||||
|
@ -39,7 +43,7 @@ Debugger::Debugger() {
|
||||||
_isAttached = false;
|
_isAttached = false;
|
||||||
_errStr = NULL;
|
_errStr = NULL;
|
||||||
_firstTime = true;
|
_firstTime = true;
|
||||||
#if USE_CONSOLE
|
#ifndef USE_TEXT_CONSOLE
|
||||||
_debuggerDialog = new GUI::ConsoleDialog(1.0f, 0.67f);
|
_debuggerDialog = new GUI::ConsoleDialog(1.0f, 0.67f);
|
||||||
_debuggerDialog->setInputCallback(debuggerInputCallback, this);
|
_debuggerDialog->setInputCallback(debuggerInputCallback, this);
|
||||||
_debuggerDialog->setCompletionCallback(debuggerCompletionCallback, this);
|
_debuggerDialog->setCompletionCallback(debuggerCompletionCallback, this);
|
||||||
|
@ -57,7 +61,7 @@ Debugger::Debugger() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Debugger::~Debugger() {
|
Debugger::~Debugger() {
|
||||||
#if USE_CONSOLE
|
#ifndef USE_TEXT_CONSOLE
|
||||||
delete _debuggerDialog;
|
delete _debuggerDialog;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -69,7 +73,7 @@ int Debugger::DebugPrintf(const char *format, ...) {
|
||||||
|
|
||||||
va_start(argptr, format);
|
va_start(argptr, format);
|
||||||
int count;
|
int count;
|
||||||
#if USE_CONSOLE
|
#ifndef USE_TEXT_CONSOLE
|
||||||
count = _debuggerDialog->vprintf(format, argptr);
|
count = _debuggerDialog->vprintf(format, argptr);
|
||||||
#else
|
#else
|
||||||
count = ::vprintf(format, argptr);
|
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
|
// Main Debugger Loop
|
||||||
void Debugger::enter() {
|
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) {
|
if (_firstTime) {
|
||||||
DebugPrintf("Debugger started, type 'exit' to return to the game.\n");
|
DebugPrintf("Debugger started, type 'exit' to return to the game.\n");
|
||||||
DebugPrintf("Type 'help' to see a little list of commands and variables.\n");
|
DebugPrintf("Type 'help' to see a little list of commands and variables.\n");
|
||||||
|
@ -133,18 +149,28 @@ void Debugger::enter() {
|
||||||
|
|
||||||
_debuggerDialog->runModal();
|
_debuggerDialog->runModal();
|
||||||
#else
|
#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");
|
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;
|
int i;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
|
@ -160,6 +186,7 @@ void Debugger::enter() {
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
continue;
|
continue;
|
||||||
} while (parseCommand(buf));
|
} while (parseCommand(buf));
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -330,6 +357,30 @@ bool Debugger::tabComplete(const char *input, Common::String &completion) const
|
||||||
return true;
|
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
|
// Variable registration function
|
||||||
void Debugger::DVar_Register(const Common::String &varname, void *pointer, int type, int optional) {
|
void Debugger::DVar_Register(const Common::String &varname, void *pointer, int type, int optional) {
|
||||||
// TODO: Filter out duplicates
|
// 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),
|
// Print a list of all registered commands (and variables, if any),
|
||||||
// nicely word-wrapped.
|
// nicely word-wrapped.
|
||||||
bool Debugger::Cmd_Help(int argc, const char **argv) {
|
bool Debugger::Cmd_Help(int argc, const char **argv) {
|
||||||
#if USE_CONSOLE
|
#ifndef USE_TEXT_CONSOLE
|
||||||
const int charsPerLine = _debuggerDialog->getCharsPerLine();
|
const int charsPerLine = _debuggerDialog->getCharsPerLine();
|
||||||
|
#elif defined(USE_READLINE)
|
||||||
|
int charsPerLine, rows;
|
||||||
|
rl_get_screen_size(&rows, &charsPerLine);
|
||||||
#else
|
#else
|
||||||
|
// Can we do better?
|
||||||
const int charsPerLine = 80;
|
const int charsPerLine = 80;
|
||||||
#endif
|
#endif
|
||||||
int width, size;
|
int width, size;
|
||||||
|
@ -460,7 +515,7 @@ bool Debugger::Cmd_DebugFlagDisable(int argc, const char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Console handler
|
// Console handler
|
||||||
#if USE_CONSOLE
|
#ifndef USE_TEXT_CONSOLE
|
||||||
bool Debugger::debuggerInputCallback(GUI::ConsoleDialog *console, const char *input, void *refCon) {
|
bool Debugger::debuggerInputCallback(GUI::ConsoleDialog *console, const char *input, void *refCon) {
|
||||||
Debugger *debugger = (Debugger *)refCon;
|
Debugger *debugger = (Debugger *)refCon;
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,7 @@
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
// Choose between text console or ScummConsole
|
#ifndef USE_TEXT_CONSOLE
|
||||||
#define USE_CONSOLE 1
|
|
||||||
|
|
||||||
#if USE_CONSOLE
|
|
||||||
class ConsoleDialog;
|
class ConsoleDialog;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -86,7 +83,7 @@ private:
|
||||||
bool _isAttached;
|
bool _isAttached;
|
||||||
char *_errStr;
|
char *_errStr;
|
||||||
bool _firstTime;
|
bool _firstTime;
|
||||||
#if USE_CONSOLE
|
#ifndef USE_TEXT_CONSOLE
|
||||||
GUI::ConsoleDialog *_debuggerDialog;
|
GUI::ConsoleDialog *_debuggerDialog;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -120,11 +117,15 @@ protected:
|
||||||
bool Cmd_DebugFlagEnable(int argc, const char **argv);
|
bool Cmd_DebugFlagEnable(int argc, const char **argv);
|
||||||
bool Cmd_DebugFlagDisable(int argc, const char **argv);
|
bool Cmd_DebugFlagDisable(int argc, const char **argv);
|
||||||
|
|
||||||
#if USE_CONSOLE
|
#ifndef USE_TEXT_CONSOLE
|
||||||
private:
|
private:
|
||||||
static bool debuggerInputCallback(GUI::ConsoleDialog *console, const char *input, void *refCon);
|
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);
|
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
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace GUI
|
} // End of namespace GUI
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue