Merge pull request #40 from MoonModules/expand-1DEffects
Drip to virtualStrip
This commit is contained in:
commit
cdd4319991
306
wled00/FX.cpp
306
wled00/FX.cpp
@ -30,6 +30,7 @@
|
||||
|
||||
#define IBN 5100
|
||||
#define PALETTE_SOLID_WRAP (strip.paletteBlend == 1 || strip.paletteBlend == 3)
|
||||
#define indexToVStrip(index, stripNr) ((index) | (int((stripNr)+1)<<16))
|
||||
|
||||
// effect utility functions
|
||||
uint8_t sin_gap(uint16_t in) {
|
||||
@ -1966,59 +1967,59 @@ static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Cycle speed,;1,2,3;
|
||||
// in step 3 above) (Effect Intensity = Sparking).
|
||||
uint16_t mode_fire_2012()
|
||||
{
|
||||
const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1;
|
||||
const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength();
|
||||
|
||||
uint32_t it = strip.now >> 5; //div 32
|
||||
//uint16_t q = cols>>2; // a quarter of flames
|
||||
|
||||
if (!SEGENV.allocateData(cols*rows)) return mode_static(); //allocation failed
|
||||
|
||||
uint16_t strips = SEGMENT.nrOfVStrips();
|
||||
if (!SEGENV.allocateData(strips * SEGLEN)) return mode_static(); //allocation failed
|
||||
byte* heat = SEGENV.data;
|
||||
|
||||
if (it != SEGENV.step) {
|
||||
SEGENV.step = it;
|
||||
uint8_t ignition = max(3,rows/10); // ignition area: 10% of segment length or minimum 3 pixels
|
||||
uint32_t it = strip.now >> 5; //div 32
|
||||
|
||||
for (int f = 0; f < cols; f++) {
|
||||
// Step 1. Cool down every cell a little
|
||||
for (int i = 0; i < rows; i++) {
|
||||
uint8_t cool = (((20 + SEGMENT.speed/3) * 16) / rows);
|
||||
/*
|
||||
// 2D enhancement: cool sides of the flame a bit more
|
||||
if (cols>5) {
|
||||
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
|
||||
struct virtualStrip {
|
||||
static void runStrip(uint16_t stripNr, byte* heat, uint32_t it) {
|
||||
|
||||
if (it != SEGENV.step)
|
||||
{
|
||||
uint8_t ignition = max(3,SEGLEN/10); // ignition area: 10% of segment length or minimum 3 pixels
|
||||
|
||||
// Step 1. Cool down every cell a little
|
||||
for (int i = 0; i < SEGLEN; i++) {
|
||||
uint8_t cool = random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2);
|
||||
uint8_t minTemp = 0;
|
||||
if (i<ignition) {
|
||||
cool /= (ignition-i); // ignition area cools slower
|
||||
minTemp = 4*(ignition-i) + 8; // and should not become black
|
||||
}
|
||||
uint8_t temp = qsub8(heat[i], cool);
|
||||
heat[i] = i<ignition && temp<minTemp ? minTemp : temp; // prevent ignition area from becoming black
|
||||
}
|
||||
|
||||
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
||||
for (int k = SEGLEN -1; k > 1; k--) {
|
||||
heat[k] = (heat[k - 1] + (heat[k - 2]<<1) ) / 3; // heat[k-2] multiplied by 2
|
||||
}
|
||||
|
||||
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
|
||||
if (random8() <= SEGMENT.intensity) {
|
||||
uint8_t y = random8(ignition);
|
||||
heat[y] = qadd8(heat[y], random8(160,255));
|
||||
}
|
||||
*/
|
||||
uint8_t temp = qsub8(heat[i+rows*f], random8(0, cool + 2));
|
||||
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
|
||||
for (int k = rows -1; k > 1; k--) {
|
||||
heat[k+rows*f] = (heat[k+rows*f - 1] + (heat[k+rows*f - 2]<<1) ) / 3; // heat[k-2] multiplied by 2
|
||||
}
|
||||
|
||||
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
|
||||
if (random8() <= SEGMENT.intensity) {
|
||||
uint8_t y = random8(ignition);
|
||||
heat[y+rows*f] = qadd8(heat[y+rows*f], random8(160,255));
|
||||
// Step 4. Map from heat cells to LED colors
|
||||
for (int j = 0; j < SEGLEN; j++) {
|
||||
SEGMENT.setPixelColor(indexToVStrip(j, stripNr), ColorFromPalette(SEGPALETTE, MIN(heat[j],240), 255, NOBLEND));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (int stripNr=0; stripNr<strips; stripNr++)
|
||||
virtualStrip::runStrip(stripNr, &heat[stripNr * SEGLEN], it);
|
||||
|
||||
if (it != SEGENV.step)
|
||||
SEGENV.step = it;
|
||||
|
||||
for (int f = 0; f < cols; f++) {
|
||||
// Step 4. Map from heat cells to LED colors
|
||||
for (int j = 0; j < rows; j++) {
|
||||
CRGB color = ColorFromPalette(SEGPALETTE, /*MIN(*/heat[j+rows*f]/*,240)*/, 255, LINEARBLEND);
|
||||
if (strip.isMatrix) SEGMENT.setPixelColorXY(f, rows -j -1, color);
|
||||
else SEGMENT.setPixelColor(j, color);
|
||||
}
|
||||
}
|
||||
return FRAMETIME;
|
||||
}
|
||||
static const char _data_FX_MODE_FIRE_2012[] PROGMEM = "Fire 2012@Cooling,Spark rate;1,2,3;!;sx=120,ix=64,1d,2d";
|
||||
static const char _data_FX_MODE_FIRE_2012[] PROGMEM = "Fire 2012@Cooling,Spark rate;1,2,3;!;sx=120,ix=64,mp12=1,1d"; //bars
|
||||
|
||||
|
||||
// ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb
|
||||
@ -2849,7 +2850,7 @@ uint16_t mode_bouncing_balls(void) {
|
||||
}
|
||||
|
||||
int pos = roundf(balls[i].height * (SEGLEN - 1));
|
||||
if (SEGLEN<32) SEGMENT.setPixelColor(pos | int((stripNr+1)<<16), color); // encode virtual strip into index
|
||||
if (SEGLEN<32) SEGMENT.setPixelColor(indexToVStrip(pos, stripNr), color); // encode virtual strip into index
|
||||
else SEGMENT.setPixelColor(balls[i].height + (stripNr+1)*10.0f, color);
|
||||
}
|
||||
}
|
||||
@ -2942,68 +2943,68 @@ typedef struct Spark {
|
||||
uint8_t colIndex;
|
||||
} spark;
|
||||
|
||||
#define maxNumPopcorn 21 // max 21 on 16 segment ESP8266
|
||||
/*
|
||||
* POPCORN
|
||||
* modified from https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Popcorn.h
|
||||
*/
|
||||
uint16_t mode_popcorn(void) {
|
||||
const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1;
|
||||
const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength();
|
||||
|
||||
//allocate segment data
|
||||
uint16_t maxNumPopcorn = 21; // max 21 on 16 segment ESP8266
|
||||
uint16_t strips = SEGMENT.nrOfVStrips();
|
||||
uint16_t dataSize = sizeof(spark) * maxNumPopcorn;
|
||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||
|
||||
Spark* popcorn = reinterpret_cast<Spark*>(SEGENV.data);
|
||||
if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed
|
||||
|
||||
float gravity = -0.0001 - (SEGMENT.speed/200000.0); // m/s/s
|
||||
gravity *= rows; //SEGLEN
|
||||
Spark* popcorn = reinterpret_cast<Spark*>(SEGENV.data);
|
||||
|
||||
bool hasCol2 = SEGCOLOR(2);
|
||||
SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1));
|
||||
|
||||
uint8_t numPopcorn = SEGMENT.intensity*maxNumPopcorn/255;
|
||||
if (numPopcorn == 0) numPopcorn = 1;
|
||||
struct virtualStrip {
|
||||
static void runStrip(uint16_t stripNr, Spark* popcorn) {
|
||||
float gravity = -0.0001 - (SEGMENT.speed/200000.0); // m/s/s
|
||||
gravity *= SEGLEN;
|
||||
|
||||
for (int i = 0; i < numPopcorn; i++) {
|
||||
if (popcorn[i].pos >= 0.0f) { // if kernel is active, update its position
|
||||
popcorn[i].pos += popcorn[i].vel;
|
||||
popcorn[i].vel += gravity;
|
||||
} else { // if kernel is inactive, randomly pop it
|
||||
if (random8() < 2) { // POP!!!
|
||||
popcorn[i].pos = 0.01f;
|
||||
popcorn[i].posX = random16(cols);
|
||||
|
||||
uint16_t peakHeight = 128 + random8(128); //0-255
|
||||
peakHeight = (peakHeight * (rows -1)) >> 8;
|
||||
popcorn[i].vel = sqrt(-2.0 * gravity * peakHeight);
|
||||
popcorn[i].velX = 0;
|
||||
|
||||
if (SEGMENT.palette) {
|
||||
popcorn[i].colIndex = random8();
|
||||
} else {
|
||||
byte col = random8(0, NUM_COLORS);
|
||||
if (!hasCol2 || !SEGCOLOR(col)) col = 0;
|
||||
popcorn[i].colIndex = col;
|
||||
uint8_t numPopcorn = SEGMENT.intensity*maxNumPopcorn/255;
|
||||
if (numPopcorn == 0) numPopcorn = 1;
|
||||
|
||||
for(int i = 0; i < numPopcorn; i++) {
|
||||
if (popcorn[i].pos >= 0.0f) { // if kernel is active, update its position
|
||||
popcorn[i].pos += popcorn[i].vel;
|
||||
popcorn[i].vel += gravity;
|
||||
} else { // if kernel is inactive, randomly pop it
|
||||
if (random8() < 2) { // POP!!!
|
||||
popcorn[i].pos = 0.01f;
|
||||
|
||||
uint16_t peakHeight = 128 + random8(128); //0-255
|
||||
peakHeight = (peakHeight * (SEGLEN -1)) >> 8;
|
||||
popcorn[i].vel = sqrt(-2.0 * gravity * peakHeight);
|
||||
|
||||
if (SEGMENT.palette)
|
||||
{
|
||||
popcorn[i].colIndex = random8();
|
||||
} else {
|
||||
byte col = random8(0, NUM_COLORS);
|
||||
if (!SEGCOLOR(2) || !SEGCOLOR(col)) col = 0;
|
||||
popcorn[i].colIndex = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (popcorn[i].pos >= 0.0f) { // draw now active popcorn (either active before or just popped)
|
||||
uint32_t col = SEGMENT.color_wheel(popcorn[i].colIndex);
|
||||
if (!SEGMENT.palette && popcorn[i].colIndex < NUM_COLORS) col = SEGCOLOR(popcorn[i].colIndex);
|
||||
uint16_t ledIndex = popcorn[i].pos;
|
||||
if (ledIndex < SEGLEN) SEGMENT.setPixelColor(indexToVStrip(ledIndex, stripNr), col);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (popcorn[i].pos >= 0.0f) { // draw now active popcorn (either active before or just popped)
|
||||
uint32_t col = SEGMENT.color_wheel(popcorn[i].colIndex);
|
||||
if (!SEGMENT.palette && popcorn[i].colIndex < NUM_COLORS) col = SEGCOLOR(popcorn[i].colIndex);
|
||||
|
||||
uint16_t ledIndex = popcorn[i].pos;
|
||||
if (ledIndex < rows) {
|
||||
if (strip.isMatrix) SEGMENT.setPixelColorXY(uint16_t(popcorn[i].posX), rows - 1 - ledIndex, col);
|
||||
else SEGMENT.setPixelColor(ledIndex, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (int stripNr=0; stripNr<strips; stripNr++)
|
||||
virtualStrip::runStrip(stripNr, &popcorn[stripNr * maxNumPopcorn]);
|
||||
|
||||
return FRAMETIME;
|
||||
}
|
||||
static const char _data_FX_MODE_POPCORN[] PROGMEM = "Popcorn@!,!;!,!,!;!;1d,2d";
|
||||
static const char _data_FX_MODE_POPCORN[] PROGMEM = "Popcorn@!,!;!,!,!;!;mp12=1,1d"; //bar
|
||||
|
||||
|
||||
//values close to 100 produce 5Hz flicker, which looks very candle-y
|
||||
@ -3375,91 +3376,84 @@ static const char _data_FX_MODE_EXPLODING_FIREWORKS[] PROGMEM = "Fireworks 1D@Gr
|
||||
*/
|
||||
uint16_t mode_drip(void)
|
||||
{
|
||||
const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1;
|
||||
const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength();
|
||||
|
||||
//allocate segment data
|
||||
uint8_t numDrops = 4;
|
||||
uint16_t dataSize = sizeof(spark) * numDrops;
|
||||
if (!SEGENV.allocateData(dataSize * cols)) return mode_static(); //allocation failed
|
||||
uint16_t strips = SEGMENT.nrOfVStrips();
|
||||
const int maxNumDrops = 4;
|
||||
uint16_t dataSize = sizeof(spark) * maxNumDrops;
|
||||
if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed
|
||||
Spark* drops = reinterpret_cast<Spark*>(SEGENV.data);
|
||||
|
||||
SEGMENT.fill(SEGCOLOR(1));
|
||||
|
||||
Spark* drops = reinterpret_cast<Spark*>(SEGENV.data);
|
||||
struct virtualStrip {
|
||||
static void runStrip(uint16_t stripNr, Spark* drops) {
|
||||
|
||||
numDrops = 1 + (SEGMENT.intensity >> 6); // 255>>6 = 3
|
||||
uint8_t numDrops = 1 + (SEGMENT.intensity >> 6); // 255>>6 = 3
|
||||
|
||||
float gravity = -0.0005 - (SEGMENT.speed/50000.0);
|
||||
gravity *= rows-1;
|
||||
int sourcedrop = 12;
|
||||
float gravity = -0.0005 - (SEGMENT.speed/50000.0);
|
||||
gravity *= SEGLEN-1;
|
||||
int sourcedrop = 12;
|
||||
|
||||
for (int k=0; k < cols; k++) {
|
||||
for (size_t j=0; j < numDrops; j++) {
|
||||
uint16_t idx = k*numDrops + j;
|
||||
|
||||
if (drops[idx].colIndex == 0) { //init
|
||||
drops[idx].pos = rows-1; // start at end
|
||||
drops[idx].vel = 0; // speed
|
||||
drops[idx].col = sourcedrop; // brightness
|
||||
drops[idx].colIndex = 1; // drop state (0 init, 1 forming, 2 falling, 5 bouncing)
|
||||
}
|
||||
|
||||
uint32_t col = color_blend(BLACK, SEGCOLOR(0), sourcedrop);
|
||||
if (strip.isMatrix) SEGMENT.setPixelColorXY(k, 0, col);
|
||||
else SEGMENT.setPixelColor(rows-1, col);// water source
|
||||
|
||||
if (drops[idx].colIndex == 1) {
|
||||
if (drops[idx].col > 255) drops[idx].col = 255;
|
||||
col = color_blend(BLACK,SEGCOLOR(0),drops[idx].col);
|
||||
if (strip.isMatrix) SEGMENT.setPixelColorXY(k, rows - 1 - uint16_t(drops[idx].pos), col);
|
||||
else SEGMENT.setPixelColor(uint16_t(drops[idx].pos), col);
|
||||
|
||||
drops[idx].col += map(SEGMENT.speed, 0, 255, 1, 6); // swelling
|
||||
|
||||
if (random8() < drops[idx].col/10) { // random drop
|
||||
drops[idx].colIndex = 2; //fall
|
||||
drops[idx].col = 255;
|
||||
for (int j=0;j<numDrops;j++) {
|
||||
if (drops[j].colIndex == 0) { //init
|
||||
drops[j].pos = SEGLEN-1; // start at end
|
||||
drops[j].vel = 0; // speed
|
||||
drops[j].col = sourcedrop; // brightness
|
||||
drops[j].colIndex = 1; // drop state (0 init, 1 forming, 2 falling, 5 bouncing)
|
||||
}
|
||||
}
|
||||
if (drops[idx].colIndex > 1) { // falling
|
||||
if (drops[idx].pos > 0) { // fall until end of segment
|
||||
drops[idx].pos += drops[idx].vel;
|
||||
if (drops[idx].pos < 0) drops[idx].pos = 0;
|
||||
drops[idx].vel += gravity; // gravity is negative
|
||||
|
||||
for (int i = 1; i < 7 - drops[idx].colIndex; i++) { // some minor math so we don't expand bouncing droplets
|
||||
uint16_t pos = constrain(uint16_t(drops[idx].pos) +i, 0, rows-1); //this is BAD, returns a pos >= SEGLEN occasionally
|
||||
col = color_blend(BLACK, SEGCOLOR(0), drops[idx].col/i);
|
||||
if (strip.isMatrix) SEGMENT.setPixelColorXY(k, rows - 1 - pos, col);
|
||||
else SEGMENT.setPixelColor(pos, col); //spread pixel with fade while falling
|
||||
SEGMENT.setPixelColor(indexToVStrip(SEGLEN-1, stripNr), color_blend(BLACK,SEGCOLOR(0), sourcedrop));// water source
|
||||
if (drops[j].colIndex==1) {
|
||||
if (drops[j].col>255) drops[j].col=255;
|
||||
SEGMENT.setPixelColor(indexToVStrip(uint16_t(drops[j].pos), stripNr), color_blend(BLACK,SEGCOLOR(0),drops[j].col));
|
||||
|
||||
drops[j].col += map(SEGMENT.speed, 0, 255, 1, 6); // swelling
|
||||
|
||||
if (random8() < drops[j].col/10) { // random drop
|
||||
drops[j].colIndex=2; //fall
|
||||
drops[j].col=255;
|
||||
}
|
||||
}
|
||||
if (drops[j].colIndex > 1) { // falling
|
||||
if (drops[j].pos > 0) { // fall until end of segment
|
||||
drops[j].pos += drops[j].vel;
|
||||
if (drops[j].pos < 0) drops[j].pos = 0;
|
||||
drops[j].vel += gravity; // gravity is negative
|
||||
|
||||
if (drops[idx].colIndex > 2) { // during bounce, some water is on the floor
|
||||
col = color_blend(SEGCOLOR(0), BLACK, drops[idx].col);
|
||||
if (strip.isMatrix) SEGMENT.setPixelColorXY(k, rows - 1, col);
|
||||
else SEGMENT.setPixelColor(0, col);
|
||||
}
|
||||
} else { // we hit bottom
|
||||
if (drops[idx].colIndex > 2) { // already hit once, so back to forming
|
||||
drops[idx].colIndex = 0;
|
||||
drops[idx].col = sourcedrop;
|
||||
|
||||
} else {
|
||||
for (int i=1;i<7-drops[j].colIndex;i++) { // some minor math so we don't expand bouncing droplets
|
||||
uint16_t pos = constrain(uint16_t(drops[j].pos) +i, 0, SEGLEN-1); //this is BAD, returns a pos >= SEGLEN occasionally
|
||||
SEGMENT.setPixelColor(indexToVStrip(pos, stripNr), color_blend(BLACK,SEGCOLOR(0),drops[j].col/i)); //spread pixel with fade while falling
|
||||
}
|
||||
|
||||
if (drops[idx].colIndex == 2) { // init bounce
|
||||
drops[idx].vel = -drops[idx].vel/4;// reverse velocity with damping
|
||||
drops[idx].pos += drops[idx].vel;
|
||||
}
|
||||
drops[idx].col = sourcedrop*2;
|
||||
drops[idx].colIndex = 5; // bouncing
|
||||
if (drops[j].colIndex > 2) { // during bounce, some water is on the floor
|
||||
SEGMENT.setPixelColor(indexToVStrip(0, stripNr), color_blend(SEGCOLOR(0),BLACK,drops[j].col));
|
||||
}
|
||||
} else { // we hit bottom
|
||||
if (drops[j].colIndex > 2) { // already hit once, so back to forming
|
||||
drops[j].colIndex = 0;
|
||||
drops[j].col = sourcedrop;
|
||||
|
||||
} else {
|
||||
|
||||
if (drops[j].colIndex==2) { // init bounce
|
||||
drops[j].vel = -drops[j].vel/4;// reverse velocity with damping
|
||||
drops[j].pos += drops[j].vel;
|
||||
}
|
||||
drops[j].col = sourcedrop*2;
|
||||
drops[j].colIndex = 5; // bouncing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (int stripNr=0; stripNr<strips; stripNr++)
|
||||
virtualStrip::runStrip(stripNr, &drops[stripNr*maxNumDrops]);
|
||||
|
||||
return FRAMETIME;
|
||||
}
|
||||
static const char _data_FX_MODE_DRIP[] PROGMEM = "Drip@Gravity,# of drips;!,!;!;1d,2d";
|
||||
static const char _data_FX_MODE_DRIP[] PROGMEM = "Drip@Gravity,# of drips;!,!;!;mp12=1,1d"; //bar
|
||||
|
||||
|
||||
/*
|
||||
@ -3493,7 +3487,7 @@ uint16_t mode_tetrix(void) {
|
||||
if (SEGENV.call == 0) {
|
||||
drop->stack = 0; // reset brick stack size
|
||||
drop->step = 0;
|
||||
//for (int i=0; i<SEGLEN; i++) SEGMENT.setPixelColor(i | int((stripNr+1)<<16), SEGCOLOR(1)); // will fill virtual strip only
|
||||
//for (int i=0; i<SEGLEN; i++) SEGMENT.setPixelColor(indexToVStrip(i, stripNr), SEGCOLOR(1)); // will fill virtual strip only
|
||||
}
|
||||
|
||||
if (drop->step == 0) { // init brick
|
||||
@ -3521,7 +3515,7 @@ uint16_t mode_tetrix(void) {
|
||||
if (uint16_t(drop->pos) < drop->stack) drop->pos = drop->stack;
|
||||
for (int i=int(drop->pos); i<SEGLEN; i++) {
|
||||
uint32_t col = i<int(drop->pos)+drop->brick ? SEGMENT.color_from_palette(drop->col, false, false, 0) : SEGCOLOR(1);
|
||||
SEGMENT.setPixelColor(i | int((stripNr+1)<<16), col);
|
||||
SEGMENT.setPixelColor(indexToVStrip(i, stripNr), col);
|
||||
}
|
||||
} else { // we hit bottom
|
||||
drop->step = 0; // proceed with next brick, go back to init
|
||||
@ -3534,7 +3528,7 @@ uint16_t mode_tetrix(void) {
|
||||
drop->brick = 0; // reset brick size (no more growing)
|
||||
if (drop->step > millis()) {
|
||||
// allow fading of virtual strip
|
||||
for (int i=0; i<SEGLEN; i++) SEGMENT.blendPixelColor(i | int((stripNr+1)<<16), SEGCOLOR(1), 25); // 10% blend with Bg color
|
||||
for (int i=0; i<SEGLEN; i++) SEGMENT.blendPixelColor(indexToVStrip(i, stripNr), SEGCOLOR(1), 25); // 10% blend with Bg color
|
||||
} else {
|
||||
drop->stack = 0; // reset brick stack size
|
||||
drop->step = 0; // proceed with next brick
|
||||
|
Loading…
Reference in New Issue
Block a user