From 3cdf854e44e7ff088fa0cbdcfa2bcc6e41822b2c Mon Sep 17 00:00:00 2001
From: ThaMighty90 <30285364+ThaMighty90@users.noreply.github.com>
Date: Fri, 25 Aug 2017 23:53:07 +0200
Subject: [PATCH] SidebySide Layout (#2859)
* added a SidebySide Layout
* Reworked, so both screen have the same height and cleaned up screen translates.
* added the option in the UI, hope this is the right way to do it. formated framebuffer_layout.cpp
* delete the x64 files
* deleted ui_configure_graphics.h
* added Option for the Layout in the xml
* got rid of SIDE_BY_SIDE_ASPECT_RATIO because it was useless. pulled translate into variables
* changed shift variables to u32 and moved them in their respective branch. remove notr="true" for the Screen layout drop down
* reworked intends :). changed function description for SideFrameLayout
* some description reworking
---
.../configuration/configure_graphics.ui | 11 ++++--
src/core/frontend/emu_window.cpp | 3 ++
src/core/frontend/framebuffer_layout.cpp | 36 ++++++++++++++++++-
src/core/frontend/framebuffer_layout.h | 11 ++++++
src/core/settings.cpp | 2 +-
src/core/settings.h | 5 +--
6 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/src/citra_qt/configuration/configure_graphics.ui b/src/citra_qt/configuration/configure_graphics.ui
index 228f2a869..b340149d5 100644
--- a/src/citra_qt/configuration/configure_graphics.ui
+++ b/src/citra_qt/configuration/configure_graphics.ui
@@ -146,17 +146,22 @@
-
- Default
+ Default
-
- Single Screen
+ Single Screen
-
- Large Screen
+ Large Screen
+
+
+ -
+
+ Side by Side
diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp
index 60b20d4e2..54fa5c7fa 100644
--- a/src/core/frontend/emu_window.cpp
+++ b/src/core/frontend/emu_window.cpp
@@ -74,6 +74,9 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height)
case Settings::LayoutOption::LargeScreen:
layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen);
break;
+ case Settings::LayoutOption::SideScreen:
+ layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen);
+ break;
case Settings::LayoutOption::Default:
default:
layout = Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen);
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index d2d02f9ff..e9f778fcb 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -141,6 +141,40 @@ FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool swapped
return res;
}
+FramebufferLayout SideFrameLayout(unsigned width, unsigned height, bool swapped) {
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+
+ FramebufferLayout res{width, height, true, true, {}, {}};
+ // Aspect ratio of both screens side by side
+ const float emulation_aspect_ratio = static_cast(Core::kScreenTopHeight) /
+ (Core::kScreenTopWidth + Core::kScreenBottomWidth);
+ float window_aspect_ratio = static_cast(height) / width;
+ MathUtil::Rectangle screen_window_area{0, 0, width, height};
+ // Find largest Rectangle that can fit in the window size with the given aspect ratio
+ MathUtil::Rectangle screen_rect =
+ maxRectangle(screen_window_area, emulation_aspect_ratio);
+ // Find sizes of top and bottom screen
+ MathUtil::Rectangle top_screen = maxRectangle(screen_rect, TOP_SCREEN_ASPECT_RATIO);
+ MathUtil::Rectangle bot_screen = 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);
+ }
+ // 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 CustomFrameLayout(unsigned width, unsigned height) {
ASSERT(width > 0);
ASSERT(height > 0);
@@ -158,4 +192,4 @@ FramebufferLayout CustomFrameLayout(unsigned width, unsigned height) {
res.bottom_screen = bot_screen;
return res;
}
-}
+} // namespace Layout
diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h
index 9a7738969..4983cf103 100644
--- a/src/core/frontend/framebuffer_layout.h
+++ b/src/core/frontend/framebuffer_layout.h
@@ -53,6 +53,17 @@ FramebufferLayout SingleFrameLayout(unsigned width, unsigned height, bool is_swa
*/
FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool is_swapped);
+/**
+* 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(unsigned width, unsigned height, bool is_swapped);
+
/**
* Factory method for constructing a custom FramebufferLayout
* @param width Window framebuffer width in pixels
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index d4f0429d1..efcf1267d 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -36,4 +36,4 @@ void Apply() {
Service::IR::ReloadInputDevices();
}
-} // namespace
+} // namespace Settings
diff --git a/src/core/settings.h b/src/core/settings.h
index 7e15b119b..ca657719a 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -15,6 +15,7 @@ enum class LayoutOption {
Default,
SingleScreen,
LargeScreen,
+ SideScreen,
};
namespace NativeButton {
@@ -70,7 +71,7 @@ enum Values {
static const std::array mapping = {{
"circle_pad", "c_stick",
}};
-} // namespace NumAnalog
+} // namespace NativeAnalog
struct Values {
// CheckNew3DS
@@ -137,4 +138,4 @@ struct Values {
static constexpr int REGION_VALUE_AUTO_SELECT = -1;
void Apply();
-}
+} // namespace Settings