diff --git a/src/citra/config.cpp b/src/citra/config.cpp index cf8a1e01e..f8447713a 100644 --- a/src/citra/config.cpp +++ b/src/citra/config.cpp @@ -160,6 +160,8 @@ void Config::ReadValues() { static_cast(sdl2_config->GetInteger("Layout", "layout_option", 0)); Settings::values.swap_screen = sdl2_config->GetBoolean("Layout", "swap_screen", false); Settings::values.upright_screen = sdl2_config->GetBoolean("Layout", "upright_screen", false); + Settings::values.large_screen_proportion = + sdl2_config->GetReal("Layout", "large_screen_proportion", 4.0); Settings::values.custom_layout = sdl2_config->GetBoolean("Layout", "custom_layout", false); Settings::values.custom_top_left = static_cast(sdl2_config->GetInteger("Layout", "custom_top_left", 0)); diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h index 9cc72ba09..19f57afb8 100644 --- a/src/citra/default_ini.h +++ b/src/citra/default_ini.h @@ -216,6 +216,10 @@ swap_screen = # 0 (default): Off, 1: On upright_screen = +# The proportion between the large and small screens when playing in Large Screen Small Screen layout. +# Must be a real value between 1.0 and 16.0. Default is 4 +large_screen_proportion = + # Dumps textures as PNG to dump/textures/[Title ID]/. # 0 (default): Off, 1: On dump_textures = diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index bfccdbe18..d611d3306 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -485,6 +485,7 @@ void Config::ReadLayoutValues() { ReadGlobalSetting(Settings::values.layout_option); ReadGlobalSetting(Settings::values.swap_screen); ReadGlobalSetting(Settings::values.upright_screen); + ReadGlobalSetting(Settings::values.large_screen_proportion); if (global) { ReadBasicSetting(Settings::values.mono_render_option); @@ -996,6 +997,7 @@ void Config::SaveLayoutValues() { WriteGlobalSetting(Settings::values.layout_option); WriteGlobalSetting(Settings::values.swap_screen); WriteGlobalSetting(Settings::values.upright_screen); + WriteGlobalSetting(Settings::values.large_screen_proportion); if (global) { WriteBasicSetting(Settings::values.mono_render_option); diff --git a/src/citra_qt/configuration/configure_enhancements.cpp b/src/citra_qt/configuration/configure_enhancements.cpp index f48612d34..1c2d6b993 100644 --- a/src/citra_qt/configuration/configure_enhancements.cpp +++ b/src/citra_qt/configuration/configure_enhancements.cpp @@ -69,6 +69,7 @@ void ConfigureEnhancements::SetConfiguration() { static_cast(Settings::values.layout_option.GetValue())); ui->swap_screen->setChecked(Settings::values.swap_screen.GetValue()); ui->upright_screen->setChecked(Settings::values.upright_screen.GetValue()); + ui->large_screen_proportion->setValue(Settings::values.large_screen_proportion.GetValue()); ui->toggle_dump_textures->setChecked(Settings::values.dump_textures.GetValue()); ui->toggle_custom_textures->setChecked(Settings::values.custom_textures.GetValue()); ui->toggle_preload_textures->setChecked(Settings::values.preload_textures.GetValue()); @@ -122,6 +123,7 @@ void ConfigureEnhancements::ApplyConfiguration() { static_cast(ui->layout_combobox->currentIndex()); Settings::values.swap_screen = ui->swap_screen->isChecked(); Settings::values.upright_screen = ui->upright_screen->isChecked(); + Settings::values.large_screen_proportion = ui->large_screen_proportion->value(); Settings::values.dump_textures = ui->toggle_dump_textures->isChecked(); Settings::values.custom_textures = ui->toggle_custom_textures->isChecked(); Settings::values.preload_textures = ui->toggle_preload_textures->isChecked(); diff --git a/src/citra_qt/configuration/configure_enhancements.ui b/src/citra_qt/configuration/configure_enhancements.ui index 0d4ed0161..d8b31af86 100644 --- a/src/citra_qt/configuration/configure_enhancements.ui +++ b/src/citra_qt/configuration/configure_enhancements.ui @@ -295,6 +295,30 @@ + + + + + + Large Screen Proportion: + + + + + + + 1 + + + 16 + + + 4 + + + + + @@ -384,6 +408,7 @@ layout_combobox swap_screen upright_screen + large_screen_proportion bg_button toggle_custom_textures toggle_dump_textures diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 44627a6b7..8e3143dbe 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -113,6 +113,7 @@ void LogSettings() { log_setting("Layout_LayoutOption", values.layout_option.GetValue()); log_setting("Layout_SwapScreen", values.swap_screen.GetValue()); log_setting("Layout_UprightScreen", values.upright_screen.GetValue()); + log_setting("Layout_LargeScreenProportion", values.large_screen_proportion.GetValue()); log_setting("Utility_DumpTextures", values.dump_textures.GetValue()); log_setting("Utility_CustomTextures", values.custom_textures.GetValue()); log_setting("Utility_UseDiskShaderCache", values.use_disk_shader_cache.GetValue()); @@ -189,6 +190,7 @@ void RestoreGlobalState(bool is_powered_on) { values.layout_option.SetGlobal(true); values.swap_screen.SetGlobal(true); values.upright_screen.SetGlobal(true); + values.large_screen_proportion.SetGlobal(true); values.bg_red.SetGlobal(true); values.bg_green.SetGlobal(true); values.bg_blue.SetGlobal(true); diff --git a/src/common/settings.h b/src/common/settings.h index a29123af1..98579cff7 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -455,6 +455,8 @@ struct Values { SwitchableSetting layout_option{LayoutOption::Default, "layout_option"}; SwitchableSetting swap_screen{false, "swap_screen"}; SwitchableSetting upright_screen{false, "upright_screen"}; + SwitchableSetting large_screen_proportion{4.f, 1.f, 16.f, + "large_screen_proportion"}; Setting custom_layout{false, "custom_layout"}; Setting custom_top_left{0, "custom_top_left"}; Setting custom_top_top{0, "custom_top_top"}; diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp index acb81fdaa..2b37a2494 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp @@ -197,7 +197,8 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height, case Settings::LayoutOption::LargeScreen: layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), - Settings::values.upright_screen.GetValue()); + Settings::values.upright_screen.GetValue(), + Settings::values.large_screen_proportion.GetValue()); break; case Settings::LayoutOption::SideScreen: layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen.GetValue(), diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index 75f330f18..092812053 100644 --- a/src/core/frontend/framebuffer_layout.cpp +++ b/src/core/frontend/framebuffer_layout.cpp @@ -231,7 +231,8 @@ FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, bool up return res; } -FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upright) { +FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upright, + float scale_factor) { ASSERT(width > 0); ASSERT(height > 0); @@ -244,25 +245,29 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr float small_screen_aspect_ratio; if (upright) { if (swapped) { - emulation_aspect_ratio = (Core::kScreenBottomWidth * 4.0f + Core::kScreenTopWidth) / - (Core::kScreenBottomHeight * 4); + emulation_aspect_ratio = + (Core::kScreenBottomWidth * scale_factor + Core::kScreenTopWidth) / + (Core::kScreenBottomHeight * scale_factor); large_screen_aspect_ratio = BOT_SCREEN_UPRIGHT_ASPECT_RATIO; small_screen_aspect_ratio = TOP_SCREEN_UPRIGHT_ASPECT_RATIO; } else { - emulation_aspect_ratio = (Core::kScreenTopWidth * 4.0f + Core::kScreenBottomWidth) / - (Core::kScreenTopHeight * 4); + emulation_aspect_ratio = + (Core::kScreenTopWidth * scale_factor + Core::kScreenBottomWidth) / + (Core::kScreenTopHeight * scale_factor); large_screen_aspect_ratio = TOP_SCREEN_UPRIGHT_ASPECT_RATIO; small_screen_aspect_ratio = BOT_SCREEN_UPRIGHT_ASPECT_RATIO; } } else { if (swapped) { - emulation_aspect_ratio = Core::kScreenBottomHeight * 4 / - (Core::kScreenBottomWidth * 4.0f + Core::kScreenTopWidth); + emulation_aspect_ratio = + Core::kScreenBottomHeight * scale_factor / + (Core::kScreenBottomWidth * scale_factor + Core::kScreenTopWidth); large_screen_aspect_ratio = BOT_SCREEN_ASPECT_RATIO; small_screen_aspect_ratio = TOP_SCREEN_ASPECT_RATIO; } else { - emulation_aspect_ratio = Core::kScreenTopHeight * 4 / - (Core::kScreenTopWidth * 4.0f + Core::kScreenBottomWidth); + emulation_aspect_ratio = + Core::kScreenTopHeight * scale_factor / + (Core::kScreenTopWidth * scale_factor + Core::kScreenBottomWidth); large_screen_aspect_ratio = TOP_SCREEN_ASPECT_RATIO; small_screen_aspect_ratio = BOT_SCREEN_ASPECT_RATIO; } @@ -271,7 +276,7 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr Common::Rectangle screen_window_area{0, 0, width, height}; Common::Rectangle total_rect = maxRectangle(screen_window_area, emulation_aspect_ratio); Common::Rectangle large_screen = maxRectangle(total_rect, large_screen_aspect_ratio); - Common::Rectangle fourth_size_rect = total_rect.Scale(.25f); + Common::Rectangle fourth_size_rect = total_rect.Scale(1.f / scale_factor); Common::Rectangle small_screen = maxRectangle(fourth_size_rect, small_screen_aspect_ratio); if (window_aspect_ratio < emulation_aspect_ratio) { @@ -416,22 +421,35 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar if (Settings::values.upright_screen.GetValue()) { if (Settings::values.swap_screen.GetValue()) { width = Core::kScreenBottomHeight * res_scale; - height = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale; + height = (Core::kScreenBottomWidth + + Core::kScreenTopWidth / + Settings::values.large_screen_proportion.GetValue()) * + res_scale; } else { width = Core::kScreenTopHeight * res_scale; - height = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 4) * res_scale; + height = (Core::kScreenTopWidth + + Core::kScreenBottomWidth / + Settings::values.large_screen_proportion.GetValue()) * + res_scale; } } else { if (Settings::values.swap_screen.GetValue()) { - width = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale; + width = (Core::kScreenBottomWidth + + Core::kScreenTopWidth / + Settings::values.large_screen_proportion.GetValue()) * + res_scale; height = Core::kScreenBottomHeight * res_scale; } else { - width = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 4) * res_scale; + width = (Core::kScreenTopWidth + + Core::kScreenBottomWidth / + Settings::values.large_screen_proportion.GetValue()) * + res_scale; height = Core::kScreenTopHeight * res_scale; } } layout = LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), - Settings::values.upright_screen.GetValue()); + Settings::values.upright_screen.GetValue(), + Settings::values.large_screen_proportion.GetValue()); break; case Settings::LayoutOption::SideScreen: if (Settings::values.upright_screen.GetValue()) { @@ -576,9 +594,12 @@ std::pair GetMinimumSizeFromLayout(Settings::LayoutOption la min_height = Core::kScreenBottomHeight; break; case Settings::LayoutOption::LargeScreen: - min_width = Settings::values.swap_screen - ? Core::kScreenTopWidth / 4 + Core::kScreenBottomWidth - : Core::kScreenTopWidth + Core::kScreenBottomWidth / 4; + min_width = + Settings::values.swap_screen + ? Core::kScreenTopWidth / Settings::values.large_screen_proportion.GetValue() + + Core::kScreenBottomWidth + : Core::kScreenTopWidth + Core::kScreenBottomWidth / + Settings::values.large_screen_proportion.GetValue(); min_height = Core::kScreenBottomHeight; break; case Settings::LayoutOption::SideScreen: diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h index 763262663..36a983ee3 100644 --- a/src/core/frontend/framebuffer_layout.h +++ b/src/core/frontend/framebuffer_layout.h @@ -83,9 +83,11 @@ FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool is_swapped, bool * @param width Window framebuffer width in pixels * @param height Window framebuffer height in pixels * @param is_swapped if true, the bottom screen will be the large display + * @param scale_factor The ratio between the large screen with respect to the smaller screen * @return Newly created FramebufferLayout object with default screen regions initialized */ -FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool is_swapped, bool upright); +FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool is_swapped, bool upright, + float scale_factor); /** * Factory method for constructing a Frame with the Top screen and bottom