Key2Joy icon indicating copy to clipboard operation
Key2Joy copied to clipboard

WASD mapped to the Left GamePad Stick for moving, sometimes gets stuck

Open luttje opened this issue 1 year ago • 8 comments

I tried this in Portal 1 and with both v 0.7.0 and 0.6.0 the game will occasionally not catch me releasing A and get me stuck walking towards the left.

A theory on why this happens:

  • Some Keyboard input is inadvertently captured besides the simulated gamepad input, but the release isn't.

I think this might be the case, because on my other monitor the tester shows the gamepad stick movement just fine.

luttje avatar Nov 01 '23 15:11 luttje

The 'sometimes' can be replicated consistently by:

  • Press and hold down A
  • Press and release W
  • Release A

Nevermind, it's a bit different

luttje avatar Nov 01 '23 16:11 luttje

Relevant mappings: image

Config where problem occurs: image

luttje avatar Nov 01 '23 16:11 luttje

Note: an issue with how mappings for gamepad sticks currently work:

Keyboard input: S KeyDown -> GamePad 2 Left x=0 y=-32768 Keyboard input: S KeyUp -> GamePad 2 Left x=0 y=32767 This will get the stick into position 0, -1

luttje avatar Nov 01 '23 16:11 luttje

Note: Abort should really be tied to Releasing Escape (not pressing as it is now), since overriding default behavior may keep escape stuck pressed down

luttje avatar Nov 01 '23 17:11 luttje

I'm having serious trouble reproducing it if I remove the mouse-move -> right stick mapping. Also I feel that this may be a problem with the game not having focus, keyboard input getting picked up (but only press) then game input getting picked up by it and switching to gamepad mode, but when the gamepad somehow gets deactivated (by keyboard input sneaking into the game again?) it gets stuck on the last pressed (but never released input key).

It's quite the bug to reproduce and it's even hard to explain. I'll put more work into this another time.

luttje avatar Nov 01 '23 18:11 luttje

I think this is a race condition between simulated game inputs. Consider the following happening in sequence:

  • Thread A: Mouse Move -> Right Stick gets the controller state
  • Thread B: Keyboard WASD -> Left stick gets the controller
  • Thread A: Mouse Move -> Right Stick Updates the controller state
  • Thread B: Keyboard WASD -> Left stick Updates the controller state with now outdated information

This is different orders would explain the weird behavior. I will try ensure only one thread is manipulating the input at a time. Or use a queue of some sort

luttje avatar Nov 01 '23 19:11 luttje

Consider replacing my faulty implementation with: https://github.com/jnm2/LowLevelHooking/blob/master/src/LowLevelHooking/GlobalKeyboardHook.cs

I especially handle nCode incorrectly

luttje avatar Nov 11 '23 21:11 luttje

Notes for possible solutions...

Other libraries:

Other windows hook related sources:

  • https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644977(v=vs.85)?redirectedfrom=MSDN
  • https://stackoverflow.com/a/42241837
  • https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawinputdevice

Other techniques and sources:

  • https://learn.microsoft.com/en-us/windows/iot/iot-enterprise/customize/keyboardfilter
  • https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-blockinput (then use raw input to read?)
  • https://www.codeproject.com/Articles/716591/Combining-Raw-Input-and-keyboard-Hook-to-selective
  • https://learn.microsoft.com/en-us/windows/win32/api/_inputdev/
  • https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enablewindow

luttje avatar Nov 19 '23 20:11 luttje