Compare commits
8 Commits
7efbae3f5f
...
uwp_clean
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6be36b20ed | ||
|
|
944b9892f9 | ||
|
|
7e0150b303 | ||
|
|
0c1ccbd177 | ||
|
|
8299059dd4 | ||
|
|
cb9d09aca0 | ||
|
|
8cc51b8223 | ||
|
|
9a9d24cb62 |
4
.github/workflows/Test_Build.yml
vendored
@@ -35,7 +35,9 @@ jobs:
|
|||||||
- name: Clone and compile 3ds-examples
|
- name: Clone and compile 3ds-examples
|
||||||
run: |
|
run: |
|
||||||
git clone --recursive https://github.com/devkitPro/3ds-examples tests/3ds-examples
|
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
|
- name: Upload binaries
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
2
.gitignore
vendored
@@ -16,7 +16,7 @@ ReleaseWithClangCL/
|
|||||||
Enabled/
|
Enabled/
|
||||||
Disabled/
|
Disabled/
|
||||||
build/
|
build/
|
||||||
|
build_uwp/
|
||||||
.vs/
|
.vs/
|
||||||
.vscode/*.log
|
.vscode/*.log
|
||||||
.cache/
|
.cache/
|
||||||
|
|||||||
@@ -108,6 +108,9 @@ struct EmulatorConfig {
|
|||||||
std::filesystem::path defaultRomPath = "";
|
std::filesystem::path defaultRomPath = "";
|
||||||
std::filesystem::path filePath;
|
std::filesystem::path filePath;
|
||||||
|
|
||||||
|
static constexpr size_t maxRecentGames = 8;
|
||||||
|
std::vector<std::filesystem::path> recentlyPlayed;
|
||||||
|
|
||||||
// Frontend window settings
|
// Frontend window settings
|
||||||
struct WindowSettings {
|
struct WindowSettings {
|
||||||
static constexpr int defaultX = 200;
|
static constexpr int defaultX = 200;
|
||||||
@@ -132,6 +135,8 @@ struct EmulatorConfig {
|
|||||||
void load();
|
void load();
|
||||||
void save();
|
void save();
|
||||||
|
|
||||||
|
void addToRecentGames(const std::filesystem::path& path);
|
||||||
|
|
||||||
static LanguageCodes languageCodeFromString(std::string inString);
|
static LanguageCodes languageCodeFromString(std::string inString);
|
||||||
static const char* languageCodeToString(LanguageCodes code);
|
static const char* languageCodeToString(LanguageCodes code);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,7 +28,11 @@ struct FrontendSettings {
|
|||||||
WindowIcon icon = WindowIcon::Rpog;
|
WindowIcon icon = WindowIcon::Rpog;
|
||||||
std::string language = "en";
|
std::string language = "en";
|
||||||
bool showImGuiDebugPanel = true;
|
bool showImGuiDebugPanel = true;
|
||||||
|
#ifdef IMGUI_FRONTEND
|
||||||
|
bool stretchImGuiOutputToWindow = true;
|
||||||
|
#else
|
||||||
bool stretchImGuiOutputToWindow = false;
|
bool stretchImGuiOutputToWindow = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
static Theme themeFromString(std::string inString);
|
static Theme themeFromString(std::string inString);
|
||||||
static const char* themeToString(Theme theme);
|
static const char* themeToString(Theme theme);
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ class MainWindow : public QMainWindow {
|
|||||||
std::vector<EmulatorMessage> messageQueue;
|
std::vector<EmulatorMessage> messageQueue;
|
||||||
|
|
||||||
QMenuBar* menuBar = nullptr;
|
QMenuBar* menuBar = nullptr;
|
||||||
|
QMenu* recentsMenu = nullptr;
|
||||||
InputMappings keyboardMappings;
|
InputMappings keyboardMappings;
|
||||||
ScreenWidget* screen;
|
ScreenWidget* screen;
|
||||||
AboutWindow* aboutWindow;
|
AboutWindow* aboutWindow;
|
||||||
@@ -123,6 +124,8 @@ class MainWindow : public QMainWindow {
|
|||||||
void emuThreadMainLoop();
|
void emuThreadMainLoop();
|
||||||
void selectLuaFile();
|
void selectLuaFile();
|
||||||
void selectROM();
|
void selectROM();
|
||||||
|
void loadROMFromPath(const std::filesystem::path& path);
|
||||||
|
void updateRecentsMenu();
|
||||||
void dumpDspFirmware();
|
void dumpDspFirmware();
|
||||||
void dumpRomFS();
|
void dumpRomFS();
|
||||||
void showAboutMenu();
|
void showAboutMenu();
|
||||||
|
|||||||
@@ -64,6 +64,11 @@ class FrontendSDL {
|
|||||||
bool keyboardAnalogY = false;
|
bool keyboardAnalogY = false;
|
||||||
bool emuPaused = false;
|
bool emuPaused = false;
|
||||||
bool returnToSelector = false;
|
bool returnToSelector = false;
|
||||||
|
#ifdef IMGUI_FRONTEND
|
||||||
|
bool controllerStartHeld = false;
|
||||||
|
bool controllerSelectHeld = false;
|
||||||
|
bool controllerPauseComboArmed = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupControllerSensors(SDL_GameController* controller);
|
void setupControllerSensors(SDL_GameController* controller);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class ImGuiLayer {
|
|||||||
void setPauseCallback(std::function<void(bool)> callback) { onPauseChange = std::move(callback); }
|
void setPauseCallback(std::function<void(bool)> callback) { onPauseChange = std::move(callback); }
|
||||||
void setVsyncCallback(std::function<void(bool)> callback) { onVsyncChange = std::move(callback); }
|
void setVsyncCallback(std::function<void(bool)> callback) { onVsyncChange = std::move(callback); }
|
||||||
void setExitToSelectorCallback(std::function<void()> callback) { onExitToSelector = std::move(callback); }
|
void setExitToSelectorCallback(std::function<void()> callback) { onExitToSelector = std::move(callback); }
|
||||||
|
void showPauseMenuFromController();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void drawDebugPanel();
|
void drawDebugPanel();
|
||||||
|
|||||||
@@ -50,6 +50,23 @@ void EmulatorConfig::load() {
|
|||||||
circlePadProEnabled = toml::find_or<toml::boolean>(general, "EnableCirclePadPro", true);
|
circlePadProEnabled = toml::find_or<toml::boolean>(general, "EnableCirclePadPro", true);
|
||||||
fastmemEnabled = toml::find_or<toml::boolean>(general, "EnableFastmem", enableFastmemDefault);
|
fastmemEnabled = toml::find_or<toml::boolean>(general, "EnableFastmem", enableFastmemDefault);
|
||||||
systemLanguage = languageCodeFromString(toml::find_or<std::string>(general, "SystemLanguage", "en"));
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +170,11 @@ void EmulatorConfig::load() {
|
|||||||
frontendSettings.icon = FrontendSettings::iconFromString(toml::find_or<std::string>(ui, "WindowIcon", "rpog"));
|
frontendSettings.icon = FrontendSettings::iconFromString(toml::find_or<std::string>(ui, "WindowIcon", "rpog"));
|
||||||
frontendSettings.language = toml::find_or<std::string>(ui, "Language", "en");
|
frontendSettings.language = toml::find_or<std::string>(ui, "Language", "en");
|
||||||
frontendSettings.showImGuiDebugPanel = toml::find_or<toml::boolean>(ui, "ShowImGuiDebugPanel", true);
|
frontendSettings.showImGuiDebugPanel = toml::find_or<toml::boolean>(ui, "ShowImGuiDebugPanel", true);
|
||||||
|
#ifdef IMGUI_FRONTEND
|
||||||
|
frontendSettings.stretchImGuiOutputToWindow = toml::find_or<toml::boolean>(ui, "StretchImGuiOutputToWindow", true);
|
||||||
|
#else
|
||||||
frontendSettings.stretchImGuiOutputToWindow = toml::find_or<toml::boolean>(ui, "StretchImGuiOutputToWindow", false);
|
frontendSettings.stretchImGuiOutputToWindow = toml::find_or<toml::boolean>(ui, "StretchImGuiOutputToWindow", false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,6 +206,12 @@ void EmulatorConfig::save() {
|
|||||||
data["General"]["EnableCirclePadPro"] = circlePadProEnabled;
|
data["General"]["EnableCirclePadPro"] = circlePadProEnabled;
|
||||||
data["General"]["EnableFastmem"] = fastmemEnabled;
|
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"]["AppVersionOnWindow"] = windowSettings.showAppVersion;
|
||||||
data["Window"]["RememberWindowPosition"] = windowSettings.rememberPosition;
|
data["Window"]["RememberWindowPosition"] = windowSettings.rememberPosition;
|
||||||
data["Window"]["WindowPosX"] = windowSettings.x;
|
data["Window"]["WindowPosX"] = windowSettings.x;
|
||||||
@@ -281,4 +308,18 @@ const char* EmulatorConfig::languageCodeToString(LanguageCodes code) {
|
|||||||
} else {
|
} else {
|
||||||
return codes[static_cast<u32>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
|
|||||||
|
|
||||||
// Create and bind actions for them
|
// Create and bind actions for them
|
||||||
auto loadGameAction = fileMenu->addAction(tr("Load game"));
|
auto loadGameAction = fileMenu->addAction(tr("Load game"));
|
||||||
|
|
||||||
|
recentsMenu = fileMenu->addMenu(tr("Recents"));
|
||||||
|
updateRecentsMenu();
|
||||||
|
|
||||||
|
fileMenu->addSeparator();
|
||||||
auto loadLuaAction = fileMenu->addAction(tr("Load Lua script"));
|
auto loadLuaAction = fileMenu->addAction(tr("Load Lua script"));
|
||||||
auto openAppFolderAction = fileMenu->addAction(tr("Open Panda3DS folder"));
|
auto openAppFolderAction = fileMenu->addAction(tr("Open Panda3DS folder"));
|
||||||
|
|
||||||
@@ -140,6 +145,10 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
|
|||||||
if (!emu->loadROM(romPath)) {
|
if (!emu->loadROM(romPath)) {
|
||||||
// For some reason just .c_str() doesn't show the proper path
|
// For some reason just .c_str() doesn't show the proper path
|
||||||
Helpers::warn("Failed to load ROM file: %s", romPath.string().c_str());
|
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()) {
|
if (!path.isEmpty()) {
|
||||||
std::filesystem::path* p = new std::filesystem::path(path.toStdU16String());
|
loadROMFromPath(std::filesystem::path(path.toStdU16String()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EmulatorMessage message{.type = MessageType::LoadROM};
|
void MainWindow::loadROMFromPath(const std::filesystem::path& path) {
|
||||||
message.path.p = p;
|
std::filesystem::path* p = new std::filesystem::path(path);
|
||||||
sendMessage(message);
|
|
||||||
|
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();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ FrontendSDL::FrontendSDL(SDL_Window* existingWindow, SDL_GLContext existingConte
|
|||||||
FrontendSDL::ImGuiWindowContext FrontendSDL::createImGuiWindowContext(const EmulatorConfig& bootConfig, const char* windowTitle) {
|
FrontendSDL::ImGuiWindowContext FrontendSDL::createImGuiWindowContext(const EmulatorConfig& bootConfig, const char* windowTitle) {
|
||||||
int windowX = SDL_WINDOWPOS_CENTERED;
|
int windowX = SDL_WINDOWPOS_CENTERED;
|
||||||
int windowY = SDL_WINDOWPOS_CENTERED;
|
int windowY = SDL_WINDOWPOS_CENTERED;
|
||||||
int windowW = 400;
|
int windowW = 640;
|
||||||
int windowH = 480;
|
int windowH = 360;
|
||||||
if (bootConfig.windowSettings.rememberPosition) {
|
if (bootConfig.windowSettings.rememberPosition) {
|
||||||
windowX = bootConfig.windowSettings.x;
|
windowX = bootConfig.windowSettings.x;
|
||||||
windowY = bootConfig.windowSettings.y;
|
windowY = bootConfig.windowSettings.y;
|
||||||
@@ -115,8 +115,13 @@ void FrontendSDL::initialize(SDL_Window* existingWindow, SDL_GLContext existingC
|
|||||||
} else {
|
} else {
|
||||||
windowX = SDL_WINDOWPOS_CENTERED;
|
windowX = SDL_WINDOWPOS_CENTERED;
|
||||||
windowY = SDL_WINDOWPOS_CENTERED;
|
windowY = SDL_WINDOWPOS_CENTERED;
|
||||||
|
#ifdef IMGUI_FRONTEND
|
||||||
|
windowWidth = 640;
|
||||||
|
windowHeight = 360;
|
||||||
|
#else
|
||||||
windowWidth = 400;
|
windowWidth = 400;
|
||||||
windowHeight = 480;
|
windowHeight = 480;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize output size and screen layout
|
// Initialize output size and screen layout
|
||||||
@@ -309,22 +314,32 @@ void FrontendSDL::run() {
|
|||||||
keyboardAnalogX = false;
|
keyboardAnalogX = false;
|
||||||
keyboardAnalogY = false;
|
keyboardAnalogY = false;
|
||||||
holdingRightClick = false;
|
holdingRightClick = false;
|
||||||
|
#ifdef IMGUI_FRONTEND
|
||||||
|
int lastDrawableW = -1;
|
||||||
|
int lastDrawableH = -1;
|
||||||
|
controllerStartHeld = false;
|
||||||
|
controllerSelectHeld = false;
|
||||||
|
controllerPauseComboArmed = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
while (programRunning) {
|
while (programRunning) {
|
||||||
#ifdef IMGUI_FRONTEND
|
#ifdef IMGUI_FRONTEND
|
||||||
const auto& cfg = emu.getConfig();
|
const auto& cfg = emu.getConfig();
|
||||||
if (cfg.frontendSettings.stretchImGuiOutputToWindow) {
|
int drawableW = 0;
|
||||||
int drawableW = 0;
|
int drawableH = 0;
|
||||||
int drawableH = 0;
|
SDL_GL_GetDrawableSize(window, &drawableW, &drawableH);
|
||||||
SDL_GL_GetDrawableSize(window, &drawableW, &drawableH);
|
if (drawableW > 0 && drawableH > 0 && (drawableW != lastDrawableW || drawableH != lastDrawableH)) {
|
||||||
if (drawableW > 0 && drawableH > 0) {
|
lastDrawableW = drawableW;
|
||||||
|
lastDrawableH = drawableH;
|
||||||
|
if (cfg.frontendSettings.stretchImGuiOutputToWindow) {
|
||||||
windowWidth = u32(drawableW);
|
windowWidth = u32(drawableW);
|
||||||
windowHeight = u32(drawableH);
|
windowHeight = u32(drawableH);
|
||||||
emu.setOutputSize(windowWidth, windowHeight);
|
emu.setOutputSize(windowWidth, windowHeight);
|
||||||
|
}
|
||||||
|
if (cfg.frontendSettings.stretchImGuiOutputToWindow) {
|
||||||
ScreenLayout::calculateCoordinates(
|
ScreenLayout::calculateCoordinates(
|
||||||
screenCoordinates, windowWidth, windowHeight, cfg.topScreenSize, cfg.screenLayout
|
screenCoordinates, windowWidth, windowHeight, cfg.topScreenSize, cfg.screenLayout
|
||||||
);
|
);
|
||||||
glViewport(0, 0, drawableW, drawableH);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -511,6 +526,24 @@ void FrontendSDL::run() {
|
|||||||
case SDL_CONTROLLER_BUTTON_START: key = Keys::Start; break;
|
case SDL_CONTROLLER_BUTTON_START: key = Keys::Start; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef IMGUI_FRONTEND
|
||||||
|
if (event.cbutton.button == SDL_CONTROLLER_BUTTON_START) {
|
||||||
|
controllerStartHeld = event.cbutton.state == SDL_PRESSED;
|
||||||
|
}
|
||||||
|
if (event.cbutton.button == SDL_CONTROLLER_BUTTON_BACK) {
|
||||||
|
controllerSelectHeld = event.cbutton.state == SDL_PRESSED;
|
||||||
|
}
|
||||||
|
if (event.cbutton.state == SDL_PRESSED && controllerStartHeld && controllerSelectHeld && controllerPauseComboArmed) {
|
||||||
|
controllerPauseComboArmed = false;
|
||||||
|
if (imgui) {
|
||||||
|
imgui->showPauseMenuFromController();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (event.cbutton.state == SDL_RELEASED && (!controllerStartHeld && !controllerSelectHeld)) {
|
||||||
|
controllerPauseComboArmed = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (key != 0) {
|
if (key != 0) {
|
||||||
if (event.cbutton.state == SDL_PRESSED) {
|
if (event.cbutton.state == SDL_PRESSED) {
|
||||||
hid.pressKey(key);
|
hid.pressKey(key);
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ void ImGuiLayer::init() {
|
|||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
||||||
io.IniFilename = nullptr;
|
io.IniFilename = nullptr;
|
||||||
showDebug = emu.getConfig().frontendSettings.showImGuiDebugPanel;
|
showDebug = emu.getConfig().frontendSettings.showImGuiDebugPanel;
|
||||||
|
|
||||||
@@ -235,6 +236,16 @@ void ImGuiLayer::handleHotkey(const SDL_Event& event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGuiLayer::showPauseMenuFromController() {
|
||||||
|
if (!showPauseMenu) {
|
||||||
|
showPauseMenu = true;
|
||||||
|
if (onPauseChange) {
|
||||||
|
isPaused = true;
|
||||||
|
onPauseChange(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<std::filesystem::path> ImGuiLayer::runGameSelector() {
|
std::optional<std::filesystem::path> ImGuiLayer::runGameSelector() {
|
||||||
std::vector<InstalledGame> games = scanAllGames();
|
std::vector<InstalledGame> games = scanAllGames();
|
||||||
bool showNoRom = games.empty();
|
bool showNoRom = games.empty();
|
||||||
@@ -280,11 +291,13 @@ std::optional<std::filesystem::path> ImGuiLayer::runGameSelector() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
ImGuiWindowFlags flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize;
|
ImGuiWindowFlags flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize;
|
||||||
|
const float maxW = std::max(200.0f, drawableW * 0.9f);
|
||||||
|
const float maxH = std::max(150.0f, drawableH * 0.9f);
|
||||||
|
|
||||||
if (showNoRom) {
|
if (showNoRom) {
|
||||||
std::string rootLabel = primaryScanRootLabel();
|
std::string rootLabel = primaryScanRootLabel();
|
||||||
ImGui::SetNextWindowPos(ImVec2(drawableW * 0.5f, drawableH * 0.5f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
ImGui::SetNextWindowPos(ImVec2(drawableW * 0.5f, drawableH * 0.5f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||||
ImGui::SetNextWindowSize(ImVec2(620, 260), ImGuiCond_Always);
|
ImGui::SetNextWindowSize(ImVec2(std::min(620.0f, maxW), std::min(260.0f, maxH)), ImGuiCond_Always);
|
||||||
ImGui::Begin("No ROMs Found", nullptr, flags);
|
ImGui::Begin("No ROMs Found", nullptr, flags);
|
||||||
ImGui::TextWrapped(
|
ImGui::TextWrapped(
|
||||||
"No ROM inserted!\n\n"
|
"No ROM inserted!\n\n"
|
||||||
@@ -305,7 +318,7 @@ std::optional<std::filesystem::path> ImGuiLayer::runGameSelector() {
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
} else if (!inSettings) {
|
} else if (!inSettings) {
|
||||||
ImGui::SetNextWindowPos(ImVec2(drawableW * 0.5f, drawableH * 0.5f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
ImGui::SetNextWindowPos(ImVec2(drawableW * 0.5f, drawableH * 0.5f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||||
ImGui::SetNextWindowSize(ImVec2(800, 600), ImGuiCond_Always);
|
ImGui::SetNextWindowSize(ImVec2(std::min(800.0f, maxW), std::min(600.0f, maxH)), ImGuiCond_Always);
|
||||||
ImGui::Begin("Select Game", nullptr, flags);
|
ImGui::Begin("Select Game", nullptr, flags);
|
||||||
|
|
||||||
for (int i = 0; i < (int)games.size(); i++) {
|
for (int i = 0; i < (int)games.size(); i++) {
|
||||||
@@ -316,7 +329,7 @@ std::optional<std::filesystem::path> ImGuiLayer::runGameSelector() {
|
|||||||
ImGui::Dummy(ImVec2(0, 8));
|
ImGui::Dummy(ImVec2(0, 8));
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Dummy(ImVec2(0, 8));
|
ImGui::Dummy(ImVec2(0, 8));
|
||||||
ImGui::SetCursorPosX((800 - 120) * 0.5f);
|
ImGui::SetCursorPosX((ImGui::GetWindowWidth() - 120.0f) * 0.5f);
|
||||||
if (ImGui::Button("Settings", ImVec2(120, 0))) {
|
if (ImGui::Button("Settings", ImVec2(120, 0))) {
|
||||||
inSettings = true;
|
inSettings = true;
|
||||||
showSettings = true;
|
showSettings = true;
|
||||||
@@ -360,12 +373,20 @@ void ImGuiLayer::drawDebugPanel() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int winW = 0;
|
||||||
|
int winH = 0;
|
||||||
|
SDL_GL_GetDrawableSize(window, &winW, &winH);
|
||||||
|
const float maxW = std::max(220.0f, winW * 0.45f);
|
||||||
|
const float maxH = std::max(120.0f, winH * 0.45f);
|
||||||
|
ImGui::SetNextWindowSizeConstraints(ImVec2(200.0f, 0.0f), ImVec2(maxW, maxH));
|
||||||
|
|
||||||
ImGui::SetNextWindowPos(ImVec2(float(kDebugPadding), float(kDebugPadding)), ImGuiCond_Always);
|
ImGui::SetNextWindowPos(ImVec2(float(kDebugPadding), float(kDebugPadding)), ImGuiCond_Always);
|
||||||
ImGui::SetNextWindowBgAlpha(0.35f);
|
ImGui::SetNextWindowBgAlpha(0.35f);
|
||||||
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize |
|
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize |
|
||||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoSavedSettings;
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoSavedSettings;
|
||||||
|
|
||||||
ImGui::Begin("##DebugOverlay", nullptr, flags);
|
ImGui::Begin("##DebugOverlay", nullptr, flags);
|
||||||
|
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + maxW - 20.0f);
|
||||||
int major = 0;
|
int major = 0;
|
||||||
int minor = 0;
|
int minor = 0;
|
||||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||||
@@ -377,6 +398,7 @@ void ImGuiLayer::drawDebugPanel() {
|
|||||||
ImGui::Text("Revision: %s", versionInfo.gitRevision.c_str());
|
ImGui::Text("Revision: %s", versionInfo.gitRevision.c_str());
|
||||||
ImGui::Text("FPS : %.1f", ImGui::GetIO().Framerate);
|
ImGui::Text("FPS : %.1f", ImGui::GetIO().Framerate);
|
||||||
ImGui::Text("Paused : %s", isPaused ? "Yes" : "No");
|
ImGui::Text("Paused : %s", isPaused ? "Yes" : "No");
|
||||||
|
ImGui::PopTextWrapPos();
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,8 +449,10 @@ void ImGuiLayer::drawSettingsPanel() {
|
|||||||
int winW = 0;
|
int winW = 0;
|
||||||
int winH = 0;
|
int winH = 0;
|
||||||
SDL_GL_GetDrawableSize(window, &winW, &winH);
|
SDL_GL_GetDrawableSize(window, &winW, &winH);
|
||||||
const float width = 520.0f;
|
const float maxW = std::max(240.0f, winW * 0.9f);
|
||||||
const float height = 640.0f * 0.65f;
|
const float maxH = std::max(200.0f, winH * 0.9f);
|
||||||
|
const float width = std::min(520.0f, maxW);
|
||||||
|
const float height = std::min(640.0f * 0.65f, maxH);
|
||||||
ImGui::SetNextWindowSize(ImVec2(width, height), ImGuiCond_Always);
|
ImGui::SetNextWindowSize(ImVec2(width, height), ImGuiCond_Always);
|
||||||
ImGui::SetNextWindowPos(ImVec2(winW * 0.5f, winH * 0.5f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
ImGui::SetNextWindowPos(ImVec2(winW * 0.5f, winH * 0.5f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 19 KiB |