Wayland: Emulate mouse warp using relative mouse mode

Several games (including Source and GoldSrc games, and Bioshock
Infinite) attempt to "fake" relative mouse mode by repeatedly warping
the cursor to the centre of the screen. Since mouse warping is not
supported under Wayland, the viewport ends up "stuck" in a rectangular
area.

Detect this case (mouse warp while the cursor is not visible), and
enable relative mouse mode, which tracks the cursor position
independently, and so can Warp successfully.

This is behind the SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP hint, which
is enabled by default, unless the application enables relative mouse
mode itself using SDL_SetRelativeMouseMode(SDL_TRUE).

Note that there is a behavoural difference, in that relative mouse mode
typically doesn't take mouse accelleration into account, but the
repeated-warping technique does, so mouse movement can seem very slow
with this (unless the game has its own mouse accelleration option, such
as in Portal 2).
This commit is contained in:
David Gow 2022-04-18 17:03:05 +08:00 committed by Sam Lantinga
parent 9e3c4b9f32
commit ad29875ee6
4 changed files with 88 additions and 3 deletions

View file

@ -1712,6 +1712,23 @@ extern "C" {
*/
#define SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION "SDL_VIDEO_WAYLAND_MODE_EMULATION"
/**
* \brief Enable or disable mouse pointer warp emulation, needed by some older games.
*
* When this hint is set, any SDL will emulate mouse warps using relative mouse mode.
* This is required for some older games (such as Source engine games), which warp the
* mouse to the centre of the screen rather than using relative mouse motion. Note that
* relative mouse mode may have different mouse acceleration behaviour than pointer warps.
*
* This variable can be set to the following values:
* "0" - All mouse warps fail, as mouse warping is not available under wayland.
* "1" - Some mouse warps will be emulated by forcing relative mouse mode.
*
* If not set, this is automatically enabled unless an application uses relative mouse
* mode directly.
*/
#define SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP "SDL_VIDEO_WAYLAND_EMULATE_MOUSE_WARP"
/**
* \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p").
*