add swap_eyes_3d setting and enable side by side full

This commit is contained in:
David Griswold 2024-08-27 11:27:22 -03:00 committed by OpenSauce04
parent 43dbe42b29
commit 05e00d3a47
5 changed files with 136 additions and 79 deletions

View File

@ -70,11 +70,11 @@ enum class SmallScreenPosition : u32 {
enum class StereoRenderOption : u32 {
Off = 0,
SideBySide = 1,
ReverseSideBySide = 2,
Anaglyph = 3,
Interlaced = 4,
ReverseInterlaced = 5,
CardboardVR = 6
SideBySideFull = 2,
Anaglyph = 4,
Interlaced = 5,
ReverseInterlaced = 6,
CardboardVR = 7
};
// Which eye to render when 3d is off. 800px wide mode could be added here in the future, when
@ -541,6 +541,7 @@ struct Values {
SwitchableSetting<StereoRenderOption> render_3d{StereoRenderOption::Off, "render_3d"};
SwitchableSetting<u32> factor_3d{0, "factor_3d"};
SwitchableSetting<bool> swap_eyes_3d{false, "swap_eyes"};
SwitchableSetting<MonoRenderOption> mono_render_option{MonoRenderOption::LeftEye,
"mono_render_option"};

View File

@ -67,9 +67,11 @@ bool EmuWindow::IsWithinTouchscreen(const Layout::FramebufferLayout& layout, uns
#endif
Settings::StereoRenderOption render_3d_mode = Settings::values.render_3d.GetValue();
if (render_3d_mode == Settings::StereoRenderOption::SideBySide ||
render_3d_mode == Settings::StereoRenderOption::ReverseSideBySide) {
if (framebuffer_x > layout.width &&
render_3d_mode == Settings::StereoRenderOption::SideBySideFull) {
framebuffer_x = static_cast<unsigned>(framebuffer_x - layout.width);
}
if (render_3d_mode == Settings::StereoRenderOption::SideBySide) {
return (framebuffer_y >= layout.bottom_screen.top &&
framebuffer_y < layout.bottom_screen.bottom &&
((framebuffer_x >= layout.bottom_screen.left / 2 &&
@ -94,17 +96,17 @@ bool EmuWindow::IsWithinTouchscreen(const Layout::FramebufferLayout& layout, uns
std::tuple<unsigned, unsigned> 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 (render_3d_mode == Settings::StereoRenderOption::SideBySide ||
render_3d_mode == Settings::StereoRenderOption::ReverseSideBySide)
if (new_x >= framebuffer_layout.width &&
render_3d_mode == Settings::StereoRenderOption::SideBySideFull) {
new_x -= framebuffer_layout.width;
} else if (new_x >= framebuffer_layout.width / 2) {
if (render_3d_mode == Settings::StereoRenderOption::SideBySide)
new_x -= framebuffer_layout.width / 2;
else if (render_3d_mode == Settings::StereoRenderOption::CardboardVR)
new_x -=
(framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2);
}
if (render_3d_mode == Settings::StereoRenderOption::SideBySide ||
render_3d_mode == Settings::StereoRenderOption::ReverseSideBySide) {
if (render_3d_mode == Settings::StereoRenderOption::SideBySide) {
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 {
@ -133,18 +135,18 @@ bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) {
if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y))
return false;
if (framebuffer_x >= framebuffer_layout.width / 2) {
if (render_3d_mode == Settings::StereoRenderOption::SideBySide ||
render_3d_mode == Settings::StereoRenderOption::ReverseSideBySide)
if (framebuffer_x >= framebuffer_layout.width &&
render_3d_mode == Settings::StereoRenderOption::SideBySideFull) {
framebuffer_x -= framebuffer_layout.width;
} else if (framebuffer_x >= framebuffer_layout.width / 2) {
if (render_3d_mode == Settings::StereoRenderOption::SideBySide)
framebuffer_x -= framebuffer_layout.width / 2;
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 (render_3d_mode == Settings::StereoRenderOption::SideBySide ||
render_3d_mode == Settings::StereoRenderOption::ReverseSideBySide) {
if (render_3d_mode == Settings::StereoRenderOption::SideBySide) {
touch_state->touch_x =
static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left / 2) /
(framebuffer_layout.bottom_screen.right / 2 -
@ -197,6 +199,13 @@ void EmuWindow::UpdateCurrentFramebufferLayout(u32 width, u32 height, bool is_po
width = std::max(width, min_size.first);
height = std::max(height, min_size.second);
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySideFull) {
if (Settings::values.upright_screen.GetValue()) {
height = height / 2;
} else {
width = width / 2;
}
}
if (is_portrait_mode) {
switch (portrait_layout_option) {
case Settings::PortraitLayoutOption::PortraitTopFullWidth:
@ -251,6 +260,13 @@ void EmuWindow::UpdateCurrentFramebufferLayout(u32 width, u32 height, bool is_po
break;
}
}
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySideFull) {
if (Settings::values.upright_screen.GetValue()) {
layout.height = height * 2;
} else {
layout.width = width * 2;
}
}
UpdateMinimumWindowSize(min_size);
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) {

View File

@ -347,39 +347,47 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped, bool
FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondary,
bool is_portrait) {
int width, height;
bool stereo_full =
Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySideFull;
FramebufferLayout layout;
if (is_portrait) {
auto layout_option = Settings::values.portrait_layout_option.GetValue();
switch (layout_option) {
case Settings::PortraitLayoutOption::PortraitCustomLayout:
return CustomFrameLayout(
std::max(Settings::values.custom_portrait_top_x.GetValue() +
Settings::values.custom_portrait_top_width.GetValue(),
Settings::values.custom_portrait_bottom_x.GetValue() +
Settings::values.custom_portrait_bottom_width.GetValue()),
std::max(Settings::values.custom_portrait_top_y.GetValue() +
Settings::values.custom_portrait_top_height.GetValue(),
Settings::values.custom_portrait_bottom_y.GetValue() +
Settings::values.custom_portrait_bottom_height.GetValue()),
Settings::values.swap_screen.GetValue(), is_portrait);
width = std::max(Settings::values.custom_portrait_top_x.GetValue() +
Settings::values.custom_portrait_top_width.GetValue(),
Settings::values.custom_portrait_bottom_x.GetValue() +
Settings::values.custom_portrait_bottom_width.GetValue());
height = std::max(Settings::values.custom_portrait_top_y.GetValue() +
Settings::values.custom_portrait_top_height.GetValue(),
Settings::values.custom_portrait_bottom_y.GetValue() +
Settings::values.custom_portrait_bottom_height.GetValue());
layout = CustomFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
is_portrait);
break;
case Settings::PortraitLayoutOption::PortraitTopFullWidth:
width = Core::kScreenTopWidth * res_scale;
height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale;
return PortraitTopFullFrameLayout(width, height,
Settings::values.swap_screen.GetValue());
layout =
PortraitTopFullFrameLayout(width, height, Settings::values.swap_screen.GetValue());
break;
}
} else {
auto layout_option = Settings::values.layout_option.GetValue();
switch (layout_option) {
case Settings::LayoutOption::CustomLayout:
return CustomFrameLayout(std::max(Settings::values.custom_top_x.GetValue() +
Settings::values.custom_top_width.GetValue(),
Settings::values.custom_bottom_x.GetValue() +
Settings::values.custom_bottom_width.GetValue()),
std::max(Settings::values.custom_top_y.GetValue() +
Settings::values.custom_top_height.GetValue(),
Settings::values.custom_bottom_y.GetValue() +
Settings::values.custom_bottom_height.GetValue()),
Settings::values.swap_screen.GetValue(), is_portrait);
layout =
CustomFrameLayout(std::max(Settings::values.custom_top_x.GetValue() +
Settings::values.custom_top_width.GetValue(),
Settings::values.custom_bottom_x.GetValue() +
Settings::values.custom_bottom_width.GetValue()),
std::max(Settings::values.custom_top_y.GetValue() +
Settings::values.custom_top_height.GetValue(),
Settings::values.custom_bottom_y.GetValue() +
Settings::values.custom_bottom_height.GetValue()),
Settings::values.swap_screen.GetValue(), is_portrait);
break;
case Settings::LayoutOption::SingleScreen:
#ifndef ANDROID
@ -394,11 +402,17 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
width = Core::kScreenTopWidth * res_scale;
height = Core::kScreenTopHeight * res_scale;
}
if (Settings::values.render_3d.GetValue() ==
Settings::StereoRenderOption::SideBySideFull) {
width = width / 2;
}
if (Settings::values.upright_screen.GetValue()) {
std::swap(width, height);
}
return SingleFrameLayout(width, height, swap_screens,
Settings::values.upright_screen.GetValue());
layout = SingleFrameLayout(width, height, swap_screens,
Settings::values.upright_screen.GetValue());
break;
}
case Settings::LayoutOption::LargeScreen: {
@ -427,10 +441,10 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
if (Settings::values.upright_screen.GetValue()) {
std::swap(width, height);
}
return LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
Settings::values.upright_screen.GetValue(),
Settings::values.large_screen_proportion.GetValue(),
Settings::values.small_screen_position.GetValue());
layout = LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
Settings::values.upright_screen.GetValue(),
Settings::values.large_screen_proportion.GetValue(),
Settings::values.small_screen_position.GetValue());
}
case Settings::LayoutOption::SideScreen:
width = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale;
@ -439,9 +453,9 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
if (Settings::values.upright_screen.GetValue()) {
std::swap(width, height);
}
return LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
Settings::values.upright_screen.GetValue(), 1,
Settings::SmallScreenPosition::MiddleRight);
layout = LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
Settings::values.upright_screen.GetValue(), 1,
Settings::SmallScreenPosition::MiddleRight);
case Settings::LayoutOption::Default:
default:
@ -451,10 +465,14 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
if (Settings::values.upright_screen.GetValue()) {
std::swap(width, height);
}
return DefaultFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
Settings::values.upright_screen.GetValue());
layout = DefaultFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
Settings::values.upright_screen.GetValue());
break;
}
}
if (stereo_full)
layout.width *= 2;
return layout;
UNREACHABLE();
}

View File

@ -726,6 +726,9 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout,
if (!layout.top_screen_enabled) {
return;
}
int leftside, rightside;
leftside = Settings::values.swap_eyes_3d.GetValue() ? 0 : 1;
rightside = Settings::values.swap_eyes_3d.GetValue() ? 1 : 0;
const float top_screen_left = static_cast<float>(top_screen.left);
const float top_screen_top = static_cast<float>(top_screen.top);
@ -742,29 +745,29 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout,
break;
}
case Settings::StereoRenderOption::SideBySide: {
DrawSingleScreen(screen_infos[0], top_screen_left / 2, top_screen_top, top_screen_width / 2,
top_screen_height, orientation);
DrawSingleScreen(screen_infos[leftside], top_screen_left / 2, top_screen_top,
top_screen_width / 2, top_screen_height, orientation);
glUniform1i(uniform_layer, 1);
DrawSingleScreen(screen_infos[1],
DrawSingleScreen(screen_infos[rightside],
static_cast<float>((top_screen_left / 2) + (layout.width / 2)),
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,
case Settings::StereoRenderOption::SideBySideFull: {
DrawSingleScreen(screen_infos[leftside], top_screen_left, top_screen_top, top_screen_width,
top_screen_height, orientation);
glUniform1i(uniform_layer, 1);
DrawSingleScreen(screen_infos[0],
static_cast<float>((top_screen_left / 2) + (layout.width / 2)),
top_screen_top, top_screen_width / 2, top_screen_height, orientation);
// DrawSingleScreen(screen_infos[rightside],
// static_cast<float>(top_screen_left + layout.width),
// 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,
DrawSingleScreen(screen_infos[leftside], top_screen_left, top_screen_top, top_screen_width,
top_screen_height, orientation);
glUniform1i(uniform_layer, 1);
DrawSingleScreen(
screen_infos[1],
screen_infos[rightside],
static_cast<float>(layout.cardboard.top_screen_right_eye + (layout.width / 2)),
top_screen_top, top_screen_width, top_screen_height, orientation);
break;
@ -772,8 +775,8 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout,
case Settings::StereoRenderOption::Anaglyph:
case Settings::StereoRenderOption::Interlaced:
case Settings::StereoRenderOption::ReverseInterlaced: {
DrawSingleScreenStereo(screen_infos[0], screen_infos[1], top_screen_left, top_screen_top,
top_screen_width, top_screen_height, orientation);
DrawSingleScreenStereo(screen_infos[leftside], screen_infos[rightside], top_screen_left,
top_screen_top, top_screen_width, top_screen_height, orientation);
break;
}
}
@ -800,7 +803,7 @@ void RendererOpenGL::DrawBottomScreen(const Layout::FramebufferLayout& layout,
break;
}
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);
@ -809,6 +812,15 @@ void RendererOpenGL::DrawBottomScreen(const Layout::FramebufferLayout& layout,
bottom_screen_top, bottom_screen_width / 2, bottom_screen_height, orientation);
break;
}
case Settings::StereoRenderOption::SideBySideFull: {
DrawSingleScreen(screen_infos[2], bottom_screen_left, bottom_screen_top,
bottom_screen_width, bottom_screen_height, orientation);
// glUniform1i(uniform_layer, 1);
// DrawSingleScreen(
// screen_infos[2], static_cast<float>(bottom_screen_left + layout.width),
// 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);

View File

@ -675,7 +675,9 @@ void RendererVulkan::DrawTopScreen(const Layout::FramebufferLayout& layout,
if (!layout.top_screen_enabled) {
return;
}
int leftside, rightside;
leftside = Settings::values.swap_eyes_3d.GetValue() ? 0 : 1;
rightside = Settings::values.swap_eyes_3d.GetValue() ? 1 : 0;
const float top_screen_left = static_cast<float>(top_screen.left);
const float top_screen_top = static_cast<float>(top_screen.top);
const float top_screen_width = static_cast<float>(top_screen.GetWidth());
@ -691,35 +693,36 @@ void RendererVulkan::DrawTopScreen(const Layout::FramebufferLayout& layout,
break;
}
case Settings::StereoRenderOption::SideBySide: {
DrawSingleScreen(0, top_screen_left / 2, top_screen_top, top_screen_width / 2,
DrawSingleScreen(leftside, top_screen_left / 2, top_screen_top, top_screen_width / 2,
top_screen_height, orientation);
draw_info.layer = 1;
DrawSingleScreen(1, static_cast<float>((top_screen_left / 2) + (layout.width / 2)),
DrawSingleScreen(rightside, static_cast<float>((top_screen_left / 2) + (layout.width / 2)),
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,
case Settings::StereoRenderOption::SideBySideFull: {
DrawSingleScreen(leftside, top_screen_left, top_screen_top, top_screen_width,
top_screen_height, orientation);
draw_info.layer = 1;
DrawSingleScreen(0, static_cast<float>((top_screen_left / 2) + (layout.width / 2)),
top_screen_top, top_screen_width / 2, top_screen_height, orientation);
DrawSingleScreen(rightside, 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);
DrawSingleScreen(leftside, top_screen_left, top_screen_top, top_screen_width,
top_screen_height, orientation);
draw_info.layer = 1;
DrawSingleScreen(
1, static_cast<float>(layout.cardboard.top_screen_right_eye + (layout.width / 2)),
rightside,
static_cast<float>(layout.cardboard.top_screen_right_eye + (layout.width / 2)),
top_screen_top, top_screen_width, top_screen_height, orientation);
break;
}
case Settings::StereoRenderOption::Anaglyph:
case Settings::StereoRenderOption::Interlaced:
case Settings::StereoRenderOption::ReverseInterlaced: {
DrawSingleScreenStereo(0, 1, top_screen_left, top_screen_top, top_screen_width,
top_screen_height, orientation);
DrawSingleScreenStereo(leftside, rightside, top_screen_left, top_screen_top,
top_screen_width, top_screen_height, orientation);
break;
}
}
@ -745,8 +748,7 @@ void RendererVulkan::DrawBottomScreen(const Layout::FramebufferLayout& layout,
bottom_screen_height, orientation);
break;
}
case Settings::StereoRenderOption::SideBySide: // Bottom screen is identical on both sides
case Settings::StereoRenderOption::ReverseSideBySide: {
case Settings::StereoRenderOption::SideBySide: {
DrawSingleScreen(2, bottom_screen_left / 2, bottom_screen_top, bottom_screen_width / 2,
bottom_screen_height, orientation);
draw_info.layer = 1;
@ -755,6 +757,14 @@ void RendererVulkan::DrawBottomScreen(const Layout::FramebufferLayout& layout,
orientation);
break;
}
case Settings::StereoRenderOption::SideBySideFull: {
DrawSingleScreen(2, bottom_screen_left, bottom_screen_top, bottom_screen_width,
bottom_screen_height, orientation);
draw_info.layer = 1;
DrawSingleScreen(2, 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);