From be88d2a59aa2d61a44264e468e7269da36f83f5c Mon Sep 17 00:00:00 2001 From: Vitor Kiguchi Date: Wed, 8 Jan 2020 17:57:41 -0300 Subject: [PATCH] implement upright orientation for side and large frame layouts --- src/core/frontend/framebuffer_layout.cpp | 114 +++++++++++++++++------ 1 file changed, 85 insertions(+), 29 deletions(-) diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index 2c6c9cdce..cb7993271 100644 --- a/src/core/frontend/framebuffer_layout.cpp +++ b/src/core/frontend/framebuffer_layout.cpp @@ -159,17 +159,38 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr ASSERT(width > 0); ASSERT(height > 0); - FramebufferLayout res{width, height, true, true, {}, {}, true}; + FramebufferLayout res{width, height, true, true, {}, {}, !upright}; // 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 = - swapped ? Core::kScreenBottomHeight * 4 / - (Core::kScreenBottomWidth * 4.0f + Core::kScreenTopWidth) - : Core::kScreenTopHeight * 4 / - (Core::kScreenTopWidth * 4.0f + 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; + float emulation_aspect_ratio; + float large_screen_aspect_ratio; + float small_screen_aspect_ratio; + if (upright) { + if (swapped) { + emulation_aspect_ratio = (Core::kScreenBottomWidth * 4.0f + Core::kScreenTopWidth) / + (Core::kScreenBottomHeight * 4); + 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); + 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); + 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); + large_screen_aspect_ratio = TOP_SCREEN_ASPECT_RATIO; + small_screen_aspect_ratio = BOT_SCREEN_ASPECT_RATIO; + } + } Common::Rectangle screen_window_area{0, 0, width, height}; Common::Rectangle total_rect = maxRectangle(screen_window_area, emulation_aspect_ratio); @@ -178,15 +199,20 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr Common::Rectangle 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); + large_screen = large_screen.TranslateX((width - total_rect.GetWidth()) / 2); } else { 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) - .TranslateY(large_screen.GetHeight() + large_screen.top - small_screen.GetHeight()); + 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()); + } 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()); + } res.top_screen = swapped ? small_screen : large_screen; res.bottom_screen = swapped ? large_screen : small_screen; return res; @@ -196,17 +222,26 @@ FramebufferLayout SideFrameLayout(u32 width, u32 height, bool swapped, bool upri ASSERT(width > 0); ASSERT(height > 0); - FramebufferLayout res{width, height, true, true, {}, {}, true}; + FramebufferLayout res{width, height, true, true, {}, {}, !upright}; + // Aspect ratio of both screens side by side - const float emulation_aspect_ratio = static_cast(Core::kScreenTopHeight) / - (Core::kScreenTopWidth + Core::kScreenBottomWidth); + float emulation_aspect_ratio = + upright ? static_cast(Core::kScreenTopWidth + Core::kScreenBottomWidth) / + Core::kScreenTopHeight + : static_cast(Core::kScreenTopHeight) / + (Core::kScreenTopWidth + Core::kScreenBottomWidth); + float window_aspect_ratio = static_cast(height) / width; Common::Rectangle screen_window_area{0, 0, width, height}; // Find largest Rectangle that can fit in the window size with the given aspect ratio Common::Rectangle screen_rect = maxRectangle(screen_window_area, emulation_aspect_ratio); // Find sizes of top and bottom screen - Common::Rectangle top_screen = maxRectangle(screen_rect, TOP_SCREEN_ASPECT_RATIO); - Common::Rectangle bot_screen = maxRectangle(screen_rect, BOT_SCREEN_ASPECT_RATIO); + Common::Rectangle top_screen = + upright ? maxRectangle(screen_rect, TOP_SCREEN_UPRIGHT_ASPECT_RATIO) + : maxRectangle(screen_rect, TOP_SCREEN_ASPECT_RATIO); + Common::Rectangle 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. @@ -219,9 +254,15 @@ FramebufferLayout SideFrameLayout(u32 width, u32 height, bool swapped, bool upri top_screen = top_screen.TranslateY(shift_vertical); bot_screen = bot_screen.TranslateY(shift_vertical); } - // 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()); + 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; } @@ -274,19 +315,34 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale) { Settings::values.upright_screen); break; case Settings::LayoutOption::LargeScreen: - if (Settings::values.swap_screen) { - width = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale; - height = Core::kScreenBottomHeight * res_scale; + if (Settings::values.upright_screen) { + if (Settings::values.swap_screen) { + width = Core::kScreenBottomHeight * res_scale; + height = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale; + } else { + width = Core::kScreenTopHeight * res_scale; + height = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 4) * res_scale; + } } else { - width = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 4) * res_scale; - height = Core::kScreenTopHeight * res_scale; + if (Settings::values.swap_screen) { + width = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale; + height = Core::kScreenBottomHeight * res_scale; + } else { + width = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 4) * res_scale; + height = Core::kScreenTopHeight * res_scale; + } } layout = LargeFrameLayout(width, height, Settings::values.swap_screen, Settings::values.upright_screen); break; case Settings::LayoutOption::SideScreen: - width = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale; - height = Core::kScreenTopHeight * res_scale; + if (Settings::values.upright_screen) { + 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, Settings::values.upright_screen); break;