YoYoGames / GameMaker-Bugs

Public tracking for GameMaker bugs
26 stars 8 forks source link

Nintendo Switch USB gamepads require filtering on desktop platforms #8426

Closed offalynne closed 3 days ago

offalynne commented 1 week ago

Description

Filing issue per Russel's request for LTS2025

Under normal circumstances, Nintendo Switch controllers do not work on Windows, Mac, or Linux over USB. However a certain HID write puts them in an active mode. Software that does this includes Steam, web browsers, and more. When in active mode, the HID devices blinker wildly which results in persistent random joystick input. In most cases such software creates an additional virtual controller, which is intended to be the device seen/used by game software. To address this, Switch USB devices need to be "blocked" upon gamepad discovery.

Here are GUIDs that always indicate a Nintendo Switch device over USB, and should always be blocked:

030000007e0500000e20000000000000 Windows Joy-Con Charger
030000007e0500000e20000000020000 MacOS Joy-Con Charger
030000007e0500000e20000011010000 Linux Joy-Con Charger
030000007e0500000e20000011810000 Linux Joy-Con Charger
030000007e0500000920000000020000 MacOS Switch Pro Controller
030000007e0500000920000011010000 Linux Switch Pro Controller

These GUIDs are platform-unique, (other platforms result in different GUIDs for these same devices) so there is no explicit need for this change to be platform-selective.

Unfortunately on Windows there is no GUID differentiation between Bluetooth (usually leads with bus, 0500...), so a Switch Pro controller can not be blocked on Windows by GUID alone. We have found that if gamepad_get_button_count() returns greater than 21, this indicates a Switch Pro Controller over USB, but not Bluetooth (where it behaves normally). So in addition to the above GUIDs, 030000007e0500000920000000000000 should be blocked if and only-if greater than 21 buttons are found for the device.

In case of a match to any of the above, the gamepad index should behave as if none is connected, so:

  1. The Async - System gamepad discovery event should not be registered
  2. The Async - System DS map async_load should not push "gamepad discovered" or "pad_index" to async_load
  3. The index should return false from gamepad_is_connected()
  4. The index should return "none" from gamepad_get_guid()
  5. The index should return "" from gamepad_get_description()

If anyone assigned to this lacks a device to test, I suggest testing another DInput device on hand (eg. PlayStation controller) to confirm the implemented blocking method works. Upon follow up I am glad to confirm a working solution locally with a relevant device from the list.

See also #8425, #8426, #8427, #8428

Expected Change

No response

Steps To Reproduce

Connect gamepad, observe issue

How reliably can you recreate this issue using your steps above?

Always

Which version of GameMaker are you reporting this issue for?

2024.8.1 (Monthly)

Which platform(s) are you seeing the problem on?

Windows

Sample Package Attached?

Sample Project Added?

rwkay commented 3 days ago

Fix added to internal develop version should be in 2024.13 Beta

offalynne commented 3 days ago

Windows by GUID [...] 030000007e0500000920000000000000 should be blocked if and only-if greater than 21 buttons are found for the device

Fails, device is not filtered Image

rwkay commented 3 days ago

I blocked the one in the message above which is 030000007e0500000e20000000000000, NOTE e2 in the middle - the one in your screenshot it 92 - should I block that one too?

Ignore me... I have just reread everything above and realised that you already answered this... I will update the code

Russell

rwkay commented 3 days ago

Added a fix to internal develop