From ab922df318d2a0de753667365cbfe8c0f8667f32 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Wed, 7 Oct 2020 20:35:52 -0400 Subject: [PATCH 01/10] Added initial window layout for Qt RAM Watch window. --- src/CMakeLists.txt | 1 + src/drivers/Qt/CheatsConf.cpp | 15 +- src/drivers/Qt/ConsoleWindow.cpp | 20 +++ src/drivers/Qt/ConsoleWindow.h | 2 + src/drivers/Qt/RamWatch.cpp | 254 +++++++++++++++++++++++++++++++ src/drivers/Qt/RamWatch.h | 51 +++++++ 6 files changed, 333 insertions(+), 10 deletions(-) create mode 100644 src/drivers/Qt/RamWatch.cpp create mode 100644 src/drivers/Qt/RamWatch.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d8083ce5..1f2298a5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -443,6 +443,7 @@ set(SRC_DRIVERS_SDL ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/fceuWrapper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ppuViewer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/NameTableViewer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/RamWatch.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/config.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/input.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/nes_shm.cpp diff --git a/src/drivers/Qt/CheatsConf.cpp b/src/drivers/Qt/CheatsConf.cpp index 18af6258..81dbd037 100644 --- a/src/drivers/Qt/CheatsConf.cpp +++ b/src/drivers/Qt/CheatsConf.cpp @@ -36,14 +36,6 @@ GuiCheatsDialog_t::GuiCheatsDialog_t(QWidget *parent) QLabel *lbl; QGroupBox *groupBox; QFrame *frame; - QScreen *screen = QGuiApplication::primaryScreen(); - double devPixRatio = 1.0f; - - if ( screen != NULL ) - { - devPixRatio = (int)( screen->devicePixelRatio() + 0.50f); - //printf("Pix Ratio: %f \n", devPixRatio ); - } font.setFamily("Courier New"); font.setStyle( QFont::StyleNormal ); @@ -51,8 +43,11 @@ GuiCheatsDialog_t::GuiCheatsDialog_t(QWidget *parent) QFontMetrics fm(font); - //fontCharWidth = fm.boundingRect('X').width() * devPixRatio; - fontCharWidth = 2.00 * fm.averageCharWidth() * devPixRatio; +#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0) + fontCharWidth = 2 * fm.horizontalAdvance(QLatin1Char('2')); +#else + fontCharWidth = 2 * fm.width(QLatin1Char('2')); +#endif setWindowTitle("Cheat Search"); diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 71e206a9..a785e037 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -35,6 +35,7 @@ #include "Qt/fceuWrapper.h" #include "Qt/ppuViewer.h" #include "Qt/NameTableViewer.h" +#include "Qt/RamWatch.h" #include "Qt/keyscan.h" #include "Qt/nes_shm.h" @@ -483,6 +484,14 @@ void consoleWin_t::createMainMenu(void) toolsMenu->addAction(cheatsAct); + // Tools -> RAM Watch + ramWatchAct = new QAction(tr("RAM Watch..."), this); + //ramWatchAct->setShortcut( QKeySequence(tr("Shift+F7"))); + ramWatchAct->setStatusTip(tr("Open RAM Watch Window")); + connect(ramWatchAct, SIGNAL(triggered()), this, SLOT(openRamWatch(void)) ); + + toolsMenu->addAction(ramWatchAct); + //----------------------------------------------------------------------- // Debug debugMenu = menuBar()->addMenu(tr("Debug")); @@ -1017,6 +1026,17 @@ void consoleWin_t::openCheats(void) cheatWin->show(); } +void consoleWin_t::openRamWatch(void) +{ + RamWatchDialog_t *ramWatchWin; + + //printf("Open GUI RAM Watch Window\n"); + + ramWatchWin = new RamWatchDialog_t(this); + + ramWatchWin->show(); +} + void consoleWin_t::openDebugWindow(void) { ConsoleDebugger *debugWin; diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index cf082440..08ea48dd 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -89,6 +89,7 @@ class consoleWin_t : public QMainWindow QAction *fdsEjectAct; QAction *fdsLoadBiosAct; QAction *cheatsAct; + QAction *ramWatchAct; QAction *debuggerAct; QAction *codeDataLogAct; QAction *traceLogAct; @@ -167,6 +168,7 @@ class consoleWin_t : public QMainWindow void openPPUViewer(void); void openNTViewer(void); void openCheats(void); + void openRamWatch(void); void openMovie(void); void stopMovie(void); void recordMovie(void); diff --git a/src/drivers/Qt/RamWatch.cpp b/src/drivers/Qt/RamWatch.cpp new file mode 100644 index 00000000..229b25f4 --- /dev/null +++ b/src/drivers/Qt/RamWatch.cpp @@ -0,0 +1,254 @@ +// HotKeyConf.cpp +// +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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/RamWatch.h" + +//---------------------------------------------------------------------------- +RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) + : QDialog( parent ) +{ + QMenuBar *menuBar; + QHBoxLayout *mainLayout; + QVBoxLayout *vbox, *vbox1; + QTreeWidgetItem *item; + QMenu *fileMenu, *watchMenu; + QAction *menuAct; + QGroupBox *frame; + int useNativeMenuBar; + + font.setFamily("Courier New"); + font.setStyle( QFont::StyleNormal ); + font.setStyleHint( QFont::Monospace ); + + QFontMetrics fm(font); + +#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0) + fontCharWidth = 2 * fm.horizontalAdvance(QLatin1Char('2')); +#else + fontCharWidth = 2 * fm.width(QLatin1Char('2')); +#endif + + setWindowTitle("RAM Watch"); + + 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 -> New List + menuAct = new QAction(tr("New List"), this); + menuAct->setShortcut( QKeySequence(tr("Ctrl+N")) ); + menuAct->setStatusTip(tr("New List")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + fileMenu->addAction(menuAct); + + // File -> Open + menuAct = new QAction(tr("Open"), this); + menuAct->setShortcut( QKeySequence(tr("Ctrl+O")) ); + menuAct->setStatusTip(tr("Open Watch File")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + fileMenu->addAction(menuAct); + + // File -> Save + menuAct = new QAction(tr("Save"), this); + menuAct->setShortcut( QKeySequence(tr("Ctrl+S")) ); + menuAct->setStatusTip(tr("Save Watch File")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + fileMenu->addAction(menuAct); + + // File -> Save As + menuAct = new QAction(tr("Save As"), this); + menuAct->setShortcut( QKeySequence(tr("Ctrl+Shift+S")) ); + menuAct->setStatusTip(tr("Save As Watch File")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + fileMenu->addAction(menuAct); + + // File -> Append + menuAct = new QAction(tr("Append"), this); + //menuAct->setShortcut( QKeySequence(tr("Ctrl+A")) ); + menuAct->setStatusTip(tr("Append to Watch File")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + fileMenu->addAction(menuAct); + + fileMenu->addSeparator(); + + // File -> Append + menuAct = new QAction(tr("Close"), this); + menuAct->setShortcut( QKeySequence(tr("Alt+F4")) ); + menuAct->setStatusTip(tr("Close Window")); + connect(menuAct, SIGNAL(triggered()), this, SLOT(closeWindow(void)) ); + + fileMenu->addAction(menuAct); + + // Watch + watchMenu = menuBar->addMenu(tr("Watch")); + + // Watch -> New Watch + menuAct = new QAction(tr("New Watch"), this); + menuAct->setShortcut( QKeySequence(tr("N")) ); + menuAct->setStatusTip(tr("New Watch")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + watchMenu->addAction(menuAct); + + // Watch -> Edit Watch + menuAct = new QAction(tr("Edit Watch"), this); + menuAct->setShortcut( QKeySequence(tr("E")) ); + menuAct->setStatusTip(tr("Edit Watch")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + watchMenu->addAction(menuAct); + + // Watch -> Remove Watch + menuAct = new QAction(tr("Remove Watch"), this); + menuAct->setShortcut( QKeySequence(tr("R")) ); + menuAct->setStatusTip(tr("Remove Watch")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + watchMenu->addAction(menuAct); + + // Watch -> Duplicate Watch + menuAct = new QAction(tr("Duplicate Watch"), this); + menuAct->setShortcut( QKeySequence(tr("A")) ); + menuAct->setStatusTip(tr("Duplicate Watch")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + watchMenu->addAction(menuAct); + + // Watch -> Add Separator + menuAct = new QAction(tr("Add Separator"), this); + menuAct->setShortcut( QKeySequence(tr("S")) ); + menuAct->setStatusTip(tr("Add Separator")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + watchMenu->addAction(menuAct); + + watchMenu->addSeparator(); + + // Watch -> Move Up + menuAct = new QAction(tr("Move Up"), this); + menuAct->setShortcut( QKeySequence(tr("U")) ); + menuAct->setStatusTip(tr("Move Up")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + watchMenu->addAction(menuAct); + + // Watch -> Move Down + menuAct = new QAction(tr("Move Down"), this); + menuAct->setShortcut( QKeySequence(tr("D")) ); + menuAct->setStatusTip(tr("Move Down")); + //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + + watchMenu->addAction(menuAct); + + //----------------------------------------------------------------------- + // End Menu + //----------------------------------------------------------------------- + + mainLayout = new QHBoxLayout(); + + tree = new QTreeWidget(); + + tree->setColumnCount(3); + + item = new QTreeWidgetItem(); + item->setText( 0, QString::fromStdString( "Address" ) ); + item->setText( 1, QString::fromStdString( "Value" ) ); + item->setText( 2, QString::fromStdString( "Notes" ) ); + item->setTextAlignment( 0, Qt::AlignLeft); + item->setTextAlignment( 1, Qt::AlignLeft); + item->setTextAlignment( 2, Qt::AlignLeft); + + tree->setHeaderItem( item ); + + tree->header()->setSectionResizeMode( QHeaderView::ResizeToContents ); + + vbox1 = new QVBoxLayout(); + vbox = new QVBoxLayout(); + frame = new QGroupBox( tr("Watches") ); + vbox1->addWidget( frame ); + frame->setLayout( vbox ); + + up_btn = new QPushButton( tr("Up") ); + vbox->addWidget( up_btn ); + + down_btn = new QPushButton( tr("Down") ); + vbox->addWidget( down_btn ); + + edit_btn = new QPushButton( tr("Edit") ); + vbox->addWidget( edit_btn ); + + del_btn = new QPushButton( tr("Remove") ); + vbox->addWidget( del_btn ); + + new_btn = new QPushButton( tr("New") ); + vbox->addWidget( new_btn ); + + dup_btn = new QPushButton( tr("Duplicate") ); + vbox->addWidget( dup_btn ); + + sep_btn = new QPushButton( tr("Separator") ); + vbox->addWidget( sep_btn ); + + mainLayout->addWidget( tree ); + mainLayout->addLayout( vbox1 ); + mainLayout->setMenuBar( menuBar ); + + cht_btn = new QPushButton( tr("Add Cheat") ); + vbox1->addWidget( cht_btn ); + + setLayout( mainLayout ); +} +//---------------------------------------------------------------------------- +RamWatchDialog_t::~RamWatchDialog_t(void) +{ + printf("Destroy RAM Watch Config Window\n"); +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::closeEvent(QCloseEvent *event) +{ + printf("RAM Watch Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::closeWindow(void) +{ + //printf("Close Window\n"); + done(0); + deleteLater(); +} +//---------------------------------------------------------------------------- diff --git a/src/drivers/Qt/RamWatch.h b/src/drivers/Qt/RamWatch.h new file mode 100644 index 00000000..1b511ee3 --- /dev/null +++ b/src/drivers/Qt/RamWatch.h @@ -0,0 +1,51 @@ +// RamWatch.h +// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Qt/main.h" + +class RamWatchDialog_t : public QDialog +{ + Q_OBJECT + + public: + RamWatchDialog_t(QWidget *parent = 0); + ~RamWatchDialog_t(void); + + protected: + void closeEvent(QCloseEvent *event); + + QFont font; + QTreeWidget *tree; + QPushButton *up_btn; + QPushButton *down_btn; + QPushButton *edit_btn; + QPushButton *del_btn; + QPushButton *new_btn; + QPushButton *dup_btn; + QPushButton *sep_btn; + QPushButton *cht_btn; + + int fontCharWidth; + + private: + + public slots: + void closeWindow(void); + private slots: + +}; From ff694ebe499bc0f9bd941f453a9a064442175982 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Wed, 7 Oct 2020 21:01:39 -0400 Subject: [PATCH 02/10] Qt Ram watch logic in work. --- src/drivers/Qt/CheatsConf.cpp | 1 + src/drivers/Qt/RamWatch.cpp | 282 ++++++++++++++++++++++++++++++++++ src/drivers/Qt/RamWatch.h | 120 +++++++++++++++ 3 files changed, 403 insertions(+) diff --git a/src/drivers/Qt/CheatsConf.cpp b/src/drivers/Qt/CheatsConf.cpp index 81dbd037..0dbfd5ee 100644 --- a/src/drivers/Qt/CheatsConf.cpp +++ b/src/drivers/Qt/CheatsConf.cpp @@ -639,6 +639,7 @@ int GuiCheatsDialog_t::activeCheatListCB (char *name, uint32 a, uint8 v, int c, item->setTextAlignment( 0, Qt::AlignLeft); item->setTextAlignment( 1, Qt::AlignLeft); + item->setTextAlignment( 2, Qt::AlignLeft); actvCheatIdx++; diff --git a/src/drivers/Qt/RamWatch.cpp b/src/drivers/Qt/RamWatch.cpp index 229b25f4..e8ce6f4d 100644 --- a/src/drivers/Qt/RamWatch.cpp +++ b/src/drivers/Qt/RamWatch.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -12,6 +13,11 @@ #include #include +#include "../../types.h" +#include "../../fceu.h" +#include "../../cheat.h" +#include "../../debug.h" + #include "Qt/main.h" #include "Qt/dface.h" #include "Qt/input.h" @@ -252,3 +258,279 @@ void RamWatchDialog_t::closeWindow(void) deleteLater(); } //---------------------------------------------------------------------------- +void RamWatchDialog_t::updateRamWatchDisplay(void) +{ + int idx=0; + QTreeWidgetItem *item; + std::list < ramWatch_t * >::iterator it; + char addrStr[32], valStr1[16], valStr2[16]; + ramWatch_t *rw; + + for (it = ramWatchList.ls.begin (); it != ramWatchList.ls.end (); it++) + { + rw = *it; + + item = tree->topLevelItem(idx); + + if ( item == NULL ) + { + item = new QTreeWidgetItem(); + + tree->addTopLevelItem( item ); + } + sprintf (addrStr, "0x%04X", rw->addr); + + rw->updateMem (); + + if (rw->size == 2) + { + if (rw->type) + { + sprintf (valStr1, "%6u", rw->val.u16); + } + else + { + sprintf (valStr1, "%6i", rw->val.i16); + } + sprintf (valStr2, "0x%04X", rw->val.u16); + } + else + { + if (rw->type) + { + sprintf (valStr1, "%6u", rw->val.u8); + } + else + { + sprintf (valStr1, "%6i", rw->val.i8); + } + sprintf (valStr2, "0x%02X", rw->val.u8); + } + + item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemNeverHasChildren ); + + //item->setFont(font); + item->setText( 0, tr(addrStr) ); + item->setText( 1, tr(valStr1) ); + item->setText( 2, tr(rw->name.c_str()) ); + + item->setTextAlignment( 0, Qt::AlignLeft); + item->setTextAlignment( 1, Qt::AlignLeft); + item->setTextAlignment( 2, Qt::AlignLeft); + + idx++; + } +} +//---------------------------------------------------------------------------- +void ramWatch_t::updateMem (void) +{ + if (size == 1) + { + val.u8 = GetMem (addr); + } + else if (size == 2) + { + val.u16 = GetMem (addr) | (GetMem (addr + 1) << 8); + } + else + { + val.u8 = GetMem (addr); + } +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::saveWatchFile (const char *filename) +{ + int i; + FILE *fp; + const char *c; + std::list < ramWatch_t * >::iterator it; + ramWatch_t *rw; + + fp = fopen (filename, "w"); + + if (fp == NULL) + { + printf ("Error: Failed to open file: %s\n", filename); + return; + } + + for (it = ramWatchList.ls.begin (); it != ramWatchList.ls.end (); it++) + { + rw = *it; + + c = rw->name.c_str (); + + fprintf (fp, "0x%04x %c%i ", rw->addr, rw->type ? 'U' : 'S', + rw->size); + + i = 0; + fprintf (fp, "\""); + while (c[i]) + { + if (c[i] == '"') + { + fprintf (fp, "\\%c", c[i]); + } + else + { + fprintf (fp, "%c", c[i]); + } + i++; + } + fprintf (fp, "\"\n"); + } + fclose (fp); + +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::loadWatchFile (const char *filename) +{ + FILE *fp; + int i, j, a, t, s, literal; + char line[512], stmp[512]; + ramWatch_t *rw; + + fp = fopen (filename, "r"); + + if (fp == NULL) + { + printf ("Error: Failed to open file: %s\n", filename); + return; + } + + while (fgets (line, sizeof (line) - 1, fp) > 0) + { + a = -1; + t = -1; + s = -1; + // Check for Comments + i = 0; + while (line[i] != 0) + { + if (literal) + { + literal = 0; + } + else + { + if (line[i] == '#') + { + line[i] = 0; + break; + } + else if (line[i] == '\\') + { + literal = 1; + } + } + i++; + } + + i = 0; + j = 0; + while (isspace (line[i])) i++; + + if ((line[i] == '0') && (tolower (line[i + 1]) == 'x')) + { + stmp[j] = '0'; + j++; + i++; + stmp[j] = 'x'; + j++; + i++; + + while (isxdigit (line[i])) + { + stmp[j] = line[i]; + i++; + j++; + } + } + else + { + while (isxdigit (line[i])) + { + stmp[j] = line[i]; + i++; + j++; + } + } + stmp[j] = 0; + + if (j == 0) continue; + + a = strtol (stmp, NULL, 0); + + while (isspace (line[i])) i++; + + t = line[i]; + i++; + s = line[i]; + i++; + + if ((t != 'U') && (t != 'S')) + { + printf ("Error: Invalid RAM Watch Byte Type: %c", t); + continue; + } + if (!isdigit (s)) + { + printf ("Error: Invalid RAM Watch Byte Size: %c", s); + continue; + } + s = s - '0'; + + if ((s != 1) && (s != 2) && (s != 4)) + { + printf ("Error: Invalid RAM Watch Byte Size: %i", s); + continue; + } + + while (isspace (line[i])) i++; + + if (line[i] == '"') + { + i++; + j = 0; + literal = 0; + while ((line[i] != 0)) + { + if (literal) + { + literal = 0; + } + else + { + if (line[i] == '"') + { + break; + } + else if (line[i] == '\\') + { + literal = 1; + } + } + if (!literal) + { + stmp[j] = line[i]; + j++; + } + i++; + } + stmp[j] = 0; + } + rw = new ramWatch_t; + + rw->addr = a; + rw->type = (t == 'U') ? 1 : 0; + rw->size = s; + rw->name.assign (stmp); + + ramWatchList.ls.push_back (rw); + } + + fclose (fp); + + //showAllRamWatchResults (1); +} +//---------------------------------------------------------------------------- diff --git a/src/drivers/Qt/RamWatch.h b/src/drivers/Qt/RamWatch.h index 1b511ee3..6fd78ffc 100644 --- a/src/drivers/Qt/RamWatch.h +++ b/src/drivers/Qt/RamWatch.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include #include @@ -18,6 +19,120 @@ #include "Qt/main.h" +struct ramWatch_t +{ + std::string name; + int addr; + int type; + int size; + + union + { + int8_t i8; + uint8_t u8; + int16_t i16; + uint16_t u16; + } val; + + ramWatch_t (void) + { + addr = 0; + type = 0; + size = 0; + val.u16 = 0; + }; + + void updateMem (void); +}; + +struct ramWatchList_t +{ + + std::list ls; + + ramWatchList_t (void) + { + + } + + ~ramWatchList_t (void) + { + ramWatch_t *rw; + + while (!ls.empty ()) + { + rw = ls.front (); + + delete rw; + + ls.pop_front (); + } + } + + size_t size (void) + { + return ls.size (); + }; + + void add_entry (const char *name, int addr, int type, int size) + { + ramWatch_t *rw = new ramWatch_t; + + rw->name.assign (name); + rw->addr = addr; + rw->type = type; + rw->size = size; + ls.push_back (rw); + } + + void updateMemoryValues (void) + { + ramWatch_t *rw; + std::list < ramWatch_t * >::iterator it; + + for (it = ls.begin (); it != ls.end (); it++) + { + rw = *it; + + rw->updateMem (); + } + } + + ramWatch_t *getIndex (size_t idx) + { + size_t i = 0; + std::list < ramWatch_t * >::iterator it; + + for (it = ls.begin (); it != ls.end (); it++) + { + if (i == idx) + { + return *it; + } + i++; + } + return NULL; + } + + int deleteIndex (size_t idx) + { + size_t i = 0; + std::list < ramWatch_t * >::iterator it; + + for (it = ls.begin (); it != ls.end (); it++) + { + if (i == idx) + { + delete *it; + ls.erase (it); + return 0; + } + i++; + } + return -1; + } +}; + class RamWatchDialog_t : public QDialog { Q_OBJECT @@ -28,6 +143,8 @@ class RamWatchDialog_t : public QDialog protected: void closeEvent(QCloseEvent *event); + void loadWatchFile (const char *filename); + void saveWatchFile (const char *filename); QFont font; QTreeWidget *tree; @@ -40,9 +157,12 @@ class RamWatchDialog_t : public QDialog QPushButton *sep_btn; QPushButton *cht_btn; + ramWatchList_t ramWatchList; + int fontCharWidth; private: + void updateRamWatchDisplay(void); public slots: void closeWindow(void); From f8e7187f0526ff535bfed4e4c8dc299dcaaeadc3 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Thu, 8 Oct 2020 06:39:08 -0400 Subject: [PATCH 03/10] Build fix for MacOSX --- src/drivers/Qt/RamWatch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/Qt/RamWatch.cpp b/src/drivers/Qt/RamWatch.cpp index e8ce6f4d..0fc48a72 100644 --- a/src/drivers/Qt/RamWatch.cpp +++ b/src/drivers/Qt/RamWatch.cpp @@ -398,7 +398,7 @@ void RamWatchDialog_t::loadWatchFile (const char *filename) return; } - while (fgets (line, sizeof (line) - 1, fp) > 0) + while (fgets (line, sizeof (line) - 1, fp) != NULL) { a = -1; t = -1; From f440c820fd5c1bfa33d8a3c649d4bdc52710b50c Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Thu, 8 Oct 2020 07:08:47 -0400 Subject: [PATCH 04/10] Added initial layout for Qt Ram Watch Edit window. --- src/drivers/Qt/RamWatch.cpp | 81 +++++++++++++++++++++++++++++++++++++ src/drivers/Qt/RamWatch.h | 2 + 2 files changed, 83 insertions(+) diff --git a/src/drivers/Qt/RamWatch.cpp b/src/drivers/Qt/RamWatch.cpp index 0fc48a72..f15550db 100644 --- a/src/drivers/Qt/RamWatch.cpp +++ b/src/drivers/Qt/RamWatch.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include "../../types.h" #include "../../fceu.h" @@ -221,6 +223,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) new_btn = new QPushButton( tr("New") ); vbox->addWidget( new_btn ); + connect( new_btn, SIGNAL(clicked(void)), this, SLOT(newWatchClicked(void))); dup_btn = new QPushButton( tr("Duplicate") ); vbox->addWidget( dup_btn ); @@ -338,6 +341,84 @@ void ramWatch_t::updateMem (void) } } //---------------------------------------------------------------------------- +void RamWatchDialog_t::openWatchEditWindow(int idx) +{ + int ret; + QDialog dialog(this); + QVBoxLayout *mainLayout, *vbox; + QHBoxLayout *hbox; + QLabel *lbl; + QLineEdit *addrEntry, *notesEntry; + QGroupBox *frame; + QRadioButton *signedTypeBtn, *unsignedTypeBtn, *hexTypeBtn, *binaryTypeBtn; + QRadioButton *dataSize1Btn, *dataSize2Btn, *dataSize4Btn; + + dialog.setWindowTitle("Add Watch"); + + mainLayout = new QVBoxLayout(); + + dialog.setLayout( mainLayout ); + + hbox = new QHBoxLayout(); + lbl = new QLabel( tr("Address") ); + addrEntry = new QLineEdit(); + + mainLayout->addLayout( hbox ); + hbox->addWidget( lbl ); + hbox->addWidget( addrEntry ); + + hbox = new QHBoxLayout(); + lbl = new QLabel( tr("Notes") ); + notesEntry = new QLineEdit(); + + mainLayout->addLayout( hbox ); + hbox->addWidget( lbl ); + hbox->addWidget( notesEntry ); + + hbox = new QHBoxLayout(); + mainLayout->addLayout( hbox ); + + vbox = new QVBoxLayout(); + frame = new QGroupBox( tr("Data Type") ); + hbox->addWidget( frame ); + frame->setLayout( vbox ); + + signedTypeBtn = new QRadioButton( tr("Signed") ); + unsignedTypeBtn = new QRadioButton( tr("Unsigned") ); + hexTypeBtn = new QRadioButton( tr("Hex") ); + binaryTypeBtn = new QRadioButton( tr("Binary") ); + + vbox->addWidget( signedTypeBtn ); + vbox->addWidget( unsignedTypeBtn ); + vbox->addWidget( hexTypeBtn ); + vbox->addWidget( binaryTypeBtn ); + + vbox = new QVBoxLayout(); + frame = new QGroupBox( tr("Data Size") ); + hbox->addWidget( frame ); + frame->setLayout( vbox ); + + dataSize1Btn = new QRadioButton( tr("1 Byte") ); + dataSize2Btn = new QRadioButton( tr("2 Bytes") ); + dataSize4Btn = new QRadioButton( tr("4 Bytes") ); + + vbox->addWidget( dataSize1Btn ); + vbox->addWidget( dataSize2Btn ); + vbox->addWidget( dataSize4Btn ); + + ret = dialog.exec(); + + if ( ret ) + { + + } +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::newWatchClicked(void) +{ + openWatchEditWindow(); +} +//---------------------------------------------------------------------------- void RamWatchDialog_t::saveWatchFile (const char *filename) { int i; diff --git a/src/drivers/Qt/RamWatch.h b/src/drivers/Qt/RamWatch.h index 6fd78ffc..52ec6d66 100644 --- a/src/drivers/Qt/RamWatch.h +++ b/src/drivers/Qt/RamWatch.h @@ -163,9 +163,11 @@ class RamWatchDialog_t : public QDialog private: void updateRamWatchDisplay(void); + void openWatchEditWindow( int idx = -1); public slots: void closeWindow(void); private slots: + void newWatchClicked(void); }; From 778d9c733df4e54a0c5390738dbd5400d1148e95 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Thu, 8 Oct 2020 22:05:31 -0400 Subject: [PATCH 05/10] Added logic for add, edit and remove ram watch entries. --- src/drivers/Qt/RamWatch.cpp | 257 +++++++++++++++++++++++++++++++++--- src/drivers/Qt/RamWatch.h | 11 +- 2 files changed, 249 insertions(+), 19 deletions(-) diff --git a/src/drivers/Qt/RamWatch.cpp b/src/drivers/Qt/RamWatch.cpp index f15550db..6811ec09 100644 --- a/src/drivers/Qt/RamWatch.cpp +++ b/src/drivers/Qt/RamWatch.cpp @@ -127,7 +127,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) menuAct = new QAction(tr("New Watch"), this); menuAct->setShortcut( QKeySequence(tr("N")) ); menuAct->setStatusTip(tr("New Watch")); - //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + connect(menuAct, SIGNAL(triggered()), this, SLOT(newWatchClicked(void)) ); watchMenu->addAction(menuAct); @@ -135,7 +135,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) menuAct = new QAction(tr("Edit Watch"), this); menuAct->setShortcut( QKeySequence(tr("E")) ); menuAct->setStatusTip(tr("Edit Watch")); - //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + connect(menuAct, SIGNAL(triggered()), this, SLOT(editWatchClicked(void)) ); watchMenu->addAction(menuAct); @@ -143,7 +143,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) menuAct = new QAction(tr("Remove Watch"), this); menuAct->setShortcut( QKeySequence(tr("R")) ); menuAct->setStatusTip(tr("Remove Watch")); - //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + connect(menuAct, SIGNAL(triggered()), this, SLOT(removeWatchClicked(void)) ); watchMenu->addAction(menuAct); @@ -169,7 +169,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) menuAct = new QAction(tr("Move Up"), this); menuAct->setShortcut( QKeySequence(tr("U")) ); menuAct->setStatusTip(tr("Move Up")); - //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + connect(menuAct, SIGNAL(triggered()), this, SLOT(moveWatchUpClicked(void)) ); watchMenu->addAction(menuAct); @@ -177,7 +177,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) menuAct = new QAction(tr("Move Down"), this); menuAct->setShortcut( QKeySequence(tr("D")) ); menuAct->setStatusTip(tr("Move Down")); - //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + connect(menuAct, SIGNAL(triggered()), this, SLOT(moveWatchDownClicked(void)) ); watchMenu->addAction(menuAct); @@ -189,15 +189,20 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) tree = new QTreeWidget(); - tree->setColumnCount(3); + tree->setColumnCount(4); item = new QTreeWidgetItem(); item->setText( 0, QString::fromStdString( "Address" ) ); - item->setText( 1, QString::fromStdString( "Value" ) ); - item->setText( 2, QString::fromStdString( "Notes" ) ); + item->setText( 1, QString::fromStdString( "Value Dec" ) ); + item->setText( 2, QString::fromStdString( "Value Hex" ) ); + item->setText( 3, QString::fromStdString( "Notes" ) ); item->setTextAlignment( 0, Qt::AlignLeft); item->setTextAlignment( 1, Qt::AlignLeft); item->setTextAlignment( 2, Qt::AlignLeft); + item->setTextAlignment( 3, Qt::AlignLeft); + + connect( tree, SIGNAL(itemClicked(QTreeWidgetItem*, int)), + this, SLOT(watchClicked( QTreeWidgetItem*, int)) ); tree->setHeaderItem( item ); @@ -211,15 +216,19 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) up_btn = new QPushButton( tr("Up") ); vbox->addWidget( up_btn ); + connect( up_btn, SIGNAL(clicked(void)), this, SLOT(moveWatchUpClicked(void))); down_btn = new QPushButton( tr("Down") ); vbox->addWidget( down_btn ); + connect( down_btn, SIGNAL(clicked(void)), this, SLOT(moveWatchDownClicked(void))); edit_btn = new QPushButton( tr("Edit") ); vbox->addWidget( edit_btn ); + connect( edit_btn, SIGNAL(clicked(void)), this, SLOT(editWatchClicked(void))); del_btn = new QPushButton( tr("Remove") ); vbox->addWidget( del_btn ); + connect( del_btn, SIGNAL(clicked(void)), this, SLOT(removeWatchClicked(void))); new_btn = new QPushButton( tr("New") ); vbox->addWidget( new_btn ); @@ -239,10 +248,17 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) vbox1->addWidget( cht_btn ); setLayout( mainLayout ); + + updateTimer = new QTimer( this ); + + connect( updateTimer, &QTimer::timeout, this, &RamWatchDialog_t::periodicUpdate ); + + updateTimer->start( 100 ); // 10hz } //---------------------------------------------------------------------------- RamWatchDialog_t::~RamWatchDialog_t(void) { + updateTimer->stop(); printf("Destroy RAM Watch Config Window\n"); } //---------------------------------------------------------------------------- @@ -261,6 +277,13 @@ void RamWatchDialog_t::closeWindow(void) deleteLater(); } //---------------------------------------------------------------------------- +void RamWatchDialog_t::periodicUpdate(void) +{ + + updateRamWatchDisplay(); + +} +//---------------------------------------------------------------------------- void RamWatchDialog_t::updateRamWatchDisplay(void) { int idx=0; @@ -281,11 +304,23 @@ void RamWatchDialog_t::updateRamWatchDisplay(void) tree->addTopLevelItem( item ); } - sprintf (addrStr, "0x%04X", rw->addr); + sprintf (addrStr, "$%04X", rw->addr); rw->updateMem (); - if (rw->size == 2) + if (rw->size == 4) + { + if (rw->type) + { + sprintf (valStr1, "%u", rw->val.u32); + } + else + { + sprintf (valStr1, "%i", rw->val.i32); + } + sprintf (valStr2, "0x%08X", rw->val.u32); + } + else if (rw->size == 2) { if (rw->type) { @@ -315,14 +350,23 @@ void RamWatchDialog_t::updateRamWatchDisplay(void) //item->setFont(font); item->setText( 0, tr(addrStr) ); item->setText( 1, tr(valStr1) ); - item->setText( 2, tr(rw->name.c_str()) ); + item->setText( 2, tr(valStr2) ); + item->setText( 3, tr(rw->name.c_str()) ); item->setTextAlignment( 0, Qt::AlignLeft); item->setTextAlignment( 1, Qt::AlignLeft); item->setTextAlignment( 2, Qt::AlignLeft); + item->setTextAlignment( 3, Qt::AlignLeft); idx++; } + tree->viewport()->update(); +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::watchClicked( QTreeWidgetItem *item, int column) +{ +// int row = tree->indexOfTopLevelItem(item); + } //---------------------------------------------------------------------------- void ramWatch_t::updateMem (void) @@ -350,10 +394,24 @@ void RamWatchDialog_t::openWatchEditWindow(int idx) QLabel *lbl; QLineEdit *addrEntry, *notesEntry; QGroupBox *frame; - QRadioButton *signedTypeBtn, *unsignedTypeBtn, *hexTypeBtn, *binaryTypeBtn; + QRadioButton *signedTypeBtn, *unsignedTypeBtn; QRadioButton *dataSize1Btn, *dataSize2Btn, *dataSize4Btn; + QPushButton *cancelButton, *okButton; + ramWatch_t *rw = NULL; - dialog.setWindowTitle("Add Watch"); + if ( idx >= 0 ) + { + rw = ramWatchList.getIndex(idx); + } + + if ( rw == NULL ) + { + dialog.setWindowTitle("Add Watch"); + } + else + { + dialog.setWindowTitle("Edit Watch"); + } mainLayout = new QVBoxLayout(); @@ -363,6 +421,10 @@ void RamWatchDialog_t::openWatchEditWindow(int idx) lbl = new QLabel( tr("Address") ); addrEntry = new QLineEdit(); + addrEntry->setMaxLength(4); + addrEntry->setInputMask( ">HHHH;0" ); + addrEntry->setCursorPosition(0); + mainLayout->addLayout( hbox ); hbox->addWidget( lbl ); hbox->addWidget( addrEntry ); @@ -385,13 +447,9 @@ void RamWatchDialog_t::openWatchEditWindow(int idx) signedTypeBtn = new QRadioButton( tr("Signed") ); unsignedTypeBtn = new QRadioButton( tr("Unsigned") ); - hexTypeBtn = new QRadioButton( tr("Hex") ); - binaryTypeBtn = new QRadioButton( tr("Binary") ); vbox->addWidget( signedTypeBtn ); vbox->addWidget( unsignedTypeBtn ); - vbox->addWidget( hexTypeBtn ); - vbox->addWidget( binaryTypeBtn ); vbox = new QVBoxLayout(); frame = new QGroupBox( tr("Data Size") ); @@ -406,11 +464,73 @@ void RamWatchDialog_t::openWatchEditWindow(int idx) vbox->addWidget( dataSize2Btn ); vbox->addWidget( dataSize4Btn ); + hbox = new QHBoxLayout(); + mainLayout->addLayout( hbox ); + + okButton = new QPushButton( tr("OK") ); + cancelButton = new QPushButton( tr("Cancel") ); + hbox->addWidget( cancelButton ); + hbox->addWidget( okButton ); + okButton->setDefault(true); + + connect( okButton, SIGNAL(clicked(void)), &dialog, SLOT(accept(void)) ); + connect( cancelButton, SIGNAL(clicked(void)), &dialog, SLOT(reject(void)) ); + + if ( rw != NULL ) + { + char stmp[64]; + + sprintf( stmp, "%04X", rw->addr ); + addrEntry->setText( tr(stmp) ); + notesEntry->setText( tr(rw->name.c_str()) ); + signedTypeBtn->setChecked( !rw->type ); + unsignedTypeBtn->setChecked( rw->type ); + dataSize1Btn->setChecked( rw->size == 1 ); + dataSize2Btn->setChecked( rw->size == 2 ); + dataSize4Btn->setChecked( rw->size == 4 ); + } + else + { + signedTypeBtn->setChecked( true ); + unsignedTypeBtn->setChecked( false ); + dataSize1Btn->setChecked( true ); + dataSize2Btn->setChecked( false ); + dataSize4Btn->setChecked( false ); + } + ret = dialog.exec(); - if ( ret ) + if ( ret == QDialog::Accepted ) { + int addr = -1, size = 1; + addr = ::strtol( addrEntry->text().toStdString().c_str(), NULL, 16 ); + + if ( dataSize4Btn->isChecked() ) + { + size = 4; + } + else if ( dataSize2Btn->isChecked() ) + { + size = 2; + } + else + { + size = 1; + } + + if ( rw == NULL ) + { + ramWatchList.add_entry( notesEntry->text().toStdString().c_str(), + addr, unsignedTypeBtn->isChecked(), size ); + } + else + { + rw->name = notesEntry->text().toStdString(); + rw->type = unsignedTypeBtn->isChecked(); + rw->addr = addr; + rw->size = size; + } } } //---------------------------------------------------------------------------- @@ -419,6 +539,107 @@ void RamWatchDialog_t::newWatchClicked(void) openWatchEditWindow(); } //---------------------------------------------------------------------------- +void RamWatchDialog_t::editWatchClicked(void) +{ + QTreeWidgetItem *item; + + item = tree->currentItem(); + + if ( item == NULL ) + { + printf( "No Item Selected\n"); + return; + } + int row = tree->indexOfTopLevelItem(item); + + openWatchEditWindow(row); +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::removeWatchClicked(void) +{ + QTreeWidgetItem *item; + + item = tree->currentItem(); + + if ( item == NULL ) + { + printf( "No Item Selected\n"); + return; + } + int row = tree->indexOfTopLevelItem(item); + + ramWatchList.deleteIndex(row); + + tree->clear(); + + updateRamWatchDisplay(); + + if ( row > 0 ) + { + item = tree->topLevelItem( row-1 ); + } + else + { + item = tree->topLevelItem( 0 ); + } + + if ( item ) + { + tree->setCurrentItem(item); + tree->viewport()->update(); + } +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::moveWatchUpClicked(void) +{ + QTreeWidgetItem *item; + + item = tree->currentItem(); + + if ( item == NULL ) + { + printf( "No Item Selected\n"); + return; + } + int row = tree->indexOfTopLevelItem(item); + + if ( row > 0 ) + { + item = tree->topLevelItem( row-1 ); + + if ( item ) + { + tree->setCurrentItem(item); + tree->viewport()->update(); + } + } +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::moveWatchDownClicked(void) +{ + QTreeWidgetItem *item; + + item = tree->currentItem(); + + if ( item == NULL ) + { + printf( "No Item Selected\n"); + return; + } + int row = tree->indexOfTopLevelItem(item); + + if ( row < (tree->topLevelItemCount()-1) ) + { + item = tree->topLevelItem( row+1 ); + + if ( item ) + { + tree->setCurrentItem(item); + tree->viewport()->update(); + } + } +} +//---------------------------------------------------------------------------- void RamWatchDialog_t::saveWatchFile (const char *filename) { int i; diff --git a/src/drivers/Qt/RamWatch.h b/src/drivers/Qt/RamWatch.h index 52ec6d66..06335e98 100644 --- a/src/drivers/Qt/RamWatch.h +++ b/src/drivers/Qt/RamWatch.h @@ -32,6 +32,8 @@ struct ramWatch_t uint8_t u8; int16_t i16; uint16_t u16; + int32_t i32; + uint32_t u32; } val; ramWatch_t (void) @@ -39,7 +41,7 @@ struct ramWatch_t addr = 0; type = 0; size = 0; - val.u16 = 0; + val.u32 = 0; }; void updateMem (void); @@ -156,6 +158,7 @@ class RamWatchDialog_t : public QDialog QPushButton *dup_btn; QPushButton *sep_btn; QPushButton *cht_btn; + QTimer *updateTimer; ramWatchList_t ramWatchList; @@ -168,6 +171,12 @@ class RamWatchDialog_t : public QDialog public slots: void closeWindow(void); private slots: + void periodicUpdate(void); void newWatchClicked(void); + void editWatchClicked(void); + void removeWatchClicked(void); + void moveWatchUpClicked(void); + void moveWatchDownClicked(void); + void watchClicked( QTreeWidgetItem *item, int column); }; From 1f11c67c84116cda668c65671ab0b9777b190ac3 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 9 Oct 2020 22:08:38 -0400 Subject: [PATCH 06/10] Successful test of all Qt RAM watch features. Minor cppcheck warning cleanup. --- src/drivers/Qt/NameTableViewer.cpp | 4 +- src/drivers/Qt/RamWatch.cpp | 520 ++++++++++++++++++++++++----- src/drivers/Qt/RamWatch.h | 88 ++++- src/drivers/Qt/TraceLogger.cpp | 3 + 4 files changed, 528 insertions(+), 87 deletions(-) diff --git a/src/drivers/Qt/NameTableViewer.cpp b/src/drivers/Qt/NameTableViewer.cpp index c64b5b16..a2ed46f3 100644 --- a/src/drivers/Qt/NameTableViewer.cpp +++ b/src/drivers/Qt/NameTableViewer.cpp @@ -44,7 +44,9 @@ static class NTCache public: NTCache(void) : curr_vnapage(0) - {} + { + memset( cache, 0, sizeof(cache) ); + } uint8_t* curr_vnapage; uint8_t cache[0x400]; diff --git a/src/drivers/Qt/RamWatch.cpp b/src/drivers/Qt/RamWatch.cpp index 6811ec09..f6423952 100644 --- a/src/drivers/Qt/RamWatch.cpp +++ b/src/drivers/Qt/RamWatch.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "../../types.h" #include "../../fceu.h" @@ -27,7 +28,9 @@ #include "Qt/keyscan.h" #include "Qt/fceuWrapper.h" #include "Qt/RamWatch.h" +#include "Qt/ConsoleUtilities.h" +ramWatchList_t ramWatchList; //---------------------------------------------------------------------------- RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) : QDialog( parent ) @@ -74,7 +77,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) menuAct = new QAction(tr("New List"), this); menuAct->setShortcut( QKeySequence(tr("Ctrl+N")) ); menuAct->setStatusTip(tr("New List")); - //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); fileMenu->addAction(menuAct); @@ -82,7 +85,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) menuAct = new QAction(tr("Open"), this); menuAct->setShortcut( QKeySequence(tr("Ctrl+O")) ); menuAct->setStatusTip(tr("Open Watch File")); - //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + connect(menuAct, SIGNAL(triggered()), this, SLOT(openListCB(void)) ); fileMenu->addAction(menuAct); @@ -90,7 +93,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) menuAct = new QAction(tr("Save"), this); menuAct->setShortcut( QKeySequence(tr("Ctrl+S")) ); menuAct->setStatusTip(tr("Save Watch File")); - //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + connect(menuAct, SIGNAL(triggered()), this, SLOT(saveListCB(void)) ); fileMenu->addAction(menuAct); @@ -98,7 +101,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) menuAct = new QAction(tr("Save As"), this); menuAct->setShortcut( QKeySequence(tr("Ctrl+Shift+S")) ); menuAct->setStatusTip(tr("Save As Watch File")); - //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + connect(menuAct, SIGNAL(triggered()), this, SLOT(saveListAs(void)) ); fileMenu->addAction(menuAct); @@ -106,7 +109,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) menuAct = new QAction(tr("Append"), this); //menuAct->setShortcut( QKeySequence(tr("Ctrl+A")) ); menuAct->setStatusTip(tr("Append to Watch File")); - //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + connect(menuAct, SIGNAL(triggered()), this, SLOT(appendListCB(void)) ); fileMenu->addAction(menuAct); @@ -151,7 +154,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) menuAct = new QAction(tr("Duplicate Watch"), this); menuAct->setShortcut( QKeySequence(tr("A")) ); menuAct->setStatusTip(tr("Duplicate Watch")); - //connect(menuAct, SIGNAL(triggered()), this, SLOT(newListCB(void)) ); + connect(menuAct, SIGNAL(triggered()), this, SLOT(dupWatchClicked(void)) ); watchMenu->addAction(menuAct); @@ -217,28 +220,37 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) up_btn = new QPushButton( tr("Up") ); vbox->addWidget( up_btn ); connect( up_btn, SIGNAL(clicked(void)), this, SLOT(moveWatchUpClicked(void))); + up_btn->setEnabled(false); down_btn = new QPushButton( tr("Down") ); vbox->addWidget( down_btn ); connect( down_btn, SIGNAL(clicked(void)), this, SLOT(moveWatchDownClicked(void))); + down_btn->setEnabled(false); edit_btn = new QPushButton( tr("Edit") ); vbox->addWidget( edit_btn ); connect( edit_btn, SIGNAL(clicked(void)), this, SLOT(editWatchClicked(void))); + edit_btn->setEnabled(false); del_btn = new QPushButton( tr("Remove") ); vbox->addWidget( del_btn ); connect( del_btn, SIGNAL(clicked(void)), this, SLOT(removeWatchClicked(void))); + del_btn->setEnabled(false); new_btn = new QPushButton( tr("New") ); vbox->addWidget( new_btn ); connect( new_btn, SIGNAL(clicked(void)), this, SLOT(newWatchClicked(void))); + new_btn->setEnabled(true); dup_btn = new QPushButton( tr("Duplicate") ); vbox->addWidget( dup_btn ); + connect( dup_btn, SIGNAL(clicked(void)), this, SLOT(dupWatchClicked(void))); + dup_btn->setEnabled(false); sep_btn = new QPushButton( tr("Separator") ); vbox->addWidget( sep_btn ); + sep_btn->setEnabled(true); + connect( sep_btn, SIGNAL(clicked(void)), this, SLOT(sepWatchClicked(void))); mainLayout->addWidget( tree ); mainLayout->addLayout( vbox1 ); @@ -246,6 +258,8 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) cht_btn = new QPushButton( tr("Add Cheat") ); vbox1->addWidget( cht_btn ); + cht_btn->setEnabled(false); + connect( cht_btn, SIGNAL(clicked(void)), this, SLOT(addCheatClicked(void))); setLayout( mainLayout ); @@ -279,6 +293,26 @@ void RamWatchDialog_t::closeWindow(void) //---------------------------------------------------------------------------- void RamWatchDialog_t::periodicUpdate(void) { + bool buttonEnable; + QTreeWidgetItem *item; + + item = tree->currentItem(); + + if ( item == NULL ) + { + buttonEnable = false; + } + else + { + buttonEnable = true; + } + up_btn->setEnabled(buttonEnable); + down_btn->setEnabled(buttonEnable); + edit_btn->setEnabled(buttonEnable); + del_btn->setEnabled(buttonEnable); + dup_btn->setEnabled(buttonEnable); + cht_btn->setEnabled(buttonEnable); + updateRamWatchDisplay(); @@ -304,45 +338,60 @@ void RamWatchDialog_t::updateRamWatchDisplay(void) tree->addTopLevelItem( item ); } - sprintf (addrStr, "$%04X", rw->addr); - - rw->updateMem (); - - if (rw->size == 4) + if ( rw->isSep || (rw->addr < 0) ) { - if (rw->type) - { - sprintf (valStr1, "%u", rw->val.u32); - } - else - { - sprintf (valStr1, "%i", rw->val.i32); - } - sprintf (valStr2, "0x%08X", rw->val.u32); - } - else if (rw->size == 2) - { - if (rw->type) - { - sprintf (valStr1, "%6u", rw->val.u16); - } - else - { - sprintf (valStr1, "%6i", rw->val.i16); - } - sprintf (valStr2, "0x%04X", rw->val.u16); + strcpy (addrStr, "--------"); } else { - if (rw->type) - { - sprintf (valStr1, "%6u", rw->val.u8); - } - else - { - sprintf (valStr1, "%6i", rw->val.i8); - } - sprintf (valStr2, "0x%02X", rw->val.u8); + sprintf (addrStr, "$%04X", rw->addr); + } + + rw->updateMem (); + + if ( rw->isSep || (rw->addr < 0) ) + { + strcpy( valStr1, "--------"); + strcpy( valStr2, "--------"); + } + else + { + if (rw->size == 4) + { + if (rw->type) + { + sprintf (valStr1, "%u", rw->val.u32); + } + else + { + sprintf (valStr1, "%i", rw->val.i32); + } + sprintf (valStr2, "0x%08X", rw->val.u32); + } + else if (rw->size == 2) + { + if (rw->type) + { + sprintf (valStr1, "%6u", rw->val.u16); + } + else + { + sprintf (valStr1, "%6i", rw->val.i16); + } + sprintf (valStr2, "0x%04X", rw->val.u16); + } + else + { + if (rw->type) + { + sprintf (valStr1, "%6u", rw->val.u8); + } + else + { + sprintf (valStr1, "%6i", rw->val.i8); + } + sprintf (valStr2, "0x%02X", rw->val.u8); + } } item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemNeverHasChildren ); @@ -367,10 +416,230 @@ void RamWatchDialog_t::watchClicked( QTreeWidgetItem *item, int column) { // int row = tree->indexOfTopLevelItem(item); +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::newListCB(void) +{ + ramWatchList.clear(); + tree->clear(); + tree->viewport()->update(); +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::openListCB(void) +{ + int ret, useNativeFileDialogVal; + QString filename; + const char *romFile = NULL; + QFileDialog dialog(this, tr("Open Watch File") ); + + dialog.setFileMode(QFileDialog::ExistingFile); + + dialog.setNameFilter(tr("Watch files (*.wch *.WCH) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + dialog.setFilter( QDir::AllEntries | QDir::Hidden ); + dialog.setLabelText( QFileDialog::Accept, tr("Open") ); + + //g_config->getOption ("SDL.LastOpenFile", &last ); + + romFile = getRomFile(); + + if ( romFile != NULL ) + { + char dir[512], base[256]; + + parseFilepath( romFile, dir, base ); + + strcat( base, ".wch"); + + dialog.setDirectory( tr(dir) ); + + dialog.selectFile( tr(base) ); + } + + // 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(); + + loadWatchFile ( filename.toStdString().c_str() ); + + return; +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::appendListCB(void) +{ + int ret, useNativeFileDialogVal; + QString filename; + const char *romFile = NULL; + QFileDialog dialog(this, tr("Append Watch List To File") ); + + if ( ramWatchList.size() == 0 ) + { + return; + } + dialog.setFileMode(QFileDialog::AnyFile); + + dialog.setNameFilter(tr("Watch Files (*.wch *.WCH) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + dialog.setFilter( QDir::AllEntries | QDir::Hidden ); + dialog.setLabelText( QFileDialog::Accept, tr("Save") ); + dialog.setDefaultSuffix( tr(".wch") ); + + romFile = getRomFile(); + + if ( romFile != NULL ) + { + char dir[512], base[256]; + + parseFilepath( romFile, dir, base ); + + strcat( base, ".wch"); + + dialog.setDirectory( tr(dir) ); + + dialog.selectFile( tr(base) ); + } + + // 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(); + + saveWatchFile( filename.toStdString().c_str(), 1 ); +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::saveListCB(void) +{ + if ( ramWatchList.size() == 0 ) + { + return; + } + + if ( saveFileName.size() > 0 ) + { + char file[512]; + + strcpy( file, saveFileName.c_str() ); + + saveWatchFile( file ); + } + else + { + saveListAs(); + } +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::saveListAs(void) +{ + int ret, useNativeFileDialogVal; + QString filename; + const char *romFile = NULL; + QFileDialog dialog(this, tr("Save Watch List To File") ); + + if ( ramWatchList.size() == 0 ) + { + return; + } + dialog.setFileMode(QFileDialog::AnyFile); + + dialog.setNameFilter(tr("Watch Files (*.wch *.WCH) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + dialog.setFilter( QDir::AllEntries | QDir::Hidden ); + dialog.setLabelText( QFileDialog::Accept, tr("Save") ); + dialog.setDefaultSuffix( tr(".wch") ); + + romFile = getRomFile(); + + if ( romFile != NULL ) + { + char dir[512], base[256]; + + parseFilepath( romFile, dir, base ); + + strcat( base, ".wch"); + + dialog.setDirectory( tr(dir) ); + + dialog.selectFile( tr(base) ); + } + + // 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(); + + saveWatchFile( filename.toStdString().c_str() ); } //---------------------------------------------------------------------------- void ramWatch_t::updateMem (void) { + if ( addr < 0 ) + { + return; + } if (size == 1) { val.u8 = GetMem (addr); @@ -385,9 +654,9 @@ void ramWatch_t::updateMem (void) } } //---------------------------------------------------------------------------- -void RamWatchDialog_t::openWatchEditWindow(int idx) +void RamWatchDialog_t::openWatchEditWindow( ramWatch_t *rw, int mode) { - int ret; + int ret, isSep = 0; QDialog dialog(this); QVBoxLayout *mainLayout, *vbox; QHBoxLayout *hbox; @@ -397,12 +666,6 @@ void RamWatchDialog_t::openWatchEditWindow(int idx) QRadioButton *signedTypeBtn, *unsignedTypeBtn; QRadioButton *dataSize1Btn, *dataSize2Btn, *dataSize4Btn; QPushButton *cancelButton, *okButton; - ramWatch_t *rw = NULL; - - if ( idx >= 0 ) - { - rw = ramWatchList.getIndex(idx); - } if ( rw == NULL ) { @@ -422,7 +685,7 @@ void RamWatchDialog_t::openWatchEditWindow(int idx) addrEntry = new QLineEdit(); addrEntry->setMaxLength(4); - addrEntry->setInputMask( ">HHHH;0" ); + addrEntry->setInputMask( ">HHHH;" ); addrEntry->setCursorPosition(0); mainLayout->addLayout( hbox ); @@ -480,8 +743,17 @@ void RamWatchDialog_t::openWatchEditWindow(int idx) { char stmp[64]; - sprintf( stmp, "%04X", rw->addr ); - addrEntry->setText( tr(stmp) ); + isSep = rw->isSep; + + if ( (rw->addr >= 0) && !rw->isSep ) + { + sprintf( stmp, "%04X", rw->addr ); + addrEntry->setText( tr(stmp) ); + } + else + { + addrEntry->setEnabled(false); + } notesEntry->setText( tr(rw->name.c_str()) ); signedTypeBtn->setChecked( !rw->type ); unsignedTypeBtn->setChecked( rw->type ); @@ -519,28 +791,25 @@ void RamWatchDialog_t::openWatchEditWindow(int idx) size = 1; } - if ( rw == NULL ) + if ( (rw == NULL) || mode ) { ramWatchList.add_entry( notesEntry->text().toStdString().c_str(), - addr, unsignedTypeBtn->isChecked(), size ); + addr, unsignedTypeBtn->isChecked(), size, isSep); } else { - rw->name = notesEntry->text().toStdString(); - rw->type = unsignedTypeBtn->isChecked(); - rw->addr = addr; - rw->size = size; + rw->name = notesEntry->text().toStdString(); + rw->type = unsignedTypeBtn->isChecked(); + rw->addr = addr; + rw->size = size; + rw->isSep = isSep; } } } //---------------------------------------------------------------------------- -void RamWatchDialog_t::newWatchClicked(void) -{ - openWatchEditWindow(); -} -//---------------------------------------------------------------------------- -void RamWatchDialog_t::editWatchClicked(void) +void RamWatchDialog_t::addCheatClicked(void) { + ramWatch_t *rw = NULL; QTreeWidgetItem *item; item = tree->currentItem(); @@ -552,7 +821,72 @@ void RamWatchDialog_t::editWatchClicked(void) } int row = tree->indexOfTopLevelItem(item); - openWatchEditWindow(row); + if ( row >= 0 ) + { + rw = ramWatchList.getIndex(row); + } + + if ( rw != NULL ) + { + FCEUI_AddCheat( rw->name.c_str(), rw->addr, GetMem(rw->addr), -1, 1 ); + } +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::newWatchClicked(void) +{ + openWatchEditWindow(); +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::sepWatchClicked(void) +{ + ramWatch_t rw; + + rw.addr = -1; + rw.isSep = 1; + + openWatchEditWindow( &rw, 1 ); +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::editWatchClicked(void) +{ + ramWatch_t *rw = NULL; + QTreeWidgetItem *item; + + item = tree->currentItem(); + + if ( item == NULL ) + { + printf( "No Item Selected\n"); + return; + } + int row = tree->indexOfTopLevelItem(item); + + if ( row >= 0 ) + { + rw = ramWatchList.getIndex(row); + } + openWatchEditWindow(rw, 0); +} +//---------------------------------------------------------------------------- +void RamWatchDialog_t::dupWatchClicked(void) +{ + ramWatch_t *rw = NULL; + QTreeWidgetItem *item; + + item = tree->currentItem(); + + if ( item == NULL ) + { + printf( "No Item Selected\n"); + return; + } + int row = tree->indexOfTopLevelItem(item); + + if ( row >= 0 ) + { + rw = ramWatchList.getIndex(row); + } + openWatchEditWindow(rw, 1); } //---------------------------------------------------------------------------- void RamWatchDialog_t::removeWatchClicked(void) @@ -576,7 +910,14 @@ void RamWatchDialog_t::removeWatchClicked(void) if ( row > 0 ) { - item = tree->topLevelItem( row-1 ); + if ( row >= tree->topLevelItemCount() ) + { + item = tree->topLevelItem( tree->topLevelItemCount()-1 ); + } + else + { + item = tree->topLevelItem( row ); + } } else { @@ -605,6 +946,7 @@ void RamWatchDialog_t::moveWatchUpClicked(void) if ( row > 0 ) { + ramWatchList.moveIndexUp(row); item = tree->topLevelItem( row-1 ); if ( item ) @@ -630,6 +972,8 @@ void RamWatchDialog_t::moveWatchDownClicked(void) if ( row < (tree->topLevelItemCount()-1) ) { + ramWatchList.moveIndexDown(row); + item = tree->topLevelItem( row+1 ); if ( item ) @@ -640,21 +984,24 @@ void RamWatchDialog_t::moveWatchDownClicked(void) } } //---------------------------------------------------------------------------- -void RamWatchDialog_t::saveWatchFile (const char *filename) +void RamWatchDialog_t::saveWatchFile (const char *filename, int append ) { int i; FILE *fp; - const char *c; + const char *c, *mode; std::list < ramWatch_t * >::iterator it; ramWatch_t *rw; - fp = fopen (filename, "w"); + mode = (append) ? "a" : "w"; + + fp = fopen (filename, mode); if (fp == NULL) { printf ("Error: Failed to open file: %s\n", filename); return; } + saveFileName.assign( filename ); for (it = ramWatchList.ls.begin (); it != ramWatchList.ls.end (); it++) { @@ -662,8 +1009,15 @@ void RamWatchDialog_t::saveWatchFile (const char *filename) c = rw->name.c_str (); - fprintf (fp, "0x%04x %c%i ", rw->addr, rw->type ? 'U' : 'S', - rw->size); + if ( rw->isSep ) + { + fprintf (fp, "0x%04x %c%c ", rw->addr, 'S', 'S' ); + } + else + { + fprintf (fp, "0x%04x %c%i ", rw->addr, rw->type ? 'U' : 'S', + rw->size); + } i = 0; fprintf (fp, "\""); @@ -688,7 +1042,7 @@ void RamWatchDialog_t::saveWatchFile (const char *filename) void RamWatchDialog_t::loadWatchFile (const char *filename) { FILE *fp; - int i, j, a, t, s, literal; + int i, j, a, t, s, isSep, literal; char line[512], stmp[512]; ramWatch_t *rw; @@ -699,12 +1053,14 @@ void RamWatchDialog_t::loadWatchFile (const char *filename) printf ("Error: Failed to open file: %s\n", filename); return; } + saveFileName.assign( filename ); while (fgets (line, sizeof (line) - 1, fp) != NULL) { a = -1; t = -1; s = -1; + isSep = 0; // Check for Comments i = 0; while (line[i] != 0) @@ -775,12 +1131,19 @@ void RamWatchDialog_t::loadWatchFile (const char *filename) printf ("Error: Invalid RAM Watch Byte Type: %c", t); continue; } - if (!isdigit (s)) + if (!isdigit (s) && (s != 'S')) { printf ("Error: Invalid RAM Watch Byte Size: %c", s); continue; } - s = s - '0'; + if (s == 'S') + { + isSep = 1; s = 1; + } + else + { + s = s - '0'; + } if ((s != 1) && (s != 2) && (s != 4)) { @@ -823,16 +1186,15 @@ void RamWatchDialog_t::loadWatchFile (const char *filename) } rw = new ramWatch_t; - rw->addr = a; - rw->type = (t == 'U') ? 1 : 0; - rw->size = s; + rw->addr = a; + rw->type = (t == 'U') ? 1 : 0; + rw->size = s; + rw->isSep = isSep; rw->name.assign (stmp); ramWatchList.ls.push_back (rw); } fclose (fp); - - //showAllRamWatchResults (1); } //---------------------------------------------------------------------------- diff --git a/src/drivers/Qt/RamWatch.h b/src/drivers/Qt/RamWatch.h index 06335e98..f1bcfdd0 100644 --- a/src/drivers/Qt/RamWatch.h +++ b/src/drivers/Qt/RamWatch.h @@ -25,6 +25,7 @@ struct ramWatch_t int addr; int type; int size; + int isSep; union { @@ -41,6 +42,7 @@ struct ramWatch_t addr = 0; type = 0; size = 0; + isSep = 0; val.u32 = 0; }; @@ -76,14 +78,29 @@ struct ramWatchList_t return ls.size (); }; - void add_entry (const char *name, int addr, int type, int size) + void clear(void) + { + ramWatch_t *rw; + + while (!ls.empty ()) + { + rw = ls.front (); + + delete rw; + + ls.pop_front (); + } + } + + void add_entry (const char *name, int addr, int type, int size, int isSep = 0) { ramWatch_t *rw = new ramWatch_t; rw->name.assign (name); - rw->addr = addr; - rw->type = type; - rw->size = size; + rw->addr = addr; + rw->type = type; + rw->size = size; + rw->isSep = isSep; ls.push_back (rw); } @@ -133,6 +150,51 @@ struct ramWatchList_t } return -1; } + + int moveIndexUp(size_t idx) + { + size_t i = 0; + std::list < ramWatch_t * >::iterator it, lp; + + lp = ls.begin(); + + for (it = ls.begin (); it != ls.end (); it++) + { + if (i == idx) + { + ls.insert( lp, *it ); + ls.erase (it); + return 0; + } + lp = it; + + i++; + } + return -1; + } + + int moveIndexDown(size_t idx) + { + size_t i = 0; + std::list < ramWatch_t * >::iterator it, next; + + for (it = ls.begin (); it != ls.end (); it++) + { + if (i == idx) + { + next = it; next++; + + if ( next != ls.end() ) + { + ls.insert( it, *next ); + ls.erase (next); + } + return 0; + } + i++; + } + return -1; + } }; class RamWatchDialog_t : public QDialog @@ -146,7 +208,7 @@ class RamWatchDialog_t : public QDialog protected: void closeEvent(QCloseEvent *event); void loadWatchFile (const char *filename); - void saveWatchFile (const char *filename); + void saveWatchFile (const char *filename, int append = 0); QFont font; QTreeWidget *tree; @@ -160,19 +222,29 @@ class RamWatchDialog_t : public QDialog QPushButton *cht_btn; QTimer *updateTimer; - ramWatchList_t ramWatchList; + std::string saveFileName; + + //ramWatchList_t ramWatchList; int fontCharWidth; private: void updateRamWatchDisplay(void); - void openWatchEditWindow( int idx = -1); + void openWatchEditWindow( ramWatch_t *rw = NULL, int mode = 0); public slots: void closeWindow(void); private slots: + void newListCB(void); + void openListCB(void); + void saveListCB(void); + void saveListAs(void); + void appendListCB(void); void periodicUpdate(void); + void addCheatClicked(void); void newWatchClicked(void); + void sepWatchClicked(void); + void dupWatchClicked(void); void editWatchClicked(void); void removeWatchClicked(void); void moveWatchUpClicked(void); @@ -180,3 +252,5 @@ class RamWatchDialog_t : public QDialog void watchClicked( QTreeWidgetItem *item, int column); }; + +extern ramWatchList_t ramWatchList; diff --git a/src/drivers/Qt/TraceLogger.cpp b/src/drivers/Qt/TraceLogger.cpp index d8e098ff..120e316c 100644 --- a/src/drivers/Qt/TraceLogger.cpp +++ b/src/drivers/Qt/TraceLogger.cpp @@ -659,6 +659,9 @@ int traceRecord_t::convToText( char *txt ) char stmp[128]; char str_axystate[32], str_procstatus[32]; + str_axystate[0] = 0; + str_procstatus[0] = 0; + txt[0] = 0; if ( opSize == 0 ) { From e03c558db6fc4b4537bb062c100104f8e65d6240 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 9 Oct 2020 22:51:56 -0400 Subject: [PATCH 07/10] Updated Qt RAM watch file format to match windows version. --- src/drivers/Qt/RamWatch.cpp | 112 +++++++++++++++++++++++++++--------- src/drivers/Qt/RamWatch.h | 2 +- 2 files changed, 86 insertions(+), 28 deletions(-) diff --git a/src/drivers/Qt/RamWatch.cpp b/src/drivers/Qt/RamWatch.cpp index f6423952..e51f796e 100644 --- a/src/drivers/Qt/RamWatch.cpp +++ b/src/drivers/Qt/RamWatch.cpp @@ -358,7 +358,7 @@ void RamWatchDialog_t::updateRamWatchDisplay(void) { if (rw->size == 4) { - if (rw->type) + if (rw->type == 'u') { sprintf (valStr1, "%u", rw->val.u32); } @@ -370,7 +370,7 @@ void RamWatchDialog_t::updateRamWatchDisplay(void) } else if (rw->size == 2) { - if (rw->type) + if (rw->type == 'u') { sprintf (valStr1, "%6u", rw->val.u16); } @@ -382,7 +382,7 @@ void RamWatchDialog_t::updateRamWatchDisplay(void) } else { - if (rw->type) + if (rw->type == 'u') { sprintf (valStr1, "%6u", rw->val.u8); } @@ -755,8 +755,8 @@ void RamWatchDialog_t::openWatchEditWindow( ramWatch_t *rw, int mode) addrEntry->setEnabled(false); } notesEntry->setText( tr(rw->name.c_str()) ); - signedTypeBtn->setChecked( !rw->type ); - unsignedTypeBtn->setChecked( rw->type ); + signedTypeBtn->setChecked( rw->type != 'u' ); + unsignedTypeBtn->setChecked( rw->type == 'u' ); dataSize1Btn->setChecked( rw->size == 1 ); dataSize2Btn->setChecked( rw->size == 2 ); dataSize4Btn->setChecked( rw->size == 4 ); @@ -799,7 +799,7 @@ void RamWatchDialog_t::openWatchEditWindow( ramWatch_t *rw, int mode) else { rw->name = notesEntry->text().toStdString(); - rw->type = unsignedTypeBtn->isChecked(); + rw->type = unsignedTypeBtn->isChecked() ? 'u' : 's'; rw->addr = addr; rw->size = size; rw->isSep = isSep; @@ -986,7 +986,7 @@ void RamWatchDialog_t::moveWatchDownClicked(void) //---------------------------------------------------------------------------- void RamWatchDialog_t::saveWatchFile (const char *filename, int append ) { - int i; + int i, lineCount = 0, sizeChar; FILE *fp; const char *c, *mode; std::list < ramWatch_t * >::iterator it; @@ -1003,6 +1003,8 @@ void RamWatchDialog_t::saveWatchFile (const char *filename, int append ) } saveFileName.assign( filename ); + fprintf( fp, "\n%zi\n", ramWatchList.size() ); + for (it = ramWatchList.ls.begin (); it != ramWatchList.ls.end (); it++) { rw = *it; @@ -1011,16 +1013,26 @@ void RamWatchDialog_t::saveWatchFile (const char *filename, int append ) if ( rw->isSep ) { - fprintf (fp, "0x%04x %c%c ", rw->addr, 'S', 'S' ); + fprintf (fp, "%05i %04X %c %c 0 ", lineCount, rw->addr, 'S', 'S' ); } else { - fprintf (fp, "0x%04x %c%i ", rw->addr, rw->type ? 'U' : 'S', - rw->size); + if ( rw->size == 4 ) + { + sizeChar = 'd'; + } + else if ( rw->size == 2 ) + { + sizeChar = 'w'; + } + else + { + sizeChar = 'b'; + } + fprintf (fp, "%05i %04X %c %c 0 ", lineCount, rw->addr, sizeChar, rw->type); } i = 0; - fprintf (fp, "\""); while (c[i]) { if (c[i] == '"') @@ -1033,7 +1045,9 @@ void RamWatchDialog_t::saveWatchFile (const char *filename, int append ) } i++; } - fprintf (fp, "\"\n"); + fprintf (fp, "\n"); + + lineCount++; } fclose (fp); @@ -1088,14 +1102,13 @@ void RamWatchDialog_t::loadWatchFile (const char *filename) j = 0; while (isspace (line[i])) i++; + while ( isdigit(line[i]) ) i++; + + while (isspace (line[i])) i++; + if ((line[i] == '0') && (tolower (line[i + 1]) == 'x')) { - stmp[j] = '0'; - j++; - i++; - stmp[j] = 'x'; - j++; - i++; + i += 2; while (isxdigit (line[i])) { @@ -1117,30 +1130,45 @@ void RamWatchDialog_t::loadWatchFile (const char *filename) if (j == 0) continue; - a = strtol (stmp, NULL, 0); + a = strtol (stmp, NULL, 16); while (isspace (line[i])) i++; - t = line[i]; - i++; - s = line[i]; + s = tolower(line[i]); i++; - if ((t != 'U') && (t != 'S')) + while (isspace (line[i])) i++; + + t = tolower(line[i]); + i++; + + if ((t != 'u') && (t != 's') && (t != 'h') && (t != 'b') ) { printf ("Error: Invalid RAM Watch Byte Type: %c", t); continue; } - if (!isdigit (s) && (s != 'S')) + if (!isdigit (s) && (s != 's') && (s != 'b') && (s != 'w') && (s != 'd') ) { printf ("Error: Invalid RAM Watch Byte Size: %c", s); continue; } - if (s == 'S') + if (s == 's') { isSep = 1; s = 1; } - else + else if ( s == 'b' ) + { + s = 1; + } + else if ( s == 'w' ) + { + s = 2; + } + else if ( s == 'd' ) + { + s = 4; + } + else if ( isdigit(s) ) { s = s - '0'; } @@ -1150,6 +1178,9 @@ void RamWatchDialog_t::loadWatchFile (const char *filename) printf ("Error: Invalid RAM Watch Byte Size: %i", s); continue; } + while (isspace (line[i])) i++; + + while (isdigit(line[i])) i++; while (isspace (line[i])) i++; @@ -1184,10 +1215,37 @@ void RamWatchDialog_t::loadWatchFile (const char *filename) } stmp[j] = 0; } + else + { + j=0; + while (line[i] != 0) + { + if ( line[i] == '\n') + { + break; + } + stmp[j] = line[i]; i++; j++; + } + stmp[j] = 0; + } + + j--; + while ( j >= 0 ) + { + if ( isspace(stmp[j]) ) + { + stmp[j] = 0; + } + else + { + break; + } + j--; + } rw = new ramWatch_t; rw->addr = a; - rw->type = (t == 'U') ? 1 : 0; + rw->type = t; rw->size = s; rw->isSep = isSep; rw->name.assign (stmp); diff --git a/src/drivers/Qt/RamWatch.h b/src/drivers/Qt/RamWatch.h index f1bcfdd0..23e1c131 100644 --- a/src/drivers/Qt/RamWatch.h +++ b/src/drivers/Qt/RamWatch.h @@ -40,7 +40,7 @@ struct ramWatch_t ramWatch_t (void) { addr = 0; - type = 0; + type = 's'; size = 0; isSep = 0; val.u32 = 0; From 66c34c2d497da24da2c229fd5f6b73e178eac06a Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 9 Oct 2020 23:08:40 -0400 Subject: [PATCH 08/10] A couple bug fixes for the Qt RAM watch window. --- src/drivers/Qt/RamWatch.cpp | 40 +++++++++++++++++++++++-------------- src/drivers/Qt/RamWatch.h | 2 +- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/drivers/Qt/RamWatch.cpp b/src/drivers/Qt/RamWatch.cpp index e51f796e..4bd298b2 100644 --- a/src/drivers/Qt/RamWatch.cpp +++ b/src/drivers/Qt/RamWatch.cpp @@ -106,9 +106,9 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) fileMenu->addAction(menuAct); // File -> Append - menuAct = new QAction(tr("Append"), this); + menuAct = new QAction(tr("Append from File"), this); //menuAct->setShortcut( QKeySequence(tr("Ctrl+A")) ); - menuAct->setStatusTip(tr("Append to Watch File")); + menuAct->setStatusTip(tr("Append from File")); connect(menuAct, SIGNAL(triggered()), this, SLOT(appendListCB(void)) ); fileMenu->addAction(menuAct); @@ -209,7 +209,7 @@ RamWatchDialog_t::RamWatchDialog_t(QWidget *parent) tree->setHeaderItem( item ); - tree->header()->setSectionResizeMode( QHeaderView::ResizeToContents ); + //tree->header()->setSectionResizeMode( QHeaderView::ResizeToContents ); vbox1 = new QVBoxLayout(); vbox = new QVBoxLayout(); @@ -344,7 +344,14 @@ void RamWatchDialog_t::updateRamWatchDisplay(void) } else { - sprintf (addrStr, "$%04X", rw->addr); + if ( rw->size > 1 ) + { + sprintf (addrStr, "$%04X-$%04X", rw->addr, rw->addr + rw->size - 1); + } + else + { + sprintf (addrStr, "$%04X", rw->addr); + } } rw->updateMem (); @@ -403,8 +410,8 @@ void RamWatchDialog_t::updateRamWatchDisplay(void) item->setText( 3, tr(rw->name.c_str()) ); item->setTextAlignment( 0, Qt::AlignLeft); - item->setTextAlignment( 1, Qt::AlignLeft); - item->setTextAlignment( 2, Qt::AlignLeft); + item->setTextAlignment( 1, Qt::AlignCenter); + item->setTextAlignment( 2, Qt::AlignCenter); item->setTextAlignment( 3, Qt::AlignLeft); idx++; @@ -492,19 +499,15 @@ void RamWatchDialog_t::appendListCB(void) int ret, useNativeFileDialogVal; QString filename; const char *romFile = NULL; - QFileDialog dialog(this, tr("Append Watch List To File") ); + QFileDialog dialog(this, tr("Append from Watch File") ); - if ( ramWatchList.size() == 0 ) - { - return; - } - dialog.setFileMode(QFileDialog::AnyFile); + dialog.setFileMode(QFileDialog::ExistingFile); dialog.setNameFilter(tr("Watch Files (*.wch *.WCH) ;; All files (*)")); dialog.setViewMode(QFileDialog::List); dialog.setFilter( QDir::AllEntries | QDir::Hidden ); - dialog.setLabelText( QFileDialog::Accept, tr("Save") ); + dialog.setLabelText( QFileDialog::Accept, tr("Load") ); dialog.setDefaultSuffix( tr(".wch") ); romFile = getRomFile(); @@ -547,7 +550,7 @@ void RamWatchDialog_t::appendListCB(void) } //qDebug() << "selected file path : " << filename.toUtf8(); - saveWatchFile( filename.toStdString().c_str(), 1 ); + loadWatchFile( filename.toStdString().c_str(), 1 ); } //---------------------------------------------------------------------------- void RamWatchDialog_t::saveListCB(void) @@ -1053,7 +1056,7 @@ void RamWatchDialog_t::saveWatchFile (const char *filename, int append ) } //---------------------------------------------------------------------------- -void RamWatchDialog_t::loadWatchFile (const char *filename) +void RamWatchDialog_t::loadWatchFile (const char *filename, int append ) { FILE *fp; int i, j, a, t, s, isSep, literal; @@ -1069,6 +1072,13 @@ void RamWatchDialog_t::loadWatchFile (const char *filename) } saveFileName.assign( filename ); + if ( !append ) + { + ramWatchList.clear(); + tree->clear(); + tree->viewport()->update(); + } + while (fgets (line, sizeof (line) - 1, fp) != NULL) { a = -1; diff --git a/src/drivers/Qt/RamWatch.h b/src/drivers/Qt/RamWatch.h index 23e1c131..b15b1b4d 100644 --- a/src/drivers/Qt/RamWatch.h +++ b/src/drivers/Qt/RamWatch.h @@ -207,7 +207,7 @@ class RamWatchDialog_t : public QDialog protected: void closeEvent(QCloseEvent *event); - void loadWatchFile (const char *filename); + void loadWatchFile (const char *filename, int append = 0); void saveWatchFile (const char *filename, int append = 0); QFont font; From a03b5d9ae8868b8424bad917498bb48af4f1561d Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 10 Oct 2020 09:03:19 -0400 Subject: [PATCH 09/10] Qt RAM watch window separator logic changed so that separator lines can span full width of viewport. Minor bug fixes to Qt RAM watch add/edit window --- src/drivers/Qt/RamWatch.cpp | 106 +++++++++++++++++++++++++++++------- 1 file changed, 86 insertions(+), 20 deletions(-) diff --git a/src/drivers/Qt/RamWatch.cpp b/src/drivers/Qt/RamWatch.cpp index 4bd298b2..63b6b5ab 100644 --- a/src/drivers/Qt/RamWatch.cpp +++ b/src/drivers/Qt/RamWatch.cpp @@ -337,6 +337,11 @@ void RamWatchDialog_t::updateRamWatchDisplay(void) item = new QTreeWidgetItem(); tree->addTopLevelItem( item ); + + item->setFont( 0, font); + item->setFont( 1, font); + item->setFont( 2, font); + item->setFont( 3, font); } if ( rw->isSep || (rw->addr < 0) ) { @@ -365,37 +370,37 @@ void RamWatchDialog_t::updateRamWatchDisplay(void) { if (rw->size == 4) { - if (rw->type == 'u') + if (rw->type == 's') { - sprintf (valStr1, "%u", rw->val.u32); + sprintf (valStr1, "%i", rw->val.i32); } else { - sprintf (valStr1, "%i", rw->val.i32); + sprintf (valStr1, "%u", rw->val.u32); } sprintf (valStr2, "0x%08X", rw->val.u32); } else if (rw->size == 2) { - if (rw->type == 'u') + if (rw->type == 's') { - sprintf (valStr1, "%6u", rw->val.u16); + sprintf (valStr1, "%6i", rw->val.i16); } else { - sprintf (valStr1, "%6i", rw->val.i16); + sprintf (valStr1, "%6u", rw->val.u16); } sprintf (valStr2, "0x%04X", rw->val.u16); } else { - if (rw->type == 'u') + if (rw->type == 's') { - sprintf (valStr1, "%6u", rw->val.u8); + sprintf (valStr1, "%6i", rw->val.i8); } else { - sprintf (valStr1, "%6i", rw->val.i8); + sprintf (valStr1, "%6u", rw->val.u8); } sprintf (valStr2, "0x%02X", rw->val.u8); } @@ -403,11 +408,45 @@ void RamWatchDialog_t::updateRamWatchDisplay(void) item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemNeverHasChildren ); - //item->setFont(font); - item->setText( 0, tr(addrStr) ); - item->setText( 1, tr(valStr1) ); - item->setText( 2, tr(valStr2) ); - item->setText( 3, tr(rw->name.c_str()) ); + if ( rw->isSep ) + { + int i,j; + char stmp[256]; + const char *c; + + j=0; + + for (i=0; i<3; i++) + { + stmp[j] = '-'; j++; + } + stmp[j] = ' '; j++; + + c = rw->name.c_str(); i = 0; + + while ( c[i] != 0 ) + { + stmp[j] = c[i]; j++; i++; + } + stmp[j] = ' '; j++; + + while ( j < 64 ) + { + stmp[j] = '-'; j++; + } + stmp[j] = 0; + + item->setFirstColumnSpanned(true); + item->setText( 0, tr(stmp) ); + } + else + { + item->setFirstColumnSpanned(false); + item->setText( 0, tr(addrStr) ); + item->setText( 1, tr(valStr1) ); + item->setText( 2, tr(valStr2) ); + item->setText( 3, tr(rw->name.c_str()) ); + } item->setTextAlignment( 0, Qt::AlignLeft); item->setTextAlignment( 1, Qt::AlignCenter); @@ -676,7 +715,21 @@ void RamWatchDialog_t::openWatchEditWindow( ramWatch_t *rw, int mode) } else { - dialog.setWindowTitle("Edit Watch"); + if ( rw->isSep ) + { + if ( mode ) + { + dialog.setWindowTitle("Add Separator"); + } + else + { + dialog.setWindowTitle("Edit Separator"); + } + } + else + { + dialog.setWindowTitle("Edit Watch"); + } } mainLayout = new QVBoxLayout(); @@ -757,12 +810,25 @@ void RamWatchDialog_t::openWatchEditWindow( ramWatch_t *rw, int mode) { addrEntry->setEnabled(false); } + notesEntry->setText( tr(rw->name.c_str()) ); - signedTypeBtn->setChecked( rw->type != 'u' ); - unsignedTypeBtn->setChecked( rw->type == 'u' ); - dataSize1Btn->setChecked( rw->size == 1 ); - dataSize2Btn->setChecked( rw->size == 2 ); - dataSize4Btn->setChecked( rw->size == 4 ); + + if ( rw->isSep ) + { + signedTypeBtn->setEnabled(false); + unsignedTypeBtn->setEnabled(false); + dataSize1Btn->setEnabled(false); + dataSize2Btn->setEnabled(false); + dataSize4Btn->setEnabled(false); + } + else + { + signedTypeBtn->setChecked( rw->type == 's' ); + unsignedTypeBtn->setChecked( rw->type != 's' ); + dataSize1Btn->setChecked( rw->size == 1 ); + dataSize2Btn->setChecked( rw->size == 2 ); + dataSize4Btn->setChecked( rw->size == 4 ); + } } else { From 689e1d1898c2592abd3ae739f546f7e8e334f8d8 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 10 Oct 2020 09:28:38 -0400 Subject: [PATCH 10/10] Updated TODO-SDL window so finished status on Qt RAM Watch window. --- TODO-SDL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO-SDL b/TODO-SDL index 6fc0b1bb..2a81dfdc 100644 --- a/TODO-SDL +++ b/TODO-SDL @@ -39,7 +39,7 @@ Movie record/save/play functionality | YES | YES Cheat search window | YES | YES | Active Cheat window | YES | YES | RAM Search Window | NO | NO | -RAM Watch Window | NO | YES | +RAM Watch Window | YES | YES | Memory Watch Window | NO | NO | TAS Editor | NO | NO | 6502 Debugger Window | YES | YES |