mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-08 07:05:40 +12:00
Merge pull request #305 from wheremyfoodat/rhappy
Add file picker to Qt frontend
This commit is contained in:
commit
8d6c222db7
3 changed files with 67 additions and 14 deletions
|
@ -5,7 +5,9 @@
|
||||||
#include <QMenuBar>
|
#include <QMenuBar>
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
|
#include <atomic>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include "emulator.hpp"
|
#include "emulator.hpp"
|
||||||
#include "panda_qt/screen.hpp"
|
#include "panda_qt/screen.hpp"
|
||||||
|
@ -24,13 +26,19 @@ class MainWindow : public QMainWindow {
|
||||||
Emulator* emu = nullptr;
|
Emulator* emu = nullptr;
|
||||||
std::thread emuThread;
|
std::thread emuThread;
|
||||||
|
|
||||||
|
std::atomic<bool> appRunning = true; // Is the application itself running?
|
||||||
|
std::atomic<bool> needToLoadROM = false;
|
||||||
|
std::filesystem::path romToLoad = "";
|
||||||
|
|
||||||
|
ScreenWidget screen;
|
||||||
QComboBox* themeSelect = nullptr;
|
QComboBox* themeSelect = nullptr;
|
||||||
QMenuBar* menuBar = nullptr;
|
QMenuBar* menuBar = nullptr;
|
||||||
ScreenWidget screen;
|
|
||||||
|
|
||||||
Theme currentTheme;
|
Theme currentTheme;
|
||||||
void setTheme(Theme theme);
|
void setTheme(Theme theme);
|
||||||
void swapEmuBuffer();
|
void swapEmuBuffer();
|
||||||
|
void emuThreadMainLoop();
|
||||||
|
void selectROM();
|
||||||
|
|
||||||
// Tracks whether we are using an OpenGL-backed renderer or a Vulkan-backed renderer
|
// Tracks whether we are using an OpenGL-backed renderer or a Vulkan-backed renderer
|
||||||
bool usingGL = false;
|
bool usingGL = false;
|
||||||
|
|
|
@ -1,18 +1,28 @@
|
||||||
#include "panda_qt/main_window.hpp"
|
#include "panda_qt/main_window.hpp"
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent), screen(this) {
|
MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent), screen(this) {
|
||||||
setWindowTitle("Alber");
|
setWindowTitle("Alber");
|
||||||
// Enable drop events for loading ROMs
|
// Enable drop events for loading ROMs
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
resize(400, 240 * 2);
|
resize(800, 240 * 4);
|
||||||
screen.show();
|
screen.show();
|
||||||
|
|
||||||
|
appRunning = true;
|
||||||
|
|
||||||
// Set our menu bar up
|
// Set our menu bar up
|
||||||
menuBar = new QMenuBar(this);
|
menuBar = new QMenuBar(this);
|
||||||
setMenuBar(menuBar);
|
setMenuBar(menuBar);
|
||||||
|
|
||||||
auto pandaMenu = menuBar->addMenu(tr("PANDA"));
|
auto fileMenu = menuBar->addMenu(tr("File"));
|
||||||
auto pandaAction = pandaMenu->addAction(tr("panda..."));
|
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"));
|
||||||
|
auto aboutMenu = menuBar->addMenu(tr("About"));
|
||||||
|
|
||||||
// Set up theme selection
|
// Set up theme selection
|
||||||
setTheme(Theme::Dark);
|
setTheme(Theme::Dark);
|
||||||
|
@ -30,7 +40,7 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
|
||||||
emu->setOutputSize(screen.surfaceWidth, screen.surfaceHeight);
|
emu->setOutputSize(screen.surfaceWidth, screen.surfaceHeight);
|
||||||
|
|
||||||
// The emulator graphics context for the thread should be initialized in the emulator thread due to how GL contexts work
|
// The emulator graphics context for the thread should be initialized in the emulator thread due to how GL contexts work
|
||||||
emuThread = std::thread([&]() {
|
emuThread = std::thread([this]() {
|
||||||
const RendererType rendererType = emu->getConfig().rendererType;
|
const RendererType rendererType = emu->getConfig().rendererType;
|
||||||
usingGL = (rendererType == RendererType::OpenGL || rendererType == RendererType::Software || rendererType == RendererType::Null);
|
usingGL = (rendererType == RendererType::OpenGL || rendererType == RendererType::Software || rendererType == RendererType::Null);
|
||||||
usingVk = (rendererType == RendererType::Vulkan);
|
usingVk = (rendererType == RendererType::Vulkan);
|
||||||
|
@ -48,16 +58,29 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
|
||||||
Helpers::panic("Unsupported graphics backend for Qt frontend!");
|
Helpers::panic("Unsupported graphics backend for Qt frontend!");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = emu->loadROM("OoT.3ds");
|
emuThreadMainLoop();
|
||||||
if (!success) {
|
});
|
||||||
Helpers::panic("Failed to load ROM");
|
}
|
||||||
|
|
||||||
|
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 (true) {
|
emu->runFrame();
|
||||||
emu->runFrame();
|
swapEmuBuffer();
|
||||||
swapEmuBuffer();
|
}
|
||||||
}
|
|
||||||
});
|
// Unbind GL context if we're using GL, otherwise some setups seem to be unable to join this thread
|
||||||
|
if (usingGL) {
|
||||||
|
screen.getGLContext()->DoneCurrent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::swapEmuBuffer() {
|
void MainWindow::swapEmuBuffer() {
|
||||||
|
@ -68,8 +91,30 @@ 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
|
// Cleanup when the main window closes
|
||||||
MainWindow::~MainWindow() {
|
MainWindow::~MainWindow() {
|
||||||
|
appRunning = false; // Set our running atomic to false in order to make the emulator thread stop, and join it
|
||||||
|
|
||||||
|
if (emuThread.joinable()) {
|
||||||
|
emuThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
delete emu;
|
delete emu;
|
||||||
delete menuBar;
|
delete menuBar;
|
||||||
delete themeSelect;
|
delete themeSelect;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#ifdef PANDA3DS_ENABLE_OPENGL
|
#ifdef PANDA3DS_ENABLE_OPENGL
|
||||||
ScreenWidget::ScreenWidget(QWidget* parent) : QWidget(parent) {
|
ScreenWidget::ScreenWidget(QWidget* parent) : QWidget(parent) {
|
||||||
// Create a native window for use with our graphics API of choice
|
// Create a native window for use with our graphics API of choice
|
||||||
resize(400, 240 * 2);
|
resize(800, 240 * 4);
|
||||||
|
|
||||||
setAutoFillBackground(false);
|
setAutoFillBackground(false);
|
||||||
setAttribute(Qt::WA_NativeWindow, true);
|
setAttribute(Qt::WA_NativeWindow, true);
|
||||||
|
|
Loading…
Add table
Reference in a new issue