From c648b6c62d90b590d8b59403cf1c30411b7672fd Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Mon, 2 Oct 2023 00:59:14 +0300 Subject: [PATCH] [Qt] Add file picker --- include/panda_qt/main_window.hpp | 5 +++ src/panda_qt/main_window.cpp | 55 ++++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/include/panda_qt/main_window.hpp b/include/panda_qt/main_window.hpp index 4e36dae5..9f9f1014 100644 --- a/include/panda_qt/main_window.hpp +++ b/include/panda_qt/main_window.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "emulator.hpp" #include "panda_qt/screen.hpp" @@ -26,6 +27,8 @@ class MainWindow : public QMainWindow { std::thread emuThread; std::atomic appRunning = true; // Is the application itself running? + std::atomic needToLoadROM = false; + std::filesystem::path romToLoad = ""; ScreenWidget screen; QComboBox* themeSelect = nullptr; @@ -34,6 +37,8 @@ class MainWindow : public QMainWindow { Theme currentTheme; void setTheme(Theme theme); void swapEmuBuffer(); + void emuThreadMainLoop(); + void selectROM(); // Tracks whether we are using an OpenGL-backed renderer or a Vulkan-backed renderer bool usingGL = false; diff --git a/src/panda_qt/main_window.cpp b/src/panda_qt/main_window.cpp index 9f99a2b7..998f711e 100644 --- a/src/panda_qt/main_window.cpp +++ b/src/panda_qt/main_window.cpp @@ -1,5 +1,8 @@ #include "panda_qt/main_window.hpp" +#include +#include + MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent), screen(this) { setWindowTitle("Alber"); // Enable drop events for loading ROMs @@ -15,6 +18,7 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent) auto fileMenu = menuBar->addMenu(tr("File")); auto pandaAction = fileMenu->addAction(tr("panda...")); + connect(pandaAction, &QAction::triggered, this, &MainWindow::selectROM); auto emulationMenu = menuBar->addMenu(tr("Emulation")); auto helpMenu = menuBar->addMenu(tr("Help")); @@ -54,16 +58,28 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent) Helpers::panic("Unsupported graphics backend for Qt frontend!"); } - bool success = emu->loadROM("OoT.3ds"); - if (!success) { - Helpers::panic("Failed to load ROM"); + // Enter our emulator main loop + emuThreadMainLoop(); + }); +} + +// This is the main loop that the emulator thread runs after being initialized +void MainWindow::emuThreadMainLoop() { + while (appRunning) { + if (needToLoadROM.load()) { + bool success = emu->loadROM(romToLoad); + if (!success) { + printf("Failed to load ROM"); + } + + needToLoadROM.store(false, std::memory_order::seq_cst); } - while (appRunning) { - emu->runFrame(); - swapEmuBuffer(); - } - }); + emu->runFrame(); + swapEmuBuffer(); + } + + printf("Emulator thread returned"); } void MainWindow::swapEmuBuffer() { @@ -74,10 +90,31 @@ void MainWindow::swapEmuBuffer() { } } +void MainWindow::selectROM() { + // Are we already waiting for a ROM to be loaded? Then complain about it! + if (needToLoadROM.load()) { + QMessageBox::warning(this, tr("Already loading ROM"), tr("Panda3DS is already busy loading a ROM, please wait")); + return; + } + + auto path = + QFileDialog::getOpenFileName(this, tr("Select 3DS ROM to load"), "", tr("Nintendo 3DS ROMs (*.3ds *.cci *.cxi *.app *.3dsx *.elf *.axf)")); + + if (!path.isEmpty()) { + romToLoad = path.toStdU16String(); + needToLoadROM.store(true, std::memory_order_seq_cst); + } +} + // Cleanup when the main window closes MainWindow::~MainWindow() { + printf("Destroying window class\n"); appRunning = false; // Set our running atomic to false in order to make the emulator thread stop, and join it - emuThread.join(); + + if (emuThread.joinable()) { + emuThread.join(); + } + printf("Emu thread joined!\n"); delete emu; delete menuBar;