Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/conf/datatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ typedef struct {
float brightness;
LedColor color1;
LedColor color2;
bool banner_mode;
LedAnimMode mode;
float speed;
} LedBar;
Expand Down
64 changes: 64 additions & 0 deletions src/conf/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2728,6 +2728,20 @@ p, li { white-space: pre-wrap; }
<cDefine>CFG_DFLT_LEDS_STATUS_ON_FRONT_WHEN_LIFTED</cDefine>
<valInt>1</valInt>
</leds.status_on_front_when_lifted>
<leds.front.banner_mode>
<longName>Enable Banner Mode</longName>
<type>5</type>
<transmittable>1</transmittable>
<description>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Roboto'; ; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;When Banner Mode is enabled, the LED strip is divided into three equal or nearly equal parts. Left and Right are the Primary color and Center is the Secondary. In Solid mode, this looks like a two-color banner. Non-rainbow animations work on top of this background.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;So whether it's game day for your favorite team or you just want to unleash your inner Gryffindor, give it a try!&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Note: Banner Mode works but not as well with LED strips that include dedicated bright white headlights.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</description>
<cDefine>CFG_DFLT_LEDS_FRONT_BANNER_MODE</cDefine>
<valInt>0</valInt>
</leds.front.banner_mode>
<leds.front.mode>
<longName>Front Mode</longName>
<type>4</type>
Expand Down Expand Up @@ -2888,6 +2902,20 @@ p, li { white-space: pre-wrap; }
<suffix></suffix>
<vTx>7</vTx>
</leds.front.speed>
<leds.rear.banner_mode>
<longName>Enable Banner Mode</longName>
<type>5</type>
<transmittable>1</transmittable>
<description>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Roboto'; ; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;When Banner Mode is enabled, the LED strip is divided into three equal or nearly equal parts. Left and Right are the Primary color and Center is the Secondary. In Solid mode, this looks like a two-color banner. Non-rainbow animations work on top of this background.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;So whether it's game day for your favorite team or you just want to unleash your inner Gryffindor, give it a try!&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Note: Banner Mode works but not as well with LED strips that include dedicated bright white headlights.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</description>
<cDefine>CFG_DFLT_LEDS_REAR_BANNER_MODE</cDefine>
<valInt>0</valInt>
</leds.rear.banner_mode>
<leds.rear.mode>
<longName>Rear Mode</longName>
<type>4</type>
Expand Down Expand Up @@ -3048,6 +3076,20 @@ p, li { white-space: pre-wrap; }
<suffix></suffix>
<vTx>7</vTx>
</leds.rear.speed>
<leds.headlights.banner_mode>
<longName>Enable Banner Mode</longName>
<type>5</type>
<transmittable>1</transmittable>
<description>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Roboto'; ; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;When Banner Mode is enabled, the LED strip is divided into three equal or nearly equal parts. Left and Right are the Primary color and Center is the Secondary. In Solid mode, this looks like a two-color banner. Non-rainbow animations work on top of this background.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;So whether it's game day for your favorite team or you just want to unleash your inner Gryffindor, give it a try!&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Note: Banner Mode works but not as well with LED strips that include dedicated bright white headlights.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</description>
<cDefine>CFG_DFLT_LEDS_HEADLIGHTS_BANNER_MODE</cDefine>
<valInt>0</valInt>
</leds.headlights.banner_mode>
<leds.headlights.mode>
<longName>Headlights Mode</longName>
<type>4</type>
Expand Down Expand Up @@ -3210,6 +3252,20 @@ p, li { white-space: pre-wrap; }
<suffix></suffix>
<vTx>7</vTx>
</leds.headlights.speed>
<leds.taillights.banner_mode>
<longName>Enable Banner Mode</longName>
<type>5</type>
<transmittable>1</transmittable>
<description>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Roboto'; ; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;When Banner Mode is enabled, the LED strip is divided into three equal or nearly equal parts. Left and Right are the Primary color and Center is the Secondary. In Solid mode, this looks like a two-color banner. Non-rainbow animations work on top of this background.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;So whether it's game day for your favorite team or you just want to unleash your inner Gryffindor, give it a try!&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Note: Banner Mode works but not as well with LED strips that include dedicated bright white headlights.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</description>
<cDefine>CFG_DFLT_LEDS_TAILLIGHTS_BANNER_MODE</cDefine>
<valInt>0</valInt>
</leds.taillights.banner_mode>
<leds.taillights.mode>
<longName>Taillights Mode</longName>
<type>4</type>
Expand Down Expand Up @@ -4139,21 +4195,25 @@ p, li { white-space: pre-wrap; }
<ser>leds.direction_transition</ser>
<ser>leds.lights_off_when_lifted</ser>
<ser>leds.status_on_front_when_lifted</ser>
<ser>leds.front.banner_mode</ser>
<ser>leds.front.mode</ser>
<ser>leds.front.brightness</ser>
<ser>leds.front.color1</ser>
<ser>leds.front.color2</ser>
<ser>leds.front.speed</ser>
<ser>leds.rear.banner_mode</ser>
<ser>leds.rear.mode</ser>
<ser>leds.rear.brightness</ser>
<ser>leds.rear.color1</ser>
<ser>leds.rear.color2</ser>
<ser>leds.rear.speed</ser>
<ser>leds.headlights.banner_mode</ser>
<ser>leds.headlights.mode</ser>
<ser>leds.headlights.brightness</ser>
<ser>leds.headlights.color1</ser>
<ser>leds.headlights.color2</ser>
<ser>leds.headlights.speed</ser>
<ser>leds.taillights.banner_mode</ser>
<ser>leds.taillights.mode</ser>
<ser>leds.taillights.brightness</ser>
<ser>leds.taillights.color1</ser>
Expand Down Expand Up @@ -4393,24 +4453,28 @@ p, li { white-space: pre-wrap; }
<param>leds.lights_off_when_lifted</param>
<param>leds.status_on_front_when_lifted</param>
<param>::sep::Front</param>
<param>leds.front.banner_mode</param>
<param>leds.front.mode</param>
<param>leds.front.brightness</param>
<param>leds.front.color1</param>
<param>leds.front.color2</param>
<param>leds.front.speed</param>
<param>::sep::Rear</param>
<param>leds.rear.banner_mode</param>
<param>leds.rear.mode</param>
<param>leds.rear.brightness</param>
<param>leds.rear.color1</param>
<param>leds.rear.color2</param>
<param>leds.rear.speed</param>
<param>::sep::Headlights</param>
<param>leds.headlights.banner_mode</param>
<param>leds.headlights.mode</param>
<param>leds.headlights.brightness</param>
<param>leds.headlights.color1</param>
<param>leds.headlights.color2</param>
<param>leds.headlights.speed</param>
<param>::sep::Taillights</param>
<param>leds.taillights.banner_mode</param>
<param>leds.taillights.mode</param>
<param>leds.taillights.brightness</param>
<param>leds.taillights.color1</param>
Expand Down
106 changes: 99 additions & 7 deletions src/leds.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,76 @@ static void strip_set_color(
strip_set_color_range(leds, strip, color, brightness, blend, 0, strip->length);
}

