Successful initial test of Qt Code/Data Logger Window.

This commit is contained in:
Matthew Budd 2020-09-28 21:23:47 -04:00
parent 086d523566
commit 445b17104a
8 changed files with 496 additions and 31 deletions

View File

@ -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){

View File

@ -4,6 +4,14 @@
#include <QInputDialog>
#include <QMessageBox>
#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);
}
//----------------------------------------------------

View File

@ -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);

View File

@ -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;
}
//---------------------------------------------------------------------------

View File

@ -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 );

View File

@ -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);

View File

@ -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

View File

@ -48,3 +48,7 @@ enum PPUPHASE {
};
extern PPUPHASE ppuphase;
extern unsigned char *cdloggervdata;
extern unsigned int cdloggerVideoDataSize;
extern volatile int rendercount, vromreadcount, undefinedvromcount;