From fa255dc808d507875966626a09f67106bfbca47a Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Mon, 13 Oct 2014 01:48:24 -0700 Subject: [PATCH] Start of log view --- src/platform/qt/CMakeLists.txt | 13 ++- src/platform/qt/GameController.cpp | 8 +- src/platform/qt/GameController.h | 2 + src/platform/qt/LogView.cpp | 98 +++++++++++++++++ src/platform/qt/LogView.h | 44 ++++++++ src/platform/qt/LogView.ui | 164 +++++++++++++++++++++++++++++ src/platform/qt/Window.cpp | 11 ++ src/platform/qt/Window.h | 4 + 8 files changed, 341 insertions(+), 3 deletions(-) create mode 100644 src/platform/qt/LogView.cpp create mode 100644 src/platform/qt/LogView.h create mode 100644 src/platform/qt/LogView.ui diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index e8ea60616..93bc46a98 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -22,7 +22,16 @@ if(NOT Qt5Widgets_FOUND OR NOT OPENGL_FOUND) return() endif() -set(SOURCE_FILES AudioDevice.cpp AudioProcessor.cpp Display.cpp GameController.cpp Window.cpp) +set(SOURCE_FILES + AudioDevice.cpp + AudioProcessor.cpp + Display.cpp + GameController.cpp + LogView.cpp + Window.cpp) + +qt5_wrap_ui(UI_FILES + LogView.ui) if(USE_GDB_STUB) set(SOURCE_FILES ${PLATFORM_SRC} ${SOURCE_FILES} GDBController.cpp GDBWindow.cpp) @@ -31,7 +40,7 @@ set(MACOSX_BUNDLE_ICON_FILE mgba.icns) set(MACOSX_BUNDLE_BUNDLE_VERSION ${LIB_VERSION_STRING}) set_source_files_properties(${CMAKE_SOURCE_DIR}/res/mgba.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) -add_executable(mGBA WIN32 MACOSX_BUNDLE main.cpp ${CMAKE_SOURCE_DIR}/res/mgba.icns ${SOURCE_FILES}) +add_executable(mGBA WIN32 MACOSX_BUNDLE main.cpp ${CMAKE_SOURCE_DIR}/res/mgba.icns ${SOURCE_FILES} ${UI_FILES}) qt5_use_modules(mGBA Widgets Multimedia OpenGL) target_link_libraries(mGBA ${PLATFORM_LIBRARY} ${OPENGL_LIBRARY} ${BINARY_NAME} Qt5::Widgets) diff --git a/src/platform/qt/GameController.cpp b/src/platform/qt/GameController.cpp index 9443c4863..0c341ac07 100644 --- a/src/platform/qt/GameController.cpp +++ b/src/platform/qt/GameController.cpp @@ -32,7 +32,8 @@ GameController::GameController(QObject* parent) .bios = 0, .renderer = &m_renderer->d, .userData = this, - .rewindBufferCapacity = 0 + .rewindBufferCapacity = 0, + .logLevel = -1, }; GBAInputMapInit(&m_threadContext.inputMap); @@ -67,6 +68,11 @@ GameController::GameController(QObject* parent) controller->frameAvailable(controller->m_drawContext); }; + m_threadContext.logHandler = [] (GBAThread* context, enum GBALogLevel level, const char* format, va_list args) { + GameController* controller = static_cast(context->userData); + controller->postLog(level, QString().vsprintf(format, args)); + }; + m_audioThread->start(); m_audioProcessor->moveToThread(m_audioThread); connect(this, SIGNAL(gameStarted(GBAThread*)), m_audioProcessor, SLOT(start())); diff --git a/src/platform/qt/GameController.h b/src/platform/qt/GameController.h index bc27acd07..d44cb6d6b 100644 --- a/src/platform/qt/GameController.h +++ b/src/platform/qt/GameController.h @@ -46,6 +46,8 @@ signals: void gamePaused(GBAThread*); void gameUnpaused(GBAThread*); + void postLog(int level, const QString& log); + public slots: void loadGame(const QString& path); void closeGame(); diff --git a/src/platform/qt/LogView.cpp b/src/platform/qt/LogView.cpp new file mode 100644 index 000000000..1f2d0702b --- /dev/null +++ b/src/platform/qt/LogView.cpp @@ -0,0 +1,98 @@ +#include "LogView.h" + +using namespace QGBA; + +LogView::LogView(QWidget* parent) + : QWidget(parent) +{ + m_ui.setupUi(this); + connect(m_ui.levelDebug, SIGNAL(toggled(bool)), this, SLOT(setLevelDebug(bool))); + connect(m_ui.levelStub, SIGNAL(toggled(bool)), this, SLOT(setLevelStub(bool))); + connect(m_ui.levelInfo, SIGNAL(toggled(bool)), this, SLOT(setLevelInfo(bool))); + connect(m_ui.levelWarn, SIGNAL(toggled(bool)), this, SLOT(setLevelWarn(bool))); + connect(m_ui.levelError, SIGNAL(toggled(bool)), this, SLOT(setLevelError(bool))); + connect(m_ui.levelFatal, SIGNAL(toggled(bool)), this, SLOT(setLevelFatal(bool))); + connect(m_ui.levelGameError, SIGNAL(toggled(bool)), this, SLOT(setLevelGameError(bool))); + m_logLevel = -1; +} + +void LogView::postLog(int level, const QString& log) { + if (!(level & m_logLevel)) { + return; + } + m_ui.view->appendPlainText(QString("%1:\t%2").arg(toString(level)).arg(log)); +} + +void LogView::clear() { + m_ui.view->clear(); +} + +void LogView::setLevelDebug(bool set) { + if (set) { + setLevel(GBA_LOG_DEBUG); + } else { + clearLevel(GBA_LOG_DEBUG); + } +} +void LogView::setLevelStub(bool set) { + if (set) { + setLevel(GBA_LOG_STUB); + } else { + clearLevel(GBA_LOG_STUB); + } +} +void LogView::setLevelInfo(bool set) { + if (set) { + setLevel(GBA_LOG_INFO); + } else { + clearLevel(GBA_LOG_INFO); + } +} +void LogView::setLevelWarn(bool set) { + if (set) { + setLevel(GBA_LOG_WARN); + } else { + clearLevel(GBA_LOG_WARN); + } +} +void LogView::setLevelError(bool set) { + if (set) { + setLevel(GBA_LOG_ERROR); + } else { + clearLevel(GBA_LOG_ERROR); + } +} +void LogView::setLevelFatal(bool set) { + if (set) { + setLevel(GBA_LOG_FATAL); + } else { + clearLevel(GBA_LOG_FATAL); + } +} +void LogView::setLevelGameError(bool set) { + if (set) { + setLevel(GBA_LOG_GAME_ERROR); + } else { + clearLevel(GBA_LOG_GAME_ERROR); + } +} + +QString LogView::toString(int level) { + switch (level) { + case GBA_LOG_DEBUG: + return tr("DEBUG"); + case GBA_LOG_STUB: + return tr("STUB"); + case GBA_LOG_INFO: + return tr("INFO"); + case GBA_LOG_WARN: + return tr("WARN"); + case GBA_LOG_ERROR: + return tr("ERROR"); + case GBA_LOG_FATAL: + return tr("FATAL"); + case GBA_LOG_GAME_ERROR: + return tr("GAME ERROR"); + } + return QString(); +} diff --git a/src/platform/qt/LogView.h b/src/platform/qt/LogView.h new file mode 100644 index 000000000..6bbf24d23 --- /dev/null +++ b/src/platform/qt/LogView.h @@ -0,0 +1,44 @@ +#ifndef QGBA_LOG_VIEW +#define QGBA_LOG_VIEW + +#include + +#include "ui_LogView.h" + +extern "C" { +#include "gba-thread.h" +} + +namespace QGBA { + +class LogView : public QWidget { +Q_OBJECT + +public: + LogView(QWidget* parent = nullptr); + +public slots: + void postLog(int level, const QString& log); + void clear(); + +private slots: + void setLevelDebug(bool); + void setLevelStub(bool); + void setLevelInfo(bool); + void setLevelWarn(bool); + void setLevelError(bool); + void setLevelFatal(bool); + void setLevelGameError(bool); + +private: + Ui::LogView m_ui; + int m_logLevel; + + static QString toString(int level); + void setLevel(int level) { m_logLevel |= level; } + void clearLevel(int level) { m_logLevel &= ~level; } +}; + +} + +#endif diff --git a/src/platform/qt/LogView.ui b/src/platform/qt/LogView.ui new file mode 100644 index 000000000..ee3d31875 --- /dev/null +++ b/src/platform/qt/LogView.ui @@ -0,0 +1,164 @@ + + + LogView + + + + 0 + 0 + 600 + 400 + + + + Logs + + + + + + + + + + + + + + Debug + + + true + + + + + + + Stub + + + true + + + + + + + Info + + + true + + + + + + + Warning + + + true + + + + + + + Error + + + true + + + + + + + Fatal + + + true + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 40 + + + + + + + + Game Error + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Clear + + + + + + + + + true + + + + + + + + + clear + clicked() + view + clear() + + + 98 + 376 + + + 299 + 311 + + + + + diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 48fb57bdd..aece9f830 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -8,6 +8,7 @@ #include "GameController.h" #include "GDBWindow.h" #include "GDBController.h" +#include "LogView.h" using namespace QGBA; @@ -21,19 +22,26 @@ Window::Window(QWidget* parent) setMinimumSize(240, 160); m_controller = new GameController(this); + m_logView = new LogView(); m_display = new Display(); setCentralWidget(m_display); connect(m_controller, SIGNAL(gameStarted(GBAThread*)), this, SLOT(gameStarted(GBAThread*))); connect(m_controller, SIGNAL(gameStopped(GBAThread*)), m_display, SLOT(stopDrawing())); connect(m_controller, SIGNAL(gameStopped(GBAThread*)), this, SLOT(gameStopped())); + connect(m_controller, SIGNAL(postLog(int, const QString&)), m_logView, SLOT(postLog(int, const QString&))); connect(this, SIGNAL(startDrawing(const uint32_t*, GBAThread*)), m_display, SLOT(startDrawing(const uint32_t*, GBAThread*)), Qt::QueuedConnection); connect(this, SIGNAL(shutdown()), m_display, SLOT(stopDrawing())); + connect(this, SIGNAL(shutdown()), m_controller, SLOT(closeGame())); connect(this, SIGNAL(audioBufferSamplesChanged(int)), m_controller, SLOT(setAudioBufferSamples(int))); connect(this, SIGNAL(fpsTargetChanged(float)), m_controller, SLOT(setFPSTarget(float))); setupMenu(menuBar()); } +Window::~Window() { + delete m_logView; +} + GBAKey Window::mapKey(int qtKey) { switch (qtKey) { case Qt::Key_Z: @@ -232,6 +240,9 @@ void Window::setupMenu(QMenuBar* menubar) { buffersMenu->addAction(setBuffer); QMenu* debuggingMenu = menubar->addMenu(tr("&Debugging")); + QAction* viewLogs = new QAction(tr("View &logs..."), nullptr); + connect(viewLogs, SIGNAL(triggered()), m_logView, SLOT(show())); + debuggingMenu->addAction(viewLogs); #ifdef USE_GDB_STUB QAction* gdbWindow = new QAction(tr("Start &GDB server..."), nullptr); connect(gdbWindow, SIGNAL(triggered()), this, SLOT(gdbOpen())); diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index 27927ee33..9db37b133 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -14,12 +14,15 @@ namespace QGBA { class GameController; class GDBController; +class LogView; class Window : public QMainWindow { Q_OBJECT public: Window(QWidget* parent = nullptr); + virtual ~Window(); + static GBAKey mapKey(int qtKey); signals: @@ -51,6 +54,7 @@ private: GameController* m_controller; Display* m_display; QList m_gameActions; + LogView* m_logView; #ifdef USE_GDB_STUB GDBController* m_gdbController;