Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hammerfight mouse stuck in place #147

Closed
slouken opened this issue Dec 1, 2021 · 15 comments
Closed

Hammerfight mouse stuck in place #147

slouken opened this issue Dec 1, 2021 · 15 comments
Assignees

Comments

@slouken
Copy link
Collaborator

slouken commented Dec 1, 2021

Hammerfight superficially works (audio plays, pixels are drawn) but something is badly wrong with the mouse capture: the cursor stays in one place, unless I Alt+Tab away and then back, in which case it moves once but then stays where it moved to. I get the same results by disabling Steam Linux Runtime, so I think maybe Hammerfight's bundled copy of SDL 1.2 (which I disabled here) has been patched to use a different mouse capture mode or something.

@sezero
Copy link
Contributor

sezero commented Dec 1, 2021

, so I think maybe Hammerfight's bundled copy of SDL 1.2 (which I disabled here)

To clarify: Real SDL1.2 (1.2.15 or git) behaves in the same bad manner?

@smcv
Copy link
Contributor

smcv commented Dec 1, 2021

Real SDL 1.2 has the same behaviour as sdl12-compat. Steps to reproduce:

  • Install Hammerfight via Steam
  • Run it
    • it uses its own bundled SDL 1.2.14
    • it works
  • Delete amd64/libSDL-1.2.so.0 and x86/libSDL-1.2.so.0
  • Run it
    • it uses the OS's libSDL 1.2 or the Steam Runtime's libSDL 1.2, whichever is newer (in my case version 1.2.15 from Debian 11)
    • it does not work, symptoms as described by @slouken
  • Re-run it using sdl12-compat
    • it does not work, same symptoms as with real SDL 1.2

So sdl12-compat is no worse here than real SDL 1.2.

@slouken
Copy link
Collaborator Author

slouken commented Dec 1, 2021

Ah, since this isn't a regression relative to public SDL 1.2, I'll go ahead and close this. Thanks for clarifying!

@slouken slouken closed this as completed Dec 1, 2021
@sezero
Copy link
Contributor

sezero commented Dec 1, 2021

Do we even know what they do and/or how they actually patched SDL1.2?

@slouken slouken reopened this Dec 1, 2021
@slouken
Copy link
Collaborator Author

slouken commented Dec 1, 2021

@icculus is going to take a look at this

@icculus
Copy link
Collaborator

icculus commented Dec 2, 2021

Hammerfight allows multiplayer by plugging in multiple mice, so it uses https://icculus.org/manymouse/ to handle that...it is likely talking to Xinput2 directly, not even on the same connection to the X server than SDL is using.

Hammerfight was my port, so I'll look more closely at it to see what's happening and if it can be worked around.

@icculus
Copy link
Collaborator

icculus commented Dec 3, 2021

So this is the code in ManyMouse that initializes its XInput2 support:

https://github.com/icculus/manymouse/blob/7f3e91bdf815f25b3508ba2e8ce4aa118232d99e/x11_xinput2.c#L264-L315

Notable because it has an obvious environmental switch to completely disable it, as a in-case-of-fire sort of thing.

If XInput2 refuses to initialize, it will fall back to using evdev support, which is to say we probably aren't completely screwed on Wayland here (I don't know if Wayland has an equivalent of XInput2, but ManyMouse doesn't currently support it and it's statically linked to the binary anyhow, but evdev in theory should work there...?).

Also notable in Hammerfight's code:

	// workaround; if SDL turns on DGA, ManyMouse's XInput2 support fails.
	char namebuf[16];
	const char *driver = SDL_VideoDriverName(namebuf, sizeof (namebuf));
	if (driver && (strcmp(driver, "x11") == 0))
	{
		if (strcmp(ManyMouse_DriverName(), "X11 XInput2 extension") == 0)
		{
			LOG::WRITE(1, LOG_CLIENT, "InputTask: forcing SDL_MOUSE_RELATIVE=0 for X11.");
			setenv("SDL_MOUSE_RELATIVE", "0", 1);
		}
	}

Also it looks like if ManyMouse fails completely, it continues on:

	const bool initOk = initManyMouse();
