From 8b237b1a869bd3c1c09f52726ac7e8c0bfa40ab3 Mon Sep 17 00:00:00 2001 From: Ilya Babanov Date: Sat, 11 Oct 2025 15:13:37 +0300 Subject: [PATCH] added rainbow mode and updated README.md --- .gitignore | 1 + README.md | 2 ++ main.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ meson.build | 5 ++++- 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 34adb9a..f5b6bf5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ dualsensectl +build.sh \ No newline at end of file diff --git a/README.md b/README.md index feb6aa5..dac6c1d 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ Linux tool for controlling Sony PlayStation 5 DualSense controller. info Get the controller firmware info lightbar STATE Enable (on) or disable (off) lightbar lightbar RED GREEN BLUE [BRIGHTNESS] Set lightbar color and brightness (0-255) + lightbar rainbow enable Enable lightbar rainbow mode + lightbar rainbow disable Disable lightbar rainbow mode led-brightness NUMBER Set player and microphone LED dimming (0-2) player-leds NUMBER [instant] Set player LEDs (1-7) or disabled (0) microphone STATE Enable (on) or disable (off) microphone diff --git a/main.c b/main.c index 32ca743..1dff1c9 100644 --- a/main.c +++ b/main.c @@ -17,6 +17,9 @@ #include #include +#include +#include + #include #include @@ -578,6 +581,56 @@ static int command_lightbar3(struct dualsense *ds, uint8_t red, uint8_t green, u return 0; } +static int command_lightbar_rainbow_enable(struct dualsense *ds) +{ + struct dualsense_output_report rp; + uint8_t rbuf[DS_OUTPUT_REPORT_BT_SIZE]; + dualsense_init_output_report(ds, &rp, rbuf); + + pid_t pid = fork(); + + if (pid == -1) { + perror("fork failed :("); + exit(1); + } else if (pid == 0) { + FILE *fp = fopen("child.pid", "w"); + if (fp) { + fprintf(fp, "%d", getpid()); + fclose(fp); + } + struct timespec req = { + .tv_sec = 0, + .tv_nsec = 200000000, + }; + struct timespec rem; + double timer = 0; + while (true) { + rp.common->valid_flag1 = DS_OUTPUT_VALID_FLAG1_LIGHTBAR_CONTROL_ENABLE; + rp.common->lightbar_red = 128 + (uint8_t)(128 * sin(3 * timer)); + rp.common->lightbar_green = 128 + (uint8_t)(128 * cos(5 * timer)); + rp.common->lightbar_blue = 128 + (uint8_t)(128 * sin(10 * timer)); + nanosleep(&req, &rem); + dualsense_send_output_report(ds, &rp); + timer += 0.03; + } + exit(0); + } + return 0; +} + +static int command_lightbar_rainbow_disable() +{ + FILE *fp = fopen("child.pid", "r"); + if (fp) { + pid_t pid; + fscanf(fp, "%d", &pid); + kill(pid, SIGTERM); + fclose(fp); + } + + return 0; +} + static int command_led_brightness(struct dualsense *ds, uint8_t number) { if (number > 2) { @@ -1335,6 +1388,15 @@ int main(int argc, char *argv[]) } else if (argc == 5 || argc == 6) { uint8_t brightness = argc == 6 ? atoi_x(argv[5]) : 255; return command_lightbar3(&ds, atoi_x(argv[2]), atoi_x(argv[3]), atoi_x(argv[4]), brightness); + } else if (argc == 4) { + if (!strcmp(argv[3], "enable")) { + return command_lightbar_rainbow_enable(&ds); + } else if (!strcmp(argv[3], "disable")) { + return command_lightbar_rainbow_disable(); + } else { + fprintf(stderr, "Invalid arguments\n"); + return 2; + } } else { fprintf(stderr, "Invalid arguments\n"); return 2; diff --git a/meson.build b/meson.build index 4e95fd8..2cc71f0 100644 --- a/meson.build +++ b/meson.build @@ -21,9 +21,12 @@ add_project_arguments( udev = dependency('libudev') hidapi_hidraw = dependency('hidapi-hidraw') +cc = meson.get_compiler('c') +m_dep = cc.find_library('m', required : false) + executable( 'dualsensectl', ['main.c'], - dependencies: [udev, hidapi_hidraw], + dependencies: [udev, hidapi_hidraw, m_dep], install: true, )