mirror of
https://github.com/azahar-emu/azahar
synced 2025-11-06 15:09:58 +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),
|
||||
DISABLE_RIGHT_EYE_RENDER("disable_right_eye_render", Settings.SECTION_RENDERER, 0),
|
||||
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
|
||||
|
||||
|
||||
@ -1083,6 +1083,18 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||
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(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.SMALL_SCREEN_POSITION,
|
||||
|
||||
@ -197,6 +197,7 @@ void Config::ReadValues() {
|
||||
ReadSetting("Layout", Settings::values.custom_bottom_x);
|
||||
ReadSetting("Layout", Settings::values.custom_bottom_y);
|
||||
ReadSetting("Layout", Settings::values.custom_bottom_width);
|
||||
ReadSetting("Layout", Settings::values.aspect_ratio);
|
||||
ReadSetting("Layout", Settings::values.custom_bottom_height);
|
||||
ReadSetting("Layout", Settings::values.cardboard_screen_size);
|
||||
ReadSetting("Layout", Settings::values.cardboard_x_shift);
|
||||
|
||||
@ -63,6 +63,24 @@
|
||||
<item>7</item>
|
||||
</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">
|
||||
<item>@string/auto_select</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_portrait">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 -->
|
||||
<string name="clear">Clear</string>
|
||||
@ -411,6 +417,7 @@
|
||||
<string name="emulation_control_dpad_slide_enable">D-Pad Sliding</string>
|
||||
<string name="emulation_open_settings">Open Settings</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_portrait_layout">Portrait Screen Layout</string>
|
||||
<string name="emulation_screen_layout_largescreen">Large Screen</string>
|
||||
|
||||
@ -106,6 +106,15 @@ enum class TextureSampling : u32 {
|
||||
Linear = 2,
|
||||
};
|
||||
|
||||
enum class AspectRatio : u32 {
|
||||
Default = 0,
|
||||
R16_9 = 1,
|
||||
R4_3 = 2,
|
||||
R21_9 = 3,
|
||||
R16_10 = 4,
|
||||
Stretch = 5,
|
||||
};
|
||||
|
||||
namespace NativeButton {
|
||||
|
||||
enum Values {
|
||||
@ -522,7 +531,7 @@ struct Values {
|
||||
Setting<u16> custom_bottom_width{640, "custom_bottom_width"};
|
||||
Setting<u16> custom_bottom_height{480, "custom_bottom_height"};
|
||||
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"};
|
||||
Setting<u16> screen_top_leftright_padding{0, "screen_top_leftright_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
|
||||
template <class T>
|
||||
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()),
|
||||
window_area.GetHeight() / screen_aspect_ratio);
|
||||
window_area.GetHeight() / window_aspect_ratio);
|
||||
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) {
|
||||
@ -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> top_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);
|
||||
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) ||
|
||||
(Settings::values.screen_bottom_stretch.GetValue() && swapped);
|
||||
const float window_aspect_ratio = static_cast<float>(height) / width;
|
||||
|
||||
if (stretched) {
|
||||
top_screen = {Settings::values.screen_top_leftright_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(),
|
||||
width - Settings::values.screen_bottom_leftright_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 {
|
||||
top_screen = top_screen.TranslateY((height - top_screen.GetHeight()) / 2);
|
||||
bot_screen = bot_screen.TranslateY((height - bot_screen.GetHeight()) / 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
res.top_screen = top_screen;
|
||||
res.bottom_screen = bot_screen;
|
||||
if (upright) {
|
||||
@ -125,9 +148,8 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
|
||||
FramebufferLayout res{width, height, true, true, {}, {}, !upright};
|
||||
// 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
|
||||
const float window_aspect_ratio = static_cast<float>(height) / width;
|
||||
float emulation_aspect_ratio;
|
||||
u32 gap = (u32)(Settings::values.screen_gap.GetValue() * scale_factor);
|
||||
|
||||
float large_height =
|
||||
swapped ? Core::kScreenBottomHeight * scale_factor : Core::kScreenTopHeight * scale_factor;
|
||||
float small_height =
|
||||
@ -137,7 +159,8 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
|
||||
float small_width =
|
||||
static_cast<float>(swapped ? Core::kScreenTopWidth : Core::kScreenBottomWidth);
|
||||
|
||||
float emulation_width, emulation_height;
|
||||
float emulation_width;
|
||||
float emulation_height;
|
||||
if (vertical) {
|
||||
// width is just the larger size at this point
|
||||
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_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> 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>{total_rect.left, total_rect.top,
|
||||
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
|
||||
large_screen = large_screen.TranslateY((height - total_rect.GetHeight()) / 2);
|
||||
}
|
||||
gap = static_cast<u32>(static_cast<float>(gap) * scale_amount);
|
||||
|
||||
switch (small_screen_position) {
|
||||
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
|
||||
|
||||
@ -44,6 +44,8 @@ struct FramebufferLayout {
|
||||
* screen.
|
||||
*/
|
||||
u32 GetScalingRatio() const;
|
||||
|
||||
static float GetAspectRatioValue(Settings::AspectRatio aspect_ratio);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user