static uint32_t anim_color_for_led(
const LedStrip *strip, const LedBar *bar, uint8_t i, float primary_blend
) {
uint32_t primary = colors[bar->color1];
uint32_t secondary = colors[bar->color2];
if (bar->banner_mode) {
const uint8_t third = strip->length / 3;
const uint8_t side_length = third + (strip->length % 3 == 2);
const uint8_t center_start = side_length;
const uint8_t right_start = center_start + third + (strip->length % 3 == 1);
primary = colors[i < center_start || i >= right_start ? bar->color1 : bar->color2];
secondary = colors[COLOR_BLACK];
}
return color_blend(secondary, primary, primary_blend);
}

static void anim_fade(Leds *leds, const LedStrip *strip, const LedBar *bar, float time) {
float p = cosine_progress(time);
if (bar->banner_mode) {
const uint8_t third = strip->length / 3;
const uint8_t side_length = third + (strip->length % 3 == 2);
const uint8_t center_length = third + (strip->length % 3 == 1);
const uint8_t center_start = side_length;
const uint8_t right_start = center_start + center_length;

strip_set_color_range(
leds,
strip,
color_blend(colors[COLOR_BLACK], colors[bar->color1], p),
strip->brightness,
1.0f,
0,
side_length
);
strip_set_color_range(
leds,
strip,
color_blend(colors[COLOR_BLACK], colors[bar->color2], p),
strip->brightness,
1.0f,
center_start,
right_start
);
strip_set_color_range(
leds,
strip,
color_blend(colors[COLOR_BLACK], colors[bar->color1], p),
strip->brightness,
1.0f,
right_start,
strip->length
);
return;
}

uint32_t color = color_blend(colors[bar->color2], colors[bar->color1], p);
strip_set_color(leds, strip, color, strip->brightness, 1.0f);
}

