Key2Joy
Key2Joy copied to clipboard
WASD mapped to the Left GamePad Stick for moving, sometimes gets stuck
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.
The 'sometimes' can be replicated consistently by:
- Press and hold down A
- Press and release W
- Release A
Nevermind, it's a bit different
Relevant mappings:
Config where problem occurs:
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
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
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.
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
Consider replacing my faulty implementation with: https://github.com/jnm2/LowLevelHooking/blob/master/src/LowLevelHooking/GlobalKeyboardHook.cs
I especially handle nCode incorrectly
Notes for possible solutions...
Other libraries:
- https://github.com/nefarius/HidHide (Non-mouse and keyboard blocking only)
- https://github.com/oblitum/Interception (A filter driver like this seems very useful in intercepting reliably) - [example implementation 1] [example implementation 2]
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