FX updates:

- Ripple (2D & no Bg)
- Glitter (no Bg)
- Sparkle (no Bg)
- Scan (no Bg)
- Two dots (no Bg)
- ICU (no Bg)
- Lightning (no Bg)
- Halloween eyes (no Bg)
- Spots (no Bg)
- Bouncing Balls (no BG)
- Popcorn (no Bg)
- Starburst (no Bg)
- Drip (no Bg)
- Whitespace cleanup
- draw_circle()

"no Bg" will allow overlapping segments if checked.
This commit is contained in:
Blaž Kristan 2023-01-06 09:10:39 +01:00
parent 98be19b29f
commit c7eccfb714
4 changed files with 317 additions and 282 deletions

View File

@ -378,7 +378,7 @@ uint16_t scan(bool dual)
uint16_t size = 1 + ((SEGMENT.intensity * SEGLEN) >> 9); uint16_t size = 1 + ((SEGMENT.intensity * SEGLEN) >> 9);
uint16_t ledIndex = (prog * ((SEGLEN *2) - size *2)) >> 16; uint16_t ledIndex = (prog * ((SEGLEN *2) - size *2)) >> 16;
SEGMENT.fill(SEGCOLOR(1)); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
int led_offset = ledIndex - (SEGLEN - size); int led_offset = ledIndex - (SEGLEN - size);
led_offset = abs(led_offset); led_offset = abs(led_offset);
@ -404,7 +404,7 @@ uint16_t scan(bool dual)
uint16_t mode_scan(void) { uint16_t mode_scan(void) {
return scan(false); return scan(false);
} }
static const char _data_FX_MODE_SCAN[] PROGMEM = "Scan@!,# of dots;!,!,!;!"; static const char _data_FX_MODE_SCAN[] PROGMEM = "Scan@!,# of dots,,,,,No Bg;!,!,!;!";
/* /*
@ -413,7 +413,7 @@ static const char _data_FX_MODE_SCAN[] PROGMEM = "Scan@!,# of dots;!,!,!;!";
uint16_t mode_dual_scan(void) { uint16_t mode_dual_scan(void) {
return scan(true); return scan(true);
} }
static const char _data_FX_MODE_DUAL_SCAN[] PROGMEM = "Scan Dual@!,# of dots;!,!,!;!"; static const char _data_FX_MODE_DUAL_SCAN[] PROGMEM = "Scan Dual@!,# of dots,,,,,No Bg;!,!,!;!";
/* /*
@ -530,6 +530,7 @@ uint16_t running_base(bool saw, bool dual=false) {
} }
SEGMENT.setPixelColor(i, ca); SEGMENT.setPixelColor(i, ca);
} }
return FRAMETIME; return FRAMETIME;
} }
@ -567,7 +568,6 @@ static const char _data_FX_MODE_SAW[] PROGMEM = "Saw@!,Width;!,!;!";
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
*/ */
uint16_t mode_twinkle(void) { uint16_t mode_twinkle(void) {
//SEGMENT.fill(SEGCOLOR(1));
SEGMENT.fade_out(224); SEGMENT.fade_out(224);
uint32_t cycleTime = 20 + (255 - SEGMENT.speed)*5; uint32_t cycleTime = 20 + (255 - SEGMENT.speed)*5;
@ -659,7 +659,7 @@ static const char _data_FX_MODE_DISSOLVE_RANDOM[] PROGMEM = "Dissolve Rnd@Repeat
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
*/ */
uint16_t mode_sparkle(void) { uint16_t mode_sparkle(void) {
for(int i = 0; i < SEGLEN; i++) { if (!SEGMENT.check2) for(int i = 0; i < SEGLEN; i++) {
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1));
} }
uint32_t cycleTime = 10 + (255 - SEGMENT.speed)*2; uint32_t cycleTime = 10 + (255 - SEGMENT.speed)*2;
@ -673,7 +673,7 @@ uint16_t mode_sparkle(void) {
SEGMENT.setPixelColor(SEGENV.aux0, SEGCOLOR(0)); SEGMENT.setPixelColor(SEGENV.aux0, SEGCOLOR(0));
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_SPARKLE[] PROGMEM = "Sparkle@!;!,!;!;;m12=0"; static const char _data_FX_MODE_SPARKLE[] PROGMEM = "Sparkle@!,,,,,,No Bg;!,!;!;;m12=0";
/* /*
@ -681,7 +681,7 @@ static const char _data_FX_MODE_SPARKLE[] PROGMEM = "Sparkle@!;!,!;!;;m12=0";
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
*/ */
uint16_t mode_flash_sparkle(void) { uint16_t mode_flash_sparkle(void) {
for(uint16_t i = 0; i < SEGLEN; i++) { if (!SEGMENT.check2) for(uint16_t i = 0; i < SEGLEN; i++) {
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
} }
@ -694,7 +694,7 @@ uint16_t mode_flash_sparkle(void) {
} }
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_FLASH_SPARKLE[] PROGMEM = "Sparkle Dark@!,!;Bg,Fx;!;;m12=0"; static const char _data_FX_MODE_FLASH_SPARKLE[] PROGMEM = "Sparkle Dark@!,!,,,,,No Bg;Bg,Fx;!;;m12=0";
/* /*
@ -702,7 +702,7 @@ static const char _data_FX_MODE_FLASH_SPARKLE[] PROGMEM = "Sparkle Dark@!,!;Bg,F
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
*/ */
uint16_t mode_hyper_sparkle(void) { uint16_t mode_hyper_sparkle(void) {
for (int i = 0; i < SEGLEN; i++) { if (!SEGMENT.check2) for (int i = 0; i < SEGLEN; i++) {
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
} }
@ -717,7 +717,7 @@ uint16_t mode_hyper_sparkle(void) {
} }
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_HYPER_SPARKLE[] PROGMEM = "Sparkle+@!,!;Bg,Fx;!;;m12=0"; static const char _data_FX_MODE_HYPER_SPARKLE[] PROGMEM = "Sparkle+@!,!,,,,,No Bg;Bg,Fx;!;;m12=0";
/* /*
@ -1366,12 +1366,12 @@ uint16_t police_base(uint32_t color1, uint32_t color2)
//Police Lights with custom colors //Police Lights with custom colors
uint16_t mode_two_dots() uint16_t mode_two_dots()
{ {
SEGMENT.fill(SEGCOLOR(2)); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(2));
uint32_t color2 = (SEGCOLOR(1) == SEGCOLOR(2)) ? SEGCOLOR(0) : SEGCOLOR(1); uint32_t color2 = (SEGCOLOR(1) == SEGCOLOR(2)) ? SEGCOLOR(0) : SEGCOLOR(1);
return police_base(SEGCOLOR(0), color2); return police_base(SEGCOLOR(0), color2);
} }
static const char _data_FX_MODE_TWO_DOTS[] PROGMEM = "Two Dots@!,Dot size;1,2,Bg;!"; static const char _data_FX_MODE_TWO_DOTS[] PROGMEM = "Two Dots@!,Dot size,,,,,No Bg;1,2,Bg;!";
/* /*
@ -1549,7 +1549,7 @@ uint16_t mode_icu(void) {
uint16_t dest = SEGENV.step & 0xFFFF; uint16_t dest = SEGENV.step & 0xFFFF;
uint8_t space = (SEGMENT.intensity >> 3) +2; uint8_t space = (SEGMENT.intensity >> 3) +2;
SEGMENT.fill(SEGCOLOR(1)); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
byte pindex = map(dest, 0, SEGLEN-SEGLEN/space, 0, 255); byte pindex = map(dest, 0, SEGLEN-SEGLEN/space, 0, 255);
uint32_t col = SEGMENT.color_from_palette(pindex, false, false, 0); uint32_t col = SEGMENT.color_from_palette(pindex, false, false, 0);
@ -1580,7 +1580,7 @@ uint16_t mode_icu(void) {
return SPEED_FORMULA_L; return SPEED_FORMULA_L;
} }
static const char _data_FX_MODE_ICU[] PROGMEM = "ICU@!,!;!,!;!"; static const char _data_FX_MODE_ICU[] PROGMEM = "ICU@!,!,,,,,No Bg;!,!;!";
/* /*
@ -1823,7 +1823,7 @@ uint16_t mode_lightning(void)
SEGENV.aux0 = 200; //200ms delay after leader SEGENV.aux0 = 200; //200ms delay after leader
} }
SEGMENT.fill(SEGCOLOR(1)); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
if (SEGENV.aux1 > 3 && !(SEGENV.aux1 & 0x01)) { //flash on even number >2 if (SEGENV.aux1 > 3 && !(SEGENV.aux1 & 0x01)) { //flash on even number >2
for (int i = ledstart; i < ledstart + ledlen; i++) for (int i = ledstart; i < ledstart + ledlen; i++)
@ -1848,7 +1848,7 @@ uint16_t mode_lightning(void)
} }
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_LIGHTNING[] PROGMEM = "Lightning@!,!;!,!;!"; static const char _data_FX_MODE_LIGHTNING[] PROGMEM = "Lightning@!,!,,,,,No Bg;!,!;!";
// Pride2015 // Pride2015
@ -1892,6 +1892,7 @@ uint16_t mode_pride_2015(void)
} }
SEGENV.step = sPseudotime; SEGENV.step = sPseudotime;
SEGENV.aux0 = sHue16; SEGENV.aux0 = sHue16;
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_PRIDE_2015[] PROGMEM = "Pride 2015@!;;"; static const char _data_FX_MODE_PRIDE_2015[] PROGMEM = "Pride 2015@!;;";
@ -1929,9 +1930,10 @@ uint16_t mode_palette()
uint8_t colorIndex = (i * 255 / SEGLEN) - counter; uint8_t colorIndex = (i * 255 / SEGLEN) - counter;
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(colorIndex, false, noWrap, 255)); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(colorIndex, false, noWrap, 255));
} }
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Cycle speed;;!"; static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Cycle speed;;!;;c3=0,o2=0";
// WLED limitation: Analog Clock overlay will NOT work when Fire2012 is active // WLED limitation: Analog Clock overlay will NOT work when Fire2012 is active
@ -2069,6 +2071,7 @@ uint16_t mode_colorwaves()
} }
SEGENV.step = sPseudotime; SEGENV.step = sPseudotime;
SEGENV.aux0 = sHue16; SEGENV.aux0 = sHue16;
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_COLORWAVES[] PROGMEM = "Colorwaves@!,Hue;!;!"; static const char _data_FX_MODE_COLORWAVES[] PROGMEM = "Colorwaves@!,Hue;!;!";
@ -2085,6 +2088,7 @@ uint16_t mode_bpm()
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); //SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(stp + (i * 2), false, PALETTE_SOLID_WRAP, 0, beat - stp + (i * 10))); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(stp + (i * 2), false, PALETTE_SOLID_WRAP, 0, beat - stp + (i * 10)));
} }
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_BPM[] PROGMEM = "Bpm@!;!;!;;sx=64"; static const char _data_FX_MODE_BPM[] PROGMEM = "Bpm@!;!;!;;sx=64";
@ -2267,6 +2271,7 @@ uint16_t mode_lake() {
//SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); //SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, false, 0, lum)); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, false, 0, lum));
} }
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_LAKE[] PROGMEM = "Lake@!;Fx;!"; static const char _data_FX_MODE_LAKE[] PROGMEM = "Lake@!;Fx;!";
@ -2396,7 +2401,7 @@ typedef struct Ripple {
#else #else
#define MAX_RIPPLES 100 #define MAX_RIPPLES 100
#endif #endif
uint16_t ripple_base(bool rainbow) uint16_t ripple_base()
{ {
uint16_t maxRipples = min(1 + (SEGLEN >> 2), MAX_RIPPLES); // 56 max for 16 segment ESP8266 uint16_t maxRipples = min(1 + (SEGLEN >> 2), MAX_RIPPLES); // 56 max for 16 segment ESP8266
uint16_t dataSize = sizeof(ripple) * maxRipples; uint16_t dataSize = sizeof(ripple) * maxRipples;
@ -2405,80 +2410,74 @@ uint16_t ripple_base(bool rainbow)
Ripple* ripples = reinterpret_cast<Ripple*>(SEGENV.data); Ripple* ripples = reinterpret_cast<Ripple*>(SEGENV.data);
// ranbow background or chosen background, all very dim.
if (rainbow) {
if (SEGENV.call ==0) {
SEGENV.aux0 = random8();
SEGENV.aux1 = random8();
}
if (SEGENV.aux0 == SEGENV.aux1) {
SEGENV.aux1 = random8();
}
else if (SEGENV.aux1 > SEGENV.aux0) {
SEGENV.aux0++;
} else {
SEGENV.aux0--;
}
SEGMENT.fill(color_blend(SEGMENT.color_wheel(SEGENV.aux0),BLACK,235));
} else {
SEGMENT.fill(SEGCOLOR(1));
}
//draw wave //draw wave
for (int i = 0; i < maxRipples; i++) for (int i = 0; i < maxRipples; i++) {
{
uint16_t ripplestate = ripples[i].state; uint16_t ripplestate = ripples[i].state;
if (ripplestate) if (ripplestate) {
{
uint8_t rippledecay = (SEGMENT.speed >> 4) +1; //faster decay if faster propagation uint8_t rippledecay = (SEGMENT.speed >> 4) +1; //faster decay if faster propagation
uint16_t rippleorigin = ripples[i].pos; uint16_t rippleorigin = ripples[i].pos;
uint32_t col = SEGMENT.color_from_palette(ripples[i].color, false, false, 255); uint32_t col = SEGMENT.color_from_palette(ripples[i].color, false, false, 255);
uint16_t propagation = ((ripplestate/rippledecay -1) * SEGMENT.speed); uint16_t propagation = ((ripplestate/rippledecay - 1) * (SEGMENT.speed + 1));
int16_t propI = propagation >> 8; int16_t propI = propagation >> 8;
uint8_t propF = propagation & 0xFF; uint8_t propF = propagation & 0xFF;
int16_t left = rippleorigin - propI -1;
uint8_t amp = (ripplestate < 17) ? triwave8((ripplestate-1)*8) : map(ripplestate,17,255,255,2); uint8_t amp = (ripplestate < 17) ? triwave8((ripplestate-1)*8) : map(ripplestate,17,255,255,2);
for (int16_t v = left; v < left +4; v++) #ifndef WLED_DISABLE_2D
if (SEGMENT.is2D()) {
uint16_t cx = rippleorigin >> 8;
uint16_t cy = rippleorigin & 0xFF;
uint8_t mag = scale8(cubicwave8((propF>>2)), amp);
if (propI > 0) SEGMENT.draw_circle(cx, cy, propI, color_blend(SEGMENT.getPixelColorXY(cx + propI, cy), col, mag));
} else
#endif
{ {
int16_t left = rippleorigin - propI -1;
for (int16_t v = left; v < left +4; v++) {
uint8_t mag = scale8(cubicwave8((propF>>2)+(v-left)*64), amp); uint8_t mag = scale8(cubicwave8((propF>>2)+(v-left)*64), amp);
if (v < SEGLEN && v >= 0)
{
SEGMENT.setPixelColor(v, color_blend(SEGMENT.getPixelColor(v), col, mag)); // TODO SEGMENT.setPixelColor(v, color_blend(SEGMENT.getPixelColor(v), col, mag)); // TODO
}
int16_t w = left + propI*2 + 3 -(v-left); int16_t w = left + propI*2 + 3 -(v-left);
if (w < SEGLEN && w >= 0)
{
SEGMENT.setPixelColor(w, color_blend(SEGMENT.getPixelColor(w), col, mag)); // TODO SEGMENT.setPixelColor(w, color_blend(SEGMENT.getPixelColor(w), col, mag)); // TODO
} }
} }
ripplestate += rippledecay; ripplestate += rippledecay;
ripples[i].state = (ripplestate > 254) ? 0 : ripplestate; ripples[i].state = (ripplestate > 254) ? 0 : ripplestate;
} else //randomly create new wave } else {//randomly create new wave
{ if (random16(IBN + 10000) <= SEGMENT.intensity) {
if (random16(IBN + 10000) <= SEGMENT.intensity)
{
ripples[i].state = 1; ripples[i].state = 1;
ripples[i].pos = random16(SEGLEN); ripples[i].pos = SEGMENT.is2D() ? ((random8(SEGENV.virtualWidth())<<8) | (random8(SEGENV.virtualHeight()))) : random16(SEGLEN);
ripples[i].color = random8(); //color ripples[i].color = random8(); //color
} }
} }
} }
return FRAMETIME; return FRAMETIME;
} }
#undef MAX_RIPPLES #undef MAX_RIPPLES
uint16_t mode_ripple(void) { uint16_t mode_ripple(void) {
if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
return ripple_base(false); return ripple_base(false);
} }
static const char _data_FX_MODE_RIPPLE[] PROGMEM = "Ripple@!,Wave #;,!;!"; static const char _data_FX_MODE_RIPPLE[] PROGMEM = "Ripple@!,Wave #,,,,,No Bg;,!;!;12";
uint16_t mode_ripple_rainbow(void) { uint16_t mode_ripple_rainbow(void) {
if (SEGENV.call ==0) {
SEGENV.aux0 = random8();
SEGENV.aux1 = random8();
}
if (SEGENV.aux0 == SEGENV.aux1) {
SEGENV.aux1 = random8();
} else if (SEGENV.aux1 > SEGENV.aux0) {
SEGENV.aux0++;
} else {
SEGENV.aux0--;
}
SEGMENT.fill(color_blend(SEGMENT.color_wheel(SEGENV.aux0),BLACK,235));
return ripple_base(true); return ripple_base(true);
} }
static const char _data_FX_MODE_RIPPLE_RAINBOW[] PROGMEM = "Ripple Rainbow@!,Wave #;;!"; static const char _data_FX_MODE_RIPPLE_RAINBOW[] PROGMEM = "Ripple Rainbow@!,Wave #;;!;12";
// TwinkleFOX by Mark Kriegsman: https://gist.github.com/kriegsman/756ea6dcae8e30845b5a // TwinkleFOX by Mark Kriegsman: https://gist.github.com/kriegsman/756ea6dcae8e30845b5a
@ -2634,7 +2633,7 @@ uint16_t mode_halloween_eyes()
uint16_t eyeLength = (2*HALLOWEEN_EYE_WIDTH) + HALLOWEEN_EYE_SPACE; uint16_t eyeLength = (2*HALLOWEEN_EYE_WIDTH) + HALLOWEEN_EYE_SPACE;
if (eyeLength >= maxWidth) return mode_static(); //bail if segment too short if (eyeLength >= maxWidth) return mode_static(); //bail if segment too short
SEGMENT.fill(SEGCOLOR(1)); //fill background if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); //fill background
uint8_t state = SEGENV.aux1 >> 8; uint8_t state = SEGENV.aux1 >> 8;
uint16_t stateTime = SEGENV.call; uint16_t stateTime = SEGENV.call;
@ -2684,7 +2683,7 @@ uint16_t mode_halloween_eyes()
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_HALLOWEEN_EYES[] PROGMEM = "Halloween Eyes@Duration,Eye fade time;!,!;!;12"; static const char _data_FX_MODE_HALLOWEEN_EYES[] PROGMEM = "Halloween Eyes@Duration,Eye fade time,,,,,No Bg;!,!;!;12";
//Speed slider sets amount of LEDs lit, intensity sets unlit //Speed slider sets amount of LEDs lit, intensity sets unlit
@ -2737,7 +2736,7 @@ static const char _data_FX_MODE_TRI_STATIC_PATTERN[] PROGMEM = "Solid Pattern Tr
uint16_t spots_base(uint16_t threshold) uint16_t spots_base(uint16_t threshold)
{ {
SEGMENT.fill(SEGCOLOR(1)); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
uint16_t maxZones = SEGLEN >> 2; uint16_t maxZones = SEGLEN >> 2;
uint16_t zones = 1 + ((SEGMENT.intensity * maxZones) >> 8); uint16_t zones = 1 + ((SEGMENT.intensity * maxZones) >> 8);
@ -2767,7 +2766,7 @@ uint16_t mode_spots()
{ {
return spots_base((255 - SEGMENT.speed) << 8); return spots_base((255 - SEGMENT.speed) << 8);
} }
static const char _data_FX_MODE_SPOTS[] PROGMEM = "Spots@,Width;!,!;!"; static const char _data_FX_MODE_SPOTS[] PROGMEM = "Spots@,Width,,,,,No Bg;!,!;!";
//Intensity slider sets number of "lights", LEDs per light fade in and out //Intensity slider sets number of "lights", LEDs per light fade in and out
@ -2778,7 +2777,7 @@ uint16_t mode_spots_fade()
uint16_t tr = (t >> 1) + (t >> 2); uint16_t tr = (t >> 1) + (t >> 2);
return spots_base(tr); return spots_base(tr);
} }
static const char _data_FX_MODE_SPOTS_FADE[] PROGMEM = "Spots Fade@Spread,Width;!,!;!"; static const char _data_FX_MODE_SPOTS_FADE[] PROGMEM = "Spots Fade@Spread,Width,,,,,No Bg;!,!;!";
//each needs 12 bytes //each needs 12 bytes
@ -2800,7 +2799,7 @@ uint16_t mode_bouncing_balls(void) {
Ball* balls = reinterpret_cast<Ball*>(SEGENV.data); Ball* balls = reinterpret_cast<Ball*>(SEGENV.data);
SEGMENT.fill(SEGCOLOR(2) ? BLACK : SEGCOLOR(1)); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(2) ? BLACK : SEGCOLOR(1));
// virtualStrip idea by @ewowi (Ewoud Wijma) // virtualStrip idea by @ewowi (Ewoud Wijma)
// requires virtual strip # to be embedded into upper 16 bits of index in setPixelColor() // requires virtual strip # to be embedded into upper 16 bits of index in setPixelColor()
@ -2857,7 +2856,7 @@ uint16_t mode_bouncing_balls(void) {
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_BOUNCINGBALLS[] PROGMEM = "Bouncing Balls@Gravity,# of balls;!,!,!;!;1;m12=1"; //bar static const char _data_FX_MODE_BOUNCINGBALLS[] PROGMEM = "Bouncing Balls@Gravity,# of balls,,,,,No Bg;!,!,!;!;1;m12=1"; //bar
/* /*
@ -2915,19 +2914,35 @@ uint16_t mode_sinelon_rainbow(void) {
static const char _data_FX_MODE_SINELON_RAINBOW[] PROGMEM = "Sinelon Rainbow@!,Trail;,,!;!"; static const char _data_FX_MODE_SINELON_RAINBOW[] PROGMEM = "Sinelon Rainbow@!,Trail;,,!;!";
// utility function that will add random glitter to SEGMENT
void glitter_base(uint8_t intensity, uint32_t col = ULTRAWHITE) {
if (intensity > random8()) {
if (SEGMENT.is2D()) {
SEGMENT.setPixelColorXY(random16(SEGMENT.virtualWidth()),random16(SEGMENT.virtualHeight()), col);
} else {
SEGMENT.setPixelColor(random16(SEGLEN), col);
}
}
}
//Rainbow with glitter, inspired by https://gist.github.com/kriegsman/062e10f7f07ba8518af6 //Rainbow with glitter, inspired by https://gist.github.com/kriegsman/062e10f7f07ba8518af6
uint16_t mode_glitter() uint16_t mode_glitter()
{ {
mode_palette(); if (!SEGMENT.check2) mode_palette();
glitter_base(SEGMENT.intensity)
if (SEGMENT.intensity > random8())
{
SEGMENT.setPixelColor(random16(SEGLEN), ULTRAWHITE);
}
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_GLITTER[] PROGMEM = "Glitter@!,!;;!;;m12=0"; //pixels static const char _data_FX_MODE_GLITTER[] PROGMEM = "Glitter@!,!,,,,,No Bg;;!;;m12=0"; //pixels
//Solid colour background with glitter
uint16_t mode_solid_glitter()
{
SEGMENT.fill(SEGCOLOR(0));
glitter_base(SEGMENT.intensity, SEGCOLOR(1));
return FRAMETIME;
}
static const char _data_FX_MODE_SOLID_GLITTER[] PROGMEM = "Solid Glitter@,!;Bg,Glitter color!;;;m12=0";
//each needs 19 bytes //each needs 19 bytes
@ -2953,7 +2968,7 @@ uint16_t mode_popcorn(void) {
Spark* popcorn = reinterpret_cast<Spark*>(SEGENV.data); Spark* popcorn = reinterpret_cast<Spark*>(SEGENV.data);
bool hasCol2 = SEGCOLOR(2); bool hasCol2 = SEGCOLOR(2);
SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1)); if (!SEGMENT.check2) SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1));
struct virtualStrip { struct virtualStrip {
static void runStrip(uint16_t stripNr, Spark* popcorn) { static void runStrip(uint16_t stripNr, Spark* popcorn) {
@ -3000,7 +3015,7 @@ uint16_t mode_popcorn(void) {
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_POPCORN[] PROGMEM = "Popcorn@!,!;!,!,!;!;;m12=1"; //bar static const char _data_FX_MODE_POPCORN[] PROGMEM = "Popcorn@!,!,,,,,No Bg;!,!,!;!;;m12=1"; //bar
//values close to 100 produce 5Hz flicker, which looks very candle-y //values close to 100 produce 5Hz flicker, which looks very candle-y
@ -3162,7 +3177,7 @@ uint16_t mode_starburst(void) {
} }
} }
SEGMENT.fill(SEGCOLOR(1)); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
for (int j=0; j<numStars; j++) for (int j=0; j<numStars; j++)
{ {
@ -3227,7 +3242,7 @@ uint16_t mode_starburst(void) {
return FRAMETIME; return FRAMETIME;
} }
#undef STARBURST_MAX_FRAG #undef STARBURST_MAX_FRAG
static const char _data_FX_MODE_STARBURST[] PROGMEM = "Fireworks Starburst@Chance,Fragments;,!;!;;pal=11,m12=0"; static const char _data_FX_MODE_STARBURST[] PROGMEM = "Fireworks Starburst@Chance,Fragments,,,,,No Bg;,!;!;;pal=11,m12=0";
/* /*
@ -3258,7 +3273,6 @@ uint16_t mode_exploding_fireworks(void)
SEGENV.aux1 = dataSize; SEGENV.aux1 = dataSize;
} }
//SEGMENT.fill(BLACK);
SEGMENT.fade_out(252); SEGMENT.fade_out(252);
Spark* sparks = reinterpret_cast<Spark*>(SEGENV.data); Spark* sparks = reinterpret_cast<Spark*>(SEGENV.data);
@ -3379,7 +3393,7 @@ uint16_t mode_drip(void)
if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed
Spark* drops = reinterpret_cast<Spark*>(SEGENV.data); Spark* drops = reinterpret_cast<Spark*>(SEGENV.data);
SEGMENT.fill(SEGCOLOR(1)); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1));
struct virtualStrip { struct virtualStrip {
static void runStrip(uint16_t stripNr, Spark* drops) { static void runStrip(uint16_t stripNr, Spark* drops) {
@ -3449,7 +3463,7 @@ uint16_t mode_drip(void)
return FRAMETIME; return FRAMETIME;
} }
static const char _data_FX_MODE_DRIP[] PROGMEM = "Drip@Gravity,# of drips;!,!;!;;m12=1"; //bar static const char _data_FX_MODE_DRIP[] PROGMEM = "Drip@Gravity,# of drips,,,,,No Bg;!,!;!;;m12=1"; //bar
/* /*
@ -3472,7 +3486,7 @@ uint16_t mode_tetrix(void) {
if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed
Tetris* drops = reinterpret_cast<Tetris*>(SEGENV.data); Tetris* drops = reinterpret_cast<Tetris*>(SEGENV.data);
if (SEGENV.call == 0) SEGMENT.fill(SEGCOLOR(1)); // will fill entire segment (1D or 2D) //if (SEGENV.call == 0) SEGMENT.fill(SEGCOLOR(1)); // will fill entire segment (1D or 2D), then use drop->step = 0 below
// virtualStrip idea by @ewowi (Ewoud Wijma) // virtualStrip idea by @ewowi (Ewoud Wijma)
// requires virtual strip # to be embedded into upper 16 bits of index in setPixelcolor() // requires virtual strip # to be embedded into upper 16 bits of index in setPixelcolor()
@ -3482,9 +3496,8 @@ uint16_t mode_tetrix(void) {
// initialize dropping on first call or segment full // initialize dropping on first call or segment full
if (SEGENV.call == 0) { if (SEGENV.call == 0) {
drop->stack = 0; // reset brick stack size drop->stack = 0; // reset brick stack size
drop->step = 0; drop->step = millis() + 2000; // start by fading out strip
if (SEGMENT.check1) drop->col = 0;// use only one color from palette if (SEGMENT.check1) drop->col = 0;// use only one color from palette
//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 if (drop->step == 0) { // init brick
@ -3772,21 +3785,6 @@ uint16_t mode_pacifica()
static const char _data_FX_MODE_PACIFICA[] PROGMEM = "Pacifica@!,Angle;;!;;pal=51"; static const char _data_FX_MODE_PACIFICA[] PROGMEM = "Pacifica@!,Angle;;!;;pal=51";
//Solid colour background with glitter
uint16_t mode_solid_glitter()
{
SEGMENT.fill(SEGCOLOR(0));
if (SEGMENT.intensity > random8())
{
SEGMENT.setPixelColor(random16(SEGLEN), ULTRAWHITE);
}
return FRAMETIME;
}
static const char _data_FX_MODE_SOLID_GLITTER[] PROGMEM = "Solid Glitter@,!;!;;;m12=0";
/* /*
* Mode simulates a gradual sunrise * Mode simulates a gradual sunrise
*/ */
@ -3800,7 +3798,7 @@ uint16_t mode_sunrise() {
SEGENV.aux0 = SEGMENT.speed; SEGENV.aux0 = SEGMENT.speed;
} }
SEGMENT.fill(0); SEGMENT.fill(BLACK);
uint16_t stage = 0xFFFF; uint16_t stage = 0xFFFF;
uint32_t s10SinceStart = (millis() - SEGENV.step) /100; //tenths of seconds uint32_t s10SinceStart = (millis() - SEGENV.step) /100; //tenths of seconds
@ -4001,7 +3999,6 @@ static const char _data_FX_MODE_FLOW[] PROGMEM = "Flow@!,Zones;;!;;m12=1"; //ver
*/ */
uint16_t mode_chunchun(void) uint16_t mode_chunchun(void)
{ {
//SEGMENT.fill(SEGCOLOR(1));
SEGMENT.fade_out(254); // add a bit of trail SEGMENT.fade_out(254); // add a bit of trail
uint16_t counter = strip.now * (6 + (SEGMENT.speed >> 4)); uint16_t counter = strip.now * (6 + (SEGMENT.speed >> 4));
uint16_t numBirds = 2 + (SEGLEN >> 3); // 2 + 1/8 of a segment uint16_t numBirds = 2 + (SEGLEN >> 3); // 2 + 1/8 of a segment

View File

@ -588,6 +588,7 @@ typedef struct Segment {
void moveX(int8_t delta); void moveX(int8_t delta);
void moveY(int8_t delta); void moveY(int8_t delta);
void move(uint8_t dir, uint8_t delta); void move(uint8_t dir, uint8_t delta);
void draw_circle(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 fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c);
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c); void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c);
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0)); } // automatic inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0)); } // automatic inline

View File

@ -428,6 +428,29 @@ void Segment::move(uint8_t dir, uint8_t delta) {
} }
} }
void Segment::draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
// Bresenhams Algorithm
int d = 3 - (2*radius);
int y = radius, x = 0;
while (y >= x) {
addPixelColorXY(cx+x, cy+y, col);
addPixelColorXY(cx-x, cy+y, col);
addPixelColorXY(cx+x, cy-y, col);
addPixelColorXY(cx-x, cy-y, col);
addPixelColorXY(cx+y, cy+x, col);
addPixelColorXY(cx-y, cy+x, col);
addPixelColorXY(cx+y, cy-x, col);
addPixelColorXY(cx-y, cy-x, col);
x++;
if (d > 0) {
y--;
d += 4 * (x - y) + 10;
} else {
d += 4 * x + 6;
}
}
}
// 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(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) {
const uint16_t cols = virtualWidth(); const uint16_t cols = virtualWidth();

View File

@ -574,6 +574,20 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
int y = roundf(cos_t(rad) * i); int y = roundf(cos_t(rad) * i);
setPixelColorXY(x, y, col); setPixelColorXY(x, y, col);
} }
// Bresenhams Algorithm
//int d = 3 - (2*i);
//int y = i, x = 0;
//while (y >= x) {
// setPixelColorXY(x, y, col);
// setPixelColorXY(y, x, col);
// x++;
// if (d > 0) {
// y--;
// d += 4 * (x - y) + 10;
// } else {
// d += 4 * x + 6;
// }
//}
} }
break; break;
case M12_pCorner: case M12_pCorner: