diff --git a/src/frontend/qt_sdl/EmuInstance.cpp b/src/frontend/qt_sdl/EmuInstance.cpp index 0d201a7c..0aa438ff 100644 --- a/src/frontend/qt_sdl/EmuInstance.cpp +++ b/src/frontend/qt_sdl/EmuInstance.cpp @@ -99,7 +99,7 @@ EmuInstance::~EmuInstance() { // TODO window cleanup and shit? - emuThread->emuStop(); + emuThread->emuExit(); emuThread->wait(); delete emuThread; @@ -165,6 +165,33 @@ void EmuInstance::osdAddMessage(unsigned int color, const char* fmt, ...) } +bool EmuInstance::emuIsActive() +{ + return emuThread->emuIsActive(); +} + +void EmuInstance::emuStop(StopReason reason) +{ + emuThread->emuStop(); + + switch (reason) + { + case StopReason::GBAModeNotSupported: + Log(LogLevel::Error, "!! GBA MODE NOT SUPPORTED\n"); + osdAddMessage(0xFFA0A0, "GBA mode not supported"); + break; + case StopReason::BadExceptionRegion: + osdAddMessage(0xFFA0A0, "Internal error"); + break; + case StopReason::PowerOff: + case StopReason::External: + osdAddMessage(0xFFC040, "Shutdown"); + default: + break; + } +} + + bool EmuInstance::usesOpenGL() { return globalCfg.GetBool("Screen.UseGL") || diff --git a/src/frontend/qt_sdl/EmuInstance.h b/src/frontend/qt_sdl/EmuInstance.h index c0d5dca6..8f5a6256 100644 --- a/src/frontend/qt_sdl/EmuInstance.h +++ b/src/frontend/qt_sdl/EmuInstance.h @@ -90,6 +90,9 @@ public: void osdAddMessage(unsigned int color, const char* fmt, ...); + bool emuIsActive(); + void emuStop(melonDS::Platform::StopReason reason); + bool usesOpenGL(); void initOpenGL(); void deinitOpenGL(); diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp index 8d4f098e..f907f258 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -32,8 +32,6 @@ using namespace melonDS; EmuSettingsDialog* EmuSettingsDialog::currentDlg = nullptr; -extern bool RunningSomething; - bool EmuSettingsDialog::needsReset = false; inline void EmuSettingsDialog::updateLastBIOSFolder(QString& filename) @@ -246,7 +244,7 @@ void EmuSettingsDialog::done(int r) if (modified) { - if (RunningSomething + if (emuInstance->emuIsActive() && QMessageBox::warning(this, "Reset necessary to apply changes", "The emulation will be reset for the changes to take place.", QMessageBox::Ok, QMessageBox::Cancel) != QMessageBox::Ok) diff --git a/src/frontend/qt_sdl/EmuThread.cpp b/src/frontend/qt_sdl/EmuThread.cpp index b27087b3..536643e4 100644 --- a/src/frontend/qt_sdl/EmuThread.cpp +++ b/src/frontend/qt_sdl/EmuThread.cpp @@ -55,18 +55,9 @@ #include "Savestate.h" #include "EmuInstance.h" -//#include "ArchiveUtil.h" -//#include "CameraManager.h" -//#include "CLI.h" - -// TODO: uniform variable spelling using namespace melonDS; -// TEMP -extern bool RunningSomething; -//extern MainWindow* mainWindow; - EmuThread::EmuThread(EmuInstance* inst, QObject* parent) : QThread(parent) { @@ -75,7 +66,7 @@ EmuThread::EmuThread(EmuInstance* inst, QObject* parent) : QThread(parent) EmuStatus = emuStatus_Exit; EmuRunning = emuStatus_Paused; EmuPauseStack = EmuPauseStackRunning; - RunningSomething = false; + emuActive = false; } void EmuThread::attachWindow(MainWindow* window) @@ -494,7 +485,7 @@ void EmuThread::emuRun() { EmuRunning = emuStatus_Running; EmuPauseStack = EmuPauseStackRunning; - RunningSomething = true; + emuActive = true; // checkme emit windowEmuStart(); @@ -538,6 +529,12 @@ void EmuThread::emuUnpause() } void EmuThread::emuStop() +{ + emuPause(); + emuActive = false; +} + +void EmuThread::emuExit() { EmuRunning = emuStatus_Exit; EmuPauseStack = EmuPauseStackRunning; @@ -558,7 +555,7 @@ bool EmuThread::emuIsRunning() bool EmuThread::emuIsActive() { - return (RunningSomething == 1); + return emuActive; } void EmuThread::updateRenderer() diff --git a/src/frontend/qt_sdl/EmuThread.h b/src/frontend/qt_sdl/EmuThread.h index 638c6f01..4e6f592f 100644 --- a/src/frontend/qt_sdl/EmuThread.h +++ b/src/frontend/qt_sdl/EmuThread.h @@ -60,6 +60,7 @@ public: void emuPause(); void emuUnpause(); void emuStop(); + void emuExit(); void emuFrameStep(); bool emuIsRunning(); @@ -108,6 +109,7 @@ private: EmuStatusKind PrevEmuStatus; EmuStatusKind EmuRunning; + bool emuActive; constexpr static int EmuPauseStackRunning = 0; constexpr static int EmuPauseStackPauseThreshold = 1; diff --git a/src/frontend/qt_sdl/FirmwareSettingsDialog.cpp b/src/frontend/qt_sdl/FirmwareSettingsDialog.cpp index 5a79391d..27bb8f4d 100644 --- a/src/frontend/qt_sdl/FirmwareSettingsDialog.cpp +++ b/src/frontend/qt_sdl/FirmwareSettingsDialog.cpp @@ -30,8 +30,6 @@ namespace Platform = melonDS::Platform; FirmwareSettingsDialog* FirmwareSettingsDialog::currentDlg = nullptr; -extern bool RunningSomething; - bool FirmwareSettingsDialog::needsReset = false; FirmwareSettingsDialog::FirmwareSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::FirmwareSettingsDialog) @@ -169,7 +167,7 @@ void FirmwareSettingsDialog::done(int r) if (modified) { - if (RunningSomething + if (emuInstance->emuIsActive() && QMessageBox::warning(this, "Reset necessary to apply changes", "The emulation will be reset for the changes to take place.", QMessageBox::Ok, QMessageBox::Cancel) != QMessageBox::Ok) diff --git a/src/frontend/qt_sdl/MPSettingsDialog.cpp b/src/frontend/qt_sdl/MPSettingsDialog.cpp index 957a8019..0b9c2a3c 100644 --- a/src/frontend/qt_sdl/MPSettingsDialog.cpp +++ b/src/frontend/qt_sdl/MPSettingsDialog.cpp @@ -34,8 +34,6 @@ MPSettingsDialog* MPSettingsDialog::currentDlg = nullptr; -extern bool RunningSomething; - MPSettingsDialog::MPSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::MPSettingsDialog) { diff --git a/src/frontend/qt_sdl/PathSettingsDialog.cpp b/src/frontend/qt_sdl/PathSettingsDialog.cpp index c9c4d0df..0e9abb09 100644 --- a/src/frontend/qt_sdl/PathSettingsDialog.cpp +++ b/src/frontend/qt_sdl/PathSettingsDialog.cpp @@ -34,8 +34,6 @@ namespace Platform = melonDS::Platform; PathSettingsDialog* PathSettingsDialog::currentDlg = nullptr; -extern bool RunningSomething; - bool PathSettingsDialog::needsReset = false; constexpr char errordialog[] = "melonDS cannot write to that directory."; @@ -97,7 +95,7 @@ void PathSettingsDialog::done(int r) if (modified) { - if (RunningSomething + if (emuInstance->emuIsActive() && QMessageBox::warning(this, "Reset necessary to apply changes", "The emulation will be reset for the changes to take place.", QMessageBox::Ok, QMessageBox::Cancel) != QMessageBox::Ok) diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 65f435da..f1af2935 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -63,22 +63,7 @@ namespace melonDS::Platform void SignalStop(StopReason reason, void* userdata) { EmuInstance* inst = (EmuInstance*)userdata; - emuStop(); - switch (reason) - { - case StopReason::GBAModeNotSupported: - Log(LogLevel::Error, "!! GBA MODE NOT SUPPORTED\n"); - //mainWindow->osdAddMessage(0xFFA0A0, "GBA mode not supported."); - break; - case StopReason::BadExceptionRegion: - //mainWindow->osdAddMessage(0xFFA0A0, "Internal error."); - break; - case StopReason::PowerOff: - case StopReason::External: - //mainWindow->osdAddMessage(0xFFC040, "Shutdown"); - default: - break; - } + inst->emuStop(reason); } diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.cpp b/src/frontend/qt_sdl/WifiSettingsDialog.cpp index d7ab5d8e..0b99216d 100644 --- a/src/frontend/qt_sdl/WifiSettingsDialog.cpp +++ b/src/frontend/qt_sdl/WifiSettingsDialog.cpp @@ -43,8 +43,6 @@ WifiSettingsDialog* WifiSettingsDialog::currentDlg = nullptr; bool WifiSettingsDialog::needsReset = false; -extern bool RunningSomething; - WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::WifiSettingsDialog) { diff --git a/src/frontend/qt_sdl/Window.cpp b/src/frontend/qt_sdl/Window.cpp index 01f9d49a..bda0df27 100644 --- a/src/frontend/qt_sdl/Window.cpp +++ b/src/frontend/qt_sdl/Window.cpp @@ -82,32 +82,62 @@ using namespace melonDS; -// TEMP -extern MainWindow* mainWindow; -//extern EmuThread* emuThread; -extern bool RunningSomething; -extern QString NdsRomMimeType; -extern QStringList NdsRomExtensions; -extern QString GbaRomMimeType; -extern QStringList GbaRomExtensions; -extern QStringList ArchiveMimeTypes; -extern QStringList ArchiveExtensions; -/*static bool FileExtensionInList(const QString& filename, const QStringList& extensions, Qt::CaseSensitivity cs); -static bool MimeTypeInList(const QMimeType& mimetype, const QStringList& superTypeNames); -static bool NdsRomByExtension(const QString& filename); -static bool GbaRomByExtension(const QString& filename); -static bool SupportedArchiveByExtension(const QString& filename); -static bool NdsRomByMimetype(const QMimeType& mimetype); -static bool GbaRomByMimetype(const QMimeType& mimetype); -static bool SupportedArchiveByMimetype(const QMimeType& mimetype); -static bool ZstdNdsRomByExtension(const QString& filename); -static bool ZstdGbaRomByExtension(const QString& filename); -static bool FileIsSupportedFiletype(const QString& filename, bool insideArchive);*/ + + extern CameraManager* camManager[2]; extern bool camStarted[2]; +QString NdsRomMimeType = "application/x-nintendo-ds-rom"; +QStringList NdsRomExtensions { ".nds", ".srl", ".dsi", ".ids" }; + +QString GbaRomMimeType = "application/x-gba-rom"; +QStringList GbaRomExtensions { ".gba", ".agb" }; + + +// This list of supported archive formats is based on libarchive(3) version 3.6.2 (2022-12-09). +QStringList ArchiveMimeTypes +{ +#ifdef ARCHIVE_SUPPORT_ENABLED + "application/zip", + "application/x-7z-compressed", + "application/vnd.rar", // *.rar + "application/x-tar", + + "application/x-compressed-tar", // *.tar.gz + "application/x-xz-compressed-tar", + "application/x-bzip-compressed-tar", + "application/x-lz4-compressed-tar", + "application/x-zstd-compressed-tar", + + "application/x-tarz", // *.tar.Z + "application/x-lzip-compressed-tar", + "application/x-lzma-compressed-tar", + "application/x-lrzip-compressed-tar", + "application/x-tzo", // *.tar.lzo +#endif +}; + +QStringList ArchiveExtensions +{ +#ifdef ARCHIVE_SUPPORT_ENABLED + ".zip", ".7z", ".rar", ".tar", + + ".tar.gz", ".tgz", + ".tar.xz", ".txz", + ".tar.bz2", ".tbz2", + ".tar.lz4", ".tlz4", + ".tar.zst", ".tzst", + + ".tar.Z", ".taz", + ".tar.lz", + ".tar.lzma", ".tlz", + ".tar.lrz", ".tlrz", + ".tar.lzo", ".tzo" +#endif +}; + // AAAAAAA static bool FileExtensionInList(const QString& filename, const QStringList& extensions, Qt::CaseSensitivity cs = Qt::CaseInsensitive) { @@ -1515,7 +1545,7 @@ void MainWindow::onImportSavefile() return; } - if (RunningSomething) + if (emuThread->emuIsActive()) { if (QMessageBox::warning(this, "melonDS", @@ -1553,7 +1583,7 @@ void MainWindow::onQuit() void MainWindow::onPause(bool checked) { - if (!RunningSomething) return; + if (!emuThread->emuIsActive()) return; if (checked) { @@ -1571,7 +1601,7 @@ void MainWindow::onPause(bool checked) void MainWindow::onReset() { - if (!RunningSomething) return; + if (!emuThread->emuIsActive()) return; emuThread->emuPause(); @@ -1585,7 +1615,7 @@ void MainWindow::onReset() void MainWindow::onStop() { - if (!RunningSomething) return; + if (!emuThread->emuIsActive()) return; emuThread->emuPause(); emuInstance->nds->Stop(); @@ -1593,7 +1623,7 @@ void MainWindow::onStop() void MainWindow::onFrameStep() { - if (!RunningSomething) return; + if (!emuThread->emuIsActive()) return; emuThread->emuFrameStep(); } @@ -1693,7 +1723,7 @@ void MainWindow::onEmuSettingsDialogFinished(int res) actCurrentGBACart->setText("GBA slot: " + emuInstance->gbaCartLabel()); - if (!RunningSomething) + if (!emuThread->emuIsActive()) actTitleManager->setEnabled(!globalCfg.GetString("DSi.NANDPath").empty()); } @@ -2049,7 +2079,7 @@ void MainWindow::onEmuStart() void MainWindow::onEmuStop() { - emuThread->emuPause(); + emuThread->emuStop(); for (int i = 0; i < 9; i++) { diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index e23fe0ec..1843aa5a 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -77,145 +77,61 @@ #include "CLI.h" -// TODO: uniform variable spelling using namespace melonDS; -QString NdsRomMimeType = "application/x-nintendo-ds-rom"; -QStringList NdsRomExtensions { ".nds", ".srl", ".dsi", ".ids" }; - -QString GbaRomMimeType = "application/x-gba-rom"; -QStringList GbaRomExtensions { ".gba", ".agb" }; QString* systemThemeName; -// This list of supported archive formats is based on libarchive(3) version 3.6.2 (2022-12-09). -QStringList ArchiveMimeTypes -{ -#ifdef ARCHIVE_SUPPORT_ENABLED - "application/zip", - "application/x-7z-compressed", - "application/vnd.rar", // *.rar - "application/x-tar", - "application/x-compressed-tar", // *.tar.gz - "application/x-xz-compressed-tar", - "application/x-bzip-compressed-tar", - "application/x-lz4-compressed-tar", - "application/x-zstd-compressed-tar", - - "application/x-tarz", // *.tar.Z - "application/x-lzip-compressed-tar", - "application/x-lzma-compressed-tar", - "application/x-lrzip-compressed-tar", - "application/x-tzo", // *.tar.lzo -#endif -}; - -QStringList ArchiveExtensions -{ -#ifdef ARCHIVE_SUPPORT_ENABLED - ".zip", ".7z", ".rar", ".tar", - - ".tar.gz", ".tgz", - ".tar.xz", ".txz", - ".tar.bz2", ".tbz2", - ".tar.lz4", ".tlz4", - ".tar.zst", ".tzst", - - ".tar.Z", ".taz", - ".tar.lz", - ".tar.lzma", ".tlz", - ".tar.lrz", ".tlrz", - ".tar.lzo", ".tzo" -#endif -}; QString emuDirectory; -bool RunningSomething; - //MainWindow* mainWindow; //EmuThread* emuThread; EmuInstance* testinst; +const int kMaxEmuInstances = 16; +EmuInstance* emuInstances[kMaxEmuInstances]; + CameraManager* camManager[2]; bool camStarted[2]; - - - -static bool FileExtensionInList(const QString& filename, const QStringList& extensions, Qt::CaseSensitivity cs = Qt::CaseInsensitive) +bool createEmuInstance() { - return std::any_of(extensions.cbegin(), extensions.cend(), [&](const auto& ext) { - return filename.endsWith(ext, cs); - }); + int id = -1; + for (int i = 0; i < kMaxEmuInstances; i++) + { + if (!emuInstances[i]) + { + id = i; + break; + } + } + + if (id == -1) + return false; + + auto inst = new EmuInstance(id); + emuInstances[id] = inst; + + return true; } -static bool MimeTypeInList(const QMimeType& mimetype, const QStringList& superTypeNames) +void deleteEmuInstance(int id) { - return std::any_of(superTypeNames.cbegin(), superTypeNames.cend(), [&](const auto& superTypeName) { - return mimetype.inherits(superTypeName); - }); + auto inst = emuInstances[id]; + if (!inst) return; + + delete inst; + emuInstances[id] = nullptr; } - -static bool NdsRomByExtension(const QString& filename) +void deleteAllEmuInstances() { - return FileExtensionInList(filename, NdsRomExtensions); + for (int i = 0; i < kMaxEmuInstances; i++) + deleteEmuInstance(i); } -static bool GbaRomByExtension(const QString& filename) -{ - return FileExtensionInList(filename, GbaRomExtensions); -} - -static bool SupportedArchiveByExtension(const QString& filename) -{ - return FileExtensionInList(filename, ArchiveExtensions); -} - - -static bool NdsRomByMimetype(const QMimeType& mimetype) -{ - return mimetype.inherits(NdsRomMimeType); -} - -static bool GbaRomByMimetype(const QMimeType& mimetype) -{ - return mimetype.inherits(GbaRomMimeType); -} - -static bool SupportedArchiveByMimetype(const QMimeType& mimetype) -{ - return MimeTypeInList(mimetype, ArchiveMimeTypes); -} - -static bool ZstdNdsRomByExtension(const QString& filename) -{ - return filename.endsWith(".zst", Qt::CaseInsensitive) && - NdsRomByExtension(filename.left(filename.size() - 4)); -} - -static bool ZstdGbaRomByExtension(const QString& filename) -{ - return filename.endsWith(".zst", Qt::CaseInsensitive) && - GbaRomByExtension(filename.left(filename.size() - 4)); -} - -static bool FileIsSupportedFiletype(const QString& filename, bool insideArchive = false) -{ - if (ZstdNdsRomByExtension(filename) || ZstdGbaRomByExtension(filename)) - return true; - - if (NdsRomByExtension(filename) || GbaRomByExtension(filename) || SupportedArchiveByExtension(filename)) - return true; - - const auto matchmode = insideArchive ? QMimeDatabase::MatchExtension : QMimeDatabase::MatchDefault; - const QMimeType mimetype = QMimeDatabase().mimeTypeForFile(filename, matchmode); - return NdsRomByMimetype(mimetype) || GbaRomByMimetype(mimetype) || SupportedArchiveByMimetype(mimetype); -} - - void pathInit() { @@ -254,12 +170,6 @@ void pathInit() } -void emuStop() -{ - RunningSomething = false; - - //emit emuThread->windowEmuStop(); -} MelonApplication::MelonApplication(int& argc, char** argv) : QApplication(argc, argv) @@ -291,6 +201,9 @@ int main(int argc, char** argv) { srand(time(nullptr)); + for (int i = 0; i < kMaxEmuInstances; i++) + emuInstances[i] = nullptr; + qputenv("QT_SCALE_FACTOR", "1"); #if QT_VERSION_MAJOR == 6 && defined(__WIN32__)