From fae1d59bce32bb725406cf59cdd6e50b39a93e22 Mon Sep 17 00:00:00 2001 From: acheronfail Date: Wed, 14 Aug 2024 23:56:23 +0930 Subject: [PATCH] LEDs: add felony effect This effect mimics the pattern of common emergency service vehicles. Its colors are configurable, as well as its speed via Refloat settings. In the case where the LED strip has an odd number of LEDs, the middle LED is kept as solid black to ensure the effect is symmetrical. Feature: Add the Felony LED effect. --- src/conf/datatypes.h | 3 ++- src/conf/settings.xml | 5 ++++ src/leds.c | 56 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/conf/datatypes.h b/src/conf/datatypes.h index 30b654d..14a39bf 100644 --- a/src/conf/datatypes.h +++ b/src/conf/datatypes.h @@ -84,7 +84,8 @@ typedef enum { LED_MODE_FADE, LED_MODE_PULSE, LED_MODE_STROBE, - LED_MODE_KNIGHT_RIDER + LED_MODE_KNIGHT_RIDER, + LED_MODE_FELONY, } LedMode; typedef enum { diff --git a/src/conf/settings.xml b/src/conf/settings.xml index 96c1bbf..5ea47bb 100644 --- a/src/conf/settings.xml +++ b/src/conf/settings.xml @@ -2254,6 +2254,7 @@ p, li { white-space: pre-wrap; } Pulse Strobe Knight Rider + Felony Front Brightness @@ -2415,6 +2416,7 @@ p, li { white-space: pre-wrap; } Pulse Strobe Knight Rider + Felony Rear Brightness @@ -2576,6 +2578,7 @@ p, li { white-space: pre-wrap; } Pulse Strobe Knight Rider + Felony Headlights Brightness @@ -2739,6 +2742,7 @@ p, li { white-space: pre-wrap; } Pulse Strobe Knight Rider + Felony Taillights Brightness @@ -3030,6 +3034,7 @@ p, li { white-space: pre-wrap; } Pulse Strobe Knight Rider + Felony Status Idle Brightness diff --git a/src/leds.c b/src/leds.c index 2baf786..a7dae68 100644 --- a/src/leds.c +++ b/src/leds.c @@ -169,14 +169,27 @@ static void led_set_color( leds->led_data[led] = RGBW(r, g, b, w); } -static void strip_set_color( - Leds *leds, const LedStrip *strip, uint32_t color, float brightness, float blend +static void strip_set_color_range( + Leds *leds, + const LedStrip *strip, + uint32_t color, + float brightness, + float blend, + uint8_t idx_start, + uint8_t idx_end ) { - for (uint8_t i = 0; i < strip->length; ++i) { + uint8_t end = idx_end < strip->length ? idx_end : strip->length; + for (uint8_t i = idx_start; i < end; ++i) { led_set_color(leds, strip, i, color, brightness, blend); } } +static void strip_set_color( + Leds *leds, const LedStrip *strip, uint32_t color, float brightness, float blend +) { + strip_set_color_range(leds, strip, color, brightness, blend, 0, strip->length); +} + // Returns a cosine wave oscillating from 0 to 1, starting at 0, with a period of 2s. static float cosine_progress(float time) { uint32_t rounded = lroundf(time); @@ -261,6 +274,40 @@ static void anim_knight_rider(Leds *leds, const LedStrip *strip, const LedBar *b } } +static void anim_felony(Leds *leds, const LedStrip *strip, const LedBar *bar, float time) { + static const uint32_t color_off = 0x00000000; + + static const float state_duration = 0.05f; + float state_mod = fmodf(time, 3.0f * state_duration); + + // also account for led strips with odd numbers of leds (leaving the middle one black) + uint8_t stop_idx = strip->length / 2; + uint8_t start_idx = strip->length / 2 + strip->length % 2; + if (state_mod < state_duration) { + strip_set_color_range( + leds, strip, colors[bar->color1], strip->brightness, 1.0f, 0, stop_idx + ); + strip_set_color_range(leds, strip, color_off, strip->brightness, 1.0f, stop_idx, start_idx); + strip_set_color_range( + leds, strip, color_off, strip->brightness, 1.0f, start_idx, strip->length + ); + } else if (state_mod < 2.0f * state_duration) { + strip_set_color_range(leds, strip, color_off, strip->brightness, 1.0f, 0, stop_idx); + strip_set_color_range(leds, strip, color_off, strip->brightness, 1.0f, stop_idx, start_idx); + strip_set_color_range( + leds, strip, colors[bar->color2], strip->brightness, 1.0f, start_idx, strip->length + ); + } else { + strip_set_color_range( + leds, strip, colors[bar->color2], strip->brightness, 1.0f, 0, stop_idx + ); + strip_set_color_range(leds, strip, color_off, strip->brightness, 1.0f, stop_idx, start_idx); + strip_set_color_range( + leds, strip, colors[bar->color1], strip->brightness, 1.0f, start_idx, strip->length + ); + } +} + static void led_strip_animate(Leds *leds, const LedStrip *strip, const LedBar *bar, float time) { time *= bar->speed; @@ -280,6 +327,9 @@ static void led_strip_animate(Leds *leds, const LedStrip *strip, const LedBar *b case LED_MODE_KNIGHT_RIDER: anim_knight_rider(leds, strip, bar, time); break; + case LED_MODE_FELONY: + anim_felony(leds, strip, bar, time); + break; } }