diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 157ecea41..a35063922 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -582,6 +582,14 @@ void GRenderWindow::resizeEvent(QResizeEvent* event) { OnFramebufferSizeChanged(); } +void GRenderWindow::moveEvent(QMoveEvent* event) { + QWidget::moveEvent(event); + if (is_secondary) { + const auto screen_pos = Common::MakeVec(pos().x(), pos().y()); + SetScreenPos(screen_pos); + } +} + bool GRenderWindow::InitRenderTarget() { { // Create a dummy render widget so that Qt diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h index 1689eebb7..e31c43511 100644 --- a/src/citra_qt/bootmanager.h +++ b/src/citra_qt/bootmanager.h @@ -136,6 +136,7 @@ public: void closeEvent(QCloseEvent* event) override; void resizeEvent(QResizeEvent* event) override; + void moveEvent(QMoveEvent* event) override; void keyPressEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override; diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 53b67f9f9..b2069dd55 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -2482,18 +2482,24 @@ void GMainWindow::OnMouseActivity() { ShowMouseCursor(); } -void GMainWindow::mouseMoveEvent([[maybe_unused]] QMouseEvent* event) { +void GMainWindow::mouseMoveEvent(QMouseEvent*) { OnMouseActivity(); } -void GMainWindow::mousePressEvent([[maybe_unused]] QMouseEvent* event) { +void GMainWindow::mousePressEvent(QMouseEvent*) { OnMouseActivity(); } -void GMainWindow::mouseReleaseEvent([[maybe_unused]] QMouseEvent* event) { +void GMainWindow::mouseReleaseEvent(QMouseEvent*) { OnMouseActivity(); } +void GMainWindow::moveEvent(QMoveEvent* event) { + QMainWindow::moveEvent(event); + const auto screen_pos = Common::MakeVec(pos().x(), pos().y()); + render_window->SetScreenPos(screen_pos); +} + void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string details) { QString status_message; diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index d3c4d03dc..5767a7bbe 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -374,6 +374,7 @@ protected: void mouseMoveEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; + void moveEvent(QMoveEvent* event) override; }; Q_DECLARE_METATYPE(std::size_t); diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index 61b09583b..9edf62136 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -9,6 +9,7 @@ #include #include "common/common_types.h" +#include "common/vector_math.h" #include "core/3ds.h" #include "core/frontend/framebuffer_layout.h" @@ -217,6 +218,17 @@ public: config = val; } + /** + * Updates the position of the client window area relative to the origin of the host display. + */ + void SetScreenPos(const Common::Vec2i pos) { + screen_pos = pos; + } + + Common::Vec2i GetScreenPos() const { + return screen_pos; + } + /** * Returns system information about the drawing area. */ @@ -274,6 +286,7 @@ protected: bool is_secondary{}; bool strict_context_required{}; WindowSystemInfo window_info; + Common::Vec2i screen_pos{}; private: /** diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index 40b86fb68..f7e2152a8 100644 --- a/src/core/frontend/framebuffer_layout.cpp +++ b/src/core/frontend/framebuffer_layout.cpp @@ -4,6 +4,7 @@ #include +#include "common/alignment.h" #include "common/assert.h" #include "common/settings.h" #include "core/3ds.h" diff --git a/src/video_core/host_shaders/opengl_present_interlaced.frag b/src/video_core/host_shaders/opengl_present_interlaced.frag index 02e507d70..8bf25c712 100644 --- a/src/video_core/host_shaders/opengl_present_interlaced.frag +++ b/src/video_core/host_shaders/opengl_present_interlaced.frag @@ -12,10 +12,12 @@ layout(binding = 1) uniform sampler2D color_texture_r; uniform vec4 o_resolution; uniform int reverse_interlaced; +uniform ivec2 screen_pos; void main() { float screen_row = o_resolution.x * frag_tex_coord.x; - if (int(screen_row) % 2 == reverse_interlaced) + const int is_even = int(screen_pos.y % 2 == 0); + if (int(screen_row) % 2 == is_even) color = texture(color_texture, frag_tex_coord); else color = texture(color_texture_r, frag_tex_coord); diff --git a/src/video_core/renderer_opengl/post_processing_opengl.cpp b/src/video_core/renderer_opengl/post_processing_opengl.cpp index 1e479b65f..04462d9aa 100644 --- a/src/video_core/renderer_opengl/post_processing_opengl.cpp +++ b/src/video_core/renderer_opengl/post_processing_opengl.cpp @@ -49,6 +49,8 @@ uniform float4 i_resolution; uniform float4 o_resolution; // Layer uniform int layer; +// Screen position +uniform int2 screen_pos; uniform sampler2D color_texture; uniform sampler2D color_texture_r; @@ -119,6 +121,11 @@ float2 GetCoordinates() return frag_tex_coord; } +int2 GetScreenPos() +{ + return screen_pos; +} + void SetOutput(float4 color_in) { color = color_in; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index be778c764..b0dcb1433 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -54,8 +54,7 @@ struct ScreenRectVertex { * * @param flipped Whether the frame should be flipped upside down. */ -static std::array MakeOrthographicMatrix(const float width, const float height, - bool flipped) { +static std::array MakeOrthographicMatrix(u32 width, u32 height, bool flipped) { std::array matrix; // Laid out in column-major order @@ -446,6 +445,7 @@ void RendererOpenGL::ReloadShader() { uniform_i_resolution = glGetUniformLocation(shader.handle, "i_resolution"); uniform_o_resolution = glGetUniformLocation(shader.handle, "o_resolution"); uniform_layer = glGetUniformLocation(shader.handle, "layer"); + uniform_screen_pos = glGetUniformLocation(shader.handle, "screen_pos"); attrib_position = glGetAttribLocation(shader.handle, "vert_position"); attrib_tex_coord = glGetAttribLocation(shader.handle, "vert_tex_coord"); } @@ -678,8 +678,7 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f glClear(GL_COLOR_BUFFER_BIT); // Set projection matrix - std::array ortho_matrix = - MakeOrthographicMatrix((float)layout.width, (float)layout.height, flipped); + const auto ortho_matrix = MakeOrthographicMatrix(layout.width, layout.height, flipped); glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data()); // Bind texture in Texture Unit 0 @@ -690,6 +689,11 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced || Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::ReverseInterlaced; + // Set the screen position + const auto screen_pos = render_window.GetScreenPos() + + Common::MakeVec(layout.top_screen.left, layout.top_screen.bottom); + glUniform2i(uniform_screen_pos, screen_pos.x, screen_pos.y); + // Bind a second texture for the right eye if in Anaglyph mode if (stereo_single_screen) { glUniform1i(uniform_color_texture_r, 1); diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 5e005e8dc..12c994244 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -108,6 +108,7 @@ private: GLuint uniform_i_resolution; GLuint uniform_o_resolution; GLuint uniform_layer; + GLuint uniform_screen_pos; // Shader attribute input indices GLuint attrib_position;