Massive rearrangement of most GUI-related classes (sorry Mark for the

changes you'll have to make to the XCode project).

The '--disable-developer' option to configure now works properly,
and developer/debugger support can be completely disabled.  When
disabled, the code will not be compiled at all, which gives an approx
35% reduction in code size (useful for the PSP port).

Cheat support is currently broken as it depends on a debugger that
may not be present, but this will be fixed soon (it isn't near
finished yet anyway).

Made changing of game properties and toggling TIA bits not exclusively
a developer thing, since there's no reason why anyone can't use it.

Bumped version to beta1.  Stella has been stewing for the past 6 months,
and it's almost about time for a release.  I promised last time that
releases would be more frequent, and I've already broken that promise :)
That means some features of the debugger won't be included for next
release, but something has to be left out ...


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@751 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-08-30 17:51:26 +00:00
parent 1cf03b53ed
commit 9c90b0d093
45 changed files with 3920 additions and 58 deletions

5
stella/configure vendored
View File

@ -678,6 +678,7 @@ CORE="$SRC/emucore"
COMMON="$SRC/common"
GUI="$SRC/gui"
DBG="$SRC/debugger"
DBGGUI="$SRC/debugger/gui"
YACC="$SRC/yacc"
INCLUDES="-I$CORE -I$CORE/m6502/src -I$CORE/m6502/src/bspf/src -I$COMMON -I$GUI"
@ -754,8 +755,8 @@ fi
if test "$_build_developer" = yes ; then
DEFINES="$DEFINES -DDEVELOPER_SUPPORT"
MODULES="$MODULES $DBG $YACC"
INCLUDES="$INCLUDES -I$DBG -I$YACC"
MODULES="$MODULES $DBG $DBGGUI $YACC"
INCLUDES="$INCLUDES -I$DBG -I$DBGGUI -I$YACC"
fi
if test "$_build_snapshot" = yes ; then

View File

@ -1,5 +1,6 @@
#include "Debugger.hxx"
// FIXME - don't use the debugger for this, since it may not be included
//#include "Debugger.hxx"
#include "CheetahCheat.hxx"
CheetahCheat::CheetahCheat(string code) {
@ -16,18 +17,20 @@ CheetahCheat::~CheetahCheat() {
bool CheetahCheat::enabled() { return _enabled; }
bool CheetahCheat::enable() {
/* FIXME
for(int i=0; i<count; i++) {
savedRom[i] = Debugger::debugger().peek(address + i);
Debugger::debugger().patchROM(address + i, value);
}
*/
return _enabled = true;
}
bool CheetahCheat::disable() {
/* FIXME
for(int i=0; i<count; i++) {
Debugger::debugger().patchROM(address + i, savedRom[i]);
}
*/
return _enabled = false;
}

View File

@ -13,12 +13,12 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Version.hxx,v 1.7 2005-08-18 18:18:59 stephena Exp $
// $Id: Version.hxx,v 1.8 2005-08-30 17:51:26 stephena Exp $
//============================================================================
#ifndef VERSION_HXX
#define VERSION_HXX
#define STELLA_VERSION "2.0_alpha7"
#define STELLA_VERSION "2.0_beta1"
#endif

View File

@ -1,6 +1,8 @@
MODULE := src/common
MODULE_OBJS := \
src/common/Cheat.o \
src/common/CheetahCheat.o \
src/common/mainSDL.o \
src/common/SoundNull.o \
src/common/SoundSDL.o \

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: ColorWidget.cxx,v 1.2 2005-08-01 22:33:14 stephena Exp $
// $Id: ColorWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: ColorWidget.hxx,v 1.2 2005-08-01 22:33:14 stephena Exp $
// $Id: ColorWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -35,7 +35,7 @@ class GuiObject;
be expanded with a TIA palette table, to set the color visually.
@author Stephen Anthony
@version $Id: ColorWidget.hxx,v 1.2 2005-08-01 22:33:14 stephena Exp $
@version $Id: ColorWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
*/
class ColorWidget : public Widget, public CommandSender
{

View File

@ -0,0 +1,280 @@
//============================================================================
//
// 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: CpuWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include <sstream>
#include "OSystem.hxx"
#include "GuiUtils.hxx"
#include "GuiObject.hxx"
#include "Debugger.hxx"
#include "CpuDebug.hxx"
#include "Widget.hxx"
#include "DataGridWidget.hxx"
#include "EditTextWidget.hxx"
#include "ToggleBitWidget.hxx"
#include "CpuWidget.hxx"
// ID's for the various widgets
// We need ID's, since there are more than one of several types of widgets
enum {
kPCRegID,
kCpuRegID
};
enum {
kPCRegAddr,
kSPRegAddr,
kARegAddr,
kXRegAddr,
kYRegAddr
};
enum {
kPSRegN = 0,
kPSRegV = 1,
kPSRegB = 3,
kPSRegD = 4,
kPSRegI = 5,
kPSRegZ = 6,
kPSRegC = 7
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
: Widget(boss, x, y, 16, 16),
CommandSender(boss)
{
const int fontWidth = font.getMaxCharWidth(),
fontHeight = font.getFontHeight(),
lineHeight = font.getLineHeight();
int xpos, ypos, lwidth;
StaticTextWidget* t;
// Create a 1x1 grid with label for the PC register
xpos = x; ypos = y; lwidth = 4 * fontWidth;
t = new StaticTextWidget(boss, xpos, ypos+2, lwidth-2, fontHeight,
"PC:", kTextAlignLeft);
t->setFont(font);
myPCGrid = new DataGridWidget(boss, font, xpos + lwidth, ypos, 1, 1, 16, 16);
myPCGrid->setTarget(this);
myPCGrid->setID(kPCRegID);
addFocusWidget(myPCGrid);
// Create a read-only textbox containing the current PC label
xpos += lwidth + myPCGrid->getWidth() + 10;
myPCLabel = new EditTextWidget(boss, xpos, ypos, fontWidth*15, lineHeight, "");
myPCLabel->setFont(font);
myPCLabel->setEditable(false);
// Create a 1x4 grid with labels for the other CPU registers
xpos = x; ypos += myPCGrid->getHeight() + 1;
myCpuGrid = new DataGridWidget(boss, font, xpos + lwidth, ypos, 1, 4, 8, 8);
myCpuGrid->setTarget(this);
myCpuGrid->setID(kCpuRegID);
addFocusWidget(myCpuGrid);
string labels[4] = { "SP:", "A:", "X:", "Y:" };
for(int row = 0; row < 4; ++row)
{
t = new StaticTextWidget(boss, xpos, ypos + row*lineHeight + 2,
lwidth-2, fontHeight,
labels[row], kTextAlignLeft);
t->setFont(font);
}
// Create a bitfield widget for changing the processor status
xpos = x; ypos += 4*lineHeight + 2;
t = new StaticTextWidget(boss, xpos, ypos+2, lwidth-2, fontHeight,
"PS:", kTextAlignLeft);
t->setFont(font);
myPSRegister = new ToggleBitWidget(boss, font, xpos+lwidth, ypos, 8, 1);
myPSRegister->setTarget(this);
addFocusWidget(myPSRegister);
// Set the strings to be used in the PSRegister
// We only do this once because it's the state that changes, not the strings
const char* offstr[] = { "n", "v", "-", "b", "d", "i", "z", "c" };
const char* onstr[] = { "N", "V", "-", "B", "D", "I", "Z", "C" };
StringList off, on;
for(int i = 0; i < 8; ++i)
{
off.push_back(offstr[i]);
on.push_back(onstr[i]);
}
myPSRegister->setList(off, on);
// Calculate real dimensions
_w = lwidth + myPCGrid->getWidth() + myPCLabel->getWidth() + 20;
_h = ypos + myPSRegister->getHeight() - y;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CpuWidget::~CpuWidget()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
{
int addr = -1, value = -1;
CpuDebug& dbg = instance()->debugger().cpuDebug();
switch(cmd)
{
case kDGItemDataChangedCmd:
switch(id)
{
case kPCRegID:
addr = myPCGrid->getSelectedAddr();
value = myPCGrid->getSelectedValue();
break;
case kCpuRegID:
addr = myCpuGrid->getSelectedAddr();
value = myCpuGrid->getSelectedValue();
break;
}
switch(addr)
{
case kPCRegAddr:
dbg.setPC(value);
break;
case kSPRegAddr:
dbg.setSP(value);
break;
case kARegAddr:
dbg.setA(value);
break;
case kXRegAddr:
dbg.setX(value);
break;
case kYRegAddr:
dbg.setY(value);
break;
}
break;
case kTWItemDataChangedCmd:
{
bool state = myPSRegister->getSelectedState();
switch(data)
{
case kPSRegN:
dbg.setN(state);
break;
case kPSRegV:
dbg.setV(state);
break;
case kPSRegB:
dbg.setB(state);
break;
case kPSRegD:
dbg.setD(state);
break;
case kPSRegI:
dbg.setI(state);
break;
case kPSRegZ:
dbg.setZ(state);
break;
case kPSRegC:
dbg.setC(state);
break;
}
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuWidget::loadConfig()
{
fillGrid();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuWidget::setOpsWidget(DataGridOpsWidget* w)
{
myPCGrid->setOpsWidget(w);
myCpuGrid->setOpsWidget(w);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuWidget::fillGrid()
{
IntArray alist;
IntArray vlist;
BoolArray changed;
// We push the enumerated items as addresses, and deal with the real
// address in the callback (handleCommand)
CpuDebug& cpu = instance()->debugger().cpuDebug();
CpuState state = (CpuState&) cpu.getState();
CpuState oldstate = (CpuState&) cpu.getOldState();
// Add PC to its own DataGridWidget
alist.push_back(kPCRegAddr);
vlist.push_back(state.PC);
changed.push_back(state.PC != oldstate.PC);
myPCGrid->setList(alist, vlist, changed);
// Add the other registers
alist.clear(); vlist.clear(); changed.clear();
alist.push_back(kSPRegAddr);
alist.push_back(kARegAddr);
alist.push_back(kXRegAddr);
alist.push_back(kYRegAddr);
// And now fill the values
vlist.push_back(state.SP);
vlist.push_back(state.A);
vlist.push_back(state.X);
vlist.push_back(state.Y);
// Figure out which items have changed
changed.push_back(state.SP != oldstate.SP);
changed.push_back(state.A != oldstate.A);
changed.push_back(state.X != oldstate.X);
changed.push_back(state.Y != oldstate.Y);
// Finally, update the register list
myCpuGrid->setList(alist, vlist, changed);
// Update the PS register booleans
changed.clear();
for(unsigned int i = 0; i < state.PSbits.size(); ++i)
changed.push_back(state.PSbits[i] != oldstate.PSbits[i]);
myPSRegister->setState(state.PSbits, changed);
}

View File

@ -0,0 +1,57 @@
//============================================================================
//
// 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: CpuWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef CPU_WIDGET_HXX
#define CPU_WIDGET_HXX
class GuiObject;
class ButtonWidget;
class EditTextWidget;
class ToggleBitWidget;
#include "Array.hxx"
#include "Widget.hxx"
#include "Command.hxx"
#include "DataGridWidget.hxx"
class CpuWidget : public Widget, public CommandSender
{
public:
CpuWidget(GuiObject* boss, const GUI::Font& font, int x, int y);
virtual ~CpuWidget();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
void loadConfig();
void setOpsWidget(DataGridOpsWidget* w);
private:
void fillGrid();
private:
DataGridWidget* myPCGrid;
DataGridWidget* myCpuGrid;
ToggleBitWidget* myPSRegister;
EditTextWidget* myPCLabel;
};
#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: DataGridOpsWidget.cxx,v 1.1 2005-08-10 18:44:37 stephena Exp $
// $Id: DataGridOpsWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: DataGridOpsWidget.hxx,v 1.1 2005-08-10 18:44:37 stephena Exp $
// $Id: DataGridOpsWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: DataGridWidget.cxx,v 1.24 2005-08-16 18:34:12 stephena Exp $
// $Id: DataGridWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: DataGridWidget.hxx,v 1.13 2005-08-15 18:52:15 stephena Exp $
// $Id: DataGridWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: DebuggerDialog.cxx,v 1.36 2005-08-23 18:32:51 stephena Exp $
// $Id: DebuggerDialog.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: DebuggerDialog.hxx,v 1.17 2005-08-22 13:53:23 stephena Exp $
// $Id: DebuggerDialog.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

View File

@ -0,0 +1,879 @@
//============================================================================
//
// 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: PromptWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include <iostream>
#include <fstream>
#include "ScrollBarWidget.hxx"
#include "FrameBuffer.hxx"
#include "EventHandler.hxx"
#include "Version.hxx"
#include "Debugger.hxx"
#include "DebuggerDialog.hxx"
#include "DebuggerParser.hxx"
#include "PromptWidget.hxx"
#include "EquateList.hxx"
#define PROMPT "> "
/* TODO:
* - it is very inefficient to redraw the full thingy when just one char is added/removed.
* Instead, we could just copy the GFX of the blank console (i.e. after the transparent
* background is drawn, before any text is drawn). Then using that, it becomes trivial
* to erase a single character, do scrolling etc.
* - a *lot* of others things, this code is in no way complete and heavily under progress
*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PromptWidget::PromptWidget(GuiObject* boss, int x, int y, int w, int h)
: Widget(boss, x, y, w - kScrollBarWidth, h),
CommandSender(boss),
_makeDirty(false),
_firstTime(true)
{
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS |
WIDGET_WANTS_TAB;
_type = kPromptWidget;
_kConsoleCharWidth = instance()->consoleFont().getMaxCharWidth();
_kConsoleCharHeight = instance()->consoleFont().getFontHeight();
_kConsoleLineHeight = _kConsoleCharHeight + 2;
// Calculate depending values
_lineWidth = (_w - kScrollBarWidth - 2) / _kConsoleCharWidth;
_linesPerPage = (_h - 2) / _kConsoleLineHeight;
memset(_buffer, 0, kBufferSize * sizeof(int));
_linesInBuffer = kBufferSize / _lineWidth;
_currentPos = 0;
_scrollLine = _linesPerPage - 1;
_firstLineInBuffer = 0;
// Add scrollbar
_scrollBar = new ScrollBarWidget(boss, _x + _w, _y, kScrollBarWidth, _h);
_scrollBar->setTarget(this);
// Init colors
defaultTextColor = kTextColor;
defaultBGColor = kBGColor;
textColor = defaultTextColor;
bgColor = defaultBGColor;
_inverse = false;
// Init History
_historyIndex = 0;
_historyLine = 0;
_historySize = 0;
for (int i = 0; i < kHistorySize; i++)
_history[i][0] = '\0';
_promptStartPos = _promptEndPos = -1;
addFocusWidget(this);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PromptWidget::~PromptWidget()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::drawWidget(bool hilite)
{
//cerr << "PromptWidget::drawWidget\n";
OverlayColor fgcolor, bgcolor;
FrameBuffer& fb = _boss->instance()->frameBuffer();
// Draw text
int start = _scrollLine - _linesPerPage + 1;
int y = _y + 2;
for (int line = 0; line < _linesPerPage; line++)
{
int x = _x + 1;
for (int column = 0; column < _lineWidth; column++) {
int c = buffer((start + line) * _lineWidth + column);
if(c & (1 << 17)) { // inverse video flag
fgcolor = bgColor;
bgcolor = (OverlayColor)((c & 0x1ffff) >> 8);
fb.fillRect(x, y, _kConsoleCharWidth, _kConsoleCharHeight, bgcolor);
} else {
fgcolor = (OverlayColor)(c >> 8);
bgcolor = bgColor;
}
fb.drawChar(&instance()->consoleFont(), c & 0x7f, x, y, fgcolor);
x += _kConsoleCharWidth;
}
y += _kConsoleLineHeight;
}
// Draw the caret
drawCaret();
// Draw the scrollbar
_scrollBar->draw();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::handleMouseDown(int x, int y, int button, int clickCount)
{
cerr << "PromptWidget::handleMouseDown\n";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::handleMouseWheel(int x, int y, int direction)
{
_scrollBar->handleMouseWheel(x, y, direction);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::printPrompt()
{
// FIXME - the following will probably be permanantly removed
// since it's always shown in the main dialog area
/*
print( instance()->debugger().showWatches() );
print( instance()->debugger().cpuState() );
print("\n");
*/
print(PROMPT);
_promptStartPos = _promptEndPos = _currentPos;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers)
{
int i;
bool handled = true;
bool dirty = false;
switch (keycode)
{
case '\n': // enter/return
case '\r':
{
nextLine();
assert(_promptEndPos >= _promptStartPos);
int len = _promptEndPos - _promptStartPos;
if (len > 0)
{
// We have to allocate the string buffer with new, since VC++ sadly does not
// comply to the C++ standard, so we can't use a dynamic sized stack array.
char *str = new char[len + 1];
// Copy the user input to str
for (i = 0; i < len; i++)
str[i] = buffer(_promptStartPos + i) & 0x7f;
str[len] = '\0';
// Add the input to the history
addToHistory(str);
// Pass the command to the debugger, and print the result
print( instance()->debugger().run(str) + "\n");
// Get rid of the string buffer
delete [] str;
}
printPrompt();
dirty = true;
break;
}
case 9: // tab
{
// Tab completion: we complete either commands or labels, but not
// both at once.
if(_currentPos <= _promptStartPos)
break;
scrollToCurrent();
int len = _promptEndPos - _promptStartPos;
int lastDelimPos = -1;
char delimiter = '\0';
char *str = new char[len + 1];
for (i = 0; i < len; i++) {
str[i] = buffer(_promptStartPos + i) & 0x7f;
if(strchr("*@<> ", str[i]) != NULL ) {
lastDelimPos = i;
delimiter = str[i];
}
}
str[len] = '\0';
const char *completionList;
const char *prefix;
int possibilities;
if(lastDelimPos < 0) {
// no delimiters, do command completion:
DebuggerParser *parser = instance()->debugger().parser();
possibilities = parser->countCompletions(str);
if(possibilities < 1) {
delete[] str;
break;
}
completionList = parser->getCompletions();
prefix = parser->getCompletionPrefix();
} else {
// we got a delimiter, so this must be a label:
EquateList *equates = instance()->debugger().equates();
possibilities = equates->countCompletions(str + lastDelimPos + 1);
if(possibilities < 1) {
delete[] str;
break;
}
completionList = equates->getCompletions();
prefix = equates->getCompletionPrefix();
}
if(possibilities == 1) {
// add to buffer as though user typed it (plus a space)
_currentPos = _promptStartPos + lastDelimPos + 1;
while(*completionList != '\0') {
putcharIntern(*completionList++);
}
putcharIntern(' ');
_promptEndPos = _currentPos;
} else {
nextLine();
// add to buffer as-is, then add PROMPT plus whatever we have so far
_currentPos = _promptStartPos + lastDelimPos + 1;
print("\n");
print(completionList);
print("\n");
print(PROMPT);
_promptStartPos = _currentPos;
for(i=0; i<lastDelimPos; i++)
putcharIntern(str[i]);
if(lastDelimPos > 0)
putcharIntern(delimiter);
print(prefix);
_promptEndPos = _currentPos;
}
delete[] str;
dirty = true;
break;
}
case 8: // backspace
if (_currentPos > _promptStartPos)
killChar(-1);
scrollToCurrent();
dirty = true;
break;
case 127:
killChar(+1);
dirty = true;
break;
case 256 + 24: // pageup
if (instance()->eventHandler().kbdShift(modifiers))
{
// Don't scroll up when at top of buffer
if(_scrollLine < _linesPerPage)
break;
_scrollLine -= _linesPerPage - 1;
if (_scrollLine < _firstLineInBuffer + _linesPerPage - 1)
_scrollLine = _firstLineInBuffer + _linesPerPage - 1;
updateScrollBuffer();
dirty = true;
}
break;
case 256 + 25: // pagedown
if (instance()->eventHandler().kbdShift(modifiers))
{
// Don't scroll down when at bottom of buffer
if(_scrollLine >= _promptEndPos / _lineWidth)
break;
_scrollLine += _linesPerPage - 1;
if (_scrollLine > _promptEndPos / _lineWidth)
_scrollLine = _promptEndPos / _lineWidth;
updateScrollBuffer();
dirty = true;
}
break;
case 256 + 22: // home
if (instance()->eventHandler().kbdShift(modifiers))
{
_scrollLine = _firstLineInBuffer + _linesPerPage - 1;
updateScrollBuffer();
}
else
_currentPos = _promptStartPos;
dirty = true;
break;
case 256 + 23: // end
if (instance()->eventHandler().kbdShift(modifiers))
{
_scrollLine = _promptEndPos / _lineWidth;
if (_scrollLine < _linesPerPage - 1)
_scrollLine = _linesPerPage - 1;
updateScrollBuffer();
}
else
_currentPos = _promptEndPos;
dirty = true;
break;
case 273: // cursor up
if (instance()->eventHandler().kbdShift(modifiers))
{
if(_scrollLine <= _firstLineInBuffer + _linesPerPage - 1)
break;
_scrollLine -= 1;
updateScrollBuffer();
dirty = true;
}
else
historyScroll(+1);
break;
case 274: // cursor down
if (instance()->eventHandler().kbdShift(modifiers))
{
// Don't scroll down when at bottom of buffer
if(_scrollLine >= _promptEndPos / _lineWidth)
break;
_scrollLine += 1;
updateScrollBuffer();
dirty = true;
}
else
historyScroll(-1);
break;
case 275: // cursor right
if (_currentPos < _promptEndPos)
_currentPos++;
dirty = true;
break;
case 276: // cursor left
if (_currentPos > _promptStartPos)
_currentPos--;
dirty = true;
break;
default:
if (instance()->eventHandler().kbdControl(modifiers))
{
specialKeys(keycode);
}
else if (instance()->eventHandler().kbdAlt(modifiers))
{
}
else if (isprint(ascii))
{
for (i = _promptEndPos - 1; i >= _currentPos; i--)
buffer(i + 1) = buffer(i);
_promptEndPos++;
putchar(ascii);
scrollToCurrent();
}
else
handled = false;
break;
}
// Take care of changes made above
if(dirty)
{
setDirty(); draw();
}
// There are times when we want the prompt and scrollbar to be marked
// as dirty *after* they've been drawn above. One such occurrence is
// when we issue a command that indirectly redraws the entire parent
// dialog (such as 'scanline' or 'frame').
// In those cases, the return code of the command must be shown, but the
// entire dialog contents are redrawn at a later time. So the prompt and
// scrollbar won't be redrawn unless they're dirty again.
if(_makeDirty)
{
setDirty();
_scrollBar->setDirty();
_makeDirty = false;
}
return handled;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::insertIntoPrompt(const char* str)
{
unsigned int l = strlen(str);
for (int i = _promptEndPos - 1; i >= _currentPos; i--)
buffer(i + l) = buffer(i);
for (unsigned int j = 0; j < l; ++j)
{
_promptEndPos++;
putcharIntern(str[j]);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::handleCommand(CommandSender* sender, int cmd,
int data, int id)
{
switch (cmd)
{
case kSetPositionCmd:
int newPos = (int)data + _linesPerPage - 1 + _firstLineInBuffer;
if (newPos != _scrollLine)
{
_scrollLine = newPos;
setDirty(); draw();
}
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::loadConfig()
{
// See logic at the end of handleKeyDown for an explanation of this
_makeDirty = true;
// Show the prompt the first time we draw this widget
if(_firstTime)
{
// Display greetings & prompt
string version = string("Stella ") + STELLA_VERSION + "\n";
print(version.c_str());
print("Debugger is ready\n");
print(PROMPT);
_promptStartPos = _promptEndPos = _currentPos;
// Take care of one-time debugger stuff
instance()->debugger().autoExec();
_firstTime = false;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::specialKeys(int keycode)
{
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)
{
setDirty(); draw();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::killChar(int direction)
{
if(direction == -1) // Delete previous character (backspace)
{
if(_currentPos <= _promptStartPos)
return;
_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 PromptWidget::killLine(int direction)
{
if(direction == -1) // erase from current position to beginning of line
{
int count = _currentPos - _promptStartPos;
if(count > 0)
for (int i = 0; i < count; i++)
killChar(-1);
}
else if(direction == 1) // erase from current position to end of line
{
for (int i = _currentPos; i < _promptEndPos; i++)
buffer(i) = ' ';
_promptEndPos = _currentPos;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::killLastWord()
{
int cnt = 0;
bool space = true;
while (_currentPos > _promptStartPos)
{
if (buffer(_currentPos - 1) == ' ')
{
if (!space)
break;
}
else
space = false;
_currentPos--;
cnt++;
}
for (int i = _currentPos; i < _promptEndPos; i++)
buffer(i) = buffer(i + cnt);
buffer(_promptEndPos) = ' ';
_promptEndPos -= cnt;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::addToHistory(const char *str)
{
strcpy(_history[_historyIndex], str);
_historyIndex = (_historyIndex + 1) % kHistorySize;
_historyLine = 0;
if (_historySize < kHistorySize)
_historySize++;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int PromptWidget::compareHistory(const char *histLine) {
return 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::historyScroll(int direction)
{
if (_historySize == 0)
return;
if (_historyLine == 0 && direction > 0)
{
int i;
for (i = 0; i < _promptEndPos - _promptStartPos; i++)
_history[_historyIndex][i] = buffer(_promptStartPos + i);
_history[_historyIndex][i] = '\0';
}
// Advance to the next line in the history
int line = _historyLine + direction;
if ((direction < 0 && line < 0) || (direction > 0 && line > _historySize))
return;
// If they press arrow-up with anything in the buffer, search backwards
// in the history.
/*
if(direction < 0 && _currentPos > _promptStartPos) {
for(;line > 0; line--) {
if(compareHistory(_history[line]) == 0)
break;
}
}
*/
_historyLine = line;
// Remove the current user text
_currentPos = _promptStartPos;
killLine(1); // to end of line
// ... and ensure the prompt is visible
scrollToCurrent();
// Print the text from the history
int idx;
if (_historyLine > 0)
idx = (_historyIndex - _historyLine + _historySize) % _historySize;
else
idx = _historyIndex;
for (int i = 0; i < kLineBufferSize && _history[idx][i] != '\0'; i++)
putcharIntern(_history[idx][i]);
_promptEndPos = _currentPos;
// Ensure once more the caret is visible (in case of very long history entries)
scrollToCurrent();
setDirty(); draw();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::nextLine()
{
// reset colors every line, so I don't have to remember to do it myself
textColor = defaultTextColor;
bgColor = defaultBGColor;
_inverse = false;
int line = _currentPos / _lineWidth;
if (line == _scrollLine)
_scrollLine++;
_currentPos = (line + 1) * _lineWidth;
updateScrollBuffer();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Call this (at least) when the current line changes or when a new line is added
void PromptWidget::updateScrollBuffer()
{
int lastchar = MAX(_promptEndPos, _currentPos);
int line = lastchar / _lineWidth;
int numlines = (line < _linesInBuffer) ? line + 1 : _linesInBuffer;
int firstline = line - numlines + 1;
if (firstline > _firstLineInBuffer)
{
// clear old line from buffer
for (int i = lastchar; i < (line+1) * _lineWidth; ++i)
buffer(i) = ' ';
_firstLineInBuffer = firstline;
}
_scrollBar->_numEntries = numlines;
_scrollBar->_currentPos = _scrollBar->_numEntries - (line - _scrollLine + _linesPerPage);
_scrollBar->_entriesPerPage = _linesPerPage;
_scrollBar->recalc();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int PromptWidget::printf(const char *format, ...)
{
va_list argptr;
va_start(argptr, format);
int count = this->vprintf(format, argptr);
va_end (argptr);
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int PromptWidget::vprintf(const char *format, va_list argptr)
{
char buf[2048];
#if defined(WIN32)
int count = _vsnprintf(buf, sizeof(buf), format, argptr);
#else
int count = vsnprintf(buf, sizeof(buf), format, argptr);
#endif
print(buf);
return count;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::putchar(int c)
{
putcharIntern(c);
setDirty(); draw(); // FIXME - not nice to redraw the full console just for one char!
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::putcharIntern(int c)
{
if (c == '\n')
nextLine();
else if(c & 0x80) { // set foreground color to TIA color
// don't print or advance cursor
// there are only 128 TIA colors, but
// OverlayColor contains 256 of them
textColor = (OverlayColor) ((c & 0x7f) << 1);
}
else if(c < ' ') { // More colors (the regular GUI ones)
textColor = (OverlayColor) (c + 0x100);
}
else if(c == 0x7f) { // toggle inverse video (DEL char)
_inverse = !_inverse;
}
else
{
buffer(_currentPos) = c | (textColor << 8) | (_inverse << 17);
_currentPos++;
if ((_scrollLine + 1) * _lineWidth == _currentPos)
{
_scrollLine++;
updateScrollBuffer();
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::print(const string& str)
{
const char* c = str.c_str();
while(*c)
putcharIntern(*c++);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::drawCaret()
{
FrameBuffer& fb = _boss->instance()->frameBuffer();
int line = _currentPos / _lineWidth;
// Don't draw the cursor if it's not in the current view
if(_scrollLine < line)
return;
int displayLine = line - _scrollLine + _linesPerPage - 1;
int x = _x + 1 + (_currentPos % _lineWidth) * _kConsoleCharWidth;
int y = _y + displayLine * _kConsoleLineHeight;
char c = buffer(_currentPos);
fb.fillRect(x, y, _kConsoleCharWidth, _kConsoleLineHeight, kTextColor);
fb.drawChar(&_boss->instance()->consoleFont(), c, x, y + 2, kBGColor);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PromptWidget::scrollToCurrent()
{
int line = _promptEndPos / _lineWidth;
if (line + _linesPerPage <= _scrollLine)
{
// TODO - this should only occur for loong edit lines, though
}
else if (line > _scrollLine)
{
_scrollLine = line;
updateScrollBuffer();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PromptWidget::saveBuffer(string& filename)
{
ofstream out(filename.c_str());
if(!out.is_open())
return false;
for(int start=0; start<_promptStartPos; start+=_lineWidth) {
int end = start+_lineWidth-1;
// look for first non-space, printing char from end of line
while( char(_buffer[end] & 0xff) <= ' ' && end >= start)
end--;
// spit out the line minus its trailing junk.
// Strip off any color/inverse bits
for(int j=start; j<=end; j++)
out << char(_buffer[j] & 0xff);
// add a \n
out << endl;
}
out.close();
return true;
}

View File

@ -0,0 +1,120 @@
//============================================================================
//
// 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: PromptWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef PROMPT_WIDGET_HXX
#define PROMPT_WIDGET_HXX
class ScrollBarWidget;
#include <stdarg.h>
#include "GuiObject.hxx"
#include "Widget.hxx"
#include "Command.hxx"
#include "bspf.hxx"
enum {
kBufferSize = 32768,
kLineBufferSize = 256,
kHistorySize = 20
};
class PromptWidget : public Widget, public CommandSender
{
public:
PromptWidget(GuiObject* boss, int x, int y, int w, int h);
virtual ~PromptWidget();
public:
int printf(const char *format, ...);
int vprintf(const char *format, va_list argptr);
#undef putchar
void putchar(int c);
void print(const string& str);
void printPrompt();
bool saveBuffer(string& filename);
protected:
inline int &buffer(int idx) { return _buffer[idx % kBufferSize]; }
void drawWidget(bool hilite);
void drawCaret();
void putcharIntern(int c);
void insertIntoPrompt(const char *str);
void updateScrollBuffer();
void scrollToCurrent();
// Line editing
void specialKeys(int keycode);
void nextLine();
void killChar(int direction);
void killLine(int direction);
void killLastWord();
// History
void addToHistory(const char *str);
void historyScroll(int direction);
void handleMouseDown(int x, int y, int button, int clickCount);
void handleMouseWheel(int x, int y, int direction);
bool handleKeyDown(int ascii, int keycode, int modifiers);
void handleCommand(CommandSender* sender, int cmd, int data, int id);
virtual bool wantsFocus() { return true; }
void loadConfig();
protected:
int _buffer[kBufferSize];
int _linesInBuffer;
int _lineWidth;
int _linesPerPage;
int _currentPos;
int _scrollLine;
int _firstLineInBuffer;
int _promptStartPos;
int _promptEndPos;
ScrollBarWidget* _scrollBar;
char _history[kHistorySize][kLineBufferSize];
int _historySize;
int _historyIndex;
int _historyLine;
int _kConsoleCharWidth, _kConsoleCharHeight, _kConsoleLineHeight;
OverlayColor defaultTextColor;
OverlayColor defaultBGColor;
OverlayColor textColor;
OverlayColor bgColor;
bool _inverse;
bool _makeDirty;
bool _firstTime;
int compareHistory(const char *histLine);
};
#endif

View File

@ -0,0 +1,419 @@
//============================================================================
//
// 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: RamWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include <sstream>
#include "OSystem.hxx"
#include "FrameBuffer.hxx"
#include "GuiUtils.hxx"
#include "GuiObject.hxx"
#include "InputTextDialog.hxx"
#include "Widget.hxx"
#include "EditTextWidget.hxx"
#include "DataGridWidget.hxx"
#include "RamDebug.hxx"
#include "RamWidget.hxx"
enum {
kUndoCmd = 'RWud',
kRevertCmd = 'RWrv',
kSearchCmd = 'RWse',
kCmpCmd = 'RWcp',
kRestartCmd = 'RWrs',
kSValEntered = 'RWsv',
kCValEntered = 'RWcv'
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RamWidget::RamWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
: Widget(boss, x, y, 16, 16),
CommandSender(boss),
myUndoAddress(-1),
myUndoValue(-1)
{
const int fontWidth = font.getMaxCharWidth(),
fontHeight = font.getFontHeight(),
lineHeight = font.getLineHeight(),
bwidth = 44,
bheight = 16;
int xpos, ypos, lwidth;
StaticTextWidget* t;
// Create a 16x8 grid holding byte values (16 x 8 = 128 RAM bytes) with labels
xpos = x; ypos = y + lineHeight; lwidth = 4 * fontWidth;
myRamGrid = new DataGridWidget(boss, font, xpos + lwidth, ypos,
16, 8, 2, 8, kBASE_16);
myRamGrid->setTarget(this);
addFocusWidget(myRamGrid);
// Create actions buttons to the left of the RAM grid
xpos += lwidth + myRamGrid->getWidth() + 4;
myUndoButton = new ButtonWidget(boss, xpos, ypos, bwidth, bheight,
"Undo", kUndoCmd, 0);
myUndoButton->setTarget(this);
ypos += bheight + bheight/2;
myRevertButton = new ButtonWidget(boss, xpos, ypos, bwidth, bheight,
"Revert", kRevertCmd, 0);
myRevertButton->setTarget(this);
ypos += 2 * bheight + 2;
mySearchButton = new ButtonWidget(boss, xpos, ypos, bwidth, bheight,
"Search", kSearchCmd, 0);
mySearchButton->setTarget(this);
ypos += bheight + bheight/2;
myCompareButton = new ButtonWidget(boss, xpos, ypos, bwidth, bheight,
"Compare", kCmpCmd, 0);
myCompareButton->setTarget(this);
ypos += bheight + bheight/2;
myRestartButton = new ButtonWidget(boss, xpos, ypos, bwidth, bheight,
"Reset", kRestartCmd, 0);
myRestartButton->setTarget(this);
// Labels for RAM grid
xpos = x; ypos = y + lineHeight;
for(int row = 0; row < 8; ++row)
{
t = new StaticTextWidget(boss, xpos-2, ypos + row*lineHeight + 2,
lwidth-2, fontHeight,
Debugger::to_hex_8(row*16 + kRamStart) + string(":"),
kTextAlignLeft);
t->setFont(font);
}
for(int col = 0; col < 16; ++col)
{
t = new StaticTextWidget(boss, xpos + col*myRamGrid->colWidth() + lwidth + 8,
ypos - lineHeight,
fontWidth, fontHeight,
Debugger::to_hex_4(col),
kTextAlignLeft);
t->setFont(font);
}
xpos = x + 10; ypos += 9 * lineHeight;
t = new StaticTextWidget(boss, xpos, ypos,
6*fontWidth, fontHeight,
"Label:", kTextAlignLeft);
t->setFont(font);
xpos += 6*fontWidth + 5;
myLabel = new EditTextWidget(boss, xpos, ypos-2, 17*fontWidth, lineHeight, "");
myLabel->setFont(font);
myLabel->setEditable(false);
xpos += 17*fontWidth + 20;
t = new StaticTextWidget(boss, xpos, ypos,
4*fontWidth, fontHeight,
"Dec:", kTextAlignLeft);
t->setFont(font);
xpos += 4*fontWidth + 5;
myDecValue = new EditTextWidget(boss, xpos, ypos-2, 4*fontWidth, lineHeight, "");
myDecValue->setFont(font);
myDecValue->setEditable(false);
xpos += 4*fontWidth + 20;
t = new StaticTextWidget(boss, xpos, ypos,
4*fontWidth, fontHeight,
"Bin:", kTextAlignLeft);
t->setFont(font);
xpos += 4*fontWidth + 5;
myBinValue = new EditTextWidget(boss, xpos, ypos-2, 9*fontWidth, lineHeight, "");
myBinValue->setFont(font);
myBinValue->setEditable(false);
// Inputbox which will pop up when searching RAM
myInputBox = new InputTextDialog(boss, font,
x + lwidth + 20, y + 2*lineHeight - 5);
myInputBox->setTarget(this);
// Start with these buttons disabled
myCompareButton->clearFlags(WIDGET_ENABLED);
myRestartButton->clearFlags(WIDGET_ENABLED);
// Calculate real dimensions
_w = lwidth + myRamGrid->getWidth();
_h = ypos + lineHeight - y;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RamWidget::~RamWidget()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
{
// We simply change the values in the ByteGridWidget
// It will then send the 'kDGItemDataChangedCmd' signal to change the actual
// memory location
int addr, value;
const char* buf;
RamDebug& dbg = instance()->debugger().ramDebug();
switch(cmd)
{
case kDGItemDataChangedCmd:
addr = myRamGrid->getSelectedAddr();
value = myRamGrid->getSelectedValue();
myUndoAddress = addr;
myUndoValue = dbg.read(addr);
dbg.write(addr, value);
myDecValue->setEditString(instance()->debugger().valueToString(value, kBASE_10));
myBinValue->setEditString(instance()->debugger().valueToString(value, kBASE_2));
myRevertButton->setEnabled(true);
myUndoButton->setEnabled(true);
break;
case kDGSelectionChangedCmd:
addr = myRamGrid->getSelectedAddr();
value = myRamGrid->getSelectedValue();
buf = instance()->debugger().equates()->getLabel(addr+kRamStart).c_str();
if(*buf) myLabel->setEditString(buf);
else myLabel->setEditString("");
myDecValue->setEditString(instance()->debugger().valueToString(value, kBASE_10));
myBinValue->setEditString(instance()->debugger().valueToString(value, kBASE_2));
break;
case kRevertCmd:
for(unsigned int i = 0; i < kRamSize; i++)
dbg.write(i, myOldValueList[i]);
fillGrid(true);
break;
case kUndoCmd:
dbg.write(myUndoAddress, myUndoValue);
myUndoButton->setEnabled(false);
fillGrid(false);
break;
case kSearchCmd:
myInputBox->setEditString("");
myInputBox->setTitle("");
myInputBox->setEmitSignal(kSValEntered);
parent()->addDialog(myInputBox);
break;
case kCmpCmd:
myInputBox->setEditString("");
myInputBox->setTitle("");
myInputBox->setEmitSignal(kCValEntered);
parent()->addDialog(myInputBox);
break;
case kRestartCmd:
doRestart();
break;
case kSValEntered:
{
const string& result = doSearch(myInputBox->getResult());
if(result != "")
myInputBox->setTitle(result);
else
parent()->removeDialog();
break;
}
case kCValEntered:
{
const string& result = doCompare(myInputBox->getResult());
if(result != "")
myInputBox->setTitle(result);
else
parent()->removeDialog();
break;
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RamWidget::loadConfig()
{
//cerr << "RamWidget::loadConfig()\n";
fillGrid(true);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RamWidget::fillGrid(bool updateOld)
{
IntArray alist;
IntArray vlist;
BoolArray changed;
if(updateOld) myOldValueList.clear();
RamDebug& dbg = instance()->debugger().ramDebug();
RamState state = (RamState&) dbg.getState();
RamState oldstate = (RamState&) dbg.getOldState();
vlist = state.ram;
if(updateOld) myOldValueList = state.ram;
for(unsigned int i = 0; i < 16*8; i++)
{
alist.push_back(i);
changed.push_back(state.ram[i] != oldstate.ram[i]);
}
myRamGrid->setList(alist, vlist, changed);
if(updateOld)
{
myRevertButton->setEnabled(false);
myUndoButton->setEnabled(false);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string RamWidget::doSearch(const string& str)
{
bool comparisonSearch = true;
if(str.length() == 0)
{
// An empty field means return all memory locations
comparisonSearch = false;
}
else if(str.find_first_of("+-", 0) != string::npos)
{
// Don't accept these characters here, only in compare
return "Invalid input +|-";
}
int searchVal = instance()->debugger().stringToValue(str);
// Clear the search array of previous items
mySearchAddr.clear();
mySearchValue.clear();
// Now, search all memory locations for this value, and add it to the
// search array
RamDebug& dbg = instance()->debugger().ramDebug();
for(int addr = 0; addr < kRamSize; ++addr)
{
int value = dbg.read(addr);
if(comparisonSearch && searchVal != value)
continue;
mySearchAddr.push_back(addr);
mySearchValue.push_back(value);
}
// If we have some hits, enable the comparison methods
if(mySearchAddr.size() > 0)
{
mySearchButton->setEnabled(false);
myCompareButton->setEnabled(true);
myRestartButton->setEnabled(true);
}
// Finally, show the search results in the list
myRamGrid->setHiliteList(mySearchAddr);
return "";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string RamWidget::doCompare(const string& str)
{
bool comparitiveSearch = false;
int searchVal = 0, offset = 0;
if(str.length() == 0)
return "Enter an absolute or comparitive value";
// Do some pre-processing on the string
string::size_type pos = str.find_first_of("+-", 0);
if(pos > 0 && pos != string::npos)
{
// Only accept '+' or '-' at the start of the string
return "Input must be [+|-]NUM";
}
// A comparitive search searches memory for locations that have changed by
// the specified amount, vs. for exact values
if(str[0] == '+' || str[0] == '-')
{
comparitiveSearch = true;
bool negative = false;
if(str[0] == '-')
negative = true;
string tmp = str;
tmp.erase(0, 1); // remove the operator
offset = instance()->debugger().stringToValue(tmp);
if(negative)
offset = -offset;
}
else
searchVal = instance()->debugger().stringToValue(str);
// Now, search all memory locations specified in mySearchArray for this value
RamDebug& dbg = instance()->debugger().ramDebug();
IntArray tempList;
for(unsigned int i = 0; i < mySearchAddr.size(); ++i)
{
if(comparitiveSearch)
{
searchVal = mySearchValue[i] + offset;
if(searchVal < 0 || searchVal > 255)
continue;
}
int addr = mySearchAddr[i];
if(dbg.read(addr) == searchVal)
tempList.push_back(addr);
}
// Update the searchArray to the new results
mySearchAddr = tempList;
// If we have some hits, enable the comparison methods
if(mySearchAddr.size() > 0)
{
myCompareButton->setEnabled(true);
myRestartButton->setEnabled(true);
}
// Finally, show the search results in the list
myRamGrid->setHiliteList(mySearchAddr);
return "";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RamWidget::doRestart()
{
// Erase all search buffers, reset to start mode
mySearchAddr.clear();
mySearchValue.clear();
myRamGrid->setHiliteList(mySearchAddr);
mySearchButton->setEnabled(true);
myCompareButton->setEnabled(false);
myRestartButton->setEnabled(false);
}

View File

@ -0,0 +1,77 @@
//============================================================================
//
// 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: RamWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef RAM_WIDGET_HXX
#define RAM_WIDGET_HXX
class GuiObject;
class InputTextDialog;
class ButtonWidget;
class EditTextWidget;
class StaticTextWidget;
#include "Array.hxx"
#include "Widget.hxx"
#include "Command.hxx"
#include "DataGridWidget.hxx"
class RamWidget : public Widget, public CommandSender
{
public:
RamWidget(GuiObject* boss, const GUI::Font& font, int x, int y);
virtual ~RamWidget();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
void loadConfig();
void setOpsWidget(DataGridOpsWidget* w) { myRamGrid->setOpsWidget(w); }
private:
void fillGrid(bool updateOld);
const string doSearch(const string& str);
const string doCompare(const string& str);
void doRestart();
private:
int myUndoAddress;
int myUndoValue;
DataGridWidget* myRamGrid;
EditTextWidget* myBinValue;
EditTextWidget* myDecValue;
EditTextWidget* myLabel;
ButtonWidget* myRevertButton;
ButtonWidget* myUndoButton;
ButtonWidget* mySearchButton;
ButtonWidget* myCompareButton;
ButtonWidget* myRestartButton;
InputTextDialog* myInputBox;
IntArray myOldValueList;
IntArray mySearchAddr;
IntArray mySearchValue;
};
#endif

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-30 17:51:26 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-30 17:51:26 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

@ -0,0 +1,139 @@
//============================================================================
//
// 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: RomWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include <sstream>
#include "Debugger.hxx"
#include "CpuDebug.hxx"
#include "GuiObject.hxx"
#include "RomListWidget.hxx"
#include "RomWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RomWidget::RomWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
: Widget(boss, x, y, 16, 16),
CommandSender(boss),
myFirstLoad(true),
mySourceAvailable(false),
myCurrentBank(-1)
{
int w = 58 * font.getMaxCharWidth(),
h = 31 * font.getLineHeight();
myRomList = new RomListWidget(boss, font, x, y, w, h);
myRomList->setTarget(this);
myRomList->setStyle(kSolidFill);
addFocusWidget(myRomList);
// Calculate real dimensions
_w = myRomList->getWidth();
_h = myRomList->getHeight();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RomWidget::~RomWidget()
{
myAddrList.clear();
myLineList.clear();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
{
switch(cmd)
{
case kListScrolledCmd:
incrementalUpdate();
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
ostringstream cmd;
cmd << "break #" << myAddrList[data];
instance()->debugger().run(cmd.str());
break;
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::loadConfig()
{
//cerr << "RomWidget::loadConfig()\n";
// Only reload full bank when necessary
if(myFirstLoad || myCurrentBank != instance()->debugger().getBank())
{
initialUpdate();
myFirstLoad = false;
}
else // only reload what's in current view
{
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);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::initialUpdate()
{
Debugger& dbg = instance()->debugger();
myCurrentBank = dbg.getBank();
// Fill romlist the current bank of source or disassembly
if(mySourceAvailable)
; // FIXME
else
{
StringList label, data;
BoolArray state;
myAddrList.clear();
myLineList.clear();
// Disassemble entire bank (up to 4096 lines)
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);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomWidget::incrementalUpdate()
{
}

View File

@ -0,0 +1,66 @@
//============================================================================
//
// 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: RomWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef ROM_WIDGET_HXX
#define ROM_WIDGET_HXX
class GuiObject;
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:
RomWidget(GuiObject* boss, const GUI::Font& font, int x, int y);
virtual ~RomWidget();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
void loadConfig();
private:
void initialUpdate();
void incrementalUpdate();
private:
RomListWidget* myRomList;
/** List of addresses indexed by line number */
IntArray myAddrList;
/** List of line numbers indexed by address */
AddrToLine myLineList;
bool myFirstLoad;
bool mySourceAvailable;
int myCurrentBank;
};
#endif

View File

@ -0,0 +1,125 @@
//============================================================================
//
// 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: TiaInfoWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include "OSystem.hxx"
#include "FrameBuffer.hxx"
#include "Debugger.hxx"
#include "TIADebug.hxx"
#include "Widget.hxx"
#include "EditTextWidget.hxx"
#include "GuiObject.hxx"
#include "TiaInfoWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TiaInfoWidget::TiaInfoWidget(GuiObject* boss, int x, int y, int w, int h)
: Widget(boss, x, y, w, h),
CommandSender(boss)
{
int xpos = x, ypos = y, lwidth = 45;
const GUI::Font& font = instance()->font();
// Add frame info
xpos = x + 10; ypos = y + 10;
new StaticTextWidget(boss, xpos, ypos, lwidth, kLineHeight, "Frame:", kTextAlignLeft);
xpos += lwidth;
myFrameCount = new EditTextWidget(boss, xpos, ypos-2, 45, kLineHeight, "");
myFrameCount->setFont(font);
myFrameCount->setEditable(false);
xpos = x + 10; ypos += kLineHeight + 5;
new StaticTextWidget(boss, xpos, ypos, lwidth, kLineHeight, "F. Cycles:", kTextAlignLeft);
xpos += lwidth;
myFrameCycles = new EditTextWidget(boss, xpos, ypos-2, 45, kLineHeight, "");
myFrameCycles->setFont(font);
myFrameCycles->setEditable(false);
xpos = x + 20; ypos += kLineHeight + 5;
myVSync = new CheckboxWidget(boss, font, xpos, ypos-3, "VSync", 0);
myVSync->setEditable(false);
xpos = x + 20; ypos += kLineHeight + 5;
myVBlank = new CheckboxWidget(boss, font, xpos, ypos-3, "VBlank", 0);
myVBlank->setEditable(false);
xpos = x + 10 + 100; ypos = y + 10;
new StaticTextWidget(boss, xpos, ypos, lwidth, kLineHeight, "Scanline:", kTextAlignLeft);
xpos += lwidth;
myScanlineCount = new EditTextWidget(boss, xpos, ypos-2, 30, kLineHeight, "");
myScanlineCount->setFont(font);
myScanlineCount->setEditable(false);
xpos = x + 10 + 100; ypos += kLineHeight + 5;
new StaticTextWidget(boss, xpos, ypos, lwidth, kLineHeight, "S. Cycles:", kTextAlignLeft);
xpos += lwidth;
myScanlineCycles = new EditTextWidget(boss, xpos, ypos-2, 30, kLineHeight, "");
myScanlineCycles->setFont(font);
myScanlineCycles->setEditable(false);
xpos = x + 10 + 100; ypos += kLineHeight + 5;
new StaticTextWidget(boss, xpos, ypos, lwidth, kLineHeight, "Pixel Pos:", kTextAlignLeft);
xpos += lwidth;
myPixelPosition = new EditTextWidget(boss, xpos, ypos-2, 30, kLineHeight, "");
myPixelPosition->setFont(font);
myPixelPosition->setEditable(false);
xpos = x + 10 + 100; ypos += kLineHeight + 5;
new StaticTextWidget(boss, xpos, ypos, lwidth, kLineHeight, "Color Clk:", kTextAlignLeft);
xpos += lwidth;
myColorClocks = new EditTextWidget(boss, xpos, ypos-2, 30, kLineHeight, "");
myColorClocks->setFont(font);
myColorClocks->setEditable(false);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TiaInfoWidget::~TiaInfoWidget()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaInfoWidget::handleMouseDown(int x, int y, int button, int clickCount)
{
cerr << "TiaInfoWidget button press: x = " << x << ", y = " << y << endl;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaInfoWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaInfoWidget::loadConfig()
{
Debugger& dbg = instance()->debugger();
TIADebug& tia = dbg.tiaDebug();
myFrameCount->setEditString(dbg.valueToString(tia.frameCount(), kBASE_10));
myFrameCycles->setEditString(dbg.valueToString(dbg.cycles(), kBASE_10));
myVSync->setState(tia.vsync());
myVBlank->setState(tia.vblank());
int clk = tia.clocksThisLine();
myScanlineCount->setEditString(dbg.valueToString(tia.scanlines(), kBASE_10));
myScanlineCycles->setEditString(dbg.valueToString(clk/3, kBASE_10));
myPixelPosition->setEditString(dbg.valueToString(clk-68, kBASE_10));
myColorClocks->setEditString(dbg.valueToString(clk, kBASE_10));
}

View File

@ -0,0 +1,57 @@
//============================================================================
//
// 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: TiaInfoWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef TIA_INFO_WIDGET_HXX
#define TIA_INFO_WIDGET_HXX
class GuiObject;
class EditTextWidget;
#include "Widget.hxx"
#include "Command.hxx"
class TiaInfoWidget : public Widget, public CommandSender
{
public:
TiaInfoWidget(GuiObject *boss, int x, int y, int w, int h);
virtual ~TiaInfoWidget();
void loadConfig();
protected:
void handleMouseDown(int x, int y, int button, int clickCount);
void handleCommand(CommandSender* sender, int cmd, int data, int id);
private:
EditTextWidget* myFrameCount;
EditTextWidget* myFrameCycles;
EditTextWidget* myScanlineCount;
EditTextWidget* myScanlineCycles;
EditTextWidget* myPixelPosition;
EditTextWidget* myColorClocks;
CheckboxWidget* myVSync;
CheckboxWidget* myVBlank;
};
#endif

View File

@ -0,0 +1,85 @@
//============================================================================
//
// 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: TiaOutputWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include "OSystem.hxx"
#include "FrameBuffer.hxx"
#include "Widget.hxx"
#include "GuiObject.hxx"
#include "TiaOutputWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TiaOutputWidget::TiaOutputWidget(GuiObject* boss, int x, int y, int w, int h)
: Widget(boss, x, y, w, h),
CommandSender(boss)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TiaOutputWidget::~TiaOutputWidget()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaOutputWidget::loadConfig()
{
setDirty(); draw();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaOutputWidget::advanceScanline(int lines)
{
while(lines)
{
instance()->console().mediaSource().updateScanline();
--lines;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaOutputWidget::advance(int frames)
{
while(frames)
{
instance()->console().mediaSource().update();
--frames;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaOutputWidget::handleMouseDown(int x, int y, int button, int clickCount)
{
int xstart = atoi(instance()->console().properties().get("Display.XStart").c_str());
int ystart = atoi(instance()->console().properties().get("Display.YStart").c_str());
cerr << "TiaOutputWidget button press:" << endl
<< "x = " << x << ", y = " << y << endl
<< "xstart = " << xstart << ", ystart = " << ystart << endl
<< endl;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TiaOutputWidget::drawWidget(bool hilite)
{
//cerr << "TiaOutputWidget::drawWidget\n";
instance()->frameBuffer().refresh();
instance()->frameBuffer().drawMediaSource();
}

View File

@ -0,0 +1,58 @@
//============================================================================
//
// 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: TiaOutputWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef TIA_OUTPUT_WIDGET_HXX
#define TIA_OUTPUT_WIDGET_HXX
class GuiObject;
#include "Widget.hxx"
#include "Command.hxx"
class TiaOutputWidget : public Widget, public CommandSender
{
public:
TiaOutputWidget(GuiObject *boss, int x, int y, int w, int h);
virtual ~TiaOutputWidget();
void handleMouseDown(int x, int y, int button, int clickCount);
void loadConfig();
// Eventually, these methods will enable access to the onscreen TIA image
// For example, clicking an area may cause an action
// (fill to this scanline, etc).
/*
virtual void handleMouseUp(int x, int y, int button, int clickCount);
virtual void handleMouseWheel(int x, int y, int direction);
virtual bool handleKeyDown(int ascii, int keycode, int modifiers);
virtual bool handleKeyUp(int ascii, int keycode, int modifiers);
virtual void handleCommand(CommandSender* sender, int cmd, int data, int id);
*/
void advanceScanline(int lines);
void advance(int frames);
protected:
void drawWidget(bool hilite);
bool wantsFocus() { return false; }
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,111 @@
//============================================================================
//
// 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: TiaWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef TIA_WIDGET_HXX
#define TIA_WIDGET_HXX
class GuiObject;
class ButtonWidget;
class DataGridWidget;
class StaticTextWidget;
class ToggleBitWidget;
class TogglePixelWidget;
class EditTextWidget;
class ColorWidget;
#include "Widget.hxx"
#include "Command.hxx"
class TiaWidget : public Widget, public CommandSender
{
public:
TiaWidget(GuiObject* boss, int x, int y, int w, int h);
virtual ~TiaWidget();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
void loadConfig();
private:
void fillGrid();
void changeColorRegs();
void convertCharToBool(BoolArray& b, unsigned char value);
int convertBoolToInt(const BoolArray& b);
private:
DataGridWidget* myRamGrid;
EditTextWidget* myBinValue;
EditTextWidget* myDecValue;
EditTextWidget* myLabel;
DataGridWidget* myColorRegs;
ColorWidget* myCOLUP0Color;
ColorWidget* myCOLUP1Color;
ColorWidget* myCOLUPFColor;
ColorWidget* myCOLUBKColor;
TogglePixelWidget* myGRP0;
TogglePixelWidget* myGRP1;
DataGridWidget* myPosP0;
DataGridWidget* myPosP1;
DataGridWidget* myPosM0;
DataGridWidget* myPosM1;
DataGridWidget* myPosBL;
DataGridWidget* myHMP0;
DataGridWidget* myHMP1;
DataGridWidget* myHMM0;
DataGridWidget* myHMM1;
DataGridWidget* myHMBL;
DataGridWidget* myNusizP0;
DataGridWidget* myNusizP1;
DataGridWidget* myNusizM0;
DataGridWidget* myNusizM1;
DataGridWidget* mySizeBL;
EditTextWidget* myNusizP0Text;
EditTextWidget* myNusizP1Text;
CheckboxWidget* myRefP0;
CheckboxWidget* myRefP1;
CheckboxWidget* myDelP0;
CheckboxWidget* myDelP1;
CheckboxWidget* myDelBL;
CheckboxWidget* myEnaM0;
CheckboxWidget* myEnaM1;
CheckboxWidget* myEnaBL;
CheckboxWidget* myResMP0;
CheckboxWidget* myResMP1;
/** Collision register bits */
CheckboxWidget* myCollision[15];
TogglePixelWidget* myPF[3];
CheckboxWidget* myRefPF;
CheckboxWidget* myScorePF;
CheckboxWidget* myPriorityPF;
};
#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: ToggleBitWidget.cxx,v 1.10 2005-08-19 15:05:09 stephena Exp $
// $Id: ToggleBitWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: ToggleBitWidget.hxx,v 1.6 2005-08-19 15:05:09 stephena Exp $
// $Id: ToggleBitWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: TogglePixelWidget.cxx,v 1.2 2005-08-19 23:02:09 stephena Exp $
// $Id: TogglePixelWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: TogglePixelWidget.hxx,v 1.2 2005-08-19 23:02:09 stephena Exp $
// $Id: TogglePixelWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: ToggleWidget.cxx,v 1.1 2005-08-19 15:05:09 stephena Exp $
// $Id: ToggleWidget.cxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

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: ToggleWidget.hxx,v 1.1 2005-08-19 15:05:09 stephena Exp $
// $Id: ToggleWidget.hxx,v 1.1 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project

View File

@ -0,0 +1,24 @@
MODULE := src/debugger/gui
MODULE_OBJS := \
src/debugger/gui/CpuWidget.o \
src/debugger/gui/PromptWidget.o \
src/debugger/gui/RamWidget.o \
src/debugger/gui/RomWidget.o \
src/debugger/gui/RomListWidget.o \
src/debugger/gui/TiaWidget.o \
src/debugger/gui/TiaInfoWidget.o \
src/debugger/gui/TiaOutputWidget.o \
src/debugger/gui/ColorWidget.o \
src/debugger/gui/DataGridOpsWidget.o \
src/debugger/gui/DataGridWidget.o \
src/debugger/gui/DebuggerDialog.o \
src/debugger/gui/ToggleBitWidget.o \
src/debugger/gui/TogglePixelWidget.o \
src/debugger/gui/ToggleWidget.o
MODULE_DIRS += \
src/debugger/gui
# Include common rules
include $(srcdir)/common.rules

View File

@ -1,8 +1,6 @@
MODULE := src/debugger
MODULE_OBJS := \
src/debugger/Cheat.o \
src/debugger/CheetahCheat.o \
src/debugger/Debugger.o \
src/debugger/DebuggerParser.o \
src/debugger/EquateList.o \
@ -41,15 +39,7 @@ MODULE_OBJS := \
src/debugger/PackedBitArray.o \
src/debugger/CpuDebug.o \
src/debugger/RamDebug.o \
src/debugger/TIADebug.o \
src/debugger/TiaInfoWidget.o \
src/debugger/TiaOutputWidget.o \
src/debugger/CpuWidget.o \
src/debugger/PromptWidget.o \
src/debugger/RamWidget.o \
src/debugger/RomWidget.o \
src/debugger/RomListWidget.o \
src/debugger/TiaWidget.o
src/debugger/TIADebug.o
MODULE_DIRS += \
src/debugger

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: Console.cxx,v 1.67 2005-08-29 18:36:41 stephena Exp $
// $Id: Console.cxx,v 1.68 2005-08-30 17:51:26 stephena Exp $
//============================================================================
#include <assert.h>
@ -80,10 +80,8 @@ Console::Console(const uInt8* image, uInt32 size, OSystem* osystem)
if(myProperties.get("Cartridge.MD5") == "")
myProperties.set("Cartridge.MD5", md5);
#ifdef DEVELOPER_SUPPORT
// A developer can override properties from the commandline
setDeveloperProperties();
#endif
// Setup the controllers based on properties
string left = myProperties.get("Controller.Left");

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.90 2005-08-30 01:10:54 stephena Exp $
// $Id: EventHandler.cxx,v 1.91 2005-08-30 17:51:26 stephena Exp $
//============================================================================
#include <algorithm>
@ -331,7 +331,6 @@ void EventHandler::poll(uInt32 time)
myOSystem->sound().adjustVolume(1);
break;
#ifdef DEVELOPER_SUPPORT
case SDLK_END: // Alt-End increases XStart
myOSystem->console().changeXStart(1);
break;
@ -347,8 +346,7 @@ void EventHandler::poll(uInt32 time)
case SDLK_PAGEDOWN: // Alt-PageDown decreases YStart
myOSystem->console().changeYStart(0);
break;
#endif
#ifdef DEVELOPER_SUPPORT
case SDLK_z:
myOSystem->console().toggleP0Bit();
break;
@ -380,7 +378,7 @@ void EventHandler::poll(uInt32 time)
case SDLK_SLASH:
myOSystem->console().enableBits(true);
break;
#endif
case SDLK_s: // Alt-s merges properties into stella.pro
myOSystem->console().saveProperties(myOSystem->propertiesOutputFilename(), true);
break;
@ -451,7 +449,6 @@ void EventHandler::poll(uInt32 time)
myOSystem->createConsole();
break;
#ifdef DEVELOPER_SUPPORT
case SDLK_END: // Ctrl-End increases Width
myOSystem->console().changeWidth(1);
break;
@ -467,7 +464,7 @@ void EventHandler::poll(uInt32 time)
case SDLK_PAGEDOWN: // Ctrl-PageDown decreases Height
myOSystem->console().changeHeight(0);
break;
#endif
case SDLK_s: // Ctrl-s saves properties to a file
string newPropertiesFile = myOSystem->baseDir() + BSPF_PATH_SEPARATOR +
myOSystem->console().properties().get("Cartridge.Name") + ".pro";
@ -1705,6 +1702,8 @@ bool EventHandler::enterDebugMode()
// Make sure screen is always refreshed when entering debug mode
// (sometimes entering on a breakpoint doesn't draw contents)
refreshDisplay();
#else
myOSystem->frameBuffer().showMessage("Developer/debugger unsupported");
#endif
return 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: Settings.cxx,v 1.56 2005-08-25 15:19:17 stephena Exp $
// $Id: Settings.cxx,v 1.57 2005-08-30 17:51:26 stephena Exp $
//============================================================================
#include <cassert>
@ -294,7 +294,6 @@ void Settings::usage()
#endif
<< " -listrominfo Display contents of stella.pro, one line per ROM entry\n"
<< " -help Show the text you're now reading\n"
#ifdef DEVELOPER_SUPPORT
<< endl
<< " The following options are meant for developers\n"
<< " Arguments are more fully explained in the manual\n"
@ -314,7 +313,6 @@ void Settings::usage()
<< " -height <arg> Sets the 'Display.Height' property\n"
<< " -cpu <arg> Sets the 'Emulation.CPU' property\n"
<< " -hmove <arg> Sets the 'Emulation.HmoveBlanks' property\n"
#endif
<< endl;
#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: LauncherOptionsDialog.cxx,v 1.10 2005-08-16 18:34:12 stephena Exp $
// $Id: LauncherOptionsDialog.cxx,v 1.11 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -105,7 +105,6 @@ LauncherOptionsDialog::~LauncherOptionsDialog()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherOptionsDialog::loadConfig()
{
cerr << "LauncherOptionsDialog::loadConfig()\n";
string s;
bool b;

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: PopUpWidget.cxx,v 1.15 2005-08-01 22:33:15 stephena Exp $
// $Id: PopUpWidget.cxx,v 1.16 2005-08-30 17:51:26 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -80,7 +80,7 @@ void PopUpDialog::drawDialog()
// by the ScummVM guys, so I'm not going to mess with it.
if(_dirty)
{
cerr << "PopUpDialog::drawDialog()\n";
// cerr << "PopUpDialog::drawDialog()\n";
FrameBuffer& fb = _popUpBoss->instance()->frameBuffer();
// Draw the menu border

View File

@ -4,13 +4,9 @@ MODULE_OBJS := \
src/gui/AboutDialog.o \
src/gui/AudioDialog.o \
src/gui/BrowserDialog.o \
src/gui/ColorWidget.o \
src/gui/CheatCodeDialog.o \
src/gui/CommandDialog.o \
src/gui/CommandMenu.o \
src/gui/DataGridWidget.o \
src/gui/DataGridOpsWidget.o \
src/gui/DebuggerDialog.o \
src/gui/DialogContainer.o \
src/gui/Dialog.o \
src/gui/EditableWidget.o \
@ -33,11 +29,8 @@ MODULE_OBJS := \
src/gui/CheckListWidget.o \
src/gui/StringListWidget.o \
src/gui/TabWidget.o \
src/gui/ToggleWidget.o \
src/gui/ToggleBitWidget.o \
src/gui/TogglePixelWidget.o \
src/gui/VideoDialog.o \
src/gui/Widget.o \
src/gui/Widget.o
MODULE_DIRS += \
src/gui