SDL_WINDOWS_JoystickDriver depends on callbacks in SDL_RAWINPUT_JoystickDriver
and SDL_HIDAPI_JoystickDriver being available. It also manages the common
WindowProc used for joystick detection in both WINDOWS and RAWINPUT drivers.
If we don't tear them down backwards, there's a window of time where we could
invoke RAWINPUT_WindowProc() after RAWINPUT_JoystickQuit() was called.
Since accessing Bluetooth prompts the user for permission on both Android and iOS, and we only need it for Steam Controller support, we'll leave it off by default. You can enable it by setting the hint SDL_HINT_JOYSTICK_HIDAPI_STEAM to "1" before calling SDL_Init()
Fixes https://github.com/libsdl-org/SDL/issues/4952
This prevents conflicts with hidapi linked with applications, as well as allowing applications to make use of HIDAPI on Android and other platforms that might not normally have an implementation available.
Enabling the RawInput backend causes SDL_XINPUT_Enabled() to return false.
That causes WGI and DInput backends to take ownership of XInput-compatible
controllers, because they think there's no XInput-specific backend enabled.
In WGI's case, it will actually race with RawInput to open the device. By
properly excluding XInput devices from WGI, we can ensure that the sets of
devices managed by WGI and RawInput don't intersect. This makes the race
harmless, since they'll never both go after the same device.
The Xbox One driver stack doesn't propagate the VID/PID down to the
HID devices that end up in the GetRawInputDeviceList() output. This
means we end up matching against the wrong VID/PID and can't properly
exclude Xbox One controllers from WGI.
Fortunately, it is possible to walk back up the device tree to find
the parent with the matching VID/PID.
This change corrects the mappings for the Atari gamecontroller and
adds support for the Atari Xbox 360 compatible gamecontroller. The Atari
game controller can switch between Atari and Xbox 360 mappings.
There were a few places throughout the SDL code where values were
clamped using SDL_min() and SDL_max(). Now that we have an SDL_clamp()
macro, use this instead.
This removes the CM_Register_Notification code on WinRT. Note
that this API _is_ available to UWP apps as of Windows 10.0.17763
(version 1809, released October 2018), according to:
https://docs.microsoft.com/en-us/uwp/win32-and-com/win32-apis#apis-from-api-ms-win-devices-config-l1-1-1dll
So it might be worth readding with some sort of preprocessor check
for minimum targeted version, or whatever is appropriate for WinRT
development.
The Game Controller Kit doesn't show the controllers at startup, so the HIDAPI driver sees them first and therefore gets preference when a controller is supported by both drivers.
This fixes bug https://github.com/libsdl-org/SDL/issues/4209
This prevents an assertion whem LINUX_JoystickGetGamepadMapping tried to
open the stick temporarily and messed with global state by doing so. Now
the global state is only set in LINUX_JoystickOpen, but the common code
is shared by both interfaces.
Fixes#4198.
To enter Bluetooth pairing mode hold B and Action (button with circle) buttons for 3 seconds.
It works via usual HIDAPI if special filter driver is not installed:
https://www.amazon.com/gp/help/customer/display.html?nodeId=GZCT4CTFHXLHEB9T
With that driver installed it mimics Xbox One controller and works via XInput under Windows.
Under DInput this controller is not usable at all.
It is called from WGI before the normal joystick detection has been run, so it needs to actually enumerate currently connected devices.
We can skip the logic checking for other drivers also supporting this device, because that logic is duplicated from the call site.
SDL_JoystickSetVirtualAxisInner() and SDL_JoystickSetVirtualHatInner()
did not properly sanitize the 'axis' and 'hat' parameters.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
- Do not call IDirectInputDevice8_QueryInterface(device, &IID_IDirectInputDevice8,...) on DIRECTINPUTDEVICE8 device
- Get joystick VendorID and ProductID via IDirectInputDevice8_GetProperty(.., DIPROP_VIDPID, ..) call instead of messing with DIDEVICEINSTANCE.guidProduct
- Normalize HID device interface path to upper case for stable operation of XInput check
- Remove useless RawInput calls in SDL_IsXInputDevice() - just check for "IG_" string in HID device interface path that we already have
There shouldn't be any observable behavior changes.
This add controller mappings for the Atari vcs (modern) controller as
well as the classic controller, for both bluetooth and USB connectivity.
Signed-off-by: Sjoerd Simons <sjoerd@collabora.com>
At least on bluetooth the guid user the version reported by the
bluetooth device. Which for Atari vcs controllers is the firmware
version. However the mapping will stay the same regardless of firmware
version, so ignore the version entirely to avoid needing a new mapping
entry for each firmware version.
Signed-off-by: Sjoerd Simons <sjoerd@collabora.com>
When Xbox One/Series Controllers are connected via USB on Windows they all are using `XBOXGIP` driver and produce a special ProductID `0x02FF` (GIP software PID) for any connected controller.
On the other hand `Xbox 360 Wireless Controller Reciever` (PID 0x0719) is using `XUSB` driver and produces special ProductID `0x02A1` (XUSB software PID) for each connected Xbox 360 Wireless Controller.
Also fixed Xbox One Series X Controller comment.
I have a buggy system which reports a udev "change" event for an empty
USB-C port every 0.14 seconds, which causes annoying frame hitches
because SDL decides that means it needs to do a libusb hid_enumerate,
which is slow (~25ms!) because of the get_usb_string() calls in there.
We only need to re-enumerate if we've seen a device added or removed, so
let's filter out the change event first.
Signed-off-by: Steven Noonan <steven@valvesoftware.com>
Signed-off-by: Sam Lantinga <slouken@libsdl.org>
The information whether a specific joystick can be used as a gamepad is
not going to change every frame, so we can cache the result into a
variable.
This dramatically reduces the performance impact of SDL2 on small
embedded devices, since the code path that is now avoided was quite
heavy.
Fixes#4229.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
In the extremely unlikely event that inotify is not available (and,
therefore, HAVE_INOTIFY is not #defined), SDL will no-longer build.
This is because <unistd.h> is only included when HAVE_INOTIFY is
defined, and PR #4098 adds a call to access(…, F_OK), which requires
<unistd.h>.
(Note that the F_OK symbol is the only one which actually prevented
SDL from compiling, but both access() and close() fell back to implicit
definitions, which is a bit concerning.)
Fixes: 8d43f45a7b ("Don't use udev for joystick enumeration if running in a container")
If we are running in a container, like Flatpak[1] or pressure-vessel[2],
it's likely that we are using user namespaces,
therefore udev event notification via netlink won't work reliably.
Use their filesystem API to detect them and automatically fallback to
the inotify-based enumeration.
[1] <https://flatpak.org/>
[2]
<https://gitlab.steamos.cloud/steamrt/steam-runtime-tools/-/tree/master/pressure-vessel>
Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
This improves SDL's ability to detect HIDAPI joystick hotplug in a
container environment because we cannot reliably receive events from
udev in a container.
For a more detailed explanation of why this issue happens with
containers, please check the previous commit
"joystick: Use inotify to detect joystick unplug if not using udev"
(b0eba1c5).
Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
As already explained in the previous commit "joystick: Allow libudev to
be disabled at runtime" (13e7d1a9), libudev can fail in a container.
To make it easier to experiment with, we add a new environment variable
"SDL_HIDAPI_JOYSTICK_DISABLE_UDEV" that disables udev and let it
fallback to the device enumeration using polling.
Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
This fixes problems with controllers not being re-detected when a computer goes to sleep and a controller is removed and plugged back in while it's asleep.
There were two different implementations of IsBluetoothXboxOneController(), one
in SDL_hidapi_xbox360.c and one in SDL_hidapi_xboxone.c. The latter had been
updated to include USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH while the former had
not.
This mismatch led to the Xbox Series X failing on macOS only. We have special
code for handling the 360Controller driver for macOS which requires us to use
the Xbox 360 driver for wired Xbox One controllers, and the SDL_hidapi_xbox360
version of IsBluetoothXboxOneController() was used to determine which devices
were wired.
In addition to adding the missing USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH, this
change moves IsBluetoothXboxOneController() into a single shared function which
will ensure this bug won't happen again.
jibb
New hint to let the user opt out of having Switch controllers' Home button lit when opened.
This is more consistent with the Switch itself (which doesn't light the button normally) and may be preferred by users who may disconnect their controller without letting the application close it.
I think this warrants a Switch-specific hint because the default behaviour is unusual (inconsistent with using a Switch controller on a Switch itself or with some other programs on PC), and because of that it's distinct from other lights (the player number on Switch controllers and the player colour on PlayStation controllers).
Existing SDL applications may not know about the need to set a specific
hint to enable rumble on PS5 controllers, even though they may already
set the equivalent SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE hint for PS4
controller rumble support.
Rather than requiring those developers update their apps, let's use the
SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE value as an indication of the behavior
they are expected for all PlayStation controllers.
jibb
I'm testing with DualShock 4, DualSense, Switch Pro Controller, and PowerA Switch Controller.
I'm using the standard mapping file from here:
https://raw.github.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt
With SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS turned off (set to "0") I expect the button positions to be the same on all devices, based on Xbox controller button naming (eg SDL_GameControllerGetButton(g, SDL_CONTROLLER_BUTTON_Y) gives me whether the North face button is pressed).
However, the Switch Pro Controller layout is wrong (matching labels rather than positions, so X and Y are swapped and A and B are swapped). And with the PowerA controller the East and West buttons are correct, but the North and South buttons are swapped instead.
Mathias Kaerlev
Also seeing this on 2.0.14. This is most likely a regression, since we weren't seeing this on an earlier SDL version.
I suspect it might be caused by this commit:
a569b21188 (diff-da9344d94c66b8c702a45e7649f412039f08bba83bd82de33f5c80ea9c8c39d5)
It seems like both the HIDAPI driver and SDL_gamecontroller.c will try to swap the buttons if the hint is set to 0, causing the button remap to cancel out.
RustyM
This is related to Bug 5034, but crashes under a somewhat different condition.
In the latest tip (changeset 13914) or with the SDL 2.0.12 source + David?s 5034 patch, unplugging and then replugging in certain controller types on macOS will crash. A mix of new controllers like Switch Pro, PS4 and Xbox One all work without issue. But if a controller without a rumble function, like many SNES retro USB gamepads, is mixed with a PS4 or Switch Pro controller it will crash.
File: joystick/darwin/SDL_sysjoystick.c
Function: static recDevice *FreeDevice(recDevice *removeDevice)
On line 159: while (device->pNext != removeDevice) {
Causes: Thread 1: EXC_BAD_ACCESS (code=1, address=0x188)
This can be reproduced in testgamecontroller" by starting the test program with both a ?retro? controller plugged in and a ?modern rumble? controller (Switch Pro/PS4). This may crash on launch, but it depends on which controller ends up as device 0. If it doesn?t crash, unplug the ?modern rumble? controller and plug it back in.
Some of the "retro" controllers I?ve seen this crash with:
- iBuffalo SNES Controller
- 8Bitdo SN30 Gamepad (in MacOS mode)
- Retrolink NES Controller
- HuiJia SNES Controller Adaptor
The issue appears macOS specific. Seen on 10.12.6 and 10.14.6. Not seen on Windows 10.
The while loop in FreeDevice() assumes that every device is not NULL.
recDevice *device = gpDeviceList;
while (device->pNext != removeDevice) {
device = device->pNext;
}
device->pNext = pDeviceNext;
So maybe we should check for NULL here? Or instead prevent adding NULL devices to the list in the first place? Checking device for NULL before entering the loop appears to work.
recDevice *device = gpDeviceList;
if (!device) {
while (device->pNext != removeDevice) {
device = device->pNext;
}
}
device->pNext = pDeviceNext;
Note that axes are changed to match the axes we're using with PlayStation controllers, since users will appreciate consistent behaviour across devices.
i.e. where the string is known guaranteed to be WCHAR*, in:
- SDL_dinputjoystick.c (WIN_IsXInputDevice): VARIANT->var is BSTR (WCHAR*)
- SDL_rawinputjoystick.c (RAWINPUT_AddDevice): string is WCHAR*
- SDL_windows_gaming_input.c (IEventHandler_CRawGameControllerVtbl_InvokeAdded):
string is WCHAR*
There should be more of these..