framebuffer_layout.cpp mini refactor (#7300)
* framebuffer_layout.cpp: simplify FrameLayoutFromResolutionScale
- upright_screen seems to only be swapped width and height calculation, so it is replaced with std::swap
- Get rid of call to GetCardboardSettings, The FrameLayoutFromResolutionScale function is used for Screenshots and Video Dumping where we dont need 3D effects
* framebuffer_layout.cpp: Combine SideFrameLayout and MobileLandscapeFrameLayout into variants of LargeFrameLayout
* framebuffer_layout.{cpp,h}: rename maxRectangle to MaxRectangle, plus
minor documentation update
* clang-format
			
			
This commit is contained in:
		| @@ -173,8 +173,7 @@ void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { | ||||
|     TouchPressed(framebuffer_x, framebuffer_y); | ||||
| } | ||||
|  | ||||
| void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height, | ||||
|                                                bool is_portrait_mode) { | ||||
| void EmuWindow::UpdateCurrentFramebufferLayout(u32 width, u32 height, bool is_portrait_mode) { | ||||
|     Layout::FramebufferLayout layout; | ||||
|  | ||||
|     // If in portrait mode, only the MobilePortrait option really makes sense | ||||
| @@ -200,7 +199,8 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height, | ||||
|             layout = | ||||
|                 Layout::LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                          Settings::values.upright_screen.GetValue(), | ||||
|                                          Settings::values.large_screen_proportion.GetValue()); | ||||
|                                          Settings::values.large_screen_proportion.GetValue(), | ||||
|                                          Layout::VerticalAlignment::Bottom); | ||||
|             break; | ||||
|         case Settings::LayoutOption::HybridScreen: | ||||
|             layout = | ||||
| @@ -208,8 +208,10 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height, | ||||
|                                            Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::SideScreen: | ||||
|             layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                              Settings::values.upright_screen.GetValue()); | ||||
|             layout = | ||||
|                 Layout::LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                          Settings::values.upright_screen.GetValue(), 1.0f, | ||||
|                                          Layout::VerticalAlignment::Bottom); | ||||
|             break; | ||||
| #ifndef ANDROID | ||||
|         case Settings::LayoutOption::SeparateWindows: | ||||
| @@ -222,8 +224,9 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height, | ||||
|                                                        Settings::values.swap_screen.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::MobileLandscape: | ||||
|             layout = Layout::MobileLandscapeFrameLayout( | ||||
|                 width, height, Settings::values.swap_screen.GetValue(), 2.25f, false); | ||||
|             layout = | ||||
|                 Layout::LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                          false, 2.25f, Layout::VerticalAlignment::Top); | ||||
|             break; | ||||
|         case Settings::LayoutOption::Default: | ||||
|         default: | ||||
|   | ||||
| @@ -30,7 +30,7 @@ u32 FramebufferLayout::GetScalingRatio() const { | ||||
|  | ||||
| // Finds the largest size subrectangle contained in window area that is confined to the aspect ratio | ||||
| template <class T> | ||||
| static Common::Rectangle<T> maxRectangle(Common::Rectangle<T> window_area, | ||||
| static Common::Rectangle<T> MaxRectangle(Common::Rectangle<T> window_area, | ||||
|                                          float screen_aspect_ratio) { | ||||
|     float scale = std::min(static_cast<float>(window_area.GetWidth()), | ||||
|                            window_area.GetHeight() / screen_aspect_ratio); | ||||
| @@ -50,15 +50,15 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool swapped, bool u | ||||
|     if (upright) { | ||||
|         // 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); | ||||
|         bot_screen = maxRectangle(screen_window_area, BOT_SCREEN_UPRIGHT_ASPECT_RATIO); | ||||
|         top_screen = MaxRectangle(screen_window_area, TOP_SCREEN_UPRIGHT_ASPECT_RATIO); | ||||
|         bot_screen = MaxRectangle(screen_window_area, BOT_SCREEN_UPRIGHT_ASPECT_RATIO); | ||||
|         // both screens width are taken into account by dividing by 2 | ||||
|         emulation_aspect_ratio = TOP_SCREEN_UPRIGHT_ASPECT_RATIO / 2; | ||||
|     } else { | ||||
|         // Default layout gives equal screen sizes to the top and bottom screen | ||||
|         screen_window_area = {0, 0, width, height / 2}; | ||||
|         top_screen = maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); | ||||
|         bot_screen = maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||||
|         top_screen = MaxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); | ||||
|         bot_screen = MaxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||||
|         // both screens height are taken into account by multiplying by 2 | ||||
|         emulation_aspect_ratio = TOP_SCREEN_ASPECT_RATIO * 2; | ||||
|     } | ||||
| @@ -71,7 +71,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool swapped, bool u | ||||
|             // Recalculate the bottom screen to account for the height difference between right and | ||||
|             // left | ||||
|             screen_window_area = {0, 0, top_screen.GetWidth(), height}; | ||||
|             bot_screen = maxRectangle(screen_window_area, BOT_SCREEN_UPRIGHT_ASPECT_RATIO); | ||||
|             bot_screen = MaxRectangle(screen_window_area, BOT_SCREEN_UPRIGHT_ASPECT_RATIO); | ||||
|             bot_screen = | ||||
|                 bot_screen.TranslateY((top_screen.GetHeight() - bot_screen.GetHeight()) / 2); | ||||
|             if (swapped) { | ||||
| @@ -96,7 +96,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool swapped, bool u | ||||
|             // Recalculate the bottom screen to account for the width difference between top and | ||||
|             // bottom | ||||
|             screen_window_area = {0, 0, width, top_screen.GetHeight()}; | ||||
|             bot_screen = maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||||
|             bot_screen = MaxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||||
|             bot_screen = bot_screen.TranslateX((top_screen.GetWidth() - bot_screen.GetWidth()) / 2); | ||||
|             if (swapped) { | ||||
|                 bot_screen = bot_screen.TranslateY(height / 2 - bot_screen.GetHeight()); | ||||
| @@ -124,8 +124,8 @@ FramebufferLayout MobilePortraitFrameLayout(u32 width, u32 height, bool swapped) | ||||
|     FramebufferLayout res{width, height, true, true, {}, {}}; | ||||
|     // Default layout gives equal screen sizes to the top and bottom screen | ||||
|     Common::Rectangle<u32> screen_window_area{0, 0, width, height / 2}; | ||||
|     Common::Rectangle<u32> top_screen = maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); | ||||
|     Common::Rectangle<u32> bot_screen = maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||||
|     Common::Rectangle<u32> top_screen = MaxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); | ||||
|     Common::Rectangle<u32> bot_screen = MaxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||||
|  | ||||
|     float window_aspect_ratio = static_cast<float>(height) / width; | ||||
|     // both screens height are taken into account by multiplying by 2 | ||||
| @@ -151,48 +151,6 @@ FramebufferLayout MobilePortraitFrameLayout(u32 width, u32 height, bool swapped) | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| FramebufferLayout MobileLandscapeFrameLayout(u32 width, u32 height, bool swapped, | ||||
|                                              float scale_factor, bool center_vertical) { | ||||
|     ASSERT(width > 0); | ||||
|     ASSERT(height > 0); | ||||
|  | ||||
|     FramebufferLayout res{width, height, true, true, {}, {}}; | ||||
|     // 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<float>(height) / width; | ||||
|     float emulation_aspect_ratio = | ||||
|         swapped ? Core::kScreenBottomHeight * scale_factor / | ||||
|                       (Core::kScreenBottomWidth * scale_factor + Core::kScreenTopWidth) | ||||
|                 : Core::kScreenTopHeight * scale_factor / | ||||
|                       (Core::kScreenTopWidth * scale_factor + Core::kScreenBottomWidth); | ||||
|     float large_screen_aspect_ratio = swapped ? BOT_SCREEN_ASPECT_RATIO : TOP_SCREEN_ASPECT_RATIO; | ||||
|     float small_screen_aspect_ratio = swapped ? TOP_SCREEN_ASPECT_RATIO : BOT_SCREEN_ASPECT_RATIO; | ||||
|  | ||||
|     Common::Rectangle<u32> screen_window_area{0, 0, width, height}; | ||||
|     Common::Rectangle<u32> total_rect = maxRectangle(screen_window_area, emulation_aspect_ratio); | ||||
|     Common::Rectangle<u32> large_screen = maxRectangle(total_rect, large_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> fourth_size_rect = total_rect.Scale(1.f / scale_factor); | ||||
|     Common::Rectangle<u32> small_screen = maxRectangle(fourth_size_rect, small_screen_aspect_ratio); | ||||
|  | ||||
|     if (window_aspect_ratio < emulation_aspect_ratio) { | ||||
|         large_screen = | ||||
|             large_screen.TranslateX((screen_window_area.GetWidth() - total_rect.GetWidth()) / 2); | ||||
|     } else if (center_vertical) { | ||||
|         large_screen = large_screen.TranslateY((height - total_rect.GetHeight()) / 2); | ||||
|     } | ||||
|  | ||||
|     // Shift the small screen to the bottom right corner | ||||
|     small_screen = small_screen.TranslateX(large_screen.right); | ||||
|     if (center_vertical) { | ||||
|         small_screen = small_screen.TranslateY(large_screen.GetHeight() + large_screen.top - | ||||
|                                                small_screen.GetHeight()); | ||||
|     } | ||||
|  | ||||
|     res.top_screen = swapped ? small_screen : large_screen; | ||||
|     res.bottom_screen = swapped ? large_screen : small_screen; | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, bool upright) { | ||||
|     ASSERT(width > 0); | ||||
|     ASSERT(height > 0); | ||||
| @@ -205,13 +163,13 @@ FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, bool up | ||||
|     Common::Rectangle<u32> bot_screen; | ||||
|     float emulation_aspect_ratio; | ||||
|     if (upright) { | ||||
|         top_screen = maxRectangle(screen_window_area, TOP_SCREEN_UPRIGHT_ASPECT_RATIO); | ||||
|         bot_screen = maxRectangle(screen_window_area, BOT_SCREEN_UPRIGHT_ASPECT_RATIO); | ||||
|         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 = | ||||
|             (swapped) ? BOT_SCREEN_UPRIGHT_ASPECT_RATIO : TOP_SCREEN_UPRIGHT_ASPECT_RATIO; | ||||
|     } else { | ||||
|         top_screen = maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); | ||||
|         bot_screen = maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||||
|         top_screen = MaxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO); | ||||
|         bot_screen = MaxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO); | ||||
|         emulation_aspect_ratio = (swapped) ? BOT_SCREEN_ASPECT_RATIO : TOP_SCREEN_ASPECT_RATIO; | ||||
|     } | ||||
|  | ||||
| @@ -232,7 +190,7 @@ FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, bool up | ||||
| } | ||||
|  | ||||
| FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upright, | ||||
|                                    float scale_factor) { | ||||
|                                    float scale_factor, VerticalAlignment vertical_alignment) { | ||||
|     ASSERT(width > 0); | ||||
|     ASSERT(height > 0); | ||||
|  | ||||
| @@ -274,10 +232,10 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr | ||||
|     } | ||||
|  | ||||
|     Common::Rectangle<u32> screen_window_area{0, 0, width, height}; | ||||
|     Common::Rectangle<u32> total_rect = maxRectangle(screen_window_area, emulation_aspect_ratio); | ||||
|     Common::Rectangle<u32> large_screen = maxRectangle(total_rect, large_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> fourth_size_rect = total_rect.Scale(1.f / scale_factor); | ||||
|     Common::Rectangle<u32> small_screen = maxRectangle(fourth_size_rect, small_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> total_rect = MaxRectangle(screen_window_area, emulation_aspect_ratio); | ||||
|     Common::Rectangle<u32> large_screen = MaxRectangle(total_rect, large_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> scaled_rect = total_rect.Scale(1.f / scale_factor); | ||||
|     Common::Rectangle<u32> small_screen = MaxRectangle(scaled_rect, small_screen_aspect_ratio); | ||||
|  | ||||
|     if (window_aspect_ratio < emulation_aspect_ratio) { | ||||
|         large_screen = large_screen.TranslateX((width - total_rect.GetWidth()) / 2); | ||||
| @@ -286,13 +244,46 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr | ||||
|     } | ||||
|     if (upright) { | ||||
|         large_screen = large_screen.TranslateY(small_screen.GetHeight()); | ||||
|         small_screen = small_screen.TranslateX(large_screen.right - small_screen.GetWidth()) | ||||
|                            .TranslateY(large_screen.top - small_screen.GetHeight()); | ||||
|         small_screen = small_screen.TranslateY(large_screen.top - small_screen.GetHeight()); | ||||
|         switch (vertical_alignment) { | ||||
|         case VerticalAlignment::Top: | ||||
|             // Shift the small screen to the top right corner | ||||
|             small_screen = small_screen.TranslateX(large_screen.left); | ||||
|             break; | ||||
|         case VerticalAlignment::Middle: | ||||
|             // Shift the small screen to the center right | ||||
|             small_screen = small_screen.TranslateX( | ||||
|                 ((large_screen.GetWidth() - small_screen.GetWidth()) / 2) + large_screen.left); | ||||
|             break; | ||||
|         case VerticalAlignment::Bottom: | ||||
|             // Shift the small screen to the bottom right corner | ||||
|             small_screen = small_screen.TranslateX(large_screen.right - small_screen.GetWidth()); | ||||
|             break; | ||||
|         default: | ||||
|             UNREACHABLE(); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|     } else { | ||||
|         // Shift the small screen to the bottom right corner | ||||
|         small_screen = | ||||
|             small_screen.TranslateX(large_screen.right) | ||||
|                 .TranslateY(large_screen.GetHeight() + large_screen.top - small_screen.GetHeight()); | ||||
|         small_screen = small_screen.TranslateX(large_screen.right); | ||||
|         switch (vertical_alignment) { | ||||
|         case VerticalAlignment::Top: | ||||
|             // Shift the small screen to the top right corner | ||||
|             small_screen = small_screen.TranslateY(large_screen.top); | ||||
|             break; | ||||
|         case VerticalAlignment::Middle: | ||||
|             // Shift the small screen to the center right | ||||
|             small_screen = small_screen.TranslateY( | ||||
|                 ((large_screen.GetHeight() - small_screen.GetHeight()) / 2) + large_screen.top); | ||||
|             break; | ||||
|         case VerticalAlignment::Bottom: | ||||
|             // Shift the small screen to the bottom right corner | ||||
|             small_screen = small_screen.TranslateY(large_screen.bottom - small_screen.GetHeight()); | ||||
|             break; | ||||
|         default: | ||||
|             UNREACHABLE(); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     res.top_screen = swapped ? small_screen : large_screen; | ||||
|     res.bottom_screen = swapped ? large_screen : small_screen; | ||||
| @@ -331,11 +322,11 @@ FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, bool u | ||||
|     } | ||||
|  | ||||
|     Common::Rectangle<u32> screen_window_area{0, 0, width, height}; | ||||
|     Common::Rectangle<u32> total_rect = maxRectangle(screen_window_area, hybrid_area_aspect_ratio); | ||||
|     Common::Rectangle<u32> large_main_screen = maxRectangle(total_rect, main_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> total_rect = MaxRectangle(screen_window_area, hybrid_area_aspect_ratio); | ||||
|     Common::Rectangle<u32> large_main_screen = MaxRectangle(total_rect, main_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> side_rect = total_rect.Scale(1.f / scale_factor); | ||||
|     Common::Rectangle<u32> small_top_screen = maxRectangle(side_rect, top_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> small_bottom_screen = maxRectangle(side_rect, bot_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> small_top_screen = MaxRectangle(side_rect, top_screen_aspect_ratio); | ||||
|     Common::Rectangle<u32> small_bottom_screen = MaxRectangle(side_rect, bot_screen_aspect_ratio); | ||||
|  | ||||
|     if (window_aspect_ratio < hybrid_area_aspect_ratio) { | ||||
|         large_main_screen = large_main_screen.TranslateX((width - total_rect.GetWidth()) / 2); | ||||
| @@ -373,54 +364,6 @@ FramebufferLayout HybridScreenLayout(u32 width, u32 height, bool swapped, bool u | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| FramebufferLayout SideFrameLayout(u32 width, u32 height, bool swapped, bool upright) { | ||||
|     ASSERT(width > 0); | ||||
|     ASSERT(height > 0); | ||||
|  | ||||
|     FramebufferLayout res{width, height, true, true, {}, {}, !upright}; | ||||
|  | ||||
|     // Aspect ratio of both screens side by side | ||||
|     float emulation_aspect_ratio = | ||||
|         upright ? static_cast<float>(Core::kScreenTopWidth + Core::kScreenBottomWidth) / | ||||
|                       Core::kScreenTopHeight | ||||
|                 : static_cast<float>(Core::kScreenTopHeight) / | ||||
|                       (Core::kScreenTopWidth + Core::kScreenBottomWidth); | ||||
|  | ||||
|     float window_aspect_ratio = static_cast<float>(height) / width; | ||||
|     Common::Rectangle<u32> screen_window_area{0, 0, width, height}; | ||||
|     // Find largest Rectangle that can fit in the window size with the given aspect ratio | ||||
|     Common::Rectangle<u32> screen_rect = maxRectangle(screen_window_area, emulation_aspect_ratio); | ||||
|     // Find sizes of top and bottom screen | ||||
|     Common::Rectangle<u32> top_screen = | ||||
|         upright ? maxRectangle(screen_rect, TOP_SCREEN_UPRIGHT_ASPECT_RATIO) | ||||
|                 : maxRectangle(screen_rect, TOP_SCREEN_ASPECT_RATIO); | ||||
|     Common::Rectangle<u32> bot_screen = | ||||
|         upright ? maxRectangle(screen_rect, BOT_SCREEN_UPRIGHT_ASPECT_RATIO) | ||||
|                 : maxRectangle(screen_rect, BOT_SCREEN_ASPECT_RATIO); | ||||
|  | ||||
|     if (window_aspect_ratio < emulation_aspect_ratio) { | ||||
|         // Apply borders to the left and right sides of the window. | ||||
|         u32 shift_horizontal = (screen_window_area.GetWidth() - screen_rect.GetWidth()) / 2; | ||||
|         top_screen = top_screen.TranslateX(shift_horizontal); | ||||
|         bot_screen = bot_screen.TranslateX(shift_horizontal); | ||||
|     } else { | ||||
|         // Window is narrower than the emulation content => apply borders to the top and bottom | ||||
|         u32 shift_vertical = (screen_window_area.GetHeight() - screen_rect.GetHeight()) / 2; | ||||
|         top_screen = top_screen.TranslateY(shift_vertical); | ||||
|         bot_screen = bot_screen.TranslateY(shift_vertical); | ||||
|     } | ||||
|     if (upright) { | ||||
|         // Leave the top screen at the top if we are swapped. | ||||
|         res.top_screen = swapped ? top_screen : top_screen.TranslateY(bot_screen.GetHeight()); | ||||
|         res.bottom_screen = swapped ? bot_screen.TranslateY(top_screen.GetHeight()) : bot_screen; | ||||
|     } else { | ||||
|         // Move the top screen to the right if we are swapped. | ||||
|         res.top_screen = swapped ? top_screen.TranslateX(bot_screen.GetWidth()) : top_screen; | ||||
|         res.bottom_screen = swapped ? bot_screen : bot_screen.TranslateX(top_screen.GetWidth()); | ||||
|     } | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| FramebufferLayout SeparateWindowsLayout(u32 width, u32 height, bool is_secondary, bool upright) { | ||||
|     // 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. | ||||
| @@ -454,131 +397,103 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped) { | ||||
| } | ||||
|  | ||||
| FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondary) { | ||||
|     FramebufferLayout layout; | ||||
|     if (Settings::values.custom_layout.GetValue() == true) { | ||||
|         layout = CustomFrameLayout(std::max(Settings::values.custom_top_right.GetValue(), | ||||
|                                             Settings::values.custom_bottom_right.GetValue()), | ||||
|                                    std::max(Settings::values.custom_top_bottom.GetValue(), | ||||
|                                             Settings::values.custom_bottom_bottom.GetValue()), | ||||
|                                    Settings::values.swap_screen.GetValue()); | ||||
|     } else { | ||||
|         int width, height; | ||||
|         switch (Settings::values.layout_option.GetValue()) { | ||||
|         case Settings::LayoutOption::SingleScreen: | ||||
|         return CustomFrameLayout(std::max(Settings::values.custom_top_right.GetValue(), | ||||
|                                           Settings::values.custom_bottom_right.GetValue()), | ||||
|                                  std::max(Settings::values.custom_top_bottom.GetValue(), | ||||
|                                           Settings::values.custom_bottom_bottom.GetValue()), | ||||
|                                  Settings::values.swap_screen.GetValue()); | ||||
|     } | ||||
|  | ||||
|     int width, height; | ||||
|     switch (Settings::values.layout_option.GetValue()) { | ||||
|     case Settings::LayoutOption::SingleScreen: | ||||
| #ifndef ANDROID | ||||
|         case Settings::LayoutOption::SeparateWindows: | ||||
|     case Settings::LayoutOption::SeparateWindows: | ||||
| #endif | ||||
|         { | ||||
|             const bool swap_screens = is_secondary || Settings::values.swap_screen.GetValue(); | ||||
|             if (Settings::values.upright_screen.GetValue()) { | ||||
|                 if (swap_screens) { | ||||
|                     width = Core::kScreenBottomHeight * res_scale; | ||||
|                     height = Core::kScreenBottomWidth * res_scale; | ||||
|                 } else { | ||||
|                     width = Core::kScreenTopHeight * res_scale; | ||||
|                     height = Core::kScreenTopWidth * res_scale; | ||||
|                 } | ||||
|             } else { | ||||
|                 if (swap_screens) { | ||||
|                     width = Core::kScreenBottomWidth * res_scale; | ||||
|                     height = Core::kScreenBottomHeight * res_scale; | ||||
|                 } else { | ||||
|                     width = Core::kScreenTopWidth * res_scale; | ||||
|                     height = Core::kScreenTopHeight * res_scale; | ||||
|                 } | ||||
|             } | ||||
|             layout = SingleFrameLayout(width, height, swap_screens, | ||||
|                                        Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
|         } | ||||
|         case Settings::LayoutOption::LargeScreen: | ||||
|             if (Settings::values.upright_screen.GetValue()) { | ||||
|                 if (Settings::values.swap_screen.GetValue()) { | ||||
|                     width = Core::kScreenBottomHeight * res_scale; | ||||
|                     height = | ||||
|                         (Core::kScreenBottomWidth + | ||||
|                          static_cast<int>(Core::kScreenTopWidth / | ||||
|                                           Settings::values.large_screen_proportion.GetValue())) * | ||||
|                         res_scale; | ||||
|                 } else { | ||||
|                     width = Core::kScreenTopHeight * res_scale; | ||||
|                     height = | ||||
|                         (Core::kScreenTopWidth + | ||||
|                          static_cast<int>(Core::kScreenBottomWidth / | ||||
|                                           Settings::values.large_screen_proportion.GetValue())) * | ||||
|                         res_scale; | ||||
|                 } | ||||
|             } else { | ||||
|                 if (Settings::values.swap_screen.GetValue()) { | ||||
|                     width = (Core::kScreenBottomWidth + | ||||
|                              Core::kScreenTopWidth / | ||||
|                                  static_cast<int>( | ||||
|                                      Settings::values.large_screen_proportion.GetValue())) * | ||||
|                             res_scale; | ||||
|                     height = Core::kScreenBottomHeight * res_scale; | ||||
|                 } else { | ||||
|                     width = (Core::kScreenTopWidth + | ||||
|                              Core::kScreenBottomWidth / | ||||
|                                  static_cast<int>( | ||||
|                                      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.large_screen_proportion.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::SideScreen: | ||||
|             if (Settings::values.upright_screen.GetValue()) { | ||||
|                 width = Core::kScreenTopHeight * res_scale; | ||||
|                 height = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale; | ||||
|             } else { | ||||
|                 width = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale; | ||||
|                 height = Core::kScreenTopHeight * res_scale; | ||||
|             } | ||||
|             layout = SideFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                      Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::MobilePortrait: | ||||
|     { | ||||
|         const bool swap_screens = is_secondary || Settings::values.swap_screen.GetValue(); | ||||
|         if (swap_screens) { | ||||
|             width = Core::kScreenBottomWidth * res_scale; | ||||
|             height = Core::kScreenBottomHeight * res_scale; | ||||
|         } else { | ||||
|             width = Core::kScreenTopWidth * res_scale; | ||||
|             height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale; | ||||
|             layout = | ||||
|                 MobilePortraitFrameLayout(width, height, Settings::values.swap_screen.GetValue()); | ||||
|             break; | ||||
|         case Settings::LayoutOption::MobileLandscape: | ||||
|             if (Settings::values.swap_screen.GetValue()) { | ||||
|                 width = | ||||
|                     (Core::kScreenBottomWidth + static_cast<int>(Core::kScreenTopWidth / 2.25f)) * | ||||
|                     res_scale; | ||||
|                 height = Core::kScreenBottomHeight * res_scale; | ||||
|             } else { | ||||
|                 width = | ||||
|                     (Core::kScreenTopWidth + static_cast<int>(Core::kScreenBottomWidth / 2.25f)) * | ||||
|                     res_scale; | ||||
|                 height = Core::kScreenTopHeight * res_scale; | ||||
|             } | ||||
|             layout = MobileLandscapeFrameLayout( | ||||
|                 width, height, Settings::values.swap_screen.GetValue(), 2.25f, false); | ||||
|             break; | ||||
|         case Settings::LayoutOption::Default: | ||||
|         default: | ||||
|             if (Settings::values.upright_screen.GetValue()) { | ||||
|                 width = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale; | ||||
|                 height = Core::kScreenTopWidth * res_scale; | ||||
|             } else { | ||||
|                 width = Core::kScreenTopWidth * res_scale; | ||||
|                 height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale; | ||||
|             } | ||||
|             layout = DefaultFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                         Settings::values.upright_screen.GetValue()); | ||||
|             break; | ||||
|             height = Core::kScreenTopHeight * res_scale; | ||||
|         } | ||||
|         if (Settings::values.upright_screen.GetValue()) { | ||||
|             std::swap(width, height); | ||||
|         } | ||||
|         return SingleFrameLayout(width, height, swap_screens, | ||||
|                                  Settings::values.upright_screen.GetValue()); | ||||
|     } | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) { | ||||
|         layout = Layout::GetCardboardSettings(layout); | ||||
|  | ||||
|     case Settings::LayoutOption::LargeScreen: | ||||
|         if (Settings::values.swap_screen.GetValue()) { | ||||
|             width = (Core::kScreenBottomWidth + | ||||
|                      Core::kScreenTopWidth / | ||||
|                          static_cast<int>(Settings::values.large_screen_proportion.GetValue())) * | ||||
|                     res_scale; | ||||
|             height = Core::kScreenBottomHeight * res_scale; | ||||
|         } else { | ||||
|             width = (Core::kScreenTopWidth + | ||||
|                      Core::kScreenBottomWidth / | ||||
|                          static_cast<int>(Settings::values.large_screen_proportion.GetValue())) * | ||||
|                     res_scale; | ||||
|             height = Core::kScreenTopHeight * res_scale; | ||||
|         } | ||||
|         if (Settings::values.upright_screen.GetValue()) { | ||||
|             std::swap(width, height); | ||||
|         } | ||||
|         return LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                 Settings::values.upright_screen.GetValue(), | ||||
|                                 Settings::values.large_screen_proportion.GetValue(), | ||||
|                                 VerticalAlignment::Bottom); | ||||
|  | ||||
|     case Settings::LayoutOption::SideScreen: | ||||
|         width = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale; | ||||
|         height = Core::kScreenTopHeight * res_scale; | ||||
|  | ||||
|         if (Settings::values.upright_screen.GetValue()) { | ||||
|             std::swap(width, height); | ||||
|         } | ||||
|         return LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                 Settings::values.upright_screen.GetValue(), 1, | ||||
|                                 VerticalAlignment::Middle); | ||||
|  | ||||
|     case Settings::LayoutOption::MobilePortrait: | ||||
|         width = Core::kScreenTopWidth * res_scale; | ||||
|         height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale; | ||||
|         return MobilePortraitFrameLayout(width, height, Settings::values.swap_screen.GetValue()); | ||||
|  | ||||
|     case Settings::LayoutOption::MobileLandscape: { | ||||
|         constexpr float large_screen_proportion = 2.25f; | ||||
|         if (Settings::values.swap_screen.GetValue()) { | ||||
|             width = (Core::kScreenBottomWidth + | ||||
|                      static_cast<int>(Core::kScreenTopWidth / large_screen_proportion)) * | ||||
|                     res_scale; | ||||
|             height = Core::kScreenBottomHeight * res_scale; | ||||
|         } else { | ||||
|             width = (Core::kScreenTopWidth + | ||||
|                      static_cast<int>(Core::kScreenBottomWidth / large_screen_proportion)) * | ||||
|                     res_scale; | ||||
|             height = Core::kScreenTopHeight * res_scale; | ||||
|         } | ||||
|         return LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(), false, | ||||
|                                 large_screen_proportion, VerticalAlignment::Top); | ||||
|     } | ||||
|     return layout; | ||||
|  | ||||
|     case Settings::LayoutOption::Default: | ||||
|     default: | ||||
|         width = Core::kScreenTopWidth * res_scale; | ||||
|         height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale; | ||||
|  | ||||
|         if (Settings::values.upright_screen.GetValue()) { | ||||
|             std::swap(width, height); | ||||
|         } | ||||
|         return DefaultFrameLayout(width, height, Settings::values.swap_screen.GetValue(), | ||||
|                                   Settings::values.upright_screen.GetValue()); | ||||
|     } | ||||
|     UNREACHABLE(); | ||||
| } | ||||
|  | ||||
| FramebufferLayout GetCardboardSettings(const FramebufferLayout& layout) { | ||||
|   | ||||
| @@ -20,6 +20,31 @@ enum class DisplayOrientation { | ||||
|     PortraitFlipped,  // 3DS rotated 270 degrees counter-clockwise | ||||
| }; | ||||
|  | ||||
| /// Describes the vertical alignment of the top and bottom screens in LargeFrameLayout | ||||
| /// Top | ||||
| /// +-------------+-----+ | ||||
| /// |             |     | | ||||
| /// |             +-----+ | ||||
| /// |             | | ||||
| /// +-------------+ | ||||
| /// Middle | ||||
| /// +-------------+ | ||||
| /// |             +-----+ | ||||
| /// |             |     | | ||||
| /// |             +-----+ | ||||
| /// +-------------+ | ||||
| /// Bottom | ||||
| /// +-------------+ | ||||
| /// |             | | ||||
| /// |             +-----+ | ||||
| /// |             |     | | ||||
| /// +-------------+-----+ | ||||
| enum class VerticalAlignment { | ||||
|     Top, | ||||
|     Middle, | ||||
|     Bottom, | ||||
| }; | ||||
|  | ||||
| /// Describes the horizontal coordinates for the right eye screen when using Cardboard VR | ||||
| struct CardboardSettings { | ||||
|     u32 top_screen_right_eye; | ||||
| @@ -43,7 +68,7 @@ struct FramebufferLayout { | ||||
|     CardboardSettings cardboard; | ||||
|  | ||||
|     /** | ||||
|      * Returns the ration of pixel size of the top screen, compared to the native size of the 3DS | ||||
|      * Returns the ratio of pixel size of the top screen, compared to the native size of the 3DS | ||||
|      * screen. | ||||
|      */ | ||||
|     u32 GetScalingRatio() const; | ||||
| @@ -54,6 +79,7 @@ struct FramebufferLayout { | ||||
|  * @param width Window framebuffer width in pixels | ||||
|  * @param height Window framebuffer height in pixels | ||||
|  * @param is_swapped if true, the bottom screen will be displayed above the top screen | ||||
|  * @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); | ||||
| @@ -67,25 +93,12 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool is_swapped, boo | ||||
|  */ | ||||
| FramebufferLayout MobilePortraitFrameLayout(u32 width, u32 height, bool is_swapped); | ||||
|  | ||||
| /** | ||||
|  * Factory method for constructing a Frame with the a 4x size Top screen with a 1x size bottom | ||||
|  * screen on the right | ||||
|  * This is useful in particular because it matches well with a 1920x1080 resolution monitor | ||||
|  * @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 Scale factor to use for bottom screen with respect to top screen | ||||
|  * @param center_vertical When true, centers the top and bottom screens vertically | ||||
|  * @return Newly created FramebufferLayout object with default screen regions initialized | ||||
|  */ | ||||
| FramebufferLayout MobileLandscapeFrameLayout(u32 width, u32 height, bool is_swapped, | ||||
|                                              float scale_factor, bool center_vertical); | ||||
|  | ||||
| /** | ||||
|  * Factory method for constructing a FramebufferLayout with only the top or bottom screen | ||||
|  * @param width Window framebuffer width in pixels | ||||
|  * @param height Window framebuffer height in pixels | ||||
|  * @param is_swapped if true, the bottom screen will be displayed (and the top won't be displayed) | ||||
|  * @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); | ||||
| @@ -97,32 +110,25 @@ 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 upright if true, the screens will be rotated 90 degrees anti-clockwise | ||||
|  * @param scale_factor The ratio between the large screen with respect to the smaller screen | ||||
|  * @param vertical_alignment The vertical alignment of the smaller screen relative to the larger | ||||
|  * screen | ||||
|  * @return Newly created FramebufferLayout object with default screen regions initialized | ||||
|  */ | ||||
| FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool is_swapped, bool upright, | ||||
|                                    float scale_factor); | ||||
|                                    float scale_factor, VerticalAlignment vertical_alignment); | ||||
| /** | ||||
|  * Factory method for constructing a frame with 2.5 times bigger top screen on the right, | ||||
|  * and 1x top and bottom screen on the left | ||||
|  * @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 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); | ||||
|  | ||||
| /** | ||||
|  * Factory method for constructing a Frame with the Top screen and bottom | ||||
|  * screen side by side | ||||
|  * This is useful for devices with small screens, like the GPDWin | ||||
|  * @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 left display | ||||
|  * @return Newly created FramebufferLayout object with default screen regions initialized | ||||
|  */ | ||||
| FramebufferLayout SideFrameLayout(u32 width, u32 height, bool is_swapped, bool upright); | ||||
|  | ||||
| /** | ||||
|  * Factory method for constructing a Frame with the Top screen and bottom | ||||
|  * screen on separate windows | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 SachinVin
					SachinVin