add more RGBLED descriptions, fix some RGB defaults

This commit is contained in:
true 2024-11-01 15:05:18 -07:00
parent 33c8a25da7
commit 280f452f9a
5 changed files with 325 additions and 256 deletions

View File

@ -33,65 +33,6 @@ const uint8_t rgb_map[RGBLED_COUNT] = {
static uint8_t timeout;
void rgb_solid(uint8_t *a, uint16_t tick)
{
// 1=bitfield, 2=timeout-set, 4=state, 5=hue, 6=sat, 7=val
// bitfield:
// 7: blank / off
// 3: override altcolor (if bit 1 is not set)
// 1: override hsv
// 0: flash
int i;
color_hsv hsv = {0, 0, 0};
// timeout
if (!timeout || (timeout > a[2])) {
timeout = a[2];
} else {
timeout--;
return;
}
if (a[1] & 0x80) {
// override off
hsv.v = 0;
} else {
// color select
if (a[1] & 0x02) {
hsv.h = a[5] * 6;
hsv.s = a[6];
hsv.v = a[7];
} else if (a[1] & 0x08) {
hsv.h = uconf.altcolor_hue * 6;
hsv.s = uconf.altcolor_sat;
hsv.v = uconf.altcolor_val;
} else {
hsv.h = uconf.favcolor_hue * 6;
hsv.s = uconf.favcolor_sat;
hsv.v = uconf.favcolor_val;
}
// flash
if (a[1] & 0x01) {
a[4] ^= 0x01;
if (a[4] & 0x01) hsv.v = 0;
}
}
// update
hsv_out[0].h = hsv.h;
hsv_out[0].s = hsv.s;
hsv_out[0].v = hsv.v;
for (i = 1; i < RGBLED_COUNT; i++) {
hsv_out[i].h = hsv_out[0].h;
hsv_out[i].s = hsv_out[0].s;
hsv_out[i].v = hsv_out[0].v;
}
}
// todo: improve fading smoothness by doing fadeout every callback instead of on timeout
// this can be done once LED bit depth is increased
void rgb_flicker(uint8_t *a, uint16_t tick)
@ -439,192 +380,6 @@ void rgb_waving(uint8_t *a, uint16_t tick)
}
}
void rgb_copmode(uint8_t *a, uint16_t tick)
{
// 0=work, 1=bitfield, 2=timeout-set, 3=timeout-work, 4=work, 56=steps, 7=val
// bitfield:
// 7 sync to tick 0
// 6 skip pattern 2
// 5 skip pattern 1
// 4 don't override sat/val to maximums (not implemented)
// 3 use different colors on either half during pattern 2
// 2 use different colors on either half during pattern 1
// 1 repeat subpattern 1
// 0 use cop colors instead of pri/alt
// others:
// a[5][7:4] amount of time to delay in pattern 2
// a[5][0:3] amount of times to repeat pattern 2 (solid color alternate)
// a[6][7:4] amount of strobe pulses in pattern 1
// a[6][0:3] amount of times to repeat pattern 1 (strobes)
int i;
uint8_t pattern, iter;
uint8_t *seq;
uint8_t w, x;
uint8_t b;
uint8_t cnt[4];
color_hsv hsv;
color_hsv hsv2;
color_hsv pri, sec;
// synchronize
if (a[1] & 0x80) {
if (!tick) {
a[3] = 0;
a[1] &= ~0x80;
} else {
return;
}
}
// timeout
if (!timeout || (timeout > a[2])) {
timeout = a[2];
} else {
timeout--;
return;
}
// colors to use
if (a[1] & 0x01) {
pri.h = 0x000;
pri.s = 0xff;
sec.h = 0x400;
sec.s = 0xff;
} else {
pri.h = uconf.favcolor_hue * 6;
pri.s = uconf.favcolor_sat;
sec.h = uconf.altcolor_hue * 6;
sec.s = uconf.altcolor_sat;
}
// pattern mode
pattern = a[0] >> 6;
iter = a[0] & 0x3f;
seq = &a[4];
cnt[0] = a[6] & 0xf;
cnt[1] = a[6] >> 4;
cnt[2] = a[5] & 0xf;
cnt[3] = a[5] >> 4;
if ((pattern == 0) && (a[1] & 0x20)) pattern++;
if ((pattern == 1) && (a[1] & 0x40)) pattern++;
if (pattern > 1) pattern = 0;
switch (pattern) {
// strobe
case 0: {
w = cnt[1] << 1;
if (!w) w = 32;
b = (a[1] & 0x02) ? 0x02 : 0x01;
x = cnt[0];
if (!x) x = 16;
x <<= b;
// set main color
hsv.h = (iter & b) ? sec.h : pri.h;
hsv.s = (iter & b) ? sec.s : pri.s;
hsv.v = 0;
// p1 alternate color mode
if (a[1] & 0x04) {
hsv2.h = (iter & b) ? pri.h : sec.h;
hsv2.s = (iter & b) ? pri.s : sec.s;
} else {
hsv2.h = hsv.h;
hsv2.s = hsv.s;
}
// set value if on
if ((*seq < w) && !(*seq & 1)) {
hsv.v = a[7];
}
if (*seq > w) {
// iteration done
iter++;
*seq = 0;
if (iter >= x) {
// pattern done
pattern++;
iter = 0;
}
break;
}
(*seq)++;
break;
}
// solid alternate
case 1: {
w = cnt[3] << 1;
if (!w) w = 32;
x = cnt[2] << 1;
if (!x) x = 32;
// set main color
hsv.h = (iter & 1) ? sec.h : pri.h;
hsv.s = (iter & 1) ? sec.s : pri.s;
hsv.v = 0;
// p2 alternate color mode
if (a[1] & 0x08) {
hsv2.h = (iter & 1) ? pri.h : sec.h;
hsv2.s = (iter & 1) ? pri.s : sec.s;
} else {
hsv2.h = hsv.h;
hsv2.s = hsv.s;
}
// set value
hsv.v = a[7];
if (*seq > w) {
// iteration done
iter++;
*seq = 0;
if (iter >= x) {
// pattern done
pattern++;
iter = 0;
}
break;
}
(*seq)++;
break;
}
}
// we only have two patterns
pattern %= 2;
// save state
a[0] = (pattern << 6) | (iter & 0x3f);
// apply to LEDs
w = RGBLED_COUNT/2;
for (i = 0; i < w; i++) {
hsv_out[rgb_map[i]].h = hsv.h;
hsv_out[rgb_map[i]].s = hsv.s;
hsv_out[rgb_map[i]].v = hsv.v;
hsv_out[rgb_map[i+w]].h = hsv2.h;
hsv_out[rgb_map[i+w]].s = hsv2.s;
hsv_out[rgb_map[i+w]].v = hsv.v;
}
}
void rgb_fade_from_center(uint8_t *a, uint16_t tick)
{
@ -640,16 +395,22 @@ void rgb_gravitycheck(uint8_t *a, uint16_t tick)
}
void rgb_solid(uint8_t *a, uint16_t tick);
const uint8_t * rgb_solid_desc(uint8_t idx);
void rgb_rainbow(uint8_t *a, uint16_t tick);
const uint8_t * rgb_rainbow_desc(uint8_t idx);
void rgb_copmode(uint8_t *a, uint16_t tick);
const uint8_t * rgb_copmode_desc(uint8_t idx);
// implemented program table
const LedProgram rgb_pgm[6] = {
{"Solid Color", rgb_solid, 0},
{"Solid Color", rgb_solid, rgb_solid_desc},
{"Flicker", rgb_flicker, 0},
{"Circles", rgb_circles, 0},
{"Waving", rgb_waving, 0},
{"Rainbow", rgb_rainbow, rgb_rainbow_desc},
{"Cop Mode", rgb_copmode, 0},
{"Cop Mode", rgb_copmode, rgb_copmode_desc},
};

