-
Notifications
You must be signed in to change notification settings - Fork 114
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
Deadzones and sensitivity do not match USB driver settings #231
Comments
I'll test this during weekend... Seems like a nice enhancement from your description. |
Linux HID has no knowledge about which axes form one thumb stick, so it can only calculate dead zones per 1D axis. But our driver has this knowledge and we can thus calculate the dead zone on a 2D plane. This commit introduces the needed infrastructure for this without changing the original behavior. See-also: https://www.gamasutra.com/blogs/JoshSutphin/20130416/190541/Doing_Thumbstick_Dead_Zones_Right.php See-also: atar-axis#231 Signed-off-by: Kai Krakow <[email protected]>
This commit sets flatness to zero to let us calculate the dead zone on a 2D plane instead of on a 1D axis, otherwise we'd have rectangular dead zones along the two axes per thumb stick. We also need to set fuzz to 0, otherwise `joydev` doesn't always return to the center. See-also: atar-axis#231 Signed-off-by: Kai Krakow <[email protected]> WIP Signed-off-by: Kai Krakow <[email protected]>
@a-kring Here's something to play with: https://github.com/kakra/xpadneo/tree/rework-deadzones-radial As outlined in medusalix/xow#105 it would be wrong to set the flatness to a low value without implementing a dead zone as this introduces centering problems in The current implementation in this branch is a bit flawed as it does cubic scaling, so the sticks now actually move in a square instead of a circle (which may not be too bad as you can reach the max values now at 45° angles). Also there are rounding errors as you can see from the small bumps around the 0° and 90° outer range, also there may occur erratic values within the dead zone and I'm not yet sure where that comes from. But it should be good enough for a test in games. |
This commit sets flatness to zero to let us calculate the dead zone on a 2D plane instead of on a 1D axis, otherwise we'd have rectangular dead zones along the two axes per thumb stick. We also need to set fuzz to 0, otherwise `joydev` doesn't always return to the center. See-also: atar-axis#231 Signed-off-by: Kai Krakow <[email protected]>
This commit sets flatness to zero to let us calculate the dead zone by scaling the axis value instead of jumping out of it. The dead zone is implemented as a smooth axial dead zone. We also need to set fuzz to 0, otherwise `joydev` doesn't always return to the center. See-also: atar-axis#231 Signed-off-by: Kai Krakow <[email protected]>
@a-kring Here's a different one which implements a classical axial dead zone but implements it as a smooth exit from the dead zone instead of jumping out of it: https://github.com/kakra/xpadneo/tree/rework-deadzones-smoothaxial |
I've been fighting to get the Bluetooth controller recognized and I just realized that ERTM is not disabled automatically by your branch. |
Hmm yes maybe... I'm using a patch for L2CAP to work around this. But following the normal install procedure it should install the ERTM setting. |
I followed the normal install procedure. It doesn't add the |
This commit makes the dead zone really tiny, this introduces phantom movement in the `joydev` API and requires applications to implement their own dead zones. See-also: atar-axis#231 Signed-off-by: Kai Krakow <[email protected]>
These values have been determined experimentally on a medium worn controller. Fixes: atar-axis#231 Signed-off-by: Kai Krakow <[email protected]>
I've updated the branches: https://github.com/kakra/xpadneo/tree/kakra/rework-deadzones: https://github.com/kakra/xpadneo/tree/kakra/rework-deadzones-radial: https://github.com/kakra/xpadneo/tree/kakra/rework-deadzones-smoothaxial: https://github.com/kakra/xpadneo/tree/kakra/rework-deadzones-xpadlike: I also looked at the Wine source. The SDL bus implementation sets the dead zone to 0 by default, so you don't need to fiddle with registry settings as long as your games use the Windows HID layer for joystick input (xinput games do). Games using dinput may be a different story as they may pick the Linux
Wine MAY apply a dead zone and does it by rescaling the values - like |
So far I tested this branch, which is a bit better than default, but it is still imprecise. I circle around my targets without hitting them, but it is closer. I could see myself getting used to it if I had to. I'll install the radial branch and restart to test. |
This comment has been minimized.
This comment has been minimized.
I think it is due to a difference in philosophy. Game and input library developers seem to expect raw output from the device. This seems to be what Steam assumes, and what the official Xbox One gamepad drivers Microsoft do. Also it is what is typically done on full-scale joysticks. Since the driver developer cannot know how the application intends to use the device, it is best to just expose it, warts and all. It is then up to the software developer to work out the best approach for their application. What the driver should probably do is get rid of atypical noise generated by the device, say a very jittery sensor or a faulty button contact that may lead to register multiple presses when only one was intended. The stick being slightly off-center in its neutral position is far from atypical for analog input devices like joysticks or gamepads, and it seems that SDL developers do not expect this to be "corrected" by the driver. The ThinkPad index finger pointing device that is usually found in the middle of laptop keyboards does something remarkable. It constantly monitors and removes drift, re-calibrating itself to the point that if you find yourself applying constant force in a particular direction for more than a few seconds, you'll see that the device starts moving in the opposite direction of its own accord when you let it go, at least for a few seconds as it re-calibrates itself again. You can get very sophisticated and find a good elegant way to deal with re-centering the stick at zero while causing minimal pain to users, but games and input libraries do not expect the driver to solve this, and will add its own corrections on top of yours, which will make matters worse, unless perhaps you use the Stadia controller approach, which is effective and doesn't conflict with ad-hoc solutions added by user space libraries and software. By the way, I tested this branch. I was expecting to love it, but it turned out to be the least usable so far. I guess linearity does matter. I'll try smoothaxial now. |
I've looked at Wine more intense: There seems no way that it applies a dead zone unless a game explicitly requested it - or you've put the default value in the registry. Otherwise it just passes plain values as received from the lower layers. Modern games use I'm currently somewhat convinced that we should not patch this in the driver - and the approach of Funny enough: Only the Linux version of SDL handles dead zones... Of all the things, that's the system that may handle dead zones in the driver already. :-( But it's probably for that matter: Games ported from |
I tried smoothaxial and it is pretty good. It is almost as good as xpad in terms of precision, with the added benefit of having the center mostly at zero. I'm still going to use my own forked version that uses xpad parametres, because it feels pretty much exactly as it does in Windows, which is just right for this particular game. It's interesting that SDL on Linux is the only version that adds a dead zone, especially observing that Windows drivers do not impose any. I will venture to guess that a discussion not unlike this one happened already, where a hardware driver developer at Microsoft may have had a version of the driver that had dead zones, a game studio developer complained that their beta players didn't like how their gamepad responded, while another game studio developer may have complained earlier about the thumb stick drifting instead of being properly centered when the user wasn't providing any input. I suppose the answer to everything ended up being: the driver gives you raw output, and as a game developer you are expected to use Xinput and parametrize it accordingly. The information about dead zones in that link seems to suggest this. |
This is actually the case when reading from I think we may end up with a driver option in |
The code for this is in place: ERTM_OVERRIDE="/etc/modprobe.d/99-xpadneo-bluetooth.conf"
if [ "$(readlink "${ERTM_OVERRIDE}")" = "/dev/null" ]; then
echo "Not disabling ERTM, local override in place..."
elif [ -L "${ERTM_OVERRIDE}" ]; then
echo >&2 "WARNING: '${ERTM_OVERRIDE}' is an arbitrary symlink, this is not supported."
echo >&2 "Skipping ERTM fixup, you're expected to manage the options on your own..."
else
echo "Disabling ERTM permanently (requires reboot)..."
echo "options bluetooth disable_ertm=y" >"${ERTM_OVERRIDE}"
echo "HINT: If you want to prevent this in the future, run 'ln -snf /dev/null ${ERTM_OVERRIDE}'."
echo "Disabling ERTM instantly..."
echo "Y" >/sys/module/bluetooth/parameters/disable_ertm
fi It should create Did you install with dkms? What's the output? |
These values have been determined experimentally on a medium worn controller. This also removes dead zones completely for the triggers as the controller already implements that in the firmware. Fuzz is shrunk by a factor of 8 because the sticks are very precise already and we don't want to filter out this precision. We can set the dead zone 25% smaller compared to Linux defaults. See-also: atar-axis#231 Signed-off-by: Kai Krakow <[email protected]>
This adds a module parameter `disable_deadzones` to remove dead zone handling from upper layers. This is only useful if you're a playing games in Wine or Proton as otherwise SDL introduces a dead zone handler which seriously hurts precision compared to native Windows usage of the controller. Do not use this if you intend to play native games that make use of the `joydev` API in Linux as the removal of the dead zones introduces axis shift and phantom movement. In Windows, games are supposed to handle dead zones by themselves while in Linux the drivers to this. Fixes: atar-axis#231 Signed-off-by: Kai Krakow <[email protected]>
These values have been determined experimentally on a medium worn controller. This also removes dead zones completely for the triggers as the controller already implements that in the firmware. Fuzz is shrunk by a factor of 8 because the sticks are very precise already and we don't want to filter out this precision. We can set the dead zone 25% smaller compared to Linux defaults. See-also: atar-axis#231 Signed-off-by: Kai Krakow <[email protected]>
This adds a module parameter `disable_deadzones` to remove dead zone handling from upper layers. This is only useful if you're a playing games in Wine or Proton as otherwise SDL introduces a dead zone handler which seriously hurts precision compared to native Windows usage of the controller. Do not use this if you intend to play native games that make use of the `joydev` API in Linux as the removal of the dead zones introduces axis shift and phantom movement. In Windows, games are supposed to handle dead zones by themselves while in Linux the drivers to this. Fixes: atar-axis#231 Signed-off-by: Kai Krakow <[email protected]>
This adds a module parameter `disable_deadzones` to remove dead zone handling from upper layers. This is only useful if you're a playing games in Wine or Proton as otherwise SDL introduces a dead zone handler which seriously hurts precision compared to native Windows usage of the controller. Do not use this if you intend to play native games that make use of the `joydev` API in Linux as the removal of the dead zones introduces axis shift and phantom movement. In Windows, games are supposed to handle dead zones by themselves while in Linux the drivers to this. Fixes: atar-axis#231 Signed-off-by: Kai Krakow <[email protected]>
After enduring some warfare against DKMS, I managed to get it all working with your branch. I confirm that this works very well. I do not see the option to disable dead zones in the output of By the way, the new default parameters set to less aggressive values also improve the experience without dead zones fully disabled. Thank you for this work. It was very interesting to go deep into low-level system stuff to see what was going on. I guess I should have a word with SDL/Wine/Proton developers such that they can tune their libraries to disable deadzones for a better experience with Windows games running on Linux. They can override these driver parameters directly from there, right? Update: I missed some of your posts above. I see that if Wine updates to use evdev directly, they can do whatever they want with the dead zones, including ignoring them completely for Windows games that do not expect them to be set by the driver. That's actually a good idea. |
That's because I'm lazy. Feel free to open a PR. I do not particularly like how this script was designed - it duplicates a lot of stuff.
Yes, that was the intention: To make a better OOTB experience without compromising compatibility with, e.g.,
May be a good idea. Andrew from the Proton project may probably be the best contact to discuss this as much (most? all?) of the work of modern Wine joystick driver is by him.
Yes and no: There's no parameter to modify but they can modify the code to read
Exactly. Reading from I played some Borderland 3 now with dead zones disabled, and there's a perceivable difference, especially when the dynamic auto-aim doesn't kick in. But it's not a huge difference for that game. Overall it feels more smooth which I attribute to the reduced fuzz value - this involved the usual stick movement outside of the dead zone, and aiming on weapon zoom is easier. Maybe I should implement the "duplicate reports filter" I'm having in mind: When using Bluetooth, the controller repeats the same HID report multiple times, not sure if this messes with the effectiveness of the fuzz filter. So thanks for the suggestion. I'll try some more games but I feel the PR can be merged now. |
Yeah, I like the pull request the way it is. Feel free. I do not get any perceivable issues from duplicate Bluetooth reports when playing Elite Dangerous. It feels as butter-smooth as wired or Windows with dead zones disabled. It really makes the game more enjoyable. I'll have to test another game where I was enduring pain caused by these dead zones: Doom Eternal. I more or less fixed the problem naively by using the Steam gamepad support, but I don't like it as it seems to add plenty of input lag on Linux. It may be just a perception issue though. I'll have to check again tomorrow. Cheers |
These values have been determined experimentally on a medium worn controller. This also removes dead zones completely for the triggers as the controller already implements that in the firmware. Fuzz is shrunk by a factor of 8 because the sticks are very precise already and we don't want to filter out this precision. We can set the dead zone 25% smaller compared to Linux defaults. See-also: #231 Signed-off-by: Kai Krakow <[email protected]>
Yeah, I always disable that, too, because it feels strange. May actually be due to the lag, I never could nail it to why I don't like it. But it's probably the lag. Also, some games seem to go crazy about whether you're using a mouse/keyboard or a gamepad, and constantly switch modes and on-screen symbols. |
I proposed a patch for SDL which enables Proton to easily fix this for all drivers and games, without any change to drivers: |
These values have been determined experimentally on a medium worn controller. This also removes dead zones completely for the triggers as the controller already implements that in the firmware. Fuzz is shrunk by a factor of 8 because the sticks are very precise already and we don't want to filter out this precision. We can set the dead zone 25% smaller compared to Linux defaults. See-also: #231 Signed-off-by: Kai Krakow <[email protected]>
This adds a module parameter `disable_deadzones` to remove dead zone handling from upper layers. This is only useful if you're a playing games in Wine or Proton as otherwise SDL introduces a dead zone handler which seriously hurts precision compared to native Windows usage of the controller. Do not use this if you intend to play native games that make use of the `joydev` API in Linux as the removal of the dead zones introduces axis shift and phantom movement. In Windows, games are supposed to handle dead zones by themselves while in Linux the drivers to this. Fixes: #231 Signed-off-by: Kai Krakow <[email protected]>
Version of xpadneo
Commit 28f5034
Severity / Impact
Xbox One Wireless controller responds differently when connected via USB or Bluetooth. This is due to default parameters such as flatness or fuzz set to different values when the device is connected using Bluetooth and xpadneo.
Describe the bug
The default parameters flatness: 4096 and fuzz: 255 are different from the USB driver's default values flatness: 128 and fuzz: 16. Refer to this comment from the related xow project: medusalix/xow#105 (comment)
Steps to Reproduce
Connect gamepad either via USB or using xpadneo and head to https://gamepad-tester.com/ to notice how radically different it reacts to precise input movements.
Expected behavior
The gamepad should feel precise and smooth using xpadneo, in the same way it does when using the USB drivers.
Screenshots/Gifs
System information
Controller and Bluetooth information
xpadneo-btmon.txt
xpadneo-dmesg.txt
xpadneo-lsusb.txt
The text was updated successfully, but these errors were encountered: