diff --git a/src/cheat.cpp b/src/cheat.cpp index e2b2ad9b..471bd80d 100644 --- a/src/cheat.cpp +++ b/src/cheat.cpp @@ -912,21 +912,21 @@ inline void FCEUI_SetCheatMapByte(uint16 address, bool cheat) cheat ? cheatMap[address / 8] |= (1 << address % 8) : cheatMap[address / 8] ^= (1 << address % 8); } -inline void FCEUI_CreateCheatMap() +void FCEUI_CreateCheatMap(void) { if (!cheatMap) cheatMap = (unsigned char*)malloc(CHEATMAP_SIZE); FCEUI_RefreshCheatMap(); } -inline void FCEUI_RefreshCheatMap() +void FCEUI_RefreshCheatMap(void) { memset(cheatMap, 0, CHEATMAP_SIZE); for (uint32 i = 0; i < numsubcheats; ++i) FCEUI_SetCheatMapByte(SubCheats[i].addr, true); } -inline void FCEUI_ReleaseCheatMap() +void FCEUI_ReleaseCheatMap(void) { if (cheatMap) { diff --git a/src/cheat.h b/src/cheat.h index 9f3dbe2b..dd9ca0ce 100644 --- a/src/cheat.h +++ b/src/cheat.h @@ -18,9 +18,10 @@ typedef unsigned char _8BYTECHEATMAP; extern int FCEUI_FindCheatMapByte(uint16 address); extern void FCEUI_SetCheatMapByte(uint16 address, bool cheat); -extern void FCEUI_CreateCheatMap(); -extern void FCEUI_RefreshCheatMap(); -extern void FCEUI_ReleaseCheatMap(); +extern void FCEUI_CreateCheatMap(void); +extern void FCEUI_RefreshCheatMap(void); +extern void FCEUI_ReleaseCheatMap(void); +extern unsigned int FrozenAddressCount; int FCEU_CheatGetByte(uint32 A); void FCEU_CheatSetByte(uint32 A, uint8 V); diff --git a/src/drivers/Qt/HexEditor.cpp b/src/drivers/Qt/HexEditor.cpp index 2f7be30f..d547bbd3 100644 --- a/src/drivers/Qt/HexEditor.cpp +++ b/src/drivers/Qt/HexEditor.cpp @@ -36,6 +36,7 @@ #include "Qt/keyscan.h" #include "Qt/fceuWrapper.h" #include "Qt/HexEditor.h" +#include "Qt/CheatsConf.h" #include "Qt/SymbolicDebug.h" #include "Qt/ConsoleDebugger.h" #include "Qt/ConsoleUtilities.h" @@ -734,6 +735,8 @@ HexEditorDialog_t::HexEditorDialog_t(QWidget *parent) populateBookmarkMenu(); + FCEUI_CreateCheatMap(); + } //---------------------------------------------------------------------------- HexEditorDialog_t::~HexEditorDialog_t(void) @@ -1216,6 +1219,11 @@ QHexEdit::QHexEdit(QWidget *parent) total_instructions_lp = 0; pxLineXScroll = 0; + frzRamAddr = -1; + frzRamVal = 0; + frzRamMode = 0; + frzIdx = 0; + highLightColor[ 0].setRgb( 0x00, 0x00, 0x00 ); highLightColor[ 1].setRgb( 0x35, 0x40, 0x00 ); highLightColor[ 2].setRgb( 0x18, 0x52, 0x18 ); @@ -1535,7 +1543,7 @@ int QHexEdit::convPixToAddr( QPoint p ) //---------------------------------------------------------------------------- void QHexEdit::keyPressEvent(QKeyEvent *event) { - printf("Hex Window Key Press: 0x%x \n", event->key() ); + //printf("Hex Window Key Press: 0x%x \n", event->key() ); if (event->matches(QKeySequence::MoveToNextChar)) { @@ -1666,10 +1674,15 @@ void QHexEdit::keyPressEvent(QKeyEvent *event) } else if (Qt::ControlModifier == event->modifiers()) { - if ( event->key() == Qt::Key_A ) - { - openGotoAddrDialog(); - } + if ( event->key() == Qt::Key_A ) + { + openGotoAddrDialog(); + } + else if ( event->key() == Qt::Key_F ) + { + frzRamAddr = ctxAddr = cursorAddr; + frzRamToggle(); + } } else if (event->key() == Qt::Key_Tab && (cursorPosX < 32) ) { // switch from hex to ascii edit @@ -1745,8 +1758,7 @@ void QHexEdit::keyPressEvent(QKeyEvent *event) //---------------------------------------------------------------------------- void QHexEdit::keyReleaseEvent(QKeyEvent *event) { - printf("Hex Window Key Release: 0x%x \n", event->key() ); - //assignHotkey( event ); + //printf("Hex Window Key Release: 0x%x \n", event->key() ); } //---------------------------------------------------------------------------- void QHexEdit::mousePressEvent(QMouseEvent * event) @@ -1771,6 +1783,11 @@ void QHexEdit::contextMenuEvent(QContextMenuEvent *event) int addr; char stmp[128]; + QPoint c = convPixToCursor( event->pos() ); + cursorPosX = c.x(); + cursorPosY = c.y(); + resetCursor(); + ctxAddr = addr = convPixToAddr( event->pos() ); //printf("contextMenuEvent\n"); @@ -1778,10 +1795,33 @@ void QHexEdit::contextMenuEvent(QContextMenuEvent *event) { case MODE_NES_RAM: { + QMenu *subMenu; + act = new QAction(tr("Add Symbolic Debug Name"), &menu); menu.addAction(act); connect( act, SIGNAL(triggered(void)), this, SLOT(addDebugSym(void)) ); + subMenu = menu.addMenu(tr("Freeze/Unfreeze Address")); + + act = new QAction(tr("Toggle State"), &menu); + act->setShortcut( QKeySequence(tr("Ctrl+F"))); + subMenu->addAction(act); + connect( act, SIGNAL(triggered(void)), this, SLOT(frzRamToggle(void)) ); + + act = new QAction(tr("Freeze"), &menu); + subMenu->addAction(act); + connect( act, SIGNAL(triggered(void)), this, SLOT(frzRamSet(void)) ); + + act = new QAction(tr("Unfreeze"), &menu); + subMenu->addAction(act); + connect( act, SIGNAL(triggered(void)), this, SLOT(frzRamUnset(void)) ); + + subMenu->addSeparator(); + + act = new QAction(tr("Unfreeze All"), &menu); + subMenu->addAction(act); + connect( act, SIGNAL(triggered(void)), this, SLOT(frzRamUnsetAll(void)) ); + sprintf( stmp, "Add Read Breakpoint for Address $%04X", addr ); act = new QAction(tr(stmp), &menu); menu.addAction(act); @@ -1891,6 +1931,160 @@ void QHexEdit::addBookMarkCB(void) } } //---------------------------------------------------------------------------- +static int RamFreezeCB(char *name, uint32 a, uint8 v, int compare,int s,int type, void *data) +{ + return ((QHexEdit*)data)->FreezeRam( name, a, v, compare, s, type ); +} +//---------------------------------------------------------------------------- +int QHexEdit::FreezeRam( const char *name, uint32_t a, uint8_t v, int c, int s, int type ) +{ + + //if ( c >= 0 ) + //{ + // printf("$%04X?%02X:%02X %i: %s\n", a, c, v, s, name ); + //} + //else + //{ + // printf("$%04X:%02X %i: %s\n", a, v, s, name ); + //} + + if ( a == frzRamAddr ) + { + switch ( frzRamMode ) + { + case 0: // Toggle + + if ( s ) + { + FCEUI_DelCheat( frzIdx ); + frzRamAddr = -1; + return 0; + } + break; + case 1: // Freeze + + if ( s ) + { + // Already Set so there is nothing further to do + frzRamAddr = -1; + return 0; + } + break; + case 2: // Unfreeze + if ( s ) + { + FCEUI_DelCheat( frzIdx ); + } + break; + default: + case 3: // Unfreeze All Handled Below + // Nothing to do + break; + } + } + + if ( frzRamMode == 3 ) + { + if ( s ) + { + FCEUI_DelCheat( frzIdx ); + } + } + + frzIdx++; + + return 1; +} +//---------------------------------------------------------------------------- +bool QHexEdit::frzRamAddrValid( int addr ) +{ + if ( addr < 0 ) + { + return false; + } + + if ( (addr < 0x2000) || ( (addr >= 0x6000) && (addr <= 0x7FFF) ) ) + { + return true; + } + return false; +} +//---------------------------------------------------------------------------- +void QHexEdit::frzRamSet(void) +{ + frzIdx = 0; + frzRamMode = 1; + frzRamAddr = ctxAddr; + + if ( !frzRamAddrValid( frzRamAddr ) ) + { + return; + } + + fceuWrapperLock(); + FCEUI_ListCheats( RamFreezeCB, this); + + if ( (frzRamAddr >= 0) && (FrozenAddressCount < 256) ) + { + FCEUI_AddCheat("", frzRamAddr, GetMem(frzRamAddr), -1, 1); + } + updateCheatDialog(); + fceuWrapperUnLock(); +} +//---------------------------------------------------------------------------- +void QHexEdit::frzRamUnset(void) +{ + frzIdx = 0; + frzRamMode = 2; + frzRamAddr = ctxAddr; + + if ( !frzRamAddrValid( frzRamAddr ) ) + { + return; + } + fceuWrapperLock(); + FCEUI_ListCheats( RamFreezeCB, this); + updateCheatDialog(); + fceuWrapperUnLock(); +} +//---------------------------------------------------------------------------- +void QHexEdit::frzRamUnsetAll(void) +{ + frzIdx = 0; + frzRamMode = 3; + frzRamAddr = ctxAddr; + + if ( !frzRamAddrValid( frzRamAddr ) ) + { + return; + } + fceuWrapperLock(); + FCEUI_ListCheats( RamFreezeCB, this); + updateCheatDialog(); + fceuWrapperUnLock(); +} +//---------------------------------------------------------------------------- +void QHexEdit::frzRamToggle(void) +{ + frzIdx = 0; + frzRamMode = 0; + frzRamAddr = ctxAddr; + + if ( !frzRamAddrValid( frzRamAddr ) ) + { + return; + } + fceuWrapperLock(); + FCEUI_ListCheats( RamFreezeCB, this); + + if ( (frzRamAddr >= 0) && (FrozenAddressCount < 256) ) + { + FCEUI_AddCheat("", frzRamAddr, GetMem(frzRamAddr), -1, 1); + } + updateCheatDialog(); + fceuWrapperUnLock(); +} +//---------------------------------------------------------------------------- void QHexEdit::addDebugSym(void) { parent->openDebugSymbolEditWindow( ctxAddr ); @@ -2238,6 +2432,7 @@ void QHexEdit::paintEvent(QPaintEvent *event) int c, cx, cy, ca; char txt[32], asciiTxt[4]; QPainter painter(this); + QColor white("white"), black("black"), blue("blue"); painter.setFont(font); w = event->rect().width(); @@ -2371,6 +2566,39 @@ void QHexEdit::paintEvent(QPaintEvent *event) painter.setPen( romFgColor ); } } + else if ( viewMode == MODE_NES_RAM ) + { + if ( FCEUI_FindCheatMapByte( addr ) ) + { + if ( reverseVideo ) + { + painter.setPen( white ); + painter.fillRect( x - (0.5*pxCharWidth) , y-pxLineSpacing+pxLineLead, 3*pxCharWidth, pxLineSpacing, blue ); + painter.fillRect( pxHexAscii + (col*pxCharWidth) - pxLineXScroll, y-pxLineSpacing+pxLineLead, pxCharWidth, pxLineSpacing, blue ); + } + else + { + painter.setPen( blue ); + } + } + else if ( actvHighlightEnable && (mb.buf[addr].actv > 0) ) + { + if ( reverseVideo ) + { + painter.setPen( rvActvTextColor[ mb.buf[addr].actv ] ); + painter.fillRect( x - (0.5*pxCharWidth) , y-pxLineSpacing+pxLineLead, 3*pxCharWidth, pxLineSpacing, highLightColor[ mb.buf[addr].actv ] ); + painter.fillRect( pxHexAscii + (col*pxCharWidth) - pxLineXScroll, y-pxLineSpacing+pxLineLead, pxCharWidth, pxLineSpacing, highLightColor[ mb.buf[addr].actv ] ); + } + else + { + painter.setPen( highLightColor[ mb.buf[addr].actv ] ); + } + } + else + { + painter.setPen( this->palette().color(QPalette::WindowText)); + } + } else if ( actvHighlightEnable && (mb.buf[addr].actv > 0) ) { if ( reverseVideo ) diff --git a/src/drivers/Qt/HexEditor.h b/src/drivers/Qt/HexEditor.h index 0ae73b7a..13c0ac57 100644 --- a/src/drivers/Qt/HexEditor.h +++ b/src/drivers/Qt/HexEditor.h @@ -116,6 +116,7 @@ class QHexEdit : public QWidget void openGotoAddrDialog(void); int checkMemActivity(void); int getAddr(void){ return cursorAddr; }; + int FreezeRam( const char *name, uint32_t a, uint8_t v, int c, int s, int type ); enum { MODE_NES_RAM = 0, @@ -136,6 +137,7 @@ class QHexEdit : public QWidget void resetCursor(void); QPoint convPixToCursor( QPoint p ); int convPixToAddr( QPoint p ); + bool frzRamAddrValid( int addr ); QFont font; @@ -179,6 +181,10 @@ class QHexEdit : public QWidget int editMask; int jumpToRomValue; int ctxAddr; + int frzRamAddr; + int frzRamVal; + int frzRamMode; + int frzIdx; bool cursorBlink; bool reverseVideo; @@ -193,6 +199,10 @@ class QHexEdit : public QWidget void addRamExecuteBP(void); void addPpuReadBP(void); void addPpuWriteBP(void); + void frzRamSet(void); + void frzRamUnset(void); + void frzRamToggle(void); + void frzRamUnsetAll(void); };