SDL: fix relative warp emulation broken by #11460

From 25390d6c21da5ba9da1c0646254852ec5f6ba0a0 Mon Sep 17 00:00:00 2001
From: expikr <[EMAIL REDACTED]>
Date: Sat, 16 Nov 2024 06:14:28 +0800
Subject: [PATCH] fix relative warp emulation broken by #11460

---
 src/events/SDL_mouse.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c
index c89251c681d98..a62c1f9d1f92f 100644
--- a/src/events/SDL_mouse.c
+++ b/src/events/SDL_mouse.c
@@ -814,28 +814,31 @@ static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL
         yrel = 0.0f;
     }
 
-    { // modify internal state
-        if (relative) {
-            if (mouse->has_position) {
-                mouse->x += xrel;
-                mouse->y += yrel;
-                ConstrainMousePosition(mouse, window, &mouse->x, &mouse->y);
-            } else {
-                mouse->x = x;
-                mouse->y = y;
-            }
-            mouse->last_x = mouse->x;
-            mouse->last_y = mouse->y;
+    // TODO: should rework overall so that relative bool arg conveys intent,
+    // and do this logic at the SDL_SendMouseMotion level instead of here.
+    bool cmd_is_meant_as_delta = relative || (mouse->relative_mode && mouse->relative_mode_warp);
+    bool cmd_is_hardware_delta = relative;
+
+    // modify internal state
+    {
+        if (cmd_is_meant_as_delta) {
             mouse->x_accu += xrel;
             mouse->y_accu += yrel;
+        }
+
+        if (cmd_is_meant_as_delta && mouse->has_position) {
+            mouse->x += xrel;
+            mouse->y += yrel;
+            ConstrainMousePosition(mouse, window, &mouse->x, &mouse->y);
         } else {
-            // Use unclamped values if we're getting events outside the window
             mouse->x = x;
             mouse->y = y;
-            mouse->last_x = x;
-            mouse->last_y = y;
         }
         mouse->has_position = true;
+
+        // Use unclamped values if we're getting events outside the window
+        mouse->last_x = cmd_is_hardware_delta ? mouse->x : x;
+        mouse->last_y = cmd_is_hardware_delta ? mouse->y : y;
     }
 
     // Move the mouse cursor, if needed
@@ -846,7 +849,7 @@ static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL
 
     // Post the event, if desired
     if (SDL_EventEnabled(SDL_EVENT_MOUSE_MOTION)) {
-        if (!relative && window_is_relative) {
+        if (!cmd_is_meant_as_delta && window_is_relative) {
             if (!mouse->relative_mode_warp_motion) {
                 return;
             }