diff --git a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h index 85854c320..4421f23b1 100644 --- a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h +++ b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h @@ -251,6 +251,7 @@ private: * Sort either the modes or the palettes using quicksort. */ void re_sortModes(const char **modeNames, byte *indexes, int count, int numSkip) { + if (!modeNames) return; listBeingSorted = modeNames; qsort(indexes + numSkip, count - numSkip, sizeof(byte), re_qstringCmp); listBeingSorted = nullptr; @@ -777,7 +778,7 @@ public: for (byte i=0; i 127) { + a = -127; + x -= 127; + } + + if (x < attdec) { //inc to max + return (int16_t) x * a / attdec; + } + else if (x < pulsewidth - attdec) { //max + return a; + } + else if (x < pulsewidth) { //dec to 0 + return (int16_t) (pulsewidth - x) * a / attdec; + } + return 0; +} + +// effect functions + /* * No blinking. Just plain old static light. */ uint16_t mode_static(void) { - strip.fill(SEGCOLOR(0)); + SEGMENT.fill(SEGCOLOR(0)); return (SEGMENT.getOption(SEG_OPTION_TRANSITIONAL)) ? FRAMETIME : 350; //update faster if in transition } static const char *_data_FX_MODE_STATIC PROGMEM = "Solid"; @@ -66,9 +105,9 @@ uint16_t blink(uint32_t color1, uint32_t color2, bool strobe, bool do_palette) { if (color == color1 && do_palette) { for(uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } - } else strip.fill(color); + } else SEGMENT.fill(color); return FRAMETIME; } @@ -87,7 +126,7 @@ static const char *_data_FX_MODE_BLINK PROGMEM = "Blink@!,;!,!,;!"; * Classic Blink effect. Cycling through the rainbow. */ uint16_t mode_blink_rainbow(void) { - return blink(strip.color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), false, false); + return blink(SEGMENT.color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), false, false); } static const char *_data_FX_MODE_BLINK_RAINBOW PROGMEM = "Blink Rainbow@Frequency,Blink duration;!,!,;!"; @@ -105,7 +144,7 @@ static const char *_data_FX_MODE_STROBE PROGMEM = "Strobe@!,;!,!,;!"; * Classic Strobe effect. Cycling through the rainbow. */ uint16_t mode_strobe_rainbow(void) { - return blink(strip.color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), true, false); + return blink(SEGMENT.color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), true, false); } static const char *_data_FX_MODE_STROBE_RAINBOW PROGMEM = "Strobe Rainbow@!,;,!,;!"; @@ -133,11 +172,11 @@ uint16_t color_wipe(bool rev, bool useRandomColors) { SEGENV.step = 3; } if (SEGENV.step == 1) { //if flag set, change to new random color - SEGENV.aux1 = strip.get_random_wheel_index(SEGENV.aux0); + SEGENV.aux1 = SEGMENT.get_random_wheel_index(SEGENV.aux0); SEGENV.step = 2; } if (SEGENV.step == 3) { - SEGENV.aux0 = strip.get_random_wheel_index(SEGENV.aux1); + SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux1); SEGENV.step = 0; } } @@ -148,19 +187,19 @@ uint16_t color_wipe(bool rev, bool useRandomColors) { rem /= (SEGMENT.intensity +1); if (rem > 255) rem = 255; - uint32_t col1 = useRandomColors? strip.color_wheel(SEGENV.aux1) : SEGCOLOR(1); + uint32_t col1 = useRandomColors? SEGMENT.color_wheel(SEGENV.aux1) : SEGCOLOR(1); for (uint16_t i = 0; i < SEGLEN; i++) { uint16_t index = (rev && back)? SEGLEN -1 -i : i; - uint32_t col0 = useRandomColors? strip.color_wheel(SEGENV.aux0) : strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0); + uint32_t col0 = useRandomColors? SEGMENT.color_wheel(SEGENV.aux0) : SEGMENT.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0); if (i < ledIndex) { - strip.setPixelColor(index, back? col1 : col0); + SEGMENT.setPixelColor(index, back? col1 : col0); } else { - strip.setPixelColor(index, back? col0 : col1); - if (i == ledIndex) strip.setPixelColor(index, color_blend(back? col0 : col1, back? col1 : col0, rem)); + SEGMENT.setPixelColor(index, back? col0 : col1); + if (i == ledIndex) SEGMENT.setPixelColor(index, color_blend(back? col0 : col1, back? col1 : col0, rem)); } } return FRAMETIME; @@ -227,11 +266,11 @@ uint16_t mode_random_color(void) { if (it != SEGENV.step) //new color { SEGENV.aux1 = SEGENV.aux0; - SEGENV.aux0 = strip.get_random_wheel_index(SEGENV.aux0); //aux0 will store our random color wheel index + SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux0); //aux0 will store our random color wheel index SEGENV.step = it; } - strip.fill(color_blend(strip.color_wheel(SEGENV.aux1), strip.color_wheel(SEGENV.aux0), fade)); + SEGMENT.fill(color_blend(SEGMENT.color_wheel(SEGENV.aux1), SEGMENT.color_wheel(SEGENV.aux0), fade)); return FRAMETIME; } static const char *_data_FX_MODE_RANDOM_COLOR PROGMEM = "Random Colors@!,Fade time;1,2,3;!"; @@ -260,11 +299,11 @@ uint16_t dynamic(boolean smooth=false) { if (smooth) { for (uint16_t i = 0; i < SEGLEN; i++) { - strip.blendPixelColor(i, strip.color_wheel(SEGENV.data[i]),16); + SEGMENT.blendPixelColor(i, SEGMENT.color_wheel(SEGENV.data[i]),16); } } else { for (uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, strip.color_wheel(SEGENV.data[i])); + SEGMENT.setPixelColor(i, SEGMENT.color_wheel(SEGENV.data[i])); } } return FRAMETIME; @@ -303,7 +342,7 @@ uint16_t mode_breath(void) { uint8_t lum = 30 + var; for(uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, color_blend(SEGCOLOR(1), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); + SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); } return FRAMETIME; @@ -316,10 +355,10 @@ static const char *_data_FX_MODE_BREATH PROGMEM = "Breathe@!,;!,!;!"; */ uint16_t mode_fade(void) { uint16_t counter = (strip.now * ((SEGMENT.speed >> 3) +10)); - uint8_t lum = strip.triwave16(counter) >> 8; + uint8_t lum = triwave16(counter) >> 8; for(uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, color_blend(SEGCOLOR(1), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); + SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); } return FRAMETIME; @@ -338,7 +377,7 @@ uint16_t scan(bool dual) uint16_t size = 1 + ((SEGMENT.intensity * SEGLEN) >> 9); uint16_t ledIndex = (prog * ((SEGLEN *2) - size *2)) >> 16; - strip.fill(SEGCOLOR(1)); + SEGMENT.fill(SEGCOLOR(1)); int led_offset = ledIndex - (SEGLEN - size); led_offset = abs(led_offset); @@ -346,12 +385,12 @@ uint16_t scan(bool dual) if (dual) { for (uint16_t j = led_offset; j < led_offset + size; j++) { uint16_t i2 = SEGLEN -1 -j; - strip.setPixelColor(i2, strip.color_from_palette(i2, true, PALETTE_SOLID_WRAP, (SEGCOLOR(2))? 2:0)); + SEGMENT.setPixelColor(i2, SEGMENT.color_from_palette(i2, true, PALETTE_SOLID_WRAP, (SEGCOLOR(2))? 2:0)); } } for (uint16_t j = led_offset; j < led_offset + size; j++) { - strip.setPixelColor(j, strip.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(j, SEGMENT.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); } return FRAMETIME; @@ -384,9 +423,9 @@ uint16_t mode_rainbow(void) { counter = counter >> 8; if (SEGMENT.intensity < 128){ - strip.fill(color_blend(strip.color_wheel(counter),WHITE,128-SEGMENT.intensity)); + SEGMENT.fill(color_blend(SEGMENT.color_wheel(counter),WHITE,128-SEGMENT.intensity)); } else { - strip.fill(strip.color_wheel(counter)); + SEGMENT.fill(SEGMENT.color_wheel(counter)); } return FRAMETIME; @@ -404,7 +443,7 @@ uint16_t mode_rainbow_cycle(void) { for(uint16_t i = 0; i < SEGLEN; i++) { //intensity/29 = 0 (1/16) 1 (1/8) 2 (1/4) 3 (1/2) 4 (1) 5 (2) 6 (4) 7 (8) 8 (16) uint8_t index = (i * (16 << (SEGMENT.intensity /29)) / SEGLEN) + counter; - strip.setPixelColor(i, strip.color_wheel(index)); + SEGMENT.setPixelColor(i, SEGMENT.color_wheel(index)); } return FRAMETIME; @@ -423,14 +462,14 @@ uint16_t running(uint32_t color1, uint32_t color2, bool theatre = false) { for(uint16_t i = 0; i < SEGLEN; i++) { uint32_t col = color2; - if (usePalette) color1 = strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0); + if (usePalette) color1 = SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0); if (theatre) { if ((i % width) == SEGENV.aux0) col = color1; } else { int8_t pos = (i % (width<<1)); if ((pos < SEGENV.aux0-width) || ((pos >= SEGENV.aux0) && (pos < SEGENV.aux0+width))) col = color1; } - strip.setPixelColor(i,col); + SEGMENT.setPixelColor(i,col); } if (it != SEGENV.step) { @@ -456,7 +495,7 @@ static const char *_data_FX_MODE_THEATER_CHASE PROGMEM = "Theater@!,Gap size;!,! * Inspired by the Adafruit examples. */ uint16_t mode_theater_chase_rainbow(void) { - return running(strip.color_wheel(SEGENV.step), SEGCOLOR(1), true); + return running(SEGMENT.color_wheel(SEGENV.step), SEGCOLOR(1), true); } static const char *_data_FX_MODE_THEATER_CHASE_RAINBOW PROGMEM = "Theater Rainbow@!,Gap size;1,2,3;!"; @@ -480,15 +519,15 @@ uint16_t running_base(bool saw, bool dual=false) { } a = 255 - a; } - uint8_t s = dual ? strip.sin_gap(a) : sin8(a); - uint32_t ca = color_blend(SEGCOLOR(1), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s); + uint8_t s = dual ? sin_gap(a) : sin8(a); + uint32_t ca = color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s); if (dual) { uint16_t b = (SEGLEN-1-i)*x_scale - counter; - uint8_t t = strip.sin_gap(b); - uint32_t cb = color_blend(SEGCOLOR(1), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), t); + uint8_t t = sin_gap(b); + uint32_t cb = color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), t); ca = color_blend(ca, cb, 127); } - strip.setPixelColor(i, ca); + SEGMENT.setPixelColor(i, ca); } return FRAMETIME; } @@ -530,7 +569,7 @@ uint16_t mode_twinkle(void) { const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); const uint16_t rows = SEGMENT.virtualHeight(); - strip.fill(SEGCOLOR(1)); + SEGMENT.fill(SEGCOLOR(1)); uint32_t cycleTime = 20 + (255 - SEGMENT.speed)*5; uint32_t it = strip.now / cycleTime; @@ -554,9 +593,9 @@ uint16_t mode_twinkle(void) { uint32_t p = ((uint32_t)cols*rows * (uint32_t)PRNG16) >> 16; uint16_t j = p % cols; uint16_t k = p / cols; - uint32_t col = strip.color_from_palette(map(p, 0, cols*rows, 0, 255), false, PALETTE_SOLID_WRAP, 0); - if (strip.isMatrix) strip.setPixelColorXY(j, k, col); - else strip.setPixelColor(j, col); + uint32_t col = SEGMENT.color_from_palette(map(p, 0, cols*rows, 0, 255), false, PALETTE_SOLID_WRAP, 0); + if (strip.isMatrix) SEGMENT.setPixelColorXY(j, k, col); + else SEGMENT.setPixelColor(j, col); } return FRAMETIME; @@ -577,15 +616,15 @@ uint16_t dissolve(uint32_t color) { { uint16_t i = random16(SEGLEN); if (SEGENV.aux0) { //dissolve to primary/palette - if (strip.getPixelColor(i) == SEGCOLOR(1) || wa) { + if (SEGMENT.getPixelColor(i) == SEGCOLOR(1) || wa) { if (color == SEGCOLOR(0)) { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); - } else { strip.setPixelColor(i, color); } + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + } else { SEGMENT.setPixelColor(i, color); } break; //only spawn 1 new pixel per frame per 50 LEDs } } else { //dissolve to secondary - if (strip.getPixelColor(i) != SEGCOLOR(1)) { strip.setPixelColor(i, SEGCOLOR(1)); break; } + if (SEGMENT.getPixelColor(i) != SEGCOLOR(1)) { SEGMENT.setPixelColor(i, SEGCOLOR(1)); break; } } } } @@ -614,7 +653,7 @@ static const char *_data_FX_MODE_DISSOLVE PROGMEM = "Dissolve@Repeat speed,Disso * Blink several LEDs on and then off in random colors */ uint16_t mode_dissolve_random(void) { - return dissolve(strip.color_wheel(random8())); + return dissolve(SEGMENT.color_wheel(random8())); } static const char *_data_FX_MODE_DISSOLVE_RANDOM PROGMEM = "Dissolve Rnd@Repeat speed,Dissolve speed;,!,;!"; @@ -625,7 +664,7 @@ static const char *_data_FX_MODE_DISSOLVE_RANDOM PROGMEM = "Dissolve Rnd@Repeat */ uint16_t mode_sparkle(void) { for(uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } uint32_t cycleTime = 10 + (255 - SEGMENT.speed)*2; uint32_t it = strip.now / cycleTime; @@ -636,8 +675,8 @@ uint16_t mode_sparkle(void) { SEGENV.step = it; } - if (strip.isMatrix) strip.setPixelColorXY(SEGENV.aux0, SEGENV.aux1, SEGCOLOR(0)); - else strip.setPixelColor(SEGENV.aux0, SEGCOLOR(0)); + if (strip.isMatrix) SEGMENT.setPixelColorXY(SEGENV.aux0, SEGENV.aux1, SEGCOLOR(0)); + else SEGMENT.setPixelColor(SEGENV.aux0, SEGCOLOR(0)); return FRAMETIME; } static const char *_data_FX_MODE_SPARKLE PROGMEM = "Sparkle@!,;!,!,;!"; @@ -649,13 +688,13 @@ static const char *_data_FX_MODE_SPARKLE PROGMEM = "Sparkle@!,;!,!,;!"; */ uint16_t mode_flash_sparkle(void) { for(uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } if (strip.now - SEGENV.aux0 > SEGENV.step) { if(random8((255-SEGMENT.intensity) >> 4) == 0) { - if (strip.isMatrix) strip.setPixelColorXY(random16(SEGLEN), random16(0,SEGMENT.virtualHeight()-1), SEGCOLOR(1)); - else strip.setPixelColor(random16(SEGLEN), SEGCOLOR(1)); //flash + if (strip.isMatrix) SEGMENT.setPixelColorXY(random16(SEGLEN), random16(0,SEGMENT.virtualHeight()-1), SEGCOLOR(1)); + else SEGMENT.setPixelColor(random16(SEGLEN), SEGCOLOR(1)); //flash } SEGENV.step = strip.now; SEGENV.aux0 = 255-SEGMENT.speed; @@ -671,14 +710,14 @@ static const char *_data_FX_MODE_FLASH_SPARKLE PROGMEM = "Sparkle Dark@!,!;Bg,Fx */ uint16_t mode_hyper_sparkle(void) { for(uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } if (strip.now - SEGENV.aux0 > SEGENV.step) { if(random8((255-SEGMENT.intensity) >> 4) == 0) { for(uint16_t i = 0; i < MAX(1, SEGLEN/3); i++) { - if (strip.isMatrix) strip.setPixelColorXY(random16(SEGLEN), random16(0,SEGMENT.virtualHeight()), SEGCOLOR(1)); - else strip.setPixelColor(random16(SEGLEN), SEGCOLOR(1)); + if (strip.isMatrix) SEGMENT.setPixelColorXY(random16(SEGLEN), random16(0,SEGMENT.virtualHeight()), SEGCOLOR(1)); + else SEGMENT.setPixelColor(random16(SEGLEN), SEGCOLOR(1)); } } SEGENV.step = strip.now; @@ -694,14 +733,14 @@ static const char *_data_FX_MODE_HYPER_SPARKLE PROGMEM = "Sparkle+@!,!;Bg,Fx,;!" */ uint16_t mode_multi_strobe(void) { for(uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } SEGENV.aux0 = 50 + 20*(uint16_t)(255-SEGMENT.speed); uint16_t count = 2 * ((SEGMENT.intensity / 10) + 1); if(SEGENV.aux1 < count) { if((SEGENV.aux1 & 1) == 0) { - strip.fill(SEGCOLOR(0)); + SEGMENT.fill(SEGCOLOR(0)); SEGENV.aux0 = 15; } else { SEGENV.aux0 = 50; @@ -725,7 +764,7 @@ static const char *_data_FX_MODE_MULTI_STROBE PROGMEM = "Strobe Mega@!,!;!,!,;!" uint16_t mode_android(void) { for(uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } if (SEGENV.aux1 > ((float)SEGMENT.intensity/255.0)*(float)SEGLEN) @@ -753,15 +792,15 @@ uint16_t mode_android(void) { if (a + SEGENV.aux1 < SEGLEN) { for(uint16_t i = a; i < a+SEGENV.aux1; i++) { - strip.setPixelColor(i, SEGCOLOR(0)); + SEGMENT.setPixelColor(i, SEGCOLOR(0)); } } else { for(uint16_t i = a; i < SEGLEN; i++) { - strip.setPixelColor(i, SEGCOLOR(0)); + SEGMENT.setPixelColor(i, SEGCOLOR(0)); } for(uint16_t i = 0; i < SEGENV.aux1 - (SEGLEN -a); i++) { - strip.setPixelColor(i, SEGCOLOR(0)); + SEGMENT.setPixelColor(i, SEGCOLOR(0)); } } SEGENV.step = a; @@ -785,9 +824,9 @@ uint16_t chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do_palett if (a < SEGENV.step) //we hit the start again, choose new color for Chase random { SEGENV.aux1 = SEGENV.aux0; //store previous random color - SEGENV.aux0 = strip.get_random_wheel_index(SEGENV.aux0); + SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux0); } - color1 = strip.color_wheel(SEGENV.aux0); + color1 = SEGMENT.color_wheel(SEGENV.aux0); } SEGENV.step = a; @@ -803,40 +842,40 @@ uint16_t chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do_palett if (do_palette) { for(uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } - } else strip.fill(color1); + } else SEGMENT.fill(color1); //if random, fill old background between a and end if (chase_random) { - color1 = strip.color_wheel(SEGENV.aux1); + color1 = SEGMENT.color_wheel(SEGENV.aux1); for (uint16_t i = a; i < SEGLEN; i++) - strip.setPixelColor(i, color1); + SEGMENT.setPixelColor(i, color1); } //fill between points a and b with color2 if (a < b) { for (uint16_t i = a; i < b; i++) - strip.setPixelColor(i, color2); + SEGMENT.setPixelColor(i, color2); } else { for (uint16_t i = a; i < SEGLEN; i++) //fill until end - strip.setPixelColor(i, color2); + SEGMENT.setPixelColor(i, color2); for (uint16_t i = 0; i < b; i++) //fill from start until b - strip.setPixelColor(i, color2); + SEGMENT.setPixelColor(i, color2); } //fill between points b and c with color2 if (b < c) { for (uint16_t i = b; i < c; i++) - strip.setPixelColor(i, color3); + SEGMENT.setPixelColor(i, color3); } else { for (uint16_t i = b; i < SEGLEN; i++) //fill until end - strip.setPixelColor(i, color3); + SEGMENT.setPixelColor(i, color3); for (uint16_t i = 0; i < c; i++) //fill from start until c - strip.setPixelColor(i, color3); + SEGMENT.setPixelColor(i, color3); } return FRAMETIME; @@ -868,7 +907,7 @@ uint16_t mode_chase_rainbow(void) { uint8_t color_sep = 256 / SEGLEN; if (color_sep == 0) color_sep = 1; // correction for segments longer than 256 LEDs uint8_t color_index = SEGENV.call & 0xFF; - uint32_t color = strip.color_wheel(((SEGENV.step * color_sep) + color_index) & 0xFF); + uint32_t color = SEGMENT.color_wheel(((SEGENV.step * color_sep) + color_index) & 0xFF); return chase(color, SEGCOLOR(0), SEGCOLOR(1), false); } @@ -881,8 +920,8 @@ static const char *_data_FX_MODE_CHASE_RAINBOW PROGMEM = "Chase Rainbow@!,Width; uint16_t mode_chase_rainbow_white(void) { uint16_t n = SEGENV.step; uint16_t m = (SEGENV.step + 1) % SEGLEN; - uint32_t color2 = strip.color_wheel(((n * 256 / SEGLEN) + (SEGENV.call & 0xFF)) & 0xFF); - uint32_t color3 = strip.color_wheel(((m * 256 / SEGLEN) + (SEGENV.call & 0xFF)) & 0xFF); + uint32_t color2 = SEGMENT.color_wheel(((n * 256 / SEGLEN) + (SEGENV.call & 0xFF)) & 0xFF); + uint32_t color3 = SEGMENT.color_wheel(((m * 256 / SEGLEN) + (SEGENV.call & 0xFF)) & 0xFF); return chase(SEGCOLOR(0), color2, color3, false); } @@ -903,7 +942,7 @@ uint16_t mode_colorful(void) { uint16_t fac = 80; if (SEGMENT.palette == 52) {numColors = 5; fac = 61;} //C9 2 has 5 colors for (uint8_t i = 0; i < numColors; i++) { - cols[i] = strip.color_from_palette(i*fac, false, true, 255); + cols[i] = SEGMENT.color_from_palette(i*fac, false, true, 255); } } } else if (SEGMENT.intensity < 80) //pastel (easter) colors @@ -926,7 +965,7 @@ uint16_t mode_colorful(void) { for (uint16_t i = 0; i < SEGLEN; i+= numColors) { - for (uint16_t j = 0; j < numColors; j++) strip.setPixelColor(i + j, cols[SEGENV.aux0 + j]); + for (uint16_t j = 0; j < numColors; j++) SEGMENT.setPixelColor(i + j, cols[SEGENV.aux0 + j]); } return FRAMETIME; @@ -939,16 +978,16 @@ static const char *_data_FX_MODE_COLORFUL PROGMEM = "Colorful@!,Saturation;1,2,3 */ uint16_t mode_traffic_light(void) { for(uint16_t i=0; i < SEGLEN; i++) - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); uint32_t mdelay = 500; for (int i = 0; i < SEGLEN-2 ; i+=3) { switch (SEGENV.aux0) { - case 0: strip.setPixelColor(i, 0x00FF0000); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break; - case 1: strip.setPixelColor(i, 0x00FF0000); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed)); strip.setPixelColor(i+1, 0x00EECC00); break; - case 2: strip.setPixelColor(i+2, 0x0000FF00); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break; - case 3: strip.setPixelColor(i+1, 0x00EECC00); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed));break; + case 0: SEGMENT.setPixelColor(i, 0x00FF0000); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break; + case 1: SEGMENT.setPixelColor(i, 0x00FF0000); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed)); SEGMENT.setPixelColor(i+1, 0x00EECC00); break; + case 2: SEGMENT.setPixelColor(i+2, 0x0000FF00); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break; + case 3: SEGMENT.setPixelColor(i+1, 0x00EECC00); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed));break; } } @@ -973,7 +1012,7 @@ uint16_t mode_chase_flash(void) { uint8_t flash_step = SEGENV.call % ((FLASH_COUNT * 2) + 1); for(uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } uint16_t delay = 10 + ((30 * (uint16_t)(255 - SEGMENT.speed)) / SEGLEN); @@ -981,8 +1020,8 @@ uint16_t mode_chase_flash(void) { if(flash_step % 2 == 0) { uint16_t n = SEGENV.step; uint16_t m = (SEGENV.step + 1) % SEGLEN; - strip.setPixelColor( n, SEGCOLOR(1)); - strip.setPixelColor( m, SEGCOLOR(1)); + SEGMENT.setPixelColor( n, SEGCOLOR(1)); + SEGMENT.setPixelColor( m, SEGCOLOR(1)); delay = 20; } else { delay = 30; @@ -1002,7 +1041,7 @@ uint16_t mode_chase_flash_random(void) { uint8_t flash_step = SEGENV.call % ((FLASH_COUNT * 2) + 1); for(uint16_t i = 0; i < SEGENV.step; i++) { - strip.setPixelColor(i, strip.color_wheel(SEGENV.aux0)); + SEGMENT.setPixelColor(i, SEGMENT.color_wheel(SEGENV.aux0)); } uint16_t delay = 1 + ((10 * (uint16_t)(255 - SEGMENT.speed)) / SEGLEN); @@ -1010,19 +1049,19 @@ uint16_t mode_chase_flash_random(void) { uint16_t n = SEGENV.step; uint16_t m = (SEGENV.step + 1) % SEGLEN; if(flash_step % 2 == 0) { - strip.setPixelColor( n, SEGCOLOR(0)); - strip.setPixelColor( m, SEGCOLOR(0)); + SEGMENT.setPixelColor( n, SEGCOLOR(0)); + SEGMENT.setPixelColor( m, SEGCOLOR(0)); delay = 20; } else { - strip.setPixelColor( n, strip.color_wheel(SEGENV.aux0)); - strip.setPixelColor( m, SEGCOLOR(1)); + SEGMENT.setPixelColor( n, SEGMENT.color_wheel(SEGENV.aux0)); + SEGMENT.setPixelColor( m, SEGCOLOR(1)); delay = 30; } } else { SEGENV.step = (SEGENV.step + 1) % SEGLEN; if (SEGENV.step == 0) { - SEGENV.aux0 = strip.get_random_wheel_index(SEGENV.aux0); + SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux0); } } return delay; @@ -1066,7 +1105,7 @@ uint16_t mode_running_random(void) { } z = 0; } - strip.setPixelColor(i, strip.color_wheel(PRNG16 >> 8)); + SEGMENT.setPixelColor(i, SEGMENT.color_wheel(PRNG16 >> 8)); z++; } @@ -1080,7 +1119,7 @@ uint16_t larson_scanner(bool dual) { uint16_t counter = strip.now * ((SEGMENT.speed >> 2) +8); uint16_t index = counter * SEGLEN >> 16; - strip.fade_out(SEGMENT.intensity); + SEGMENT.fade_out(SEGMENT.intensity); if (SEGENV.step > index && SEGENV.step - index > SEGLEN/2) { SEGENV.aux0 = !SEGENV.aux0; @@ -1088,19 +1127,19 @@ uint16_t larson_scanner(bool dual) { for (uint16_t i = SEGENV.step; i < index; i++) { uint16_t j = (SEGENV.aux0)?i:SEGLEN-1-i; - strip.setPixelColor( j, strip.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor( j, SEGMENT.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); } if (dual) { uint32_t c; if (SEGCOLOR(2) != 0) { c = SEGCOLOR(2); } else { - c = strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0); + c = SEGMENT.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0); } for (uint16_t i = SEGENV.step; i < index; i++) { uint16_t j = (SEGENV.aux0)?SEGLEN-1-i:i; - strip.setPixelColor(j, c); + SEGMENT.setPixelColor(j, c); } } @@ -1126,16 +1165,16 @@ uint16_t mode_comet(void) { uint16_t index = (counter * SEGLEN) >> 16; if (SEGENV.call == 0) SEGENV.aux0 = index; - strip.fade_out(SEGMENT.intensity); + SEGMENT.fade_out(SEGMENT.intensity); - strip.setPixelColor( index, strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor( index, SEGMENT.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); if (index > SEGENV.aux0) { for (uint16_t i = SEGENV.aux0; i < index ; i++) { - strip.setPixelColor( i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor( i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } } else if (index < SEGENV.aux0 && index < 10) { for (uint16_t i = 0; i < index ; i++) { - strip.setPixelColor( i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor( i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } } SEGENV.aux0 = index++; @@ -1152,7 +1191,7 @@ uint16_t mode_fireworks() { const uint16_t width = strip.isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); const uint16_t height = SEGMENT.virtualHeight(); - strip.fade_out(0); + SEGMENT.fade_out(0); if (SEGENV.call == 0) { SEGENV.aux0 = UINT16_MAX; @@ -1161,19 +1200,19 @@ uint16_t mode_fireworks() { bool valid1 = (SEGENV.aux0 < width*height); bool valid2 = (SEGENV.aux1 < width*height); uint32_t sv1 = 0, sv2 = 0; - if (valid1) sv1 = strip.isMatrix ? strip.getPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width) : strip.getPixelColor(SEGENV.aux0); // get spark color - if (valid2) sv2 = strip.isMatrix ? strip.getPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width) : strip.getPixelColor(SEGENV.aux1); - if (!SEGENV.step) strip.blur(16); - if (valid1) { if (strip.isMatrix) strip.setPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width, sv1); else strip.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur - if (valid2) { if (strip.isMatrix) strip.setPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width, sv2); else strip.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur + if (valid1) sv1 = strip.isMatrix ? SEGMENT.getPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width) : SEGMENT.getPixelColor(SEGENV.aux0); // get spark color + if (valid2) sv2 = strip.isMatrix ? SEGMENT.getPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width) : SEGMENT.getPixelColor(SEGENV.aux1); + if (!SEGENV.step) SEGMENT.blur(16); + if (valid1) { if (strip.isMatrix) SEGMENT.setPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width, sv1); else SEGMENT.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur + if (valid2) { if (strip.isMatrix) SEGMENT.setPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width, sv2); else SEGMENT.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur for (uint16_t i=0; i> 1)) == 0) { uint16_t index = random16(width*height); uint16_t j = index % width, k = index / width; - uint32_t col = strip.color_from_palette(random8(), false, false, 0); - if (strip.isMatrix) strip.setPixelColorXY(j, k, col); - else strip.setPixelColor(index, col); + uint32_t col = SEGMENT.color_from_palette(random8(), false, false, 0); + if (strip.isMatrix) SEGMENT.setPixelColorXY(j, k, col); + else SEGMENT.setPixelColor(index, col); SEGENV.aux1 = SEGENV.aux0; // old spark SEGENV.aux0 = index; // remember where spark occured } @@ -1192,16 +1231,16 @@ uint16_t mode_rain() if (SEGENV.step > SPEED_FORMULA_L) { SEGENV.step = 1; if (strip.isMatrix) { - strip.move(6,1); // move all pixels down + SEGMENT.move(6,1); // move all pixels down SEGENV.aux0 = (SEGENV.aux0 % width) + (SEGENV.aux0 / width + 1) * width; SEGENV.aux1 = (SEGENV.aux1 % width) + (SEGENV.aux1 / width + 1) * width; } else { //shift all leds left - uint32_t ctemp = strip.getPixelColor(0); + uint32_t ctemp = SEGMENT.getPixelColor(0); for(uint16_t i = 0; i < SEGLEN - 1; i++) { - strip.setPixelColor(i, strip.getPixelColor(i+1)); + SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); } - strip.setPixelColor(SEGLEN -1, ctemp); // wrap around + SEGMENT.setPixelColor(SEGLEN -1, ctemp); // wrap around SEGENV.aux0++; // increase spark index SEGENV.aux1++; } @@ -1222,7 +1261,7 @@ uint16_t mode_fire_flicker(void) { uint32_t cycleTime = 40 + (255 - SEGMENT.speed); uint32_t it = strip.now / cycleTime; if (SEGENV.step == it) return FRAMETIME; - + byte w = (SEGCOLOR(0) >> 24); byte r = (SEGCOLOR(0) >> 16); byte g = (SEGCOLOR(0) >> 8); @@ -1232,9 +1271,9 @@ uint16_t mode_fire_flicker(void) { for(uint16_t i = 0; i < SEGLEN; i++) { byte flicker = random8(lum); if (SEGMENT.palette == 0) { - strip.setPixelColor(i, MAX(r - flicker, 0), MAX(g - flicker, 0), MAX(b - flicker, 0), MAX(w - flicker, 0)); + SEGMENT.setPixelColor(i, MAX(r - flicker, 0), MAX(g - flicker, 0), MAX(b - flicker, 0), MAX(w - flicker, 0)); } else { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, 255 - flicker)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, 255 - flicker)); } } @@ -1266,7 +1305,7 @@ uint16_t gradient_base(bool loading) { val = MIN(abs(pp-i),MIN(abs(p1-i),abs(p2-i))); } val = (brd > val) ? val/brd * 255 : 255; - strip.setPixelColor(i, color_blend(SEGCOLOR(0), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1), val)); + SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(0), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1), val)); } return FRAMETIME; @@ -1303,8 +1342,8 @@ uint16_t police_base(uint32_t color1, uint32_t color2) for (uint16_t i = 0; i < width; i++) { uint16_t indexR = (offset + i) % SEGLEN; uint16_t indexB = (offset + i + (SEGLEN>>1)) % SEGLEN; - strip.setPixelColor(indexR, color1); - strip.setPixelColor(indexB, color2); + SEGMENT.setPixelColor(indexR, color1); + SEGMENT.setPixelColor(indexB, color2); } return FRAMETIME; } @@ -1313,7 +1352,7 @@ uint16_t police_base(uint32_t color1, uint32_t color2) //Police Lights Red and Blue //uint16_t mode_police() //{ -// strip.fill(SEGCOLOR(1)); +// SEGMENT.fill(SEGCOLOR(1)); // return police_base(RED, BLUE); //} //static const char *_data_FX_MODE_POLICE PROGMEM = "Police@!,Width;,Bg,;0"; @@ -1322,7 +1361,7 @@ uint16_t police_base(uint32_t color1, uint32_t color2) //Police Lights with custom colors uint16_t mode_two_dots() { - strip.fill(SEGCOLOR(2)); + SEGMENT.fill(SEGCOLOR(2)); uint32_t color2 = (SEGCOLOR(1) == SEGCOLOR(2)) ? SEGCOLOR(0) : SEGCOLOR(1); return police_base(SEGCOLOR(0), color2); @@ -1348,7 +1387,7 @@ uint16_t mode_fairy() { uint16_t PRNG16 = 5100 + strip.getCurrSegmentId(); for (uint16_t i = 0; i < SEGLEN; i++) { PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; //next 'random' number - strip.setPixelColor(i, strip.color_from_palette(PRNG16 >> 8, false, false, 0)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(PRNG16 >> 8, false, false, 0)); } //amount of flasher pixels depending on intensity (0: none, 255: every LED) @@ -1393,7 +1432,7 @@ uint16_t mode_fairy() { } } if (stateTime > 255) stateTime = 255; //for flasher brightness calculation, fades in first 255 ms of state - //flasherBri[f - firstFlasher] = (flashers[f].stateOn) ? 255-strip.gamma8((510 - stateTime) >> 1) : strip.gamma8((510 - stateTime) >> 1); + //flasherBri[f - firstFlasher] = (flashers[f].stateOn) ? 255-SEGMENT.gamma8((510 - stateTime) >> 1) : SEGMENT.gamma8((510 - stateTime) >> 1); flasherBri[f - firstFlasher] = (flashers[f].stateOn) ? stateTime : 255 - (stateTime >> 0); flasherBriSum += flasherBri[f - firstFlasher]; } @@ -1405,10 +1444,10 @@ uint16_t mode_fairy() { uint8_t bri = (flasherBri[f - firstFlasher] * globalPeakBri) / 255; PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; //next 'random' number uint16_t flasherPos = f*flasherDistance; - strip.setPixelColor(flasherPos, color_blend(SEGCOLOR(1), strip.color_from_palette(PRNG16 >> 8, false, false, 0), bri)); + SEGMENT.setPixelColor(flasherPos, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(PRNG16 >> 8, false, false, 0), bri)); for (uint16_t i = flasherPos+1; i < flasherPos+flasherDistance && i < SEGLEN; i++) { PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; //next 'random' number - strip.setPixelColor(i, strip.color_from_palette(PRNG16 >> 8, false, false, 0, globalPeakBri)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(PRNG16 >> 8, false, false, 0, globalPeakBri)); } } } @@ -1460,7 +1499,7 @@ uint16_t mode_fairytwinkle() { PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; //next 'random' number diff = (PRNG16 > lastR) ? PRNG16 - lastR : lastR - PRNG16; } - strip.setPixelColor(f, color_blend(SEGCOLOR(1), strip.color_from_palette(PRNG16 >> 8, false, false, 0), flasherBri)); + SEGMENT.setPixelColor(f, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(PRNG16 >> 8, false, false, 0), flasherBri)); } return FRAMETIME; } @@ -1480,10 +1519,10 @@ uint16_t tricolor_chase(uint32_t color1, uint32_t color2) { if (index > (width*3)-1) index = 0; uint32_t color = color1; - if (index > (width<<1)-1) color = strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1); + if (index > (width<<1)-1) color = SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1); else if (index > width-1) color = color2; - strip.setPixelColor(SEGLEN - i -1, color); + SEGMENT.setPixelColor(SEGLEN - i -1, color); } return FRAMETIME; } @@ -1505,18 +1544,18 @@ uint16_t mode_icu(void) { uint16_t dest = SEGENV.step & 0xFFFF; uint8_t space = (SEGMENT.intensity >> 3) +2; - strip.fill(SEGCOLOR(1)); + SEGMENT.fill(SEGCOLOR(1)); byte pindex = map(dest, 0, SEGLEN-SEGLEN/space, 0, 255); - uint32_t col = strip.color_from_palette(pindex, false, false, 0); + uint32_t col = SEGMENT.color_from_palette(pindex, false, false, 0); - strip.setPixelColor(dest, col); - strip.setPixelColor(dest + SEGLEN/space, col); + SEGMENT.setPixelColor(dest, col); + SEGMENT.setPixelColor(dest + SEGLEN/space, col); if(SEGENV.aux0 == dest) { // pause between eye movements if(random8(6) == 0) { // blink once in a while - strip.setPixelColor(dest, SEGCOLOR(1)); - strip.setPixelColor(dest + SEGLEN/space, SEGCOLOR(1)); + SEGMENT.setPixelColor(dest, SEGCOLOR(1)); + SEGMENT.setPixelColor(dest + SEGLEN/space, SEGCOLOR(1)); return 200; } SEGENV.aux0 = random16(SEGLEN-SEGLEN/space); @@ -1531,8 +1570,8 @@ uint16_t mode_icu(void) { dest--; } - strip.setPixelColor(dest, col); - strip.setPixelColor(dest + SEGLEN/space, col); + SEGMENT.setPixelColor(dest, col); + SEGMENT.setPixelColor(dest + SEGLEN/space, col); return SPEED_FORMULA_L; } @@ -1552,26 +1591,26 @@ uint16_t mode_tricolor_wipe(void) for (uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2)); } if(ledIndex < SEGLEN) { //wipe from 0 to 1 for (uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, (i > ledOffset)? SEGCOLOR(0) : SEGCOLOR(1)); + SEGMENT.setPixelColor(i, (i > ledOffset)? SEGCOLOR(0) : SEGCOLOR(1)); } } else if (ledIndex < SEGLEN*2) { //wipe from 1 to 2 ledOffset = ledIndex - SEGLEN; for (uint16_t i = ledOffset +1; i < SEGLEN; i++) { - strip.setPixelColor(i, SEGCOLOR(1)); + SEGMENT.setPixelColor(i, SEGCOLOR(1)); } } else //wipe from 2 to 0 { ledOffset = ledIndex - SEGLEN*2; for (uint16_t i = 0; i <= ledOffset; i++) { - strip.setPixelColor(i, SEGCOLOR(0)); + SEGMENT.setPixelColor(i, SEGCOLOR(0)); } } @@ -1611,13 +1650,13 @@ uint16_t mode_tricolor_fade(void) for(uint16_t i = 0; i < SEGLEN; i++) { uint32_t color; if (stage == 2) { - color = color_blend(strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), color2, stp); + color = color_blend(SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), color2, stp); } else if (stage == 1) { - color = color_blend(color1, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), stp); + color = color_blend(color1, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), stp); } else { color = color_blend(color1, color2, stp); } - strip.setPixelColor(i, color); + SEGMENT.setPixelColor(i, color); } return FRAMETIME; @@ -1636,7 +1675,7 @@ uint16_t mode_multi_comet(void) if (SEGENV.step == it) return FRAMETIME; if (!SEGENV.allocateData(sizeof(uint16_t) * 8)) return mode_static(); //allocation failed - strip.fade_out(SEGMENT.intensity); + SEGMENT.fade_out(SEGMENT.intensity); uint16_t* comets = reinterpret_cast(SEGENV.data); @@ -1645,10 +1684,10 @@ uint16_t mode_multi_comet(void) uint16_t index = comets[i]; if (SEGCOLOR(2) != 0) { - strip.setPixelColor(index, i % 2 ? strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(2)); + SEGMENT.setPixelColor(index, i % 2 ? SEGMENT.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(2)); } else { - strip.setPixelColor(index, strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(index, SEGMENT.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); } comets[i]++; } else { @@ -1695,7 +1734,7 @@ uint16_t mode_random_chase(void) uint8_t g = random8(6) != 0 ? (color >> 8 & 0xFF) : random8(); uint8_t b = random8(6) != 0 ? (color & 0xFF) : random8(); color = RGBW32(r, g, b, 0); - strip.setPixelColor(i, r, g, b); + SEGMENT.setPixelColor(i, r, g, b); if (i == SEGLEN -1 && SEGENV.aux1 != (it & 0xFFFF)) { //new first color in next frame SEGENV.step = color; SEGENV.aux0 = random16_get_seed(); @@ -1764,7 +1803,7 @@ uint16_t mode_oscillate(void) color = (color == BLACK) ? SEGCOLOR(j) : color_blend(color, SEGCOLOR(j), 128); } } - strip.setPixelColor(i, color); + SEGMENT.setPixelColor(i, color); } SEGENV.step = it; @@ -1789,12 +1828,12 @@ uint16_t mode_lightning(void) SEGENV.aux0 = 200; //200ms delay after leader } - strip.fill(SEGCOLOR(1)); + SEGMENT.fill(SEGCOLOR(1)); if (SEGENV.aux1 > 3 && !(SEGENV.aux1 & 0x01)) { //flash on even number >2 for (int i = ledstart; i < ledstart + ledlen; i++) { - strip.setPixelColor(i,strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, bri)); + SEGMENT.setPixelColor(i,SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, bri)); } SEGENV.aux1--; @@ -1851,10 +1890,10 @@ uint16_t mode_pride_2015(void) bri8 += (255 - brightdepth); CRGB newcolor = CHSV( hue8, sat8, bri8); - fastled_col = CRGB(strip.getPixelColor(i)); + fastled_col = CRGB(SEGMENT.getPixelColor(i)); nblend(fastled_col, newcolor, 64); - strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } SEGENV.step = sPseudotime; SEGENV.aux0 = sHue16; @@ -1865,14 +1904,14 @@ static const char *_data_FX_MODE_PRIDE_2015 PROGMEM = "Pride 2015@!,;;"; //eight colored dots, weaving in and out of sync with each other uint16_t mode_juggle(void){ - strip.fade_out(SEGMENT.intensity); + SEGMENT.fade_out(SEGMENT.intensity); CRGB fastled_col; byte dothue = 0; for ( byte i = 0; i < 8; i++) { uint16_t index = 0 + beatsin88((128 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1); - fastled_col = CRGB(strip.getPixelColor(index)); + fastled_col = CRGB(SEGMENT.getPixelColor(index)); fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(strip.currentPalette, dothue, 255); - strip.setPixelColor(index, fastled_col.red, fastled_col.green, fastled_col.blue); + SEGMENT.setPixelColor(index, fastled_col.red, fastled_col.green, fastled_col.blue); dothue += 32; } return FRAMETIME; @@ -1896,7 +1935,7 @@ uint16_t mode_palette() if (noWrap) colorIndex = map(colorIndex, 0, 255, 0, 240); //cut off blend at palette "end" - strip.setPixelColor(i, strip.color_from_palette(colorIndex, false, true, 255)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(colorIndex, false, true, 255)); } return FRAMETIME; } @@ -1977,13 +2016,13 @@ uint16_t mode_fire_2012() // Step 4. Map from heat cells to LED colors for (uint16_t j = 0; j < rows; j++) { CRGB color = ColorFromPalette(strip.currentPalette, /*MIN(*/heat[j+rows*f]/*,240)*/, 255, LINEARBLEND); - if (strip.isMatrix) strip.setPixelColorXY(f, rows -j -1, color); - else strip.setPixelColor(j, color); + if (strip.isMatrix) SEGMENT.setPixelColorXY(f, rows -j -1, color); + else SEGMENT.setPixelColor(j, color); } } return FRAMETIME; } -static const char *_data_FX_MODE_FIRE_2012 PROGMEM = "Fire 2012@Cooling=120,Spark rate=64;1,2,3;!"; +static const char *_data_FX_MODE_FIRE_2012 PROGMEM = "Fire 2012@Cooling=120,Spark rate=64;1,2,3;!=35"; // ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb @@ -2026,16 +2065,16 @@ uint16_t mode_colorwaves() bri8 += (255 - brightdepth); CRGB newcolor = ColorFromPalette(strip.currentPalette, hue8, bri8); - fastled_col = CRGB(strip.getPixelColor(i)); + fastled_col = CRGB(SEGMENT.getPixelColor(i)); nblend(fastled_col, newcolor, 128); - strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } SEGENV.step = sPseudotime; SEGENV.aux0 = sHue16; return FRAMETIME; } -static const char *_data_FX_MODE_COLORWAVES PROGMEM = "Colorwaves"; +static const char *_data_FX_MODE_COLORWAVES PROGMEM = "Colorwaves@!,!;!,!,!;!=26"; // colored stripes pulsing at a defined Beats-Per-Minute (BPM) @@ -2046,7 +2085,7 @@ uint16_t mode_bpm() uint8_t beat = beatsin8(SEGMENT.speed, 64, 255); for (uint16_t i = 0; i < SEGLEN; i++) { fastled_col = ColorFromPalette(strip.currentPalette, stp + (i * 2), beat - stp + (i * 10)); - strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; } @@ -2060,13 +2099,13 @@ uint16_t mode_fillnoise8() for (uint16_t i = 0; i < SEGLEN; i++) { uint8_t index = inoise8(i * SEGLEN, SEGENV.step + i * SEGLEN); fastled_col = ColorFromPalette(strip.currentPalette, index, 255, LINEARBLEND); - strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } SEGENV.step += beatsin8(SEGMENT.speed, 1, 6); //10,1,4 return FRAMETIME; } -static const char *_data_FX_MODE_FILLNOISE8 PROGMEM = "Fill Noise"; +static const char *_data_FX_MODE_FILLNOISE8 PROGMEM = "Fill Noise@!,!;!,!,!;!=9"; uint16_t mode_noise16_1() @@ -2090,12 +2129,12 @@ uint16_t mode_noise16_1() uint8_t index = sin8(noise * 3); // map LED color based on noise data fastled_col = ColorFromPalette(strip.currentPalette, index, 255, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. - strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; } -static const char *_data_FX_MODE_NOISE16_1 PROGMEM = "Noise 1"; +static const char *_data_FX_MODE_NOISE16_1 PROGMEM = "Noise 1@!,!;!,!,!;!=20"; uint16_t mode_noise16_2() @@ -2115,12 +2154,12 @@ uint16_t mode_noise16_2() uint8_t index = sin8(noise * 3); // map led color based on noise data fastled_col = ColorFromPalette(strip.currentPalette, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. - strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; } -static const char *_data_FX_MODE_NOISE16_2 PROGMEM = "Noise 2"; +static const char *_data_FX_MODE_NOISE16_2 PROGMEM = "Noise 2@!,!;!,!,!;!=43"; uint16_t mode_noise16_3() @@ -2143,12 +2182,12 @@ uint16_t mode_noise16_3() uint8_t index = sin8(noise * 3); // map led color based on noise data fastled_col = ColorFromPalette(strip.currentPalette, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. - strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; } -static const char *_data_FX_MODE_NOISE16_3 PROGMEM = "Noise 3"; +static const char *_data_FX_MODE_NOISE16_3 PROGMEM = "Noise 3@!,!;!,!,!;!=35"; //https://github.com/aykevl/ledstrip-spark/blob/master/ledstrip.ino @@ -2159,11 +2198,11 @@ uint16_t mode_noise16_4() for (uint16_t i = 0; i < SEGLEN; i++) { int16_t index = inoise16(uint32_t(i) << 12, stp); fastled_col = ColorFromPalette(strip.currentPalette, index); - strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; } -static const char *_data_FX_MODE_NOISE16_4 PROGMEM = "Noise 4"; +static const char *_data_FX_MODE_NOISE16_4 PROGMEM = "Noise 4@!,!;!,!,!;!=26"; //based on https://gist.github.com/kriegsman/5408ecd397744ba0393e @@ -2181,7 +2220,7 @@ uint16_t mode_colortwinkle() for (uint16_t i = 0; i < rows*cols; i++) { uint16_t j = i % cols, k = i / cols; - fastled_col = CRGB(strip.isMatrix ? strip.getPixelColorXY(j, k) : strip.getPixelColor(i)); + fastled_col = CRGB(strip.isMatrix ? SEGMENT.getPixelColorXY(j, k) : SEGMENT.getPixelColor(i)); prev = fastled_col; uint16_t index = i >> 3; uint8_t bitNum = i & 0x07; @@ -2196,19 +2235,19 @@ uint16_t mode_colortwinkle() bitWrite(SEGENV.data[index], bitNum, false); } - if (strip.isMatrix) strip.setPixelColorXY(j, k, fastled_col); - else strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + if (strip.isMatrix) SEGMENT.setPixelColorXY(j, k, fastled_col); + else SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); - uint32_t col = strip.isMatrix ? strip.getPixelColorXY(j, k) : strip.getPixelColor(i); + uint32_t col = strip.isMatrix ? SEGMENT.getPixelColorXY(j, k) : SEGMENT.getPixelColor(i); if (CRGB(col) == prev) { //fix "stuck" pixels fastled_col += fastled_col; - if (strip.isMatrix) strip.setPixelColorXY(j, k, fastled_col); - else strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + if (strip.isMatrix) SEGMENT.setPixelColorXY(j, k, fastled_col); + else SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } } else { fastled_col.nscale8(255 - fadeDownAmount); - if (strip.isMatrix) strip.setPixelColorXY(j, k, fastled_col); - else strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + if (strip.isMatrix) SEGMENT.setPixelColorXY(j, k, fastled_col); + else SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } } @@ -2217,14 +2256,14 @@ uint16_t mode_colortwinkle() for (uint8_t times = 0; times < 5; times++) { //attempt to spawn a new pixel 5 times uint16_t i = random16(rows*cols); uint16_t j = i % cols, k = i / cols; - uint32_t col = strip.isMatrix ? strip.getPixelColorXY(j, k) : strip.getPixelColor(i); + uint32_t col = strip.isMatrix ? SEGMENT.getPixelColorXY(j, k) : SEGMENT.getPixelColor(i); if (col == 0) { fastled_col = ColorFromPalette(strip.currentPalette, random8(), 64, NOBLEND); uint16_t index = i >> 3; uint8_t bitNum = i & 0x07; bitWrite(SEGENV.data[index], bitNum, true); - if (strip.isMatrix) strip.setPixelColorXY(j, k, fastled_col); - else strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + if (strip.isMatrix) SEGMENT.setPixelColorXY(j, k, fastled_col); + else SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); break; //only spawn 1 new pixel per frame per 50 LEDs } } @@ -2248,7 +2287,7 @@ uint16_t mode_lake() { int index = cos8((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2; uint8_t lum = (index > wave3) ? index - wave3 : 0; fastled_col = ColorFromPalette(strip.currentPalette, map(index,0,255,0,240), lum, LINEARBLEND); - strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; } @@ -2273,7 +2312,7 @@ uint16_t mode_meteor() { { byte meteorTrailDecay = 128 + random8(127); trail[i] = scale8(trail[i], meteorTrailDecay); - strip.setPixelColor(i, strip.color_from_palette(trail[i], false, true, 255)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(trail[i], false, true, 255)); } } @@ -2285,7 +2324,7 @@ uint16_t mode_meteor() { } trail[index] = 240; - strip.setPixelColor(index, strip.color_from_palette(trail[index], false, true, 255)); + SEGMENT.setPixelColor(index, SEGMENT.color_from_palette(trail[index], false, true, 255)); } return FRAMETIME; @@ -2312,7 +2351,7 @@ uint16_t mode_meteor_smooth() { trail[i] += change; if (trail[i] > 245) trail[i] = 0; if (trail[i] > 240) trail[i] = 240; - strip.setPixelColor(i, strip.color_from_palette(trail[i], false, true, 255)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(trail[i], false, true, 255)); } } @@ -2322,7 +2361,7 @@ uint16_t mode_meteor_smooth() { if(in + j >= SEGLEN) { index = (in + j - SEGLEN); } - strip.setPixelColor(index, color_blend(strip.getPixelColor(index), strip.color_from_palette(240, false, true, 255), 48)); + SEGMENT.setPixelColor(index, color_blend(SEGMENT.getPixelColor(index), SEGMENT.color_from_palette(240, false, true, 255), 48)); trail[index] = 240; } @@ -2352,10 +2391,10 @@ uint16_t mode_railway() if (SEGENV.aux0) pos = 255 - pos; for (uint16_t i = 0; i < SEGLEN; i += 2) { - strip.setPixelColor(i, strip.color_from_palette(255 - pos, false, false, 255)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(255 - pos, false, false, 255)); if (i < SEGLEN -1) { - strip.setPixelColor(i + 1, strip.color_from_palette(pos, false, false, 255)); + SEGMENT.setPixelColor(i + 1, SEGMENT.color_from_palette(pos, false, false, 255)); } } SEGENV.step += FRAMETIME; @@ -2403,9 +2442,9 @@ uint16_t ripple_base(bool rainbow) } else { SEGENV.aux0--; } - strip.fill(color_blend(strip.color_wheel(SEGENV.aux0),BLACK,235)); + SEGMENT.fill(color_blend(SEGMENT.color_wheel(SEGENV.aux0),BLACK,235)); } else { - strip.fill(SEGCOLOR(1)); + SEGMENT.fill(SEGCOLOR(1)); } //draw wave @@ -2416,7 +2455,7 @@ uint16_t ripple_base(bool rainbow) { uint8_t rippledecay = (SEGMENT.speed >> 4) +1; //faster decay if faster propagation uint16_t rippleorigin = ripples[i].pos; - uint32_t col = strip.color_from_palette(ripples[i].color, false, false, 255); + uint32_t col = SEGMENT.color_from_palette(ripples[i].color, false, false, 255); uint16_t propagation = ((ripplestate/rippledecay -1) * SEGMENT.speed); int16_t propI = propagation >> 8; uint8_t propF = propagation & 0xFF; @@ -2428,12 +2467,12 @@ uint16_t ripple_base(bool rainbow) uint8_t mag = scale8(cubicwave8((propF>>2)+(v-left)*64), amp); if (v < SEGLEN && v >= 0) { - strip.setPixelColor(v, color_blend(strip.getPixelColor(v), col, mag)); + SEGMENT.setPixelColor(v, color_blend(SEGMENT.getPixelColor(v), col, mag)); } int16_t w = left + propI*2 + 3 -(v-left); if (w < SEGLEN && w >= 0) { - strip.setPixelColor(w, color_blend(strip.getPixelColor(w), col, mag)); + SEGMENT.setPixelColor(w, color_blend(SEGMENT.getPixelColor(w), col, mag)); } } ripplestate += rippledecay; @@ -2580,15 +2619,15 @@ uint16_t twinklefox_base(bool cat) if (deltabright >= 32 || (!bg)) { // If the new pixel is significantly brighter than the background color, // use the new color. - strip.setPixelColor(i, c.red, c.green, c.blue); + SEGMENT.setPixelColor(i, c.red, c.green, c.blue); } else if (deltabright > 0) { // If the new pixel is just slightly brighter than the background color, // mix a blend of the new color and the background color - strip.setPixelColor(i, color_blend(RGBW32(bg.r,bg.g,bg.b,0), RGBW32(c.r,c.g,c.b,0), deltabright * 8)); + SEGMENT.setPixelColor(i, color_blend(RGBW32(bg.r,bg.g,bg.b,0), RGBW32(c.r,c.g,c.b,0), deltabright * 8)); } else { // if the new pixel is not at all brighter than the background color, // just use the background color. - strip.setPixelColor(i, bg.r, bg.g, bg.b); + SEGMENT.setPixelColor(i, bg.r, bg.g, bg.b); } } return FRAMETIME; @@ -2618,7 +2657,7 @@ uint16_t mode_halloween_eyes() uint16_t eyeLength = (2*HALLOWEEN_EYE_WIDTH) + HALLOWEEN_EYE_SPACE; if (eyeLength > SEGLEN) return mode_static(); //bail if segment too short - strip.fill(SEGCOLOR(1)); //fill background + SEGMENT.fill(SEGCOLOR(1)); //fill background uint8_t state = SEGENV.aux1 >> 8; uint16_t stateTime = SEGENV.call; @@ -2637,15 +2676,15 @@ uint16_t mode_halloween_eyes() uint32_t fadestage = (strip.now - SEGENV.step)*255 / stateTime; if (fadestage > 255) fadestage = 255; - uint32_t c = color_blend(strip.color_from_palette(SEGENV.aux1 & 0xFF, false, false, 0), SEGCOLOR(1), fadestage); + uint32_t c = color_blend(SEGMENT.color_from_palette(SEGENV.aux1 & 0xFF, false, false, 0), SEGCOLOR(1), fadestage); for (uint16_t i = 0; i < HALLOWEEN_EYE_WIDTH; i++) { if (strip.isMatrix) { - strip.setPixelColorXY(startPos + i, SEGMENT.offset, c); - strip.setPixelColorXY(start2ndEye + i, SEGMENT.offset, c); + SEGMENT.setPixelColorXY(startPos + i, SEGMENT.offset, c); + SEGMENT.setPixelColorXY(start2ndEye + i, SEGMENT.offset, c); } else { - strip.setPixelColor(startPos + i, c); - strip.setPixelColor(start2ndEye + i, c); + SEGMENT.setPixelColor(startPos + i, c); + SEGMENT.setPixelColor(start2ndEye + i, c); } } } @@ -2680,7 +2719,7 @@ uint16_t mode_static_pattern() uint16_t cnt = 0; for (uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, (drawingLit) ? strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(1)); + SEGMENT.setPixelColor(i, (drawingLit) ? SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(1)); cnt++; if (cnt >= ((drawingLit) ? lit : unlit)) { cnt = 0; @@ -2701,11 +2740,11 @@ uint16_t mode_tri_static_pattern() for (uint16_t i = 0; i < SEGLEN; i++) { if ( currSeg % 3 == 0 ) { - strip.setPixelColor(i, SEGCOLOR(0)); + SEGMENT.setPixelColor(i, SEGCOLOR(0)); } else if( currSeg % 3 == 1) { - strip.setPixelColor(i, SEGCOLOR(1)); + SEGMENT.setPixelColor(i, SEGCOLOR(1)); } else { - strip.setPixelColor(i, (SEGCOLOR(2) > 0 ? SEGCOLOR(2) : WHITE)); + SEGMENT.setPixelColor(i, (SEGCOLOR(2) > 0 ? SEGCOLOR(2) : WHITE)); } currSegCount += 1; if (currSegCount >= segSize) { @@ -2721,7 +2760,7 @@ static const char *_data_FX_MODE_TRI_STATIC_PATTERN PROGMEM = "Solid Pattern Tri uint16_t spots_base(uint16_t threshold) { - strip.fill(SEGCOLOR(1)); + SEGMENT.fill(SEGCOLOR(1)); uint16_t maxZones = SEGLEN >> 2; uint16_t zones = 1 + ((SEGMENT.intensity * maxZones) >> 8); @@ -2733,11 +2772,11 @@ uint16_t spots_base(uint16_t threshold) uint16_t pos = offset + z * zoneLen; for (uint16_t i = 0; i < zoneLen; i++) { - uint16_t wave = strip.triwave16((i * 0xFFFF) / zoneLen); + uint16_t wave = triwave16((i * 0xFFFF) / zoneLen); if (wave > threshold) { uint16_t index = 0 + pos + i; uint8_t s = (wave - threshold)*255 / (0xFFFF - threshold); - strip.setPixelColor(index, color_blend(strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255-s)); + SEGMENT.setPixelColor(index, color_blend(SEGMENT.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255-s)); } } } @@ -2758,7 +2797,7 @@ static const char *_data_FX_MODE_SPOTS PROGMEM = "Spots@Spread,Width;!,!,;!"; uint16_t mode_spots_fade() { uint16_t counter = strip.now * ((SEGMENT.speed >> 2) +8); - uint16_t t = strip.triwave16(counter); + uint16_t t = triwave16(counter); uint16_t tr = (t >> 1) + (t >> 2); return spots_base(tr); } @@ -2797,7 +2836,7 @@ uint16_t mode_bouncing_balls(void) { } bool hasCol2 = SEGCOLOR(2); - strip.fill(hasCol2 ? BLACK : SEGCOLOR(1)); + SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1)); for (uint8_t i = 0; i < numBalls; i++) { float timeSinceLastBounce = (time - balls[i].lastBounceTime)/((255-SEGMENT.speed)*8/256 +1); @@ -2817,13 +2856,13 @@ uint16_t mode_bouncing_balls(void) { uint32_t color = SEGCOLOR(0); if (SEGMENT.palette) { - color = strip.color_wheel(i*(256/MAX(numBalls, 8))); + color = SEGMENT.color_wheel(i*(256/MAX(numBalls, 8))); } else if (hasCol2) { color = SEGCOLOR(i % NUM_COLORS); } uint16_t pos = round(balls[i].height * (SEGLEN - 1)); - strip.setPixelColor(pos, color); + SEGMENT.setPixelColor(pos, color); } return FRAMETIME; @@ -2835,30 +2874,30 @@ static const char *_data_FX_MODE_BOUNCINGBALLS PROGMEM = "Bouncing Balls@Gravity * Sinelon stolen from FASTLED examples */ uint16_t sinelon_base(bool dual, bool rainbow=false) { - strip.fade_out(SEGMENT.intensity); + SEGMENT.fade_out(SEGMENT.intensity); uint16_t pos = beatsin16(SEGMENT.speed/10,0,SEGLEN-1); if (SEGENV.call == 0) SEGENV.aux0 = pos; - uint32_t color1 = strip.color_from_palette(pos, true, false, 0); + uint32_t color1 = SEGMENT.color_from_palette(pos, true, false, 0); uint32_t color2 = SEGCOLOR(2); if (rainbow) { - color1 = strip.color_wheel((pos & 0x07) * 32); + color1 = SEGMENT.color_wheel((pos & 0x07) * 32); } - strip.setPixelColor(pos, color1); + SEGMENT.setPixelColor(pos, color1); if (dual) { - if (!color2) color2 = strip.color_from_palette(pos, true, false, 0); + if (!color2) color2 = SEGMENT.color_from_palette(pos, true, false, 0); if (rainbow) color2 = color1; //rainbow - strip.setPixelColor(SEGLEN-1-pos, color2); + SEGMENT.setPixelColor(SEGLEN-1-pos, color2); } if (SEGENV.aux0 != pos) { if (SEGENV.aux0 < pos) { for (uint16_t i = SEGENV.aux0; i < pos ; i++) { - strip.setPixelColor(i, color1); - if (dual) strip.setPixelColor(SEGLEN-1-i, color2); + SEGMENT.setPixelColor(i, color1); + if (dual) SEGMENT.setPixelColor(SEGLEN-1-i, color2); } } else { for (uint16_t i = SEGENV.aux0; i > pos ; i--) { - strip.setPixelColor(i, color1); - if (dual) strip.setPixelColor(SEGLEN-1-i, color2); + SEGMENT.setPixelColor(i, color1); + if (dual) SEGMENT.setPixelColor(SEGLEN-1-i, color2); } } SEGENV.aux0 = pos; @@ -2895,14 +2934,14 @@ uint16_t mode_glitter() uint16_t height = SEGMENT.virtualHeight(); uint16_t width = SEGMENT.virtualWidth(); for (uint16_t i = 0; i random8()) strip.setPixelColorXY(random16(width-1), i, ULTRAWHITE); + if (SEGMENT.intensity > random8()) SEGMENT.setPixelColorXY(random16(width-1), i, ULTRAWHITE); } } else - if (SEGMENT.intensity > random8()) strip.setPixelColor(random16(SEGLEN), ULTRAWHITE); + if (SEGMENT.intensity > random8()) SEGMENT.setPixelColor(random16(SEGLEN), ULTRAWHITE); return FRAMETIME; } -static const char *_data_FX_MODE_GLITTER PROGMEM = "Glitter@,!;!,!,!;!"; +static const char *_data_FX_MODE_GLITTER PROGMEM = "Glitter@,!;!,!,!;!=11"; //each needs 19 bytes @@ -2933,7 +2972,7 @@ uint16_t mode_popcorn(void) { gravity *= rows; //SEGLEN bool hasCol2 = SEGCOLOR(2); - strip.fill(hasCol2 ? BLACK : SEGCOLOR(1)); + SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1)); uint8_t numPopcorn = SEGMENT.intensity*maxNumPopcorn/255; if (numPopcorn == 0) numPopcorn = 1; @@ -2962,13 +3001,13 @@ uint16_t mode_popcorn(void) { } } if (popcorn[i].pos >= 0.0f) { // draw now active popcorn (either active before or just popped) - uint32_t col = strip.color_wheel(popcorn[i].colIndex); + uint32_t col = SEGMENT.color_wheel(popcorn[i].colIndex); if (!SEGMENT.palette && popcorn[i].colIndex < NUM_COLORS) col = SEGCOLOR(popcorn[i].colIndex); uint16_t ledIndex = popcorn[i].pos; if (ledIndex < rows) { - if (strip.isMatrix) strip.setPixelColorXY(uint16_t(popcorn[i].posX), rows - 1 - ledIndex, col); - else strip.setPixelColor(ledIndex, col); + if (strip.isMatrix) SEGMENT.setPixelColorXY(uint16_t(popcorn[i].posX), rows - 1 - ledIndex, col); + else SEGMENT.setPixelColor(ledIndex, col); } } } @@ -3042,12 +3081,12 @@ uint16_t candle(bool multi) } if (i > 0) { - strip.setPixelColor(i, color_blend(SEGCOLOR(1), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s)); + SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s)); SEGENV.data[d] = s; SEGENV.data[d+1] = s_target; SEGENV.data[d+2] = fadeStep; } else { for (uint16_t j = 0; j < SEGLEN; j++) { - strip.setPixelColor(j, color_blend(SEGCOLOR(1), strip.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0), s)); + SEGMENT.setPixelColor(j, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0), s)); } SEGENV.aux0 = s; SEGENV.aux1 = s_target; SEGENV.step = fadeStep; @@ -3122,7 +3161,7 @@ uint16_t mode_starburst(void) { uint16_t startPos = random16(SEGLEN-1); float multiplier = (float)(random8())/255.0 * 1.0; - stars[j].color = CRGB(strip.color_wheel(random8())); + stars[j].color = CRGB(SEGMENT.color_wheel(random8())); stars[j].pos = startPos; stars[j].vel = maxSpeed * (float)(random8())/255.0 * multiplier; stars[j].birth = it; @@ -3137,7 +3176,7 @@ uint16_t mode_starburst(void) { } } - strip.fill(SEGCOLOR(1)); + SEGMENT.fill(SEGCOLOR(1)); for (int j=0; j SEGLEN) end = SEGLEN; for (int p = start; p < end; p++) { - strip.setPixelColor(p, c.r, c.g, c.b); + SEGMENT.setPixelColor(p, c.r, c.g, c.b); } } } @@ -3233,8 +3272,8 @@ uint16_t mode_exploding_fireworks(void) SEGENV.aux1 = dataSize; } - //strip.fill(BLACK); - strip.fade_out(252); + //SEGMENT.fill(BLACK); + SEGMENT.fade_out(252); Spark* sparks = reinterpret_cast(SEGENV.data); Spark* flare = sparks; //first spark is flare data @@ -3257,8 +3296,8 @@ uint16_t mode_exploding_fireworks(void) // launch if (flare->vel > 12 * gravity) { // flare - if (strip.isMatrix) strip.setPixelColorXY(int(flare->posX), rows - uint16_t(flare->pos) - 1, flare->col, flare->col, flare->col); - else strip.setPixelColor(int(flare->posX) ? rows - int(flare->pos) - 1 : int(flare->pos), flare->col, flare->col, flare->col); + if (strip.isMatrix) SEGMENT.setPixelColorXY(int(flare->posX), rows - uint16_t(flare->pos) - 1, flare->col, flare->col, flare->col); + else SEGMENT.setPixelColor(int(flare->posX) ? rows - int(flare->pos) - 1 : int(flare->pos), flare->col, flare->col, flare->col); flare->pos += flare->vel; flare->posX += flare->velX; flare->pos = constrain(flare->pos, 0, rows-1); @@ -3309,7 +3348,7 @@ uint16_t mode_exploding_fireworks(void) if (sparks[i].pos > 0 && sparks[i].pos < rows) { if (strip.isMatrix && !(sparks[i].posX >= 0 && sparks[i].posX < cols)) continue; uint16_t prog = sparks[i].col; - uint32_t spColor = (SEGMENT.palette) ? strip.color_wheel(sparks[i].colIndex) : SEGCOLOR(0); + uint32_t spColor = (SEGMENT.palette) ? SEGMENT.color_wheel(sparks[i].colIndex) : SEGCOLOR(0); CRGB c = CRGB::Black; //HeatColor(sparks[i].col); if (prog > 300) { //fade from white to spark color c = CRGB(color_blend(spColor, WHITE, (prog - 300)*5)); @@ -3319,11 +3358,11 @@ uint16_t mode_exploding_fireworks(void) c.g = qsub8(c.g, cooling); c.b = qsub8(c.b, cooling * 2); } - if (strip.isMatrix) strip.setPixelColorXY(int(sparks[i].posX), rows - int(sparks[i].pos) - 1, c.red, c.green, c.blue); - else strip.setPixelColor(int(sparks[i].posX) ? rows - int(sparks[i].pos) - 1 : int(sparks[i].pos), c.red, c.green, c.blue); + if (strip.isMatrix) SEGMENT.setPixelColorXY(int(sparks[i].posX), rows - int(sparks[i].pos) - 1, c.red, c.green, c.blue); + else SEGMENT.setPixelColor(int(sparks[i].posX) ? rows - int(sparks[i].pos) - 1 : int(sparks[i].pos), c.red, c.green, c.blue); } } - strip.blur(16); + SEGMENT.blur(16); *dying_gravity *= .8f; // as sparks burn out they fall slower } else { SEGENV.aux0 = 6 + random8(10); //wait for this many frames @@ -3355,7 +3394,7 @@ uint16_t mode_drip(void) uint16_t dataSize = sizeof(spark) * numDrops; if (!SEGENV.allocateData(dataSize * cols)) return mode_static(); //allocation failed - strip.fill(SEGCOLOR(1)); + SEGMENT.fill(SEGCOLOR(1)); Spark* drops = reinterpret_cast(SEGENV.data); @@ -3377,14 +3416,14 @@ uint16_t mode_drip(void) } uint32_t col = color_blend(BLACK, SEGCOLOR(0), sourcedrop); - if (strip.isMatrix) strip.setPixelColorXY(k, 0, col); - else strip.setPixelColor(rows-1, col);// water source + if (strip.isMatrix) SEGMENT.setPixelColorXY(k, 0, col); + else SEGMENT.setPixelColor(rows-1, col);// water source if (drops[idx].colIndex == 1) { if (drops[idx].col > 255) drops[idx].col = 255; col = color_blend(BLACK,SEGCOLOR(0),drops[idx].col); - if (strip.isMatrix) strip.setPixelColorXY(k, rows - 1 - uint16_t(drops[idx].pos), col); - else strip.setPixelColor(uint16_t(drops[idx].pos), col); + if (strip.isMatrix) SEGMENT.setPixelColorXY(k, rows - 1 - uint16_t(drops[idx].pos), col); + else SEGMENT.setPixelColor(uint16_t(drops[idx].pos), col); drops[idx].col += map(SEGMENT.speed, 0, 255, 1, 6); // swelling @@ -3402,14 +3441,14 @@ uint16_t mode_drip(void) for (uint16_t i = 1; i < 7 - drops[idx].colIndex; i++) { // some minor math so we don't expand bouncing droplets uint16_t pos = constrain(uint16_t(drops[idx].pos) +i, 0, rows-1); //this is BAD, returns a pos >= SEGLEN occasionally col = color_blend(BLACK, SEGCOLOR(0), drops[idx].col/i); - if (strip.isMatrix) strip.setPixelColorXY(k, rows - 1 - pos, col); - else strip.setPixelColor(pos, col); //spread pixel with fade while falling + if (strip.isMatrix) SEGMENT.setPixelColorXY(k, rows - 1 - pos, col); + else SEGMENT.setPixelColor(pos, col); //spread pixel with fade while falling } if (drops[idx].colIndex > 2) { // during bounce, some water is on the floor col = color_blend(SEGCOLOR(0), BLACK, drops[idx].col); - if (strip.isMatrix) strip.setPixelColorXY(k, rows - 1, col); - else strip.setPixelColor(0, col); + if (strip.isMatrix) SEGMENT.setPixelColorXY(k, rows - 1, col); + else SEGMENT.setPixelColor(0, col); } } else { // we hit bottom if (drops[idx].colIndex > 2) { // already hit once, so back to forming @@ -3455,14 +3494,14 @@ uint16_t mode_tetrix(void) { if (SEGENV.call == 0 || SEGENV.aux1 >= SEGLEN) { SEGENV.aux1 = 0; // reset brick stack size SEGENV.step = 0; - strip.fill(SEGCOLOR(1)); + SEGMENT.fill(SEGCOLOR(1)); return 250; // short wait } if (SEGENV.step == 0) { //init drop->speed = 0.0238 * (SEGMENT.speed ? (SEGMENT.speed>>2)+1 : random8(6,64)); // set speed drop->pos = SEGLEN; // start at end of segment (no need to subtract 1) - drop->col = strip.color_from_palette(random8(0,15)<<4,false,false,0); // limit color choices so there is enough HUE gap + drop->col = SEGMENT.color_from_palette(random8(0,15)<<4,false,false,0); // limit color choices so there is enough HUE gap SEGENV.step = 1; // drop state (0 init, 1 forming, 2 falling) SEGENV.aux0 = (SEGMENT.intensity ? (SEGMENT.intensity>>5)+1 : random8(1,5)) * (1+(SEGLEN>>6)); // size of brick } @@ -3477,7 +3516,7 @@ uint16_t mode_tetrix(void) { if (drop->pos > SEGENV.aux1) { // fall until top of stack drop->pos -= drop->speed; // may add gravity as: speed += gravity if (int(drop->pos) < SEGENV.aux1) drop->pos = SEGENV.aux1; - for (uint16_t i=int(drop->pos); ipos)+SEGENV.aux0 ? drop->col : SEGCOLOR(1)); + for (uint16_t i=int(drop->pos); ipos)+SEGENV.aux0 ? drop->col : SEGCOLOR(1)); } else { // we hit bottom SEGENV.step = 0; // go back to init SEGENV.aux1 += SEGENV.aux0; // increase the stack size @@ -3506,7 +3545,7 @@ uint16_t mode_plasma(void) { + cos8((i*(1+ 2*(SEGMENT.speed >> 5))+thatPhase) & 0xFF)/2; // factor=15 // Hey, you can even change the frequencies if you wish. uint8_t thisBright = qsub8(colorIndex, beatsin8(7,0, (128 - (SEGMENT.intensity>>1)))); CRGB color = ColorFromPalette(strip.currentPalette, colorIndex, thisBright, LINEARBLEND); - strip.setPixelColor(i, color.red, color.green, color.blue); + SEGMENT.setPixelColor(i, color.red, color.green, color.blue); } return FRAMETIME; @@ -3530,19 +3569,19 @@ uint16_t mode_percent(void) { if (percent < 100) { for (uint16_t i = 0; i < SEGLEN; i++) { if (i < SEGENV.step) { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } else { - strip.setPixelColor(i, SEGCOLOR(1)); + SEGMENT.setPixelColor(i, SEGCOLOR(1)); } } } else { for (uint16_t i = 0; i < SEGLEN; i++) { if (i < (SEGLEN - SEGENV.step)) { - strip.setPixelColor(i, SEGCOLOR(1)); + SEGMENT.setPixelColor(i, SEGCOLOR(1)); } else { - strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } } } @@ -3585,7 +3624,7 @@ uint16_t mode_heartbeat(void) { } for (uint16_t i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, color_blend(strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255 - (SEGENV.aux1 >> 8))); + SEGMENT.setPixelColor(i, color_blend(SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255 - (SEGENV.aux1 >> 8))); } return FRAMETIME; @@ -3673,7 +3712,7 @@ uint16_t mode_pacifica() SEGENV.step = sCIStart4; SEGENV.step = (SEGENV.step << 16) + sCIStart3; // Clear out the LED array to a dim background blue-green - //strip.fill(132618); + //SEGMENT.fill(132618); uint8_t basethreshold = beatsin8( 9, 55, 65); uint8_t wave = beat8( 7 ); @@ -3701,7 +3740,7 @@ uint16_t mode_pacifica() c.green = scale8(c.green, 200); c |= CRGB( 2, 5, 7); - strip.setPixelColor(i, c.red, c.green, c.blue); + SEGMENT.setPixelColor(i, c.red, c.green, c.blue); } strip.now = nowOld; @@ -3713,16 +3752,16 @@ static const char *_data_FX_MODE_PACIFICA PROGMEM = "Pacifica"; //Solid colour background with glitter uint16_t mode_solid_glitter() { - strip.fill(SEGCOLOR(0)); + SEGMENT.fill(SEGCOLOR(0)); if (strip.isMatrix) { uint16_t height = SEGMENT.virtualHeight(); uint16_t width = SEGMENT.virtualWidth(); for (uint16_t i = 0; i random8()) strip.setPixelColorXY(random16(width-1), i, ULTRAWHITE); + if (SEGMENT.intensity > random8()) SEGMENT.setPixelColorXY(random16(width-1), i, ULTRAWHITE); } } else - if (SEGMENT.intensity > random8()) strip.setPixelColor(random16(SEGLEN), ULTRAWHITE); + if (SEGMENT.intensity > random8()) SEGMENT.setPixelColor(random16(SEGLEN), ULTRAWHITE); return FRAMETIME; } @@ -3742,14 +3781,14 @@ uint16_t mode_sunrise() { SEGENV.aux0 = SEGMENT.speed; } - strip.fill(0); + SEGMENT.fill(0); uint16_t stage = 0xFFFF; uint32_t s10SinceStart = (millis() - SEGENV.step) /100; //tenths of seconds if (SEGMENT.speed > 120) { //quick sunrise and sunset uint16_t counter = (strip.now >> 1) * (((SEGMENT.speed -120) >> 1) +1); - stage = strip.triwave16(counter); + stage = triwave16(counter); } else if (SEGMENT.speed) { //sunrise uint8_t durMins = SEGMENT.speed; if (durMins > 60) durMins -= 60; @@ -3762,24 +3801,24 @@ uint16_t mode_sunrise() { for (uint16_t i = 0; i <= SEGLEN/2; i++) { //default palette is Fire - uint32_t c = strip.color_from_palette(0, false, true, 255); //background + uint32_t c = SEGMENT.color_from_palette(0, false, true, 255); //background - uint16_t wave = strip.triwave16((i * stage) / SEGLEN); + uint16_t wave = triwave16((i * stage) / SEGLEN); wave = (wave >> 8) + ((wave * SEGMENT.intensity) >> 15); if (wave > 240) { //clipped, full white sun - c = strip.color_from_palette( 240, false, true, 255); + c = SEGMENT.color_from_palette( 240, false, true, 255); } else { //transition - c = strip.color_from_palette(wave, false, true, 255); + c = SEGMENT.color_from_palette(wave, false, true, 255); } - strip.setPixelColor(i, c); - strip.setPixelColor(SEGLEN - i - 1, c); + SEGMENT.setPixelColor(i, c); + SEGMENT.setPixelColor(SEGLEN - i - 1, c); } return FRAMETIME; } -static const char *_data_FX_MODE_SUNRISE PROGMEM = "Sunrise@Time [min]=60,;;0"; +static const char *_data_FX_MODE_SUNRISE PROGMEM = "Sunrise@Time [min]=60,;;!=35"; /* @@ -3802,7 +3841,7 @@ uint16_t phased_base(uint8_t moder) { // We're making sine wave val += *phase * (i % modVal +1) /2; // This sets the varying phase change of the waves. By Andrew Tuline. uint8_t b = cubicwave8(val); // Now we make an 8 bit sinewave. b = (b > cutOff) ? (b - cutOff) : 0; // A ternary operator to cutoff the light. - strip.setPixelColor(i, color_blend(SEGCOLOR(1), strip.color_from_palette(index, false, false, 0), b)); + SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(index, false, false, 0), b)); index += 256 / SEGLEN; if (SEGLEN > 256) index ++; // Correction for segments longer than 256 LEDs } @@ -3834,9 +3873,9 @@ uint16_t mode_twinkleup(void) { // A very short twinkle routine uint8_t ranstart = random8(); // The starting value (aka brightness) for each pixel. Must be consistent each time through the loop for this to work. uint8_t pixBri = sin8(ranstart + 16 * strip.now/(256-SEGMENT.speed)); if (random8() > SEGMENT.intensity) pixBri = 0; - uint32_t col = color_blend(SEGCOLOR(1), strip.color_from_palette(random8() + strip.now/100, false, PALETTE_SOLID_WRAP, 0), pixBri); - if (strip.isMatrix) strip.setPixelColorXY(j, k, col); - else strip.setPixelColor(i, col); + uint32_t col = color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(random8() + strip.now/100, false, PALETTE_SOLID_WRAP, 0), pixBri); + if (strip.isMatrix) SEGMENT.setPixelColorXY(j, k, col); + else SEGMENT.setPixelColor(i, col); } return FRAMETIME; @@ -3873,7 +3912,7 @@ uint16_t mode_noisepal(void) { // Slow noise for(int i = 0; i < SEGLEN; i++) { uint8_t index = inoise8(i*scale, SEGENV.aux0+i*scale); // Get a value from the noise function. I'm using both x and y axis. color = ColorFromPalette(palettes[0], index, 255, LINEARBLEND); // Use the my own palette. - strip.setPixelColor(i, color.red, color.green, color.blue); + SEGMENT.setPixelColor(i, color.red, color.green, color.blue); } SEGENV.aux0 += beatsin8(10,1,4); // Moving along the distance. Vary it a bit with a sine wave. @@ -3897,7 +3936,7 @@ uint16_t mode_sinewave(void) { // Adjustable sinewave. By Andrew Tul for (int i=0; i> 1; - strip.fill(strip.color_from_palette(-counter, false, true, 255)); + SEGMENT.fill(SEGMENT.color_from_palette(-counter, false, true, 255)); for (uint16_t z = 0; z < zones; z++) { @@ -3934,13 +3973,13 @@ uint16_t mode_flow(void) uint8_t colorIndex = (i * 255 / zoneLen) - counter; uint16_t led = (z & 0x01) ? i : (zoneLen -1) -i; if (SEGMENT.getOption(SEG_OPTION_REVERSED)) led = (zoneLen -1) -led; - strip.setPixelColor(pos + led, strip.color_from_palette(colorIndex, false, true, 255)); + SEGMENT.setPixelColor(pos + led, SEGMENT.color_from_palette(colorIndex, false, true, 255)); } } return FRAMETIME; } -static const char *_data_FX_MODE_FLOW PROGMEM = "Flow"; +static const char *_data_FX_MODE_FLOW PROGMEM = "Flow@!,!;!,!,!;!=6"; /* @@ -3949,7 +3988,7 @@ static const char *_data_FX_MODE_FLOW PROGMEM = "Flow"; */ uint16_t mode_chunchun(void) { - strip.fill(SEGCOLOR(1)); + SEGMENT.fill(SEGCOLOR(1)); uint16_t counter = strip.now * (6 + (SEGMENT.speed >> 4)); uint16_t numBirds = 2 + (SEGLEN >> 3); // 2 + 1/8 of a segment uint16_t span = (SEGMENT.intensity << 8) / numBirds; @@ -3959,8 +3998,8 @@ uint16_t mode_chunchun(void) counter -= span; uint16_t megumin = sin16(counter) + 0x8000; uint16_t bird = uint32_t(megumin * SEGLEN) >> 16; - uint32_t c = strip.color_from_palette((i * 255)/ numBirds, false, false, 0); // no palette wrapping - strip.setPixelColor(bird, c); + uint32_t c = SEGMENT.color_from_palette((i * 255)/ numBirds, false, false, 0); // no palette wrapping + SEGMENT.setPixelColor(bird, c); } return FRAMETIME; } @@ -4007,7 +4046,7 @@ uint16_t mode_dancing_shadows(void) if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed Spotlight* spotlights = reinterpret_cast(SEGENV.data); - strip.fill(BLACK); + SEGMENT.fill(BLACK); unsigned long time = millis(); bool respawn = false; @@ -4049,19 +4088,19 @@ uint16_t mode_dancing_shadows(void) spotlights[i].type = random8(SPOT_TYPES_COUNT); } - uint32_t color = strip.color_from_palette(spotlights[i].colorIdx, false, false, 0); + uint32_t color = SEGMENT.color_from_palette(spotlights[i].colorIdx, false, false, 0); int start = spotlights[i].position; if (spotlights[i].width <= 1) { if (start >= 0 && start < SEGLEN) { - strip.blendPixelColor(start, color, 128); + SEGMENT.blendPixelColor(start, color, 128); } } else { switch (spotlights[i].type) { case SPOT_TYPE_SOLID: for (uint8_t j = 0; j < spotlights[i].width; j++) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - strip.blendPixelColor(start + j, color, 128); + SEGMENT.blendPixelColor(start + j, color, 128); } } break; @@ -4069,7 +4108,7 @@ uint16_t mode_dancing_shadows(void) case SPOT_TYPE_GRADIENT: for (uint8_t j = 0; j < spotlights[i].width; j++) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - strip.blendPixelColor(start + j, color, cubicwave8(map(j, 0, spotlights[i].width - 1, 0, 255))); + SEGMENT.blendPixelColor(start + j, color, cubicwave8(map(j, 0, spotlights[i].width - 1, 0, 255))); } } break; @@ -4077,7 +4116,7 @@ uint16_t mode_dancing_shadows(void) case SPOT_TYPE_2X_GRADIENT: for (uint8_t j = 0; j < spotlights[i].width; j++) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - strip.blendPixelColor(start + j, color, cubicwave8(2 * map(j, 0, spotlights[i].width - 1, 0, 255))); + SEGMENT.blendPixelColor(start + j, color, cubicwave8(2 * map(j, 0, spotlights[i].width - 1, 0, 255))); } } break; @@ -4085,7 +4124,7 @@ uint16_t mode_dancing_shadows(void) case SPOT_TYPE_2X_DOT: for (uint8_t j = 0; j < spotlights[i].width; j += 2) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - strip.blendPixelColor(start + j, color, 128); + SEGMENT.blendPixelColor(start + j, color, 128); } } break; @@ -4093,7 +4132,7 @@ uint16_t mode_dancing_shadows(void) case SPOT_TYPE_3X_DOT: for (uint8_t j = 0; j < spotlights[i].width; j += 3) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - strip.blendPixelColor(start + j, color, 128); + SEGMENT.blendPixelColor(start + j, color, 128); } } break; @@ -4101,7 +4140,7 @@ uint16_t mode_dancing_shadows(void) case SPOT_TYPE_4X_DOT: for (uint8_t j = 0; j < spotlights[i].width; j += 4) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - strip.blendPixelColor(start + j, color, 128); + SEGMENT.blendPixelColor(start + j, color, 128); } } break; @@ -4119,7 +4158,7 @@ static const char *_data_FX_MODE_DANCING_SHADOWS PROGMEM = "Dancing Shadows@!,# By Stefan Seegel */ uint16_t mode_washing_machine(void) { - float speed = strip.tristate_square8(strip.now >> 7, 90, 15); + float speed = tristate_square8(strip.now >> 7, 90, 15); float quot = 32.0f - ((float)SEGMENT.speed / 16.0f); speed /= quot; @@ -4127,7 +4166,7 @@ uint16_t mode_washing_machine(void) { for (int i=0; i> 7)); - strip.setPixelColor(i, strip.color_from_palette(col, false, PALETTE_SOLID_WRAP, 3)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(col, false, PALETTE_SOLID_WRAP, 3)); } return FRAMETIME; @@ -4148,13 +4187,13 @@ uint16_t mode_blends(void) { uint8_t shift = (strip.now * ((SEGMENT.speed >> 3) +1)) >> 8; for (int i = 0; i < pixelLen; i++) { - pixels[i] = color_blend(pixels[i], strip.color_from_palette(shift + quadwave8((i + 1) * 16), false, PALETTE_SOLID_WRAP, 255), blendSpeed); + pixels[i] = color_blend(pixels[i], SEGMENT.color_from_palette(shift + quadwave8((i + 1) * 16), false, PALETTE_SOLID_WRAP, 255), blendSpeed); shift += 3; } uint16_t offset = 0; for (int i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, pixels[offset++]); + SEGMENT.setPixelColor(i, pixels[offset++]); if (offset > pixelLen) offset = 0; } @@ -4276,7 +4315,7 @@ uint16_t mode_tv_simulator(void) { // set strip color for (i = 0; i < SEGLEN; i++) { - strip.setPixelColor(i, r >> 8, g >> 8, b >> 8); // Quantize to 8-bit + SEGMENT.setPixelColor(i, r >> 8, g >> 8, b >> 8); // Quantize to 8-bit } // if total duration has passed, remember last color and restart the loop @@ -4413,7 +4452,7 @@ uint16_t mode_aurora(void) { waves = reinterpret_cast(SEGENV.data); for(int i = 0; i < SEGENV.aux1; i++) { - waves[i].init(SEGLEN, CRGB(strip.color_from_palette(random8(), false, false, random(0, 3)))); + waves[i].init(SEGLEN, CRGB(SEGMENT.color_from_palette(random8(), false, false, random(0, 3)))); } } else { waves = reinterpret_cast(SEGENV.data); @@ -4425,7 +4464,7 @@ uint16_t mode_aurora(void) { if(!(waves[i].stillAlive())) { //If a wave dies, reinitialize it starts over. - waves[i].init(SEGLEN, CRGB(strip.color_from_palette(random8(), false, false, random(0, 3)))); + waves[i].init(SEGLEN, CRGB(SEGMENT.color_from_palette(random8(), false, false, random(0, 3)))); } } @@ -4447,7 +4486,7 @@ uint16_t mode_aurora(void) { } } - strip.setPixelColor(i, mixedRgb[0], mixedRgb[1], mixedRgb[2]); + SEGMENT.setPixelColor(i, mixedRgb[0], mixedRgb[1], mixedRgb[2]); } return FRAMETIME; @@ -4463,11 +4502,11 @@ static const char *_data_FX_MODE_AURORA PROGMEM = "Aurora@!=24,!;1,2,3;!=50"; // Controls are speed, # of pixels, faderate. uint16_t mode_perlinmove(void) { - strip.fade_out(255-SEGMENT.custom1); + SEGMENT.fade_out(255-SEGMENT.custom1); for (uint16_t i = 0; i < SEGMENT.intensity/16 + 1; i++) { uint16_t locn = inoise16(millis()*128/(260-SEGMENT.speed)+i*15000, millis()*128/(260-SEGMENT.speed)); // Get a new pixel location from moving noise. uint16_t pixloc = map(locn, 50*256, 192*256, 0, SEGLEN-1); // Map that to the length of the strand, and ensure we don't go over. - strip.setPixelColor(pixloc, strip.color_from_palette(pixloc%255, false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(pixloc, SEGMENT.color_from_palette(pixloc%255, false, PALETTE_SOLID_WRAP, 0)); } return FRAMETIME; @@ -4483,7 +4522,7 @@ uint16_t mode_wavesins(void) { for (uint16_t i = 0; i < SEGLEN; i++) { uint8_t bri = sin8(millis()/4 + i * SEGMENT.intensity); - strip.setPixelColor(i, ColorFromPalette(strip.currentPalette, beatsin8(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * SEGMENT.custom3), bri, LINEARBLEND)); + SEGMENT.setPixelColor(i, ColorFromPalette(strip.currentPalette, beatsin8(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * SEGMENT.custom3), bri, LINEARBLEND)); } return FRAMETIME; @@ -4506,7 +4545,7 @@ uint16_t mode_FlowStripe(void) { c = sin8(c); c = sin8(c / 2 + t); byte b = sin8(c + t/8); - strip.setPixelColor(i, CHSV(b + hue, 255, 255)); + SEGMENT.setPixelColor(i, CHSV(b + hue, 255, 255)); } return FRAMETIME; @@ -4514,9 +4553,10 @@ uint16_t mode_FlowStripe(void) { static const char *_data_FX_MODE_FLOWSTRIPE PROGMEM = "Flow Stripe@Hue speed,Effect speed;;"; +#ifndef WLED_DISABLE_2D /////////////////////////////////////////////////////////////////////////////// //*************************** 2D routines *********************************** -#define XY(x,y) strip.XY(x,y) +#define XY(x,y) SEGMENT.XY(x,y) // Black hole @@ -4534,10 +4574,10 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma // initialize on first call if (SEGENV.call == 0) { - strip.fill_solid(leds, CRGB::Black); + SEGMENT.fill_solid(leds, CRGB::Black); } - strip.fadeToBlackBy(leds, 16 + (SEGMENT.speed>>3)); // create fading trails + SEGMENT.fadeToBlackBy(leds, 16 + (SEGMENT.speed>>3)); // create fading trails float t = (float)(millis())/128; // timebase // outer stars for (byte i = 0; i < 8; i++) { @@ -4554,9 +4594,9 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma // central white dot leds[XY(cols/2,rows/2)] = CHSV(0,0,255); // blur everything a bit - strip.blur2d(leds, 16); + SEGMENT.blur2d(leds, 16); - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2DBlackHole() static const char *_data_FX_MODE_2DBLACKHOLE PROGMEM = "2D Black Hole@Fade rate,Outer Y freq.,Outer X freq.,Inner X freq.,Inner Y freq.;;"; @@ -4576,7 +4616,7 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so CRGB *leds = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { - strip.fill_solid(leds, CRGB::Black); + SEGMENT.fill_solid(leds, CRGB::Black); //for (uint16_t i = 0; i < w*h; i++) leds[i] = CRGB::Black; SEGENV.aux0 = 0; // start with red hue } @@ -4587,7 +4627,7 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so byte numLines = SEGMENT.intensity/16 + 1; SEGENV.aux0++; // hue - strip.fadeToBlackBy(leds, 40); + SEGMENT.fadeToBlackBy(leds, 40); for (byte i = 0; i < numLines; i++) { byte x1 = beatsin8(2 + SEGMENT.speed/16, 0, (cols - 1)); @@ -4613,9 +4653,9 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so leds[XY(y1, y2)] += CRGB::White; } } - strip.blur2d(leds, 4); + SEGMENT.blur2d(leds, 4); - strip.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. + SEGMENT.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. return FRAMETIME; } // mode_2DColoredBursts() static const char *_data_FX_MODE_2DCOLOREDBURSTS PROGMEM = "2D Colored Bursts@Speed,# of lines;;!"; @@ -4634,17 +4674,17 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, 0); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, 0); - strip.fadeToBlackBy(leds, 64); + SEGMENT.fadeToBlackBy(leds, 64); for(int i = 0; i < cols; i++) { leds[XY(i, beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4))] = ColorFromPalette(strip.currentPalette, i*5+millis()/17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND); leds[XY(i, beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4+128))] = ColorFromPalette(strip.currentPalette,i*5+128+millis()/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND); // 180 degrees (128) out of phase } - strip.blur2d(leds, SEGMENT.intensity/8); + SEGMENT.blur2d(leds, SEGMENT.intensity/8); - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2Ddna() static const char *_data_FX_MODE_2DDNA PROGMEM = "2D DNA@Scroll speed,Blur;;!"; @@ -4664,7 +4704,7 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma CRGB *leds = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { - strip.fill_solid(leds, CRGB::Black); + SEGMENT.fill_solid(leds, CRGB::Black); SEGENV.aux0 = 0; // hue } @@ -4672,7 +4712,7 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma uint8_t freq = SEGMENT.intensity/8; uint32_t ms = millis() / 20; - strip.nscale8(leds, 120); + SEGMENT.nscale8(leds, 120); for (uint16_t i = 0; i < rows; i++) { uint16_t x = beatsin8(speeds, 0, cols - 1, 0, i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, i * freq + 128); @@ -4692,7 +4732,7 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma } } - strip.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. + SEGMENT.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. return FRAMETIME; } // mode_2DDNASpiral() static const char *_data_FX_MODE_2DDNASPIRAL PROGMEM = "2D DNA Spiral@Scroll speed,Blur;;!"; @@ -4713,9 +4753,9 @@ uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmateli if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); - strip.fadeToBlackBy(leds, 128); + SEGMENT.fadeToBlackBy(leds, 128); const uint16_t maxDim = MAX(cols, rows)/2; unsigned long t = millis() / (32 - (SEGMENT.speed>>3)); @@ -4725,9 +4765,9 @@ uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmateli uint16_t myY = (rows>>1) + (uint16_t)(cos_t(angle) * i) + (rows%2); leds[XY(myX,myY)] = ColorFromPalette(strip.currentPalette, (i * 20) + (t / 20), 255, LINEARBLEND); } - strip.blur2d(leds, SEGMENT.intensity>>3); + SEGMENT.blur2d(leds, SEGMENT.intensity>>3); - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2DDrift() static const char *_data_FX_MODE_2DDRIFT PROGMEM = "2D Drift@Rotation speed,Blur amount;;!"; @@ -4746,7 +4786,7 @@ uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); uint16_t xscale = SEGMENT.intensity*4; uint32_t yscale = SEGMENT.speed*8; @@ -4764,7 +4804,7 @@ uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline } // for i } // for j - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2Dfirenoise() static const char *_data_FX_MODE_2DFIRENOISE PROGMEM = "2D Firenoise@X scale,Y scale;;"; @@ -4783,15 +4823,15 @@ uint16_t mode_2DFrizzles(void) { // By: Stepko https://editor.so if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); - strip.fadeToBlackBy(leds, 16); + SEGMENT.fadeToBlackBy(leds, 16); for (byte i = 8; i > 0; i--) { leds[XY(beatsin8(SEGMENT.speed/8 + i, 0, cols - 1), beatsin8(SEGMENT.intensity/8 - i, 0, rows - 1))] += ColorFromPalette(strip.currentPalette, beatsin8(12, 0, 255), 255, LINEARBLEND); } - strip.blur2d(leds, 16); + SEGMENT.blur2d(leds, 16); - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2DFrizzles() static const char *_data_FX_MODE_2DFRIZZLES PROGMEM = "2D Frizzles@X frequency,Y frequency;;!"; @@ -4830,10 +4870,10 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https: if (state == 0) leds[XY(x,y)] = backgroundColor; else - leds[XY(x,y)] = (CRGB)strip.color_from_palette(random8(), false, PALETTE_SOLID_WRAP, 0); + leds[XY(x,y)] = (CRGB)SEGMENT.color_from_palette(random8(), false, PALETTE_SOLID_WRAP, 0); } - strip.fill_solid(prevLeds, CRGB::Black); + SEGMENT.fill_solid(prevLeds, CRGB::Black); SEGENV.aux1 = 0; SEGENV.aux0 = 0xFFFF; @@ -4894,7 +4934,7 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https: SEGENV.aux1 = SEGENV.aux0; SEGENV.aux0 = crc; - strip.setPixels(leds); + SEGMENT.setPixels(leds); return (SEGMENT.getOption(SEG_OPTION_TRANSITIONAL)) ? FRAMETIME : FRAMETIME_FIXED * (128-(SEGMENT.speed>>1)); // update only when appropriate time passes (in 42 FPS slots) } // mode_2Dgameoflife() static const char *_data_FX_MODE_2DGAMEOFLIFE PROGMEM = "2D Game Of Life@!,;!,!;!"; @@ -4912,7 +4952,7 @@ uint16_t mode_2DHiphotic() { // By: ldirko https://edit for (uint16_t x = 0; x < cols; x++) { for (uint16_t y = 0; y < rows; y++) { - strip.setPixelColorXY(x, y, strip.color_from_palette(sin8(cos8(x * SEGMENT.speed/16 + a / 3) + sin8(y * SEGMENT.intensity/16 + a / 4) + a), false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(sin8(cos8(x * SEGMENT.speed/16 + a / 3) + sin8(y * SEGMENT.intensity/16 + a / 4) + a), false, PALETTE_SOLID_WRAP, 0)); } } @@ -5023,9 +5063,9 @@ uint16_t mode_2DJulia(void) { // An animated Julia set // We color each pixel based on how long it takes to get to infinity, or black if it never gets there. if (iter == maxIterations) { - strip.setPixelColorXY(i, j, 0); + SEGMENT.setPixelColorXY(i, j, 0); } else { - strip.setPixelColorXY(i, j, strip.color_from_palette(iter*255/maxIterations, false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColorXY(i, j, SEGMENT.color_from_palette(iter*255/maxIterations, false, PALETTE_SOLID_WRAP, 0)); } x += dx; } @@ -5047,8 +5087,8 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - strip.fadeToBlackBy(SEGMENT.intensity); - //strip.fade_out(SEGMENT.intensity); + SEGMENT.fadeToBlackBy(SEGMENT.intensity); + //SEGMENT.fade_out(SEGMENT.intensity); //for (int i=0; i < 4*(cols+rows); i ++) { for (int i=0; i < 256; i ++) { @@ -5058,7 +5098,7 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline uint8_t ylocn = cos8(strip.now/2+i*2); xlocn = map(xlocn,0,255,0,cols-1); ylocn = map(ylocn,0,255,0,rows-1); - strip.setPixelColorXY(xlocn, ylocn, strip.color_from_palette(strip.now/100+i, false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColorXY(xlocn, ylocn, SEGMENT.color_from_palette(strip.now/100+i, false, PALETTE_SOLID_WRAP, 0)); } return FRAMETIME; @@ -5079,7 +5119,7 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); uint8_t fade = map(SEGMENT.custom1, 0, 255, 50, 250); // equals trail size uint8_t speed = (256-SEGMENT.speed) >> map(MIN(rows, 150), 0, 150, 0, 3); // slower speeds for small displays @@ -5125,7 +5165,7 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. leds[XY(spawnX, 0)] = spawnColor; } - strip.setPixels(leds); + SEGMENT.setPixels(leds); } // if millis return FRAMETIME; @@ -5176,14 +5216,14 @@ uint16_t mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have // map color between thresholds if (color > 0 and color < 60) { - strip.setPixelColorXY(x, y, strip.color_from_palette(map(color * 9, 9, 531, 0, 255), false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(map(color * 9, 9, 531, 0, 255), false, PALETTE_SOLID_WRAP, 0)); } else { - strip.setPixelColorXY(x, y, strip.color_from_palette(0, false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(0, false, PALETTE_SOLID_WRAP, 0)); } // show the 3 points, too - strip.setPixelColorXY(x1, y1, CRGB::White); - strip.setPixelColorXY(x2, y2, CRGB::White); - strip.setPixelColorXY(x3, y3, CRGB::White); + SEGMENT.setPixelColorXY(x1, y1, CRGB::White); + SEGMENT.setPixelColorXY(x2, y2, CRGB::White); + SEGMENT.setPixelColorXY(x3, y3, CRGB::White); } } @@ -5207,7 +5247,7 @@ uint16_t mode_2Dnoise(void) { // By Andrew Tuline for (uint16_t y = 0; y < rows; y++) { for (uint16_t x = 0; x < cols; x++) { uint8_t pixelHue8 = inoise8(x * scale, y * scale, millis() / (16 - SEGMENT.speed/16)); - strip.setPixelColorXY(x, y, ColorFromPalette(strip.currentPalette, pixelHue8)); + SEGMENT.setPixelColorXY(x, y, ColorFromPalette(strip.currentPalette, pixelHue8)); } } @@ -5229,9 +5269,9 @@ uint16_t mode_2DPlasmaball(void) { // By: Stepko https://edito if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); - strip.fadeToBlackBy(leds, 64); + SEGMENT.fadeToBlackBy(leds, 64); float t = millis() / (33 - SEGMENT.speed/8); for (uint16_t i = 0; i < cols; i++) { uint16_t thisVal = inoise8(i * 30, t, t); @@ -5252,9 +5292,9 @@ uint16_t mode_2DPlasmaball(void) { // By: Stepko https://edito (rows - 1 - cy == 0)) ? ColorFromPalette(strip.currentPalette, beat8(5), thisVal, LINEARBLEND) : CRGB::Black; } } - strip.blur2d(leds, 4); + SEGMENT.blur2d(leds, 4); - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2DPlasmaball() static const char *_data_FX_MODE_2DPLASMABALL PROGMEM = "2D Plasma Ball@Speed;!,!,!;!"; @@ -5280,7 +5320,7 @@ uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https if (SEGENV.call == 0) { SEGENV.step = 0; - strip.fill_solid(leds, CRGB::Black); + SEGMENT.fill_solid(leds, CRGB::Black); } float adjustHeight = (float)map(rows, 8, 32, 28, 12); @@ -5313,7 +5353,7 @@ uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https } } - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2DPolarLights() static const char *_data_FX_MODE_2DPOLARLIGHTS PROGMEM = "2D Polar Lights@Speed,Scale;;"; @@ -5332,9 +5372,9 @@ uint16_t mode_2DPulser(void) { // By: ldirko https://edi if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); - strip.fadeToBlackBy(leds, 8 - (SEGMENT.intensity>>5)); + SEGMENT.fadeToBlackBy(leds, 8 - (SEGMENT.intensity>>5)); uint16_t a = strip.now / (18 - SEGMENT.speed / 16); uint16_t x = (a / 14); @@ -5342,9 +5382,9 @@ uint16_t mode_2DPulser(void) { // By: ldirko https://edi uint16_t index = XY(x, y); // XY() will wrap x or y leds[index] = ColorFromPalette(strip.currentPalette, map(y, 0, rows-1, 0, 255), 255, LINEARBLEND); - strip.blur2d(leds, 1 + (SEGMENT.intensity>>4)); + SEGMENT.blur2d(leds, 1 + (SEGMENT.intensity>>4)); - strip.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. + SEGMENT.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. return FRAMETIME; } // mode_2DPulser() static const char *_data_FX_MODE_2DPULSER PROGMEM = "2D Pulser@Speed,Blur;;!"; @@ -5363,9 +5403,9 @@ uint16_t mode_2DSindots(void) { // By: ldirko http if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); - strip.fadeToBlackBy(leds, 15); + SEGMENT.fadeToBlackBy(leds, 15); byte t1 = millis() / (257 - SEGMENT.speed); // 20; byte t2 = sin8(t1) / 4 * 2; for (uint16_t i = 0; i < 13; i++) { @@ -5373,9 +5413,9 @@ uint16_t mode_2DSindots(void) { // By: ldirko http byte y = sin8(t2 + i * SEGMENT.intensity/8)*(rows-1)/255; // max index now 255x15/255=15! leds[XY(x, y)] = ColorFromPalette(strip.currentPalette, i * 255 / 13, 255, LINEARBLEND); } - strip.blur2d(leds, 16); + SEGMENT.blur2d(leds, 16); - strip.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. + SEGMENT.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. return FRAMETIME; } // mode_2DSindots() static const char *_data_FX_MODE_2DSINDOTS PROGMEM = "2D Sindots@Speed,Dot distance;;!"; @@ -5396,13 +5436,13 @@ uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://g if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); const uint8_t kBorderWidth = 2; - strip.fadeToBlackBy(leds, 24); + SEGMENT.fadeToBlackBy(leds, 24); uint8_t blurAmount = SEGMENT.custom3>>4; - strip.blur2d(leds, blurAmount); + SEGMENT.blur2d(leds, blurAmount); // Use two out-of-sync sine waves uint8_t i = beatsin8(19, kBorderWidth, cols-kBorderWidth); @@ -5418,7 +5458,7 @@ uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://g leds[XY(j, n)] += ColorFromPalette(strip.currentPalette, ms/41, 255, LINEARBLEND); leds[XY(k, p)] += ColorFromPalette(strip.currentPalette, ms/73, 255, LINEARBLEND); - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2Dsquaredswirl() static const char *_data_FX_MODE_2DSQUAREDSWIRL PROGMEM = "2D Squared Swirl@,,,,Blur;,,;!"; @@ -5438,7 +5478,7 @@ uint16_t mode_2DSunradiation(void) { // By: ldirko https://edi CRGB *leds = reinterpret_cast(SEGENV.data); byte *bump = reinterpret_cast(SEGENV.data + dataSize); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); unsigned long t = millis() / 4; int index = 0; @@ -5469,7 +5509,7 @@ uint16_t mode_2DSunradiation(void) { // By: ldirko https://edi yindex += (cols + 2); } - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2DSunradiation() static const char *_data_FX_MODE_2DSUNRADIATION PROGMEM = "2D Sun Radiation@Variance,Brightness;;"; @@ -5488,7 +5528,7 @@ uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.so if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); uint8_t hue; int offsetX = beatsin16(3, -360, 360); @@ -5504,7 +5544,7 @@ uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.so } } - strip.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. + SEGMENT.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. return FRAMETIME; } // mode_2DTartan() static const char *_data_FX_MODE_2DTARTAN PROGMEM = "2D Tartan@X scale,Y scale;;!"; @@ -5523,7 +5563,7 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); uint32_t tb = strip.now >> 12; // every ~4s if (tb > SEGENV.step) { @@ -5535,8 +5575,8 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht SEGENV.step = tb + random8(4); } - strip.fadeToBlackBy(leds, map(SEGMENT.speed, 0, 255, 248, 16)); - strip.move(SEGENV.aux0, 1, leds); + SEGMENT.fadeToBlackBy(leds, map(SEGMENT.speed, 0, 255, 248, 16)); + SEGMENT.move(SEGENV.aux0, 1, leds); for (byte i = 0; i < 8; i++) { byte x = beatsin8(12 + i, 2, cols - 3); byte y = beatsin8(15 + i, 2, rows - 3); @@ -5549,12 +5589,12 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht leds[XY(x, y - 1)] += color; } } - strip.blur2d(leds, SEGMENT.intensity>>3); + SEGMENT.blur2d(leds, SEGMENT.intensity>>3); - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } -static const char *_data_FX_MODE_SPACESHIPS PROGMEM = "2D Spaceships@!,Blur;!,!,!;!"; +static const char *_data_FX_MODE_2DSPACESHIPS PROGMEM = "2D Spaceships@!,Blur;!,!,!;!"; ///////////////////////// @@ -5592,7 +5632,7 @@ uint16_t mode_2Dcrazybees(void) { bee_t *bee = reinterpret_cast(SEGENV.data + dataSize); if (SEGENV.call == 0) { - strip.fill_solid(leds, CRGB::Black); + SEGMENT.fill_solid(leds, CRGB::Black); for (byte i = 0; i < n; i++) { bee[i].posX = random8(0, cols); bee[i].posY = random8(0, rows); @@ -5603,7 +5643,7 @@ uint16_t mode_2Dcrazybees(void) { if (millis() > SEGENV.step) { SEGENV.step = millis() + (FRAMETIME * 8 / ((SEGMENT.speed>>5)+1)); - strip.fadeToBlackBy(leds, 32); + SEGMENT.fadeToBlackBy(leds, 32); for (byte i = 0; i < n; i++) { leds[XY(bee[i].aimX + 1, bee[i].aimY)] += CHSV(bee[i].hue, 255, 255); @@ -5625,13 +5665,13 @@ uint16_t mode_2Dcrazybees(void) { bee[i].aimed(cols, rows); } } - strip.blur2d(leds, SEGMENT.intensity>>4); + SEGMENT.blur2d(leds, SEGMENT.intensity>>4); - strip.setPixels(leds); + SEGMENT.setPixels(leds); } return FRAMETIME; } -static const char *_data_FX_MODE_CRAZYBEES PROGMEM = "2D Crazy Bees@!,Blur;;"; +static const char *_data_FX_MODE_2DCRAZYBEES PROGMEM = "2D Crazy Bees@!,Blur;;"; ///////////////////////// @@ -5668,7 +5708,7 @@ uint16_t mode_2Dghostrider(void) { if (SEGENV.call == 0 || SEGENV.aux0 != cols || SEGENV.aux1 != rows) { SEGENV.aux0 = cols; SEGENV.aux1 = rows; - strip.fill_solid(leds, CRGB::Black); + SEGMENT.fill_solid(leds, CRGB::Black); randomSeed(strip.now); lighter->angleSpeed = random8(0,20) - 10; lighter->Vspeed = 5; @@ -5684,10 +5724,10 @@ uint16_t mode_2Dghostrider(void) { if (millis() > SEGENV.step) { SEGENV.step = millis() + 1024 / (cols+rows); - strip.fadeToBlackBy(leds, (SEGMENT.speed>>2)+64); + SEGMENT.fadeToBlackBy(leds, (SEGMENT.speed>>2)+64); CRGB color = CRGB::White; - strip.wu_pixel(leds, lighter->gPosX * 256 / 10, lighter->gPosY * 256 / 10, color); + SEGMENT.wu_pixel(leds, lighter->gPosX * 256 / 10, lighter->gPosY * 256 / 10, color); lighter->gPosX += lighter->Vspeed * sin_t(radians(lighter->gAngle)); lighter->gPosY += lighter->Vspeed * cos_t(radians(lighter->gAngle)); @@ -5715,15 +5755,15 @@ uint16_t mode_2Dghostrider(void) { lighter->lightersPosX[i] += -7 * sin_t(radians(lighter->Angle[i])); lighter->lightersPosY[i] += -7 * cos_t(radians(lighter->Angle[i])); } - strip.wu_pixel(leds, lighter->lightersPosX[i] * 256 / 10, lighter->lightersPosY[i] * 256 / 10, ColorFromPalette(strip.currentPalette, (256 - lighter->time[i]))); + SEGMENT.wu_pixel(leds, lighter->lightersPosX[i] * 256 / 10, lighter->lightersPosY[i] * 256 / 10, ColorFromPalette(strip.currentPalette, (256 - lighter->time[i]))); } - strip.blur2d(leds, SEGMENT.intensity>>3); + SEGMENT.blur2d(leds, SEGMENT.intensity>>3); } - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } -static const char *_data_FX_MODE_GHOST_RIDER PROGMEM = "2D Ghost Rider@Fade rate,Blur;!,!,!;!"; +static const char *_data_FX_MODE_2DGHOSTRIDER PROGMEM = "2D Ghost Rider@Fade rate,Blur;!,!,!;!"; //////////////////////////// @@ -5755,7 +5795,7 @@ uint16_t mode_2Dfloatingblobs(void) { if (SEGENV.call == 0 || SEGENV.aux0 != cols || SEGENV.aux1 != rows) { SEGENV.aux0 = cols; SEGENV.aux1 = rows; - strip.fill_solid(leds, CRGB::Black); + SEGMENT.fill_solid(leds, CRGB::Black); for (byte i = 0; i < MAX_BLOBS; i++) { blob->r[i] = cols>15 ? random8(1, cols/8.f) : 1; blob->sX[i] = (float) random8(3, cols) / (float)(256 - SEGMENT.speed); // speed x @@ -5769,7 +5809,7 @@ uint16_t mode_2Dfloatingblobs(void) { } } - strip.fadeToBlackBy(leds, 20); + SEGMENT.fadeToBlackBy(leds, 20); // Bounce balls around for (byte i = 0; i < Amount; i++) { @@ -5790,7 +5830,7 @@ uint16_t mode_2Dfloatingblobs(void) { } CRGB c = ColorFromPalette(strip.currentPalette, blob->color[i]); //if (!SEGMENT.palette) c = SEGCOLOR(0); - if (blob->r[i] > 1.f) strip.fill_circle(leds, blob->y[i], blob->x[i], blob->r[i], c); + if (blob->r[i] > 1.f) SEGMENT.fill_circle(leds, blob->y[i], blob->x[i], blob->r[i], c); else leds[XY(blob->y[i], blob->x[i])] += c; // move x if (blob->x[i] + blob->r[i] >= cols - 1) blob->x[i] += (blob->sX[i] * ((cols - 1 - blob->x[i]) / blob->r[i] + 0.005f)); @@ -5819,15 +5859,15 @@ uint16_t mode_2Dfloatingblobs(void) { blob->y[i] = rows - 1.01f; } } - strip.blur2d(leds, cols+rows); + SEGMENT.blur2d(leds, cols+rows); if (SEGENV.step < millis()) SEGENV.step = millis() + 2000; // change colors every 2 seconds - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } #undef MAX_BLOBS -static const char *_data_FX_MODE_BLOBS PROGMEM = "2D Blobs@!,# blobs;!,!,!;!"; +static const char *_data_FX_MODE_2DBLOBS PROGMEM = "2D Blobs@!,# blobs;!,!,!;!"; //////////////////////////// @@ -5867,17 +5907,17 @@ uint16_t mode_2Dscrollingtext(void) { SEGENV.step = millis() + map(SEGMENT.speed, 0, 255, 10*FRAMETIME_FIXED, 2*FRAMETIME_FIXED); } - strip.fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color + SEGMENT.fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color for (uint16_t i = 0; i < numberOfLetters; i++) { if (int(cols) - int(SEGENV.aux0) + letterWidth*(i+1) < 0) continue; // don't draw characters off-screen if (text[i]<32 || text[i]>126) continue; // skip non-ANSII characters (may add UTF translation at some point) - strip.drawCharacter(text[i], int(cols) - int(SEGENV.aux0) + letterWidth*i, yoffset, letterWidth, letterHeight, strip.color_from_palette(SEGENV.aux1, false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.drawCharacter(text[i], int(cols) - int(SEGENV.aux0) + letterWidth*i, yoffset, letterWidth, letterHeight, SEGMENT.color_from_palette(SEGENV.aux1, false, PALETTE_SOLID_WRAP, 0)); } return FRAMETIME; } -static const char *_data_FX_MODE_SCROLL_TEXT PROGMEM = "2D Scrolling Text@!,Y Offset,Trail=0,Font size;!,!;!"; +static const char *_data_FX_MODE_2DSCROLLTEXT PROGMEM = "2D Scrolling Text@!,Y Offset,Trail=0,Font size;!,!;!"; //////////////////////////// @@ -5899,21 +5939,23 @@ uint16_t mode_2Ddriftrose(void) { CRGB *leds = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { - strip.fill_solid(leds, CRGB::Black); + SEGMENT.fill_solid(leds, CRGB::Black); } - strip.fadeToBlackBy(leds, 32+(SEGMENT.speed>>3)); + SEGMENT.fadeToBlackBy(leds, 32+(SEGMENT.speed>>3)); for (byte i = 1; i < 37; i++) { uint32_t x = (CX + (sin_t(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f; uint32_t y = (CY + (cos_t(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f; - strip.wu_pixel(leds, x, y, CHSV(i * 10, 255, 255)); + SEGMENT.wu_pixel(leds, x, y, CHSV(i * 10, 255, 255)); } - strip.blur2d(leds, (SEGMENT.intensity>>4)+1); + SEGMENT.blur2d(leds, (SEGMENT.intensity>>4)+1); - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } -static const char *_data_FX_MODE_DRIFT_ROSE PROGMEM = "2D Drift Rose@Fade,Blur;;"; +static const char *_data_FX_MODE_2DDRIFTROSE PROGMEM = "2D Drift Rose@Fade,Blur;;"; + +#endif // WLED_DISABLE_2D /////////////////////////////////////////////////////////////////////////////// @@ -6126,22 +6168,22 @@ uint16_t mode_ripplepeak(void) { // * Ripple peak. By Andrew Tuli } uint8_t samplePeak = *(uint8_t*)um_data->u_data[5]; float FFT_MajorPeak = *(float*) um_data->u_data[6]; - uint8_t maxVol = *(uint8_t*)um_data->u_data[9]; - uint8_t binNum = *(uint8_t*)um_data->u_data[10]; + uint8_t *maxVol = (uint8_t*)um_data->u_data[9]; + uint8_t *binNum = (uint8_t*)um_data->u_data[10]; // printUmData(); if (SEGENV.call == 0) { SEGENV.aux0 = 255; - SEGMENT.custom2 = binNum; - SEGMENT.custom3 = maxVol * 2; + SEGMENT.custom2 = *binNum; + SEGMENT.custom3 = *maxVol * 2; } - binNum = SEGMENT.custom2; // Select a bin. - maxVol = SEGMENT.custom3/2; // Our volume comparator. + *binNum = SEGMENT.custom2; // Select a bin. + *maxVol = SEGMENT.custom3/2; // Our volume comparator. - strip.fade_out(240); // Lower frame rate means less effective fading than FastLED - strip.fade_out(240); + SEGMENT.fade_out(240); // Lower frame rate means less effective fading than FastLED + SEGMENT.fade_out(240); for (uint16_t i = 0; i < SEGMENT.intensity/16; i++) { // Limit the number of ripples. if (samplePeak) ripples[i].state = 255; @@ -6161,7 +6203,7 @@ uint16_t mode_ripplepeak(void) { // * Ripple peak. By Andrew Tuli break; case 0: - strip.setPixelColor(ripples[i].pos, color_blend(SEGCOLOR(1), strip.color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0)); + SEGMENT.setPixelColor(ripples[i].pos, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0)); ripples[i].state++; break; @@ -6170,8 +6212,8 @@ uint16_t mode_ripplepeak(void) { // * Ripple peak. By Andrew Tuli break; default: // Middle of the ripples. - strip.setPixelColor((ripples[i].pos + ripples[i].state + SEGLEN) % SEGLEN, color_blend(SEGCOLOR(1), strip.color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0/ripples[i].state*2)); - strip.setPixelColor((ripples[i].pos - ripples[i].state + SEGLEN) % SEGLEN, color_blend(SEGCOLOR(1), strip.color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0/ripples[i].state*2)); + SEGMENT.setPixelColor((ripples[i].pos + ripples[i].state + SEGLEN) % SEGLEN, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0/ripples[i].state*2)); + SEGMENT.setPixelColor((ripples[i].pos - ripples[i].state + SEGLEN) % SEGLEN, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0/ripples[i].state*2)); ripples[i].state++; // Next step. break; } // switch step @@ -6182,6 +6224,7 @@ uint16_t mode_ripplepeak(void) { // * Ripple peak. By Andrew Tuli static const char *_data_FX_MODE_RIPPLEPEAK PROGMEM = " ♪ Ripple Peak@Fade rate,Max # of ripples,,Select bin,Volume (minimum);!,!;!"; +#ifndef WLED_DISABLE_2D ///////////////////////// // * 2D Swirl // ///////////////////////// @@ -6196,11 +6239,11 @@ uint16_t mode_2DSwirl(void) { if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); const uint8_t borderWidth = 2; - strip.blur2d(leds, SEGMENT.custom1); + SEGMENT.blur2d(leds, SEGMENT.custom1); uint8_t i = beatsin8( 27*SEGMENT.speed/255, borderWidth, cols - borderWidth); uint8_t j = beatsin8( 41*SEGMENT.speed/255, borderWidth, rows - borderWidth); @@ -6229,7 +6272,7 @@ uint16_t mode_2DSwirl(void) { leds[XY( i, nj)] += ColorFromPalette(strip.currentPalette, (ms / 37 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 37, 200, 255); leds[XY(ni, j)] += ColorFromPalette(strip.currentPalette, (ms / 41 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 41, 200, 255); - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2DSwirl() static const char *_data_FX_MODE_2DSWIRL PROGMEM = " ♪ 2D Swirl@!,Sensitivity=64,Blur;,Bg Swirl;!"; @@ -6250,7 +6293,7 @@ uint16_t mode_2DWaverly(void) { CRGB *leds = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { - strip.fill_solid(leds, CRGB::Black); + SEGMENT.fill_solid(leds, CRGB::Black); } um_data_t *um_data; @@ -6262,7 +6305,7 @@ uint16_t mode_2DWaverly(void) { uint8_t soundAgc = *(uint8_t*)um_data->u_data[1]; float sampleAgc = *(float*) um_data->u_data[2]; - strip.fadeToBlackBy(leds, SEGMENT.speed); + SEGMENT.fadeToBlackBy(leds, SEGMENT.speed); long t = millis() / 2; for (uint16_t i = 0; i < cols; i++) { @@ -6279,13 +6322,14 @@ uint16_t mode_2DWaverly(void) { leds[XY((cols - 1) - i, (rows - 1) - j)] += ColorFromPalette(strip.currentPalette, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND); } } - strip.blur2d(leds, 16); + SEGMENT.blur2d(leds, 16); - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2DWaverly() static const char *_data_FX_MODE_2DWAVERLY PROGMEM = " ♪ 2D Waverly@Amplification,Sensitivity=64;;!"; +#endif // WLED_DISABLE_2D // float version of map() static float mapf(float x, float in_min, float in_max, float out_min, float out_max){ @@ -6318,7 +6362,7 @@ uint16_t mode_gravcenter(void) { // Gravcenter. By Andrew Tuline. float tmpSound = (soundAgc) ? sampleAgc : sampleAvg; - strip.fade_out(240); + SEGMENT.fade_out(240); float segmentSampleAvg = tmpSound * (float)SEGMENT.intensity / 255.0f; segmentSampleAvg *= 0.125; // divide by 8, to compensate for later "sensitivty" upscaling @@ -6329,8 +6373,8 @@ uint16_t mode_gravcenter(void) { // Gravcenter. By Andrew Tuline. for (int i=0; i= gravcen->topLED) @@ -6339,8 +6383,8 @@ uint16_t mode_gravcenter(void) { // Gravcenter. By Andrew Tuline. gravcen->topLED--; if (gravcen->topLED >= 0) { - strip.setPixelColor(gravcen->topLED+SEGLEN/2, strip.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); - strip.setPixelColor(SEGLEN/2-1-gravcen->topLED, strip.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(gravcen->topLED+SEGLEN/2, SEGMENT.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(SEGLEN/2-1-gravcen->topLED, SEGMENT.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); } gravcen->gravityCounter = (gravcen->gravityCounter + 1) % gravity; @@ -6371,8 +6415,8 @@ uint16_t mode_gravcentric(void) { // Gravcentric. By Andrew float tmpSound = (soundAgc) ? sampleAgc : sampleAvg; - strip.fade_out(240); - strip.fade_out(240); // twice? really? + SEGMENT.fade_out(240); + SEGMENT.fade_out(240); // twice? really? float segmentSampleAvg = tmpSound * (float)SEGMENT.intensity / 255.0; segmentSampleAvg *= 0.125f; // divide by 8, to compensate for later "sensitivty" upscaling @@ -6383,8 +6427,8 @@ uint16_t mode_gravcentric(void) { // Gravcentric. By Andrew for (int i=0; i= gravcen->topLED) @@ -6393,8 +6437,8 @@ uint16_t mode_gravcentric(void) { // Gravcentric. By Andrew gravcen->topLED--; if (gravcen->topLED >= 0) { - strip.setPixelColor(gravcen->topLED+SEGLEN/2, CRGB::Gray); - strip.setPixelColor(SEGLEN/2-1-gravcen->topLED, CRGB::Gray); + SEGMENT.setPixelColor(gravcen->topLED+SEGLEN/2, CRGB::Gray); + SEGMENT.setPixelColor(SEGLEN/2-1-gravcen->topLED, CRGB::Gray); } gravcen->gravityCounter = (gravcen->gravityCounter + 1) % gravity; @@ -6424,7 +6468,7 @@ uint16_t mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. float tmpSound = (soundAgc) ? sampleAgc : sampleAvg; - strip.fade_out(240); + SEGMENT.fade_out(240); float segmentSampleAvg = tmpSound * (float)SEGMENT.intensity / 255.0; segmentSampleAvg *= 0.25; // divide by 4, to compensate for later "sensitivty" upscaling @@ -6435,7 +6479,7 @@ uint16_t mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. for (int i=0; i= gravcen->topLED) @@ -6444,7 +6488,7 @@ uint16_t mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. gravcen->topLED--; if (gravcen->topLED > 0) { - strip.setPixelColor(gravcen->topLED, strip.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(gravcen->topLED, SEGMENT.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); } gravcen->gravityCounter = (gravcen->gravityCounter + 1) % gravity; @@ -6472,7 +6516,7 @@ uint16_t mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. float sampleGain = *(float*)um_data->u_data[13]; uint8_t inputLevel = *(uint8_t*)um_data->u_data[17]; - strip.fade_out(240); + SEGMENT.fade_out(240); //TODO: implement inputLevel as a global or slider inputLevel = SEGMENT.custom1; @@ -6501,7 +6545,7 @@ uint16_t mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. { for (int i=0; i= gravcen->topLED) @@ -6510,7 +6554,7 @@ uint16_t mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. gravcen->topLED--; if (gravcen->topLED > 0) { - strip.setPixelColor(gravcen->topLED, strip.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(gravcen->topLED, SEGMENT.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); } gravcen->gravityCounter = (gravcen->gravityCounter + 1) % gravity; @@ -6531,11 +6575,11 @@ uint16_t mode_juggles(void) { // Juggles. By Andrew Tuline. } float sampleAgc = *(float*)um_data->u_data[2]; - strip.fade_out(224); + SEGMENT.fade_out(224); uint16_t my_sampleAgc = fmax(fmin(sampleAgc, 255.0), 0); for (uint8_t i=0; iu_data[3]; int16_t rawSampleAgc = *(int16_t*)um_data->u_data[4]; - if (SEGENV.call == 0) strip.fill(BLACK); + if (SEGENV.call == 0) SEGMENT.fill(BLACK); uint8_t secondHand = micros()/(256-SEGMENT.speed)/500 % 16; if(SEGENV.aux0 != secondHand) { @@ -6564,8 +6608,8 @@ uint16_t mode_matripix(void) { // Matripix. By Andrew Tuline. uint8_t tmpSound = (soundAgc) ? rawSampleAgc : sampleRaw; int pixBri = tmpSound * SEGMENT.intensity / 64; - for (uint16_t i=0; iu_data[1]; float sampleAgc = *(float*)um_data->u_data[2]; - strip.fade_out(SEGMENT.speed); - strip.fade_out(SEGMENT.speed); + SEGMENT.fade_out(SEGMENT.speed); + SEGMENT.fade_out(SEGMENT.speed); float tmpSound = (soundAgc) ? sampleAgc : sampleAvg; float tmpSound2 = tmpSound * (float)SEGMENT.intensity / 256.0; // Too sensitive. @@ -6600,7 +6644,7 @@ uint16_t mode_midnoise(void) { // Midnoise. By Andrew Tuline. for (int i=(SEGLEN/2-maxLen); i<(SEGLEN/2+maxLen); i++) { uint8_t index = inoise8(i*tmpSound+SEGENV.aux0, SEGENV.aux1+i*tmpSound); // Get a value from the noise function. I'm using both x and y axis. - strip.setPixelColor(i, strip.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0)); } SEGENV.aux0=SEGENV.aux0+beatsin8(5,0,10); @@ -6637,7 +6681,7 @@ uint16_t mode_noisefire(void) { // Noisefire. By Andrew Tuline. uint8_t tmpSound = (soundAgc) ? sampleAgc : sampleAvg; CRGB color = ColorFromPalette(strip.currentPalette, index, tmpSound*2, LINEARBLEND); // Use the my own palette. - strip.setPixelColor(i, color); + SEGMENT.setPixelColor(i, color); } return FRAMETIME; @@ -6662,7 +6706,7 @@ uint16_t mode_noisemeter(void) { // Noisemeter. By Andrew Tuline. int16_t rawSampleAgc = *(int16_t*)um_data->u_data[4]; uint8_t fadeRate = map(SEGMENT.speed,0,255,224,255); - strip.fade_out(fadeRate); + SEGMENT.fade_out(fadeRate); float tmpSound = (soundAgc) ? rawSampleAgc : sampleRaw; float tmpSound2 = tmpSound * 2.0 * (float)SEGMENT.intensity / 255.0; @@ -6672,7 +6716,7 @@ uint16_t mode_noisemeter(void) { // Noisemeter. By Andrew Tuline. tmpSound = soundAgc ? sampleAgc : sampleAvg; // now use smoothed value (sampleAvg or sampleAgc) for (int i=0; i 128) //color_vertical / color bars toggle colorIndex = map(y, 0, rows-1, 0, 255); - ledColor = strip.color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0); - strip.setPixelColorXY(x, rows-1 - y, ledColor); + ledColor = SEGMENT.color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0); + SEGMENT.setPixelColorXY(x, rows-1 - y, ledColor); } if (previousBarHeight[x] > 0) - strip.setPixelColorXY(x, rows - previousBarHeight[x], (SEGCOLOR(2) != BLACK) ? SEGCOLOR(2) : ledColor); + SEGMENT.setPixelColorXY(x, rows - previousBarHeight[x], (SEGCOLOR(2) != BLACK) ? SEGCOLOR(2) : ledColor); if (rippleTime && previousBarHeight[x]>0) previousBarHeight[x]--; //delay/ripple effect } @@ -7500,16 +7545,19 @@ uint16_t mode_2DFunkyPlank(void) { // Written by ??? Adapted by Wil } } - strip.setPixels(leds); + SEGMENT.setPixels(leds); return FRAMETIME; } // mode_2DFunkyPlank static const char *_data_FX_MODE_2DFUNKYPLANK PROGMEM = " ♫ 2D Funky Plank@Scroll speed,,# of bands;;"; +#endif // WLED_DISABLE_2D + //end audio only routines #endif +#ifndef WLED_DISABLE_2D ///////////////////////// // 2D Akemi // ///////////////////////// @@ -7571,7 +7619,7 @@ uint16_t mode_2DAkemi(void) { for (uint16_t y=0; y < rows; y++) for (uint16_t x=0; x < cols; x++) { CRGB color; CRGB soundColor = ORANGE; - CRGB faceColor = strip.color_wheel(counter); + CRGB faceColor = SEGMENT.color_wheel(counter); CRGB armsAndLegsColor = SEGCOLOR(1) > 0 ? SEGCOLOR(1) : 0xFFE0A0; //default warmish white 0xABA8FF; //0xFF52e5;// uint8_t ak = pgm_read_byte_near(akemi + ((y * 32)/rows) * 32 + (x * 32)/cols); // akemi[(y * 32)/rows][(x * 32)/cols] switch (ak) { @@ -7588,10 +7636,10 @@ uint16_t mode_2DAkemi(void) { } if (SEGMENT.intensity > 128 && fftResult && fftResult[0] > 128) { //dance if base is high - strip.setPixelColorXY(x, 0, BLACK); - strip.setPixelColorXY(x, y+1, color); + SEGMENT.setPixelColorXY(x, 0, BLACK); + SEGMENT.setPixelColorXY(x, y+1, color); } else - strip.setPixelColorXY(x, y, color); + SEGMENT.setPixelColorXY(x, y, color); } //add geq left and right @@ -7599,11 +7647,11 @@ uint16_t mode_2DAkemi(void) { for (uint16_t x=0; x < cols/8; x++) { uint16_t band = x * cols/8; uint16_t barHeight = map(fftResult[band], 0, 255, 0, 17*rows/32); - CRGB color = strip.color_from_palette((band * 35), false, PALETTE_SOLID_WRAP, 0); + CRGB color = SEGMENT.color_from_palette((band * 35), false, PALETTE_SOLID_WRAP, 0); for (uint16_t y=0; y < barHeight; y++) { - strip.setPixelColorXY(x, rows/2-y, color); - strip.setPixelColorXY(cols-1-x, rows/2-y, color); + SEGMENT.setPixelColorXY(x, rows/2-y, color); + SEGMENT.setPixelColorXY(cols-1-x, rows/2-y, color); } } } @@ -7611,14 +7659,25 @@ uint16_t mode_2DAkemi(void) { return FRAMETIME; } // mode_2DAkemi static const char *_data_FX_MODE_2DAKEMI PROGMEM = "2D Akemi@Color speed,Dance;Head palette,Arms & Legs,Eyes & Mouth;Face palette"; +#endif // WLED_DISABLE_2D ////////////////////////////////////////////////////////////////////////////////////////// // mode data static const char *_data_RESERVED PROGMEM = "Reserved"; + +void WS2812FX::addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name) { + if (id == 255) { for (int i=1; i<_modeCount; i++) if (_mode[i] == &mode_static) { id = i; break; } } // find empty slot + if (id < _modeCount) { + if (_mode[id] != &mode_static) return; // do not overwrite alerady added effect + _mode[id] = mode_fn; + _modeData[id] = mode_name; + } +} + void WS2812FX::setupEffectData() { // fill reserved word in case there will be any gaps in the array - for (int i=0; i> n) & 0x01); } inline bool isSelected() { return getOption(0); } inline bool isActive() { return stop > start; } @@ -390,22 +410,71 @@ typedef struct Segment { // 35 (36 in memory) bytes inline uint16_t length() { return width(); } inline uint16_t groupLength() { return grouping + spacing; } inline uint8_t getLightCapabilities() { return _capabilities; } - bool setColor(uint8_t slot, uint32_t c, uint8_t segn); //returns true if changed - void setCCT(uint16_t k, uint8_t segn); - void setOpacity(uint8_t o, uint8_t segn); - void setOption(uint8_t n, bool val, uint8_t segn = 255); + + bool setColor(uint8_t slot, uint32_t c); //returns true if changed + void setCCT(uint16_t k); + void setOpacity(uint8_t o); + void setOption(uint8_t n, bool val); + uint8_t differs(Segment& b); + void refreshLightCapabilities(); + + // 1D strip + uint16_t virtualLength(); + void setPixelColor(int n, uint32_t c); // set relative pixel within segment with color + void setPixelColor(int n, byte r, byte g, byte b, byte w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } // automatically inline + void setPixelColor(int n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); } // automatically inline + void setPixelColor(float i, uint32_t c, bool aa = true); + void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); } + void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, c.red, c.green, c.blue, 0, aa); } + uint32_t getPixelColor(uint16_t i); + // 1D support functions (some implement 2D as well) + void blur(uint8_t); + void fill(uint32_t c); + void fade_out(uint8_t r); + void fadeToBlackBy(uint8_t fadeBy); + void blendPixelColor(uint16_t n, uint32_t color, uint8_t blend); + void addPixelColor(uint16_t n, uint32_t color); + uint8_t get_random_wheel_index(uint8_t pos); + uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255); + uint32_t color_wheel(uint8_t pos); + // 2D matrix uint16_t virtualWidth(); uint16_t virtualHeight(); - // 1D strip - uint16_t virtualLength(); - uint8_t differs(Segment& b); - void refreshLightCapabilities(); + uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment (for leds[]) + void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color + void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline + void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, c.red, c.green, c.blue); } // automatically inline + void setPixelColorXY(float x, float y, uint32_t c, bool aa = true); + void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); } + void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, c.red, c.green, c.blue, 0, aa); } + uint32_t getPixelColorXY(uint16_t x, uint16_t y); + // 2D support functions + void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend); + void addPixelColorXY(uint16_t x, uint16_t y, uint32_t color); + void blur1d(CRGB* leds, fract8 blur_amount); + void blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds=nullptr); // 1D box blur (with weight) + void blur2d(CRGB* leds, fract8 blur_amount); + void blurRow(uint16_t row, fract8 blur_amount, CRGB* leds=nullptr); + void blurCol(uint16_t col, fract8 blur_amount, CRGB* leds=nullptr); + void moveX(CRGB *leds, int8_t delta); + void moveY(CRGB *leds, int8_t delta); + void move(uint8_t dir, uint8_t delta, CRGB *leds=nullptr); + void fill_solid(CRGB* leds, CRGB c); + void fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB c); + void fadeToBlackBy(CRGB* leds, uint8_t fadeBy); + void nscale8(CRGB* leds, uint8_t scale); + void setPixels(CRGB* leds); + void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds = nullptr); + void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color, CRGB *leds = nullptr); + void wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c); + inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) { drawLine(x0, y0, x1, y1, CRGB(byte(c>>16), byte(c>>8), byte(c))); } + inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t c) { drawCharacter(chr, x, y, w, h, CRGB(byte(c>>16), byte(c>>8), byte(c))); } } segment; // segment runtime parameters -typedef struct Segment_runtime { // 28 bytes +typedef struct Segment_runtime { // 23 (24 in memory) bytes unsigned long next_time; // millis() of next update uint32_t step; // custom "step" var uint32_t call; // call counter @@ -429,25 +498,9 @@ typedef struct Segment_runtime { // 28 bytes } segment_runtime; -// color transitions -typedef struct ColorTransition { // 12 bytes - uint32_t colorOld = 0; - uint32_t transitionStart; - uint16_t transitionDur; - uint8_t segment = 0xFF; //lower 6 bits: the segment this transition is for (255 indicates transition not in use/available) upper 2 bits: color channel - uint8_t briOld = 0; - - static void startTransition(uint8_t oldBri, uint32_t oldCol, uint8_t segn, uint8_t slot); - uint8_t currentBri(bool turningOff = false, uint8_t slot = 0); - uint16_t progress(bool allowEnd = false); //transition progression between 0-65535 - uint32_t currentColor(uint32_t colorNew) { - return color_blend(colorOld, colorNew, progress(true), true); - } -} color_transition; - // main "strip" class -class WS2812FX { +class WS2812FX { // 96 bytes typedef uint16_t (*mode_ptr)(void); // pointer to mode function typedef void (*show_callback)(void); // pre show callback @@ -457,7 +510,10 @@ class WS2812FX { WS2812FX() { WS2812FX::instance = this; - setupEffectData(); + _mode = new mode_ptr[_modeCount]; + _modeData = new const char*[_modeCount]; + if (_mode && _modeData) setupEffectData(); + else _modeCount = 1; // only Solid will work _brightness = DEFAULT_BRIGHTNESS; currentPalette = CRGBPalette16(CRGB::Black); targetPalette = CloudColors_p; @@ -467,15 +523,16 @@ class WS2812FX { resetSegments(); } + ~WS2812FX() { + delete[] _mode; + delete[] _modeData; + } + static WS2812FX* getInstance(void) { return instance; } void finalizeInit(), service(void), - blur(uint8_t), - fill(uint32_t c, uint8_t seg=255), - fade_out(uint8_t r), - fadeToBlackBy(uint8_t fadeBy), setMode(uint8_t segid, uint8_t m), setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), setColor(uint8_t slot, uint32_t c), @@ -490,21 +547,18 @@ class WS2812FX { resetSegments(), makeAutoSegments(bool forceReset = false), fixInvalidSegments(), - setPixelColor(int n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), - setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = false), - blendPixelColor(uint16_t n, uint32_t color, uint8_t blend), + setPixelColor(int n, uint32_t c), show(void), setTargetFps(uint8_t fps), deserializeMap(uint8_t n=0); - void addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name) { if (id < _modeCount) { _mode[id] = mode_fn; _modeData[id] = mode_name;} } - void setupEffectData(void); // defined in FX.cpp + void fill(uint32_t c) { for (int i = 0; i < _length; i++) setPixelColor(i, c); } // fill whole strip with color (inline) + void addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name); // add effect to the list; defined in FX.cpp + void setupEffectData(void); // add default effects to the list; defined in FX.cpp // outsmart the compiler :) by correctly overloading - inline void setPixelColor(int n, uint32_t c) {setPixelColor(n, byte(c>>16), byte(c>>8), byte(c), byte(c>>24));} - inline void setPixelColor(int n, CRGB c) {setPixelColor(n, c.red, c.green, c.blue);} - inline void setPixelColor(float i, uint32_t c, bool aa=true) {setPixelColor(i, byte(c>>16), byte(c>>8), byte(c), byte(c>>24), aa);} - inline void setPixelColor(float i, CRGB c, bool aa=true) {setPixelColor(i, c.red, c.green, c.blue, 0, aa);} + inline void setPixelColor(int n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } + inline void setPixelColor(int n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); } inline void trigger(void) { _triggered = true; } // Forces the next frame to be computed on all active segments. inline void setShowCallback(show_callback cb) { _callback = cb; } inline void setTransition(uint16_t t) { _transitionDur = t; } @@ -531,8 +585,7 @@ class WS2812FX { getLastActiveSegmentId(void), setPixelSegment(uint8_t n), gamma8(uint8_t), - gamma8_cal(uint8_t, float), - get_random_wheel_index(uint8_t); + gamma8_cal(uint8_t, float); inline uint8_t getBrightness(void) { return _brightness; } inline uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; } @@ -541,31 +594,21 @@ class WS2812FX { inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } inline uint8_t getTargetFps() { return _targetFps; } inline uint8_t getModeCount() { return _modeCount; } - inline uint8_t sin_gap(uint16_t in) { - if (in & 0x100) return 0; - return sin8(in + 192); // correct phase shift of sine so that it starts and stops at 0 - } - - int8_t - tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec); uint16_t ablMilliampsMax, currentMilliamps, - triwave16(uint16_t), getLengthPhysical(void), getFps(); inline uint16_t getFrameTime(void) { return _frametime; } inline uint16_t getMinShowDelay(void) { return MIN_SHOW_DELAY; } inline uint16_t getLengthTotal(void) { return _length; } - inline uint16_t segLen(void) { return _virtualSegmentLength; } + inline uint16_t getTransition(void) { return _transitionDur; } uint32_t now, timebase, - color_wheel(uint8_t), - color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255), currentColor(uint32_t colorNew, uint8_t tNr), gamma32(uint32_t), getPixelColor(uint16_t); @@ -574,7 +617,7 @@ class WS2812FX { inline uint32_t segColor(uint8_t i) { return _colors_t[i]; } const char * - getModeData(uint8_t id = 0) { return id<_modeCount ? _modeData[id] : nullptr; } + getModeData(uint8_t id = 0) { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); } const char ** getModeDataSrc(void) { return _modeData; } @@ -589,6 +632,8 @@ class WS2812FX { bool isMatrix = false; +#ifndef WLED_DISABLE_2D + #define WLED_MAX_PANELS 64 uint8_t hPanels = 1, vPanels = 1; @@ -599,7 +644,6 @@ class WS2812FX { matrixWidth = DEFAULT_LED_COUNT, matrixHeight = 1; - #define WLED_MAX_PANELS 64 typedef struct panel_bitfield_t { unsigned char bottomStart : 1, // starts at bottom? @@ -610,41 +654,15 @@ class WS2812FX { Panel matrix = {0,0,0,0}, panel[WLED_MAX_PANELS] = {{0,0,0,0}}; +#endif void setUpMatrix(), - setPixelColorXY(int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), - setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = false), - blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend), - addPixelColorXY(uint16_t x, uint16_t y, uint32_t color), - blur1d(CRGB* leds, fract8 blur_amount), - blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds=nullptr), // 1D box blur (with weight) - blur2d(CRGB* leds, fract8 blur_amount), - blurRow(uint16_t row, fract8 blur_amount, CRGB* leds=nullptr), - blurCol(uint16_t col, fract8 blur_amount, CRGB* leds=nullptr), - moveX(CRGB *leds, int8_t delta), - moveY(CRGB *leds, int8_t delta), - move(uint8_t dir, uint8_t delta, CRGB *leds=nullptr), - fill_solid(CRGB* leds, CRGB c), - fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB c), - fadeToBlackBy(CRGB* leds, uint8_t fadeBy), - nscale8(CRGB* leds, uint8_t scale), - setPixels(CRGB* leds), - drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds = nullptr), - drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color, CRGB *leds = nullptr), - wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c); + setPixelColorXY(int x, int y, uint32_t c); // outsmart the compiler :) by correctly overloading - inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColorXY(x, y, byte(c>>16), byte(c>>8), byte(c), byte(c>>24)); } - inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, c.red, c.green, c.blue, 0); } - inline void setPixelColorXY(float x, float y, uint32_t c, bool aa=true) { setPixelColorXY(x, y, byte(c>>16), byte(c>>8), byte(c), byte(c>>24), aa); } - inline void setPixelColorXY(float x, float y, CRGB c, bool aa=true) { setPixelColorXY(x, y, c.red, c.green, c.blue, 0, aa); } - inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) { drawLine(x0, y0, x1, y1, CRGB(byte(c>>16), byte(c>>8), byte(c))); } - inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t c) { drawCharacter(chr, x, y, w, h, CRGB(byte(c>>16), byte(c>>8), byte(c))); } - - uint16_t - XY(uint16_t, uint16_t), - get2DPixelIndex(uint16_t x, uint16_t y, uint8_t seg=255); + inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline + inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, c.red, c.green, c.blue); } uint32_t getPixelColorXY(uint16_t, uint16_t); @@ -654,8 +672,20 @@ class WS2812FX { CRGBPalette16 currentPalette; CRGBPalette16 targetPalette; + uint32_t _colors_t[3]; + uint16_t _virtualSegmentLength; + + segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 27 bytes per element + // start, stop, offset, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[], capabilities, custom 1, custom 2, custom 3 + {0, 7, 0, DEFAULT_SPEED, DEFAULT_INTENSITY, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}, 0, DEFAULT_C1, DEFAULT_C2, DEFAULT_C3, 0, 1} + }; + friend class Segment; + + segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element + friend class Segment_runtime; + private: - uint16_t _length, _virtualSegmentLength; + uint16_t _length; uint16_t _rand16seed; uint8_t _brightness; uint16_t _usedSegmentData = 0; @@ -671,9 +701,8 @@ class WS2812FX { _triggered; uint8_t _modeCount = MODE_COUNT; - // TODO: allocate memory using new or malloc() - mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element - const char *_modeData[MODE_COUNT]; // mode (effect) name and its slider control data array + mode_ptr *_mode; // SRAM footprint: 4 bytes per element + const char **_modeData; // mode (effect) name and its slider control data array show_callback _callback = nullptr; @@ -683,26 +712,12 @@ class WS2812FX { uint32_t _lastPaletteChange = 0; uint32_t _lastShow = 0; - uint32_t _colors_t[3]; - uint8_t _bri_t; bool _no_rgb = false; uint8_t _segment_index = 0; uint8_t _segment_index_palette_last = 99; uint8_t _mainSegment; - segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 27 bytes per element - // start, stop, offset, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[], capabilities, custom 1, custom 2, custom 3 - {0, 7, 0, DEFAULT_SPEED, DEFAULT_INTENSITY, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}, 0, DEFAULT_C1, DEFAULT_C2, DEFAULT_C3, 0, 1} - }; - friend class Segment; - - segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element - friend class Segment_runtime; - - ColorTransition transitions[MAX_NUM_TRANSITIONS]; //12 bytes per element - friend class ColorTransition; - void estimateCurrentAndLimitBri(void), load_gradient_palette(uint8_t), diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 6afaa3470..439960f7e 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -26,23 +26,6 @@ #include "FX.h" #include "palettes.h" -#ifdef SEGMENT - #undef SEGMENT -#endif -#ifdef SEGCOLOR - #undef SEGCOLOR -#endif -#ifdef SEGENV - #undef SEGENV -#endif -#ifdef SEGLEN - #undef SEGLEN -#endif -#define SEGMENT _segments[_segment_index] -#define SEGCOLOR(x) _colors_t[x] -#define SEGENV _segment_runtimes[_segment_index] -#define SEGLEN _virtualSegmentLength - // setUpMatrix() - constructs ledmap array from matrix of panels with WxH pixels // this converts physical (possibly irregular) LED arrangement into well defined // array of logical pixels: fist entry corresponds to left-topmost logical pixel @@ -52,6 +35,7 @@ // but ledmap takes care of that. ledmap is constructed upon initialization // so matrix should disable regular ledmap processing void WS2812FX::setUpMatrix() { +#ifndef WLED_DISABLE_2D // erase old ledmap, just in case. if (customMappingTable != nullptr) delete[] customMappingTable; customMappingTable = nullptr; @@ -63,7 +47,7 @@ void WS2812FX::setUpMatrix() { // safety check if (matrixWidth * matrixHeight > MAX_LEDS) { - matrixWidth = getLengthTotal(); + matrixWidth = _length; matrixHeight = 1; isMatrix = false; return; @@ -111,93 +95,112 @@ void WS2812FX::setUpMatrix() { #endif } else { // memory allocation error - matrixWidth = getLengthTotal(); + matrixWidth = _length; matrixHeight = 1; isMatrix = false; return; } } else { // not a matrix set up - matrixWidth = getLengthTotal(); + matrixWidth = _length; matrixHeight = 1; } +#endif } +// absolute matrix version of setPixelColor() +void IRAM_ATTR WS2812FX::setPixelColorXY(int x, int y, uint32_t col) +{ +#ifndef WLED_DISABLE_2D + if (!isMatrix) return; // not a matrix set-up + uint16_t index = y * matrixWidth + x; + if (index >= _length) return; + if (index < customMappingSize) index = customMappingTable[index]; + busses.setPixelColor(index, col); +#endif +} + +// returns RGBW values of pixel +uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) { +#ifndef WLED_DISABLE_2D + uint16_t index = (y * matrixWidth + x); + if (index >= _length) return 0; + if (index < customMappingSize) index = customMappingTable[index]; + return busses.getPixelColor(index); +#else + return 0; +#endif +} + +/////////////////////////////////////////////////////////// +// Segment:: routines +/////////////////////////////////////////////////////////// + // XY(x,y) - gets pixel index within current segment (often used to reference leds[] array element) -uint16_t IRAM_ATTR WS2812FX::XY(uint16_t x, uint16_t y) { - uint16_t width = SEGMENT.virtualWidth(); // segment width in logical pixels - uint16_t height = SEGMENT.virtualHeight(); // segment height in logical pixels +uint16_t IRAM_ATTR Segment::XY(uint16_t x, uint16_t y) { +#ifndef WLED_DISABLE_2D + uint16_t width = virtualWidth(); // segment width in logical pixels + uint16_t height = virtualHeight(); // segment height in logical pixels return (x%width) + (y%height) * width; +#else + return 0; +#endif } -// get2DPixelIndex(x,y,seg) - returns an index of segment pixel in a matrix layout -// index still needs to undergo ledmap processing to represent actual physical pixel -// matrix is always organized by matrixHeight number of matrixWidth pixels from top to bottom, left to right -// so: pixel at get2DPixelIndex(5,6) in a 2D segment with [start=10, stop=19, startY=20, stopY=29 : 10x10 pixels] -// corresponds to pixel with logical index of 847 (0 based) if a 2D segment belongs to a 32x32 matrix. -// math: (matrixWidth * (startY + y)) + start + x => (32 * (20+6)) + 10 + 5 = 847 -uint16_t IRAM_ATTR WS2812FX::get2DPixelIndex(uint16_t x, uint16_t y, uint8_t seg) { - if (seg == 255) seg = _segment_index; - x %= _segments[seg].width(); // just in case constrain x (wrap around) - y %= _segments[seg].height(); // just in case constrain y (wrap around) - return ((_segments[seg].startY + y) * matrixWidth) + _segments[seg].start + x; -} - -void IRAM_ATTR WS2812FX::setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w) +void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col) { - if (!isMatrix) return; // not a matrix set-up +#ifndef WLED_DISABLE_2D + if (!strip.isMatrix) return; // not a matrix set-up - if (_bri_t < 255) { - r = scale8(r, _bri_t); - g = scale8(g, _bri_t); - b = scale8(b, _bri_t); - w = scale8(w, _bri_t); + uint8_t _bri_t = getOption(SEG_OPTION_TRANSITIONAL) ? transition.briOld : opacity; + if (_bri_t < 255) { + byte r = scale8(R(col), _bri_t); + byte g = scale8(G(col), _bri_t); + byte b = scale8(B(col), _bri_t); + byte w = scale8(W(col), _bri_t); + col = RGBW32(r, g, b, w); } - uint32_t col = RGBW32(r, g, b, w); - if (SEGMENT.getOption(SEG_OPTION_REVERSED) ) x = SEGMENT.virtualWidth() - x - 1; - if (SEGMENT.getOption(SEG_OPTION_REVERSED_Y)) y = SEGMENT.virtualHeight() - y - 1; - if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed + if (getOption(SEG_OPTION_REVERSED) ) x = virtualWidth() - x - 1; + if (getOption(SEG_OPTION_REVERSED_Y)) y = virtualHeight() - y - 1; + if (getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed - x *= SEGMENT.groupLength(); // expand to physical pixels - y *= SEGMENT.groupLength(); // expand to physical pixels - if (x >= SEGMENT.width() || y >= SEGMENT.height()) return; // if pixel would fall out of segment just exit + x *= groupLength(); // expand to physical pixels + y *= groupLength(); // expand to physical pixels + if (x >= width() || y >= height()) return; // if pixel would fall out of segment just exit - for (uint8_t j = 0; j < SEGMENT.grouping; j++) { // groupping vertically - for (uint8_t g = 0; g < SEGMENT.grouping; g++) { // groupping horizontally - uint16_t index, xX = (x+g), yY = (y+j); - if (xX >= SEGMENT.width() || yY >= SEGMENT.height()) continue; // we have reached one dimension's end + for (int j = 0; j < grouping; j++) { // groupping vertically + for (int g = 0; g < grouping; g++) { // groupping horizontally + uint16_t xX = (x+g), yY = (y+j); + if (xX >= width() || yY >= height()) continue; // we have reached one dimension's end - index = get2DPixelIndex(xX, yY); - if (index < customMappingSize) index = customMappingTable[index]; - busses.setPixelColor(index, col); + strip.setPixelColorXY(start + xX, startY + yY, col); - if (SEGMENT.getOption(SEG_OPTION_MIRROR)) { //set the corresponding horizontally mirrored pixel - index = SEGMENT.getOption(SEG_OPTION_TRANSPOSED) ? get2DPixelIndex(xX, SEGMENT.height() - yY - 1) : get2DPixelIndex(SEGMENT.width() - xX - 1, yY); - if (index < customMappingSize) index = customMappingTable[index]; - busses.setPixelColor(index, col); + if (getOption(SEG_OPTION_MIRROR)) { //set the corresponding horizontally mirrored pixel + if (getOption(SEG_OPTION_TRANSPOSED)) strip.setPixelColorXY(start + xX, startY + height() - yY - 1, col); + else strip.setPixelColorXY(start + width() - xX - 1, startY + yY, col); } - if (SEGMENT.getOption(SEG_OPTION_MIRROR_Y)) { //set the corresponding vertically mirrored pixel - index = SEGMENT.getOption(SEG_OPTION_TRANSPOSED) ? get2DPixelIndex(SEGMENT.width() - xX - 1, yY) : get2DPixelIndex(xX, SEGMENT.height() - yY - 1); - if (index < customMappingSize) index = customMappingTable[index]; - busses.setPixelColor(index, col); + if (getOption(SEG_OPTION_MIRROR_Y)) { //set the corresponding vertically mirrored pixel + if (getOption(SEG_OPTION_TRANSPOSED)) strip.setPixelColorXY(start + width() - xX - 1, startY + yY, col); + else strip.setPixelColorXY(start + xX, startY + height() - yY - 1, col); } - if (SEGMENT.getOption(SEG_OPTION_MIRROR_Y) && SEGMENT.getOption(SEG_OPTION_MIRROR)) { //set the corresponding vertically AND horizontally mirrored pixel - index = get2DPixelIndex(SEGMENT.width() - xX - 1, SEGMENT.height() - yY - 1); - if (index < customMappingSize) index = customMappingTable[index]; - busses.setPixelColor(index, col); + if (getOption(SEG_OPTION_MIRROR_Y) && getOption(SEG_OPTION_MIRROR)) { //set the corresponding vertically AND horizontally mirrored pixel + strip.setPixelColorXY(width() - xX - 1, height() - yY - 1, col); } } } +#endif } // anti-aliased version of setPixelColorXY() -void /*IRAM_ATTR*/ WS2812FX::setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w, bool aa) +void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa) { +#ifndef WLED_DISABLE_2D + if (!strip.isMatrix) return; // not a matrix set-up if (x<0.0f || x>1.0f || y<0.0f || y>1.0f) return; // not normalized - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); float fX = x * (cols-1); float fY = y * (rows-1); @@ -216,80 +219,59 @@ void /*IRAM_ATTR*/ WS2812FX::setPixelColorXY(float x, float y, byte r, byte g, b uint32_t cXRYB = getPixelColorXY(xR, yB); if (xL!=xR && yT!=yB) { - // blend TL pixel - cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, uint8_t(sqrtf(dL*dT)*255.0f)); - setPixelColorXY(xL, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT)); - // blend TR pixel - cXRYT = color_blend(RGBW32(r,g,b,w), cXRYT, uint8_t(sqrtf(dR*dT)*255.0f)); - setPixelColorXY(xR, yT, R(cXRYT), G(cXRYT), B(cXRYT), W(cXRYT)); - // blend BL pixel - cXLYB = color_blend(RGBW32(r,g,b,w), cXLYB, uint8_t(sqrtf(dL*dB)*255.0f)); - setPixelColorXY(xL, yB, R(cXLYB), G(cXLYB), B(cXLYB), W(cXLYB)); - // blend BR pixel - cXRYB = color_blend(RGBW32(r,g,b,w), cXRYB, uint8_t(sqrtf(dR*dB)*255.0f)); - setPixelColorXY(xR, yB, R(cXRYB), G(cXRYB), B(cXRYB), W(cXRYB)); + setPixelColorXY(xL, yT, color_blend(col, cXLYT, uint8_t(sqrtf(dL*dT)*255.0f))); // blend TL pixel + setPixelColorXY(xR, yT, color_blend(col, cXRYT, uint8_t(sqrtf(dR*dT)*255.0f))); // blend TR pixel + setPixelColorXY(xL, yB, color_blend(col, cXLYB, uint8_t(sqrtf(dL*dB)*255.0f))); // blend BL pixel + setPixelColorXY(xR, yB, color_blend(col, cXRYB, uint8_t(sqrtf(dR*dB)*255.0f))); // blend BR pixel } else if (xR!=xL && yT==yB) { - // blend L pixel - cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, uint8_t(dL*255.0f)); - setPixelColorXY(xR, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT)); - // blend R pixel - cXRYT = color_blend(RGBW32(r,g,b,w), cXRYT, uint8_t(dR*255.0f)); - setPixelColorXY(xR, yT, R(cXRYT), G(cXRYT), B(cXRYT), W(cXRYT)); + setPixelColorXY(xR, yT, color_blend(col, cXLYT, uint8_t(dL*255.0f))); // blend L pixel + setPixelColorXY(xR, yT, color_blend(col, cXRYT, uint8_t(dR*255.0f))); // blend R pixel } else if (xR==xL && yT!=yB) { - // blend T pixel - cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, uint8_t(dT*255.0f)); - setPixelColorXY(xR, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT)); - // blend B pixel - cXLYB = color_blend(RGBW32(r,g,b,w), cXLYB, uint8_t(dB*255.0f)); - setPixelColorXY(xL, yB, R(cXLYB), G(cXLYB), B(cXLYB), W(cXLYB)); + setPixelColorXY(xR, yT, color_blend(col, cXLYT, uint8_t(dT*255.0f))); // blend T pixel + setPixelColorXY(xL, yB, color_blend(col, cXLYB, uint8_t(dB*255.0f))); // blend B pixel } else { - // exact match (x & y land on a pixel) - setPixelColorXY(xL, yT, r, g, b, w); + setPixelColorXY(xL, yT, col); // exact match (x & y land on a pixel) } } else { - setPixelColorXY(uint16_t(roundf(fX)), uint16_t(roundf(fY)), r, g, b, w); + setPixelColorXY(uint16_t(roundf(fX)), uint16_t(roundf(fY)), col); } +#endif } // returns RGBW values of pixel -uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) { - uint16_t index; - if (SEGLEN) { - if (SEGMENT.getOption(SEG_OPTION_REVERSED) ) x = SEGMENT.virtualWidth() - x - 1; - if (SEGMENT.getOption(SEG_OPTION_REVERSED_Y)) y = SEGMENT.virtualHeight() - y - 1; - if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed - - x *= SEGMENT.groupLength(); // expand to physical pixels - y *= SEGMENT.groupLength(); // expand to physical pixels - if (x >= SEGMENT.width() || y >= SEGMENT.height()) return 0; - - index = get2DPixelIndex(x, y); - } else { - index = y * matrixWidth + x; - } - if (index < customMappingSize) index = customMappingTable[index]; - - return busses.getPixelColor(index); +uint32_t Segment::getPixelColorXY(uint16_t x, uint16_t y) { +#ifndef WLED_DISABLE_2D + if (getOption(SEG_OPTION_REVERSED) ) x = virtualWidth() - x - 1; + if (getOption(SEG_OPTION_REVERSED_Y)) y = virtualHeight() - y - 1; + if (getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed + x *= groupLength(); // expand to physical pixels + y *= groupLength(); // expand to physical pixels + if (x >= width() || y >= height()) return 0; + return strip.getPixelColorXY(start + x, startY + y); +#else + return 0; +#endif } -/* - * Blends the specified color with the existing pixel color. - */ -void WS2812FX::blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { +// Blends the specified color with the existing pixel color. +void Segment::blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { +#ifndef WLED_DISABLE_2D setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend)); +#endif } -/* - * Adds the specified color with the existing pixel color perserving color balance. - */ -void WS2812FX::addPixelColorXY(uint16_t x, uint16_t y, uint32_t color) { +// Adds the specified color with the existing pixel color perserving color balance. +void Segment::addPixelColorXY(uint16_t x, uint16_t y, uint32_t color) { +#ifndef WLED_DISABLE_2D setPixelColorXY(x, y, color_add(getPixelColorXY(x,y), color)); +#endif } // blurRow: perform a blur on a row of a rectangular matrix -void WS2812FX::blurRow(uint16_t row, fract8 blur_amount, CRGB* leds) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::blurRow(uint16_t row, fract8 blur_amount, CRGB* leds) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); if (row >= rows) return; // blur one row @@ -311,12 +293,14 @@ void WS2812FX::blurRow(uint16_t row, fract8 blur_amount, CRGB* leds) { else setPixelColorXY(x, row, cur); carryover = part; } +#endif } // blurCol: perform a blur on a column of a rectangular matrix -void WS2812FX::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); if (col >= cols) return; // blur one column @@ -338,6 +322,7 @@ void WS2812FX::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) { else setPixelColorXY(col, i, cur); carryover = part; } +#endif } // blur1d: one-dimensional blur filter. Spreads light to 2 line neighbors. @@ -354,17 +339,20 @@ void WS2812FX::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) { // eventually all the way to black; this is by design so that // it can be used to (slowly) clear the LEDs to black. -void WS2812FX::blur1d(CRGB* leds, fract8 blur_amount) { - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::blur1d(CRGB* leds, fract8 blur_amount) { +#ifndef WLED_DISABLE_2D + const uint16_t rows = virtualHeight(); for (uint16_t y = 0; y < rows; y++) blurRow(y, blur_amount, leds); +#endif } // 1D Box blur (with added weight - blur_amount: [0=no blur, 255=max blur]) -void WS2812FX::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); - const uint16_t dim1 = vertical ? rows : cols; - const uint16_t dim2 = vertical ? cols : rows; +void Segment::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); + const uint16_t dim1 = vertical ? rows : cols; + const uint16_t dim2 = vertical ? cols : rows; if (i >= dim2) return; const float seep = blur_amount/255.f; const float keep = 3.f - 2.f*seep; @@ -392,63 +380,65 @@ void WS2812FX::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds) if (leds) leds[XY(x,y)] = tmp[j]; else setPixelColorXY(x, y, tmp[j]); } +#endif } -void WS2812FX::blur2d(CRGB* leds, fract8 blur_amount) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::blur2d(CRGB* leds, fract8 blur_amount) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); for (uint16_t i = 0; i < rows; i++) blurRow(i, blur_amount, leds); // blur all rows for (uint16_t k = 0; k < cols; k++) blurCol(k, blur_amount, leds); // blur all columns +#endif } -void WS2812FX::moveX(CRGB *leds, int8_t delta) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::moveX(CRGB *leds, int8_t delta) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); if (!delta) return; if (delta > 0) { for (uint8_t y = 0; y < rows; y++) for (uint8_t x = 0; x < cols-1; x++) { + if (x + delta >= cols) break; if (leds) leds[XY(x, y)] = leds[XY((x + delta)%cols, y)]; else setPixelColorXY(x, y, getPixelColorXY((x + delta)%cols, y)); } } else { for (uint8_t y = 0; y < rows; y++) for (int16_t x = cols-1; x >= 0; x--) { - if (x + delta < 0) { - if (leds) leds[XY(x, y)] = leds[XY(cols + delta, y)]; - else setPixelColorXY(x, y, getPixelColorXY(cols + delta, y)); - } else { - if (leds) leds[XY(x, y)] = leds[XY(x + delta, y)]; - else setPixelColorXY(x, y, getPixelColorXY(x + delta, y)); - } + if (x + delta < 0) break; + if (leds) leds[XY(x, y)] = leds[XY(x + delta, y)]; + else setPixelColorXY(x, y, getPixelColorXY(x + delta, y)); } } +#endif } -void WS2812FX::moveY(CRGB *leds, int8_t delta) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::moveY(CRGB *leds, int8_t delta) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); if (!delta) return; if (delta > 0) { for (uint8_t x = 0; x < cols; x++) for (uint8_t y = 0; y < rows-1; y++) { - if (leds) leds[XY(x, y)] = leds[XY(x, (y + delta)%rows)]; - else setPixelColorXY(x, y, getPixelColorXY(x, (y + delta)%rows)); + if (y + delta >= rows) break; + if (leds) leds[XY(x, y)] = leds[XY(x, (y + delta))]; + else setPixelColorXY(x, y, getPixelColorXY(x, (y + delta))); } } else { for (uint8_t x = 0; x < cols; x++) for (int16_t y = rows-1; y >= 0; y--) { - if (y + delta < 0) { - if (leds) leds[XY(x, y)] = leds[XY(x, rows + delta)]; - else setPixelColorXY(x, y, getPixelColorXY(x, rows + delta)); - } else { - if (leds) leds[XY(x, y)] = leds[XY(x, y + delta)]; - else setPixelColorXY(x, y, getPixelColorXY(x, y + delta)); - } + if (y + delta < 0) break; + if (leds) leds[XY(x, y)] = leds[XY(x, y + delta)]; + else setPixelColorXY(x, y, getPixelColorXY(x, y + delta)); } } +#endif } // move() - move all pixels in desired direction delta number of pixels // @param dir direction: 0=left, 1=left-up, 2=up, 3=right-up, 4=right, 5=right-down, 6=down, 7=left-down // @param delta number of pixels to move -void WS2812FX::move(uint8_t dir, uint8_t delta, CRGB *leds) { +void Segment::move(uint8_t dir, uint8_t delta, CRGB *leds) { +#ifndef WLED_DISABLE_2D if (delta==0) return; switch (dir) { case 0: moveX(leds, delta); break; @@ -460,21 +450,25 @@ void WS2812FX::move(uint8_t dir, uint8_t delta, CRGB *leds) { case 6: moveY(leds,-delta); break; case 7: moveX(leds, delta); moveY(leds,-delta); break; } +#endif } -void WS2812FX::fill_solid(CRGB* leds, CRGB color) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::fill_solid(CRGB* leds, CRGB color) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { if (leds) leds[XY(x,y)] = color; else setPixelColorXY(x, y, color); } +#endif } // by stepko, taken from https://editor.soulmatelights.com/gallery/573-blobs -void WS2812FX::fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); for (int16_t y = -radius; y <= radius; y++) { for (int16_t x = -radius; x <= radius; x++) { if (x * x + y * y <= radius * radius && @@ -483,31 +477,39 @@ void WS2812FX::fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, leds[XY(cx + x, cy + y)] += col; } } +#endif } -void WS2812FX::fadeToBlackBy(CRGB* leds, uint8_t fadeBy) { +void Segment::fadeToBlackBy(CRGB* leds, uint8_t fadeBy) { +#ifndef WLED_DISABLE_2D nscale8(leds, 255 - fadeBy); +#endif } -void WS2812FX::nscale8(CRGB* leds, uint8_t scale) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::nscale8(CRGB* leds, uint8_t scale) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { if (leds) leds[XY(x,y)].nscale8(scale); else setPixelColorXY(x, y, CRGB(getPixelColorXY(x, y)).nscale8(scale)); } +#endif } -void WS2812FX::setPixels(CRGB* leds) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::setPixels(CRGB* leds) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) setPixelColorXY(x, y, leds[XY(x,y)]); +#endif } //line function -void WS2812FX::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); if (x0 >= cols || x1 >= cols || y0 >= rows || y1 >= rows) return; const int16_t dx = abs(x1-x0), sx = x0-dx) { err -= dy; x0 += sx; } if (e2 < dy) { err += dx; y0 += sy; } } +#endif } +#ifndef WLED_DISABLE_2D // font curtesy of https://github.com/idispatch/raster-fonts static const unsigned char console_font_6x8[] PROGMEM = { @@ -6672,19 +6676,21 @@ static const unsigned char console_font_5x8[] PROGMEM = { 0x00, /* 00000 */ 0x00, /* 00000 */ }; +#endif // draws a raster font character on canvas // only supports 5x8 and 6x8 fonts ATM -void WS2812FX::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color, CRGB *leds) { - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); +void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color, CRGB *leds) { +#ifndef WLED_DISABLE_2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); if (w<5 || w>6 || h!=8) return; for (uint8_t i = 0; i= rows) break; // drawing off-screen - uint8_t bits; + uint8_t bits = 0; switch (w) { case 5: bits = pgm_read_byte_near(&console_font_5x8[(chr * 8) + i]); break; case 6: bits = pgm_read_byte_near(&console_font_6x8[(chr * 8) + i]); break; @@ -6697,10 +6703,12 @@ void WS2812FX::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, } } } +#endif } #define WU_WEIGHT(a,b) ((uint8_t) (((a)*(b)+(a)+(b))>>8)) -void WS2812FX::wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c) { //awesome wu_pixel procedure by reddit u/sutaburosu +void Segment::wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c) { //awesome wu_pixel procedure by reddit u/sutaburosu +#ifndef WLED_DISABLE_2D // extract the fractional parts and derive their inverses uint8_t xx = x & 0xff, yy = y & 0xff, ix = 255 - xx, iy = 255 - yy; // calculate the intensities for each affected pixel @@ -6713,5 +6721,6 @@ void WS2812FX::wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c) { //awe leds[xy].g = qadd8(leds[xy].g, c.g * wu[i] >> 8); leds[xy].b = qadd8(leds[xy].b, c.b * wu[i] >> 8); } +#endif } #undef WU_WEIGHT diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 023e6ce92..dd0f255f0 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -27,23 +27,6 @@ #include "FX.h" #include "palettes.h" -#ifdef SEGMENT - #undef SEGMENT -#endif -#ifdef SEGCOLOR - #undef SEGCOLOR -#endif -#ifdef SEGENV - #undef SEGENV -#endif -#ifdef SEGLEN - #undef SEGLEN -#endif -#define SEGMENT _segments[_segment_index] -#define SEGCOLOR(x) _colors_t[x] -#define SEGENV _segment_runtimes[_segment_index] -#define SEGLEN _virtualSegmentLength - /* Custom per-LED mapping has moved! @@ -87,45 +70,78 @@ #endif -bool Segment::setColor(uint8_t slot, uint32_t c, uint8_t segn) { //returns true if changed - if (slot >= NUM_COLORS || segn >= MAX_NUM_SEGMENTS) return false; - if (c == colors[slot]) return false; - uint8_t b = (slot == 1) ? cct : opacity; - ColorTransition::startTransition(b, colors[slot], segn, slot); - colors[slot] = c; return true; +/////////////////////////////////////////////////////////////////////////////// +// ColorTransition class implementation +/////////////////////////////////////////////////////////////////////////////// + +void ColorTransition::startTransition(Segment *seg, uint16_t dur, uint8_t oldBri, uint8_t oldCct, uint32_t *oldCol) { + currentBri(oldBri); + currentBri(oldCct, true); + for (size_t i=0; isetOption(SEG_OPTION_TRANSITIONAL, true); } -void Segment::setCCT(uint16_t k, uint8_t segn) { - if (segn >= MAX_NUM_SEGMENTS) return; +uint16_t ColorTransition::progress() { //transition progression between 0-65535 + uint32_t timeNow = millis(); + if (timeNow - transitionStart > transitionDur) return 0xFFFFU; + uint32_t elapsed = timeNow - transitionStart; + return min(0xFFFFU, elapsed * 0xFFFFU / transitionDur); +} + +uint8_t ColorTransition::currentBri(uint8_t briNew, bool useCct) { + uint32_t prog = progress() + 1; + if (useCct) return cctOld = ((briNew * prog) + cctOld * (0x10000 - prog)) >> 16; + else return briOld = ((briNew * prog) + briOld * (0x10000 - prog)) >> 16; +} + +void ColorTransition::handleTransition(Segment *seg, uint8_t &newBri, uint8_t &newCct, uint32_t *newCol) { + if (!seg->getOption(SEG_OPTION_TRANSITIONAL)) return; // if segment is not transitioning + newBri = currentBri(seg->opacity); + newCct = currentBri(seg->cct, true); + for (size_t i=0; icolors[i]); + if (progress() == 0xFFFFU) seg->setOption(SEG_OPTION_TRANSITIONAL, false); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Segment class implementation +/////////////////////////////////////////////////////////////////////////////// + +bool Segment::setColor(uint8_t slot, uint32_t c) { //returns true if changed + if (slot >= NUM_COLORS || c == colors[slot]) return false; + transition.startTransition(this, strip.getTransition(), opacity, cct, colors); + colors[slot] = c; + return true; +} + +void Segment::setCCT(uint16_t k) { if (k > 255) { //kelvin value, convert to 0-255 if (k < 1900) k = 1900; if (k > 10091) k = 10091; k = (k - 1900) >> 5; } if (cct == k) return; - ColorTransition::startTransition(cct, colors[1], segn, 1); + transition.startTransition(this, strip.getTransition(), opacity, cct, colors); cct = k; } -void Segment::setOpacity(uint8_t o, uint8_t segn) { - if (segn >= MAX_NUM_SEGMENTS) return; +void Segment::setOpacity(uint8_t o) { if (opacity == o) return; - ColorTransition::startTransition(opacity, colors[0], segn, 0); + transition.startTransition(this, strip.getTransition(), opacity, cct, colors); opacity = o; } -void Segment::setOption(uint8_t n, bool val, uint8_t segn) { - bool prevOn = false; - if (n == SEG_OPTION_ON) { - prevOn = getOption(SEG_OPTION_ON); - if (!val && prevOn) { //fade off - ColorTransition::startTransition(opacity, colors[0], segn, 0); - } +void Segment::setOption(uint8_t n, bool val) { + bool prevOn = getOption(SEG_OPTION_ON); + if (n == SEG_OPTION_ON && !val && prevOn) { // fade out (off) + transition.startTransition(this, strip.getTransition(), opacity, cct, colors); } if (val) options |= 0x01 << n; else options &= ~(0x01 << n); - if (n == SEG_OPTION_ON && val && !prevOn) { //fade on - ColorTransition::startTransition(0, colors[0], segn, 0); + if (n == SEG_OPTION_ON && val && !prevOn) { // fade in (on) + transition.startTransition(this, strip.getTransition(), opacity, cct, colors); } } @@ -152,6 +168,95 @@ uint16_t Segment::virtualLength() { return vLength; } +void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col) +{ + if (strip.isMatrix) { + // map linear pixel into 2D segment area (even for 1D segments, expanding vertically) + uint16_t h = virtualHeight(); // segment height in logical pixels + for (int y = 0; y < h; y++) { // expand 1D effect vertically + setPixelColorXY(i, y * groupLength(), col); + } + return; + } + + uint16_t len = length(); + uint8_t _bri_t = getOption(SEG_OPTION_TRANSITIONAL) ? transition.briOld : opacity; + if (_bri_t < 255) { + byte r = scale8(R(col), _bri_t); + byte g = scale8(G(col), _bri_t); + byte b = scale8(B(col), _bri_t); + byte w = scale8(W(col), _bri_t); + col = RGBW32(r, g, b, w); + } + + // expand pixel (taking into account start, grouping, spacing [and offset]) + i = i * groupLength(); + if (getOption(SEG_OPTION_REVERSED)) { // is segment reversed? + if (getOption(SEG_OPTION_MIRROR)) { // is segment mirrored? + i = (len - 1) / 2 - i; //only need to index half the pixels + } else { + i = (len - 1) - i; + } + } + i += start; // starting pixel in a group + + // set all the pixels in the group + for (int j = 0; j < grouping; j++) { + uint16_t indexSet = i + ((getOption(SEG_OPTION_REVERSED)) ? -j : j); + if (indexSet >= start && indexSet < stop) { + if (getOption(SEG_OPTION_MIRROR)) { //set the corresponding mirrored pixel + uint16_t indexMir = stop - indexSet + start - 1; + indexMir += offset; // offset/phase + if (indexMir >= stop) indexMir -= len; // wrap + strip.setPixelColor(indexMir, col); + } + indexSet += offset; // offset/phase + if (indexSet >= stop) indexSet -= len; // wrap + strip.setPixelColor(indexSet, col); + } + } +} + +// anti-aliased normalized version of setPixelColor() +void Segment::setPixelColor(float i, uint32_t col, bool aa) +{ + if (i<0.0f || i>1.0f) return; // not normalized + + float fC = i * (virtualLength()-1); + if (aa) { + uint16_t iL = roundf(fC-0.49f); + uint16_t iR = roundf(fC+0.49f); + float dL = fC - iL; + float dR = iR - fC; + uint32_t cIL = getPixelColor(iL); + uint32_t cIR = getPixelColor(iR); + if (iR!=iL) { + // blend L pixel + cIL = color_blend(col, cIL, uint8_t(dL*255.0f)); + setPixelColor(iL, cIL); + // blend R pixel + cIR = color_blend(col, cIR, uint8_t(dR*255.0f)); + setPixelColor(iR, cIR); + } else { + // exact match (x & y land on a pixel) + setPixelColor(iL, col); + } + } else { + setPixelColor(uint16_t(roundf(fC)), col); + } +} + +uint32_t Segment::getPixelColor(uint16_t i) +{ + if (getOption(SEG_OPTION_REVERSED)) i = virtualLength() - i - 1; + i *= groupLength(); + i += start; + /* offset/phase */ + i += offset; + if (i >= stop) i -= length(); + return strip.getPixelColor(i); +} + uint8_t Segment::differs(Segment& b) { uint8_t d = 0; if (start != b.start) d |= SEG_DIFFERS_BOUNDS; @@ -210,6 +315,177 @@ void Segment::refreshLightCapabilities() { _capabilities = capabilities; } +/* + * Fills segment with color + */ +void Segment::fill(uint32_t c) { + const uint16_t cols = strip.isMatrix ? virtualWidth() : virtualLength(); + const uint16_t rows = virtualHeight(); // will be 1 for 1D + for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { + if (strip.isMatrix) setPixelColorXY(x, y, c); + else setPixelColor(x, c); + } +} + +// Blends the specified color with the existing pixel color. +void Segment::blendPixelColor(uint16_t n, uint32_t color, uint8_t blend) { + setPixelColor(n, color_blend(getPixelColor(n), color, blend)); +} + +// Adds the specified color with the existing pixel color perserving color balance. +void Segment::addPixelColor(uint16_t n, uint32_t color) { + setPixelColor(n, color_add(getPixelColor(n), color)); +} + +/* + * fade out function, higher rate = quicker fade + */ +void Segment::fade_out(uint8_t rate) { + const uint16_t cols = strip.isMatrix ? virtualWidth() : virtualLength(); + const uint16_t rows = virtualHeight(); // will be 1 for 1D + + rate = (255-rate) >> 1; + float mappedRate = float(rate) +1.1; + + uint32_t color = colors[1]; // SEGCOLOR(1); // target color + int w2 = W(color); + int r2 = R(color); + int g2 = G(color); + int b2 = B(color); + + for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { + color = strip.isMatrix ? getPixelColorXY(x, y) : getPixelColor(x); + int w1 = W(color); + int r1 = R(color); + int g1 = G(color); + int b1 = B(color); + + int wdelta = (w2 - w1) / mappedRate; + int rdelta = (r2 - r1) / mappedRate; + int gdelta = (g2 - g1) / mappedRate; + int bdelta = (b2 - b1) / mappedRate; + + // if fade isn't complete, make sure delta is at least 1 (fixes rounding issues) + wdelta += (w2 == w1) ? 0 : (w2 > w1) ? 1 : -1; + rdelta += (r2 == r1) ? 0 : (r2 > r1) ? 1 : -1; + gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1; + bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1; + + if (strip.isMatrix) setPixelColorXY(x, y, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta); + else setPixelColor(x, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta); + } +} + +// fades all pixels to black using nscale8() +void Segment::fadeToBlackBy(uint8_t fadeBy) { + const uint16_t cols = strip.isMatrix ? virtualWidth() : virtualLength(); + const uint16_t rows = virtualHeight(); // will be 1 for 1D + + for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { + if (strip.isMatrix) setPixelColorXY(x, y, CRGB(getPixelColorXY(x,y)).nscale8(255-fadeBy)); + else setPixelColor(x, CRGB(getPixelColor(x)).nscale8(255-fadeBy)); + } +} + +/* + * blurs segment content, source: FastLED colorutils.cpp + */ +void Segment::blur(uint8_t blur_amount) +{ + if (strip.isMatrix) { + // compatibility with 2D + const uint16_t cols = virtualWidth(); + const uint16_t rows = virtualHeight(); + for (uint16_t i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows + for (uint16_t k = 0; k < cols; k++) blurCol(k, blur_amount); // blur all columns + return; + } + uint8_t keep = 255 - blur_amount; + uint8_t seep = blur_amount >> 1; + CRGB carryover = CRGB::Black; + for(uint16_t i = 0; i < virtualLength(); i++) + { + CRGB cur = CRGB(getPixelColor(i)); + CRGB part = cur; + part.nscale8(seep); + cur.nscale8(keep); + cur += carryover; + if(i > 0) { + uint32_t c = getPixelColor(i-1); + uint8_t r = R(c); + uint8_t g = G(c); + uint8_t b = B(c); + setPixelColor(i-1, qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue)); + } + setPixelColor(i,cur.red, cur.green, cur.blue); + carryover = part; + } +} + +/* + * Put a value 0 to 255 in to get a color value. + * The colours are a transition r -> g -> b -> back to r + * Inspired by the Adafruit examples. + */ +uint32_t Segment::color_wheel(uint8_t pos) { // TODO + if (palette) return color_from_palette(pos, false, true, 0); + pos = 255 - pos; + if(pos < 85) { + return ((uint32_t)(255 - pos * 3) << 16) | ((uint32_t)(0) << 8) | (pos * 3); + } else if(pos < 170) { + pos -= 85; + return ((uint32_t)(0) << 16) | ((uint32_t)(pos * 3) << 8) | (255 - pos * 3); + } else { + pos -= 170; + return ((uint32_t)(pos * 3) << 16) | ((uint32_t)(255 - pos * 3) << 8) | (0); + } +} + +/* + * Returns a new, random wheel index with a minimum distance of 42 from pos. + */ +uint8_t Segment::get_random_wheel_index(uint8_t pos) { + uint8_t r = 0, x = 0, y = 0, d = 0; + + while(d < 42) { + r = random8(); + x = abs(pos - r); + y = 255 - x; + d = MIN(x, y); + } + return r; +} + +/* + * Gets a single color from the currently selected palette. + * @param i Palette Index (if mapping is true, the full palette will be _virtualSegmentLength long, if false, 255). Will wrap around automatically. + * @param mapping if true, LED position in segment is considered for color + * @param wrap FastLED palettes will usally wrap back to the start smoothly. Set false to get a hard edge + * @param mcol If the default palette 0 is selected, return the standard color 0, 1 or 2 instead. If >2, Party palette is used instead + * @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling) + * @returns Single color from palette + */ +uint32_t IRAM_ATTR Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) +{ + if ((palette == 0 && mcol < 3) || strip._no_rgb) { + uint32_t color = colors[mcol]; // SEGCOLOR(mcol); + if (pbri == 255) return color; + return RGBW32(scale8_video(R(color),pbri), scale8_video(G(color),pbri), scale8_video(B(color),pbri), scale8_video(W(color),pbri)); + } + + uint8_t paletteIndex = i; + if (mapping && virtualLength() > 1) paletteIndex = (i*255)/(virtualLength() -1); + if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end" + CRGB fastled_col; + fastled_col = ColorFromPalette(strip.currentPalette, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); + + return RGBW32(fastled_col.r, fastled_col.g, fastled_col.b, 0); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Segment_runtime class implementation +/////////////////////////////////////////////////////////////////////////////// bool Segment_runtime::allocateData(uint16_t len){ if (data && _dataLen == len) return true; //already allocated @@ -230,7 +506,7 @@ bool Segment_runtime::allocateData(uint16_t len){ return true; } -void Segment_runtime::deallocateData(){ +void Segment_runtime::deallocateData() { free(data); data = nullptr; WS2812FX::getInstance()->_usedSegmentData -= _dataLen; @@ -252,86 +528,10 @@ void Segment_runtime::resetIfRequired() { } } -void ColorTransition::startTransition(uint8_t oldBri, uint32_t oldCol, uint8_t segn, uint8_t slot) { - WS2812FX *instance = WS2812FX::getInstance(); - if (segn >= MAX_NUM_SEGMENTS || slot >= NUM_COLORS || instance->_transitionDur == 0) return; - if (instance->_brightness == 0) return; //do not need transitions if master bri is off - if (!instance->_segments[segn].getOption(SEG_OPTION_ON)) return; //not if segment is off either - uint8_t tIndex = 0xFF; //none found - uint16_t tProgression = 0; - uint8_t s = segn + (slot << 6); //merge slot and segment into one byte - - for (uint8_t i = 0; i < MAX_NUM_TRANSITIONS; i++) { - uint8_t tSeg = instance->transitions[i].segment; - //see if this segment + color already has a running transition - if (tSeg == s) { - tIndex = i; break; - } - if (tSeg == 0xFF) { //free transition - tIndex = i; tProgression = 0xFFFF; - } - } - - if (tIndex == 0xFF) { //no slot found yet - for (uint8_t i = 0; i < MAX_NUM_TRANSITIONS; i++) { - //find most progressed transition to overwrite - uint16_t prog = instance->transitions[i].progress(); - if (prog > tProgression) { - tIndex = i; tProgression = prog; - } - } - } - - ColorTransition& t = instance->transitions[tIndex]; - if (t.segment == s) //this is an active transition on the same segment+color - { - bool wasTurningOff = (oldBri == 0); - t.briOld = t.currentBri(wasTurningOff, slot); - t.colorOld = t.currentColor(oldCol); - } else { - t.briOld = oldBri; - t.colorOld = oldCol; - uint8_t prevSeg = t.segment & 0x3F; - if (prevSeg < MAX_NUM_SEGMENTS) instance->_segments[prevSeg].setOption(SEG_OPTION_TRANSITIONAL, false); - } - t.transitionDur = instance->_transitionDur; - t.transitionStart = millis(); - t.segment = s; - instance->_segments[segn].setOption(SEG_OPTION_TRANSITIONAL, true); - //refresh immediately, required for Solid mode - if (instance->_segment_runtimes[segn].next_time > t.transitionStart + 22) instance->_segment_runtimes[segn].next_time = t.transitionStart; -} - -uint16_t ColorTransition::progress(bool allowEnd) { //transition progression between 0-65535 - WS2812FX *instance = WS2812FX::getInstance(); - uint32_t timeNow = millis(); - if (timeNow - transitionStart > transitionDur) { - if (allowEnd) { - uint8_t segn = segment & 0x3F; - if (segn < MAX_NUM_SEGMENTS) instance->_segments[segn].setOption(SEG_OPTION_TRANSITIONAL, false); - segment = 0xFF; - } - return 0xFFFF; - } - uint32_t elapsed = timeNow - transitionStart; - uint32_t prog = elapsed * 0xFFFF / transitionDur; - return (prog > 0xFFFF) ? 0xFFFF : prog; -} - -uint8_t ColorTransition::currentBri(bool turningOff, uint8_t slot) { - WS2812FX *instance = WS2812FX::getInstance(); - uint8_t segn = segment & 0x3F; - if (segn >= MAX_NUM_SEGMENTS) return 0; - uint8_t briNew = instance->_segments[segn].opacity; - if (slot == 0) { - if (!instance->_segments[segn].getOption(SEG_OPTION_ON) || turningOff) briNew = 0; - } else { //transition slot 1 brightness for CCT transition - briNew = instance->_segments[segn].cct; - } - uint32_t prog = progress() + 1; - return ((briNew * prog) + (briOld * (0x10000 - prog))) >> 16; -} +/////////////////////////////////////////////////////////////////////////////// +// WS2812FX class implementation +/////////////////////////////////////////////////////////////////////////////// //do not call this method from system context (network callback) void WS2812FX::finalizeInit(void) @@ -401,43 +601,38 @@ void WS2812FX::service() { // reset the segment runtime data if needed, called before isActive to ensure deleted // segment's buffers are cleared - SEGENV.resetIfRequired(); + _segment_runtimes[_segment_index].resetIfRequired(); - if (!SEGMENT.isActive()) continue; + if (!_segments[_segment_index].isActive()) continue; // last condition ensures all solid segments are updated at the same time - if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) + if(nowUp > _segment_runtimes[_segment_index].next_time || _triggered || (doShow && _segments[_segment_index].mode == 0)) { - if (SEGMENT.grouping == 0) SEGMENT.grouping = 1; //sanity check + if (_segments[_segment_index].grouping == 0) _segments[_segment_index].grouping = 1; //sanity check doShow = true; uint16_t delay = FRAMETIME; - if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen - _virtualSegmentLength = SEGMENT.virtualLength(); - _bri_t = SEGMENT.opacity; - _colors_t[0] = SEGMENT.colors[0]; - _colors_t[1] = SEGMENT.colors[1]; - _colors_t[2] = SEGMENT.colors[2]; - uint8_t _cct_t = SEGMENT.cct; - if (!SEGMENT.getOption(SEG_OPTION_ON)) _bri_t = 0; - for (uint8_t t = 0; t < MAX_NUM_TRANSITIONS; t++) { - if ((transitions[t].segment & 0x3F) != i) continue; - uint8_t slot = transitions[t].segment >> 6; - if (slot == 0) _bri_t = transitions[t].currentBri(); - if (slot == 1) _cct_t = transitions[t].currentBri(false, 1); - _colors_t[slot] = transitions[t].currentColor(SEGMENT.colors[slot]); - } + if (!_segments[_segment_index].getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen + Segment &seg = _segments[_segment_index]; + _virtualSegmentLength = seg.virtualLength(); + uint8_t _bri_t = seg.getOption(SEG_OPTION_ON) ? seg.opacity : 0; + uint8_t _cct_t = seg.cct; + _colors_t[0] = seg.colors[0]; + _colors_t[1] = seg.colors[1]; + _colors_t[2] = seg.colors[2]; + if (seg.getOption(SEG_OPTION_TRANSITIONAL)) seg.transition.handleTransition(&seg, _bri_t, _cct_t, _colors_t); + if (!cctFromRgb || correctWB) busses.setSegmentCCT(_cct_t, correctWB); for (uint8_t c = 0; c < NUM_COLORS; c++) { _colors_t[c] = gamma32(_colors_t[c]); } handle_palette(); - delay = (*_mode[SEGMENT.mode])(); - if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++; + delay = (*_mode[seg.mode])(); + if (seg.mode != FX_MODE_HALLOWEEN_EYES) _segment_runtimes[_segment_index].call++; } - SEGENV.next_time = nowUp + delay; + _segment_runtimes[_segment_index].next_time = nowUp + delay; } } _virtualSegmentLength = 0; @@ -449,84 +644,40 @@ void WS2812FX::service() { _triggered = false; } -// anti-aliased normalized version of setPixelColor() -void /*IRAM_ATTR*/ WS2812FX::setPixelColor(float i, byte r, byte g, byte b, byte w, bool aa) +void WS2812FX::setPixelColor(int i, uint32_t col) { - if (i<0.0f || i>1.0f) return; // not normalized + if (i >= _length) return; - float fC = i * (_virtualSegmentLength-1); - if (aa) { - uint16_t iL = roundf(fC-0.49f); - uint16_t iR = roundf(fC+0.49f); - float dL = fC - iL; - float dR = iR - fC; - uint32_t cIL = getPixelColor(iL); - uint32_t cIR = getPixelColor(iR); - if (iR!=iL) { - // blend L pixel - cIL = color_blend(RGBW32(r,g,b,w), cIL, uint8_t(dL*255.0f)); - setPixelColor(iL, R(cIL), G(cIL), B(cIL), W(cIL)); - // blend R pixel - cIR = color_blend(RGBW32(r,g,b,w), cIR, uint8_t(dR*255.0f)); - setPixelColor(iR, R(cIR), G(cIR), B(cIR), W(cIR)); - } else { - // exact match (x & y land on a pixel) - setPixelColor(iL, r, g, b, w); - } - } else { - setPixelColor(uint16_t(roundf(fC)), r, g, b, w); - } -} - -void IRAM_ATTR WS2812FX::setPixelColor(int i, byte r, byte g, byte b, byte w) -{ - uint8_t segIdx = _virtualSegmentLength ? _segment_index : _mainSegment; - if (isMatrix && _virtualSegmentLength) { - // map linear pixel into 2D segment area (even for 1D segments, expanding vertically) - uint16_t h = _segments[segIdx].virtualHeight(); // segment height in logical pixels - for (uint16_t y = 0; y < h; y++) { // expand 1D effect vertically - setPixelColorXY(i, y * _segments[segIdx].groupLength(), r, g, b, w); - } - return; - } - - if (_virtualSegmentLength || (realtimeMode && useMainSegmentOnly)) { - //color_blend(getpixel, col, _bri_t); (pseudocode for future blending of segments) - if (_virtualSegmentLength && _bri_t < 255) { // _virtualSegmentLength!=0 -> from segment/FX - r = scale8(r, _bri_t); - g = scale8(g, _bri_t); - b = scale8(b, _bri_t); - w = scale8(w, _bri_t); - } - uint32_t col = RGBW32(r, g, b, w); - uint16_t len = _segments[segIdx].length(); // length of segment in number of pixels + // if realtime mode is active and applying to main segment + if (realtimeMode && useMainSegmentOnly) { + uint16_t len = _segments[_mainSegment].length(); // length of segment in number of pixels // get physical pixel address (taking into account start, grouping, spacing [and offset]) - i = i * _segments[segIdx].groupLength(); - if (_segments[segIdx].getOption(SEG_OPTION_REVERSED)) { // is segment reversed? - if (_segments[segIdx].getOption(SEG_OPTION_MIRROR)) { // is segment mirrored? + i = i * _segments[_mainSegment].groupLength(); + if (_segments[_mainSegment].getOption(SEG_OPTION_REVERSED)) { // is segment reversed? + if (_segments[_mainSegment].getOption(SEG_OPTION_MIRROR)) { // is segment mirrored? i = (len - 1) / 2 - i; //only need to index half the pixels } else { i = (len - 1) - i; } } - i += _segments[segIdx].start; // starting pixel in a group + i += _segments[_mainSegment].start; // starting pixel in a group // set all the pixels in the group - for (uint16_t j = 0; j < _segments[segIdx].grouping; j++) { - uint16_t indexSet = i + ((_segments[segIdx].getOption(SEG_OPTION_REVERSED)) ? -j : j); - if (indexSet >= _segments[segIdx].start && indexSet < _segments[segIdx].stop) { + for (uint16_t j = 0; j < _segments[_mainSegment].grouping; j++) { + uint16_t indexSet = i + ((_segments[_mainSegment].getOption(SEG_OPTION_REVERSED)) ? -j : j); + if (indexSet >= _segments[_mainSegment].start && indexSet < _segments[_mainSegment].stop) { - if (_segments[segIdx].getOption(SEG_OPTION_MIRROR)) { //set the corresponding mirrored pixel - uint16_t indexMir = _segments[segIdx].stop - indexSet + _segments[segIdx].start - 1; - indexMir += _segments[segIdx].offset; // offset/phase - if (indexMir >= _segments[segIdx].stop) indexMir -= len; // wrap + if (_segments[_mainSegment].getOption(SEG_OPTION_MIRROR)) { //set the corresponding mirrored pixel + uint16_t indexMir = _segments[_mainSegment].stop - indexSet + _segments[_mainSegment].start - 1; + indexMir += _segments[_mainSegment].offset; // offset/phase + if (indexMir >= _segments[_mainSegment].stop) indexMir -= len; // wrap if (indexMir < customMappingSize) indexMir = customMappingTable[indexMir]; busses.setPixelColor(indexMir, col); } - indexSet += _segments[segIdx].offset; // offset/phase - if (indexSet >= _segments[segIdx].stop) indexSet -= len; // wrap + indexSet += _segments[_mainSegment].offset; // offset/phase + if (indexSet >= _segments[_mainSegment].stop) indexSet -= len; // wrap if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet]; busses.setPixelColor(indexSet, col); @@ -534,10 +685,20 @@ void IRAM_ATTR WS2812FX::setPixelColor(int i, byte r, byte g, byte b, byte w) } } else { if (i < customMappingSize) i = customMappingTable[i]; - busses.setPixelColor(i, RGBW32(r, g, b, w)); + busses.setPixelColor(i, col); } } +uint32_t WS2812FX::getPixelColor(uint16_t i) +{ + if (i >= _length) return 0; + //#ifndef WLED_DISABLE_2D + //if (isMatrix) return getPixelColorXY(i%matrixWidth, i/matrixWidth); // compatibility w/ non-effect fn + //#endif + if (i < customMappingSize) i = customMappingTable[i]; + return busses.getPixelColor(i); +} + //DISCLAIMER //The following function attemps to calculate the current LED power usage, @@ -683,7 +844,7 @@ void WS2812FX::setColor(uint8_t slot, uint32_t c) { for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { if (_segments[i].isActive() && _segments[i].isSelected()) { - _segments[i].setColor(slot, c, i); + _segments[i].setColor(slot, c); } } } @@ -692,7 +853,7 @@ void WS2812FX::setCCT(uint16_t k) { for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { if (_segments[i].isActive() && _segments[i].isSelected()) { - _segments[i].setCCT(k, i); + _segments[i].setCCT(k); } } } @@ -758,31 +919,6 @@ uint8_t WS2812FX::getActiveSegmentsNum(void) { return c; } -uint32_t WS2812FX::getPixelColor(uint16_t i) -{ - if (isMatrix) return getPixelColorXY(i%matrixWidth, i/matrixWidth); // compatibility w/ non-effect fn - - // get physical pixel - if (SEGMENT.getOption(SEG_OPTION_REVERSED)) i = SEGMENT.virtualLength() - i - 1; - i *= SEGMENT.groupLength(); - //if (SEGMENT.getOption(SEG_OPTION_REVERSED)) { - // if (SEGMENT.getOption(SEG_OPTION_MIRROR)) i = (SEGMENT.length() - 1) / 2 - i; //only need to index half the pixels - // else i = (SEGMENT.length() - 1) - i; - //} - i += SEGMENT.start; - - if (_virtualSegmentLength) { - /* offset/phase */ - i += SEGMENT.offset; - if (i >= SEGMENT.stop) i -= SEGMENT.length(); - } - - if (i < customMappingSize) i = customMappingTable[i]; - if (i >= _length) return 0; - - return busses.getPixelColor(i); -} - uint16_t WS2812FX::getLengthPhysical(void) { uint16_t len = 0; for (uint8_t b = 0; b < busses.getNumBusses(); b++) { @@ -850,10 +986,12 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, return; } if (isMatrix) { + #ifndef WLED_DISABLE_2D if (i1 < matrixWidth) seg.start = i1; seg.stop = i2 > matrixWidth ? matrixWidth : i2; if (startY < matrixHeight) seg.startY = startY; seg.stopY = stopY > matrixHeight ? matrixHeight : MAX(1,stopY); + #endif } else { if (i1 < _length) seg.start = i1; seg.stop = i2 > _length ? _length : i2; @@ -898,7 +1036,7 @@ void WS2812FX::resetSegments() { for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++) { - _segments[i].colors[0] = color_wheel(i*51); + _segments[i].colors[0] = _segments[i].color_wheel(i*51); _segments[i].grouping = 1; _segments[i].setOption(SEG_OPTION_ON, 1); _segments[i].opacity = 255; @@ -915,6 +1053,7 @@ void WS2812FX::resetSegments() { void WS2812FX::makeAutoSegments(bool forceReset) { if (isMatrix) { + #ifndef WLED_DISABLE_2D // only create 1 2D segment uint8_t mainSeg = getMainSegmentId(); if (forceReset) { @@ -925,6 +1064,7 @@ void WS2812FX::makeAutoSegments(bool forceReset) { if (getActiveSegmentsNum() < 2) { setSegment(mainSeg, 0, matrixWidth, 1, 0, 0, 0, matrixHeight); } + #endif } else if (autoSegments) { //make one segment per bus uint16_t segStarts[MAX_NUM_SEGMENTS] = {0}; uint16_t segStops [MAX_NUM_SEGMENTS] = {0}; @@ -947,7 +1087,7 @@ void WS2812FX::makeAutoSegments(bool forceReset) { s++; } for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { - _segments[i].setOption(SEG_OPTION_SELECTED, true, i); + _segments[i].setOption(SEG_OPTION_SELECTED, true); setSegment(i, segStarts[i], segStops[i]); } } else { @@ -1003,7 +1143,7 @@ uint8_t WS2812FX::setPixelSegment(uint8_t n) uint8_t prevSegId = _segment_index; if (n < MAX_NUM_SEGMENTS) { _segment_index = n; - _virtualSegmentLength = SEGMENT.virtualLength(); + //_virtualSegmentLength = _segments[_segment_index].virtualLength(); } return prevSegId; } @@ -1031,187 +1171,41 @@ void WS2812FX::setTransitionMode(bool t) } } -/* - * Fills segment with color - */ -void WS2812FX::fill(uint32_t c, uint8_t seg) { - uint8_t oldSeg; - if (seg != 255) oldSeg = setPixelSegment(seg); - const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); - const uint16_t rows = SEGMENT.virtualHeight(); // will be 1 for 1D - for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { - if (isMatrix) setPixelColorXY(x, y, c); - else setPixelColor(x, c); - } - if (seg != 255) setPixelSegment(oldSeg); -} - -/* - * Blends the specified color with the existing pixel color. - */ -void WS2812FX::blendPixelColor(uint16_t n, uint32_t color, uint8_t blend) -{ - setPixelColor(n, color_blend(getPixelColor(n), color, blend)); -} - -/* - * fade out function, higher rate = quicker fade - */ -void WS2812FX::fade_out(uint8_t rate) { - const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); - const uint16_t rows = SEGMENT.virtualHeight(); // will be 1 for 1D - - rate = (255-rate) >> 1; - float mappedRate = float(rate) +1.1; - - uint32_t color = SEGCOLOR(1); // target color - int w2 = W(color); - int r2 = R(color); - int g2 = G(color); - int b2 = B(color); - - for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { - color = isMatrix ? getPixelColorXY(x, y) : getPixelColor(x); - int w1 = W(color); - int r1 = R(color); - int g1 = G(color); - int b1 = B(color); - - int wdelta = (w2 - w1) / mappedRate; - int rdelta = (r2 - r1) / mappedRate; - int gdelta = (g2 - g1) / mappedRate; - int bdelta = (b2 - b1) / mappedRate; - - // if fade isn't complete, make sure delta is at least 1 (fixes rounding issues) - wdelta += (w2 == w1) ? 0 : (w2 > w1) ? 1 : -1; - rdelta += (r2 == r1) ? 0 : (r2 > r1) ? 1 : -1; - gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1; - bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1; - - if (isMatrix) setPixelColorXY(x, y, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta); - else setPixelColor(x, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta); - } -} - -// fades all pixels to black using nscale8() -void WS2812FX::fadeToBlackBy(uint8_t fadeBy) { - const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); - const uint16_t rows = SEGMENT.virtualHeight(); // will be 1 for 1D - - for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { - if (isMatrix) setPixelColorXY(x, y, CRGB(getPixelColorXY(x,y)).nscale8(255-fadeBy)); - else setPixelColor(x, CRGB(getPixelColor(x)).nscale8(255-fadeBy)); - } -} - -/* - * blurs segment content, source: FastLED colorutils.cpp - */ -void WS2812FX::blur(uint8_t blur_amount) -{ - if (isMatrix) { - // compatibility with 2D - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); - for (uint16_t i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows - for (uint16_t k = 0; k < cols; k++) blurCol(k, blur_amount); // blur all columns - return; - } - uint8_t keep = 255 - blur_amount; - uint8_t seep = blur_amount >> 1; - CRGB carryover = CRGB::Black; - for(uint16_t i = 0; i < _virtualSegmentLength; i++) - { - CRGB cur = CRGB(getPixelColor(i)); - CRGB part = cur; - part.nscale8(seep); - cur.nscale8(keep); - cur += carryover; - if(i > 0) { - uint32_t c = getPixelColor(i-1); - uint8_t r = R(c); - uint8_t g = G(c); - uint8_t b = B(c); - setPixelColor(i-1, qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue)); - } - setPixelColor(i,cur.red, cur.green, cur.blue); - carryover = part; - } -} - -uint16_t WS2812FX::triwave16(uint16_t in) -{ - if (in < 0x8000) return in *2; - return 0xFFFF - (in - 0x8000)*2; -} - -/* - * Generates a tristate square wave w/ attac & decay - * @param x input value 0-255 - * @param pulsewidth 0-127 - * @param attdec attac & decay, max. pulsewidth / 2 - * @returns signed waveform value - */ -int8_t WS2812FX::tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec) { - int8_t a = 127; - if (x > 127) { - a = -127; - x -= 127; - } - - if (x < attdec) { //inc to max - return (int16_t) x * a / attdec; - } - else if (x < pulsewidth - attdec) { //max - return a; - } - else if (x < pulsewidth) { //dec to 0 - return (int16_t) (pulsewidth - x) * a / attdec; - } - return 0; -} - -/* - * Put a value 0 to 255 in to get a color value. - * The colours are a transition r -> g -> b -> back to r - * Inspired by the Adafruit examples. - */ -uint32_t WS2812FX::color_wheel(uint8_t pos) { - if (SEGMENT.palette) return color_from_palette(pos, false, true, 0); - pos = 255 - pos; - if(pos < 85) { - return ((uint32_t)(255 - pos * 3) << 16) | ((uint32_t)(0) << 8) | (pos * 3); - } else if(pos < 170) { - pos -= 85; - return ((uint32_t)(0) << 16) | ((uint32_t)(pos * 3) << 8) | (255 - pos * 3); - } else { - pos -= 170; - return ((uint32_t)(pos * 3) << 16) | ((uint32_t)(255 - pos * 3) << 8) | (0); - } -} - -/* - * Returns a new, random wheel index with a minimum distance of 42 from pos. - */ -uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) { - uint8_t r = 0, x = 0, y = 0, d = 0; - - while(d < 42) { - r = random8(); - x = abs(pos - r); - y = 255 - x; - d = MIN(x, y); - } - return r; -} - - void WS2812FX::load_gradient_palette(uint8_t index) { - byte i = constrain(index, 0, GRADIENT_PALETTE_COUNT -1); byte tcp[72]; //support gradient palettes with up to 18 entries - memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[i])), 72); - targetPalette.loadDynamicGradientPalette(tcp); + if (index>127) { + char fileName[32]; + strcpy_P(fileName, PSTR("/palette")); + if (index>128) sprintf(fileName +7, "%d", index-127); + strcat(fileName, ".json"); + + if (WLED_FS.exists(fileName)) { + StaticJsonDocument<1536> pDoc; // barely enough to fit 72 numbers + DEBUG_PRINT(F("Reading palette from ")); + DEBUG_PRINTLN(fileName); + + if (readObjectFromFile(fileName, nullptr, &pDoc)) { + JsonArray pal = pDoc[F("palette")]; + if (!pal.isNull() && pal.size()>7) { // not an empty palette (at least 2 entries) + size_t palSize = MIN(pal.size(), 72); + palSize -= palSize % 4; // make sure size is multiple of 4 + for (int i=0; i()<256; i+=4) { + tcp[ i ] = (uint8_t) pal[ i ].as(); // index + tcp[i+1] = (uint8_t) pal[i+1].as(); // R + tcp[i+2] = (uint8_t) pal[i+2].as(); // G + tcp[i+3] = (uint8_t) pal[i+3].as(); // B + } + targetPalette.loadDynamicGradientPalette(tcp); + } + } + releaseJSONBufferLock(); + } + } else { + byte i = constrain(index, 0, GRADIENT_PALETTE_COUNT -1); + memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[i])), 72); + targetPalette.loadDynamicGradientPalette(tcp); + } } @@ -1223,10 +1217,11 @@ void WS2812FX::handle_palette(void) bool singleSegmentMode = (_segment_index == _segment_index_palette_last); _segment_index_palette_last = _segment_index; - byte paletteIndex = SEGMENT.palette; + byte paletteIndex = _segments[_segment_index].palette; if (paletteIndex == 0) //default palette. Differs depending on effect { - switch (SEGMENT.mode) + // TODO: get default palette ID from _modeData[] + switch (_segments[_segment_index].mode) { case FX_MODE_FIRE_2012 : paletteIndex = 35; break; //heat palette case FX_MODE_COLORWAVES : paletteIndex = 26; break; //landscape 33 @@ -1240,7 +1235,7 @@ void WS2812FX::handle_palette(void) case FX_MODE_FLOW : paletteIndex = 6; break; //party } } - if (SEGMENT.mode >= FX_MODE_METEOR && paletteIndex == 0) paletteIndex = 4; + if (_segments[_segment_index].mode >= FX_MODE_METEOR && paletteIndex == 0) paletteIndex = 4; switch (paletteIndex) { @@ -1251,7 +1246,7 @@ void WS2812FX::handle_palette(void) { targetPalette = PartyColors_p; break; //fallback } - if (millis() - _lastPaletteChange > 1000 + ((uint32_t)(255-SEGMENT.intensity))*100) + if (millis() - _lastPaletteChange > 1000 + ((uint32_t)(255-_segments[_segment_index].intensity))*100) { targetPalette = CRGBPalette16( CHSV(random8(), 255, random8(128, 255)), @@ -1300,7 +1295,7 @@ void WS2812FX::handle_palette(void) load_gradient_palette(paletteIndex -13); } - if (singleSegmentMode && paletteFade && SEGENV.call > 0) //only blend if just one segment uses FastLED mode + if (singleSegmentMode && paletteFade && _segment_runtimes[_segment_index].call > 0) //only blend if just one segment uses FastLED mode { nblendPaletteTowardPalette(currentPalette, targetPalette, 48); } else @@ -1310,33 +1305,6 @@ void WS2812FX::handle_palette(void) } -/* - * Gets a single color from the currently selected palette. - * @param i Palette Index (if mapping is true, the full palette will be _virtualSegmentLength long, if false, 255). Will wrap around automatically. - * @param mapping if true, LED position in segment is considered for color - * @param wrap FastLED palettes will usally wrap back to the start smoothly. Set false to get a hard edge - * @param mcol If the default palette 0 is selected, return the standard color 0, 1 or 2 instead. If >2, Party palette is used instead - * @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling) - * @returns Single color from palette - */ -uint32_t IRAM_ATTR WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) -{ - if ((SEGMENT.palette == 0 && mcol < 3) || _no_rgb) { - uint32_t color = SEGCOLOR(mcol); - if (pbri == 255) return color; - return RGBW32(scale8_video(R(color),pbri), scale8_video(G(color),pbri), scale8_video(B(color),pbri), scale8_video(W(color),pbri)); - } - - uint8_t paletteIndex = i; - if (mapping && _virtualSegmentLength > 1) paletteIndex = (i*255)/(_virtualSegmentLength -1); - if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end" - CRGB fastled_col; - fastled_col = ColorFromPalette(currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND); - - return RGBW32(fastled_col.r, fastled_col.g, fastled_col.b, 0); -} - - //load custom mapping table from JSON file (called from finalizeInit() or deserializeState()) void WS2812FX::deserializeMap(uint8_t n) { if (isMatrix) return; // 2D support creates its own ledmap diff --git a/wled00/button.cpp b/wled00/button.cpp index 0d224b73a..0567abb0e 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -199,7 +199,7 @@ void handleAnalog(uint8_t b) if (aRead == 0) { seg.setOption(SEG_OPTION_ON, 0); // off } else { - seg.setOpacity(aRead, macroDoublePress[b]); + seg.setOpacity(aRead); seg.setOption(SEG_OPTION_ON, 1); } // this will notify clients of update (websockets,mqtt,etc) diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index be5e1679c..b8796b8d8 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -91,6 +91,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { Bus::setCCTBlend(strip.cctBlending); strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS + #ifndef WLED_DISABLE_2D // 2D Matrix Settings JsonObject matrix = hw_led[F("matrix")]; if (!matrix.isNull()) { @@ -125,6 +126,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { strip.setUpMatrix(); } + #endif JsonArray ins = hw_led["ins"]; @@ -620,6 +622,7 @@ void serializeConfig() { hw_led["fps"] = strip.getTargetFps(); hw_led[F("rgbwm")] = Bus::getAutoWhiteMode(); // global override + #ifndef WLED_DISABLE_2D // 2D Matrix Settings if (strip.isMatrix) { JsonObject matrix = hw_led.createNestedObject(F("matrix")); @@ -641,6 +644,7 @@ void serializeConfig() { pnl["s"] = strip.panel[i].serpentine; } } + #endif JsonArray hw_led_ins = hw_led.createNestedArray("ins"); diff --git a/wled00/colors.cpp b/wled00/colors.cpp index ee00e84b3..abe1cc4cf 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -51,7 +51,7 @@ uint32_t color_add(uint32_t c1, uint32_t c2) void setRandomColor(byte* rgb) { - lastRandomIndex = strip.get_random_wheel_index(lastRandomIndex); + lastRandomIndex = strip.getMainSegment().get_random_wheel_index(lastRandomIndex); colorHStoRGB(lastRandomIndex*256,255,rgb); } diff --git a/wled00/ir.cpp b/wled00/ir.cpp index eaebfc323..aef847c1e 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -226,9 +226,9 @@ void changeColor(uint32_t c, int16_t cct=-1) if (isRGB) mask |= 0x00FFFFFF; // RGB if (hasW) mask |= 0xFF000000; // white if (hasW && !wSlider && (c & 0xFF000000)) { // segment has white channel & white channel is auto calculated & white specified - seg.setColor(0, c | 0xFFFFFF, i); // for accurate/brighter mode we fake white (since button may not set white color to 0xFFFFFF) - } else if (c & mask) seg.setColor(0, c & mask, i); // only apply if not black - if (isCCT && cct >= 0) seg.setCCT(cct, i); + seg.setColor(0, c | 0xFFFFFF); // for accurate/brighter mode we fake white (since button may not set white color to 0xFFFFFF) + } else if (c & mask) seg.setColor(0, c & mask); // only apply if not black + if (isCCT && cct >= 0) seg.setCCT(cct); } setValuesFromFirstSelectedSeg(); } else { @@ -243,9 +243,9 @@ void changeColor(uint32_t c, int16_t cct=-1) if (isRGB) mask |= 0x00FFFFFF; // RGB if (hasW) mask |= 0xFF000000; // white if (hasW && !wSlider && (c & 0xFF000000)) { // segment has white channel & white channel is auto calculated & white specified - seg.setColor(0, c | 0xFFFFFF, i); // for accurate/brighter mode we fake white (since button may not set white color to 0xFFFFFF) - } else if (c & mask) seg.setColor(0, c & mask, i); // only apply if not black - if (isCCT && cct >= 0) seg.setCCT(cct, i); + seg.setColor(0, c | 0xFFFFFF); // for accurate/brighter mode we fake white (since button may not set white color to 0xFFFFFF) + } else if (c & mask) seg.setColor(0, c & mask); // only apply if not black + if (isCCT && cct >= 0) seg.setCCT(cct); setValuesFromMainSeg(); } stateChanged = true; diff --git a/wled00/json.cpp b/wled00/json.cpp index 6a7ee85b0..0c4ce2115 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -72,7 +72,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) uint16_t spc = elem[F("spc")] | seg.spacing; uint16_t of = seg.offset; - if (spc>0 && spc!=seg.spacing) strip.fill(BLACK, id); // clear spacing gaps + if (spc>0 && spc!=seg.spacing) seg.fill(BLACK); // clear spacing gaps uint16_t len = 1; if (stop > start) len = stop - start; @@ -88,18 +88,18 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) byte segbri = seg.opacity; if (getVal(elem["bri"], &segbri)) { - if (segbri > 0) seg.setOpacity(segbri, id); - seg.setOption(SEG_OPTION_ON, segbri, id); + if (segbri > 0) seg.setOpacity(segbri); + seg.setOption(SEG_OPTION_ON, segbri); } bool on = elem["on"] | seg.getOption(SEG_OPTION_ON); if (elem["on"].is() && elem["on"].as()[0] == 't') on = !on; - seg.setOption(SEG_OPTION_ON, on, id); + seg.setOption(SEG_OPTION_ON, on); bool frz = elem["frz"] | seg.getOption(SEG_OPTION_FREEZE); if (elem["frz"].is() && elem["frz"].as()[0] == 't') frz = !seg.getOption(SEG_OPTION_FREEZE); - seg.setOption(SEG_OPTION_FREEZE, frz, id); + seg.setOption(SEG_OPTION_FREEZE, frz); - seg.setCCT(elem["cct"] | seg.cct, id); + seg.setCCT(elem["cct"] | seg.cct); JsonArray colarr = elem["col"]; if (!colarr.isNull()) @@ -115,7 +115,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) if (hexCol == nullptr) { //Kelvin color temperature (or invalid), e.g 2400 int kelvin = colarr[i] | -1; if (kelvin < 0) continue; - if (kelvin == 0) seg.setColor(i, 0, id); + if (kelvin == 0) seg.setColor(i, 0); if (kelvin > 0) colorKtoRGB(kelvin, brgbw); colValid = true; } else { //HEX string, e.g. "FFAA00" @@ -132,7 +132,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) if (!colValid) continue; - seg.setColor(i, RGBW32(rgbw[0],rgbw[1],rgbw[2],rgbw[3]), id); + seg.setColor(i, RGBW32(rgbw[0],rgbw[1],rgbw[2],rgbw[3])); if (seg.mode == FX_MODE_STATIC) strip.trigger(); //instant refresh } } @@ -152,10 +152,12 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) seg.setOption(SEG_OPTION_SELECTED, elem[F("sel")] | seg.getOption(SEG_OPTION_SELECTED)); seg.setOption(SEG_OPTION_REVERSED, elem["rev"] | seg.getOption(SEG_OPTION_REVERSED)); seg.setOption(SEG_OPTION_MIRROR , elem[F("mi")] | seg.getOption(SEG_OPTION_MIRROR )); + #ifndef WLED_DISABLE_2D // 2D options seg.setOption(SEG_OPTION_REVERSED_Y, elem[F("rY")] | seg.getOption(SEG_OPTION_REVERSED_Y)); seg.setOption(SEG_OPTION_MIRROR_Y , elem[F("mY")] | seg.getOption(SEG_OPTION_MIRROR_Y )); seg.setOption(SEG_OPTION_TRANSPOSED, elem[F("tp")] | seg.getOption(SEG_OPTION_TRANSPOSED)); + #endif byte fx = seg.mode; if (getVal(elem["fx"], &fx, 1, strip.getModeCount())) { //load effect ('r' random, '~' inc/dec, 1-255 exact value) @@ -173,7 +175,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) JsonArray iarr = elem[F("i")]; //set individual LEDs if (!iarr.isNull()) { - uint8_t oldSegId = strip.setPixelSegment(id); + //uint8_t oldSegId = strip.setPixelSegment(id); // set brightness immediately and disable transition transitionDelayTemp = 0; @@ -183,7 +185,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) // freeze and init to black if (!seg.getOption(SEG_OPTION_FREEZE)) { seg.setOption(SEG_OPTION_FREEZE, true); - strip.fill(0); + seg.fill(0); } uint16_t start = 0, stop = 0; @@ -215,16 +217,16 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) if (set < 2) stop = start + 1; for (uint16_t i = start; i < stop; i++) { if (strip.gammaCorrectCol) { - strip.setPixelColor(i, strip.gamma8(rgbw[0]), strip.gamma8(rgbw[1]), strip.gamma8(rgbw[2]), strip.gamma8(rgbw[3])); + seg.setPixelColor(i, strip.gamma8(rgbw[0]), strip.gamma8(rgbw[1]), strip.gamma8(rgbw[2]), strip.gamma8(rgbw[3])); } else { - strip.setPixelColor(i, rgbw[0], rgbw[1], rgbw[2], rgbw[3]); + seg.setPixelColor(i, rgbw[0], rgbw[1], rgbw[2], rgbw[3]); } } if (!set) start++; set = 0; } } - strip.setPixelSegment(oldSegId); + //strip.setPixelSegment(oldSegId); strip.trigger(); } // send UDP if not in preset and something changed that is not just selection @@ -249,10 +251,10 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) if (bri && !onBefore) { // unfreeze all segments when turning on for (uint8_t s=0; s < strip.getMaxSegments(); s++) { - strip.getSegment(s).setOption(SEG_OPTION_FREEZE, false, s); + strip.getSegment(s).setOption(SEG_OPTION_FREEZE, false); } if (realtimeMode && !realtimeOverride && useMainSegmentOnly) { // keep live segment frozen if live - strip.getMainSegment().setOption(SEG_OPTION_FREEZE, true, strip.getMainSegmentId()); + strip.getMainSegment().setOption(SEG_OPTION_FREEZE, true); } } @@ -304,7 +306,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) realtimeOverride = root[F("lor")] | realtimeOverride; if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS; if (realtimeMode && useMainSegmentOnly) { - strip.getMainSegment().setOption(SEG_OPTION_FREEZE, !realtimeOverride, strip.getMainSegmentId()); + strip.getMainSegment().setOption(SEG_OPTION_FREEZE, !realtimeOverride); } if (root.containsKey("live")) { @@ -520,11 +522,13 @@ void serializeInfo(JsonObject root) leds[F("maxseg")] = strip.getMaxSegments(); //leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config + #ifndef WLED_DISABLE_2D if (strip.isMatrix) { JsonObject matrix = leds.createNestedObject("matrix"); matrix["w"] = strip.matrixWidth; matrix["h"] = strip.matrixHeight; } + #endif uint8_t totalLC = 0; JsonArray lcarr = leds.createNestedArray(F("seglc")); diff --git a/wled00/led.cpp b/wled00/led.cpp index b43053bef..97d2810d1 100644 --- a/wled00/led.cpp +++ b/wled00/led.cpp @@ -41,8 +41,8 @@ void applyValuesToSelectedSegs() if (effectCurrent != selsegPrev.mode) {strip.setMode(i, effectCurrent); stateChanged = true;} uint32_t col0 = RGBW32( col[0], col[1], col[2], col[3]); uint32_t col1 = RGBW32(colSec[0], colSec[1], colSec[2], colSec[3]); - if (col0 != selsegPrev.colors[0]) {seg.setColor(0, col0, i); stateChanged = true;} - if (col1 != selsegPrev.colors[1]) {seg.setColor(1, col1, i); stateChanged = true;} + if (col0 != selsegPrev.colors[0]) {seg.setColor(0, col0); stateChanged = true;} + if (col1 != selsegPrev.colors[1]) {seg.setColor(1, col1); stateChanged = true;} } } diff --git a/wled00/lx_parser.cpp b/wled00/lx_parser.cpp index 8c5a9f91b..47674823b 100644 --- a/wled00/lx_parser.cpp +++ b/wled00/lx_parser.cpp @@ -69,7 +69,7 @@ void parseLxJson(int lxValue, byte segId, bool secondary) } else { DEBUG_PRINT(F("LX: segment ")); DEBUG_PRINTLN(segId); - strip.getSegment(segId).setColor(secondary, RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3]), segId); + strip.getSegment(segId).setColor(secondary, RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3])); } } } diff --git a/wled00/set.cpp b/wled00/set.cpp index c1edc811b..29bd9fe40 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -554,6 +554,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) releaseJSONBufferLock(); } + #ifndef WLED_DISABLE_2D //2D panels if (subPage == 10) { @@ -577,6 +578,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) } strip.setUpMatrix(); // will check limits } + #endif lastEditTime = millis(); if (subPage != 2 && !doReboot) serializeConfig(); //do not save if factory reset or LED settings (which are saved after LED re-init) @@ -664,9 +666,9 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) pos = req.indexOf(F("SB=")); //Segment brightness/opacity if (pos > 0) { byte segbri = getNumVal(&req, pos); - selseg.setOption(SEG_OPTION_ON, segbri, selectedSeg); + selseg.setOption(SEG_OPTION_ON, segbri); if (segbri) { - selseg.setOpacity(segbri, selectedSeg); + selseg.setOpacity(segbri); } } @@ -769,7 +771,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) if (pos > 0) { colorFromDecOrHexString(tmpCol, (char*)req.substring(pos + 3).c_str()); uint32_t col2 = RGBW32(tmpCol[0], tmpCol[1], tmpCol[2], tmpCol[3]); - selseg.setColor(2, col2, selectedSeg); // defined above (SS= or main) + selseg.setColor(2, col2); // defined above (SS= or main) stateChanged = true; if (!singleSegment) strip.setColor(2, col2); // will set color to all active & selected segments } @@ -798,14 +800,14 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) if (col0Changed) { stateChanged = true; uint32_t colIn0 = RGBW32(colIn[0], colIn[1], colIn[2], colIn[3]); - selseg.setColor(0, colIn0, selectedSeg); + selseg.setColor(0, colIn0); if (!singleSegment) strip.setColor(0, colIn0); // will set color to all active & selected segments } if (col1Changed) { stateChanged = true; uint32_t colIn1 = RGBW32(colInSec[0], colInSec[1], colInSec[2], colInSec[3]); - selseg.setColor(1, colIn1, selectedSeg); + selseg.setColor(1, colIn1); if (!singleSegment) strip.setColor(1, colIn1); // will set color to all active & selected segments } @@ -925,7 +927,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) realtimeOverride = getNumVal(&req, pos); if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS; if (realtimeMode && useMainSegmentOnly) { - strip.getMainSegment().setOption(SEG_OPTION_FREEZE, !realtimeOverride, strip.getMainSegmentId()); + strip.getMainSegment().setOption(SEG_OPTION_FREEZE, !realtimeOverride); } } diff --git a/wled00/udp.cpp b/wled00/udp.cpp index f14ad1467..6b9c9b177 100644 --- a/wled00/udp.cpp +++ b/wled00/udp.cpp @@ -146,7 +146,7 @@ void realtimeLock(uint32_t timeoutMs, byte md) Segment& mainseg = strip.getMainSegment(); start = mainseg.start; stop = mainseg.stop; - mainseg.setOption(SEG_OPTION_FREEZE, true, strip.getMainSegmentId()); + mainseg.setOption(SEG_OPTION_FREEZE, true); } else { start = 0; stop = strip.getLengthTotal(); @@ -156,7 +156,7 @@ void realtimeLock(uint32_t timeoutMs, byte md) // if WLED was off and using main segment only, freeze non-main segments so they stay off if (useMainSegmentOnly && bri == 0) { for (uint8_t s=0; s < strip.getMaxSegments(); s++) { - strip.getSegment(s).setOption(SEG_OPTION_FREEZE, true, s); + strip.getSegment(s).setOption(SEG_OPTION_FREEZE, true); } } } @@ -183,7 +183,7 @@ void exitRealtime() { realtimeMode = REALTIME_MODE_INACTIVE; // inform UI immediately realtimeIP[0] = 0; if (useMainSegmentOnly) { // unfreeze live segment again - strip.getMainSegment().setOption(SEG_OPTION_FREEZE, false, strip.getMainSegmentId()); + strip.getMainSegment().setOption(SEG_OPTION_FREEZE, false); } updateInterfaces(CALL_MODE_WS_SEND); } @@ -351,8 +351,8 @@ void handleNotifications() strip.setSegment(id, start, stop, selseg.grouping, selseg.spacing, offset); continue; } - for (uint8_t j = 0; j<4; j++) selseg.setOption(j, (udpIn[9 +ofs] >> j) & 0x01, id); //only take into account mirrored, selected, on, reversed - selseg.setOpacity(udpIn[10+ofs], id); + for (uint8_t j = 0; j<4; j++) selseg.setOption(j, (udpIn[9 +ofs] >> j) & 0x01); //only take into account mirrored, selected, on, reversed + selseg.setOpacity(udpIn[10+ofs]); if (applyEffects) { strip.setMode(id, udpIn[11+ofs]); selseg.speed = udpIn[12+ofs]; @@ -360,10 +360,10 @@ void handleNotifications() selseg.palette = udpIn[14+ofs]; } if (receiveNotificationColor || !someSel) { - selseg.setColor(0, RGBW32(udpIn[15+ofs],udpIn[16+ofs],udpIn[17+ofs],udpIn[18+ofs]), id); - selseg.setColor(1, RGBW32(udpIn[19+ofs],udpIn[20+ofs],udpIn[21+ofs],udpIn[22+ofs]), id); - selseg.setColor(2, RGBW32(udpIn[23+ofs],udpIn[24+ofs],udpIn[25+ofs],udpIn[26+ofs]), id); - selseg.setCCT(udpIn[27+ofs], id); + selseg.setColor(0, RGBW32(udpIn[15+ofs],udpIn[16+ofs],udpIn[17+ofs],udpIn[18+ofs])); + selseg.setColor(1, RGBW32(udpIn[19+ofs],udpIn[20+ofs],udpIn[21+ofs],udpIn[22+ofs])); + selseg.setColor(2, RGBW32(udpIn[23+ofs],udpIn[24+ofs],udpIn[25+ofs],udpIn[26+ofs])); + selseg.setCCT(udpIn[27+ofs]); } //setSegment() also properly resets segments if (receiveSegmentBounds) { diff --git a/wled00/util.cpp b/wled00/util.cpp index 6900c88c8..2af571abf 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -238,14 +238,13 @@ uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLe char lineBuffer[256]; //strcpy_P(lineBuffer, (const char*)pgm_read_dword(&(WS2812FX::_modeData[mode]))); strcpy_P(lineBuffer, strip.getModeData(mode)); - if (strlen(lineBuffer) > 0) { - size_t j = 0; - for (; j < maxLen; j++) { - if (lineBuffer[j] == '\0' || lineBuffer[j] == '@') break; - dest[j] = lineBuffer[j]; - } - dest[j] = 0; // terminate string + size_t len = strlen(lineBuffer); + size_t j = 0; + for (; j < maxLen && j < len; j++) { + if (lineBuffer[j] == '\0' || lineBuffer[j] == '@') break; + dest[j] = lineBuffer[j]; } + dest[j] = 0; // terminate string return strlen(dest); } else return 0; } diff --git a/wled00/wled.h b/wled00/wled.h index e86e340d9..e854526b9 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2207041 +#define VERSION 2207081 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG @@ -152,19 +152,19 @@ using PSRAMDynamicJsonDocument = BasicJsonDocument; #define PSRAMDynamicJsonDocument DynamicJsonDocument #endif +#include "const.h" #include "fcn_declare.h" #include "html_ui.h" #ifdef WLED_ENABLE_SIMPLE_UI -#include "html_simple.h" + #include "html_simple.h" #endif #include "html_settings.h" #include "html_other.h" -#include "FX.h" #include "ir_codes.h" -#include "const.h" #include "NodeStruct.h" #include "pin_manager.h" #include "bus_manager.h" +#include "FX.h" #ifndef CLIENT_SSID #define CLIENT_SSID DEFAULT_CLIENT_SSID diff --git a/wled00/xml.cpp b/wled00/xml.cpp index b621012fd..dd8a24d4f 100644 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -636,6 +636,7 @@ void getSettingsJS(byte subPage, char* dest) if (subPage == 10) // 2D matrices { sappend('v',SET_F("SOMP"),strip.isMatrix); + #ifndef WLED_DISABLE_2D oappend(SET_F("resetPanels();")); if (strip.isMatrix) { sappend('v',SET_F("PH"),strip.panelH); @@ -660,5 +661,8 @@ void getSettingsJS(byte subPage, char* dest) pO[l] = 'S'; sappend('c',pO,strip.panel[i].serpentine); } } + #else + oappend(SET_F("gId(\"somp\").remove(1);")); // remove 2D option from dropdown + #endif } }