diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a13bd2b..4ef224bb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -431,6 +431,7 @@ set(SRC_DRIVERS_SDL ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GuiConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/LuaControl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/CheatsConf.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HexEditor.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleUtilities.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleVideoConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleSoundConf.cpp diff --git a/src/drivers/Qt/CheatsConf.cpp b/src/drivers/Qt/CheatsConf.cpp index 2f1de97d..1f53e556 100644 --- a/src/drivers/Qt/CheatsConf.cpp +++ b/src/drivers/Qt/CheatsConf.cpp @@ -50,7 +50,8 @@ GuiCheatsDialog_t::GuiCheatsDialog_t(QWidget *parent) QFontMetrics fm(font); - fontCharWidth = fm.boundingRect('X').width() * devPixRatio; + //fontCharWidth = fm.boundingRect('X').width() * devPixRatio; + fontCharWidth = 2.00 * fm.averageCharWidth() * devPixRatio; setWindowTitle("Cheat Search"); @@ -415,12 +416,22 @@ GuiCheatsDialog_t::~GuiCheatsDialog_t(void) } wasPausedByCheats = false; + printf("Destroy Cheat Window Event\n"); +} +//---------------------------------------------------------------------------- +void GuiCheatsDialog_t::closeEvent(QCloseEvent *event) +{ + printf("Cheat Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); } //---------------------------------------------------------------------------- void GuiCheatsDialog_t::closeWindow(void) { //printf("Close Window\n"); done(0); + deleteLater(); } //---------------------------------------------------------------------------- int GuiCheatsDialog_t::addSearchResult (uint32_t a, uint8_t last, uint8_t current) @@ -742,25 +753,10 @@ void GuiCheatsDialog_t::saveCheatFile(void) if ( GameInfo ) { - char *_filename; - if ((_filename = strrchr(GameInfo->filename, '\\')) || (_filename = strrchr(GameInfo->filename, '/'))) - { - strcpy( dir, _filename + 1); - } - else - { - strcpy( dir, GameInfo->filename); - } + getFileBaseName( GameInfo->filename, dir ); + + strcat( dir, ".cht"); - _filename = strrchr( dir, '.'); - if (_filename) - { - strcpy(_filename, ".cht"); - } - else - { - strcat( dir, ".cht"); - } dialog.selectFile( dir ); } diff --git a/src/drivers/Qt/CheatsConf.h b/src/drivers/Qt/CheatsConf.h index d687cb70..fbc46a24 100644 --- a/src/drivers/Qt/CheatsConf.h +++ b/src/drivers/Qt/CheatsConf.h @@ -33,6 +33,7 @@ class GuiCheatsDialog_t : public QDialog int activeCheatListCB (char *name, uint32 a, uint8 v, int c, int s, int type, void *data); protected: + void closeEvent(QCloseEvent *event); QGroupBox *actCheatFrame; QGroupBox *cheatSearchFrame; diff --git a/src/drivers/Qt/ConsoleSoundConf.cpp b/src/drivers/Qt/ConsoleSoundConf.cpp index 9932a7ca..b02c2253 100644 --- a/src/drivers/Qt/ConsoleSoundConf.cpp +++ b/src/drivers/Qt/ConsoleSoundConf.cpp @@ -1,5 +1,7 @@ // ConsoleSoundConf.cpp // +#include + #include "../../fceu.h" #include "../../driver.h" #include "Qt/ConsoleSoundConf.h" @@ -217,7 +219,22 @@ ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent) //---------------------------------------------------- ConsoleSndConfDialog_t::~ConsoleSndConfDialog_t(void) { - + printf("Destroy Sound Config Window\n"); +} +//---------------------------------------------------------------------------- +void ConsoleSndConfDialog_t::closeEvent(QCloseEvent *event) +{ + printf("Sound Config Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); +} +//---------------------------------------------------------------------------- +void ConsoleSndConfDialog_t::closeWindow(void) +{ + //printf("Sound Close Window\n"); + done(0); + deleteLater(); } //---------------------------------------------------- void ConsoleSndConfDialog_t::setCheckBoxFromProperty( QCheckBox *cbx, const char *property ) diff --git a/src/drivers/Qt/ConsoleSoundConf.h b/src/drivers/Qt/ConsoleSoundConf.h index 40e86d2a..40f8de1f 100644 --- a/src/drivers/Qt/ConsoleSoundConf.h +++ b/src/drivers/Qt/ConsoleSoundConf.h @@ -25,6 +25,8 @@ class ConsoleSndConfDialog_t : public QDialog ~ConsoleSndConfDialog_t(void); protected: + void closeEvent(QCloseEvent *event); + QCheckBox *enaChkbox; QCheckBox *enaLowPass; QCheckBox *swapDutyChkbox; @@ -44,6 +46,7 @@ class ConsoleSndConfDialog_t : public QDialog void setSliderFromProperty( QSlider *slider, QLabel *lbl, const char *property ); private slots: + void closeWindow(void); void bufSizeChanged(int value); void volumeChanged(int value); void triangleChanged(int value); diff --git a/src/drivers/Qt/ConsoleUtilities.cpp b/src/drivers/Qt/ConsoleUtilities.cpp index 6af44d62..fcb9a23c 100644 --- a/src/drivers/Qt/ConsoleUtilities.cpp +++ b/src/drivers/Qt/ConsoleUtilities.cpp @@ -2,6 +2,7 @@ #include #include +#include "../../fceu.h" #include "Qt/ConsoleUtilities.h" //--------------------------------------------------------------------------- @@ -35,3 +36,50 @@ int getDirFromFile( const char *path, char *dir ) return 0; } //--------------------------------------------------------------------------- +const char *getRomFile( void ) +{ + if ( GameInfo ) + { + return GameInfo->filename; + } + return NULL; +} +//--------------------------------------------------------------------------- +// Return file base name stripping out preceding path and trailing suffix. +int getFileBaseName( const char *filepath, char *base ) +{ + int i=0,j=0,end=0; + if ( filepath == NULL ) + { + base[0] = 0; + return 0; + } + i=0; j=0; + while ( filepath[i] != 0 ) + { + if ( (filepath[i] == '/') || (filepath[i] == '\\') ) + { + j = i; + } + i++; + } + i = j; + + j=0; + while ( filepath[i] != 0 ) + { + base[j] = filepath[i]; i++; j++; + } + base[j] = 0; end=j; + + while ( j > 1 ) + { + j--; + if ( base[j] == '.' ) + { + end=j; base[j] = 0; break; + } + } + return end; +} +//--------------------------------------------------------------------------- diff --git a/src/drivers/Qt/ConsoleUtilities.h b/src/drivers/Qt/ConsoleUtilities.h index 0f4417e2..e55e0361 100644 --- a/src/drivers/Qt/ConsoleUtilities.h +++ b/src/drivers/Qt/ConsoleUtilities.h @@ -1,3 +1,7 @@ // ConsoleUtilities.h int getDirFromFile( const char *path, char *dir ); + +const char *getRomFile( void ); + +int getFileBaseName( const char *filepath, char *base ); diff --git a/src/drivers/Qt/ConsoleVideoConf.cpp b/src/drivers/Qt/ConsoleVideoConf.cpp index 44f4116b..1da2f639 100644 --- a/src/drivers/Qt/ConsoleVideoConf.cpp +++ b/src/drivers/Qt/ConsoleVideoConf.cpp @@ -1,5 +1,7 @@ // ConsoleVideoConf.cpp // +#include + #include "../../fceu.h" #include "Qt/main.h" #include "Qt/dface.h" @@ -105,7 +107,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent) button = new QPushButton( tr("Close") ); hbox1->addWidget( button ); - connect(button, SIGNAL(clicked()), this, SLOT(closewindow(void)) ); + connect(button, SIGNAL(clicked()), this, SLOT(closeWindow(void)) ); main_vbox->addLayout( hbox1 ); @@ -115,8 +117,24 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent) //---------------------------------------------------- ConsoleVideoConfDialog_t::~ConsoleVideoConfDialog_t(void) { + printf("Destroy Video Config Window\n"); } +//---------------------------------------------------------------------------- +void ConsoleVideoConfDialog_t::closeEvent(QCloseEvent *event) +{ + printf("Video Config Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); +} +//---------------------------------------------------------------------------- +void ConsoleVideoConfDialog_t::closeWindow(void) +{ + //printf("Video Config Close Window\n"); + done(0); + deleteLater(); +} //---------------------------------------------------- void ConsoleVideoConfDialog_t::resetVideo(void) { @@ -237,8 +255,3 @@ void ConsoleVideoConfDialog_t::applyChanges( void ) resetVideo(); } //---------------------------------------------------- -void ConsoleVideoConfDialog_t::closewindow( void ) -{ - done(0); -} -//---------------------------------------------------- diff --git a/src/drivers/Qt/ConsoleVideoConf.h b/src/drivers/Qt/ConsoleVideoConf.h index 00b38d86..73d86e76 100644 --- a/src/drivers/Qt/ConsoleVideoConf.h +++ b/src/drivers/Qt/ConsoleVideoConf.h @@ -25,6 +25,8 @@ class ConsoleVideoConfDialog_t : public QDialog ~ConsoleVideoConfDialog_t(void); protected: + void closeEvent(QCloseEvent *bar); + QComboBox *driverSelect; QComboBox *regionSelect; QCheckBox *gl_LF_chkBox; @@ -40,6 +42,9 @@ class ConsoleVideoConfDialog_t : public QDialog void resetVideo(void); + public slots: + void closeWindow(void); + private slots: void use_new_PPU_changed( int value ); void frameskip_changed( int value ); @@ -49,7 +54,6 @@ class ConsoleVideoConfDialog_t : public QDialog void regionChanged(int index); void driverChanged(int index); void applyChanges( void ); - void closewindow( void ); }; diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 8376262b..57102e8e 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -24,6 +24,7 @@ #include "Qt/GuiConf.h" #include "Qt/LuaControl.h" #include "Qt/CheatsConf.h" +#include "Qt/HexEditor.h" #include "Qt/ConsoleUtilities.h" #include "Qt/ConsoleSoundConf.h" #include "Qt/ConsoleVideoConf.h" @@ -74,8 +75,6 @@ consoleWin_t::consoleWin_t(QWidget *parent) emulatorThread->start(); - gamePadConfWin = NULL; - } consoleWin_t::~consoleWin_t(void) @@ -84,10 +83,8 @@ consoleWin_t::~consoleWin_t(void) gameTimer->stop(); - if ( gamePadConfWin != NULL ) - { - gamePadConfWin->closeWindow(); - } + closeGamePadConfWindow(); + fceuWrapperLock(); fceuWrapperClose(); fceuWrapperUnLock(); @@ -143,11 +140,8 @@ void consoleWin_t::QueueErrorMsgWindow( const char *msg ) void consoleWin_t::closeEvent(QCloseEvent *event) { //printf("Main Window Close Event\n"); - if ( gamePadConfWin != NULL ) - { - //printf("Command Game Pad Close\n"); - gamePadConfWin->closeWindow(); - } + closeGamePadConfWindow(); + event->accept(); closeApp(); @@ -484,6 +478,18 @@ void consoleWin_t::createMainMenu(void) toolsMenu->addAction(cheatsAct); + //----------------------------------------------------------------------- + // Debug + debugMenu = menuBar()->addMenu(tr("Debug")); + + // Debug -> Hex Editor + hexEditAct = new QAction(tr("Hex Editor..."), this); + //hexEditAct->setShortcut( QKeySequence(tr("Shift+F7"))); + hexEditAct->setStatusTip(tr("Open Memory Hex Editor")); + connect(hexEditAct, SIGNAL(triggered()), this, SLOT(openHexEditor(void)) ); + + debugMenu->addAction(hexEditAct); + //----------------------------------------------------------------------- // Movie movieMenu = menuBar()->addMenu(tr("Movie")); @@ -888,30 +894,14 @@ void consoleWin_t::loadLua(void) luaCtrlWin = new LuaControlDialog_t(this); luaCtrlWin->show(); - luaCtrlWin->exec(); - - delete luaCtrlWin; - - //printf("Lua Control Window Destroyed\n"); #endif } void consoleWin_t::openGamePadConfWin(void) { - if ( gamePadConfWin != NULL ) - { - printf("GamePad Config Window Already Open\n"); - return; - } //printf("Open GamePad Config Window\n"); - gamePadConfWin = new GamePadConfDialog_t(this); - gamePadConfWin->show(); - gamePadConfWin->exec(); - - delete gamePadConfWin; - gamePadConfWin = NULL; - //printf("GamePad Config Window Destroyed\n"); + openGamePadConfWindow(this); } void consoleWin_t::openGameSndConfWin(void) @@ -923,11 +913,6 @@ void consoleWin_t::openGameSndConfWin(void) sndConfWin = new ConsoleSndConfDialog_t(this); sndConfWin->show(); - sndConfWin->exec(); - - delete sndConfWin; - - //printf("Sound Config Window Destroyed\n"); } void consoleWin_t::openGameVideoConfWin(void) @@ -939,11 +924,6 @@ void consoleWin_t::openGameVideoConfWin(void) vidConfWin = new ConsoleVideoConfDialog_t(this); vidConfWin->show(); - vidConfWin->exec(); - - delete vidConfWin; - - //printf("Video Config Window Destroyed\n"); } void consoleWin_t::openHotkeyConfWin(void) @@ -955,11 +935,6 @@ void consoleWin_t::openHotkeyConfWin(void) hkConfWin = new HotKeyConfDialog_t(this); hkConfWin->show(); - hkConfWin->exec(); - - delete hkConfWin; - - //printf("Hotkey Config Window Destroyed\n"); } void consoleWin_t::openPaletteConfWin(void) @@ -971,11 +946,6 @@ void consoleWin_t::openPaletteConfWin(void) paletteConfWin = new PaletteConfDialog_t(this); paletteConfWin->show(); - paletteConfWin->exec(); - - delete paletteConfWin; - - //printf("Palette Config Window Destroyed\n"); } void consoleWin_t::openGuiConfWin(void) @@ -987,11 +957,6 @@ void consoleWin_t::openGuiConfWin(void) guiConfWin = new GuiConfDialog_t(this); guiConfWin->show(); - guiConfWin->exec(); - - delete guiConfWin; - - //printf("GUI Config Window Destroyed\n"); } void consoleWin_t::openCheats(void) @@ -1003,11 +968,17 @@ void consoleWin_t::openCheats(void) cheatWin = new GuiCheatsDialog_t(this); cheatWin->show(); - cheatWin->exec(); +} - delete cheatWin; +void consoleWin_t::openHexEditor(void) +{ + HexEditorDialog_t *hexEditWin; - //printf("GUI Cheat Window Destroyed\n"); + //printf("Open GUI Hex Editor Window\n"); + + hexEditWin = new HexEditorDialog_t(this); + + hexEditWin->show(); } void consoleWin_t::toggleAutoResume(void) @@ -1383,11 +1354,6 @@ void consoleWin_t::aboutFCEUX(void) aboutWin = new AboutWindow(this); aboutWin->show(); - aboutWin->exec(); - - delete aboutWin; - - //printf("About Window Destroyed\n"); return; } diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index e2bd6a69..eb5fdddb 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -53,6 +53,7 @@ class consoleWin_t : public QMainWindow QMenu *optMenu; QMenu *emuMenu; QMenu *toolsMenu; + QMenu *debugMenu; QMenu *movieMenu; QMenu *helpMenu; @@ -88,6 +89,7 @@ class consoleWin_t : public QMainWindow QAction *fdsEjectAct; QAction *fdsLoadBiosAct; QAction *cheatsAct; + QAction *hexEditAct; QAction *openMovAct; QAction *stopMovAct; QAction *recMovAct; @@ -97,8 +99,6 @@ class consoleWin_t : public QMainWindow emulatorThread_t *emulatorThread; - GamePadConfDialog_t *gamePadConfWin; - std::string errorMsg; bool errorMsgValid; @@ -155,6 +155,7 @@ class consoleWin_t : public QMainWindow void fdsEjectDisk(void); void fdsLoadBiosFile(void); void openCheats(void); + void openHexEditor(void); void openMovie(void); void stopMovie(void); void recordMovie(void); diff --git a/src/drivers/Qt/GamePadConf.cpp b/src/drivers/Qt/GamePadConf.cpp index 03df69bb..2847a01c 100644 --- a/src/drivers/Qt/GamePadConf.cpp +++ b/src/drivers/Qt/GamePadConf.cpp @@ -36,6 +36,30 @@ struct GamePadConfigLocalData_t static GamePadConfigLocalData_t lcl[GAMEPAD_NUM_DEVICES]; +static GamePadConfDialog_t *gamePadConfWin = NULL; + +//---------------------------------------------------- +int openGamePadConfWindow( QWidget *parent ) +{ + if ( gamePadConfWin != NULL ) + { + return -1; + } + gamePadConfWin = new GamePadConfDialog_t(parent); + + gamePadConfWin->show(); + + return 0; +} +//---------------------------------------------------- +int closeGamePadConfWindow(void) +{ + if ( gamePadConfWin != NULL ) + { + gamePadConfWin->closeWindow(); + } + return 0; +} //---------------------------------------------------- GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) : QDialog( parent ) @@ -56,6 +80,8 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) std::string prefix; char stmp[256]; + gamePadConfWin = this; + // Ensure that joysticks are enabled, no harm calling init again. InitJoysticks(); @@ -279,6 +305,9 @@ GamePadConfDialog_t::~GamePadConfDialog_t(void) { inputTimer->stop(); buttonConfigStatus = 0; + gamePadConfWin = NULL; + + printf("GamePad Window Deleted\n"); } void GamePadConfDialog_t::keyPressEvent(QKeyEvent *event) { @@ -500,6 +529,7 @@ void GamePadConfDialog_t::closeEvent(QCloseEvent *event) printf("GamePad Close Window Event\n"); buttonConfigStatus = 0; done(0); + deleteLater(); event->accept(); } //---------------------------------------------------- @@ -510,6 +540,7 @@ void GamePadConfDialog_t::closeWindow(void) printf("Close Window\n"); buttonConfigStatus = 0; done(0); + deleteLater(); } //---------------------------------------------------- void GamePadConfDialog_t::changeButton0(void) diff --git a/src/drivers/Qt/GamePadConf.h b/src/drivers/Qt/GamePadConf.h index 5efafeb3..7d5fabe2 100644 --- a/src/drivers/Qt/GamePadConf.h +++ b/src/drivers/Qt/GamePadConf.h @@ -99,3 +99,7 @@ class GamePadConfDialog_t : public QDialog void updatePeriodic(void); }; + +int openGamePadConfWindow( QWidget *parent ); + +int closeGamePadConfWindow(void); diff --git a/src/drivers/Qt/GuiConf.cpp b/src/drivers/Qt/GuiConf.cpp index 256aacb2..0eab340b 100644 --- a/src/drivers/Qt/GuiConf.cpp +++ b/src/drivers/Qt/GuiConf.cpp @@ -46,13 +46,22 @@ GuiConfDialog_t::GuiConfDialog_t(QWidget *parent) //---------------------------------------------------- GuiConfDialog_t::~GuiConfDialog_t(void) { - + printf("Destroy GUI Config Close Window\n"); +} +//---------------------------------------------------------------------------- +void GuiConfDialog_t::closeEvent(QCloseEvent *event) +{ + printf("GUI Config Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); } //---------------------------------------------------- void GuiConfDialog_t::closeWindow(void) { //printf("Close Window\n"); done(0); + deleteLater(); } //---------------------------------------------------- void GuiConfDialog_t::useNativeFileDialogChanged(int state) diff --git a/src/drivers/Qt/GuiConf.h b/src/drivers/Qt/GuiConf.h index 032dd4db..aa0bcc84 100644 --- a/src/drivers/Qt/GuiConf.h +++ b/src/drivers/Qt/GuiConf.h @@ -26,6 +26,8 @@ class GuiConfDialog_t : public QDialog ~GuiConfDialog_t(void); protected: + void closeEvent(QCloseEvent *event); + QCheckBox *useNativeFileDialog; QCheckBox *useNativeMenuBar; private: diff --git a/src/drivers/Qt/HexEditor.cpp b/src/drivers/Qt/HexEditor.cpp new file mode 100644 index 00000000..aefea213 --- /dev/null +++ b/src/drivers/Qt/HexEditor.cpp @@ -0,0 +1,1533 @@ +// HotKeyConf.cpp +// +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../../types.h" +#include "../../fceu.h" +#include "../../cheat.h" +#include "../../debug.h" +#include "../../driver.h" +#include "../../version.h" +#include "../../movie.h" +#include "../../palette.h" +#include "../../fds.h" +#include "../../cart.h" +#include "../../ines.h" +#include "../common/configSys.h" + +#include "Qt/main.h" +#include "Qt/dface.h" +#include "Qt/input.h" +#include "Qt/config.h" +#include "Qt/keyscan.h" +#include "Qt/fceuWrapper.h" +#include "Qt/HexEditor.h" +#include "Qt/ConsoleUtilities.h" + +//---------------------------------------------------------------------------- +static int getRAM( unsigned int i ) +{ + return GetMem(i); +} +//---------------------------------------------------------------------------- +static int getPPU( unsigned int i ) +{ + i &= 0x3FFF; + if (i < 0x2000)return VPage[(i) >> 10][(i)]; + //NSF PPU Viewer crash here (UGETAB) (Also disabled by 'MaxSize = 0x2000') + if (GameInfo->type == GIT_NSF) + return 0; + else + { + if (i < 0x3F00) + return vnapage[(i >> 10) & 0x3][i & 0x3FF]; + return READPAL_MOTHEROFALL(i & 0x1F); + } + return 0; +} +//---------------------------------------------------------------------------- +static int getOAM( unsigned int i ) +{ + return SPRAM[i & 0xFF]; +} +//---------------------------------------------------------------------------- +static int getROM( unsigned int offset) +{ + if (offset < 16) + { + return *((unsigned char *)&head+offset); + } + else if (offset < (16+PRGsize[0]) ) + { + return PRGptr[0][offset-16]; + } + else if (offset < (16+PRGsize[0]+CHRsize[0]) ) + { + return CHRptr[0][offset-16-PRGsize[0]]; + } + return -1; +} +//---------------------------------------------------------------------------- +static void PalettePoke(uint32 addr, uint8 data) +{ + data = data & 0x3F; + addr = addr & 0x1F; + if ((addr & 3) == 0) + { + addr = (addr & 0xC) >> 2; + if (addr == 0) + { + PALRAM[0x00] = PALRAM[0x04] = PALRAM[0x08] = PALRAM[0x0C] = data; + } + else + { + UPALRAM[addr-1] = UPALRAM[0x10|(addr-1)] = data; + } + } + else + { + PALRAM[addr] = data; + } +} +//---------------------------------------------------------------------------- +static int writeMem( int mode, unsigned int addr, int value ) +{ + value = value & 0x000000ff; + + switch ( mode ) + { + default: + case QHexEdit::MODE_NES_RAM: + { + if ( addr < 0x8000 ) + { + writefunc wfunc; + + wfunc = GetWriteHandler (addr); + + if (wfunc) + { + wfunc ((uint32) addr, + (uint8) (value & 0x000000ff)); + } + } + else + { + fprintf( stdout, "Error: Writing into RAM addresses >= 0x8000 is unsafe. Operation Denied.\n"); + } + } + break; + case QHexEdit::MODE_NES_PPU: + { + addr &= 0x3FFF; + if (addr < 0x2000) + { + VPage[addr >> 10][addr] = value; //todo: detect if this is vrom and turn it red if so + } + if ((addr >= 0x2000) && (addr < 0x3F00)) + { + vnapage[(addr >> 10) & 0x3][addr & 0x3FF] = value; //todo: this causes 0x3000-0x3f00 to mirror 0x2000-0x2f00, is this correct? + } + if ((addr >= 0x3F00) && (addr < 0x3FFF)) + { + PalettePoke(addr, value); + } + } + break; + case QHexEdit::MODE_NES_OAM: + { + addr &= 0xFF; + SPRAM[addr] = value; + } + break; + case QHexEdit::MODE_NES_ROM: + { + if (addr < 16) + { + fprintf( stdout, "You can't edit ROM header here, however you can use iNES Header Editor to edit the header if it's an iNES format file."); + } + else if ( (addr >= 16) && (addr < PRGsize[0]+16) ) + { + *(uint8 *)(GetNesPRGPointer(addr-16)) = value; + } + else if ( (addr >= PRGsize[0]+16) && (addr < CHRsize[0]+PRGsize[0]+16) ) + { + *(uint8 *)(GetNesCHRPointer(addr-16-PRGsize[0])) = value; + } + } + break; + } + return 0; +} +//---------------------------------------------------------------------------- + +static int convToXchar( int i ) +{ + int c = 0; + + if ( (i >= 0) && (i < 10) ) + { + c = i + '0'; + } + else if ( i < 16 ) + { + c = (i - 10) + 'A'; + } + return c; +} +//---------------------------------------------------------------------------- + +static int convFromXchar( int i ) +{ + int c = 0; + + i = ::toupper(i); + + if ( (i >= '0') && (i <= '9') ) + { + c = i - '0'; + } + else if ( (i >= 'A') && (i <= 'F') ) + { + c = (i - 'A') + 10; + } + return c; +} + +//---------------------------------------------------------------------------- +memBlock_t::memBlock_t( void ) +{ + buf = NULL; + _size = 0; + _maxLines = 0; + memAccessFunc = NULL; +} +//---------------------------------------------------------------------------- + +memBlock_t::~memBlock_t(void) +{ + if ( buf != NULL ) + { + ::free( buf ); buf = NULL; + } + _size = 0; + _maxLines = 0; +} + +//---------------------------------------------------------------------------- +int memBlock_t::reAlloc( int newSize ) +{ + if ( newSize == 0 ) + { + return 0; + } + if ( _size == newSize ) + { + return 0; + } + + if ( buf != NULL ) + { + ::free( buf ); buf = NULL; + } + _size = 0; + _maxLines = 0; + + buf = (struct memByte_t *)malloc( newSize * sizeof(struct memByte_t) ); + + if ( buf != NULL ) + { + _size = newSize; + init(); + + if ( (_size % 16) ) + { + _maxLines = (_size / 16) + 1; + } + else + { + _maxLines = (_size / 16); + } + } + return (buf == NULL); +} +//---------------------------------------------------------------------------- +void memBlock_t::setAccessFunc( int (*newMemAccessFunc)( unsigned int offset) ) +{ + memAccessFunc = newMemAccessFunc; +} +//---------------------------------------------------------------------------- +void memBlock_t::init(void) +{ + for (int i=0; i<_size; i++) + { + buf[i].data = memAccessFunc(i); + buf[i].color = 0; + buf[i].actv = 0; + //buf[i].draw = 1; + } +} +//---------------------------------------------------------------------------- +HexEditorDialog_t::HexEditorDialog_t(QWidget *parent) + : QDialog( parent ) +{ + //QVBoxLayout *mainLayout; + QGridLayout *grid; + QMenuBar *menuBar; + QMenu *fileMenu, *viewMenu, *colorMenu; + QAction *saveROM, *closeAct; + QAction *viewRAM, *viewPPU, *viewOAM, *viewROM; + QAction *actHlgt, *actHlgtRV, *actColorFG, *actColorBG; + QActionGroup *group; + int useNativeMenuBar; + + setWindowTitle("Hex Editor"); + + resize( 512, 512 ); + + menuBar = new QMenuBar(this); + + // This is needed for menu bar to show up on MacOS + g_config->getOption( "SDL.UseNativeMenuBar", &useNativeMenuBar ); + + menuBar->setNativeMenuBar( useNativeMenuBar ? true : false ); + //----------------------------------------------------------------------- + // Menu + //----------------------------------------------------------------------- + // File + fileMenu = menuBar->addMenu(tr("File")); + + // File -> Save ROM + saveROM = new QAction(tr("Save ROM"), this); + //saveROM->setShortcuts(QKeySequence::Open); + saveROM->setStatusTip(tr("Save ROM File")); + connect(saveROM, SIGNAL(triggered()), this, SLOT(saveRomFile(void)) ); + + fileMenu->addAction(saveROM); + + // File -> Save ROM As + saveROM = new QAction(tr("Save ROM As"), this); + //saveROM->setShortcuts(QKeySequence::Open); + saveROM->setStatusTip(tr("Save ROM File As")); + connect(saveROM, SIGNAL(triggered()), this, SLOT(saveRomFileAs(void)) ); + + fileMenu->addAction(saveROM); + + fileMenu->addSeparator(); + + // File -> Close + closeAct = new QAction(tr("Close"), this); + //closeAct->setShortcuts(QKeySequence::Open); + closeAct->setStatusTip(tr("Close Window")); + connect(closeAct, SIGNAL(triggered()), this, SLOT(closeWindow(void)) ); + + fileMenu->addAction(closeAct); + + // View + viewMenu = menuBar->addMenu(tr("View")); + + group = new QActionGroup(this); + + group->setExclusive(true); + + // View -> RAM + viewRAM = new QAction(tr("RAM"), this); + //viewRAM->setShortcuts(QKeySequence::Open); + viewRAM->setStatusTip(tr("View RAM")); + viewRAM->setCheckable(true); + connect(viewRAM, SIGNAL(triggered()), this, SLOT(setViewRAM(void)) ); + + group->addAction(viewRAM); + viewMenu->addAction(viewRAM); + + // View -> PPU + viewPPU = new QAction(tr("PPU"), this); + //viewPPU->setShortcuts(QKeySequence::Open); + viewPPU->setStatusTip(tr("View PPU")); + viewPPU->setCheckable(true); + connect(viewPPU, SIGNAL(triggered()), this, SLOT(setViewPPU(void)) ); + + group->addAction(viewPPU); + viewMenu->addAction(viewPPU); + + // View -> OAM + viewOAM = new QAction(tr("OAM"), this); + //viewOAM->setShortcuts(QKeySequence::Open); + viewOAM->setStatusTip(tr("View OAM")); + viewOAM->setCheckable(true); + connect(viewOAM, SIGNAL(triggered()), this, SLOT(setViewOAM(void)) ); + + group->addAction(viewOAM); + viewMenu->addAction(viewOAM); + + // View -> ROM + viewROM = new QAction(tr("ROM"), this); + //viewROM->setShortcuts(QKeySequence::Open); + viewROM->setStatusTip(tr("View ROM")); + viewROM->setCheckable(true); + connect(viewROM, SIGNAL(triggered()), this, SLOT(setViewROM(void)) ); + + group->addAction(viewROM); + viewMenu->addAction(viewROM); + + viewRAM->setChecked(true); // Set default view + + // Color Menu + colorMenu = menuBar->addMenu(tr("Color")); + + // Color -> Highlight Activity + actHlgt = new QAction(tr("Highlight Activity"), this); + //actHlgt->setShortcuts(QKeySequence::Open); + actHlgt->setStatusTip(tr("Highlight Activity")); + actHlgt->setCheckable(true); + actHlgt->setChecked(true); + connect(actHlgt, SIGNAL(triggered(bool)), this, SLOT(actvHighlightCB(bool)) ); + + colorMenu->addAction(actHlgt); + + // Color -> Highlight Reverse Video + actHlgtRV = new QAction(tr("Highlight Reverse Video"), this); + //actHlgtRV->setShortcuts(QKeySequence::Open); + actHlgtRV->setStatusTip(tr("Highlight Reverse Video")); + actHlgtRV->setCheckable(true); + actHlgtRV->setChecked(true); + connect(actHlgtRV, SIGNAL(triggered(bool)), this, SLOT(actvHighlightRVCB(bool)) ); + + colorMenu->addAction(actHlgtRV); + + // Color -> ForeGround Color + actColorFG = new QAction(tr("ForeGround Color"), this); + //actColorFG->setShortcuts(QKeySequence::Open); + actColorFG->setStatusTip(tr("ForeGround Color")); + connect(actColorFG, SIGNAL(triggered(void)), this, SLOT(pickForeGroundColor(void)) ); + + colorMenu->addAction(actColorFG); + + // Color -> BackGround Color + actColorBG = new QAction(tr("BackGround Color"), this); + //actColorBG->setShortcuts(QKeySequence::Open); + actColorBG->setStatusTip(tr("BackGround Color")); + connect(actColorBG, SIGNAL(triggered(void)), this, SLOT(pickBackGroundColor(void)) ); + + colorMenu->addAction(actColorBG); + + // Bookmarks Menu + bookmarkMenu = menuBar->addMenu(tr("Bookmarks")); + + populateBookmarkMenu(); + + //----------------------------------------------------------------------- + // Menu End + //----------------------------------------------------------------------- + //mainLayout = new QVBoxLayout(); + + grid = new QGridLayout(this); + editor = new QHexEdit(this); + vbar = new QScrollBar( Qt::Vertical, this ); + hbar = new QScrollBar( Qt::Horizontal, this ); + + grid->setMenuBar( menuBar ); + + grid->addWidget( editor, 0, 0 ); + grid->addWidget( vbar , 0, 1 ); + grid->addWidget( hbar , 1, 0 ); + //mainLayout->addLayout( grid ); + + setLayout( grid ); + + hbar->setMinimum(0); + hbar->setMaximum(100); + vbar->setMinimum(0); + vbar->setMaximum( 0x10000 / 16 ); + + editor->setScrollBars( hbar, vbar ); + + //connect( vbar, SIGNAL(sliderMoved(int)), this, SLOT(vbarMoved(int)) ); + connect( hbar, SIGNAL(valueChanged(int)), this, SLOT(hbarChanged(int)) ); + connect( vbar, SIGNAL(valueChanged(int)), this, SLOT(vbarChanged(int)) ); + + editor->memModeUpdate(); + + periodicTimer = new QTimer( this ); + + connect( periodicTimer, &QTimer::timeout, this, &HexEditorDialog_t::updatePeriodic ); + + periodicTimer->start( 100 ); // 10hz +} +//---------------------------------------------------------------------------- +HexEditorDialog_t::~HexEditorDialog_t(void) +{ + printf("Hex Editor Deleted\n"); + periodicTimer->stop(); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::populateBookmarkMenu(void) +{ + QAction *act; + + bookmarkMenu->clear(); + + // Bookmarks -> Remove All Bookmarks + act = new QAction(tr("Remove All Bookmarks"), this); + //act->setShortcuts(QKeySequence::Open); + act->setStatusTip(tr("Remove All Bookmarks")); + //connect(act, SIGNAL(triggered(void)), this, SLOT(pickBackGroundColor(void)) ); + + bookmarkMenu->addAction(act); + bookmarkMenu->addSeparator(); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::closeEvent(QCloseEvent *event) +{ + printf("Hex Editor Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::closeWindow(void) +{ + //printf("Close Window\n"); + done(0); + deleteLater(); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::pickForeGroundColor(void) +{ + int ret; + QColorDialog dialog( this ); + + dialog.setOption( QColorDialog::DontUseNativeDialog, true ); + dialog.show(); + ret = dialog.exec(); + + if ( ret == QDialog::Accepted ) + { + editor->setForeGroundColor( dialog.selectedColor() ); + } +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::pickBackGroundColor(void) +{ + int ret; + QColorDialog dialog( this ); + + dialog.setOption( QColorDialog::DontUseNativeDialog, true ); + dialog.show(); + ret = dialog.exec(); + + if ( ret == QDialog::Accepted ) + { + editor->setBackGroundColor( dialog.selectedColor() ); + } +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::vbarMoved(int value) +{ + //printf("VBar Moved: %i\n", value); + editor->setLine( value ); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::vbarChanged(int value) +{ + //printf("VBar Changed: %i\n", value); + editor->setLine( value ); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::hbarChanged(int value) +{ + //printf("HBar Changed: %i\n", value); + editor->setHorzScroll( value ); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::gotoAddress( int newAddr ) +{ + editor->setAddr( newAddr ); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::saveRomFile(void) +{ + //FlushUndoBuffer(); + iNesSave(); + //UpdateColorTable(); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::saveRomFileAs(void) +{ + int ret, useNativeFileDialogVal; + QString filename; + QFileDialog dialog(this, tr("Save ROM To File") ); + + dialog.setFileMode(QFileDialog::AnyFile); + + dialog.setNameFilter(tr("NES Files (*.nes *.NES) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + dialog.setFilter( QDir::AllEntries | QDir::Hidden ); + dialog.setLabelText( QFileDialog::Accept, tr("Save") ); + dialog.setDefaultSuffix( tr(".nes") ); + + // Check config option to use native file dialog or not + g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal); + + dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal); + + dialog.show(); + ret = dialog.exec(); + + if ( ret ) + { + QStringList fileList; + fileList = dialog.selectedFiles(); + + if ( fileList.size() > 0 ) + { + filename = fileList[0]; + } + } + + if ( filename.isNull() ) + { + return; + } + qDebug() << "selected file path : " << filename.toUtf8(); + + iNesSaveAs( filename.toStdString().c_str() ); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::setViewRAM(void) +{ + editor->setMode( QHexEdit::MODE_NES_RAM ); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::setViewPPU(void) +{ + editor->setMode( QHexEdit::MODE_NES_PPU ); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::setViewOAM(void) +{ + editor->setMode( QHexEdit::MODE_NES_OAM ); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::setViewROM(void) +{ + editor->setMode( QHexEdit::MODE_NES_ROM ); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::actvHighlightCB(bool enable) +{ + //printf("Highlight: %i \n", enable ); + editor->setHighlightActivity( enable ); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::actvHighlightRVCB(bool enable) +{ + //printf("Highlight: %i \n", enable ); + editor->setHighlightReverseVideo( enable ); +} +//---------------------------------------------------------------------------- +void HexEditorDialog_t::updatePeriodic(void) +{ + //printf("Update Periodic\n"); + + editor->checkMemActivity(); + + editor->memModeUpdate(); + + editor->update(); +} +//---------------------------------------------------------------------------- +QHexEdit::QHexEdit(QWidget *parent) + : QWidget( parent ) +{ + QPalette pal; + + this->setFocusPolicy(Qt::StrongFocus); + + font.setFamily("Courier New"); + font.setStyle( QFont::StyleNormal ); + font.setStyleHint( QFont::Monospace ); + + pal = this->palette(); + pal.setColor(QPalette::Base , Qt::black); + pal.setColor(QPalette::Background, Qt::black); + pal.setColor(QPalette::WindowText, Qt::white); + + //editor->setAutoFillBackground(true); + this->setPalette(pal); + + calcFontData(); + + memAccessFunc = getRAM; + viewMode = MODE_NES_RAM; + lineOffset = 0; + cursorPosX = 0; + cursorPosY = 0; + cursorBlink = true; + cursorBlinkCount = 0; + maxLineOffset = 0; + editAddr = -1; + editValue = 0; + editMask = 0; + reverseVideo = true; + actvHighlightEnable = true; + total_instructions_lp = 0; + pxLineXScroll = 0; + + highLightColor[ 0].setRgb( 0x00, 0x00, 0x00 ); + highLightColor[ 1].setRgb( 0x35, 0x40, 0x00 ); + highLightColor[ 2].setRgb( 0x18, 0x52, 0x18 ); + highLightColor[ 3].setRgb( 0x34, 0x5C, 0x5E ); + highLightColor[ 4].setRgb( 0x00, 0x4C, 0x80 ); + highLightColor[ 5].setRgb( 0x00, 0x03, 0xBA ); + highLightColor[ 6].setRgb( 0x38, 0x00, 0xD1 ); + highLightColor[ 7].setRgb( 0x72, 0x12, 0xB2 ); + highLightColor[ 8].setRgb( 0xAB, 0x00, 0xBA ); + highLightColor[ 9].setRgb( 0xB0, 0x00, 0x6F ); + highLightColor[10].setRgb( 0xC2, 0x00, 0x37 ); + highLightColor[11].setRgb( 0xBA, 0x0C, 0x00 ); + highLightColor[12].setRgb( 0xC9, 0x2C, 0x00 ); + highLightColor[13].setRgb( 0xBF, 0x53, 0x00 ); + highLightColor[14].setRgb( 0xCF, 0x72, 0x00 ); + highLightColor[15].setRgb( 0xC7, 0x8B, 0x3C ); + + for (int i=0; i= 0.5 ) + { + grayScale = 0.0; + } + else + { + grayScale = 1.0; + } + rvActvTextColor[i].setRgbF( grayScale, grayScale, grayScale ); + } +} +//---------------------------------------------------------------------------- +QHexEdit::~QHexEdit(void) +{ + +} +//---------------------------------------------------------------------------- +void QHexEdit::calcFontData(void) +{ + this->setFont(font); + QFontMetrics metrics(font); +#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0) + pxCharWidth = metrics.horizontalAdvance(QLatin1Char('2')); +#else + pxCharWidth = metrics.width(QLatin1Char('2')); +#endif + pxCharHeight = metrics.height(); + pxLineSpacing = metrics.lineSpacing() * 1.25; + pxLineLead = pxLineSpacing - pxCharHeight; + pxXoffset = pxCharWidth; + pxYoffset = pxLineSpacing * 2.0; + pxHexOffset = pxXoffset + (7*pxCharWidth); + pxHexAscii = pxHexOffset + (16*3*pxCharWidth) + (pxCharWidth); + pxLineWidth = pxHexAscii + (17*pxCharWidth); + //_pxGapAdr = _pxCharWidth / 2; + //_pxGapAdrHex = _pxCharWidth; + //_pxGapHexAscii = 2 * _pxCharWidth; + pxCursorHeight = pxCharHeight; + //_pxSelectionSub = _pxCharHeight / 5; + viewLines = (viewHeight - pxLineSpacing) / pxLineSpacing; +} +//---------------------------------------------------------------------------- +void QHexEdit::setHighlightActivity( int enable ) +{ + actvHighlightEnable = enable; +} +//---------------------------------------------------------------------------- +void QHexEdit::setHighlightReverseVideo( int enable ) +{ + reverseVideo = enable; +} +//---------------------------------------------------------------------------- +void QHexEdit::setForeGroundColor( QColor fg ) +{ + QPalette pal; + + pal = this->palette(); + //pal.setColor(QPalette::Base , Qt::black); + //pal.setColor(QPalette::Background, Qt::black); + pal.setColor(QPalette::WindowText, fg ); + + this->setPalette(pal); +} +//---------------------------------------------------------------------------- +void QHexEdit::setBackGroundColor( QColor bg ) +{ + QPalette pal; + + pal = this->palette(); + //pal.setColor(QPalette::Base , Qt::black); + pal.setColor(QPalette::Background, bg ); + //pal.setColor(QPalette::WindowText, fg ); + + this->setPalette(pal); +} +//---------------------------------------------------------------------------- +void QHexEdit::setMode( int mode ) +{ + if ( viewMode != mode ) + { + viewMode = mode; + memModeUpdate(); + } +} +//---------------------------------------------------------------------------- +void QHexEdit::setLine( int newLineOffset ) +{ + lineOffset = newLineOffset; +} +//---------------------------------------------------------------------------- +void QHexEdit::setAddr( int newAddr ) +{ + int addr; + lineOffset = newAddr / 16; + + if ( lineOffset < 0 ) + { + lineOffset = 0; + } + else if ( lineOffset >= maxLineOffset ) + { + lineOffset = maxLineOffset; + } + + addr = 16*lineOffset; + + cursorPosX = 2*((newAddr - addr)%16); + cursorPosY = (newAddr - addr)/16; +} +//---------------------------------------------------------------------------- +void QHexEdit::setHorzScroll( int value ) +{ + float f; + //printf("Value: %i \n", value); + + if ( viewWidth >= pxLineWidth ) + { + f = 0.0; + } + else + { + f = 0.010f * (float)value * (float)(pxLineWidth - viewWidth); + } + + pxLineXScroll = (int)f; +} +//---------------------------------------------------------------------------- +void QHexEdit::setScrollBars( QScrollBar *h, QScrollBar *v ) +{ + hbar = h; vbar = v; +} +//---------------------------------------------------------------------------- +void QHexEdit::resizeEvent(QResizeEvent *event) +{ + viewWidth = event->size().width(); + viewHeight = event->size().height(); + + //printf("QHexEdit Resize: %ix%i\n", viewWidth, viewHeight ); + + viewLines = (viewHeight - pxLineSpacing) / pxLineSpacing; + + maxLineOffset = mb.numLines() - viewLines + 1; + + if ( viewWidth >= pxLineWidth ) + { + pxLineXScroll = 0; + } + else + { + pxLineXScroll = (int)(0.010f * (float)hbar->value() * (float)(pxLineWidth - viewWidth) ); + } + +} +//---------------------------------------------------------------------------- +void QHexEdit::resetCursor(void) +{ + cursorBlink = true; + cursorBlinkCount = 0; + editAddr = -1; + editValue = 0; + editMask = 0; +} +//---------------------------------------------------------------------------- +QPoint QHexEdit::convPixToCursor( QPoint p ) +{ + QPoint c(0,0); + + //printf("Pos: %ix%i \n", p.x(), p.y() ); + + p.setX( p.x() + pxLineXScroll ); + + if ( p.x() < pxHexOffset ) + { + c.setX(0); + } + else if ( (p.x() >= pxHexOffset) && (p.x() < pxHexAscii) ) + { + float px = ( (float)p.x() - (float)pxHexOffset) / (float)(pxCharWidth); + float ox = (px/3.0); + float rx = fmodf(px,3.0); + + if ( rx >= 2.50 ) + { + c.setX( 2*( (int)ox + 1 ) ); + } + else + { + //if ( rx >= 1.0 ) + //{ + // c.setX( 2*( (int)ox ) + 1 ); + //} + //else + //{ + c.setX( 2*( (int)ox ) ); + //} + } + } + else + { + c.setX( 32 + (p.x() - pxHexAscii) / pxCharWidth ); + } + if ( c.x() >= 48 ) + { + c.setX( 47 ); + } + + if ( p.y() < pxYoffset ) + { + c.setY( 0 ); + } + else + { + float ly = ( (float)pxLineLead / (float)pxLineSpacing ); + float py = ( (float)p.y() - (float)pxLineSpacing) / (float)pxLineSpacing; + float ry = fmod( py, 1.0 ); + + if ( ry < ly ) + { + c.setY( ((int)py) - 1 ); + } + else + { + c.setY( (int)py ); + } + } + if ( c.y() < 0 ) + { + c.setY(0); + } + else if ( c.y() >= viewLines ) + { + c.setY( viewLines - 1 ); + } + //printf("c: %ix%i \n", cx, cy ); + // + + return c; +} +//---------------------------------------------------------------------------- +int QHexEdit::convPixToAddr( QPoint p ) +{ + int a,addr; + QPoint c = convPixToCursor(p); + + //printf("Cursor: %ix%i\n", c.x(), c.y() ); + + if ( c.x() < 32 ) + { + a = (c.x() / 2); + + addr = 16*(lineOffset + c.y()) + a; + } + else + { + a = (c.x()-32); + + addr = 16*(lineOffset + c.y()) + a; + } + return addr; +} +//---------------------------------------------------------------------------- +void QHexEdit::keyPressEvent(QKeyEvent *event) +{ + printf("Hex Window Key Press: 0x%x \n", event->key() ); + + if (event->matches(QKeySequence::MoveToNextChar)) + { + if ( cursorPosX < 32 ) + { + if ( cursorPosX % 2 ) + { + cursorPosX++; + } + else + { + cursorPosX += 2; + } + } + else + { + cursorPosX++; + } + if ( cursorPosX >= 48 ) + { + cursorPosX = 47; + } + resetCursor(); + } + else if (event->matches(QKeySequence::MoveToPreviousChar)) + { + if ( cursorPosX < 33 ) + { + if ( cursorPosX % 2 ) + { + cursorPosX -= 3; + } + else + { + cursorPosX -= 2; + } + } + else + { + cursorPosX--; + } + if ( cursorPosX < 0 ) + { + cursorPosX = 0; + } + resetCursor(); + } + else if (event->matches(QKeySequence::MoveToEndOfLine)) + { + cursorPosX = 47; + resetCursor(); + } + else if (event->matches(QKeySequence::MoveToStartOfLine)) + { + cursorPosX = 0; + resetCursor(); + } + else if (event->matches(QKeySequence::MoveToPreviousLine)) + { + cursorPosY--; + + if ( cursorPosY < 0 ) + { + lineOffset--; + + if ( lineOffset < 0 ) + { + lineOffset = 0; + } + cursorPosY = 0; + + vbar->setValue( lineOffset ); + } + resetCursor(); + } + else if (event->matches(QKeySequence::MoveToNextLine)) + { + cursorPosY++; + + if ( cursorPosY >= viewLines ) + { + lineOffset++; + + if ( lineOffset >= maxLineOffset ) + { + lineOffset = maxLineOffset; + } + cursorPosY = viewLines-1; + + vbar->setValue( lineOffset ); + } + resetCursor(); + + } + else if (event->matches(QKeySequence::MoveToNextPage)) + { + lineOffset += ( (3 * viewLines) / 4); + + if ( lineOffset >= maxLineOffset ) + { + lineOffset = maxLineOffset; + } + vbar->setValue( lineOffset ); + resetCursor(); + } + else if (event->matches(QKeySequence::MoveToPreviousPage)) + { + lineOffset -= ( (3 * viewLines) / 4); + + if ( lineOffset < 0 ) + { + lineOffset = 0; + } + vbar->setValue( lineOffset ); + resetCursor(); + } + else if (event->matches(QKeySequence::MoveToEndOfDocument)) + { + lineOffset = maxLineOffset; + vbar->setValue( lineOffset ); + resetCursor(); + } + else if (event->matches(QKeySequence::MoveToStartOfDocument)) + { + lineOffset = 0; + vbar->setValue( lineOffset ); + resetCursor(); + } + else if (event->key() == Qt::Key_Tab && (cursorPosX < 32) ) + { // switch from hex to ascii edit + cursorPosX = 32 + (cursorPosX / 2); + } + else if (event->key() == Qt::Key_Backtab && (cursorPosX >= 32) ) + { // switch from ascii to hex edit + cursorPosX = 2 * (cursorPosX - 32); + } + else + { + int key; + if ( cursorPosX >= 32 ) + { // Edit Area is ASCII + key = (uchar)event->text()[0].toLatin1(); + + if ( ::isascii( key ) ) + { + int offs = (cursorPosX-32); + int addr = 16*(lineOffset+cursorPosY) + offs; + fceuWrapperLock(); + writeMem( viewMode, addr, key ); + fceuWrapperUnLock(); + + editAddr = -1; + editValue = 0; + editMask = 0; + } + } + else + { // Edit Area is Hex + key = int(event->text()[0].toUpper().toLatin1()); + + if ( ::isxdigit( key ) ) + { + int offs, nibbleValue, nibbleIndex; + + offs = (cursorPosX / 2); + nibbleIndex = (cursorPosX % 2); + + editAddr = 16*(lineOffset+cursorPosY) + offs; + + nibbleValue = convFromXchar( key ); + + if ( nibbleIndex ) + { + nibbleValue = editValue | nibbleValue; + + fceuWrapperLock(); + writeMem( viewMode, editAddr, nibbleValue ); + fceuWrapperUnLock(); + + editAddr = -1; + editValue = 0; + editMask = 0; + } + else + { + editValue = (nibbleValue << 4); + editMask = 0x00f0; + } + cursorPosX++; + + if ( cursorPosX >= 32 ) + { + cursorPosX = 0; + } + } + } + //printf("Key: %c %i \n", key, key); + } +} +//---------------------------------------------------------------------------- +void QHexEdit::keyReleaseEvent(QKeyEvent *event) +{ + printf("Hex Window Key Release: 0x%x \n", event->key() ); + //assignHotkey( event ); +} +//---------------------------------------------------------------------------- +void QHexEdit::mousePressEvent(QMouseEvent * event) +{ + QPoint c = convPixToCursor( event->pos() ); + + //printf("c: %ix%i \n", c.x(), c.y() ); + + if ( event->button() == Qt::LeftButton ) + { + cursorPosX = c.x(); + cursorPosY = c.y(); + resetCursor(); + } + +} +//---------------------------------------------------------------------------- +void QHexEdit::contextMenuEvent(QContextMenuEvent *event) +{ + QAction *act; + QMenu menu(this); + int addr; + char stmp[128]; + + addr = convPixToAddr( event->pos() ); + //printf("contextMenuEvent\n"); + + switch ( viewMode ) + { + case MODE_NES_RAM: + { + act = new QAction(tr("TODO Add Symbolic Debug Name"), this); + menu.addAction(act); + + sprintf( stmp, "TODO Add Read Breakpoint for Address $%04X", addr ); + act = new QAction(tr(stmp), this); + menu.addAction(act); + + sprintf( stmp, "TODO Add Write Breakpoint for Address $%04X", addr ); + act = new QAction(tr(stmp), this); + menu.addAction(act); + + sprintf( stmp, "TODO Add Execute Breakpoint for Address $%04X", addr ); + act = new QAction(tr(stmp), this); + menu.addAction(act); + + if ( addr > 0x6000 ) + { + int romAddr = GetNesFileAddress(addr); + + if ( romAddr >= 0 ) + { + jumpToRomValue = romAddr; + sprintf( stmp, "Go Here in ROM File: (%08X)", romAddr ); + act = new QAction(tr(stmp), this); + menu.addAction(act); + connect( act, SIGNAL(triggered(void)), this, SLOT(jumpToROM(void)) ); + } + } + + act = new QAction(tr("TODO Add Bookmark"), this); + menu.addAction(act); + } + break; + case MODE_NES_PPU: + { + act = new QAction(tr("TODO Add Bookmark"), this); + menu.addAction(act); + } + break; + case MODE_NES_OAM: + { + act = new QAction(tr("TODO Add Bookmark"), this); + menu.addAction(act); + } + break; + case MODE_NES_ROM: + { + act = new QAction(tr("TODO Add Bookmark"), this); + menu.addAction(act); + } + break; + } + + menu.exec(event->globalPos()); + +} +//---------------------------------------------------------------------------- +void QHexEdit::jumpToROM(void) +{ + setMode( MODE_NES_ROM ); + + maxLineOffset = mb.numLines() - viewLines + 1; + + if ( lineOffset > maxLineOffset ) + { + lineOffset = maxLineOffset; + } + setAddr( jumpToRomValue ); +} +//---------------------------------------------------------------------------- +int QHexEdit::checkMemActivity(void) +{ + int c; + + // Don't perform memory activity checks when: + // 1. In ROM View Mode + // 2. The simulation is not cycling (paused) + + if ( ( viewMode == MODE_NES_ROM ) || + ( total_instructions_lp == total_instructions ) ) + { + return -1; + } + + for (int i=0; i 0 ) + { + //mb.buf[i].draw = 1; + mb.buf[i].actv--; + } + } + } + total_instructions_lp = total_instructions; + + return 0; +} +//---------------------------------------------------------------------------- +void QHexEdit::memModeUpdate(void) +{ + int memSize; + + switch ( getMode() ) + { + default: + case MODE_NES_RAM: + memAccessFunc = getRAM; + memSize = 0x10000; + break; + case MODE_NES_PPU: + memAccessFunc = getPPU; + if ( GameInfo ) + { + memSize = (GameInfo->type == GIT_NSF ? 0x2000 : 0x4000); + } + else + { + memSize = 0x4000; + } + break; + case MODE_NES_OAM: + memAccessFunc = getOAM; + memSize = 0x100; + break; + case MODE_NES_ROM: + + if ( GameInfo != NULL ) + { + memAccessFunc = getROM; + memSize = 16 + CHRsize[0] + PRGsize[0]; + } + else + { // No Game Loaded!!! Get out of Function + memAccessFunc = NULL; + memSize = 0; + return; + } + break; + } + + if ( memSize != mb.size() ) + { + mb.setAccessFunc( memAccessFunc ); + + if ( mb.reAlloc( memSize ) ) + { + printf("Error: Failed to allocate memview buffer size\n"); + return; + } + } +} +//---------------------------------------------------------------------------- +void QHexEdit::paintEvent(QPaintEvent *event) +{ + int x, y, w, h, row, col, nrow, addr; + int c, cx, cy, ca; + char txt[32], asciiTxt[4]; + QPainter painter(this); + + painter.setFont(font); + w = event->rect().width(); + h = event->rect().height(); + + viewWidth = w; + viewHeight = h; + //painter.fillRect( 0, 0, w, h, QColor("white") ); + + nrow = (h - pxLineSpacing) / pxLineSpacing; + + if ( nrow < 1 ) nrow = 1; + + viewLines = nrow; + + if ( cursorPosY >= viewLines ) + { + cursorPosY = viewLines-1; + } + //printf("Draw Area: %ix%i \n", event->rect().width(), event->rect().height() ); + // + maxLineOffset = mb.numLines() - nrow + 1; + + if ( lineOffset > maxLineOffset ) + { + lineOffset = maxLineOffset; + } + + painter.fillRect( 0, 0, w, h, this->palette().color(QPalette::Background) ); + + if ( cursorBlinkCount >= 5 ) + { + cursorBlink = !cursorBlink; + cursorBlinkCount = 0; + } + else + { + cursorBlinkCount++; + } + + cy = pxYoffset + (pxLineSpacing*cursorPosY) - pxCursorHeight + pxLineLead; + + if ( cursorPosX < 32 ) + { + int a = (cursorPosX / 2); + int r = (cursorPosX % 2); + cx = pxHexOffset + (a*3*pxCharWidth) + (r*pxCharWidth) - pxLineXScroll; + + ca = 16*(lineOffset + cursorPosY) + a; + } + else + { + int a = (cursorPosX-32); + cx = pxHexAscii + (a*pxCharWidth) - pxLineXScroll; + + ca = 16*(lineOffset + cursorPosY) + a; + } + + if ( cursorBlink ) + { + painter.fillRect( cx , cy, pxCharWidth, pxCursorHeight, QColor("gray") ); + } + + painter.setPen( this->palette().color(QPalette::WindowText)); + + //painter.setPen( QColor("white") ); + addr = lineOffset * 16; + y = pxYoffset; + + for ( row=0; row < nrow; row++) + { + x = pxXoffset - pxLineXScroll; + + painter.setPen( this->palette().color(QPalette::WindowText)); + sprintf( txt, "%06X", addr ); + painter.drawText( x, y, tr(txt) ); + + x = pxHexOffset - pxLineXScroll; + + for (col=0; col<16; col++) + { + if ( addr < mb.size() ) + { + c = mb.buf[addr].data; + + if ( ::isprint(c) ) + { + asciiTxt[0] = c; + } + else + { + asciiTxt[0] = '.'; + } + asciiTxt[1] = 0; + + if ( addr == editAddr ) + { // Set a cell currently being editting to red text + painter.setPen( QColor("red") ); + txt[0] = convToXchar( (editValue >> 4) & 0x0F ); + txt[1] = convToXchar( c & 0x0F ); + txt[2] = 0; + painter.drawText( x, y, tr(txt) ); + painter.setPen( this->palette().color(QPalette::WindowText)); + } + 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)); + } + txt[0] = convToXchar( (c >> 4) & 0x0F ); + txt[1] = convToXchar( c & 0x0F ); + txt[2] = 0; + + if ( cursorBlink && (ca == addr) ) + { + painter.fillRect( cx , cy, pxCharWidth, pxCursorHeight, QColor("gray") ); + } + painter.drawText( x, y, tr(txt) ); + painter.drawText( pxHexAscii + (col*pxCharWidth) - pxLineXScroll, y, tr(asciiTxt) ); + } + } + x += (3*pxCharWidth); + addr++; + } + + //addr += 16; + y += pxLineSpacing; + } + + painter.setPen( this->palette().color(QPalette::WindowText)); + painter.drawText( pxHexOffset - pxLineXScroll, pxLineSpacing, "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F" ); + painter.drawLine( pxHexOffset - (pxCharWidth/2) - pxLineXScroll, 0, pxHexOffset - (pxCharWidth/2) - pxLineXScroll, h ); + painter.drawLine( pxHexAscii - (pxCharWidth/2) - pxLineXScroll, 0, pxHexAscii - (pxCharWidth/2) - pxLineXScroll, h ); + painter.drawLine( 0, pxLineSpacing + (pxLineLead), w, pxLineSpacing + (pxLineLead) ); + +} +//---------------------------------------------------------------------------- diff --git a/src/drivers/Qt/HexEditor.h b/src/drivers/Qt/HexEditor.h new file mode 100644 index 00000000..a2f7079a --- /dev/null +++ b/src/drivers/Qt/HexEditor.h @@ -0,0 +1,171 @@ +// GamePadConf.h +// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct memByte_t +{ + unsigned char data; + unsigned char color; + unsigned char actv; +}; + +struct memBlock_t +{ + memBlock_t(void); + ~memBlock_t(void); + + void init(void); + int size(void){ return _size; } + int numLines(void){ return _maxLines; } + int reAlloc( int newSize ); + void setAccessFunc( int (*newMemAccessFunc)( unsigned int offset) ); + + struct memByte_t *buf; + int _size; + int _maxLines; + int (*memAccessFunc)( unsigned int offset); +}; + +class QHexEdit : public QWidget +{ + Q_OBJECT + + public: + QHexEdit(QWidget *parent = 0); + ~QHexEdit(void); + + int getMode(void){ return viewMode; }; + void setMode( int mode ); + void setLine( int newLineOffset ); + void setAddr( int newAddrOffset ); + void setScrollBars( QScrollBar *h, QScrollBar *v ); + void setHorzScroll( int value ); + void setHighlightActivity( int enable ); + void setHighlightReverseVideo( int enable ); + void setForeGroundColor( QColor fg ); + void setBackGroundColor( QColor bg ); + void memModeUpdate(void); + int checkMemActivity(void); + + enum { + MODE_NES_RAM = 0, + MODE_NES_PPU, + MODE_NES_OAM, + MODE_NES_ROM + }; + static const int HIGHLIGHT_ACTIVITY_NUM_COLORS = 16; + protected: + void paintEvent(QPaintEvent *event); + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *event); + void mousePressEvent(QMouseEvent * event); + void resizeEvent(QResizeEvent *event); + void contextMenuEvent(QContextMenuEvent *event); + + void calcFontData(void); + void resetCursor(void); + QPoint convPixToCursor( QPoint p ); + int convPixToAddr( QPoint p ); + + QFont font; + + memBlock_t mb; + int (*memAccessFunc)( unsigned int offset); + + QScrollBar *vbar; + QScrollBar *hbar; + QColor highLightColor[ HIGHLIGHT_ACTIVITY_NUM_COLORS ]; + QColor rvActvTextColor[ HIGHLIGHT_ACTIVITY_NUM_COLORS ]; + + uint64_t total_instructions_lp; + + int viewMode; + int lineOffset; + int pxCharWidth; + int pxCharHeight; + int pxCursorHeight; + int pxLineSpacing; + int pxLineLead; + int pxLineWidth; + int pxLineXScroll; + int pxXoffset; + int pxYoffset; + int pxHexOffset; + int pxHexAscii; + int cursorPosX; + int cursorPosY; + int cursorBlinkCount; + int viewLines; + int viewWidth; + int viewHeight; + int maxLineOffset; + int editAddr; + int editValue; + int editMask; + int jumpToRomValue; + + bool cursorBlink; + bool reverseVideo; + bool actvHighlightEnable; + + private slots: + void jumpToROM(void); + +}; + +class HexEditorDialog_t : public QDialog +{ + Q_OBJECT + + public: + HexEditorDialog_t(QWidget *parent = 0); + ~HexEditorDialog_t(void); + + protected: + void closeEvent(QCloseEvent *bar); + + void gotoAddress(int newAddr); + void populateBookmarkMenu(void); + + QScrollBar *vbar; + QScrollBar *hbar; + QHexEdit *editor; + QTimer *periodicTimer; + QMenu *bookmarkMenu; + + private: + + public slots: + void closeWindow(void); + private slots: + void updatePeriodic(void); + void vbarMoved(int value); + void vbarChanged(int value); + void hbarChanged(int value); + void saveRomFile(void); + void saveRomFileAs(void); + void setViewRAM(void); + void setViewPPU(void); + void setViewOAM(void); + void setViewROM(void); + void actvHighlightCB(bool value); + void actvHighlightRVCB(bool value); + void pickForeGroundColor(void); + void pickBackGroundColor(void); +}; diff --git a/src/drivers/Qt/HotKeyConf.cpp b/src/drivers/Qt/HotKeyConf.cpp index 13c33f1c..d1db2131 100644 --- a/src/drivers/Qt/HotKeyConf.cpp +++ b/src/drivers/Qt/HotKeyConf.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "Qt/main.h" #include "Qt/dface.h" @@ -68,13 +69,22 @@ HotKeyConfDialog_t::HotKeyConfDialog_t(QWidget *parent) //---------------------------------------------------------------------------- HotKeyConfDialog_t::~HotKeyConfDialog_t(void) { - + printf("Destroy Hot Key Config Window\n"); +} +//---------------------------------------------------------------------------- +void HotKeyConfDialog_t::closeEvent(QCloseEvent *event) +{ + printf("Hot Key Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); } //---------------------------------------------------------------------------- void HotKeyConfDialog_t::closeWindow(void) { //printf("Close Window\n"); done(0); + deleteLater(); } //---------------------------------------------------------------------------- void HotKeyConfDialog_t::assignHotkey(QKeyEvent *event) diff --git a/src/drivers/Qt/HotKeyConf.h b/src/drivers/Qt/HotKeyConf.h index cba35cee..bf9c8a8f 100644 --- a/src/drivers/Qt/HotKeyConf.h +++ b/src/drivers/Qt/HotKeyConf.h @@ -27,6 +27,7 @@ class HotKeyConfDialog_t : public QDialog ~HotKeyConfDialog_t(void); protected: + void closeEvent(QCloseEvent *event); void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); void assignHotkey(QKeyEvent *event); diff --git a/src/drivers/Qt/LuaControl.cpp b/src/drivers/Qt/LuaControl.cpp index 28e1bcff..2aa40271 100644 --- a/src/drivers/Qt/LuaControl.cpp +++ b/src/drivers/Qt/LuaControl.cpp @@ -102,6 +102,8 @@ LuaControlDialog_t::~LuaControlDialog_t(void) { std::list ::iterator it; + printf("Destroy Lua Control Window\n"); + for (it = winList.begin(); it != winList.end(); it++) { if ( (*it) == this ) @@ -113,10 +115,19 @@ LuaControlDialog_t::~LuaControlDialog_t(void) } } //---------------------------------------------------- +void LuaControlDialog_t::closeEvent(QCloseEvent *event) +{ + printf("Lua Control Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); +} +//---------------------------------------------------- void LuaControlDialog_t::closeWindow(void) { - //printf("Close Window\n"); + //printf("Lua Control Close Window\n"); done(0); + deleteLater(); } //---------------------------------------------------- void LuaControlDialog_t::openLuaScriptFile(void) diff --git a/src/drivers/Qt/LuaControl.h b/src/drivers/Qt/LuaControl.h index 824f52fa..522e686a 100644 --- a/src/drivers/Qt/LuaControl.h +++ b/src/drivers/Qt/LuaControl.h @@ -29,6 +29,8 @@ class LuaControlDialog_t : public QDialog void refreshState(void); protected: + void closeEvent(QCloseEvent *bar); + QLineEdit *scriptPath; QLineEdit *scriptArgs; QPushButton *browseButton; diff --git a/src/drivers/Qt/PaletteConf.cpp b/src/drivers/Qt/PaletteConf.cpp index 2adbe66e..d799b8ca 100644 --- a/src/drivers/Qt/PaletteConf.cpp +++ b/src/drivers/Qt/PaletteConf.cpp @@ -148,13 +148,22 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent) //---------------------------------------------------- PaletteConfDialog_t::~PaletteConfDialog_t(void) { - + printf("Destroy Palette Config Window\n"); +} +//---------------------------------------------------------------------------- +void PaletteConfDialog_t::closeEvent(QCloseEvent *event) +{ + printf("Palette Config Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); } //---------------------------------------------------- void PaletteConfDialog_t::closeWindow(void) { //printf("Close Window\n"); done(0); + deleteLater(); } //---------------------------------------------------- void PaletteConfDialog_t::hueChanged(int v) diff --git a/src/drivers/Qt/PaletteConf.h b/src/drivers/Qt/PaletteConf.h index 494d78aa..5b28d9c0 100644 --- a/src/drivers/Qt/PaletteConf.h +++ b/src/drivers/Qt/PaletteConf.h @@ -26,6 +26,8 @@ class PaletteConfDialog_t : public QDialog ~PaletteConfDialog_t(void); protected: + void closeEvent(QCloseEvent *event); + QLineEdit *custom_palette_path; QCheckBox *useCustom; QCheckBox *GrayScale; diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index cfbbb98b..a8dcad5f 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -104,7 +104,8 @@ void FCEUD_PrintError(const char *errormsg) */ FILE *FCEUD_UTF8fopen(const char *fn, const char *mode) { - return(fopen(fn,mode)); + FILE *fp = ::fopen(fn,mode); + return(fp); } /** diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index ce2bf93b..1510857b 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -1570,6 +1570,7 @@ const char * ButtonName (const ButtConfig * bc) { int joyNum, inputNum; const char *inputType, *inputDirection; + char direction[128] = ""; joyNum = bc->DeviceNum; @@ -1582,7 +1583,6 @@ const char * ButtonName (const ButtConfig * bc) else if (bc->ButtonNum & 0x2000) { int inputValue; - char direction[128] = ""; inputType = "Hat"; inputNum = (bc->ButtonNum >> 8) & 0x1F; diff --git a/src/ines.cpp b/src/ines.cpp index 1b75ae07..00abebeb 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -956,7 +956,7 @@ init_ok: } // bbit edited: the whole function below was added -int iNesSave() { +int iNesSave(void) { char name[2048]; strcpy(name, LoadedRomFName); @@ -967,7 +967,7 @@ int iNesSave() { return iNesSaveAs(name); } -int iNesSaveAs(char* name) +int iNesSaveAs(const char* name) { //adelikat: TODO: iNesSave() and this have pretty much the same code, outsource the common code to a single function //caitsith2: done. iNesSave() now gets filename and calls iNesSaveAs with that filename. diff --git a/src/ines.h b/src/ines.h index 6ad2657b..6f9d65e8 100644 --- a/src/ines.h +++ b/src/ines.h @@ -43,8 +43,8 @@ extern uint8 *VROM; extern uint32 VROM_size; extern uint32 ROM_size; extern uint8 *ExtraNTARAM; -extern int iNesSave(); //bbit Edited: line added -extern int iNesSaveAs(char* name); +extern int iNesSave(void); //bbit Edited: line added +extern int iNesSaveAs(const char* name); extern char LoadedRomFName[2048]; //bbit Edited: line added extern const TMasterRomInfo* MasterRomInfo; extern TMasterRomInfoParams MasterRomInfoParams;