Use SDL_SetRelativeMouseMode to detect mouse movements, fixes xinput issues
authorWuzzy <Wuzzy2@mail.ru>
Sat, 28 Oct 2017 17:48:54 +0200
changeset 12798 575c0de98505
parent 12797 8fa21750470f
child 12799 bca911f8e804
Use SDL_SetRelativeMouseMode to detect mouse movements, fixes xinput issues
ChangeLog.txt
hedgewars/SDLh.pas
hedgewars/hwengine.pas
hedgewars/uCursor.pas
hedgewars/uWorld.pas
--- a/ChangeLog.txt	Sat Oct 28 07:59:41 2017 +0200
+++ b/ChangeLog.txt	Sat Oct 28 17:48:54 2017 +0200
@@ -67,6 +67,7 @@
  + Temporarily suspend Heavy Wind mode while turn timer is not running
  + Engine supports now really gigantic maps
  * Fixed cursor often jumping back to screen center when putting target location while moving cursor
+ * Fixed cursor not working at all when using custom mouse sensitivity set by the xinput program
  * Fixed team getting infinite ammo when stockpiling >= 100 ammo (max. finite ammo is now limited to 99)
  * Fixed failure to collect crate across wrap world edge
  * Remove buggy “/finish” chat command
--- a/hedgewars/SDLh.pas	Sat Oct 28 07:59:41 2017 +0200
+++ b/hedgewars/SDLh.pas	Sat Oct 28 17:48:54 2017 +0200
@@ -1106,6 +1106,7 @@
 function  SDL_RenderSetViewport(window: PSDL_Window; rect: PSDL_Rect): LongInt; cdecl; external SDLLibName;
 
 function  SDL_GetRelativeMouseState(x, y: PLongInt): Byte; cdecl; external SDLLibName;
+procedure SDL_SetRelativeMouseMode(enabled: Boolean); cdecl; external SDLLibName;
 function  SDL_PixelFormatEnumToMasks(format: TSDL_ArrayByteOrder; bpp: PLongInt; Rmask, Gmask, Bmask, Amask: PLongInt): Boolean; cdecl; external SDLLibName;
 
 procedure SDL_WarpMouseInWindow(window: PSDL_Window; x, y: LongInt); cdecl; external SDLLibName;
--- a/hedgewars/hwengine.pas	Sat Oct 28 07:59:41 2017 +0200
+++ b/hedgewars/hwengine.pas	Sat Oct 28 17:48:54 2017 +0200
@@ -364,6 +364,7 @@
     if not allOK then exit;
     //SDL_StartTextInput();
     SDL_ShowCursor(0);
+    SDL_SetRelativeMouseMode(true);
 
 
 {$IFDEF USE_VIDEO_RECORDING}
--- a/hedgewars/uCursor.pas	Sat Oct 28 07:59:41 2017 +0200
+++ b/hedgewars/uCursor.pas	Sat Oct 28 17:48:54 2017 +0200
@@ -6,6 +6,7 @@
 procedure resetPosition;
 procedure updatePosition;
 procedure handlePositionUpdate(x, y: LongInt);
+procedure setSystemCursor(enabled: boolean);
 
 implementation
 
@@ -18,28 +19,16 @@
 
 procedure resetPosition;
 begin
-    // Move curser by 1px in case it's already centered.
-    // The game camera in the Alpha for 0.9.23 screwed up if
-    // the game started with the mouse already being centered.
-    // This fixes it, but we might have overlooked a related
-    // bug somewhere else.
-    // No big deal since this function is (so far) only called once.
-    SDL_WarpMouse((cScreenWidth div 2) + 1, cScreenHeight div 2);
     SDL_WarpMouse(cScreenWidth div 2, cScreenHeight div 2);
 end;
 
 procedure updatePosition;
 var x, y: LongInt;
 begin
-    SDL_GetMouseState(@x, @y);
+    SDL_GetRelativeMouseState(@x, @y);
 
-    if(x <> cScreenWidth div 2) or (y <> cScreenHeight div 2) then
-    begin
-        handlePositionUpdate(x - cScreenWidth div 2, y - cScreenHeight div 2);
-
-        if cHasFocus then
-            SDL_WarpMouse(cScreenWidth div 2, cScreenHeight div 2);
-    end
+    if(x <> 0) or (y <> 0) then
+        handlePositionUpdate(x, y);
 end;
 
 procedure handlePositionUpdate(x, y: LongInt);
@@ -48,4 +37,21 @@
     CursorPoint.Y:= CursorPoint.Y - y;
 end;
 
+procedure setSystemCursor(enabled: boolean);
+begin
+    if enabled then
+        begin
+        SDL_SetRelativeMouseMode(false);
+        if cHasFocus then
+            resetPosition();
+        SDL_ShowCursor(1);
+        end
+    else
+        begin
+        SDL_ShowCursor(0);
+        SDL_GetRelativeMouseState(nil, nil);
+        SDL_SetRelativeMouseMode(true);
+        end;
+end;
+
 end.
--- a/hedgewars/uWorld.pas	Sat Oct 28 07:59:41 2017 +0200
+++ b/hedgewars/uWorld.pas	Sat Oct 28 17:48:54 2017 +0200
@@ -2014,10 +2014,10 @@
 
 procedure updateCursorVisibility;
 begin
-    if isPaused or isAFK then
-        SDL_ShowCursor(1)
+    if isPaused or isAFK or (GameState = gsConfirm) then
+        uCursor.setSystemCursor(true)
     else
-        SDL_ShowCursor(ord(GameState = gsConfirm))
+        uCursor.setSystemCursor(false);
 end;
 
 procedure SetUtilityWidgetState(ammoType: TAmmoType);