Can you send me a code on making joysticks unique for ID slots?
Can you learn to ask questions in a descriptive way so that it is clear what you are asking and what exactly you need, please? ![]()
To answer your question — joystick IDs, like all other device IDs, are unique and no code is needed to make them so. SDL internally ensures their uniqueness within the application.
If you want to have your own list of joysticks (which is nothing unusual) and, for example, access them via an index in the list, instead of the internal ID, then any container capable of storing only the internal IDs of the joysticks or your own structures representing these devices, containing additional data besides the ID itself, will suffice. It can even be a simple array.
To ensure that your list always contains a set of joysticks that matches what SDL stores internally, and in the order in which they were detected/connected, you must update the state of this list based on few SDL events:
-
SDL_EVENT_JOYSTICK_ADDED— the event provides the internal ID of the newly detected joystick. In this case, add the new device to the end of your list. -
SDL_EVENT_JOYSTICK_REMOVED— the event provides the internal ID of the joystick that has been disconnected from the system. Search your list of joysticks and when you find a device with a matching ID, remove it from your list. Deleting should not change the order of the remaining joysticks in your list. -
SDL_EVENT_JOYSTICK_UPDATE_COMPLETE— the event provides the ID of the joystick whose update has been completed. Find the device with this ID in your list and update its data if necessary.
And that’s basically it — nothing difficult.
The joystickID may be different between program runs (if one controller is detected in a different order than the first time), or when the controller is removed and plugged back in.
If you are looking for something more persistent, then try using SDL_JoystickGUID, which will be the same every time you plug a specific controller in (no matter what order or what USB port the controllers are plugged in).
Most of the numbers in the GUID pertain to the company and product name and version, but it looks like there is a small subsection in the GUID that allows for randomized values so that duplicate controllers can still be identified. I’m testing this with two gamepads that are about a year apart in purchase time, so I might be wrong about this part.
If you have two identical joysticks, then the GUID will be the same for both of them. Moreover, you can have two different joysticks and still both of them can have the same GUID. All because some manufacturers uses the same data (product ID, vendor ID etc.) for multiple, even completely different products.
I checked this topic some time ego, when developing mapping subsystem in my engine — three different Data Frog joysticks (NES, SNES and Sega clones), despite being completely different, all have identical parameters (name, the number of hats, axes, buttons, product ID, vendor ID etc.) and thus the GUID, so it is impossible to distinguish which is which at the source code level.
But I will investigate this topic again, because the tests mentioned above was done when the engine used SDL2. The current version uses SDL3, so the situation can be different (but I bet that nothing changed).
I think you are right and I just got “Lucky” that my seemingly identical remotes just got different GUID, there was probably a version update that happened between those two purchases. It was a solid year or more between.
I still think it’s a good idea to use the controller’s GUIDs in your game;
If one player changes the mapping for their XBox controller in a game, they don’t necessarily want their NES controller to take on that remapping, especially since the NES controller can’t take on changes in which actions are mapped to joysticks or missing buttons. (Nobody wants that, SDL doesn’t pose a risk like this, it’s just a setup for my next paragraph)
However, If Player Jan makes a change to one NES controller, I believe they do generally expect to have the same interaction with all other identical NES controllers they come into contact with in that game. (Which is why I imply in the previous post that I was perhaps not quite lucky about getting different GUIDs for very similar looking devices). If they do have my problem, then at least they can expect to not have to remap the same remote every time they play the game.
The reason that Player Profiles are important is that player Jan’s changes to their NES controllers should not affect player Andy’s session with that same controller the next day.
So you set up Player Profiles in which you store the GUID of controllers that the player has interacted with. If this player has not seen this GUID before, then load SDL’s defaults for the new controller, otherwise load the map from the player’s previous session data.
It does disappoint me that you might have three different styles of controllers with the same GUID, but as long as the controller layout is similar, those persistent mappings would still be beneficial.
One step further: I like the idea of a player profile that asks the player at the beginning to press gas, press break, press reverse, shift-up, shift-down, etc.
Have them calibrate their controller to their own expectations.
Like in the good old days, when programmers weren’t lazy and games didn’t try to be ”clever” for the sake of it. Back then, when you connected a controller to your PC, you had to go into the game control settings, select the controller, and then set its mapping manually, as you like. The default mapping was only for the keyboard, but even that could be changed freely.
Today, you plug in a controller and the game comes up with a default mapping for it, which is often either non-existent or nonsensical. Today, programmers are so stupid low-skilled and lazy that even manufacturers implement functions in controller firmware that should be implemented in the engine/game — an example is snapping the position of analog sticks to the main axes or buttons remapping. This is absurd…
Or even better — I connect the controller to my PC, and the game doesn’t see it at all, even though it works fine and the operating system recognizes it without any problems. An example is my $50 SEGA Saturn® Wireless Pro Controller — poor Hollow Knight: Silksong doesn’t recognize it at all, and I have to switch it to Xbox 360 compatibility mode to be able to play. Unity is garbage.
There will be no automatic mapping in my game — nothing will happen when you connect the controller (except for adding it to the list of available devices). Players will have to set up the controls themselves, just like in the good old days. I wrote a mapper based on the SDL joystick API, that allows to assign any device to any player (one or more per player), and then assign specific gameplay actions to specific triggers — complete freedom.
There is also no problem with supporting few identical controllers for different players at the same time, because the mapping is created and assigned to the player and their controller, not just to the controller.
It took me some time to write this mapper, but it was worth it because it can provide functionality and configuration freedom that most modern games lack. As long as SDL is able to provide correct joystick events, you can use any controller, even your own, built using Arduino.