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; } }