Added RomListWidget class, which derives from CheckListWidget. Created

a new class since the RomWidget isn't just a checkbox and string.
Eventually, it will consist of multiple fields.

Added highlighting of the line at current PC to RomWidget.  It attempts
to reduce scrolling as much as possible (since each scroll requires a
re-disassembly) by instead scrolling the line at PC.  When the bottom
of the list is reached, it 'snaps' back again to the top.  So, for
example, moving through 31 consecutive items in a list of 30 only scrolls
once, not 30 times.  This is different from normal
ListWidget/CheckListWidget operation, which scrolls the whole list
line by line at the bottom of the current view.

One can scroll around in the RomWidget, and then press 'space' to snap
back to the line of current PC (so you'll never get lost while
scrolling through code).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@748 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-08-26 16:44:17 +00:00
parent 3fbe8aae44
commit 787fe3eebc
13 changed files with 300 additions and 37 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: Debugger.cxx,v 1.88 2005-08-25 18:18:48 stephena Exp $
// $Id: Debugger.cxx,v 1.89 2005-08-26 16:44:16 stephena Exp $
//============================================================================
#include "bspf.hxx"
@ -779,8 +779,8 @@ const string& Debugger::disassemble(int start, int lines) {
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::disassemble(StringList& addr, StringList& data,
int start, int lines)
void Debugger::disassemble(StringList& addrLabel, IntArray& addr,
StringList& data, int start, int lines)
{
char buf[255], bbuf[255];
string result;
@ -789,7 +789,8 @@ void Debugger::disassemble(StringList& addr, StringList& data,
result = "";
const char *label = equateList->getFormatted(start, 4);
addr.push_back(label);
addrLabel.push_back(label);
addr.push_back(start);
result += label;
result += ": ";

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: Debugger.hxx,v 1.71 2005-08-24 22:01:45 stephena Exp $
// $Id: Debugger.hxx,v 1.72 2005-08-26 16:44:16 stephena Exp $
//============================================================================
#ifndef DEBUGGER_HXX
@ -76,7 +76,7 @@ typedef uInt16 (Debugger::*DEBUGGER_WORD_METHOD)();
for all debugging operations in Stella (parser, 6502 debugger, etc).
@author Stephen Anthony
@version $Id: Debugger.hxx,v 1.71 2005-08-24 22:01:45 stephena Exp $
@version $Id: Debugger.hxx,v 1.72 2005-08-26 16:44:16 stephena Exp $
*/
class Debugger : public DialogContainer
{
@ -187,7 +187,8 @@ class Debugger : public DialogContainer
Disassemble from the starting address the specified number of lines
and place addresses and data in given arrays.
*/
void disassemble(StringList& addr, StringList& data, int start, int lines);
void disassemble(StringList& addrLabel, IntArray& addr,
StringList& data, int start, int lines);
int step();
int trace();

View File

@ -0,0 +1,143 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: RomListWidget.cxx,v 1.1 2005-08-26 16:44:16 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include "RomListWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h)
: CheckListWidget(boss, font, x, y, w, h),
myHighlightedItem(-1)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RomListWidget::~RomListWidget()
{
}
/*
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomListWidget::setList(const StringList& list, const BoolArray& state)
{
_list = list;
_stateList = state;
assert(_list.size() == _stateList.size());
// Enable all checkboxes
for(int i = 0; i < _rows; ++i)
_checkList[i]->setFlags(WIDGET_ENABLED);
// Then turn off any extras
if((int)_stateList.size() < _rows)
for(int i = _stateList.size(); i < _rows; ++i)
_checkList[i]->clearFlags(WIDGET_ENABLED);
ListWidget::recalc();
}
*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomListWidget::drawWidget(bool hilite)
{
//cerr << "RomListWidget::drawWidget\n";
FrameBuffer& fb = _boss->instance()->frameBuffer();
int i, pos, len = _list.size();
string buffer;
int deltax;
// Draw a thin frame around the list and to separate columns
fb.hLine(_x, _y, _x + _w - 1, kColor);
fb.hLine(_x, _y + _h - 1, _x + _w - 1, kShadowColor);
fb.vLine(_x, _y, _y + _h - 1, kColor);
fb.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor);
// Draw the list items
for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++)
{
// Draw checkboxes for correct lines (takes scrolling into account)
_checkList[i]->setState(_stateList[pos]);
_checkList[i]->setDirty();
_checkList[i]->draw();
const int y = _y + 2 + _rowHeight * i;
GUI::Rect r(getEditRect());
// Draw highlighted item inverted, on a highlighted background.
if (_highlightedItem == pos)
{
fb.fillRect(_x + r.left - 3, _y + 1 + _rowHeight * i,
_w - r.left, _rowHeight,
kHiliteColor);
}
// Draw the selected item inverted, on a highlighted background.
if (_selectedItem == pos)
{
if (_hasFocus && !_editMode)
fb.fillRect(_x + r.left - 3, _y + 1 + _rowHeight * i,
_w - r.left, _rowHeight,
kTextColorHi);
else
fb.frameRect(_x + r.left - 3, _y + 1 + _rowHeight * i,
_w - r.left, _rowHeight,
kTextColorHi);
}
if (_selectedItem == pos && _editMode)
{
buffer = _editString;
adjustOffset();
deltax = -_editScrollOffset;
fb.drawString(_font, buffer, _x + r.left, y, r.width(), kTextColor,
kTextAlignLeft, deltax, false);
}
else
{
buffer = _list[pos];
deltax = 0;
fb.drawString(_font, buffer, _x + r.left, y, r.width(), kTextColor);
}
}
// Only draw the caret while editing, and if it's in the current viewport
if(_editMode && (_selectedItem >= _scrollBar->_currentPos) &&
(_selectedItem < _scrollBar->_currentPos + _rows))
drawCaret();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GUI::Rect RomListWidget::getEditRect() const
{
GUI::Rect r(2, 1, _w, _rowHeight);
const int yoffset = (_selectedItem - _currentPos) * _rowHeight,
xoffset = CheckboxWidget::boxSize() + 10;
r.top += yoffset;
r.bottom += yoffset;
r.left += xoffset;
r.right -= xoffset - 15;
return r;
}

View File

@ -0,0 +1,46 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: RomListWidget.hxx,v 1.1 2005-08-26 16:44:16 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef ROM_LIST_WIDGET_HXX
#define ROM_LIST_WIDGET_HXX
class CheckboxWidget;
#include "CheckListWidget.hxx"
/** RomListWidget */
class RomListWidget : public CheckListWidget
{
public:
RomListWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h);
virtual ~RomListWidget();
protected:
void drawWidget(bool hilite);
GUI::Rect getEditRect() const;
private:
int myHighlightedItem;
};
#endif

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: RomWidget.cxx,v 1.6 2005-08-25 18:18:48 stephena Exp $
// $Id: RomWidget.cxx,v 1.7 2005-08-26 16:44:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -22,8 +22,9 @@
#include <sstream>
#include "Debugger.hxx"
#include "CpuDebug.hxx"
#include "GuiObject.hxx"
#include "CheckListWidget.hxx"
#include "RomListWidget.hxx"
#include "RomWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -37,7 +38,7 @@ RomWidget::RomWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
int w = 58 * font.getMaxCharWidth(),
h = 31 * font.getLineHeight();
myRomList = new CheckListWidget(boss, font, x, y, w, h);
myRomList = new RomListWidget(boss, font, x, y, w, h);
myRomList->setTarget(this);
myRomList->setStyle(kSolidFill);
addFocusWidget(myRomList);
@ -50,6 +51,8 @@ RomWidget::RomWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RomWidget::~RomWidget()
{
myAddrList.clear();
myLineList.clear();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -62,14 +65,18 @@ void RomWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
break;
case kListItemChecked:
{
// We don't care about state, as breakpoints are turned on
// and off with the same command
// FIXME - at some point, we might want to add 'breakon'
// and 'breakoff' to DebuggerParser, so the states
// don't get out of sync
instance()->debugger().run(string("break " + myAddrList[data]));
ostringstream cmd;
cmd << "break #" << myAddrList[data];
instance()->debugger().run(cmd.str());
break;
}
}
}
@ -87,6 +94,12 @@ void RomWidget::loadConfig()
{
incrementalUpdate();
}
// Update romlist to point to current PC
int pc = instance()->debugger().cpuDebug().pc();
AddrToLine::iterator iter = myLineList.find(pc);
if(iter != myLineList.end())
myRomList->setHighlighted(iter->second);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -101,15 +114,21 @@ void RomWidget::initialUpdate()
; // FIXME
else
{
StringList data;
StringList label, data;
BoolArray state;
myAddrList.clear();
myLineList.clear();
// Disassemble entire bank (up to 4096 lines)
dbg.disassemble(myAddrList, data, 0xf000, 4096);
dbg.disassemble(label, myAddrList, data, 0xf000, 4096);
for(unsigned int i = 0; i < data.size(); ++i)
state.push_back(false);
// Create a mapping from addresses to line numbers
myLineList.clear();
for(unsigned int i = 0; i < myAddrList.size(); ++i)
myLineList.insert(make_pair(myAddrList[i], i));
myRomList->setList(data, state);
}
}

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: RomWidget.hxx,v 1.4 2005-08-25 18:18:48 stephena Exp $
// $Id: RomWidget.hxx,v 1.5 2005-08-26 16:44:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -23,13 +23,18 @@
#define ROM_WIDGET_HXX
class GuiObject;
class CheckListWidget;
class RomListWidget;
class StringList;
#include <map>
#include "Array.hxx"
#include "Widget.hxx"
#include "Command.hxx"
typedef map<int,int> AddrToLine;
class RomWidget : public Widget, public CommandSender
{
public:
@ -45,9 +50,13 @@ class RomWidget : public Widget, public CommandSender
void incrementalUpdate();
private:
CheckListWidget* myRomList;
RomListWidget* myRomList;
StringList myAddrList;
/** List of addresses indexed by line number */
IntArray myAddrList;
/** List of line numbers indexed by address */
AddrToLine myLineList;
bool myFirstLoad;
bool mySourceAvailable;

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: TiaOutputWidget.cxx,v 1.5 2005-08-11 19:12:38 stephena Exp $
// $Id: TiaOutputWidget.cxx,v 1.6 2005-08-26 16:44:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -79,7 +79,7 @@ cerr << "TiaOutputWidget button press:" << endl
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaOutputWidget::drawWidget(bool hilite)
{
cerr << "TiaOutputWidget::drawWidget\n";
//cerr << "TiaOutputWidget::drawWidget\n";
instance()->frameBuffer().refresh();
instance()->frameBuffer().drawMediaSource();
}

View File

@ -48,6 +48,7 @@ MODULE_OBJS := \
src/debugger/PromptWidget.o \
src/debugger/RamWidget.o \
src/debugger/RomWidget.o \
src/debugger/RomListWidget.o \
src/debugger/TiaWidget.o
MODULE_DIRS += \

View File

@ -13,13 +13,12 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: CheckListWidget.cxx,v 1.6 2005-08-25 18:18:48 stephena Exp $
// $Id: CheckListWidget.cxx,v 1.7 2005-08-26 16:44:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include "ScrollBarWidget.hxx"
#include "CheckListWidget.hxx"
#include "Widget.hxx"

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: CheckListWidget.hxx,v 1.5 2005-08-25 18:18:48 stephena Exp $
// $Id: CheckListWidget.hxx,v 1.6 2005-08-26 16:44:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -59,7 +59,7 @@ class CheckListWidget : public ListWidget
void drawWidget(bool hilite);
GUI::Rect getEditRect() const;
private:
protected:
BoolArray _stateList;
CheckboxArray _checkList;
};

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: Dialog.cxx,v 1.27 2005-08-15 18:52:15 stephena Exp $
// $Id: Dialog.cxx,v 1.28 2005-08-26 16:44:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -176,7 +176,7 @@ void Dialog::drawDialog()
if(_dirty)
{
cerr << "Dialog::drawDialog()\n";
// cerr << "Dialog::drawDialog()\n";
FrameBuffer& fb = instance()->frameBuffer();
fb.fillRect(_x+1, _y+1, _w-2, _h-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: ListWidget.cxx,v 1.28 2005-08-23 18:32:51 stephena Exp $
// $Id: ListWidget.cxx,v 1.29 2005-08-26 16:44:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -38,6 +38,7 @@ ListWidget::ListWidget(GuiObject* boss, const GUI::Font& font,
_cols(0),
_currentPos(0),
_selectedItem(-1),
_highlightedItem(-1),
_currentKeyDown(0),
_editMode(false),
_caretInverse(true),
@ -81,7 +82,31 @@ void ListWidget::setSelected(int item)
sendCommand(kListSelectionChangedCmd, _selectedItem, _id);
_currentPos = _selectedItem - _rows / 2;
scrollToCurrent();
scrollToSelected();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ListWidget::setHighlighted(int item)
{
assert(item >= -1 && item < (int)_list.size());
if (isEnabled() && _highlightedItem != item)
{
if (_editMode)
abortEditMode();
_highlightedItem = item;
// FIXME - don't know if we need to send a signal
//sendCommand(kListSelectionChangedCmd, _selectedItem, _id);
// Only scroll the list if we're about to pass the page boundary
if(_currentPos == 0)
_currentPos = _highlightedItem;
else if(_highlightedItem == _currentPos + _rows)
_currentPos += _rows;
scrollToHighlighted();
}
}
@ -99,6 +124,8 @@ void ListWidget::scrollTo(int item)
_currentPos = item;
scrollBarRecalc();
}
setDirty(); draw();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -238,6 +265,15 @@ bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers)
// not editmode
switch (keycode)
{
case ' ': // space
// Snap list back to currently highlighted line
if(_highlightedItem >= 0)
{
_currentPos = _highlightedItem;
scrollToHighlighted();
}
break;
case '\n': // enter/return
case '\r':
if (_selectedItem >= 0)
@ -288,7 +324,7 @@ bool ListWidget::handleKeyDown(int ascii, int keycode, int modifiers)
if (_selectedItem != oldSelectedItem)
{
_scrollBar->draw();
scrollToCurrent();
scrollToSelected();
sendCommand(kListSelectionChangedCmd, _selectedItem, _id);
}
@ -330,21 +366,21 @@ void ListWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ListWidget::scrollToCurrent()
void ListWidget::scrollToCurrent(int item)
{
bool scrolled = false;
// Only do something if the current item is not in our view port
if (_selectedItem < _currentPos)
if (item < _currentPos)
{
// it's above our view
_currentPos = _selectedItem;
_currentPos = item;
scrolled = true;
}
else if (_selectedItem >= _currentPos + _rows )
else if (item >= _currentPos + _rows )
{
// it's below our view
_currentPos = _selectedItem - _rows + 1;
_currentPos = item - _rows + 1;
scrolled = 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: ListWidget.hxx,v 1.11 2005-08-23 18:32:51 stephena Exp $
// $Id: ListWidget.hxx,v 1.12 2005-08-26 16:44:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -26,10 +26,10 @@
#include "Widget.hxx"
#include "Command.hxx"
#include "EditableWidget.hxx"
#include "ScrollBarWidget.hxx"
#include "Rect.hxx"
class StringList;
class ScrollBarWidget;
// Some special commands
enum {
@ -48,9 +48,12 @@ class ListWidget : public EditableWidget
int x, int y, int w, int h);
virtual ~ListWidget();
int getSelected() const { return _selectedItem; }
int getSelected() const { return _selectedItem; }
void setSelected(int item);
int getHighlighted() const { return _highlightedItem; }
void setHighlighted(int item);
const StringList& getList() const { return _list; }
const string& getSelectedString() const { return _list[_selectedItem]; }
@ -79,7 +82,11 @@ class ListWidget : public EditableWidget
void abortEditMode();
void lostFocusWidget();
void scrollToCurrent();
void scrollToSelected() { scrollToCurrent(_selectedItem); }
void scrollToHighlighted() { scrollToCurrent(_highlightedItem); }
private:
void scrollToCurrent(int item);
protected:
int _rows;
@ -88,6 +95,7 @@ class ListWidget : public EditableWidget
int _colWidth;
int _currentPos;
int _selectedItem;
int _highlightedItem;
int _currentKeyDown;
bool _editMode;