mirror of https://github.com/mgba-emu/mgba.git
Start of log view
This commit is contained in:
parent
eef1a5e8a3
commit
fa255dc808
|
@ -22,7 +22,16 @@ if(NOT Qt5Widgets_FOUND OR NOT OPENGL_FOUND)
|
||||||
return()
|
return()
|
||||||
endif()
|
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)
|
if(USE_GDB_STUB)
|
||||||
set(SOURCE_FILES ${PLATFORM_SRC} ${SOURCE_FILES} GDBController.cpp GDBWindow.cpp)
|
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(MACOSX_BUNDLE_BUNDLE_VERSION ${LIB_VERSION_STRING})
|
||||||
set_source_files_properties(${CMAKE_SOURCE_DIR}/res/mgba.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
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)
|
qt5_use_modules(mGBA Widgets Multimedia OpenGL)
|
||||||
target_link_libraries(mGBA ${PLATFORM_LIBRARY} ${OPENGL_LIBRARY} ${BINARY_NAME} Qt5::Widgets)
|
target_link_libraries(mGBA ${PLATFORM_LIBRARY} ${OPENGL_LIBRARY} ${BINARY_NAME} Qt5::Widgets)
|
||||||
|
|
|
@ -32,7 +32,8 @@ GameController::GameController(QObject* parent)
|
||||||
.bios = 0,
|
.bios = 0,
|
||||||
.renderer = &m_renderer->d,
|
.renderer = &m_renderer->d,
|
||||||
.userData = this,
|
.userData = this,
|
||||||
.rewindBufferCapacity = 0
|
.rewindBufferCapacity = 0,
|
||||||
|
.logLevel = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
GBAInputMapInit(&m_threadContext.inputMap);
|
GBAInputMapInit(&m_threadContext.inputMap);
|
||||||
|
@ -67,6 +68,11 @@ GameController::GameController(QObject* parent)
|
||||||
controller->frameAvailable(controller->m_drawContext);
|
controller->frameAvailable(controller->m_drawContext);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
m_threadContext.logHandler = [] (GBAThread* context, enum GBALogLevel level, const char* format, va_list args) {
|
||||||
|
GameController* controller = static_cast<GameController*>(context->userData);
|
||||||
|
controller->postLog(level, QString().vsprintf(format, args));
|
||||||
|
};
|
||||||
|
|
||||||
m_audioThread->start();
|
m_audioThread->start();
|
||||||
m_audioProcessor->moveToThread(m_audioThread);
|
m_audioProcessor->moveToThread(m_audioThread);
|
||||||
connect(this, SIGNAL(gameStarted(GBAThread*)), m_audioProcessor, SLOT(start()));
|
connect(this, SIGNAL(gameStarted(GBAThread*)), m_audioProcessor, SLOT(start()));
|
||||||
|
|
|
@ -46,6 +46,8 @@ signals:
|
||||||
void gamePaused(GBAThread*);
|
void gamePaused(GBAThread*);
|
||||||
void gameUnpaused(GBAThread*);
|
void gameUnpaused(GBAThread*);
|
||||||
|
|
||||||
|
void postLog(int level, const QString& log);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void loadGame(const QString& path);
|
void loadGame(const QString& path);
|
||||||
void closeGame();
|
void closeGame();
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef QGBA_LOG_VIEW
|
||||||
|
#define QGBA_LOG_VIEW
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#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
|
|
@ -0,0 +1,164 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>LogView</class>
|
||||||
|
<widget class="QWidget" name="LogView">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>600</width>
|
||||||
|
<height>400</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Logs</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="levelDebug">
|
||||||
|
<property name="text">
|
||||||
|
<string>Debug</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="levelStub">
|
||||||
|
<property name="text">
|
||||||
|
<string>Stub</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="levelInfo">
|
||||||
|
<property name="text">
|
||||||
|
<string>Info</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="levelWarn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Warning</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="levelError">
|
||||||
|
<property name="text">
|
||||||
|
<string>Error</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="levelFatal">
|
||||||
|
<property name="text">
|
||||||
|
<string>Fatal</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="levelGameError">
|
||||||
|
<property name="text">
|
||||||
|
<string>Game Error</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="clear">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="view">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>clear</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>view</receiver>
|
||||||
|
<slot>clear()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>98</x>
|
||||||
|
<y>376</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>299</x>
|
||||||
|
<y>311</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -8,6 +8,7 @@
|
||||||
#include "GameController.h"
|
#include "GameController.h"
|
||||||
#include "GDBWindow.h"
|
#include "GDBWindow.h"
|
||||||
#include "GDBController.h"
|
#include "GDBController.h"
|
||||||
|
#include "LogView.h"
|
||||||
|
|
||||||
using namespace QGBA;
|
using namespace QGBA;
|
||||||
|
|
||||||
|
@ -21,19 +22,26 @@ Window::Window(QWidget* parent)
|
||||||
setMinimumSize(240, 160);
|
setMinimumSize(240, 160);
|
||||||
|
|
||||||
m_controller = new GameController(this);
|
m_controller = new GameController(this);
|
||||||
|
m_logView = new LogView();
|
||||||
m_display = new Display();
|
m_display = new Display();
|
||||||
setCentralWidget(m_display);
|
setCentralWidget(m_display);
|
||||||
connect(m_controller, SIGNAL(gameStarted(GBAThread*)), this, SLOT(gameStarted(GBAThread*)));
|
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*)), m_display, SLOT(stopDrawing()));
|
||||||
connect(m_controller, SIGNAL(gameStopped(GBAThread*)), this, SLOT(gameStopped()));
|
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(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_display, SLOT(stopDrawing()));
|
||||||
|
connect(this, SIGNAL(shutdown()), m_controller, SLOT(closeGame()));
|
||||||
connect(this, SIGNAL(audioBufferSamplesChanged(int)), m_controller, SLOT(setAudioBufferSamples(int)));
|
connect(this, SIGNAL(audioBufferSamplesChanged(int)), m_controller, SLOT(setAudioBufferSamples(int)));
|
||||||
connect(this, SIGNAL(fpsTargetChanged(float)), m_controller, SLOT(setFPSTarget(float)));
|
connect(this, SIGNAL(fpsTargetChanged(float)), m_controller, SLOT(setFPSTarget(float)));
|
||||||
|
|
||||||
setupMenu(menuBar());
|
setupMenu(menuBar());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window::~Window() {
|
||||||
|
delete m_logView;
|
||||||
|
}
|
||||||
|
|
||||||
GBAKey Window::mapKey(int qtKey) {
|
GBAKey Window::mapKey(int qtKey) {
|
||||||
switch (qtKey) {
|
switch (qtKey) {
|
||||||
case Qt::Key_Z:
|
case Qt::Key_Z:
|
||||||
|
@ -232,6 +240,9 @@ void Window::setupMenu(QMenuBar* menubar) {
|
||||||
buffersMenu->addAction(setBuffer);
|
buffersMenu->addAction(setBuffer);
|
||||||
|
|
||||||
QMenu* debuggingMenu = menubar->addMenu(tr("&Debugging"));
|
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
|
#ifdef USE_GDB_STUB
|
||||||
QAction* gdbWindow = new QAction(tr("Start &GDB server..."), nullptr);
|
QAction* gdbWindow = new QAction(tr("Start &GDB server..."), nullptr);
|
||||||
connect(gdbWindow, SIGNAL(triggered()), this, SLOT(gdbOpen()));
|
connect(gdbWindow, SIGNAL(triggered()), this, SLOT(gdbOpen()));
|
||||||
|
|
|
@ -14,12 +14,15 @@ namespace QGBA {
|
||||||
|
|
||||||
class GameController;
|
class GameController;
|
||||||
class GDBController;
|
class GDBController;
|
||||||
|
class LogView;
|
||||||
|
|
||||||
class Window : public QMainWindow {
|
class Window : public QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Window(QWidget* parent = nullptr);
|
Window(QWidget* parent = nullptr);
|
||||||
|
virtual ~Window();
|
||||||
|
|
||||||
static GBAKey mapKey(int qtKey);
|
static GBAKey mapKey(int qtKey);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -51,6 +54,7 @@ private:
|
||||||
GameController* m_controller;
|
GameController* m_controller;
|
||||||
Display* m_display;
|
Display* m_display;
|
||||||
QList<QAction*> m_gameActions;
|
QList<QAction*> m_gameActions;
|
||||||
|
LogView* m_logView;
|
||||||
|
|
||||||
#ifdef USE_GDB_STUB
|
#ifdef USE_GDB_STUB
|
||||||
GDBController* m_gdbController;
|
GDBController* m_gdbController;
|
||||||
|
|
Loading…
Reference in New Issue