View File

@ -0,0 +1,91 @@
/*
* rgbprog_basic.c
* Created Nov 1, 2024
*/
#include <stdint.h>
#include "rgbled.h"
#include "user_config.h"
static uint8_t timeout;
const uint8_t * rgb_solid_desc(uint8_t idx)
{
switch (idx) {
case 0:
case 1: return RGB_STR_UNUSED;
case 2: return ">7 = blank";
case 3: return "Bitfield";
case 4:
case 5: return RGB_STR_DELAY;
case 10:
case 11: return "Override Hue";
case 12:
case 13: return "Override Sat";
case 14:
case 15: return "Override Val";
default:
return RGB_STR_RESERVED;
}
}
void rgb_solid(uint8_t *a, uint16_t tick)
{
// 1=bitfield, 2=timeout-set, 4=state, 5=hue, 6=sat, 7=val
// bitfield:
// 7: blank / off
// 3: override altcolor (if bit 1 is not set)
// 1: override hsv
// 0: flash
int i;
color_hsv hsv = {0, 0, 0};
// timeout
if (!timeout || (timeout > a[2])) {
timeout = a[2];
} else {
timeout--;
return;
}
if (a[1] & 0x80) {
// override off
hsv.v = 0;
} else {
// color select
if (a[1] & 0x02) {
hsv.h = a[5] * 6;
hsv.s = a[6];
hsv.v = a[7];
} else if (a[1] & 0x08) {
hsv.h = uconf.altcolor_hue * 6;
hsv.s = uconf.altcolor_sat;
hsv.v = uconf.altcolor_val;
} else {
hsv.h = uconf.favcolor_hue * 6;
hsv.s = uconf.favcolor_sat;
hsv.v = uconf.favcolor_val;
}
// flash
if (a[1] & 0x01) {
a[4] ^= 0x01;
if (a[4] & 0x01) hsv.v = 0;
}
}
// update
hsv_out[0].h = hsv.h;
hsv_out[0].s = hsv.s;
hsv_out[0].v = hsv.v;
for (i = 1; i < RGBLED_COUNT; i++) {
hsv_out[i].h = hsv_out[0].h;
hsv_out[i].s = hsv_out[0].s;
hsv_out[i].v = hsv_out[0].v;
}
}

