Added DPC+ scheme to the debugger ROM tab. This may need to be

extended into yet another tab, since there's still the need to
show the display bank, frequency bank and DPC Harmony RAM.  Or
maybe there isn't a need to see this extra stuff??

Some more cleanups of the graphics/UI API.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2703 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2013-04-21 20:02:55 +00:00
parent f1530ca86d
commit 777a6ceb8c
19 changed files with 525 additions and 70 deletions

View File

@ -59,7 +59,7 @@ CheatCodeDialog::CheatCodeDialog(OSystem* osystem, DialogContainer* parent,
myCheatList = myCheatList =
new CheckListWidget(this, font, xpos, ypos, _w - buttonWidth - 25, new CheckListWidget(this, font, xpos, ypos, _w - buttonWidth - 25,
_h - 2*buttonHeight - 10); _h - 2*buttonHeight - 10);
myCheatList->setStyle(kXFill); myCheatList->setStyle(CheckListWidget::XFill);
myCheatList->setEditable(false); myCheatList->setEditable(false);
wid.push_back(myCheatList); wid.push_back(myCheatList);
@ -209,7 +209,7 @@ void CheatCodeDialog::handleCommand(CommandSender* sender, int cmd,
close(); close();
break; break;
case kListItemDoubleClickedCmd: case ListWidget::kDoubleClickedCmd:
editCheat(); editCheat();
break; break;

View File

@ -315,6 +315,9 @@ string Debugger::valueToString(int value, BaseFormat outputBase) const
case kBASE_16_4: // base 16: 4 bytes wide case kBASE_16_4: // base 16: 4 bytes wide
BSPF_snprintf(vToS_buf, 5, "%04X", value); BSPF_snprintf(vToS_buf, 5, "%04X", value);
break; break;
case kBASE_16_8: // base 16: 8 bytes wide
BSPF_snprintf(vToS_buf, 9, "%08X", value);
break;
case kBASE_16: // base 16: 2, 4, 8 bytes (depending on value) case kBASE_16: // base 16: 2, 4, 8 bytes (depending on value)
default: default:

View File

@ -38,6 +38,7 @@ typedef enum {
kBASE_16_1, // base 16: 1 byte wide kBASE_16_1, // base 16: 1 byte wide
kBASE_16_2, // base 16: 2 bytes wide kBASE_16_2, // base 16: 2 bytes wide
kBASE_16_4, // base 16: 4 bytes wide kBASE_16_4, // base 16: 4 bytes wide
kBASE_16_8, // base 16: 8 bytes wide
kBASE_10, // base 10: 3 or 5 bytes (depending on value) kBASE_10, // base 10: 3 or 5 bytes (depending on value)
kBASE_2, // base 2: 8 or 16 bits (depending on value) kBASE_2, // base 2: 8 or 16 bits (depending on value)
kBASE_2_8, // base 2: 1 byte (8 bits) wide kBASE_2_8, // base 2: 1 byte (8 bits) wide

View File

@ -0,0 +1,318 @@
//============================================================================
//
// 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-2013 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id$
//============================================================================
#include "CartDPCPlus.hxx"
#include "DataGridWidget.hxx"
#include "PopUpWidget.hxx"
#include "CartDPCPlusWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeDPCPlusWidget::CartridgeDPCPlusWidget(
GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h, CartridgeDPCPlus& cart)
: CartDebugWidget(boss, font, x, y, w, h),
myCart(cart)
{
uInt16 size = cart.mySize;
ostringstream info;
info << "Extended DPC cartridge, six 4K banks, 4K display bank, 1K frequency table, "
<< "8K DPC RAM\n"
<< "DPC registers accessible @ $F000 - $F07F\n"
<< " $F000 - $F03F (R), $F040 - $F07F (W)\n"
<< "Banks accessible at hotspots $FF6 to $FFB\n"
<< "Startup bank = " << cart.myStartBank << "\n";
#if 0
// Eventually, we should query this from the debugger/disassembler
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF6; i < 6; ++i, offset += 0x1000)
{
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
start -= start % 0x1000;
info << "Bank " << i << " @ $" << HEX4 << (start + 0x80) << " - "
<< "$" << (start + 0xFFF) << " (hotspot = $" << (spot+i) << ")\n";
}
#endif
int xpos = 10,
ypos = addBaseInformation(size, "Activision (Pitfall II)", info.str()) +
myLineHeight;
StringMap items;
items.push_back("0 ($FF6)", "0");
items.push_back("1 ($FF7)", "1");
items.push_back("2 ($FF8)", "2");
items.push_back("3 ($FF9)", "3");
items.push_back("4 ($FFA)", "4");
items.push_back("5 ($FFB)", "5");
myBank =
new PopUpWidget(boss, font, xpos, ypos-2, font.getStringWidth("0 ($FFx) "),
myLineHeight, items, "Set bank: ",
font.getStringWidth("Set bank: "), kBankChanged);
myBank->setTarget(this);
addFocusWidget(myBank);
// Top registers
int lwidth = font.getStringWidth("Counter Registers: ");
xpos = 10; ypos += myLineHeight + 8;
new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Top Registers: ", kTextAlignLeft);
xpos += lwidth;
myTops = new DataGridWidget(boss, font, xpos, ypos-2, 8, 1, 2, 8, kBASE_16);
myTops->setTarget(this);
myTops->setEditable(false);
// Bottom registers
xpos = 10; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Bottom Registers: ", kTextAlignLeft);
xpos += lwidth;
myBottoms = new DataGridWidget(boss, font, xpos, ypos-2, 8, 1, 2, 8, kBASE_16);
myBottoms->setTarget(this);
myBottoms->setEditable(false);
// Counter registers
xpos = 10; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Counter Registers: ", kTextAlignLeft);
xpos += lwidth;
myCounters = new DataGridWidget(boss, font, xpos, ypos-2, 8, 1, 4, 16, kBASE_16_4);
myCounters->setTarget(this);
myCounters->setEditable(false);
// Fractional counter registers
xpos = 10; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Frac Counters: ", kTextAlignLeft);
xpos += lwidth;
myFracCounters = new DataGridWidget(boss, font, xpos, ypos-2, 4, 2, 8, 32, kBASE_16_8);
myFracCounters->setTarget(this);
myFracCounters->setEditable(false);
// Fractional increment registers
xpos = 10; ypos += myFracCounters->getHeight() + 8;
new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Frac Increments: ", kTextAlignLeft);
xpos += lwidth;
myFracIncrements = new DataGridWidget(boss, font, xpos, ypos-2, 8, 1, 2, 8, kBASE_16);
myFracIncrements->setTarget(this);
myFracIncrements->setEditable(false);
// Special function parameters
xpos = 10; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Function Params: ", kTextAlignLeft);
xpos += lwidth;
myParameter = new DataGridWidget(boss, font, xpos, ypos-2, 8, 1, 2, 8, kBASE_16);
myParameter->setTarget(this);
myParameter->setEditable(false);
// Music counters
xpos = 10; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Music Counters: ", kTextAlignLeft);
xpos += lwidth;
myMusicCounters = new DataGridWidget(boss, font, xpos, ypos-2, 3, 1, 8, 32, kBASE_16_8);
myMusicCounters->setTarget(this);
myMusicCounters->setEditable(false);
// Music frequencies
xpos = 10; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Music Frequencies: ", kTextAlignLeft);
xpos += lwidth;
myMusicFrequencies = new DataGridWidget(boss, font, xpos, ypos-2, 3, 1, 8, 32, kBASE_16_8);
myMusicFrequencies->setTarget(this);
myMusicFrequencies->setEditable(false);
// Music waveforms
xpos = 10; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Music Waveforms: ", kTextAlignLeft);
xpos += lwidth;
myMusicWaveforms = new DataGridWidget(boss, font, xpos, ypos-2, 3, 1, 4, 16, kBASE_16_4);
myMusicWaveforms->setTarget(this);
myMusicWaveforms->setEditable(false);
// Current random number
lwidth = font.getStringWidth("Current random number: ");
xpos = 10; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Current random number: ", kTextAlignLeft);
xpos += lwidth;
myRandom = new DataGridWidget(boss, font, xpos, ypos-2, 1, 1, 8, 32, kBASE_16_8);
myRandom->setTarget(this);
myRandom->setEditable(false);
// Fast fetch and immediate mode LDA flags
xpos += myRandom->getWidth() + 30;
myFastFetch = new CheckboxWidget(boss, font, xpos, ypos, "Fast Fetcher enabled");
myFastFetch->setTarget(this);
myFastFetch->setEditable(false);
ypos += myLineHeight + 4;
myIMLDA = new CheckboxWidget(boss, font, xpos, ypos, "Immediate mode LDA");
myIMLDA->setTarget(this);
myIMLDA->setEditable(false);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPCPlusWidget::saveOldState()
{
myOldState.tops.clear();
myOldState.bottoms.clear();
myOldState.counters.clear();
myOldState.fraccounters.clear();
myOldState.fracinc.clear();
myOldState.param.clear();
myOldState.mcounters.clear();
myOldState.mfreqs.clear();
myOldState.mwaves.clear();
for(int i = 0; i < 8; ++i)
{
myOldState.tops.push_back(myCart.myTops[i]);
myOldState.bottoms.push_back(myCart.myBottoms[i]);
myOldState.counters.push_back(myCart.myCounters[i]);
myOldState.fraccounters.push_back(myCart.myFractionalCounters[i]);
myOldState.fracinc.push_back(myCart.myFractionalIncrements[i]);
myOldState.param.push_back(myCart.myParameter[i]);
}
for(int i = 0; i < 3; ++i)
{
myOldState.mcounters.push_back(myCart.myMusicCounters[i]);
myOldState.mfreqs.push_back(myCart.myMusicFrequencies[i]);
myOldState.mwaves.push_back(myCart.myMusicWaveforms[i]);
}
myOldState.random = myCart.myRandomNumber;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPCPlusWidget::loadConfig()
{
myBank->setSelected(myCart.myCurrentBank);
// Get registers, using change tracking
IntArray alist;
IntArray vlist;
BoolArray changed;
alist.clear(); vlist.clear(); changed.clear();
for(int i = 0; i < 8; ++i)
{
alist.push_back(0); vlist.push_back(myCart.myTops[i]);
changed.push_back(myCart.myTops[i] != myOldState.tops[i]);
}
myTops->setList(alist, vlist, changed);
alist.clear(); vlist.clear(); changed.clear();
for(int i = 0; i < 8; ++i)
{
alist.push_back(0); vlist.push_back(myCart.myBottoms[i]);
changed.push_back(myCart.myBottoms[i] != myOldState.bottoms[i]);
}
myBottoms->setList(alist, vlist, changed);
alist.clear(); vlist.clear(); changed.clear();
for(int i = 0; i < 8; ++i)
{
alist.push_back(0); vlist.push_back(myCart.myCounters[i]);
changed.push_back(myCart.myCounters[i] != myOldState.counters[i]);
}
myCounters->setList(alist, vlist, changed);
alist.clear(); vlist.clear(); changed.clear();
for(int i = 0; i < 8; ++i)
{
alist.push_back(0); vlist.push_back(myCart.myFractionalCounters[i]);
changed.push_back(myCart.myFractionalCounters[i] != (uInt32)myOldState.fraccounters[i]);
}
myFracCounters->setList(alist, vlist, changed);
alist.clear(); vlist.clear(); changed.clear();
for(int i = 0; i < 8; ++i)
{
alist.push_back(0); vlist.push_back(myCart.myFractionalIncrements[i]);
changed.push_back(myCart.myFractionalIncrements[i] != myOldState.fracinc[i]);
}
myFracIncrements->setList(alist, vlist, changed);
alist.clear(); vlist.clear(); changed.clear();
for(int i = 0; i < 8; ++i)
{
alist.push_back(0); vlist.push_back(myCart.myParameter[i]);
changed.push_back(myCart.myParameter[i] != myOldState.param[i]);
}
myParameter->setList(alist, vlist, changed);
alist.clear(); vlist.clear(); changed.clear();
for(int i = 0; i < 3; ++i)
{
alist.push_back(0); vlist.push_back(myCart.myMusicCounters[i]);
changed.push_back(myCart.myMusicCounters[i] != (uInt32)myOldState.mcounters[i]);
}
myMusicCounters->setList(alist, vlist, changed);
alist.clear(); vlist.clear(); changed.clear();
for(int i = 0; i < 3; ++i)
{
alist.push_back(0); vlist.push_back(myCart.myMusicFrequencies[i]);
changed.push_back(myCart.myMusicFrequencies[i] != (uInt32)myOldState.mfreqs[i]);
}
myMusicFrequencies->setList(alist, vlist, changed);
alist.clear(); vlist.clear(); changed.clear();
for(int i = 0; i < 3; ++i)
{
alist.push_back(0); vlist.push_back(myCart.myMusicWaveforms[i]);
changed.push_back(myCart.myMusicWaveforms[i] != myOldState.mwaves[i]);
}
myMusicWaveforms->setList(alist, vlist, changed);
myRandom->setList(0, myCart.myRandomNumber,
myCart.myRandomNumber != myOldState.random);
myFastFetch->setState(myCart.myFastFetch);
myIMLDA->setState(myCart.myLDAimmediate);
CartDebugWidget::loadConfig();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPCPlusWidget::handleCommand(CommandSender* sender,
int cmd, int data, int id)
{
if(cmd == kBankChanged)
{
myCart.unlockBank();
myCart.bank(myBank->getSelected());
myCart.lockBank();
invalidate();
}
}

View File

@ -0,0 +1,79 @@
//============================================================================
//
// 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-2013 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id$
//============================================================================
#ifndef CARTRIDGEDPCPlus_WIDGET_HXX
#define CARTRIDGEDPCPlus_WIDGET_HXX
class CartridgeDPCPlus;
class PopUpWidget;
class CheckboxWidget;
class DataGridWidget;
#include "CartDebugWidget.hxx"
class CartridgeDPCPlusWidget : public CartDebugWidget
{
public:
CartridgeDPCPlusWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h,
CartridgeDPCPlus& cart);
virtual ~CartridgeDPCPlusWidget() { }
void saveOldState();
void loadConfig();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
private:
struct CartState {
ByteArray tops;
ByteArray bottoms;
IntArray counters;
IntArray fraccounters;
ByteArray fracinc;
ByteArray param;
IntArray mcounters;
IntArray mfreqs;
IntArray mwaves;
uInt32 random;
};
private:
CartridgeDPCPlus& myCart;
PopUpWidget* myBank;
DataGridWidget* myTops;
DataGridWidget* myBottoms;
DataGridWidget* myCounters;
DataGridWidget* myFracCounters;
DataGridWidget* myFracIncrements;
DataGridWidget* myParameter;
DataGridWidget* myMusicCounters;
DataGridWidget* myMusicFrequencies;
DataGridWidget* myMusicWaveforms;
CheckboxWidget* myFastFetch;
CheckboxWidget* myIMLDA;
DataGridWidget* myRandom;
CartState myState, myOldState;
enum { kBankChanged = 'bkCH' };
};
#endif

View File

@ -60,7 +60,7 @@ CartridgeDPCWidget::CartridgeDPCWidget(
font.getStringWidth("Set bank: "), kBankChanged); font.getStringWidth("Set bank: "), kBankChanged);
myBank->setTarget(this); myBank->setTarget(this);
addFocusWidget(myBank); addFocusWidget(myBank);
ypos += myLineHeight + 12; ypos += myLineHeight + 8;
// Data fetchers // Data fetchers
int lwidth = font.getStringWidth("Data Fetchers: "); int lwidth = font.getStringWidth("Data Fetchers: ");
@ -69,7 +69,7 @@ CartridgeDPCWidget::CartridgeDPCWidget(
// Top registers // Top registers
lwidth = font.getStringWidth("Counter Registers: "); lwidth = font.getStringWidth("Counter Registers: ");
xpos = 18; ypos += myLineHeight + 8; xpos = 18; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth, new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Top Registers: ", kTextAlignLeft); myFontHeight, "Top Registers: ", kTextAlignLeft);
xpos += lwidth; xpos += lwidth;
@ -79,7 +79,7 @@ CartridgeDPCWidget::CartridgeDPCWidget(
myTops->setEditable(false); myTops->setEditable(false);
// Bottom registers // Bottom registers
xpos = 18; ypos += myLineHeight + 8; xpos = 18; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth, new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Bottom Registers: ", kTextAlignLeft); myFontHeight, "Bottom Registers: ", kTextAlignLeft);
xpos += lwidth; xpos += lwidth;
@ -89,7 +89,7 @@ CartridgeDPCWidget::CartridgeDPCWidget(
myBottoms->setEditable(false); myBottoms->setEditable(false);
// Counter registers // Counter registers
xpos = 18; ypos += myLineHeight + 8; xpos = 18; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth, new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Counter Registers: ", kTextAlignLeft); myFontHeight, "Counter Registers: ", kTextAlignLeft);
xpos += lwidth; xpos += lwidth;
@ -99,9 +99,9 @@ CartridgeDPCWidget::CartridgeDPCWidget(
myCounters->setEditable(false); myCounters->setEditable(false);
// Flag registers // Flag registers
xpos = 18; ypos += myLineHeight + 8; xpos = 18; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth, new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Bottom Registers: ", kTextAlignLeft); myFontHeight, "Flag Registers: ", kTextAlignLeft);
xpos += lwidth; xpos += lwidth;
myFlags = new DataGridWidget(boss, font, xpos, ypos-2, 8, 1, 2, 8, kBASE_16); myFlags = new DataGridWidget(boss, font, xpos, ypos-2, 8, 1, 2, 8, kBASE_16);
@ -120,7 +120,7 @@ CartridgeDPCWidget::CartridgeDPCWidget(
myMusicMode->setEditable(false); myMusicMode->setEditable(false);
// Current random number // Current random number
xpos = 10; ypos += myLineHeight + 8; xpos = 10; ypos += myLineHeight + 4;
new StaticTextWidget(boss, font, xpos, ypos, lwidth, new StaticTextWidget(boss, font, xpos, ypos, lwidth,
myFontHeight, "Current random number: ", kTextAlignLeft); myFontHeight, "Current random number: ", kTextAlignLeft);
xpos += lwidth; xpos += lwidth;

View File

@ -96,7 +96,7 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& font,
t->setTarget(this); t->setTarget(this);
t->setID(i); t->setID(i);
t->drawBox(false); t->drawBox(false);
t->setFill(true); t->setFill(CheckboxWidget::O);
t->setTextColor(kTextColorEm); t->setTextColor(kTextColorEm);
ypos += _fontHeight; ypos += _fontHeight;

View File

@ -27,6 +27,7 @@ MODULE_OBJS := \
src/debugger/gui/Cart4KWidget.o \ src/debugger/gui/Cart4KWidget.o \
src/debugger/gui/CartCVWidget.o \ src/debugger/gui/CartCVWidget.o \
src/debugger/gui/CartDPCWidget.o \ src/debugger/gui/CartDPCWidget.o \
src/debugger/gui/CartDPCPlusWidget.o \
src/debugger/gui/CartE0Widget.o \ src/debugger/gui/CartE0Widget.o \
src/debugger/gui/CartE7Widget.o \ src/debugger/gui/CartE7Widget.o \
src/debugger/gui/CartEFWidget.o \ src/debugger/gui/CartEFWidget.o \

View File

@ -103,7 +103,7 @@ void CartridgeDPCPlus::setInitialState()
memcpy(myDisplayImage, myProgramImage + 0x6000, 0x1400); memcpy(myDisplayImage, myProgramImage + 0x6000, 0x1400);
// Initialize the DPC data fetcher registers // Initialize the DPC data fetcher registers
for(uInt16 i = 0; i < 8; ++i) for(int i = 0; i < 8; ++i)
myTops[i] = myBottoms[i] = myCounters[i] = myFractionalIncrements[i] = myTops[i] = myBottoms[i] = myCounters[i] = myFractionalIncrements[i] =
myFractionalCounters[i] = 0; myFractionalCounters[i] = 0;

View File

@ -24,20 +24,29 @@ class System;
#ifdef THUMB_SUPPORT #ifdef THUMB_SUPPORT
class Thumbulator; class Thumbulator;
#endif #endif
#ifdef DEBUGGER_SUPPORT
#include "CartDPCPlusWidget.hxx"
#endif
#include "bspf.hxx" #include "bspf.hxx"
#include "Cart.hxx" #include "Cart.hxx"
/** /**
Cartridge class used for DPC+. There are six 4K program banks, a 4K Cartridge class used for DPC+, derived from Pitfall II. There are six 4K
display bank, 1K frequency table and the DPC chip. For complete details on program banks, a 4K display bank, 1K frequency table and the DPC chip.
the DPC chip see David P. Crane's United States Patent Number 4,644,495. DPC chip access is mapped to $1000 - $1080 ($1000 - $103F is read port,
$1040 - $107F is write port).
@author Darrell Spice Jr, Fred Quimby, Stephen Anthony For complete details on the DPC chip see David P. Crane's United States
Patent Number 4,644,495.
@author Darrell Spice Jr, Fred Quimby, Stephen Anthony, Bradford W. Mott
@version $Id$ @version $Id$
*/ */
class CartridgeDPCPlus : public Cartridge class CartridgeDPCPlus : public Cartridge
{ {
friend class CartridgeDPCPlusWidget;
public: public:
/** /**
Create a new cartridge using the specified image Create a new cartridge using the specified image
@ -131,6 +140,18 @@ class CartridgeDPCPlus : public Cartridge
*/ */
string name() const { return "CartridgeDPC+"; } string name() const { return "CartridgeDPC+"; }
#ifdef DEBUGGER_SUPPORT
/**
Get debugger widget responsible for accessing the inner workings
of the cart.
*/
CartDebugWidget* debugWidget(GuiObject* boss,
const GUI::Font& font, int x, int y, int w, int h)
{
return new CartridgeDPCPlusWidget(boss, font, x, y, w, h, *this);
}
#endif
public: public:
/** /**
Get the byte at the specified address. Get the byte at the specified address.

View File

@ -213,7 +213,7 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd,
break; break;
case kGoUpCmd: case kGoUpCmd:
case kListPrevDirCmd: case ListWidget::kPrevDirCmd:
_node = _node.getParent(); _node = _node.getParent();
updateListing(); updateListing();
break; break;
@ -223,8 +223,8 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd,
updateListing(); updateListing();
break; break;
case kListItemActivatedCmd: case ListWidget::kActivatedCmd:
case kListItemDoubleClickedCmd: case ListWidget::kDoubleClickedCmd:
{ {
int item = _fileList->getSelected(); int item = _fileList->getSelected();
if(item >= 0) if(item >= 0)

View File

@ -58,16 +58,16 @@ void CheckListWidget::setStyle(CheckStyle style)
{ {
for(unsigned int i = 0; i < _checkList.size(); ++i) for(unsigned int i = 0; i < _checkList.size(); ++i)
{ {
if(style == kXFill) if(style == XFill)
{ {
_checkList[i]->drawBox(true); _checkList[i]->drawBox(true);
_checkList[i]->setFill(false); _checkList[i]->setFill(CheckboxWidget::X);
_checkList[i]->setTextColor(kTextColor); _checkList[i]->setTextColor(kTextColor);
} }
else if(style == kSolidFill) else if(style == SolidFill)
{ {
_checkList[i]->drawBox(false); _checkList[i]->drawBox(false);
_checkList[i]->setFill(true); _checkList[i]->setFill(CheckboxWidget::Full);
_checkList[i]->setTextColor(kTextColorEm); _checkList[i]->setTextColor(kTextColorEm);
} }
} }

View File

@ -27,22 +27,22 @@ class CheckboxWidget;
#include "ListWidget.hxx" #include "ListWidget.hxx"
// Some special commands
enum {
kListItemChecked = 'LIct' // checkbox toggled on current line
};
enum CheckStyle {
kXFill,
kSolidFill
};
typedef Common::Array<CheckboxWidget*> CheckboxArray; typedef Common::Array<CheckboxWidget*> CheckboxArray;
/** CheckListWidget */ /** CheckListWidget */
class CheckListWidget : public ListWidget class CheckListWidget : public ListWidget
{ {
public:
enum {
kListItemChecked = 'LIct' // checkbox toggled on current line
};
enum CheckStyle {
XFill,
SolidFill
};
public: public:
CheckListWidget(GuiObject* boss, const GUI::Font& font, CheckListWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h); int x, int y, int w, int h);

View File

@ -351,7 +351,7 @@ void EventMappingWidget::handleCommand(CommandSender* sender, int cmd,
{ {
switch(cmd) switch(cmd)
{ {
case kListSelectionChangedCmd: case ListWidget::kSelectionChangedCmd:
if(myActionsList->getSelected() >= 0) if(myActionsList->getSelected() >= 0)
{ {
myActionSelected = myActionsList->getSelected(); myActionSelected = myActionsList->getSelected();
@ -361,7 +361,7 @@ void EventMappingWidget::handleCommand(CommandSender* sender, int cmd,
break; break;
/* /*
case kListItemDoubleClickedCmd: case ListWidget::kDoubleClickedCmd:
if(myActionsList->getSelected() >= 0) if(myActionsList->getSelected() >= 0)
{ {
myActionSelected = myActionsList->getSelected(); myActionSelected = myActionsList->getSelected();

View File

@ -508,8 +508,8 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
switch (cmd) switch (cmd)
{ {
case kStartCmd: case kStartCmd:
case kListItemActivatedCmd: case ListWidget::kActivatedCmd:
case kListItemDoubleClickedCmd: case ListWidget::kDoubleClickedCmd:
{ {
int item = myList->getSelected(); int item = myList->getSelected();
if(item >= 0) if(item >= 0)
@ -566,12 +566,12 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
break; break;
case kPrevDirCmd: case kPrevDirCmd:
case kListPrevDirCmd: case ListWidget::kPrevDirCmd:
myCurrentNode = myCurrentNode.getParent(); myCurrentNode = myCurrentNode.getParent();
updateListing(myNodeNames.empty() ? "" : myNodeNames.pop()); updateListing(myNodeNames.empty() ? "" : myNodeNames.pop());
break; break;
case kListSelectionChangedCmd: case ListWidget::kSelectionChangedCmd:
loadRomInfo(); loadRomInfo();
break; break;

View File

@ -81,7 +81,7 @@ void ListWidget::setSelected(int item)
abortEditMode(); abortEditMode();
_selectedItem = item; _selectedItem = item;
sendCommand(kListSelectionChangedCmd, _selectedItem, _id); sendCommand(ListWidget::kSelectionChangedCmd, _selectedItem, _id);
_currentPos = _selectedItem - _rows / 2; _currentPos = _selectedItem - _rows / 2;
scrollToSelected(); scrollToSelected();
@ -154,7 +154,7 @@ void ListWidget::scrollBarRecalc()
{ {
_scrollBar->_currentPos = _currentPos; _scrollBar->_currentPos = _currentPos;
_scrollBar->recalc(); _scrollBar->recalc();
sendCommand(kListScrolledCmd, _currentPos, _id); sendCommand(ListWidget::kScrolledCmd, _currentPos, _id);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -174,7 +174,7 @@ void ListWidget::handleMouseDown(int x, int y, int button, int clickCount)
if (_editMode) if (_editMode)
abortEditMode(); abortEditMode();
_selectedItem = newSelectedItem; _selectedItem = newSelectedItem;
sendCommand(kListSelectionChangedCmd, _selectedItem, _id); sendCommand(ListWidget::kSelectionChangedCmd, _selectedItem, _id);
setDirty(); draw(); setDirty(); draw();
} }
@ -189,7 +189,7 @@ void ListWidget::handleMouseUp(int x, int y, int button, int clickCount)
// send the double click command // send the double click command
if (clickCount == 2 && (_selectedItem == findItem(x, y))) if (clickCount == 2 && (_selectedItem == findItem(x, y)))
{ {
sendCommand(kListItemDoubleClickedCmd, _selectedItem, _id); sendCommand(ListWidget::kDoubleClickedCmd, _selectedItem, _id);
// Start edit mode // Start edit mode
if(_editable && !_editMode) if(_editable && !_editMode)
@ -279,7 +279,7 @@ bool ListWidget::handleKeyDown(StellaKey key, StellaMod mod, char ascii)
_scrollBar->draw(); _scrollBar->draw();
scrollToSelected(); scrollToSelected();
sendCommand(kListSelectionChangedCmd, _selectedItem, _id); sendCommand(ListWidget::kSelectionChangedCmd, _selectedItem, _id);
} }
_currentKeyDown = key; _currentKeyDown = key;
@ -311,7 +311,7 @@ bool ListWidget::handleEvent(Event::Type e)
if (_editable) if (_editable)
startEditMode(); startEditMode();
else else
sendCommand(kListItemActivatedCmd, _selectedItem, _id); sendCommand(ListWidget::kActivatedCmd, _selectedItem, _id);
} }
break; break;
@ -346,7 +346,7 @@ bool ListWidget::handleEvent(Event::Type e)
break; break;
case Event::UIPrevDir: case Event::UIPrevDir:
sendCommand(kListPrevDirCmd, _selectedItem, _id); sendCommand(ListWidget::kPrevDirCmd, _selectedItem, _id);
break; break;
default: default:
@ -358,7 +358,7 @@ bool ListWidget::handleEvent(Event::Type e)
_scrollBar->draw(); _scrollBar->draw();
scrollToSelected(); scrollToSelected();
sendCommand(kListSelectionChangedCmd, _selectedItem, _id); sendCommand(ListWidget::kSelectionChangedCmd, _selectedItem, _id);
} }
return handled; return handled;
@ -385,7 +385,7 @@ void ListWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
setDirty(); draw(); setDirty(); draw();
// Let boss know the list has scrolled // Let boss know the list has scrolled
sendCommand(kListScrolledCmd, _currentPos, _id); sendCommand(ListWidget::kScrolledCmd, _currentPos, _id);
} }
break; break;
} }
@ -418,7 +418,7 @@ void ListWidget::scrollToCurrent(int item)
setDirty(); draw(); setDirty(); draw();
if(oldScrollPos != _currentPos) if(oldScrollPos != _currentPos)
sendCommand(kListScrolledCmd, _currentPos, _id); sendCommand(ListWidget::kScrolledCmd, _currentPos, _id);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -443,7 +443,7 @@ void ListWidget::endEditMode()
// Send a message that editing finished with a return/enter key press // Send a message that editing finished with a return/enter key press
_editMode = false; _editMode = false;
_list[_selectedItem] = _editString; _list[_selectedItem] = _editString;
sendCommand(kListItemDataChangedCmd, _selectedItem, _id); sendCommand(ListWidget::kDataChangedCmd, _selectedItem, _id);
// Reset to normal data entry // Reset to normal data entry
EditableWidget::endEditMode(); EditableWidget::endEditMode();

View File

@ -32,21 +32,20 @@ class StringList;
#include "ScrollBarWidget.hxx" #include "ScrollBarWidget.hxx"
#include "Rect.hxx" #include "Rect.hxx"
// Some special commands
enum {
kListItemDoubleClickedCmd = 'LIdb', // double click on item - 'data' will be item index
kListItemActivatedCmd = 'LIac', // item activated by return/enter - 'data' will be item index
kListItemDataChangedCmd = 'LIch', // item data changed - 'data' will be item index
kListItemRClickedCmd = 'LIrc', // right click on item - 'data' will be item index
kListSelectionChangedCmd = 'Lsch', // selection changed - 'data' will be item index
kListScrolledCmd = 'Lscl', // list scrolled - 'data' will be current position
kListPrevDirCmd = 'Lpdr' // request to go to parent list, if applicable
};
/** ListWidget */ /** ListWidget */
class ListWidget : public EditableWidget class ListWidget : public EditableWidget
{ {
public:
enum {
kDoubleClickedCmd = 'LIdb', // double click on item - 'data' will be item index
kActivatedCmd = 'LIac', // item activated by return/enter - 'data' will be item index
kDataChangedCmd = 'LIch', // item data changed - 'data' will be item index
kRClickedCmd = 'LIrc', // right click on item - 'data' will be item index
kSelectionChangedCmd = 'Lsch', // selection changed - 'data' will be item index
kScrolledCmd = 'Lscl', // list scrolled - 'data' will be current position
kPrevDirCmd = 'Lpdr' // request to go to parent list, if applicable
};
public: public:
ListWidget(GuiObject* boss, const GUI::Font& font, ListWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h, bool quickSelect = true); int x, int y, int w, int h, bool quickSelect = true);

View File

@ -424,6 +424,18 @@ static unsigned int checked_img_o[8] =
0x00011000, 0x00011000,
}; };
static unsigned int checked_img_full[8] =
{
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
0x11111111,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CheckboxWidget::CheckboxWidget(GuiObject *boss, const GUI::Font& font, CheckboxWidget::CheckboxWidget(GuiObject *boss, const GUI::Font& font,
int x, int y, const string& label, int x, int y, const string& label,
@ -431,7 +443,6 @@ CheckboxWidget::CheckboxWidget(GuiObject *boss, const GUI::Font& font,
: ButtonWidget(boss, font, x, y, 16, 16, label, cmd), : ButtonWidget(boss, font, x, y, 16, 16, label, cmd),
_state(false), _state(false),
_holdFocus(true), _holdFocus(true),
_fillRect(false),
_drawBox(true), _drawBox(true),
_fillColor(kColor), _fillColor(kColor),
_boxY(0), _boxY(0),
@ -456,6 +467,8 @@ CheckboxWidget::CheckboxWidget(GuiObject *boss, const GUI::Font& font,
_boxY = (_h - 14) / 2; _boxY = (_h - 14) / 2;
else // center text else // center text
_textY = (14 - _font.getFontHeight()) / 2; _textY = (14 - _font.getFontHeight()) / 2;
setFill(CheckboxWidget::X);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -474,6 +487,25 @@ void CheckboxWidget::handleMouseUp(int x, int y, int button, int clickCount)
void CheckboxWidget::setEditable(bool editable) void CheckboxWidget::setEditable(bool editable)
{ {
_editable = editable; _editable = editable;
if(!_editable)
setFill(CheckboxWidget::Full);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CheckboxWidget::setFill(FillType type)
{
switch(type)
{
case CheckboxWidget::X:
_img = checked_img_x;
break;
case CheckboxWidget::O:
_img = checked_img_o;
break;
case CheckboxWidget::Full:
_img = checked_img_full;
break;
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -500,11 +532,7 @@ void CheckboxWidget::drawWidget(bool hilite)
if(isEnabled()) if(isEnabled())
{ {
if(_state) if(_state)
{ s.drawBitmap(_img, _x + 3, _y + _boxY + 3, kCheckColor);
uInt32* img = _fillRect ? checked_img_o : checked_img_x;
uInt32 color = _fillRect ? kWidFrameColor : kCheckColor;
s.drawBitmap(img, _x + 3, _y + _boxY + 3, color);
}
} }
else else
s.fillRect(_x + 2, _y + _boxY + 2, 10, 10, kColor); s.fillRect(_x + 2, _y + _boxY + 2, 10, 10, kColor);

View File

@ -242,6 +242,11 @@ class ButtonWidget : public StaticTextWidget, public CommandSender
/* CheckboxWidget */ /* CheckboxWidget */
class CheckboxWidget : public ButtonWidget class CheckboxWidget : public ButtonWidget
{ {
public:
enum FillType {
X, O, Full
};
public: public:
CheckboxWidget(GuiObject* boss, const GUI::Font& font, int x, int y, CheckboxWidget(GuiObject* boss, const GUI::Font& font, int x, int y,
const string& label, int cmd = 0); const string& label, int cmd = 0);
@ -251,7 +256,7 @@ class CheckboxWidget : public ButtonWidget
virtual void handleMouseLeft(int button) {} virtual void handleMouseLeft(int button) {}
void setEditable(bool editable); void setEditable(bool editable);
void setFill(bool fill) { _fillRect = fill; } void setFill(FillType type);
void drawBox(bool draw) { _drawBox = draw; } void drawBox(bool draw) { _drawBox = draw; }
void setState(bool state); void setState(bool state);
@ -266,9 +271,9 @@ class CheckboxWidget : public ButtonWidget
protected: protected:
bool _state; bool _state;
bool _holdFocus; bool _holdFocus;
bool _fillRect;
bool _drawBox; bool _drawBox;
uInt32* _img;
uInt32 _fillColor; uInt32 _fillColor;
private: private: