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

Re-add and improve methods to get the name of gamepad inputs #89193

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

YeldhamDev
Copy link
Member

  • Readd get_joy_axis_string(), now with the extra parameter value.
  • Readd get_joy_button_string(), now with the extra parameter scheme.
  • Add the new get_joy_scheme(), to detect what button layout the gamepad has. Can be used with get_joy_button_string().

Closes godotengine/godot-proposals#6930.

@YeldhamDev
Copy link
Member Author

Changes made.

Copy link
Contributor

@Mickeon Mickeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how to feel about this. On one hand it is great to have these names and "schemes" natively. But on the other, it's a bit... prone to be superfluous? I hope I do not sound mean in any way.

After this is merged we are going to get more requests.
Users know there's many controllers out there, and that supporting them all natively is just not possible. But, what about the GameCube controller (which is still loved by many), other pseudo-retro controllers, or even the Steam Controller?

Plus, what about localization? The PR as is cannot localize these, which kind of defeats the purpose. If the need is for controller icons, only get_joy_scheme is necessary here.

All in all, to try and make it brief, I feel like this can be done with custom code or specialized addons much better for the following reasons:

  • Users that do not need it simply ignore them;
  • They would not bloat the core engine;
  • They can be designed for more specific controllers;
  • They can easily be expanded upon in the future (even for older versions of the engine).
  • The provided strings can be localized as the developer wishes to.

@YeldhamDev
Copy link
Member Author

I don't know how to feel about this. On one hand it is great to have these names and "schemes" natively. But on the other, it's a bit... prone to be superfluous? I hope I do not sound mean in any way.

I disagree. On my own game, the name of inputs is used on its keybinding settings, I rely a lot on get_keycode_string(), and used to rely on get_joy_button/axis_string() methods too before they were abruptly removed.

After this is merged we are going to get more requests.
Users know there's many controllers out there, and that supporting them all natively is just not possible. But, what about the GameCube controller (which is still loved by many), other pseudo-retro controllers, or even the Steam Controller?

You talk like new controller schemes are made all the time, they just sticky to preexisting ones.

The GameCube controller also uses the same names for it's buttons as the other Nintendo controllers (but thanks for reminding me, I should add it to criteria in the Nintendo scheme), and the Steam controller uses the same as the Xbox ones.

Plus, what about localization? The PR as is cannot localize these, which kind of defeats the purpose. If the need is for controller icons, only get_joy_scheme is necessary here.

With the exception of the generic names, the others mainly uses letters for them (LT, ZL, etc), there's barely anything to localize. And for the few that could need, nothing stops users from localizing them. I do localization for some key names returned by get_keycode_string(), for example.

  • They would not bloat the core engine;

This is hardly bloat...

  • They can be designed for more specific controllers;

The generic names can suffice for the niche controllers for most people.

  • They can easily be expanded upon in the future (even for older versions of the engine).

I'm not sure what point you're trying to make here.

@akien-mga
Copy link
Member

CC @Riteo who seemed interested in this kind of feature (in Wayland context, but well, it's adjacent :)).

@Riteo
Copy link
Contributor

Riteo commented Mar 8, 2024

Ooooh yeah this is some interesting stuff, thanks @akien-mga for the ping :D

As akien pointed out, I was personally interested in adding a proper controller support on Wayland (like, way upstream) and discussing about the hypotethical Godot APIs for that.

I have not researched much on the subject yet so TIWAGOS in regards to what I am about to say.

Joystick parsing is a very big mess and the only reliable way I've seen to detect the right controller is to use the actual native driver when possible (I think it's called HIDAPI on windows), which is the approach used by SDL. In a pinch, name parsing should work good enough as we already depend on a special joystick DB after all.

What I don't completely agree on is the fact that the controllers' schemes are bound to some very generic enums: I'd much prefer, personally, to have lots of entries explaining different controllers than a few minimalistic ones, like JOY_SCHEME_SONY_PS3, JOY_SCHEME_NINTENDO_GAMECUBE and so on.

Yes, controllers are all very similar, but if they have clearly distinct feature-sets or shapes (considering compatible designs as simple reimplementations of said "standards"), then we should enumerate those, even just for visualization purposes (think about of the old-school picture-of-a-controller rebinding screen).

IMO bloat is a minimal concern, as we're adding just a bunch of string checks and a few enums. Plus, being the keycodes the same by definition (they have some loose semantic association IIRC), we could just keep the three string maps and call it a day, simply associating all the JOY_SCHEME_NINTENDO_* enums to the same map and so on.

Edit: In short, I really like this feature, although I'd make the joystick enum way more descriptive, like SDL does: https://github.com/libsdl-org/SDL/blob/fb87f8f15c11477f294b6486f967ea167dcc20d6/src/joystick/controller_type.h#L43-L60

@YeldhamDev
Copy link
Member Author

@Riteo I like the idea, but nothing stops us from expanding the JoyScheme enum when the need arrives, with the current ones serving as a fallback of sorts.

@Riteo
Copy link
Contributor

Riteo commented Mar 8, 2024

@YeldhamDev I'm not exactly sure on how we'd use the generic fallbacks. Could you please elaborate a little bit more?

@YeldhamDev
Copy link
Member Author

I mean like if we could identify that the gamepad uses a Xbox scheme, but not pinpoint what controller it exactly is.

@Riteo
Copy link
Contributor

Riteo commented Mar 8, 2024

@YeldhamDev if we have an heuristic for that, I suppose we could have some enums akin to JOY_SCHEME_NINTENDO_GENERIC (and so on).

Not exactly sure how we'd figure that out though 🤷

@YeldhamDev
Copy link
Member Author

Not exactly sure how we'd figure that out though 🤷

When we can't check the driver in the platform for whatever reason, but we can still use our list for the name, which it's how the PR works.

I suppose we could have some enums akin to JOY_SCHEME_NINTENDO_GENERIC (and so on).

I don't think the suffix _GENERIC is really necessary, since they are the only ones currently available it would look awkward, even if it would be a form of future proofing.

@Riteo
Copy link
Contributor

Riteo commented Mar 13, 2024

@YeldhamDev

I don't think the suffix _GENERIC is really necessary, since they are the only ones currently available it would look awkward, even if it would be a form of future proofing.

Well, I think that we should definitely add more precise enums, so if we don't do that now I think that we should keep the generic suffix.

@YeldhamDev
Copy link
Member Author

@Riteo Alright, what do you think of the new names?

@Riteo
Copy link
Contributor

Riteo commented Mar 16, 2024

@YeldhamDev yeah, that's what I was thinking of :D

Sorry if I came as too aggressive.

@Rubonnek
Copy link
Member

Rubonnek commented May 4, 2024

This PR also partially implements godotengine/godot-proposals#8519, Input.get_joy_type() in that proposal is equivalent to Input.get_joy_scheme() in this PR.

The difference is an implementation detail -- proposal #8519 suggests the use of the vendor and product IDs provided by the joypad in order to identify its button layout. I agree with that implementation since it seems more correct and precise at the same time. Currently Godot is able to extract the vendor_id and product_id but only on Linux through Input.get_joy_info() merged back in #78539. I've opened a PR to include the Windows implementation to extract and expose those IDs on #91539 and if merged, only Mac will be missing, but seems plausible to do the same on Mac.

That said, if we were to implement Input.get_joy_scheme() that way, we'd need a vendor_id and product_id database that maps each joypad to its button layout type, and here are two I've found so far by going over the proposals:

We could massage the data to create an ID for each controller the same way SDL does it, and have that ID map to a specific scheme.

I don't think we should compile those databases into the engine because users needs may differ vastly and for some devices there seems to be no way to tell the button layout and overall it seems best served as an addon, but at the same time it also seems trivial to include an scons option to avoid compiling in the joypad scheme database for those who don't want it included.

