Skip to content

Commit 6be36b2

Browse files
authored
Merge branch 'wheremyfoodat:master' into uwp_clean
2 parents 8299059 + 944b989 commit 6be36b2

File tree

5 files changed

+99
-6
lines changed

5 files changed

+99
-6
lines changed

.github/workflows/Test_Build.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ jobs:
3535
- name: Clone and compile 3ds-examples
3636
run: |
3737
git clone --recursive https://github.com/devkitPro/3ds-examples tests/3ds-examples
38-
make -C tests/3ds-examples
38+
# The devkitpro docker image is outdated and cannot build 3ds-examples at the moment
39+
# TODO: Reenable this when it's updated again
40+
# make -C tests/3ds-examples
3941
4042
- name: Upload binaries
4143
uses: actions/upload-artifact@v4

include/config.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ struct EmulatorConfig {
108108
std::filesystem::path defaultRomPath = "";
109109
std::filesystem::path filePath;
110110

111+
static constexpr size_t maxRecentGames = 8;
112+
std::vector<std::filesystem::path> recentlyPlayed;
113+
111114
// Frontend window settings
112115
struct WindowSettings {
113116
static constexpr int defaultX = 200;
@@ -132,6 +135,8 @@ struct EmulatorConfig {
132135
void load();
133136
void save();
134137

138+
void addToRecentGames(const std::filesystem::path& path);
139+
135140
static LanguageCodes languageCodeFromString(std::string inString);
136141
static const char* languageCodeToString(LanguageCodes code);
137142
};

include/panda_qt/main_window.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class MainWindow : public QMainWindow {
103103
std::vector<EmulatorMessage> messageQueue;
104104

105105
QMenuBar* menuBar = nullptr;
106+
QMenu* recentsMenu = nullptr;
106107
InputMappings keyboardMappings;
107108
ScreenWidget* screen;
108109
AboutWindow* aboutWindow;
@@ -123,6 +124,8 @@ class MainWindow : public QMainWindow {
123124
void emuThreadMainLoop();
124125
void selectLuaFile();
125126
void selectROM();
127+
void loadROMFromPath(const std::filesystem::path& path);
128+
void updateRecentsMenu();
126129
void dumpDspFirmware();
127130
void dumpRomFS();
128131
void showAboutMenu();

src/config.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,23 @@ void EmulatorConfig::load() {
5050
circlePadProEnabled = toml::find_or<toml::boolean>(general, "EnableCirclePadPro", true);
5151
fastmemEnabled = toml::find_or<toml::boolean>(general, "EnableFastmem", enableFastmemDefault);
5252
systemLanguage = languageCodeFromString(toml::find_or<std::string>(general, "SystemLanguage", "en"));
53+
54+
// Load recent games list
55+
if (general.contains("RecentGames") && general.at("RecentGames").is_array()) {
56+
const auto& recentsArray = general.at("RecentGames").as_array();
57+
recentlyPlayed.clear();
58+
59+
for (const auto& item : recentsArray) {
60+
if (item.is_string()) {
61+
std::filesystem::path gamePath = toml::get<std::string>(item);
62+
63+
recentlyPlayed.push_back(gamePath);
64+
if (recentlyPlayed.size() >= maxRecentGames) {
65+
break;
66+
}
67+
}
68+
}
69+
}
5370
}
5471
}
5572

@@ -189,6 +206,12 @@ void EmulatorConfig::save() {
189206
data["General"]["EnableCirclePadPro"] = circlePadProEnabled;
190207
data["General"]["EnableFastmem"] = fastmemEnabled;
191208

209+
toml::array recentsArray;
210+
for (const auto& gamePath : recentlyPlayed) {
211+
recentsArray.push_back(gamePath.string());
212+
}
213+
data["General"]["RecentGames"] = recentsArray;
214+
192215
data["Window"]["AppVersionOnWindow"] = windowSettings.showAppVersion;
193216
data["Window"]["RememberWindowPosition"] = windowSettings.rememberPosition;
194217
data["Window"]["WindowPosX"] = windowSettings.x;
@@ -285,4 +308,18 @@ const char* EmulatorConfig::languageCodeToString(LanguageCodes code) {
285308
} else {
286309
return codes[static_cast<u32>(code)];
287310
}
288-
}
311+
}
312+
void EmulatorConfig::addToRecentGames(const std::filesystem::path& path) {
313+
// Remove path if it's already in the list
314+
auto it = std::find(recentlyPlayed.begin(), recentlyPlayed.end(), path);
315+
if (it != recentlyPlayed.end()) {
316+
recentlyPlayed.erase(it);
317+
}
318+
319+
recentlyPlayed.insert(recentlyPlayed.begin(), path);
320+
321+
// Limit how many games can be saved
322+
if (recentlyPlayed.size() > maxRecentGames) {
323+
recentlyPlayed.resize(maxRecentGames);
324+
}
325+
}

src/panda_qt/main_window.cpp

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
5353

5454
// Create and bind actions for them
5555
auto loadGameAction = fileMenu->addAction(tr("Load game"));
56+
57+
recentsMenu = fileMenu->addMenu(tr("Recents"));
58+
updateRecentsMenu();
59+
60+
fileMenu->addSeparator();
5661
auto loadLuaAction = fileMenu->addAction(tr("Load Lua script"));
5762
auto openAppFolderAction = fileMenu->addAction(tr("Open Panda3DS folder"));
5863

@@ -140,6 +145,10 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
140145
if (!emu->loadROM(romPath)) {
141146
// For some reason just .c_str() doesn't show the proper path
142147
Helpers::warn("Failed to load ROM file: %s", romPath.string().c_str());
148+
} else {
149+
emu->getConfig().addToRecentGames(romPath);
150+
emu->getConfig().save();
151+
updateRecentsMenu();
143152
}
144153
}
145154

@@ -240,11 +249,48 @@ void MainWindow::selectROM() {
240249
);
241250

242251
if (!path.isEmpty()) {
243-
std::filesystem::path* p = new std::filesystem::path(path.toStdU16String());
252+
loadROMFromPath(std::filesystem::path(path.toStdU16String()));
253+
}
254+
}
244255

