diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h
index 31df12c5f..35bfd2a47 100644
--- a/src/android/app/src/main/jni/default_ini.h
+++ b/src/android/app/src/main/jni/default_ini.h
@@ -155,7 +155,7 @@ bg_blue =
bg_green =
# Whether and how Stereoscopic 3D should be rendered
-# 0 (default): Off, 1: Side by Side, 2: Anaglyph, 3: Interlaced, 4: Reverse Interlaced, 5: Cardboard VR
+# 0 (default): Off, 1: Side by Side, 2: Full Side by Side, 3: Anaglyph, 4: Interlaced, 5: Reverse Interlaced, 6: Cardboard VR
render_3d =
# Change 3D Intensity
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h
index be3c67948..2aa1d39b0 100644
--- a/src/citra/default_ini.h
+++ b/src/citra/default_ini.h
@@ -156,7 +156,7 @@ bg_blue =
bg_green =
# Whether and how Stereoscopic 3D should be rendered
-# 0 (default): Off, 1: Side by Side, 2: Anaglyph, 3: Interlaced, 4: Reverse Interlaced
+# 0 (default): Off, 1: Side by Side, 2: Full Side by Side, 3: Anaglyph, 4: Interlaced, 5: Reverse Interlaced
render_3d =
# Change 3D Intensity
diff --git a/src/citra_qt/configuration/configure_enhancements.ui b/src/citra_qt/configuration/configure_enhancements.ui
index a57d1cdbd..de43775d1 100644
--- a/src/citra_qt/configuration/configure_enhancements.ui
+++ b/src/citra_qt/configuration/configure_enhancements.ui
@@ -234,6 +234,11 @@
Side by Side
+ -
+
+ Full Side by Side
+
+
-
Anaglyph
diff --git a/src/common/settings.h b/src/common/settings.h
index e463ba4d7..97627a5c5 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -54,10 +54,11 @@ enum class LayoutOption : u32 {
enum class StereoRenderOption : u32 {
Off = 0,
SideBySide = 1,
- Anaglyph = 2,
- Interlaced = 3,
- ReverseInterlaced = 4,
- CardboardVR = 5
+ FullSideBySide = 2,
+ Anaglyph = 3,
+ Interlaced = 4,
+ ReverseInterlaced = 5,
+ CardboardVR = 6
};
// Which eye to render when 3d is off. 800px wide mode could be added here in the future, when
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index 11d2249ac..547e54fa0 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -172,14 +172,28 @@ FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, bool up
bot_screen = MaxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO);
emulation_aspect_ratio = (swapped) ? BOT_SCREEN_ASPECT_RATIO : TOP_SCREEN_ASPECT_RATIO;
}
+ if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::FullSideBySide &&
+ !(Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows &&
+ swapped)) {
+ emulation_aspect_ratio /= 2;
+ }
float window_aspect_ratio = static_cast(height) / width;
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);
+ if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::FullSideBySide &&
+ !(Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows &&
+ swapped)) {
+ top_screen =
+ top_screen.TranslateX((screen_window_area.GetWidth() / 2 - top_screen.GetWidth()) / 2);
+ bot_screen =
+ bot_screen.TranslateX((screen_window_area.GetWidth() / 2 - bot_screen.GetWidth()) / 2);
+ } else {
+ 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);
@@ -230,6 +244,9 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
small_screen_aspect_ratio = BOT_SCREEN_ASPECT_RATIO;
}
}
+ if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::FullSideBySide) {
+ emulation_aspect_ratio /= 2;
+ }
Common::Rectangle screen_window_area{0, 0, width, height};
Common::Rectangle total_rect = MaxRectangle(screen_window_area, emulation_aspect_ratio);
@@ -238,7 +255,11 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
Common::Rectangle small_screen = MaxRectangle(scaled_rect, small_screen_aspect_ratio);
if (window_aspect_ratio < emulation_aspect_ratio) {
- large_screen = large_screen.TranslateX((width - total_rect.GetWidth()) / 2);
+ if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::FullSideBySide) {
+ large_screen = large_screen.TranslateX((width / 2 - total_rect.GetWidth()) / 2);
+ } else {
+ large_screen = large_screen.TranslateX((width - total_rect.GetWidth()) / 2);
+ }
} else {
large_screen = large_screen.TranslateY((height - total_rect.GetHeight()) / 2);
}
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index ce22270cf..100d2464a 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -747,6 +747,15 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout,
top_screen_top, top_screen_width / 2, top_screen_height, orientation);
break;
}
+ case Settings::StereoRenderOption::FullSideBySide: {
+ DrawSingleScreen(screen_infos[0], top_screen_left, top_screen_top, top_screen_width,
+ top_screen_height, orientation);
+ glUniform1i(uniform_layer, 1);
+ DrawSingleScreen(screen_infos[1],
+ static_cast(top_screen_left + (layout.width / 2)),
+ top_screen_top, top_screen_width, top_screen_height, orientation);
+ break;
+ }
case Settings::StereoRenderOption::CardboardVR: {
DrawSingleScreen(screen_infos[0], top_screen_left, top_screen_top, top_screen_width,
top_screen_height, orientation);
@@ -801,6 +810,17 @@ void RendererOpenGL::DrawBottomScreen(const Layout::FramebufferLayout& layout,
}
break;
}
+ case Settings::StereoRenderOption::FullSideBySide: {
+ DrawSingleScreen(screen_infos[2], bottom_screen_left, bottom_screen_top,
+ bottom_screen_width, bottom_screen_height, orientation);
+ if (Settings::values.layout_option.GetValue() != Settings::LayoutOption::SeparateWindows){
+ glUniform1i(uniform_layer, 1);
+ DrawSingleScreen(
+ screen_infos[2], static_cast(bottom_screen_left + (layout.width / 2)),
+ bottom_screen_top, bottom_screen_width, bottom_screen_height, orientation);
+ }
+ break;
+ }
case Settings::StereoRenderOption::CardboardVR: {
DrawSingleScreen(screen_infos[2], bottom_screen_left, bottom_screen_top,
bottom_screen_width, bottom_screen_height, orientation);
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index dd0776c0e..e6d358c4b 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -703,6 +703,14 @@ void RendererVulkan::DrawTopScreen(const Layout::FramebufferLayout& layout,
top_screen_top, top_screen_width / 2, top_screen_height, orientation);
break;
}
+ case Settings::StereoRenderOption::FullSideBySide: {
+ DrawSingleScreen(0, top_screen_left, top_screen_top, top_screen_width,
+ top_screen_height, orientation);
+ draw_info.layer = 1;
+ DrawSingleScreen(1, static_cast(top_screen_left + (layout.width / 2)),
+ top_screen_top, top_screen_width, top_screen_height, orientation);
+ break;
+ }
case Settings::StereoRenderOption::CardboardVR: {
DrawSingleScreen(0, top_screen_left, top_screen_top, top_screen_width, top_screen_height,
orientation);
@@ -756,6 +764,17 @@ void RendererVulkan::DrawBottomScreen(const Layout::FramebufferLayout& layout,
}
break;
}
+ case Settings::StereoRenderOption::FullSideBySide: {
+ DrawSingleScreen(2, bottom_screen_left, bottom_screen_top, bottom_screen_width,
+ bottom_screen_height, orientation);
+ if (Settings::values.layout_option.GetValue() != Settings::LayoutOption::SeparateWindows){
+ draw_info.layer = 1;
+ DrawSingleScreen(2, static_cast(bottom_screen_left + (layout.width / 2)),
+ bottom_screen_top, bottom_screen_width, bottom_screen_height,
+ orientation);
+ }
+ break;
+ }
case Settings::StereoRenderOption::CardboardVR: {
DrawSingleScreen(2, bottom_screen_left, bottom_screen_top, bottom_screen_width,
bottom_screen_height, orientation);