View File

@ -0,0 +1,218 @@
/*
* rgbprog_copmode.c
* Created Nov 1, 2024
*/
#include <stdint.h>
#include "rgbled.h"
#include "user_config.h"
static uint8_t timeout;
const uint8_t * rgb_copmode_desc(uint8_t idx)
{
switch (idx) {
case 2: return "Bitfield Hi";
case 3: return "Bitfield Lo";
case 4:
case 5: return RGB_STR_DELAY;
case 10: return "Pat2 Delay";
case 11: return "Pat2 Cycles";
case 12: return "Pat1 Delay";
case 13: return "Pat1 Cycles";
case 14:
case 15: return RGB_STR_BRIGHTNESS;
default:
return RGB_STR_RESERVED;
}
}
void rgb_copmode(uint8_t *a, uint16_t tick)
{
// 0=work, 1=bitfield, 2=timeout-set, 3=timeout-work, 4=work, 56=steps, 7=val
// bitfield:
// 7 sync to tick 0
// 6 skip pattern 2
// 5 skip pattern 1
// 4 don't override sat/val to maximums (not implemented)
// 3 use different colors on either half during pattern 2
// 2 use different colors on either half during pattern 1
// 1 repeat subpattern 1
// 0 use cop colors instead of pri/alt
// others:
// a[5][7:4] amount of time to delay in pattern 2
// a[5][0:3] amount of times to repeat pattern 2 (solid color alternate)
// a[6][7:4] amount of strobe pulses in pattern 1
// a[6][0:3] amount of times to repeat pattern 1 (strobes)
int i;
uint8_t pattern, iter;
uint8_t *seq;
uint8_t w, x;
uint8_t b;
uint8_t cnt[4];
color_hsv hsv;
color_hsv hsv2;
color_hsv pri, sec;
// synchronize
if (a[1] & 0x80) {
if (!tick) {
a[3] = 0;
a[1] &= ~0x80;
} else {
return;
}
}
// timeout
if (!timeout || (timeout > a[2])) {
timeout = a[2];
} else {
timeout--;
return;
}
// colors to use
if (a[1] & 0x01) {
pri.h = 0x000;
pri.s = 0xff;
sec.h = 0x400;
sec.s = 0xff;
} else {
pri.h = uconf.favcolor_hue * 6;
pri.s = uconf.favcolor_sat;
sec.h = uconf.altcolor_hue * 6;
sec.s = uconf.altcolor_sat;
}
// pattern mode
pattern = a[0] >> 6;
iter = a[0] & 0x3f;
seq = &a[4];
cnt[0] = a[6] & 0xf;
cnt[1] = a[6] >> 4;
cnt[2] = a[5] & 0xf;
cnt[3] = a[5] >> 4;
if ((pattern == 0) && (a[1] & 0x20)) pattern++;
if ((pattern == 1) && (a[1] & 0x40)) pattern++;
if (pattern > 1) pattern = 0;
switch (pattern) {
// strobe
case 0: {
w = cnt[1] << 1;
if (!w) w = 32;
b = (a[1] & 0x02) ? 0x02 : 0x01;
x = cnt[0];
if (!x) x = 16;
x <<= b;
// set main color
hsv.h = (iter & b) ? sec.h : pri.h;
hsv.s = (iter & b) ? sec.s : pri.s;
hsv.v = 0;
// p1 alternate color mode
if (a[1] & 0x04) {
hsv2.h = (iter & b) ? pri.h : sec.h;
hsv2.s = (iter & b) ? pri.s : sec.s;
} else {
hsv2.h = hsv.h;
hsv2.s = hsv.s;
}
// set value if on
if ((*seq < w) && !(*seq & 1)) {
hsv.v = a[7];
}
if (*seq > w) {
// iteration done
iter++;
*seq = 0;
if (iter >= x) {
// pattern done
pattern++;
iter = 0;
}
break;
}
(*seq)++;
break;
}
// solid alternate
case 1: {
w = cnt[3] << 1;
if (!w) w = 32;
x = cnt[2] << 1;
if (!x) x = 32;
// set main color
hsv.h = (iter & 1) ? sec.h : pri.h;
hsv.s = (iter & 1) ? sec.s : pri.s;
hsv.v = 0;
// p2 alternate color mode
if (a[1] & 0x08) {
hsv2.h = (iter & 1) ? pri.h : sec.h;
hsv2.s = (iter & 1) ? pri.s : sec.s;
} else {
hsv2.h = hsv.h;
hsv2.s = hsv.s;
}
// set value
hsv.v = a[7];
if (*seq > w) {
// iteration done
iter++;
*seq = 0;
if (iter >= x) {
// pattern done
pattern++;
iter = 0;
}
break;
}
(*seq)++;
break;
}
}
// we only have two patterns
pattern %= 2;
// save state
a[0] = (pattern << 6) | (iter & 0x3f);
// apply to LEDs
w = RGBLED_COUNT/2;
for (i = 0; i < w; i++) {
hsv_out[rgb_map[i]].h = hsv.h;
hsv_out[rgb_map[i]].s = hsv.s;
hsv_out[rgb_map[i]].v = hsv.v;
hsv_out[rgb_map[i+w]].h = hsv2.h;
hsv_out[rgb_map[i+w]].s = hsv2.s;
hsv_out[rgb_map[i+w]].v = hsv.v;
}
}

