We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 5117

Summary: [Patch] Add SDL_JoystickSetLED
Product: SDL Reporter: Ethan Lee <flibitijibibo>
Component: joystickAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: enhancement    
Priority: P2 CC: meyraud705, rustym
Version: HG 2.0   
Hardware: All   
OS: All   
Attachments: SDL_JoystickSetLED
Add LED functions to WGI and RAWINPUT

Description Ethan Lee 2020-04-30 16:06:50 UTC
Created attachment 4327 [details]
SDL_JoystickSetLED

Attached is a patch to expose an API for setting the color of an LED on a joystick. The main (and admittedly, only) example is the light bar found on the PS4 and PS5 controllers.

Currently, there are only two ways to access the light bar:

- Steam Input
- `chmod`ing /sys/class/leds/ manually, then writing directly to userspace files:

https://github.com/FNA-XNA/FNA/blob/master/src/FNAPlatform/SDL2_FNAPlatform.cs#L2679

It's ugly, unreliable, either platform-specific or store-specific, and kind of pointless to do now that we're directly accessing the device via hidapi anyhow.

Some games using the above hack include Transistor, FEZ, TowerFall, Mercenary Kings, Dust: An Elysian Tail, Apotheon, and probably more that I've forgotten about over the years. Luckily they all use it behind FNA's SetLightBarEXT extension, so updating SDL and using this new function resolves the hack without actually touching the games themselves.

Just about the only thing I'm unsure about is the way we send the LED packet - it reuses the Rumble call, which feels a bit odd to me, but it looks like SDL_hidapi_rumble.c handles it pretty gracefully, so it may not be as bad as it looks.

Example program below!

--------------------------------------------------------------------------------

#include "SDL.h"

int main(int argc, char **argv)
{
	SDL_Window *window;
	SDL_Renderer *renderer;
	SDL_GameController *controller;
	SDL_Event evt;
	Uint8 r, g, b;
	int x, y;
	Uint8 run = 1;

	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER);

	SDL_CreateWindowAndRenderer(
		640,
		480,
		SDL_WINDOW_SHOWN,
		&window,
		&renderer
	);
	controller = SDL_GameControllerOpen(0);
	
	while (run)
	{
		while (SDL_PollEvent(&evt) > 0)
		{
			if (evt.type == SDL_QUIT)
			{
				run = 0;
			}
		}

		SDL_GetMouseState(&x, &y);
		r = (Uint8) ((x / 640.0f) * 255);
		b = (Uint8) ((x / 480.0f) * 255);
		g = r + b / 2;

		SDL_GameControllerSetLED(controller, r, g, b);
		SDL_SetRenderDrawColor(renderer, r, g, b, 0xFF);
		SDL_RenderClear(renderer);
		SDL_RenderPresent(renderer);
	}

	SDL_GameControllerClose(controller);
	SDL_DestroyRenderer(renderer);
	SDL_DestroyWindow(window);
	SDL_Quit();
}
Comment 1 RustyM 2020-06-16 15:26:31 UTC
I added this patch to my local build this morning and it totally rocks! This would be a fun addition to SDL.
Comment 2 Sam Lantinga 2020-11-05 17:48:36 UTC
This has been added, thanks!
Comment 3 Mathieu Eyraud 2020-11-06 14:03:53 UTC
LED functions for WGI and RAWINPUT drivers are missing.
Comment 4 Mathieu Eyraud 2020-11-06 14:04:57 UTC
Created attachment 4507 [details]
Add LED functions to WGI and RAWINPUT
Comment 5 Sam Lantinga 2020-11-07 10:49:56 UTC
Patch added, thanks!
https://hg.libsdl.org/SDL/rev/3dc79844832a