First pass at Cheat Code dialog. It's nowhere near finished, but it does

work: clicking "Load" loads the code "db000f" (no walls, in Pitfall).
Once loaded, you can enable and disable it with the checkbox.

I was going to add text entry and list widgets tonight, but I'm starving
and out of food, and should probably go eat... so tonight's nightly build
is going to be kind of a tease :)


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@712 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
urchlay 2005-08-05 02:28:22 +00:00
parent 9f58ffb471
commit 332ba0cfe1
13 changed files with 297 additions and 46 deletions

View File

@ -60,8 +60,7 @@ What the debugger can do:
breakpoints, traps, etc).
- Built-in functions for use with "breakif", to support common conditions
(such as breaking when the user presses Game Select...)
- Save patched ROM ("saverom filename.bin"). This currently works for every
cart type except DPC (Pitfall II).
- Save patched ROM ("saverom filename.bin").
Planned features for Stella 2.0 release:
- Graphical TIA tab, with register names and GUI buttons for

View File

@ -0,0 +1,38 @@
#include "Cheat.hxx"
#include "CheetahCheat.hxx"
uInt16 Cheat::unhex(string hex) {
int ret = 0;
for(unsigned int i=0; i<hex.size(); i++) {
char c = hex[i];
ret *= 16;
if(c >= '0' && c <= '9')
ret += c - '0';
else if(c >= 'A' && c <= 'F')
ret += c - 'A' + 10;
else
ret += c - 'a' + 10;
}
return ret;
}
Cheat* Cheat::parse(string code) {
for(unsigned int i=0; i<code.size(); i++)
if(!isxdigit(code[i]))
return 0;
switch(code.size()) {
case 6:
return new CheetahCheat(code);
default:
return 0;
}
}
Cheat::~Cheat() {
}

View File

@ -0,0 +1,22 @@
#ifndef CHEAT_HXX
#define CHEAT_HXX
#include "bspf.hxx"
class Cheat {
public:
static Cheat *parse(string code);
static uInt16 unhex(string hex);
virtual ~Cheat();
virtual bool enabled() = 0;
virtual bool enable() = 0;
virtual bool disable() = 0;
protected:
// Cheat(string code);
};
#endif

View File

