From 317b91533b1547e9cb4e427a468da5d1d576ba39 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 19 Nov 2024 00:33:39 +0100 Subject: [PATCH] avoid spawning message boxes from the emuthread --- src/frontend/qt_sdl/EmuInstance.cpp | 37 ++++++++++-------- src/frontend/qt_sdl/EmuInstance.h | 8 ++-- src/frontend/qt_sdl/EmuThread.cpp | 28 +++++++++----- src/frontend/qt_sdl/EmuThread.h | 9 +++-- src/frontend/qt_sdl/Window.cpp | 58 ++++++++++++++++++++++------- 5 files changed, 94 insertions(+), 46 deletions(-) diff --git a/src/frontend/qt_sdl/EmuInstance.cpp b/src/frontend/qt_sdl/EmuInstance.cpp index f690bdb8..309abe66 100644 --- a/src/frontend/qt_sdl/EmuInstance.cpp +++ b/src/frontend/qt_sdl/EmuInstance.cpp @@ -29,7 +29,6 @@ #include #include -#include #include #ifdef ARCHIVE_SUPPORT_ENABLED @@ -1457,16 +1456,22 @@ void EmuInstance::reset() } -bool EmuInstance::bootToMenu() +bool EmuInstance::bootToMenu(QString& errorstr) { // Keep whatever cart is in the console, if any. if (!updateConsole()) + { // Try to update the console, but keep the existing cart. If that fails... + errorstr = "Failed to boot the firmware."; return false; + } // BIOS and firmware files are loaded, patched, and installed in UpdateConsole if (nds->NeedsDirectBoot()) + { + errorstr = "This firmware is not bootable."; return false; + } initFirmwareSaveManager(); nds->Reset(); @@ -1843,7 +1848,7 @@ QString EmuInstance::getSavErrorString(std::string& filepath, bool gba) return QString::fromStdString(err1); } -bool EmuInstance::loadROM(QStringList filepath, bool reset) +bool EmuInstance::loadROM(QStringList filepath, bool reset, QString& errorstr) { unique_ptr filedata = nullptr; u32 filelen; @@ -1852,7 +1857,7 @@ bool EmuInstance::loadROM(QStringList filepath, bool reset) if (!loadROMData(filepath, filedata, filelen, basepath, romname)) { - QMessageBox::critical(mainWindow, "melonDS", "Failed to load the DS ROM."); + errorstr = "Failed to load the DS ROM."; return false; } @@ -1874,7 +1879,7 @@ bool EmuInstance::loadROM(QStringList filepath, bool reset) { if (!Platform::CheckFileWritable(origsav)) { - QMessageBox::critical(mainWindow, "melonDS", getSavErrorString(origsav, false)); + errorstr = getSavErrorString(origsav, false); return false; } @@ -1882,7 +1887,7 @@ bool EmuInstance::loadROM(QStringList filepath, bool reset) } else if (!Platform::CheckFileWritable(savname)) { - QMessageBox::critical(mainWindow, "melonDS", getSavErrorString(savname, false)); + errorstr = getSavErrorString(savname, false); return false; } @@ -1909,7 +1914,7 @@ bool EmuInstance::loadROM(QStringList filepath, bool reset) if (!cart) { // If we couldn't parse the ROM... - QMessageBox::critical(mainWindow, "melonDS", "Failed to load the DS ROM."); + errorstr = "Failed to load the DS ROM."; return false; } @@ -1920,7 +1925,7 @@ bool EmuInstance::loadROM(QStringList filepath, bool reset) if (!updateConsole()) { - QMessageBox::critical(mainWindow, "melonDS", "Failed to load the DS ROM."); + errorstr = "Failed to load the DS ROM."; return false; } @@ -1996,11 +2001,11 @@ QString EmuInstance::cartLabel() } -bool EmuInstance::loadGBAROM(QStringList filepath) +bool EmuInstance::loadGBAROM(QStringList filepath, QString& errorstr) { if (consoleType == 1) { - QMessageBox::critical(mainWindow, "melonDS", "The DSi doesn't have a GBA slot."); + errorstr = "The DSi doesn't have a GBA slot."; return false; } @@ -2011,7 +2016,7 @@ bool EmuInstance::loadGBAROM(QStringList filepath) if (!loadROMData(filepath, filedata, filelen, basepath, romname)) { - QMessageBox::critical(mainWindow, "melonDS", "Failed to load the GBA ROM."); + errorstr = "Failed to load the GBA ROM."; return false; } @@ -2033,7 +2038,7 @@ bool EmuInstance::loadGBAROM(QStringList filepath) { if (!Platform::CheckFileWritable(origsav)) { - QMessageBox::critical(mainWindow, "melonDS", getSavErrorString(origsav, true)); + errorstr = getSavErrorString(origsav, true); return false; } @@ -2041,7 +2046,7 @@ bool EmuInstance::loadGBAROM(QStringList filepath) } else if (!Platform::CheckFileWritable(savname)) { - QMessageBox::critical(mainWindow, "melonDS", getSavErrorString(savname, true)); + errorstr = getSavErrorString(savname, true); return false; } @@ -2061,7 +2066,7 @@ bool EmuInstance::loadGBAROM(QStringList filepath) auto cart = GBACart::ParseROM(std::move(filedata), filelen, std::move(savedata), savelen, this); if (!cart) { - QMessageBox::critical(mainWindow, "melonDS", "Failed to load the GBA ROM."); + errorstr = "Failed to load the GBA ROM."; return false; } @@ -2080,14 +2085,14 @@ bool EmuInstance::loadGBAROM(QStringList filepath) return true; } -void EmuInstance::loadGBAAddon(int type) +void EmuInstance::loadGBAAddon(int type, QString& errorstr) { if (consoleType == 1) return; auto cart = GBACart::LoadAddon(type, this); if (!cart) { - QMessageBox::critical(mainWindow, "melonDS", "Failed to load the GBA addon."); + errorstr = "Failed to load the GBA addon."; return; } diff --git a/src/frontend/qt_sdl/EmuInstance.h b/src/frontend/qt_sdl/EmuInstance.h index 35943492..48e4e5b9 100644 --- a/src/frontend/qt_sdl/EmuInstance.h +++ b/src/frontend/qt_sdl/EmuInstance.h @@ -182,7 +182,7 @@ private: std::optional loadSDCard(const std::string& key) noexcept; void setBatteryLevels(); void reset(); - bool bootToMenu(); + bool bootToMenu(QString& errorstr); melonDS::u32 decompressROM(const melonDS::u8* inContent, const melonDS::u32 inSize, std::unique_ptr& outContent); void clearBackupState(); std::pair, std::string> generateDefaultFirmware(); @@ -191,13 +191,13 @@ private: bool loadROMData(const QStringList& filepath, std::unique_ptr& filedata, melonDS::u32& filelen, std::string& basepath, std::string& romname) noexcept; QString getSavErrorString(std::string& filepath, bool gba); - bool loadROM(QStringList filepath, bool reset); + bool loadROM(QStringList filepath, bool reset, QString& errorstr); void ejectCart(); bool cartInserted(); QString cartLabel(); - bool loadGBAROM(QStringList filepath); - void loadGBAAddon(int type); + bool loadGBAROM(QStringList filepath, QString& errorstr); + void loadGBAAddon(int type, QString& errorstr); void ejectGBACart(); bool gbaCartInserted(); QString gbaAddonName(int addon); diff --git a/src/frontend/qt_sdl/EmuThread.cpp b/src/frontend/qt_sdl/EmuThread.cpp index a7feffce..88e20238 100644 --- a/src/frontend/qt_sdl/EmuThread.cpp +++ b/src/frontend/qt_sdl/EmuThread.cpp @@ -577,7 +577,7 @@ void EmuThread::handleMessages() case msg_BootROM: msgResult = 0; - if (!emuInstance->loadROM(msg.param.value(), true)) + if (!emuInstance->loadROM(msg.param.value(), true, msgError)) break; assert(emuInstance->nds != nullptr); @@ -587,7 +587,7 @@ void EmuThread::handleMessages() case msg_BootFirmware: msgResult = 0; - if (!emuInstance->bootToMenu()) + if (!emuInstance->bootToMenu(msgError)) break; assert(emuInstance->nds != nullptr); @@ -597,7 +597,7 @@ void EmuThread::handleMessages() case msg_InsertCart: msgResult = 0; - if (!emuInstance->loadROM(msg.param.value(), false)) + if (!emuInstance->loadROM(msg.param.value(), false, msgError)) break; msgResult = 1; @@ -609,7 +609,7 @@ void EmuThread::handleMessages() case msg_InsertGBACart: msgResult = 0; - if (!emuInstance->loadGBAROM(msg.param.value())) + if (!emuInstance->loadGBAROM(msg.param.value(), msgError)) break; msgResult = 1; @@ -617,7 +617,7 @@ void EmuThread::handleMessages() case msg_InsertGBAAddon: msgResult = 0; - emuInstance->loadGBAAddon(msg.param.value()); + emuInstance->loadGBAAddon(msg.param.value(), msgError); msgResult = 1; break; @@ -753,36 +753,45 @@ bool EmuThread::emuIsActive() return emuActive; } -int EmuThread::bootROM(const QStringList& filename) +int EmuThread::bootROM(const QStringList& filename, QString& errorstr) { sendMessage({.type = msg_BootROM, .param = filename}); waitMessage(); if (!msgResult) + { + errorstr = msgError; return msgResult; + } sendMessage(msg_EmuRun); waitMessage(); + errorstr = ""; return msgResult; } -int EmuThread::bootFirmware() +int EmuThread::bootFirmware(QString& errorstr) { sendMessage(msg_BootFirmware); waitMessage(); if (!msgResult) + { + errorstr = msgError; return msgResult; + } sendMessage(msg_EmuRun); waitMessage(); + errorstr = ""; return msgResult; } -int EmuThread::insertCart(const QStringList& filename, bool gba) +int EmuThread::insertCart(const QStringList& filename, bool gba, QString& errorstr) { MessageType msgtype = gba ? msg_InsertGBACart : msg_InsertCart; sendMessage({.type = msgtype, .param = filename}); waitMessage(); + errorstr = msgResult ? "" : msgError; return msgResult; } @@ -792,10 +801,11 @@ void EmuThread::ejectCart(bool gba) waitMessage(); } -int EmuThread::insertGBAAddon(int type) +int EmuThread::insertGBAAddon(int type, QString& errorstr) { sendMessage({.type = msg_InsertGBAAddon, .param = type}); waitMessage(); + errorstr = msgResult ? "" : msgError; return msgResult; } diff --git a/src/frontend/qt_sdl/EmuThread.h b/src/frontend/qt_sdl/EmuThread.h index 9fa95f3e..61212553 100644 --- a/src/frontend/qt_sdl/EmuThread.h +++ b/src/frontend/qt_sdl/EmuThread.h @@ -111,11 +111,11 @@ public: void emuFrameStep(); void emuReset(); - int bootROM(const QStringList& filename); - int bootFirmware(); - int insertCart(const QStringList& filename, bool gba); + int bootROM(const QStringList& filename, QString& errorstr); + int bootFirmware(QString& errorstr); + int insertCart(const QStringList& filename, bool gba, QString& errorstr); void ejectCart(bool gba); - int insertGBAAddon(int type); + int insertGBAAddon(int type, QString& errorstr); int saveState(const QString& filename); int loadState(const QString& filename); @@ -179,6 +179,7 @@ private: int emuPauseStack; int msgResult = 0; + QString msgError; QMutex msgMutex; QSemaphore msgSemaphore; diff --git a/src/frontend/qt_sdl/Window.cpp b/src/frontend/qt_sdl/Window.cpp index 71e4f15a..a80b385c 100644 --- a/src/frontend/qt_sdl/Window.cpp +++ b/src/frontend/qt_sdl/Window.cpp @@ -986,10 +986,12 @@ void MainWindow::dropEvent(QDropEvent* event) isNdsRom |= ZstdNdsRomByExtension(filename); isGbaRom |= ZstdGbaRomByExtension(filename); + QString errorstr; if (isNdsRom) { - if (!emuThread->bootROM(file)) + if (!emuThread->bootROM(file, errorstr)) { + QMessageBox::critical(this, "melonDS", errorstr); return; } @@ -1002,8 +1004,9 @@ void MainWindow::dropEvent(QDropEvent* event) } else if (isGbaRom) { - if (!emuThread->insertCart(file, true)) + if (!emuThread->insertCart(file, true, errorstr)) { + QMessageBox::critical(this, "melonDS", errorstr); return; } @@ -1071,6 +1074,8 @@ bool MainWindow::verifySetup() bool MainWindow::preloadROMs(QStringList file, QStringList gbafile, bool boot) { + QString errorstr; + if (file.isEmpty() && gbafile.isEmpty()) return false; @@ -1082,8 +1087,11 @@ bool MainWindow::preloadROMs(QStringList file, QStringList gbafile, bool boot) bool gbaloaded = false; if (!gbafile.isEmpty()) { - if (!emuThread->insertCart(gbafile, true)) + if (!emuThread->insertCart(gbafile, true, errorstr)) + { + QMessageBox::critical(this, "melonDS", errorstr); return false; + } gbaloaded = true; } @@ -1093,13 +1101,19 @@ bool MainWindow::preloadROMs(QStringList file, QStringList gbafile, bool boot) { if (boot) { - if (!emuThread->bootROM(file)) + if (!emuThread->bootROM(file, errorstr)) + { + QMessageBox::critical(this, "melonDS", errorstr); return false; + } } else { - if (!emuThread->insertCart(file, false)) + if (!emuThread->insertCart(file, false, errorstr)) + { + QMessageBox::critical(this, "melonDS", errorstr); return false; + } } recentFileList.removeAll(file.join("|")); @@ -1109,8 +1123,11 @@ bool MainWindow::preloadROMs(QStringList file, QStringList gbafile, bool boot) } else if (boot) { - if (!emuThread->bootFirmware()) + if (!emuThread->bootFirmware(errorstr)) + { + QMessageBox::critical(this, "melonDS", errorstr); return false; + } } updateCartInserted(false); @@ -1308,8 +1325,10 @@ void MainWindow::onOpenFile() if (file.isEmpty()) return; - if (!emuThread->bootROM(file)) + QString errorstr; + if (!emuThread->bootROM(file, errorstr)) { + QMessageBox::critical(this, "melonDS", errorstr); return; } @@ -1419,8 +1438,10 @@ void MainWindow::onClickRecentFile() if (file.isEmpty()) return; - if (!emuThread->bootROM(file)) + QString errorstr; + if (!emuThread->bootROM(file, errorstr)) { + QMessageBox::critical(this, "melonDS", errorstr); return; } @@ -1436,9 +1457,10 @@ void MainWindow::onBootFirmware() if (!verifySetup()) return; - if (!emuThread->bootFirmware()) + QString errorstr; + if (!emuThread->bootFirmware(errorstr)) { - QMessageBox::critical(this, "melonDS", "This firmware is not bootable."); + QMessageBox::critical(this, "melonDS", errorstr); return; } } @@ -1449,8 +1471,10 @@ void MainWindow::onInsertCart() if (file.isEmpty()) return; - if (!emuThread->insertCart(file, false)) + QString errorstr; + if (!emuThread->insertCart(file, false, errorstr)) { + QMessageBox::critical(this, "melonDS", errorstr); return; } @@ -1469,8 +1493,10 @@ void MainWindow::onInsertGBACart() if (file.isEmpty()) return; - if (!emuThread->insertCart(file, true)) + QString errorstr; + if (!emuThread->insertCart(file, true, errorstr)) { + QMessageBox::critical(this, "melonDS", errorstr); return; } @@ -1482,7 +1508,13 @@ void MainWindow::onInsertGBAAddon() QAction* act = (QAction*)sender(); int type = act->data().toInt(); - emuThread->insertGBAAddon(type); + QString errorstr; + if (!emuThread->insertGBAAddon(type, errorstr)) + { + QMessageBox::critical(this, "melonDS", errorstr); + return; + } + updateCartInserted(true); }