Merge branch 'segment-api' into audioreactive-prototype

This commit is contained in:
Blaz Kristan 2022-07-29 22:29:15 +02:00
commit 267239e3f2
10 changed files with 2163 additions and 2141 deletions

View File

@ -1910,7 +1910,7 @@ uint16_t mode_juggle(void){
for ( byte i = 0; i < 8; i++) { for ( byte i = 0; i < 8; i++) {
uint16_t index = 0 + beatsin88((128 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1); uint16_t index = 0 + beatsin88((128 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1);
fastled_col = CRGB(SEGMENT.getPixelColor(index)); fastled_col = CRGB(SEGMENT.getPixelColor(index));
fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(strip.currentPalette, dothue, 255); fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(SEGPALETTE, dothue, 255);
SEGMENT.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; dothue += 32;
} }
@ -2015,14 +2015,14 @@ uint16_t mode_fire_2012()
for (uint16_t f = 0; f < cols; f++) { for (uint16_t f = 0; f < cols; f++) {
// Step 4. Map from heat cells to LED colors // Step 4. Map from heat cells to LED colors
for (uint16_t j = 0; j < rows; j++) { for (uint16_t j = 0; j < rows; j++) {
CRGB color = ColorFromPalette(strip.currentPalette, /*MIN(*/heat[j+rows*f]/*,240)*/, 255, LINEARBLEND); CRGB color = ColorFromPalette(SEGPALETTE, /*MIN(*/heat[j+rows*f]/*,240)*/, 255, LINEARBLEND);
if (strip.isMatrix) SEGMENT.setPixelColorXY(f, rows -j -1, color); if (strip.isMatrix) SEGMENT.setPixelColorXY(f, rows -j -1, color);
else SEGMENT.setPixelColor(j, color); else SEGMENT.setPixelColor(j, color);
} }
} }
return FRAMETIME; return FRAMETIME;
} }
static const char *_data_FX_MODE_FIRE_2012 PROGMEM = "Fire 2012 1D/2D@Cooling=120,Spark rate=64;1,2,3;!=35"; static const char *_data_FX_MODE_FIRE_2012 PROGMEM = "Fire 2012 1D/2D@Cooling=120,Spark rate=64;1,2,3;!";
// ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb // ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb
@ -2064,7 +2064,7 @@ uint16_t mode_colorwaves()
uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536; uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536;
bri8 += (255 - brightdepth); bri8 += (255 - brightdepth);
CRGB newcolor = ColorFromPalette(strip.currentPalette, hue8, bri8); CRGB newcolor = ColorFromPalette(SEGPALETTE, hue8, bri8);
fastled_col = CRGB(SEGMENT.getPixelColor(i)); fastled_col = CRGB(SEGMENT.getPixelColor(i));
nblend(fastled_col, newcolor, 128); nblend(fastled_col, newcolor, 128);
@ -2074,7 +2074,7 @@ uint16_t mode_colorwaves()
SEGENV.aux0 = sHue16; SEGENV.aux0 = sHue16;
return FRAMETIME; return FRAMETIME;
} }
static const char *_data_FX_MODE_COLORWAVES PROGMEM = "Colorwaves@!,!;!,!,!;!=26"; static const char *_data_FX_MODE_COLORWAVES PROGMEM = "Colorwaves@!,!;!,!,!;!";
// colored stripes pulsing at a defined Beats-Per-Minute (BPM) // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
@ -2084,7 +2084,7 @@ uint16_t mode_bpm()
uint32_t stp = (strip.now / 20) & 0xFF; uint32_t stp = (strip.now / 20) & 0xFF;
uint8_t beat = beatsin8(SEGMENT.speed, 64, 255); uint8_t beat = beatsin8(SEGMENT.speed, 64, 255);
for (uint16_t i = 0; i < SEGLEN; i++) { for (uint16_t i = 0; i < SEGLEN; i++) {
fastled_col = ColorFromPalette(strip.currentPalette, stp + (i * 2), beat - stp + (i * 10)); fastled_col = ColorFromPalette(SEGPALETTE, stp + (i * 2), beat - stp + (i * 10));
SEGMENT.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; return FRAMETIME;
@ -2098,14 +2098,14 @@ uint16_t mode_fillnoise8()
CRGB fastled_col; CRGB fastled_col;
for (uint16_t i = 0; i < SEGLEN; i++) { for (uint16_t i = 0; i < SEGLEN; i++) {
uint8_t index = inoise8(i * SEGLEN, SEGENV.step + i * SEGLEN); uint8_t index = inoise8(i * SEGLEN, SEGENV.step + i * SEGLEN);
fastled_col = ColorFromPalette(strip.currentPalette, index, 255, LINEARBLEND); fastled_col = ColorFromPalette(SEGPALETTE, index, 255, LINEARBLEND);
SEGMENT.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 SEGENV.step += beatsin8(SEGMENT.speed, 1, 6); //10,1,4
return FRAMETIME; return FRAMETIME;
} }
static const char *_data_FX_MODE_FILLNOISE8 PROGMEM = "Fill Noise@!,!;!,!,!;!=9"; static const char *_data_FX_MODE_FILLNOISE8 PROGMEM = "Fill Noise@!,!;!,!,!;!";
uint16_t mode_noise16_1() uint16_t mode_noise16_1()
@ -2128,13 +2128,13 @@ uint16_t mode_noise16_1()
uint8_t index = sin8(noise * 3); // map LED color based on noise data 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. fastled_col = ColorFromPalette(SEGPALETTE, index, 255, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
SEGMENT.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; return FRAMETIME;
} }
static const char *_data_FX_MODE_NOISE16_1 PROGMEM = "Noise 1@!,!;!,!,!;!=20"; static const char *_data_FX_MODE_NOISE16_1 PROGMEM = "Noise 1@!,!;!,!,!;!";
uint16_t mode_noise16_2() uint16_t mode_noise16_2()
@ -2153,13 +2153,13 @@ uint16_t mode_noise16_2()
uint8_t index = sin8(noise * 3); // map led color based on noise data 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. fastled_col = ColorFromPalette(SEGPALETTE, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
SEGMENT.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; return FRAMETIME;
} }
static const char *_data_FX_MODE_NOISE16_2 PROGMEM = "Noise 2@!,!;!,!,!;!=43"; static const char *_data_FX_MODE_NOISE16_2 PROGMEM = "Noise 2@!,!;!,!,!;!";
uint16_t mode_noise16_3() uint16_t mode_noise16_3()
@ -2181,13 +2181,13 @@ uint16_t mode_noise16_3()
uint8_t index = sin8(noise * 3); // map led color based on noise data 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. fastled_col = ColorFromPalette(SEGPALETTE, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
SEGMENT.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; return FRAMETIME;
} }
static const char *_data_FX_MODE_NOISE16_3 PROGMEM = "Noise 3@!,!;!,!,!;!=35"; static const char *_data_FX_MODE_NOISE16_3 PROGMEM = "Noise 3@!,!;!,!,!;!";
//https://github.com/aykevl/ledstrip-spark/blob/master/ledstrip.ino //https://github.com/aykevl/ledstrip-spark/blob/master/ledstrip.ino
@ -2197,12 +2197,12 @@ uint16_t mode_noise16_4()
uint32_t stp = (strip.now * SEGMENT.speed) >> 7; uint32_t stp = (strip.now * SEGMENT.speed) >> 7;
for (uint16_t i = 0; i < SEGLEN; i++) { for (uint16_t i = 0; i < SEGLEN; i++) {
int16_t index = inoise16(uint32_t(i) << 12, stp); int16_t index = inoise16(uint32_t(i) << 12, stp);
fastled_col = ColorFromPalette(strip.currentPalette, index); fastled_col = ColorFromPalette(SEGPALETTE, index);
SEGMENT.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; return FRAMETIME;
} }
static const char *_data_FX_MODE_NOISE16_4 PROGMEM = "Noise 4@!,!;!,!,!;!=26"; static const char *_data_FX_MODE_NOISE16_4 PROGMEM = "Noise 4@!,!;!,!,!;!";
//based on https://gist.github.com/kriegsman/5408ecd397744ba0393e //based on https://gist.github.com/kriegsman/5408ecd397744ba0393e
@ -2258,7 +2258,7 @@ uint16_t mode_colortwinkle()
uint16_t j = i % cols, k = i / cols; uint16_t j = i % cols, k = i / cols;
uint32_t col = strip.isMatrix ? SEGMENT.getPixelColorXY(j, k) : SEGMENT.getPixelColor(i); uint32_t col = strip.isMatrix ? SEGMENT.getPixelColorXY(j, k) : SEGMENT.getPixelColor(i);
if (col == 0) { if (col == 0) {
fastled_col = ColorFromPalette(strip.currentPalette, random8(), 64, NOBLEND); fastled_col = ColorFromPalette(SEGPALETTE, random8(), 64, NOBLEND);
uint16_t index = i >> 3; uint16_t index = i >> 3;
uint8_t bitNum = i & 0x07; uint8_t bitNum = i & 0x07;
bitWrite(SEGENV.data[index], bitNum, true); bitWrite(SEGENV.data[index], bitNum, true);
@ -2286,7 +2286,7 @@ uint16_t mode_lake() {
{ {
int index = cos8((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2; int index = cos8((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2;
uint8_t lum = (index > wave3) ? index - wave3 : 0; uint8_t lum = (index > wave3) ? index - wave3 : 0;
fastled_col = ColorFromPalette(strip.currentPalette, map(index,0,255,0,240), lum, LINEARBLEND); fastled_col = ColorFromPalette(SEGPALETTE, map(index,0,255,0,240), lum, LINEARBLEND);
SEGMENT.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; return FRAMETIME;
@ -2551,7 +2551,7 @@ CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat)
uint8_t hue = slowcycle8 - salt; uint8_t hue = slowcycle8 - salt;
CRGB c; CRGB c;
if (bright > 0) { if (bright > 0) {
c = ColorFromPalette(strip.currentPalette, hue, bright, NOBLEND); c = ColorFromPalette(SEGPALETTE, hue, bright, NOBLEND);
if(COOL_LIKE_INCANDESCENT == 1) { if(COOL_LIKE_INCANDESCENT == 1) {
// This code takes a pixel, and if its in the 'fading down' // This code takes a pixel, and if its in the 'fading down'
// part of the cycle, it adjusts the color a little bit like the // part of the cycle, it adjusts the color a little bit like the
@ -2941,7 +2941,7 @@ uint16_t mode_glitter()
return FRAMETIME; return FRAMETIME;
} }
static const char *_data_FX_MODE_GLITTER PROGMEM = "Glitter@,!;!,!,!;!=11;mp12=0"; //pixels static const char *_data_FX_MODE_GLITTER PROGMEM = "Glitter@,!;!,!,!;!;mp12=0"; //pixels
//each needs 19 bytes //each needs 19 bytes
@ -3544,7 +3544,7 @@ uint16_t mode_plasma(void) {
uint8_t colorIndex = cubicwave8((i*(2+ 3*(SEGMENT.speed >> 5))+thisPhase) & 0xFF)/2 // factor=23 // Create a wave and add a phase change and add another wave with its own phase change. uint8_t colorIndex = cubicwave8((i*(2+ 3*(SEGMENT.speed >> 5))+thisPhase) & 0xFF)/2 // factor=23 // Create a wave and add a phase change and add another wave with its own phase change.
+ cos8((i*(1+ 2*(SEGMENT.speed >> 5))+thatPhase) & 0xFF)/2; // factor=15 // Hey, you can even change the frequencies if you wish. + 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)))); uint8_t thisBright = qsub8(colorIndex, beatsin8(7,0, (128 - (SEGMENT.intensity>>1))));
CRGB color = ColorFromPalette(strip.currentPalette, colorIndex, thisBright, LINEARBLEND); CRGB color = ColorFromPalette(SEGPALETTE, colorIndex, thisBright, LINEARBLEND);
SEGMENT.setPixelColor(i, color.red, color.green, color.blue); SEGMENT.setPixelColor(i, color.red, color.green, color.blue);
} }
@ -3687,9 +3687,9 @@ uint16_t mode_pacifica()
0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF }; 0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF };
if (SEGMENT.palette) { if (SEGMENT.palette) {
pacifica_palette_1 = strip.currentPalette; pacifica_palette_1 = SEGPALETTE;
pacifica_palette_2 = strip.currentPalette; pacifica_palette_2 = SEGPALETTE;
pacifica_palette_3 = strip.currentPalette; pacifica_palette_3 = SEGPALETTE;
} }
// Increment the four "color index start" counters, one for each wave layer. // Increment the four "color index start" counters, one for each wave layer.
@ -3818,7 +3818,7 @@ uint16_t mode_sunrise() {
return FRAMETIME; return FRAMETIME;
} }
static const char *_data_FX_MODE_SUNRISE PROGMEM = "Sunrise@Time [min]=60,;;!=35"; static const char *_data_FX_MODE_SUNRISE PROGMEM = "Sunrise@Time [min]=60,;;!";
/* /*
@ -3907,7 +3907,7 @@ uint16_t mode_noisepal(void) { // Slow noise
//EVERY_N_MILLIS(10) { //(don't have to time this, effect function is only called every 24ms) //EVERY_N_MILLIS(10) { //(don't have to time this, effect function is only called every 24ms)
nblendPaletteTowardPalette(palettes[0], palettes[1], 48); // Blend towards the target palette over 48 iterations. nblendPaletteTowardPalette(palettes[0], palettes[1], 48); // Blend towards the target palette over 48 iterations.
if (SEGMENT.palette > 0) palettes[0] = strip.currentPalette; if (SEGMENT.palette > 0) palettes[0] = SEGPALETTE;
for(int i = 0; i < SEGLEN; i++) { 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. 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.
@ -3979,7 +3979,7 @@ uint16_t mode_flow(void)
return FRAMETIME; return FRAMETIME;
} }
static const char *_data_FX_MODE_FLOW PROGMEM = "Flow@!,!;!,!,!;!=6;mp12=1"; //vertical static const char *_data_FX_MODE_FLOW PROGMEM = "Flow@!,!;!,!,!;!;mp12=1"; //vertical
/* /*
@ -4522,7 +4522,7 @@ uint16_t mode_wavesins(void) {
for (uint16_t i = 0; i < SEGLEN; i++) { for (uint16_t i = 0; i < SEGLEN; i++) {
uint8_t bri = sin8(millis()/4 + i * SEGMENT.intensity); uint8_t bri = sin8(millis()/4 + i * SEGMENT.intensity);
SEGMENT.setPixelColor(i, ColorFromPalette(strip.currentPalette, beatsin8(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * SEGMENT.custom3), bri, LINEARBLEND)); SEGMENT.setPixelColor(i, ColorFromPalette(SEGPALETTE, beatsin8(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * SEGMENT.custom3), bri, LINEARBLEND));
} }
return FRAMETIME; return FRAMETIME;
@ -4634,7 +4634,7 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (cols - 1)); byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (cols - 1));
byte y1 = beatsin8(5 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 24); byte y1 = beatsin8(5 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 24);
byte y2 = beatsin8(3 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 48 + 64); byte y2 = beatsin8(3 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 48 + 64);
CRGB color = ColorFromPalette(strip.currentPalette, i * 255 / numLines + (SEGENV.aux0&0xFF), 255, LINEARBLEND); CRGB color = ColorFromPalette(SEGPALETTE, i * 255 / numLines + (SEGENV.aux0&0xFF), 255, LINEARBLEND);
byte xsteps = abs8(x1 - y1) + 1; byte xsteps = abs8(x1 - y1) + 1;
byte ysteps = abs8(x2 - y2) + 1; byte ysteps = abs8(x2 - y2) + 1;
@ -4679,8 +4679,8 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa
SEGMENT.fadeToBlackBy(leds, 64); SEGMENT.fadeToBlackBy(leds, 64);
for(int i = 0; i < cols; i++) { 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))] = ColorFromPalette(SEGPALETTE, 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 leds[XY(i, beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4+128))] = ColorFromPalette(SEGPALETTE,i*5+128+millis()/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND); // 180 degrees (128) out of phase
} }
SEGMENT.blur2d(leds, SEGMENT.intensity/8); SEGMENT.blur2d(leds, SEGMENT.intensity/8);
@ -4724,7 +4724,7 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma
for (size_t k = 1; k <= steps; k++) { for (size_t k = 1; k <= steps; k++) {
byte dx = lerp8by8(x, x1, k * 255 / steps); byte dx = lerp8by8(x, x1, k * 255 / steps);
uint16_t index = XY(dx, i); uint16_t index = XY(dx, i);
leds[index] += ColorFromPalette(strip.currentPalette, SEGENV.aux0, 255, LINEARBLEND); leds[index] += ColorFromPalette(SEGPALETTE, SEGENV.aux0, 255, LINEARBLEND);
leds[index] %= (k * 255 / steps); //for draw gradient line leds[index] %= (k * 255 / steps); //for draw gradient line
} }
leds[XY(x, i)] += CRGB::DarkSlateGray; leds[XY(x, i)] += CRGB::DarkSlateGray;
@ -4763,7 +4763,7 @@ uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmateli
float angle = radians(t * (maxDim - i)); float angle = radians(t * (maxDim - i));
uint16_t myX = (cols>>1) + (uint16_t)(sin_t(angle) * i) + (cols%2); uint16_t myX = (cols>>1) + (uint16_t)(sin_t(angle) * i) + (cols%2);
uint16_t myY = (rows>>1) + (uint16_t)(cos_t(angle) * i) + (rows%2); 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); leds[XY(myX,myY)] = ColorFromPalette(SEGPALETTE, (i * 20) + (t / 20), 255, LINEARBLEND);
} }
SEGMENT.blur2d(leds, SEGMENT.intensity>>3); SEGMENT.blur2d(leds, SEGMENT.intensity>>3);
@ -4792,7 +4792,7 @@ uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline
uint32_t yscale = SEGMENT.speed*8; uint32_t yscale = SEGMENT.speed*8;
uint8_t indexx = 0; uint8_t indexx = 0;
strip.currentPalette = CRGBPalette16( CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0), SEGPALETTE = CRGBPalette16( CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0),
CRGB::Red, CRGB::Red, CRGB::Red, CRGB::DarkOrange, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::DarkOrange,
CRGB::DarkOrange,CRGB::DarkOrange, CRGB::Orange, CRGB::Orange, CRGB::DarkOrange,CRGB::DarkOrange, CRGB::Orange, CRGB::Orange,
CRGB::Yellow, CRGB::Orange, CRGB::Yellow, CRGB::Yellow); CRGB::Yellow, CRGB::Orange, CRGB::Yellow, CRGB::Yellow);
@ -4800,7 +4800,7 @@ uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline
for (uint16_t j=0; j < cols; j++) { for (uint16_t j=0; j < cols; j++) {
for (uint16_t i=0; i < rows; i++) { for (uint16_t i=0; i < rows; i++) {
indexx = inoise8(j*yscale*rows/255, i*xscale+millis()/4); // We're moving along our Perlin map. indexx = inoise8(j*yscale*rows/255, i*xscale+millis()/4); // We're moving along our Perlin map.
leds[XY(j,i)] = ColorFromPalette(strip.currentPalette, min(i*(indexx)>>4, 255), i*255/cols, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. leds[XY(j,i)] = ColorFromPalette(SEGPALETTE, min(i*(indexx)>>4, 255), i*255/cols, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
} // for i } // for i
} // for j } // for j
@ -4827,7 +4827,7 @@ uint16_t mode_2DFrizzles(void) { // By: Stepko https://editor.so
SEGMENT.fadeToBlackBy(leds, 16); SEGMENT.fadeToBlackBy(leds, 16);
for (size_t i = 8; i > 0; i--) { for (size_t 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); leds[XY(beatsin8(SEGMENT.speed/8 + i, 0, cols - 1), beatsin8(SEGMENT.intensity/8 - i, 0, rows - 1))] += ColorFromPalette(SEGPALETTE, beatsin8(12, 0, 255), 255, LINEARBLEND);
} }
SEGMENT.blur2d(leds, 16); SEGMENT.blur2d(leds, 16);
@ -5247,7 +5247,7 @@ uint16_t mode_2Dnoise(void) { // By Andrew Tuline
for (uint16_t y = 0; y < rows; y++) { for (uint16_t y = 0; y < rows; y++) {
for (uint16_t x = 0; x < cols; x++) { for (uint16_t x = 0; x < cols; x++) {
uint8_t pixelHue8 = inoise8(x * scale, y * scale, millis() / (16 - SEGMENT.speed/16)); uint8_t pixelHue8 = inoise8(x * scale, y * scale, millis() / (16 - SEGMENT.speed/16));
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(strip.currentPalette, pixelHue8)); SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, pixelHue8));
} }
} }
@ -5289,7 +5289,7 @@ uint16_t mode_2DPlasmaball(void) { // By: Stepko https://edito
(cols - cx == 0) || (cols - cx == 0) ||
(cols - 1 - cx == 0) || (cols - 1 - cx == 0) ||
((rows - cy == 0) || ((rows - cy == 0) ||
(rows - 1 - cy == 0)) ? ColorFromPalette(strip.currentPalette, beat8(5), thisVal, LINEARBLEND) : CRGB::Black; (rows - 1 - cy == 0)) ? ColorFromPalette(SEGPALETTE, beat8(5), thisVal, LINEARBLEND) : CRGB::Black;
} }
} }
SEGMENT.blur2d(leds, 4); SEGMENT.blur2d(leds, 4);
@ -5380,7 +5380,7 @@ uint16_t mode_2DPulser(void) { // By: ldirko https://edi
uint16_t x = (a / 14); uint16_t x = (a / 14);
uint16_t y = map((sin8(a * 5) + sin8(a * 4) + sin8(a * 2)), 0, 765, rows-1, 0); uint16_t y = map((sin8(a * 5) + sin8(a * 4) + sin8(a * 2)), 0, 765, rows-1, 0);
uint16_t index = XY(x, y); // XY() will wrap x or y 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); leds[index] = ColorFromPalette(SEGPALETTE, map(y, 0, rows-1, 0, 255), 255, LINEARBLEND);
SEGMENT.blur2d(leds, 1 + (SEGMENT.intensity>>4)); SEGMENT.blur2d(leds, 1 + (SEGMENT.intensity>>4));
@ -5411,7 +5411,7 @@ uint16_t mode_2DSindots(void) { // By: ldirko http
for (uint16_t i = 0; i < 13; i++) { for (uint16_t i = 0; i < 13; i++) {
byte x = sin8(t1 + i * SEGMENT.intensity/8)*(cols-1)/255; // max index now 255x15/255=15! byte x = sin8(t1 + i * SEGMENT.intensity/8)*(cols-1)/255; // max index now 255x15/255=15!
byte y = sin8(t2 + i * SEGMENT.intensity/8)*(rows-1)/255; // max index now 255x15/255=15! 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); leds[XY(x, y)] = ColorFromPalette(SEGPALETTE, i * 255 / 13, 255, LINEARBLEND);
} }
SEGMENT.blur2d(leds, 16); SEGMENT.blur2d(leds, 16);
@ -5454,9 +5454,9 @@ uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://g
uint16_t ms = millis(); uint16_t ms = millis();
leds[XY(i, m)] += ColorFromPalette(strip.currentPalette, ms/29, 255, LINEARBLEND); leds[XY(i, m)] += ColorFromPalette(SEGPALETTE, ms/29, 255, LINEARBLEND);
leds[XY(j, n)] += ColorFromPalette(strip.currentPalette, ms/41, 255, LINEARBLEND); leds[XY(j, n)] += ColorFromPalette(SEGPALETTE, ms/41, 255, LINEARBLEND);
leds[XY(k, p)] += ColorFromPalette(strip.currentPalette, ms/73, 255, LINEARBLEND); leds[XY(k, p)] += ColorFromPalette(SEGPALETTE, ms/73, 255, LINEARBLEND);
SEGMENT.setPixels(leds); SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
@ -5538,9 +5538,9 @@ uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.so
for (uint16_t y = 0; y < rows; y++) { for (uint16_t y = 0; y < rows; y++) {
uint16_t index = XY(x, y); uint16_t index = XY(x, y);
hue = x * beatsin16(10, 1, 10) + offsetY; hue = x * beatsin16(10, 1, 10) + offsetY;
leds[index] = ColorFromPalette(strip.currentPalette, hue, sin8(x * SEGMENT.speed + offsetX) * sin8(x * SEGMENT.speed + offsetX) / 255, LINEARBLEND); leds[index] = ColorFromPalette(SEGPALETTE, hue, sin8(x * SEGMENT.speed + offsetX) * sin8(x * SEGMENT.speed + offsetX) / 255, LINEARBLEND);
hue = y * 3 + offsetX; hue = y * 3 + offsetX;
leds[index] += ColorFromPalette(strip.currentPalette, hue, sin8(y * SEGMENT.intensity + offsetY) * sin8(y * SEGMENT.intensity + offsetY) / 255, LINEARBLEND); leds[index] += ColorFromPalette(SEGPALETTE, hue, sin8(y * SEGMENT.intensity + offsetY) * sin8(y * SEGMENT.intensity + offsetY) / 255, LINEARBLEND);
} }
} }
@ -5580,7 +5580,7 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht
for (size_t i = 0; i < 8; i++) { for (size_t i = 0; i < 8; i++) {
byte x = beatsin8(12 + i, 2, cols - 3); byte x = beatsin8(12 + i, 2, cols - 3);
byte y = beatsin8(15 + i, 2, rows - 3); byte y = beatsin8(15 + i, 2, rows - 3);
CRGB color = ColorFromPalette(strip.currentPalette, beatsin8(12 + i, 0, 255), 255); CRGB color = ColorFromPalette(SEGPALETTE, beatsin8(12 + i, 0, 255), 255);
leds[XY(x, y)] += color; leds[XY(x, y)] += color;
if (cols > 24 || rows > 24) { if (cols > 24 || rows > 24) {
leds[XY(x + 1, y)] += color; leds[XY(x + 1, y)] += color;
@ -5615,7 +5615,7 @@ uint16_t mode_2Dcrazybees(void) {
uint8_t posX, posY, aimX, aimY, hue; uint8_t posX, posY, aimX, aimY, hue;
int8_t deltaX, deltaY, signX, signY, error; int8_t deltaX, deltaY, signX, signY, error;
void aimed(uint16_t w, uint16_t h) { void aimed(uint16_t w, uint16_t h) {
randomSeed(millis()); random16_set_seed(millis());
aimX = random8(0, w); aimX = random8(0, w);
aimY = random8(0, h); aimY = random8(0, h);
hue = random8(); hue = random8();
@ -5709,7 +5709,7 @@ uint16_t mode_2Dghostrider(void) {
SEGENV.aux0 = cols; SEGENV.aux0 = cols;
SEGENV.aux1 = rows; SEGENV.aux1 = rows;
SEGMENT.fill_solid(leds, CRGB::Black); SEGMENT.fill_solid(leds, CRGB::Black);
randomSeed(strip.now); random16_set_seed(strip.now);
lighter->angleSpeed = random8(0,20) - 10; lighter->angleSpeed = random8(0,20) - 10;
lighter->Vspeed = 5; lighter->Vspeed = 5;
lighter->gPosX = (cols/2) * 10; lighter->gPosX = (cols/2) * 10;
@ -5755,7 +5755,7 @@ uint16_t mode_2Dghostrider(void) {
lighter->lightersPosX[i] += -7 * sin_t(radians(lighter->Angle[i])); lighter->lightersPosX[i] += -7 * sin_t(radians(lighter->Angle[i]));
lighter->lightersPosY[i] += -7 * cos_t(radians(lighter->Angle[i])); lighter->lightersPosY[i] += -7 * cos_t(radians(lighter->Angle[i]));
} }
SEGMENT.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(SEGPALETTE, (256 - lighter->time[i])));
} }
SEGMENT.blur2d(leds, SEGMENT.intensity>>3); SEGMENT.blur2d(leds, SEGMENT.intensity>>3);
} }
@ -5828,7 +5828,7 @@ uint16_t mode_2Dfloatingblobs(void) {
blob->grow[i] = true; blob->grow[i] = true;
} }
} }
CRGB c = ColorFromPalette(strip.currentPalette, blob->color[i]); CRGB c = ColorFromPalette(SEGPALETTE, blob->color[i]);
//if (!SEGMENT.palette) c = SEGCOLOR(0); //if (!SEGMENT.palette) c = SEGCOLOR(0);
if (blob->r[i] > 1.f) SEGMENT.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; else leds[XY(blob->y[i], blob->x[i])] += c;
@ -6100,12 +6100,14 @@ uint16_t mode_2DSwirl(void) {
// printUmData(); // printUmData();
leds[XY( i, j)] += ColorFromPalette(strip.currentPalette, (ms / 11 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 11, 200, 255); float tmpSound = (soundAgc) ? rawSampleAgc : sampleRaw;
leds[XY( j, i)] += ColorFromPalette(strip.currentPalette, (ms / 13 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 13, 200, 255);
leds[XY(ni, nj)] += ColorFromPalette(strip.currentPalette, (ms / 17 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 17, 200, 255); leds[XY( i, j)] += ColorFromPalette(SEGPALETTE, (ms / 11 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 11, 200, 255);
leds[XY(nj, ni)] += ColorFromPalette(strip.currentPalette, (ms / 29 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 29, 200, 255); leds[XY( j, i)] += ColorFromPalette(SEGPALETTE, (ms / 13 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 13, 200, 255);
leds[XY( i, nj)] += ColorFromPalette(strip.currentPalette, (ms / 37 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 37, 200, 255); leds[XY(ni, nj)] += ColorFromPalette(SEGPALETTE, (ms / 17 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 17, 200, 255);
leds[XY(ni, j)] += ColorFromPalette(strip.currentPalette, (ms / 41 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 41, 200, 255); leds[XY(nj, ni)] += ColorFromPalette(SEGPALETTE, (ms / 29 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 29, 200, 255);
leds[XY( i, nj)] += ColorFromPalette(SEGPALETTE, (ms / 37 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 37, 200, 255);
leds[XY(ni, j)] += ColorFromPalette(SEGPALETTE, (ms / 41 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 41, 200, 255);
SEGMENT.setPixels(leds); SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
@ -6151,8 +6153,8 @@ uint16_t mode_2DWaverly(void) {
uint16_t thisMax = map(thisVal, 0, 512, 0, rows); uint16_t thisMax = map(thisVal, 0, 512, 0, rows);
for (uint16_t j = 0; j < thisMax; j++) { for (uint16_t j = 0; j < thisMax; j++) {
leds[XY(i, j)] += ColorFromPalette(strip.currentPalette, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND); leds[XY(i, j)] += ColorFromPalette(SEGPALETTE, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND);
leds[XY((cols - 1) - i, (rows - 1) - j)] += ColorFromPalette(strip.currentPalette, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND); leds[XY((cols - 1) - i, (rows - 1) - j)] += ColorFromPalette(SEGPALETTE, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND);
} }
} }
SEGMENT.blur2d(leds, 16); SEGMENT.blur2d(leds, 16);
@ -6407,7 +6409,7 @@ static const char *_data_FX_MODE_MIDNOISE PROGMEM = "Midnoise ♪@Fade rate,Maxi
////////////////////// //////////////////////
// I am the god of hellfire. . . Volume (only) reactive fire routine. Oh, look how short this is. // I am the god of hellfire. . . Volume (only) reactive fire routine. Oh, look how short this is.
uint16_t mode_noisefire(void) { // Noisefire. By Andrew Tuline. uint16_t mode_noisefire(void) { // Noisefire. By Andrew Tuline.
strip.currentPalette = CRGBPalette16(CHSV(0,255,2), CHSV(0,255,4), CHSV(0,255,8), CHSV(0, 255, 8), // Fire palette definition. Lower value = darker. SEGPALETTE = CRGBPalette16(CHSV(0,255,2), CHSV(0,255,4), CHSV(0,255,8), CHSV(0, 255, 8), // Fire palette definition. Lower value = darker.
CHSV(0, 255, 16), CRGB::Red, CRGB::Red, CRGB::Red, CHSV(0, 255, 16), CRGB::Red, CRGB::Red, CRGB::Red,
CRGB::DarkOrange,CRGB::DarkOrange, CRGB::Orange, CRGB::Orange, CRGB::DarkOrange,CRGB::DarkOrange, CRGB::Orange, CRGB::Orange,
CRGB::Yellow, CRGB::Orange, CRGB::Yellow, CRGB::Yellow); CRGB::Yellow, CRGB::Orange, CRGB::Yellow, CRGB::Yellow);
@ -6423,7 +6425,9 @@ uint16_t mode_noisefire(void) { // Noisefire. By Andrew Tuline.
uint16_t index = inoise8(i*SEGMENT.speed/64,millis()*SEGMENT.speed/64*SEGLEN/255); // X location is constant, but we move along the Y at the rate of millis(). By Andrew Tuline. uint16_t index = inoise8(i*SEGMENT.speed/64,millis()*SEGMENT.speed/64*SEGLEN/255); // X location is constant, but we move along the Y at the rate of millis(). By Andrew Tuline.
index = (255 - i*256/SEGLEN) * index/(256-SEGMENT.intensity); // Now we need to scale index so that it gets blacker as we get close to one of the ends. index = (255 - i*256/SEGLEN) * index/(256-SEGMENT.intensity); // Now we need to scale index so that it gets blacker as we get close to one of the ends.
// This is a simple y=mx+b equation that's been scaled. index/128 is another scaling. // This is a simple y=mx+b equation that's been scaled. index/128 is another scaling.
CRGB color = ColorFromPalette(strip.currentPalette, index, volumeSmth*2, LINEARBLEND); // Use the my own palette. uint8_t tmpSound = (soundAgc) ? sampleAgc : sampleAvg;
CRGB color = ColorFromPalette(SEGPALETTE, index, tmpSound*2, LINEARBLEND); // Use the my own palette.
SEGMENT.setPixelColor(i, color); SEGMENT.setPixelColor(i, color);
} }

View File

@ -76,7 +76,7 @@ uint32_t color_add(uint32_t,uint32_t);
#ifndef MAX_NUM_SEGMENTS #ifndef MAX_NUM_SEGMENTS
#define MAX_NUM_SEGMENTS 32 #define MAX_NUM_SEGMENTS 32
#endif #endif
#define MAX_SEGMENT_DATA 20480 #define MAX_SEGMENT_DATA 32768
#endif #endif
/* How much data bytes each segment should max allocate to leave enough space for other segments, /* How much data bytes each segment should max allocate to leave enough space for other segments,
@ -91,6 +91,7 @@ uint32_t color_add(uint32_t,uint32_t);
//#define SEGCOLOR(x) strip._segments[s//trip.getCurrSegmentId()].currentColor(x, strip._segments[strip.getCurrSegmentId()].colors[x]) //#define SEGCOLOR(x) strip._segments[s//trip.getCurrSegmentId()].currentColor(x, strip._segments[strip.getCurrSegmentId()].colors[x])
//#define SEGLEN strip._segments[strip.getCurrSegmentId()].virtualLength() //#define SEGLEN strip._segments[strip.getCurrSegmentId()].virtualLength()
#define SEGCOLOR(x) strip.segColor(x) /* saves us a few kbytes of code */ #define SEGCOLOR(x) strip.segColor(x) /* saves us a few kbytes of code */
#define SEGPALETTE strip._currentPalette
#define SEGLEN strip._virtualSegmentLength /* saves us a few kbytes of code */ #define SEGLEN strip._virtualSegmentLength /* saves us a few kbytes of code */
#define SPEED_FORMULA_L (5U + (50U*(255U - SEGMENT.speed))/SEGLEN) #define SPEED_FORMULA_L (5U + (50U*(255U - SEGMENT.speed))/SEGLEN)
@ -382,19 +383,19 @@ typedef struct Segment {
union { union {
uint16_t options; //bit pattern: msb first: [transposed mirrorY reverseY] transitional (tbd) paused needspixelstate mirrored on reverse selected uint16_t options; //bit pattern: msb first: [transposed mirrorY reverseY] transitional (tbd) paused needspixelstate mirrored on reverse selected
struct { struct {
uint16_t selected:1; // 0 : selected bool selected : 1; // 0 : selected
uint16_t reverse:1; // 1 : reversed bool reverse : 1; // 1 : reversed
uint16_t on:1; // 2 : is On bool on : 1; // 2 : is On
uint16_t mirror:1; // 3 : mirrored bool mirror : 1; // 3 : mirrored
uint16_t pxs:1; // 4 : indicates that the effect does not use FRAMETIME or needs getPixelColor (?) bool pxs : 1; // 4 : indicates that the effect does not use FRAMETIME or needs getPixelColor (?)
uint16_t freeze:1; // 5 : paused/frozen bool freeze : 1; // 5 : paused/frozen
uint16_t reset:1; // 6 : indicates that Segment runtime requires reset bool reset : 1; // 6 : indicates that Segment runtime requires reset
uint16_t transitional:1; // 7 : transitional (there is transition occuring) bool transitional: 1; // 7 : transitional (there is transition occuring)
uint16_t reverse_y:1; // 8 : reversed Y (2D) bool reverse_y : 1; // 8 : reversed Y (2D)
uint16_t mirror_y:1; // 9 : mirrored Y (2D) bool mirror_y : 1; // 9 : mirrored Y (2D)
uint16_t transpose:1; // 10 : transposed (2D, swapped X & Y) bool transpose : 1; // 10 : transposed (2D, swapped X & Y)
uint16_t map1D2D:2; // 11-12 : mapping for 1D effect on 2D (0-strip, 1-expand vertically, 2-circular, 3-rectangular) uint8_t map1D2D : 2; // 11-12 : mapping for 1D effect on 2D (0-strip, 1-expand vertically, 2-circular, 3-rectangular)
uint16_t soundSim:3; // 13-15 : 0-7 sound simulation types uint8_t soundSim : 3; // 13-15 : 0-7 sound simulation types
}; };
}; };
uint8_t grouping, spacing; uint8_t grouping, spacing;
@ -415,18 +416,29 @@ typedef struct Segment {
byte* data; byte* data;
private: private:
uint8_t _capabilities; union {
uint8_t _capabilities;
struct {
bool _isRGB : 1;
bool _hasW : 1;
bool _isCCT : 1;
bool _manualW : 1;
uint8_t _reserved : 4;
};
};
uint16_t _dataLen; uint16_t _dataLen;
// transition data, valid only if getOption(SEG_OPTION_TRANSITIONAL)==true // transition data, valid only if getOption(SEG_OPTION_TRANSITIONAL)==true, holds values during transition
//struct Transition { //struct Transition {
uint32_t _colorT[NUM_COLORS]; uint32_t _colorT[NUM_COLORS];
uint8_t _briT; uint8_t _briT; // temporary brightness
uint8_t _cctT; uint8_t _cctT; // temporary CCT
uint32_t _start; CRGBPalette16 _palT; // temporary palette
uint16_t _dur; //uint8_t _modeP; // previous mode/effect (transitioning effects is way more complex than this)
// Transition(uint16_t dur=10) : _briT(255), _cctT(127), _start(millis()), _dur(dur) {} uint32_t _start;
// Transition(uint16_t d, uint8_t b, uint8_t c, const uint32_t *o) : _briT(b), _cctT(c), _start(millis()), _dur(d) { uint16_t _dur;
// Transition(uint16_t dur=750) : _briT(255), _cctT(127), _palT(CRGBPalette16(CRGB::Black)), _modeP(FX_MODE_STATIC), _start(millis()), _dur(dur) {}
// Transition(uint16_t d, uint8_t b, uint8_t c, const uint32_t *o) : _briT(b), _cctT(c), _palT(CRGBPalette16(CRGB::Black)), _modeP(FX_MODE_STATIC), _start(millis()), _dur(d) {
// for (size_t i=0; i<NUM_COLORS; i++) _colorT[i] = o[i]; // for (size_t i=0; i<NUM_COLORS; i++) _colorT[i] = o[i];
// } // }
//} *_t; // this struct will bootloop ESP //} *_t; // this struct will bootloop ESP
@ -489,21 +501,21 @@ typedef struct Segment {
Segment& operator= (const Segment &orig); // copy assignment Segment& operator= (const Segment &orig); // copy assignment
Segment& operator= (Segment &&orig) noexcept; // move assignment Segment& operator= (Segment &&orig) noexcept; // move assignment
inline bool getOption(uint8_t n) { return ((options >> n) & 0x01); } inline bool getOption(uint8_t n) { return ((options >> n) & 0x01); }
inline bool isSelected() { return getOption(0); } inline bool isSelected(void) { return getOption(0); }
inline bool isActive() { return stop > start; } inline bool isActive(void) { return stop > start; }
inline uint16_t width() { return stop - start; } inline uint16_t width(void) { return stop - start; }
inline uint16_t height() { return stopY - startY; } inline uint16_t height(void) { return stopY - startY; }
inline uint16_t length() { return width(); } inline uint16_t length(void) { return width(); }
inline uint16_t groupLength() { return grouping + spacing; } inline uint16_t groupLength(void) { return grouping + spacing; }
inline uint8_t getLightCapabilities() { return _capabilities; } inline uint8_t getLightCapabilities(void) { return _capabilities; }
bool setColor(uint8_t slot, uint32_t c); //returns true if changed bool setColor(uint8_t slot, uint32_t c); //returns true if changed
void setCCT(uint16_t k); void setCCT(uint16_t k);
void setOpacity(uint8_t o); void setOpacity(uint8_t o);
void setOption(uint8_t n, bool val); void setOption(uint8_t n, bool val);
uint8_t differs(Segment& b); uint8_t differs(Segment& b);
void refreshLightCapabilities(); void refreshLightCapabilities(void);
// runtime data functions // runtime data functions
bool allocateData(uint16_t len); bool allocateData(uint16_t len);
@ -516,17 +528,19 @@ typedef struct Segment {
* Call resetIfRequired before calling the next effect function. * Call resetIfRequired before calling the next effect function.
* Safe to call from interrupts and network requests. * Safe to call from interrupts and network requests.
*/ */
inline void markForReset() { reset = true; } // setOption(SEG_OPTION_RESET, true) inline void markForReset(void) { reset = true; } // setOption(SEG_OPTION_RESET, true)
// transition functions // transition functions
void startTransition(uint16_t dur); // transition has to start before actual segment values change void startTransition(uint16_t dur); // transition has to start before actual segment values change
void handleTransition(void); void handleTransition(void);
uint16_t progress(); //transition progression between 0-65535 uint16_t progress(void); //transition progression between 0-65535
uint8_t currentBri(uint8_t briNew, bool useCct = false); uint8_t currentBri(uint8_t briNew, bool useCct = false);
uint32_t currentColor(uint8_t slot, uint32_t colorNew) { return getOption(SEG_OPTION_TRANSITIONAL) /*&& !_t*/ ? color_blend(/*_t->*/_colorT[slot], colorNew, progress(), true) : colorNew; } uint32_t currentColor(uint8_t slot, uint32_t colorNew) { return getOption(SEG_OPTION_TRANSITIONAL) /*&& !_t*/ ? color_blend(/*_t->*/_colorT[slot], colorNew, progress(), true) : colorNew; }
CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal);
CRGBPalette16 &currentPalette(CRGBPalette16 &tgt, uint8_t paletteID);
// 1D strip // 1D strip
uint16_t virtualLength(); uint16_t virtualLength(void);
void setPixelColor(int n, uint32_t c); // set relative pixel within segment with color 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, 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(int n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); } // automatically inline
@ -546,8 +560,8 @@ typedef struct Segment {
uint32_t color_wheel(uint8_t pos); uint32_t color_wheel(uint8_t pos);
// 2D matrix // 2D matrix
uint16_t virtualWidth(); uint16_t virtualWidth(void);
uint16_t virtualHeight(); uint16_t virtualHeight(void);
uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment (for leds[]) 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, 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, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline
@ -585,9 +599,10 @@ class WS2812FX { // 96 bytes
typedef uint16_t (*mode_ptr)(void); // pointer to mode function typedef uint16_t (*mode_ptr)(void); // pointer to mode function
typedef void (*show_callback)(void); // pre show callback typedef void (*show_callback)(void); // pre show callback
typedef struct ModeData { typedef struct ModeData {
uint8_t _id; // mode (effect) id
mode_ptr _fcn; // mode (effect) function mode_ptr _fcn; // mode (effect) function
const char *_data; // mode (effect) name and its slider control data array const char *_data; // mode (effect) name and its UI control data
ModeData(uint16_t (*fcn)(void), const char *data) : _fcn(fcn), _data(data) {} ModeData(uint8_t id, uint16_t (*fcn)(void), const char *data) : _id(id), _fcn(fcn), _data(data) {}
} mode_data_t; } mode_data_t;
static WS2812FX* instance; static WS2812FX* instance;
@ -616,13 +631,13 @@ class WS2812FX { // 96 bytes
matrix{0,0,0,0}, matrix{0,0,0,0},
panel{{0,0,0,0}}, panel{{0,0,0,0}},
#endif #endif
currentPalette(CRGBPalette16(CRGB::Black)), // semi-private (just obscured) used in effect functions through macros
targetPalette(CloudColors_p), _currentPalette(CRGBPalette16(CRGB::Black)),
_bri_t(0), _bri_t(0),
_colors_t{0,0,0}, _colors_t{0,0,0},
_virtualSegmentLength(0), _virtualSegmentLength(0),
// true private variables
_length(DEFAULT_LED_COUNT), _length(DEFAULT_LED_COUNT),
_rand16seed(0),
_brightness(DEFAULT_BRIGHTNESS), _brightness(DEFAULT_BRIGHTNESS),
_usedSegmentData(0), _usedSegmentData(0),
_transitionDur(750), _transitionDur(750),
@ -633,37 +648,27 @@ class WS2812FX { // 96 bytes
_isOffRefreshRequired(false), _isOffRefreshRequired(false),
_hasWhiteChannel(false), _hasWhiteChannel(false),
_triggered(false), _triggered(false),
_no_rgb(false),
_modeCount(MODE_COUNT), _modeCount(MODE_COUNT),
_callback(nullptr), _callback(nullptr),
customMappingTable(nullptr), customMappingTable(nullptr),
customMappingSize(0), customMappingSize(0),
_lastPaletteChange(0),
_lastShow(0), _lastShow(0),
_segment_index(0), _segment_index(0),
_segment_index_palette_last(99),
_mainSegment(0) _mainSegment(0)
{ {
WS2812FX::instance = this; WS2812FX::instance = this;
_mode.reserve(_modeCount); _mode.reserve(_modeCount); // allocate memory to prevent initial fragmentation
_modeData.reserve(_modeCount); _modeData.reserve(_modeCount); // allocate memory to prevent initial fragmentation
if (_mode.capacity() <= 1 || _modeData.capacity() <= 1) _modeCount = 1; if (_mode.capacity() <= 1 || _modeData.capacity() <= 1) _modeCount = 1;
else setupEffectData(); else setupEffectData();
/*
_mode = new mode_ptr[_modeCount];
_modeData = new const char*[_modeCount];
if (_mode && _modeData) setupEffectData();
else _modeCount = 1; // only Solid will work
*/
} }
~WS2812FX() { ~WS2812FX() {
if (customMappingTable) delete[] customMappingTable; if (customMappingTable) delete[] customMappingTable;
//delete[] _mode;
//delete[] _modeData;
_mode.clear(); _mode.clear();
_modeData.clear(); _modeData.clear();
_segments.clear(); _segments.clear();
customPalettes.clear();
} }
static WS2812FX* getInstance(void) { return instance; } static WS2812FX* getInstance(void) { return instance; }
@ -812,50 +817,38 @@ class WS2812FX { // 96 bytes
// end 2D support // end 2D support
CRGBPalette16 currentPalette; void loadCustomPalettes(void); // loads custom palettes from JSON
CRGBPalette16 targetPalette; CRGBPalette16 _currentPalette; // palette used for current effect (includes transition)
std::vector<CRGBPalette16> customPalettes; // TODO: move custom palettes out of WS2812FX class
// using public variables to reduce code size increase due to inline function getSegment() (with bounds checking) // using public variables to reduce code size increase due to inline function getSegment() (with bounds checking)
// and color transitions // and color transitions
uint8_t _bri_t; // used for opacity transitions uint8_t _bri_t; // opacity used for effect (includes transition)
uint32_t _colors_t[3]; // used for color transitions uint32_t _colors_t[3]; // color used for effect (includes transition)
uint16_t _virtualSegmentLength; uint16_t _virtualSegmentLength;
//segment _segments[MAX_NUM_SEGMENTS]; // SRAM footprint: 88 bytes per element std::vector<segment> _segments;
std::vector<segment> _segments; // deleting a segment while effects play crashes ESP
friend class Segment; friend class Segment;
//size_t segSize = sizeof(Segment);
//size_t segsSize = sizeof(_segments);
private: private:
uint16_t _length; uint16_t _length;
uint16_t _rand16seed; uint8_t _brightness;
uint8_t _brightness;
uint16_t _usedSegmentData; uint16_t _usedSegmentData;
uint16_t _transitionDur; uint16_t _transitionDur;
uint8_t _targetFps; uint8_t _targetFps;
uint16_t _frametime; uint16_t _frametime;
uint16_t _cumulativeFps; uint16_t _cumulativeFps;
// will require only 1 byte // will require only 1 byte
// struct { struct {
// byte _isServicing : 1; bool _isServicing : 1;
// byte _isOffRefreshRequired : 1; bool _isOffRefreshRequired : 1; //periodic refresh is required for the strip to remain off.
// byte _hasWhiteChannel : 1; bool _hasWhiteChannel : 1;
// byte _triggered : 1; bool _triggered : 1;
// byte _no_rgb : 1; };
// };
bool
_isServicing,
_isOffRefreshRequired, //periodic refresh is required for the strip to remain off.
_hasWhiteChannel,
_triggered,
_no_rgb;
uint8_t _modeCount; uint8_t _modeCount;
//mode_ptr *_mode; // SRAM footprint: 4 bytes per element
//const char **_modeData; // mode (effect) name and its slider control data array
std::vector<mode_ptr> _mode; // SRAM footprint: 4 bytes per element std::vector<mode_ptr> _mode; // SRAM footprint: 4 bytes per element
std::vector<const char*> _modeData; // mode (effect) name and its slider control data array std::vector<const char*> _modeData; // mode (effect) name and its slider control data array
@ -864,17 +857,13 @@ class WS2812FX { // 96 bytes
uint16_t* customMappingTable; uint16_t* customMappingTable;
uint16_t customMappingSize; uint16_t customMappingSize;
uint32_t _lastPaletteChange;
uint32_t _lastShow; uint32_t _lastShow;
uint8_t _segment_index; uint8_t _segment_index;
uint8_t _segment_index_palette_last;
uint8_t _mainSegment; uint8_t _mainSegment;
void void
estimateCurrentAndLimitBri(void), estimateCurrentAndLimitBri(void);
load_gradient_palette(uint8_t),
handle_palette(void);
}; };
extern const char JSON_mode_names[]; extern const char JSON_mode_names[];

View File

@ -82,7 +82,7 @@ Segment::Segment(const Segment &orig) {
_dataLen = 0; _dataLen = 0;
//_t = nullptr; //_t = nullptr;
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); } if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
if (orig.data) { allocateData(orig._dataLen); memcpy(data, orig.data, orig._dataLen); } if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); }
//if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); } //if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
DEBUG_PRINTF(" Original data: %p (%d)\n", orig.data, (int)orig._dataLen); DEBUG_PRINTF(" Original data: %p (%d)\n", orig.data, (int)orig._dataLen);
DEBUG_PRINTF(" Constructed data: %p (%d)\n", data, (int)_dataLen); DEBUG_PRINTF(" Constructed data: %p (%d)\n", data, (int)_dataLen);
@ -112,7 +112,7 @@ Segment& Segment::operator= (const Segment &orig) {
_dataLen = 0; _dataLen = 0;
//_t = nullptr; //_t = nullptr;
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); } if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
if (orig.data) { allocateData(orig._dataLen); memcpy(data, orig.data, orig._dataLen); } if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); }
//if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); } //if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
DEBUG_PRINTF(" Original data: %p (%d)\n", orig.data, (int)orig._dataLen); DEBUG_PRINTF(" Original data: %p (%d)\n", orig.data, (int)orig._dataLen);
DEBUG_PRINTF(" Copied data: %p (%d)\n", data, (int)_dataLen); DEBUG_PRINTF(" Copied data: %p (%d)\n", data, (int)_dataLen);
@ -188,15 +188,22 @@ void Segment::startTransition(uint16_t dur) {
// starting a transition has to occur before change so we get current values 1st // starting a transition has to occur before change so we get current values 1st
/*uint8_t*/ _briT = currentBri(getOption(SEG_OPTION_ON) ? opacity : 0); // comment out uint8_t if not using Transition struct /*uint8_t*/ _briT = currentBri(getOption(SEG_OPTION_ON) ? opacity : 0); // comment out uint8_t if not using Transition struct
/*uint8_t*/ _cctT = currentBri(cct, true); // comment out uint8_t if not using Transition struct /*uint8_t*/ _cctT = currentBri(cct, true); // comment out uint8_t if not using Transition struct
/*CRGBPalette16 _palT;*/ loadPalette(_palT, palette);
///*uint8_t*/ _modeP = mode; // comment out uint8_t if not using Transition struct
//uint32_t _colorT[NUM_COLORS]; // comment out if not using Transition struct //uint32_t _colorT[NUM_COLORS]; // comment out if not using Transition struct
for (size_t i=0; i<NUM_COLORS; i++) _colorT[i] = currentColor(i, colors[i]); for (size_t i=0; i<NUM_COLORS; i++) _colorT[i] = currentColor(i, colors[i]);
// comment out if not using Transition struct // using transition struct
//if (!_t) _t = new Transition(dur); // no previous transition running //if (!_t) _t = new Transition(dur); // no previous transition running
//if (!_t) return; // failed to allocat data //if (!_t) return; // failed to allocat data
//_t->_briT = _briT; //_t->_briT = _briT;
//_t->_cctT = _cctT; //_t->_cctT = _cctT;
//_t->_palT = _palT;
//_t->_modeT = _modeP;
//for (size_t i=0; i<NUM_COLORS; i++) _t->_colorT[i] = _colorT[i]; //for (size_t i=0; i<NUM_COLORS; i++) _t->_colorT[i] = _colorT[i];
// comment out if using transition struct as it is done in constructor
_dur = dur;
_start = millis();
setOption(SEG_OPTION_TRANSITIONAL, true); setOption(SEG_OPTION_TRANSITIONAL, true);
} }
@ -219,6 +226,96 @@ uint8_t Segment::currentBri(uint8_t briNew, bool useCct) {
} }
} }
CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
static unsigned long _lastPaletteChange = 0; // perhaps it should be per segment
byte tcp[72];
if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0;
if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0;
//default palette. Differs depending on effect
if (pal == 0) switch (mode) {
case FX_MODE_FIRE_2012 : pal = 35; break; // heat palette
case FX_MODE_COLORWAVES : pal = 26; break; // landscape 33
case FX_MODE_FILLNOISE8 : pal = 9; break; // ocean colors
case FX_MODE_NOISE16_1 : pal = 20; break; // Drywet
case FX_MODE_NOISE16_2 : pal = 43; break; // Blue cyan yellow
case FX_MODE_NOISE16_3 : pal = 35; break; // heat palette
case FX_MODE_NOISE16_4 : pal = 26; break; // landscape 33
case FX_MODE_GLITTER : pal = 11; break; // rainbow colors
case FX_MODE_SUNRISE : pal = 35; break; // heat palette
case FX_MODE_FLOW : pal = 6; break; // party
}
switch (pal) {
case 0: //default palette. Exceptions for specific effects above
targetPalette = PartyColors_p; break;
case 1: {//periodically replace palette with a random one. Doesn't work with multiple FastLED segments
if (millis() - _lastPaletteChange > 1000 + ((uint32_t)(255-intensity))*100) {
targetPalette = CRGBPalette16(
CHSV(random8(), 255, random8(128, 255)),
CHSV(random8(), 255, random8(128, 255)),
CHSV(random8(), 192, random8(128, 255)),
CHSV(random8(), 255, random8(128, 255)));
_lastPaletteChange = millis();
} break;}
case 2: {//primary color only
CRGB prim = CRGB(colors[0]);
targetPalette = CRGBPalette16(prim); break;}
case 3: {//primary + secondary
CRGB prim = CRGB(colors[0]);
CRGB sec = CRGB(colors[1]);
targetPalette = CRGBPalette16(prim,prim,sec,sec); break;}
case 4: {//primary + secondary + tertiary
CRGB prim = CRGB(colors[0]);
CRGB sec = CRGB(colors[1]);
CRGB ter = CRGB(colors[2]);
targetPalette = CRGBPalette16(ter,sec,prim); break;}
case 5: {//primary + secondary (+tert if not off), more distinct
CRGB prim = CRGB(colors[0]);
CRGB sec = CRGB(colors[1]);
if (colors[2]) {
CRGB ter = CRGB(colors[2]);
targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,ter,ter,ter,ter,ter,prim);
} else {
targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,sec,sec,sec);
}
break;}
case 6: //Party colors
targetPalette = PartyColors_p; break;
case 7: //Cloud colors
targetPalette = CloudColors_p; break;
case 8: //Lava colors
targetPalette = LavaColors_p; break;
case 9: //Ocean colors
targetPalette = OceanColors_p; break;
case 10: //Forest colors
targetPalette = ForestColors_p; break;
case 11: //Rainbow colors
targetPalette = RainbowColors_p; break;
case 12: //Rainbow stripe colors
targetPalette = RainbowStripeColors_p; break;
default: //progmem palettes
if (pal>245) {
targetPalette = strip.customPalettes[255-pal]; // we checked bounds above
} else {
memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[pal-13])), 72);
targetPalette.loadDynamicGradientPalette(tcp);
}
break;
}
return targetPalette;
}
CRGBPalette16 &Segment::currentPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
loadPalette(targetPalette, pal);
//if (_t && progress() < 0xFFFFU) {
if (strip.paletteFade && getOption(SEG_OPTION_TRANSITIONAL) && progress() < 0xFFFFU) { // TODO: get rid of
// blend palettes
uint8_t blends = map(_dur, 0, 0xFFFF, 48, 6); // do not blend palettes too quickly (0-65.5s)
nblendPaletteTowardPalette(/*_t->*/_palT, targetPalette, blends);
targetPalette = /*_t->*/_palT; // copy transitioning/temporary palette
}
return targetPalette;
}
void Segment::handleTransition() { void Segment::handleTransition() {
if (!getOption(SEG_OPTION_TRANSITIONAL)) return; if (!getOption(SEG_OPTION_TRANSITIONAL)) return;
unsigned long maxWait = millis() + 20; unsigned long maxWait = millis() + 20;
@ -231,7 +328,7 @@ void Segment::handleTransition() {
bool Segment::setColor(uint8_t slot, uint32_t c) { //returns true if changed bool Segment::setColor(uint8_t slot, uint32_t c) { //returns true if changed
if (slot >= NUM_COLORS || c == colors[slot]) return false; if (slot >= NUM_COLORS || c == colors[slot]) return false;
startTransition(strip.getTransition()); // start transition prior to change if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
colors[slot] = c; colors[slot] = c;
return true; return true;
} }
@ -243,19 +340,19 @@ void Segment::setCCT(uint16_t k) {
k = (k - 1900) >> 5; k = (k - 1900) >> 5;
} }
if (cct == k) return; if (cct == k) return;
startTransition(strip.getTransition()); // start transition prior to change if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
cct = k; cct = k;
} }
void Segment::setOpacity(uint8_t o) { void Segment::setOpacity(uint8_t o) {
if (opacity == o) return; if (opacity == o) return;
startTransition(strip.getTransition()); // start transition prior to change if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
opacity = o; opacity = o;
} }
void Segment::setOption(uint8_t n, bool val) { void Segment::setOption(uint8_t n, bool val) {
bool prevOn = getOption(SEG_OPTION_ON); bool prevOn = getOption(SEG_OPTION_ON);
if (n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change if (fadeTransition && n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change
if (val) options |= 0x01 << n; if (val) options |= 0x01 << n;
else options &= ~(0x01 << n); else options &= ~(0x01 << n);
} }
@ -640,8 +737,9 @@ uint8_t Segment::get_random_wheel_index(uint8_t pos) {
*/ */
uint32_t IRAM_ATTR Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) 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) { // default palette or no RGB support on segment
uint32_t color = colors[mcol]; // SEGCOLOR(mcol); if (palette == 0 || !(_capabilities & 0x01)) {
uint32_t color = colors[constrain(mcol,0,NUM_COLORS-1)]; // SEGCOLOR(mcol);
if (pbri == 255) return color; 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)); return RGBW32(scale8_video(R(color),pbri), scale8_video(G(color),pbri), scale8_video(B(color),pbri), scale8_video(W(color),pbri));
} }
@ -650,7 +748,10 @@ uint32_t IRAM_ATTR Segment::color_from_palette(uint16_t i, bool mapping, bool wr
if (mapping && virtualLength() > 1) paletteIndex = (i*255)/(virtualLength() -1); if (mapping && virtualLength() > 1) paletteIndex = (i*255)/(virtualLength() -1);
if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end" if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
CRGB fastled_col; CRGB fastled_col;
fastled_col = ColorFromPalette(strip.currentPalette, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); CRGBPalette16 curPal;
if (transitional) curPal = /*_t->*/_palT;
else loadPalette(curPal, palette);
fastled_col = ColorFromPalette(curPal, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
return RGBW32(fastled_col.r, fastled_col.g, fastled_col.b, 0); return RGBW32(fastled_col.r, fastled_col.g, fastled_col.b, 0);
} }
@ -743,19 +844,23 @@ void WS2812FX::service() {
if (!seg.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen if (!seg.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen
_virtualSegmentLength = seg.virtualLength(); _virtualSegmentLength = seg.virtualLength();
_bri_t = seg.currentBri(seg.getOption(SEG_OPTION_ON) ? seg.opacity : 0); _bri_t = seg.currentBri(seg.getOption(SEG_OPTION_ON) ? seg.opacity : 0);
uint8_t _cct_t = seg.currentBri(seg.cct, true); uint8_t _cct_t = seg.currentBri(seg.cct, true);
_colors_t[0] = seg.currentColor(0, seg.colors[0]); _colors_t[0] = seg.currentColor(0, seg.colors[0]);
_colors_t[1] = seg.currentColor(1, seg.colors[1]); _colors_t[1] = seg.currentColor(1, seg.colors[1]);
_colors_t[2] = seg.currentColor(2, seg.colors[2]); _colors_t[2] = seg.currentColor(2, seg.colors[2]);
seg.currentPalette(_currentPalette, seg.palette);
seg.handleTransition(); seg.handleTransition();
if (!cctFromRgb || correctWB) busses.setSegmentCCT(_cct_t, correctWB); if (!cctFromRgb || correctWB) busses.setSegmentCCT(_cct_t, correctWB);
for (uint8_t c = 0; c < NUM_COLORS; c++) { for (uint8_t c = 0; c < NUM_COLORS; c++) {
_colors_t[c] = gamma32(_colors_t[c]); _colors_t[c] = gamma32(_colors_t[c]);
} }
handle_palette();
// effect blending (execute previous effect)
// actual code may be a bit more involved as effects have runtime data including allocated memory
//if (getOption(SEG_OPTION_TRANSITIONAL) && seg._modeP) (*_mode[seg._modeP])(progress());
delay = (*_mode[seg.mode])(); delay = (*_mode[seg.mode])();
if (seg.mode != FX_MODE_HALLOWEEN_EYES) seg.call++; if (seg.mode != FX_MODE_HALLOWEEN_EYES) seg.call++;
} }
@ -971,7 +1076,7 @@ void WS2812FX::setMode(uint8_t segid, uint8_t m) {
if (m >= getModeCount()) m = getModeCount() - 1; if (m >= getModeCount()) m = getModeCount() - 1;
if (_segments[segid].mode != m) { if (_segments[segid].mode != m) {
//_segments[segid].startTransition(strip.getTransition()); // set effect transitions //_segments[segid].startTransition(_transitionDur); // set effect transitions
_segments[segid].markForReset(); _segments[segid].markForReset();
_segments[segid].mode = m; _segments[segid].mode = m;
} }
@ -1357,30 +1462,25 @@ void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col)
void WS2812FX::setTransitionMode(bool t) void WS2812FX::setTransitionMode(bool t)
{ {
for (segment &seg : _segments) seg.startTransition(t ? getTransition() : 0); for (segment &seg : _segments) if (!seg.transitional) seg.startTransition(t ? _transitionDur : 0);
// for (uint8_t i = 0; i < getMaxSegments(); i++) { // for (uint8_t i = 0; i < getMaxSegments(); i++) {
// Segment &seg = getSegment(i); // Segment &seg = getSegment(i);
// seg.startTransition(t ? getTransition() : 0); // if (!seg.transitional)seg.startTransition(t ? _transitionDur : 0);
// } // }
} }
void WS2812FX::load_gradient_palette(uint8_t index) void WS2812FX::loadCustomPalettes()
{ {
// NOTE: due to constant execution (in every effect update) of this code
// if loading from FS is requested it will produce excessive flickering
// loading of palette into RAM from FS should be optimised in such case
// (it is mandatory to load palettes in each service() as each segment can
// have its own palette)
byte tcp[72]; //support gradient palettes with up to 18 entries byte tcp[72]; //support gradient palettes with up to 18 entries
if (index>114) { CRGBPalette16 targetPalette;
for (int index = 0; index<10; index++) {
char fileName[32]; char fileName[32];
strcpy_P(fileName, PSTR("/palette")); strcpy_P(fileName, PSTR("/palette"));
sprintf(fileName +8, "%d", index-115); // palette ID == 128 sprintf(fileName +8, "%d", index);
strcat(fileName, ".json"); strcat(fileName, ".json");
StaticJsonDocument<1536> pDoc; // barely enough to fit 72 numbers
if (WLED_FS.exists(fileName)) { if (WLED_FS.exists(fileName)) {
StaticJsonDocument<1536> pDoc; // barely enough to fit 72 numbers
DEBUG_PRINT(F("Reading palette from ")); DEBUG_PRINT(F("Reading palette from "));
DEBUG_PRINTLN(fileName); DEBUG_PRINTLN(fileName);
@ -1394,115 +1494,17 @@ void WS2812FX::load_gradient_palette(uint8_t index)
tcp[i+1] = (uint8_t) pal[i+1].as<int>(); // R tcp[i+1] = (uint8_t) pal[i+1].as<int>(); // R
tcp[i+2] = (uint8_t) pal[i+2].as<int>(); // G tcp[i+2] = (uint8_t) pal[i+2].as<int>(); // G
tcp[i+3] = (uint8_t) pal[i+3].as<int>(); // B tcp[i+3] = (uint8_t) pal[i+3].as<int>(); // B
DEBUG_PRINTF("%d(%d) : %d %d %d\n", i, int(tcp[i]), int(tcp[i+1]), int(tcp[i+2]), int(tcp[i+3]));
} }
targetPalette.loadDynamicGradientPalette(tcp); customPalettes.push_back(targetPalette.loadDynamicGradientPalette(tcp));
} }
} }
} } else {
} else { break;
byte i = constrain(index, 0, GRADIENT_PALETTE_COUNT -1);
memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[i])), 72);
targetPalette.loadDynamicGradientPalette(tcp);
}
}
/*
* FastLED palette modes helper function. Limitation: Due to memory reasons, multiple active segments with FastLED will disable the Palette transitions
*/
void WS2812FX::handle_palette(void)
{
bool singleSegmentMode = (_segment_index == _segment_index_palette_last);
_segment_index_palette_last = _segment_index;
byte paletteIndex = _segments[_segment_index].palette;
if (paletteIndex == 0) //default palette. Differs depending on effect
{
// 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
case FX_MODE_FILLNOISE8 : paletteIndex = 9; break; //ocean colors
case FX_MODE_NOISE16_1 : paletteIndex = 20; break; //Drywet
case FX_MODE_NOISE16_2 : paletteIndex = 43; break; //Blue cyan yellow
case FX_MODE_NOISE16_3 : paletteIndex = 35; break; //heat palette
case FX_MODE_NOISE16_4 : paletteIndex = 26; break; //landscape 33
case FX_MODE_GLITTER : paletteIndex = 11; break; //rainbow colors
case FX_MODE_SUNRISE : paletteIndex = 35; break; //heat palette
case FX_MODE_FLOW : paletteIndex = 6; break; //party
} }
} }
if (_segments[_segment_index].mode >= FX_MODE_METEOR && paletteIndex == 0) paletteIndex = 4;
switch (paletteIndex)
{
case 0: //default palette. Exceptions for specific effects above
targetPalette = PartyColors_p; break;
case 1: {//periodically replace palette with a random one. Doesn't work with multiple FastLED segments
if (!singleSegmentMode)
{
targetPalette = PartyColors_p; break; //fallback
}
if (millis() - _lastPaletteChange > 1000 + ((uint32_t)(255-_segments[_segment_index].intensity))*100)
{
targetPalette = CRGBPalette16(
CHSV(random8(), 255, random8(128, 255)),
CHSV(random8(), 255, random8(128, 255)),
CHSV(random8(), 192, random8(128, 255)),
CHSV(random8(), 255, random8(128, 255)));
_lastPaletteChange = millis();
} break;}
case 2: {//primary color only
CRGB prim = CRGB(SEGCOLOR(0));
targetPalette = CRGBPalette16(prim); break;}
case 3: {//primary + secondary
CRGB prim = CRGB(SEGCOLOR(0));
CRGB sec = CRGB(SEGCOLOR(1));
targetPalette = CRGBPalette16(prim,prim,sec,sec); break;}
case 4: {//primary + secondary + tertiary
CRGB prim = CRGB(SEGCOLOR(0));
CRGB sec = CRGB(SEGCOLOR(1));
CRGB ter = CRGB(SEGCOLOR(2));
targetPalette = CRGBPalette16(ter,sec,prim); break;}
case 5: {//primary + secondary (+tert if not off), more distinct
CRGB prim = CRGB(SEGCOLOR(0));
CRGB sec = CRGB(SEGCOLOR(1));
if (SEGCOLOR(2)) {
CRGB ter = CRGB(SEGCOLOR(2));
targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,ter,ter,ter,ter,ter,prim);
} else {
targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,sec,sec,sec);
}
break;}
case 6: //Party colors
targetPalette = PartyColors_p; break;
case 7: //Cloud colors
targetPalette = CloudColors_p; break;
case 8: //Lava colors
targetPalette = LavaColors_p; break;
case 9: //Ocean colors
targetPalette = OceanColors_p; break;
case 10: //Forest colors
targetPalette = ForestColors_p; break;
case 11: //Rainbow colors
targetPalette = RainbowColors_p; break;
case 12: //Rainbow stripe colors
targetPalette = RainbowStripeColors_p; break;
default: //progmem palettes
load_gradient_palette(paletteIndex -13);
}
if (singleSegmentMode && paletteFade && _segments[_segment_index].call > 0) //only blend if just one segment uses FastLED mode
{
nblendPaletteTowardPalette(currentPalette, targetPalette, 48);
} else
{
currentPalette = targetPalette;
}
} }
//load custom mapping table from JSON file (called from finalizeInit() or deserializeState()) //load custom mapping table from JSON file (called from finalizeInit() or deserializeState())
void WS2812FX::deserializeMap(uint8_t n) { void WS2812FX::deserializeMap(uint8_t n) {
if (isMatrix) return; // 2D support creates its own ledmap if (isMatrix) return; // 2D support creates its own ledmap

View File

@ -844,28 +844,18 @@ function populateEffects()
function populatePalettes() function populatePalettes()
{ {
var palettes = lJson; lJson.shift(); // temporary remove default
palettes.shift(); // temporary remove default lJson.sort((a,b) => (a[1]).localeCompare(b[1]));
for (let i = 0; i < palettes.length; i++) { lJson.unshift([0,"Default"]);
palettes[i] = {
"id": palettes[i][0],
"name": palettes[i][1]
};
}
palettes.sort((a,b) => (a.name).localeCompare(b.name));
palettes.unshift({
"id": 0,
"name": "Default"
});
var html = ""; var html = "";
for (let pa of palettes) { for (let pa of lJson) {
html += generateListItemHtml( html += generateListItemHtml(
'palette', 'palette',
pa.id, pa[0],
pa.name, pa[1],
'setPalette', 'setPalette',
`<div class="lstIprev" style="${genPalPrevCss(pa.id)}"></div>` `<div class="lstIprev" style="${genPalPrevCss(pa[0])}"></div>`
); );
} }
@ -905,7 +895,7 @@ function genPalPrevCss(id)
let r, g, b; let r, g, b;
let index = false; let index = false;
if (Array.isArray(e)) { if (Array.isArray(e)) {
index = e[0]/255*100; index = Math.round(e[0]/255*100);
r = e[1]; r = e[1];
g = e[2]; g = e[2];
b = e[3]; b = e[3];
@ -921,7 +911,7 @@ function genPalPrevCss(id)
b = parseInt(cd[i].dataset.b); b = parseInt(cd[i].dataset.b);
} }
if (index === false) { if (index === false) {
index = j / paletteData.length * 100; index = Math.round(j / paletteData.length * 100);
} }
gradient.push(`rgb(${r},${g},${b}) ${index}%`); gradient.push(`rgb(${r},${g},${b}) ${index}%`);
@ -932,7 +922,7 @@ function genPalPrevCss(id)
function generateListItemHtml(listName, id, name, clickAction, extraHtml = '', effectPar = '') function generateListItemHtml(listName, id, name, clickAction, extraHtml = '', effectPar = '')
{ {
return `<div class="lstI${id==0?' sticky':''}" data-id="${id}" data-opt="${effectPar}" onClick="${clickAction}(${id})"> return `<div class="lstI${id==0?' sticky':''}" data-id="${id}" ${effectPar===''?'':'data-opt="'+effectPar+'"'}onClick="${clickAction}(${id})">
<label class="radio schkl" onclick="event.preventDefault()"> <label class="radio schkl" onclick="event.preventDefault()">
<input type="radio" value="${id}" name="${listName}"> <input type="radio" value="${id}" name="${listName}">
<span class="radiomark"></span> <span class="radiomark"></span>
@ -1485,8 +1475,23 @@ function requestJson(command=null)
if (!json) { showToast('Empty response', true); return; } if (!json) { showToast('Empty response', true); return; }
if (json.success) return; if (json.success) return;
if (json.info) { if (json.info) {
parseInfo(json.info); let i = json.info;
if (isInfo) populateInfo(lastinfo); // append custom palettes (when loading for the 1st time)
if (!command && isEmpty(lastinfo) && i.leds && i.leds.cpal) {
for (let j = 0; j<i.leds.cpal; j++) {
let div = d.createElement("div");
gId('pallist').appendChild(div);
div.outerHTML = generateListItemHtml(
'palette',
255-j,
'~ Custom '+j+1+' ~',
'setPalette',
`<div class="lstIprev" style="${genPalPrevCss(255-j)}"></div>`
);
}
}
parseInfo(i);
if (isInfo) populateInfo(i);
} }
var s = json.state ? json.state : json; var s = json.state ? json.state : json;
readState(s); readState(s);

File diff suppressed because it is too large Load Diff

View File

@ -222,7 +222,13 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
//getVal also supports inc/decrementing and random //getVal also supports inc/decrementing and random
getVal(elem[F("sx")], &seg.speed); getVal(elem[F("sx")], &seg.speed);
getVal(elem[F("ix")], &seg.intensity); getVal(elem[F("ix")], &seg.intensity);
getVal(elem["pal"], &seg.palette, 1, strip.getPaletteCount()); uint8_t pal = seg.palette;
if (getVal(elem["pal"], &pal, 1, strip.getPaletteCount())) {
if (pal != seg.palette) {
if (strip.paletteBlend) seg.startTransition(strip.getTransition());
seg.palette = pal;
}
}
getVal(elem[F("c1")], &seg.custom1); getVal(elem[F("c1")], &seg.custom1);
getVal(elem[F("c2")], &seg.custom2); getVal(elem[F("c2")], &seg.custom2);
getVal(elem[F("c3")], &seg.custom3); getVal(elem[F("c3")], &seg.custom3);
@ -322,6 +328,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
} }
} }
// temporary transition (applies only once)
tr = root[F("tt")] | -1; tr = root[F("tt")] | -1;
if (tr >= 0) if (tr >= 0)
{ {
@ -514,7 +521,6 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme
root["on"] = (bri > 0); root["on"] = (bri > 0);
root["bri"] = briLast; root["bri"] = briLast;
root[F("transition")] = transitionDelay/100; //in 100ms root[F("transition")] = transitionDelay/100; //in 100ms
//root[F("tdd")] = transitionDelayDefault/100; //in 100ms
} }
if (!forPreset) { if (!forPreset) {
@ -582,6 +588,7 @@ void serializeInfo(JsonObject root)
leds[F("maxseg")] = strip.getMaxSegments(); leds[F("maxseg")] = strip.getMaxSegments();
//leds[F("actseg")] = strip.getActiveSegmentsNum(); //leds[F("actseg")] = strip.getActiveSegmentsNum();
//leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config //leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
leds[F("cpal")] = strip.customPalettes.size();
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
if (strip.isMatrix) { if (strip.isMatrix) {
@ -778,6 +785,7 @@ void setPaletteColors(JsonArray json, byte* tcp)
void serializePalettes(JsonObject root, AsyncWebServerRequest* request) void serializePalettes(JsonObject root, AsyncWebServerRequest* request)
{ {
byte tcp[72];
#ifdef ESP8266 #ifdef ESP8266
int itemPerPage = 5; int itemPerPage = 5;
#else #else
@ -790,19 +798,20 @@ void serializePalettes(JsonObject root, AsyncWebServerRequest* request)
} }
int palettesCount = strip.getPaletteCount(); int palettesCount = strip.getPaletteCount();
int customPalettes = strip.customPalettes.size();
int maxPage = (palettesCount -1) / itemPerPage; int maxPage = (palettesCount + customPalettes -1) / itemPerPage;
if (page > maxPage) page = maxPage; if (page > maxPage) page = maxPage;
int start = itemPerPage * page; int start = itemPerPage * page;
int end = start + itemPerPage; int end = start + itemPerPage;
if (end >= palettesCount) end = palettesCount; if (end > palettesCount + customPalettes) end = palettesCount + customPalettes;
root[F("m")] = maxPage; root[F("m")] = maxPage; // inform caller how many pages there are
JsonObject palettes = root.createNestedObject("p"); JsonObject palettes = root.createNestedObject("p");
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
JsonArray curPalette = palettes.createNestedArray(String(i)); JsonArray curPalette = palettes.createNestedArray(String(i>=palettesCount ? 255 - i + palettesCount : i));
switch (i) { switch (i) {
case 0: //default palette case 0: //default palette
setPaletteColors(curPalette, PartyColors_p); setPaletteColors(curPalette, PartyColors_p);
@ -868,9 +877,12 @@ void serializePalettes(JsonObject root, AsyncWebServerRequest* request)
break; break;
default: default:
{ {
byte tcp[72]; if (i>=palettesCount) {
memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[i - 13])), 72); setPaletteColors(curPalette, strip.customPalettes[i - palettesCount]);
setPaletteColors(curPalette, tcp); } else {
memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[i - 13])), 72);
setPaletteColors(curPalette, tcp);
}
} }
break; break;
} }

