Integrate standalone FSUI into Panda SDL frontend

This commit is contained in:
moonpower
2026-04-03 06:16:04 +02:00
parent 6be36b20ed
commit f2bc79352f
14 changed files with 2348 additions and 471 deletions

View File

@@ -15,7 +15,10 @@
// We are legally allowed, as per the author's wish, to use the above code without any licensing restrictions
// However we still want to follow the license as closely as possible and offer the proper attributions.
EmulatorConfig::EmulatorConfig(const std::filesystem::path& path) : filePath(path) { load(); }
EmulatorConfig::EmulatorConfig(const std::filesystem::path& path) : filePath(path) {
frontendSettings.enableFullscreenUI = FrontendSettings::defaultFullscreenUIEnabled();
load();
}
void EmulatorConfig::load() {
const std::filesystem::path& path = filePath;
@@ -70,6 +73,31 @@ void EmulatorConfig::load() {
}
}
if (data.contains("GameList")) {
auto gameListResult = toml::expect<toml::value>(data.at("GameList"));
if (gameListResult.is_ok()) {
auto gameList = gameListResult.unwrap();
fsuiGameListPaths.clear();
if (gameList.contains("Paths") && gameList.at("Paths").is_array()) {
for (const auto& item : gameList.at("Paths").as_array()) {
if (item.is_string()) {
fsuiGameListPaths.emplace_back(toml::get<std::string>(item));
}
}
}
fsuiGameListRecursivePaths.clear();
if (gameList.contains("RecursivePaths") && gameList.at("RecursivePaths").is_array()) {
for (const auto& item : gameList.at("RecursivePaths").as_array()) {
if (item.is_string()) {
fsuiGameListRecursivePaths.emplace_back(toml::get<std::string>(item));
}
}
}
}
}
if (data.contains("Window")) {
auto windowResult = toml::expect<toml::value>(data.at("Window"));
if (windowResult.is_ok()) {
@@ -170,6 +198,14 @@ void EmulatorConfig::load() {
frontendSettings.icon = FrontendSettings::iconFromString(toml::find_or<std::string>(ui, "WindowIcon", "rpog"));
frontendSettings.language = toml::find_or<std::string>(ui, "Language", "en");
frontendSettings.showImGuiDebugPanel = toml::find_or<toml::boolean>(ui, "ShowImGuiDebugPanel", true);
frontendSettings.enableFullscreenUI =
toml::find_or<toml::boolean>(ui, "EnableFullscreenUI", FrontendSettings::defaultFullscreenUIEnabled());
fsuiTheme = toml::find_or<std::string>(ui, "FullscreenUITheme", "Dark");
fsuiPromptIconPack = toml::find_or<std::string>(ui, "FullscreenUIPromptIcons", "Auto");
fsuiBackgroundImagePath = toml::find_or<std::string>(ui, "FullscreenUIBackgroundImage", "");
fsuiDefaultGameView = static_cast<int>(toml::find_or<toml::integer>(ui, "DefaultFullscreenUIGameView", 0));
fsuiGameSort = static_cast<int>(toml::find_or<toml::integer>(ui, "FullscreenUIGameSort", 0));
fsuiGameSortReverse = toml::find_or<toml::boolean>(ui, "FullscreenUIGameSortReverse", false);
#ifdef IMGUI_FRONTEND
frontendSettings.stretchImGuiOutputToWindow = toml::find_or<toml::boolean>(ui, "StretchImGuiOutputToWindow", true);
#else
@@ -177,6 +213,14 @@ void EmulatorConfig::load() {
#endif
}
}
if (data.contains("Folders")) {
auto foldersResult = toml::expect<toml::value>(data.at("Folders"));
if (foldersResult.is_ok()) {
auto folders = foldersResult.unwrap();
fsuiCoversPath = toml::find_or<std::string>(folders, "Covers", "");
}
}
}
void EmulatorConfig::save() {
@@ -212,6 +256,18 @@ void EmulatorConfig::save() {
}
data["General"]["RecentGames"] = recentsArray;
toml::array pathsArray;
for (const auto& path : fsuiGameListPaths) {
pathsArray.push_back(path.string());
}
data["GameList"]["Paths"] = pathsArray;
toml::array recursivePathsArray;
for (const auto& path : fsuiGameListRecursivePaths) {
recursivePathsArray.push_back(path.string());
}
data["GameList"]["RecursivePaths"] = recursivePathsArray;
data["Window"]["AppVersionOnWindow"] = windowSettings.showAppVersion;
data["Window"]["RememberWindowPosition"] = windowSettings.rememberPosition;
data["Window"]["WindowPosX"] = windowSettings.x;
@@ -250,7 +306,15 @@ void EmulatorConfig::save() {
data["UI"]["WindowIcon"] = std::string(FrontendSettings::iconToString(frontendSettings.icon));
data["UI"]["Language"] = frontendSettings.language;
data["UI"]["ShowImGuiDebugPanel"] = frontendSettings.showImGuiDebugPanel;
data["UI"]["EnableFullscreenUI"] = frontendSettings.enableFullscreenUI;
data["UI"]["FullscreenUITheme"] = fsuiTheme;
data["UI"]["FullscreenUIPromptIcons"] = fsuiPromptIconPack;
data["UI"]["FullscreenUIBackgroundImage"] = fsuiBackgroundImagePath.string();
data["UI"]["DefaultFullscreenUIGameView"] = fsuiDefaultGameView;
data["UI"]["FullscreenUIGameSort"] = fsuiGameSort;
data["UI"]["FullscreenUIGameSortReverse"] = fsuiGameSortReverse;
data["UI"]["StretchImGuiOutputToWindow"] = frontendSettings.stretchImGuiOutputToWindow;
data["Folders"]["Covers"] = fsuiCoversPath.string();
std::ofstream file(path, std::ios::out);
file << data;

View File

@@ -4,6 +4,10 @@
#include <cctype>
#include <unordered_map>
#if defined(__WINRT__) && !defined(__ANDROID__)
#include <SDL.h>
#endif
// Frontend setting serialization/deserialization functions
FrontendSettings::Theme FrontendSettings::themeFromString(std::string inString) {
@@ -62,4 +66,14 @@ const char* FrontendSettings::iconToString(WindowIcon icon) {
case WindowIcon::Rpog:
default: return "rpog";
}
}
}
bool FrontendSettings::defaultFullscreenUIEnabled() {
#if defined(__WINRT__) && !defined(__ANDROID__)
return SDL_WinRTGetDeviceFamily() == SDL_WINRT_DEVICEFAMILY_XBOX;
#elif defined(__XBOXONE__) || defined(__XBOXSERIES__)
return true;
#else
return false;
#endif
}

View File

@@ -298,7 +298,20 @@ void FrontendSDL::initialize(SDL_Window* existingWindow, SDL_GLContext existingC
#endif
}
bool FrontendSDL::loadROM(const std::filesystem::path& path) { return emu.loadROM(path); }
bool FrontendSDL::loadROM(const std::filesystem::path& path) {
const bool loaded = emu.loadROM(path);
if (loaded) {
emuPaused = false;
#ifdef IMGUI_FRONTEND
if (imgui) {
imgui->setPaused(false);
}
#endif
emu.getConfig().addToRecentGames(path);
emu.getConfig().save();
}
return loaded;
}
std::optional<std::filesystem::path> FrontendSDL::selectGame() {
#ifdef IMGUI_FRONTEND
@@ -717,7 +730,9 @@ void FrontendSDL::run() {
// TODO: Should this be uncommented?
// kernel.evalReschedule();
#ifndef IMGUI_FRONTEND
SDL_GL_SwapWindow(window);
#endif
}
#ifdef IMGUI_FRONTEND
@@ -800,4 +815,4 @@ void FrontendSDL::togglePaused() {
setPaused(!emuPaused);
}
FrontendSDL::~FrontendSDL() = default;
FrontendSDL::~FrontendSDL() = default;

File diff suppressed because it is too large Load Diff

1418
src/panda_sdl/panda_fsui.cpp Normal file

File diff suppressed because it is too large Load Diff