libsdl-org / SDL

Simple Directmedia Layer

Home Page:https://libsdl.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SDL3, Steam Deck is reported as Steam Virtual Gamepad

isXander opened this issue · comments

Even with the hint SDL_JOYSTICK_HIDAPI_STEAMDECK, gyro and back paddles are not detected.
This has been tested with multiple decks by multiple users with the same results.

  • Users have tried both enabling and disabling back buttons in the Steam UI.
  • Users have used 'No Gyro' option in Steam Input, since the rest are emulation modes like to mouse.
  • Users have been directed to disable any alternative controller mapping in Steam.
  • Users are launching the game through the Steam-mode, not the desktop mode

Rumble is working.

I have not yet had the opportunity to send these users testgamecontroller. Is there a way to debug what driver is currently being used for a joystick so I can confirm that hidapi_steamdeck.c is being used here?

Is there anything I can do to help diagnose this issue I'm having for you?

If the joystick guid has 6800 at the end, it's using the HIDAPI driver.

I will ask my users to check this.
I'm not able to check right now but, recently I've discovered that decks appear to be going by a different PID, not sure if this is the upgrade to SDL3... 0x11ff. Could this be the reason why this may not be working? I see that the driver is only used via a vid pid check.

@slouken This does indeed seem to be the problem.

{ MAKE_CONTROLLER_ID( 0x28de, 0x1205 ), k_eControllerType_SteamControllerNeptune, NULL }, // Valve Steam Deck Builtin Controller

SDL itself is reporting the Steam Deck as VID = 0x28de, PID = 0x11ff, which matches
{ MAKE_CONTROLLER_ID( 0x28de, 0x11ff ), k_eControllerType_UnknownNonSteamController, "Steam Virtual Gamepad" }, // Steam virtual gamepad

the unknown steam virtual gamepad. Is this a Steam input interference?

You could say there is nothing you can do here, but then what is the point of the deck driver, if it can never even be used?

Further testing, it looks like this is a regression with SDL3.
With SDL2, the steam deck reports 0x1205, with SDL3, the exact same deck reports 0x11ff.

For more context, the steam deck driver is only enabled when the controller type matches k_eControllerType_SteamControllerNeptune. Has anything changed with VID/PID identification since SDL2?

@mmmaisel What set up did you use to ever get this working?

When I developed the HIDAPI SteamDeck driver, I used a SteamDeck running ArchLinux and the AntiMicroX input mapper to access the controller over SDL2. The mapped input was used to play some non-steam games. But the testcontroller tool from SDL3 shows the gyro and accelerometer values fine for me as well.

Since Linux allows only one application to open a hidraw device (Edit: It actually allows it), I think a problem could be the running Steam client which already opens the hidraw device as part of SteamInput.
Please also note that there is a quirk in the SteamDeck kernel driver that hides the classic gamepad device as soon as the hidraw device is opened (see https://github.com/torvalds/linux/blob/master/drivers/hid/hid-steam.c).
As an overall result, only the Steam virtual gamepad may be present and accessible.

So for the average steam deck user, this driver is completely useless, as it can never be used?

Problem is that testing under the same conditions using SDL2, the actual deck device is found, so are you sure this is the cause?

So for the average steam deck user, this driver is completely useless,
as it can never be used?

The main use-case of this driver was when steam input is not available or
does not work, like adding gyro support to non-steam games through an external
mapper. The average steam deck users should not have to use this driver because
there should be steam input available.

This driver was created before SDL3 supported using Linux kernel drivers
to access motion sensors (#8125). With this issue fixed, the correct way
forward is to expose the the steam decks motion sensors through the kernel
driver so that multiple applications can use it.
There is a prototype driver for this available at
https://github.com/mmmaisel/linux/blob/steam-deck-gyro/drivers/hid/hid-steam.c

Problem is that testing under the same conditions using SDL2, the actual deck
device is found, so are you sure this is the cause?

Do the gyroscope, accelerometer and back paddles work for SDL2?
If not, it may have picked up something else that reports itself as
Steam Deck controller. This could be (just guessing) the existing kernel driver
that exposes a generic gamepad without motion sensors.
Otherwise, there may be a way I didn't know about to open the hidraw device
from the steam client (if it was running) and SDL simultaneously.

Further testing, it looks like this is a regression with SDL3.
With SDL2, the steam deck reports 0x1205, with SDL3, the exact same deck
reports 0x11ff.

If motion sensors work in the SDL2 setup, this test looks like a regression
to me from remote.

SDL2 did not pick up any back buttons or motion sensors. This was my main motivator for moving to SDL3, since I saw this explicit driver I assumed for it to work.

In my context, Steam Input is available, playing a non-steam game, though it provides no way to just pass through the gyro or back buttons to the virtual gamepad, it can only emulate gyro as a mouse or joystick, and map the back buttons to something else. This is impossible.

So at the moment, I should just wait for the kernel driver to make its way into Linux stable and then SteamOS?

One thing to note is that with SDL2, the touchpads were available for use as well.

What exactly is different from SDL2 to SDL3 that means HID is identified differently? Looking at the linux hid file, there appears to be no differences at all.

The kernel driver is currently more a mostly untested proof-of-concept than something ready to use. So it still needs a long time until this may be eventually upstreamed.

The SDL hidapi driver was also included in the latest SDL2 release 2.30 and should behave the same as the SDL3 one. If your game does not support SDL2, updating your local SDL2 library may help to get access to the gyro.

Additionally, to use the hidraw driver the hidrawX device in /dev has to be read-writeable for you local user (e.g. through a group). In my case the steam deck controller is /dev/hidraw2 with permissions 660, owner root, group uucp and my local user is member of the uucp group.
If the device is not accessible, SDL will just ignore the hidraw driver and fall back to the generic kernel driver (without gyro support).

Does your game has built-in gyro support or do you like to use some external mapping to some buttons?

I'm not making a game. I am modding Minecraft to add controller support, and I do have explicit gyro support in there. I will ask the steam deck users to try and chmod their hidraw devices to see if it helps, but it's not exactly intuitive for them to have to do that.

I found out that it is actually possible to open a hidraw device by multiple applications simultaneously on Linux. I corrected my above comment.
Also, with the current SDL3 version (675c9f0) I was able to successfully run both, the SDL2 testgamecontroller and the SDL3 testcontroller, apps simultaneously on the hidraw SteamDeck driver and they both received valid input.

However, replacing testgamecontroller with a real SDL2 app like wine control or antimicrox does not work. It disconnects the input from the test app.

Edit: This issue only happens on my SteamDeck. I cannot reproduce it with the DualSense hidraw driver on a PC. There, testcontroller, testgamecontroller, wine control and antimicrox are running together without any issue.

Has anything new happened with this/anyone found a way to get this to work in a real application?

I would like to use the extra features of the Deck's controller with an application that uses SDL for input, specifically the gyroscope, in a scenario where the usual workaround of gyro-to-mouse is not really applicable - but Valve's frustrating insistence on treating anyone without Steam API access as a second class citizen in relation to input is so far putting a stop to even attempting doing this. From all I've tried there doesn't seem to be a way to get the input from the Deck's extra controls to work with SDL or otherwise while the Steam client is running.

For the use case with the steam client, I added a sysfs switch to my prototype kernel driver that allows to override the exclusive access quirk.
This worked in first tests when using the kernel driver to access the device with SDL3 (SDL2 does not support the kernel sensors interface as far as I know).

Also, upstream Linux 6.8 changed that you have to press and hold the top left "options" button for a short moment, until it beeps, to enable the controller at all.

If you're running a game while Steam is running, Valve recommends using Steam Input to get access to the advanced features of the Steam Deck hardware. I understand why that isn't optimal for your use case, but I'm going to go ahead and close this as unplanned for now.