-
-
Notifications
You must be signed in to change notification settings - Fork 54
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
Joystick Interposer evdev support, fixes SDL, Wine, Retroarch, RPCS3, and more. #173
base: main
Are you sure you want to change the base?
Conversation
de3c25e
to
b28e51f
Compare
c54628f
to
b0ec08c
Compare
@danisla Feel free to switch from Draft PR if you are ready. |
That is in order for the near future. I know the source of error. |
Ok maybe we’ll just leave it disabled for now and you can re-enable it the build steps later. |
Anyways, when you are ready, press "Ready for review" and I'll directly make necessary edits. |
I'm seeing a segfault during the entrypoint when running with the
It looks like the Moving this back to draft to fix the entrypoint issue. |
@danisla I am seeing that this issue might also be relevant, although separate. The concern I have with #171 is whether the below can be made more simple in any way; need a sufficient understanding of the websockets package. This is mostly redundant except def custom_response(self, status, custom_headers, body):
"""A wrapper indentical to https://github.com/python-websockets/websockets/blob/main/src/websockets/server.py#L482
but allows 'body' type to be either bytes or string.
"""
status = http.HTTPStatus(status)
headers = Headers(
[
("Date", email.utils.formatdate(usegmt=True)),
("Connection", "close"),
("Content-Length", str(len(body))),
("Content-Type", "text/plain; charset=utf-8"),
]
)
# overriding and appending headers if provided
for key, value in custom_headers:
if headers.get(key) is not None:
del headers[key]
headers[key] = value
# Expecting bytes, but if it's string then convert to bytes
if isinstance(body, str):
body = body.encode()
return Response(status.value, status.phrase, headers, body) |
This doesn't seem related to the joystick interposer function, so we'll solve it in the respective issue. |
Yeah, just for reference. |
@danisla For the purpose of documentation, what are the exhaustive interface (and/or driver) options that this interposer now supports? (e.g. joydev, udev/evdev, sdl1/2, hid, etc...) And can one use udev and sdl2 options here if one chooses so? https://docs.libretro.com/guides/input-controller-drivers/#linux |
2124f43
to
283bf52
Compare
283bf52
to
262e2a4
Compare
udev is not supported. only evdev devices, so sdl and direct raw joystick drivers. |
Applications using libudev will fail when relying on |
96b7913
to
1c3e7e5
Compare
Discussion with @ABeltramo (A) and @danisla (D), myself (E): A: It wouldn't work with a ton of modern games running on Steam A: There are 2 main issues on the top of my head: For Number 1: E: https://nick.tay.blue/2024/01/21/wine-dualsense/ What would this do, here? A: Nope, that's not how Proton and the hidraw stuff works. Proton uses SDL when hidraw is not available. There are games that will require access to the hidraw device because that's how they work on Windows: they access the raw USB device directly and don't go via xinput E: The last lines of the link you sent me says differently, unless I'm reading it incorrectly: One final snag is that many distros do not allow user access to hidraw devices. Steam ships some udev rules to allow this for certain common controller types, but not most. In other words, your user may not have access to the hidraw device for your controller, especially if it is a less well-known controller. In those cases, we access it through SDL2 via its linux js backend and try to treat it as an Xbox controller, even if it is not mapped with the Steam client mapping feature. A: I'm not sure what to say.. If you try out games in Proton you'll quickly see that is not always the case, just having /dev/input/event* present there is usually not enough. For Number 2: E: May the below improve things (i.e. reduce the percentage of games where this is an impasse)? https://steamcommunity.com/groups/SteamClientBeta/discussions/3/3123786356703008701/?ctp=4 I'm happy to report I basically got them to finally relent and give you that option 🙂 You have two options: ValvePlug Either will get the job done, I prefer my own ValvePlug software because it's integrated with Special K. I can enable Steam Input (as if), then restart the Steam client from SKIF. https://github.com/SpecialKO/ValvePlug A: If you don't expose /dev/uinput Steam will run with Steam Input disabled, or you can easily disable it in the settings. That doesn't mean that games that require it will have a working joypad E: So you mean that in any game that doesn't use xinput and requires raw gamepads in Windows will all use hidraw in Wine? A: Ok found what I was looking for, there's something here: https://github.com/GloriousEggroll/proton-ge-custom/blob/master/docs/CONTROLLERS.md E: What's the percentage of case 1 and case 2 in general? Any representative offline AAA games? A: I don't want to give you a fake number I obviously don't have stats on this. For example any recent Sony exclusive game (Helldivers, Horizon, God of war) will probably have issues with your implementation E: So basically God of War's Windows port? A: Yep, correct. Ragnarok doesn't pick up some joypads even on a normal desktop if you don't enable Steam Input. Not sure if that's just specific to the DualSense controller (what I've tested) or it also applies to the Xbox joypads E: Our experiences are generally not from Steam (Wine + GoG) so yeah I understand that there are substantial edge cases. f you bring us back data from an Xbox-compatible controller in your setup, we'll be much more convinced about this. A: It's fairly well known that Steam Input is required for some games, I do have the same issues on my Steam Deck for example when using the integrated joypad which isn't a PS pad. I can quickly try out the Xbox one joypad on GOW Ragnarock in a minute.. E: It might also be possible that different Proton variants may produce different results. A: Ragnarock with a real xbox one joypad works without steam input. For Number 3: A: Yep, we've got that with hotplug in docker since 2023/11 E: Will containerd have any additional reason not to be possible compared to Docker? A: The only thing needed is mknod it shouldn't be an issue with containerd D: exposing /dev/uinput also requires exposing the entire /dev/input/ directory to all continers. when you create a device with uinput, it also creates a /dev/input/eventX device. The uinput-device-plugin would use nsenter to wire these mounts together when a new uinput device was created, so /dev/input/event100 on the host would get mapped to something like /dev/input/event0 in the container. A: That is not technically correct. For devices that you create via uinput you can mknod just the devices that you control without exposing the full /dev/input. This is what we do in Wolf E: Relevant information contained within the games-on-whales/wolf#81 issue. |
1c3e7e5
to
66ce8bd
Compare
66ce8bd
to
707bf00
Compare
The following link points to information on implementation of virtual xbox joypad ( using libevdev and moonlight protocol) and steam recognizes it without issues. https://abeltra.me/blog/inputtino-uhid-2/ https://github.com/games-on-whales/wolf/blob/stable/src/moonlight-server/control/input_handler.cpp https://github.com/games-on-whales/inputtino/blob/stable/src/uinput/joypad_xbox.cpp |
447258b
to
263c30a
Compare
263c30a
to
62606a0
Compare
As you might know, @ABeltramo is the developer of the projects you identified, and we have had a very constructive discussion above. We will keep on communicating with him regarding the landscape around this in general. |
More relevant resources (need to identify the stack): https://github.com/ShadowBlip/InputPlumber Feedback by @danisla I just met with the InputPlumber devs in person. They have a cool project with similar goals and approaches. For containers, it’s heavily dependent on mounting udev, uhid, uinput and /dev/input from the host. So needs a lot of work to adapt for multi-container. Their primary use case is handheld gaming devices. They had about 10 of them on display at the booth. |
Method to create a mount on |
Changes
open64
and makes socket non-blocking when added to anepoll
./dev/input/event*
joystick devices.SDL_JOYSTICK_DEVICE
workaround for SDL apps is no longer needed.Application Specific
General
All interposed joysticks will now appear connected even if no joystick is connected to the browser. This makes for a better hotplugging experience.

Retroarch
To use with retroarch, edit your
retroarch.cfg
(at~/.config/retroarch/retroarch.cfg
) and set:RPCS3
Select

SDL
as controller handler then selectSelkies Controller 1
from the device list.Wine
Run

wine control
and then open theGame Controllers
app to test joystick support.Testing
nvidia-egl-desktop:24.04
Dockerfile.egl.jstest
:Build and run:
gst-py-example:main-ubuntu24.04
Dockerfile.example.jstest
Build:
Run: