mirror of
https://github.com/azahar-emu/azahar
synced 2025-11-06 23:19:57 +01:00
android: Add aspect ratio setting for single screen layout mode (#913)
* android: Add aspect ratio setting for single screen layout mode Co-Authored-By: Morph <39850852+Morph1984@users.noreply.github.com> * Partial rewrite to address issues and improve readability --------- Co-authored-by: Morph <39850852+Morph1984@users.noreply.github.com> Co-authored-by: OpenSauce04 <opensauce04@gmail.com>
This commit is contained in:
parent
c204ebf021
commit
580d46e3d6
@ -68,7 +68,8 @@ enum class IntSetting(
|
|||||||
ORIENTATION_OPTION("screen_orientation", Settings.SECTION_LAYOUT, 2),
|
ORIENTATION_OPTION("screen_orientation", Settings.SECTION_LAYOUT, 2),
|
||||||
DISABLE_RIGHT_EYE_RENDER("disable_right_eye_render", Settings.SECTION_RENDERER, 0),
|
DISABLE_RIGHT_EYE_RENDER("disable_right_eye_render", Settings.SECTION_RENDERER, 0),
|
||||||
TURBO_LIMIT("turbo_limit", Settings.SECTION_CORE, 200),
|
TURBO_LIMIT("turbo_limit", Settings.SECTION_CORE, 200),
|
||||||
PERFORMANCE_OVERLAY_POSITION("performance_overlay_position", Settings.SECTION_LAYOUT, 0);
|
PERFORMANCE_OVERLAY_POSITION("performance_overlay_position", Settings.SECTION_LAYOUT, 0),
|
||||||
|
ASPECT_RATIO("aspect_ratio", Settings.SECTION_LAYOUT, 0);
|
||||||
|
|
||||||
override var int: Int = defaultValue
|
override var int: Int = defaultValue
|
||||||
|
|
||||||
|
|||||||
@ -1083,6 +1083,18 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
IntSetting.PORTRAIT_SCREEN_LAYOUT.defaultValue
|
IntSetting.PORTRAIT_SCREEN_LAYOUT.defaultValue
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
add(
|
||||||
|
SingleChoiceSetting(
|
||||||
|
IntSetting.ASPECT_RATIO,
|
||||||
|
R.string.emulation_aspect_ratio,
|
||||||
|
0,
|
||||||
|
R.array.aspectRatioNames,
|
||||||
|
R.array.aspectRatioValues,
|
||||||
|
IntSetting.ASPECT_RATIO.key,
|
||||||
|
IntSetting.ASPECT_RATIO.defaultValue,
|
||||||
|
isEnabled = IntSetting.SCREEN_LAYOUT.int == 1,
|
||||||
|
)
|
||||||
|
)
|
||||||
add(
|
add(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
IntSetting.SMALL_SCREEN_POSITION,
|
IntSetting.SMALL_SCREEN_POSITION,
|
||||||
|
|||||||
@ -197,6 +197,7 @@ void Config::ReadValues() {
|
|||||||
ReadSetting("Layout", Settings::values.custom_bottom_x);
|
ReadSetting("Layout", Settings::values.custom_bottom_x);
|
||||||
ReadSetting("Layout", Settings::values.custom_bottom_y);
|
ReadSetting("Layout", Settings::values.custom_bottom_y);
|
||||||
ReadSetting("Layout", Settings::values.custom_bottom_width);
|
ReadSetting("Layout", Settings::values.custom_bottom_width);
|
||||||
|
ReadSetting("Layout", Settings::values.aspect_ratio);
|
||||||
ReadSetting("Layout", Settings::values.custom_bottom_height);
|
ReadSetting("Layout", Settings::values.custom_bottom_height);
|
||||||
ReadSetting("Layout", Settings::values.cardboard_screen_size);
|
ReadSetting("Layout", Settings::values.cardboard_screen_size);
|
||||||
ReadSetting("Layout", Settings::values.cardboard_x_shift);
|
ReadSetting("Layout", Settings::values.cardboard_x_shift);
|
||||||
|
|||||||
@ -63,6 +63,24 @@
|
|||||||
<item>7</item>
|
<item>7</item>
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
|
<string-array name="aspectRatioNames">
|
||||||
|
<item>@string/aspect_ratio_default</item>
|
||||||
|
<item>@string/aspect_ratio_16_9</item>
|
||||||
|
<item>@string/aspect_ratio_4_3</item>
|
||||||
|
<item>@string/aspect_ratio_21_9_fullscreen</item>
|
||||||
|
<item>@string/aspect_ratio_16_10_fullscreen_stretched</item>
|
||||||
|
<item>@string/aspect_ratio_stretch</item>
|
||||||
|
</string-array>
|
||||||
|
<integer-array name="aspectRatioValues">
|
||||||
|
<item>0</item>
|
||||||
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
|
<item>3</item>
|
||||||
|
<item>4</item>
|
||||||
|
<item>5</item>
|
||||||
|
</integer-array>
|
||||||
|
|
||||||
|
|
||||||
<string-array name="regionNames">
|
<string-array name="regionNames">
|
||||||
<item>@string/auto_select</item>
|
<item>@string/auto_select</item>
|
||||||
<item>@string/system_region_jpn</item>
|
<item>@string/system_region_jpn</item>
|
||||||
|
|||||||
@ -326,6 +326,12 @@
|
|||||||
<string name="layout_screen_orientation_landscape_reverse">Reverse Landscape</string>
|
<string name="layout_screen_orientation_landscape_reverse">Reverse Landscape</string>
|
||||||
<string name="layout_screen_orientation_portrait">Portrait</string>
|
<string name="layout_screen_orientation_portrait">Portrait</string>
|
||||||
<string name="layout_screen_orientation_portrait_reverse">Reverse Portrait</string>
|
<string name="layout_screen_orientation_portrait_reverse">Reverse Portrait</string>
|
||||||
|
<string name="aspect_ratio_default">Default</string>
|
||||||
|
<string name="aspect_ratio_16_9">16:9</string>
|
||||||
|
<string name="aspect_ratio_4_3">4:3</string>
|
||||||
|
<string name="aspect_ratio_21_9_fullscreen">21:9</string>
|
||||||
|
<string name="aspect_ratio_16_10_fullscreen_stretched">16:10</string>
|
||||||
|
<string name="aspect_ratio_stretch">Stretch</string>
|
||||||
|
|
||||||
<!-- Miscellaneous -->
|
<!-- Miscellaneous -->
|
||||||
<string name="clear">Clear</string>
|
<string name="clear">Clear</string>
|
||||||
@ -411,6 +417,7 @@
|
|||||||
<string name="emulation_control_dpad_slide_enable">D-Pad Sliding</string>
|
<string name="emulation_control_dpad_slide_enable">D-Pad Sliding</string>
|
||||||
<string name="emulation_open_settings">Open Settings</string>
|
<string name="emulation_open_settings">Open Settings</string>
|
||||||
<string name="emulation_open_cheats">Open Cheats</string>
|
<string name="emulation_open_cheats">Open Cheats</string>
|
||||||
|
<string name="emulation_aspect_ratio">Aspect Ratio</string>
|
||||||
<string name="emulation_switch_screen_layout">Landscape Screen Layout</string>
|
<string name="emulation_switch_screen_layout">Landscape Screen Layout</string>
|
||||||
<string name="emulation_switch_portrait_layout">Portrait Screen Layout</string>
|
<string name="emulation_switch_portrait_layout">Portrait Screen Layout</string>
|
||||||
<string name="emulation_screen_layout_largescreen">Large Screen</string>
|
<string name="emulation_screen_layout_largescreen">Large Screen</string>
|
||||||
|
|||||||
@ -106,6 +106,15 @@ enum class TextureSampling : u32 {
|
|||||||
Linear = 2,
|
Linear = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class AspectRatio : u32 {
|
||||||
|
Default = 0,
|
||||||
|
R16_9 = 1,
|
||||||
|
R4_3 = 2,
|
||||||
|
R21_9 = 3,
|
||||||
|
R16_10 = 4,
|
||||||
|
Stretch = 5,
|
||||||
|
};
|
||||||
|
|
||||||
namespace NativeButton {
|
namespace NativeButton {
|
||||||
|
|
||||||
enum Values {
|
enum Values {
|
||||||
@ -522,7 +531,7 @@ struct Values {
|
|||||||
Setting<u16> custom_bottom_width{640, "custom_bottom_width"};
|
Setting<u16> custom_bottom_width{640, "custom_bottom_width"};
|
||||||
Setting<u16> custom_bottom_height{480, "custom_bottom_height"};
|
Setting<u16> custom_bottom_height{480, "custom_bottom_height"};
|
||||||
Setting<u16> custom_second_layer_opacity{100, "custom_second_layer_opacity"};
|
Setting<u16> custom_second_layer_opacity{100, "custom_second_layer_opacity"};
|
||||||
|
SwitchableSetting<AspectRatio> aspect_ratio{AspectRatio::Default, "aspect_ratio"};
|
||||||
SwitchableSetting<bool> screen_top_stretch{false, "screen_top_stretch"};
|
SwitchableSetting<bool> screen_top_stretch{false, "screen_top_stretch"};
|
||||||
Setting<u16> screen_top_leftright_padding{0, "screen_top_leftright_padding"};
|
Setting<u16> screen_top_leftright_padding{0, "screen_top_leftright_padding"};
|
||||||
Setting<u16> screen_top_topbottom_padding{0, "screen_top_topbottom_padding"};
|
Setting<u16> screen_top_topbottom_padding{0, "screen_top_topbottom_padding"};
|
||||||
|
|||||||
@ -27,11 +27,11 @@ u32 FramebufferLayout::GetScalingRatio() const {
|
|||||||
// Finds the largest size subrectangle contained in window area that is confined to the aspect ratio
|
// Finds the largest size subrectangle contained in window area that is confined to the aspect ratio
|
||||||
template <class T>
|
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 window_aspect_ratio) {
|
||||||
float scale = std::min(static_cast<float>(window_area.GetWidth()),
|
float scale = std::min(static_cast<float>(window_area.GetWidth()),
|
||||||
window_area.GetHeight() / screen_aspect_ratio);
|
window_area.GetHeight() / window_aspect_ratio);
|
||||||
return Common::Rectangle<T>{0, 0, static_cast<T>(std::round(scale)),
|
return Common::Rectangle<T>{0, 0, static_cast<T>(std::round(scale)),
|
||||||
static_cast<T>(std::round(scale * screen_aspect_ratio))};
|
static_cast<T>(std::round(scale * window_aspect_ratio))};
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool swapped, bool upright) {
|
FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool swapped, bool upright) {
|
||||||
@ -76,15 +76,41 @@ FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, bool up
|
|||||||
Common::Rectangle<u32> screen_window_area{0, 0, width, height};
|
Common::Rectangle<u32> screen_window_area{0, 0, width, height};
|
||||||
Common::Rectangle<u32> top_screen;
|
Common::Rectangle<u32> top_screen;
|
||||||
Common::Rectangle<u32> bot_screen;
|
Common::Rectangle<u32> bot_screen;
|
||||||
float emulation_aspect_ratio;
|
|
||||||
|
// TODO: This is kind of gross, make it platform agnostic. -OS
|
||||||
|
#ifdef ANDROID
|
||||||
|
const float window_aspect_ratio = static_cast<float>(height) / width;
|
||||||
|
const auto aspect_ratio_setting = Settings::values.aspect_ratio.GetValue();
|
||||||
|
|
||||||
|
float emulation_aspect_ratio = (swapped) ? BOT_SCREEN_ASPECT_RATIO : TOP_SCREEN_ASPECT_RATIO;
|
||||||
|
switch (aspect_ratio_setting) {
|
||||||
|
case Settings::AspectRatio::Default:
|
||||||
|
break;
|
||||||
|
case Settings::AspectRatio::Stretch:
|
||||||
|
emulation_aspect_ratio = window_aspect_ratio;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
emulation_aspect_ratio = res.GetAspectRatioValue(aspect_ratio_setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
top_screen = MaxRectangle(screen_window_area, emulation_aspect_ratio);
|
||||||
|
bot_screen = MaxRectangle(screen_window_area, emulation_aspect_ratio);
|
||||||
|
|
||||||
|
if (window_aspect_ratio < emulation_aspect_ratio) {
|
||||||
|
top_screen =
|
||||||
|
top_screen.TranslateX((screen_window_area.GetWidth() - top_screen.GetWidth()) / 2);
|
||||||
|
bot_screen =
|
||||||
|
bot_screen.TranslateX((screen_window_area.GetWidth() - bot_screen.GetWidth()) / 2);
|
||||||
|
} else {
|
||||||
|
top_screen = top_screen.TranslateY((height - top_screen.GetHeight()) / 2);
|
||||||
|
bot_screen = bot_screen.TranslateY((height - bot_screen.GetHeight()) / 2);
|
||||||
|
}
|
||||||
|
#else
|
||||||
top_screen = MaxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO);
|
top_screen = MaxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO);
|
||||||
bot_screen = MaxRectangle(screen_window_area, BOT_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;
|
|
||||||
|
|
||||||
const bool stretched = (Settings::values.screen_top_stretch.GetValue() && !swapped) ||
|
const bool stretched = (Settings::values.screen_top_stretch.GetValue() && !swapped) ||
|
||||||
(Settings::values.screen_bottom_stretch.GetValue() && swapped);
|
(Settings::values.screen_bottom_stretch.GetValue() && swapped);
|
||||||
const float window_aspect_ratio = static_cast<float>(height) / width;
|
|
||||||
|
|
||||||
if (stretched) {
|
if (stretched) {
|
||||||
top_screen = {Settings::values.screen_top_leftright_padding.GetValue(),
|
top_screen = {Settings::values.screen_top_leftright_padding.GetValue(),
|
||||||
Settings::values.screen_top_topbottom_padding.GetValue(),
|
Settings::values.screen_top_topbottom_padding.GetValue(),
|
||||||
@ -94,15 +120,12 @@ FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, bool up
|
|||||||
Settings::values.screen_bottom_topbottom_padding.GetValue(),
|
Settings::values.screen_bottom_topbottom_padding.GetValue(),
|
||||||
width - Settings::values.screen_bottom_leftright_padding.GetValue(),
|
width - Settings::values.screen_bottom_leftright_padding.GetValue(),
|
||||||
height - Settings::values.screen_bottom_topbottom_padding.GetValue()};
|
height - Settings::values.screen_bottom_topbottom_padding.GetValue()};
|
||||||
} else if (window_aspect_ratio < emulation_aspect_ratio) {
|
|
||||||
top_screen =
|
|
||||||
top_screen.TranslateX((screen_window_area.GetWidth() - top_screen.GetWidth()) / 2);
|
|
||||||
bot_screen =
|
|
||||||
bot_screen.TranslateX((screen_window_area.GetWidth() - bot_screen.GetWidth()) / 2);
|
|
||||||
} else {
|
} else {
|
||||||
top_screen = top_screen.TranslateY((height - top_screen.GetHeight()) / 2);
|
top_screen = top_screen.TranslateY((height - top_screen.GetHeight()) / 2);
|
||||||
bot_screen = bot_screen.TranslateY((height - bot_screen.GetHeight()) / 2);
|
bot_screen = bot_screen.TranslateY((height - bot_screen.GetHeight()) / 2);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
res.top_screen = top_screen;
|
res.top_screen = top_screen;
|
||||||
res.bottom_screen = bot_screen;
|
res.bottom_screen = bot_screen;
|
||||||
if (upright) {
|
if (upright) {
|
||||||
@ -125,9 +148,8 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
|
|||||||
FramebufferLayout res{width, height, true, true, {}, {}, !upright};
|
FramebufferLayout res{width, height, true, true, {}, {}, !upright};
|
||||||
// Split the window into two parts. Give proportional width to the smaller screen
|
// Split the window into two parts. Give proportional width to the smaller screen
|
||||||
// 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;
|
|
||||||
float emulation_aspect_ratio;
|
|
||||||
u32 gap = (u32)(Settings::values.screen_gap.GetValue() * scale_factor);
|
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 =
|
||||||
@ -137,7 +159,8 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
|
|||||||
float small_width =
|
float small_width =
|
||||||
static_cast<float>(swapped ? Core::kScreenTopWidth : Core::kScreenBottomWidth);
|
static_cast<float>(swapped ? Core::kScreenTopWidth : Core::kScreenBottomWidth);
|
||||||
|
|
||||||
float emulation_width, emulation_height;
|
float emulation_width;
|
||||||
|
float emulation_height;
|
||||||
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);
|
||||||
@ -147,11 +170,15 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
|
|||||||
emulation_height = std::max(large_height, small_height);
|
emulation_height = std::max(large_height, small_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
emulation_aspect_ratio = emulation_height / emulation_width;
|
const float window_aspect_ratio = static_cast<float>(height) / width;
|
||||||
|
const float emulation_aspect_ratio = emulation_height / emulation_width;
|
||||||
|
|
||||||
Common::Rectangle<u32> screen_window_area{0, 0, width, height};
|
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> total_rect = MaxRectangle(screen_window_area, emulation_aspect_ratio);
|
||||||
const float scale_amount = total_rect.GetHeight() * 1.f / emulation_height * 1.f;
|
// TODO: Wtf does this `scale_amount` value represent? -OS
|
||||||
|
const float scale_amount = static_cast<float>(total_rect.GetHeight()) / emulation_height;
|
||||||
|
gap = static_cast<u32>(static_cast<float>(gap) * scale_amount);
|
||||||
|
|
||||||
Common::Rectangle<u32> large_screen =
|
Common::Rectangle<u32> large_screen =
|
||||||
Common::Rectangle<u32>{total_rect.left, total_rect.top,
|
Common::Rectangle<u32>{total_rect.left, total_rect.top,
|
||||||
static_cast<u32>(large_width * scale_amount + total_rect.left),
|
static_cast<u32>(large_width * scale_amount + total_rect.left),
|
||||||
@ -168,7 +195,6 @@ 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:
|
||||||
@ -676,4 +702,21 @@ std::pair<unsigned, unsigned> GetMinimumSizeFromLayout(Settings::LayoutOption la
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float FramebufferLayout::GetAspectRatioValue(Settings::AspectRatio aspect_ratio) {
|
||||||
|
switch (aspect_ratio) {
|
||||||
|
case Settings::AspectRatio::R16_9:
|
||||||
|
return 9.0f / 16.0f;
|
||||||
|
case Settings::AspectRatio::R4_3:
|
||||||
|
return 3.0f / 4.0f;
|
||||||
|
case Settings::AspectRatio::R21_9:
|
||||||
|
return 9.0f / 21.0f;
|
||||||
|
case Settings::AspectRatio::R16_10:
|
||||||
|
return 10.0f / 16.0f;
|
||||||
|
default:
|
||||||
|
LOG_ERROR(Frontend, "Unknown aspect ratio enum value: {}",
|
||||||
|
static_cast<std::underlying_type<Settings::AspectRatio>::type>(aspect_ratio));
|
||||||
|
return 1.0f; // Arbitrary fallback value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Layout
|
} // namespace Layout
|
||||||
|
|||||||
@ -44,6 +44,8 @@ struct FramebufferLayout {
|
|||||||
* screen.
|
* screen.
|
||||||
*/
|
*/
|
||||||
u32 GetScalingRatio() const;
|
u32 GetScalingRatio() const;
|
||||||
|
|
||||||
|
static float GetAspectRatioValue(Settings::AspectRatio aspect_ratio);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user