Skip to content
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

Controller name returned on macOS does not match other platforms #96756

Open
plink-plonk-will opened this issue Sep 9, 2024 · 6 comments
Open

Comments

@plink-plonk-will
Copy link
Contributor

plink-plonk-will commented Sep 9, 2024

Tested versions

System information

Godot v4.3.stable - macOS 14.6.1 - Vulkan (Forward+) - integrated Apple M1 Max - Apple M1 Max (10 Threads)

Issue description

With the switch to using GCController, the controller name returned no longer matches other platforms. For instance, "PS5 Controller" becomes "DualSense Wireless Controller". This causes a problem when using this value in GDScript to determine controller icon sets across platforms: checking for an additional value on Mac doesn't seem to be a robust solution.

Unfortunately, there doesn't seem to be a way to associate an IOHIDDevice with GCController: so a robust code solution doesn't appear to be possible. SDL works around this by doing string compares and translating the GCController vendorId to the original ids (eg. 0x0ce6 (PS5 controller) 0x054c (Sony)). What I wonder is - should the same thing be done in Godot, or should the differences be handled in the game code?

Some notes:

This is an entry point to seeing how SDL handles this:

https://github.com/libsdl-org/SDL/blob/6e885d96193a4b0096fe7fed6d4e6c3e5f247283/src/joystick/apple/SDL_mfijoystick.m#L387

Here's a stack overflow detailing how you could tell if a IOHIDDevice would be handled by GCController, but I was unable to get the method mentioned to get a valid vendor or product id. I suspect the underlying API has changed, and this is not part of the exposed interface anyway - so even it worked, I suspect it might be risky from an app store review perspective.

https://stackoverflow.com/questions/33509296/supporting-both-gccontroller-and-iohiddeviceref

Steps to reproduce

Use var controller_name := Input.get_joy_name(device), and compare the results from other platforms with that on macOS.

Minimal reproduction project (MRP)

It's really just the returned value from Input.get_joy_name(device).

@AdriaandeJongh
Copy link
Contributor

I suspect this has to do with Apple being the middleman in controller support, whereas on Windows you have 3rd party drivers that are supposedly consistent. I made a workaround for this in my own input manager:

func _deduce_controller_type_from_name(controller_name: String) -> ControllerType:
	if controller_name.contains("XInput") or\
			controller_name.contains("Xbox"):
		return ControllerType.XBOX
	elif controller_name.contains("Sony") or\
			controller_name.contains("Playstation") or\
			controller_name.contains("PS4") or\
			controller_name.contains("PS5") or \
			controller_name.contains("DualSense"):
		return ControllerType.PLAYSTATION
	elif controller_name.contains("Joy-Con"):
		if controller_name.contains("(L)"):
			return ControllerType.SWITCH_JOYCON_LEFT
		else:
			return ControllerType.SWITCH_JOYCON_RIGHT
	elif controller_name.contains("Switch"):
		return ControllerType.SWITCH
	elif SteamManager.is_on_steam_deck or controller_name.contains("Steam"):
		return ControllerType.STEAM_DECK
	
	return ControllerType.GENERIC

@plink-plonk-will
Copy link
Contributor Author

Yes - that's the workable approach at the moment. The issue is more a question of if that should be done in the engine code instead (like in SDL2). I'm happy to open a PR to do it at the engine level if that's deemed to be the correct approach, but also totally understand if it should be considered non-portable.

@AdriaandeJongh
Copy link
Contributor

The workaround I posted above somehow no longer works?! The names I'm getting now are "Controller" and "Wireless Controller", making it impossible to determine the type of controller! Uggghhh. Will make a new issue.

@plink-plonk-will
Copy link
Contributor Author

plink-plonk-will commented Oct 9, 2024

Which version macOS and Godot are you using? The method used in the link above (rsubtil/controller_icons#83) works for me with macOS 15.0.1, and Godot 4.3 stable. It also looks like the Godot code for dealing with "joystick" on Mac hasn't changed since then.

@AdriaandeJongh
Copy link
Contributor

AdriaandeJongh commented Oct 9, 2024

That's the weird thing: I am using Godot v4.3.stable on macOS 15.0.1. So are my team mates, who are seeing the same issue.

@plink-plonk-will
Copy link
Contributor Author

That is very strange. I am still getting "DualSense Wireless Controller" returned from Input.get_joy_name(device). The exact build of macOS I'm running is 24A348. And Godot is unmodified v4.3.stable.official [77dcf97].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants