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()
|
||||
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)
|
||||
|
|
|
@ -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<GameController*>(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()));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 "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()));
|
||||
|
|
|
@ -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<QAction*> m_gameActions;
|
||||
LogView* m_logView;
|
||||
|
||||
#ifdef USE_GDB_STUB
|
||||
GDBController* m_gdbController;
|
||||
|
|
Loading…
Reference in New Issue