Watchdog timer (@poelzi).

Transpose optimisations.
Rain effect updated.
This commit is contained in:
Blaz Kristan 2022-05-30 22:21:13 +02:00
parent d7e1dc1f95
commit 366006273d
6 changed files with 265 additions and 388 deletions

View File

@ -497,11 +497,8 @@ static const char *_data_FX_MODE_SAW PROGMEM = "Saw@!,Width;!,!,;!";
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
*/ */
uint16_t WS2812FX::mode_twinkle(void) { uint16_t WS2812FX::mode_twinkle(void) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN on 1D const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
fill(SEGCOLOR(1)); fill(SEGCOLOR(1));
@ -1169,7 +1166,7 @@ static const char *_data_FX_MODE_COMET PROGMEM = "Lighthouse";
* Fireworks function. * Fireworks function.
*/ */
uint16_t WS2812FX::mode_fireworks() { uint16_t WS2812FX::mode_fireworks() {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN on 1D const uint16_t width = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t height = SEGMENT.virtualHeight();
fade_out(0); fade_out(0);
@ -1183,8 +1180,7 @@ uint16_t WS2812FX::mode_fireworks() {
uint32_t sv1 = 0, sv2 = 0; uint32_t sv1 = 0, sv2 = 0;
if (valid1) sv1 = isMatrix ? getPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width) : getPixelColor(SEGENV.aux0); // get spark color if (valid1) sv1 = isMatrix ? getPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width) : getPixelColor(SEGENV.aux0); // get spark color
if (valid2) sv2 = isMatrix ? getPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width) : getPixelColor(SEGENV.aux1); if (valid2) sv2 = isMatrix ? getPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width) : getPixelColor(SEGENV.aux1);
if (isMatrix) blur2d(nullptr, 64); if (!SEGENV.step) blur(16);
else blur(127);
if (valid1) { if (isMatrix) setPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width, sv1); else setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur if (valid1) { if (isMatrix) setPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width, sv1); else setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur
if (valid2) { if (isMatrix) setPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width, sv2); else setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur if (valid2) { if (isMatrix) setPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width, sv2); else setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur
@ -1207,35 +1203,29 @@ static const char *_data_FX_MODE_FIREWORKS PROGMEM = "Fireworks@,Frequency=192;!
//Twinkling LEDs running. Inspired by https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Rain.h //Twinkling LEDs running. Inspired by https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Rain.h
uint16_t WS2812FX::mode_rain() uint16_t WS2812FX::mode_rain()
{ {
if (isMatrix) { const uint16_t width = SEGMENT.virtualWidth();
return mode_static(); const uint16_t height = SEGMENT.virtualHeight();
/*
SEGMENT.custom2 = 255; // use colors
SEGMENT.custom1 = 128; // trail
uint32_t old = SEGCOLOR(1);
CRGB c = CRGB(old).nscale8(248);
SEGCOLOR(1) = RGBW32(c.r, c.g, c.b, W(old));
uint16_t time = mode_2Dmatrix();
SEGCOLOR(1) = old;
return time;
*/
}
SEGENV.step += FRAMETIME; SEGENV.step += FRAMETIME;
if (SEGENV.step > SPEED_FORMULA_L) { if (SEGENV.step > SPEED_FORMULA_L) {
SEGENV.step = 0; SEGENV.step = 1;
//shift all leds left if (isMatrix) {
uint32_t ctemp = getPixelColor(0); move(6,1); // move all pixels down
for(uint16_t i = 0; i < SEGLEN - 1; i++) { SEGENV.aux0 = (SEGENV.aux0 % width) + (SEGENV.aux0 / width + 1) * width;
setPixelColor(i, getPixelColor(i+1)); SEGENV.aux1 = (SEGENV.aux1 % width) + (SEGENV.aux1 / width + 1) * width;
} else {
//shift all leds left
uint32_t ctemp = getPixelColor(0);
for(uint16_t i = 0; i < SEGLEN - 1; i++) {
setPixelColor(i, getPixelColor(i+1));
}
setPixelColor(SEGLEN -1, ctemp); // wrap around
SEGENV.aux0++; // increase spark index
SEGENV.aux1++;
} }
setPixelColor(SEGLEN -1, ctemp); // wrap around
SEGENV.aux0++; // increase spark index
SEGENV.aux1++;
if (SEGENV.aux0 == 0) SEGENV.aux0 = UINT16_MAX; // reset previous spark positiom if (SEGENV.aux0 == 0) SEGENV.aux0 = UINT16_MAX; // reset previous spark positiom
if (SEGENV.aux1 == 0) SEGENV.aux0 = UINT16_MAX; // reset previous spark positiom if (SEGENV.aux1 == 0) SEGENV.aux0 = UINT16_MAX; // reset previous spark positiom
if (SEGENV.aux0 == SEGLEN) SEGENV.aux0 = 0; // ignore if (SEGENV.aux0 >= width*height) SEGENV.aux0 = 0; // ignore
if (SEGENV.aux1 == SEGLEN) SEGENV.aux1 = 0; if (SEGENV.aux1 >= width*height) SEGENV.aux1 = 0;
} }
return mode_fireworks(); return mode_fireworks();
} }
@ -1960,11 +1950,8 @@ static const char *_data_FX_MODE_PALETTE PROGMEM = "Palette@!,;1,2,3;!";
// in step 3 above) (Effect Intensity = Sparking). // in step 3 above) (Effect Intensity = Sparking).
uint16_t WS2812FX::mode_fire_2012() uint16_t WS2812FX::mode_fire_2012()
{ {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN on 1D const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height; // will be 1 for 1D
uint32_t it = now >> 5; //div 32 uint32_t it = now >> 5; //div 32
uint16_t q = cols>>2; // a quarter of flames uint16_t q = cols>>2; // a quarter of flames
@ -2199,13 +2186,10 @@ 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
uint16_t WS2812FX::mode_colortwinkle() uint16_t WS2812FX::mode_colortwinkle()
{ {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN on 1D const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
uint16_t dataSize = (width*height+7) >> 3; //1 bit per LED uint16_t dataSize = (cols*rows+7) >> 3; //1 bit per LED
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB fastled_col, prev; CRGB fastled_col, prev;
@ -2952,11 +2936,8 @@ typedef struct Spark {
* modified from https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Popcorn.h * modified from https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Popcorn.h
*/ */
uint16_t WS2812FX::mode_popcorn(void) { uint16_t WS2812FX::mode_popcorn(void) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN on 1D const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height; // will be 1 for 1D
//allocate segment data //allocate segment data
uint16_t maxNumPopcorn = 21; // max 21 on 16 segment ESP8266 uint16_t maxNumPopcorn = 21; // max 21 on 16 segment ESP8266
@ -3248,11 +3229,8 @@ static const char *_data_FX_MODE_STARBURST PROGMEM = "Fireworks Starburst";
*/ */
uint16_t WS2812FX::mode_exploding_fireworks(void) uint16_t WS2812FX::mode_exploding_fireworks(void)
{ {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN on 1D const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height; // will be 1 for 1D
//allocate segment data //allocate segment data
uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640 uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640
@ -3261,7 +3239,7 @@ uint16_t WS2812FX::mode_exploding_fireworks(void)
if (segs <= (MAX_NUM_SEGMENTS /4)) maxData *= 2; //ESP8266: 1024 if <= 4 segs ESP32: 2560 if <= 8 segs if (segs <= (MAX_NUM_SEGMENTS /4)) maxData *= 2; //ESP8266: 1024 if <= 4 segs ESP32: 2560 if <= 8 segs
int maxSparks = maxData / sizeof(spark); //ESP8266: max. 21/42/85 sparks/seg, ESP32: max. 53/106/213 sparks/seg int maxSparks = maxData / sizeof(spark); //ESP8266: max. 21/42/85 sparks/seg, ESP32: max. 53/106/213 sparks/seg
uint16_t numSparks = min(2 + (rows >> 1), maxSparks); uint16_t numSparks = min(2 + (cols >> 1), maxSparks);
uint16_t dataSize = sizeof(spark) * numSparks; uint16_t dataSize = sizeof(spark) * numSparks;
if (!SEGENV.allocateData(dataSize + sizeof(float))) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize + sizeof(float))) return mode_static(); //allocation failed
float *dying_gravity = reinterpret_cast<float*>(SEGENV.data + dataSize); float *dying_gravity = reinterpret_cast<float*>(SEGENV.data + dataSize);
@ -3279,16 +3257,16 @@ uint16_t WS2812FX::mode_exploding_fireworks(void)
Spark* flare = sparks; //first spark is flare data Spark* flare = sparks; //first spark is flare data
float gravity = -0.0004 - (SEGMENT.speed/800000.0); // m/s/s float gravity = -0.0004 - (SEGMENT.speed/800000.0); // m/s/s
gravity *= rows; gravity *= isMatrix ? rows : cols;
if (SEGENV.aux0 < 2) { //FLARE if (SEGENV.aux0 < 2) { //FLARE
if (SEGENV.aux0 == 0) { //init flare if (SEGENV.aux0 == 0) { //init flare
flare->pos = 0; flare->pos = 0;
flare->posX = isMatrix ? random16(cols) : (SEGMENT.intensity > random8()); // will enable random firing side on 1D flare->posX = isMatrix ? random16(2,cols-1) : (SEGMENT.intensity > random8()); // will enable random firing side on 1D
uint16_t peakHeight = 75 + random8(180); //0-255 uint16_t peakHeight = 75 + random8(180); //0-255
peakHeight = (peakHeight * (rows -1)) >> 8; peakHeight = (peakHeight * ((isMatrix ? rows : cols) -1)) >> 8;
flare->vel = sqrt(-2.0 * gravity * peakHeight); flare->vel = sqrt(-2.0 * gravity * peakHeight);
flare->velX = isMatrix ? (random8(6)-3)/23 : 0; // no X velocity on 1D flare->velX = isMatrix ? (random8(8)-4)/32.f : 0; // no X velocity on 1D
flare->col = 255; //brightness flare->col = 255; //brightness
SEGENV.aux0 = 1; SEGENV.aux0 = 1;
} }
@ -3300,7 +3278,7 @@ uint16_t WS2812FX::mode_exploding_fireworks(void)
else setPixelColor(int(flare->posX) ? rows - int(flare->pos) - 1 : int(flare->pos), flare->col, flare->col, flare->col); else setPixelColor(int(flare->posX) ? rows - int(flare->pos) - 1 : int(flare->pos), flare->col, flare->col, flare->col);
flare->pos += flare->vel; flare->pos += flare->vel;
flare->posX += flare->velX; flare->posX += flare->velX;
flare->pos = constrain(flare->pos, 0, rows-1); flare->pos = constrain(flare->pos, 0, (isMatrix ? rows : cols)-1);
flare->posX = constrain(flare->posX, 0, cols-isMatrix); flare->posX = constrain(flare->posX, 0, cols-isMatrix);
flare->vel += gravity; flare->vel += gravity;
flare->col -= 2; flare->col -= 2;
@ -3322,13 +3300,13 @@ uint16_t WS2812FX::mode_exploding_fireworks(void)
for (int i = 1; i < nSparks; i++) { for (int i = 1; i < nSparks; i++) {
sparks[i].pos = flare->pos; sparks[i].pos = flare->pos;
sparks[i].posX = flare->posX; sparks[i].posX = flare->posX;
sparks[i].vel = (float(random16(0, 20000)) / 10000.0) - 0.9; // from -0.9 to 1.1 sparks[i].vel = (float(random16(0, 20000)) / 10000.0f) - 0.9f; // from -0.9 to 1.1
sparks[i].vel *= rows<32 ? 0.5 : 1; // reduce velocity for smaller strips sparks[i].vel *= rows<32 ? 0.5 : 1; // reduce velocity for smaller strips
sparks[i].velX = isMatrix ? (float(random16(0, 16000)) / 10000.0) - 0.8 : 0; // from -0.8 to 0.8 sparks[i].velX = isMatrix ? (float(random16(0, 4000)) / 10000.0f) - 0.2f : 0; // from -0.2 to 0.2
sparks[i].col = 345;//abs(sparks[i].vel * 750.0); // set colors before scaling velocity to keep them bright sparks[i].col = 345;//abs(sparks[i].vel * 750.0); // set colors before scaling velocity to keep them bright
//sparks[i].col = constrain(sparks[i].col, 0, 345); //sparks[i].col = constrain(sparks[i].col, 0, 345);
sparks[i].colIndex = random8(); sparks[i].colIndex = random8();
sparks[i].vel *= flare->pos/rows; // proportional to height sparks[i].vel *= flare->pos/(isMatrix ? rows : cols); // proportional to height
sparks[i].velX *= isMatrix ? flare->posX/cols : 0; // proportional to width sparks[i].velX *= isMatrix ? flare->posX/cols : 0; // proportional to width
sparks[i].vel *= -gravity *50; sparks[i].vel *= -gravity *50;
} }
@ -3345,8 +3323,8 @@ uint16_t WS2812FX::mode_exploding_fireworks(void)
sparks[i].velX += isMatrix ? *dying_gravity : 0; sparks[i].velX += isMatrix ? *dying_gravity : 0;
if (sparks[i].col > 3) sparks[i].col -= 4; if (sparks[i].col > 3) sparks[i].col -= 4;
if (sparks[i].pos > 0 && sparks[i].pos < rows) { if (sparks[i].pos > 0 && sparks[i].pos < (isMatrix ? rows : cols)) {
if (isMatrix && !(sparks[i].posX > 0 && sparks[i].posX < cols)) continue; if (isMatrix && !(sparks[i].posX >= 0 && sparks[i].posX < cols)) continue;
uint16_t prog = sparks[i].col; uint16_t prog = sparks[i].col;
uint32_t spColor = (SEGMENT.palette) ? color_wheel(sparks[i].colIndex) : SEGCOLOR(0); uint32_t spColor = (SEGMENT.palette) ? color_wheel(sparks[i].colIndex) : SEGCOLOR(0);
CRGB c = CRGB::Black; //HeatColor(sparks[i].col); CRGB c = CRGB::Black; //HeatColor(sparks[i].col);
@ -3362,6 +3340,7 @@ uint16_t WS2812FX::mode_exploding_fireworks(void)
else setPixelColor(int(sparks[i].posX) ? rows - int(sparks[i].pos) - 1 : int(sparks[i].pos), c.red, c.green, c.blue); else setPixelColor(int(sparks[i].posX) ? rows - int(sparks[i].pos) - 1 : int(sparks[i].pos), c.red, c.green, c.blue);
} }
} }
blur(16);
*dying_gravity *= .8; // as sparks burn out they fall slower *dying_gravity *= .8; // as sparks burn out they fall slower
} else { } else {
SEGENV.aux0 = 6 + random8(10); //wait for this many frames SEGENV.aux0 = 6 + random8(10); //wait for this many frames
@ -3385,11 +3364,8 @@ static const char *_data_FX_MODE_EXPLODING_FIREWORKS PROGMEM = "Fireworks 1D@Gra
*/ */
uint16_t WS2812FX::mode_drip(void) uint16_t WS2812FX::mode_drip(void)
{ {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN on 1D const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height; // will be 1 for 1D
//allocate segment data //allocate segment data
uint8_t numDrops = 4; uint8_t numDrops = 4;
@ -3866,11 +3842,8 @@ static const char *_data_FX_MODE_PHASEDNOISE PROGMEM = "Phased Noise";
uint16_t WS2812FX::mode_twinkleup(void) { // A very short twinkle routine with fade-in and dual controls. By Andrew Tuline. uint16_t WS2812FX::mode_twinkleup(void) { // A very short twinkle routine with fade-in and dual controls. By Andrew Tuline.
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN on 1D const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height; // will be 1 for 1D
random16_set_seed(535); // The randomizer needs to be re-set each time through the loop in order for the same 'random' numbers to be the same each time through. random16_set_seed(535); // The randomizer needs to be re-set each time through the loop in order for the same 'random' numbers to be the same each time through.
@ -4510,12 +4483,9 @@ static const char *_data_FX_MODE_AURORA PROGMEM = "Aurora@!=24,!;1,2,3;!=50";
uint16_t WS2812FX::mode_2DBlackHole(void) { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline uint16_t WS2812FX::mode_2DBlackHole(void) { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED); const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -4558,12 +4528,10 @@ static const char *_data_FX_MODE_BLACK_HOLE PROGMEM = "2D Black Hole@Fade rate,O
uint16_t WS2812FX::mode_2DColoredBursts() { // By: ldirko https://editor.soulmatelights.com/gallery/819-colored-bursts , modified by: Andrew Tuline uint16_t WS2812FX::mode_2DColoredBursts() { // By: ldirko https://editor.soulmatelights.com/gallery/819-colored-bursts , modified by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -4620,12 +4588,10 @@ static const char *_data_FX_MODE_COLORED_BURSTS PROGMEM = "2D Colored Bursts@Spe
uint16_t WS2812FX::mode_2Ddna(void) { // dna originally by by ldirko at https://pastebin.com/pCkkkzcs. Updated by Preyy. WLED conversion by Andrew Tuline. uint16_t WS2812FX::mode_2Ddna(void) { // dna originally by by ldirko at https://pastebin.com/pCkkkzcs. Updated by Preyy. WLED conversion by Andrew Tuline.
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN on 1D const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -4652,12 +4618,10 @@ static const char *_data_FX_MODE_DNA PROGMEM = "2D DNA@Scroll speed,Blur;;!";
uint16_t WS2812FX::mode_2DDNASpiral() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , modified by: Andrew Tuline uint16_t WS2812FX::mode_2DDNASpiral() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , modified by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN on 1D const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -4703,12 +4667,10 @@ static const char *_data_FX_MODE_DNA_SPIRAL PROGMEM = "2D DNA Spiral@Scroll spee
uint16_t WS2812FX::mode_2DDrift() { // By: Stepko https://editor.soulmatelights.com/gallery/884-drift , Modified by: Andrew Tuline uint16_t WS2812FX::mode_2DDrift() { // By: Stepko https://editor.soulmatelights.com/gallery/884-drift , Modified by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (cols<8 || rows<8) return mode_static(); if (cols<8 || rows<8) return mode_static();
@ -4719,7 +4681,7 @@ uint16_t WS2812FX::mode_2DDrift() { // By: Stepko https://editor.
fadeToBlackBy(leds, 128); fadeToBlackBy(leds, 128);
const uint16_t maxDim = MAX(width, rows)/2; const uint16_t maxDim = MAX(cols, rows)/2;
unsigned long t = millis() / (32 - (SEGMENT.speed>>3)); unsigned long t = millis() / (32 - (SEGMENT.speed>>3));
for (float i = 1; i < maxDim; i += 0.25) { for (float i = 1; i < maxDim; i += 0.25) {
float angle = radians(t * (maxDim - i)); float angle = radians(t * (maxDim - i));
@ -4741,12 +4703,10 @@ static const char *_data_FX_MODE_DRIFT PROGMEM = "2D Drift@Rotation speed,Blur a
uint16_t WS2812FX::mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline. Yet another short routine. uint16_t WS2812FX::mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline. Yet another short routine.
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -4781,13 +4741,10 @@ static const char *_data_FX_MODE_FIRENOISE PROGMEM = "2D Firenoise@X scale,Y sca
uint16_t WS2812FX::mode_2DFrizzles(void) { // By: Stepko https://editor.soulmatelights.com/gallery/640-color-frizzles , Modified by: Andrew Tuline uint16_t WS2812FX::mode_2DFrizzles(void) { // By: Stepko https://editor.soulmatelights.com/gallery/640-color-frizzles , Modified by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -4817,12 +4774,10 @@ typedef struct ColorCount {
uint16_t WS2812FX::mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https://natureofcode.com/book/chapter-7-cellular-automata/ and https://github.com/DougHaber/nlife-color uint16_t WS2812FX::mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https://natureofcode.com/book/chapter-7-cellular-automata/ and https://github.com/DougHaber/nlife-color
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize*2 + sizeof(unsigned long))) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize*2 + sizeof(unsigned long))) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -4918,11 +4873,8 @@ static const char *_data_FX_MODE_GAMEOFLIFE PROGMEM = "2D Game Of Life@!,;!,!;!"
uint16_t WS2812FX::mode_2DHiphotic() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , Modified by: Andrew Tuline uint16_t WS2812FX::mode_2DHiphotic() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , Modified by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint32_t a = now / 8; const uint32_t a = now / 8;
for (uint16_t x = 0; x < cols; x++) { for (uint16_t x = 0; x < cols; x++) {
@ -4953,11 +4905,8 @@ typedef struct Julia {
uint16_t WS2812FX::mode_2DJulia(void) { // An animated Julia set by Andrew Tuline. uint16_t WS2812FX::mode_2DJulia(void) { // An animated Julia set by Andrew Tuline.
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
if (!SEGENV.allocateData(sizeof(julia))) return mode_static(); if (!SEGENV.allocateData(sizeof(julia))) return mode_static();
Julia* julias = reinterpret_cast<Julia*>(SEGENV.data); Julia* julias = reinterpret_cast<Julia*>(SEGENV.data);
@ -5062,12 +5011,10 @@ static const char *_data_FX_MODE_JULIA PROGMEM = "2D Julia@,Max iterations per p
uint16_t WS2812FX::mode_2DLissajous(void) { // By: Andrew Tuline uint16_t WS2812FX::mode_2DLissajous(void) { // By: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; //uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
//uint16_t dataSize = sizeof(CRGB) * width * height;
//if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed //if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
//CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); //CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -5100,13 +5047,10 @@ static const char *_data_FX_MODE_LISSAJOUS PROGMEM = "2D Lissajous@X frequency,F
uint16_t WS2812FX::mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi. uint16_t WS2812FX::mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi.
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -5171,11 +5115,8 @@ static const char *_data_FX_MODE_MATRIX PROGMEM = "2D Matrix@Falling speed,Spawn
uint16_t WS2812FX::mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have one of the dimensions be 2 or less. Adapted by Andrew Tuline. uint16_t WS2812FX::mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have one of the dimensions be 2 or less. Adapted by Andrew Tuline.
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
float speed = 0.25f * (1+(SEGMENT.speed>>6)); float speed = 0.25f * (1+(SEGMENT.speed>>6));
@ -5234,11 +5175,9 @@ static const char *_data_FX_MODE_MEATBALS PROGMEM = "2D Metaballs@Speed;!,!,!;!"
uint16_t WS2812FX::mode_2Dnoise(void) { // By Andrew Tuline uint16_t WS2812FX::mode_2Dnoise(void) { // By Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t scale = SEGMENT.intensity+2; const uint16_t scale = SEGMENT.intensity+2;
for (uint16_t y = 0; y < rows; y++) { for (uint16_t y = 0; y < rows; y++) {
@ -5259,12 +5198,10 @@ static const char *_data_FX_MODE_2DNOISE PROGMEM = "2D Noise@Speed,Scale;!,!,!;!
uint16_t WS2812FX::mode_2DPlasmaball(void) { // By: Stepko https://editor.soulmatelights.com/gallery/659-plasm-ball , Modified by: Andrew Tuline uint16_t WS2812FX::mode_2DPlasmaball(void) { // By: Stepko https://editor.soulmatelights.com/gallery/659-plasm-ball , Modified by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -5309,12 +5246,10 @@ static const char *_data_FX_MODE_PLASMA_BALL PROGMEM = "2D Plasma Ball@Speed;!,!
uint16_t WS2812FX::mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https://editor.soulmatelights.com/gallery/762-polar-lights , Modified by: Andrew Tuline uint16_t WS2812FX::mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https://editor.soulmatelights.com/gallery/762-polar-lights , Modified by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -5368,12 +5303,10 @@ static const char *_data_FX_MODE_POLAR_LIGHTS PROGMEM = "2D Polar Lights@Speed,S
uint16_t WS2812FX::mode_2DPulser(void) { // By: ldirko https://editor.soulmatelights.com/gallery/878-pulse-test , modifed by: Andrew Tuline uint16_t WS2812FX::mode_2DPulser(void) { // By: ldirko https://editor.soulmatelights.com/gallery/878-pulse-test , modifed by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -5401,12 +5334,10 @@ static const char *_data_FX_MODE_PULSER PROGMEM = "2D Pulser@Speed,Blur;;!";
uint16_t WS2812FX::mode_2DSindots(void) { // By: ldirko https://editor.soulmatelights.com/gallery/597-sin-dots , modified by: Andrew Tuline uint16_t WS2812FX::mode_2DSindots(void) { // By: ldirko https://editor.soulmatelights.com/gallery/597-sin-dots , modified by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -5437,12 +5368,10 @@ uint16_t WS2812FX::mode_2Dsquaredswirl(void) { // By: Mark Kriegsman.
// Modifed by: Andrew Tuline // Modifed by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -5481,14 +5410,12 @@ static const char *_data_FX_MODE_SQUARED_SWIRL PROGMEM = "2D Squared Swirl@,,,,B
uint16_t WS2812FX::mode_2DSunradiation(void) { // By: ldirko https://editor.soulmatelights.com/gallery/599-sun-radiation , modified by: Andrew Tuline uint16_t WS2812FX::mode_2DSunradiation(void) { // By: ldirko https://editor.soulmatelights.com/gallery/599-sun-radiation , modified by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize + (sizeof(byte)*(width+2)*(height+2)))) return mode_static(); //allocation failed const uint16_t dataSize = sizeof(CRGB) * rows * cols;
if (!SEGENV.allocateData(dataSize + (sizeof(byte)*(cols+2)*(rows+2)))) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
byte *bump = reinterpret_cast<byte*>(SEGENV.data + dataSize); byte *bump = reinterpret_cast<byte*>(SEGENV.data + dataSize);
@ -5535,13 +5462,10 @@ static const char *_data_FX_MODE_SUN_RADIATION PROGMEM = "2D Sun Radiation@Varia
uint16_t WS2812FX::mode_2Dtartan(void) { // By: Elliott Kember https://editor.soulmatelights.com/gallery/3-tartan , Modified by: Andrew Tuline uint16_t WS2812FX::mode_2Dtartan(void) { // By: Elliott Kember https://editor.soulmatelights.com/gallery/3-tartan , Modified by: Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -5574,12 +5498,10 @@ static const char *_data_FX_MODE_TARTAN PROGMEM = "2D Tartan@X scale,Y scale;;!"
uint16_t WS2812FX::mode_2DWaverly(void) { // By: Stepko, https://editor.soulmatelights.com/gallery/652-wave , modified by Andrew Tuline uint16_t WS2812FX::mode_2DWaverly(void) { // By: Stepko, https://editor.soulmatelights.com/gallery/652-wave , modified by Andrew Tuline
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -5614,11 +5536,8 @@ static const char *_data_FX_MODE_WAVERLY PROGMEM = "2D Waverly@Fade rate,Sensiti
uint16_t WS2812FX::mode_2DAkemi(void) { uint16_t WS2812FX::mode_2DAkemi(void) {
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
uint16_t counter = (now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF; uint16_t counter = (now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF;
counter = counter >> 8; counter = counter >> 8;
@ -5711,12 +5630,10 @@ static const char *_data_FX_MODE_AKEMI PROGMEM = "2D Akemi@Color speed,Dance;Hea
uint16_t WS2812FX::mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [https://editor.soulmatelights.com/gallery/639-space-ships], adapted by Blaz Kristan uint16_t WS2812FX::mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [https://editor.soulmatelights.com/gallery/639-space-ships], adapted by Blaz Kristan
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
@ -5725,8 +5642,8 @@ uint16_t WS2812FX::mode_2Dspaceships(void) { //// Space ships by stepko (c)05
uint32_t tb = now >> 12; // every ~4s uint32_t tb = now >> 12; // every ~4s
if (tb > SEGENV.step) { if (tb > SEGENV.step) {
int16_t dir = SEGENV.aux0; int8_t dir = ++SEGENV.aux0;
dir += (int)random8(2)-1; dir += (int)random8(3)-1;
if (dir > 7) SEGENV.aux0 = 0; if (dir > 7) SEGENV.aux0 = 0;
else if (dir < 0) SEGENV.aux0 = 7; else if (dir < 0) SEGENV.aux0 = 7;
else SEGENV.aux0 = dir; else SEGENV.aux0 = dir;
@ -5734,37 +5651,7 @@ uint16_t WS2812FX::mode_2Dspaceships(void) { //// Space ships by stepko (c)05
} }
fadeToBlackBy(leds, map(SEGMENT.speed, 0, 255, 248, 16)); fadeToBlackBy(leds, map(SEGMENT.speed, 0, 255, 248, 16));
move(SEGENV.aux0, 1, leds);
switch (SEGENV.aux0) {
case 0:
moveX(leds, 1);
break;
case 1:
moveX(leds, 1);
moveY(leds, -1);
break;
case 2:
moveY(leds, -1);
break;
case 3:
moveX(leds, -1);
moveY(leds, -1);
break;
case 4:
moveX(leds, -1);
break;
case 5:
moveX(leds, -1);
moveY(leds, 1);
break;
case 6:
moveY(leds, 1);
break;
case 7:
moveX(leds, 1);
moveY(leds, 1);
break;
}
for (byte i = 0; i < 8; i++) { for (byte 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);
@ -5793,14 +5680,12 @@ static const char *_data_FX_MODE_SPACESHIPS PROGMEM = "2D Spaceships@!,Blur;!,!,
uint16_t WS2812FX::mode_2Dcrazybees(void) { uint16_t WS2812FX::mode_2Dcrazybees(void) {
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
byte n = MIN(MAX_BEES, (width * height) / 256 + 1); const uint16_t dataSize = sizeof(CRGB) * rows * cols;
byte n = MIN(MAX_BEES, (rows * cols) / 256 + 1);
typedef struct Bee { typedef struct Bee {
uint8_t posX, posY, aimX, aimY, hue; uint8_t posX, posY, aimX, aimY, hue;
@ -5853,7 +5738,7 @@ uint16_t WS2812FX::mode_2Dcrazybees(void) {
bee[i].posY += bee[i].signY; bee[i].posY += bee[i].signY;
} }
} else { } else {
bee[i].aimed(width, rows); bee[i].aimed(cols, rows);
} }
} }
blur2d(leds, SEGMENT.intensity>>4); blur2d(leds, SEGMENT.intensity>>4);
@ -5873,13 +5758,10 @@ static const char *_data_FX_MODE_CRAZYBEES PROGMEM = "2D Crazy Bees@!,Blur;;";
uint16_t WS2812FX::mode_2Dghostrider(void) { uint16_t WS2812FX::mode_2Dghostrider(void) {
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
typedef struct Lighter { typedef struct Lighter {
int gPosX; int gPosX;
@ -5898,7 +5780,7 @@ uint16_t WS2812FX::mode_2Dghostrider(void) {
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
lighter_t *lighter = reinterpret_cast<lighter_t*>(SEGENV.data + dataSize); lighter_t *lighter = reinterpret_cast<lighter_t*>(SEGENV.data + dataSize);
const int maxLighters = min(width+height,LIGHTERS_AM); const int maxLighters = min(cols + rows, LIGHTERS_AM);
if (SEGENV.call == 0) { if (SEGENV.call == 0) {
fill_solid(leds, CRGB::Black); fill_solid(leds, CRGB::Black);
@ -5967,13 +5849,10 @@ static const char *_data_FX_MODE_GHOST_RIDER PROGMEM = "2D Ghost Rider@Fade rate
uint16_t WS2812FX::mode_2Dfloatingblobs(void) { uint16_t WS2812FX::mode_2Dfloatingblobs(void) {
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
typedef struct Blob { typedef struct Blob {
float x[MAX_BLOBS], y[MAX_BLOBS]; float x[MAX_BLOBS], y[MAX_BLOBS];
@ -6071,11 +5950,8 @@ static const char *_data_FX_MODE_BLOBS PROGMEM = "2D Blobs@!,# blobs;!,!,!;!";
uint16_t WS2812FX::mode_2Dscrollingtext(void) { uint16_t WS2812FX::mode_2Dscrollingtext(void) {
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const int letterWidth = 6; const int letterWidth = 6;
const int letterHeight = 8; const int letterHeight = 8;
@ -6110,12 +5986,10 @@ static const char *_data_FX_MODE_SCROLL_TEXT PROGMEM = "2D Scrolling Text@!,Y Of
uint16_t WS2812FX::mode_2Ddriftrose(void) { uint16_t WS2812FX::mode_2Ddriftrose(void) {
if (!isMatrix) return mode_static(); // not a 2D set-up if (!isMatrix) return mode_static(); // not a 2D set-up
const uint16_t width = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isMatrix && !isTransposed ? height : width; const uint16_t dataSize = sizeof(CRGB) * rows * cols;
const uint16_t cols = isMatrix && !isTransposed ? width : height;
const uint16_t dataSize = sizeof(CRGB) * width * height;
const float CX = cols/2.f - .5f; const float CX = cols/2.f - .5f;
const float CY = rows/2.f - .5f; const float CY = rows/2.f - .5f;
@ -6144,7 +6018,7 @@ static const char *_data_FX_MODE_DRIFT_ROSE PROGMEM = "2D Drift Rose@Fade,Blur;;
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// mode data // mode data
const char *WS2812FX::_modeData[] = { const char *WS2812FX::_modeData[MODE_COUNT] = {
_data_FX_MODE_STATIC, _data_FX_MODE_STATIC,
_data_FX_MODE_BLINK, _data_FX_MODE_BLINK,
_data_FX_MODE_BREATH, _data_FX_MODE_BREATH,

View File

@ -306,8 +306,8 @@ class WS2812FX {
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() { return getOption(0); }
inline bool isActive() { return stop > start; } inline bool isActive() { return stop > start; }
inline uint16_t width() { return /*getOption(SEG_OPTION_TRANSPOSED) ? stopY - startY :*/ stop - start; } inline uint16_t width() { return stop - start; }
inline uint16_t height() { return /*getOption(SEG_OPTION_TRANSPOSED) ? stop - start :*/ stopY - startY; } inline uint16_t height() { return stopY - startY; }
inline uint16_t length() { return width(); } inline uint16_t length() { return width(); }
inline uint16_t groupLength() { return grouping + spacing; } inline uint16_t groupLength() { return grouping + spacing; }
inline uint8_t getLightCapabilities() { return _capabilities; } inline uint8_t getLightCapabilities() { return _capabilities; }
@ -352,13 +352,13 @@ class WS2812FX {
// 2D matrix // 2D matrix
uint16_t virtualWidth() { uint16_t virtualWidth() {
uint16_t groupLen = groupLength(); uint16_t groupLen = groupLength();
uint16_t vWidth = (width() + groupLen - 1) / groupLen; uint16_t vWidth = ((getOption(SEG_OPTION_TRANSPOSED) ? height() : width()) + groupLen - 1) / groupLen;
if (getOption(SEG_OPTION_MIRROR)) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED if (getOption(SEG_OPTION_MIRROR)) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED
return vWidth; return vWidth;
} }
uint16_t virtualHeight() { uint16_t virtualHeight() {
uint16_t groupLen = groupLength(); uint16_t groupLen = groupLength();
uint16_t vHeight = (height() + groupLen - 1) / groupLen; uint16_t vHeight = ((getOption(SEG_OPTION_TRANSPOSED) ? width() : height()) + groupLen - 1) / groupLen;
if (getOption(SEG_OPTION_MIRROR_Y)) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED if (getOption(SEG_OPTION_MIRROR_Y)) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED
return vHeight; return vHeight;
} }
@ -930,6 +930,7 @@ class WS2812FX {
blurCol(uint16_t col, fract8 blur_amount, CRGB* leds=nullptr), blurCol(uint16_t col, fract8 blur_amount, CRGB* leds=nullptr),
moveX(CRGB *leds, int8_t delta), moveX(CRGB *leds, int8_t delta),
moveY(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_solid(CRGB* leds, CRGB c),
fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB c), fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB c),
fadeToBlackBy(CRGB* leds, uint8_t fadeBy), fadeToBlackBy(CRGB* leds, uint8_t fadeBy),

View File

@ -106,11 +106,11 @@ void WS2812FX::setUpMatrix() {
} }
} }
// XY(x,y) - gets pixel index within current segment // 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 IRAM_ATTR WS2812FX::XY(uint16_t x, uint16_t y) {
uint16_t width = SEGMENT.virtualWidth(); // segment width in logical pixels uint16_t width = SEGMENT.virtualWidth(); // segment width in logical pixels
uint16_t height = SEGMENT.virtualHeight(); // segment height in logical pixels uint16_t height = SEGMENT.virtualHeight(); // segment height in logical pixels
/*
if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) { if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) {
uint16_t t; uint16_t t;
// swap X & Y if segment transposed // swap X & Y if segment transposed
@ -118,6 +118,7 @@ uint16_t IRAM_ATTR WS2812FX::XY(uint16_t x, uint16_t y) {
// swap width & height if segment transposed // swap width & height if segment transposed
t = width; width = height; height = t; t = width; width = height; height = t;
} }
*/
return (x%width) + (y%height) * width; return (x%width) + (y%height) * width;
} }
@ -178,7 +179,7 @@ void IRAM_ATTR WS2812FX::setPixelColorXY(uint16_t x, uint16_t y, byte r, byte g,
} }
} }
// not working correctly ATM // returns RGBW values of pixel
uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) { uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) {
if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
@ -204,11 +205,9 @@ void WS2812FX::blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t
// blurRow: perform a blur on a row of a rectangular matrix // blurRow: perform a blur on a row of a rectangular matrix
void WS2812FX::blurRow(uint16_t row, fract8 blur_amount, CRGB* leds) { void WS2812FX::blurRow(uint16_t row, fract8 blur_amount, CRGB* leds) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
const uint16_t cols = isTransposed ? height : width;
if (row >= rows) return; if (row >= rows) return;
// blur one row // blur one row
uint8_t keep = 255 - blur_amount; uint8_t keep = 255 - blur_amount;
@ -233,11 +232,9 @@ void WS2812FX::blurRow(uint16_t row, fract8 blur_amount, CRGB* leds) {
// blurCol: perform a blur on a column of a rectangular matrix // blurCol: perform a blur on a column of a rectangular matrix
void WS2812FX::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) { void WS2812FX::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
const uint16_t cols = isTransposed ? height : width;
if (col >= cols) return; if (col >= cols) return;
// blur one column // blur one column
uint8_t keep = 255 - blur_amount; uint8_t keep = 255 - blur_amount;
@ -275,21 +272,14 @@ void WS2812FX::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) {
// it can be used to (slowly) clear the LEDs to black. // it can be used to (slowly) clear the LEDs to black.
void WS2812FX::blur1d(CRGB* leds, fract8 blur_amount) { void WS2812FX::blur1d(CRGB* leds, fract8 blur_amount) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t height = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
//const uint16_t cols = isTransposed ? height : width;
for (uint16_t y = 0; y < rows; y++) blurRow(y, blur_amount, leds); for (uint16_t y = 0; y < rows; y++) blurRow(y, blur_amount, leds);
} }
// 1D Box blur (with added weight - blur_amount: [0=no blur, 255=max blur]) // 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) { void WS2812FX::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
const uint16_t cols = isTransposed ? height : width;
const uint16_t dim1 = vertical ? rows : cols; const uint16_t dim1 = vertical ? rows : cols;
const uint16_t dim2 = vertical ? cols : rows; const uint16_t dim2 = vertical ? cols : rows;
if (i >= dim2) return; if (i >= dim2) return;
@ -322,67 +312,76 @@ void WS2812FX::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds)
} }
void WS2812FX::blur2d(CRGB* leds, fract8 blur_amount) { void WS2812FX::blur2d(CRGB* leds, fract8 blur_amount) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = !isTransposed ? height : width;
const uint16_t cols = !isTransposed ? width : height;
for (uint16_t i = 0; i < rows; i++) blurRow(i, blur_amount, leds); // blur all rows 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 for (uint16_t k = 0; k < cols; k++) blurCol(k, blur_amount, leds); // blur all columns
} }
void WS2812FX::moveX(CRGB *leds, int8_t delta) { void WS2812FX::moveX(CRGB *leds, int8_t delta) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED); if (!delta) return;
const uint16_t rows = isTransposed ? width : height; if (delta > 0) {
const uint16_t cols = isTransposed ? height : width; for (uint8_t y = 0; y < rows; y++) for (uint8_t x = 0; x < cols-1; x++) {
if (delta) { if (leds) leds[XY(x, y)] = leds[XY((x + delta)%cols, y)];
if (delta > 0) { else setPixelColorXY(x, y, getPixelColorXY((x + delta)%cols, y));
for (uint8_t y = 0; y < rows; y++) { }
for (uint8_t x = 0; x < cols-1; x++) { } else {
leds[XY(x, y)] = leds[XY(x + delta, y)]; 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 { else setPixelColorXY(x, y, getPixelColorXY(cols + delta, y));
for (uint8_t y = 0; y < rows; y++) { } else {
for (uint8_t x = cols - 1; x > 0; x--) { if (leds) leds[XY(x, y)] = leds[XY(x + delta, y)];
leds[XY(x, y)] = leds[XY(x + delta, y)]; else setPixelColorXY(x, y, getPixelColorXY(x + delta, y));
}
} }
} }
} }
} }
void WS2812FX::moveY(CRGB *leds, int8_t delta) { void WS2812FX::moveY(CRGB *leds, int8_t delta) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED); if (!delta) return;
const uint16_t rows = isTransposed ? width : height; if (delta > 0) {
const uint16_t cols = isTransposed ? height : width; for (uint8_t x = 0; x < cols; x++) for (uint8_t y = 0; y < rows-1; y++) {
if (delta) { if (leds) leds[XY(x, y)] = leds[XY(x, (y + delta)%rows)];
if (delta > 0) { else setPixelColorXY(x, y, getPixelColorXY(x, (y + delta)%rows));
for (uint8_t x = 0; x < cols; x++) { }
for (uint8_t y = 0; y < rows-1; y++) { } else {
leds[XY(x, y)] = leds[XY(x, y + delta)]; 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 { else setPixelColorXY(x, y, getPixelColorXY(x, rows + delta));
for (uint8_t x = 0; x < cols; x++) { } else {
for (uint8_t y = rows - 1; y > 0; y--) { if (leds) leds[XY(x, y)] = leds[XY(x, y + delta)];
leds[XY(x, y)] = leds[XY(x, y + delta)]; else setPixelColorXY(x, y, getPixelColorXY(x, y + delta));
}
} }
} }
} }
} }
// 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) {
if (delta==0) return;
switch (dir) {
case 0: moveX(leds, delta); break;
case 1: moveX(leds, delta); moveY(leds, delta); break;
case 2: moveY(leds, delta); break;
case 3: moveX(leds,-delta); moveY(leds, delta); break;
case 4: moveX(leds,-delta); break;
case 5: moveX(leds,-delta); moveY(leds,-delta); break;
case 6: moveY(leds,-delta); break;
case 7: moveX(leds, delta); moveY(leds,-delta); break;
}
}
void WS2812FX::fill_solid(CRGB* leds, CRGB color) { void WS2812FX::fill_solid(CRGB* leds, CRGB color) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
const uint16_t cols = isTransposed ? height : width;
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
if (leds) leds[XY(x,y)] = color; if (leds) leds[XY(x,y)] = color;
else setPixelColorXY(x, y, color); else setPixelColorXY(x, y, color);
@ -391,11 +390,8 @@ void WS2812FX::fill_solid(CRGB* leds, CRGB color) {
// by stepko, taken from https://editor.soulmatelights.com/gallery/573-blobs // 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) { void WS2812FX::fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
const uint16_t cols = isTransposed ? height : width;
for (int16_t y = -radius; y <= radius; y++) { for (int16_t y = -radius; y <= radius; y++) {
for (int16_t x = -radius; x <= radius; x++) { for (int16_t x = -radius; x <= radius; x++) {
if (x * x + y * y <= radius * radius && if (x * x + y * y <= radius * radius &&
@ -411,11 +407,8 @@ void WS2812FX::fadeToBlackBy(CRGB* leds, uint8_t fadeBy) {
} }
void WS2812FX::nscale8(CRGB* leds, uint8_t scale) { void WS2812FX::nscale8(CRGB* leds, uint8_t scale) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
const uint16_t cols = isTransposed ? height : width;
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
if (leds) leds[XY(x,y)].nscale8(scale); if (leds) leds[XY(x,y)].nscale8(scale);
else setPixelColorXY(x, y, col_to_crgb(getPixelColorXY(x, y)).nscale8(scale)); else setPixelColorXY(x, y, col_to_crgb(getPixelColorXY(x, y)).nscale8(scale));
@ -423,21 +416,15 @@ void WS2812FX::nscale8(CRGB* leds, uint8_t scale) {
} }
void WS2812FX::setPixels(CRGB* leds) { void WS2812FX::setPixels(CRGB* leds) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
const uint16_t cols = isTransposed ? height : width;
for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) setPixelColorXY(x, y, leds[XY(x,y)]); for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) setPixelColorXY(x, y, leds[XY(x,y)]);
} }
//line function //line function
void WS2812FX::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds) { void WS2812FX::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
const uint16_t cols = isTransposed ? height : width;
if (x0 >= cols || x1 >= cols || y0 >= rows || y1 >= rows) return; if (x0 >= cols || x1 >= cols || y0 >= rows || y1 >= rows) return;
const int16_t dx = abs(x1-x0), sx = x0<x1 ? 1 : -1; const int16_t dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
const int16_t dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; const int16_t dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
@ -3529,11 +3516,8 @@ static const unsigned char console_font_6x8[] PROGMEM = {
}; };
void WS2812FX::drawCharacter(unsigned char chr, int16_t x, int16_t y, CRGB color, CRGB *leds) { void WS2812FX::drawCharacter(unsigned char chr, int16_t x, int16_t y, CRGB color, CRGB *leds) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
const uint16_t cols = isTransposed ? height : width;
for (uint8_t i = 0; i<8; i++) { // character height for (uint8_t i = 0; i<8; i++) { // character height
int16_t y0 = y + i; int16_t y0 = y + i;

View File

@ -890,11 +890,8 @@ uint32_t IRAM_ATTR WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint1
* Fills segment with color * Fills segment with color
*/ */
void WS2812FX::fill(uint32_t c) { void WS2812FX::fill(uint32_t c) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight(); // will be 1 for 1D
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
const uint16_t cols = isTransposed ? height : width;
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
if (isMatrix) setPixelColorXY(x, y, c); if (isMatrix) setPixelColorXY(x, y, c);
else setPixelColor(x, c); else setPixelColor(x, c);
@ -913,11 +910,8 @@ void WS2812FX::blendPixelColor(uint16_t n, uint32_t color, uint8_t blend)
* fade out function, higher rate = quicker fade * fade out function, higher rate = quicker fade
*/ */
void WS2812FX::fade_out(uint8_t rate) { void WS2812FX::fade_out(uint8_t rate) {
const uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength();
const uint16_t height = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight(); // will be 1 for 1D
const bool isTransposed = SEGMENT.getOption(SEG_OPTION_TRANSPOSED);
const uint16_t rows = isTransposed ? width : height;
const uint16_t cols = isTransposed ? height : width;
rate = (255-rate) >> 1; rate = (255-rate) >> 1;
float mappedRate = float(rate) +1.1; float mappedRate = float(rate) +1.1;
@ -956,6 +950,14 @@ void WS2812FX::fade_out(uint8_t rate) {
*/ */
void WS2812FX::blur(uint8_t blur_amount) 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 keep = 255 - blur_amount;
uint8_t seep = blur_amount >> 1; uint8_t seep = blur_amount >> 1;
CRGB carryover = CRGB::Black; CRGB carryover = CRGB::Black;

View File

@ -214,6 +214,15 @@ void WLED::loop()
loops++; loops++;
#endif // WLED_DEBUG #endif // WLED_DEBUG
toki.resetTick(); toki.resetTick();
#if WLED_WATCHDOG_TIMEOUT > 0
// we finished our mainloop, reset the watchdog timer
#ifdef ARDUINO_ARCH_ESP32
esp_task_wdt_reset();
#else
ESP.wdtFeed();
#endif
#endif
} }
void WLED::enableWatchdog() { void WLED::enableWatchdog() {

View File

@ -8,7 +8,7 @@
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2205251 #define VERSION 2205301
//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
@ -49,6 +49,12 @@
// filesystem specific debugging // filesystem specific debugging
//#define WLED_DEBUG_FS //#define WLED_DEBUG_FS
#ifndef WLED_WATCHDOG_TIMEOUT
// 3 seconds should be enough to detect a lockup
// define WLED_WATCHDOG_TIMEOUT=0 to disable watchdog
#define WLED_WATCHDOG_TIMEOUT 3
#endif
//optionally disable brownout detector on ESP32. //optionally disable brownout detector on ESP32.
//This is generally a terrible idea, but improves boot success on boards with a 3.3v regulator + cap setup that can't provide 400mA peaks //This is generally a terrible idea, but improves boot success on boards with a 3.3v regulator + cap setup that can't provide 400mA peaks
//#define WLED_DISABLE_BROWNOUT_DET //#define WLED_DISABLE_BROWNOUT_DET
@ -78,6 +84,7 @@
#else #else
#include <LittleFS.h> #include <LittleFS.h>
#endif #endif
#include "esp_task_wdt.h"
#endif #endif
#include "src/dependencies/network/Network.h" #include "src/dependencies/network/Network.h"