feat: enable stretching ImGui output based on frontend settings and adjust window sizes

This commit is contained in:
moonpower
2026-02-02 01:59:36 +03:00
parent 9a9d24cb62
commit 8cc51b8223
4 changed files with 46 additions and 13 deletions

View File

@@ -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);

View File

@@ -153,7 +153,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
} }
} }
} }

View File

@@ -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,29 @@ void FrontendSDL::run() {
keyboardAnalogX = false; keyboardAnalogX = false;
keyboardAnalogY = false; keyboardAnalogY = false;
holdingRightClick = false; holdingRightClick = false;
#ifdef IMGUI_FRONTEND
int lastDrawableW = -1;
int lastDrawableH = -1;
#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) { if (drawableW > 0 && drawableH > 0 && (drawableW != lastDrawableW || drawableH != lastDrawableH)) {
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

View File

@@ -280,11 +280,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 +307,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 +318,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 +362,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 +387,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 +438,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));