diff --git a/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt
index 2ec4716b7..60f9e5dcd 100644
--- a/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt
+++ b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt
@@ -41,7 +41,8 @@ enum class SmallScreenPosition(val int: Int) {
enum class PortraitScreenLayout(val int: Int) {
// These must match what is defined in src/common/settings.h
TOP_FULL_WIDTH(0),
- CUSTOM_PORTRAIT_LAYOUT(1);
+ CUSTOM_PORTRAIT_LAYOUT(1),
+ ORIGINAL(2);
companion object {
fun from(int: Int): PortraitScreenLayout {
diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt
index e91876584..765fcd5ec 100644
--- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt
+++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt
@@ -886,10 +886,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
val layoutOptionMenuItem = when (IntSetting.PORTRAIT_SCREEN_LAYOUT.int) {
PortraitScreenLayout.TOP_FULL_WIDTH.int ->
R.id.menu_portrait_layout_top_full
-
PortraitScreenLayout.CUSTOM_PORTRAIT_LAYOUT.int ->
R.id.menu_portrait_layout_custom
-
+ PortraitScreenLayout.ORIGINAL.int ->
+ R.id.menu_portrait_layout_original
else ->
R.id.menu_portrait_layout_top_full
@@ -914,6 +914,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
true
}
+ R.id.menu_portrait_layout_original -> {
+ screenAdjustmentUtil.changePortraitOrientation(PortraitScreenLayout.ORIGINAL.int)
+ true
+ }
+
else -> true
}
}
diff --git a/src/android/app/src/main/res/menu/menu_portrait_screen_layout.xml b/src/android/app/src/main/res/menu/menu_portrait_screen_layout.xml
index afa9f27e0..4b8e4b7cd 100644
--- a/src/android/app/src/main/res/menu/menu_portrait_screen_layout.xml
+++ b/src/android/app/src/main/res/menu/menu_portrait_screen_layout.xml
@@ -11,6 +11,10 @@
android:id="@+id/menu_portrait_layout_custom"
android:title="@string/emulation_screen_layout_custom" />
+
+
diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml
index 4159d9e4e..c50001792 100644
--- a/src/android/app/src/main/res/values/arrays.xml
+++ b/src/android/app/src/main/res/values/arrays.xml
@@ -32,11 +32,13 @@
- @string/emulation_portrait_layout_top_full
- @string/emulation_screen_layout_custom
+ - @string/emulation_screen_layout_original
- 0
- 1
+ - 2
diff --git a/src/common/settings.h b/src/common/settings.h
index e484c1cd2..f96c0383e 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -51,6 +51,7 @@ enum class PortraitLayoutOption : u32 {
// formerly mobile portrait
PortraitTopFullWidth,
PortraitCustomLayout,
+ PortraitOriginal
};
/** Defines where the small screen will appear relative to the large screen
diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp
index 6c2811cf0..963ac0ca9 100644
--- a/src/core/frontend/emu_window.cpp
+++ b/src/core/frontend/emu_window.cpp
@@ -207,6 +207,9 @@ void EmuWindow::UpdateCurrentFramebufferLayout(u32 width, u32 height, bool is_po
layout = Layout::CustomFrameLayout(
width, height, Settings::values.swap_screen.GetValue(), is_portrait_mode);
break;
+ case Settings::PortraitLayoutOption::PortraitOriginal:
+ layout = Layout::PortraitOriginalLayout(width, height, Settings::values.swap_screen.GetValue());
+ break;
}
} else {
switch (layout_option) {
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index 7cf52a29c..0729cae34 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -51,6 +51,19 @@ FramebufferLayout PortraitTopFullFrameLayout(u32 width, u32 height, bool swapped
return res;
}
+FramebufferLayout PortraitOriginalLayout(u32 width, u32 height, bool swapped) {
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+ const float scale_factor = 1;
+ FramebufferLayout res = LargeFrameLayout(width, height, swapped, false, scale_factor,
+ Settings::SmallScreenPosition::BelowLarge);
+ const int shiftY = -(int)(swapped ? res.bottom_screen.top : res.top_screen.top);
+ res.top_screen = res.top_screen.TranslateY(shiftY);
+ res.bottom_screen = res.bottom_screen.TranslateY(shiftY);
+ return res;
+
+}
+
FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, bool upright) {
ASSERT(width > 0);
ASSERT(height > 0);
@@ -346,7 +359,7 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped, bool
FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondary,
bool is_portrait) {
- int width, height;
+ u32 width, height;
if (is_portrait) {
auto layout_option = Settings::values.portrait_layout_option.GetValue();
switch (layout_option) {
@@ -363,9 +376,13 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
Settings::values.swap_screen.GetValue(), is_portrait);
case Settings::PortraitLayoutOption::PortraitTopFullWidth:
width = Core::kScreenTopWidth * res_scale;
- height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale;
+ height = static_cast(Core::kScreenTopHeight + Core::kScreenBottomHeight * 1.25) * res_scale;
return PortraitTopFullFrameLayout(width, height,
Settings::values.swap_screen.GetValue());
+ case Settings::PortraitLayoutOption::PortraitOriginal:
+ width = Core::kScreenTopWidth * res_scale;
+ height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale;
+ return PortraitOriginalLayout(width, height, Settings::values.swap_screen.GetValue());
}
} else {
auto layout_option = Settings::values.layout_option.GetValue();
@@ -479,6 +496,7 @@ FramebufferLayout GetCardboardSettings(const FramebufferLayout& layout) {
if (is_portrait) {
switch (Settings::values.portrait_layout_option.GetValue()) {
case Settings::PortraitLayoutOption::PortraitTopFullWidth:
+ case Settings::PortraitLayoutOption::PortraitOriginal:
cardboard_screen_width = top_screen_width;
cardboard_screen_height = top_screen_height + bottom_screen_height;
bottom_screen_left += (top_screen_width - bottom_screen_width) / 2;
diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h
index adcf26630..60bc2f437 100644
--- a/src/core/frontend/framebuffer_layout.h
+++ b/src/core/frontend/framebuffer_layout.h
@@ -62,8 +62,8 @@ FramebufferLayout reverseLayout(FramebufferLayout layout);
FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool is_swapped, bool upright);
/**
- * Factory method for constructing the mobile Full Width Top layout
- * Two screens at top, full width, no gap between them
+ * Factory method for constructing the mobile Full Width (Default) layout
+ * Two screens at top, full width (so different heights)
* @param width Window framebuffer width in pixels
* @param height Window framebuffer height in pixels
* @param is_swapped if true, the bottom screen will be displayed above the top screen
@@ -71,6 +71,16 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height, bool is_swapped, boo
*/
FramebufferLayout PortraitTopFullFrameLayout(u32 width, u32 height, bool is_swapped);
+/**
+ * Factory method for constructing the mobile Original layout
+ * Two screens at top, equal heights
+ * @param width Window framebuffer width in pixels
+ * @param height Window framebuffer height in pixels
+ * @param is_swapped if true, the bottom screen will be displayed above the top screen
+ * @return Newly created FramebufferLayout object with mobile portrait screen regions initialized
+ */
+FramebufferLayout PortraitOriginalLayout(u32 width, u32 height, bool is_swapped);
+
/**
* Factory method for constructing a FramebufferLayout with only the top or bottom screen
* @param width Window framebuffer width in pixels