From 3ae463d1f203c579a196199d0686b61777f99ca2 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 29 Nov 2020 00:04:20 -0500 Subject: [PATCH 1/2] Bug fix for Qt GUI crashing when to load a non-existant ROM via the command line. --- src/drivers/Qt/fceuWrapper.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 79abd540..1bc35efe 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -107,7 +107,10 @@ void FCEUD_PrintError(const char *errormsg) { fprintf(stderr, "%s\n", errormsg); - consoleWindow->QueueErrorMsgWindow( errormsg ); + if ( consoleWindow ) + { + consoleWindow->QueueErrorMsgWindow( errormsg ); + } } /** From 4f08d7a8cc8834735b2e5726d73bd8f44a811cdf Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 29 Nov 2020 20:11:28 -0500 Subject: [PATCH 2/2] Added message log viewer window to the Qt GUI. --- src/CMakeLists.txt | 1 + src/drivers/Qt/ConsoleWindow.cpp | 20 +++ src/drivers/Qt/ConsoleWindow.h | 2 + src/drivers/Qt/MsgLogViewer.cpp | 274 +++++++++++++++++++++++++++++++ src/drivers/Qt/MsgLogViewer.h | 46 ++++++ src/drivers/Qt/fceuWrapper.cpp | 33 +--- 6 files changed, 346 insertions(+), 30 deletions(-) create mode 100644 src/drivers/Qt/MsgLogViewer.cpp create mode 100644 src/drivers/Qt/MsgLogViewer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cbeded37..b866e492 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -443,6 +443,7 @@ set(SRC_DRIVERS_SDL ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/CheatsConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GameGenie.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HexEditor.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/MsgLogViewer.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 diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index fe910d7e..c7654d4a 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -47,6 +47,7 @@ #include "Qt/ConsoleUtilities.h" #include "Qt/ConsoleSoundConf.h" #include "Qt/ConsoleVideoConf.h" +#include "Qt/MsgLogViewer.h" #include "Qt/AboutWindow.h" #include "Qt/fceuWrapper.h" #include "Qt/ppuViewer.h" @@ -776,6 +777,13 @@ void consoleWin_t::createMainMenu(void) connect(aboutActQt, SIGNAL(triggered()), this, SLOT(aboutQt(void)) ); helpMenu->addAction(aboutActQt); + + // Help -> Message Log + msgLogAct = new QAction(tr("Message Log"), this); + msgLogAct->setStatusTip(tr("Message Log")); + connect(msgLogAct, SIGNAL(triggered()), this, SLOT(openMsgLogWin(void)) ); + + helpMenu->addAction(msgLogAct); }; //--------------------------------------------------------------------------- void consoleWin_t::closeApp(void) @@ -1813,6 +1821,18 @@ void consoleWin_t::aboutQt(void) return; } +void consoleWin_t::openMsgLogWin(void) +{ + //printf("Open Message Log Window\n"); + MsgLogViewDialog_t *msgLogWin; + + msgLogWin = new MsgLogViewDialog_t(this); + + msgLogWin->show(); + + return; +} + int consoleWin_t::setNicePriority( int value ) { int ret = 0; diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 971f2c85..bf9f83c5 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -117,6 +117,7 @@ class consoleWin_t : public QMainWindow QAction *fullscreen; QAction *aboutAct; QAction *aboutActQt; + QAction *msgLogAct; QAction *state[10]; QAction *powerAct; QAction *resetAct; @@ -174,6 +175,7 @@ class consoleWin_t : public QMainWindow void closeROMCB(void); void aboutFCEUX(void); void aboutQt(void); + void openMsgLogWin(void); void openInputConfWin(void); void openGameSndConfWin(void); void openGameVideoConfWin(void); diff --git a/src/drivers/Qt/MsgLogViewer.cpp b/src/drivers/Qt/MsgLogViewer.cpp new file mode 100644 index 00000000..3d29209a --- /dev/null +++ b/src/drivers/Qt/MsgLogViewer.cpp @@ -0,0 +1,274 @@ +// MsgLogViewer.cpp +// +#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/MsgLogViewer.h" +#include "Qt/ConsoleWindow.h" + +#define MSG_LOG_MAX_LINES 256 + +class msgLogBuf_t +{ + public: + msgLogBuf_t(void) + { + char filename[256]; + + strcpy( filename, "/tmp/fceux.log" ); + + fp = ::fopen( filename, "w+"); + + if ( fp == NULL ) + { + printf("Error: Failed to open message log file: '%s'\n", filename); + } + maxLines = MSG_LOG_MAX_LINES; + totalLines = 0; + head = tail = 0; + } + + ~msgLogBuf_t(void) + { + if ( fp != NULL ) + { + ::fclose(fp); fp = NULL; + } + } + + void clear(void) + { + head = tail = 0; + } + + void addLine( const char *txt, bool NewLine = false ) + { + long ofs; + + if ( fp == NULL ) return; + + ::fseek( fp, 0L, SEEK_END); + + ofs = ::ftell(fp); + + if ( NewLine ) + { + ::fprintf( fp, "%s\n", txt ); + } + else + { + ::fprintf( fp, "%s", txt ); + } + + fpOfsList[head] = ofs; + + head = (head + 1) % MSG_LOG_MAX_LINES; + + if ( head == tail ) + { + tail = (tail + 1) % MSG_LOG_MAX_LINES; + } + + totalLines++; + } + + size_t getTotalLineCount(void) + { + return totalLines; + } + + size_t size(void) + { + size_t s; + + s = head - tail; + + if ( s < 0 ) + { + s += MSG_LOG_MAX_LINES; + } + return s; + } + + void loadTextViewer( QPlainTextEdit *viewer ) + { + long ofs, nbytes; + + if ( fp == NULL ) + { + return; + } + + if ( head == tail ) + { + return; + } + char buf[65536]; + + ofs = fpOfsList[tail]; + + ::fseek( fp, ofs, SEEK_SET); + + //printf("Seek: %li \n", ofs ); + + if ( (nbytes = ::fread( buf, 1, sizeof(buf), fp )) > 0 ) + { + //printf("READ: %li \n", nbytes ); + buf[ nbytes ] = 0; + viewer->setPlainText( buf ); + } + } + + private: + FILE *fp; + size_t maxLines; + size_t totalLines; + size_t head; + size_t tail; + + long fpOfsList[MSG_LOG_MAX_LINES]; +}; + +static msgLogBuf_t msgLog; +//---------------------------------------------------------------------------- +MsgLogViewDialog_t::MsgLogViewDialog_t(QWidget *parent) + : QDialog( parent ) +{ + QVBoxLayout *mainLayout; + QHBoxLayout *hbox; + QPushButton *clearBtn, *closeBtn; + + setWindowTitle("Message Log Viewer"); + + resize( 512, 512 ); + + mainLayout = new QVBoxLayout(); + + txtView = new QPlainTextEdit(); + txtView->setReadOnly(true); + + mainLayout->addWidget( txtView ); + + hbox = new QHBoxLayout(); + clearBtn = new QPushButton( tr("Clear") ); + closeBtn = new QPushButton( tr("Close") ); + hbox->addWidget( clearBtn ); + hbox->addWidget( closeBtn ); + + connect( clearBtn, SIGNAL(clicked(void)), this, SLOT(clearLog(void)) ); + connect( closeBtn, SIGNAL(clicked(void)), this, SLOT(closeWindow(void)) ); + + mainLayout->addLayout( hbox ); + + setLayout( mainLayout ); + + totalLines = 0; + + updateTimer = new QTimer( this ); + + connect( updateTimer, &QTimer::timeout, this, &MsgLogViewDialog_t::updatePeriodic ); + + updateTimer->start( 500 ); // 2hz + + msgLog.loadTextViewer( txtView ); + + totalLines = msgLog.getTotalLineCount(); + + txtView->moveCursor(QTextCursor::End); +} +//---------------------------------------------------------------------------- +MsgLogViewDialog_t::~MsgLogViewDialog_t(void) +{ + printf("Destroy Msg Log Key Config Window\n"); + updateTimer->stop(); +} +//---------------------------------------------------------------------------- +void MsgLogViewDialog_t::closeEvent(QCloseEvent *event) +{ + printf("Msg Log Key Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); +} +//---------------------------------------------------------------------------- +void MsgLogViewDialog_t::closeWindow(void) +{ + //printf("Close Window\n"); + done(0); + deleteLater(); +} +//---------------------------------------------------------------------------- +void MsgLogViewDialog_t::clearLog(void) +{ + fceuWrapperLock(); + + msgLog.clear(); + + txtView->clear(); + + fceuWrapperUnLock(); +} +//---------------------------------------------------------------------------- +void MsgLogViewDialog_t::updatePeriodic(void) +{ + if ( msgLog.getTotalLineCount() != totalLines ) + { + fceuWrapperLock(); + + msgLog.loadTextViewer( txtView ); + + totalLines = msgLog.getTotalLineCount(); + + fceuWrapperUnLock(); + + txtView->moveCursor(QTextCursor::End); + } +} +//---------------------------------------------------------------------------- +/** +* Prints a textual message without adding a newline at the end. +* +* @param text The text of the message. +* +* TODO: This function should have a better name. +**/ +void FCEUD_Message(const char *text) +{ + fputs(text, stdout); + //fprintf(stdout, "\n"); + // + msgLog.addLine( text, false ); +} +//---------------------------------------------------------------------------- +/** +* Shows an error message in a message box. +* (For now: prints to stderr.) +* +* If running in Qt mode, display a dialog message box of the error. +* +* @param errormsg Text of the error message. +**/ +void FCEUD_PrintError(const char *errormsg) +{ + fprintf(stderr, "%s\n", errormsg); + + msgLog.addLine( errormsg, true ); + + if ( consoleWindow ) + { + consoleWindow->QueueErrorMsgWindow( errormsg ); + } +} +//---------------------------------------------------------------------------- diff --git a/src/drivers/Qt/MsgLogViewer.h b/src/drivers/Qt/MsgLogViewer.h new file mode 100644 index 00000000..d43edcf8 --- /dev/null +++ b/src/drivers/Qt/MsgLogViewer.h @@ -0,0 +1,46 @@ +// MsgLogViewer.h +// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Qt/main.h" + +class MsgLogViewDialog_t : public QDialog +{ + Q_OBJECT + + public: + MsgLogViewDialog_t(QWidget *parent = 0); + ~MsgLogViewDialog_t(void); + + protected: + void closeEvent(QCloseEvent *event); + + QTimer *updateTimer; + QPlainTextEdit *txtView; + + size_t totalLines; + + private: + + public slots: + void closeWindow(void); + private slots: + void updatePeriodic(void); + void clearLog(void); + +}; + diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 1bc35efe..49b90e79 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -82,36 +82,9 @@ int mutecapture = 0; //***************************************************************** // -/** -* Prints a textual message without adding a newline at the end. -* -* @param text The text of the message. -* -* TODO: This function should have a better name. -**/ -void FCEUD_Message(const char *text) -{ - fputs(text, stdout); - //fprintf(stdout, "\n"); -} - -/** -* Shows an error message in a message box. -* (For now: prints to stderr.) -* -* If running in Qt mode, display a dialog message box of the error. -* -* @param errormsg Text of the error message. -**/ -void FCEUD_PrintError(const char *errormsg) -{ - fprintf(stderr, "%s\n", errormsg); - - if ( consoleWindow ) - { - consoleWindow->QueueErrorMsgWindow( errormsg ); - } -} +// Message functions defined in MsgLogViewer.cpp +//void FCEUD_Message(const char *text) +//void FCEUD_PrintError(const char *errormsg) /** * Opens a file, C++ style, to be read a byte at a time.