libretro / RetroArch

Cross-platform, sophisticated frontend for the libretro API. Licensed GPLv3.
http://www.libretro.com
GNU General Public License v3.0
10.2k stars 1.82k forks source link

Linux: XB1 controller rumble doesn't work unless initialized with fftest #6539

Open auxym opened 6 years ago

auxym commented 6 years ago

First and foremost, with 191 repos under libretro, I wasn't sure where to post this issue, so please forgive me (and point me in the right direction) if this isn't the correct place.

Description

I own a wired xbox one controller, a third party device made by PDP. If I start Retroarch after a boot and start an N64 game with rumble support (Goldeneye, THPS2, OOT...), rumble does not work.

However, I have found a workaround: if I first run fftest /dev/by-id/<event device> and rumble it (effect 4 or 5), then I can start up retroarch, load up a core/ROM and rumble will work!

This leads me to believe that retroarch should be sending some sort of "initalization" stuff to the controller and isn't doing it.

Expected behavior

Boot -> Plug in controller -> Start up retroarch -> Load core/ROM -> Working rumble

Actual behavior

Game starts and says a rumble pack is detected, but the controller doesn't actually vibrate when it should.

Steps to reproduce the bug

  1. Cold boot PC
  2. Start up retroarch and load mupen64 core
  3. (I'm using SDL2 as input driver, let me know if I should test another driver)
  4. Load a ROM with rumble support, say THPS2
  5. Start a single session game and observe that the controller does not rumble, eg when grinding.

Bisect Results

I'm not sure whether this is a regression, I've recently started using libretro with this hardware. If anyone has reason to believe this worked in the past, please give a working version/commit and I try testing / bisecting.

Version/Commit

Everything installed from stable PPAs:

libretro-core-info/xenial,xenial,now 1.7.0-r201802192247-7fac334-12~ubuntu16.04.1 all [installed,automatic]
libretro-mupen64plus/xenial,now 2.5-r201710241904-4b41ada-12~ubuntu16.04.1 amd64 [installed]
retroarch/xenial,now 1.7.1-r201802200210-6fc6bfb-74~ubuntu16.04.1 amd64 [installed,automatic]
retroarch-assets/xenial,xenial,now 1.7.0-r201801300004-505ad62-13~ubuntu16.04.1 all [installed,automatic]

Environment information

orbea commented 6 years ago

The SDL2 input driver is there as a measure of last resort. I would suggest using either the x or udev input drivers. For the udev input driver your user will need to be part of the input user group.

Are you using this gamepad with the xpad kernel driver? Does rumble work with other emulators or games?

auxym commented 6 years ago

OK, just tried udev joypad driver, same behavior.

I am indeed using xpad.

I can get rumble working in fftest, or even in retroarch/mupen64 core after running fftest at least once. I had a look at the fftest code, and it's basically doing:

  1. Upload the effects with an ioctl syscall.
  2. Play the effect by writing a struct to the device.
  3. Stop by writing another struct to the device.

My hypothesis is that step 1 might be missing in retroarch. I'm looking into building a minimal version of that program that only does step 1, to validate that.

orbea commented 6 years ago

fwiw, my experiences with using xpad and third party controllers has been less than optimal too. This includes a broken rumble, although not quite the same as what you are experiencing.

auxym commented 6 years ago

Yeah, xpad is not perfect for sure. XB1 controller support seems particularly hack-ish at the moment (the driver keeps a list of quirks for each controller type).

That said, the fact that fftest works without a hitch was, to me, a good pointer that the bug might be on the retroarch side.

Do you have any idea where the linux udev rumble api would be implemented in retroarch? I'm really not much of a C hacker, but I could have a quick look and maybe even submit a PR if it's a really easy fix.

gouchi commented 6 years ago

For the udev joypad driver.

auxym commented 6 years ago

I spent a bit of time this morning looking into this, adding a bunch of logging to the udev driver to figure out what it is doing.

I think I figured it out: it's not the effect upload as I initially thought; the driver seems to be doing that correctly. It actually seems to have to do with the FF master gain. fftest sets the master gain to 75% on each run. This write call with FF_GAIN is never done in the udev driver.

Quick testing shows that adding it seems to fix my issue. I should have time to a bit more testing and then submit a PR with the fix in the next few days.

It could also explain why no one else seems to be experiencing the issue: probably with OEM controllers the gain is set to default to some non-zero value, while on my 3rd party pad it defaults to 0%.

Now I have to ask, would the maintainers be OK with a hard-coded 75% default master gain? Or should we put the value in config.h? Or add an actual menu/config file entry? In the latter case, I would probably need guidance or even better, someone volunteering to implement that part.

gouchi commented 5 years ago

Hi @auxym did you have the opportunity to provide a PR ?

auxym commented 5 years ago

I did not get around to submitting a proper PR, but here is the commit I tested successfully:

https://github.com/auxym/RetroArch/commit/72a9a4e5ce31c087d20b6b433f21aed9f04d076e

LMK if you think think this could work as a quick and dirty PR and I can submit it.

gouchi commented 5 years ago

I asked people to test this patch and update this issue as I don't have XB1 controller to test.

gouchi commented 6 months ago

@auxym Can you make a test with latest RA as this PR has been merged and it should help to fix this issue.

Thank you.