View File

@ -130,7 +130,7 @@ void stateUpdated(byte callMode) {
if (fadeTransition) { if (fadeTransition) {
//set correct delay if not using notification delay //set correct delay if not using notification delay
if (callMode != CALL_MODE_NOTIFICATION && !jsonTransitionOnce) transitionDelayTemp = transitionDelay; if (callMode != CALL_MODE_NOTIFICATION && !jsonTransitionOnce) transitionDelayTemp = transitionDelay; // load actual transition duration
jsonTransitionOnce = false; jsonTransitionOnce = false;
strip.setTransition(transitionDelayTemp); strip.setTransition(transitionDelayTemp);
if (transitionDelayTemp == 0) { if (transitionDelayTemp == 0) {
@ -143,7 +143,7 @@ void stateUpdated(byte callMode) {
briOld = briT; briOld = briT;
tperLast = 0; tperLast = 0;
} }
strip.setTransitionMode(true); strip.setTransitionMode(true); // force all segments to transition mode
transitionActive = true; transitionActive = true;
transitionStartTime = millis(); transitionStartTime = millis();
} else { } else {

View File

@ -188,8 +188,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
fadeTransition = request->hasArg(F("TF")); fadeTransition = request->hasArg(F("TF"));
t = request->arg(F("TD")).toInt(); t = request->arg(F("TD")).toInt();
if (t >= 0) transitionDelay = t; if (t >= 0) transitionDelayDefault = t;
transitionDelayDefault = t;
strip.paletteFade = request->hasArg(F("PF")); strip.paletteFade = request->hasArg(F("PF"));
nightlightTargetBri = request->arg(F("TB")).toInt(); nightlightTargetBri = request->arg(F("TB")).toInt();
@ -827,10 +826,13 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) { for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) {
Segment& seg = strip.getSegment(i); Segment& seg = strip.getSegment(i);
if (i != selectedSeg && (singleSegment || !seg.isActive() || !seg.isSelected())) continue; // skip non main segments if not applying to all if (i != selectedSeg && (singleSegment || !seg.isActive() || !seg.isSelected())) continue; // skip non main segments if not applying to all
if (fxModeChanged) strip.setMode(i, effectIn); if (fxModeChanged) { seg.mode = effectIn; seg.markForReset(); }
if (speedChanged) seg.speed = speedIn; if (speedChanged) seg.speed = speedIn;
if (intensityChanged) seg.intensity = intensityIn; if (intensityChanged) seg.intensity = intensityIn;
if (paletteChanged) seg.palette = paletteIn; if (paletteChanged) {
if (strip.paletteBlend) seg.startTransition(strip.getTransition());
seg.palette = paletteIn;
}
} }
//set advanced overlay //set advanced overlay

View File

@ -411,6 +411,7 @@ void WLED::beginStrip()
{ {
// Initialize NeoPixel Strip and button // Initialize NeoPixel Strip and button
strip.finalizeInit(); // busses created during deserializeConfig() strip.finalizeInit(); // busses created during deserializeConfig()
strip.loadCustomPalettes();
strip.deserializeMap(); strip.deserializeMap();
strip.makeAutoSegments(); strip.makeAutoSegments();
strip.setBrightness(0); strip.setBrightness(0);

View File

@ -8,7 +8,7 @@
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2207271 #define VERSION 2207293
//uncomment this if you have a "my_config.h" file you'd like to use //uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG //#define WLED_USE_MY_CONFIG
@ -458,12 +458,12 @@ WLED_GLOBAL bool wasConnected _INIT(false);
WLED_GLOBAL byte lastRandomIndex _INIT(0); // used to save last random color so the new one is not the same WLED_GLOBAL byte lastRandomIndex _INIT(0); // used to save last random color so the new one is not the same
// transitions // transitions
WLED_GLOBAL bool transitionActive _INIT(false); WLED_GLOBAL bool transitionActive _INIT(false);
WLED_GLOBAL uint16_t transitionDelayDefault _INIT(transitionDelay); WLED_GLOBAL uint16_t transitionDelayDefault _INIT(transitionDelay); // default transition time (storec in cfg.json)
WLED_GLOBAL uint16_t transitionDelayTemp _INIT(transitionDelay); WLED_GLOBAL uint16_t transitionDelayTemp _INIT(transitionDelay); // actual transition duration (overrides transitionDelay in certain cases)
WLED_GLOBAL unsigned long transitionStartTime; WLED_GLOBAL unsigned long transitionStartTime;
WLED_GLOBAL float tperLast _INIT(0); // crossfade transition progress, 0.0f - 1.0f WLED_GLOBAL float tperLast _INIT(0.0f); // crossfade transition progress, 0.0f - 1.0f
WLED_GLOBAL bool jsonTransitionOnce _INIT(false); WLED_GLOBAL bool jsonTransitionOnce _INIT(false); // flag to override transitionDelay (playlist, JSON API: "live" & "seg":{"i"} & "tt")
// nightlight // nightlight
WLED_GLOBAL bool nightlightActive _INIT(false); WLED_GLOBAL bool nightlightActive _INIT(false);