From e4788130e5a83406afa7db9564e38b94273c8b0d Mon Sep 17 00:00:00 2001 From: N00byKing Date: Fri, 6 Apr 2018 15:21:01 +0200 Subject: [PATCH 1/8] citra, citra_qt, settings.h: Add Options for Stereoscopic 3D --- src/citra/config.cpp | 4 +++ src/citra/default_ini.h | 8 ++++++ src/citra_qt/configuration/config.cpp | 4 +++ .../configuration/configure_graphics.cpp | 4 +++ .../configuration/configure_graphics.ui | 27 +++++++++++++++++++ src/core/settings.h | 3 +++ 6 files changed, 50 insertions(+) diff --git a/src/citra/config.cpp b/src/citra/config.cpp index b4e3a2ce9..29ebc39da 100644 --- a/src/citra/config.cpp +++ b/src/citra/config.cpp @@ -108,6 +108,10 @@ void Config::ReadValues() { Settings::values.frame_limit = static_cast(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); + Settings::values.toggle_3d = sdl2_config->GetBoolean("Renderer", "toggle_3d", false); + Settings::values.factor_3d = + static_cast(sdl2_config->GetInteger("Renderer", "factor_3d", 0)); + Settings::values.bg_red = (float)sdl2_config->GetReal("Renderer", "bg_red", 0.0); Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0); Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 0.0); diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h index 7179d6f94..9b2565962 100644 --- a/src/citra/default_ini.h +++ b/src/citra/default_ini.h @@ -116,6 +116,14 @@ bg_red = bg_blue = bg_green = +# Toggles Stereoscopic 3D +# 0 (default): Off, 1: On +toggle_3d = + +# Change 3D Intensity +# 0 - 100: Intensity. 0 (default) +factor_3d = + [Layout] # Layout for the screen inside the render window. # 0 (default): Default Top Bottom Screen, 1: Single Screen Only, 2: Large Screen Small Screen, 3: Side by Side diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index bdb296659..0e94a3d77 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -100,6 +100,8 @@ void Config::ReadValues() { qt_config->endGroup(); qt_config->beginGroup("Layout"); + Settings::values.toggle_3d = qt_config->value("toggle_3d", false).toBool(); + Settings::values.factor_3d = qt_config->value("factor_3d", 0).toInt(); Settings::values.layout_option = static_cast(qt_config->value("layout_option").toInt()); Settings::values.swap_screen = qt_config->value("swap_screen", false).toBool(); @@ -292,6 +294,8 @@ void Config::SaveValues() { qt_config->endGroup(); qt_config->beginGroup("Layout"); + qt_config->setValue("toggle_3d", Settings::values.toggle_3d); + qt_config->setValue("factor_3d", Settings::values.factor_3d); qt_config->setValue("layout_option", static_cast(Settings::values.layout_option)); qt_config->setValue("swap_screen", Settings::values.swap_screen); qt_config->setValue("custom_layout", Settings::values.custom_layout); diff --git a/src/citra_qt/configuration/configure_graphics.cpp b/src/citra_qt/configuration/configure_graphics.cpp index f167d3742..7868702f5 100644 --- a/src/citra_qt/configuration/configure_graphics.cpp +++ b/src/citra_qt/configuration/configure_graphics.cpp @@ -40,6 +40,8 @@ void ConfigureGraphics::setConfiguration() { ui->toggle_vsync->setChecked(Settings::values.use_vsync); ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit); ui->frame_limit->setValue(Settings::values.frame_limit); + ui->factor_3d->setValue(Settings::values.factor_3d); + ui->toggle_3d->setChecked(Settings::values.toggle_3d); ui->layout_combobox->setCurrentIndex(static_cast(Settings::values.layout_option)); ui->swap_screen->setChecked(Settings::values.swap_screen); } @@ -55,6 +57,8 @@ void ConfigureGraphics::applyConfiguration() { Settings::values.use_vsync = ui->toggle_vsync->isChecked(); Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked(); Settings::values.frame_limit = ui->frame_limit->value(); + Settings::values.factor_3d = ui->factor_3d->value(); + Settings::values.toggle_3d = ui->toggle_3d->isChecked(); Settings::values.layout_option = static_cast(ui->layout_combobox->currentIndex()); Settings::values.swap_screen = ui->swap_screen->isChecked(); diff --git a/src/citra_qt/configuration/configure_graphics.ui b/src/citra_qt/configuration/configure_graphics.ui index 330a5fb82..9ba4bd0b1 100644 --- a/src/citra_qt/configuration/configure_graphics.ui +++ b/src/citra_qt/configuration/configure_graphics.ui @@ -228,6 +228,33 @@ Layout + + + + + + Enable Stereoscopic 3D + + + + + + + % + + + 0 + + + 100 + + + 0 + + + + + diff --git a/src/core/settings.h b/src/core/settings.h index b57a1cbed..d715388c8 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -132,6 +132,9 @@ struct Values { float bg_green; float bg_blue; + bool toggle_3d; + u8 factor_3d; + // Audio std::string sink_id; bool enable_audio_stretching; From 2814bbc3dae881e20fc22e084e5ea15ded8760fd Mon Sep 17 00:00:00 2001 From: N00byKing Date: Fri, 6 Apr 2018 15:25:13 +0200 Subject: [PATCH 2/8] renderer_opengl: Allow usage of Stereoscopic 3D --- .../renderer_opengl/renderer_opengl.cpp | 28 ++++++++++++++----- .../renderer_opengl/renderer_opengl.h | 4 +-- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 65c18aecc..10d3d382b 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -103,12 +103,13 @@ void RendererOpenGL::SwapBuffers() { OpenGLState prev_state = OpenGLState::GetCurState(); state.Apply(); - for (int i : {0, 1}) { - const auto& framebuffer = GPU::g_regs.framebuffer_config[i]; + for (int i : {0, 1, 2}) { + int fb_id = i == 2 ? 1 : 0; + const auto& framebuffer = GPU::g_regs.framebuffer_config[fb_id]; // Main LCD (0): 0x1ED02204, Sub LCD (1): 0x1ED02A04 u32 lcd_color_addr = - (i == 0) ? LCD_REG_INDEX(color_fill_top) : LCD_REG_INDEX(color_fill_bottom); + (fb_id == 0) ? LCD_REG_INDEX(color_fill_top) : LCD_REG_INDEX(color_fill_bottom); lcd_color_addr = HW::VADDR_LCD + 4 * lcd_color_addr; LCD::Regs::ColorFill color_fill = {0}; LCD::Read(color_fill.raw, lcd_color_addr); @@ -129,7 +130,7 @@ void RendererOpenGL::SwapBuffers() { // performance problem. ConfigureFramebufferTexture(screen_infos[i].texture, framebuffer); } - LoadFBToScreenInfo(framebuffer, screen_infos[i]); + LoadFBToScreenInfo(framebuffer, screen_infos[i], i == 1); // Resize the texture in case the framebuffer size has changed screen_infos[i].texture.width = framebuffer.width; @@ -160,10 +161,12 @@ void RendererOpenGL::SwapBuffers() { * Loads framebuffer from emulated memory into the active OpenGL texture. */ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& framebuffer, - ScreenInfo& screen_info) { + ScreenInfo& screen_info, bool right_eye) { const PAddr framebuffer_addr = - framebuffer.active_fb == 0 ? framebuffer.address_left1 : framebuffer.address_left2; + framebuffer.active_fb == 0 + ? (!right_eye ? framebuffer.address_left1 : framebuffer.address_right1) + : (!right_eye ? framebuffer.address_left2 : framebuffer.address_right2); LOG_TRACE(Render_OpenGL, "0x%08x bytes from 0x%08x(%dx%d), fmt %x", framebuffer.stride * framebuffer.height, framebuffer_addr, (int)framebuffer.width, @@ -397,11 +400,22 @@ void RendererOpenGL::DrawScreens() { if (layout.top_screen_enabled) { DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left, (float)top_screen.top, (float)top_screen.GetWidth(), (float)top_screen.GetHeight()); + if (Settings::values.toggle_3d) { + DrawSingleScreenRotated( + screen_infos[1], ((float)top_screen.left * 3) + (float)top_screen.GetWidth(), + (float)top_screen.top, (float)top_screen.GetWidth(), (float)top_screen.GetHeight()); + } } if (layout.bottom_screen_enabled) { - DrawSingleScreenRotated(screen_infos[1], (float)bottom_screen.left, + DrawSingleScreenRotated(screen_infos[2], (float)bottom_screen.left, (float)bottom_screen.top, (float)bottom_screen.GetWidth(), (float)bottom_screen.GetHeight()); + if (Settings::values.toggle_3d) { + DrawSingleScreenRotated( + screen_infos[2], ((float)bottom_screen.left * 3) + (float)bottom_screen.GetWidth(), + (float)bottom_screen.top, (float)bottom_screen.GetWidth(), + (float)bottom_screen.GetHeight()); + } } m_current_frame++; diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index f827a26af..991e9475f 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -62,7 +62,7 @@ private: // Loads framebuffer from emulated memory into the display information structure void LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& framebuffer, - ScreenInfo& screen_info); + ScreenInfo& screen_info, bool right_eye); // Fills active OpenGL texture with the given RGB color. void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture); @@ -76,7 +76,7 @@ private: OGLProgram shader; /// Display information for top and bottom screens respectively - std::array screen_infos; + std::array screen_infos; // Shader uniform location indices GLuint uniform_modelview_matrix; From f4894d5677f37b3be15f765d9b9c38dd18018630 Mon Sep 17 00:00:00 2001 From: N00byKing Date: Fri, 6 Apr 2018 15:27:56 +0200 Subject: [PATCH 3/8] shared_page: Allow Setting the 3D Slider Currently, changing the Option while the Game is running does not work --- src/core/hle/shared_page.cpp | 4 ++++ src/core/hle/shared_page.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/core/hle/shared_page.cpp b/src/core/hle/shared_page.cpp index 8a8a32d51..11184deea 100644 --- a/src/core/hle/shared_page.cpp +++ b/src/core/hle/shared_page.cpp @@ -97,4 +97,8 @@ void Set3DLed(u8 state) { shared_page.ledstate_3d = state; } +void Set3DSliderState(float_le state) { + shared_page.sliderstate_3d = state; +} + } // namespace SharedPage diff --git a/src/core/hle/shared_page.h b/src/core/hle/shared_page.h index 4d3f0d455..5ba413a95 100644 --- a/src/core/hle/shared_page.h +++ b/src/core/hle/shared_page.h @@ -84,4 +84,6 @@ void SetWifiLinkLevel(WifiLinkLevel); void Set3DLed(u8); +void Set3DSliderState(float_le); + } // namespace SharedPage From 594e95084beff1f7829b5db8c9f28801a127caa1 Mon Sep 17 00:00:00 2001 From: N00byKing Date: Fri, 6 Apr 2018 16:32:17 +0200 Subject: [PATCH 4/8] shared_page: Set 3D Slider --- src/core/hle/shared_page.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/hle/shared_page.cpp b/src/core/hle/shared_page.cpp index 11184deea..20780c223 100644 --- a/src/core/hle/shared_page.cpp +++ b/src/core/hle/shared_page.cpp @@ -8,6 +8,7 @@ #include "core/core_timing.h" #include "core/hle/service/ptm/ptm.h" #include "core/hle/shared_page.h" +#include "core/settings.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -83,6 +84,10 @@ void Init() { update_time_event = CoreTiming::RegisterEvent("SharedPage::UpdateTimeCallback", UpdateTimeCallback); CoreTiming::ScheduleEvent(0, update_time_event); + + float_le slidestate = + Settings::values.toggle_3d ? (float_le)Settings::values.factor_3d / 100 : 0.0f; + shared_page.sliderstate_3d = slidestate; } void SetMacAddress(const MacAddress& addr) { From d27312b8161309132a3725bfab66d263c6d1e0a6 Mon Sep 17 00:00:00 2001 From: N00byKing Date: Fri, 6 Apr 2018 23:36:57 +0200 Subject: [PATCH 5/8] shared_page: Remove Get3DSliderstate --- src/core/hle/shared_page.cpp | 6 +----- src/core/hle/shared_page.h | 2 -- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/core/hle/shared_page.cpp b/src/core/hle/shared_page.cpp index 20780c223..730f0271f 100644 --- a/src/core/hle/shared_page.cpp +++ b/src/core/hle/shared_page.cpp @@ -85,7 +85,7 @@ void Init() { CoreTiming::RegisterEvent("SharedPage::UpdateTimeCallback", UpdateTimeCallback); CoreTiming::ScheduleEvent(0, update_time_event); - float_le slidestate = + float slidestate = Settings::values.toggle_3d ? (float_le)Settings::values.factor_3d / 100 : 0.0f; shared_page.sliderstate_3d = slidestate; } @@ -102,8 +102,4 @@ void Set3DLed(u8 state) { shared_page.ledstate_3d = state; } -void Set3DSliderState(float_le state) { - shared_page.sliderstate_3d = state; -} - } // namespace SharedPage diff --git a/src/core/hle/shared_page.h b/src/core/hle/shared_page.h index 5ba413a95..4d3f0d455 100644 --- a/src/core/hle/shared_page.h +++ b/src/core/hle/shared_page.h @@ -84,6 +84,4 @@ void SetWifiLinkLevel(WifiLinkLevel); void Set3DLed(u8); -void Set3DSliderState(float_le); - } // namespace SharedPage From 8c0ede544f54bace5909c7da55984fa0fef1fdb2 Mon Sep 17 00:00:00 2001 From: jmorriz124 <38574033+jmorriz124@users.noreply.github.com> Date: Fri, 27 Apr 2018 11:49:11 -0400 Subject: [PATCH 6/8] 3dtv botenable improved (#1) * Fixed crash when right eye isn't available * Enabled swap screens in stereo views. Fixed window alignment in stereo views to handle all screen aspect ratios. * Minor code cleanup and clang fomat updates. * Minor cleanup of swapped and aspect ratio code --- src/video_core/renderer_opengl/renderer_opengl.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 10d3d382b..c5060571f 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -163,6 +163,9 @@ void RendererOpenGL::SwapBuffers() { void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& framebuffer, ScreenInfo& screen_info, bool right_eye) { + if (framebuffer.address_right1 == 0 || framebuffer.address_right2 == 0) + right_eye = false; + const PAddr framebuffer_addr = framebuffer.active_fb == 0 ? (!right_eye ? framebuffer.address_left1 : framebuffer.address_right1) From 523c52c7088ddfba0b2461a4c418f91f314dc7b1 Mon Sep 17 00:00:00 2001 From: N00byKing Date: Fri, 1 Jun 2018 13:53:38 +0200 Subject: [PATCH 7/8] renderer_opengl: Add Universal 3D Layout Adaption --- .../renderer_opengl/renderer_opengl.cpp | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index c5060571f..625a3755b 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -401,23 +401,32 @@ void RendererOpenGL::DrawScreens() { glUniform1i(uniform_color_texture, 0); if (layout.top_screen_enabled) { - DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left, (float)top_screen.top, - (float)top_screen.GetWidth(), (float)top_screen.GetHeight()); - if (Settings::values.toggle_3d) { - DrawSingleScreenRotated( - screen_infos[1], ((float)top_screen.left * 3) + (float)top_screen.GetWidth(), - (float)top_screen.top, (float)top_screen.GetWidth(), (float)top_screen.GetHeight()); + if (!Settings::values.toggle_3d) { + DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left, (float)top_screen.top, + (float)top_screen.GetWidth(), (float)top_screen.GetHeight()); + } else { + DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left / 2, + (float)top_screen.top, (float)top_screen.GetWidth() / 2, + (float)top_screen.GetHeight()); + DrawSingleScreenRotated(screen_infos[1], + ((float)top_screen.left / 2) + ((float)layout.width / 2), + (float)top_screen.top, (float)top_screen.GetWidth() / 2, + (float)top_screen.GetHeight()); } } if (layout.bottom_screen_enabled) { - DrawSingleScreenRotated(screen_infos[2], (float)bottom_screen.left, - (float)bottom_screen.top, (float)bottom_screen.GetWidth(), - (float)bottom_screen.GetHeight()); - if (Settings::values.toggle_3d) { - DrawSingleScreenRotated( - screen_infos[2], ((float)bottom_screen.left * 3) + (float)bottom_screen.GetWidth(), - (float)bottom_screen.top, (float)bottom_screen.GetWidth(), - (float)bottom_screen.GetHeight()); + if (!Settings::values.toggle_3d) { + DrawSingleScreenRotated(screen_infos[2], (float)bottom_screen.left, + (float)bottom_screen.top, (float)bottom_screen.GetWidth(), + (float)bottom_screen.GetHeight()); + } else { + DrawSingleScreenRotated(screen_infos[2], (float)bottom_screen.left / 2, + (float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2, + (float)bottom_screen.GetHeight()); + DrawSingleScreenRotated(screen_infos[2], + ((float)bottom_screen.left / 2) + ((float)layout.width / 2), + (float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2, + (float)bottom_screen.GetHeight()); } } From 74367203cf0d9683e47633862549a9d2ba453d83 Mon Sep 17 00:00:00 2001 From: N00byKing Date: Sun, 17 Jun 2018 13:52:16 +0200 Subject: [PATCH 8/8] emu_window: Adapt Touchscreen to 3D Settings --- src/core/frontend/emu_window.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp index e67394177..5aa98238e 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp @@ -60,9 +60,17 @@ EmuWindow::~EmuWindow() { */ static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x, unsigned framebuffer_y) { - return ( - framebuffer_y >= layout.bottom_screen.top && framebuffer_y < layout.bottom_screen.bottom && - framebuffer_x >= layout.bottom_screen.left && framebuffer_x < layout.bottom_screen.right); + if (Settings::values.toggle_3d) { + 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); + } else { + return (framebuffer_y >= layout.bottom_screen.top && + framebuffer_y < layout.bottom_screen.bottom && + framebuffer_x >= layout.bottom_screen.left && + framebuffer_x < layout.bottom_screen.right); + } } std::tuple EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) { @@ -80,9 +88,16 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { return; std::lock_guard guard(touch_state->mutex); - touch_state->touch_x = - static_cast(framebuffer_x - framebuffer_layout.bottom_screen.left) / - (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left); + if (Settings::values.toggle_3d) { + touch_state->touch_x = + static_cast(framebuffer_x - framebuffer_layout.bottom_screen.left / 2) / + (framebuffer_layout.bottom_screen.right / 2 - + framebuffer_layout.bottom_screen.left / 2); + } else { + touch_state->touch_x = + static_cast(framebuffer_x - framebuffer_layout.bottom_screen.left) / + (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left); + } touch_state->touch_y = static_cast(framebuffer_y - framebuffer_layout.bottom_screen.top) / (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top);