From b8328593fe3d60ecb066ad0959d8c1e8dfb4d3c5 Mon Sep 17 00:00:00 2001 From: Zaneo Date: Tue, 14 Apr 2015 00:06:44 -0400 Subject: [PATCH] EmuWindow: Clip mouse input coordinates to emulated screen dimensions. If the mouse position for a mouse move/drag would take it outside the emulated screen dimensions, clip the coordinates to the emulated screen dimensions. Qt and GLFW will report negative coordinates for mouse positions to the left, or above citra window. Added restriction to mouse coordinates passed to touchmoved by Qt/GLFW to be greater or equal to zero. --- src/citra/emu_window/emu_window_glfw.cpp | 2 +- src/citra_qt/bootmanager.cpp | 2 +- src/common/emu_window.cpp | 22 ++++++++++++++++------ src/common/emu_window.h | 5 +++++ 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp index 997e3bc7d5..f879ee7ca7 100644 --- a/src/citra/emu_window/emu_window_glfw.cpp +++ b/src/citra/emu_window/emu_window_glfw.cpp @@ -31,7 +31,7 @@ void EmuWindow_GLFW::OnMouseButtonEvent(GLFWwindow* win, int button, int action, } void EmuWindow_GLFW::OnCursorPosEvent(GLFWwindow* win, double x, double y) { - GetEmuWindow(win)->TouchMoved(static_cast(x), static_cast(y)); + GetEmuWindow(win)->TouchMoved(static_cast(std::max(x, 0.0)), static_cast(std::max(y, 0.0))); } /// Called by GLFW when a key event occurs diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index b81bd61673..a8bff92475 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -288,7 +288,7 @@ void GRenderWindow::mousePressEvent(QMouseEvent *event) void GRenderWindow::mouseMoveEvent(QMouseEvent *event) { auto pos = event->pos(); - this->TouchMoved(static_cast(pos.x()), static_cast(pos.y())); + this->TouchMoved(static_cast(std::max(pos.x(), 0)), static_cast(std::max(pos.y(), 0))); } void GRenderWindow::mouseReleaseEvent(QMouseEvent *event) diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp index 6516fc633d..f5b6c7301d 100644 --- a/src/common/emu_window.cpp +++ b/src/common/emu_window.cpp @@ -28,6 +28,17 @@ static bool IsWithinTouchscreen(const EmuWindow::FramebufferLayout& layout, unsi framebuffer_x < layout.bottom_screen.right); } +std::tuple EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) { + + new_x = std::max(new_x, framebuffer_layout.bottom_screen.left); + new_x = std::min(new_x, framebuffer_layout.bottom_screen.right-1); + + new_y = std::max(new_y, framebuffer_layout.bottom_screen.top); + new_y = std::min(new_y, framebuffer_layout.bottom_screen.bottom-1); + + return std::make_tuple(new_x, new_y); +} + void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) return; @@ -52,14 +63,13 @@ void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { if (!touch_pressed) return; - if (IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) - TouchPressed(framebuffer_x, framebuffer_y); - else - TouchReleased(); + if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) + std::tie(framebuffer_x, framebuffer_y) = ClipToTouchScreen(framebuffer_x, framebuffer_y); + + TouchPressed(framebuffer_x, framebuffer_y); } -EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(unsigned width, - unsigned height) { +EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(unsigned width, unsigned height) { ASSERT(width > 0); ASSERT(height > 0); diff --git a/src/common/emu_window.h b/src/common/emu_window.h index c8e2de04ad..e0fc12a483 100644 --- a/src/common/emu_window.h +++ b/src/common/emu_window.h @@ -206,5 +206,10 @@ private: u16 touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320) u16 touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240) + /** + * Clip the provided coordinates to be inside the touchscreen area. + */ + std::tuple ClipToTouchScreen(unsigned new_x, unsigned new_y); + Service::HID::PadState pad_state; };