# HG changeset patch # User Wuzzy # Date 1555609465 -7200 # Node ID 9443dc6663ba1a725d65368538cb812c0b13367e # Parent b2beb784e4b552806a727734b04b4be29275326d Refactor mouse movement handling diff -r b2beb784e4b5 -r 9443dc6663ba hedgewars/SDLh.pas --- a/hedgewars/SDLh.pas Tue Apr 16 00:07:15 2019 +0300 +++ b/hedgewars/SDLh.pas Thu Apr 18 19:44:25 2019 +0200 @@ -109,6 +109,10 @@ SDL_BUTTON_X1 = 4; SDL_BUTTON_X2 = 5; + // SDL_ShowCursor consts + SDL_QUERY = -1; + SDL_DISABLE = 0; + SDL_ENABLE = 1; SDL_TEXTEDITINGEVENT_TEXT_SIZE = 32; SDL_TEXTINPUTEVENT_TEXT_SIZE = 32; @@ -554,6 +558,7 @@ TSDL_Keycode = LongInt; TSDL_Scancode = LongInt; TSDL_JoystickID = LongInt; + TSDL_bool = LongInt; TSDL_eventaction = (SDL_ADDEVENT, SDL_PEEPEVENT, SDL_GETEVENT); @@ -1107,6 +1112,7 @@ function SDL_RenderReadPixels(renderer: PSDL_Renderer; rect: PSDL_Rect; format: LongInt; pixels: Pointer; pitch: LongInt): LongInt; cdecl; external SDLLibName; function SDL_RenderSetViewport(window: PSDL_Window; rect: PSDL_Rect): LongInt; cdecl; external SDLLibName; +function SDL_SetRelativeMouseMode(enabled: TSDL_bool): LongInt; cdecl; external SDLLibName; function SDL_GetRelativeMouseState(x, y: PLongInt): Byte; cdecl; external SDLLibName; function SDL_PixelFormatEnumToMasks(format: TSDL_ArrayByteOrder; bpp: PLongInt; Rmask, Gmask, Bmask, Amask: PLongInt): Boolean; cdecl; external SDLLibName; diff -r b2beb784e4b5 -r 9443dc6663ba hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Tue Apr 16 00:07:15 2019 +0300 +++ b/hedgewars/hwengine.pas Thu Apr 18 19:44:25 2019 +0200 @@ -254,14 +254,17 @@ SDL_FINGERUP: onTouchUp(event.tfinger.x, event.tfinger.y, event.tfinger.fingerId); {$ELSE} + SDL_MOUSEMOTION: + ProcessMouseMotion(event.motion.xrel, event.motion.yrel); + SDL_MOUSEBUTTONDOWN: if GameState = gsConfirm then ParseCommand('quit', true) else - if (GameState >= gsGame) then ProcessMouse(event.button, true); + if (GameState >= gsGame) then ProcessMouseButton(event.button, true); SDL_MOUSEBUTTONUP: - if (GameState >= gsGame) then ProcessMouse(event.button, false); + if (GameState >= gsGame) then ProcessMouseButton(event.button, false); SDL_MOUSEWHEEL: begin @@ -383,8 +386,8 @@ end; if not allOK then exit; - SDL_ShowCursor(0); + SDL_ShowCursor(SDL_DISABLE); {$IFDEF USE_VIDEO_RECORDING} if GameType = gmtRecord then diff -r b2beb784e4b5 -r 9443dc6663ba hedgewars/uCursor.pas --- a/hedgewars/uCursor.pas Tue Apr 16 00:07:15 2019 +0300 +++ b/hedgewars/uCursor.pas Thu Apr 18 19:44:25 2019 +0200 @@ -4,7 +4,9 @@ procedure init; procedure resetPosition; -procedure updatePosition; +procedure resetPositionDelta(); +procedure updatePositionDelta(xrel, yrel: LongInt); +procedure updatePosition(); procedure handlePositionUpdate(x, y: LongInt); implementation @@ -13,38 +15,35 @@ procedure init; begin + SDL_ShowCursor(SDL_DISABLE); resetPosition(); + SDL_SetRelativeMouseMode(SDL_TRUE); end; procedure resetPosition; begin if GameType = gmtRecord then exit; - // 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); + resetPositionDelta(); +end; + +procedure resetPositionDelta(); +begin + CursorPointDelta.X:= 0; + CursorPointDelta.Y:= 0; end; -procedure updatePosition; -var x, y: LongInt; +procedure updatePositionDelta(xrel, yrel: LongInt); begin - x:= cScreenWidth div 2; - y:= cScreenHeight div 2; - if GameType <> gmtRecord then - SDL_GetMouseState(@x, @y); + CursorPointDelta.X:= CursorPointDelta.X + xrel; + CursorPointDelta.Y:= CursorPointDelta.Y + yrel; +end; - if(x <> cScreenWidth div 2) or (y <> cScreenHeight div 2) then - begin - handlePositionUpdate(x - cScreenWidth div 2, y - cScreenHeight div 2); - - if cHasFocus and (GameType <> gmtRecord) then - SDL_WarpMouse(cScreenWidth div 2, cScreenHeight div 2); - end +procedure updatePosition(); +begin + handlePositionUpdate(CursorPointDelta.X, CursorPointDelta.Y); + resetPositionDelta(); end; procedure handlePositionUpdate(x, y: LongInt); diff -r b2beb784e4b5 -r 9443dc6663ba hedgewars/uInputHandler.pas --- a/hedgewars/uInputHandler.pas Tue Apr 16 00:07:15 2019 +0300 +++ b/hedgewars/uInputHandler.pas Thu Apr 18 19:44:25 2019 +0200 @@ -32,7 +32,8 @@ function KeyBindToName(bind: shortstring): shortstring; //procedure MaskModifier(var code: LongInt; modifier: LongWord); procedure MaskModifier(Modifier: shortstring; var code: LongInt); -procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean); +procedure ProcessMouseButton(event: TSDL_MouseButtonEvent; ButtonDown: boolean); +procedure ProcessMouseMotion(xrel, yrel: LongInt); //procedure ProcessMouseWheel(x, y: LongInt); procedure ProcessMouseWheel(y: LongInt); procedure ProcessKey(event: TSDL_KeyboardEvent); inline; @@ -59,7 +60,7 @@ procedure ControllerButtonEvent(joy, button: Byte; pressed: Boolean); implementation -uses uConsole, uCommands, uVariables, uConsts, uUtils, uDebug, uPhysFSLayer; +uses uConsole, uCommands, uVariables, uConsts, uUtils, uDebug, uPhysFSLayer, uCursor; const LSHIFT = $0200; @@ -278,7 +279,7 @@ ProcessKey(code, event.type_ = SDL_KEYDOWN); end; -procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean); +procedure ProcessMouseButton(event: TSDL_MouseButtonEvent; ButtonDown: boolean); begin //writelntoconsole('[MOUSE] '+inttostr(event.button)); case event.button of @@ -291,6 +292,11 @@ end; end; +procedure ProcessMouseMotion(xrel, yrel: LongInt); +begin + uCursor.updatePositionDelta(xrel, yrel); +end; + var mwheelupCode, mwheeldownCode: Integer; //procedure ProcessMouseWheel(x, y: LongInt); diff -r b2beb784e4b5 -r 9443dc6663ba hedgewars/uMisc.pas --- a/hedgewars/uMisc.pas Tue Apr 16 00:07:15 2019 +0300 +++ b/hedgewars/uMisc.pas Thu Apr 18 19:44:25 2019 +0200 @@ -26,7 +26,6 @@ procedure initModule; procedure freeModule; -procedure movecursor(dx, dy: LongInt); function doSurfaceConversion(tmpsurf: PSDL_Surface): PSDL_Surface; function MakeScreenshot(filename: shortstring; k: LongInt; dump: LongWord): boolean; function GetTeamStatString(p: PTeam): shortstring; @@ -46,17 +45,6 @@ var conversionFormat : PSDL_PixelFormat; -procedure movecursor(dx, dy: LongInt); -var x, y: LongInt; -begin -if (dx = 0) and (dy = 0) then exit; - -SDL_GetMouseState(@x, @y); -Inc(x, dx); -Inc(y, dy); -SDL_WarpMouse(x, y); -end; - {$IFDEF PNG_SCREENSHOTS} // this funtion will be executed in separate thread function SaveScreenshot(screenshot: pointer): LongInt; cdecl; export; diff -r b2beb784e4b5 -r 9443dc6663ba hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Tue Apr 16 00:07:15 2019 +0300 +++ b/hedgewars/uVariables.pas Thu Apr 18 19:44:25 2019 +0200 @@ -234,6 +234,7 @@ TargetCursorPoint : TPoint; CursorPoint : TPoint; + CursorPointDelta : TPoint; TargetPoint : TPoint; ScreenFade : TScreenFade; diff -r b2beb784e4b5 -r 9443dc6663ba hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Tue Apr 16 00:07:15 2019 +0300 +++ b/hedgewars/uWorld.pas Thu Apr 18 19:44:25 2019 +0200 @@ -1974,7 +1974,6 @@ if CursorPoint.Y < cScreenHeight - (AmmoRect.y + AmmoRect.h - AMSlotSize - 5) then//check bottom CursorPoint.Y:= cScreenHeight - (AmmoRect.y + AmmoRect.h - AMSlotSize - 5); prevPoint:= CursorPoint; - //if cHasFocus then SDL_WarpMouse(CursorPoint.X + cScreenWidth div 2, cScreenHeight - CursorPoint.Y); exit end; @@ -2030,7 +2029,6 @@ // this moves the camera according to CursorPoint X and Y prevPoint:= CursorPoint; -//if cHasFocus then SDL_WarpMouse(CursorPoint.X + (cScreenWidth shr 1), cScreenHeight - CursorPoint.Y); if WorldDy > LAND_HEIGHT + 1024 then WorldDy:= LAND_HEIGHT + 1024; if WorldDy < wdy then @@ -2148,10 +2146,21 @@ procedure updateCursorVisibility; begin - if isPaused or isAFK then - SDL_ShowCursor(1) + if isPaused or isAFK or (GameState = gsConfirm) then + begin + SDL_SetRelativeMouseMode(SDL_FALSE); + if SDL_ShowCursor(SDL_QUERY) = SDL_DISABLE then + begin + uCursor.resetPosition; + SDL_ShowCursor(SDL_ENABLE); + end; + end else - SDL_ShowCursor(ord(GameState = gsConfirm)) + begin + uCursor.resetPositionDelta; + SDL_ShowCursor(SDL_DISABLE); + SDL_SetRelativeMouseMode(SDL_TRUE); + end; end; procedure updateTouchWidgets(ammoType: TAmmoType);