From 3afee333941bf1597df025f3acb7b478a53b4210 Mon Sep 17 00:00:00 2001 From: Vitor Kiguchi Date: Tue, 9 Jan 2024 13:21:52 -0300 Subject: [PATCH] layout: add handedness option to upright rotation --- src/citra/emu_window/emu_window_sdl2_sw.cpp | 2 +- src/citra_qt/bootmanager.cpp | 3 +- src/citra_qt/configuration/config.cpp | 2 + .../configuration/configure_enhancements.cpp | 8 ++ .../configuration/configure_enhancements.ui | 39 +++++++++ src/common/settings.h | 6 ++ src/core/frontend/emu_window.cpp | 19 +++-- src/core/frontend/framebuffer_layout.cpp | 84 +++++++++++++------ src/core/frontend/framebuffer_layout.h | 15 ++-- .../renderer_opengl/renderer_opengl.cpp | 29 +++---- .../renderer_vulkan/renderer_vulkan.cpp | 28 +++---- 11 files changed, 160 insertions(+), 75 deletions(-) diff --git a/src/citra/emu_window/emu_window_sdl2_sw.cpp b/src/citra/emu_window/emu_window_sdl2_sw.cpp index 3f2cf6db910f..4597dc666581 100644 --- a/src/citra/emu_window/emu_window_sdl2_sw.cpp +++ b/src/citra/emu_window/emu_window_sdl2_sw.cpp @@ -64,7 +64,7 @@ std::unique_ptr EmuWindow_SDL2_SW::CreateSharedContex void EmuWindow_SDL2_SW::Present() { const auto layout{Layout::DefaultFrameLayout( - Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight, false, false)}; + Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight, false, Layout::DisplayOrientation::Landscape)}; using VideoCore::ScreenId; diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 17c1b30fdfb2..a7da138eb117 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -339,7 +339,8 @@ struct SoftwareRenderWidget : public RenderWidget { using VideoCore::ScreenId; - const auto layout{Layout::DefaultFrameLayout(width(), height(), false, false)}; + const auto layout{ + Layout::DefaultFrameLayout(width(), height(), false, Layout::DisplayOrientation::Landscape)}; QPainter painter(this); const auto draw_screen = [&](ScreenId screen_id) { diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index 5c0abbc2a9fa..55dbe2932842 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -508,6 +508,7 @@ void Config::ReadLayoutValues() { ReadGlobalSetting(Settings::values.swap_screen); ReadGlobalSetting(Settings::values.upright_screen); ReadGlobalSetting(Settings::values.large_screen_proportion); + ReadGlobalSetting(Settings::values.rotation_hand); if (global) { ReadBasicSetting(Settings::values.mono_render_option); @@ -1028,6 +1029,7 @@ void Config::SaveLayoutValues() { WriteGlobalSetting(Settings::values.swap_screen); WriteGlobalSetting(Settings::values.upright_screen); WriteGlobalSetting(Settings::values.large_screen_proportion); + WriteGlobalSetting(Settings::values.rotation_hand); 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 55b8a79eb990..88e5fc3a8fc6 100644 --- a/src/citra_qt/configuration/configure_enhancements.cpp +++ b/src/citra_qt/configuration/configure_enhancements.cpp @@ -62,11 +62,15 @@ void ConfigureEnhancements::SetConfiguration() { !Settings::values.texture_filter.UsingGlobal()); ConfigurationShared::SetPerGameSetting(ui->layout_combobox, &Settings::values.layout_option); + ConfigurationShared::SetPerGameSetting(ui->handedness_combobox, + &Settings::values.rotation_hand); } else { ui->resolution_factor_combobox->setCurrentIndex( Settings::values.resolution_factor.GetValue()); ui->layout_combobox->setCurrentIndex( static_cast(Settings::values.layout_option.GetValue())); + ui->handedness_combobox->setCurrentIndex( + static_cast(Settings::values.rotation_hand.GetValue())); ui->texture_filter_combobox->setCurrentIndex( static_cast(Settings::values.texture_filter.GetValue())); } @@ -155,6 +159,7 @@ void ConfigureEnhancements::ApplyConfiguration() { swap_screen); ConfigurationShared::ApplyPerGameSetting(&Settings::values.upright_screen, ui->toggle_upright_screen, upright_screen); + ConfigurationShared::ApplyPerGameSetting(&Settings::values.rotation_hand, ui->handedness_combobox); ConfigurationShared::ApplyPerGameSetting(&Settings::values.dump_textures, ui->toggle_dump_textures, dump_textures); ConfigurationShared::ApplyPerGameSetting(&Settings::values.custom_textures, @@ -216,4 +221,7 @@ void ConfigureEnhancements::SetupPerGameUI() { ConfigurationShared::SetColoredComboBox( ui->layout_combobox, ui->widget_layout, static_cast(Settings::values.layout_option.GetValue(true))); + ConfigurationShared::SetColoredComboBox( + ui->handedness_combobox, ui->widget_hand, + static_cast(Settings::values.rotation_hand.GetValue(true))); } diff --git a/src/citra_qt/configuration/configure_enhancements.ui b/src/citra_qt/configuration/configure_enhancements.ui index ef77b2bc6ad2..46f0ccde67c0 100644 --- a/src/citra_qt/configuration/configure_enhancements.ui +++ b/src/citra_qt/configuration/configure_enhancements.ui @@ -373,6 +373,45 @@ + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Rotation Handedness + + + + + + + + Right Handed + + + + + Left Handed + + + + + + + diff --git a/src/common/settings.h b/src/common/settings.h index 3b51e5dd453e..7197d50afab8 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -67,6 +67,11 @@ enum class MonoRenderOption : u32 { RightEye = 1, }; +enum class RotationHand : u32 { + RightHanded = 0, + LeftHanded = 1, +}; + enum class AudioEmulation : u32 { HLE = 0, LLE = 1, @@ -476,6 +481,7 @@ struct Values { SwitchableSetting layout_option{LayoutOption::Default, "layout_option"}; SwitchableSetting swap_screen{false, "swap_screen"}; SwitchableSetting upright_screen{false, "upright_screen"}; + SwitchableSetting rotation_hand{RotationHand::RightHanded, "rotation_hand"}; SwitchableSetting large_screen_proportion{4.f, 1.f, 16.f, "large_screen_proportion"}; Setting custom_layout{false, "custom_layout"}; diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp index 63c446983f26..03d1ed064ce6 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp @@ -147,7 +147,7 @@ bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { static_cast(framebuffer_y - framebuffer_layout.bottom_screen.top) / (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); - if (!framebuffer_layout.is_rotated) { + if (framebuffer_layout.orientation == Layout::DisplayOrientation::Landscape) { std::swap(touch_state->touch_x, touch_state->touch_y); touch_state->touch_x = 1.f - touch_state->touch_x; } @@ -183,6 +183,9 @@ void EmuWindow::UpdateCurrentFramebufferLayout(u32 width, u32 height, bool is_po const auto min_size = Layout::GetMinimumSizeFromLayout(layout_option, Settings::values.upright_screen.GetValue()); + const Layout::DisplayOrientation orientation = Layout::MakeDisplayOrientation( + Settings::values.upright_screen.GetValue(), Settings::values.rotation_hand.GetValue()); + if (Settings::values.custom_layout.GetValue() == true) { layout = Layout::CustomFrameLayout(width, height, Settings::values.swap_screen.GetValue()); } else { @@ -193,30 +196,30 @@ void EmuWindow::UpdateCurrentFramebufferLayout(u32 width, u32 height, bool is_po case Settings::LayoutOption::SingleScreen: layout = Layout::SingleFrameLayout(width, height, Settings::values.swap_screen.GetValue(), - Settings::values.upright_screen.GetValue()); + orientation); break; case Settings::LayoutOption::LargeScreen: layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), - Settings::values.upright_screen.GetValue(), + orientation, Settings::values.large_screen_proportion.GetValue(), Layout::VerticalAlignment::Bottom); break; case Settings::LayoutOption::HybridScreen: layout = Layout::HybridScreenLayout(width, height, Settings::values.swap_screen.GetValue(), - Settings::values.upright_screen.GetValue()); + orientation); break; case Settings::LayoutOption::SideScreen: layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), - Settings::values.upright_screen.GetValue(), 1.0f, + orientation, 1.0f, Layout::VerticalAlignment::Bottom); break; #ifndef ANDROID case Settings::LayoutOption::SeparateWindows: layout = Layout::SeparateWindowsLayout(width, height, is_secondary, - Settings::values.upright_screen.GetValue()); + orientation); break; #endif case Settings::LayoutOption::MobilePortrait: @@ -226,13 +229,13 @@ void EmuWindow::UpdateCurrentFramebufferLayout(u32 width, u32 height, bool is_po case Settings::LayoutOption::MobileLandscape: layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), - false, 2.25f, Layout::VerticalAlignment::Top); + Layout::DisplayOrientation::Landscape, 2.25f, Layout::VerticalAlignment::Top); break; case Settings::LayoutOption::Default: default: layout = Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen.GetValue(), - Settings::values.upright_screen.GetValue()); + orientation); break; } UpdateMinimumWindowSize(min_size); diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index 11d2249ac4b5..59476bf98935 100644 --- a/src/core/frontend/framebuffer_layout.cpp +++ b/src/core/frontend/framebuffer_layout.cpp @@ -21,13 +21,27 @@ static constexpr float BOT_SCREEN_UPRIGHT_ASPECT_RATIO = static_cast(Core::kScreenBottomWidth) / Core::kScreenBottomHeight; u32 FramebufferLayout::GetScalingRatio() const { - if (is_rotated) { + if (orientation == DisplayOrientation::Portrait || orientation == DisplayOrientation::PortraitFlipped) { return static_cast(((top_screen.GetWidth() - 1) / Core::kScreenTopWidth) + 1); } else { return static_cast(((top_screen.GetWidth() - 1) / Core::kScreenTopHeight) + 1); } } +DisplayOrientation MakeDisplayOrientation(bool upright, Settings::RotationHand handedness) { + if (upright) { + if (handedness == Settings::RotationHand::LeftHanded) { + return DisplayOrientation::PortraitFlipped; + } + else { + return DisplayOrientation::Portrait; + } + } + else { + return DisplayOrientation::Landscape; + } +} + // Finds the largest size subrectangle contained in window area that is confined to the aspect ratio template static Common::Rectangle MaxRectangle(Common::Rectangle window_area, @@ -38,16 +52,21 @@ static Common::Rectangle MaxRectangle(Common::Rectangle window_area, static_cast(std::round(scale * screen_aspect_ratio))}; } -FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool swapped, bool upright) { +FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool swapped, DisplayOrientation orientation) { ASSERT(width > 0); ASSERT(height > 0); - FramebufferLayout res{width, height, true, true, {}, {}, !upright}; + FramebufferLayout res{width, height, true, true, {}, {}, orientation}; Common::Rectangle screen_window_area; Common::Rectangle top_screen; Common::Rectangle bot_screen; float emulation_aspect_ratio; - if (upright) { + + if (orientation == DisplayOrientation::PortraitFlipped) + swapped = !swapped; + + if (orientation == DisplayOrientation::Portrait || + orientation == DisplayOrientation::PortraitFlipped) { // Default layout gives equal screen sizes to the top and bottom screen screen_window_area = {0, 0, width / 2, height}; top_screen = MaxRectangle(screen_window_area, TOP_SCREEN_UPRIGHT_ASPECT_RATIO); @@ -67,7 +86,8 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool swapped, bool u if (window_aspect_ratio < emulation_aspect_ratio) { // Window is wider than the emulation content => apply borders to the right and left sides - if (upright) { + if (orientation == DisplayOrientation::Portrait || + orientation == DisplayOrientation::PortraitFlipped) { // Recalculate the bottom screen to account for the height difference between right and // left screen_window_area = {0, 0, top_screen.GetWidth(), height}; @@ -87,7 +107,8 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool swapped, bool u } } else { // Window is narrower than the emulation content => apply borders to the top and bottom - if (upright) { + if (orientation == DisplayOrientation::Portrait || + orientation == DisplayOrientation::PortraitFlipped) { top_screen = top_screen.TranslateY( (screen_window_area.GetHeight() - top_screen.GetHeight()) / 2); bot_screen = bot_screen.TranslateY( @@ -105,7 +126,8 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool swapped, bool u } } } - if (upright) { + if (orientation == DisplayOrientation::Portrait || + orientation == DisplayOrientation::PortraitFlipped) { // Move the top screen to the right if we are swapped. res.top_screen = swapped ? top_screen.TranslateX(width / 2) : top_screen; res.bottom_screen = swapped ? bot_screen : bot_screen.TranslateX(width / 2); @@ -151,18 +173,19 @@ FramebufferLayout MobilePortraitFrameLayout(u32 width, u32 height, bool swapped) return res; } -FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, bool upright) { +FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, DisplayOrientation orientation) { ASSERT(width > 0); ASSERT(height > 0); // The drawing code needs at least somewhat valid values for both screens // so just calculate them both even if the other isn't showing. - FramebufferLayout res{width, height, !swapped, swapped, {}, {}, !upright}; + FramebufferLayout res{width, height, !swapped, swapped, {}, {}, orientation}; Common::Rectangle screen_window_area{0, 0, width, height}; Common::Rectangle top_screen; Common::Rectangle bot_screen; float emulation_aspect_ratio; - if (upright) { + if (orientation == DisplayOrientation::Portrait || + orientation == DisplayOrientation::PortraitFlipped) { top_screen = MaxRectangle(screen_window_area, TOP_SCREEN_UPRIGHT_ASPECT_RATIO); bot_screen = MaxRectangle(screen_window_area, BOT_SCREEN_UPRIGHT_ASPECT_RATIO); emulation_aspect_ratio = @@ -189,19 +212,20 @@ 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, DisplayOrientation orientation, float scale_factor, VerticalAlignment vertical_alignment) { ASSERT(width > 0); ASSERT(height > 0); - FramebufferLayout res{width, height, true, true, {}, {}, !upright}; + FramebufferLayout res{width, height, true, true, {}, {}, orientation}; // Split the window into two parts. Give 4x width to the main screen and 1x width to the small // To do that, find the total emulation box and maximize that based on window size float window_aspect_ratio = static_cast(height) / width; float emulation_aspect_ratio; float large_screen_aspect_ratio; float small_screen_aspect_ratio; - if (upright) { + if (orientation == DisplayOrientation::Portrait || + orientation == DisplayOrientation::PortraitFlipped) { if (swapped) { emulation_aspect_ratio = (Core::kScreenBottomWidth * scale_factor + Core::kScreenTopWidth) / @@ -242,7 +266,8 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr } else { large_screen = large_screen.TranslateY((height - total_rect.GetHeight()) / 2); } - if (upright) { + if (orientation == DisplayOrientation::Portrait || + orientation == DisplayOrientation::PortraitFlipped) { large_screen = large_screen.TranslateY(small_screen.GetHeight()); small_screen = small_screen.TranslateY(large_screen.top - small_screen.GetHeight()); switch (vertical_alignment) { @@ -290,11 +315,11 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr return res; } -FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, bool upright) { +FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, DisplayOrientation orientation) { ASSERT(width > 0); ASSERT(height > 0); - FramebufferLayout res{width, height, true, true, {}, {}, !upright, true, {}}; + FramebufferLayout res{width, height, true, true, {}, {}, orientation, true, {}}; // Split the window into two parts. Give 2.25x width to the main screen, // and make a bar on the right side with 1x width top screen and 1.25x width bottom screen @@ -314,7 +339,8 @@ FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, bool u (Core::kScreenBottomWidth * scale_factor + Core::kScreenTopWidth); } - if (upright) { + if (orientation == DisplayOrientation::Portrait || + orientation == DisplayOrientation::PortraitFlipped) { hybrid_area_aspect_ratio = 1.f / hybrid_area_aspect_ratio; main_screen_aspect_ratio = 1.f / main_screen_aspect_ratio; top_screen_aspect_ratio = TOP_SCREEN_UPRIGHT_ASPECT_RATIO; @@ -336,7 +362,8 @@ FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, bool u // Scale the bottom screen so it's width is the same as top screen small_bottom_screen = small_bottom_screen.Scale(1.25f); - if (upright) { + if (orientation == DisplayOrientation::Portrait || + orientation == DisplayOrientation::PortraitFlipped) { large_main_screen = large_main_screen.TranslateY(small_bottom_screen.GetHeight()); // Shift small bottom screen to upper right corner small_bottom_screen = @@ -364,18 +391,20 @@ FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, bool u return res; } -FramebufferLayout SeparateWindowsLayout(u32 width, u32 height, bool is_secondary, bool upright) { +FramebufferLayout SeparateWindowsLayout(u32 width, u32 height, bool is_secondary, DisplayOrientation orientation) { // When is_secondary is true, we disable the top screen, and enable the bottom screen. // The same logic is found in the SingleFrameLayout using the is_swapped bool. is_secondary = Settings::values.swap_screen ? !is_secondary : is_secondary; - return SingleFrameLayout(width, height, is_secondary, upright); + return SingleFrameLayout(width, height, is_secondary, orientation); } FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped) { ASSERT(width > 0); ASSERT(height > 0); - FramebufferLayout res{width, height, true, true, {}, {}, !Settings::values.upright_screen}; + const DisplayOrientation orientation = MakeDisplayOrientation( + Settings::values.upright_screen.GetValue(), Settings::values.rotation_hand.GetValue()); + FramebufferLayout res{width, height, true, true, {}, {}, orientation}; Common::Rectangle top_screen{Settings::values.custom_top_left.GetValue(), Settings::values.custom_top_top.GetValue(), @@ -405,6 +434,9 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar Settings::values.swap_screen.GetValue()); } + const DisplayOrientation orientation = MakeDisplayOrientation( + Settings::values.upright_screen.GetValue(), Settings::values.rotation_hand.GetValue()); + int width, height; switch (Settings::values.layout_option.GetValue()) { case Settings::LayoutOption::SingleScreen: @@ -424,7 +456,7 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar std::swap(width, height); } return SingleFrameLayout(width, height, swap_screens, - Settings::values.upright_screen.GetValue()); + orientation); } case Settings::LayoutOption::LargeScreen: @@ -445,7 +477,7 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar std::swap(width, height); } return LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), - Settings::values.upright_screen.GetValue(), + orientation, Settings::values.large_screen_proportion.GetValue(), VerticalAlignment::Bottom); @@ -457,7 +489,7 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar std::swap(width, height); } return LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), - Settings::values.upright_screen.GetValue(), 1, + orientation, 1, VerticalAlignment::Middle); case Settings::LayoutOption::MobilePortrait: @@ -478,7 +510,7 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar res_scale; height = Core::kScreenTopHeight * res_scale; } - return LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), false, + return LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), DisplayOrientation::Landscape, large_screen_proportion, VerticalAlignment::Top); } @@ -491,7 +523,7 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar std::swap(width, height); } return DefaultFrameLayout(width, height, Settings::values.swap_screen.GetValue(), - Settings::values.upright_screen.GetValue()); + orientation); } UNREACHABLE(); } diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h index f2ed553fdcfa..f739245318d1 100644 --- a/src/core/frontend/framebuffer_layout.h +++ b/src/core/frontend/framebuffer_layout.h @@ -8,6 +8,7 @@ namespace Settings { enum class LayoutOption : u32; +enum class RotationHand : u32; } namespace Layout { @@ -60,7 +61,7 @@ struct FramebufferLayout { bool bottom_screen_enabled; Common::Rectangle top_screen; Common::Rectangle bottom_screen; - bool is_rotated = true; + DisplayOrientation orientation = DisplayOrientation::Landscape; bool additional_screen_enabled; Common::Rectangle additional_screen; @@ -82,7 +83,7 @@ struct FramebufferLayout { * @param upright if true, the screens will be rotated 90 degrees anti-clockwise * @return Newly created FramebufferLayout object with default screen regions initialized */ -FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool is_swapped, bool upright); +FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool is_swapped, DisplayOrientation orientation); /** * Factory method for constructing a mobile portrait FramebufferLayout @@ -101,7 +102,7 @@ FramebufferLayout MobilePortraitFrameLayout(u32 width, u32 height, bool is_swapp * @param upright if true, the screens will be rotated 90 degrees anti-clockwise * @return Newly created FramebufferLayout object with default screen regions initialized */ -FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool is_swapped, bool upright); +FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool is_swapped, DisplayOrientation orientation); /** * Factory method for constructing a Frame with the a 4x size Top screen with a 1x size bottom @@ -116,7 +117,7 @@ FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool is_swapped, bool * 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, DisplayOrientation orientation, float scale_factor, VerticalAlignment vertical_alignment); /** * Factory method for constructing a frame with 2.5 times bigger top screen on the right, @@ -127,7 +128,7 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool is_swapped, bool * @param upright if true, the screens will be rotated 90 degrees anti-clockwise * @return Newly created FramebufferLayout object with default screen regions initialized */ -FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, bool upright); +FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, DisplayOrientation orientation); /** * Factory method for constructing a Frame with the Top screen and bottom @@ -137,7 +138,7 @@ FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, bool u * @param is_secondary if true, the bottom screen will be enabled instead of the top screen * @return Newly created FramebufferLayout object with default screen regions initialized */ -FramebufferLayout SeparateWindowsLayout(u32 width, u32 height, bool is_secondary, bool upright); +FramebufferLayout SeparateWindowsLayout(u32 width, u32 height, bool is_secondary, DisplayOrientation orientation); /** * Factory method for constructing a custom FramebufferLayout @@ -164,4 +165,6 @@ FramebufferLayout GetCardboardSettings(const FramebufferLayout& layout); std::pair GetMinimumSizeFromLayout(Settings::LayoutOption layout, bool upright_screen); +DisplayOrientation MakeDisplayOrientation(bool upright, Settings::RotationHand handedness); + } // namespace Layout diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index e9423fc6d0ff..7d1d21e9227a 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -729,39 +729,37 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout, const float top_screen_width = static_cast(top_screen.GetWidth()); const float top_screen_height = static_cast(top_screen.GetHeight()); - const auto orientation = layout.is_rotated ? Layout::DisplayOrientation::Landscape - : Layout::DisplayOrientation::Portrait; switch (Settings::values.render_3d.GetValue()) { case Settings::StereoRenderOption::Off: { const int eye = static_cast(Settings::values.mono_render_option.GetValue()); DrawSingleScreen(screen_infos[eye], top_screen_left, top_screen_top, top_screen_width, - top_screen_height, orientation); + top_screen_height, layout.orientation); break; } case Settings::StereoRenderOption::SideBySide: { DrawSingleScreen(screen_infos[0], top_screen_left / 2, top_screen_top, top_screen_width / 2, - top_screen_height, orientation); + top_screen_height, layout.orientation); glUniform1i(uniform_layer, 1); DrawSingleScreen(screen_infos[1], static_cast((top_screen_left / 2) + (layout.width / 2)), - top_screen_top, top_screen_width / 2, top_screen_height, orientation); + top_screen_top, top_screen_width / 2, top_screen_height, layout.orientation); break; } case Settings::StereoRenderOption::CardboardVR: { DrawSingleScreen(screen_infos[0], top_screen_left, top_screen_top, top_screen_width, - top_screen_height, orientation); + top_screen_height, layout.orientation); glUniform1i(uniform_layer, 1); DrawSingleScreen( screen_infos[1], static_cast(layout.cardboard.top_screen_right_eye + (layout.width / 2)), - top_screen_top, top_screen_width, top_screen_height, orientation); + top_screen_top, top_screen_width, top_screen_height, layout.orientation); break; } case Settings::StereoRenderOption::Anaglyph: case Settings::StereoRenderOption::Interlaced: case Settings::StereoRenderOption::ReverseInterlaced: { DrawSingleScreenStereo(screen_infos[0], screen_infos[1], top_screen_left, top_screen_top, - top_screen_width, top_screen_height, orientation); + top_screen_width, top_screen_height, layout.orientation); break; } } @@ -778,32 +776,29 @@ void RendererOpenGL::DrawBottomScreen(const Layout::FramebufferLayout& layout, const float bottom_screen_width = static_cast(bottom_screen.GetWidth()); const float bottom_screen_height = static_cast(bottom_screen.GetHeight()); - const auto orientation = layout.is_rotated ? Layout::DisplayOrientation::Landscape - : Layout::DisplayOrientation::Portrait; - switch (Settings::values.render_3d.GetValue()) { case Settings::StereoRenderOption::Off: { DrawSingleScreen(screen_infos[2], bottom_screen_left, bottom_screen_top, - bottom_screen_width, bottom_screen_height, orientation); + bottom_screen_width, bottom_screen_height, layout.orientation); break; } case Settings::StereoRenderOption::SideBySide: { DrawSingleScreen(screen_infos[2], bottom_screen_left / 2, bottom_screen_top, - bottom_screen_width / 2, bottom_screen_height, orientation); + bottom_screen_width / 2, bottom_screen_height, layout.orientation); glUniform1i(uniform_layer, 1); DrawSingleScreen( screen_infos[2], static_cast((bottom_screen_left / 2) + (layout.width / 2)), - bottom_screen_top, bottom_screen_width / 2, bottom_screen_height, orientation); + bottom_screen_top, bottom_screen_width / 2, bottom_screen_height, layout.orientation); break; } case Settings::StereoRenderOption::CardboardVR: { DrawSingleScreen(screen_infos[2], bottom_screen_left, bottom_screen_top, - bottom_screen_width, bottom_screen_height, orientation); + bottom_screen_width, bottom_screen_height, layout.orientation); glUniform1i(uniform_layer, 1); DrawSingleScreen( screen_infos[2], static_cast(layout.cardboard.bottom_screen_right_eye + (layout.width / 2)), - bottom_screen_top, bottom_screen_width, bottom_screen_height, orientation); + bottom_screen_top, bottom_screen_width, bottom_screen_height, layout.orientation); break; } case Settings::StereoRenderOption::Anaglyph: @@ -811,7 +806,7 @@ void RendererOpenGL::DrawBottomScreen(const Layout::FramebufferLayout& layout, case Settings::StereoRenderOption::ReverseInterlaced: { DrawSingleScreenStereo(screen_infos[2], screen_infos[2], bottom_screen_left, bottom_screen_top, bottom_screen_width, bottom_screen_height, - orientation); + layout.orientation); break; } } diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 74a231bff706..3c94d59a3680 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -682,37 +682,35 @@ void RendererVulkan::DrawTopScreen(const Layout::FramebufferLayout& layout, const float top_screen_width = static_cast(top_screen.GetWidth()); const float top_screen_height = static_cast(top_screen.GetHeight()); - const auto orientation = layout.is_rotated ? Layout::DisplayOrientation::Landscape - : Layout::DisplayOrientation::Portrait; switch (Settings::values.render_3d.GetValue()) { case Settings::StereoRenderOption::Off: { const int eye = static_cast(Settings::values.mono_render_option.GetValue()); DrawSingleScreen(eye, top_screen_left, top_screen_top, top_screen_width, top_screen_height, - orientation); + layout.orientation); break; } case Settings::StereoRenderOption::SideBySide: { DrawSingleScreen(0, top_screen_left / 2, top_screen_top, top_screen_width / 2, - top_screen_height, orientation); + top_screen_height, layout.orientation); draw_info.layer = 1; DrawSingleScreen(1, static_cast((top_screen_left / 2) + (layout.width / 2)), - top_screen_top, top_screen_width / 2, top_screen_height, orientation); + top_screen_top, top_screen_width / 2, top_screen_height, layout.orientation); break; } case Settings::StereoRenderOption::CardboardVR: { DrawSingleScreen(0, top_screen_left, top_screen_top, top_screen_width, top_screen_height, - orientation); + layout.orientation); draw_info.layer = 1; DrawSingleScreen( 1, static_cast(layout.cardboard.top_screen_right_eye + (layout.width / 2)), - top_screen_top, top_screen_width, top_screen_height, orientation); + top_screen_top, top_screen_width, top_screen_height, layout.orientation); break; } case Settings::StereoRenderOption::Anaglyph: case Settings::StereoRenderOption::Interlaced: case Settings::StereoRenderOption::ReverseInterlaced: { DrawSingleScreenStereo(0, 1, top_screen_left, top_screen_top, top_screen_width, - top_screen_height, orientation); + top_screen_height, layout.orientation); break; } } @@ -729,38 +727,36 @@ void RendererVulkan::DrawBottomScreen(const Layout::FramebufferLayout& layout, const float bottom_screen_width = static_cast(bottom_screen.GetWidth()); const float bottom_screen_height = static_cast(bottom_screen.GetHeight()); - const auto orientation = layout.is_rotated ? Layout::DisplayOrientation::Landscape - : Layout::DisplayOrientation::Portrait; switch (Settings::values.render_3d.GetValue()) { case Settings::StereoRenderOption::Off: { DrawSingleScreen(2, bottom_screen_left, bottom_screen_top, bottom_screen_width, - bottom_screen_height, orientation); + bottom_screen_height, layout.orientation); break; } case Settings::StereoRenderOption::SideBySide: { DrawSingleScreen(2, bottom_screen_left / 2, bottom_screen_top, bottom_screen_width / 2, - bottom_screen_height, orientation); + bottom_screen_height, layout.orientation); draw_info.layer = 1; DrawSingleScreen(2, static_cast((bottom_screen_left / 2) + (layout.width / 2)), bottom_screen_top, bottom_screen_width / 2, bottom_screen_height, - orientation); + layout.orientation); break; } case Settings::StereoRenderOption::CardboardVR: { DrawSingleScreen(2, bottom_screen_left, bottom_screen_top, bottom_screen_width, - bottom_screen_height, orientation); + bottom_screen_height, layout.orientation); draw_info.layer = 1; DrawSingleScreen( 2, static_cast(layout.cardboard.bottom_screen_right_eye + (layout.width / 2)), - bottom_screen_top, bottom_screen_width, bottom_screen_height, orientation); + bottom_screen_top, bottom_screen_width, bottom_screen_height, layout.orientation); break; } case Settings::StereoRenderOption::Anaglyph: case Settings::StereoRenderOption::Interlaced: case Settings::StereoRenderOption::ReverseInterlaced: { DrawSingleScreenStereo(2, 2, bottom_screen_left, bottom_screen_top, bottom_screen_width, - bottom_screen_height, orientation); + bottom_screen_height, layout.orientation); break; } }