@ -0,0 +1,33 @@
#include "Debugger.hxx"
#include "CheetahCheat.hxx"
CheetahCheat::CheetahCheat(string code) {
_enabled = false;
address = 0xf000 + unhex(code.substr(0, 3));
value = unhex(code.substr(3, 2));
count = unhex(code.substr(5, 1)) + 1;
}
CheetahCheat::~CheetahCheat() {
}
bool CheetahCheat::enabled() { return _enabled; }
bool CheetahCheat::enable() {
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() {
for(int i=0; i<count; i++) {
Debugger::debugger().patchROM(address + i, savedRom[i]);
}
return _enabled = false;
}

View File

@ -0,0 +1,25 @@
#ifndef CHEETAH_CHEAT_HXX
#define CHEETAH_CHEAT_HXX
#include "Cheat.hxx"
class CheetahCheat : public Cheat {
public:
CheetahCheat(string code);
~CheetahCheat();
virtual bool enabled();
virtual bool enable();
virtual bool disable();
private:
bool _enabled;
uInt8 savedRom[16];
uInt16 address;
uInt8 value;
uInt8 count;
};
#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: Debugger.hxx,v 1.65 2005-08-04 22:59:38 stephena Exp $
// $Id: Debugger.hxx,v 1.66 2005-08-05 02:28:21 urchlay Exp $
//============================================================================
#ifndef DEBUGGER_HXX
@ -82,7 +82,7 @@ typedef uInt16 (Debugger::*DEBUGGER_WORD_METHOD)();
for all debugging operations in Stella (parser, 6502 debugger, etc).
@author Stephen Anthony
@version $Id: Debugger.hxx,v 1.65 2005-08-04 22:59:38 stephena Exp $
@version $Id: Debugger.hxx,v 1.66 2005-08-05 02:28:21 urchlay Exp $
*/
class Debugger : public DialogContainer
{
@ -265,6 +265,9 @@ class Debugger : public DialogContainer
bool saveROM(string filename);
bool setBank(int bank);
bool patchROM(int addr, int value);
private:
/**
Save state of each debugger subsystem
@ -330,9 +333,7 @@ class Debugger : public DialogContainer
PromptWidget *prompt() { return myPrompt; }
void addLabel(string label, int address);
bool setBank(int bank);
const char *getCartType();
bool patchROM(int addr, int value);
void saveState(int state);
void loadState(int state);

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: DebuggerParser.cxx,v 1.74 2005-07-30 22:08:24 urchlay Exp $
// $Id: DebuggerParser.cxx,v 1.75 2005-08-05 02:28:21 urchlay Exp $
//============================================================================
#include "bspf.hxx"
@ -25,6 +25,8 @@
#include "YaccParser.hxx"
#include "M6502.hxx"
#include "Expression.hxx"
#include "CheetahCheat.hxx"
#include "Cheat.hxx"
#include "DebuggerParser.hxx"
@ -1304,42 +1306,13 @@ void DebuggerParser::executeCheetah() {
for(int arg = 0; arg < argCount; arg++) {
string& cheat = argStrings[arg];
if(cheat.size() != 6) {
commandResult += red(cheat + ": Invalid Cheetah code (must be 6 hex digits)");
return;
Cheat *c = Cheat::parse(cheat);
if(c) {
c->enable();
commandResult = "Cheetah code " + cheat + " enabled\n";
} else {
commandResult = red("Invalid cheetah code " + cheat + "\n");
}
for(int i=0; i<6; i++) {
if(conv_hex_digit(cheat[i]) < 0) {
commandResult += red(cheat + ": Invalid hex digit in Cheetah code");
return;
}
}
int addr = 0;
for(int i=0; i<3; i++) {
addr = addr * 16 + conv_hex_digit(cheat[i]);
}
addr += 0xf000;
int value = 0;
for(int i=3; i<5; i++) {
value = value * 16 + conv_hex_digit(cheat[i]);
}
int count = conv_hex_digit(cheat[5]) + 1;
for(int i=0; i<count; i++)
debugger->patchROM(addr + i, value);
commandResult += cheat;
commandResult += ": ";
commandResult += debugger->valueToString(count);
commandResult += " address";
if(count != 1) commandResult += "es";
commandResult += " modified.";
if(arg != argCount - 1) commandResult += "\n";
}
}

View File

@ -1,6 +1,8 @@
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 \

View File

@ -0,0 +1,87 @@
//============================================================================
//
// 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: CheatCodeDialog.cxx,v 1.1 2005-08-05 02:28:22 urchlay Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include "OSystem.hxx"
#include "Props.hxx"
#include "Widget.hxx"
#include "Dialog.hxx"
#include "CheatCodeDialog.hxx"
#include "GuiUtils.hxx"
#include "bspf.hxx"
enum {
kEnableCheat = 'ENAC',
kLoadCmd = 'LDCH',
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CheatCodeDialog::CheatCodeDialog(OSystem* osystem, DialogContainer* parent,
int x, int y, int w, int h)
: Dialog(osystem, parent, x, y, w, h)
{
myTitle = new StaticTextWidget(this, 10, 5, w - 20, kFontHeight, "Cheat Codes", kTextAlignCenter);
addButton(w - (kButtonWidth + 10), h - 24, "Close", kCloseCmd, 'C');
addButton(w - (kButtonWidth + 10), h - 48, "Load", kLoadCmd, 'C');
myEnableCheat = new CheckboxWidget(this, 10, 20, kButtonWidth+10, kLineHeight,
"Enabled", kEnableCheat);
myEnableCheat->setState(false);
myCheat = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CheatCodeDialog::~CheatCodeDialog()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CheatCodeDialog::handleCommand(CommandSender* sender, int cmd,
int data, int id)
{
switch(cmd)
{
case kLoadCmd:
myCheat = Cheat::parse("db000f");
loadConfig();
break;
case kEnableCheat:
if(!myCheat)
myEnableCheat->setState(false);
else if(myCheat->enabled())
myCheat->disable();
else
myCheat->enable();
break;
default:
Dialog::handleCommand(sender, cmd, data, 0);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CheatCodeDialog::loadConfig() {
cerr << "CheatCodeDialog::loadConfig()" << endl;
myEnableCheat->setState(myCheat && myCheat->enabled());
myEnableCheat->setEnabled(myCheat != 0);
}

View File

@ -0,0 +1,56 @@
//============================================================================
//
// 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: CheatCodeDialog.hxx,v 1.1 2005-08-05 02:28:22 urchlay Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef CHEAT_CODE_DIALOG_HXX
#define CHEAT_CODE_DIALOG_HXX
class DialogContainer;
class CommandSender;
class ButtonWidget;
class StaticTextWidget;
#include "OSystem.hxx"
#include "Dialog.hxx"
#include "Widget.hxx"
#include "Cheat.hxx"
#include "Props.hxx"
#include "bspf.hxx"
class CheatCodeDialog : public Dialog
{
public:
CheatCodeDialog(OSystem* osystem, DialogContainer* parent,
int x, int y, int w, int h);
~CheatCodeDialog();
protected:
ButtonWidget *myExitButton;
StaticTextWidget *myTitle;
CheckboxWidget *myEnableCheat;
private:
virtual void handleCommand(CommandSender* sender, int cmd, int data, int id);
void loadConfig();
Cheat *myCheat;
};
#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: OptionsDialog.cxx,v 1.21 2005-07-05 15:25:44 stephena Exp $
// $Id: OptionsDialog.cxx,v 1.22 2005-08-05 02:28:22 urchlay Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -41,14 +41,15 @@ enum {
kInfoCmd = 'INFO',
kHelpCmd = 'HELP',
kAboutCmd = 'ABOU',
kExitCmd = 'EXIM'
kExitCmd = 'EXIM',
kCheatCmd = 'CHET'
};
enum {
kRowHeight = 22,
kBigButtonWidth = 90,
kMainMenuWidth = (kBigButtonWidth + 2 * 8),
kMainMenuHeight = 7 * kRowHeight + 10,
kMainMenuHeight = 8 * kRowHeight + 10,
};
#define addBigButton(label, cmd, hotkey) \
@ -64,6 +65,7 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent)
myAudioDialog(NULL),
myEventMappingDialog(NULL),
myGameInfoDialog(NULL),
myCheatCodeDialog(NULL),
myHelpDialog(NULL),
myAboutDialog(NULL)
{
@ -79,6 +81,7 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent)
#endif
addBigButton("Event Mapping", kEMapCmd, 0);
addBigButton("Game Information", kInfoCmd, 0);
addBigButton("Cheat Code", kCheatCmd, 0);
addBigButton("Help", kHelpCmd, 0);
addBigButton("About", kAboutCmd, 0);
addBigButton("Exit Menu", kExitCmd, 0);
@ -105,6 +108,10 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent)
checkBounds(fbWidth, fbHeight, &x, &y, &w, &h);
myGameInfoDialog = new GameInfoDialog(myOSystem, parent, x, y, w, h);
w = 255; h = 150;
checkBounds(fbWidth, fbHeight, &x, &y, &w, &h);
myCheatCodeDialog = new CheatCodeDialog(myOSystem, parent, x, y, w, h);
w = 255; h = 150;
checkBounds(fbWidth, fbHeight, &x, &y, &w, &h);
myHelpDialog = new HelpDialog(myOSystem, parent, x, y, w, h);
@ -121,6 +128,7 @@ OptionsDialog::~OptionsDialog()
delete myAudioDialog;
delete myEventMappingDialog;
delete myGameInfoDialog;
delete myCheatCodeDialog;
delete myHelpDialog;
delete myAboutDialog;
}
@ -168,6 +176,10 @@ void OptionsDialog::handleCommand(CommandSender* sender, int cmd,
parent()->addDialog(myGameInfoDialog);
break;
case kCheatCmd:
parent()->addDialog(myCheatCodeDialog);
break;
case kHelpCmd:
parent()->addDialog(myHelpDialog);
break;

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: OptionsDialog.hxx,v 1.11 2005-07-05 15:25:44 stephena Exp $
// $Id: OptionsDialog.hxx,v 1.12 2005-08-05 02:28:22 urchlay Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -34,6 +34,7 @@ class AboutDialog;
#include "OSystem.hxx"
#include "Dialog.hxx"
#include "GameInfoDialog.hxx"
#include "CheatCodeDialog.hxx"
#include "bspf.hxx"
class OptionsDialog : public Dialog
@ -52,6 +53,7 @@ class OptionsDialog : public Dialog
AudioDialog* myAudioDialog;
EventMappingDialog* myEventMappingDialog;
GameInfoDialog* myGameInfoDialog;
CheatCodeDialog* myCheatCodeDialog;
HelpDialog* myHelpDialog;
AboutDialog* myAboutDialog;

View File

@ -6,6 +6,7 @@ MODULE_OBJS := \
src/gui/AudioDialog.o \
src/gui/BrowserDialog.o \
src/gui/ColorWidget.o \
src/gui/CheatCodeDialog.o \
src/gui/DataGridWidget.o \
src/gui/DebuggerDialog.o \
src/gui/DialogContainer.o \