add CONTROLLERS documentation
This commit is contained in:
parent
37869b4260
commit
936c18088e
1 changed files with 113 additions and 0 deletions
113
docs/CONTROLLERS.md
Normal file
113
docs/CONTROLLERS.md
Normal file
|
@ -0,0 +1,113 @@
|
|||
---
|
||||
How controllers work in Proton
|
||||
---
|
||||
|
||||
There are five methods that Windows games can use to access controllers:
|
||||
dinput, xinput, winmm, hid, and rawinput. Games can use any combination of all
|
||||
of these APIs.
|
||||
|
||||
rawinput allows direct access to the gamepad hardware. The application must
|
||||
know the HID protocol, and/or know the device-specific protocol for
|
||||
non-standard devices like Xbox controllers.
|
||||
|
||||
hid is a layer above rawinput, where Windows will talk HID to the controller on
|
||||
the game's behalf. This turns the raw HID protocol data into usable things like
|
||||
buttons and joysticks.
|
||||
|
||||
dinput is a "legacy" API that allows applictions to talk to any type of
|
||||
joystick. On Windows, it is likely implemented on top of HID. Notably, dinput
|
||||
allows easy access to controllers that no other API does, so it is still used
|
||||
by modern games despite being "legacy."
|
||||
|
||||
xinput is the new API that supports only Xbox controllers. On Windows, it is
|
||||
likely implemented on top of rawinput, as Xbox controllers do not behave like
|
||||
standard HID devices.
|
||||
|
||||
winmm is the very legacy API, for when joysticks were hooked up through the
|
||||
soundcard. On modern Windows, it is likely implemented on top of hid.
|
||||
|
||||
|
||||
Here is a diagram for how these APIs are mapped down to the system by Proton:
|
||||
|
||||
|
||||
--------
|
||||
|game.exe|
|
||||
--------
|
||||
/ | | | | application
|
||||
********|**|*|*|**|***********************
|
||||
------ / | | | | wine
|
||||
|xinput| | | | |
|
||||
------ / | | |
|
||||
| / | | |
|
||||
--- / / | \
|
||||
|hid|--- / | \
|
||||
--- / | \
|
||||
| / | \
|
||||
-------- ------ -----
|
||||
|rawinput| |dinput| |winmm|
|
||||
-------- ------ -----
|
||||
| | |
|
||||
----------- | ----------------
|
||||
|winebus.sys| | |winejoystick.drv|
|
||||
----------- | ----------------
|
||||
| \ / | wine
|
||||
***|*********|***********|****************
|
||||
\ | | linux
|
||||
\ ---- |
|
||||
\ |SDL2| |
|
||||
\ ---- |
|
||||
\ | \ |
|
||||
\ | ---- |
|
||||
\ | \ |
|
||||
------ -----------
|
||||
|hidraw| |input event|
|
||||
------ -----------
|
||||
|
||||
Some things to note:
|
||||
|
||||
SDL2 provides the controller mapping feature of the Steam client. If you don't
|
||||
go through SDL2, then you don't get that mapping feature. Also notice that
|
||||
winebus.sys must turn SDL2 events into usable winebus data (HID protocol). We
|
||||
also allow direct access to hidraw devices so games which can speak HID (or
|
||||
other) protocol can talk directly to those devices.
|
||||
|
||||
Xbox controllers do not speak real HID. Instead Windows provides a HID
|
||||
compatibility layer so dinput, which is implemented on top of HID, will present
|
||||
the Xbox controller to legacy games. Of course some games (Unity) have noticed
|
||||
that, and talk directly to this internal HID interface, so we had to duplicate
|
||||
it bit-for-bit in winebus.sys.
|
||||
|
||||
Some games support talking directly to certain controller types. For example,
|
||||
many modern games support PlayStation 4 controllers directly and will provide
|
||||
layouts and button images in-game specific to DualShock 4 controllers. For this
|
||||
reason, we don't want to present every controller through xinput, which should
|
||||
only present Xbox controllers.
|
||||
|
||||
However, we also want users to be able to use any controller, even if the game
|
||||
only supports xinput. Steam provides a controller mapping feature, which is
|
||||
presented as a virtual Steam Controller. We turn this virtual Steam Controller
|
||||
into an xinput device. This means any controller which is mapped will appear to
|
||||
the game as an xinput device, in addition to the other APIs. Controllers which
|
||||
are not mapped will appear as the real controller, which the game may or may
|
||||
not support.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Future improvements:
|
||||
|
||||
winmm's joystick APIs should be implemented on top of HID so it can use the
|
||||
Steam controller mapping feature via winebus/SDL2.
|
||||
|
||||
xinput should be implemented on top of rawinput, as the Xbox HID compatibility
|
||||
layer does not provide all of the features xinput requires. We currently use a
|
||||
hack to work around this.
|
||||
|
||||
dinput should be implemented on top of HID, so we can avoid the code
|
||||
duplication we have now with both winebus and dinput using SDL2 directly.
|
Loading…
Reference in a new issue