static void anim_strobe(Leds *leds, const LedStrip *strip, const LedBar *bar, float time) {
uint32_t color = fmodf(time, 2.0f) >= 1.0f ? colors[bar->color2] : colors[bar->color1];
strip_set_color(leds, strip, color, strip->brightness, 1.0f);
float primary_blend = fmodf(time, 2.0f) >= 1.0f ? 0.0f : 1.0f;
if (bar->banner_mode) {
for (uint8_t i = 0; i < strip->length; ++i) {
uint32_t color = anim_color_for_led(strip, bar, i, primary_blend);
led_set_color(leds, strip, i, color, strip->brightness, 1.0f);
}
} else {
uint32_t color = anim_color_for_led(strip, bar, 0, primary_blend);
strip_set_color(leds, strip, color, strip->brightness, 1.0f);
}
}

static void anim_pulse(
Expand All @@ -250,8 +311,7 @@ static void anim_pulse(
float k1 = clampf(dist1 / feather, 0.0f, 1.0f);
float k2 = clampf(dist2 / feather, 0.0f, 1.0f);

uint32_t color =
color_blend(colors[bar->color2], colors[bar->color1], fminf(k1, k2) * fade);
uint32_t color = anim_color_for_led(strip, bar, i, fminf(k1, k2) * fade);
led_set_color(leds, strip, i, color, strip->brightness, 1.0f);
}
}
Expand Down Expand Up @@ -285,7 +345,7 @@ static void anim_knight_rider(Leds *leds, const LedStrip *strip, const LedBar *b
k2 = 1 - x2 + floorf(x2);
}

uint32_t color = color_blend(colors[bar->color2], colors[bar->color1], fmaxf(k1, k2));
uint32_t color = anim_color_for_led(strip, bar, i, fmaxf(k1, k2));
led_set_color(leds, strip, i, color, strip->brightness, 1.0f);
}
}
Expand All @@ -299,7 +359,15 @@ static void anim_felony(Leds *leds, const LedStrip *strip, const LedBar *bar, fl
// 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) {
if (bar->banner_mode) {
for (uint8_t i = 0; i < strip->length; ++i) {
bool active = state_mod < state_duration ? i < stop_idx
: state_mod < 2.0f * state_duration ? false
: i >= start_idx;
uint32_t color = active ? anim_color_for_led(strip, bar, i, 1.0f) : color_off;
led_set_color(leds, strip, i, color, strip->brightness, 1.0f);
}
} else if (state_mod < state_duration) {
strip_set_color_range(
leds, strip, colors[bar->color1], strip->brightness, 1.0f, 0, stop_idx
);
Expand Down Expand Up @@ -355,7 +423,31 @@ static void led_strip_animate(Leds *leds, const LedStrip *strip, const LedBar *b

switch (bar->mode) {
case LED_ANIM_SOLID:
strip_set_color(leds, strip, colors[bar->color1], strip->brightness, 1.0f);
if (bar->banner_mode) {
const uint8_t third = strip->length / 3;
const uint8_t side_length = third + (strip->length % 3 == 2);
const uint8_t center_length = third + (strip->length % 3 == 1);
const uint8_t center_start = side_length;
const uint8_t right_start = center_start + center_length;

strip_set_color_range(
leds, strip, colors[bar->color1], strip->brightness, 1.0f, 0, side_length
);
strip_set_color_range(
leds, strip, colors[bar->color2], strip->brightness, 1.0f, center_start, right_start
);
strip_set_color_range(
leds,
strip,
colors[bar->color1],
strip->brightness,
1.0f,
right_start,
strip->length
);
} else {
strip_set_color(leds, strip, colors[bar->color1], strip->brightness, 1.0f);
}
break;
case LED_ANIM_FADE:
anim_fade(leds, strip, bar, time);
Expand Down
Loading