Skip to content

[3.x] Xbox One Controller not detected by Godot Engine macOS #53329

@lukekras

Description

@lukekras

Godot version

3.3.3.stable (b973f99), 3.3.4.stable (faf3f88), 3.3.5.rc (820b1ae), 3.4.beta (90a7342)

System information

macOS Big Sur 11.6, Xbox One Controller (Vendor: 045e Product: 02dd)

Issue description

Godot Engine doesn't detect Xbox One Controller (STANDARD GAMEPAD Vendor: 045e Product: 02dd)

macOS Big Sur (Version 11.6) System Information shows the controller in the USB Device Tree.
Apple -> About This Mac -> System Report... -> Hardware -> USB -> USB 3.0 Bus -> Controller
Controller:

Product ID: 0x02dd
Vendor ID: 0x045e (Microsoft Corporation)
Version: 2.03
...
Speed: Up to 12 Mb/s
Manufacturer: Microsoft
Location ID: 0x14300000 / 3
...

Opening a Chrome browser to Gamepad Tester shows the controller, and you can interactively see the buttons and hats working.

Xbox Controller
Xbox One Controller (STANDARD GAMEPAD Vendor: 045e Product: 02dd)

Steps to reproduce

Steps

Checkout and open Godot Demo Projects - Joypads.

The XBox Controller is not recognised. Press the Remap and the Godot console output prints "Unable to find controller". Disconnect and reconnect the controller from the USB port. Still not detected in Godot.

This was tested in the following versions with the same result.
Godot Engine v3.3.3.stable.official [b973f99]
Godot Engine v3.3.4.stable.official [faf3f88]
Godot Engine v3.3.5.rc.custom_build [820b1ae]
Godot Engine v3.4.beta.custom_build [90a7342]

Comments

Looking at game controller db, the UID looks to have the Vendor: 045e and Product: 02dd numbers (if you swap the bytes around). The tests were done on an Intel Mac (little endian), so swapped bytes fits, but it's not a closed case.

I tracked the code to running some macOS IOKit code in joypad_osx.cpp. I suspect that the IOHIDManager* calls maybe are broken in Big Sur, or my version of Big Sur (Version 11.6).

void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const {

	CFRunLoopRef runloop = CFRunLoopGetCurrent();
	IOReturn ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
	ERR_FAIL_COND(ret != kIOReturnSuccess);

	IOHIDManagerSetDeviceMatchingMultiple(hid_manager, p_matching_array);
	IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, joypad_added_callback, NULL);
	IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, joypad_removed_callback, NULL);
	IOHIDManagerScheduleWithRunLoop(hid_manager, runloop, GODOT_JOY_LOOP_RUN_MODE);

	while (CFRunLoopRunInMode(GODOT_JOY_LOOP_RUN_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) {
		/* no-op. Callback fires once per existing device. */
	}
}

I did some searches on "The Internet Machine" and there was some discussion around Apple's changes to IOKit and the introduction of DriverKit in Big Sur and beyond. Reimplementing controllers with DriverKit seems like the only way forward on Apple devices, but I suspect a nontrivial change. DriverKit may even be already on the Godot roadmap. DriverKit Sample Code. It would be good to get a controller DriverKit example from Apple. Maybe with a DriverKit implementation in Godot, most of the controller bugs on Mac platform might just go away.

Minimal reproduction project

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    For team assessment

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions