2D optimisations.

This commit is contained in:
Blaz Kristan 2022-08-02 18:27:32 +02:00
parent 7ca1d99412
commit 0ba8bace0d
6 changed files with 2080 additions and 2112 deletions

View File

@ -1990,13 +1990,15 @@ uint16_t mode_fire_2012()
// Step 1. Cool down every cell a little // Step 1. Cool down every cell a little
for(int i = 0; i < rows; i++) { for(int i = 0; i < rows; i++) {
uint8_t cool = (((20 + SEGMENT.speed/3) * 16) / rows); uint8_t cool = (((20 + SEGMENT.speed/3) * 16) / rows);
/*
// 2D enhancement: cool sides of the flame a bit more // 2D enhancement: cool sides of the flame a bit more
if (cols>5) { if (cols>5) {
if (f < q) cool = qadd8(cool, 2*(uint16_t)((cool * (q-f))/cols)); // cool segment sides a bit more if (f < q) cool = qadd8(cool, 2*(uint16_t)((cool * (q-f))/cols)); // cool segment sides a bit more
if (f > 3*q) cool = qadd8(cool, 2*(uint16_t)((cool * (cols-f))/cols)); // cool segment sides a bit more if (f > 3*q) cool = qadd8(cool, 2*(uint16_t)((cool * (cols-f))/cols)); // cool segment sides a bit more
} }
*/
uint8_t temp = qsub8(heat[i+rows*f], random8(0, cool + 2)); uint8_t temp = qsub8(heat[i+rows*f], random8(0, cool + 2));
heat[i+rows*f] = (temp==0 && i<ignition) ? random8(8,16) : temp; // prevent ignition area from becoming black heat[i+rows*f] = (temp==0 && i<ignition) ? random8(1,16) : temp; // prevent ignition area from becoming black
} }
// Step 2. Heat from each cell drifts 'up' and diffuses a little // Step 2. Heat from each cell drifts 'up' and diffuses a little
@ -2047,6 +2049,8 @@ uint16_t mode_colorwaves()
uint16_t brightnesstheta16 = sPseudotime; uint16_t brightnesstheta16 = sPseudotime;
CRGB fastled_col; CRGB fastled_col;
if (SEGENV.call == 0) SEGMENT.fill(BLACK);
for ( uint16_t i = 0 ; i < SEGLEN; i++) { for ( uint16_t i = 0 ; i < SEGLEN; i++) {
hue16 += hueinc16; hue16 += hueinc16;
uint8_t hue8 = hue16 >> 8; uint8_t hue8 = hue16 >> 8;
@ -4565,45 +4569,33 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
//const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
//if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
//CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
uint16_t x, y; uint16_t x, y;
// initialize on first call // initialize on first call
if (SEGENV.call == 0) { if (SEGENV.call == 0) {
SEGMENT.setUpLeds(); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK); SEGMENT.fill(BLACK);
//SEGMENT.fill_solid(leds, CRGB::Black);
} }
SEGMENT.fadeToBlackBy(16 + (SEGMENT.speed>>3)); // create fading trails SEGMENT.fadeToBlackBy(16 + (SEGMENT.speed>>3)); // create fading trails
//SEGMENT.fadeToBlackBy(leds, 16 + (SEGMENT.speed>>3)); // create fading trails
float t = (float)(millis())/128; // timebase float t = (float)(millis())/128; // timebase
// outer stars // outer stars
for (size_t i = 0; i < 8; i++) { for (size_t i = 0; i < 8; i++) {
x = beatsin8(SEGMENT.custom1>>3, 0, cols - 1, 0, ((i % 2) ? 128 : 0) + t * i); x = beatsin8(SEGMENT.custom1>>3, 0, cols - 1, 0, ((i % 2) ? 128 : 0) + t * i);
y = beatsin8(SEGMENT.intensity>>3, 0, rows - 1, 0, ((i % 2) ? 192 : 64) + t * i); y = beatsin8(SEGMENT.intensity>>3, 0, rows - 1, 0, ((i % 2) ? 192 : 64) + t * i);
SEGMENT.setPixelColorXY(x, y, CHSV(i*32, 255, 255)); SEGMENT.addPixelColorXY(x, y, CHSV(i*32, 255, 255));
//leds[XY(x,y)] += CHSV(i*32, 255, 255);
} }
// inner stars // inner stars
for (size_t i = 0; i < 4; i++) { for (size_t i = 0; i < 4; i++) {
x = beatsin8(SEGMENT.custom2>>3, cols/4, cols - 1 - cols/4, 0, ((i % 2) ? 128 : 0) + t * i); x = beatsin8(SEGMENT.custom2>>3, cols/4, cols - 1 - cols/4, 0, ((i % 2) ? 128 : 0) + t * i);
y = beatsin8(SEGMENT.custom3>>3, rows/4, rows - 1 - rows/4, 0, ((i % 2) ? 192 : 64) + t * i); y = beatsin8(SEGMENT.custom3>>3, rows/4, rows - 1 - rows/4, 0, ((i % 2) ? 192 : 64) + t * i);
SEGMENT.setPixelColorXY(x, y, CHSV(i*32, 255, 255)); SEGMENT.addPixelColorXY(x, y, CHSV(i*32, 255, 255));
//leds[XY(x,y)] += CHSV(i*32, 255, 255);
} }
// central white dot // central white dot
SEGMENT.setPixelColorXY(cols/2, rows/2, CHSV(0, 0, 255)); SEGMENT.setPixelColorXY(cols/2, rows/2, CHSV(0, 0, 255));
//leds[XY()] = CHSV(0,0,255);
// blur everything a bit // blur everything a bit
SEGMENT.blur(16); SEGMENT.blur(16);
//SEGMENT.blur2d(leds, 16);
//SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} // mode_2DBlackHole() } // mode_2DBlackHole()
static const char *_data_FX_MODE_2DBLACKHOLE PROGMEM = "Black Hole@Fade rate,Outer Y freq.,Outer X freq.,Inner X freq.,Inner Y freq.;;;2d"; static const char *_data_FX_MODE_2DBLACKHOLE PROGMEM = "Black Hole@Fade rate,Outer Y freq.,Outer X freq.,Inner X freq.,Inner Y freq.;;;2d";
@ -4617,13 +4609,10 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
if (SEGENV.call == 0) { if (SEGENV.call == 0) {
SEGMENT.fill_solid(leds, CRGB::Black); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
SEGENV.aux0 = 0; // start with red hue SEGENV.aux0 = 0; // start with red hue
} }
@ -4633,8 +4622,7 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
byte numLines = SEGMENT.intensity/16 + 1; byte numLines = SEGMENT.intensity/16 + 1;
SEGENV.aux0++; // hue SEGENV.aux0++; // hue
SEGMENT.fadeToBlackBy(leds, 40); SEGMENT.fadeToBlackBy(40);
for (size_t i = 0; i < numLines; i++) { for (size_t i = 0; i < numLines; i++) {
byte x1 = beatsin8(2 + SEGMENT.speed/16, 0, (cols - 1)); byte x1 = beatsin8(2 + SEGMENT.speed/16, 0, (cols - 1));
byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (cols - 1)); byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (cols - 1));
@ -4649,19 +4637,17 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
for (size_t i = 1; i <= steps; i++) { for (size_t i = 1; i <= steps; i++) {
byte dx = lerp8by8(x1, y1, i * 255 / steps); byte dx = lerp8by8(x1, y1, i * 255 / steps);
byte dy = lerp8by8(x2, y2, i * 255 / steps); byte dy = lerp8by8(x2, y2, i * 255 / steps);
int index = XY(dx, dy); SEGMENT.addPixelColorXY(dx, dy, color); // use setPixelColorXY for different look
leds[index] += color; // change to += for brightness look if (grad) SEGMENT.fadePixelColorXY(dx, dy, (i * 255 / steps)); //Draw gradient line
if (grad) leds[index] %= (i * 255 / steps); //Draw gradient line
} }
if (dot) { //add white point at the ends of line if (dot) { //add white point at the ends of line
leds[XY(x1, x2)] += CRGB::White; SEGMENT.addPixelColorXY(x1, x2, WHITE);
leds[XY(y1, y2)] += CRGB::White; SEGMENT.addPixelColorXY(y1, y2, WHITE);
} }
} }
SEGMENT.blur2d(leds, 4); SEGMENT.blur(4);
SEGMENT.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method.
return FRAMETIME; return FRAMETIME;
} // mode_2DColoredBursts() } // mode_2DColoredBursts()
static const char *_data_FX_MODE_2DCOLOREDBURSTS PROGMEM = "Colored Bursts@Speed,# of lines;;!;2d"; static const char *_data_FX_MODE_2DCOLOREDBURSTS PROGMEM = "Colored Bursts@Speed,# of lines;;!;2d";
@ -4675,22 +4661,20 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (SEGENV.call == 0) {
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
}
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); SEGMENT.fadeToBlackBy(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(SEGPALETTE, i*5+millis()/17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND); SEGMENT.setPixelColorXY(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(SEGPALETTE,i*5+128+millis()/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND); // 180 degrees (128) out of phase SEGMENT.setPixelColorXY(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));
} }
SEGMENT.blur2d(leds, SEGMENT.intensity/8); SEGMENT.blur(SEGMENT.intensity>>3);
SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} // mode_2Ddna() } // mode_2Ddna()
static const char *_data_FX_MODE_2DDNA PROGMEM = "DNA@Scroll speed,Blur;1,2,3;!;2d"; static const char *_data_FX_MODE_2DDNA PROGMEM = "DNA@Scroll speed,Blur;1,2,3;!;2d";
@ -4704,13 +4688,10 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
if (SEGENV.call == 0) { if (SEGENV.call == 0) {
SEGMENT.fill_solid(leds, CRGB::Black); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
SEGENV.aux0 = 0; // hue SEGENV.aux0 = 0; // hue
} }
@ -4718,7 +4699,7 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma
uint8_t freq = SEGMENT.intensity/8; uint8_t freq = SEGMENT.intensity/8;
uint32_t ms = millis() / 20; uint32_t ms = millis() / 20;
SEGMENT.nscale8(leds, 120); SEGMENT.fadeToBlackBy(135);
for(int i = 0; i < rows; i++) { for(int i = 0; i < rows; i++) {
uint16_t x = beatsin8(speeds, 0, cols - 1, 0, i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, i * freq + 128); uint16_t x = beatsin8(speeds, 0, cols - 1, 0, i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, i * freq + 128);
@ -4729,19 +4710,17 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma
byte steps = abs8(x - x1) + 1; byte steps = abs8(x - x1) + 1;
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); SEGMENT.addPixelColorXY(dx, i, ColorFromPalette(SEGPALETTE, SEGENV.aux0, 255, LINEARBLEND));
leds[index] += ColorFromPalette(SEGPALETTE, SEGENV.aux0, 255, LINEARBLEND); SEGMENT.fadePixelColorXY(dx, i, (k * 255 / steps));
leds[index] %= (k * 255 / steps); //for draw gradient line
} }
leds[XY(x, i)] += CRGB::DarkSlateGray; SEGMENT.addPixelColorXY(x, i, DARKSLATEGRAY);
leds[XY(x1, i)] += CRGB::White; SEGMENT.addPixelColorXY(x1, i, WHITE);
} }
} }
SEGMENT.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method.
return FRAMETIME; return FRAMETIME;
} // mode_2DDNASpiral() } // mode_2DDNASpiral()
static const char *_data_FX_MODE_2DDNASPIRAL PROGMEM = "DNA Spiral@Scroll speed,Blur;;!;2d"; static const char *_data_FX_MODE_2DDNASPIRAL PROGMEM = "DNA Spiral@Scroll speed,Y frequency;;!;2d";
///////////////////////// /////////////////////////
@ -4752,16 +4731,13 @@ uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmateli
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
//if (cols<8 || rows<8) return mode_static(); // makes no sense to run on smaller than 8x8 if (SEGENV.call == 0) {
SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
}
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed SEGMENT.fadeToBlackBy(128);
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black);
SEGMENT.fadeToBlackBy(leds, 128);
const uint16_t maxDim = MAX(cols, 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));
@ -4769,11 +4745,10 @@ 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(SEGPALETTE, (i * 20) + (t / 20), 255, LINEARBLEND); SEGMENT.setPixelColorXY(myX, myY, ColorFromPalette(SEGPALETTE, (i * 20) + (t / 20), 255, LINEARBLEND));
} }
SEGMENT.blur2d(leds, SEGMENT.intensity>>3); SEGMENT.blur(SEGMENT.intensity>>3);
SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} // mode_2DDrift() } // mode_2DDrift()
static const char *_data_FX_MODE_2DDRIFT PROGMEM = "Drift@Rotation speed,Blur amount;;!;2d"; static const char *_data_FX_MODE_2DDRIFT PROGMEM = "Drift@Rotation speed,Blur amount;;!;2d";
@ -4787,33 +4762,31 @@ uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (SEGENV.call == 0) {
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); }
uint16_t xscale = SEGMENT.intensity*4; uint16_t xscale = SEGMENT.intensity*4;
uint32_t yscale = SEGMENT.speed*8; uint32_t yscale = SEGMENT.speed*8;
uint8_t indexx = 0; uint8_t indexx = 0;
SEGPALETTE = 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);
for(int j=0; j < cols; j++) { for(int j=0; j < cols; j++) {
for(int i=0; i < rows; i++) { for(int 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(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. SEGMENT.setPixelColorXY(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
SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} // mode_2Dfirenoise() } // mode_2Dfirenoise()
static const char *_data_FX_MODE_2DFIRENOISE PROGMEM = "Firenoise@X scale,Y scale;;2d"; static const char *_data_FX_MODE_2DFIRENOISE PROGMEM = "Firenoise@X scale,Y scale;;;2d";
////////////////////////////// //////////////////////////////
@ -4824,23 +4797,23 @@ uint16_t mode_2DFrizzles(void) { // By: Stepko https://editor.so
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (SEGENV.call == 0) {
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black);
SEGMENT.fadeToBlackBy(leds, 16);
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(SEGPALETTE, beatsin8(12, 0, 255), 255, LINEARBLEND);
} }
SEGMENT.blur2d(leds, 16);
SEGMENT.setPixels(leds); SEGMENT.fadeToBlackBy(16);
for (size_t i = 8; i > 0; i--) {
SEGMENT.addPixelColorXY(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.blur(SEGMENT.custom1>>3);
return FRAMETIME; return FRAMETIME;
} // mode_2DFrizzles() } // mode_2DFrizzles()
static const char *_data_FX_MODE_2DFRIZZLES PROGMEM = "Frizzles@X frequency,Y frequency;;!;2d"; static const char *_data_FX_MODE_2DFRIZZLES PROGMEM = "Frizzles@X frequency,Y frequency,Blur;;!;2d";
/////////////////////////////////////////// ///////////////////////////////////////////
@ -5094,7 +5067,6 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
SEGMENT.fadeToBlackBy(SEGMENT.intensity); SEGMENT.fadeToBlackBy(SEGMENT.intensity);
//SEGMENT.fade_out(SEGMENT.intensity);
//for (int i=0; i < 4*(cols+rows); i ++) { //for (int i=0; i < 4*(cols+rows); i ++) {
for (int i=0; i < 256; i ++) { for (int i=0; i < 256; i ++) {
@ -5120,12 +5092,11 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams.
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (SEGENV.call == 0) {
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); }
uint8_t fade = map(SEGMENT.custom1, 0, 255, 50, 250); // equals trail size uint8_t fade = map(SEGMENT.custom1, 0, 255, 50, 250); // equals trail size
uint8_t speed = (256-SEGMENT.speed) >> map(MIN(rows, 150), 0, 150, 0, 3); // slower speeds for small displays uint8_t speed = (256-SEGMENT.speed) >> map(MIN(rows, 150), 0, 150, 0, 3); // slower speeds for small displays
@ -5142,24 +5113,23 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams.
if (strip.now - SEGENV.step >= speed) { if (strip.now - SEGENV.step >= speed) {
SEGENV.step = strip.now; SEGENV.step = strip.now;
for (int16_t row=rows-1; row>=0; row--) { for (int row=rows-1; row>=0; row--) {
for (int16_t col=0; col<cols; col++) { for (int col=0; col<cols; col++) {
if (leds[XY(col, row)] == spawnColor) { CRGB pix = SEGMENT.getPixelColorXY(col, row);
leds[XY(col, row)] = trailColor; // create trail if (pix == spawnColor) {
if (row < rows-1) leds[XY(col, row+1)] = spawnColor; SEGMENT.setPixelColorXY(col, row, trailColor); // create trail
if (row < rows-1) SEGMENT.setPixelColorXY(col, row+1, spawnColor);
} else {
// fade other pixels
SEGMENT.setPixelColorXY(col, row, pix.nscale8(fade));
} }
} }
} }
// fade all leds
for (int x=0; x<cols; x++) for (int y=0; y<rows; y++) {
if (leds[XY(x,y)] != spawnColor) leds[XY(x,y)].nscale8(fade); // only fade trail
}
// check for empty screen to ensure code spawn // check for empty screen to ensure code spawn
bool emptyScreen = true; bool emptyScreen = true;
for(int x=0; x<cols; x++) for(int y=0; y<rows; y++) { for(int x=0; x<cols; x++) for(int y=0; y<rows; y++) {
if (leds[XY(x,y)]) { if (SEGMENT.getPixelColorXY(x,y)) {
emptyScreen = false; emptyScreen = false;
break; break;
} }
@ -5168,10 +5138,8 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams.
// spawn new falling code // spawn new falling code
if (random8() < SEGMENT.intensity || emptyScreen) { if (random8() < SEGMENT.intensity || emptyScreen) {
uint8_t spawnX = random8(cols); uint8_t spawnX = random8(cols);
leds[XY(spawnX, 0)] = spawnColor; SEGMENT.setPixelColorXY(spawnX, 0, spawnColor);
} }
SEGMENT.setPixels(leds);
} // if millis } // if millis
return FRAMETIME; return FRAMETIME;
@ -5227,9 +5195,9 @@ uint16_t mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have
SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(0, false, PALETTE_SOLID_WRAP, 0)); SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(0, false, PALETTE_SOLID_WRAP, 0));
} }
// show the 3 points, too // show the 3 points, too
SEGMENT.setPixelColorXY(x1, y1, CRGB::White); SEGMENT.setPixelColorXY(x1, y1, WHITE);
SEGMENT.setPixelColorXY(x2, y2, CRGB::White); SEGMENT.setPixelColorXY(x2, y2, WHITE);
SEGMENT.setPixelColorXY(x3, y3, CRGB::White); SEGMENT.setPixelColorXY(x3, y3, WHITE);
} }
} }
@ -5270,14 +5238,14 @@ uint16_t mode_2DPlasmaball(void) { // By: Stepko https://edito
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (SEGENV.call == 0) {
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
}
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); SEGMENT.fadeToBlackBy(SEGMENT.custom1>>2);
SEGMENT.fadeToBlackBy(leds, 64);
float t = millis() / (33 - SEGMENT.speed/8); float t = millis() / (33 - SEGMENT.speed/8);
for(int i = 0; i < cols; i++) { for(int i = 0; i < cols; i++) {
uint16_t thisVal = inoise8(i * 30, t, t); uint16_t thisVal = inoise8(i * 30, t, t);
@ -5290,20 +5258,19 @@ uint16_t mode_2DPlasmaball(void) { // By: Stepko https://edito
uint16_t cx = (i + thisMax_); uint16_t cx = (i + thisMax_);
uint16_t cy = (j + thisMax); uint16_t cy = (j + thisMax);
leds[XY(i, j)] += ((x - y > -2) && (x - y < 2)) || SEGMENT.addPixelColorXY(i, j, ((x - y > -2) && (x - y < 2)) ||
((cols - 1 - x - y) > -2 && (cols - 1 - x - y < 2)) || ((cols - 1 - x - y) > -2 && (cols - 1 - x - y < 2)) ||
(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(SEGPALETTE, beat8(5), thisVal, LINEARBLEND) : CRGB::Black; (rows - 1 - cy == 0)) ? ColorFromPalette(SEGPALETTE, beat8(5), thisVal, LINEARBLEND) : CRGB::Black);
} }
} }
SEGMENT.blur2d(leds, 4); SEGMENT.blur(SEGMENT.custom2>>5);
SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} // mode_2DPlasmaball() } // mode_2DPlasmaball()
static const char *_data_FX_MODE_2DPLASMABALL PROGMEM = "Plasma Ball@Speed;!,!,!;!;2d"; static const char *_data_FX_MODE_2DPLASMABALL PROGMEM = "Plasma Ball@Speed,,Fade,Blur;!,!,!;!;2d";
//////////////////////////////// ////////////////////////////////
@ -5317,16 +5284,13 @@ uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
CRGBPalette16 auroraPalette = {0x000000, 0x003300, 0x006600, 0x009900, 0x00cc00, 0x00ff00, 0x33ff00, 0x66ff00, 0x99ff00, 0xccff00, 0xffff00, 0xffcc00, 0xff9900, 0xff6600, 0xff3300, 0xff0000}; CRGBPalette16 auroraPalette = {0x000000, 0x003300, 0x006600, 0x009900, 0x00cc00, 0x00ff00, 0x33ff00, 0x66ff00, 0x99ff00, 0xccff00, 0xffff00, 0xffcc00, 0xff9900, 0xff6600, 0xff3300, 0xff0000};
if (SEGENV.call == 0) { if (SEGENV.call == 0) {
SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
SEGENV.step = 0; SEGENV.step = 0;
SEGMENT.fill_solid(leds, CRGB::Black);
} }
float adjustHeight = (float)map(rows, 8, 32, 28, 12); float adjustHeight = (float)map(rows, 8, 32, 28, 12);
@ -5352,14 +5316,13 @@ uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https
for(int x = 0; x < cols; x++) { for(int x = 0; x < cols; x++) {
for(int y = 0; y < rows; y++) { for(int y = 0; y < rows; y++) {
SEGENV.step++; SEGENV.step++;
leds[XY(x, y)] = ColorFromPalette(auroraPalette, SEGMENT.setPixelColorXY(x, y, ColorFromPalette(auroraPalette,
qsub8( qsub8(
inoise8((SEGENV.step%2) + x * _scale, y * 16 + SEGENV.step % 16, SEGENV.step / _speed), inoise8((SEGENV.step%2) + x * _scale, y * 16 + SEGENV.step % 16, SEGENV.step / _speed),
fabs((float)rows / 2 - (float)y) * adjustHeight)); fabs((float)rows / 2 - (float)y) * adjustHeight)));
} }
} }
SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} // mode_2DPolarLights() } // mode_2DPolarLights()
static const char *_data_FX_MODE_2DPOLARLIGHTS PROGMEM = "Polar Lights@Speed,Scale;;;2d"; static const char *_data_FX_MODE_2DPOLARLIGHTS PROGMEM = "Polar Lights@Speed,Scale;;;2d";
@ -5373,24 +5336,21 @@ uint16_t mode_2DPulser(void) { // By: ldirko https://edi
//const uint16_t cols = SEGMENT.virtualWidth(); //const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (SEGENV.call == 0) {
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
}
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); SEGMENT.fadeToBlackBy(8 - (SEGMENT.intensity>>5));
SEGMENT.fadeToBlackBy(leds, 8 - (SEGMENT.intensity>>5));
uint16_t a = strip.now / (18 - SEGMENT.speed / 16); uint16_t a = strip.now / (18 - SEGMENT.speed / 16);
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 SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, 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.blur(1 + (SEGMENT.intensity>>4));
SEGMENT.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method.
return FRAMETIME; return FRAMETIME;
} // mode_2DPulser() } // mode_2DPulser()
static const char *_data_FX_MODE_2DPULSER PROGMEM = "Pulser@Speed,Blur;;!;2d"; static const char *_data_FX_MODE_2DPULSER PROGMEM = "Pulser@Speed,Blur;;!;2d";
@ -5404,27 +5364,26 @@ uint16_t mode_2DSindots(void) { // By: ldirko http
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (SEGENV.call == 0) {
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
}
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); SEGMENT.fadeToBlackBy(SEGMENT.custom1>>3);
SEGMENT.fadeToBlackBy(leds, 15);
byte t1 = millis() / (257 - SEGMENT.speed); // 20; byte t1 = millis() / (257 - SEGMENT.speed); // 20;
byte t2 = sin8(t1) / 4 * 2; byte t2 = sin8(t1) / 4 * 2;
for(int i = 0; i < 13; i++) { for(int 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(SEGPALETTE, i * 255 / 13, 255, LINEARBLEND); SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, i * 255 / 13, 255, LINEARBLEND));
} }
SEGMENT.blur2d(leds, 16); SEGMENT.blur(SEGMENT.custom2>>3);
SEGMENT.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method.
return FRAMETIME; return FRAMETIME;
} // mode_2DSindots() } // mode_2DSindots()
static const char *_data_FX_MODE_2DSINDOTS PROGMEM = "Sindots@Speed,Dot distance;;!;2d"; static const char *_data_FX_MODE_2DSINDOTS PROGMEM = "Sindots@Speed,Dot distance,Fade rate,Blur;;!;2d";
////////////////////////////// //////////////////////////////
@ -5437,18 +5396,18 @@ uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://g
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (SEGENV.call == 0) {
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); }
const uint8_t kBorderWidth = 2; const uint8_t kBorderWidth = 2;
SEGMENT.fadeToBlackBy(leds, 24); SEGMENT.fadeToBlackBy(24);
uint8_t blurAmount = SEGMENT.custom3>>4; uint8_t blurAmount = SEGMENT.custom3>>4;
SEGMENT.blur2d(leds, blurAmount); SEGMENT.blur(blurAmount);
// Use two out-of-sync sine waves // Use two out-of-sync sine waves
uint8_t i = beatsin8(19, kBorderWidth, cols-kBorderWidth); uint8_t i = beatsin8(19, kBorderWidth, cols-kBorderWidth);
@ -5460,11 +5419,10 @@ uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://g
uint16_t ms = millis(); uint16_t ms = millis();
leds[XY(i, m)] += ColorFromPalette(SEGPALETTE, ms/29, 255, LINEARBLEND); SEGMENT.addPixelColorXY(i, m, ColorFromPalette(SEGPALETTE, ms/29, 255, LINEARBLEND));
leds[XY(j, n)] += ColorFromPalette(SEGPALETTE, ms/41, 255, LINEARBLEND); SEGMENT.addPixelColorXY(j, n, ColorFromPalette(SEGPALETTE, ms/41, 255, LINEARBLEND));
leds[XY(k, p)] += ColorFromPalette(SEGPALETTE, ms/73, 255, LINEARBLEND); SEGMENT.addPixelColorXY(k, p, ColorFromPalette(SEGPALETTE, ms/73, 255, LINEARBLEND));
SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} // mode_2Dsquaredswirl() } // mode_2Dsquaredswirl()
static const char *_data_FX_MODE_2DSQUAREDSWIRL PROGMEM = "Squared Swirl@,,,,Blur;,,;!;2d"; static const char *_data_FX_MODE_2DSQUAREDSWIRL PROGMEM = "Squared Swirl@,,,,Blur;,,;!;2d";
@ -5478,13 +5436,14 @@ uint16_t mode_2DSunradiation(void) { // By: ldirko https://edi
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize + (sizeof(byte)*(cols+2)*(rows+2)))) return mode_static(); //allocation failed if (!SEGENV.allocateData(sizeof(byte)*(cols+2)*(rows+2))) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); byte *bump = reinterpret_cast<byte*>(SEGENV.data);
byte *bump = reinterpret_cast<byte*>(SEGENV.data + dataSize);
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); if (SEGENV.call == 0) {
SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
}
unsigned long t = millis() / 4; unsigned long t = millis() / 4;
int index = 0; int index = 0;
@ -5510,15 +5469,14 @@ uint16_t mode_2DSunradiation(void) { // By: ldirko https://edi
int temp = difx * difx + dify * dify; int temp = difx * difx + dify * dify;
int col = 255 - temp / 8; //8 its a size of effect int col = 255 - temp / 8; //8 its a size of effect
if (col < 0) col = 0; if (col < 0) col = 0;
leds[XY(x, y)] = HeatColor(col / (3.0f-(float)(SEGMENT.intensity)/128.f)); SEGMENT.setPixelColorXY(x, y, HeatColor(col / (3.0f-(float)(SEGMENT.intensity)/128.f)));
} }
yindex += (cols + 2); yindex += (cols + 2);
} }
SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} // mode_2DSunradiation() } // mode_2DSunradiation()
static const char *_data_FX_MODE_2DSUNRADIATION PROGMEM = "Sun Radiation@Variance,Brightness;;2d"; static const char *_data_FX_MODE_2DSUNRADIATION PROGMEM = "Sun Radiation@Variance,Brightness;;;2d";
///////////////////////// /////////////////////////
@ -5529,12 +5487,11 @@ uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.so
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (SEGENV.call == 0) {
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); }
uint8_t hue; uint8_t hue;
int offsetX = beatsin16(3, -360, 360); int offsetX = beatsin16(3, -360, 360);
@ -5542,15 +5499,13 @@ uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.so
for(int x = 0; x < cols; x++) { for(int x = 0; x < cols; x++) {
for(int y = 0; y < rows; y++) { for(int y = 0; y < rows; y++) {
uint16_t index = XY(x, y);
hue = x * beatsin16(10, 1, 10) + offsetY; hue = x * beatsin16(10, 1, 10) + offsetY;
leds[index] = ColorFromPalette(SEGPALETTE, hue, sin8(x * SEGMENT.speed + offsetX) * sin8(x * SEGMENT.speed + offsetX) / 255, LINEARBLEND); SEGMENT.setPixelColorXY(x, y, 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(SEGPALETTE, hue, sin8(y * SEGMENT.intensity + offsetY) * sin8(y * SEGMENT.intensity + offsetY) / 255, LINEARBLEND); SEGMENT.addPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, hue, sin8(y * SEGMENT.intensity + offsetY) * sin8(y * SEGMENT.intensity + offsetY) / 255, LINEARBLEND));
} }
} }
SEGMENT.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method.
return FRAMETIME; return FRAMETIME;
} // mode_2DTartan() } // mode_2DTartan()
static const char *_data_FX_MODE_2DTARTAN PROGMEM = "Tartan@X scale,Y scale;;!;2d"; static const char *_data_FX_MODE_2DTARTAN PROGMEM = "Tartan@X scale,Y scale;;!;2d";
@ -5564,12 +5519,11 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (SEGENV.call == 0) {
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
if (SEGENV.call == 0) SEGMENT.fill_solid(leds, CRGB::Black); }
uint32_t tb = strip.now >> 12; // every ~4s uint32_t tb = strip.now >> 12; // every ~4s
if (tb > SEGENV.step) { if (tb > SEGENV.step) {
@ -5581,23 +5535,23 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht
SEGENV.step = tb + random8(4); SEGENV.step = tb + random8(4);
} }
SEGMENT.fadeToBlackBy(leds, map(SEGMENT.speed, 0, 255, 248, 16)); SEGMENT.fadeToBlackBy(map(SEGMENT.speed, 0, 255, 248, 16));
SEGMENT.move(SEGENV.aux0, 1, leds); SEGMENT.move(SEGENV.aux0, 1);
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(SEGPALETTE, beatsin8(12 + i, 0, 255), 255); CRGB color = ColorFromPalette(SEGPALETTE, beatsin8(12 + i, 0, 255), 255);
leds[XY(x, y)] += color; SEGMENT.addPixelColorXY(x, y, color);
if (cols > 24 || rows > 24) { if (cols > 24 || rows > 24) {
leds[XY(x + 1, y)] += color; SEGMENT.addPixelColorXY(x+1, y, color);
leds[XY(x - 1, y)] += color; SEGMENT.addPixelColorXY(x-1, y, color);
leds[XY(x, y + 1)] += color; SEGMENT.addPixelColorXY(x, y+1, color);
leds[XY(x, y - 1)] += color; SEGMENT.addPixelColorXY(x, y-1, color);
} }
} }
SEGMENT.blur2d(leds, SEGMENT.intensity>>3); SEGMENT.blur(SEGMENT.intensity>>3);
SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} }
static const char *_data_FX_MODE_2DSPACESHIPS PROGMEM = "Spaceships@!,Blur;!,!,!;!;2d"; static const char *_data_FX_MODE_2DSPACESHIPS PROGMEM = "Spaceships@!,Blur;!,!,!;!;2d";
@ -5613,7 +5567,6 @@ uint16_t mode_2Dcrazybees(void) {
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
byte n = MIN(MAX_BEES, (rows * cols) / 256 + 1); byte n = MIN(MAX_BEES, (rows * cols) / 256 + 1);
@ -5633,12 +5586,12 @@ uint16_t mode_2Dcrazybees(void) {
}; };
} bee_t; } bee_t;
if (!SEGENV.allocateData(dataSize + sizeof(bee_t)*MAX_BEES)) return mode_static(); //allocation failed if (!SEGENV.allocateData(sizeof(bee_t)*MAX_BEES)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); bee_t *bee = reinterpret_cast<bee_t*>(SEGENV.data);
bee_t *bee = reinterpret_cast<bee_t*>(SEGENV.data + dataSize);
if (SEGENV.call == 0) { if (SEGENV.call == 0) {
SEGMENT.fill_solid(leds, CRGB::Black); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
bee[i].posX = random8(0, cols); bee[i].posX = random8(0, cols);
bee[i].posY = random8(0, rows); bee[i].posY = random8(0, rows);
@ -5649,15 +5602,15 @@ uint16_t mode_2Dcrazybees(void) {
if (millis() > SEGENV.step) { if (millis() > SEGENV.step) {
SEGENV.step = millis() + (FRAMETIME * 8 / ((SEGMENT.speed>>5)+1)); SEGENV.step = millis() + (FRAMETIME * 8 / ((SEGMENT.speed>>5)+1));
SEGMENT.fadeToBlackBy(leds, 32); SEGMENT.fadeToBlackBy(32);
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
leds[XY(bee[i].aimX + 1, bee[i].aimY)] += CHSV(bee[i].hue, 255, 255); SEGMENT.addPixelColorXY(bee[i].aimX + 1, bee[i].aimY, CRGB(CHSV(bee[i].hue, 255, 255)));
leds[XY(bee[i].aimX, bee[i].aimY + 1)] += CHSV(bee[i].hue, 255, 255); SEGMENT.addPixelColorXY(bee[i].aimX, bee[i].aimY + 1, CRGB(CHSV(bee[i].hue, 255, 255)));
leds[XY(bee[i].aimX - 1, bee[i].aimY)] += CHSV(bee[i].hue, 255, 255); SEGMENT.addPixelColorXY(bee[i].aimX - 1, bee[i].aimY, CRGB(CHSV(bee[i].hue, 255, 255)));
leds[XY(bee[i].aimX, bee[i].aimY - 1)] += CHSV(bee[i].hue, 255, 255); SEGMENT.addPixelColorXY(bee[i].aimX, bee[i].aimY - 1, CRGB(CHSV(bee[i].hue, 255, 255)));
if (bee[i].posX != bee[i].aimX || bee[i].posY != bee[i].aimY) { if (bee[i].posX != bee[i].aimX || bee[i].posY != bee[i].aimY) {
leds[XY(bee[i].posX, bee[i].posY)] = CHSV(bee[i].hue, 60, 255); SEGMENT.setPixelColorXY(bee[i].posX, bee[i].posY, CRGB(CHSV(bee[i].hue, 60, 255)));
int8_t error2 = bee[i].error * 2; int8_t error2 = bee[i].error * 2;
if (error2 > -bee[i].deltaY) { if (error2 > -bee[i].deltaY) {
bee[i].error -= bee[i].deltaY; bee[i].error -= bee[i].deltaY;
@ -5671,9 +5624,7 @@ uint16_t mode_2Dcrazybees(void) {
bee[i].aimed(cols, rows); bee[i].aimed(cols, rows);
} }
} }
SEGMENT.blur2d(leds, SEGMENT.intensity>>4); SEGMENT.blur(SEGMENT.intensity>>4);
SEGMENT.setPixels(leds);
} }
return FRAMETIME; return FRAMETIME;
} }
@ -5690,7 +5641,6 @@ uint16_t mode_2Dghostrider(void) {
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
typedef struct Lighter { typedef struct Lighter {
int16_t gPosX; int16_t gPosX;
@ -5705,16 +5655,16 @@ uint16_t mode_2Dghostrider(void) {
int8_t Vspeed; int8_t Vspeed;
} lighter_t; } lighter_t;
if (!SEGENV.allocateData(dataSize + sizeof(lighter_t))) return mode_static(); //allocation failed if (!SEGENV.allocateData(sizeof(lighter_t))) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); lighter_t *lighter = reinterpret_cast<lighter_t*>(SEGENV.data);
lighter_t *lighter = reinterpret_cast<lighter_t*>(SEGENV.data + dataSize);
const size_t maxLighters = min(cols + rows, LIGHTERS_AM); const size_t maxLighters = min(cols + rows, LIGHTERS_AM);
if (SEGENV.call == 0) SEGMENT.setUpLeds();
if (SEGENV.call == 0 || SEGENV.aux0 != cols || SEGENV.aux1 != rows) { if (SEGENV.call == 0 || SEGENV.aux0 != cols || SEGENV.aux1 != rows) {
SEGENV.aux0 = cols; SEGENV.aux0 = cols;
SEGENV.aux1 = rows; SEGENV.aux1 = rows;
SEGMENT.fill_solid(leds, CRGB::Black); SEGMENT.fill(BLACK);
random16_set_seed(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;
@ -5730,10 +5680,10 @@ uint16_t mode_2Dghostrider(void) {
if (millis() > SEGENV.step) { if (millis() > SEGENV.step) {
SEGENV.step = millis() + 1024 / (cols+rows); SEGENV.step = millis() + 1024 / (cols+rows);
SEGMENT.fadeToBlackBy(leds, (SEGMENT.speed>>2)+64); SEGMENT.fadeToBlackBy((SEGMENT.speed>>2)+64);
CRGB color = CRGB::White; CRGB color = CRGB::White;
SEGMENT.wu_pixel(leds, lighter->gPosX * 256 / 10, lighter->gPosY * 256 / 10, color); SEGMENT.wu_pixel(lighter->gPosX * 256 / 10, lighter->gPosY * 256 / 10, color);
lighter->gPosX += lighter->Vspeed * sin_t(radians(lighter->gAngle)); lighter->gPosX += lighter->Vspeed * sin_t(radians(lighter->gAngle));
lighter->gPosY += lighter->Vspeed * cos_t(radians(lighter->gAngle)); lighter->gPosY += lighter->Vspeed * cos_t(radians(lighter->gAngle));
@ -5761,12 +5711,11 @@ 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(SEGPALETTE, (256 - lighter->time[i]))); SEGMENT.wu_pixel(lighter->lightersPosX[i] * 256 / 10, lighter->lightersPosY[i] * 256 / 10, ColorFromPalette(SEGPALETTE, (256 - lighter->time[i])));
} }
SEGMENT.blur2d(leds, SEGMENT.intensity>>3); SEGMENT.blur(SEGMENT.intensity>>3);
} }
SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} }
static const char *_data_FX_MODE_2DGHOSTRIDER PROGMEM = "Ghost Rider@Fade rate,Blur;!,!,!;!;2d"; static const char *_data_FX_MODE_2DGHOSTRIDER PROGMEM = "Ghost Rider@Fade rate,Blur;!,!,!;!;2d";
@ -5782,7 +5731,6 @@ uint16_t mode_2Dfloatingblobs(void) {
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
typedef struct Blob { typedef struct Blob {
float x[MAX_BLOBS], y[MAX_BLOBS]; float x[MAX_BLOBS], y[MAX_BLOBS];
@ -5794,14 +5742,14 @@ uint16_t mode_2Dfloatingblobs(void) {
uint8_t Amount = (SEGMENT.intensity>>5) + 1; // NOTE: be sure to update MAX_BLOBS if you change this uint8_t Amount = (SEGMENT.intensity>>5) + 1; // NOTE: be sure to update MAX_BLOBS if you change this
if (!SEGENV.allocateData(dataSize + sizeof(blob_t))) return mode_static(); //allocation failed if (!SEGENV.allocateData(sizeof(blob_t))) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data); blob_t *blob = reinterpret_cast<blob_t*>(SEGENV.data);
blob_t *blob = reinterpret_cast<blob_t*>(SEGENV.data + dataSize);
if (SEGENV.call == 0) SEGMENT.setUpLeds();
if (SEGENV.call == 0 || SEGENV.aux0 != cols || SEGENV.aux1 != rows) { if (SEGENV.call == 0 || SEGENV.aux0 != cols || SEGENV.aux1 != rows) {
SEGENV.aux0 = cols; SEGENV.aux0 = cols;
SEGENV.aux1 = rows; SEGENV.aux1 = rows;
SEGMENT.fill_solid(leds, CRGB::Black); SEGMENT.fill(BLACK);
for (size_t i = 0; i < MAX_BLOBS; i++) { for (size_t i = 0; i < MAX_BLOBS; i++) {
blob->r[i] = cols>15 ? random8(1, cols/8.f) : 1; blob->r[i] = cols>15 ? random8(1, cols/8.f) : 1;
blob->sX[i] = (float) random8(3, cols) / (float)(256 - SEGMENT.speed); // speed x blob->sX[i] = (float) random8(3, cols) / (float)(256 - SEGMENT.speed); // speed x
@ -5815,7 +5763,7 @@ uint16_t mode_2Dfloatingblobs(void) {
} }
} }
SEGMENT.fadeToBlackBy(leds, 20); SEGMENT.fadeToBlackBy(20);
// Bounce balls around // Bounce balls around
for (size_t i = 0; i < Amount; i++) { for (size_t i = 0; i < Amount; i++) {
@ -5836,8 +5784,8 @@ uint16_t mode_2Dfloatingblobs(void) {
} }
CRGB c = ColorFromPalette(SEGPALETTE, 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(blob->y[i], blob->x[i], blob->r[i], c);
else leds[XY(blob->y[i], blob->x[i])] += c; else SEGMENT.setPixelColorXY(blob->y[i], blob->x[i], c);
// move x // move x
if (blob->x[i] + blob->r[i] >= cols - 1) blob->x[i] += (blob->sX[i] * ((cols - 1 - blob->x[i]) / blob->r[i] + 0.005f)); if (blob->x[i] + blob->r[i] >= cols - 1) blob->x[i] += (blob->sX[i] * ((cols - 1 - blob->x[i]) / blob->r[i] + 0.005f));
else if (blob->x[i] - blob->r[i] <= 0) blob->x[i] += (blob->sX[i] * (blob->x[i] / blob->r[i] + 0.005f)); else if (blob->x[i] - blob->r[i] <= 0) blob->x[i] += (blob->sX[i] * (blob->x[i] / blob->r[i] + 0.005f));
@ -5865,15 +5813,14 @@ uint16_t mode_2Dfloatingblobs(void) {
blob->y[i] = rows - 1.01f; blob->y[i] = rows - 1.01f;
} }
} }
SEGMENT.blur2d(leds, cols+rows); SEGMENT.blur(SEGMENT.custom1>>2);
if (SEGENV.step < millis()) SEGENV.step = millis() + 2000; // change colors every 2 seconds if (SEGENV.step < millis()) SEGENV.step = millis() + 2000; // change colors every 2 seconds
SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} }
#undef MAX_BLOBS #undef MAX_BLOBS
static const char *_data_FX_MODE_2DBLOBS PROGMEM = "Blobs@!,# blobs;!,!,!;!;2d"; static const char *_data_FX_MODE_2DBLOBS PROGMEM = "Blobs@!,# blobs,Blur;!,!,!;!;c1=8,2d";
//////////////////////////// ////////////////////////////
@ -5935,28 +5882,25 @@ uint16_t mode_2Ddriftrose(void) {
const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight(); const uint16_t rows = SEGMENT.virtualHeight();
const uint16_t dataSize = sizeof(CRGB) * SEGMENT.length(); // using width*height prevents reallocation if mirroring is enabled
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;
const float L = min(cols, rows) / 2.f; const float L = min(cols, rows) / 2.f;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
if (SEGENV.call == 0) { if (SEGENV.call == 0) {
SEGMENT.fill_solid(leds, CRGB::Black); SEGMENT.setUpLeds();
SEGMENT.fill(BLACK);
} }
SEGMENT.fadeToBlackBy(leds, 32+(SEGMENT.speed>>3)); SEGMENT.fadeToBlackBy(32+(SEGMENT.speed>>3));
for (size_t i = 1; i < 37; i++) { for (size_t i = 1; i < 37; i++) {
uint32_t x = (CX + (sin_t(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f; uint32_t x = (CX + (sin_t(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f;
uint32_t y = (CY + (cos_t(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f; uint32_t y = (CY + (cos_t(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f;
SEGMENT.wu_pixel(leds, x, y, CHSV(i * 10, 255, 255)); SEGMENT.wu_pixel(x, y, CHSV(i * 10, 255, 255));
} }
SEGMENT.blur2d(leds, (SEGMENT.intensity>>4)+1); SEGMENT.blur((SEGMENT.intensity>>4)+1);
SEGMENT.setPixels(leds);
return FRAMETIME; return FRAMETIME;
} }
static const char *_data_FX_MODE_2DDRIFTROSE PROGMEM = "Drift Rose@Fade,Blur;;;2d"; static const char *_data_FX_MODE_2DDRIFTROSE PROGMEM = "Drift Rose@Fade,Blur;;;2d";

View File

@ -104,6 +104,8 @@
#define ORANGE (uint32_t)0xFF3000 #define ORANGE (uint32_t)0xFF3000
#define PINK (uint32_t)0xFF1493 #define PINK (uint32_t)0xFF1493
#define ULTRAWHITE (uint32_t)0xFFFFFFFF #define ULTRAWHITE (uint32_t)0xFFFFFFFF
#define DARKSLATEGRAY (uint32_t)0x2F4F4F
#define DARKSLATEGREY (uint32_t)0x2F4F4F
// options // options
// bit 7: segment is in transition mode // bit 7: segment is in transition mode
@ -551,15 +553,19 @@ typedef struct Segment {
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
void setPixelColor(float i, uint32_t c, bool aa = true); void setPixelColor(float i, uint32_t c, bool aa = true);
void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); } void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); }
void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, c.red, c.green, c.blue, 0, aa); } void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, c.red, c.green, c.blue, 0, aa); }
uint32_t getPixelColor(uint16_t i); uint32_t getPixelColor(uint16_t i);
// 1D support functions (some implement 2D as well) // 1D support functions (some implement 2D as well)
void blur(uint8_t); void blur(uint8_t);
void fill(uint32_t c); void fill(uint32_t c);
void fade_out(uint8_t r); void fade_out(uint8_t r);
void fadeToBlackBy(uint8_t fadeBy); void fadeToBlackBy(uint8_t fadeBy);
void blendPixelColor(uint16_t n, uint32_t color, uint8_t blend); void blendPixelColor(int n, uint32_t color, uint8_t blend);
void addPixelColor(uint16_t n, uint32_t color); void blendPixelColor(int n, CRGB c, uint8_t blend) { blendPixelColor(n, RGBW32(c.red, c.green, c.blue, 0), blend); }
void addPixelColor(int n, uint32_t color);
void addPixelColor(int n, byte r, byte g, byte b, byte w = 0) { addPixelColor(n, RGBW32(r,g,b,w)); } // automatically inline
void addPixelColor(int n, CRGB c) { addPixelColor(n, RGBW32(c.red, c.green, c.blue, 0)); } // automatically inline
void fadePixelColor(uint16_t n, uint8_t fade);
uint8_t get_random_wheel_index(uint8_t pos); uint8_t get_random_wheel_index(uint8_t pos);
uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255); uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255);
uint32_t color_wheel(uint8_t pos); uint32_t color_wheel(uint8_t pos);
@ -570,30 +576,34 @@ typedef struct Segment {
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
void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, c.red, c.green, c.blue); } // automatically inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.red, c.green, c.blue, 0)); } // automatically inline
void setPixelColorXY(float x, float y, uint32_t c, bool aa = true); void setPixelColorXY(float x, float y, uint32_t c, bool aa = true);
void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); } void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); }
void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, c.red, c.green, c.blue, 0, aa); } void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, c.red, c.green, c.blue, 0, aa); }
uint32_t getPixelColorXY(uint16_t x, uint16_t y); uint32_t getPixelColorXY(uint16_t x, uint16_t y);
// 2D support functions // 2D support functions
void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend); void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend);
void addPixelColorXY(uint16_t x, uint16_t y, uint32_t color); void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.red, c.green, c.blue,0), blend); }
void addPixelColorXY(int x, int y, uint32_t color);
void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { addPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline
void addPixelColorXY(int x, int y, CRGB c) { addPixelColorXY(x, y, RGBW32(c.red, c.green, c.blue,0)); }
void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade);
void box_blur(uint16_t i, bool vertical, fract8 blur_amount); // 1D box blur (with weight)
void blur1d(CRGB* leds, fract8 blur_amount); void blur1d(CRGB* leds, fract8 blur_amount);
void blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds=nullptr); // 1D box blur (with weight)
void blur2d(CRGB* leds, fract8 blur_amount); void blur2d(CRGB* leds, fract8 blur_amount);
void blurRow(uint16_t row, fract8 blur_amount, CRGB* leds=nullptr); void blurRow(uint16_t row, fract8 blur_amount, CRGB* leds=nullptr);
void blurCol(uint16_t col, fract8 blur_amount, CRGB* leds=nullptr); void blurCol(uint16_t col, fract8 blur_amount, CRGB* leds=nullptr);
void moveX(CRGB *leds, int8_t delta); void moveX(int8_t delta);
void moveY(CRGB *leds, int8_t delta); void moveY(int8_t delta);
void move(uint8_t dir, uint8_t delta, CRGB *leds=nullptr); void move(uint8_t dir, uint8_t delta);
void fill_solid(CRGB* leds, CRGB c); void fill_solid(CRGB* leds, CRGB c);
void fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB c); void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c);
void fadeToBlackBy(CRGB* leds, uint8_t fadeBy); void fadeToBlackBy(CRGB* leds, uint8_t fadeBy);
void nscale8(CRGB* leds, uint8_t scale); void nscale8(CRGB* leds, uint8_t scale);
void setPixels(CRGB* leds); void setPixels(CRGB* leds);
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds = nullptr); void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c);
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color, CRGB *leds = nullptr); void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color, CRGB *leds = nullptr);
void wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c); void wu_pixel(uint32_t x, uint32_t y, CRGB c);
inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) { drawLine(x0, y0, x1, y1, CRGB(byte(c>>16), byte(c>>8), byte(c))); } inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) { drawLine(x0, y0, x1, y1, CRGB(byte(c>>16), byte(c>>8), byte(c))); }
inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t c) { drawCharacter(chr, x, y, w, h, CRGB(byte(c>>16), byte(c>>8), byte(c))); } inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t c) { drawCharacter(chr, x, y, w, h, CRGB(byte(c>>16), byte(c>>8), byte(c))); }
} segment; } segment;

