Merge 501ac3a5734c498f372774b4a88f6ce15350c585 into 42d77cd720eb42845c2afb77c6d7157e02c8c325

This commit is contained in:
David Griswold 2025-03-13 02:31:00 -03:00 committed by GitHub
commit f8793a6090
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 88 additions and 17 deletions

View File

@ -33,6 +33,7 @@ enum class IntSetting(
LANDSCAPE_BOTTOM_Y("custom_bottom_y",Settings.SECTION_LAYOUT,480), LANDSCAPE_BOTTOM_Y("custom_bottom_y",Settings.SECTION_LAYOUT,480),
LANDSCAPE_BOTTOM_WIDTH("custom_bottom_width",Settings.SECTION_LAYOUT,640), LANDSCAPE_BOTTOM_WIDTH("custom_bottom_width",Settings.SECTION_LAYOUT,640),
LANDSCAPE_BOTTOM_HEIGHT("custom_bottom_height",Settings.SECTION_LAYOUT,480), LANDSCAPE_BOTTOM_HEIGHT("custom_bottom_height",Settings.SECTION_LAYOUT,480),
SCREEN_GAP("screen_gap",Settings.SECTION_LAYOUT,0),
PORTRAIT_SCREEN_LAYOUT("portrait_layout_option",Settings.SECTION_LAYOUT,0), PORTRAIT_SCREEN_LAYOUT("portrait_layout_option",Settings.SECTION_LAYOUT,0),
PORTRAIT_TOP_X("custom_portrait_top_x",Settings.SECTION_LAYOUT,0), PORTRAIT_TOP_X("custom_portrait_top_x",Settings.SECTION_LAYOUT,0),
PORTRAIT_TOP_Y("custom_portrait_top_y",Settings.SECTION_LAYOUT,0), PORTRAIT_TOP_Y("custom_portrait_top_y",Settings.SECTION_LAYOUT,0),

View File

@ -973,6 +973,18 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
IntSetting.SMALL_SCREEN_POSITION.defaultValue IntSetting.SMALL_SCREEN_POSITION.defaultValue
) )
) )
add(
SliderSetting(
IntSetting.SCREEN_GAP,
R.string.screen_gap,
R.string.screen_gap_description,
0,
480,
"px",
IntSetting.SCREEN_GAP.key,
IntSetting.SCREEN_GAP.defaultValue.toFloat()
)
)
add( add(
SliderSetting( SliderSetting(
FloatSetting.LARGE_SCREEN_PROPORTION, FloatSetting.LARGE_SCREEN_PROPORTION,

View File

@ -183,11 +183,13 @@ void Config::ReadValues() {
layoutInt = static_cast<int>(Settings::LayoutOption::LargeScreen); layoutInt = static_cast<int>(Settings::LayoutOption::LargeScreen);
} }
Settings::values.layout_option = static_cast<Settings::LayoutOption>(layoutInt); Settings::values.layout_option = static_cast<Settings::LayoutOption>(layoutInt);
Settings::values.screen_gap = static_cast<float>(sdl2_config->GetReal("Layout","screen_gap",0));
Settings::values.large_screen_proportion = Settings::values.large_screen_proportion =
static_cast<float>(sdl2_config->GetReal("Layout", "large_screen_proportion", 2.25)); static_cast<float>(sdl2_config->GetReal("Layout", "large_screen_proportion", 2.25));
Settings::values.small_screen_position = static_cast<Settings::SmallScreenPosition>( Settings::values.small_screen_position = static_cast<Settings::SmallScreenPosition>(
sdl2_config->GetInteger("Layout", "small_screen_position", sdl2_config->GetInteger("Layout", "small_screen_position",
static_cast<int>(Settings::SmallScreenPosition::TopRight))); static_cast<int>(Settings::SmallScreenPosition::TopRight)));
ReadSetting("Layout",Settings::values.screen_gap);
ReadSetting("Layout", Settings::values.custom_top_x); ReadSetting("Layout", Settings::values.custom_top_x);
ReadSetting("Layout", Settings::values.custom_top_y); ReadSetting("Layout", Settings::values.custom_top_y);
ReadSetting("Layout", Settings::values.custom_top_width); ReadSetting("Layout", Settings::values.custom_top_width);

View File

@ -197,6 +197,12 @@ disable_right_eye_render =
# 5: Custom Layout # 5: Custom Layout
layout_option = layout_option =
# Screen Gap - adds a gap between screens in all two-screen modes
# Measured in pixels relative to the 240px default height of the screens
# Scales with the larger screen (so 24 is 10% of the larger screen height)
# Default value is 0.0
screen_gap =
# Large Screen Proportion - Relative size of large:small in large screen mode # Large Screen Proportion - Relative size of large:small in large screen mode
# Default value is 2.25 # Default value is 2.25
large_screen_proportion = large_screen_proportion =

View File

@ -384,6 +384,8 @@
<string name="small_screen_position_bottom_left">Bottom Left</string> <string name="small_screen_position_bottom_left">Bottom Left</string>
<string name="small_screen_position_above">Above</string> <string name="small_screen_position_above">Above</string>
<string name="small_screen_position_below">Below</string> <string name="small_screen_position_below">Below</string>
<string name="screen_gap">Screen Gap</string>
<string name="screen_gap_description">Gap between screens in all two-screen modes. Measured in px relative to the 240px height of the larger screen.</string>
<string name="large_screen_proportion">Large Screen Proportion</string> <string name="large_screen_proportion">Large Screen Proportion</string>
<string name="large_screen_proportion_description">How many times larger is the large screen than the small screen in Large Screen layout?</string> <string name="large_screen_proportion_description">How many times larger is the large screen than the small screen in Large Screen layout?</string>
<string name="emulation_adjust_custom_layout">Adjust Custom Layout in Settings</string> <string name="emulation_adjust_custom_layout">Adjust Custom Layout in Settings</string>

View File

@ -519,6 +519,7 @@ void QtConfig::ReadLayoutValues() {
ReadGlobalSetting(Settings::values.swap_screen); ReadGlobalSetting(Settings::values.swap_screen);
ReadGlobalSetting(Settings::values.upright_screen); ReadGlobalSetting(Settings::values.upright_screen);
ReadGlobalSetting(Settings::values.large_screen_proportion); ReadGlobalSetting(Settings::values.large_screen_proportion);
ReadGlobalSetting(Settings::values.screen_gap);
ReadGlobalSetting(Settings::values.small_screen_position); ReadGlobalSetting(Settings::values.small_screen_position);
if (global) { if (global) {
@ -1076,6 +1077,7 @@ void QtConfig::SaveLayoutValues() {
WriteGlobalSetting(Settings::values.swap_screen); WriteGlobalSetting(Settings::values.swap_screen);
WriteGlobalSetting(Settings::values.upright_screen); WriteGlobalSetting(Settings::values.upright_screen);
WriteGlobalSetting(Settings::values.large_screen_proportion); WriteGlobalSetting(Settings::values.large_screen_proportion);
WriteGlobalSetting(Settings::values.screen_gap);
WriteGlobalSetting(Settings::values.small_screen_position); WriteGlobalSetting(Settings::values.small_screen_position);
if (global) { if (global) {
WriteBasicSetting(Settings::values.mono_render_option); WriteBasicSetting(Settings::values.mono_render_option);

View File

@ -124,6 +124,7 @@ void ConfigureLayout::SetConfiguration() {
ui->toggle_swap_screen->setChecked(Settings::values.swap_screen.GetValue()); ui->toggle_swap_screen->setChecked(Settings::values.swap_screen.GetValue());
ui->toggle_upright_screen->setChecked(Settings::values.upright_screen.GetValue()); ui->toggle_upright_screen->setChecked(Settings::values.upright_screen.GetValue());
ui->screen_gap->setValue(Settings::values.screen_gap.GetValue());
ui->large_screen_proportion->setValue(Settings::values.large_screen_proportion.GetValue()); ui->large_screen_proportion->setValue(Settings::values.large_screen_proportion.GetValue());
ui->small_screen_position_combobox->setCurrentIndex( ui->small_screen_position_combobox->setCurrentIndex(
static_cast<int>(Settings::values.small_screen_position.GetValue())); static_cast<int>(Settings::values.small_screen_position.GetValue()));
@ -163,6 +164,7 @@ void ConfigureLayout::RetranslateUI() {
void ConfigureLayout::ApplyConfiguration() { void ConfigureLayout::ApplyConfiguration() {
Settings::values.large_screen_proportion = ui->large_screen_proportion->value(); Settings::values.large_screen_proportion = ui->large_screen_proportion->value();
Settings::values.screen_gap = ui->screen_gap->value();
Settings::values.small_screen_position = static_cast<Settings::SmallScreenPosition>( Settings::values.small_screen_position = static_cast<Settings::SmallScreenPosition>(
ui->small_screen_position_combobox->currentIndex()); ui->small_screen_position_combobox->currentIndex());
Settings::values.custom_top_x = ui->custom_top_x->value(); Settings::values.custom_top_x = ui->custom_top_x->value();

View File

@ -107,6 +107,44 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="screen_gap_layout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Screen Gap</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="screen_gap">
<property name="minimum">
<double>0.0</double>
</property>
<property name="maximum">
<double>720.0</double>
</property>
<property name="value">
<double>0.0</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QWidget" name="widget" native="true"> <widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="proportion_layout"> <layout class="QHBoxLayout" name="proportion_layout">

View File

@ -115,6 +115,7 @@ void LogSettings() {
log_setting("Layout_PortraitLayoutOption", values.portrait_layout_option.GetValue()); log_setting("Layout_PortraitLayoutOption", values.portrait_layout_option.GetValue());
log_setting("Layout_SwapScreen", values.swap_screen.GetValue()); log_setting("Layout_SwapScreen", values.swap_screen.GetValue());
log_setting("Layout_UprightScreen", values.upright_screen.GetValue()); log_setting("Layout_UprightScreen", values.upright_screen.GetValue());
log_setting("Layout_ScreenGap",values.screen_gap.GetValue());
log_setting("Layout_LargeScreenProportion", values.large_screen_proportion.GetValue()); log_setting("Layout_LargeScreenProportion", values.large_screen_proportion.GetValue());
log_setting("Layout_SmallScreenPosition", values.small_screen_position.GetValue()); log_setting("Layout_SmallScreenPosition", values.small_screen_position.GetValue());
log_setting("Utility_DumpTextures", values.dump_textures.GetValue()); log_setting("Utility_DumpTextures", values.dump_textures.GetValue());
@ -208,6 +209,7 @@ void RestoreGlobalState(bool is_powered_on) {
values.swap_screen.SetGlobal(true); values.swap_screen.SetGlobal(true);
values.upright_screen.SetGlobal(true); values.upright_screen.SetGlobal(true);
values.large_screen_proportion.SetGlobal(true); values.large_screen_proportion.SetGlobal(true);
values.screen_gap.SetGlobal(true);
values.small_screen_position.SetGlobal(true); values.small_screen_position.SetGlobal(true);
values.bg_red.SetGlobal(true); values.bg_red.SetGlobal(true);
values.bg_green.SetGlobal(true); values.bg_green.SetGlobal(true);

View File

@ -506,6 +506,7 @@ struct Values {
SwitchableSetting<bool> upright_screen{false, "upright_screen"}; SwitchableSetting<bool> upright_screen{false, "upright_screen"};
SwitchableSetting<float, true> large_screen_proportion{4.f, 1.f, 16.f, SwitchableSetting<float, true> large_screen_proportion{4.f, 1.f, 16.f,
"large_screen_proportion"}; "large_screen_proportion"};
SwitchableSetting<float> screen_gap{0.f,"screen_gap"};
SwitchableSetting<SmallScreenPosition> small_screen_position{SmallScreenPosition::BottomRight, SwitchableSetting<SmallScreenPosition> small_screen_position{SmallScreenPosition::BottomRight,
"small_screen_position"}; "small_screen_position"};
Setting<u16> custom_top_x{0, "custom_top_x"}; Setting<u16> custom_top_x{0, "custom_top_x"};

View File

@ -115,7 +115,7 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
// To do that, find the total emulation box and maximize that based on window size // To do that, find the total emulation box and maximize that based on window size
const float window_aspect_ratio = static_cast<float>(height) / width; const float window_aspect_ratio = static_cast<float>(height) / width;
float emulation_aspect_ratio; float emulation_aspect_ratio;
u32 gap = (u32)(Settings::values.screen_gap.GetValue() * scale_factor);
float large_height = float large_height =
swapped ? Core::kScreenBottomHeight * scale_factor : Core::kScreenTopHeight * scale_factor; swapped ? Core::kScreenBottomHeight * scale_factor : Core::kScreenTopHeight * scale_factor;
float small_height = float small_height =
@ -129,9 +129,9 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
if (vertical) { if (vertical) {
// width is just the larger size at this point // width is just the larger size at this point
emulation_width = std::max(large_width, small_width); emulation_width = std::max(large_width, small_width);
emulation_height = large_height + small_height; emulation_height = large_height + small_height + gap;
} else { } else {
emulation_width = large_width + small_width; emulation_width = large_width + small_width + gap;
emulation_height = std::max(large_height, small_height); emulation_height = std::max(large_height, small_height);
} }
@ -156,47 +156,48 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
// shift the large screen so it is at the top position of the bounding rectangle // shift the large screen so it is at the top position of the bounding rectangle
large_screen = large_screen.TranslateY((height - total_rect.GetHeight()) / 2); large_screen = large_screen.TranslateY((height - total_rect.GetHeight()) / 2);
} }
gap = static_cast<u32>(static_cast<float>(gap) * scale_amount);
switch (small_screen_position) { switch (small_screen_position) {
case Settings::SmallScreenPosition::TopRight: case Settings::SmallScreenPosition::TopRight:
// Shift the small screen to the top right corner // Shift the small screen to the top right corner
small_screen = small_screen.TranslateX(large_screen.right); small_screen = small_screen.TranslateX(large_screen.right + gap);
small_screen = small_screen.TranslateY(large_screen.top); small_screen = small_screen.TranslateY(large_screen.top);
break; break;
case Settings::SmallScreenPosition::MiddleRight: case Settings::SmallScreenPosition::MiddleRight:
// Shift the small screen to the center right // Shift the small screen to the center right
small_screen = small_screen.TranslateX(large_screen.right); small_screen = small_screen.TranslateX(large_screen.right + gap);
small_screen = small_screen.TranslateY( small_screen = small_screen.TranslateY(
((large_screen.GetHeight() - small_screen.GetHeight()) / 2) + large_screen.top); ((large_screen.GetHeight() - small_screen.GetHeight()) / 2) + large_screen.top);
break; break;
case Settings::SmallScreenPosition::BottomRight: case Settings::SmallScreenPosition::BottomRight:
// Shift the small screen to the bottom right corner // Shift the small screen to the bottom right corner
small_screen = small_screen.TranslateX(large_screen.right); small_screen = small_screen.TranslateX(large_screen.right + gap);
small_screen = small_screen.TranslateY(large_screen.bottom - small_screen.GetHeight()); small_screen = small_screen.TranslateY(large_screen.bottom - small_screen.GetHeight());
break; break;
case Settings::SmallScreenPosition::TopLeft: case Settings::SmallScreenPosition::TopLeft:
// shift the small screen to the upper left then shift the large screen to its right // shift the small screen to the upper left then shift the large screen to its right
small_screen = small_screen.TranslateX(large_screen.left); small_screen = small_screen.TranslateX(large_screen.left);
large_screen = large_screen.TranslateX(small_screen.GetWidth()); large_screen = large_screen.TranslateX(small_screen.GetWidth() + gap);
small_screen = small_screen.TranslateY(large_screen.top); small_screen = small_screen.TranslateY(large_screen.top);
break; break;
case Settings::SmallScreenPosition::MiddleLeft: case Settings::SmallScreenPosition::MiddleLeft:
// shift the small screen to the middle left and shift the large screen to its right // shift the small screen to the middle left and shift the large screen to its right
small_screen = small_screen.TranslateX(large_screen.left); small_screen = small_screen.TranslateX(large_screen.left);
large_screen = large_screen.TranslateX(small_screen.GetWidth()); large_screen = large_screen.TranslateX(small_screen.GetWidth() + gap);
small_screen = small_screen.TranslateY( small_screen = small_screen.TranslateY(
((large_screen.GetHeight() - small_screen.GetHeight()) / 2) + large_screen.top); ((large_screen.GetHeight() - small_screen.GetHeight()) / 2) + large_screen.top);
break; break;
case Settings::SmallScreenPosition::BottomLeft: case Settings::SmallScreenPosition::BottomLeft:
// shift the small screen to the bottom left and shift the large screen to its right // shift the small screen to the bottom left and shift the large screen to its right
small_screen = small_screen.TranslateX(large_screen.left); small_screen = small_screen.TranslateX(large_screen.left);
large_screen = large_screen.TranslateX(small_screen.GetWidth()); large_screen = large_screen.TranslateX(small_screen.GetWidth() + gap);
small_screen = small_screen.TranslateY(large_screen.bottom - small_screen.GetHeight()); small_screen = small_screen.TranslateY(large_screen.bottom - small_screen.GetHeight());
break; break;
case Settings::SmallScreenPosition::AboveLarge: case Settings::SmallScreenPosition::AboveLarge:
// shift the large screen down and the bottom screen above it // shift the large screen down and the bottom screen above it
small_screen = small_screen.TranslateY(large_screen.top); small_screen = small_screen.TranslateY(large_screen.top);
large_screen = large_screen.TranslateY(small_screen.GetHeight()); large_screen = large_screen.TranslateY(small_screen.GetHeight() + gap);
// If the "large screen" is actually smaller, center it // If the "large screen" is actually smaller, center it
if (large_screen.GetWidth() < total_rect.GetWidth()) { if (large_screen.GetWidth() < total_rect.GetWidth()) {
large_screen = large_screen =
@ -212,7 +213,7 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
large_screen = large_screen =
large_screen.TranslateX((total_rect.GetWidth() - large_screen.GetWidth()) / 2); large_screen.TranslateX((total_rect.GetWidth() - large_screen.GetWidth()) / 2);
} }
small_screen = small_screen.TranslateY(large_screen.bottom); small_screen = small_screen.TranslateY(large_screen.bottom + gap);
small_screen = small_screen.TranslateX(large_screen.left + large_screen.GetWidth() / 2 - small_screen = small_screen.TranslateX(large_screen.left + large_screen.GetWidth() / 2 -
small_screen.GetWidth() / 2); small_screen.GetWidth() / 2);
break; break;
@ -346,7 +347,8 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped, bool
FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondary, FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondary,
bool is_portrait) { bool is_portrait) {
int width, height; int width, height, gap;
gap = (int)(Settings::values.screen_gap.GetValue()) * res_scale;
if (is_portrait) { if (is_portrait) {
auto layout_option = Settings::values.portrait_layout_option.GetValue(); auto layout_option = Settings::values.portrait_layout_option.GetValue();
switch (layout_option) { switch (layout_option) {
@ -363,7 +365,8 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
Settings::values.swap_screen.GetValue(), is_portrait); Settings::values.swap_screen.GetValue(), is_portrait);
case Settings::PortraitLayoutOption::PortraitTopFullWidth: case Settings::PortraitLayoutOption::PortraitTopFullWidth:
width = Core::kScreenTopWidth * res_scale; width = Core::kScreenTopWidth * res_scale;
height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale; height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale + gap;
return PortraitTopFullFrameLayout(width, height, return PortraitTopFullFrameLayout(width, height,
Settings::values.swap_screen.GetValue()); Settings::values.swap_screen.GetValue());
} }
@ -418,9 +421,9 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
Settings::SmallScreenPosition::BelowLarge) { Settings::SmallScreenPosition::BelowLarge) {
// vertical, so height is sum of heights, width is larger of widths // vertical, so height is sum of heights, width is larger of widths
width = std::max(largeWidth, smallWidth) * res_scale; width = std::max(largeWidth, smallWidth) * res_scale;
height = (largeHeight + smallHeight) * res_scale; height = (largeHeight + smallHeight) * res_scale + gap;
} else { } else {
width = (largeWidth + smallWidth) * res_scale; width = (largeWidth + smallWidth) * res_scale + gap;
height = std::max(largeHeight, smallHeight) * res_scale; height = std::max(largeHeight, smallHeight) * res_scale;
} }
@ -433,7 +436,7 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
Settings::values.small_screen_position.GetValue()); Settings::values.small_screen_position.GetValue());
} }
case Settings::LayoutOption::SideScreen: case Settings::LayoutOption::SideScreen:
width = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale; width = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale + gap;
height = Core::kScreenTopHeight * res_scale; height = Core::kScreenTopHeight * res_scale;
if (Settings::values.upright_screen.GetValue()) { if (Settings::values.upright_screen.GetValue()) {
@ -446,7 +449,7 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
case Settings::LayoutOption::Default: case Settings::LayoutOption::Default:
default: default:
width = Core::kScreenTopWidth * res_scale; width = Core::kScreenTopWidth * res_scale;
height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale; height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale + gap;
if (Settings::values.upright_screen.GetValue()) { if (Settings::values.upright_screen.GetValue()) {
std::swap(width, height); std::swap(width, height);