From 086d523566cff669db2a1534bce248ce6d757ee7 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 27 Sep 2020 10:59:24 -0400 Subject: [PATCH 1/5] Added initial code data logger window layout for Qt GUI. --- src/CMakeLists.txt | 1 + src/drivers/Qt/CodeDataLogger.cpp | 168 ++++++++++++++++++++++++++++++ src/drivers/Qt/CodeDataLogger.h | 48 +++++++++ src/drivers/Qt/ConsoleWindow.cpp | 22 +++- src/drivers/Qt/ConsoleWindow.h | 2 + 5 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 src/drivers/Qt/CodeDataLogger.cpp create mode 100644 src/drivers/Qt/CodeDataLogger.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0e90b19b..04c266e1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -432,6 +432,7 @@ set(SRC_DRIVERS_SDL ${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/CodeDataLogger.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/SymbolicDebug.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleDebugger.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleUtilities.cpp diff --git a/src/drivers/Qt/CodeDataLogger.cpp b/src/drivers/Qt/CodeDataLogger.cpp new file mode 100644 index 00000000..4ec7a510 --- /dev/null +++ b/src/drivers/Qt/CodeDataLogger.cpp @@ -0,0 +1,168 @@ +// CodeDataLogger.cpp +// +#include +#include +#include + +#include "Qt/CodeDataLogger.h" +#include "Qt/main.h" +#include "Qt/dface.h" +#include "Qt/input.h" +#include "Qt/config.h" +#include "Qt/fceuWrapper.h" + +//---------------------------------------------------- +CodeDataLoggerDialog_t::CodeDataLoggerDialog_t(QWidget *parent) + : QDialog( parent ) +{ + QVBoxLayout *mainLayout, *vbox1, *vbox; + QHBoxLayout *hbox; + QGridLayout *grid; + QGroupBox *frame, *subframe; + QPushButton *btn; + QLabel *lbl; + + updateTimer = new QTimer( this ); + + connect( updateTimer, &QTimer::timeout, this, &CodeDataLoggerDialog_t::updatePeriodic ); + + setWindowTitle( tr("Code Data Logger") ); + + mainLayout = new QVBoxLayout(); + vbox1 = new QVBoxLayout(); + grid = new QGridLayout(); + lbl = new QLabel( tr("Press Start to Run Logger") ); + cdlFileLabel = new QLabel( tr("CDL File:") ); + + vbox1->addLayout( grid ); + vbox1->addWidget( lbl ); + vbox1->addWidget( cdlFileLabel ); + + frame = new QGroupBox(tr("Code/Data Log Status")); + frame->setLayout( vbox1 ); + + prgLoggedCodeLabel = new QLabel( tr("0x00000 0.00%") ); + prgLoggedDataLabel = new QLabel( tr("0x00000 0.00%") ); + prgUnloggedLabel = new QLabel( tr("0x00000 0.00%") ); + chrLoggedCodeLabel = new QLabel( tr("0x00000 0.00%") ); + chrLoggedDataLabel = new QLabel( tr("0x00000 0.00%") ); + chrUnloggedLabel = new QLabel( tr("0x00000 0.00%") ); + autoSaveCdlCbox = new QCheckBox( tr("Auto-save .CDL when closing ROMs") ); + autoLoadCdlCbox = new QCheckBox( tr("Auto-load .CDL when opening this window") ); + autoResumeLogCbox = new QCheckBox( tr("Auto-resume logging when loading ROMs") ); + + subframe = new QGroupBox(tr("PRG Logged as Code")); + vbox = new QVBoxLayout(); + vbox->addWidget( prgLoggedCodeLabel ); + subframe->setLayout( vbox ); + + grid->addWidget( subframe, 0, 0, Qt::AlignCenter ); + + subframe = new QGroupBox(tr("PRG Logged as Data")); + vbox = new QVBoxLayout(); + vbox->addWidget( prgLoggedDataLabel ); + subframe->setLayout( vbox ); + + grid->addWidget( subframe, 0, 1, Qt::AlignCenter ); + + subframe = new QGroupBox(tr("PRG not Logged")); + vbox = new QVBoxLayout(); + vbox->addWidget( prgUnloggedLabel ); + subframe->setLayout( vbox ); + + grid->addWidget( subframe, 0, 2, Qt::AlignCenter ); + + subframe = new QGroupBox(tr("CHR Logged as Code")); + vbox = new QVBoxLayout(); + vbox->addWidget( chrLoggedCodeLabel ); + subframe->setLayout( vbox ); + + grid->addWidget( subframe, 1, 0, Qt::AlignCenter ); + + subframe = new QGroupBox(tr("CHR Logged as Data")); + vbox = new QVBoxLayout(); + vbox->addWidget( chrLoggedDataLabel ); + subframe->setLayout( vbox ); + + grid->addWidget( subframe, 1, 1, Qt::AlignCenter ); + + subframe = new QGroupBox(tr("CHR not Logged")); + vbox = new QVBoxLayout(); + vbox->addWidget( chrUnloggedLabel ); + subframe->setLayout( vbox ); + + grid->addWidget( subframe, 1, 2, Qt::AlignCenter ); + + grid = new QGridLayout(); + vbox1->addLayout( grid ); + btn = new QPushButton( tr("Reset Log") ); + grid->addWidget( btn, 0, 0, Qt::AlignCenter ); + + btn = new QPushButton( tr("Start") ); + grid->addWidget( btn, 0, 1, Qt::AlignCenter ); + + btn = new QPushButton( tr("Save") ); + grid->addWidget( btn, 0, 2, Qt::AlignCenter ); + + btn = new QPushButton( tr("Load") ); + grid->addWidget( btn, 1, 0, Qt::AlignCenter ); + + btn = new QPushButton( tr("Save As") ); + grid->addWidget( btn, 1, 2, Qt::AlignCenter ); + + hbox = new QHBoxLayout(); + vbox1->addLayout( hbox ); + + subframe = new QGroupBox(tr("Logging Workflow Options")); + vbox = new QVBoxLayout(); + vbox->addWidget( autoSaveCdlCbox ); + vbox->addWidget( autoLoadCdlCbox ); + vbox->addWidget( autoResumeLogCbox ); + subframe->setLayout( vbox ); + hbox->addWidget( subframe ); + + subframe = new QGroupBox(tr("Generate ROM")); + vbox = new QVBoxLayout(); + + btn = new QPushButton( tr("Save Stripped Data") ); + vbox->addWidget( btn ); + btn = new QPushButton( tr("Save Unused Data") ); + vbox->addWidget( btn ); + subframe->setLayout( vbox ); + hbox->addWidget( subframe ); + + mainLayout->addWidget( frame ); + + setLayout( mainLayout ); + + updateTimer->start( 100 ); // 10hz + +} +//---------------------------------------------------- +CodeDataLoggerDialog_t::~CodeDataLoggerDialog_t(void) +{ + updateTimer->stop(); + + printf("Code Data Logger Window Deleted\n"); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::closeEvent(QCloseEvent *event) +{ + printf("Code Data Logger Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::closeWindow(void) +{ + printf("Code Data Logger Close Window\n"); + done(0); + deleteLater(); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::updatePeriodic(void) +{ + +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/CodeDataLogger.h b/src/drivers/Qt/CodeDataLogger.h new file mode 100644 index 00000000..301e710e --- /dev/null +++ b/src/drivers/Qt/CodeDataLogger.h @@ -0,0 +1,48 @@ +// CodeDataLogger.h +// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class CodeDataLoggerDialog_t : public QDialog +{ + Q_OBJECT + + public: + CodeDataLoggerDialog_t(QWidget *parent = 0); + ~CodeDataLoggerDialog_t(void); + + protected: + QTimer *updateTimer; + QLabel *prgLoggedCodeLabel; + QLabel *prgLoggedDataLabel; + QLabel *prgUnloggedLabel; + QLabel *chrLoggedCodeLabel; + QLabel *chrLoggedDataLabel; + QLabel *chrUnloggedLabel; + QLabel *cdlFileLabel; + QCheckBox *autoSaveCdlCbox; + QCheckBox *autoLoadCdlCbox; + QCheckBox *autoResumeLogCbox; + void closeEvent(QCloseEvent *bar); + private: + + public slots: + void closeWindow(void); + private slots: + void updatePeriodic(void); + +}; + diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 9e06722e..44e701e1 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -25,6 +25,7 @@ #include "Qt/LuaControl.h" #include "Qt/CheatsConf.h" #include "Qt/HexEditor.h" +#include "Qt/CodeDataLogger.h" #include "Qt/ConsoleDebugger.h" #include "Qt/ConsoleUtilities.h" #include "Qt/ConsoleSoundConf.h" @@ -483,7 +484,7 @@ void consoleWin_t::createMainMenu(void) // Debug debugMenu = menuBar()->addMenu(tr("Debug")); - // Debug -> Hex Editor + // Debug -> Debugger debuggerAct = new QAction(tr("Debugger..."), this); //debuggerAct->setShortcut( QKeySequence(tr("Shift+F7"))); debuggerAct->setStatusTip(tr("Open 6502 Debugger")); @@ -499,6 +500,14 @@ void consoleWin_t::createMainMenu(void) debugMenu->addAction(hexEditAct); + // Debug -> Code/Data Logger + codeDataLogAct = new QAction(tr("Code/Data Logger..."), this); + //codeDataLogAct->setShortcut( QKeySequence(tr("Shift+F7"))); + codeDataLogAct->setStatusTip(tr("Open Code Data Logger")); + connect(codeDataLogAct, SIGNAL(triggered()), this, SLOT(openCodeDataLogger(void)) ); + + debugMenu->addAction(codeDataLogAct); + //----------------------------------------------------------------------- // Movie movieMenu = menuBar()->addMenu(tr("Movie")); @@ -1003,6 +1012,17 @@ void consoleWin_t::openHexEditor(void) hexEditWin->show(); } +void consoleWin_t::openCodeDataLogger(void) +{ + CodeDataLoggerDialog_t *cdlWin; + + //printf("Open Code Data Logger Window\n"); + + cdlWin = new CodeDataLoggerDialog_t(this); + + cdlWin->show(); +} + void consoleWin_t::toggleAutoResume(void) { //printf("Auto Resume: %i\n", autoResume->isChecked() ); diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index e2f16e33..501c018a 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -90,6 +90,7 @@ class consoleWin_t : public QMainWindow QAction *fdsLoadBiosAct; QAction *cheatsAct; QAction *debuggerAct; + QAction *codeDataLogAct; QAction *hexEditAct; QAction *openMovAct; QAction *stopMovAct; @@ -133,6 +134,7 @@ class consoleWin_t : public QMainWindow void openHotkeyConfWin(void); void openPaletteConfWin(void); void openGuiConfWin(void); + void openCodeDataLogger(void); void toggleAutoResume(void); void toggleFullscreen(void); void updatePeriodic(void); From 445b17104a7ed12ab01aacb4f82ec17b905a635e Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Mon, 28 Sep 2020 21:23:47 -0400 Subject: [PATCH 2/5] Successful initial test of Qt Code/Data Logger Window. --- src/debug.cpp | 8 +- src/drivers/Qt/CodeDataLogger.cpp | 386 +++++++++++++++++++++++++++- src/drivers/Qt/CodeDataLogger.h | 41 ++- src/drivers/Qt/ConsoleUtilities.cpp | 60 +++++ src/drivers/Qt/ConsoleUtilities.h | 2 + src/drivers/Qt/config.cpp | 5 + src/drivers/Qt/fceuWrapper.cpp | 21 +- src/ppu.h | 4 + 8 files changed, 496 insertions(+), 31 deletions(-) diff --git a/src/debug.cpp b/src/debug.cpp index 47e873ed..89bcafa8 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -421,12 +421,12 @@ int condition(watchpointinfo* wp) //--------------------- -volatile int codecount, datacount, undefinedcount; -unsigned char *cdloggerdata; +volatile int codecount = 0, datacount = 0, undefinedcount = 0; +unsigned char *cdloggerdata = NULL; unsigned int cdloggerdataSize = 0; -static int indirectnext; +static int indirectnext = 0; -int debug_loggingCD; +int debug_loggingCD = 0; //called by the cpu to perform logging if CDLogging is enabled void LogCDVectors(int which){ diff --git a/src/drivers/Qt/CodeDataLogger.cpp b/src/drivers/Qt/CodeDataLogger.cpp index 4ec7a510..55e6a584 100644 --- a/src/drivers/Qt/CodeDataLogger.cpp +++ b/src/drivers/Qt/CodeDataLogger.cpp @@ -4,6 +4,14 @@ #include #include +#include "../../types.h" +#include "../../fceu.h" +#include "../../cart.h" +#include "../../x6502.h" +#include "../../debug.h" +#include "../../ppu.h" + +#include "Qt/ConsoleUtilities.h" #include "Qt/CodeDataLogger.h" #include "Qt/main.h" #include "Qt/dface.h" @@ -11,6 +19,12 @@ #include "Qt/config.h" #include "Qt/fceuWrapper.h" +static int autoSaveCDL = true; +static int autoLoadCDL = true; +static int autoResumeCDL = false; +static char loadedcdfile[512] = {0}; + +static int getDefaultCDLFile( char *filepath ); //---------------------------------------------------- CodeDataLoggerDialog_t::CodeDataLoggerDialog_t(QWidget *parent) : QDialog( parent ) @@ -20,7 +34,6 @@ CodeDataLoggerDialog_t::CodeDataLoggerDialog_t(QWidget *parent) QGridLayout *grid; QGroupBox *frame, *subframe; QPushButton *btn; - QLabel *lbl; updateTimer = new QTimer( this ); @@ -30,27 +43,42 @@ CodeDataLoggerDialog_t::CodeDataLoggerDialog_t(QWidget *parent) mainLayout = new QVBoxLayout(); vbox1 = new QVBoxLayout(); + hbox = new QHBoxLayout(); grid = new QGridLayout(); - lbl = new QLabel( tr("Press Start to Run Logger") ); + statLabel = new QLabel( tr(" Logger is Paused: Press Start to Run ") ); cdlFileLabel = new QLabel( tr("CDL File:") ); vbox1->addLayout( grid ); - vbox1->addWidget( lbl ); + vbox1->addLayout( hbox ); vbox1->addWidget( cdlFileLabel ); + hbox->addWidget( statLabel, 0, Qt::AlignHCenter ); + frame = new QGroupBox(tr("Code/Data Log Status")); frame->setLayout( vbox1 ); - prgLoggedCodeLabel = new QLabel( tr("0x00000 0.00%") ); - prgLoggedDataLabel = new QLabel( tr("0x00000 0.00%") ); - prgUnloggedLabel = new QLabel( tr("0x00000 0.00%") ); - chrLoggedCodeLabel = new QLabel( tr("0x00000 0.00%") ); - chrLoggedDataLabel = new QLabel( tr("0x00000 0.00%") ); - chrUnloggedLabel = new QLabel( tr("0x00000 0.00%") ); + prgLoggedCodeLabel = new QLabel( tr("0x000000 0.00%") ); + prgLoggedDataLabel = new QLabel( tr("0x000000 0.00%") ); + prgUnloggedLabel = new QLabel( tr("0x000000 0.00%") ); + chrLoggedCodeLabel = new QLabel( tr("0x000000 0.00%") ); + chrLoggedDataLabel = new QLabel( tr("0x000000 0.00%") ); + chrUnloggedLabel = new QLabel( tr("0x000000 0.00%") ); autoSaveCdlCbox = new QCheckBox( tr("Auto-save .CDL when closing ROMs") ); autoLoadCdlCbox = new QCheckBox( tr("Auto-load .CDL when opening this window") ); autoResumeLogCbox = new QCheckBox( tr("Auto-resume logging when loading ROMs") ); + g_config->getOption("SDL.AutoSaveCDL", &autoSaveCDL); + g_config->getOption("SDL.AutoLoadCDL", &autoLoadCDL); + g_config->getOption("SDL.AutoResumeCDL", &autoResumeCDL); + + autoSaveCdlCbox->setChecked( autoSaveCDL ); + autoLoadCdlCbox->setChecked( autoLoadCDL ); + autoResumeLogCbox->setChecked( autoResumeCDL ); + + connect(autoSaveCdlCbox , SIGNAL(stateChanged(int)), this, SLOT(autoSaveCdlStateChange(int)) ); + connect(autoLoadCdlCbox , SIGNAL(stateChanged(int)), this, SLOT(autoLoadCdlStateChange(int)) ); + connect(autoResumeLogCbox, SIGNAL(stateChanged(int)), this, SLOT(autoResumeCdlStateChange(int)) ); + subframe = new QGroupBox(tr("PRG Logged as Code")); vbox = new QVBoxLayout(); vbox->addWidget( prgLoggedCodeLabel ); @@ -97,9 +125,11 @@ CodeDataLoggerDialog_t::CodeDataLoggerDialog_t(QWidget *parent) vbox1->addLayout( grid ); btn = new QPushButton( tr("Reset Log") ); grid->addWidget( btn, 0, 0, Qt::AlignCenter ); + connect( btn, SIGNAL(clicked(void)), this, SLOT(ResetCDLogClicked(void))); - btn = new QPushButton( tr("Start") ); - grid->addWidget( btn, 0, 1, Qt::AlignCenter ); + startPauseButton = new QPushButton( tr("Start") ); + grid->addWidget( startPauseButton, 0, 1, Qt::AlignCenter ); + connect( startPauseButton, SIGNAL(clicked(void)), this, SLOT(StartPauseCDLogClicked(void))); btn = new QPushButton( tr("Save") ); grid->addWidget( btn, 0, 2, Qt::AlignCenter ); @@ -137,6 +167,12 @@ CodeDataLoggerDialog_t::CodeDataLoggerDialog_t(QWidget *parent) updateTimer->start( 100 ); // 10hz + if (autoLoadCDL) + { + char nameo[2048]; + getDefaultCDLFile( nameo ); + LoadCDLog(nameo); + } } //---------------------------------------------------- CodeDataLoggerDialog_t::~CodeDataLoggerDialog_t(void) @@ -161,8 +197,334 @@ void CodeDataLoggerDialog_t::closeWindow(void) deleteLater(); } //---------------------------------------------------- -void CodeDataLoggerDialog_t::updatePeriodic(void) +void CodeDataLoggerDialog_t::autoSaveCdlStateChange(int state) { + autoSaveCDL = state != Qt::Unchecked; + g_config->setOption("SDL.AutoSaveCDL", autoSaveCDL); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::autoLoadCdlStateChange(int state) +{ + autoLoadCDL = state != Qt::Unchecked; + + g_config->setOption("SDL.AutoLoadCDL", autoLoadCDL); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::autoResumeCdlStateChange(int state) +{ + autoResumeCDL = state != Qt::Unchecked; + + g_config->setOption("SDL.AutoResumeCDL", autoResumeCDL); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::updatePeriodic(void) +{ + char str[768]; + float fcodecount = codecount; + float fdatacount = datacount; + float frendercount = rendercount; + float fvromreadcount = vromreadcount; + float fundefinedcount = undefinedcount; + float fundefinedvromcount = undefinedvromcount; + float fromsize = cdloggerdataSize; + float fvromsize = (cdloggerVideoDataSize != 0) ? cdloggerVideoDataSize : 1; + + if ( FCEUI_GetLoggingCD() ) + { + startPauseButton->setText( tr("Pause") ); + statLabel->setText( tr(" Logger is Running: Press Pause to Stop ") ); + statLabel->setStyleSheet("background-color: green; color: white;"); + } + else + { + startPauseButton->setText( tr("Start") ); + statLabel->setText( tr(" Logger is Paused: Press Start to Run ") ); + statLabel->setStyleSheet("background-color: red; color: white;"); + } + + if ( cdloggerdataSize > 0 ) + { + sprintf(str,"0x%06x %.2f%%", codecount, (fcodecount / fromsize) * 100); + prgLoggedCodeLabel->setText( tr(str) ); + + sprintf(str,"0x%06x %.2f%%", datacount,(fdatacount / fromsize) * 100); + prgLoggedDataLabel->setText( tr(str) ); + + sprintf(str,"0x%06x %.2f%%", undefinedcount, (fundefinedcount / fromsize) * 100); + prgUnloggedLabel->setText( tr(str) ); + + sprintf(str,"0x%06x %.2f%%", rendercount, (frendercount / fvromsize) * 100); + chrLoggedCodeLabel->setText( tr(str) ); + + sprintf(str,"0x%06x %.2f%%", vromreadcount, (fvromreadcount / fvromsize) * 100); + chrLoggedDataLabel->setText( tr(str) ); + + sprintf(str,"0x%06x %.2f%%", undefinedvromcount, (fundefinedvromcount / fvromsize) * 100); + chrUnloggedLabel->setText( tr(str) ); + } + else + { + prgLoggedCodeLabel->setText( tr("------") ); + prgLoggedDataLabel->setText( tr("------") ); + prgUnloggedLabel->setText( tr("------") ); + chrLoggedCodeLabel->setText( tr("------") ); + chrLoggedDataLabel->setText( tr("------") ); + chrUnloggedLabel->setText( tr("------") ); + } + + sprintf( str, "CDL File: %s", loadedcdfile ); + + cdlFileLabel->setText( tr(str) ); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::ResetCDLogClicked(void) +{ + ::ResetCDLog(); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::StartPauseCDLogClicked(void) +{ + if ( FCEUI_GetLoggingCD() ) + { + printf("CD Logging Paused\n"); + PauseCDLogging(); + startPauseButton->setText( tr("Start") ); + } + else + { + printf("CD Logging Started\n"); + StartCDLogging(); + startPauseButton->setText( tr("Pause") ); + } +} +//---------------------------------------------------- +static int getDefaultCDLFile( char *filepath ) +{ + const char *romFile; + char dir[512], baseFile[256]; + + filepath[0] = 0; + + romFile = getRomFile(); + + if ( romFile == NULL ) + { + return -1; + } + + parseFilepath( romFile, dir, baseFile ); + + sprintf( filepath, "%s/%s.cdl", dir, baseFile ); + + //printf("%s\n", filepath ); + + return 0; +} +//---------------------------------------------------- +void FreeCDLog(void) +{ + fceuWrapperLock(); + if (cdloggerdata) + { + free(cdloggerdata); + cdloggerdata = NULL; + cdloggerdataSize = 0; + } + if (cdloggervdata) + { + free(cdloggervdata); + cdloggervdata = NULL; + cdloggerVideoDataSize = 0; + } + fceuWrapperUnLock(); +} +//---------------------------------------------------- +void InitCDLog(void) +{ + fceuWrapperLock(); + cdloggerdataSize = PRGsize[0]; + cdloggerdata = (unsigned char*)malloc(cdloggerdataSize); + if (!CHRram[0] || (CHRptr[0] == PRGptr[0])) { // Some kind of workaround for my OneBus VRAM hack, will remove it if I find another solution for that + cdloggerVideoDataSize = CHRsize[0]; + cdloggervdata = (unsigned char*)malloc(cdloggerVideoDataSize); + } else { + if (GameInfo->type != GIT_NSF) { + cdloggerVideoDataSize = 0; + cdloggervdata = (unsigned char*)malloc(8192); + } + } + fceuWrapperUnLock(); +} +//---------------------------------------------------- +void ResetCDLog(void) +{ + if ( GameInfo == NULL ) + { + return; + } + fceuWrapperLock(); + + codecount = datacount = rendercount = vromreadcount = 0; + undefinedcount = cdloggerdataSize; + + if ( cdloggerdata != NULL ) + { + memset(cdloggerdata, 0, cdloggerdataSize); + } + if (cdloggerVideoDataSize != 0) + { + undefinedvromcount = cdloggerVideoDataSize; + + if ( cdloggervdata != NULL ) + { + memset(cdloggervdata, 0, cdloggerVideoDataSize); + } + } + else + { + if (GameInfo->type != GIT_NSF) + { + undefinedvromcount = 8192; + memset(cdloggervdata, 0, 8192); + } + } + fceuWrapperUnLock(); +} +//---------------------------------------------------- +bool LoadCDLog(const char* nameo) +{ + FILE *FP; + int i,j; + + FP = fopen(nameo, "rb"); + if (FP == NULL) + return false; + + for(i = 0;i < (int)cdloggerdataSize;i++) + { + j = fgetc(FP); + if (j == EOF) + break; + if ((j & 1) && !(cdloggerdata[i] & 1)) + codecount++; //if the new byte has something logged and + if ((j & 2) && !(cdloggerdata[i] & 2)) + datacount++; //and the old one doesn't. Then increment + if ((j & 3) && !(cdloggerdata[i] & 3)) + undefinedcount--; //the appropriate counter. + cdloggerdata[i] |= j; + } + + if(cdloggerVideoDataSize != 0) + { + for(i = 0;i < (int)cdloggerVideoDataSize;i++) + { + j = fgetc(FP); + if(j == EOF)break; + if((j & 1) && !(cdloggervdata[i] & 1))rendercount++; //if the new byte has something logged and + if((j & 2) && !(cdloggervdata[i] & 2))vromreadcount++; //if the new byte has something logged and + if((j & 3) && !(cdloggervdata[i] & 3))undefinedvromcount--; //the appropriate counter. + cdloggervdata[i] |= j; + } + } + + fclose(FP); + RenameCDLog(nameo); + + return true; +} +//---------------------------------------------------- +void StartCDLogging(void) +{ + fceuWrapperLock(); + FCEUI_SetLoggingCD(1); + //EnableTracerMenuItems(); + //SetDlgItemText(hCDLogger, BTN_CDLOGGER_START_PAUSE, "Pause"); + fceuWrapperUnLock(); +} +//---------------------------------------------------- +bool PauseCDLogging(void) +{ + // can't pause while Trace Logger is using + //if ((logging) && (logging_options & LOG_NEW_INSTRUCTIONS)) + //{ + // MessageBox(hCDLogger, "The Trace Logger is currently using this for some of its features.\nPlease turn the Trace Logger off and try again.","Unable to Pause Code/Data Logger", MB_OK); + // return false; + //} + fceuWrapperLock(); + FCEUI_SetLoggingCD(0); + //EnableTracerMenuItems(); + //SetDlgItemText(hCDLogger, BTN_CDLOGGER_START_PAUSE, "Start"); + fceuWrapperUnLock(); + return true; +} +//---------------------------------------------------- +void CDLoggerROMClosed(void) +{ + PauseCDLogging(); + if (autoSaveCDL) + { + SaveCDLogFile(); + } +} +//---------------------------------------------------- +void CDLoggerROMChanged(void) +{ + FreeCDLog(); + InitCDLog(); + ResetCDLog(); + RenameCDLog(""); + + if (!autoResumeCDL) + return; + + // try to load respective CDL file + char nameo[1024]; + getDefaultCDLFile( nameo ); + + FILE *FP; + FP = fopen(nameo, "rb"); + if (FP != NULL) + { + // .cdl file with this ROM name exists + fclose(FP); + //if (!hCDLogger) + //{ + // DoCDLogger(); + //} + if (LoadCDLog(nameo)) + { + StartCDLogging(); + } + } +} +//---------------------------------------------------- +void RenameCDLog(const char* newName) +{ + strcpy(loadedcdfile, newName); +} +//---------------------------------------------------- +void SaveCDLogFile(void) +{ + if (loadedcdfile[0] == 0) + { + char nameo[1024]; + getDefaultCDLFile( nameo ); + RenameCDLog(nameo); + } + + FILE *FP; + FP = fopen(loadedcdfile, "wb"); + if (FP == NULL) + { + FCEUD_PrintError("Error Saving File"); + return; + } + fwrite(cdloggerdata, cdloggerdataSize, 1, FP); + if (cdloggerVideoDataSize != 0) + { + fwrite(cdloggervdata, cdloggerVideoDataSize, 1, FP); + } + fclose(FP); } //---------------------------------------------------- diff --git a/src/drivers/Qt/CodeDataLogger.h b/src/drivers/Qt/CodeDataLogger.h index 301e710e..c1782041 100644 --- a/src/drivers/Qt/CodeDataLogger.h +++ b/src/drivers/Qt/CodeDataLogger.h @@ -25,24 +25,43 @@ class CodeDataLoggerDialog_t : public QDialog ~CodeDataLoggerDialog_t(void); protected: - QTimer *updateTimer; - QLabel *prgLoggedCodeLabel; - QLabel *prgLoggedDataLabel; - QLabel *prgUnloggedLabel; - QLabel *chrLoggedCodeLabel; - QLabel *chrLoggedDataLabel; - QLabel *chrUnloggedLabel; - QLabel *cdlFileLabel; - QCheckBox *autoSaveCdlCbox; - QCheckBox *autoLoadCdlCbox; - QCheckBox *autoResumeLogCbox; + QTimer *updateTimer; + QLabel *prgLoggedCodeLabel; + QLabel *prgLoggedDataLabel; + QLabel *prgUnloggedLabel; + QLabel *chrLoggedCodeLabel; + QLabel *chrLoggedDataLabel; + QLabel *chrUnloggedLabel; + QLabel *cdlFileLabel; + QLabel *statLabel; + QCheckBox *autoSaveCdlCbox; + QCheckBox *autoLoadCdlCbox; + QCheckBox *autoResumeLogCbox; + QPushButton *startPauseButton; void closeEvent(QCloseEvent *bar); + private: public slots: void closeWindow(void); private slots: void updatePeriodic(void); + void ResetCDLogClicked(void); + void StartPauseCDLogClicked(void); + void autoSaveCdlStateChange(int state); + void autoLoadCdlStateChange(int state); + void autoResumeCdlStateChange(int state); }; +void InitCDLog(void); +void ResetCDLog(void); +void FreeCDLog(void); +void StartCDLogging(void); +bool PauseCDLogging(void); +bool LoadCDLog(const char* nameo); +void RenameCDLog(const char* newName); +void CDLoggerROMClosed(void); +void CDLoggerROMChanged(void); +void SaveCDLogFile(void); + diff --git a/src/drivers/Qt/ConsoleUtilities.cpp b/src/drivers/Qt/ConsoleUtilities.cpp index d118dd7d..c9fa3a48 100644 --- a/src/drivers/Qt/ConsoleUtilities.cpp +++ b/src/drivers/Qt/ConsoleUtilities.cpp @@ -83,3 +83,63 @@ int getFileBaseName( const char *filepath, char *base ) return end; } //--------------------------------------------------------------------------- +int parseFilepath( const char *filepath, char *dir, char *base, char *suffix ) +{ + 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+1; + } + if ( dir ) + { + dir[i] = filepath[i]; + } + i++; + } + if ( dir ) + { + dir[j] = 0; + } + i = j; + + if ( base == NULL ) + { + return end; + } + + j=0; + while ( filepath[i] != 0 ) + { + base[j] = filepath[i]; i++; j++; + } + base[j] = 0; end=j; + + if ( suffix ) + { + suffix[0] = 0; + } + + while ( j > 1 ) + { + j--; + if ( base[j] == '.' ) + { + if ( suffix ) + { + strcpy( suffix, &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 e55e0361..12838ddc 100644 --- a/src/drivers/Qt/ConsoleUtilities.h +++ b/src/drivers/Qt/ConsoleUtilities.h @@ -5,3 +5,5 @@ int getDirFromFile( const char *path, char *dir ); const char *getRomFile( void ); int getFileBaseName( const char *filepath, char *base ); + +int parseFilepath( const char *filepath, char *dir, char *base, char *suffix = NULL ); diff --git a/src/drivers/Qt/config.cpp b/src/drivers/Qt/config.cpp index 3fec6409..35d6b0f2 100644 --- a/src/drivers/Qt/config.cpp +++ b/src/drivers/Qt/config.cpp @@ -263,6 +263,11 @@ InitConfig() config->addOption("autoLoadDebugFiles", "SDL.AutoLoadDebugFiles", 1); config->addOption("autoOpenDebugger" , "SDL.AutoOpenDebugger" , 0); + // Code Data Logger Options + config->addOption("autoSaveCDL" , "SDL.AutoSaveCDL", 1); + config->addOption("autoLoadCDL" , "SDL.AutoLoadCDL", 1); + config->addOption("autoResumeCDL", "SDL.AutoResumeCDL", 0); + // overwrite the config file? config->addOption("no-config", "SDL.NoConfig", 0); diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index f618991f..0f204e16 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -16,6 +16,7 @@ #include "Qt/unix-netplay.h" #include "Qt/HexEditor.h" #include "Qt/SymbolicDebug.h" +#include "Qt/CodeDataLogger.h" #include "Qt/ConsoleDebugger.h" #include "Qt/ConsoleWindow.h" #include "Qt/fceux_git_info.h" @@ -247,6 +248,8 @@ int LoadGame(const char *path) debugSymbolTable.loadGameSymbols(); + CDLoggerROMChanged(); + int state_to_load; g_config->getOption("SDL.AutoLoadState", &state_to_load); if (state_to_load >= 0 && state_to_load < 10){ @@ -299,6 +302,7 @@ CloseGame(void) debugSymbolTable.save(); debugSymbolTable.clear(); + CDLoggerROMClosed(); int state_to_save; g_config->getOption("SDL.AutoSaveState", &state_to_save); @@ -946,17 +950,23 @@ static void DoFun(int frameskip, int periodic_saves) void fceuWrapperLock(void) { mutexPending++; - consoleWindow->mutex->lock(); + if ( consoleWindow != NULL ) + { + consoleWindow->mutex->lock(); + } mutexPending--; mutexLocks++; } bool fceuWrapperTryLock(int timeout) { - bool lockAcq; + bool lockAcq = false; mutexPending++; - lockAcq = consoleWindow->mutex->tryLock( timeout ); + if ( consoleWindow != NULL ) + { + lockAcq = consoleWindow->mutex->tryLock( timeout ); + } mutexPending--; if ( lockAcq ) @@ -970,7 +980,10 @@ void fceuWrapperUnLock(void) { if ( mutexLocks > 0 ) { - consoleWindow->mutex->unlock(); + if ( consoleWindow != NULL ) + { + consoleWindow->mutex->unlock(); + } mutexLocks--; } else diff --git a/src/ppu.h b/src/ppu.h index a3d2ded5..4555264d 100644 --- a/src/ppu.h +++ b/src/ppu.h @@ -48,3 +48,7 @@ enum PPUPHASE { }; extern PPUPHASE ppuphase; + +extern unsigned char *cdloggervdata; +extern unsigned int cdloggerVideoDataSize; +extern volatile int rendercount, vromreadcount, undefinedvromcount; From 63933a1821312f4fad4fd088efaf6a327069853b Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Mon, 28 Sep 2020 21:51:14 -0400 Subject: [PATCH 3/5] Added CDL File load/save logic. --- src/drivers/Qt/CodeDataLogger.cpp | 134 +++++++++++++++++++++++++++- src/drivers/Qt/CodeDataLogger.h | 3 + src/drivers/Qt/ConsoleUtilities.cpp | 4 +- 3 files changed, 138 insertions(+), 3 deletions(-) diff --git a/src/drivers/Qt/CodeDataLogger.cpp b/src/drivers/Qt/CodeDataLogger.cpp index 55e6a584..cd272d0d 100644 --- a/src/drivers/Qt/CodeDataLogger.cpp +++ b/src/drivers/Qt/CodeDataLogger.cpp @@ -1,6 +1,7 @@ // CodeDataLogger.cpp // #include +#include #include #include @@ -133,12 +134,15 @@ CodeDataLoggerDialog_t::CodeDataLoggerDialog_t(QWidget *parent) btn = new QPushButton( tr("Save") ); grid->addWidget( btn, 0, 2, Qt::AlignCenter ); + connect( btn, SIGNAL(clicked(void)), this, SLOT(saveCdlFile(void))); btn = new QPushButton( tr("Load") ); grid->addWidget( btn, 1, 0, Qt::AlignCenter ); + connect( btn, SIGNAL(clicked(void)), this, SLOT(loadCdlFile(void))); btn = new QPushButton( tr("Save As") ); grid->addWidget( btn, 1, 2, Qt::AlignCenter ); + connect( btn, SIGNAL(clicked(void)), this, SLOT(saveCdlFileAs(void))); hbox = new QHBoxLayout(); vbox1->addLayout( hbox ); @@ -287,18 +291,142 @@ void CodeDataLoggerDialog_t::StartPauseCDLogClicked(void) { if ( FCEUI_GetLoggingCD() ) { - printf("CD Logging Paused\n"); + //printf("CD Logging Paused\n"); PauseCDLogging(); startPauseButton->setText( tr("Start") ); } else { - printf("CD Logging Started\n"); + //printf("CD Logging Started\n"); StartCDLogging(); startPauseButton->setText( tr("Pause") ); } } //---------------------------------------------------- +void CodeDataLoggerDialog_t::saveCdlFile(void) +{ + SaveCDLogFile(); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::saveCdlFileAs(void) +{ + int ret, useNativeFileDialogVal; + QString filename; + const char *romFile; + QFileDialog dialog(this, tr("Save CDL To File") ); + + dialog.setFileMode(QFileDialog::AnyFile); + + dialog.setNameFilter(tr("CDL Files (*.cdl *.CDL) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + dialog.setFilter( QDir::AllEntries | QDir::Hidden ); + dialog.setLabelText( QFileDialog::Accept, tr("Save") ); + dialog.setDefaultSuffix( tr(".cdl") ); + + romFile = getRomFile(); + + if ( romFile != NULL ) + { + char dir[512], base[256]; + + parseFilepath( romFile, dir, base ); + + strcat( base, ".cdl"); + + 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(); + + fceuWrapperLock(); + strcpy( loadedcdfile, filename.toStdString().c_str() ); + SaveCDLogFile(); + fceuWrapperUnLock(); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::loadCdlFile(void) +{ + int ret, useNativeFileDialogVal; + QString filename; + char dir[512]; + const char *romFile; + QFileDialog dialog(this, tr("Load CDL File") ); + + dialog.setFileMode(QFileDialog::ExistingFile); + + dialog.setNameFilter(tr("CDL files (*.cdl *.CDL) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + dialog.setFilter( QDir::AllEntries | QDir::Hidden ); + dialog.setLabelText( QFileDialog::Accept, tr("Load") ); + + romFile = getRomFile(); + + if ( romFile ) + { + getDirFromFile( romFile, dir ); + + dialog.setDirectory( tr(dir) ); + } + + // 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(); + + fceuWrapperLock(); + LoadCDLog ( filename.toStdString().c_str() ); + fceuWrapperUnLock(); + + return; +} +//---------------------------------------------------- static int getDefaultCDLFile( char *filepath ) { const char *romFile; @@ -399,7 +527,9 @@ bool LoadCDLog(const char* nameo) FP = fopen(nameo, "rb"); if (FP == NULL) + { return false; + } for(i = 0;i < (int)cdloggerdataSize;i++) { diff --git a/src/drivers/Qt/CodeDataLogger.h b/src/drivers/Qt/CodeDataLogger.h index c1782041..c768c8a9 100644 --- a/src/drivers/Qt/CodeDataLogger.h +++ b/src/drivers/Qt/CodeDataLogger.h @@ -45,6 +45,9 @@ class CodeDataLoggerDialog_t : public QDialog public slots: void closeWindow(void); private slots: + void loadCdlFile(void); + void saveCdlFile(void); + void saveCdlFileAs(void); void updatePeriodic(void); void ResetCDLogClicked(void); void StartPauseCDLogClicked(void); diff --git a/src/drivers/Qt/ConsoleUtilities.cpp b/src/drivers/Qt/ConsoleUtilities.cpp index c9fa3a48..9bedc75f 100644 --- a/src/drivers/Qt/ConsoleUtilities.cpp +++ b/src/drivers/Qt/ConsoleUtilities.cpp @@ -88,7 +88,9 @@ int parseFilepath( const char *filepath, char *dir, char *base, char *suffix ) int i=0,j=0,end=0; if ( filepath == NULL ) { - base[0] = 0; + if ( dir ) dir[0] = 0; + if ( base ) base[0] = 0; + if ( suffix) suffix[0] = 0; return 0; } i=0; j=0; From 92007f8467f06060d08734f6113a8133af1559a3 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Mon, 28 Sep 2020 22:18:25 -0400 Subject: [PATCH 4/5] Added CDL generated ROM functionality. --- src/drivers/Qt/CodeDataLogger.cpp | 182 +++++++++++++++++++++++++++++- src/drivers/Qt/CodeDataLogger.h | 5 +- 2 files changed, 185 insertions(+), 2 deletions(-) diff --git a/src/drivers/Qt/CodeDataLogger.cpp b/src/drivers/Qt/CodeDataLogger.cpp index cd272d0d..3f209fb4 100644 --- a/src/drivers/Qt/CodeDataLogger.cpp +++ b/src/drivers/Qt/CodeDataLogger.cpp @@ -11,6 +11,8 @@ #include "../../x6502.h" #include "../../debug.h" #include "../../ppu.h" +#include "../../ines.h" +#include "../../nsf.h" #include "Qt/ConsoleUtilities.h" #include "Qt/CodeDataLogger.h" @@ -160,8 +162,10 @@ CodeDataLoggerDialog_t::CodeDataLoggerDialog_t(QWidget *parent) btn = new QPushButton( tr("Save Stripped Data") ); vbox->addWidget( btn ); + connect( btn, SIGNAL(clicked(void)), this, SLOT(SaveStrippedROMClicked(void))); btn = new QPushButton( tr("Save Unused Data") ); vbox->addWidget( btn ); + connect( btn, SIGNAL(clicked(void)), this, SLOT(SaveUnusedROMClicked(void))); subframe->setLayout( vbox ); hbox->addWidget( subframe ); @@ -169,7 +173,7 @@ CodeDataLoggerDialog_t::CodeDataLoggerDialog_t(QWidget *parent) setLayout( mainLayout ); - updateTimer->start( 100 ); // 10hz + updateTimer->start( 200 ); // 5hz if (autoLoadCDL) { @@ -427,6 +431,182 @@ void CodeDataLoggerDialog_t::loadCdlFile(void) return; } //---------------------------------------------------- +void CodeDataLoggerDialog_t::SaveStrippedROM(int invert) +{ + + //this is based off of iNesSave() + //todo: make this support NSF + // + if (!GameInfo) + return; + + if (GameInfo->type==GIT_NSF) + { + printf("Sorry, you're not allowed to save optimized NSFs yet. Please don't optimize individual banks, as there are still some issues with several NSFs to be fixed, and it is easier to fix those issues with as much of the bank data intact as possible."); + return; + } + + if (codecount == 0) + { + printf("Unable to Generate Stripped ROM. Get Something Logged and try again."); + return; + } + + int i, ret, useNativeFileDialogVal; + QString filename; + const char *romFile; + QFileDialog dialog(this, tr("Save Stripped File As...") ); + + dialog.setFileMode(QFileDialog::AnyFile); + + if (GameInfo->type==GIT_NSF) + { + dialog.setNameFilter(tr("NSF Files (*.nsf *.NSF) ;; All files (*)")); + dialog.setDefaultSuffix( tr(".nsf") ); + } + else + { + dialog.setNameFilter(tr("NES Files (*.nes *.NES) ;; All files (*)")); + dialog.setDefaultSuffix( tr(".nes") ); + } + dialog.setViewMode(QFileDialog::List); + dialog.setFilter( QDir::AllEntries | QDir::Hidden ); + dialog.setLabelText( QFileDialog::Accept, tr("Save") ); + + romFile = getRomFile(); + + if ( romFile != NULL ) + { + char dir[512], base[256]; + + parseFilepath( romFile, dir, base ); + + dialog.setDirectory( tr(dir) ); + } + + // 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(); + + FILE *fp = fopen( filename.toStdString().c_str(),"wb"); + if (!fp) + { + FCEUD_PrintError("Error opening target stripped rom file!"); + return; + } + + if (GameInfo->type==GIT_NSF) + { + uint8 NSFLoadLow; + uint8 NSFLoadHigh; + //Not used because if bankswitching, the addresses involved + //could still end up being used through writes + //static uint16 LoadAddr; + //LoadAddr=NSFHeader.LoadAddressLow; + //LoadAddr|=(NSFHeader.LoadAddressHigh&0x7F)<<8; + + //Simple store/restore for writing a working NSF header + NSFLoadLow = NSFHeader.LoadAddressLow; + NSFLoadHigh = NSFHeader.LoadAddressHigh; + NSFHeader.LoadAddressLow=0; + NSFHeader.LoadAddressHigh&=0xF0; + fwrite(&NSFHeader,1,0x8,fp); + NSFHeader.LoadAddressLow = NSFLoadLow; + NSFHeader.LoadAddressHigh = NSFLoadHigh; + + fseek(fp,0x8,SEEK_SET); + for (i = 0;i < ((NSFMaxBank+1)*4096);i++){ + unsigned char pchar; + if (cdloggerdata[i] & 3) + { + pchar = invert?0:NSFDATA[i]; + } + else + { + pchar = invert?NSFDATA[i]:0; + } + fputc(pchar, fp); + } + + } + else + { + iNES_HEADER cdlhead; + + cdlhead.ID[0] = 'N'; + cdlhead.ID[1] = 'E'; + cdlhead.ID[2] = 'S'; + cdlhead.ID[3] = 0x1A; + + cdlhead.ROM_size = cdloggerdataSize >> 14; + cdlhead.VROM_size = cdloggerVideoDataSize >> 13; + + fwrite(&cdlhead,1,16,fp); + + for (i = 0; i < (int)cdloggerdataSize; i++){ + unsigned char pchar; + if (cdloggerdata[i] & 3) + { + pchar = invert?0:PRGptr[0][i]; + } + else + { + pchar = invert?PRGptr[0][i]:0; + } + fputc(pchar, fp); + } + + if (cdloggerVideoDataSize != 0) + { + // since the OldPPU at least logs the $2007 read accesses, we should save the data anyway + for (i = 0; i < (int)cdloggerVideoDataSize; i++) { + unsigned char vchar; + if (cdloggervdata[i] & 3) + { + vchar = invert?0:CHRptr[0][i]; + } + else + { + vchar = invert?CHRptr[0][i]:0; + } + fputc(vchar, fp); + } + } + } + fclose(fp); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::SaveStrippedROMClicked(void) +{ + SaveStrippedROM(0); +} +//---------------------------------------------------- +void CodeDataLoggerDialog_t::SaveUnusedROMClicked(void) +{ + SaveStrippedROM(1); +} +//---------------------------------------------------- static int getDefaultCDLFile( char *filepath ) { const char *romFile; diff --git a/src/drivers/Qt/CodeDataLogger.h b/src/drivers/Qt/CodeDataLogger.h index c768c8a9..ff8241b6 100644 --- a/src/drivers/Qt/CodeDataLogger.h +++ b/src/drivers/Qt/CodeDataLogger.h @@ -40,6 +40,8 @@ class CodeDataLoggerDialog_t : public QDialog QPushButton *startPauseButton; void closeEvent(QCloseEvent *bar); + void SaveStrippedROM(int invert); + private: public slots: @@ -54,7 +56,8 @@ class CodeDataLoggerDialog_t : public QDialog void autoSaveCdlStateChange(int state); void autoLoadCdlStateChange(int state); void autoResumeCdlStateChange(int state); - + void SaveStrippedROMClicked(void); + void SaveUnusedROMClicked(void); }; void InitCDLog(void); From de2fd3eef3abfc973c093ea65bdc021236939a46 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Mon, 28 Sep 2020 23:40:13 -0400 Subject: [PATCH 5/5] Added Qt hex editor logic to color ROM bytes from CD Logger data. --- src/drivers/Qt/HexEditor.cpp | 120 ++++++++++++++++++++++++++++++++++- src/drivers/Qt/HexEditor.h | 2 + 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/src/drivers/Qt/HexEditor.cpp b/src/drivers/Qt/HexEditor.cpp index ebb77223..e5dd46a1 100644 --- a/src/drivers/Qt/HexEditor.cpp +++ b/src/drivers/Qt/HexEditor.cpp @@ -24,6 +24,7 @@ #include "../../movie.h" #include "../../palette.h" #include "../../fds.h" +#include "../../ppu.h" #include "../../cart.h" #include "../../ines.h" #include "../common/configSys.h" @@ -1999,6 +2000,106 @@ int QHexEdit::checkMemActivity(void) return 0; } //---------------------------------------------------------------------------- +int QHexEdit::getRomAddrColor( int addr, QColor &fg, QColor &bg ) +{ + int temp_offset; + QColor color, oppColor; + + fg = this->palette().color(QPalette::WindowText); + bg = this->palette().color(QPalette::Background); + + if ( reverseVideo ) + { + color = this->palette().color(QPalette::Background); + oppColor = this->palette().color(QPalette::WindowText); + } + else + { + color = this->palette().color(QPalette::WindowText); + oppColor = this->palette().color(QPalette::Background); + } + + if ( viewMode != MODE_NES_ROM ) + { + return -1; + } + if (cdloggerdataSize == 0) + { + return -1; + } + temp_offset = addr - 16; + + if (temp_offset >= 0) + { + if ((unsigned int)temp_offset < cdloggerdataSize) + { + // PRG + if ((cdloggerdata[temp_offset] & 3) == 3) + { + // the byte is both Code and Data - green + color.setRgb(0, 190, 0); + } + else if ((cdloggerdata[temp_offset] & 3) == 1) + { + // the byte is Code - dark-yellow + color.setRgb(160, 140, 0); + oppColor.setRgb( 0, 0, 0 ); + } + else if ((cdloggerdata[temp_offset] & 3) == 2) + { + // the byte is Data - blue/cyan + if (cdloggerdata[temp_offset] & 0x40) + { + // PCM data - cyan + color.setRgb(0, 130, 160); + } + else + { + // non-PCM data - blue + color.setRgb(0, 0, 210); + } + } + } + else + { + temp_offset -= cdloggerdataSize; + if (((unsigned int)temp_offset < cdloggerVideoDataSize)) + { + // CHR + if ((cdloggervdata[temp_offset] & 3) == 3) + { + // the byte was both rendered and read programmatically - light-green + color.setRgb(5, 255, 5); + } + else if ((cdloggervdata[temp_offset] & 3) == 1) + { + // the byte was rendered - yellow + color.setRgb(210, 190, 0); + oppColor.setRgb( 0, 0, 0 ); + } + else if ((cdloggervdata[temp_offset] & 3) == 2) + { + // the byte was read programmatically - light-blue + color.setRgb(15, 15, 255); + } + } + } + } + + if ( reverseVideo ) + { + bg = color; + fg = oppColor; + } + else + { + fg = color; + bg = oppColor; + } + + return 0; +} +//---------------------------------------------------------------------------- void QHexEdit::memModeUpdate(void) { int memSize; @@ -2178,7 +2279,24 @@ void QHexEdit::paintEvent(QPaintEvent *event) } else { - if ( actvHighlightEnable && (mb.buf[addr].actv > 0) ) + if ( viewMode == MODE_NES_ROM ) + { + QColor romBgColor, romFgColor; + + getRomAddrColor( addr, romFgColor, romBgColor ); + + if ( reverseVideo ) + { + painter.setPen( romFgColor ); + painter.fillRect( x - (0.5*pxCharWidth) , y-pxLineSpacing+pxLineLead, 3*pxCharWidth, pxLineSpacing, romBgColor ); + painter.fillRect( pxHexAscii + (col*pxCharWidth) - pxLineXScroll, y-pxLineSpacing+pxLineLead, pxCharWidth, pxLineSpacing, romBgColor ); + } + else + { + painter.setPen( romFgColor ); + } + } + else if ( actvHighlightEnable && (mb.buf[addr].actv > 0) ) { if ( reverseVideo ) { diff --git a/src/drivers/Qt/HexEditor.h b/src/drivers/Qt/HexEditor.h index 04925bc6..a7f5a8b1 100644 --- a/src/drivers/Qt/HexEditor.h +++ b/src/drivers/Qt/HexEditor.h @@ -138,6 +138,8 @@ class QHexEdit : public QWidget QFont font; + int getRomAddrColor( int addr, QColor &fg, QColor &bg ); + memBlock_t mb; int (*memAccessFunc)( unsigned int offset);