View File

@ -256,7 +256,7 @@ uint32_t Segment::getPixelColorXY(uint16_t x, uint16_t y) {
if (x >= width() || y >= height()) return 0; if (x >= width() || y >= height()) return 0;
return strip.getPixelColorXY(start + x, startY + y); return strip.getPixelColorXY(start + x, startY + y);
#else #else
return 0; return getPixelColor(x);
#endif #endif
} }
@ -264,13 +264,26 @@ uint32_t Segment::getPixelColorXY(uint16_t x, uint16_t y) {
void Segment::blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { void Segment::blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) {
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend)); setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend));
#else
setPixelColor(x, color_blend(getPixelColor(x), color, blend));
#endif #endif
} }
// Adds the specified color with the existing pixel color perserving color balance. // Adds the specified color with the existing pixel color perserving color balance.
void Segment::addPixelColorXY(uint16_t x, uint16_t y, uint32_t color) { void Segment::addPixelColorXY(int x, int y, uint32_t color) {
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
setPixelColorXY(x, y, color_add(getPixelColorXY(x,y), color)); setPixelColorXY(x, y, color_add(getPixelColorXY(x,y), color));
#else
setPixelColor(x, color_add(getPixelColor(x), color));
#endif
}
void Segment::fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) {
#ifndef WLED_DISABLE_2D
CRGB pix = CRGB(getPixelColorXY(x,y)).nscale8_video(fade);
setPixelColor(x, y, pix);
#else
setPixelColor(x, CRGB(getPixelColor(x)).nscale8_video(fade));
#endif #endif
} }
@ -354,7 +367,7 @@ void Segment::blur1d(CRGB* leds, fract8 blur_amount) {
} }
// 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 Segment::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds) { void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) {
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
const uint16_t cols = virtualWidth(); const uint16_t cols = virtualWidth();
const uint16_t rows = virtualHeight(); const uint16_t rows = virtualHeight();
@ -372,9 +385,9 @@ void Segment::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds)
uint16_t yp = vertical ? y-1 : y; uint16_t yp = vertical ? y-1 : y;
uint16_t xn = vertical ? x : x+1; uint16_t xn = vertical ? x : x+1;
uint16_t yn = vertical ? y+1 : y; uint16_t yn = vertical ? y+1 : y;
CRGB curr = leds ? leds[XY(x,y)] : CRGB(getPixelColorXY(x,y)); CRGB curr = getPixelColorXY(x,y);
CRGB prev = (xp<0 || yp<0) ? CRGB::Black : (leds ? leds[XY(xp,yp)] : CRGB(getPixelColorXY(xp,yp))); CRGB prev = (xp<0 || yp<0) ? CRGB::Black : getPixelColorXY(xp,yp);
CRGB next = ((vertical && yn>=dim1) || (!vertical && xn>=dim1)) ? CRGB::Black : (leds ? leds[XY(xn,yn)] : CRGB(getPixelColorXY(xn,yn))); CRGB next = ((vertical && yn>=dim1) || (!vertical && xn>=dim1)) ? CRGB::Black : getPixelColorXY(xn,yn);
uint16_t r, g, b; uint16_t r, g, b;
r = (curr.r*keep + (prev.r + next.r)*seep) / 3; r = (curr.r*keep + (prev.r + next.r)*seep) / 3;
g = (curr.g*keep + (prev.g + next.g)*seep) / 3; g = (curr.g*keep + (prev.g + next.g)*seep) / 3;
@ -384,8 +397,7 @@ void Segment::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds)
for (uint16_t j = 0; j < dim1; j++) { for (uint16_t j = 0; j < dim1; j++) {
uint16_t x = vertical ? i : j; uint16_t x = vertical ? i : j;
uint16_t y = vertical ? j : i; uint16_t y = vertical ? j : i;
if (leds) leds[XY(x,y)] = tmp[j]; setPixelColorXY(x, y, tmp[j]);
else setPixelColorXY(x, y, tmp[j]);
} }
#endif #endif
} }
@ -399,7 +411,7 @@ void Segment::blur2d(CRGB* leds, fract8 blur_amount) {
#endif #endif
} }
void Segment::moveX(CRGB *leds, int8_t delta) { void Segment::moveX(int8_t delta) {
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
const uint16_t cols = virtualWidth(); const uint16_t cols = virtualWidth();
const uint16_t rows = virtualHeight(); const uint16_t rows = virtualHeight();
@ -407,20 +419,18 @@ void Segment::moveX(CRGB *leds, int8_t delta) {
if (delta > 0) { if (delta > 0) {
for (uint8_t y = 0; y < rows; y++) for (uint8_t x = 0; x < cols-1; x++) { for (uint8_t y = 0; y < rows; y++) for (uint8_t x = 0; x < cols-1; x++) {
if (x + delta >= cols) break; if (x + delta >= cols) break;
if (leds) leds[XY(x, y)] = leds[XY((x + delta)%cols, y)]; setPixelColorXY(x, y, getPixelColorXY((x + delta)%cols, y));
else setPixelColorXY(x, y, getPixelColorXY((x + delta)%cols, y));
} }
} else { } else {
for (uint8_t y = 0; y < rows; y++) for (int16_t x = cols-1; x >= 0; x--) { for (uint8_t y = 0; y < rows; y++) for (int16_t x = cols-1; x >= 0; x--) {
if (x + delta < 0) break; if (x + delta < 0) break;
if (leds) leds[XY(x, y)] = leds[XY(x + delta, y)]; setPixelColorXY(x, y, getPixelColorXY(x + delta, y));
else setPixelColorXY(x, y, getPixelColorXY(x + delta, y));
} }
} }
#endif #endif
} }
void Segment::moveY(CRGB *leds, int8_t delta) { void Segment::moveY(int8_t delta) {
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
const uint16_t cols = virtualWidth(); const uint16_t cols = virtualWidth();
const uint16_t rows = virtualHeight(); const uint16_t rows = virtualHeight();
@ -428,14 +438,12 @@ void Segment::moveY(CRGB *leds, int8_t delta) {
if (delta > 0) { if (delta > 0) {
for (uint8_t x = 0; x < cols; x++) for (uint8_t y = 0; y < rows-1; y++) { for (uint8_t x = 0; x < cols; x++) for (uint8_t y = 0; y < rows-1; y++) {
if (y + delta >= rows) break; if (y + delta >= rows) break;
if (leds) leds[XY(x, y)] = leds[XY(x, (y + delta))]; setPixelColorXY(x, y, getPixelColorXY(x, (y + delta)));
else setPixelColorXY(x, y, getPixelColorXY(x, (y + delta)));
} }
} else { } else {
for (uint8_t x = 0; x < cols; x++) for (int16_t y = rows-1; y >= 0; y--) { for (uint8_t x = 0; x < cols; x++) for (int16_t y = rows-1; y >= 0; y--) {
if (y + delta < 0) break; if (y + delta < 0) break;
if (leds) leds[XY(x, y)] = leds[XY(x, y + delta)]; setPixelColorXY(x, y, getPixelColorXY(x, y + delta));
else setPixelColorXY(x, y, getPixelColorXY(x, y + delta));
} }
} }
#endif #endif
@ -444,18 +452,18 @@ void Segment::moveY(CRGB *leds, int8_t delta) {
// move() - move all pixels in desired direction delta number of pixels // 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 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 // @param delta number of pixels to move
void Segment::move(uint8_t dir, uint8_t delta, CRGB *leds) { void Segment::move(uint8_t dir, uint8_t delta) {
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
if (delta==0) return; if (delta==0) return;
switch (dir) { switch (dir) {
case 0: moveX(leds, delta); break; case 0: moveX( delta); break;
case 1: moveX(leds, delta); moveY(leds, delta); break; case 1: moveX( delta); moveY( delta); break;
case 2: moveY(leds, delta); break; case 2: moveY( delta); break;
case 3: moveX(leds,-delta); moveY(leds, delta); break; case 3: moveX(-delta); moveY( delta); break;
case 4: moveX(leds,-delta); break; case 4: moveX(-delta); break;
case 5: moveX(leds,-delta); moveY(leds,-delta); break; case 5: moveX(-delta); moveY(-delta); break;
case 6: moveY(leds,-delta); break; case 6: moveY(-delta); break;
case 7: moveX(leds, delta); moveY(leds,-delta); break; case 7: moveX( delta); moveY(-delta); break;
} }
#endif #endif
} }
@ -470,7 +478,7 @@ void Segment::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 Segment::fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) { void Segment::fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
const uint16_t cols = virtualWidth(); const uint16_t cols = virtualWidth();
const uint16_t rows = virtualHeight(); const uint16_t rows = virtualHeight();
@ -479,7 +487,7 @@ void Segment::fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius,
if (x * x + y * y <= radius * radius && if (x * x + y * y <= radius * radius &&
int16_t(cx)+x>=0 && int16_t(cy)+y>=0 && int16_t(cx)+x>=0 && int16_t(cy)+y>=0 &&
int16_t(cx)+x<cols && int16_t(cy)+y<rows) int16_t(cx)+x<cols && int16_t(cy)+y<rows)
leds[XY(cx + x, cy + y)] += col; setPixelColorXY(cx + x, cy + y, col);
} }
} }
#endif #endif
@ -511,7 +519,7 @@ void Segment::setPixels(CRGB* leds) {
} }
//line function //line function
void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds) { void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) {
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
const uint16_t cols = virtualWidth(); const uint16_t cols = virtualWidth();
const uint16_t rows = virtualHeight(); const uint16_t rows = virtualHeight();
@ -520,8 +528,7 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB
const int16_t dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; const int16_t dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
int16_t err = (dx>dy ? dx : -dy)/2, e2; int16_t err = (dx>dy ? dx : -dy)/2, e2;
for (;;) { for (;;) {
if (leds == nullptr) setPixelColorXY(x0,y0,c); setPixelColorXY(x0,y0,c);
else leds[XY(x0,y0)] = c;
if (x0==x1 && y0==y1) break; if (x0==x1 && y0==y1) break;
e2 = err; e2 = err;
if (e2 >-dx) { err -= dy; x0 += sx; } if (e2 >-dx) { err -= dy; x0 += sx; }
@ -6712,7 +6719,7 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w,
} }
#define WU_WEIGHT(a,b) ((uint8_t) (((a)*(b)+(a)+(b))>>8)) #define WU_WEIGHT(a,b) ((uint8_t) (((a)*(b)+(a)+(b))>>8))
void Segment::wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c) { //awesome wu_pixel procedure by reddit u/sutaburosu void Segment::wu_pixel(uint32_t x, uint32_t y, CRGB c) { //awesome wu_pixel procedure by reddit u/sutaburosu
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
// extract the fractional parts and derive their inverses // extract the fractional parts and derive their inverses
uint8_t xx = x & 0xff, yy = y & 0xff, ix = 255 - xx, iy = 255 - yy; uint8_t xx = x & 0xff, yy = y & 0xff, ix = 255 - xx, iy = 255 - yy;
@ -6721,10 +6728,11 @@ void Segment::wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c) { //awes
WU_WEIGHT(ix, yy), WU_WEIGHT(xx, yy)}; WU_WEIGHT(ix, yy), WU_WEIGHT(xx, yy)};
// multiply the intensities by the colour, and saturating-add them to the pixels // multiply the intensities by the colour, and saturating-add them to the pixels
for (uint8_t i = 0; i < 4; i++) { for (uint8_t i = 0; i < 4; i++) {
uint16_t xy = XY((x >> 8) + (i & 1), (y >> 8) + ((i >> 1) & 1)); CRGB led = getPixelColorXY((x >> 8) + (i & 1), (y >> 8) + ((i >> 1) & 1));
leds[xy].r = qadd8(leds[xy].r, c.r * wu[i] >> 8); led.r = qadd8(led.r, c.r * wu[i] >> 8);
leds[xy].g = qadd8(leds[xy].g, c.g * wu[i] >> 8); led.g = qadd8(led.g, c.g * wu[i] >> 8);
leds[xy].b = qadd8(leds[xy].b, c.b * wu[i] >> 8); led.b = qadd8(led.b, c.b * wu[i] >> 8);
setPixelColorXY(int((x >> 8) + (i & 1)), int((y >> 8) + ((i >> 1) & 1)), led);
} }
#endif #endif
} }

