From 75663d0601e4920b8164e810f76679d27e894867 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 21 Jan 2024 22:27:04 +0200 Subject: [PATCH] More app folder utilities --- include/emulator.hpp | 2 ++ src/emulator.cpp | 39 ++++++++++++++++++++---------------- src/panda_qt/main_window.cpp | 11 ++++++++-- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/include/emulator.hpp b/include/emulator.hpp index f45374253..da12c1bdc 100644 --- a/include/emulator.hpp +++ b/include/emulator.hpp @@ -128,6 +128,8 @@ class Emulator { std::filesystem::path getConfigPath(); std::filesystem::path getAndroidAppPath(); + // Get the root path for the emulator's app data + std::filesystem::path getAppDataRoot(); std::span getSMDH(); }; diff --git a/src/emulator.cpp b/src/emulator.cpp index e94170a28..673e0ebc0 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -117,25 +117,16 @@ void Emulator::runFrame() { } } -bool Emulator::loadROM(const std::filesystem::path& path) { - // Reset the emulator if we've already loaded a ROM - if (romType != ROMType::None) { - reset(ReloadOption::NoReload); - } - - // Reset whatever state needs to be reset before loading a new ROM - memory.loadedCXI = std::nullopt; - memory.loaded3DSX = std::nullopt; - - // Get path for saving files (AppData on Windows, /home/user/.local/share/ApplicationName on Linux, etc) - // Inside that path, we be use a game-specific folder as well. Eg if we were loading a ROM called PenguinDemo.3ds, the savedata would be in - // %APPDATA%/Alber/PenguinDemo/SaveData on Windows, and so on. We do this because games save data in their own filesystem on the cart. - // If the portable build setting is enabled, then those saves go in the executable directory instead +// Get path for saving files (AppData on Windows, /home/user/.local/share/ApplicationName on Linux, etc) +// Inside that path, we be use a game-specific folder as well. Eg if we were loading a ROM called PenguinDemo.3ds, the savedata would be in +// %APPDATA%/Alber/PenguinDemo/SaveData on Windows, and so on. We do this because games save data in their own filesystem on the cart. +// If the portable build setting is enabled, then those saves go in the executable directory instead +std::filesystem::path Emulator::getAppDataRoot() { std::filesystem::path appDataPath; - #ifdef __ANDROID__ +#ifdef __ANDROID__ appDataPath = getAndroidAppPath(); - #else +#else char* appData; if (!config.usePortableBuild) { appData = SDL_GetPrefPath(nullptr, "Alber"); @@ -145,8 +136,22 @@ bool Emulator::loadROM(const std::filesystem::path& path) { appDataPath = std::filesystem::path(appData) / "Emulator Files"; } SDL_free(appData); - #endif +#endif + + return appDataPath; +} + +bool Emulator::loadROM(const std::filesystem::path& path) { + // Reset the emulator if we've already loaded a ROM + if (romType != ROMType::None) { + reset(ReloadOption::NoReload); + } + + // Reset whatever state needs to be reset before loading a new ROM + memory.loadedCXI = std::nullopt; + memory.loaded3DSX = std::nullopt; + const std::filesystem::path appDataPath = getAppDataRoot(); const std::filesystem::path dataPath = appDataPath / path.filename().stem(); const std::filesystem::path aesKeysPath = appDataPath / "sysdata" / "aes_keys.txt"; IOFile::setAppDataDir(dataPath); diff --git a/src/panda_qt/main_window.cpp b/src/panda_qt/main_window.cpp index e390aa44b..5c6611194 100644 --- a/src/panda_qt/main_window.cpp +++ b/src/panda_qt/main_window.cpp @@ -1,6 +1,8 @@ #include "panda_qt/main_window.hpp" +#include #include +#include #include #include @@ -26,8 +28,14 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent) // Create and bind actions for them auto loadGameAction = fileMenu->addAction(tr("Load game")); auto loadLuaAction = fileMenu->addAction(tr("Load Lua script")); + auto openAppFolderAction = fileMenu->addAction(tr("Open Panda3DS folder")); + connect(loadGameAction, &QAction::triggered, this, &MainWindow::selectROM); connect(loadLuaAction, &QAction::triggered, this, &MainWindow::selectLuaFile); + connect(openAppFolderAction, &QAction::triggered, this, [this]() { + QString path = QString::fromStdU16String(emu->getAppDataRoot().u16string()); + QDesktopServices::openUrl(QUrl::fromLocalFile(path)); + }); auto pauseAction = emulationMenu->addAction(tr("Pause")); auto resumeAction = emulationMenu->addAction(tr("Resume")); @@ -194,8 +202,7 @@ void MainWindow::dumpRomFS() { return; } std::filesystem::path path(folder.toStdU16String()); - - // TODO: This might break if the game accesses RomFS while we're dumping, we should move it to the emulator thread when we've got a message queue going + messageQueueMutex.lock(); RomFS::DumpingResult res = emu->dumpRomFS(path); messageQueueMutex.unlock();