That said, including the joypad scheme database within the engine by default could also be beneficial for everyone in the gamedev community -- it gets more eyes on this functionality and as a community we could slowly build a better joypad scheme database. It would also be nice to have a centralized FOSS joypad scheme database every other engine could use. I don't know if there's any specific database used by many engines currently, but regardless in mdqinc/SDL_GameControllerDB#692 (comment) offalynne, the maintainer of community_gamepad_type.txt linked above, also expressed interest in breaking out that database into its own project which would be a nice to have.

@fire fire changed the title Readd and improve methods to get the name of gamepad inputs Re-add and improve methods to get the name of gamepad inputs May 4, 2024
@Riteo
Copy link
Contributor

Riteo commented May 4, 2024

@Rubonnek

it gets more eyes on this functionality and as a community we could slowly build a better joypad scheme database. It would also be nice to have a centralized FOSS joypad scheme database every other engine could use.

IMO it gets even better in the long term. In *nix land, there is work for a Wayland protocol allowing the window manager itself to translate, tunnel and report the type of controller data being sent directly into a window (i.e. no manual device reading): https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/244

In other words, in the long term, for certain platforms, game engines won't even have to worry about this whole mess in the first place, as controllers will become a regular input device.

@Sauermann Sauermann modified the milestones: 4.3, 4.4 Jul 24, 2024
@offalynne
Copy link

offalynne commented Aug 23, 2024

In my opinion, Godot should implement SDL for (at least) gamepad support to greatly simplify this effort as per godotengine/godot-proposals#9000

@Rubonnek I broadly support the suggestions you put forward, the data linked is Zlib and MIT licensed respectively, anyone so-inclined may repurpose it as proposed. In practice I don't love the idea of mine and many-contributors work being taken up wholesale for this feature, given Godot has been passing the burden of support to the SDL community project for years without actually implementing SDL (which would encourage compatible contributions instead of further driving user inquiry about Godot's incompatibilities upstream)

@h0lley
Copy link

h0lley commented Aug 29, 2024

user perspective here, can't agree with Mickeon's concerns.

something that matches schemes "roughly" (e.g. generic xbox/nintendo/sony) would already be a great help as it would cover the vast majority of cases and should not be something each game has to implement itself.

it's also fine for those functions to return English strings and that does not mean that they cannot be localized.

I remember having used get_joy_button_string() with Godot 3. I understand that it wasn't very flexible in terms of supporting various schemes but it was better than nothing. I was surprised and disappointed when it was removed due to it fulfilling such a common need (nowadays any game that is to be market competitive should display device-responsive button mapping). I understand that it can be non-trivial to reliably get the correct button labeling of the currently used gamepad, but that's precisely why I'd expect it to be on the engine-side.

as for reducing this to get_joy_scheme() only, in my current project I'd much prefer to show the button labels as text rather than as images as that allows for more flexibility in consistent styling (not having to re-do all assets when the style changes).

GDScript version of get_joy_scheme() for others users needing this earlier:

enum GamepadScheme {UNKNOWN, NINTENDO, PLAYSTATION, XBOX}

func get_gamepad_scheme(device := 0) -> GamepadScheme:
	var gamepad_name := Input.get_joy_name(device)

	var scheme_identifiers := {
		GamepadScheme.NINTENDO: ["nintendo", "joy-con", "gamecube"],
		GamepadScheme.PLAYSTATION: ["sony", "playstation", "dualshock",
			"ps1", "ps2", "ps3", "ps4", "ps5"],
		GamepadScheme.XBOX: ["xbox", "microsoft"]}
	
	for scheme: GamepadScheme in scheme_identifiers:
		for scheme_term: String in scheme_identifiers[scheme]:
			if gamepad_name.containsn(scheme_term):
				return scheme

	return GamepadScheme.UNKNOWN

also this little thing for the four action buttons only:

func get_gamepad_action_label(button_index: int, scheme: GamepadScheme) -> String:
	return {
		GamepadScheme.NINTENDO: ["B", "A", "Y", "X"],
		GamepadScheme.PLAYSTATION: ["×", "○", "□", "△"],
		GamepadScheme.XBOX: ["A", "B", "X", "Y"]
		}[scheme][button_index]

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

Successfully merging this pull request may close these issues.

Bring back get_joy_axis/button_string() methods to Input
10 participants