#endif

	APP::CORE_HAVE_RI = initOk;

	if (!initOk) {
		LOG::WRITE(1, LOG_CLIENT, "InputTask: not using RI.");
		HID mouse(0, "Simple", HIDTYPE_MOUSE);
		mouse.m_speed = DEFAULT_MOUSE_SENS / (SYS_MOUSE_SPEED * 0.1f); 
		HIDS.push_back(mouse);
	}

Presumably using SDL's mouse events in this case for single player...?

@smcv
Copy link
Contributor

smcv commented Dec 3, 2021

I don't know if Wayland has an equivalent of XInput2

Xwayland should implement approximately the same protocols that Xorg does, and X11-specific code like this will only work when connected to Xwayland anyway.

@smcv
Copy link
Contributor

smcv commented Dec 3, 2021

evdev in theory should work there

Unprivileged users can't usually use evdev mice (or keyboards) directly due to concerns about keyloggers. The device node is owned by root:input, and is fd-passed from logind to the Wayland compositor if using one, or to Xorg if using that, or Xorg runs as root and opens the device node as root if you're not using logind.

@icculus
Copy link
Collaborator

icculus commented Dec 3, 2021

Xwayland should implement approximately the same protocols that Xorg does, and X11-specific code like this will only work when connected to Xwayland anyway.

Sorry, I wasn't clear; I meant I don't know if there's an equivalent Wayland protocol available to apps that could be added to ManyMouse.

It sounds like evdev is going to be a non-starter too, but honestly if these both fail and we can make single-player mouse input work through the standard SDL paths, that's fine with me.

If someone really wants multiplayer and is on Wayland, they can adjust permissions in /dev or add themselves to the input group, etc, but demand for this feature is probably vanishingly small...I would assume most Hammerfight players experience the single-player story mode.

@sulix
Copy link
Contributor

sulix commented Dec 4, 2021

For what it's worth, I tested this on my system, and I can't reproduce this issue at all under XWayland (on a KDE/KWin wayland session in (K)Ubuntu 21.10). The bundled SDL 1.2, normal SDL 1.2 and sdl12-compat all have working mouse support.

The ManyMouse stuff doesn't seem to work with Xinput2: I don't think XWayland supports multiple mouse inputs, the log showing:

0:0:0:17	initManyMouse initiated.
0:0:0:17		0.xwayland-pointer:10
0:0:0:17		1.xwayland-relative-pointer
0:0:0:17	initManyMouse finished successful with 2 devices.

And the game is playable, but it shows only a single mouse cursor.

Interestingly, it still uses Xinput2 (with the exact same two xwayland mice) when SDL_VIDEODRIVER=wayland, though in this case, the mouse is not usable in-game at all (if the multiple-mice support is enabled in the game settings, if not, it works fine).

But — as you suggest — everything works fine if MANYMOUSE_NO_XINPUT2=1 is set (even with my ancient old serial mouse).

@icculus
Copy link
Collaborator

icculus commented Dec 4, 2021

One more update: I don't appear to have access to the Hammerfight depot to upload a new build anymore, and the publisher that could grant access hasn't updated their website since 2015, so unless Valve wants to intervene, we're probably going forward with the binaries as they are.

@icculus
Copy link
Collaborator

icculus commented Dec 6, 2021

Okay, so the simplest way to deal with this is change this in Config.ini:

CORE_INIT_RI=true

Make that false and it won't even try to initialize ManyMouse, and will use standard SDL 1.2 mouse events for single-player input. (The "RI" stands for "RawInput," which Hammerfight uses on Windows for multi-mice support).

Game works fine under Wayland (with a single mouse input, of course) with sdl12-compat with that change.

I don't know how we want to proceed at this point; it's not an sdl12-compat issue, and we'd probably need to alter the Steam depot to fix this across the board...but as it stands, at least end-users have a path forward now.

@sezero
Copy link
Contributor

sezero commented Dec 6, 2021

Maybe append a compatibility table to README and mention this workaround there?

@icculus
Copy link
Collaborator

icculus commented Dec 13, 2021

Maybe append a compatibility table to README and mention this workaround there?

Good idea, done.

I'm closing this bug now, because there's not much else to be done here.

@icculus icculus closed this as completed Dec 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants