From 3fe28520cafd4598e50512e988bd4a427e1c676f Mon Sep 17 00:00:00 2001 From: Adam Higerd Date: Mon, 28 Apr 2025 19:37:01 -0500 Subject: [PATCH] Qt: route Qt logging to mGBA's logging system --- src/platform/qt/AudioDevice.cpp | 6 ++-- src/platform/qt/AudioProcessorQt.cpp | 4 +-- src/platform/qt/AudioProcessorSDL.cpp | 2 +- src/platform/qt/CheatsModel.cpp | 2 +- src/platform/qt/CheatsView.cpp | 2 +- src/platform/qt/CoreController.cpp | 10 +++---- src/platform/qt/CoreManager.cpp | 6 ++-- src/platform/qt/DebuggerConsoleController.cpp | 2 +- src/platform/qt/DisplayGL.cpp | 2 +- src/platform/qt/GBAApp.cpp | 1 + src/platform/qt/GIFView.cpp | 2 +- src/platform/qt/InputController.cpp | 6 ++-- src/platform/qt/LogController.cpp | 28 +++++++++++++++++++ src/platform/qt/LogController.h | 1 + src/platform/qt/MemoryAccessLogController.cpp | 4 +-- src/platform/qt/MemoryDump.cpp | 2 +- src/platform/qt/MemoryModel.cpp | 4 +-- src/platform/qt/MultiplayerController.cpp | 12 ++++---- src/platform/qt/PaletteView.cpp | 2 +- src/platform/qt/SaveConverter.cpp | 2 +- src/platform/qt/VideoView.cpp | 2 +- src/platform/qt/Window.cpp | 4 +-- 22 files changed, 68 insertions(+), 38 deletions(-) diff --git a/src/platform/qt/AudioDevice.cpp b/src/platform/qt/AudioDevice.cpp index bf027cd43..c00071381 100644 --- a/src/platform/qt/AudioDevice.cpp +++ b/src/platform/qt/AudioDevice.cpp @@ -31,7 +31,7 @@ AudioDevice::~AudioDevice() { void AudioDevice::setFormat(const QAudioFormat& format) { if (!m_context || !mCoreThreadIsActive(m_context)) { - LOG(QT, INFO) << tr("Can't set format of context-less audio device"); + qInfo() << tr("Can't set format of context-less audio device"); return; } mCoreSyncLockAudio(&m_context->impl->sync); @@ -52,7 +52,7 @@ void AudioDevice::setInput(mCoreThread* input) { qint64 AudioDevice::readData(char* data, qint64 maxSize) { if (!m_context->core) { - LOG(QT, WARN) << tr("Audio device is missing its core"); + qWarning() << tr("Audio device is missing its core"); return 0; } @@ -80,7 +80,7 @@ qint64 AudioDevice::readData(char* data, qint64 maxSize) { } qint64 AudioDevice::writeData(const char*, qint64) { - LOG(QT, WARN) << tr("Writing data to read-only audio device"); + qWarning() << tr("Writing data to read-only audio device"); return 0; } diff --git a/src/platform/qt/AudioProcessorQt.cpp b/src/platform/qt/AudioProcessorQt.cpp index 87ad5b5ac..e9fcf3641 100644 --- a/src/platform/qt/AudioProcessorQt.cpp +++ b/src/platform/qt/AudioProcessorQt.cpp @@ -53,7 +53,7 @@ void AudioProcessorQt::stop() { bool AudioProcessorQt::start() { if (!input()) { - LOG(QT, WARN) << tr("Can't start an audio processor without input"); + qWarning() << tr("Can't start an audio processor without input"); return false; } @@ -78,7 +78,7 @@ bool AudioProcessorQt::start() { QAudioDevice device(QMediaDevices::defaultAudioOutput()); m_audioOutput = std::make_unique(device, format); - LOG(QT, INFO) << "Audio outputting to " << device.description(); + qInfo() << "Audio outputting to " << device.description(); connect(m_audioOutput.get(), &QAudioSink::stateChanged, this, [this](QAudio::State state) { if (state != QAudio::IdleState) { return; diff --git a/src/platform/qt/AudioProcessorSDL.cpp b/src/platform/qt/AudioProcessorSDL.cpp index bfa9782d1..0be57b891 100644 --- a/src/platform/qt/AudioProcessorSDL.cpp +++ b/src/platform/qt/AudioProcessorSDL.cpp @@ -31,7 +31,7 @@ void AudioProcessorSDL::stop() { bool AudioProcessorSDL::start() { if (!input()) { - LOG(QT, WARN) << tr("Can't start an audio processor without input"); + qWarning() << tr("Can't start an audio processor without input"); return false; } diff --git a/src/platform/qt/CheatsModel.cpp b/src/platform/qt/CheatsModel.cpp index 85528c1b6..6e28df356 100644 --- a/src/platform/qt/CheatsModel.cpp +++ b/src/platform/qt/CheatsModel.cpp @@ -208,7 +208,7 @@ void CheatsModel::endAppendRow() { void CheatsModel::loadFile(const QString& path) { VFile* vf = VFileDevice::open(path, O_RDONLY); if (!vf) { - LOG(QT, WARN) << tr("Failed to open cheats file: %1").arg(path); + qWarning() << tr("Failed to open cheats file: %1").arg(path); return; } beginResetModel(); diff --git a/src/platform/qt/CheatsView.cpp b/src/platform/qt/CheatsView.cpp index 243987d6b..db0ce50c5 100644 --- a/src/platform/qt/CheatsView.cpp +++ b/src/platform/qt/CheatsView.cpp @@ -183,7 +183,7 @@ void CheatsView::enterCheat() { set->refresh(set, m_controller->cheatDevice()); } if (failure) { - LOG(QT, ERROR) << tr("Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types."); + qCritical() << tr("Some cheats could not be added. Please ensure they're formatted correctly and/or try other cheat types."); } m_ui.codeEntry->clear(); } diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 55e743be1..1e4ff5138 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -824,7 +824,7 @@ void CoreController::loadSave(const QString& path, bool temporary) { m_resetActions.append([this, path, temporary]() { VFile* vf = VFileDevice::open(path, temporary ? O_RDONLY : O_RDWR); if (!vf) { - LOG(QT, ERROR) << tr("Failed to open save file: %1").arg(path); + qCritical() << tr("Failed to open save file: %1").arg(path); return; } @@ -882,7 +882,7 @@ void CoreController::loadPatch(const QString& patchPath) { void CoreController::replaceGame(const QString& path) { QFileInfo info(path); if (!info.isReadable()) { - LOG(QT, ERROR) << tr("Failed to open game file: %1").arg(path); + qCritical() << tr("Failed to open game file: %1").arg(path); return; } QString fname = info.canonicalFilePath(); @@ -912,7 +912,7 @@ void CoreController::yankPak() { break; #endif case mPLATFORM_NONE: - LOG(QT, ERROR) << tr("Can't yank pack in unexpected platform!"); + qCritical() << tr("Can't yank pack in unexpected platform!"); break; } } @@ -1027,7 +1027,7 @@ void CoreController::importSharkport(const QString& path) { } VFile* vf = VFileDevice::open(path, O_RDONLY); if (!vf) { - LOG(QT, ERROR) << tr("Failed to open snapshot file for reading: %1").arg(path); + qCritical() << tr("Failed to open snapshot file for reading: %1").arg(path); return; } Interrupter interrupter(this); @@ -1044,7 +1044,7 @@ void CoreController::exportSharkport(const QString& path) { } VFile* vf = VFileDevice::open(path, O_WRONLY | O_CREAT | O_TRUNC); if (!vf) { - LOG(QT, ERROR) << tr("Failed to open snapshot file for writing: %1").arg(path); + qCritical() << tr("Failed to open snapshot file for writing: %1").arg(path); return; } Interrupter interrupter(this); diff --git a/src/platform/qt/CoreManager.cpp b/src/platform/qt/CoreManager.cpp index 385b3440b..4abdcb8a1 100644 --- a/src/platform/qt/CoreManager.cpp +++ b/src/platform/qt/CoreManager.cpp @@ -49,7 +49,7 @@ CoreController* CoreManager::loadGame(const QString& path) { dir->close(dir); return loadGame(vf, fname, base); } else { - LOG(QT, ERROR) << tr("Failed to open game file: %1").arg(path); + qCritical() << tr("Failed to open game file: %1").arg(path); } return nullptr; } @@ -87,7 +87,7 @@ CoreController* CoreManager::loadGame(VFile* vf, const QString& path, const QStr mCore* core = mCoreFindVF(vf); if (!core) { vf->close(vf); - LOG(QT, ERROR) << tr("Could not load game. Are you sure it's in the correct format?"); + qCritical() << tr("Could not load game. Are you sure it's in the correct format?"); return nullptr; } @@ -114,7 +114,7 @@ CoreController* CoreManager::loadGame(VFile* vf, const QString& path, const QStr bytes = info.dir().canonicalPath().toUtf8(); mDirectorySetAttachBase(&core->dirs, VDirOpen(bytes.constData())); if (!mCoreAutoloadSave(core)) { - LOG(QT, ERROR) << tr("Failed to open save file; in-game saves cannot be updated. Please ensure the save directory is writable without additional privileges (e.g. UAC on Windows)."); + qCritical() << tr("Failed to open save file; in-game saves cannot be updated. Please ensure the save directory is writable without additional privileges (e.g. UAC on Windows)."); } mCoreAutoloadCheats(core); diff --git a/src/platform/qt/DebuggerConsoleController.cpp b/src/platform/qt/DebuggerConsoleController.cpp index 716c31639..25bbe64cd 100644 --- a/src/platform/qt/DebuggerConsoleController.cpp +++ b/src/platform/qt/DebuggerConsoleController.cpp @@ -173,7 +173,7 @@ void DebuggerConsoleController::historyLoad() { void DebuggerConsoleController::historySave() { QFile log(ConfigController::configDir() + "/cli_history.log"); if (!log.open(QIODevice::WriteOnly | QIODevice::Text)) { - LOG(QT, WARN) << tr("Could not open CLI history for writing"); + qWarning() << tr("Could not open CLI history for writing"); return; } for (const QString& line : m_history) { diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 00af3cb8d..8e5849dbf 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -310,7 +310,7 @@ bool DisplayGL::highestCompatible(QSurfaceFormat& format) { #ifdef BUILD_GL #if defined(BUILD_GLES2) || defined(BUILD_GLES3) || defined(USE_EPOXY) - LOG(QT, WARN) << tr("Failed to create an OpenGL 3 context, trying old-style..."); + qWarning() << tr("Failed to create an OpenGL 3 context, trying old-style..."); #endif if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { format.setVersion(1, 4); diff --git a/src/platform/qt/GBAApp.cpp b/src/platform/qt/GBAApp.cpp index 258df9f0c..27d57e167 100644 --- a/src/platform/qt/GBAApp.cpp +++ b/src/platform/qt/GBAApp.cpp @@ -71,6 +71,7 @@ GBAApp::GBAApp(int& argc, char* argv[], ConfigController* config) AudioProcessor::setDriver(static_cast(m_configController->getQtOption("audioDriver").toInt())); } + LogController::installMessageHandler(); LogController::global()->load(m_configController); #ifdef USE_DISCORD_RPC diff --git a/src/platform/qt/GIFView.cpp b/src/platform/qt/GIFView.cpp index c3bf496da..ef9ddee77 100644 --- a/src/platform/qt/GIFView.cpp +++ b/src/platform/qt/GIFView.cpp @@ -60,7 +60,7 @@ void GIFView::startRecording() { } FFmpegEncoderSetLooping(&m_encoder, m_ui.loop->isChecked()); if (!FFmpegEncoderOpen(&m_encoder, m_filename.toUtf8().constData())) { - LOG(QT, ERROR) << tr("Failed to open output file: %1").arg(m_filename); + qCritical() << tr("Failed to open output file: %1").arg(m_filename); return; } m_ui.start->setEnabled(false); diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index 3deca07f3..4d7d7d8f7 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -724,9 +724,9 @@ void InputController::prepareCamFormat() { } } if (!goodFormatFound) { - LOG(QT, WARN) << "Could not find a valid camera format!"; + qWarning() << "Could not find a valid camera format!"; for (const auto& format : cameraFormats) { - LOG(QT, WARN) << "Camera supported format: " << QString::number(format); + qWarning() << "Camera supported format: " << QString::number(format); } } m_camera->setViewfinderSettings(settings); @@ -745,7 +745,7 @@ void InputController::prepareCamFormat() { } } if (!goodFormatFound) { - LOG(QT, WARN) << "Could not find a valid camera format!"; + qWarning() << "Could not find a valid camera format!"; } m_camera->setCameraFormat(bestFormat); #endif diff --git a/src/platform/qt/LogController.cpp b/src/platform/qt/LogController.cpp index d60771073..5d2ec8dbf 100644 --- a/src/platform/qt/LogController.cpp +++ b/src/platform/qt/LogController.cpp @@ -6,6 +6,9 @@ #include "LogController.h" #include +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#include +#endif #include "ConfigController.h" @@ -18,6 +21,31 @@ using namespace QGBA; LogController LogController::s_global(mLOG_ALL); int LogController::s_qtCat{-1}; +static void logMessageHandler(QtMsgType msgType, const QMessageLogContext&, const QString& msg) { + switch (msgType) { + case QtDebugMsg: + LOG(QT, DEBUG) << msg; + break; + case QtInfoMsg: + LOG(QT, INFO) << msg; + break; + case QtCriticalMsg: + LOG(QT, ERROR) << msg; + break; + case QtFatalMsg: + LOG(QT, FATAL) << msg; + break; + case QtWarningMsg: + default: + LOG(QT, WARN) << msg; + break; + } +} + +QtMessageHandler LogController::installMessageHandler() { + return qInstallMessageHandler(logMessageHandler); +} + LogController::LogController(int levels, QObject* parent) : QObject(parent) { diff --git a/src/platform/qt/LogController.h b/src/platform/qt/LogController.h index 6bd4e5707..2ab7962fb 100644 --- a/src/platform/qt/LogController.h +++ b/src/platform/qt/LogController.h @@ -48,6 +48,7 @@ public: Stream operator()(int category, int level); static LogController* global(); + static QtMessageHandler installMessageHandler(); static QString toString(int level); static int categoryId(const char*); diff --git a/src/platform/qt/MemoryAccessLogController.cpp b/src/platform/qt/MemoryAccessLogController.cpp index d62b2f8a5..d8b4cc00d 100644 --- a/src/platform/qt/MemoryAccessLogController.cpp +++ b/src/platform/qt/MemoryAccessLogController.cpp @@ -114,7 +114,7 @@ void MemoryAccessLogController::load(bool loadExisting) { } VFile* vf = VFileDevice::open(m_path, flags); if (!vf) { - LOG(QT, ERROR) << tr("Failed to open memory log file"); + qCritical() << tr("Failed to open memory log file"); return; } @@ -123,7 +123,7 @@ void MemoryAccessLogController::load(bool loadExisting) { m_controller->attachDebuggerModule(&m_logger.d); if (!mDebuggerAccessLoggerOpen(&m_logger, vf, flags)) { mDebuggerAccessLoggerDeinit(&m_logger); - LOG(QT, ERROR) << tr("Failed to open memory log file"); + qCritical() << tr("Failed to open memory log file"); return; } emit loaded(true); diff --git a/src/platform/qt/MemoryDump.cpp b/src/platform/qt/MemoryDump.cpp index 59cef31be..01d228566 100644 --- a/src/platform/qt/MemoryDump.cpp +++ b/src/platform/qt/MemoryDump.cpp @@ -27,7 +27,7 @@ void MemoryDump::save() { } QFile outfile(filename); if (!outfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - LOG(QT, WARN) << tr("Failed to open output file: %1").arg(filename); + qWarning() << tr("Failed to open output file: %1").arg(filename); return; } QByteArray out(serialize()); diff --git a/src/platform/qt/MemoryModel.cpp b/src/platform/qt/MemoryModel.cpp index ca264d4c1..2ce02f644 100644 --- a/src/platform/qt/MemoryModel.cpp +++ b/src/platform/qt/MemoryModel.cpp @@ -219,7 +219,7 @@ void MemoryModel::save() { } QFile outfile(filename); if (!outfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - LOG(QT, WARN) << tr("Failed to open output file: %1").arg(filename); + qWarning() << tr("Failed to open output file: %1").arg(filename); return; } QByteArray out(serialize()); @@ -233,7 +233,7 @@ void MemoryModel::load() { } QFile infile(filename); if (!infile.open(QIODevice::ReadOnly)) { - LOG(QT, WARN) << tr("Failed to open input file: %1").arg(filename); + qWarning() << tr("Failed to open input file: %1").arg(filename); return; } QByteArray bytestring(infile.readAll()); diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp index e95498fad..bdcde615d 100644 --- a/src/platform/qt/MultiplayerController.cpp +++ b/src/platform/qt/MultiplayerController.cpp @@ -310,7 +310,7 @@ bool MultiplayerController::attachGame(CoreController* controller) { break; } if (!player.saveId) { - LOG(QT, ERROR) << "Couldn't find available save ID"; + qCritical() << "Couldn't find available save ID"; player.saveId = 1; } } else if (saveId) { @@ -364,7 +364,7 @@ void MultiplayerController::detachGame(CoreController* controller) { interrupters.append(playerController); } if (pid < 0) { - LOG(QT, WARN) << tr("Trying to detach a multiplayer player that's not attached"); + qWarning() << tr("Trying to detach a multiplayer player that's not attached"); return; } switch (controller->platform()) { @@ -404,7 +404,7 @@ void MultiplayerController::detachGame(CoreController* controller) { QPair path(controller->path(), controller->baseDirectory()); Player& p = m_pids.find(pid).value(); if (!p.saveId) { - LOG(QT, WARN) << tr("Clearing invalid save ID"); + qWarning() << tr("Clearing invalid save ID"); } else { m_claimedSaves[path] &= ~(1 << (p.saveId - 1)); if (!m_claimedSaves[path]) { @@ -413,7 +413,7 @@ void MultiplayerController::detachGame(CoreController* controller) { } if (p.preferredId < 0) { - LOG(QT, WARN) << tr("Clearing invalid preferred ID"); + qWarning() << tr("Clearing invalid preferred ID"); } else { m_claimedIds &= ~(1 << p.preferredId); } @@ -434,7 +434,7 @@ int MultiplayerController::playerId(CoreController* controller) const { for (int i = 0; i < m_players.count(); ++i) { const Player* p = player(i); if (!p) { - LOG(QT, ERROR) << tr("Trying to get player ID for a multiplayer player that's not attached"); + qCritical() << tr("Trying to get player ID for a multiplayer player that's not attached"); return -1; } if (p->controller == controller) { @@ -448,7 +448,7 @@ int MultiplayerController::saveId(CoreController* controller) const { for (int i = 0; i < m_players.count(); ++i) { const Player* p = player(i); if (!p) { - LOG(QT, ERROR) << tr("Trying to get save ID for a multiplayer player that's not attached"); + qCritical() << tr("Trying to get save ID for a multiplayer player that's not attached"); return -1; } if (p->controller == controller) { diff --git a/src/platform/qt/PaletteView.cpp b/src/platform/qt/PaletteView.cpp index de09c270a..896c561cf 100644 --- a/src/platform/qt/PaletteView.cpp +++ b/src/platform/qt/PaletteView.cpp @@ -139,7 +139,7 @@ void PaletteView::exportPalette(int start, int length) { } VFile* vf = VFileDevice::open(filename, O_WRONLY | O_CREAT | O_TRUNC); if (!vf) { - LOG(QT, ERROR) << tr("Failed to open output palette file: %1").arg(filename); + qCritical() << tr("Failed to open output palette file: %1").arg(filename); return; } if (filename.endsWith(".pal", Qt::CaseInsensitive)) { diff --git a/src/platform/qt/SaveConverter.cpp b/src/platform/qt/SaveConverter.cpp index 3383e006e..a8047471c 100644 --- a/src/platform/qt/SaveConverter.cpp +++ b/src/platform/qt/SaveConverter.cpp @@ -656,7 +656,7 @@ QByteArray SaveConverter::AnnotatedSave::convertTo(const SaveConverter::Annotate } if (platform != target.platform) { - LOG(QT, ERROR) << tr("Cannot convert save games between platforms"); + qCritical() << tr("Cannot convert save games between platforms"); return {}; } diff --git a/src/platform/qt/VideoView.cpp b/src/platform/qt/VideoView.cpp index 356133bbb..e81584ce4 100644 --- a/src/platform/qt/VideoView.cpp +++ b/src/platform/qt/VideoView.cpp @@ -223,7 +223,7 @@ void VideoView::startRecording() { return; } if (!FFmpegEncoderOpen(&m_encoder, m_filename.toUtf8().constData())) { - LOG(QT, ERROR) << tr("Failed to open output video file: %1").arg(m_filename); + qCritical() << tr("Failed to open output video file: %1").arg(m_filename); return; } m_ui.start->setEnabled(false); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 8f09d439f..4632ca558 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1053,7 +1053,7 @@ void Window::reloadDisplayDriver() { } m_display = std::unique_ptr(Display::create(this)); if (!m_display) { - LOG(QT, ERROR) << tr("Failed to create an appropriate display device, falling back to software display. " + qCritical() << tr("Failed to create an appropriate display device, falling back to software display. " "Games may run slowly, especially with larger windows."); Display::setDriver(Display::Driver::QT); m_display = std::unique_ptr(Display::create(this)); @@ -1126,7 +1126,7 @@ void Window::reloadAudioDriver() { m_audioProcessor->setInput(m_controller); m_audioProcessor->configure(m_config); if (!m_audioProcessor->start()) { - LOG(QT, WARN) << "Failed to start audio processor"; + qWarning() << "Failed to start audio processor"; } }