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
This commit is contained in:
ThaMighty90 2017-08-25 23:53:07 +02:00 committed by bunnei
parent 61442d6afb
commit 3cdf854e44
6 changed files with 61 additions and 7 deletions

View file

@ -146,17 +146,22 @@
<widget class="QComboBox" name="layout_combobox"> <widget class="QComboBox" name="layout_combobox">
<item> <item>
<property name="text"> <property name="text">
<string notr="true">Default</string> <string>Default</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string notr="true">Single Screen</string> <string>Single Screen</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string notr="true">Large Screen</string> <string>Large Screen</string>
</property>
</item>
<item>
<property name="text">
<string>Side by Side</string>
</property> </property>
</item> </item>
</widget> </widget>

View file

@ -74,6 +74,9 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height)
case Settings::LayoutOption::LargeScreen: case Settings::LayoutOption::LargeScreen:
layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen); layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen);
break; break;
case Settings::LayoutOption::SideScreen:
layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen);
break;
case Settings::LayoutOption::Default: case Settings::LayoutOption::Default:
default: default:
layout = Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen); layout = Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen);

View file

@ -141,6 +141,40 @@ FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool swapped
return res; 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<float>(Core::kScreenTopHeight) /
(Core::kScreenTopWidth + Core::kScreenBottomWidth);
float window_aspect_ratio = static_cast<float>(height) / width;
MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height};
// Find largest Rectangle that can fit in the window size with the given aspect ratio
MathUtil::Rectangle<unsigned> screen_rect =
maxRectangle(screen_window_area, emulation_aspect_ratio);
// Find sizes of top and bottom screen
MathUtil::Rectangle<unsigned> top_screen = maxRectangle(screen_rect, TOP_SCREEN_ASPECT_RATIO);
MathUtil::Rectangle<unsigned> 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) { FramebufferLayout CustomFrameLayout(unsigned width, unsigned height) {
ASSERT(width > 0); ASSERT(width > 0);
ASSERT(height > 0); ASSERT(height > 0);
@ -158,4 +192,4 @@ FramebufferLayout CustomFrameLayout(unsigned width, unsigned height) {
res.bottom_screen = bot_screen; res.bottom_screen = bot_screen;
return res; return res;
} }
} } // namespace Layout

View file

@ -53,6 +53,17 @@ FramebufferLayout SingleFrameLayout(unsigned width, unsigned height, bool is_swa
*/ */
FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool is_swapped); 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 * Factory method for constructing a custom FramebufferLayout
* @param width Window framebuffer width in pixels * @param width Window framebuffer width in pixels

View file

@ -36,4 +36,4 @@ void Apply() {
Service::IR::ReloadInputDevices(); Service::IR::ReloadInputDevices();
} }
} // namespace } // namespace Settings

View file

@ -15,6 +15,7 @@ enum class LayoutOption {
Default, Default,
SingleScreen, SingleScreen,
LargeScreen, LargeScreen,
SideScreen,
}; };
namespace NativeButton { namespace NativeButton {
@ -70,7 +71,7 @@ enum Values {
static const std::array<const char*, NumAnalogs> mapping = {{ static const std::array<const char*, NumAnalogs> mapping = {{
"circle_pad", "c_stick", "circle_pad", "c_stick",
}}; }};
} // namespace NumAnalog } // namespace NativeAnalog
struct Values { struct Values {
// CheckNew3DS // CheckNew3DS
@ -137,4 +138,4 @@ struct Values {
static constexpr int REGION_VALUE_AUTO_SELECT = -1; static constexpr int REGION_VALUE_AUTO_SELECT = -1;
void Apply(); void Apply();
} } // namespace Settings