Qt: route Qt logging to mGBA's logging system

This commit is contained in:
Adam Higerd 2025-04-28 19:37:01 -05:00 committed by Vicki Pfau
parent c4ae9015d9
commit 3fe28520ca
22 changed files with 68 additions and 38 deletions

View File

@ -31,7 +31,7 @@ AudioDevice::~AudioDevice() {
void AudioDevice::setFormat(const QAudioFormat& format) { void AudioDevice::setFormat(const QAudioFormat& format) {
if (!m_context || !mCoreThreadIsActive(m_context)) { 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; return;
} }
mCoreSyncLockAudio(&m_context->impl->sync); mCoreSyncLockAudio(&m_context->impl->sync);
@ -52,7 +52,7 @@ void AudioDevice::setInput(mCoreThread* input) {
qint64 AudioDevice::readData(char* data, qint64 maxSize) { qint64 AudioDevice::readData(char* data, qint64 maxSize) {
if (!m_context->core) { if (!m_context->core) {
LOG(QT, WARN) << tr("Audio device is missing its core"); qWarning() << tr("Audio device is missing its core");
return 0; return 0;
} }
@ -80,7 +80,7 @@ qint64 AudioDevice::readData(char* data, qint64 maxSize) {
} }
qint64 AudioDevice::writeData(const char*, qint64) { 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; return 0;
} }

View File

@ -53,7 +53,7 @@ void AudioProcessorQt::stop() {
bool AudioProcessorQt::start() { bool AudioProcessorQt::start() {
if (!input()) { 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; return false;
} }
@ -78,7 +78,7 @@ bool AudioProcessorQt::start() {
QAudioDevice device(QMediaDevices::defaultAudioOutput()); QAudioDevice device(QMediaDevices::defaultAudioOutput());
m_audioOutput = std::make_unique<QAudioSink>(device, format); m_audioOutput = std::make_unique<QAudioSink>(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) { connect(m_audioOutput.get(), &QAudioSink::stateChanged, this, [this](QAudio::State state) {
if (state != QAudio::IdleState) { if (state != QAudio::IdleState) {
return; return;

View File

@ -31,7 +31,7 @@ void AudioProcessorSDL::stop() {
bool AudioProcessorSDL::start() { bool AudioProcessorSDL::start() {
if (!input()) { 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; return false;
} }

View File

@ -208,7 +208,7 @@ void CheatsModel::endAppendRow() {
void CheatsModel::loadFile(const QString& path) { void CheatsModel::loadFile(const QString& path) {
VFile* vf = VFileDevice::open(path, O_RDONLY); VFile* vf = VFileDevice::open(path, O_RDONLY);
if (!vf) { 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; return;
} }
beginResetModel(); beginResetModel();

View File

@ -183,7 +183,7 @@ void CheatsView::enterCheat() {
set->refresh(set, m_controller->cheatDevice()); set->refresh(set, m_controller->cheatDevice());
} }
if (failure) { 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(); m_ui.codeEntry->clear();
} }

View File

@ -824,7 +824,7 @@ void CoreController::loadSave(const QString& path, bool temporary) {
m_resetActions.append([this, path, temporary]() { m_resetActions.append([this, path, temporary]() {
VFile* vf = VFileDevice::open(path, temporary ? O_RDONLY : O_RDWR); VFile* vf = VFileDevice::open(path, temporary ? O_RDONLY : O_RDWR);
if (!vf) { 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; return;
} }
@ -882,7 +882,7 @@ void CoreController::loadPatch(const QString& patchPath) {
void CoreController::replaceGame(const QString& path) { void CoreController::replaceGame(const QString& path) {
QFileInfo info(path); QFileInfo info(path);
if (!info.isReadable()) { 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; return;
} }
QString fname = info.canonicalFilePath(); QString fname = info.canonicalFilePath();
@ -912,7 +912,7 @@ void CoreController::yankPak() {
break; break;
#endif #endif
case mPLATFORM_NONE: case mPLATFORM_NONE:
LOG(QT, ERROR) << tr("Can't yank pack in unexpected platform!"); qCritical() << tr("Can't yank pack in unexpected platform!");
break; break;
} }
} }
@ -1027,7 +1027,7 @@ void CoreController::importSharkport(const QString& path) {
} }
VFile* vf = VFileDevice::open(path, O_RDONLY); VFile* vf = VFileDevice::open(path, O_RDONLY);
if (!vf) { 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; return;
} }
Interrupter interrupter(this); Interrupter interrupter(this);
@ -1044,7 +1044,7 @@ void CoreController::exportSharkport(const QString& path) {
} }
VFile* vf = VFileDevice::open(path, O_WRONLY | O_CREAT | O_TRUNC); VFile* vf = VFileDevice::open(path, O_WRONLY | O_CREAT | O_TRUNC);
if (!vf) { 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; return;
} }
Interrupter interrupter(this); Interrupter interrupter(this);

View File

@ -49,7 +49,7 @@ CoreController* CoreManager::loadGame(const QString& path) {
dir->close(dir); dir->close(dir);
return loadGame(vf, fname, base); return loadGame(vf, fname, base);
} else { } 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; return nullptr;
} }
@ -87,7 +87,7 @@ CoreController* CoreManager::loadGame(VFile* vf, const QString& path, const QStr
mCore* core = mCoreFindVF(vf); mCore* core = mCoreFindVF(vf);
if (!core) { if (!core) {
vf->close(vf); 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; return nullptr;
} }
@ -114,7 +114,7 @@ CoreController* CoreManager::loadGame(VFile* vf, const QString& path, const QStr
bytes = info.dir().canonicalPath().toUtf8(); bytes = info.dir().canonicalPath().toUtf8();
mDirectorySetAttachBase(&core->dirs, VDirOpen(bytes.constData())); mDirectorySetAttachBase(&core->dirs, VDirOpen(bytes.constData()));
if (!mCoreAutoloadSave(core)) { 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); mCoreAutoloadCheats(core);

View File

@ -173,7 +173,7 @@ void DebuggerConsoleController::historyLoad() {
void DebuggerConsoleController::historySave() { void DebuggerConsoleController::historySave() {
QFile log(ConfigController::configDir() + "/cli_history.log"); QFile log(ConfigController::configDir() + "/cli_history.log");
if (!log.open(QIODevice::WriteOnly | QIODevice::Text)) { 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; return;
} }
for (const QString& line : m_history) { for (const QString& line : m_history) {

View File

@ -310,7 +310,7 @@ bool DisplayGL::highestCompatible(QSurfaceFormat& format) {
#ifdef BUILD_GL #ifdef BUILD_GL
#if defined(BUILD_GLES2) || defined(BUILD_GLES3) || defined(USE_EPOXY) #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 #endif
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
format.setVersion(1, 4); format.setVersion(1, 4);

View File

@ -71,6 +71,7 @@ GBAApp::GBAApp(int& argc, char* argv[], ConfigController* config)
AudioProcessor::setDriver(static_cast<AudioProcessor::Driver>(m_configController->getQtOption("audioDriver").toInt())); AudioProcessor::setDriver(static_cast<AudioProcessor::Driver>(m_configController->getQtOption("audioDriver").toInt()));
} }
LogController::installMessageHandler();
LogController::global()->load(m_configController); LogController::global()->load(m_configController);
#ifdef USE_DISCORD_RPC #ifdef USE_DISCORD_RPC

View File

@ -60,7 +60,7 @@ void GIFView::startRecording() {
} }
FFmpegEncoderSetLooping(&m_encoder, m_ui.loop->isChecked()); FFmpegEncoderSetLooping(&m_encoder, m_ui.loop->isChecked());
if (!FFmpegEncoderOpen(&m_encoder, m_filename.toUtf8().constData())) { 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; return;
} }
m_ui.start->setEnabled(false); m_ui.start->setEnabled(false);

View File

@ -724,9 +724,9 @@ void InputController::prepareCamFormat() {
} }
} }
if (!goodFormatFound) { 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) { 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); m_camera->setViewfinderSettings(settings);
@ -745,7 +745,7 @@ void InputController::prepareCamFormat() {
} }
} }
if (!goodFormatFound) { if (!goodFormatFound) {
LOG(QT, WARN) << "Could not find a valid camera format!"; qWarning() << "Could not find a valid camera format!";
} }
m_camera->setCameraFormat(bestFormat); m_camera->setCameraFormat(bestFormat);
#endif #endif

View File

@ -6,6 +6,9 @@
#include "LogController.h" #include "LogController.h"
#include <QMessageBox> #include <QMessageBox>
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
#include <QtLogging>
#endif
#include "ConfigController.h" #include "ConfigController.h"
@ -18,6 +21,31 @@ using namespace QGBA;
LogController LogController::s_global(mLOG_ALL); LogController LogController::s_global(mLOG_ALL);
int LogController::s_qtCat{-1}; 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) LogController::LogController(int levels, QObject* parent)
: QObject(parent) : QObject(parent)
{ {

View File

@ -48,6 +48,7 @@ public:
Stream operator()(int category, int level); Stream operator()(int category, int level);
static LogController* global(); static LogController* global();
static QtMessageHandler installMessageHandler();
static QString toString(int level); static QString toString(int level);
static int categoryId(const char*); static int categoryId(const char*);

View File

@ -114,7 +114,7 @@ void MemoryAccessLogController::load(bool loadExisting) {
} }
VFile* vf = VFileDevice::open(m_path, flags); VFile* vf = VFileDevice::open(m_path, flags);
if (!vf) { if (!vf) {
LOG(QT, ERROR) << tr("Failed to open memory log file"); qCritical() << tr("Failed to open memory log file");
return; return;
} }
@ -123,7 +123,7 @@ void MemoryAccessLogController::load(bool loadExisting) {
m_controller->attachDebuggerModule(&m_logger.d); m_controller->attachDebuggerModule(&m_logger.d);
if (!mDebuggerAccessLoggerOpen(&m_logger, vf, flags)) { if (!mDebuggerAccessLoggerOpen(&m_logger, vf, flags)) {
mDebuggerAccessLoggerDeinit(&m_logger); mDebuggerAccessLoggerDeinit(&m_logger);
LOG(QT, ERROR) << tr("Failed to open memory log file"); qCritical() << tr("Failed to open memory log file");
return; return;
} }
emit loaded(true); emit loaded(true);

View File

@ -27,7 +27,7 @@ void MemoryDump::save() {
} }
QFile outfile(filename); QFile outfile(filename);
if (!outfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { 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; return;
} }
QByteArray out(serialize()); QByteArray out(serialize());

View File

@ -219,7 +219,7 @@ void MemoryModel::save() {
} }
QFile outfile(filename); QFile outfile(filename);
if (!outfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { 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; return;
} }
QByteArray out(serialize()); QByteArray out(serialize());
@ -233,7 +233,7 @@ void MemoryModel::load() {
} }
QFile infile(filename); QFile infile(filename);
if (!infile.open(QIODevice::ReadOnly)) { 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; return;
} }
QByteArray bytestring(infile.readAll()); QByteArray bytestring(infile.readAll());

View File

@ -310,7 +310,7 @@ bool MultiplayerController::attachGame(CoreController* controller) {
break; break;
} }
if (!player.saveId) { if (!player.saveId) {
LOG(QT, ERROR) << "Couldn't find available save ID"; qCritical() << "Couldn't find available save ID";
player.saveId = 1; player.saveId = 1;
} }
} else if (saveId) { } else if (saveId) {
@ -364,7 +364,7 @@ void MultiplayerController::detachGame(CoreController* controller) {
interrupters.append(playerController); interrupters.append(playerController);
} }
if (pid < 0) { 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; return;
} }
switch (controller->platform()) { switch (controller->platform()) {
@ -404,7 +404,7 @@ void MultiplayerController::detachGame(CoreController* controller) {
QPair<QString, QString> path(controller->path(), controller->baseDirectory()); QPair<QString, QString> path(controller->path(), controller->baseDirectory());
Player& p = m_pids.find(pid).value(); Player& p = m_pids.find(pid).value();
if (!p.saveId) { if (!p.saveId) {
LOG(QT, WARN) << tr("Clearing invalid save ID"); qWarning() << tr("Clearing invalid save ID");
} else { } else {
m_claimedSaves[path] &= ~(1 << (p.saveId - 1)); m_claimedSaves[path] &= ~(1 << (p.saveId - 1));
if (!m_claimedSaves[path]) { if (!m_claimedSaves[path]) {
@ -413,7 +413,7 @@ void MultiplayerController::detachGame(CoreController* controller) {
} }
if (p.preferredId < 0) { if (p.preferredId < 0) {
LOG(QT, WARN) << tr("Clearing invalid preferred ID"); qWarning() << tr("Clearing invalid preferred ID");
} else { } else {
m_claimedIds &= ~(1 << p.preferredId); m_claimedIds &= ~(1 << p.preferredId);
} }
@ -434,7 +434,7 @@ int MultiplayerController::playerId(CoreController* controller) const {
for (int i = 0; i < m_players.count(); ++i) { for (int i = 0; i < m_players.count(); ++i) {
const Player* p = player(i); const Player* p = player(i);
if (!p) { 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; return -1;
} }
if (p->controller == controller) { if (p->controller == controller) {
@ -448,7 +448,7 @@ int MultiplayerController::saveId(CoreController* controller) const {
for (int i = 0; i < m_players.count(); ++i) { for (int i = 0; i < m_players.count(); ++i) {
const Player* p = player(i); const Player* p = player(i);
if (!p) { 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; return -1;
} }
if (p->controller == controller) { if (p->controller == controller) {

View File

@ -139,7 +139,7 @@ void PaletteView::exportPalette(int start, int length) {
} }
VFile* vf = VFileDevice::open(filename, O_WRONLY | O_CREAT | O_TRUNC); VFile* vf = VFileDevice::open(filename, O_WRONLY | O_CREAT | O_TRUNC);
if (!vf) { 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; return;
} }
if (filename.endsWith(".pal", Qt::CaseInsensitive)) { if (filename.endsWith(".pal", Qt::CaseInsensitive)) {

View File

@ -656,7 +656,7 @@ QByteArray SaveConverter::AnnotatedSave::convertTo(const SaveConverter::Annotate
} }
if (platform != target.platform) { if (platform != target.platform) {
LOG(QT, ERROR) << tr("Cannot convert save games between platforms"); qCritical() << tr("Cannot convert save games between platforms");
return {}; return {};
} }

View File

@ -223,7 +223,7 @@ void VideoView::startRecording() {
return; return;
} }
if (!FFmpegEncoderOpen(&m_encoder, m_filename.toUtf8().constData())) { 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; return;
} }
m_ui.start->setEnabled(false); m_ui.start->setEnabled(false);

View File

@ -1053,7 +1053,7 @@ void Window::reloadDisplayDriver() {
} }
m_display = std::unique_ptr<QGBA::Display>(Display::create(this)); m_display = std::unique_ptr<QGBA::Display>(Display::create(this));
if (!m_display) { 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."); "Games may run slowly, especially with larger windows.");
Display::setDriver(Display::Driver::QT); Display::setDriver(Display::Driver::QT);
m_display = std::unique_ptr<Display>(Display::create(this)); m_display = std::unique_ptr<Display>(Display::create(this));
@ -1126,7 +1126,7 @@ void Window::reloadAudioDriver() {
m_audioProcessor->setInput(m_controller); m_audioProcessor->setInput(m_controller);
m_audioProcessor->configure(m_config); m_audioProcessor->configure(m_config);
if (!m_audioProcessor->start()) { if (!m_audioProcessor->start()) {
LOG(QT, WARN) << "Failed to start audio processor"; qWarning() << "Failed to start audio processor";
} }
} }