245-
EmulatorMessage message{.type = MessageType::LoadROM};
246-
message.path.p = p;
247-
sendMessage(message);
256+
void MainWindow::loadROMFromPath(const std::filesystem::path& path) {
257+
std::filesystem::path* p = new std::filesystem::path(path);
258+
259+
EmulatorMessage message{.type = MessageType::LoadROM};
260+
message.path.p = p;
261+
sendMessage(message);
262+
263+
emu->getConfig().addToRecentGames(path);
264+
emu->getConfig().save();
265+
updateRecentsMenu();
266+
}
267+
268+
void MainWindow::updateRecentsMenu() {
269+
recentsMenu->clear();
270+
const auto& recentGames = emu->getConfig().recentlyPlayed;
271+
272+
if (recentGames.empty()) {
273+
// Add a disabled "No recent games" item
274+
QAction* noRecentsAction = recentsMenu->addAction(tr("No recent games"));
275+
noRecentsAction->setEnabled(false);
276+
} else {
277+
for (const auto& gamePath : recentGames) {
278+
QString displayName = QString::fromStdU16String(gamePath.filename().u16string());
279+
QAction* action = recentsMenu->addAction(displayName);
280+
281+
// Store the full path in the action's data, set tooltip to show full path
282+
action->setData(QString::fromStdU16String(gamePath.u16string()));
283+
action->setToolTip(QString::fromStdU16String(gamePath.u16string()));
284+
connect(action, &QAction::triggered, this, [this, gamePath]() { loadROMFromPath(gamePath); });
285+
}
286+
287+
recentsMenu->addSeparator();
288+
QAction* clearAction = recentsMenu->addAction(tr("Clear recent games"));
289+
connect(clearAction, &QAction::triggered, this, [this]() {
290+
emu->getConfig().recentlyPlayed.clear();
291+
emu->getConfig().save();
292+
updateRecentsMenu();
293+
});
248294
}
249295
}
250296

0 commit comments

Comments
 (0)