View File

@ -190,6 +190,7 @@ void Segment::deallocateData() {
void Segment::resetIfRequired() { void Segment::resetIfRequired() {
if (reset) { // (getOption(SEG_OPTION_RESET)) if (reset) { // (getOption(SEG_OPTION_RESET))
if (leds) { free(leds); leds = nullptr; DEBUG_PRINTLN(F("Freeing leds.")); } if (leds) { free(leds); leds = nullptr; DEBUG_PRINTLN(F("Freeing leds.")); }
if (_t) _t->_dur = 0;
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
reset = false; // setOption(SEG_OPTION_RESET, false); reset = false; // setOption(SEG_OPTION_RESET, false);
} }
@ -621,15 +622,20 @@ void Segment::fill(uint32_t c) {
} }
// Blends the specified color with the existing pixel color. // Blends the specified color with the existing pixel color.
void Segment::blendPixelColor(uint16_t n, uint32_t color, uint8_t blend) { void Segment::blendPixelColor(int n, uint32_t color, uint8_t blend) {
setPixelColor(n, color_blend(getPixelColor(n), color, blend)); setPixelColor(n, color_blend(getPixelColor(n), color, blend));
} }
// Adds the specified color with the existing pixel color perserving color balance. // Adds the specified color with the existing pixel color perserving color balance.
void Segment::addPixelColor(uint16_t n, uint32_t color) { void Segment::addPixelColor(int n, uint32_t color) {
setPixelColor(n, color_add(getPixelColor(n), color)); setPixelColor(n, color_add(getPixelColor(n), color));
} }
void Segment::fadePixelColor(uint16_t n, uint8_t fade) {
CRGB pix = CRGB(getPixelColor(n)).nscale8_video(fade);
setPixelColor(n, pix);
}
/* /*
* fade out function, higher rate = quicker fade * fade out function, higher rate = quicker fade
*/ */

View File

@ -1151,9 +1151,9 @@ function updateSelectedFx()
var selectedName = selectedEffect.querySelector(".lstIname").innerText; var selectedName = selectedEffect.querySelector(".lstIname").innerText;
var segs = gId("segcont").querySelectorAll(`div[data-map="map2D"]`); var segs = gId("segcont").querySelectorAll(`div[data-map="map2D"]`);
for (const seg of segs) if (selectedName.indexOf("2D ")<0) seg.classList.remove("hide"); else seg.classList.add("hide"); for (const seg of segs) if (selectedName.indexOf("\u25A6")<0) seg.classList.remove("hide"); else seg.classList.add("hide");
var segs = gId("segcont").querySelectorAll(`div[data-snd="ssim"]`); var segs = gId("segcont").querySelectorAll(`div[data-snd="ssim"]`);
for (const seg of segs) if (selectedName.indexOf("")<0 && selectedName.indexOf("")<0) seg.classList.add("hide"); else seg.classList.remove("hide"); // also "♫ "? for (const seg of segs) if (selectedName.indexOf("\u266A")<0 && selectedName.indexOf("\266B")<0) seg.classList.add("hide"); else seg.classList.remove("hide"); // also "♫ "?
} }
} }

File diff suppressed because it is too large Load Diff