From a30f9a828107a22959a909378d8a39b8876bda8a Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Sat, 24 Aug 2024 13:17:45 +0100 Subject: [PATCH] Added "Reverse Side by Side" Sterioscopic 3D mode --- .../app/src/main/res/values/arrays.xml | 1 + .../app/src/main/res/values/strings.xml | 1 + src/common/settings.h | 9 ++++--- src/core/frontend/emu_window.cpp | 27 +++++++++++++------ .../configuration/configure_enhancements.ui | 5 ++++ .../renderer_opengl/renderer_opengl.cpp | 12 ++++++++- .../renderer_vulkan/renderer_vulkan.cpp | 13 +++++++-- 7 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 66dfd8707..bd819acd6 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -166,6 +166,7 @@ @string/off @string/side_by_side + @string/reverse_side_by_side @string/anaglyph @string/interlaced @string/reverse_interlaced diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 9e4511172..bcac3b8c1 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -563,6 +563,7 @@ Side by Side + Reverse Side by Side Anaglyph Interlaced Reverse Interlaced diff --git a/src/common/settings.h b/src/common/settings.h index a7991514c..a7867651b 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -56,10 +56,11 @@ enum class PortraitLayoutOption : u32 { enum class StereoRenderOption : u32 { Off = 0, SideBySide = 1, - Anaglyph = 2, - Interlaced = 3, - ReverseInterlaced = 4, - CardboardVR = 5 + ReverseSideBySide = 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/emu_window.cpp b/src/core/frontend/emu_window.cpp index 20edbad66..07c78c12b 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp @@ -66,14 +66,17 @@ bool EmuWindow::IsWithinTouchscreen(const Layout::FramebufferLayout& layout, uns } #endif - if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) { + Settings::StereoRenderOption render_3d_mode = Settings::values.render_3d.GetValue(); + + if (render_3d_mode == Settings::StereoRenderOption::SideBySide || + render_3d_mode == Settings::StereoRenderOption::ReverseSideBySide) { return (framebuffer_y >= layout.bottom_screen.top && framebuffer_y < layout.bottom_screen.bottom && ((framebuffer_x >= layout.bottom_screen.left / 2 && framebuffer_x < layout.bottom_screen.right / 2) || (framebuffer_x >= (layout.bottom_screen.left / 2) + (layout.width / 2) && framebuffer_x < (layout.bottom_screen.right / 2) + (layout.width / 2)))); - } else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) { + } else if (render_3d_mode == Settings::StereoRenderOption::CardboardVR) { return (framebuffer_y >= layout.bottom_screen.top && framebuffer_y < layout.bottom_screen.bottom && ((framebuffer_x >= layout.bottom_screen.left && @@ -90,14 +93,18 @@ bool EmuWindow::IsWithinTouchscreen(const Layout::FramebufferLayout& layout, uns } std::tuple EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) const { + Settings::StereoRenderOption render_3d_mode = Settings::values.render_3d.GetValue(); + if (new_x >= framebuffer_layout.width / 2) { - if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) + if (render_3d_mode == Settings::StereoRenderOption::SideBySide || + render_3d_mode == Settings::StereoRenderOption::ReverseSideBySide) new_x -= framebuffer_layout.width / 2; - else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) + else if (render_3d_mode == Settings::StereoRenderOption::CardboardVR) new_x -= (framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2); } - if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) { + if (render_3d_mode == Settings::StereoRenderOption::SideBySide || + render_3d_mode == Settings::StereoRenderOption::ReverseSideBySide) { new_x = std::max(new_x, framebuffer_layout.bottom_screen.left / 2); new_x = std::min(new_x, framebuffer_layout.bottom_screen.right / 2 - 1); } else { @@ -122,18 +129,22 @@ void EmuWindow::CreateTouchState() { } bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { + Settings::StereoRenderOption render_3d_mode = Settings::values.render_3d.GetValue(); + if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) return false; if (framebuffer_x >= framebuffer_layout.width / 2) { - if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) + if (render_3d_mode == Settings::StereoRenderOption::SideBySide || + render_3d_mode == Settings::StereoRenderOption::ReverseSideBySide) framebuffer_x -= framebuffer_layout.width / 2; - else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) + else if (render_3d_mode == Settings::StereoRenderOption::CardboardVR) framebuffer_x -= (framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2); } std::scoped_lock guard(touch_state->mutex); - if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) { + if (render_3d_mode == Settings::StereoRenderOption::SideBySide || + render_3d_mode == Settings::StereoRenderOption::ReverseSideBySide) { touch_state->touch_x = static_cast(framebuffer_x - framebuffer_layout.bottom_screen.left / 2) / (framebuffer_layout.bottom_screen.right / 2 - diff --git a/src/lime_qt/configuration/configure_enhancements.ui b/src/lime_qt/configuration/configure_enhancements.ui index f2128191f..7287aa331 100644 --- a/src/lime_qt/configuration/configure_enhancements.ui +++ b/src/lime_qt/configuration/configure_enhancements.ui @@ -234,6 +234,11 @@ Side by Side + + + Reverse Side by Side + + Anaglyph diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 309c72fdb..6b99075c1 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -750,6 +750,15 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout, top_screen_top, top_screen_width / 2, top_screen_height, orientation); break; } + case Settings::StereoRenderOption::ReverseSideBySide: { + DrawSingleScreen(screen_infos[1], top_screen_left / 2, top_screen_top, top_screen_width / 2, + top_screen_height, orientation); + glUniform1i(uniform_layer, 1); + DrawSingleScreen(screen_infos[0], + static_cast((top_screen_left / 2) + (layout.width / 2)), + top_screen_top, top_screen_width / 2, 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); @@ -790,7 +799,8 @@ void RendererOpenGL::DrawBottomScreen(const Layout::FramebufferLayout& layout, bottom_screen_width, bottom_screen_height, orientation); break; } - case Settings::StereoRenderOption::SideBySide: { + case Settings::StereoRenderOption::SideBySide: // Bottom screen is identical on both sides + case Settings::StereoRenderOption::ReverseSideBySide: { DrawSingleScreen(screen_infos[2], bottom_screen_left / 2, bottom_screen_top, bottom_screen_width / 2, bottom_screen_height, orientation); glUniform1i(uniform_layer, 1); diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 6b7356574..edce31a39 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -1,4 +1,4 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Lime3DS Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -694,6 +694,14 @@ void RendererVulkan::DrawTopScreen(const Layout::FramebufferLayout& layout, top_screen_top, top_screen_width / 2, top_screen_height, orientation); break; } + case Settings::StereoRenderOption::ReverseSideBySide: { + DrawSingleScreen(1, top_screen_left / 2, top_screen_top, top_screen_width / 2, + top_screen_height, orientation); + draw_info.layer = 1; + DrawSingleScreen(0, static_cast((top_screen_left / 2) + (layout.width / 2)), + top_screen_top, top_screen_width / 2, top_screen_height, orientation); + break; + } case Settings::StereoRenderOption::CardboardVR: { DrawSingleScreen(0, top_screen_left, top_screen_top, top_screen_width, top_screen_height, orientation); @@ -733,7 +741,8 @@ void RendererVulkan::DrawBottomScreen(const Layout::FramebufferLayout& layout, bottom_screen_height, orientation); break; } - case Settings::StereoRenderOption::SideBySide: { + case Settings::StereoRenderOption::SideBySide: // Bottom screen is identical on both sides + case Settings::StereoRenderOption::ReverseSideBySide: { DrawSingleScreen(2, bottom_screen_left / 2, bottom_screen_top, bottom_screen_width / 2, bottom_screen_height, orientation); draw_info.layer = 1;