diff --git a/rpcs3/Emu/Io/MouseHandler.h b/rpcs3/Emu/Io/MouseHandler.h index 6d6e6dbf2d..49a72f1b71 100644 --- a/rpcs3/Emu/Io/MouseHandler.h +++ b/rpcs3/Emu/Io/MouseHandler.h @@ -107,8 +107,8 @@ using MouseDataList = std::list; struct Mouse { - s16 x_pos; - s16 y_pos; + s32 x_pos; + s32 y_pos; u8 buttons; // actual mouse button positions MouseTabletDataList m_tablet_datalist; @@ -208,7 +208,7 @@ public: } } - void Move(const s32 x_pos_new, const s32 y_pos_new, bool is_qt_fullscreen = false) + void Move(const s32 x_pos_new, const s32 y_pos_new, const bool is_qt_fullscreen = false, s32 x_delta = 0, s32 y_delta = 0) { semaphore_lock lock(mutex); @@ -230,19 +230,17 @@ public: new_data.update = CELL_MOUSE_DATA_UPDATE; new_data.buttons = m_mice[p].buttons; - if (is_qt_fullscreen) + if (!is_qt_fullscreen) { - new_data.x_axis = static_cast(std::clamp(x_pos_new, -127, 128)); - new_data.y_axis = static_cast(std::clamp(y_pos_new, -127, 128)); + x_delta = x_pos_new - m_mice[p].x_pos; + y_delta = y_pos_new - m_mice[p].y_pos; } - else - { - new_data.x_axis = static_cast(std::clamp(x_pos_new - m_mice[p].x_pos, -127, 128)); - new_data.y_axis = static_cast(std::clamp(y_pos_new - m_mice[p].y_pos, -127, 128)); - m_mice[p].x_pos = x_pos_new; - m_mice[p].y_pos = y_pos_new; - } + new_data.x_axis = static_cast(std::clamp(x_delta, -127, 128)); + new_data.y_axis = static_cast(std::clamp(y_delta, -127, 128)); + + m_mice[p].x_pos = x_pos_new; + m_mice[p].y_pos = y_pos_new; /*CellMouseRawData& rawdata = GetRawData(p); rawdata.data[rawdata.len % CELL_MOUSE_MAX_CODES] = 0; // (TODO) diff --git a/rpcs3/basic_mouse_handler.cpp b/rpcs3/basic_mouse_handler.cpp index babe75eb51..788c0dbace 100644 --- a/rpcs3/basic_mouse_handler.cpp +++ b/rpcs3/basic_mouse_handler.cpp @@ -93,9 +93,30 @@ void basic_mouse_handler::MouseMove(QMouseEvent* event) { if (m_target && m_target->visibility() == QWindow::Visibility::FullScreen) { - QPoint p_delta = m_target->geometry().topLeft() + QPoint(m_target->width() / 2, m_target->height() / 2); - QCursor::setPos(p_delta); - MouseHandlerBase::Move(event->x() - p_delta.x(), event->y() - p_delta.y(), true); + // get the screen dimensions + const QSize screen = m_target->size(); + + // get the center of the screen in global coordinates + QPoint p_center = m_target->geometry().topLeft() + QPoint(screen.width() / 2, screen.height() / 2); + + // reset the mouse to the center for consistent results since edge movement won't be registered + QCursor::setPos(m_target->screen(), p_center); + + // convert the center into screen coordinates + p_center = m_target->mapFromGlobal(p_center); + + // current mouse position, starting at the center + static QPoint p_real(p_center); + + // get the delta of the mouse position to the screen center + const QPoint p_delta = event->pos() - p_center; + + // update the current position without leaving the screen borders + p_real.setX(std::clamp(p_real.x() + p_delta.x(), 0, screen.width())); + p_real.setY(std::clamp(p_real.y() + p_delta.y(), 0, screen.height())); + + // pass the 'real' position and the current delta to the screen center + MouseHandlerBase::Move(p_real.x(), p_real.y(), true, p_delta.x(), p_delta.y()); } else {