Merge branch 'wheremyfoodat:master' into uwp_clean

This commit is contained in:
MoonPower
2026-04-01 22:50:54 +02:00
committed by GitHub
5 changed files with 99 additions and 6 deletions

View File

@@ -35,7 +35,9 @@ jobs:
- name: Clone and compile 3ds-examples
run: |
git clone --recursive https://github.com/devkitPro/3ds-examples tests/3ds-examples
make -C tests/3ds-examples
# The devkitpro docker image is outdated and cannot build 3ds-examples at the moment
# TODO: Reenable this when it's updated again
# make -C tests/3ds-examples
- name: Upload binaries
uses: actions/upload-artifact@v4

View File

@@ -108,6 +108,9 @@ struct EmulatorConfig {
std::filesystem::path defaultRomPath = "";
std::filesystem::path filePath;
static constexpr size_t maxRecentGames = 8;
std::vector<std::filesystem::path> recentlyPlayed;
// Frontend window settings
struct WindowSettings {
static constexpr int defaultX = 200;
@@ -132,6 +135,8 @@ struct EmulatorConfig {
void load();
void save();
void addToRecentGames(const std::filesystem::path& path);
static LanguageCodes languageCodeFromString(std::string inString);
static const char* languageCodeToString(LanguageCodes code);
};

View File

@@ -103,6 +103,7 @@ class MainWindow : public QMainWindow {
std::vector<EmulatorMessage> messageQueue;
QMenuBar* menuBar = nullptr;
QMenu* recentsMenu = nullptr;
InputMappings keyboardMappings;
ScreenWidget* screen;
AboutWindow* aboutWindow;
@@ -123,6 +124,8 @@ class MainWindow : public QMainWindow {
void emuThreadMainLoop();
void selectLuaFile();
void selectROM();
void loadROMFromPath(const std::filesystem::path& path);
void updateRecentsMenu();
void dumpDspFirmware();
void dumpRomFS();
void showAboutMenu();

View File

@@ -50,6 +50,23 @@ void EmulatorConfig::load() {
circlePadProEnabled = toml::find_or<toml::boolean>(general, "EnableCirclePadPro", true);
fastmemEnabled = toml::find_or<toml::boolean>(general, "EnableFastmem", enableFastmemDefault);
systemLanguage = languageCodeFromString(toml::find_or<std::string>(general, "SystemLanguage", "en"));
// Load recent games list
if (general.contains("RecentGames") && general.at("RecentGames").is_array()) {
const auto& recentsArray = general.at("RecentGames").as_array();
recentlyPlayed.clear();
for (const auto& item : recentsArray) {
if (item.is_string()) {
std::filesystem::path gamePath = toml::get<std::string>(item);
recentlyPlayed.push_back(gamePath);
if (recentlyPlayed.size() >= maxRecentGames) {
break;
}
}
}
}
}
}
@@ -189,6 +206,12 @@ void EmulatorConfig::save() {
data["General"]["EnableCirclePadPro"] = circlePadProEnabled;
data["General"]["EnableFastmem"] = fastmemEnabled;
toml::array recentsArray;
for (const auto& gamePath : recentlyPlayed) {
recentsArray.push_back(gamePath.string());
}
data["General"]["RecentGames"] = recentsArray;
data["Window"]["AppVersionOnWindow"] = windowSettings.showAppVersion;
data["Window"]["RememberWindowPosition"] = windowSettings.rememberPosition;
data["Window"]["WindowPosX"] = windowSettings.x;
@@ -286,3 +309,17 @@ const char* EmulatorConfig::languageCodeToString(LanguageCodes code) {
return codes[static_cast<u32>(code)];
}
}
void EmulatorConfig::addToRecentGames(const std::filesystem::path& path) {
// Remove path if it's already in the list
auto it = std::find(recentlyPlayed.begin(), recentlyPlayed.end(), path);
if (it != recentlyPlayed.end()) {
recentlyPlayed.erase(it);
}
recentlyPlayed.insert(recentlyPlayed.begin(), path);
// Limit how many games can be saved
if (recentlyPlayed.size() > maxRecentGames) {
recentlyPlayed.resize(maxRecentGames);
}
}

View File

@@ -53,6 +53,11 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
// Create and bind actions for them
auto loadGameAction = fileMenu->addAction(tr("Load game"));
recentsMenu = fileMenu->addMenu(tr("Recents"));
updateRecentsMenu();
fileMenu->addSeparator();
auto loadLuaAction = fileMenu->addAction(tr("Load Lua script"));
auto openAppFolderAction = fileMenu->addAction(tr("Open Panda3DS folder"));
@@ -140,6 +145,10 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
if (!emu->loadROM(romPath)) {
// For some reason just .c_str() doesn't show the proper path
Helpers::warn("Failed to load ROM file: %s", romPath.string().c_str());
} else {
emu->getConfig().addToRecentGames(romPath);
emu->getConfig().save();
updateRecentsMenu();
}
}
@@ -240,11 +249,48 @@ void MainWindow::selectROM() {
);
if (!path.isEmpty()) {
std::filesystem::path* p = new std::filesystem::path(path.toStdU16String());
loadROMFromPath(std::filesystem::path(path.toStdU16String()));
}
}
EmulatorMessage message{.type = MessageType::LoadROM};
message.path.p = p;
sendMessage(message);
void MainWindow::loadROMFromPath(const std::filesystem::path& path) {
std::filesystem::path* p = new std::filesystem::path(path);
EmulatorMessage message{.type = MessageType::LoadROM};
message.path.p = p;
sendMessage(message);
emu->getConfig().addToRecentGames(path);
emu->getConfig().save();
updateRecentsMenu();
}
void MainWindow::updateRecentsMenu() {
recentsMenu->clear();
const auto& recentGames = emu->getConfig().recentlyPlayed;
if (recentGames.empty()) {
// Add a disabled "No recent games" item
QAction* noRecentsAction = recentsMenu->addAction(tr("No recent games"));
noRecentsAction->setEnabled(false);
} else {
for (const auto& gamePath : recentGames) {
QString displayName = QString::fromStdU16String(gamePath.filename().u16string());
QAction* action = recentsMenu->addAction(displayName);
// Store the full path in the action's data, set tooltip to show full path
action->setData(QString::fromStdU16String(gamePath.u16string()));
action->setToolTip(QString::fromStdU16String(gamePath.u16string()));
connect(action, &QAction::triggered, this, [this, gamePath]() { loadROMFromPath(gamePath); });
}
recentsMenu->addSeparator();
QAction* clearAction = recentsMenu->addAction(tr("Clear recent games"));
connect(clearAction, &QAction::triggered, this, [this]() {
emu->getConfig().recentlyPlayed.clear();
emu->getConfig().save();
updateRecentsMenu();
});
}
}