diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index 136671bff..17b0e1e9b 100644 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp @@ -188,6 +188,18 @@ void Config::ReadValues() { ReadSetting("Layout", Settings::values.cardboard_x_shift); ReadSetting("Layout", Settings::values.cardboard_y_shift); +#ifdef ANDROID + ReadSetting("Layout", Settings::values.custom_portrait_layout); + ReadSetting("Layout", Settings::values.custom_portrait_top_left); + ReadSetting("Layout", Settings::values.custom_portrait_top_top); + ReadSetting("Layout", Settings::values.custom_portrait_top_right); + ReadSetting("Layout", Settings::values.custom_portrait_top_bottom); + ReadSetting("Layout", Settings::values.custom_portrait_bottom_left); + ReadSetting("Layout", Settings::values.custom_portrait_bottom_top); + ReadSetting("Layout", Settings::values.custom_portrait_bottom_right); + ReadSetting("Layout", Settings::values.custom_portrait_bottom_bottom); +#endif + // Utility ReadSetting("Utility", Settings::values.dump_textures); ReadSetting("Utility", Settings::values.custom_textures); diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h index b96999da9..856ad3eb4 100644 --- a/src/android/app/src/main/jni/default_ini.h +++ b/src/android/app/src/main/jni/default_ini.h @@ -184,6 +184,7 @@ filter_mode = layout_option = # Toggle custom layout (using the settings below) on or off. +# Only applies to landscape on Android # 0 (default): Off, 1: On custom_layout = @@ -198,6 +199,22 @@ custom_bottom_y = custom_bottom_width = custom_bottom_height = +# Custom Layout Options for Android Portrait Mode +# Toggle custom layout (using the settings below) on or off. +# 0 (default): Off, 1: On +custom_portrait_layout = + +# Screen placement when using Custom layout option +# 0x, 0y is the top left corner of the render window. +custom_portrait_top_left = +custom_portrait_top_top = +custom_portrait_top_right = +custom_portrait_top_bottom = +custom_portrait_bottom_left = +custom_portrait_bottom_top = +custom_portrait_bottom_right = +custom_portrait_bottom_bottom = + # Swaps the prominent screen with the other screen. # For example, if Single Screen is chosen, setting this to 1 will display the bottom screen instead of the top screen. # 0 (default): Top Screen is prominent, 1: Bottom Screen is prominent diff --git a/src/common/settings.h b/src/common/settings.h index 580c0b65c..38c70a2bc 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -506,6 +506,16 @@ struct Values { Setting screen_bottom_leftright_padding{0, "screen_bottom_leftright_padding"}; Setting screen_bottom_topbottom_padding{0, "screen_bottom_topbottom_padding"}; + Setting custom_portrait_layout{false, "custom_portrait_layout"}; + Setting custom_portrait_top_left{0, "custom_portrait_top_left"}; + Setting custom_portrait_top_top{0, "custom_portrait_top_top"}; + Setting custom_portrait_top_right{400, "custom_portrait_top_right"}; + Setting custom_portrait_top_bottom{240, "custom_portrait_top_bottom"}; + Setting custom_portrait_bottom_left{40, "custom_portrait_bottom_left"}; + Setting custom_portrait_bottom_top{240, "custom_portrait_bottom_top"}; + Setting custom_portrait_bottom_right{360, "custom_portrait_bottom_right"}; + Setting custom_portrait_bottom_bottom{480, "custom_portrait_bottom_bottom"}; + SwitchableSetting bg_red{0.f, "bg_red"}; SwitchableSetting bg_green{0.f, "bg_green"}; SwitchableSetting bg_blue{0.f, "bg_blue"}; diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp index 872cce7d1..3765986cb 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp @@ -183,8 +183,10 @@ void EmuWindow::UpdateCurrentFramebufferLayout(u32 width, u32 height, bool is_po const auto min_size = Layout::GetMinimumSizeFromLayout(layout_option, Settings::values.upright_screen.GetValue()); - if (Settings::values.custom_layout.GetValue() == true) { - layout = Layout::CustomFrameLayout(width, height, Settings::values.swap_screen.GetValue()); + if ((Settings::values.custom_layout.GetValue() == true && !is_portrait_mode) || + (Settings::values.custom_portrait_layout.GetValue() == true && is_portrait_mode)) { + layout = Layout::CustomFrameLayout(width, height, Settings::values.swap_screen.GetValue(), + is_portrait_mode); } else { width = std::max(width, min_size.first); height = std::max(height, min_size.second); diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index fbb4667fc..44f82f012 100644 --- a/src/core/frontend/framebuffer_layout.cpp +++ b/src/core/frontend/framebuffer_layout.cpp @@ -382,24 +382,30 @@ FramebufferLayout SeparateWindowsLayout(u32 width, u32 height, bool is_secondary return SingleFrameLayout(width, height, is_secondary, upright); } -FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped) { +FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped, bool is_portrait_mode) { ASSERT(width > 0); ASSERT(height > 0); FramebufferLayout res{width, height, true, true, {}, {}, !Settings::values.upright_screen}; + u16 top_left = is_portrait_mode ? Settings::values.custom_portrait_top_left.GetValue() + : Settings::values.custom_top_left.GetValue(); + u16 top_right = is_portrait_mode ? Settings::values.custom_portrait_top_right.GetValue() + : Settings::values.custom_top_right.GetValue(); + u16 top_top = is_portrait_mode ? Settings::values.custom_portrait_top_top.GetValue() + : Settings::values.custom_top_top.GetValue(); + u16 top_bottom = is_portrait_mode ? Settings::values.custom_portrait_top_bottom.GetValue() + : Settings::values.custom_top_bottom.GetValue(); + u16 bottom_left = is_portrait_mode ? Settings::values.custom_portrait_bottom_left.GetValue() + : Settings::values.custom_bottom_left.GetValue(); + u16 bottom_right = is_portrait_mode ? Settings::values.custom_portrait_bottom_right.GetValue() + : Settings::values.custom_bottom_right.GetValue(); + u16 bottom_top = is_portrait_mode ? Settings::values.custom_portrait_bottom_top.GetValue() + : Settings::values.custom_bottom_top.GetValue(); + u16 bottom_bottom = is_portrait_mode ? Settings::values.custom_portrait_bottom_bottom.GetValue() + : Settings::values.custom_bottom_bottom.GetValue(); - Common::Rectangle top_screen{Settings::values.custom_top_x.GetValue(), - Settings::values.custom_top_y.GetValue(), - (u32)(Settings::values.custom_top_x.GetValue() + - Settings::values.custom_top_width.GetValue()), - (u32)(Settings::values.custom_top_y.GetValue() + - Settings::values.custom_top_height.GetValue())}; - Common::Rectangle bot_screen{Settings::values.custom_bottom_x.GetValue(), - Settings::values.custom_bottom_y.GetValue(), - (u32)(Settings::values.custom_bottom_x.GetValue() + - Settings::values.custom_bottom_width.GetValue()), - (u32)(Settings::values.custom_bottom_y.GetValue() + - Settings::values.custom_bottom_height.GetValue())}; + Common::Rectangle top_screen{top_left, top_top, top_right, top_bottom}; + Common::Rectangle bot_screen{bottom_left, bottom_top, bottom_right, bottom_bottom}; if (is_swapped) { res.top_screen = bot_screen; @@ -412,12 +418,21 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped) { } FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondary) { - if (Settings::values.custom_layout.GetValue() == true) { - return CustomFrameLayout(std::max(Settings::values.custom_top_width.GetValue(), - Settings::values.custom_bottom_width.GetValue()), - std::max(Settings::values.custom_top_height.GetValue(), - Settings::values.custom_bottom_height.GetValue()), - Settings::values.swap_screen.GetValue()); + bool is_portrait_mode = + Settings::values.layout_option.GetValue() == Settings::LayoutOption::MobilePortrait; + if (Settings::values.custom_layout.GetValue() == true && !is_portrait_mode) { + return CustomFrameLayout(std::max(Settings::values.custom_top_right.GetValue(), + Settings::values.custom_bottom_right.GetValue()), + std::max(Settings::values.custom_top_bottom.GetValue(), + Settings::values.custom_bottom_bottom.GetValue()), + Settings::values.swap_screen.GetValue(), is_portrait_mode); + } else if (Settings::values.custom_portrait_layout.GetValue() == true && is_portrait_mode) { + return CustomFrameLayout( + std::max(Settings::values.custom_portrait_top_right.GetValue(), + Settings::values.custom_portrait_bottom_right.GetValue()), + std::max(Settings::values.custom_portrait_top_bottom.GetValue(), + Settings::values.custom_portrait_bottom_bottom.GetValue()), + Settings::values.swap_screen.GetValue(), is_portrait_mode); } int width, height; diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h index f2ed553fd..37cbb564c 100644 --- a/src/core/frontend/framebuffer_layout.h +++ b/src/core/frontend/framebuffer_layout.h @@ -145,7 +145,8 @@ FramebufferLayout SeparateWindowsLayout(u32 width, u32 height, bool is_secondary * @param height Window framebuffer height in pixels * @return Newly created FramebufferLayout object with default screen regions initialized */ -FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped); +FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped, + bool is_portrait_mode = false); /** * Convenience method to get frame layout by resolution scale diff --git a/src/lime/config.cpp b/src/lime/config.cpp index e67b7ed9f..8532cf83c 100644 --- a/src/lime/config.cpp +++ b/src/lime/config.cpp @@ -183,6 +183,16 @@ void Config::ReadValues() { ReadSetting("Layout", Settings::values.screen_bottom_leftright_padding); ReadSetting("Layout", Settings::values.screen_bottom_topbottom_padding); + ReadSetting("Layout", Settings::values.custom_portrait_layout); + ReadSetting("Layout", Settings::values.custom_portrait_top_left); + ReadSetting("Layout", Settings::values.custom_portrait_top_top); + ReadSetting("Layout", Settings::values.custom_portrait_top_right); + ReadSetting("Layout", Settings::values.custom_portrait_top_bottom); + ReadSetting("Layout", Settings::values.custom_portrait_bottom_left); + ReadSetting("Layout", Settings::values.custom_portrait_bottom_top); + ReadSetting("Layout", Settings::values.custom_portrait_bottom_right); + ReadSetting("Layout", Settings::values.custom_portrait_bottom_bottom); + // Utility ReadSetting("Utility", Settings::values.dump_textures); ReadSetting("Utility", Settings::values.custom_textures); diff --git a/src/lime_qt/configuration/config.cpp b/src/lime_qt/configuration/config.cpp index 3919fe430..752fd6509 100644 --- a/src/lime_qt/configuration/config.cpp +++ b/src/lime_qt/configuration/config.cpp @@ -538,6 +538,15 @@ void Config::ReadLayoutValues() { ReadBasicSetting(Settings::values.screen_bottom_stretch); ReadBasicSetting(Settings::values.screen_bottom_leftright_padding); ReadBasicSetting(Settings::values.screen_bottom_topbottom_padding); + ReadBasicSetting(Settings::values.custom_portrait_layout); + ReadBasicSetting(Settings::values.custom_portrait_top_left); + ReadBasicSetting(Settings::values.custom_portrait_top_top); + ReadBasicSetting(Settings::values.custom_portrait_top_right); + ReadBasicSetting(Settings::values.custom_portrait_top_bottom); + ReadBasicSetting(Settings::values.custom_portrait_bottom_left); + ReadBasicSetting(Settings::values.custom_portrait_bottom_top); + ReadBasicSetting(Settings::values.custom_portrait_bottom_right); + ReadBasicSetting(Settings::values.custom_portrait_bottom_bottom); } qt_config->endGroup(); @@ -1090,6 +1099,15 @@ void Config::SaveLayoutValues() { WriteBasicSetting(Settings::values.screen_bottom_stretch); WriteBasicSetting(Settings::values.screen_bottom_leftright_padding); WriteBasicSetting(Settings::values.screen_bottom_topbottom_padding); + WriteBasicSetting(Settings::values.custom_portrait_layout); + WriteBasicSetting(Settings::values.custom_portrait_top_left); + WriteBasicSetting(Settings::values.custom_portrait_top_top); + WriteBasicSetting(Settings::values.custom_portrait_top_right); + WriteBasicSetting(Settings::values.custom_portrait_top_bottom); + WriteBasicSetting(Settings::values.custom_portrait_bottom_left); + WriteBasicSetting(Settings::values.custom_portrait_bottom_top); + WriteBasicSetting(Settings::values.custom_portrait_bottom_right); + WriteBasicSetting(Settings::values.custom_portrait_bottom_bottom); } qt_config->endGroup();