Further work on the debugger console:

Added typical Unix shell shortcut keys (still TODO is Ctrl-U)
Fixed delete action causing crashes
Made cursor redraw at the correct place

Still TODO: use Unicode to accurately represent keypresses onscreen.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@471 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-06-07 19:01:53 +00:00
parent 93f9e9e526
commit 08548e51df
5 changed files with 177 additions and 142 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: EventHandler.cxx,v 1.70 2005-06-05 23:46:19 stephena Exp $
// $Id: EventHandler.cxx,v 1.71 2005-06-07 19:01:53 stephena Exp $
//============================================================================
#include <algorithm>
@ -246,14 +246,18 @@ void EventHandler::poll(uInt32 time)
SDLMod mod = event.key.keysym.mod;
uInt8 state = event.key.type == SDL_KEYDOWN ? 1 : 0;
if(event.type == SDL_KEYDOWN)
{
if(kbdShift(mod))
cerr << "shift key: " << (char)key << endl;
else
cerr << "key: " << (char)key << endl;
}
// An attempt to speed up event processing
// All SDL-specific event actions are accessed by either
// Control/Cmd or Alt/Shift-Cmd keys. So we quickly check for those.
#ifndef MAC_OSX
if(mod & KMOD_ALT && state)
#else
if((mod & KMOD_META) && (mod & KMOD_SHIFT) && state)
#endif
if(kbdAlt(mod) && state)
{
// These keys work in all states
switch(int(key))
@ -349,11 +353,7 @@ void EventHandler::poll(uInt32 time)
}
}
}
#ifndef MAC_OSX
else if(mod & KMOD_CTRL && state)
#else
else if((mod & KMOD_META) && !(mod & KMOD_SHIFT) && state)
#endif
else if(kbdControl(mod) && state)
{
// These keys work in all states
switch(int(key))
@ -442,9 +442,9 @@ void EventHandler::poll(uInt32 time)
}
}
}
else
// Otherwise, let the event handler deal with it
handleKeyEvent(key, mod, state);
// Otherwise, let the event handler deal with it
handleKeyEvent(key, mod, state);
break; // SDL_KEYUP, SDL_KEYDOWN
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: EventHandler.hxx,v 1.34 2005-05-28 17:25:41 stephena Exp $
// $Id: EventHandler.hxx,v 1.35 2005-06-07 19:01:53 stephena Exp $
//============================================================================
#ifndef EVENTHANDLER_HXX
@ -74,7 +74,7 @@ struct Stella_Joystick {
mapping can take place.
@author Stephen Anthony
@version $Id: EventHandler.hxx,v 1.34 2005-05-28 17:25:41 stephena Exp $
@version $Id: EventHandler.hxx,v 1.35 2005-06-07 19:01:53 stephena Exp $
*/
class EventHandler
{
@ -180,6 +180,29 @@ class EventHandler
*/
void setPaddleMode(uInt32 num, bool showmessage = false);
inline bool kbdAlt(int mod)
{
#ifndef MAC_OSX
return (mod & KMOD_ALT) > 0;
#else
return ((mod & KMOD_META) && (mod & KMOD_SHIFT));
#endif
}
inline bool kbdControl(int mod)
{
#ifndef MAC_OSX
return (mod & KMOD_CTRL) > 0;
#else
return ((mod & KMOD_META) && !(mod & KMOD_SHIFT))
#endif
}
inline bool kbdShift(int mod)
{
return (mod & KMOD_SHIFT) > 0;
}
// Holds static strings for the remap menu
static ActionList ourActionList[61];

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: ListWidget.cxx,v 1.9 2005-06-07 01:14:39 stephena Exp $
// $Id: ListWidget.cxx,v 1.10 2005-06-07 19:01:53 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -188,6 +188,11 @@ static bool matchingCharsIgnoringCase(string s, string pattern)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers)
{
// Ignore all mod keys
if(instance()->eventHandler().kbdControl(modifiers) ||
instance()->eventHandler().kbdControl(modifiers))
return true;
bool handled = true;
bool dirty = false;
int oldSelectedItem = _selectedItem;
@ -250,7 +255,7 @@ bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers)
dirty = true;
break;
default:
if (isprint((char)ascii))
if (ascii < 128)
{
_list[_selectedItem] += (char)ascii;
dirty = true;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: PromptDialog.cxx,v 1.1 2005-06-07 01:14:39 stephena Exp $
// $Id: PromptDialog.cxx,v 1.2 2005-06-07 19:01:53 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -21,6 +21,8 @@
#include "ScrollBarWidget.hxx"
#include "FrameBuffer.hxx"
#include "EventHandler.hxx"
#include "Version.hxx"
#include "PromptDialog.hxx"
@ -56,12 +58,6 @@ PromptDialog::PromptDialog(OSystem* osystem, DialogContainer* parent,
_scrollLine = _linesPerPage - 1;
_firstLineInBuffer = 0;
_caretVisible = true;//false;
_caretTime = 0;
_slideMode = kNoSlideMode;
_slideTime = 0;
// Add scrollbar
_scrollBar = new ScrollBarWidget(this, _w - kScrollBarWidth - 1, 0, kScrollBarWidth, _h);
_scrollBar->setTarget(this);
@ -80,8 +76,9 @@ PromptDialog::PromptDialog(OSystem* osystem, DialogContainer* parent,
_promptStartPos = _promptEndPos = -1;
// Display greetings & prompt
print("HELLO!!");//gScummVMFullVersion);
print("\nDebugger is ready\n");
string version = string("Stella version ") + STELLA_VERSION + "\n";
print(version.c_str());
print("Debugger is ready\n");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -89,6 +86,16 @@ PromptDialog::~PromptDialog()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptDialog::loadConfig()
{
if (_promptStartPos == -1)
{
print(PROMPT);
_promptStartPos = _promptEndPos = _currentPos;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptDialog::drawDialog()
{
@ -120,6 +127,9 @@ void PromptDialog::drawDialog()
y += kConsoleLineHeight;
}
// Draw the caret
drawCaret();
// Draw the scrollbar
_scrollBar->draw();
}
@ -133,27 +143,19 @@ void PromptDialog::handleMouseWheel(int x, int y, int direction)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptDialog::handleKeyDown(int ascii, int keycode, int modifiers)
{
cerr << "PromptDialog::handleKeyDown\n";
int i;
if (_slideMode != kNoSlideMode)
return;
switch (keycode)
{
case '\n': // enter/return
case '\r':
{
if (_caretVisible)
drawCaret(true);
nextLine();
assert(_promptEndPos >= _promptStartPos);
int len = _promptEndPos - _promptStartPos;
bool keepRunning = true;
if (len > 0)
{
// We have to allocate the string buffer with new, since VC++ sadly does not
@ -172,6 +174,7 @@ cerr << "PromptDialog::handleKeyDown\n";
if (_callbackProc)
keepRunning = (*_callbackProc)(this, str, _callbackRefCon);
cerr << "Command entered: \'" << str << "\'\n";
// Get rid of the string buffer
delete [] str;
}
@ -185,14 +188,9 @@ cerr << "PromptDialog::handleKeyDown\n";
}
case 8: // backspace
if (_caretVisible)
drawCaret(true);
if (_currentPos > _promptStartPos)
{
_currentPos--;
killChar();
}
killChar(-1);
scrollToCurrent();
draw(); // FIXME - not nice to redraw the full console just for one char!
instance()->frameBuffer().refresh();
@ -214,8 +212,6 @@ cerr << "PromptDialog::handleKeyDown\n";
char *completion = 0;
if ((*_completionCallbackProc)(this, str, completion, _callbackRefCon))
{
if (_caretVisible)
drawCaret(true);
insertIntoPrompt(completion);
scrollToCurrent();
draw();
@ -228,7 +224,7 @@ cerr << "PromptDialog::handleKeyDown\n";
}
case 127:
killChar();
killChar(1);
draw();
instance()->frameBuffer().refresh();
break;
@ -258,7 +254,7 @@ cerr << "PromptDialog::handleKeyDown\n";
break;
case 256 + 22: // home
if (1) // FIXME - shift modifiers == OSystem::KBD_SHIFT)
if (0) // FIXME - shift modifiers == OSystem::KBD_SHIFT)
{
_scrollLine = _firstLineInBuffer + _linesPerPage - 1;
updateScrollBuffer();
@ -271,7 +267,7 @@ cerr << "PromptDialog::handleKeyDown\n";
break;
case 256 + 23: // end
if (1) // FIXME - shift modifiers == OSystem::KBD_SHIFT)
if (0) // FIXME - shift modifiers == OSystem::KBD_SHIFT)
{
_scrollLine = _promptEndPos / _lineWidth;
if (_scrollLine < _linesPerPage - 1)
@ -308,16 +304,26 @@ cerr << "PromptDialog::handleKeyDown\n";
break;
default:
/* FIXME
} else if (modifiers == OSystem::KBD_CTRL) {
specialKeys(keycode);
*/
if (isprint((char)ascii))
cerr << "ascii: " << ascii << endl;
if (instance()->eventHandler().kbdControl(modifiers))
{
specialKeys(keycode);
}
else if (instance()->eventHandler().kbdAlt(modifiers))
{
cerr << "Alt from prompt\n";
}
else if (ascii < 256)
{
// Do uppercase letters
// if(instance()->eventHandler().kbdShift(modifiers))
// ascii = ascii & ~0x20;
for (i = _promptEndPos - 1; i >= _currentPos; i--)
buffer(i + 1) = buffer(i);
_promptEndPos++;
putchar((char)ascii);
putchar((int)*(SDL_GetKeyName((SDLKey)ascii)));
// putchar(ascii);
scrollToCurrent();
}
break;
@ -359,51 +365,90 @@ void PromptDialog::handleCommand(CommandSender* sender, int cmd, int data)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptDialog::specialKeys(int keycode)
{
/* FIXME - add UNIX style line editing
switch (keycode) {
case 'a':
_currentPos = _promptStartPos;
draw();
break;
case 'd':
if (_currentPos < _promptEndPos) {
killChar();
draw();
}
break;
case 'e':
_currentPos = _promptEndPos;
draw();
break;
case 'k':
killLine();
draw();
break;
case 'w':
killLastWord();
draw();
break;
}
*/
bool handled = false;
switch (keycode)
{
case 'a':
_currentPos = _promptStartPos;
handled = true;
break;
case 'd':
killChar(1);
handled = true;
break;
case 'e':
_currentPos = _promptEndPos;
handled = true;
break;
case 'k':
killLine(1);
handled = true;
break;
case 'u':
killLine(-1);
handled = true;
break;
case 'w':
killLastWord();
handled = true;
break;
}
if(handled)
{
draw();
instance()->frameBuffer().refresh();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptDialog::killChar()
void PromptDialog::killChar(int direction)
{
for (int i = _currentPos; i < _promptEndPos; i++)
buffer(i) = buffer(i + 1);
if(direction == -1) // Delete previous character (backspace)
{
if(_currentPos <= _promptStartPos)
return;
buffer(_promptEndPos) = ' ';
_promptEndPos--;
_currentPos--;
for (int i = _currentPos; i < _promptEndPos; i++)
buffer(i) = buffer(i + 1);
buffer(_promptEndPos) = ' ';
_promptEndPos--;
}
else if(direction == 1) // Delete next character (delete)
{
if(_currentPos >= _promptEndPos)
return;
// There are further characters to the right of cursor
if(_currentPos + 1 <= _promptEndPos)
{
for (int i = _currentPos; i < _promptEndPos; i++)
buffer(i) = buffer(i + 1);
buffer(_promptEndPos) = ' ';
_promptEndPos--;
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptDialog::killLine()
void PromptDialog::killLine(int direction)
{
for (int i = _currentPos; i < _promptEndPos; i++)
buffer(i) = ' ';
if(direction == 1) // erase from current position to end of line
{
for (int i = _currentPos; i < _promptEndPos; i++)
buffer(i) = ' ';
_promptEndPos = _currentPos;
_promptEndPos = _currentPos;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -464,13 +509,9 @@ void PromptDialog::historyScroll(int direction)
return;
_historyLine = line;
// Hide caret if visible
if (_caretVisible)
drawCaret(true);
// Remove the current user text
_currentPos = _promptStartPos;
killLine();
killLine(1); // to end of line
// ... and ensure the prompt is visible
scrollToCurrent();
@ -559,10 +600,8 @@ int PromptDialog::vprintf(const char *format, va_list argptr)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptDialog::putchar(int c)
{
if (_caretVisible)
drawCaret(true);
putcharIntern(c);
draw(); // FIXME - not nice to redraw the full console just for one char!
instance()->frameBuffer().refresh();
}
@ -578,7 +617,7 @@ void PromptDialog::putcharIntern(int c)
_currentPos++;
if ((_scrollLine + 1) * _lineWidth == _currentPos)
{
_scrollLine++;
_scrollLine++;
updateScrollBuffer();
}
}
@ -587,9 +626,6 @@ void PromptDialog::putcharIntern(int c)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptDialog::print(const char *str)
{
if (_caretVisible)
drawCaret(true);
while (*str)
putcharIntern(*str++);
@ -598,38 +634,19 @@ void PromptDialog::print(const char *str)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptDialog::drawCaret(bool erase)
void PromptDialog::drawCaret()
{
FrameBuffer& fb = instance()->frameBuffer();
int line = _currentPos / _lineWidth;
int displayLine = line - _scrollLine + _linesPerPage - 1;
// Only draw caret if visible
if (!isVisible() || displayLine < 0 || displayLine >= _linesPerPage)
{
_caretVisible = false;
return;
}
int x = _x + 1 + (_currentPos % _lineWidth) * kConsoleCharWidth;
int y = _y + displayLine * kConsoleLineHeight;
char c = buffer(_currentPos);
if (erase)
{
fb.fillRect(x, y, kConsoleCharWidth, kConsoleLineHeight, kBGColor);
fb.drawChar(c, x, y + 2, kTextColor);
}
else
{
fb.fillRect(x, y, kConsoleCharWidth, kConsoleLineHeight, kTextColor);
fb.drawChar(c, x, y + 2, kBGColor);
}
//FIXMEg_gui.addDirtyRect(x, y, kConsoleCharWidth, kConsoleLineHeight);
fb.refresh();
_caretVisible = !erase;
fb.fillRect(x, y, kConsoleCharWidth, kConsoleLineHeight, kTextColor);
fb.drawChar(c, x, y + 2, kBGColor);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: PromptDialog.hxx,v 1.1 2005-06-07 01:14:39 stephena Exp $
// $Id: PromptDialog.hxx,v 1.2 2005-06-07 19:01:53 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -43,10 +43,6 @@ class PromptDialog : public Dialog
int x, int y, int w, int h);
virtual ~PromptDialog();
void handleMouseWheel(int x, int y, int direction);
void handleKeyDown(int ascii, int keycode, int modifiers);
void handleCommand(CommandSender* sender, int cmd, int data);
public:
int printf(const char *format, ...);
int vprintf(const char *format, va_list argptr);
@ -69,7 +65,7 @@ class PromptDialog : public Dialog
inline char &buffer(int idx) { return _buffer[idx % kBufferSize]; }
void drawDialog();
void drawCaret(bool erase);
void drawCaret();
void putcharIntern(int c);
void insertIntoPrompt(const char *str);
void print(const char *str);
@ -79,14 +75,20 @@ class PromptDialog : public Dialog
// Line editing
void specialKeys(int keycode);
void nextLine();
void killChar();
void killLine();
void killChar(int direction);
void killLine(int direction);
void killLastWord();
// History
void addToHistory(const char *str);
void historyScroll(int direction);
private:
void handleMouseWheel(int x, int y, int direction);
void handleKeyDown(int ascii, int keycode, int modifiers);
void handleCommand(CommandSender* sender, int cmd, int data);
void loadConfig();
protected:
char _buffer[kBufferSize];
int _linesInBuffer;
@ -101,18 +103,6 @@ class PromptDialog : public Dialog
int _promptStartPos;
int _promptEndPos;
bool _caretVisible;
int _caretTime;
enum SlideMode {
kNoSlideMode,
kUpSlideMode,
kDownSlideMode
};
SlideMode _slideMode;
int _slideTime;
ScrollBarWidget* _scrollBar;
// The _callbackProc is called whenver a data line is entered