diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 2b7cd726..f1c861f7 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -604,22 +604,36 @@ static const char _data_FX_MODE_TWINKLE[] PROGMEM = "Twinkle@!,!;!,!;!;;m12=0"; * Dissolve function */ uint16_t dissolve(uint32_t color) { + uint16_t dataSize = (SEGLEN+7) >> 3; //1 bit per LED + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + + if (SEGENV.call == 0) { + memset(SEGMENT.data, 0xFF, dataSize); // start by fading pixels up + SEGENV.aux0 = 1; + } + for (int j = 0; j <= SEGLEN / 15; j++) { if (random8() <= SEGMENT.intensity) { - for (size_t times = 0; times < 10; times++) //attempt to spawn a new pixel 10 times - { - uint16_t i = random16(SEGLEN); + for (size_t times = 0; times < 10; times++) { //attempt to spawn a new pixel 10 times + unsigned i = random16(SEGLEN); + unsigned index = i >> 3; + unsigned bitNum = i & 0x07; + bool fadeUp = bitRead(SEGENV.data[index], bitNum); if (SEGENV.aux0) { //dissolve to primary/palette - if (SEGMENT.getPixelColor(i) == SEGCOLOR(1) /*|| wa*/) { + if (fadeUp) { if (color == SEGCOLOR(0)) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } else { SEGMENT.setPixelColor(i, color); } + bitWrite(SEGENV.data[index], bitNum, false); break; //only spawn 1 new pixel per frame per 50 LEDs } } else { //dissolve to secondary - if (SEGMENT.getPixelColor(i) != SEGCOLOR(1)) { SEGMENT.setPixelColor(i, SEGCOLOR(1)); break; } + if (!fadeUp) { + SEGMENT.setPixelColor(i, SEGCOLOR(1)); break; + bitWrite(SEGENV.data[index], bitNum, true); + } } } } @@ -628,6 +642,7 @@ uint16_t dissolve(uint32_t color) { if (SEGENV.step > (255 - SEGMENT.speed) + 15U) { SEGENV.aux0 = !SEGENV.aux0; SEGENV.step = 0; + memset(SEGMENT.data, (SEGENV.aux0 ? 0xFF : 0), dataSize); // switch fading } else { SEGENV.step++; }