View File

@ -249,7 +249,7 @@ void menu_2_disp(uint8_t idx)
// which item selected?
switch (idx) {
case LI_PROGRAM_SELECT: {
ssd1306fb_draw_str(font_table[0].font, "RGB Program", 1);
ssd1306fb_draw_str(font_table[0].font, "Edge LED Program", 1);
ssd1306fb_set_cursor(16, 15);
ssd1306fb_draw_str(font_table[0].font, rgb_pgm[uconf.ledprog_rgb_idx].name, 1);
@ -263,7 +263,7 @@ void menu_2_disp(uint8_t idx)
s = uconf.ledprog_rgb_data[uconf.ledprog_rgb_idx];
if (edit_mode == MENU_BTNSTYLE_MENU) {
ssd1306fb_draw_str(font_table[0].font, "RGB Settings", 1);
ssd1306fb_draw_str(font_table[0].font, "Program Settings", 1);
} else {
if (rgb_pgm[uconf.ledprog_rgb_idx].edit_disp) {
topline = (uint8_t *)rgb_pgm[uconf.ledprog_rgb_idx].edit_disp(prog_data_idx);

View File

@ -21,18 +21,17 @@ uint8_t sysflags;
uint16_t uconf_flash_offset;
static const uint8_t uconf_edge_defaults[8][8] = {
{0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0},
{0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0},
{0x15, 0x42, 0x50, 0x00, 0xa0, 0x30, 0xff, 0x20},
{0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0},
{0x03, 0x11, 0x05, 0x00, 0x00, 0x00, 0xff, 0x80},
{0x00, 0x01, 0x04, 0x00, 0x00, 0x66, 0x46, 0x80},
{0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0}, // solid color
{0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0}, // flicker
{0x15, 0x42, 0x50, 0x00, 0xa0, 0x30, 0xff, 0x20}, // circles
{0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0}, // waving
{0x03, 0x11, 0x05, 0x00, 0x00, 0x00, 0xff, 0x80}, // rainbow
{0x00, 0x01, 0x01, 0x00, 0x00, 0x66, 0x46, 0x80}, // cop mode
{0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0},
{0x03, 0x10, 0x04, 0x00, 0x00, 0x00, 0xff, 0xa0}
};
void uconf_defaults()
{
int i;