-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
(Input) Proper analog trigger support #6920
Comments
I'm not sure I'm the best person to fix this but perhaps we can pool knowledge. input/drivers/* -> function xxx_input_state, e.g. udev_input_state
input/input_driver.c -> function input_joypad_analog
To debug this on the faulty platform (I can't), put a printf to log the value of res in input_joypad_analog The value should always be from 0 to 0x7FFF (+32767), just like the analogue sticks. If the driver is returning weird values, we're past the point of being able to do something about it at this stage - it's a driver bug to report out of range or compressed values. ps. XInput triggers work great for me, FWIW |
Thanks so much. I added the printf at the very bottom of the input_joypad_analog function (right above "return res;"). I observed that the values thrown to terminal were constant at "0" unless I pushed either the left or right trigger, in which case the corresponding value immediately jumped to "32767". So they are registering, and within the expected range, just not treated as analog for some reason. Note that the values returned for the left and right joysticks (not triggers) are reported properly as analog, as they slowly change values up to 32767 as the joystick is pushed left or right slowly. BTW, I think a good ingame test is in Daytona USA's "Analog Calibration" section - if you slowly push "Gas" (default right trigger) I'm pretty sure it should show the needle slowly moving from left to right. In my case, it goes immediately from far-left to far-right, as consistent with the printf test above. Try it yourself when you have a chance and let me know what you get in Xinput. Also, in case it matters: Dolphin emulator's input settings applet lets you see analog trigger values as the triggers are pressed. In that applet, I can see the range slowly increasing when I slowly press the triggers, as it should. |
Ok, sounds like the common input code isn't getting any analog data back for the trigger and is falling back to digital input, as designed (in case you mapped a face button to an expected analog input) Might wanna verify that by moving your printf to right after Based on what you've told me, I'm wondering about what's happening deeper in the udev code. In the file input/drivers_joypad/udev_joypad.c in function udev_joypad_axis. I'd be very curious what's going on in there:
Also if that proves to be a bust - my next port of call would be udev_joypad_poll in the same file.
Past that I'm out of ideas... DISCLAIMER: I've never looked at this udev code in my life before now, if someone else wrote this and knows more about it feel free to chip in, I'm just commenting using my general debugging experience. |
Okay, I moved the code, so now I have: res = abs( drv->axis( joypad_info.joy_idx, axis ) ); Now when I launch a game, all inputs report "0" whether buttons/triggers are pressed or not. Hopefully that helps. Incidentally, since you mentioned udev code - not sure if it matters but I also changed the "Joypad Driver" in the RA UI from "udev" to "sdl2" and restarted, but I still get the same digital trigger behavior. You ask some good questions, for example it would certainly be great to know whether the udev_joypad_axis function gets called at all for triggers. I'm happy to try out any other changes to the code you may suggest to get some answers together for us - e.g. I could printf some more test indicator values in certain spots to see if specific functions are being called when input occurs etc. Otherwise maybe @twinaphex knows or can find the person/people who wrote the original input code to provide more direct responses. |
If all inputs report 0, that means reicast's requests for triggers are calling the driver code and getting no analogue data. This fits what what you're describing but I can't explain why the driver is acting like that. btw. you should be able to debug all my questions with printfs in the UDEV code. But if SDL2 isn't working that's sounding like maybe a config error? Have you tried binding a thumbstick axis to RetroPad's L2 / R2 and seeing what happens? I'm going to take a step back at this point. |
Regarding debugging, I wouldn't know where in the udev code to put the printfs but if you give me an idea of where you'd like them, I'll certainly do that and provide results. As you suggested I set the right thumbstick X axis to RetroPad's L2 / R2 - now the code with the printf in the new location returns values from 0 to 32767 properly, and Daytona's analog calibration tool works fine with the thumbstick. Otherwise I think my configuration is not a factor but maybe @mickski56 could comment here as well, as he encountered the same issue. |
printf's in the udev code: go crazy and pepper them all over! Sounds like your controller's triggers aren't being read by the analog code. Definitely sounds like a bug in udev / config / linux. |
Hmm.. well it doesn't appear to be a bug in udev / linux, triggers are known to be working fine for many other games/emulators such as Dolphin (as I mentioned) that use analog triggers. Update: I have a linux graphical input tool called "jstest" which shows all axes and how they respond to input. This tool shows that the D-Pad is mapped to axes 6 and 7; whereas the L2 / R2 triggers are mapped to axes 2 and 5 respectively. With this tool, the analog triggers behave as they should, with values that slowly move as you slowly press them. Out of curiosity I ran Dolphin and RA controller setups side-by-side, and I noticed that with Dolphin, it sets the D-Pad to axes 6 and 7, and sets the L2 / R2 analog triggers to axes 2 and 5, respectively - this matches my jstest tool, and as mentioned before, triggers behave as they should here too. However, RA sets the D-Pad to "Hat #0 up/down/left/right" and analog triggers to axes 6 and 7 (i.e. the D-Pad axes according to both jstest and Dolphin). So it appears that for some reason, RA wants to treat the triggers as if they're digital D-Pad axes. |
2nd Update: I fixed it! Well, at least in the config. As I stated above, it appears that the RA UI doesn't set the analog triggers properly. However, you can manually edit the retroarch.cfg file to set them properly, as follows:
Of course, a proper fix will involve fixing whatever code sets these values in the RA UI, so the above hack won't be necessary. The RA UI code to set other analog values seems to be fine, so I'm hoping this isn't too tricky to track down, but again I'm happy to help wherever I can. |
Hey @twinaphex , over to you :) |
@Shoegzer annoyingly I'm still getting 50% dead zones on my triggers. My axes are mapped the same as yours. Printf's in input_driver.c print out values in the range 0 to 32676 but only for 50% to 100% trigger. The "proper fix" is probably updates in retroarch-joypad-autoconfig, not having any overridden bindings in retroarch.cfg and using per core/game overides if you need to swap buttons around. Some of the latest autoconfigs have triggers enabled some don't. Tho if you have both triggers and buttons both enabled for the same trigger in the *controller.cfg you get buttons. |
@mickski56 are you sure the dead zone is an RA issue? How do you know it's exactly 50% or are you estimating? I've also found that in both Dolphin (input menu) and RA (reicast/Daytona calibration menu), when I press the trigger slowly, it doesn't actually register until about 10-15% of the way pressed (and changing the analog dead zone setting in RA's input menu doesn't seem to have any effect). Perhaps this is just the design of the hardware in both of our cases? In any event you are quite right about jstest, I just don't know of an equivalent udev/evdev tool unless you do? By the way, should I assume that you could set your analog triggers in RA's menu without my manual fix above? I still think there's an issue with the code somewhere in RA, as I can set the other analog sticks just fine, and I haven't overridden anything to my knowledge. |
@Shoegzer pretty sure it's an RA issue. Back to RA, using evtest I can tell where my triggers start to work it's around 5-10 % & I can also see where 50% is. Stand alone reicast also works how I would expect i.e. 5% to 100% on the triggers. I'm going to try Dolphin (input menu) just for a double check. btw if i change input_player1_l2_axis = "+2" to input_player1_l2_axis = "-2" i get the trigger working ~10% - 100% (full range) but it's inverted, i.e.0% is interpreted as full press. No it doesen't with some printf's in input_driver.c and sdl_joypad.c I can see this is not the case, it's just the way my triggers work making it less noticable when 50% - 100% is ignored. don't try this it stops the front end from working (don't plug the joystick in until you're in the game calibration page) If you have the command line tool jstest, can you run "jstest /dev/input/js0" and tell me what the minimum value for the trigger axis is (trigger at 0%) please. |
With the above mentioned printf's I can summarize the problem as follows. The low level driver in this case sdl_joystick.c reports trigger movement as -32767 -- 0 -- 32767 (which is what you want from a stick, but not a trigger). input_driver.c gets an axis bind by various means but they are always specified as half an axis (0 -- 32767 or 0 -- -32767) so 50% of the trigger movement is not bound and never used. Can anyone confirm that trigger axes report this way for them on linux dualshock3 or xbox360. |
Does this mean: hands off -> 0 360 pad works like this on Windows in DirectInput mode and it's unhelpful! Which is why you need XInput to use triggers properly (as Xinput reports 0->255 for both triggers independently) |
Ah that What happens if you press both triggers partially, I would assume the value is added? This behavior is up to the underlying driver (OS level driver) and I don't think there is much that can be done in the retroarch side. |
I assume both your triggers are axis 2? |
L2 is axis 2, hands off is -32767 full pull is 32767 half pull is 0 |
Oh, that sounds fixable
…On Thu, Jun 28, 2018, 7:17 PM mickski56 ***@***.***> wrote:
L2 is axis 2, hands off is -32767 full pull is 32767
R2 is axis 5hands off is -32767 full pull is 32767
The only test program on linux that I can find that returns 0 > 255 is
evtest
Maybe linux is not ready for triggers yet
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#6920 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABpC0BV1x4zWtWiQiV0ye-4LB1N__ju9ks5uBXIUgaJpZM4U2hAp>
.
|
@mickski56 well that's strange but totally explains what's happening with your 50% deadzone. I wonder if it's possible to query the min/max value for an axis. The sdl_joystick code needs to shape triggers to be between 0 and 32767 with an offset and a scale. Definitely outside of my wheelhouse to fix this, sorry |
I had another look at sdl_joystick.c and came up with this. Thanks @hiddenasbestos
My programming skills are sadly lacking. It hard codes the axis numbers which means it works as expected on a dualshock 3 but not on an xbox360 pad. Maybe check if any axes are reporting -0x7fff during initialisation. |
Why are you using the SDL joypad driver though? It's one of the least mature and well developed drivers. |
SDL joypad because the rumble cuts off nicely in metropolis street racer reicast core, with udev once it starts it doesn't stop. I've just looked at udev_joypad.c I could modify that just as well the axis read code is very similar. |
Actually the libretro convention for axes is -32768 to 32766. If xinput uses 0-255 for the triggers, xinput is the anomaly. The analog button system should try to follow that, and the xinput driver too I guess. I'll try to do some testing with dinput / xinput on the weekend, just got home. |
XInput gets 0,255 from the API but scales up to 0,32767 before passing the data on. The convention for analog buttons is 0 means fully released and +32767 means fully pulled |
Great to see some new developments and thoughts shared on this since I've been out. @mickski56 I've confirmed that my controller (ds4) goes from -32767 (released) to +32757 (fully pressed), hence matching your observation. Sounds like this is pretty well established by now though. Thanks also for your tip regarding jstest/evdev. That motivated me to research the differences further and I found this interesting Reddit post from a Linux gamedev a year or so ago regarding joydev and evdev. I'm not sure how much of it is still relevant though I suspect at least most. I too have encountered the rumbling problems you mentioned (though rumble should eventually stop once rumble events are called again) but it never occurred to me that it could be specific to the evdev driver as I've always just used that driver for its other benefits. Do you feel this deserves a separate issue report to fix? I'm happy to test any new code to fix the immediate issue though - and yes, @hiddenasbestos it could affect a future ps2 core, as it already affects both reicast and dolphin cores since they both use analog triggers. It would likely affect the upcoming supermodel core too since I imagine most users will want to map analog triggers to gas/brake in Daytona 2, Scud Race etc. |
@Shoegzer you could try this patch to udev_joystick.c .If you can't wait for full range trigger action.
I'd be quite interested to see if this works on a dualshock 4, as ABS_Z & ABS_RZ are just numeric constants defined in <linux/input.h>. Although I have a xbox360 pad that also defines triggers as axes 4 & 5, So I can test it myself. Still needs some method of detecting how the axis behaves tho. It will do weird things to any trigger that is 0 -> 32676 or -32676 -> 0. The Linux Gamepad Specification link say triggers should report 0 -> 32676 but legacy devices can report anything they like. As for the rumble I'm not sure if it's in retroarch or reicast. I think I saw an open issue on reicast about needing to implement some functions to make rumble quit. reicast-emulator/issues/47 |
@mickski56 thanks. I see what you did in the code, and it seems like it should work; however it didn't. I tried setting the axes in the UI and I still get axes 6 and 7 instead of +2 and +5. Also thanks for pointing out that issue report about rumble in reicast, I missed that one. |
Solving the problem with a hard coded scale and offset is just kicking the can down the road for the next bug report to come in one day saying "I get weirdness on my triggers with DualShock5" because it's using some other range that this code doesn't correct properly. Is there a way to ask the low-level driver what the min/max range of each axis is? DirectInput can query the driver - surely Linux can too? ... or maybe Linux is a fixed spec like XInput and this is fine. I'm not an expert, just magic numbers making me feel like there's a potential problem waiting for future generations. |
I think it's fixed sort of. The Linux Gamepad Specification says |
Cool, thanks. We would also need to cover Windows as well. |
I have no windows box available, but I think the windows system drivers behave differently. |
@mickski56 Fantastic work, thanks for this fix. I've tested and it works fine here. I've updated the issue above to document the details behind the main reason it was opened, involving digital mapping of L2 and R2 analog triggers in the GUI. This seems to be the only direct problem remaining. Regarding the rumble problems @mickski56 reported in this thread, I opened this issue which I believe has something to do with this. Finally, there is still the problem of Dolphin analog triggers being mapped as digital, as noted in this issue. |
This seems to have been fixed and the remaining issues have their own issues so I am going to close this, please correct me if I have misunderstood! |
@orbea actually a big reason I opened the issue was due to the fact that the RA UI treats L2 and R2 as digital buttons, not analog axes - so when I try to set them through the UI, they get mapped incorrectly. Currently I have to manually edit retroarch.cfg with the proper values. I updated the issue summary accordingly. Can you please reopen? |
Not sure if it's useful but I confirm this is still happening in Retroarch 1.7.8 running on Windows 10 and using xinput driver. If you try to map L2/R2 analog triggers of a Dual Shock 4 using Retroarch UI it detects them as buttons instead of axes. I opened a PR in |
Zoltan added an analog button and keyboard tester to the inbuilt Remote RetroPad core ( |
…: Updated information: Removed hardware/firmware details for a tested controller The original information about hardware/firmware versions and tested GNU/Linux distributions has been removed. This is because the issue was identified as a bug in RetroArch, not related to specific controller versions. Removed: # # Successful evaluation of DualSense firmware versions + Tested GNU/Linux distribution (and kernel): # * DualSense (Model number: CFI-ZCT1W A. DualSense firmware: 0402) + Trisquel GNU/Linux 11 in live mode ($ uname -a: Linux trisquel 5.15.0-67-generic libretro#74+11.0trisquel18 SMP Sun Mar 5 03:14:11 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux) Replaced (https://github.com/libretro/retroarch-joypad-autoconfig/pull/1135/files) with: # Note 2024-06-04 : # See libretro/RetroArch#6920 # RetroArch's in-app feature to create autoconfig files is flawed and will attempt to create the 2 lines : # input_l2_btn = "6" # input_r2_btn = "7" # Those 2 lines are a downgrade from the 2 following lines which additionally allow l2/r2 to be polled as analog axises :
Should the title of this issue include "L2/R2"? Only L2/R2 are configured incorrectly by RetroArch for me, not L3/R3 axes: |
…abled).cfg #!/bin/bash input_device_display_name="Data Frog P02" old_value__input_l2="104" new_value__input_l2="+6" old_value__input_r2="105" new_value__input_r2="+7" extend_filename=" (disabled)" sed -i " /input_device/a input_device_display_name = \"$input_device_display_name\" /input_vendor_id/i\# Due to the uncommon nature of this device, the autoconfig file is not active by default. This precaution is taken to avoid potential conflicts with the widely-used Sony-PlayStation4-DualShock4-Controller.cfg file. To activate this configuration, you'll need to remove the comment symbols from the two lines that follow : # Inactivate the controller s/^input_vendor_id/# &/ s/^input_product_id/# &/ " "$1" sed -i " s|input_l2_btn = \"$old_value__input_l2\"|input_l2_axis = \"$new_value__input_l2\"|; s|input_r2_btn = \"$old_value__input_r2\"|input_r2_axis = \"$new_value__input_r2\"|; " "$1" ##################################### # Add multicomment text block that is easy to copy/paste to this file # Define the content to be inserted read -r -d '' insert_content << EOF # RetroArch's in-app feature to create autoconfig files is flawed (libretro/RetroArch#6920) and will attempt to create the 2 lines : # input_l2_btn = "$old_value__input_l2" # input_r2_btn = "$old_value__input_r2" # Those 2 lines are a downgrade from the 2 following lines (copied from Sony_DualShock_4_Controller_v2.cfg) which additionally allow l2/r2 to be polled as analog axises : EOF # Create a unique temporary file tmp_file="/tmp/tmp_file" # Write insert content to the temporary file echo "$insert_content" > "$tmp_file" # Add lines above "world" sed -i "/^input_l2_axis/e cat $tmp_file" "$1" # Remove the temporary file rm "$tmp_file" ########################### mv "$1" "$(echo "$1" | sed "s|.cfg|$extend_filename.cfg|")"
# RetroArch's in-app feature to create analog triggers (input_l2_axis, and input_r2_axis) for the autoconfig files is flawed (libretro/RetroArch#6920) # While manual changes are typically possible, they don't work for DualSense controllers on Android, where the analog triggers remain unresponsive. PS4 controllers, however, are unaffected (libretro/RetroArch#16791).
# See libretro/RetroArch#6920 # RetroArch's in-app feature to create autoconfig files is flawed and will attempt to create the 2 lines : # input_l2_btn = "6" # input_r2_btn = "7" # Those 2 lines are a downgrade from the 2 following lines which additionally allow l2/r2 to be polled as analog axes :
# See libretro/RetroArch#6920 # RetroArch's in-app feature to create autoconfig files is flawed and will attempt to create the 2 lines : # input_l2_btn = "6" # input_r2_btn = "7" # Those 2 lines are a downgrade from the 2 following lines which additionally allow l2/r2 to be polled as analog axes :
# See libretro/RetroArch#6920 # RetroArch's in-app feature to create autoconfig files is flawed and will attempt to create the 2 lines : # input_l2_btn = "6" # input_r2_btn = "7" # Those 2 lines are a downgrade from the 2 following lines which additionally allow l2/r2 to be polled as analog axes :
This is still an issue in RetroArch 1.20.0 (tested today). |
From this issue, RA doesn't appear to support analog triggers properly, at least in linux. Hopefully with this fixed, cores such as reicast and other future cores making use of such inputs will function as they should.
Updated with details: In linux, attempting to set L2 and R2 within the RA GUI results in inproper digital values (axes 6 and 7 in my case) rather than proper analog values (axes +2 and +5 in my case). Manually editing retroarch.cfg to add the proper values will work, however this is counter-intuitive and not everyone would know to do that. All other details are in the upper part of this thread.
@hiddenasbestos realizing you're probably the best person on the team for this, if you could find some time to look into adding such support, I can help you test whatever you'd need. I currently have a test Intel Kaby Lake-based system with kernel 4.15 and ds4 pads, and can compile RA as needed. Thanks very much.
The text was updated successfully, but these errors were encountered: