API change.
New SR effects. Bugfixes.
This commit is contained in:
parent
adb7726974
commit
c9bdecdb69
392
wled00/FX.cpp
392
wled00/FX.cpp
@ -1102,6 +1102,7 @@ uint16_t WS2812FX::mode_comet(void) {
|
||||
*/
|
||||
uint16_t WS2812FX::mode_fireworks() {
|
||||
fade_out(0);
|
||||
|
||||
if (SEGENV.call == 0) {
|
||||
SEGENV.aux0 = UINT16_MAX;
|
||||
SEGENV.aux1 = UINT16_MAX;
|
||||
@ -1857,13 +1858,6 @@ uint16_t WS2812FX::mode_fire_2012()
|
||||
|
||||
byte* heat = SEGENV.data;
|
||||
|
||||
if (SEGENV.call == 0) {
|
||||
DEBUG_PRINTLN(nFlames);
|
||||
DEBUG_PRINTLN(SEGLEN);
|
||||
DEBUG_PRINTLN(nFlames*SEGLEN);
|
||||
DEBUG_PRINTLN(q);
|
||||
}
|
||||
|
||||
if (it != SEGENV.step) {
|
||||
SEGENV.step = it;
|
||||
uint8_t ignition = max(3,SEGLEN/10); // ignition area: 10% of segment length or minimum 3 pixels
|
||||
@ -4248,8 +4242,8 @@ uint16_t WS2812FX::mode_aurora(void) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//*************************** 2D routines ***********************************
|
||||
|
||||
// sample 2D routine
|
||||
uint16_t WS2812FX::mode_2DBlackHole_A() { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline
|
||||
// Black hole
|
||||
uint16_t WS2812FX::mode_2DBlackHole(void) { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline
|
||||
uint16_t w = SEGMENT.virtualWidth();
|
||||
uint16_t h = SEGMENT.virtualHeight();
|
||||
uint16_t dataSize = sizeof(CRGB) * w * h;
|
||||
@ -4262,24 +4256,24 @@ uint16_t WS2812FX::mode_2DBlackHole_A() { // By: Stepko https://edito
|
||||
// initialize on first call
|
||||
if (SEGENV.call == 0) {
|
||||
for (y = 0; y < h; y++) for (x = 0; x < w; x++) {
|
||||
leds[x + y * w] = CRGB::Black;
|
||||
leds[XY(x,y)] = CRGB::Black;
|
||||
}
|
||||
}
|
||||
|
||||
fadeToBlackBy(32, leds); // create fading trails
|
||||
fadeToBlackBy(leds, 32); // create fading trails
|
||||
float t = (float)(millis())/128;
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
x = beatsin8(SEGMENT.c1x>>3, 0, w - 1, 0, ((i % 2) ? 128 : 0) + t * i);
|
||||
y = beatsin8(10 , 0, h - 1, 0, ((i % 2) ? 192 : 64) + t * i);
|
||||
leds[x + y * w] += CHSV(i*32, 255, 255);
|
||||
leds[XY(x,y)] += CHSV(i*32, 255, 255);
|
||||
}
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
x = beatsin8(SEGMENT.c2x>>3, w/4, w - 1 - w/4, 0, ((i % 2) ? 128 : 0) + t * i);
|
||||
y = beatsin8(SEGMENT.c3x>>3, h/4, h - 1 - h/4, 0, ((i % 2) ? 192 : 64) + t * i);
|
||||
leds[x + y * w] += CHSV(i*32, 255, 255);
|
||||
leds[XY(x,y)] += CHSV(i*32, 255, 255);
|
||||
}
|
||||
leds[w/2 * (1 + h)] = CHSV(0,0,255);
|
||||
blur2d(16, leds);
|
||||
leds[XY(w/2,h/2)] = CHSV(0,0,255);
|
||||
blur2d(leds, 16);
|
||||
|
||||
for (y = 0; y < h; y++) for (x = 0; x < w; x++) {
|
||||
uint16_t o = x + y * w;
|
||||
@ -4288,26 +4282,356 @@ uint16_t WS2812FX::mode_2DBlackHole_A() { // By: Stepko https://edito
|
||||
return FRAMETIME;
|
||||
} // mode_2DBlackHole()
|
||||
|
||||
// same as above not using leds[]
|
||||
uint16_t WS2812FX::mode_2DBlackHole_B() { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline
|
||||
uint16_t w = SEGMENT.virtualWidth();
|
||||
uint16_t h = SEGMENT.virtualHeight();
|
||||
uint16_t x, y;
|
||||
/////////////////////
|
||||
// 2D DNA //
|
||||
/////////////////////
|
||||
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 width = SEGMENT.virtualWidth();
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
uint16_t dataSize = sizeof(CRGB) * width * height;
|
||||
|
||||
fade_out2D(32); // create fading trails
|
||||
float t = (float)(millis())/128;
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
x = beatsin8(SEGMENT.c1x>>3, 0, w - 1, 0, ((i % 2) ? 128 : 0) + t * i);
|
||||
y = beatsin8(10 , 0, h - 1, 0, ((i % 2) ? 192 : 64) + t * i);
|
||||
setPixelColorXY(x, y, col_to_crgb(getPixelColorXY(x,y)) + CHSV(i*32, 255, 255));
|
||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
|
||||
|
||||
fadeToBlackBy(leds, 64);
|
||||
|
||||
for(int i = 0; i < width; i++) { // change to height if you want to re-orient, and swap the 4 lines below.
|
||||
leds[XY(i, beatsin8(SEGMENT.speed/8, 0, height-1, 0, i*4))] = ColorFromPalette(currentPalette, i*5+millis()/17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND);
|
||||
leds[XY(i, beatsin8(SEGMENT.speed/8, 0, height-1, 0, i*4+128))] = ColorFromPalette(currentPalette,i*5+128+millis()/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND); // 180 degrees (128) out of phase
|
||||
}
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
x = beatsin8(SEGMENT.c2x>>3, w/4, w - 1 - w/4, 0, ((i % 2) ? 128 : 0) + t * i);
|
||||
y = beatsin8(SEGMENT.c3x>>3, h/4, h - 1 - h/4, 0, ((i % 2) ? 192 : 64) + t * i);
|
||||
setPixelColorXY(x, y, col_to_crgb(getPixelColorXY(x,y)) + CHSV(i*32, 255, 255));
|
||||
}
|
||||
setPixelColorXY(w/2, h/2, WHITE);
|
||||
//blur2d(16);
|
||||
|
||||
blur2d(leds, SEGMENT.intensity/8);
|
||||
|
||||
setPixels(leds);
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_2DBlackHole()
|
||||
} // mode_2Ddna()
|
||||
|
||||
/////////////////////////
|
||||
// 2D DNA Spiral //
|
||||
/////////////////////////
|
||||
uint16_t WS2812FX::mode_2DDNASpiral() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , modified by: Andrew Tuline
|
||||
uint16_t width = SEGMENT.virtualWidth();
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
uint16_t dataSize = sizeof(CRGB) * width * height;
|
||||
|
||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
|
||||
|
||||
uint8_t speeds = SEGMENT.speed/2;
|
||||
uint8_t freq = SEGMENT.intensity/8;
|
||||
|
||||
static byte hue = 0;
|
||||
uint32_t ms = millis() / 20;
|
||||
nscale8(leds, 120);
|
||||
|
||||
for (uint16_t i = 0; i < height; i++) {
|
||||
uint16_t x = beatsin8(speeds, 0, width - 1, 0, i * freq) + beatsin8(speeds - 7, 0, width - 1, 0, i * freq + 128);
|
||||
uint16_t x1 = beatsin8(speeds, 0, width - 1, 0, 128 + i * freq) + beatsin8(speeds - 7, 0, width - 1, 0, 128 + 64 + i * freq);
|
||||
hue = i * 128 / width + ms; //ewowi20210629: not width - 1 to avoid crash if width = 1
|
||||
if ((i + ms / 8) & 3) {
|
||||
x = x / 2; x1 = x1 / 2;
|
||||
byte steps = abs8(x - x1) + 1;
|
||||
for (byte k = 1; k <= steps; k++) {
|
||||
byte dx = lerp8by8(x, x1, k * 255 / steps);
|
||||
uint16_t index = XY(dx, i);
|
||||
leds[index] += ColorFromPalette(currentPalette, hue, 255, LINEARBLEND);
|
||||
leds[index] %= (k * 255 / steps); //for draw gradient line
|
||||
}
|
||||
leds[XY(x, i)] += CRGB::DarkSlateGray;
|
||||
leds[XY(x1, i)] += CRGB::White;
|
||||
}
|
||||
}
|
||||
|
||||
setPixels(leds); // Use this ONLY if we're going to display via leds[x] method.
|
||||
return FRAMETIME;
|
||||
} // mode_2DDNASpiral()
|
||||
|
||||
/////////////////////////
|
||||
// 2D Drift //
|
||||
/////////////////////////
|
||||
uint16_t WS2812FX::mode_2DDrift() { // By: Stepko https://editor.soulmatelights.com/gallery/884-drift , Modified by: Andrew Tuline
|
||||
uint16_t width = SEGMENT.virtualWidth();
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
uint16_t dataSize = sizeof(CRGB) * width * height;
|
||||
|
||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
|
||||
|
||||
#define CenterX ((width / 2) - 0.5)
|
||||
#define CenterY ((height / 2) - 0.5)
|
||||
const byte maxDim = max(width, height);
|
||||
fadeToBlackBy(leds, 128);
|
||||
unsigned long t = millis() / (32 - SEGMENT.speed/8);
|
||||
for (float i = 1; i < maxDim / 2; i += 0.25) {
|
||||
float angle = radians(t * (maxDim / 2 - i));
|
||||
uint16_t myX = (uint16_t)(CenterX + sin_t(angle) * i);
|
||||
uint16_t myY = (uint16_t)(CenterY + cos_t(angle) * i);
|
||||
leds[XY( myX, myY)] += ColorFromPalette(currentPalette, (i * 20) + (t / 20), 255, LINEARBLEND);
|
||||
}
|
||||
blur2d(leds, SEGMENT.intensity/8);
|
||||
|
||||
setPixels(leds); // Use this ONLY if we're going to display via leds[x] method.
|
||||
return FRAMETIME;
|
||||
} // mode_2DDrift()
|
||||
|
||||
//////////////////////////
|
||||
// 2D Firenoise //
|
||||
//////////////////////////
|
||||
uint16_t WS2812FX::mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline. Yet another short routine.
|
||||
uint16_t width = SEGMENT.virtualWidth();
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
uint16_t dataSize = sizeof(CRGB) * width * height;
|
||||
|
||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
|
||||
|
||||
uint16_t xscale = SEGMENT.intensity*4;
|
||||
uint32_t yscale = SEGMENT.speed*8;
|
||||
uint8_t indexx = 0;
|
||||
|
||||
currentPalette = 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::DarkOrange,CRGB::DarkOrange, CRGB::Orange, CRGB::Orange,
|
||||
CRGB::Yellow, CRGB::Orange, CRGB::Yellow, CRGB::Yellow);
|
||||
|
||||
for (uint16_t j=0; j < width; j++) {
|
||||
for (uint16_t i=0; i < height; i++) {
|
||||
indexx = inoise8(j*yscale*height/255, i*xscale+millis()/4); // We're moving along our Perlin map.
|
||||
leds[XY(j,i)] = ColorFromPalette(currentPalette, min(i*(indexx)>>4, 255), i*255/width, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
|
||||
} // for i
|
||||
} // for j
|
||||
|
||||
setPixels(leds);
|
||||
return FRAMETIME;
|
||||
} // mode_2Dfirenoise()
|
||||
|
||||
//////////////////////////////
|
||||
// 2D Frizzles //
|
||||
//////////////////////////////
|
||||
uint16_t WS2812FX::mode_2DFrizzles(void) { // By: Stepko https://editor.soulmatelights.com/gallery/640-color-frizzles , Modified by: Andrew Tuline
|
||||
uint16_t width = SEGMENT.virtualWidth();
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
uint16_t dataSize = sizeof(CRGB) * width * height;
|
||||
|
||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
|
||||
|
||||
fadeToBlackBy(leds, 16);
|
||||
for (byte i = 8; i > 0; i--) {
|
||||
leds[XY(beatsin8(SEGMENT.speed/8 + i, 0, width - 1), beatsin8(SEGMENT.intensity/8 - i, 0, height - 1))] += ColorFromPalette(currentPalette, beatsin8(12, 0, 255), 255, LINEARBLEND);
|
||||
}
|
||||
blur2d(leds, 16);
|
||||
|
||||
setPixels(leds);
|
||||
return FRAMETIME;
|
||||
} // mode_2DFrizzles()
|
||||
|
||||
///////////////////////////////////////////
|
||||
// 2D Cellular Automata Game of life //
|
||||
///////////////////////////////////////////
|
||||
|
||||
/////////////////////////
|
||||
// 2D Hiphotic //
|
||||
/////////////////////////
|
||||
uint16_t WS2812FX::mode_2DHiphotic() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , Modified by: Andrew Tuline
|
||||
uint16_t width = SEGMENT.virtualWidth();
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
uint16_t dataSize = sizeof(CRGB) * width * height;
|
||||
|
||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
|
||||
|
||||
uint32_t a = millis() / 8;
|
||||
|
||||
for (uint16_t x = 0; x < width; x++) {
|
||||
for (uint16_t y = 0; y < height; y++) {
|
||||
leds[XY(x,y)] = ColorFromPalette(currentPalette, sin8(cos8(x * SEGMENT.speed/16 + a / 3) + sin8(y * SEGMENT.intensity/16 + a / 4) + a), 255, LINEARBLEND);
|
||||
}
|
||||
}
|
||||
|
||||
setPixels(leds); // Use this ONLY if we're going to display via leds[x] method.
|
||||
return FRAMETIME;
|
||||
} // mode_2DHiphotic()
|
||||
|
||||
/////////////////////////
|
||||
// 2D Julia //
|
||||
/////////////////////////
|
||||
|
||||
//////////////////////////////
|
||||
// 2D Lissajous //
|
||||
//////////////////////////////
|
||||
uint16_t WS2812FX::mode_2DLissajous(void) { // By: Andrew Tuline
|
||||
uint16_t width = SEGMENT.virtualWidth();
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
uint16_t dataSize = sizeof(CRGB) * width * height;
|
||||
|
||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
|
||||
|
||||
fadeToBlackBy(leds, SEGMENT.intensity);
|
||||
|
||||
for (int i=0; i < 256; i ++) {
|
||||
|
||||
uint8_t xlocn = sin8(millis()/2+i*SEGMENT.speed/64);
|
||||
uint8_t ylocn = cos8(millis()/2+i*128/64);
|
||||
|
||||
xlocn = map(xlocn,0,255,0,width-1);
|
||||
ylocn = map(ylocn,0,255,0,height-1);
|
||||
leds[XY(xlocn,ylocn)] = ColorFromPalette(currentPalette, millis()/100+i, 255, LINEARBLEND);
|
||||
}
|
||||
|
||||
setPixels(leds);
|
||||
return FRAMETIME;
|
||||
} // mode_2DLissajous()
|
||||
|
||||
|
||||
///////////////////////
|
||||
// 2D Matrix //
|
||||
///////////////////////
|
||||
uint16_t WS2812FX::mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi.
|
||||
uint16_t width = SEGMENT.virtualWidth();
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
uint16_t dataSize = sizeof(CRGB) * width * height;
|
||||
|
||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||
CRGB *leds = reinterpret_cast<CRGB*>(SEGENV.data);
|
||||
|
||||
if (SEGENV.call == 0) fill_solid(leds, 0);
|
||||
|
||||
uint8_t fade = map(SEGMENT.c1x, 0, 255, 50, 250); // equals trail size
|
||||
uint8_t speed = (256-SEGMENT.speed) >> map(MIN(height, 150), 0, 150, 0, 3); // slower speeds for small displays
|
||||
|
||||
CRGB spawnColor;
|
||||
CRGB trailColor;
|
||||
if (SEGMENT.c2x > 128) {
|
||||
spawnColor = SEGCOLOR(0);
|
||||
trailColor = SEGCOLOR(1);
|
||||
} else {
|
||||
spawnColor = CRGB(175,255,175);
|
||||
trailColor = CRGB(27,130,39);
|
||||
}
|
||||
|
||||
if (millis() - SEGENV.step >= speed) {
|
||||
SEGENV.step = millis();
|
||||
for (int16_t row=height-1; row>=0; row--) {
|
||||
for (int16_t col=0; col<width; col++) {
|
||||
if (leds[XY(col, row)] == spawnColor) {
|
||||
leds[XY(col, row)] = trailColor; // create trail
|
||||
if (row < height-1) leds[XY(col, row+1)] = spawnColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fade all leds
|
||||
for (int x=0; x<width; x++) for (int y=0; y<height; y++) {
|
||||
if (leds[XY(x,y)] != spawnColor) leds[XY(x,y)].nscale8(fade); // only fade trail
|
||||
}
|
||||
|
||||
// check for empty screen to ensure code spawn
|
||||
bool emptyScreen = true;
|
||||
for (uint16_t x=0; x<width; x++) for (uint16_t y=0; y<height; y++) {
|
||||
if (leds[XY(x,y)]) {
|
||||
emptyScreen = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// spawn new falling code
|
||||
if (random8() < SEGMENT.intensity || emptyScreen) {
|
||||
uint8_t spawnX = random8(width);
|
||||
leds[XY(spawnX, 0)] = spawnColor;
|
||||
}
|
||||
|
||||
setPixels(leds);
|
||||
} // if millis
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_2Dmatrix()
|
||||
|
||||
uint16_t WS2812FX::mode_2DAkemi(void) {
|
||||
uint16_t width = SEGMENT.virtualWidth();
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
|
||||
uint16_t counter = (now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF;
|
||||
counter = counter >> 8;
|
||||
|
||||
//Akemi
|
||||
uint8_t akemi[32][32]={
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,2,2,3,3,3,3,3,3,2,2,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,2,3,3,0,0,0,0,0,0,3,3,2,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,2,3,0,0,0,6,5,5,4,0,0,0,3,2,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,2,3,0,0,6,6,5,5,5,5,4,4,0,0,3,2,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,2,3,0,6,5,5,5,5,5,5,5,5,4,0,3,2,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,2,3,0,6,5,5,5,5,5,5,5,5,5,5,4,0,3,2,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,3,2,0,6,5,5,5,5,5,5,5,5,5,5,4,0,2,3,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,3,2,3,6,5,5,7,7,5,5,5,5,7,7,5,5,4,3,2,3,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,2,3,1,3,6,5,1,7,7,7,5,5,1,7,7,7,5,4,3,1,3,2,0,0,0,0,0},
|
||||
{0,0,0,0,0,8,3,1,3,6,5,1,7,7,7,5,5,1,7,7,7,5,4,3,1,3,8,9,0,0,0,0},
|
||||
{0,0,0,0,0,8,3,1,3,6,5,5,1,1,5,5,5,5,1,1,5,5,4,3,1,3,8,0,0,0,0,0},
|
||||
{0,0,0,0,0,2,3,1,3,6,5,5,5,5,5,5,5,5,5,5,5,5,4,3,1,3,2,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,3,2,3,6,5,5,5,5,5,5,5,5,5,5,5,5,4,3,2,3,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,6,5,5,5,5,5,7,7,5,5,5,5,5,4,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,6,5,5,5,5,5,5,5,5,5,5,5,5,4,0,0,0,0,0,0,0,0,0},
|
||||
{1,0,0,0,0,0,0,0,0,6,5,5,5,5,5,5,5,5,5,5,5,5,4,0,0,0,0,0,0,0,0,2},
|
||||
{0,2,2,2,0,0,0,0,0,6,5,5,5,5,5,5,5,5,5,5,5,5,4,0,0,0,0,0,2,2,2,0},
|
||||
{0,0,0,3,2,0,0,0,6,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,2,2,0,0,0},
|
||||
{0,0,0,3,2,0,0,0,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,0,0,0,2,3,0,0,0},
|
||||
{0,0,0,0,3,2,0,0,0,0,3,3,0,3,3,0,0,3,3,0,3,3,0,0,0,0,2,2,0,0,0,0},
|
||||
{0,0,0,0,3,2,0,0,0,0,3,2,0,3,2,0,0,3,2,0,3,2,0,0,0,0,2,3,0,0,0,0},
|
||||
{0,0,0,0,0,3,2,0,0,3,2,0,0,3,2,0,0,3,2,0,0,3,2,0,0,2,3,0,0,0,0,0},
|
||||
{0,0,0,0,0,3,2,2,2,2,0,0,0,3,2,0,0,3,2,0,0,0,3,2,2,2,3,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,3,3,3,0,0,0,0,3,2,0,0,3,2,0,0,0,0,3,3,3,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,3,2,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,3,2,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,3,2,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,3,2,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
};
|
||||
|
||||
//draw and color Akemi
|
||||
for (uint16_t y=0; y < height; y++) for (uint16_t x=0; x < width; x++) {
|
||||
CRGB color = BLACK;
|
||||
CRGB faceColor = color_wheel(counter);
|
||||
CRGB armsAndLegsColor = SEGCOLOR(1) > 0 ? SEGCOLOR(1) : 0xFFE0A0; //default warmish white 0xABA8FF; //0xFF52e5;//
|
||||
CRGB soundColor = ORANGE;
|
||||
float lightFactor = 0.15;
|
||||
float normalFactor = 0.4;
|
||||
float base = 0.0; //fftResult[0]/255.0;
|
||||
switch (akemi[(y * 32)/height][(x * 32)/width]) {
|
||||
case 0: color = BLACK; break;
|
||||
case 3: armsAndLegsColor.r *= lightFactor; armsAndLegsColor.g *= lightFactor; armsAndLegsColor.b *= lightFactor; color = armsAndLegsColor; break; //light arms and legs 0x9B9B9B
|
||||
case 2: armsAndLegsColor.r *= normalFactor; armsAndLegsColor.g *= normalFactor; armsAndLegsColor.b *= normalFactor; color = armsAndLegsColor; break; //normal arms and legs 0x888888
|
||||
case 1: color = armsAndLegsColor; break; //dark arms and legs 0x686868
|
||||
case 6: faceColor.r *= lightFactor; faceColor.g *= lightFactor; faceColor.b *= lightFactor; color=faceColor; break; //light face 0x31AAFF
|
||||
case 5: faceColor.r *= normalFactor; faceColor.g *= normalFactor; faceColor.b *= normalFactor; color=faceColor; break; //normal face 0x0094FF
|
||||
case 4: color = faceColor; break; //dark face 0x007DC6
|
||||
case 7: color = SEGCOLOR(2) > 0 ? SEGCOLOR(2) : 0xFFFFFF; break; //eyes and mouth default white
|
||||
case 8: if (base > 0.4) {soundColor.r *= base; soundColor.g *= base; soundColor.b *= base; color=soundColor;} else color = armsAndLegsColor; break;
|
||||
default: color = BLACK;
|
||||
}
|
||||
|
||||
if (SEGMENT.intensity > 128 /*&& fftResult[0] > 128*/) { //dance if base is high
|
||||
setPixelColorXY(x, 0, BLACK);
|
||||
setPixelColorXY(x, y+1, color);
|
||||
} else
|
||||
setPixelColorXY(x, y, color);
|
||||
}
|
||||
|
||||
//add geq left and right
|
||||
/*
|
||||
for (uint16_t x=0; x < width/8; x++) {
|
||||
uint16_t band = x * width/8;
|
||||
uint16_t barHeight = map(fftResult[band], 0, 255, 0, 17*height/32);
|
||||
CRGB color = color_from_palette((band * 35), false, PALETTE_SOLID_WRAP, 0);
|
||||
|
||||
for (uint16_t y=0; y < barHeight; y++) {
|
||||
setPixelColorXY(x, height/2-y, color);
|
||||
setPixelColorXY(width-1-x, height/2-y, color);
|
||||
}
|
||||
}
|
||||
*/
|
||||
return FRAMETIME;
|
||||
} // mode_2DAkemi
|
60
wled00/FX.h
60
wled00/FX.h
@ -120,8 +120,6 @@
|
||||
#define REVERSE (uint8_t)0x002
|
||||
#define SELECTED (uint8_t)0x001
|
||||
|
||||
#define MODE_COUNT 120
|
||||
|
||||
#define FX_MODE_STATIC 0
|
||||
#define FX_MODE_BLINK 1
|
||||
#define FX_MODE_BREATH 2
|
||||
@ -240,8 +238,18 @@
|
||||
#define FX_MODE_BLENDS 115
|
||||
#define FX_MODE_TV_SIMULATOR 116
|
||||
#define FX_MODE_DYNAMIC_SMOOTH 117
|
||||
#define FX_MODE_BLACK_HOLE_A 118
|
||||
#define FX_MODE_BLACK_HOLE_B 119
|
||||
#define FX_MODE_BLACK_HOLE 118
|
||||
#define FX_MODE_DNA 119
|
||||
#define FX_MODE_DNA_SPIRAL 120
|
||||
#define FX_MODE_DRIFT 121
|
||||
#define FX_MODE_FIRENOISE 122
|
||||
#define FX_MODE_FRIZZLES 123
|
||||
#define FX_MODE_HIPNOTIC 124
|
||||
#define FX_MODE_LISSAJOUS 125
|
||||
#define FX_MODE_MATRIX 126
|
||||
#define FX_MODE_AKEMI 127
|
||||
|
||||
#define MODE_COUNT 128
|
||||
|
||||
|
||||
class WS2812FX {
|
||||
@ -606,8 +614,16 @@ class WS2812FX {
|
||||
_mode[FX_MODE_BLENDS] = &WS2812FX::mode_blends;
|
||||
_mode[FX_MODE_TV_SIMULATOR] = &WS2812FX::mode_tv_simulator;
|
||||
_mode[FX_MODE_DYNAMIC_SMOOTH] = &WS2812FX::mode_dynamic_smooth;
|
||||
_mode[FX_MODE_BLACK_HOLE_A] = &WS2812FX::mode_2DBlackHole_A;
|
||||
_mode[FX_MODE_BLACK_HOLE_B] = &WS2812FX::mode_2DBlackHole_B;
|
||||
_mode[FX_MODE_BLACK_HOLE] = &WS2812FX::mode_2DBlackHole;
|
||||
_mode[FX_MODE_DNA] = &WS2812FX::mode_2Ddna;
|
||||
_mode[FX_MODE_DNA_SPIRAL] = &WS2812FX::mode_2DDNASpiral;
|
||||
_mode[FX_MODE_DRIFT] = &WS2812FX::mode_2DDrift;
|
||||
_mode[FX_MODE_FIRENOISE] = &WS2812FX::mode_2Dfirenoise;
|
||||
_mode[FX_MODE_FRIZZLES] = &WS2812FX::mode_2DFrizzles;
|
||||
_mode[FX_MODE_HIPNOTIC] = &WS2812FX::mode_2DHiphotic;
|
||||
_mode[FX_MODE_LISSAJOUS] = &WS2812FX::mode_2DLissajous;
|
||||
_mode[FX_MODE_MATRIX] = &WS2812FX::mode_2Dmatrix;
|
||||
_mode[FX_MODE_AKEMI] = &WS2812FX::mode_2DAkemi;
|
||||
|
||||
_brightness = DEFAULT_BRIGHTNESS;
|
||||
currentPalette = CRGBPalette16(CRGB::Black);
|
||||
@ -863,30 +879,37 @@ class WS2812FX {
|
||||
void
|
||||
setUpMatrix(),
|
||||
setPixelColorXY(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
fill2D(uint32_t),
|
||||
blur1d(fract8 blur_amount, CRGB* leds=nullptr),
|
||||
blur2d(fract8 blur_amount, CRGB* leds=nullptr),
|
||||
blurRows(fract8 blur_amount, CRGB* leds=nullptr),
|
||||
blurColumns(fract8 blur_amount, CRGB* leds=nullptr),
|
||||
fill_solid(const struct CRGB& color, CRGB* leds=nullptr),
|
||||
fade_out2D(uint8_t r),
|
||||
fadeToBlackBy(uint8_t fadeBy, CRGB* leds=nullptr),
|
||||
nscale8(uint8_t scale, CRGB* leds=nullptr),
|
||||
blur1d(CRGB* leds, fract8 blur_amount),
|
||||
blur2d(CRGB* leds, fract8 blur_amount),
|
||||
blurRow(uint16_t row, fract8 blur_amount, CRGB* leds=nullptr),
|
||||
blurCol(uint16_t col, fract8 blur_amount, CRGB* leds=nullptr),
|
||||
fill_solid(CRGB* leds, const struct CRGB& color),
|
||||
fadeToBlackBy(CRGB* leds, uint8_t fadeBy),
|
||||
nscale8(CRGB* leds, uint8_t scale),
|
||||
setPixels(CRGB* leds);
|
||||
|
||||
inline void setPixelColorXY(uint16_t x, uint16_t y, uint32_t c) { setPixelColorXY(x, y, byte(c>>16), byte(c>>8), byte(c), byte(c>>24)); }
|
||||
inline void setPixelColorXY(uint16_t x, uint16_t y, CRGB &c) { setPixelColorXY(x, y, c.red, c.green, c.blue); }
|
||||
|
||||
uint16_t
|
||||
XY(uint16_t x, uint16_t y, uint8_t seg=255);
|
||||
XY(uint16_t, uint16_t),
|
||||
getPixelIndex(uint16_t x, uint16_t y, uint8_t seg=255);
|
||||
|
||||
uint32_t
|
||||
getPixelColorXY(uint16_t, uint16_t);
|
||||
|
||||
// 2D modes
|
||||
uint16_t
|
||||
mode_2DBlackHole_A(),
|
||||
mode_2DBlackHole_B();
|
||||
mode_2DBlackHole(void),
|
||||
mode_2Ddna(void),
|
||||
mode_2DDNASpiral(void),
|
||||
mode_2DDrift(void),
|
||||
mode_2Dfirenoise(void),
|
||||
mode_2DFrizzles(void),
|
||||
mode_2DHiphotic(void),
|
||||
mode_2DLissajous(void),
|
||||
mode_2Dmatrix(void),
|
||||
mode_2DAkemi(void);
|
||||
|
||||
// end 2D support
|
||||
|
||||
@ -922,6 +945,7 @@ class WS2812FX {
|
||||
color_wipe(bool, bool),
|
||||
dynamic(bool),
|
||||
scan(bool),
|
||||
fireworks_base(CRGB*),
|
||||
running_base(bool,bool),
|
||||
larson_scanner(bool),
|
||||
sinelon_base(bool,bool),
|
||||
|
@ -106,13 +106,20 @@ void WS2812FX::setUpMatrix() {
|
||||
}
|
||||
}
|
||||
|
||||
// XY(x,y,seg) - returns an index of segment pixel in a matrix layout
|
||||
// XY(x,y) - gets pixel index within current segment
|
||||
uint16_t IRAM_ATTR WS2812FX::XY(uint16_t x, uint16_t y) {
|
||||
uint16_t width = SEGMENT.virtualWidth(); // segment width in logical pixels
|
||||
if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
||||
return x + y * width;
|
||||
}
|
||||
|
||||
// getPixelIndex(x,y,seg) - returns an index of segment pixel in a matrix layout
|
||||
// index still needs to undergo ledmap processing to represent actual physical pixel
|
||||
// matrix is always organized by matrixHeight number of matrixWidth pixels from top to bottom, left to right
|
||||
// so: pixel at XY(5,6) in a 2D segment with [start=10, stop=19, startY=20, stopY=29 : 10x10 pixels]
|
||||
// so: pixel at getPixelIndex(5,6) in a 2D segment with [start=10, stop=19, startY=20, stopY=29 : 10x10 pixels]
|
||||
// corresponds to pixel with logical index of 847 (0 based) if a 2D segment belongs to a 32x32 matrix.
|
||||
// math: (matrixWidth * (startY + y)) + start + x => (32 * (20+6)) + 10 + 5 = 847
|
||||
uint16_t IRAM_ATTR WS2812FX::XY(uint16_t x, uint16_t y, uint8_t seg) {
|
||||
uint16_t IRAM_ATTR WS2812FX::getPixelIndex(uint16_t x, uint16_t y, uint8_t seg) {
|
||||
if (seg == 255) seg = _segment_index;
|
||||
x %= _segments[seg].width(); // just in case constrain x (wrap around)
|
||||
y %= _segments[seg].height(); // just in case constrain y (wrap around)
|
||||
@ -122,8 +129,8 @@ uint16_t IRAM_ATTR WS2812FX::XY(uint16_t x, uint16_t y, uint8_t seg) {
|
||||
void IRAM_ATTR WS2812FX::setPixelColorXY(uint16_t x, uint16_t y, byte r, byte g, byte b, byte w)
|
||||
{
|
||||
if (!isMatrix) return; // not a matrix set-up
|
||||
uint8_t segIdx = SEGLEN ? _segment_index : _mainSegment;
|
||||
if (SEGLEN && _bri_t < 255) {
|
||||
|
||||
if (_bri_t < 255) {
|
||||
r = scale8(r, _bri_t);
|
||||
g = scale8(g, _bri_t);
|
||||
b = scale8(b, _bri_t);
|
||||
@ -131,33 +138,33 @@ void IRAM_ATTR WS2812FX::setPixelColorXY(uint16_t x, uint16_t y, byte r, byte g,
|
||||
}
|
||||
uint32_t col = RGBW32(r, g, b, w);
|
||||
|
||||
uint16_t width = _segments[segIdx].virtualWidth(); // segment width in logical pixels (includes grouping, spacing, mirror & transposed)
|
||||
uint16_t height = _segments[segIdx].virtualHeight(); // segment height in logical pixels (includes grouping, spacing, mirror & transposed)
|
||||
if (_segments[segIdx].getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
||||
uint16_t width = SEGMENT.virtualWidth(); // segment width in logical pixels (includes grouping, spacing, mirror & transposed)
|
||||
uint16_t height = SEGMENT.virtualHeight(); // segment height in logical pixels (includes grouping, spacing, mirror & transposed)
|
||||
if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
||||
|
||||
x *= _segments[segIdx].groupLength();
|
||||
y *= _segments[segIdx].groupLength();
|
||||
x *= SEGMENT.groupLength();
|
||||
y *= SEGMENT.groupLength();
|
||||
if (x >= width || y >= height) return; // if pixel would fall out of segment just exit
|
||||
|
||||
for (uint8_t j = 0; j < _segments[segIdx].grouping; j++) { // groupping vertically
|
||||
for (uint8_t g = 0; g < _segments[segIdx].grouping; g++) { // groupping horizontally
|
||||
for (uint8_t j = 0; j < SEGMENT.grouping; j++) { // groupping vertically
|
||||
for (uint8_t g = 0; g < SEGMENT.grouping; g++) { // groupping horizontally
|
||||
uint16_t index, xX = (x+g), yY = (y+j);
|
||||
if (xX >= width || yY >= height) continue; // we have reached one dimension's end
|
||||
if (xX >= SEGMENT.width() || yY >= SEGMENT.height()) continue; // we have reached one dimension's end
|
||||
|
||||
if (_segments[segIdx].getOption(SEG_OPTION_REVERSED) ) xX = width - xX - 1;
|
||||
if (_segments[segIdx].getOption(SEG_OPTION_REVERSED_Y)) yY = height - yY - 1;
|
||||
if (SEGMENT.getOption(SEG_OPTION_REVERSED) ) xX = width - xX - 1;
|
||||
if (SEGMENT.getOption(SEG_OPTION_REVERSED_Y)) yY = height - yY - 1;
|
||||
|
||||
index = XY(xX, yY, segIdx);
|
||||
index = getPixelIndex(xX, yY);
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
busses.setPixelColor(index, col);
|
||||
|
||||
if (_segments[segIdx].getOption(SEG_OPTION_MIRROR)) { //set the corresponding horizontally mirrored pixel
|
||||
index = XY(_segments[segIdx].width() - xX - 1, yY, segIdx);
|
||||
if (SEGMENT.getOption(SEG_OPTION_MIRROR)) { //set the corresponding horizontally mirrored pixel
|
||||
index = getPixelIndex(SEGMENT.width() - xX - 1, yY);
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
busses.setPixelColor(index, col);
|
||||
}
|
||||
if (_segments[segIdx].getOption(SEG_OPTION_MIRROR_Y)) { //set the corresponding vertically mirrored pixel
|
||||
index = XY(xX, _segments[segIdx].height() - yY - 1, segIdx);
|
||||
if (SEGMENT.getOption(SEG_OPTION_MIRROR_Y)) { //set the corresponding vertically mirrored pixel
|
||||
index = getPixelIndex(xX, SEGMENT.height() - yY - 1);
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
busses.setPixelColor(index, col);
|
||||
}
|
||||
@ -168,74 +175,70 @@ void IRAM_ATTR WS2812FX::setPixelColorXY(uint16_t x, uint16_t y, byte r, byte g,
|
||||
|
||||
uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y)
|
||||
{
|
||||
uint8_t segIdx = _segment_index;
|
||||
uint16_t width = _segments[segIdx].virtualWidth(); // segment width in logical pixels
|
||||
uint16_t height = _segments[segIdx].virtualHeight(); // segment height in logical pixels
|
||||
if (_segments[segIdx].getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
||||
uint16_t width = SEGMENT.virtualWidth(); // segment width in logical pixels
|
||||
uint16_t height = SEGMENT.virtualHeight(); // segment height in logical pixels
|
||||
if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
||||
|
||||
x *= _segments[segIdx].groupLength();
|
||||
y *= _segments[segIdx].groupLength();
|
||||
if (x >= width || y >= height) return 0;
|
||||
x *= SEGMENT.groupLength();
|
||||
y *= SEGMENT.groupLength();
|
||||
if (x >= SEGMENT.width() || y >= SEGMENT.height()) return 0;
|
||||
|
||||
if (_segments[segIdx].getOption(SEG_OPTION_REVERSED) ) x = width - x - 1;
|
||||
if (_segments[segIdx].getOption(SEG_OPTION_REVERSED_Y)) y = height - y - 1;
|
||||
if (SEGMENT.getOption(SEG_OPTION_REVERSED) ) x = width - x - 1;
|
||||
if (SEGMENT.getOption(SEG_OPTION_REVERSED_Y)) y = height - y - 1;
|
||||
|
||||
uint16_t index = XY(x, y, segIdx);
|
||||
uint16_t index = getPixelIndex(x, y);
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
|
||||
return busses.getPixelColor(index);
|
||||
}
|
||||
|
||||
|
||||
// blurRows: perform a blur1d on every row of a rectangular matrix
|
||||
void WS2812FX::blurRows(fract8 blur_amount, CRGB* leds)
|
||||
void WS2812FX::blurRow(uint16_t y, fract8 blur_amount, CRGB* leds)
|
||||
{
|
||||
uint16_t width = SEGMENT.virtualWidth();
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
uint8_t keep = 255 - blur_amount;
|
||||
uint8_t seep = blur_amount >> 1;
|
||||
CRGB carryover = CRGB::Black;
|
||||
for (uint16_t y = 0; y < height; y++) for (uint16_t x = 0; x < width; x++) {
|
||||
CRGB cur = leds ? leds[x + y * width] : col_to_crgb(getPixelColorXY(x,y));
|
||||
for (uint16_t x = 0; x < width; x++) {
|
||||
CRGB cur = leds ? leds[XY(x,y)] : col_to_crgb(getPixelColorXY(x,y));
|
||||
CRGB part = cur;
|
||||
part.nscale8(seep);
|
||||
cur.nscale8(keep);
|
||||
cur += carryover;
|
||||
if (x) {
|
||||
if (leds) leds[(x-1) + y * width] += part;
|
||||
if (leds) leds[XY((x-1),y)] += part;
|
||||
else setPixelColorXY(x-1, y, col_to_crgb(getPixelColorXY(x-1, y)) + part);
|
||||
}
|
||||
if (leds) leds[x + y * width] = cur;
|
||||
if (leds) leds[XY(x,y)] = cur;
|
||||
else setPixelColorXY(x, y, cur);
|
||||
carryover = part;
|
||||
}
|
||||
}
|
||||
|
||||
// blurColumns: perform a blur1d on each column of a rectangular matrix
|
||||
void WS2812FX::blurColumns(fract8 blur_amount, CRGB* leds)
|
||||
void WS2812FX::blurCol(uint16_t x, fract8 blur_amount, CRGB* leds)
|
||||
{
|
||||
uint16_t width = SEGMENT.virtualWidth();
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
// blur columns
|
||||
uint8_t keep = 255 - blur_amount;
|
||||
uint8_t seep = blur_amount >> 1;
|
||||
for ( uint16_t x = 0; x < width; x++) {
|
||||
CRGB carryover = CRGB::Black;
|
||||
for ( uint16_t y = 0; y < height; y++) {
|
||||
CRGB cur = leds ? leds[x + y * width] : col_to_crgb(getPixelColorXY(x,y));
|
||||
CRGB cur = leds ? leds[XY(x,y)] : col_to_crgb(getPixelColorXY(x,y));
|
||||
CRGB part = cur;
|
||||
part.nscale8(seep);
|
||||
cur.nscale8(keep);
|
||||
cur += carryover;
|
||||
if (y) {
|
||||
if (leds) leds[x + (y-1) * width] += part;
|
||||
if (leds) leds[XY(x,(y-1))] += part;
|
||||
else setPixelColorXY(x, y-1, col_to_crgb(getPixelColorXY(x,y-1)) + part);
|
||||
}
|
||||
if (leds) leds[x + y * width] = cur;
|
||||
if (leds) leds[XY(x,y)] = cur;
|
||||
else setPixelColorXY(x, y, cur);
|
||||
carryover = part;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// blur1d: one-dimensional blur filter. Spreads light to 2 line neighbors.
|
||||
// blur2d: two-dimensional blur filter. Spreads light to 8 XY neighbors.
|
||||
@ -251,86 +254,66 @@ void WS2812FX::blurColumns(fract8 blur_amount, CRGB* leds)
|
||||
// eventually all the way to black; this is by design so that
|
||||
// it can be used to (slowly) clear the LEDs to black.
|
||||
|
||||
void WS2812FX::blur1d(fract8 blur_amount, CRGB* leds)
|
||||
void WS2812FX::blur1d(CRGB* leds, fract8 blur_amount)
|
||||
{
|
||||
blurRows(blur_amount, leds);
|
||||
uint16_t height = SEGMENT.virtualHeight();
|
||||
for ( uint16_t y = 0; y < height; y++)
|
||||
blurRow(y, blur_amount, leds);
|
||||
}
|
||||
|
||||
void WS2812FX::blur2d(fract8 blur_amount, CRGB* leds)
|
||||
void WS2812FX::blur2d(CRGB* leds, fract8 blur_amount)
|
||||
{
|
||||
blurRows(blur_amount, leds);
|
||||
blurColumns(blur_amount, leds);
|
||||
uint16_t w = SEGMENT.virtualWidth(); // same as SEGLEN
|
||||
uint16_t h = SEGMENT.virtualHeight();
|
||||
uint8_t keep = 255 - blur_amount;
|
||||
uint8_t seep = blur_amount >> 1;
|
||||
for (uint16_t k = 0; k < h; k++) {
|
||||
CRGB carryover = CRGB::Black;
|
||||
for(uint16_t i = 0; i < w; i++) {
|
||||
CRGB cur = leds ? leds[XY(i,k)] : col_to_crgb(getPixelColorXY(i, k));
|
||||
CRGB part = cur;
|
||||
part.nscale8(seep);
|
||||
cur.nscale8(keep);
|
||||
cur += carryover;
|
||||
if (i > 0) {
|
||||
CRGB c = leds ? leds[XY(i,k)] : col_to_crgb(getPixelColorXY(i-1, k));
|
||||
c += part;
|
||||
if (leds) leds[XY(i-1,k)] = c;
|
||||
else setPixelColorXY(i-1, k, c.red, c.green, c.blue);
|
||||
}
|
||||
// seep from previous row
|
||||
if (k > 0) {
|
||||
CRGB c = col_to_crgb(getPixelColorXY(i, k-1));
|
||||
c.nscale8(seep);
|
||||
cur += c;
|
||||
}
|
||||
if (leds) leds[XY(i,k)] = cur;
|
||||
else setPixelColorXY(i, k, cur.red, cur.green, cur.blue);
|
||||
carryover = part;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//ewowi20210628: new functions moved from colorutils: add segment awareness
|
||||
|
||||
/*
|
||||
* Fills segment with color
|
||||
*/
|
||||
void WS2812FX::fill2D(uint32_t c) {
|
||||
void WS2812FX::fill_solid(CRGB* leds, const struct CRGB& color) {
|
||||
uint16_t w = SEGMENT.virtualWidth();
|
||||
uint16_t h = SEGMENT.virtualHeight();
|
||||
for(uint16_t y = 0; y < h; y++) for (uint16_t x = 0; x < w; x++) {
|
||||
setPixelColorXY(x, y, c);
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::fill_solid(const struct CRGB& color, CRGB* leds) {
|
||||
uint16_t w = SEGMENT.virtualWidth();
|
||||
uint16_t h = SEGMENT.virtualHeight();
|
||||
for(uint16_t y = 0; y < h; y++) for (uint16_t x = 0; x < w; x++) {
|
||||
if (leds) leds[x + y * w] = color;
|
||||
if (leds) leds[XY(x,y)] = color;
|
||||
else setPixelColorXY(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fade out function, higher rate = quicker fade
|
||||
* TODO: may be better to use approach of nscale8()
|
||||
*/
|
||||
void WS2812FX::fade_out2D(uint8_t rate) {
|
||||
uint16_t w = SEGMENT.virtualWidth();
|
||||
uint16_t h = SEGMENT.virtualHeight();
|
||||
rate = (255-rate) >> 1;
|
||||
float mappedRate = float(rate) +1.1;
|
||||
|
||||
uint32_t color = SEGCOLOR(1); // target color
|
||||
int w2 = W(color);
|
||||
int r2 = R(color);
|
||||
int g2 = G(color);
|
||||
int b2 = B(color);
|
||||
|
||||
for(uint16_t y = 0; y < h; y++) for (uint16_t x = 0; x < w; x++) {
|
||||
color = getPixelColorXY(x, y);
|
||||
int w1 = W(color);
|
||||
int r1 = R(color);
|
||||
int g1 = G(color);
|
||||
int b1 = B(color);
|
||||
|
||||
int wdelta = (w2 - w1) / mappedRate;
|
||||
int rdelta = (r2 - r1) / mappedRate;
|
||||
int gdelta = (g2 - g1) / mappedRate;
|
||||
int bdelta = (b2 - b1) / mappedRate;
|
||||
|
||||
// if fade isn't complete, make sure delta is at least 1 (fixes rounding issues)
|
||||
wdelta += (w2 == w1) ? 0 : (w2 > w1) ? 1 : -1;
|
||||
rdelta += (r2 == r1) ? 0 : (r2 > r1) ? 1 : -1;
|
||||
gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1;
|
||||
bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1;
|
||||
|
||||
setPixelColorXY(x, y, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta);
|
||||
}
|
||||
void WS2812FX::fadeToBlackBy(CRGB* leds, uint8_t fadeBy) {
|
||||
nscale8(leds, 255 - fadeBy);
|
||||
}
|
||||
|
||||
void WS2812FX::fadeToBlackBy(uint8_t fadeBy, CRGB* leds) {
|
||||
nscale8(255 - fadeBy, leds);
|
||||
}
|
||||
|
||||
void WS2812FX::nscale8(uint8_t scale, CRGB* leds) {
|
||||
void WS2812FX::nscale8(CRGB* leds, uint8_t scale) {
|
||||
uint16_t w = SEGMENT.virtualWidth();
|
||||
uint16_t h = SEGMENT.virtualHeight();
|
||||
for(uint16_t y = 0; y < h; y++) for (uint16_t x = 0; x < w; x++) {
|
||||
if (leds) leds[x + y * w].nscale8(scale);
|
||||
if (leds) leds[XY(x,y)].nscale8(scale);
|
||||
else setPixelColorXY(x, y, col_to_crgb(getPixelColorXY(x, y)).nscale8(scale));
|
||||
}
|
||||
}
|
||||
@ -338,5 +321,5 @@ void WS2812FX::nscale8(uint8_t scale, CRGB* leds) {
|
||||
void WS2812FX::setPixels(CRGB* leds) {
|
||||
uint16_t w = SEGMENT.virtualWidth();
|
||||
uint16_t h = SEGMENT.virtualHeight();
|
||||
for (uint16_t y = 0; y < h; y++) for (uint16_t x = 0; x < w; x++) setPixelColorXY(x, y, leds[x + y*w]);
|
||||
for (uint16_t y = 0; y < h; y++) for (uint16_t x = 0; x < w; x++) setPixelColorXY(x, y, leds[XY(x,y)]);
|
||||
}
|
||||
|
@ -185,12 +185,11 @@ void WS2812FX::service() {
|
||||
void IRAM_ATTR WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
{
|
||||
uint8_t segIdx = SEGLEN ? _segment_index : _mainSegment;
|
||||
if (isMatrix) {
|
||||
if (isMatrix && SEGLEN) {
|
||||
// map linear pixel into 2D segment area (even for 1D segments, expanding vertically)
|
||||
uint16_t h = _segments[segIdx].height(); // segment height in logical pixels
|
||||
uint8_t l = _segments[segIdx].groupLength();
|
||||
for (uint16_t y = 0; y < h; y += l) { // expand 1D effect vertically
|
||||
setPixelColorXY(i, y, r, g, b, w);
|
||||
uint16_t h = _segments[segIdx].virtualHeight(); // segment height in logical pixels
|
||||
for (uint16_t y = 0; y < h; y++) { // expand 1D effect vertically
|
||||
setPixelColorXY(i, y * _segments[segIdx].groupLength(), r, g, b, w);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -711,9 +710,9 @@ void WS2812FX::resetSegments() {
|
||||
_segments[0].setOption(SEG_OPTION_ON, 1);
|
||||
_segments[0].opacity = 255;
|
||||
_segments[0].cct = 127;
|
||||
_segments[0].c1x = 0;
|
||||
_segments[0].c2x = 0;
|
||||
_segments[0].c3x = 0;
|
||||
_segments[0].c1x = DEFAULT_C1;
|
||||
_segments[0].c2x = DEFAULT_C2;
|
||||
_segments[0].c3x = DEFAULT_C3;
|
||||
|
||||
for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
@ -724,9 +723,9 @@ void WS2812FX::resetSegments() {
|
||||
_segments[i].cct = 127;
|
||||
_segments[i].speed = DEFAULT_SPEED;
|
||||
_segments[i].intensity = DEFAULT_INTENSITY;
|
||||
_segments[i].c1x = 0;
|
||||
_segments[i].c2x = 0;
|
||||
_segments[i].c3x = 0;
|
||||
_segments[i].c1x = DEFAULT_C1;
|
||||
_segments[i].c2x = DEFAULT_C2;
|
||||
_segments[i].c3x = DEFAULT_C3;
|
||||
_segment_runtimes[i].markForReset();
|
||||
}
|
||||
_segment_runtimes[0].markForReset();
|
||||
@ -891,8 +890,11 @@ uint32_t IRAM_ATTR WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint1
|
||||
* Fills segment with color
|
||||
*/
|
||||
void WS2812FX::fill(uint32_t c) {
|
||||
for(uint16_t i = 0; i < SEGLEN; i++) {
|
||||
setPixelColor(i, c);
|
||||
uint16_t w = SEGMENT.virtualWidth(); // same as SEGLEN
|
||||
uint16_t h = SEGMENT.virtualHeight();
|
||||
for(uint16_t y = 0; y < h; y++) for (uint16_t x = 0; x < w; x++) {
|
||||
if (isMatrix) setPixelColorXY(x, y, c);
|
||||
else setPixelColor(x, c);
|
||||
}
|
||||
}
|
||||
|
||||
@ -908,6 +910,8 @@ void WS2812FX::blendPixelColor(uint16_t n, uint32_t color, uint8_t blend)
|
||||
* fade out function, higher rate = quicker fade
|
||||
*/
|
||||
void WS2812FX::fade_out(uint8_t rate) {
|
||||
uint16_t w = SEGMENT.virtualWidth(); // same as SEGLEN
|
||||
uint16_t h = SEGMENT.virtualHeight();
|
||||
rate = (255-rate) >> 1;
|
||||
float mappedRate = float(rate) +1.1;
|
||||
|
||||
@ -917,8 +921,8 @@ void WS2812FX::fade_out(uint8_t rate) {
|
||||
int g2 = G(color);
|
||||
int b2 = B(color);
|
||||
|
||||
for(uint16_t i = 0; i < SEGLEN; i++) {
|
||||
color = getPixelColor(i);
|
||||
for(uint16_t y = 0; y < h; y++) for (uint16_t x = 0; x < w; x++) {
|
||||
color = isMatrix ? getPixelColorXY(x, y) : getPixelColor(x);
|
||||
int w1 = W(color);
|
||||
int r1 = R(color);
|
||||
int g1 = G(color);
|
||||
@ -935,7 +939,8 @@ void WS2812FX::fade_out(uint8_t rate) {
|
||||
gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1;
|
||||
bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1;
|
||||
|
||||
setPixelColor(i, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta);
|
||||
if (isMatrix) setPixelColorXY(x, y, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta);
|
||||
else setPixelColor(x, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1427,8 +1432,16 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
||||
"Blends@Shift speed,Blend speed;1,2,3,!",
|
||||
"TV Simulator",
|
||||
"Dynamic Smooth",
|
||||
"2D Black Hole A@!,!,C1,C2,C3;!;!",
|
||||
"2D Black Hole B@!,!,C1,C2,C3;!;!"
|
||||
"2D Black Hole@!,!,Inner X,Outer X,Outer Y;!,!,!;!",
|
||||
"2D DNA",
|
||||
"2D DNA Spiral",
|
||||
"2D Drift",
|
||||
"2D Firenoise",
|
||||
"2D Frizzles",
|
||||
"2D Hipnotic",
|
||||
"2D Lissajous",
|
||||
"2D Matrix@!,!,Fade,Matrix?;!,!,!;!",
|
||||
"2D Akemi@!,!;!,!;!"
|
||||
])=====";
|
||||
|
||||
const char JSON_palette_names[] PROGMEM = R"=====([
|
||||
|
Loading…
Reference in New Issue
Block a user