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

Supporting Joystick Colors (Joycons + Pro Controller) #12167

Open
folkerthoogenraad opened this issue Feb 3, 2025 · 7 comments
Open

Supporting Joystick Colors (Joycons + Pro Controller) #12167

folkerthoogenraad opened this issue Feb 3, 2025 · 7 comments

Comments

@folkerthoogenraad
Copy link

folkerthoogenraad commented Feb 3, 2025

Hi, whilst working on my game (for desktop + nintendo switch) I wanted to get the controller colors from the Joycon controllers. Via the SDL-switch port it is possible, but I'd like to be able to support this on desktop too.

Via the HID API, combined with the amazing work done on reverse engineering of the joycons. It can be done by using the subcommand to read (part of) the flash memory of the joycon. Using this it was rather easy to read the colors from the indiviual joycons.

Proof of concept

In SDL_hidapi_switch.c I made a small proof of concept:

Additional defines for the memory addresses to read from the flash memory.

#define k_unSPIColorsStartOffset 0x6050
#define k_unSPIColorsEndOffset   0x605b

Additional struct in the SwitchSubcommandInputPacket_t data union.

struct
{
    SwitchSPIOpData_t opData;
    Uint8 body[3];
    Uint8 buttons[3];
    Uint8 body_left[3];
    Uint8 body_right[3];
} colorData;

And finally, reading the color data:

SwitchSPIOpData_t readColorDataParams;

readColorDataParams.unAddress = k_unSPIColorsStartOffset;
readColorDataParams.ucLength = k_unSPIColorsLength;

SwitchSubcommandInputPacket_t *readColorDataReply = NULL;

if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readColorDataParams, sizeof(readColorDataParams), &readColorDataReply)) {
    return false;
}

// Use the colors here
readColorDataReply->colorData

Support

I'd love to implement this into the SDL codebase fully, but I'm running into some issues with the design for it.

Something like would be nice:

extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickGetColor(SDL_Joystick *joystick, SDL_Color *color);

The problem I'm running into is that we need some unified way of looking at controller colors for other types of controllers too. I heard (but haven't confirmed) that PS5 controllers also support this, for example.

  • Controllers can have different colors and parts of the controller colored.
    • Pro controller can have body color, button color, a left grip and a right grip color (As far as I could see only the splatoon controller has this)
    • Joycons only have body and button colors
  • Joycons have body and button color but when two are connected they get combined into one L + R controller (i think by the joystick driver in sdl?) instead, giving us two body and button colors.

Should we implement this into SDL? If so, what should the public api look like and how do we address the multiple colors in different formats?

@JaydenMaalouf
Copy link

I believe SDL_JoystickSetLED already exists to support this functionality
However, it does not have an accompanying getter, so you cannot retrieve the current colour.
Also, the docs specifically mention PS4 DS controllers, so I am unsure if this works with other devices

@flibitijibibo
Copy link
Collaborator

I believe SDL_JoystickSetLED already exists to support this functionality However, it does not have an accompanying getter, so you cannot retrieve the current colour. Also, the docs specifically mention PS4 DS controllers, so I am unsure if this works with other devices

For reference this is the opposite of the LED interface - this would expose the color of the physical device itself (i.e. "is this the standard grey joycon or the red/blue ones").

I thought Sony did this too but it looks like they went all-in with the light bar as a unique identifier. Maybe future Steam Deck/Controller revisions can make use of this? I'd like to have this too but I don't know what other devices do here.

@folkerthoogenraad
Copy link
Author

I believe SDL_JoystickSetLED already exists to support this functionality However, it does not have an accompanying getter, so you cannot retrieve the current colour. Also, the docs specifically mention PS4 DS controllers, so I am unsure if this works with other devices

This isn't about the LED (although I think a getter there would be nice too). This is specifically about the color of the physical controller.

@slouken
Copy link
Collaborator

slouken commented Feb 3, 2025

Yeah, this kind of functionality isn't available for any other controller, so I wouldn't add a bespoke API function for it. Instead I'd probably go with something like the SendEffect() API which sends a raw HID packet to the controller, but maybe call it QueryFeature() and returns back data?

@flibitijibibo
Copy link
Collaborator

Another weird idea: could it be an optional Property within the GameController handle? That would at least make the raw color data accessible until other devices expose a similar feature.

@slouken
Copy link
Collaborator

slouken commented Feb 3, 2025

Oh, that's an interesting idea... we always query it when those controllers connect? We could store it as a 32-bit RGBA value?

@flibitijibibo
Copy link
Collaborator

That's what I'm thinking - hidapi backends can specify whatever properties they want, and any dev that's savvy enough to know of any particular device quirks can grab them if they want to, without having export a whole function to do so.

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

No branches or pull requests

4 participants