From 37b984de8967123a8771853cee5b7fa701314e8f Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Fri, 23 Jan 2026 06:04:37 +0100 Subject: [PATCH 1/7] remove "return FRAMETIME" from all FX, fix timing for some FX - all FX now render every frame, no more "speed up" during transitions --- usermods/user_fx/README.md | 19 +- usermods/user_fx/user_fx.cpp | 6 +- wled00/FX.cpp | 1373 ++++++++++++++-------------------- wled00/FX.h | 4 +- wled00/FX_fcn.cpp | 10 +- wled00/FXparticleSystem.cpp | 5 +- wled00/FXparticleSystem.h | 2 +- 7 files changed, 577 insertions(+), 842 deletions(-) diff --git a/usermods/user_fx/README.md b/usermods/user_fx/README.md index 704b71df01..3d592fd071 100644 --- a/usermods/user_fx/README.md +++ b/usermods/user_fx/README.md @@ -81,7 +81,7 @@ Pre-loaded in this template is an example 2D Effect called "Diffusion Fire". (T The effect starts off by checking to see if the segment that the effect is being applied to is a 2D Matrix, and if it is not, then it returns the static effect which displays no pattern: ```cpp if (!strip.isMatrix || !SEGMENT.is2D()) -return mode_static(); // not a 2D set-up + mode_static(); // not a 2D set-up ``` The next code block contains several constant variable definitions which essentially serve to extract the dimensions of the user's 2D matrix and allow WLED to interpret the matrix as a 1D coordinate system (WLED must do this for all 2D animations): ```cpp @@ -128,7 +128,7 @@ unsigned dataSize = cols * rows; // SEGLEN (virtual length) is equivalent to vW ```cpp if (!SEGENV.allocateData(dataSize)) -return mode_static(); // allocation failed + mode_static(); // allocation failed ``` * Upon the first call, this section allocates a persistent data buffer tied to the segment environment (`SEGENV.data`). All subsequent calls simply ensure that the data is still valid. * The syntax `SEGENV.allocateData(n)` requests a buffer of size n bytes (1 byte per pixel here). @@ -250,20 +250,7 @@ After calculating tmp_row, we now handle rendering the pixels by updating the ac * `SEGCOLOR(0)` gets the first user-selected color for the segment. * The final line of code fades that base color according to the heat value (acts as brightness multiplier). -The final piece of this custom effect returns the frame time: -```cpp -} -return FRAMETIME; -} -``` -* The first bracket closes the earlier `if ((strip.now - SEGENV.step) >= refresh_ms)` block. - * It ensures that the fire simulation (scrolling, sparking, diffusion, rendering) only runs when enough time has passed since the last update. -* returning the frame time tells WLED how soon this effect wants to be called again. - * `FRAMETIME` is a predefined macro in WLED, typically set to ~16ms, corresponding to ~60 FPS (frames per second). - * Even though the effect logic itself controls when to update based on refresh_ms, WLED will still call this function at roughly FRAMETIME intervals to check whether an update is needed. -* ⚠️ Important: Because the actual frame logic is gated by strip.now - SEGENV.step, returning FRAMETIME here doesn’t cause excessive updates — it just keeps the engine responsive. **Also note that an Effect should ALWAYS return FRAMETIME. Not doing so can cause glitches.** -* The final bracket closes the `mode_diffusionfire()` function itself. - +* Even though the effect logic itself controls when to update based on refresh_ms, WLED will still call this function at roughly FRAMETIME intervals (the FPS limit set in config) to check whether an update is needed. If nothing needs to change, the frame still needs to be re-rendered so color or brightness transitions will be smooth. ### The Metadata String At the end of every effect is an important line of code called the **metadata string**. diff --git a/usermods/user_fx/user_fx.cpp b/usermods/user_fx/user_fx.cpp index da6937c87d..fddeb174f8 100644 --- a/usermods/user_fx/user_fx.cpp +++ b/usermods/user_fx/user_fx.cpp @@ -3,9 +3,8 @@ // for information how FX metadata strings work see https://kno.wled.ge/interfaces/json-api/#effect-metadata // static effect, used if an effect fails to initialize -static uint16_t mode_static(void) { +static void mode_static(void) { SEGMENT.fill(SEGCOLOR(0)); - return strip.isOffRefreshRequired() ? FRAMETIME : 350; } ///////////////////////// @@ -13,7 +12,7 @@ static uint16_t mode_static(void) { ///////////////////////// // Diffusion Fire: fire effect intended for 2D setups smaller than 16x16 -static uint16_t mode_diffusionfire(void) { +static void mode_diffusionfire(void) { if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up @@ -84,7 +83,6 @@ unsigned dataSize = cols * rows; // SEGLEN (virtual length) is equivalent to vW } } } - return FRAMETIME; } static const char _data_FX_MODE_DIFFUSIONFIRE[] PROGMEM = "Diffusion Fire@!,Spark rate,Diffusion Speed,Turbulence,,Use palette;;Color;;2;pal=35"; diff --git a/wled00/FX.cpp b/wled00/FX.cpp index d60c525261..82cc671f8f 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -131,20 +131,18 @@ static um_data_t* getAudioData() { /* * No blinking. Just plain old static light. */ -uint16_t mode_static(void) { +void mode_static(void) { SEGMENT.fill(SEGCOLOR(0)); - return strip.isOffRefreshRequired() ? FRAMETIME : 350; } static const char _data_FX_MODE_STATIC[] PROGMEM = "Solid"; /* * Copy a segment and perform (optional) color adjustments */ -uint16_t mode_copy_segment(void) { +void mode_copy_segment(void) { uint32_t sourceid = SEGMENT.custom3; if (sourceid >= strip.getSegmentsNum() || sourceid == strip.getCurrSegmentId()) { // invalid source SEGMENT.fadeToBlackBy(5); // fade out - return FRAMETIME; } Segment& sourcesegment = strip.getSegment(sourceid); @@ -184,7 +182,6 @@ uint16_t mode_copy_segment(void) { } } } - return FRAMETIME; } static const char _data_FX_MODE_COPY[] PROGMEM = "Copy Segment@,Color shift,Lighten,Brighten,ID,Axis(2D),FullStack(last frame);;;12;ix=0,c1=0,c2=0,c3=0"; @@ -194,7 +191,7 @@ static const char _data_FX_MODE_COPY[] PROGMEM = "Copy Segment@,Color shift,Ligh * Alternate between color1 and color2 * if(strobe == true) then create a strobe effect */ -uint16_t blink(uint32_t color1, uint32_t color2, bool strobe, bool do_palette) { +void blink(uint32_t color1, uint32_t color2, bool strobe, bool do_palette) { uint32_t cycleTime = (255 - SEGMENT.speed)*20; uint32_t onTime = FRAMETIME; if (!strobe) onTime += ((cycleTime * SEGMENT.intensity) >> 8); @@ -217,16 +214,14 @@ uint16_t blink(uint32_t color1, uint32_t color2, bool strobe, bool do_palette) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } } else SEGMENT.fill(color); - - return FRAMETIME; } /* * Normal blinking. Intensity sets duty cycle. */ -uint16_t mode_blink(void) { - return blink(SEGCOLOR(0), SEGCOLOR(1), false, true); +void mode_blink(void) { + blink(SEGCOLOR(0), SEGCOLOR(1), false, true); } static const char _data_FX_MODE_BLINK[] PROGMEM = "Blink@!,Duty cycle;!,!;!;01"; @@ -234,8 +229,8 @@ static const char _data_FX_MODE_BLINK[] PROGMEM = "Blink@!,Duty cycle;!,!;!;01"; /* * Classic Blink effect. Cycling through the rainbow. */ -uint16_t mode_blink_rainbow(void) { - return blink(SEGMENT.color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), false, false); +void mode_blink_rainbow(void) { + blink(SEGMENT.color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), false, false); } static const char _data_FX_MODE_BLINK_RAINBOW[] PROGMEM = "Blink Rainbow@Frequency,Blink duration;!,!;!;01"; @@ -243,7 +238,7 @@ static const char _data_FX_MODE_BLINK_RAINBOW[] PROGMEM = "Blink Rainbow@Frequen /* * Classic Strobe effect. */ -uint16_t mode_strobe(void) { +void mode_strobe(void) { return blink(SEGCOLOR(0), SEGCOLOR(1), true, true); } static const char _data_FX_MODE_STROBE[] PROGMEM = "Strobe@!;!,!;!;01"; @@ -252,7 +247,7 @@ static const char _data_FX_MODE_STROBE[] PROGMEM = "Strobe@!;!,!;!;01"; /* * Classic Strobe effect. Cycling through the rainbow. */ -uint16_t mode_strobe_rainbow(void) { +void mode_strobe_rainbow(void) { return blink(SEGMENT.color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), true, false); } static const char _data_FX_MODE_STROBE_RAINBOW[] PROGMEM = "Strobe Rainbow@!;,!;!;01"; @@ -263,8 +258,8 @@ static const char _data_FX_MODE_STROBE_RAINBOW[] PROGMEM = "Strobe Rainbow@!;,!; * LEDs are turned on (color1) in sequence, then turned off (color2) in sequence. * if (bool rev == true) then LEDs are turned off in reverse order */ -uint16_t color_wipe(bool rev, bool useRandomColors) { - if (SEGLEN <= 1) return mode_static(); +void color_wipe(bool rev, bool useRandomColors) { + if (SEGLEN <= 1) mode_static(); uint32_t cycleTime = 750 + (255 - SEGMENT.speed)*150; uint32_t perc = strip.now % cycleTime; unsigned prog = (perc * 65535) / cycleTime; @@ -311,15 +306,14 @@ uint16_t color_wipe(bool rev, bool useRandomColors) { if (i == ledIndex) SEGMENT.setPixelColor(index, color_blend(back? col0 : col1, back? col1 : col0, uint8_t(rem))); } } - return FRAMETIME; } /* * Lights all LEDs one after another. */ -uint16_t mode_color_wipe(void) { - return color_wipe(false, false); +void mode_color_wipe(void) { + color_wipe(false, false); } static const char _data_FX_MODE_COLOR_WIPE[] PROGMEM = "Wipe@!,!;!,!;!"; @@ -327,8 +321,8 @@ static const char _data_FX_MODE_COLOR_WIPE[] PROGMEM = "Wipe@!,!;!,!;!"; /* * Lights all LEDs one after another. Turns off opposite */ -uint16_t mode_color_sweep(void) { - return color_wipe(true, false); +void mode_color_sweep(void) { + color_wipe(true, false); } static const char _data_FX_MODE_COLOR_SWEEP[] PROGMEM = "Sweep@!,!;!,!;!"; @@ -337,8 +331,8 @@ static const char _data_FX_MODE_COLOR_SWEEP[] PROGMEM = "Sweep@!,!;!,!;!"; * Turns all LEDs after each other to a random color. * Then starts over with another color. */ -uint16_t mode_color_wipe_random(void) { - return color_wipe(false, true); +void mode_color_wipe_random(void) { + color_wipe(false, true); } static const char _data_FX_MODE_COLOR_WIPE_RANDOM[] PROGMEM = "Wipe Random@!;;!"; @@ -346,8 +340,8 @@ static const char _data_FX_MODE_COLOR_WIPE_RANDOM[] PROGMEM = "Wipe Random@!;;!" /* * Random color introduced alternating from start and end of strip. */ -uint16_t mode_color_sweep_random(void) { - return color_wipe(true, true); +void mode_color_sweep_random(void) { + color_wipe(true, true); } static const char _data_FX_MODE_COLOR_SWEEP_RANDOM[] PROGMEM = "Sweep Random@!;;!"; @@ -356,7 +350,7 @@ static const char _data_FX_MODE_COLOR_SWEEP_RANDOM[] PROGMEM = "Sweep Random@!;; * Lights all LEDs up in one random color. Then switches them * to the next random color. */ -uint16_t mode_random_color(void) { +void mode_random_color(void) { uint32_t cycleTime = 200 + (255 - SEGMENT.speed)*50; uint32_t it = strip.now / cycleTime; uint32_t rem = strip.now % cycleTime; @@ -380,7 +374,6 @@ uint16_t mode_random_color(void) { } SEGMENT.fill(color_blend(SEGMENT.color_wheel(SEGENV.aux1), SEGMENT.color_wheel(SEGENV.aux0), uint8_t(fade))); - return FRAMETIME; } static const char _data_FX_MODE_RANDOM_COLOR[] PROGMEM = "Random Colors@!,Fade time;;!;01"; @@ -389,8 +382,8 @@ static const char _data_FX_MODE_RANDOM_COLOR[] PROGMEM = "Random Colors@!,Fade t * Lights every LED in a random color. Changes all LED at the same time * to new random colors. */ -uint16_t mode_dynamic(void) { - if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed +void mode_dynamic(void) { + if (!SEGENV.allocateData(SEGLEN)) mode_static(); //allocation failed if(SEGENV.call == 0) { //SEGMENT.fill(BLACK); @@ -416,7 +409,6 @@ uint16_t mode_dynamic(void) { SEGMENT.setPixelColor(i, SEGMENT.color_wheel(SEGENV.data[i])); } } - return FRAMETIME; } static const char _data_FX_MODE_DYNAMIC[] PROGMEM = "Dynamic@!,!,,,,Smooth;;!"; @@ -424,12 +416,11 @@ static const char _data_FX_MODE_DYNAMIC[] PROGMEM = "Dynamic@!,!,,,,Smooth;;!"; /* * effect "Dynamic" with smooth color-fading */ -uint16_t mode_dynamic_smooth(void) { +void mode_dynamic_smooth(void) { bool old = SEGMENT.check1; SEGMENT.check1 = true; mode_dynamic(); SEGMENT.check1 = old; - return FRAMETIME; } static const char _data_FX_MODE_DYNAMIC_SMOOTH[] PROGMEM = "Dynamic Smooth@!,!;;!"; @@ -437,7 +428,7 @@ static const char _data_FX_MODE_DYNAMIC_SMOOTH[] PROGMEM = "Dynamic Smooth@!,!;; /* * Does the "standby-breathing" of well known i-Devices. */ -uint16_t mode_breath(void) { +void mode_breath(void) { unsigned var = 0; unsigned counter = (strip.now * ((SEGMENT.speed >> 3) +10)) & 0xFFFFU; counter = (counter >> 2) + (counter >> 4); //0-16384 + 0-2048 @@ -451,7 +442,6 @@ uint16_t mode_breath(void) { SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); } - return FRAMETIME; } static const char _data_FX_MODE_BREATH[] PROGMEM = "Breathe@!;!,!;!;01"; @@ -459,15 +449,13 @@ static const char _data_FX_MODE_BREATH[] PROGMEM = "Breathe@!;!,!;!;01"; /* * Fades the LEDs between two colors */ -uint16_t mode_fade(void) { +void mode_fade(void) { unsigned counter = (strip.now * ((SEGMENT.speed >> 3) +10)); uint8_t lum = triwave16(counter) >> 8; for (unsigned i = 0; i < SEGLEN; i++) { SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); } - - return FRAMETIME; } static const char _data_FX_MODE_FADE[] PROGMEM = "Fade@!;!,!;!;01"; @@ -475,8 +463,8 @@ static const char _data_FX_MODE_FADE[] PROGMEM = "Fade@!;!,!;!;01"; /* * Scan mode parent function */ -uint16_t scan(bool dual) { - if (SEGLEN <= 1) return mode_static(); +void scan(bool dual) { + if (SEGLEN <= 1) mode_static(); uint32_t cycleTime = 750 + (255 - SEGMENT.speed)*150; uint32_t perc = strip.now % cycleTime; int prog = (perc * 65535) / cycleTime; @@ -498,16 +486,14 @@ uint16_t scan(bool dual) { for (int j = led_offset; j < led_offset + size; j++) { SEGMENT.setPixelColor(j, SEGMENT.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); } - - return FRAMETIME; } /* * Runs a single pixel back and forth. */ -uint16_t mode_scan(void) { - return scan(false); +void mode_scan(void) { + scan(false); } static const char _data_FX_MODE_SCAN[] PROGMEM = "Scan@!,# of dots,,,,,Overlay;!,!,!;!"; @@ -515,8 +501,8 @@ static const char _data_FX_MODE_SCAN[] PROGMEM = "Scan@!,# of dots,,,,,Overlay;! /* * Runs two pixel back and forth in opposite directions. */ -uint16_t mode_dual_scan(void) { - return scan(true); +void mode_dual_scan(void) { + scan(true); } static const char _data_FX_MODE_DUAL_SCAN[] PROGMEM = "Scan Dual@!,# of dots,,,,,Overlay;!,!,!;!"; @@ -524,7 +510,7 @@ static const char _data_FX_MODE_DUAL_SCAN[] PROGMEM = "Scan Dual@!,# of dots,,,, /* * Cycles all LEDs at once through a rainbow. */ -uint16_t mode_rainbow(void) { +void mode_rainbow(void) { unsigned counter = (strip.now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF; counter = counter >> 8; @@ -533,8 +519,6 @@ uint16_t mode_rainbow(void) { } else { SEGMENT.fill(SEGMENT.color_wheel(counter)); } - - return FRAMETIME; } static const char _data_FX_MODE_RAINBOW[] PROGMEM = "Colorloop@!,Saturation;;!;01"; @@ -542,7 +526,7 @@ static const char _data_FX_MODE_RAINBOW[] PROGMEM = "Colorloop@!,Saturation;;!;0 /* * Cycles a rainbow over the entire string of LEDs. */ -uint16_t mode_rainbow_cycle(void) { +void mode_rainbow_cycle(void) { unsigned counter = (strip.now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF; counter = counter >> 8; @@ -551,8 +535,6 @@ uint16_t mode_rainbow_cycle(void) { uint8_t index = (i * (16 << (SEGMENT.intensity /29)) / SEGLEN) + counter; SEGMENT.setPixelColor(i, SEGMENT.color_wheel(index)); } - - return FRAMETIME; } static const char _data_FX_MODE_RAINBOW_CYCLE[] PROGMEM = "Rainbow@!,Size;;!"; @@ -560,7 +542,7 @@ static const char _data_FX_MODE_RAINBOW_CYCLE[] PROGMEM = "Rainbow@!,Size;;!"; /* * Alternating pixels running function. */ -static uint16_t running(uint32_t color1, uint32_t color2, bool theatre = false) { +static void running(uint32_t color1, uint32_t color2, bool theatre = false) { int width = (theatre ? 3 : 1) + (SEGMENT.intensity >> 4); // window uint32_t cycleTime = 50 + (255 - SEGMENT.speed); uint32_t it = strip.now / cycleTime; @@ -582,7 +564,6 @@ static uint16_t running(uint32_t color1, uint32_t color2, bool theatre = false) SEGENV.aux0 = (SEGENV.aux0 +1) % (theatre ? width : (width<<1)); SEGENV.step = it; } - return FRAMETIME; } @@ -590,8 +571,8 @@ static uint16_t running(uint32_t color1, uint32_t color2, bool theatre = false) * Theatre-style crawling lights. * Inspired by the Adafruit examples. */ -uint16_t mode_theater_chase(void) { - return running(SEGCOLOR(0), SEGCOLOR(1), true); +void mode_theater_chase(void) { + running(SEGCOLOR(0), SEGCOLOR(1), true); } static const char _data_FX_MODE_THEATER_CHASE[] PROGMEM = "Theater@!,Gap size;!,!;!"; @@ -600,8 +581,8 @@ static const char _data_FX_MODE_THEATER_CHASE[] PROGMEM = "Theater@!,Gap size;!, * Theatre-style crawling lights with rainbow effect. * Inspired by the Adafruit examples. */ -uint16_t mode_theater_chase_rainbow(void) { - return running(SEGMENT.color_wheel(SEGENV.step), SEGCOLOR(1), true); +void mode_theater_chase_rainbow(void) { + running(SEGMENT.color_wheel(SEGENV.step), SEGCOLOR(1), true); } static const char _data_FX_MODE_THEATER_CHASE_RAINBOW[] PROGMEM = "Theater Rainbow@!,Gap size;,!;!"; @@ -609,7 +590,7 @@ static const char _data_FX_MODE_THEATER_CHASE_RAINBOW[] PROGMEM = "Theater Rainb /* * Running lights effect with smooth sine transition base. */ -static uint16_t running_base(bool saw, bool dual=false) { +static void running_base(bool saw, bool dual=false) { unsigned x_scale = SEGMENT.intensity >> 2; uint32_t counter = (strip.now * SEGMENT.speed) >> 9; @@ -635,8 +616,6 @@ static uint16_t running_base(bool saw, bool dual=false) { } SEGMENT.setPixelColor(i, ca); } - - return FRAMETIME; } @@ -644,8 +623,8 @@ static uint16_t running_base(bool saw, bool dual=false) { * Running lights in opposite directions. * Idea: Make the gap width controllable with a third slider in the future */ -uint16_t mode_running_dual(void) { - return running_base(false, true); +void mode_running_dual(void) { + running_base(false, true); } static const char _data_FX_MODE_RUNNING_DUAL[] PROGMEM = "Running Dual@!,Wave width;L,!,R;!"; @@ -653,8 +632,8 @@ static const char _data_FX_MODE_RUNNING_DUAL[] PROGMEM = "Running Dual@!,Wave wi /* * Running lights effect with smooth sine transition. */ -uint16_t mode_running_lights(void) { - return running_base(false); +void mode_running_lights(void) { + running_base(false); } static const char _data_FX_MODE_RUNNING_LIGHTS[] PROGMEM = "Running@!,Wave width;!,!;!"; @@ -662,8 +641,8 @@ static const char _data_FX_MODE_RUNNING_LIGHTS[] PROGMEM = "Running@!,Wave width /* * Running lights effect with sawtooth transition. */ -uint16_t mode_saw(void) { - return running_base(true); +void mode_saw(void) { + running_base(true); } static const char _data_FX_MODE_SAW[] PROGMEM = "Saw@!,Width;!,!;!"; @@ -672,7 +651,7 @@ static const char _data_FX_MODE_SAW[] PROGMEM = "Saw@!,Width;!,!;!"; * Blink several LEDs in random colors on, reset, repeat. * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ -uint16_t mode_twinkle(void) { +void mode_twinkle(void) { SEGMENT.fade_out(224); uint32_t cycleTime = 20 + (255 - SEGMENT.speed)*5; @@ -698,8 +677,6 @@ uint16_t mode_twinkle(void) { unsigned j = p >> 16; SEGMENT.setPixelColor(j, SEGMENT.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); } - - return FRAMETIME; } static const char _data_FX_MODE_TWINKLE[] PROGMEM = "Twinkle@!,!;!,!;!;;m12=0"; //pixels @@ -707,9 +684,9 @@ static const char _data_FX_MODE_TWINKLE[] PROGMEM = "Twinkle@!,!;!,!;!;;m12=0"; /* * Dissolve function */ -uint16_t dissolve(uint32_t color) { +void dissolve(uint32_t color) { unsigned dataSize = sizeof(uint32_t) * SEGLEN; - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed uint32_t* pixels = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { @@ -757,16 +734,14 @@ uint16_t dissolve(uint32_t color) { } else SEGENV.step++; } - - return FRAMETIME; } /* * Blink several LEDs on and then off */ -uint16_t mode_dissolve(void) { - return dissolve(SEGMENT.check1 ? SEGMENT.color_wheel(hw_random8()) : SEGCOLOR(0)); +void mode_dissolve(void) { + dissolve(SEGMENT.check1 ? SEGMENT.color_wheel(hw_random8()) : SEGCOLOR(0)); } static const char _data_FX_MODE_DISSOLVE[] PROGMEM = "Dissolve@Repeat speed,Dissolve speed,,,,Random,Complete;!,!;!"; @@ -774,8 +749,8 @@ static const char _data_FX_MODE_DISSOLVE[] PROGMEM = "Dissolve@Repeat speed,Diss /* * Blink several LEDs on and then off in random colors */ -uint16_t mode_dissolve_random(void) { - return dissolve(SEGMENT.color_wheel(hw_random8())); +void mode_dissolve_random(void) { + dissolve(SEGMENT.color_wheel(hw_random8())); } static const char _data_FX_MODE_DISSOLVE_RANDOM[] PROGMEM = "Dissolve Rnd@Repeat speed,Dissolve speed;,!;!"; @@ -783,7 +758,7 @@ static const char _data_FX_MODE_DISSOLVE_RANDOM[] PROGMEM = "Dissolve Rnd@Repeat * Blinks one LED at a time. * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ -uint16_t mode_sparkle(void) { +void mode_sparkle(void) { if (!SEGMENT.check2) for (unsigned i = 0; i < SEGLEN; i++) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } @@ -796,7 +771,6 @@ uint16_t mode_sparkle(void) { } SEGMENT.setPixelColor(SEGENV.aux0, SEGCOLOR(0)); - return FRAMETIME; } static const char _data_FX_MODE_SPARKLE[] PROGMEM = "Sparkle@!,,,,,,Overlay;!,!;!;;m12=0"; @@ -804,7 +778,7 @@ static const char _data_FX_MODE_SPARKLE[] PROGMEM = "Sparkle@!,,,,,,Overlay;!,!; * Lights all LEDs in the color. Flashes single col 1 pixels randomly. (List name: Sparkle Dark) * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ -uint16_t mode_flash_sparkle(void) { +void mode_flash_sparkle(void) { if (!SEGMENT.check2) for (unsigned i = 0; i < SEGLEN; i++) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } @@ -816,7 +790,6 @@ uint16_t mode_flash_sparkle(void) { SEGENV.step = strip.now; SEGENV.aux0 = 255-SEGMENT.speed; } - return FRAMETIME; } static const char _data_FX_MODE_FLASH_SPARKLE[] PROGMEM = "Sparkle Dark@!,!,,,,,Overlay;Bg,Fx;!;;m12=0"; @@ -825,7 +798,7 @@ static const char _data_FX_MODE_FLASH_SPARKLE[] PROGMEM = "Sparkle Dark@!,!,,,,, * Like flash sparkle. With more flash. * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ -uint16_t mode_hyper_sparkle(void) { +void mode_hyper_sparkle(void) { if (!SEGMENT.check2) for (unsigned i = 0; i < SEGLEN; i++) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } @@ -840,7 +813,6 @@ uint16_t mode_hyper_sparkle(void) { SEGENV.step = strip.now; SEGENV.aux0 = 255-SEGMENT.speed; } - return FRAMETIME; } static const char _data_FX_MODE_HYPER_SPARKLE[] PROGMEM = "Sparkle+@!,!,,,,,Overlay;Bg,Fx;!;;m12=0"; @@ -848,7 +820,7 @@ static const char _data_FX_MODE_HYPER_SPARKLE[] PROGMEM = "Sparkle+@!,!,,,,,Over /* * Strobe effect with different strobe count and pause, controlled by speed. */ -uint16_t mode_multi_strobe(void) { +void mode_multi_strobe(void) { for (unsigned i = 0; i < SEGLEN; i++) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } @@ -869,8 +841,6 @@ uint16_t mode_multi_strobe(void) { if (SEGENV.aux1 > count) SEGENV.aux1 = 0; SEGENV.step = strip.now; } - - return FRAMETIME; } static const char _data_FX_MODE_MULTI_STROBE[] PROGMEM = "Strobe Mega@!,!;!,!;!;01"; @@ -878,8 +848,8 @@ static const char _data_FX_MODE_MULTI_STROBE[] PROGMEM = "Strobe Mega@!,!;!,!;!; /* * Android loading circle, refactored by @dedehai */ -uint16_t mode_android(void) { - if (!SEGENV.allocateData(sizeof(uint32_t))) return mode_static(); +void mode_android(void) { + if (!SEGENV.allocateData(sizeof(uint32_t))) mode_static(); uint32_t* counter = reinterpret_cast(SEGENV.data); unsigned size = SEGENV.aux1 >> 1; // upper 15 bit unsigned shrinking = SEGENV.aux1 & 0x01; // lowest bit @@ -911,7 +881,6 @@ uint16_t mode_android(void) { else SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } - return FRAMETIME; } static const char _data_FX_MODE_ANDROID[] PROGMEM = "Android@!,Width;!,!;!;;m12=1"; //vertical @@ -920,7 +889,7 @@ static const char _data_FX_MODE_ANDROID[] PROGMEM = "Android@!,Width;!,!;!;;m12= * color1 = background color * color2 and color3 = colors of two adjacent leds */ -static uint16_t chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do_palette) { +static void chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do_palette) { uint16_t counter = strip.now * ((SEGMENT.speed >> 2) + 1); uint16_t a = (counter * SEGLEN) >> 16; @@ -982,16 +951,14 @@ static uint16_t chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do for (unsigned i = 0; i < c; i++) //fill from start until c SEGMENT.setPixelColor(i, color3); } - - return FRAMETIME; } /* * Bicolor chase, more primary color. */ -uint16_t mode_chase_color(void) { - return chase(SEGCOLOR(1), (SEGCOLOR(2)) ? SEGCOLOR(2) : SEGCOLOR(0), SEGCOLOR(0), true); +void mode_chase_color(void) { + chase(SEGCOLOR(1), (SEGCOLOR(2)) ? SEGCOLOR(2) : SEGCOLOR(0), SEGCOLOR(0), true); } static const char _data_FX_MODE_CHASE_COLOR[] PROGMEM = "Chase@!,Width;!,!,!;!"; @@ -999,8 +966,8 @@ static const char _data_FX_MODE_CHASE_COLOR[] PROGMEM = "Chase@!,Width;!,!,!;!"; /* * Primary running followed by random color. */ -uint16_t mode_chase_random(void) { - return chase(SEGCOLOR(1), (SEGCOLOR(2)) ? SEGCOLOR(2) : SEGCOLOR(0), SEGCOLOR(0), false); +void mode_chase_random(void) { + chase(SEGCOLOR(1), (SEGCOLOR(2)) ? SEGCOLOR(2) : SEGCOLOR(0), SEGCOLOR(0), false); } static const char _data_FX_MODE_CHASE_RANDOM[] PROGMEM = "Chase Random@!,Width;!,,!;!"; @@ -1008,13 +975,13 @@ static const char _data_FX_MODE_CHASE_RANDOM[] PROGMEM = "Chase Random@!,Width;! /* * Primary, secondary running on rainbow. */ -uint16_t mode_chase_rainbow(void) { +void mode_chase_rainbow(void) { unsigned color_sep = 256 / SEGLEN; if (color_sep == 0) color_sep = 1; // correction for segments longer than 256 LEDs unsigned color_index = SEGENV.call & 0xFF; uint32_t color = SEGMENT.color_wheel(((SEGENV.step * color_sep) + color_index) & 0xFF); - return chase(color, SEGCOLOR(0), SEGCOLOR(1), false); + chase(color, SEGCOLOR(0), SEGCOLOR(1), false); } static const char _data_FX_MODE_CHASE_RAINBOW[] PROGMEM = "Chase Rainbow@!,Width;!,!;!"; @@ -1022,13 +989,13 @@ static const char _data_FX_MODE_CHASE_RAINBOW[] PROGMEM = "Chase Rainbow@!,Width /* * Primary running on rainbow. */ -uint16_t mode_chase_rainbow_white(void) { +void mode_chase_rainbow_white(void) { uint16_t n = SEGENV.step; uint16_t m = (SEGENV.step + 1) % SEGLEN; uint32_t color2 = SEGMENT.color_wheel(((n * 256 / SEGLEN) + (SEGENV.call & 0xFF)) & 0xFF); uint32_t color3 = SEGMENT.color_wheel(((m * 256 / SEGLEN) + (SEGENV.call & 0xFF)) & 0xFF); - return chase(SEGCOLOR(0), color2, color3, false); + chase(SEGCOLOR(0), color2, color3, false); } static const char _data_FX_MODE_CHASE_RAINBOW_WHITE[] PROGMEM = "Rainbow Runner@!,Size;Bg;!"; @@ -1036,7 +1003,7 @@ static const char _data_FX_MODE_CHASE_RAINBOW_WHITE[] PROGMEM = "Rainbow Runner@ /* * Red - Amber - Green - Blue lights running */ -uint16_t mode_colorful(void) { +void mode_colorful(void) { unsigned numColors = 4; //3, 4, or 5 uint32_t cols[9]{0x00FF0000,0x00EEBB00,0x0000EE00,0x000077CC}; if (SEGMENT.intensity > 160 || SEGMENT.palette) { //palette or color @@ -1072,8 +1039,6 @@ uint16_t mode_colorful(void) { { for (unsigned j = 0; j < numColors; j++) SEGMENT.setPixelColor(i + j, cols[SEGENV.aux0 + j]); } - - return FRAMETIME; } static const char _data_FX_MODE_COLORFUL[] PROGMEM = "Colorful@!,Saturation;1,2,3;!"; @@ -1081,8 +1046,8 @@ static const char _data_FX_MODE_COLORFUL[] PROGMEM = "Colorful@!,Saturation;1,2, /* * Emulates a traffic light. */ -uint16_t mode_traffic_light(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_traffic_light(void) { + if (SEGLEN <= 1) mode_static(); for (unsigned i=0; i < SEGLEN; i++) SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); uint32_t mdelay = 500; @@ -1104,8 +1069,6 @@ uint16_t mode_traffic_light(void) { if (SEGENV.aux0 > 3) SEGENV.aux0 = 0; SEGENV.step = strip.now; } - - return FRAMETIME; } static const char _data_FX_MODE_TRAFFIC_LIGHT[] PROGMEM = "Traffic Light@!,US style;,!;!"; @@ -1114,29 +1077,37 @@ static const char _data_FX_MODE_TRAFFIC_LIGHT[] PROGMEM = "Traffic Light@!,US st * Sec flashes running on prim. */ #define FLASH_COUNT 4 -uint16_t mode_chase_flash(void) { - if (SEGLEN <= 1) return mode_static(); - unsigned flash_step = SEGENV.call % ((FLASH_COUNT * 2) + 1); +void mode_chase_flash(void) { + if (SEGLEN <= 1) mode_static(); + unsigned now = strip.now; // save time for delay calculation + bool advance = true; + unsigned flash_step = SEGENV.aux1 % ((FLASH_COUNT * 2) + 1); + if (now < SEGENV.step) + advance = false; // limit update rate but render every frame for smooth transitions + else + SEGENV.aux1++; for (unsigned i = 0; i < SEGLEN; i++) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } + unsigned index = SEGENV.aux0; + unsigned n = index; + unsigned m = (index + 1) % SEGLEN; unsigned delay = 10 + ((30 * (uint16_t)(255 - SEGMENT.speed)) / SEGLEN); if(flash_step < (FLASH_COUNT * 2)) { if(flash_step % 2 == 0) { - unsigned n = SEGENV.step; - unsigned m = (SEGENV.step + 1) % SEGLEN; SEGMENT.setPixelColor( n, SEGCOLOR(1)); SEGMENT.setPixelColor( m, SEGCOLOR(1)); delay = 20; } else { delay = 30; } - } else { - SEGENV.step = (SEGENV.step + 1) % SEGLEN; + } else if (advance) { + SEGENV.aux0 = m; // advance to next position } - return delay; + if (advance) + SEGENV.step = now + delay; // set next update time } static const char _data_FX_MODE_CHASE_FLASH[] PROGMEM = "Chase Flash@!;Bg,Fx;!"; @@ -1144,8 +1115,14 @@ static const char _data_FX_MODE_CHASE_FLASH[] PROGMEM = "Chase Flash@!;Bg,Fx;!"; /* * Prim flashes running, followed by random color. */ -uint16_t mode_chase_flash_random(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_chase_flash_random(void) { + if (SEGLEN <= 1) mode_static(); + unsigned now = strip.now; // save time for delay calculation + bool advance = true; + if (now < SEGENV.step) { + SEGENV.call--; // revert increment to skip moving the animation forward and just render the same frame again + advance = false; + } unsigned flash_step = SEGENV.call % ((FLASH_COUNT * 2) + 1); for (int i = 0; i < SEGENV.aux1; i++) { @@ -1165,14 +1142,15 @@ uint16_t mode_chase_flash_random(void) { SEGMENT.setPixelColor( m, SEGCOLOR(1)); delay = 30; } - } else { + } else if (advance) { SEGENV.aux1 = (SEGENV.aux1 + 1) % SEGLEN; if (SEGENV.aux1 == 0) { SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0); } } - return delay; + if (advance) + SEGENV.step = now + delay; // set next update time } static const char _data_FX_MODE_CHASE_FLASH_RANDOM[] PROGMEM = "Chase Flash Rnd@!;!,!;!"; @@ -1180,8 +1158,8 @@ static const char _data_FX_MODE_CHASE_FLASH_RANDOM[] PROGMEM = "Chase Flash Rnd@ /* * Alternating color/sec pixels running. */ -uint16_t mode_running_color(void) { - return running(SEGCOLOR(0), SEGCOLOR(1)); +void mode_running_color(void) { + running(SEGCOLOR(0), SEGCOLOR(1)); } static const char _data_FX_MODE_RUNNING_COLOR[] PROGMEM = "Chase 2@!,Width;!,!;!"; @@ -1189,7 +1167,7 @@ static const char _data_FX_MODE_RUNNING_COLOR[] PROGMEM = "Chase 2@!,Width;!,!;! /* * Random colored pixels running. ("Stream") */ -uint16_t mode_running_random(void) { +void mode_running_random(void) { uint32_t cycleTime = 25 + (3 * (uint32_t)(255 - SEGMENT.speed)); uint32_t it = strip.now / cycleTime; if (SEGENV.call == 0) SEGENV.aux0 = hw_random(); // random seed for PRNG on start @@ -1218,7 +1196,6 @@ uint16_t mode_running_random(void) { } SEGENV.aux1 = it; - return FRAMETIME; } static const char _data_FX_MODE_RUNNING_RANDOM[] PROGMEM = "Stream@!,Zone size;;!"; @@ -1226,21 +1203,21 @@ static const char _data_FX_MODE_RUNNING_RANDOM[] PROGMEM = "Stream@!,Zone size;; /* * K.I.T.T. */ -uint16_t mode_larson_scanner(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_larson_scanner(void) { + if (SEGLEN <= 1) mode_static(); const unsigned speed = FRAMETIME * map(SEGMENT.speed, 0, 255, 96, 2); // map into useful range const unsigned pixels = SEGLEN / speed; // how many pixels to advance per frame SEGMENT.fade_out(255-SEGMENT.intensity); - if (SEGENV.step > strip.now) return FRAMETIME; // we have a pause + if (SEGENV.step > strip.now) return; // we have a pause unsigned index = SEGENV.aux1 + pixels; // are we slow enough to use frames per pixel? if (pixels == 0) { const unsigned frames = speed / SEGLEN; // how many frames per 1 pixel - if (SEGENV.step++ < frames) return FRAMETIME; + if (SEGENV.step++ < frames) return; SEGENV.step = 0; index++; } @@ -1266,7 +1243,6 @@ uint16_t mode_larson_scanner(void) { } SEGENV.aux1 = index; } - return FRAMETIME; } static const char _data_FX_MODE_LARSON_SCANNER[] PROGMEM = "Scanner@!,Trail,Delay,,,Dual,Bi-delay;!,!,!;!;;m12=0,c1=0"; @@ -1274,17 +1250,17 @@ static const char _data_FX_MODE_LARSON_SCANNER[] PROGMEM = "Scanner@!,Trail,Dela * Creates two Larson scanners moving in opposite directions * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/DualLarson.h */ -uint16_t mode_dual_larson_scanner(void){ +void mode_dual_larson_scanner(void){ SEGMENT.check1 = true; - return mode_larson_scanner(); + mode_larson_scanner(); } static const char _data_FX_MODE_DUAL_LARSON_SCANNER[] PROGMEM = "Scanner Dual@!,Trail,Delay,,,Dual,Bi-delay;!,!,!;!;;m12=0,c1=0"; /* * Firing comets from one end. "Lighthouse" */ -uint16_t mode_comet(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_comet(void) { + if (SEGLEN <= 1) mode_static(); unsigned counter = (strip.now * ((SEGMENT.speed >>2) +1)) & 0xFFFF; unsigned index = (counter * SEGLEN) >> 16; if (SEGENV.call == 0) SEGENV.aux0 = index; @@ -1302,16 +1278,14 @@ uint16_t mode_comet(void) { } } SEGENV.aux0 = index++; - - return FRAMETIME; } static const char _data_FX_MODE_COMET[] PROGMEM = "Lighthouse@!,Fade rate;!,!;!"; /* * Fireworks function. */ -uint16_t mode_fireworks() { - if (SEGLEN <= 1) return mode_static(); +void mode_fireworks() { + if (SEGLEN <= 1) mode_static(); const uint16_t width = SEGMENT.is2D() ? SEG_W : SEGLEN; const uint16_t height = SEG_H; @@ -1346,13 +1320,12 @@ uint16_t mode_fireworks() { SEGENV.aux0 = index; // remember where spark occurred } } - return FRAMETIME; } static const char _data_FX_MODE_FIREWORKS[] PROGMEM = "Fireworks@,Frequency;!,!;!;12;ix=192,pal=11"; //Twinkling LEDs running. Inspired by https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Rain.h -uint16_t mode_rain() { - if (SEGLEN <= 1) return mode_static(); +void mode_rain() { + if (SEGLEN <= 1) mode_static(); const unsigned width = SEG_W; const unsigned height = SEG_H; SEGENV.step += FRAMETIME; @@ -1380,17 +1353,17 @@ uint16_t mode_rain() { if (SEGENV.aux0 >= width*height) SEGENV.aux0 = 0; // ignore if (SEGENV.aux1 >= width*height) SEGENV.aux1 = 0; } - return mode_fireworks(); + mode_fireworks(); } static const char _data_FX_MODE_RAIN[] PROGMEM = "Rain@!,Spawning rate;!,!;!;12;ix=128,pal=0"; /* * Fire flicker function */ -uint16_t mode_fire_flicker(void) { +void mode_fire_flicker(void) { uint32_t cycleTime = 40 + (255 - SEGMENT.speed); uint32_t it = strip.now / cycleTime; - if (SEGENV.step == it) return FRAMETIME; + if (SEGENV.step == it) return; byte w = (SEGCOLOR(0) >> 24); byte r = (SEGCOLOR(0) >> 16); @@ -1408,7 +1381,6 @@ uint16_t mode_fire_flicker(void) { } SEGENV.step = it; - return FRAMETIME; } static const char _data_FX_MODE_FIRE_FLICKER[] PROGMEM = "Fire Flicker@!,!;!;!;01"; @@ -1416,8 +1388,8 @@ static const char _data_FX_MODE_FIRE_FLICKER[] PROGMEM = "Fire Flicker@!,!;!;!;0 /* * Gradient run base function */ -uint16_t gradient_base(bool loading) { - if (SEGLEN <= 1) return mode_static(); +void gradient_base(bool loading) { + if (SEGLEN <= 1) mode_static(); uint16_t counter = strip.now * ((SEGMENT.speed >> 2) + 1); uint16_t pp = (counter * SEGLEN) >> 16; if (SEGENV.call == 0) pp = 0; @@ -1436,16 +1408,14 @@ uint16_t gradient_base(bool loading) { val = (brd > val) ? (val * 255) / brd : 255; SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(0), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1), uint8_t(val))); } - - return FRAMETIME; } /* * Gradient run */ -uint16_t mode_gradient(void) { - return gradient_base(false); +void mode_gradient(void) { + gradient_base(false); } static const char _data_FX_MODE_GRADIENT[] PROGMEM = "Gradient@!,Spread;!,!;!;;ix=16"; @@ -1453,16 +1423,16 @@ static const char _data_FX_MODE_GRADIENT[] PROGMEM = "Gradient@!,Spread;!,!;!;;i /* * Gradient run with hard transition */ -uint16_t mode_loading(void) { - return gradient_base(true); +void mode_loading(void) { + gradient_base(true); } static const char _data_FX_MODE_LOADING[] PROGMEM = "Loading@!,Fade;!,!;!;;ix=16"; /* * Two dots running */ -uint16_t mode_two_dots() { - if (SEGLEN <= 1) return mode_static(); +void mode_two_dots() { + if (SEGLEN <= 1) mode_static(); unsigned delay = 1 + (FRAMETIME<<3) / SEGLEN; // longer segments should change faster uint32_t it = strip.now / map(SEGMENT.speed, 0, 255, delay<<4, delay); unsigned offset = it % SEGLEN; @@ -1477,7 +1447,6 @@ uint16_t mode_two_dots() { SEGMENT.setPixelColor(indexR, color1); SEGMENT.setPixelColor(indexB, color2); } - return FRAMETIME; } static const char _data_FX_MODE_TWO_DOTS[] PROGMEM = "Two Dots@!,Dot size,,,,,Overlay;1,2,Bg;!"; @@ -1495,7 +1464,7 @@ typedef struct Flasher { #define FLASHERS_PER_ZONE 6 #define MAX_SHIMMER 92 -uint16_t mode_fairy() { +void mode_fairy() { //set every pixel to a 'random' color from palette (using seed so it doesn't change between frames) uint16_t PRNG16 = 5100 + strip.getCurrSegmentId(); for (unsigned i = 0; i < SEGLEN; i++) { @@ -1504,12 +1473,12 @@ uint16_t mode_fairy() { } //amount of flasher pixels depending on intensity (0: none, 255: every LED) - if (SEGMENT.intensity == 0) return FRAMETIME; + if (SEGMENT.intensity == 0) return; unsigned flasherDistance = ((255 - SEGMENT.intensity) / 28) +1; //1-10 unsigned numFlashers = (SEGLEN / flasherDistance) +1; unsigned dataSize = sizeof(flasher) * numFlashers; - if (!SEGENV.allocateData(dataSize)) return FRAMETIME; //allocation failed + if (!SEGENV.allocateData(dataSize)) return; //allocation failed Flasher* flashers = reinterpret_cast(SEGENV.data); unsigned now16 = strip.now & 0xFFFF; @@ -1564,7 +1533,6 @@ uint16_t mode_fairy() { } } } - return FRAMETIME; } static const char _data_FX_MODE_FAIRY[] PROGMEM = "Fairy@!,# of flashers;!,!;!"; @@ -1573,9 +1541,9 @@ static const char _data_FX_MODE_FAIRY[] PROGMEM = "Fairy@!,# of flashers;!,!;!"; * Fairytwinkle. Like Colortwinkle, but starting from all lit and not relying on strip.getPixelColor * Warning: Uses 4 bytes of segment data per pixel */ -uint16_t mode_fairytwinkle() { +void mode_fairytwinkle() { unsigned dataSize = sizeof(flasher) * SEGLEN; - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed Flasher* flashers = reinterpret_cast(SEGENV.data); unsigned now16 = strip.now & 0xFFFF; uint16_t PRNG16 = 5100 + strip.getCurrSegmentId(); @@ -1614,7 +1582,6 @@ uint16_t mode_fairytwinkle() { } SEGMENT.setPixelColor(f, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(PRNG16 >> 8, false, false, 0), flasherBri)); } - return FRAMETIME; } static const char _data_FX_MODE_FAIRYTWINKLE[] PROGMEM = "Fairytwinkle@!,!;!,!;!;;m12=0"; //pixels @@ -1622,7 +1589,7 @@ static const char _data_FX_MODE_FAIRYTWINKLE[] PROGMEM = "Fairytwinkle@!,!;!,!;! /* * Tricolor chase function */ -uint16_t tricolor_chase(uint32_t color1, uint32_t color2) { +void tricolor_chase(uint32_t color1, uint32_t color2) { uint32_t cycleTime = 50 + ((255 - SEGMENT.speed)<<1); uint32_t it = strip.now / cycleTime; // iterator unsigned width = (1 + (SEGMENT.intensity>>4)); // value of 1-16 for each colour @@ -1637,15 +1604,14 @@ uint16_t tricolor_chase(uint32_t color1, uint32_t color2) { SEGMENT.setPixelColor(SEGLEN - i -1, color); } - return FRAMETIME; } /* * Tricolor chase mode */ -uint16_t mode_tricolor_chase(void) { - return tricolor_chase(SEGCOLOR(2), SEGCOLOR(0)); +void mode_tricolor_chase(void) { + tricolor_chase(SEGCOLOR(2), SEGCOLOR(0)); } static const char _data_FX_MODE_TRICOLOR_CHASE[] PROGMEM = "Chase 3@!,Size;1,2,3;!"; @@ -1653,40 +1619,71 @@ static const char _data_FX_MODE_TRICOLOR_CHASE[] PROGMEM = "Chase 3@!,Size;1,2,3 /* * ICU mode */ -uint16_t mode_icu(void) { - unsigned dest = SEGENV.step & 0xFFFF; - unsigned space = (SEGMENT.intensity >> 3) +2; +void mode_icu(void) { + // states: 0 = pause1, 1 = blink, 2 = pause2, 3 = move - if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); + uint16_t now = strip.now; // save time for delay calculation, use low16 bits only + unsigned dest = SEGENV.aux1; + unsigned space = (SEGMENT.intensity >> 3) +2; + uint16_t state = SEGENV.step >> 16; // upper bytes of step store current state + uint16_t nextUpdate = SEGENV.step & 0xFFFF; // lower bytes store time for next update byte pindex = map(dest, 0, SEGLEN-SEGLEN/space, 0, 255); uint32_t col = SEGMENT.color_from_palette(pindex, false, false, 0); - - SEGMENT.setPixelColor(dest, col); - SEGMENT.setPixelColor(dest + SEGLEN/space, col); - - if(SEGENV.aux0 == dest) { // pause between eye movements - if(hw_random8(6) == 0) { // blink once in a while - SEGMENT.setPixelColor(dest, SEGCOLOR(1)); - SEGMENT.setPixelColor(dest + SEGLEN/space, SEGCOLOR(1)); - return 200; + uint32_t bgcol = SEGMENT.check2 ? BLACK : SEGCOLOR(1); + SEGMENT.fill(bgcol); // apply background color or clear + // draw eyes if not blinking + if (state != 1) { + SEGMENT.setPixelColor(dest, col); + SEGMENT.setPixelColor(dest + SEGLEN/space, col); + // render next position if moving + if (state == 3) { + if(SEGENV.aux0 > SEGENV.aux1) { + dest++; + } else if (SEGENV.aux0 < SEGENV.aux1) { + dest--; + } + SEGMENT.setPixelColor(dest, col); + SEGMENT.setPixelColor(dest + SEGLEN/space, col); } - SEGENV.aux0 = hw_random16(SEGLEN-SEGLEN/space); - return 1000 + hw_random16(2000); } - if(SEGENV.aux0 > SEGENV.step) { - SEGENV.step++; - dest++; - } else if (SEGENV.aux0 < SEGENV.step) { - SEGENV.step--; - dest--; + // update state + if ((int16_t)(now - nextUpdate) >= 0) { // time to update, cast to int to handle wraparound properly + switch (state) { + case 0: // pause part 1 + // first pause part finished, blink or pause some more + state++; + if(hw_random8(6) == 0) { // blink once in a while + nextUpdate = uint16_t(now + 200); + break; + } + // fall through if not blinking + case 1: // blink + // not blinking or finished blinking -> pause part 2 + nextUpdate = uint16_t(now + 500 + hw_random16(1000)); + state++; + break; + case 2: // pause part 2 + // pause finished, move + SEGENV.aux0 = hw_random16(SEGLEN-SEGLEN/space); // choose a new destination + nextUpdate = now; + state++; + break; + default: // move (state 3) + SEGENV.aux1 = dest; // update destination to moved position + nextUpdate = uint16_t(now + SPEED_FORMULA_L); + if (SEGENV.aux0 == dest) { + // reached destination + nextUpdate = uint16_t(now + 500 + hw_random16(1000)); + state = 0; + } + break; + } } - SEGMENT.setPixelColor(dest, col); - SEGMENT.setPixelColor(dest + SEGLEN/space, col); - - return SPEED_FORMULA_L; + // use upper bits of SEGENV.step to store current state, lower bits for next update time + SEGENV.step = (state << 16) | nextUpdate; } static const char _data_FX_MODE_ICU[] PROGMEM = "ICU@!,!,,,,,Overlay;!,!;!"; @@ -1694,7 +1691,7 @@ static const char _data_FX_MODE_ICU[] PROGMEM = "ICU@!,!,,,,,Overlay;!,!;!"; /* * Custom mode by Aircoookie. Color Wipe, but with 3 colors */ -uint16_t mode_tricolor_wipe(void) { +void mode_tricolor_wipe(void) { uint32_t cycleTime = 1000 + (255 - SEGMENT.speed)*200; uint32_t perc = strip.now % cycleTime; unsigned prog = (perc * 65535) / cycleTime; @@ -1725,8 +1722,6 @@ uint16_t mode_tricolor_wipe(void) { SEGMENT.setPixelColor(i, SEGCOLOR(0)); } } - - return FRAMETIME; } static const char _data_FX_MODE_TRICOLOR_WIPE[] PROGMEM = "Tri Wipe@!;1,2,3;!"; @@ -1736,7 +1731,7 @@ static const char _data_FX_MODE_TRICOLOR_WIPE[] PROGMEM = "Tri Wipe@!;1,2,3;!"; * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/TriFade.h * Modified by Aircoookie */ -uint16_t mode_tricolor_fade(void) { +void mode_tricolor_fade(void) { uint16_t counter = strip.now * ((SEGMENT.speed >> 3) +1); uint32_t prog = (counter * 768) >> 16; @@ -1769,8 +1764,6 @@ uint16_t mode_tricolor_fade(void) { } SEGMENT.setPixelColor(i, color); } - - return FRAMETIME; } static const char _data_FX_MODE_TRICOLOR_FADE[] PROGMEM = "Tri Fade@!;1,2,3;!"; @@ -1779,11 +1772,11 @@ static const char _data_FX_MODE_TRICOLOR_FADE[] PROGMEM = "Tri Fade@!;1,2,3;!"; * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/MultiComet.h */ #define MAX_COMETS 8 -uint16_t mode_multi_comet(void) { +void mode_multi_comet(void) { uint32_t cycleTime = 10 + (uint32_t)(255 - SEGMENT.speed); uint32_t it = strip.now / cycleTime; - if (SEGENV.step == it) return FRAMETIME; - if (!SEGENV.allocateData(sizeof(uint16_t) * MAX_COMETS)) return mode_static(); //allocation failed + if (SEGENV.step == it) return; + if (!SEGENV.allocateData(sizeof(uint16_t) * MAX_COMETS)) mode_static(); //allocation failed SEGMENT.fade_out(SEGMENT.intensity/2 + 128); @@ -1808,7 +1801,6 @@ uint16_t mode_multi_comet(void) { } SEGENV.step = it; - return FRAMETIME; } static const char _data_FX_MODE_MULTI_COMET[] PROGMEM = "Multi Comet@!,Fade;!,!;!;1"; #undef MAX_COMETS @@ -1817,7 +1809,7 @@ static const char _data_FX_MODE_MULTI_COMET[] PROGMEM = "Multi Comet@!,Fade;!,!; * Running random pixels ("Stream 2") * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/RandomChase.h */ -uint16_t mode_random_chase(void) { +void mode_random_chase(void) { if (SEGENV.call == 0) { SEGENV.step = RGBW32(random8(), random8(), random8(), 0); SEGENV.aux0 = random16(); @@ -1843,7 +1835,6 @@ uint16_t mode_random_chase(void) { SEGENV.aux1 = it & 0xFFFF; random16_set_seed(prevSeed); // restore original seed so other effects can use "random" PRNG - return FRAMETIME; } static const char _data_FX_MODE_RANDOM_CHASE[] PROGMEM = "Stream 2@!;;"; @@ -1859,11 +1850,11 @@ typedef struct Oscillator { /* / Oscillating bars of color, updated with standard framerate */ -uint16_t mode_oscillate(void) { +void mode_oscillate(void) { constexpr unsigned numOscillators = 3; constexpr unsigned dataSize = sizeof(oscillator) * numOscillators; - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed Oscillator* oscillators = reinterpret_cast(SEGENV.data); @@ -1905,14 +1896,12 @@ uint16_t mode_oscillate(void) { } SEGENV.step = it; - return FRAMETIME; } static const char _data_FX_MODE_OSCILLATE[] PROGMEM = "Oscillate"; -//TODO -uint16_t mode_lightning(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_lightning(void) { + if (SEGLEN <= 1) mode_static(); unsigned ledstart = hw_random16(SEGLEN); // Determine starting location of flash unsigned ledlen = 1 + hw_random16(SEGLEN -ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1) uint8_t bri = 255/hw_random8(1, 3); @@ -1949,12 +1938,11 @@ uint16_t mode_lightning(void) { SEGENV.step = strip.now; } } - return FRAMETIME; } static const char _data_FX_MODE_LIGHTNING[] PROGMEM = "Lightning@!,!,,,,,Overlay;!,!;!"; // combined function from original pride and colorwaves -uint16_t mode_colorwaves_pride_base(bool isPride2015) { +void mode_colorwaves_pride_base(bool isPride2015) { unsigned duration = 10 + SEGMENT.speed; unsigned sPseudotime = SEGENV.step; unsigned sHue16 = SEGENV.aux0; @@ -2000,30 +1988,28 @@ uint16_t mode_colorwaves_pride_base(bool isPride2015) { SEGENV.step = sPseudotime; SEGENV.aux0 = sHue16; - - return FRAMETIME; } // Pride2015 // Animated, ever-changing rainbows. // by Mark Kriegsman: https://gist.github.com/kriegsman/964de772d64c502760e5 -uint16_t mode_pride_2015(void) { - return mode_colorwaves_pride_base(true); +void mode_pride_2015(void) { + mode_colorwaves_pride_base(true); } static const char _data_FX_MODE_PRIDE_2015[] PROGMEM = "Pride 2015@!;;"; // ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb // This function draws color waves with an ever-changing, // widely-varying set of parameters, using a color palette. -uint16_t mode_colorwaves() { - return mode_colorwaves_pride_base(false); +void mode_colorwaves() { + mode_colorwaves_pride_base(false); } static const char _data_FX_MODE_COLORWAVES[] PROGMEM = "Colorwaves@!,Hue;!;!;;pal=26"; //eight colored dots, weaving in and out of sync with each other -uint16_t mode_juggle(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_juggle(void) { + if (SEGLEN <= 1) mode_static(); SEGMENT.fadeToBlackBy(192 - (3*SEGMENT.intensity/4)); CRGB fastled_col; @@ -2035,12 +2021,11 @@ uint16_t mode_juggle(void) { SEGMENT.setPixelColor(index, fastled_col); dothue += 32; } - return FRAMETIME; } static const char _data_FX_MODE_JUGGLE[] PROGMEM = "Juggle@!,Trail;;!;;sx=64,ix=128"; -uint16_t mode_palette() { +void mode_palette() { // Set up some compile time constants so that we can handle integer and float based modes using the same code base. #ifdef ESP8266 using mathType = int32_t; @@ -2134,7 +2119,6 @@ uint16_t mode_palette() { } } } - return FRAMETIME; } static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Shift,Size,Rotation,,,Animate Shift,Animate Rotation,Anamorphic;;!;12;ix=112,c1=0,o1=1,o2=0,o3=1"; @@ -2167,10 +2151,10 @@ static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Shift,Size,Rotation // There are two main parameters you can play with to control the look and // feel of your fire: COOLING (used in step 1 above) (Speed = COOLING), and SPARKING (used // in step 3 above) (Effect Intensity = Sparking). -uint16_t mode_fire_2012() { - if (SEGLEN <= 1) return mode_static(); +void mode_fire_2012() { + if (SEGLEN <= 1) mode_static(); const unsigned strips = SEGMENT.nrOfVStrips(); - if (!SEGENV.allocateData(strips * SEGLEN)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(strips * SEGLEN)) mode_static(); //allocation failed byte* heat = SEGENV.data; const uint32_t it = strip.now >> 5; //div 32 @@ -2221,39 +2205,33 @@ uint16_t mode_fire_2012() { if (it != SEGENV.step) SEGENV.step = it; - - return FRAMETIME; } static const char _data_FX_MODE_FIRE_2012[] PROGMEM = "Fire 2012@Cooling,Spark rate,,2D Blur,Boost;;!;1;pal=35,sx=64,ix=160,m12=1,c2=128"; // bars #endif // WLED_PS_DONT_REPLACE_x_FX // colored stripes pulsing at a defined Beats-Per-Minute (BPM) -uint16_t mode_bpm() { +void mode_bpm() { uint32_t stp = (strip.now / 20) & 0xFF; uint8_t beat = beatsin8_t(SEGMENT.speed, 64, 255); for (unsigned i = 0; i < SEGLEN; i++) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(stp + (i * 2), false, PALETTE_SOLID_WRAP, 0, beat - stp + (i * 10))); } - - return FRAMETIME; } static const char _data_FX_MODE_BPM[] PROGMEM = "Bpm@!;!;!;;sx=64"; -uint16_t mode_fillnoise8() { +void mode_fillnoise8() { if (SEGENV.call == 0) SEGENV.step = hw_random(); for (unsigned i = 0; i < SEGLEN; i++) { unsigned index = perlin8(i * SEGLEN, SEGENV.step + i * SEGLEN); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0)); } SEGENV.step += beatsin8_t(SEGMENT.speed, 1, 6); //10,1,4 - - return FRAMETIME; } static const char _data_FX_MODE_FILLNOISE8[] PROGMEM = "Fill Noise@!;!;!"; -uint16_t mode_noise16_1() { +void mode_noise16_1() { unsigned scale = 320; // the "zoom factor" for the noise SEGENV.step += (1 + SEGMENT.speed/16); @@ -2268,13 +2246,11 @@ uint16_t mode_noise16_1() { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0)); } - - return FRAMETIME; } static const char _data_FX_MODE_NOISE16_1[] PROGMEM = "Noise 1@!;!;!;;pal=20"; -uint16_t mode_noise16_2() { +void mode_noise16_2() { unsigned scale = 1000; // the "zoom factor" for the noise SEGENV.step += (1 + (SEGMENT.speed >> 1)); @@ -2286,13 +2262,11 @@ uint16_t mode_noise16_2() { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0, noise)); } - - return FRAMETIME; } static const char _data_FX_MODE_NOISE16_2[] PROGMEM = "Noise 2@!;!;!;;pal=43"; -uint16_t mode_noise16_3() { +void mode_noise16_3() { unsigned scale = 800; // the "zoom factor" for the noise SEGENV.step += (1 + SEGMENT.speed); @@ -2307,28 +2281,29 @@ uint16_t mode_noise16_3() { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0, noise)); } - - return FRAMETIME; } static const char _data_FX_MODE_NOISE16_3[] PROGMEM = "Noise 3@!;!;!;;pal=35"; //https://github.com/aykevl/ledstrip-spark/blob/master/ledstrip.ino -uint16_t mode_noise16_4() { +void mode_noise16_4() { uint32_t stp = (strip.now * SEGMENT.speed) >> 7; for (unsigned i = 0; i < SEGLEN; i++) { int index = perlin16(uint32_t(i) << 12, stp); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0)); } - return FRAMETIME; } static const char _data_FX_MODE_NOISE16_4[] PROGMEM = "Noise 4@!;!;!;;pal=26"; //based on https://gist.github.com/kriegsman/5408ecd397744ba0393e -uint16_t mode_colortwinkle() { +void mode_colortwinkle() { unsigned dataSize = (SEGLEN+7) >> 3; //1 bit per LED - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + + //limit update rate + if (strip.now - SEGENV.step < FRAMETIME_FIXED) return; + SEGENV.step = strip.now; CRGBW col, prev; fract8 fadeUpAmount = strip.getBrightness()>28 ? 8 + (SEGMENT.speed>>2) : 68-strip.getBrightness(); @@ -2374,13 +2349,12 @@ uint16_t mode_colortwinkle() { } } } - return FRAMETIME_FIXED; } static const char _data_FX_MODE_COLORTWINKLE[] PROGMEM = "Colortwinkles@Fade speed,Spawn speed;;!;;m12=0"; //pixels //Calm effect, like a lake at night -uint16_t mode_lake() { +void mode_lake() { unsigned sp = SEGMENT.speed/10; int wave1 = beatsin8_t(sp +2, -64,64); int wave2 = beatsin8_t(sp +1, -64,64); @@ -2392,8 +2366,6 @@ uint16_t mode_lake() { uint8_t lum = (index > wave3) ? index - wave3 : 0; SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, false, 0, lum)); } - - return FRAMETIME; } static const char _data_FX_MODE_LAKE[] PROGMEM = "Lake@!;Fx;!"; @@ -2401,9 +2373,9 @@ static const char _data_FX_MODE_LAKE[] PROGMEM = "Lake@!;Fx;!"; // meteor effect & meteor smooth (merged by @dedehai) // send a meteor from begining to to the end of the strip with a trail that randomly decays. // adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain -uint16_t mode_meteor() { - if (SEGLEN <= 1) return mode_static(); - if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed +void mode_meteor() { + if (SEGLEN <= 1) mode_static(); + if (!SEGENV.allocateData(SEGLEN)) mode_static(); //allocation failed const bool meteorSmooth = SEGMENT.check3; byte* trail = SEGENV.data; @@ -2464,14 +2436,13 @@ uint16_t mode_meteor() { } SEGENV.step += SEGMENT.speed +1; - return FRAMETIME; } static const char _data_FX_MODE_METEOR[] PROGMEM = "Meteor@!,Trail,,,,Gradient,,Smooth;;!;1"; //Railway Crossing / Christmas Fairy lights -uint16_t mode_railway() { - if (SEGLEN <= 1) return mode_static(); +void mode_railway() { + if (SEGLEN <= 1) mode_static(); unsigned dur = (256 - SEGMENT.speed) * 40; uint16_t rampdur = (dur * SEGMENT.intensity) >> 8; if (SEGENV.step > dur) @@ -2496,7 +2467,6 @@ uint16_t mode_railway() { } } SEGENV.step += FRAMETIME; - return FRAMETIME; } static const char _data_FX_MODE_RAILWAY[] PROGMEM = "Railway@!,Smoothness;1,2;!;;pal=3"; @@ -2517,11 +2487,11 @@ typedef struct Ripple { #else #define MAX_RIPPLES 100 #endif -static uint16_t ripple_base(uint8_t blurAmount = 0) { +static void ripple_base(uint8_t blurAmount = 0) { unsigned maxRipples = min(1 + (int)(SEGLEN >> 2), MAX_RIPPLES); // 56 max for 16 segment ESP8266 unsigned dataSize = sizeof(ripple) * maxRipples; - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed Ripple* ripples = reinterpret_cast(SEGENV.data); @@ -2566,25 +2536,24 @@ static uint16_t ripple_base(uint8_t blurAmount = 0) { } } SEGMENT.blur(blurAmount); - return FRAMETIME; } #undef MAX_RIPPLES -uint16_t mode_ripple(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_ripple(void) { + if (SEGLEN <= 1) mode_static(); if(SEGMENT.custom1 || SEGMENT.check2) // blur or overlay SEGMENT.fade_out(250); else SEGMENT.fill(SEGCOLOR(1)); - return ripple_base(SEGMENT.custom1>>1); + ripple_base(SEGMENT.custom1>>1); } static const char _data_FX_MODE_RIPPLE[] PROGMEM = "Ripple@!,Wave #,Blur,,,,Overlay;,!;!;12;c1=0"; -uint16_t mode_ripple_rainbow(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_ripple_rainbow(void) { + if (SEGLEN <= 1) mode_static(); if (SEGENV.call ==0) { SEGENV.aux0 = hw_random8(); SEGENV.aux1 = hw_random8(); @@ -2597,7 +2566,7 @@ uint16_t mode_ripple_rainbow(void) { SEGENV.aux0--; } SEGMENT.fill(color_blend(SEGMENT.color_wheel(SEGENV.aux0),BLACK,uint8_t(235))); - return ripple_base(); + ripple_base(); } static const char _data_FX_MODE_RIPPLE_RAINBOW[] PROGMEM = "Ripple Rainbow@!,Wave #;;!;12"; @@ -2668,7 +2637,7 @@ static CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat) // "CalculateOneTwinkle" on each pixel. It then displays // either the twinkle color of the background color, // whichever is brighter. -static uint16_t twinklefox_base(bool cat) +static void twinklefox_base(bool cat) { // "PRNG16" is the pseudorandom number generator // It MUST be reset to the same starting value each time @@ -2724,25 +2693,23 @@ static uint16_t twinklefox_base(bool cat) SEGMENT.setPixelColor(i, bg); } } - return FRAMETIME; } - -uint16_t mode_twinklefox() +void mode_twinklefox() { - return twinklefox_base(false); + twinklefox_base(false); } static const char _data_FX_MODE_TWINKLEFOX[] PROGMEM = "Twinklefox@!,Twinkle rate,,,,Cool;!,!;!"; -uint16_t mode_twinklecat() +void mode_twinklecat() { - return twinklefox_base(true); + twinklefox_base(true); } static const char _data_FX_MODE_TWINKLECAT[] PROGMEM = "Twinklecat@!,Twinkle rate,,,,Cool,Reverse;!,!;!"; -uint16_t mode_halloween_eyes() +void mode_halloween_eyes() { enum eyeState : uint8_t { initializeOn = 0, @@ -2764,14 +2731,14 @@ uint16_t mode_halloween_eyes() uint32_t blinkEndTime; }; - if (SEGLEN <= 1) return mode_static(); + if (SEGLEN <= 1) mode_static(); const unsigned maxWidth = strip.isMatrix ? SEG_W : SEGLEN; const unsigned HALLOWEEN_EYE_SPACE = MAX(2, strip.isMatrix ? SEG_W>>4: SEGLEN>>5); const unsigned HALLOWEEN_EYE_WIDTH = HALLOWEEN_EYE_SPACE/2; unsigned eyeLength = (2*HALLOWEEN_EYE_WIDTH) + HALLOWEEN_EYE_SPACE; - if (eyeLength >= maxWidth) return mode_static(); //bail if segment too short + if (eyeLength >= maxWidth) mode_static(); //bail if segment too short - if (!SEGENV.allocateData(sizeof(EyeData))) return mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(EyeData))) mode_static(); //allocation failed EyeData& data = *reinterpret_cast(SEGENV.data); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); //fill background @@ -2893,14 +2860,12 @@ uint16_t mode_halloween_eyes() } data.startTime = strip.now; } - - return FRAMETIME; } static const char _data_FX_MODE_HALLOWEEN_EYES[] PROGMEM = "Halloween Eyes@Eye off time,Eye on time,,,,,Overlay;!,!;!;12"; //Speed slider sets amount of LEDs lit, intensity sets unlit -uint16_t mode_static_pattern() +void mode_static_pattern() { unsigned lit = 1 + SEGMENT.speed; unsigned unlit = 1 + SEGMENT.intensity; @@ -2915,13 +2880,11 @@ uint16_t mode_static_pattern() drawingLit = !drawingLit; } } - - return FRAMETIME; } static const char _data_FX_MODE_STATIC_PATTERN[] PROGMEM = "Solid Pattern@Fg size,Bg size;Fg,!;!;;pal=0"; -uint16_t mode_tri_static_pattern() +void mode_tri_static_pattern() { unsigned segSize = (SEGMENT.intensity >> 5) +1; unsigned currSeg = 0; @@ -2941,15 +2904,13 @@ uint16_t mode_tri_static_pattern() currSegCount = 0; } } - - return FRAMETIME; } static const char _data_FX_MODE_TRI_STATIC_PATTERN[] PROGMEM = "Solid Pattern Tri@,Size;1,2,3;;;pal=0"; -static uint16_t spots_base(uint16_t threshold) +static void spots_base(uint16_t threshold) { - if (SEGLEN <= 1) return mode_static(); + if (SEGLEN <= 1) mode_static(); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); unsigned maxZones = SEGLEN >> 2; @@ -2970,26 +2931,24 @@ static uint16_t spots_base(uint16_t threshold) } } } - - return FRAMETIME; } //Intensity slider sets number of "lights", speed sets LEDs per light -uint16_t mode_spots() +void mode_spots() { - return spots_base((255 - SEGMENT.speed) << 8); + spots_base((255 - SEGMENT.speed) << 8); } static const char _data_FX_MODE_SPOTS[] PROGMEM = "Spots@Spread,Width,,,,,Overlay;!,!;!"; //Intensity slider sets number of "lights", LEDs per light fade in and out -uint16_t mode_spots_fade() +void mode_spots_fade() { unsigned counter = strip.now * ((SEGMENT.speed >> 2) +8); unsigned t = triwave16(counter); unsigned tr = (t >> 1) + (t >> 2); - return spots_base(tr); + spots_base(tr); } static const char _data_FX_MODE_SPOTS_FADE[] PROGMEM = "Spots Fade@Spread,Width,,,,,Overlay;!,!;!"; @@ -3003,13 +2962,13 @@ typedef struct Ball { /* * Bouncing Balls Effect */ -uint16_t mode_bouncing_balls(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_bouncing_balls(void) { + if (SEGLEN <= 1) mode_static(); //allocate segment data const unsigned strips = SEGMENT.nrOfVStrips(); // adapt for 2D const size_t maxNumBalls = 16; unsigned dataSize = sizeof(ball) * maxNumBalls; - if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize * strips)) mode_static(); //allocation failed Ball* balls = reinterpret_cast(SEGENV.data); @@ -3071,8 +3030,6 @@ uint16_t mode_bouncing_balls(void) { for (unsigned stripNr=0; stripNr(SEGENV.data); @@ -3172,8 +3129,6 @@ static uint16_t rolling_balls(void) { balls[i].lastBounceUpdate = strip.now; balls[i].height = thisHeight; } - - return FRAMETIME; } static const char _data_FX_MODE_ROLLINGBALLS[] PROGMEM = "Rolling Balls@!,# of balls,,,,Collide,Overlay,Trails;!,!,!;!;1;m12=1"; //bar #endif // WLED_PS_DONT_REPLACE_1D_FX @@ -3201,7 +3156,7 @@ typedef struct PacManChars { bool eaten; // used for power dots only } pacmancharacters_t; -static uint16_t mode_pacman(void) { +static void mode_pacman(void) { constexpr unsigned ORANGEYELLOW = 0xFFCC00; constexpr unsigned PURPLEISH = 0xB000B0; constexpr unsigned ORANGEISH = 0xFF8800; @@ -3221,7 +3176,7 @@ static uint16_t mode_pacman(void) { // Allocate segment data unsigned dataSize = sizeof(pacmancharacters_t) * (numGhosts + maxPowerDots + 1); // +1 is the PacMan character - if (SEGLEN <= 16 + (2*numGhosts) || !SEGENV.allocateData(dataSize)) return mode_static(); + if (SEGLEN <= 16 + (2*numGhosts) || !SEGENV.allocateData(dataSize)) mode_static(); pacmancharacters_t *character = reinterpret_cast(SEGENV.data); // Calculate when blue ghosts start blinking. @@ -3369,7 +3324,6 @@ static uint16_t mode_pacman(void) { } SEGMENT.blur(SEGMENT.custom2>>1); - return FRAMETIME; } static const char _data_FX_MODE_PACMAN[] PROGMEM = "PacMan@Speed,# of PowerDots,Blink distance,Blur,# of Ghosts,Dots,Smear,Compact;;!;1;m12=0,sx=192,ix=64,c1=64,c2=0,c3=12,o1=1,o2=0"; @@ -3377,8 +3331,8 @@ static const char _data_FX_MODE_PACMAN[] PROGMEM = "PacMan@Speed,# of PowerDots, /* * Sinelon stolen from FASTLED examples */ -static uint16_t sinelon_base(bool dual, bool rainbow=false) { - if (SEGLEN <= 1) return mode_static(); +static void sinelon_base(bool dual, bool rainbow=false) { + if (SEGLEN <= 1) mode_static(); SEGMENT.fade_out(SEGMENT.intensity); unsigned pos = beatsin16_t(SEGMENT.speed/10,0,SEGLEN-1); if (SEGENV.call == 0) SEGENV.aux0 = pos; @@ -3407,25 +3361,23 @@ static uint16_t sinelon_base(bool dual, bool rainbow=false) { } SEGENV.aux0 = pos; } - - return FRAMETIME; } -uint16_t mode_sinelon(void) { - return sinelon_base(false); +void mode_sinelon(void) { + sinelon_base(false); } static const char _data_FX_MODE_SINELON[] PROGMEM = "Sinelon@!,Trail;!,!,!;!"; -uint16_t mode_sinelon_dual(void) { - return sinelon_base(true); +void mode_sinelon_dual(void) { + sinelon_base(true); } static const char _data_FX_MODE_SINELON_DUAL[] PROGMEM = "Sinelon Dual@!,Trail;!,!,!;!"; -uint16_t mode_sinelon_rainbow(void) { - return sinelon_base(false, true); +void mode_sinelon_rainbow(void) { + sinelon_base(false, true); } static const char _data_FX_MODE_SINELON_RAINBOW[] PROGMEM = "Sinelon Rainbow@!,Trail;,,!;!"; @@ -3435,7 +3387,7 @@ void glitter_base(uint8_t intensity, uint32_t col = ULTRAWHITE) { } //Glitter with palette background, inspired by https://gist.github.com/kriegsman/062e10f7f07ba8518af6 -uint16_t mode_glitter() +void mode_glitter() { if (!SEGMENT.check2) { // use "* Color 1" palette for solid background (replacing "Solid glitter") unsigned counter = 0; @@ -3452,17 +3404,15 @@ uint16_t mode_glitter() } } glitter_base(SEGMENT.intensity, SEGCOLOR(2) ? SEGCOLOR(2) : ULTRAWHITE); - return FRAMETIME; } static const char _data_FX_MODE_GLITTER[] PROGMEM = "Glitter@!,!,,,,,Overlay;,,Glitter color;!;;pal=11,m12=0"; //pixels //Solid colour background with glitter (can be replaced by Glitter) -uint16_t mode_solid_glitter() +void mode_solid_glitter() { SEGMENT.fill(SEGCOLOR(0)); glitter_base(SEGMENT.intensity, SEGCOLOR(2) ? SEGCOLOR(2) : ULTRAWHITE); - return FRAMETIME; } static const char _data_FX_MODE_SOLID_GLITTER[] PROGMEM = "Solid Glitter@,!;Bg,,Glitter color;;;m12=0"; @@ -3480,14 +3430,14 @@ typedef struct Spark { * POPCORN * modified from https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Popcorn.h */ -uint16_t mode_popcorn(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_popcorn(void) { + if (SEGLEN <= 1) mode_static(); //allocate segment data unsigned strips = SEGMENT.nrOfVStrips(); unsigned usablePopcorns = maxNumPopcorn; if (usablePopcorns * strips * sizeof(spark) > FAIR_DATA_PER_SEG) usablePopcorns = FAIR_DATA_PER_SEG / (strips * sizeof(spark)) + 1; // at least 1 popcorn per vstrip unsigned dataSize = sizeof(spark) * usablePopcorns; // on a matrix 64x64 this could consume a little less than 27kB when Bar expansion is used - if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize * strips)) mode_static(); //allocation failed Spark* popcorn = reinterpret_cast(SEGENV.data); @@ -3536,8 +3486,6 @@ uint16_t mode_popcorn(void) { for (unsigned stripNr=0; stripNr maxStars) numStars = maxStars; unsigned dataSize = sizeof(star) * numStars; - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed uint32_t it = strip.now; @@ -3761,7 +3712,6 @@ uint16_t mode_starburst(void) { } } } - return FRAMETIME; } #undef STARBURST_MAX_FRAG static const char _data_FX_MODE_STARBURST[] PROGMEM = "Fireworks Starburst@Chance,Fragments,,,,,Overlay;,!;!;;pal=11,m12=0"; @@ -3773,9 +3723,9 @@ static const char _data_FX_MODE_STARBURST[] PROGMEM = "Fireworks Starburst@Chanc * adapted from: http://www.anirama.com/1000leds/1d-fireworks/ * adapted for 2D WLED by blazoncek (Blaz Kristan (AKA blazoncek)) */ -uint16_t mode_exploding_fireworks(void) +void mode_exploding_fireworks(void) { - if (SEGLEN <= 1) return mode_static(); + if (SEGLEN <= 1) mode_static(); const int cols = SEGMENT.is2D() ? SEG_W : 1; const int rows = SEGMENT.is2D() ? SEG_H : SEGLEN; @@ -3788,7 +3738,7 @@ uint16_t mode_exploding_fireworks(void) unsigned numSparks = min(5 + ((rows*cols) >> 1), maxSparks); unsigned dataSize = sizeof(spark) * numSparks; - if (!SEGENV.allocateData(dataSize + sizeof(float))) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize + sizeof(float))) mode_static(); //allocation failed float *dying_gravity = reinterpret_cast(SEGENV.data + dataSize); if (dataSize != SEGENV.aux1) { //reset to flare if sparks were reallocated (it may be good idea to reset segment if bounds change) @@ -3900,8 +3850,6 @@ uint16_t mode_exploding_fireworks(void) SEGENV.aux0 = 0; //back to flare } } - - return FRAMETIME; } #undef MAX_SPARKS static const char _data_FX_MODE_EXPLODING_FIREWORKS[] PROGMEM = "Fireworks 1D@Gravity,Firing side;!,!;!;12;pal=11,ix=128"; @@ -3911,14 +3859,14 @@ static const char _data_FX_MODE_EXPLODING_FIREWORKS[] PROGMEM = "Fireworks 1D@Gr * Drip Effect * ported of: https://www.youtube.com/watch?v=sru2fXh4r7k */ -uint16_t mode_drip(void) +void mode_drip(void) { - if (SEGLEN <= 1) return mode_static(); + if (SEGLEN <= 1) mode_static(); //allocate segment data unsigned strips = SEGMENT.nrOfVStrips(); const int maxNumDrops = 4; unsigned dataSize = sizeof(spark) * maxNumDrops; - if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize * strips)) mode_static(); //allocation failed Spark* drops = reinterpret_cast(SEGENV.data); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); @@ -3988,8 +3936,6 @@ uint16_t mode_drip(void) for (unsigned stripNr=0; stripNr(SEGENV.data); //if (SEGENV.call == 0) SEGMENT.fill(SEGCOLOR(1)); // will fill entire segment (1D or 2D), then use drop->step = 0 below @@ -4078,8 +4024,6 @@ uint16_t mode_tetrix(void) { for (unsigned stripNr=0; stripNr size) SEGENV.aux1 -= size; else SEGENV.aux1 = 0; if (SEGENV.aux1 < active_leds) SEGENV.aux1 = active_leds; } - - return FRAMETIME; } static const char _data_FX_MODE_PERCENT[] PROGMEM = "Percent@!,% of fill,,,,One color;!,!;!"; @@ -4165,7 +4105,7 @@ static const char _data_FX_MODE_PERCENT[] PROGMEM = "Percent@!,% of fill,,,,One * Modulates the brightness similar to a heartbeat * (unimplemented?) tries to draw an ECG approximation on a 2D matrix */ -uint16_t mode_heartbeat(void) { +void mode_heartbeat(void) { unsigned bpm = 40 + (SEGMENT.speed >> 3); uint32_t msPerBeat = (60000L / bpm); uint32_t secondBeat = (msPerBeat / 3); @@ -4188,8 +4128,6 @@ uint16_t mode_heartbeat(void) { for (unsigned i = 0; i < SEGLEN; i++) { SEGMENT.setPixelColor(i, color_blend(SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), uint8_t(255 - (SEGENV.aux1 >> 8)))); } - - return FRAMETIME; } static const char _data_FX_MODE_HEARTBEAT[] PROGMEM = "Heartbeat@!,!;!,!;!;01;m12=1"; @@ -4234,7 +4172,7 @@ static CRGB pacifica_one_layer(uint16_t i, const CRGBPalette16& p, uint16_t cist return CRGB(ColorFromPalette(p, sindex8, bri, LINEARBLEND)); } -uint16_t mode_pacifica() +void mode_pacifica() { uint32_t nowOld = strip.now; @@ -4306,7 +4244,6 @@ uint16_t mode_pacifica() } strip.now = nowOld; - return FRAMETIME; } static const char _data_FX_MODE_PACIFICA[] PROGMEM = "Pacifica@!,Angle;;!;;pal=51"; @@ -4314,8 +4251,8 @@ static const char _data_FX_MODE_PACIFICA[] PROGMEM = "Pacifica@!,Angle;;!;;pal=5 /* * Mode simulates a gradual sunrise */ -uint16_t mode_sunrise() { - if (SEGLEN <= 1) return mode_static(); +void mode_sunrise() { + if (SEGLEN <= 1) mode_static(); //speed 0 - static sun //speed 1 - 60: sunrise time in minutes //speed 60 - 120 : sunset time in minutes - 60; @@ -4356,8 +4293,6 @@ uint16_t mode_sunrise() { SEGMENT.setPixelColor(i, c); SEGMENT.setPixelColor(SEGLEN - i - 1, c); } - - return FRAMETIME; } static const char _data_FX_MODE_SUNRISE[] PROGMEM = "Sunrise@Time [min],Width;;!;;pal=35,sx=60"; @@ -4365,7 +4300,7 @@ static const char _data_FX_MODE_SUNRISE[] PROGMEM = "Sunrise@Time [min],Width;;! /* * Effects by Andrew Tuline */ -static uint16_t phased_base(uint8_t moder) { // We're making sine waves here. By Andrew Tuline. +static void phased_base(uint8_t moder) { // We're making sine waves here. By Andrew Tuline. unsigned allfreq = 16; // Base frequency. float *phase = reinterpret_cast(&SEGENV.step); // Phase change value gets calculated (float fits into unsigned long). @@ -4386,24 +4321,22 @@ static uint16_t phased_base(uint8_t moder) { // We're making si index += 256 / SEGLEN; if (SEGLEN > 256) index ++; // Correction for segments longer than 256 LEDs } - - return FRAMETIME; } -uint16_t mode_phased(void) { - return phased_base(0); +void mode_phased(void) { + phased_base(0); } static const char _data_FX_MODE_PHASED[] PROGMEM = "Phased@!,!;!,!;!"; -uint16_t mode_phased_noise(void) { - return phased_base(1); +void mode_phased_noise(void) { + phased_base(1); } static const char _data_FX_MODE_PHASEDNOISE[] PROGMEM = "Phased Noise@!,!;!,!;!"; -uint16_t mode_twinkleup(void) { // A very short twinkle routine with fade-in and dual controls. By Andrew Tuline. +void mode_twinkleup(void) { // A very short twinkle routine with fade-in and dual controls. By Andrew Tuline. unsigned prevSeed = random16_get_seed(); // save seed so we can restore it at the end of the function random16_set_seed(535); // The randomizer needs to be re-set each time through the loop in order for the same 'random' numbers to be the same each time through. @@ -4415,18 +4348,17 @@ uint16_t mode_twinkleup(void) { // A very short twinkle routine } random16_set_seed(prevSeed); // restore original seed so other effects can use "random" PRNG - return FRAMETIME; } static const char _data_FX_MODE_TWINKLEUP[] PROGMEM = "Twinkleup@!,Intensity;!,!;!;;m12=0"; // Peaceful noise that's slow and with gradually changing palettes. Does not support WLED palettes or default colours or controls. -uint16_t mode_noisepal(void) { // Slow noise palette by Andrew Tuline. +void mode_noisepal(void) { // Slow noise palette by Andrew Tuline. unsigned scale = 15 + (SEGMENT.intensity >> 2); //default was 30 //#define scale 30 unsigned dataSize = sizeof(CRGBPalette16) * 2; //allocate space for 2 Palettes (2 * 16 * 3 = 96 bytes) - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed CRGBPalette16* palettes = reinterpret_cast(SEGENV.data); @@ -4450,8 +4382,6 @@ uint16_t mode_noisepal(void) { // Slow noise } SEGENV.aux0 += beatsin8_t(10,1,4); // Moving along the distance. Vary it a bit with a sine wave. - - return FRAMETIME; } static const char _data_FX_MODE_NOISEPAL[] PROGMEM = "Noise Pal@!,Scale;;!"; @@ -4459,7 +4389,7 @@ static const char _data_FX_MODE_NOISEPAL[] PROGMEM = "Noise Pal@!,Scale;;!"; // Sine waves that have controllable phase change speed, frequency and cutoff. By Andrew Tuline. // SEGMENT.speed ->Speed, SEGMENT.intensity -> Frequency (SEGMENT.fft1 -> Color change, SEGMENT.fft2 -> PWM cutoff) // -uint16_t mode_sinewave(void) { // Adjustable sinewave. By Andrew Tuline +void mode_sinewave(void) { // Adjustable sinewave. By Andrew Tuline //#define qsuba(x, b) ((x>b)?x-b:0) // Analog Unsigned subtraction macro. if result <0, then => 0 unsigned colorIndex = strip.now /32;//(256 - SEGMENT.fft1); // Amount of colour change. @@ -4472,8 +4402,6 @@ uint16_t mode_sinewave(void) { // Adjustable sinewave. By Andrew Tul //setPixCol(i, i*colorIndex/255, pixBri); SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i*colorIndex/255, false, PALETTE_SOLID_WRAP, 0), pixBri)); } - - return FRAMETIME; } static const char _data_FX_MODE_SINEWAVE[] PROGMEM = "Sine@!,Scale;;!"; @@ -4481,7 +4409,7 @@ static const char _data_FX_MODE_SINEWAVE[] PROGMEM = "Sine@!,Scale;;!"; /* * Best of both worlds from Palette and Spot effects. By Aircoookie */ -uint16_t mode_flow(void) +void mode_flow(void) { unsigned counter = 0; if (SEGMENT.speed != 0) @@ -4510,8 +4438,6 @@ uint16_t mode_flow(void) SEGMENT.setPixelColor(pos + led, SEGMENT.color_from_palette(colorIndex, false, true, 255)); } } - - return FRAMETIME; } static const char _data_FX_MODE_FLOW[] PROGMEM = "Flow@!,Zones;;!;;m12=1"; //vertical @@ -4520,9 +4446,9 @@ static const char _data_FX_MODE_FLOW[] PROGMEM = "Flow@!,Zones;;!;;m12=1"; //ver * Dots waving around in a sine/pendulum motion. * Little pixel birds flying in a circle. By Aircoookie */ -uint16_t mode_chunchun(void) +void mode_chunchun(void) { - if (SEGLEN <= 1) return mode_static(); + if (SEGLEN <= 1) mode_static(); SEGMENT.fade_out(254); // add a bit of trail unsigned counter = strip.now * (6 + (SEGMENT.speed >> 4)); unsigned numBirds = 2 + (SEGLEN >> 3); // 2 + 1/8 of a segment @@ -4536,7 +4462,6 @@ uint16_t mode_chunchun(void) bird = constrain(bird, 0U, SEGLEN-1U); SEGMENT.setPixelColor(bird, SEGMENT.color_from_palette((i * 255)/ numBirds, false, false, 0)); // no palette wrapping } - return FRAMETIME; } static const char _data_FX_MODE_CHUNCHUN[] PROGMEM = "Chunchun@!,Gap size;!,!;!"; @@ -4571,15 +4496,15 @@ typedef struct Spotlight { * * By Steve Pomeroy @xxv */ -uint16_t mode_dancing_shadows(void) +void mode_dancing_shadows(void) { - if (SEGLEN <= 1) return mode_static(); + if (SEGLEN <= 1) mode_static(); unsigned numSpotlights = map(SEGMENT.intensity, 0, 255, 2, SPOT_MAX_COUNT); // 49 on 32 segment ESP32, 17 on 16 segment ESP8266 bool initialize = SEGENV.aux0 != numSpotlights; SEGENV.aux0 = numSpotlights; unsigned dataSize = sizeof(spotlight) * numSpotlights; - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed Spotlight* spotlights = reinterpret_cast(SEGENV.data); SEGMENT.fill(BLACK); @@ -4683,8 +4608,6 @@ uint16_t mode_dancing_shadows(void) } } } - - return FRAMETIME; } static const char _data_FX_MODE_DANCING_SHADOWS[] PROGMEM = "Dancing Shadows@!,# of shadows;!;!"; #endif // WLED_PS_DONT_REPLACE_1D_FX @@ -4693,7 +4616,7 @@ static const char _data_FX_MODE_DANCING_SHADOWS[] PROGMEM = "Dancing Shadows@!,# Imitates a washing machine, rotating same waves forward, then pause, then backward. By Stefan Seegel */ -uint16_t mode_washing_machine(void) { +void mode_washing_machine(void) { int speed = tristate_square8(strip.now >> 7, 90, 15); SEGENV.step += (speed * 2048) / (512 - SEGMENT.speed); @@ -4702,8 +4625,6 @@ uint16_t mode_washing_machine(void) { uint8_t col = sin8_t(((SEGMENT.intensity / 25 + 1) * 255 * i / SEGLEN) + (SEGENV.step >> 7)); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(col, false, PALETTE_SOLID_WRAP, 3)); } - - return FRAMETIME; } static const char _data_FX_MODE_WASHING_MACHINE[] PROGMEM = "Washing Machine@!,!;;!"; @@ -4712,12 +4633,11 @@ static const char _data_FX_MODE_WASHING_MACHINE[] PROGMEM = "Washing Machine@!,! Image effect Draws a .gif image from filesystem on the matrix/strip */ -uint16_t mode_image(void) { +void mode_image(void) { #ifndef WLED_ENABLE_GIF - return mode_static(); + mode_static(); #else renderImageToSegment(SEGMENT); - return FRAMETIME; #endif // if (status != 0 && status != 254 && status != 255) { // Serial.print("GIF renderer return: "); @@ -4730,10 +4650,10 @@ static const char _data_FX_MODE_IMAGE[] PROGMEM = "Image@!,Blur,;;;12;sx=128,ix= Blends random colors across palette Modified, originally by Mark Kriegsman https://gist.github.com/kriegsman/1f7ccbbfa492a73c015e */ -uint16_t mode_blends(void) { +void mode_blends(void) { unsigned pixelLen = SEGLEN > UINT8_MAX ? UINT8_MAX : SEGLEN; unsigned dataSize = sizeof(uint32_t) * (pixelLen + 1); // max segment length of 56 pixels on 16 segment ESP8266 - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed uint32_t* pixels = reinterpret_cast(SEGENV.data); uint8_t blendSpeed = map(SEGMENT.intensity, 0, UINT8_MAX, 10, 128); unsigned shift = (strip.now * ((SEGMENT.speed >> 3) +1)) >> 8; @@ -4748,8 +4668,6 @@ uint16_t mode_blends(void) { SEGMENT.setPixelColor(i, pixels[offset++]); if (offset >= pixelLen) offset = 0; } - - return FRAMETIME; } static const char _data_FX_MODE_BLENDS[] PROGMEM = "Blends@Shift speed,Blend speed;;!"; @@ -4779,11 +4697,11 @@ typedef struct TvSim { uint16_t pb = 0; } tvSim; -uint16_t mode_tv_simulator(void) { +void mode_tv_simulator(void) { int nr, ng, nb, r, g, b, i, hue; uint8_t sat, bri, j; - if (!SEGENV.allocateData(sizeof(tvSim))) return mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(tvSim))) mode_static(); //allocation failed TvSim* tvSimulator = reinterpret_cast(SEGENV.data); uint8_t colorSpeed = map(SEGMENT.speed, 0, UINT8_MAX, 1, 20); @@ -4877,8 +4795,6 @@ uint16_t mode_tv_simulator(void) { tvSimulator->pb = nb; SEGENV.aux0 = 0; } - - return FRAMETIME; } static const char _data_FX_MODE_TV_SIMULATOR[] PROGMEM = "TV Simulator@!,!;;!;01"; @@ -4993,11 +4909,11 @@ class AuroraWave { bool stillAlive() { return alive; } }; -uint16_t mode_aurora(void) { +void mode_aurora(void) { AuroraWave* waves; SEGENV.aux1 = map(SEGMENT.intensity, 0, 255, 2, W_MAX_COUNT); // aux1 = Wavecount if (!SEGENV.allocateData(sizeof(AuroraWave) * SEGENV.aux1)) { - return mode_static(); + mode_static(); } waves = reinterpret_cast(SEGENV.data); @@ -5026,7 +4942,6 @@ uint16_t mode_aurora(void) { SEGMENT.setPixelColor(i, mixedRgb); } - return FRAMETIME; } static const char _data_FX_MODE_AURORA[] PROGMEM = "Aurora@!,!;1,2,3;!;;sx=24,pal=50"; @@ -5038,16 +4953,14 @@ static const char _data_FX_MODE_AURORA[] PROGMEM = "Aurora@!,!;1,2,3;!;;sx=24,pa ///////////////////////// // 16 bit perlinmove. Use Perlin Noise instead of sinewaves for movement. By Andrew Tuline. // Controls are speed, # of pixels, faderate. -uint16_t mode_perlinmove(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_perlinmove(void) { + if (SEGLEN <= 1) mode_static(); SEGMENT.fade_out(255-SEGMENT.custom1); for (int i = 0; i < SEGMENT.intensity/16 + 1; i++) { unsigned locn = perlin16(strip.now*128/(260-SEGMENT.speed)+i*15000, strip.now*128/(260-SEGMENT.speed)); // Get a new pixel location from moving noise. unsigned pixloc = map(locn, 50*256, 192*256, 0, SEGLEN-1); // Map that to the length of the strand, and ensure we don't go over. SEGMENT.setPixelColor(pixloc, SEGMENT.color_from_palette(pixloc%255, false, PALETTE_SOLID_WRAP, 0)); } - - return FRAMETIME; } // mode_perlinmove() static const char _data_FX_MODE_PERLINMOVE[] PROGMEM = "Perlin Move@!,# of pixels,Fade rate;!,!;!"; @@ -5056,7 +4969,7 @@ static const char _data_FX_MODE_PERLINMOVE[] PROGMEM = "Perlin Move@!,# of pixel // Waveins // ///////////////////////// // Uses beatsin8() + phase shifting. By: Andrew Tuline -uint16_t mode_wavesins(void) { +void mode_wavesins(void) { for (unsigned i = 0; i < SEGLEN; i++) { uint8_t bri = sin8_t(strip.now/4 + i * SEGMENT.intensity); @@ -5064,8 +4977,6 @@ uint16_t mode_wavesins(void) { //SEGMENT.setPixelColor(i, ColorFromPalette(SEGPALETTE, index, bri, LINEARBLEND)); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0, bri)); } - - return FRAMETIME; } // mode_waveins() static const char _data_FX_MODE_WAVESINS[] PROGMEM = "Wavesins@!,Brightness variation,Starting color,Range of colors,Color variation;!;!"; @@ -5074,8 +4985,8 @@ static const char _data_FX_MODE_WAVESINS[] PROGMEM = "Wavesins@!,Brightness vari // Flow Stripe // ////////////////////////////// // By: ldirko https://editor.soulmatelights.com/gallery/392-flow-led-stripe , modifed by: Andrew Tuline, fixed by @DedeHai -uint16_t mode_FlowStripe(void) { - if (SEGLEN <= 1) return mode_static(); +void mode_FlowStripe(void) { + if (SEGLEN <= 1) mode_static(); const int hl = SEGLEN * 10 / 13; uint8_t hue = strip.now / (SEGMENT.speed+1); uint32_t t = strip.now / (SEGMENT.intensity/8+1); @@ -5087,8 +4998,6 @@ uint16_t mode_FlowStripe(void) { byte b = sin8_t(c + t/8); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(b + hue, false, true, 3)); } - - return FRAMETIME; } // mode_FlowStripe() static const char _data_FX_MODE_FLOWSTRIPE[] PROGMEM = "Flow Stripe@Hue speed,Effect speed;;!;pal=11"; @@ -5097,8 +5006,8 @@ static const char _data_FX_MODE_FLOWSTRIPE[] PROGMEM = "Flow Stripe@Hue speed,Ef It can be used as an overlay to other effects or standalone by DedeHai (Damian Schneider), based on idea from @Charming-Lime (#4905) */ -uint16_t mode_shimmer() { - if(!SEGENV.allocateData(sizeof(uint32_t))) { return mode_static(); } +void mode_shimmer() { + if(!SEGENV.allocateData(sizeof(uint32_t))) { mode_static(); } uint32_t* lastTime = reinterpret_cast(SEGENV.data); uint32_t radius = (SEGMENT.custom1 * SEGLEN >> 7) + 1; // [1, 2*SEGLEN+1] pixels @@ -5160,8 +5069,6 @@ uint16_t mode_shimmer() { SEGMENT.setPixelColor(i, SEGCOLOR(1)); } } - - return FRAMETIME; } static const char _data_FX_MODE_SHIMMER[] PROGMEM = "Shimmer@Speed,Interval,Size,Granular,Flow,Zebra,Reverse,Sporadic;Fx,Bg,Cx;!;1;pal=15,sx=220,ix=10,c2=0,c3=0"; @@ -5171,8 +5078,8 @@ static const char _data_FX_MODE_SHIMMER[] PROGMEM = "Shimmer@Speed,Interval,Size // Black hole -uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DBlackHole(void) { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5196,8 +5103,6 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma SEGMENT.setPixelColorXY(cols/2, rows/2, WHITE); // blur everything a bit if (SEGMENT.check3) SEGMENT.blur(16, cols*rows < 100); - - return FRAMETIME; } // 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.,Solid,,Blur;!;!;2;pal=11"; @@ -5205,8 +5110,8 @@ static const char _data_FX_MODE_2DBLACKHOLE[] PROGMEM = "Black Hole@Fade rate,Ou //////////////////////////// // 2D Colored Bursts // //////////////////////////// -uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.soulmatelights.com/gallery/819-colored-bursts , modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DColoredBursts() { // By: ldirko https://editor.soulmatelights.com/gallery/819-colored-bursts , modified by: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5248,8 +5153,6 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so } } SEGMENT.blur(SEGMENT.custom3>>1, SEGMENT.check2); - - return FRAMETIME; } // mode_2DColoredBursts() static const char _data_FX_MODE_2DCOLOREDBURSTS[] PROGMEM = "Colored Bursts@Speed,# of lines,,,Blur,Gradient,Smear,Dots;;!;2;c3=16"; @@ -5257,8 +5160,8 @@ static const char _data_FX_MODE_2DCOLOREDBURSTS[] PROGMEM = "Colored Bursts@Spee ///////////////////// // 2D DNA // ///////////////////// -uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pastebin.com/pCkkkzcs. Updated by Preyy. WLED conversion by Andrew Tuline. - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Ddna(void) { // dna originally by by ldirko at https://pastebin.com/pCkkkzcs. Updated by Preyy. WLED conversion by Andrew Tuline. + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5269,16 +5172,14 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa SEGMENT.setPixelColorXY(i, beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4+128), ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10+128), LINEARBLEND)); } SEGMENT.blur(SEGMENT.intensity / (8 - (SEGMENT.check1 * 2)), SEGMENT.check1); - - return FRAMETIME; } // mode_2Ddna() static const char _data_FX_MODE_2DDNA[] PROGMEM = "DNA@Scroll speed,Blur,,,,Smear;;!;2;ix=0"; ///////////////////////// // 2D DNA Spiral // ///////////////////////// -uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulmatelights.com/gallery/512-dna-spiral-variation , modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DDNASpiral() { // By: ldirko https://editor.soulmatelights.com/gallery/512-dna-spiral-variation , modified by: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5316,8 +5217,6 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma } } SEGMENT.blur(((uint16_t)SEGMENT.custom1 * 3) / (6 + SEGMENT.check1), SEGMENT.check1); - - return FRAMETIME; } // mode_2DDNASpiral() static const char _data_FX_MODE_2DDNASPIRAL[] PROGMEM = "DNA Spiral@Scroll speed,Y frequency,Blur,,,Smear;;!;2;c1=0"; @@ -5325,8 +5224,8 @@ static const char _data_FX_MODE_2DDNASPIRAL[] PROGMEM = "DNA Spiral@Scroll speed ///////////////////////// // 2D Drift // ///////////////////////// -uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmatelights.com/gallery/884-drift , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DDrift() { // By: Stepko https://editor.soulmatelights.com/gallery/884-drift , Modified by: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5346,8 +5245,6 @@ uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmateli if (SEGMENT.check1) SEGMENT.setPixelColorXY(colsCenter + myCos, rowsCenter + mySin, ColorFromPalette(SEGPALETTE, (i * 20) + t_20, 255, LINEARBLEND)); } SEGMENT.blur(SEGMENT.intensity>>(3 - SEGMENT.check2), SEGMENT.check2); - - return FRAMETIME; } // mode_2DDrift() static const char _data_FX_MODE_2DDRIFT[] PROGMEM = "Drift@Rotation speed,Blur,,,,Twin,Smear;;!;2;ix=0"; @@ -5355,8 +5252,8 @@ static const char _data_FX_MODE_2DDRIFT[] PROGMEM = "Drift@Rotation speed,Blur,, ////////////////////////// // 2D Firenoise // ////////////////////////// -uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline. Yet another short routine. - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline. Yet another short routine. + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5380,8 +5277,6 @@ uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline SEGMENT.setPixelColorXY(j, i, ColorFromPalette(pal, min(i*indexx/11, 225U), i*255/rows, LINEARBLEND)); // With that value, look up the 8 bit colour palette value and assign it to the current LED. } // for i } // for j - - return FRAMETIME; } // mode_2Dfirenoise() static const char _data_FX_MODE_2DFIRENOISE[] PROGMEM = "Firenoise@X scale,Y scale,,,,Palette;;!;2;pal=66"; @@ -5389,8 +5284,8 @@ static const char _data_FX_MODE_2DFIRENOISE[] PROGMEM = "Firenoise@X scale,Y sca ////////////////////////////// // 2D Frizzles // ////////////////////////////// -uint16_t mode_2DFrizzles(void) { // By: Stepko https://editor.soulmatelights.com/gallery/640-color-frizzles , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DFrizzles(void) { // By: Stepko https://editor.soulmatelights.com/gallery/640-color-frizzles , Modified by: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5402,7 +5297,6 @@ uint16_t mode_2DFrizzles(void) { // By: Stepko https://editor.so ColorFromPalette(SEGPALETTE, beatsin8_t(12, 0, 255), 255, LINEARBLEND)); } SEGMENT.blur(SEGMENT.custom1 >> (3 + SEGMENT.check1), SEGMENT.check1); - return FRAMETIME; } // mode_2DFrizzles() static const char _data_FX_MODE_2DFRIZZLES[] PROGMEM = "Frizzles@X frequency,Y frequency,Blur,,,Smear;;!;2"; @@ -5414,13 +5308,13 @@ typedef struct Cell { uint8_t alive : 1, faded : 1, toggleStatus : 1, edgeCell: 1, oscillatorCheck : 1, spaceshipCheck : 1, unused : 2; } Cell; -uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https://natureofcode.com/book/chapter-7-cellular-automata/ +void mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https://natureofcode.com/book/chapter-7-cellular-automata/ // and https://github.com/DougHaber/nlife-color , Modified By: Brandon Butler - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W, rows = SEG_H; const unsigned maxIndex = cols * rows; - if (!SEGENV.allocateData(SEGMENT.length() * sizeof(Cell))) return mode_static(); // allocation failed + if (!SEGENV.allocateData(SEGMENT.length() * sizeof(Cell))) mode_static(); // allocation failed Cell *cells = reinterpret_cast (SEGENV.data); @@ -5479,7 +5373,6 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https: } } } - return FRAMETIME; } // Repeat detection @@ -5563,7 +5456,6 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https: ++generation; SEGENV.step = strip.now; } - return FRAMETIME; } // mode_2Dgameoflife() static const char _data_FX_MODE_2DGAMEOFLIFE[] PROGMEM = "Game Of Life@!,,Blur,,,,,Mutation;!,!;!;2;pal=11,sx=128"; @@ -5571,8 +5463,8 @@ static const char _data_FX_MODE_2DGAMEOFLIFE[] PROGMEM = "Game Of Life@!,,Blur,, ///////////////////////// // 2D Hiphotic // ///////////////////////// -uint16_t mode_2DHiphotic() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DHiphotic() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , Modified by: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5583,8 +5475,6 @@ uint16_t mode_2DHiphotic() { // By: ldirko https://edit SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(sin8_t(cos8_t(x * SEGMENT.speed/16 + a / 3) + sin8_t(y * SEGMENT.intensity/16 + a / 4) + a), false, PALETTE_SOLID_WRAP, 0)); } } - - return FRAMETIME; } // mode_2DHiphotic() static const char _data_FX_MODE_2DHIPHOTIC[] PROGMEM = "Hiphotic@X scale,Y scale,,,Speed;!;!;2"; @@ -5603,13 +5493,13 @@ typedef struct Julia { float xymag; } julia; -uint16_t mode_2DJulia(void) { // An animated Julia set by Andrew Tuline. - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DJulia(void) { // An animated Julia set by Andrew Tuline. + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; - if (!SEGENV.allocateData(sizeof(julia))) return mode_static(); + if (!SEGENV.allocateData(sizeof(julia))) mode_static(); Julia* julias = reinterpret_cast(SEGENV.data); float reAl; @@ -5701,8 +5591,6 @@ uint16_t mode_2DJulia(void) { // An animated Julia set } if(SEGMENT.check1) SEGMENT.blur(100, true); - - return FRAMETIME; } // mode_2DJulia() static const char _data_FX_MODE_2DJULIA[] PROGMEM = "Julia@,Max iterations per pixel,X center,Y center,Area size, Blur;!;!;2;ix=24,c1=128,c2=128,c3=16"; @@ -5710,8 +5598,8 @@ static const char _data_FX_MODE_2DJULIA[] PROGMEM = "Julia@,Max iterations per p ////////////////////////////// // 2D Lissajous // ////////////////////////////// -uint16_t mode_2DLissajous(void) { // By: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DLissajous(void) { // By: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5730,8 +5618,6 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline SEGMENT.setPixelColorXY((uint8_t)xlocn, (uint8_t)ylocn, SEGMENT.color_from_palette(strip.now/100+i, false, PALETTE_SOLID_WRAP, 0)); } SEGMENT.blur(SEGMENT.custom1 >> (1 + SEGMENT.check1 * 3), SEGMENT.check1); - - return FRAMETIME; } // mode_2DLissajous() static const char _data_FX_MODE_2DLISSAJOUS[] PROGMEM = "Lissajous@X frequency,Fade rate,Blur,,Speed,Smear;!;!;2;c1=0"; @@ -5739,15 +5625,15 @@ static const char _data_FX_MODE_2DLISSAJOUS[] PROGMEM = "Lissajous@X frequency,F /////////////////////// // 2D Matrix // /////////////////////// -uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi, and softhack007. - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi, and softhack007. + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; const auto XY = [&](int x, int y) { return (x%cols) + (y%rows) * cols; }; unsigned dataSize = (SEGMENT.length()+7) >> 3; //1 bit per LED for trails - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed if (SEGENV.call == 0) { SEGMENT.fill(BLACK); @@ -5801,8 +5687,6 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. bitSet(SEGENV.data[index], bitNum); } } - - return FRAMETIME; } // mode_2Dmatrix() static const char _data_FX_MODE_2DMATRIX[] PROGMEM = "Matrix@!,Spawning rate,Trail,,,Custom color;Spawn,Trail;;2"; @@ -5810,8 +5694,8 @@ static const char _data_FX_MODE_2DMATRIX[] PROGMEM = "Matrix@!,Spawning rate,Tra ///////////////////////// // 2D Metaballs // ///////////////////////// -uint16_t mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have one of the dimensions be 2 or less. Adapted by Andrew Tuline. - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have one of the dimensions be 2 or less. Adapted by Andrew Tuline. + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5860,8 +5744,6 @@ uint16_t mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have SEGMENT.setPixelColorXY(x3, y3, WHITE); } } - - return FRAMETIME; } // mode_2Dmetaballs() static const char _data_FX_MODE_2DMETABALLS[] PROGMEM = "Metaballs@!;;!;2"; @@ -5869,8 +5751,8 @@ static const char _data_FX_MODE_2DMETABALLS[] PROGMEM = "Metaballs@!;;!;2"; ////////////////////// // 2D Noise // ////////////////////// -uint16_t mode_2Dnoise(void) { // By Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dnoise(void) { // By Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5883,8 +5765,6 @@ uint16_t mode_2Dnoise(void) { // By Andrew Tuline SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, pixelHue8)); } } - - return FRAMETIME; } // mode_2Dnoise() static const char _data_FX_MODE_2DNOISE[] PROGMEM = "Noise2D@!,Scale;;!;2"; @@ -5892,8 +5772,8 @@ static const char _data_FX_MODE_2DNOISE[] PROGMEM = "Noise2D@!,Scale;;!;2"; ////////////////////////////// // 2D Plasma Ball // ////////////////////////////// -uint16_t mode_2DPlasmaball(void) { // By: Stepko https://editor.soulmatelights.com/gallery/659-plasm-ball , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DPlasmaball(void) { // By: Stepko https://editor.soulmatelights.com/gallery/659-plasm-ball , Modified by: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5920,8 +5800,6 @@ uint16_t mode_2DPlasmaball(void) { // By: Stepko https://edito } } SEGMENT.blur(SEGMENT.custom2>>5); - - return FRAMETIME; } // mode_2DPlasmaball() static const char _data_FX_MODE_2DPLASMABALL[] PROGMEM = "Plasma Ball@Speed,,Fade,Blur;;!;2"; @@ -5930,8 +5808,8 @@ static const char _data_FX_MODE_2DPLASMABALL[] PROGMEM = "Plasma Ball@Speed,,Fad // 2D Polar Lights // //////////////////////////////// -uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https://editor.soulmatelights.com/gallery/762-polar-lights , Modified by: Andrew Tuline & @dedehai (palette support) - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https://editor.soulmatelights.com/gallery/762-polar-lights , Modified by: Andrew Tuline & @dedehai (palette support) + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5955,8 +5833,6 @@ uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(palindex, false, false, 255, palbrightness)); } } - - return FRAMETIME; } // mode_2DPolarLights() static const char _data_FX_MODE_2DPOLARLIGHTS[] PROGMEM = "Polar Lights@!,Scale,,,,Flip Palette;;!;2;pal=71"; @@ -5964,8 +5840,8 @@ static const char _data_FX_MODE_2DPOLARLIGHTS[] PROGMEM = "Polar Lights@!,Scale, ///////////////////////// // 2D Pulser // ///////////////////////// -uint16_t mode_2DPulser(void) { // By: ldirko https://editor.soulmatelights.com/gallery/878-pulse-test , modifed by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DPulser(void) { // By: ldirko https://editor.soulmatelights.com/gallery/878-pulse-test , modifed by: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5977,8 +5853,6 @@ uint16_t mode_2DPulser(void) { // By: ldirko https://edi SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, map(y, 0, rows-1, 0, 255), 255, LINEARBLEND)); SEGMENT.blur(SEGMENT.intensity>>4); - - return FRAMETIME; } // mode_2DPulser() static const char _data_FX_MODE_2DPULSER[] PROGMEM = "Pulser@!,Blur;;!;2"; @@ -5986,8 +5860,8 @@ static const char _data_FX_MODE_2DPULSER[] PROGMEM = "Pulser@!,Blur;;!;2"; ///////////////////////// // 2D Sindots // ///////////////////////// -uint16_t mode_2DSindots(void) { // By: ldirko https://editor.soulmatelights.com/gallery/597-sin-dots , modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DSindots(void) { // By: ldirko https://editor.soulmatelights.com/gallery/597-sin-dots , modified by: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6006,8 +5880,6 @@ uint16_t mode_2DSindots(void) { // By: ldirko http SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, i * 255 / 13, 255, LINEARBLEND)); } SEGMENT.blur(SEGMENT.custom2 >> (3 + SEGMENT.check1), SEGMENT.check1); - - return FRAMETIME; } // mode_2DSindots() static const char _data_FX_MODE_2DSINDOTS[] PROGMEM = "Sindots@!,Dot distance,Fade rate,Blur,,Smear;;!;2;"; @@ -6016,9 +5888,9 @@ static const char _data_FX_MODE_2DSINDOTS[] PROGMEM = "Sindots@!,Dot distance,Fa // 2D Squared Swirl // ////////////////////////////// // custom3 affects the blur amount. -uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://gist.github.com/kriegsman/368b316c55221134b160 +void mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://gist.github.com/kriegsman/368b316c55221134b160 // Modifed by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6039,8 +5911,6 @@ uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://g SEGMENT.addPixelColorXY(i, m, ColorFromPalette(SEGPALETTE, strip.now/29, 255, LINEARBLEND)); SEGMENT.addPixelColorXY(j, n, ColorFromPalette(SEGPALETTE, strip.now/41, 255, LINEARBLEND)); SEGMENT.addPixelColorXY(k, p, ColorFromPalette(SEGPALETTE, strip.now/73, 255, LINEARBLEND)); - - return FRAMETIME; } // mode_2Dsquaredswirl() static const char _data_FX_MODE_2DSQUAREDSWIRL[] PROGMEM = "Squared Swirl@,Fade,,,Blur;;!;2"; @@ -6048,13 +5918,13 @@ static const char _data_FX_MODE_2DSQUAREDSWIRL[] PROGMEM = "Squared Swirl@,Fade, ////////////////////////////// // 2D Sun Radiation // ////////////////////////////// -uint16_t mode_2DSunradiation(void) { // By: ldirko https://editor.soulmatelights.com/gallery/599-sun-radiation , modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DSunradiation(void) { // By: ldirko https://editor.soulmatelights.com/gallery/599-sun-radiation , modified by: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; - if (!SEGENV.allocateData(sizeof(byte)*(cols+2)*(rows+2))) return mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(byte)*(cols+2)*(rows+2))) mode_static(); //allocation failed byte *bump = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { @@ -6090,8 +5960,6 @@ uint16_t mode_2DSunradiation(void) { // By: ldirko https://edi } yindex += (cols + 2); } - - return FRAMETIME; } // mode_2DSunradiation() static const char _data_FX_MODE_2DSUNRADIATION[] PROGMEM = "Sun Radiation@Variance,Brightness;;;2"; @@ -6099,8 +5967,8 @@ static const char _data_FX_MODE_2DSUNRADIATION[] PROGMEM = "Sun Radiation@Varian ///////////////////////// // 2D Tartan // ///////////////////////// -uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.soulmatelights.com/gallery/3-tartan , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dtartan(void) { // By: Elliott Kember https://editor.soulmatelights.com/gallery/3-tartan , Modified by: Andrew Tuline + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6129,8 +5997,6 @@ uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.so SEGMENT.addPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, hue, intensity, LINEARBLEND)); } } - - return FRAMETIME; } // mode_2DTartan() static const char _data_FX_MODE_2DTARTAN[] PROGMEM = "Tartan@X scale,Y scale,,,Sharpness;;!;2"; @@ -6138,8 +6004,8 @@ static const char _data_FX_MODE_2DTARTAN[] PROGMEM = "Tartan@X scale,Y scale,,,S ///////////////////////// // 2D spaceships // ///////////////////////// -uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [https://editor.soulmatelights.com/gallery/639-space-ships], adapted by Blaz Kristan (AKA blazoncek) - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [https://editor.soulmatelights.com/gallery/639-space-ships], adapted by Blaz Kristan (AKA blazoncek) + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6170,8 +6036,6 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht } } SEGMENT.blur(SEGMENT.intensity >> 3, SEGMENT.check1); - - return FRAMETIME; } static const char _data_FX_MODE_2DSPACESHIPS[] PROGMEM = "Spaceships@!,Blur,,,,Smear;;!;2"; @@ -6181,8 +6045,8 @@ static const char _data_FX_MODE_2DSPACESHIPS[] PROGMEM = "Spaceships@!,Blur,,,,S ///////////////////////// //// Crazy bees by stepko (c)12.02.21 [https://editor.soulmatelights.com/gallery/651-crazy-bees], adapted by Blaz Kristan (AKA blazoncek), improved by @dedehai #define MAX_BEES 5 -uint16_t mode_2Dcrazybees(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dcrazybees(void) { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6205,7 +6069,7 @@ uint16_t mode_2Dcrazybees(void) { }; } bee_t; - if (!SEGENV.allocateData(sizeof(bee_t)*MAX_BEES)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(bee_t)*MAX_BEES)) mode_static(); //allocation failed bee_t *bee = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { @@ -6243,7 +6107,6 @@ uint16_t mode_2Dcrazybees(void) { } } } - return FRAMETIME; } static const char _data_FX_MODE_2DCRAZYBEES[] PROGMEM = "Crazy Bees@!,Blur,,,,Smear;;!;2;pal=11,ix=0"; #undef MAX_BEES @@ -6254,8 +6117,8 @@ static const char _data_FX_MODE_2DCRAZYBEES[] PROGMEM = "Crazy Bees@!,Blur,,,,Sm ///////////////////////// //// Ghost Rider by stepko (c)2021 [https://editor.soulmatelights.com/gallery/716-ghost-rider], adapted by Blaz Kristan (AKA blazoncek) #define LIGHTERS_AM 64 // max lighters (adequate for 32x32 matrix) -uint16_t mode_2Dghostrider(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dghostrider(void) { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6273,7 +6136,7 @@ uint16_t mode_2Dghostrider(void) { int8_t Vspeed; } lighter_t; - if (!SEGENV.allocateData(sizeof(lighter_t))) return mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(lighter_t))) mode_static(); //allocation failed lighter_t *lighter = reinterpret_cast(SEGENV.data); const size_t maxLighters = min(cols + rows, LIGHTERS_AM); @@ -6332,8 +6195,6 @@ uint16_t mode_2Dghostrider(void) { } SEGMENT.blur(SEGMENT.intensity>>3); } - - return FRAMETIME; } static const char _data_FX_MODE_2DGHOSTRIDER[] PROGMEM = "Ghost Rider@Fade rate,Blur;;!;2"; #undef LIGHTERS_AM @@ -6343,8 +6204,8 @@ static const char _data_FX_MODE_2DGHOSTRIDER[] PROGMEM = "Ghost Rider@Fade rate, //////////////////////////// //// Floating Blobs by stepko (c)2021 [https://editor.soulmatelights.com/gallery/573-blobs], adapted by Blaz Kristan (AKA blazoncek) #define MAX_BLOBS 8 -uint16_t mode_2Dfloatingblobs(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dfloatingblobs(void) { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6359,7 +6220,7 @@ uint16_t mode_2Dfloatingblobs(void) { size_t Amount = (SEGMENT.intensity>>5) + 1; // NOTE: be sure to update MAX_BLOBS if you change this - if (!SEGENV.allocateData(sizeof(blob_t))) return mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(blob_t))) mode_static(); //allocation failed blob_t *blob = reinterpret_cast(SEGENV.data); if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) { @@ -6431,8 +6292,6 @@ uint16_t mode_2Dfloatingblobs(void) { SEGMENT.blur(SEGMENT.custom1>>2); if (SEGENV.step < strip.now) SEGENV.step = strip.now + 2000; // change colors every 2 seconds - - return FRAMETIME; } static const char _data_FX_MODE_2DBLOBS[] PROGMEM = "Blobs@!,# blobs,Blur,Trail;!;!;2;c1=8"; #undef MAX_BLOBS @@ -6441,8 +6300,8 @@ static const char _data_FX_MODE_2DBLOBS[] PROGMEM = "Blobs@!,# blobs,Blur,Trail; //////////////////////////// // 2D Scrolling text // //////////////////////////// -uint16_t mode_2Dscrollingtext(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dscrollingtext(void) { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6582,8 +6441,6 @@ uint16_t mode_2Dscrollingtext(void) { if (xoffset + rotLW < 0) continue; // don't draw characters off-screen SEGMENT.drawCharacter(text[i], xoffset, yoffset, letterWidth, letterHeight, col1, col2, rotate); } - - return FRAMETIME; } static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Offset,Trail,Font size,Rotate,Gradient,,Reverse;!,!,Gradient;!;2;ix=128,c1=0,rev=0,mi=0,rY=0,mY=0"; @@ -6592,8 +6449,8 @@ static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Off // 2D Drift Rose // //////////////////////////// //// Drift Rose by stepko (c)2021 [https://editor.soulmatelights.com/gallery/1369-drift-rose-pattern], adapted by Blaz Kristan (AKA blazoncek) improved by @dedehai -uint16_t mode_2Ddriftrose(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Ddriftrose(void) { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6611,8 +6468,6 @@ uint16_t mode_2Ddriftrose(void) { else SEGMENT.wu_pixel(x, y, ColorFromPalette(SEGPALETTE, i * 10)); } SEGMENT.blur(SEGMENT.intensity >> 4, SEGMENT.check1); - - return FRAMETIME; } static const char _data_FX_MODE_2DDRIFTROSE[] PROGMEM = "Drift Rose@Fade,Blur,,,,Smear;;!;2;pal=11"; @@ -6620,14 +6475,14 @@ static const char _data_FX_MODE_2DDRIFTROSE[] PROGMEM = "Drift Rose@Fade,Blur,,, // 2D PLASMA ROTOZOOMER // ///////////////////////////// // Plasma Rotozoomer by ldirko (c)2020 [https://editor.soulmatelights.com/gallery/457-plasma-rotozoomer], adapted for WLED by Blaz Kristan (AKA blazoncek) -uint16_t mode_2Dplasmarotozoom() { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dplasmarotozoom() { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; unsigned dataSize = SEGMENT.length() + sizeof(float); - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed float *a = reinterpret_cast(SEGENV.data); byte *plasma = reinterpret_cast(SEGENV.data+sizeof(float)); @@ -6657,8 +6512,6 @@ uint16_t mode_2Dplasmarotozoom() { } *a -= 0.03f + float(SEGENV.speed-128)*0.0002f; // rotation speed if(*a < -6283.18530718f) *a += 6283.18530718f; // 1000*2*PI, protect sin/cos from very large input float values (will give wrong results) - - return FRAMETIME; } static const char _data_FX_MODE_2DPLASMAROTOZOOM[] PROGMEM = "Rotozoomer@!,Scale,,,,Alt;;!;2;pal=54"; @@ -6673,13 +6526,13 @@ static const char _data_FX_MODE_2DPLASMAROTOZOOM[] PROGMEM = "Rotozoomer@!,Scale ///////////////////////////////// // * Ripple Peak // ///////////////////////////////// -uint16_t mode_ripplepeak(void) { // * Ripple peak. By Andrew Tuline. +void mode_ripplepeak(void) { // * Ripple peak. By Andrew Tuline. // This currently has no controls. #define MAXSTEPS 16 // Case statement wouldn't allow a variable. unsigned maxRipples = 16; unsigned dataSize = sizeof(Ripple) * maxRipples; - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed Ripple* ripples = reinterpret_cast(SEGENV.data); um_data_t *um_data = getAudioData(); @@ -6738,8 +6591,6 @@ uint16_t mode_ripplepeak(void) { // * Ripple peak. By Andrew Tuli break; } // switch step } // for i - - return FRAMETIME; } // mode_ripplepeak() static const char _data_FX_MODE_RIPPLEPEAK[] PROGMEM = "Ripple Peak@Fade rate,Max # of ripples,Select bin,Volume (min);!,!;!;1v;c2=0,m12=0,si=0"; // Pixel, Beatsin @@ -6749,8 +6600,8 @@ static const char _data_FX_MODE_RIPPLEPEAK[] PROGMEM = "Ripple Peak@Fade rate,Ma // * 2D Swirl // ///////////////////////// // By: Mark Kriegsman https://gist.github.com/kriegsman/5adca44e14ad025e6d3b , modified by Andrew Tuline -uint16_t mode_2DSwirl(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DSwirl(void) { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6778,8 +6629,6 @@ uint16_t mode_2DSwirl(void) { SEGMENT.addPixelColorXY(nj,ni, ColorFromPalette(SEGPALETTE, (strip.now / 29 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND)); //CHSV( ms / 29, 200, 255); SEGMENT.addPixelColorXY( i,nj, ColorFromPalette(SEGPALETTE, (strip.now / 37 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND)); //CHSV( ms / 37, 200, 255); SEGMENT.addPixelColorXY(ni, j, ColorFromPalette(SEGPALETTE, (strip.now / 41 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND)); //CHSV( ms / 41, 200, 255); - - return FRAMETIME; } // mode_2DSwirl() static const char _data_FX_MODE_2DSWIRL[] PROGMEM = "Swirl@!,Sensitivity,Blur;,Bg Swirl;!;2v;ix=64,si=0"; // Beatsin // TODO: color 1 unused? @@ -6788,8 +6637,8 @@ static const char _data_FX_MODE_2DSWIRL[] PROGMEM = "Swirl@!,Sensitivity,Blur;,B // * 2D Waverly // ///////////////////////// // By: Stepko, https://editor.soulmatelights.com/gallery/652-wave , modified by Andrew Tuline -uint16_t mode_2DWaverly(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DWaverly(void) { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6815,8 +6664,6 @@ uint16_t mode_2DWaverly(void) { } } if (SEGMENT.check3) SEGMENT.blur(16, cols*rows < 100); - - return FRAMETIME; } // mode_2DWaverly() static const char _data_FX_MODE_2DWAVERLY[] PROGMEM = "Waverly@Amplification,Sensitivity,,,,,Blur;;!;2v;ix=64,si=0"; // Beatsin @@ -6834,11 +6681,11 @@ typedef struct Gravity { // Gravcenter effects By Andrew Tuline. // Gravcenter base function for Gravcenter (0), Gravcentric (1), Gravimeter (2), Gravfreq (3) (merged by @dedehai) -uint16_t mode_gravcenter_base(unsigned mode) { - if (SEGLEN == 1) return mode_static(); +void mode_gravcenter_base(unsigned mode) { + if (SEGLEN == 1) mode_static(); const unsigned dataSize = sizeof(gravity); - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed Gravity* gravcen = reinterpret_cast(SEGENV.data); um_data_t *um_data = getAudioData(); @@ -6915,20 +6762,18 @@ uint16_t mode_gravcenter_base(unsigned mode) { } } gravcen->gravityCounter = (gravcen->gravityCounter + 1) % gravity; - - return FRAMETIME; } -uint16_t mode_gravcenter(void) { // Gravcenter. By Andrew Tuline. - return mode_gravcenter_base(0); +void mode_gravcenter(void) { // Gravcenter. By Andrew Tuline. + mode_gravcenter_base(0); } static const char _data_FX_MODE_GRAVCENTER[] PROGMEM = "Gravcenter@Rate of fall,Sensitivity;!,!;!;1v;ix=128,m12=2,si=0"; // Circle, Beatsin /////////////////////// // * GRAVCENTRIC // /////////////////////// -uint16_t mode_gravcentric(void) { // Gravcentric. By Andrew Tuline. - return mode_gravcenter_base(1); +void mode_gravcentric(void) { // Gravcentric. By Andrew Tuline. + mode_gravcenter_base(1); } static const char _data_FX_MODE_GRAVCENTRIC[] PROGMEM = "Gravcentric@Rate of fall,Sensitivity;!,!;!;1v;ix=128,m12=3,si=0"; // Corner, Beatsin @@ -6936,8 +6781,8 @@ static const char _data_FX_MODE_GRAVCENTRIC[] PROGMEM = "Gravcentric@Rate of fal /////////////////////// // * GRAVIMETER // /////////////////////// -uint16_t mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. - return mode_gravcenter_base(2); +void mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. + mode_gravcenter_base(2); } static const char _data_FX_MODE_GRAVIMETER[] PROGMEM = "Gravimeter@Rate of fall,Sensitivity;!,!;!;1v;ix=128,m12=2,si=0"; // Circle, Beatsin @@ -6945,8 +6790,8 @@ static const char _data_FX_MODE_GRAVIMETER[] PROGMEM = "Gravimeter@Rate of fall, /////////////////////// // ** Gravfreq // /////////////////////// -uint16_t mode_gravfreq(void) { // Gravfreq. By Andrew Tuline. - return mode_gravcenter_base(3); +void mode_gravfreq(void) { // Gravfreq. By Andrew Tuline. + mode_gravcenter_base(3); } static const char _data_FX_MODE_GRAVFREQ[] PROGMEM = "Gravfreq@Rate of fall,Sensitivity;!,!;!;1f;ix=128,m12=0,si=0"; // Pixels, Beatsin @@ -6954,7 +6799,7 @@ static const char _data_FX_MODE_GRAVFREQ[] PROGMEM = "Gravfreq@Rate of fall,Sens ////////////////////// // * JUGGLES // ////////////////////// -uint16_t mode_juggles(void) { // Juggles. By Andrew Tuline. +void mode_juggles(void) { // Juggles. By Andrew Tuline. um_data_t *um_data = getAudioData(); float volumeSmth = *(float*) um_data->u_data[0]; @@ -6965,8 +6810,6 @@ uint16_t mode_juggles(void) { // Juggles. By Andrew Tuline. // if SEGLEN equals 1, we will always set color to the first and only pixel, but the effect is still good looking SEGMENT.setPixelColor(beatsin16_t(SEGMENT.speed/4+i*2,0,SEGLEN-1), color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(strip.now/4+i*2, false, PALETTE_SOLID_WRAP, 0), my_sampleAgc)); } - - return FRAMETIME; } // mode_juggles() static const char _data_FX_MODE_JUGGLES[] PROGMEM = "Juggles@!,# of balls;!,!;!;01v;m12=0,si=0"; // Pixels, Beatsin @@ -6974,10 +6817,10 @@ static const char _data_FX_MODE_JUGGLES[] PROGMEM = "Juggles@!,# of balls;!,!;!; ////////////////////// // * MATRIPIX // ////////////////////// -uint16_t mode_matripix(void) { // Matripix. By Andrew Tuline. +void mode_matripix(void) { // Matripix. By Andrew Tuline. // effect can work on single pixels, we just lose the shifting effect unsigned dataSize = sizeof(uint32_t) * SEGLEN; - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed uint32_t* pixels = reinterpret_cast(SEGENV.data); um_data_t *um_data = getAudioData(); @@ -7001,8 +6844,6 @@ uint16_t mode_matripix(void) { // Matripix. By Andrew Tuline. pixels[k] = color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(strip.now, false, PALETTE_SOLID_WRAP, 0), pixBri); SEGMENT.setPixelColor(k, pixels[k]); } - - return FRAMETIME; } // mode_matripix() static const char _data_FX_MODE_MATRIPIX[] PROGMEM = "Matripix@!,Brightness;!,!;!;1v;ix=64,m12=2,si=1"; //,rev=1,mi=1,rY=1,mY=1 Circle, WeWillRockYou, reverseX @@ -7010,8 +6851,8 @@ static const char _data_FX_MODE_MATRIPIX[] PROGMEM = "Matripix@!,Brightness;!,!; ////////////////////// // * MIDNOISE // ////////////////////// -uint16_t mode_midnoise(void) { // Midnoise. By Andrew Tuline. - if (SEGLEN <= 1) return mode_static(); +void mode_midnoise(void) { // Midnoise. By Andrew Tuline. + if (SEGLEN <= 1) mode_static(); // Changing xdist to SEGENV.aux0 and ydist to SEGENV.aux1. um_data_t *um_data = getAudioData(); @@ -7033,8 +6874,6 @@ uint16_t mode_midnoise(void) { // Midnoise. By Andrew Tuline. SEGENV.aux0=SEGENV.aux0+beatsin8_t(5,0,10); SEGENV.aux1=SEGENV.aux1+beatsin8_t(4,0,10); - - return FRAMETIME; } // mode_midnoise() static const char _data_FX_MODE_MIDNOISE[] PROGMEM = "Midnoise@Fade rate,Max. length;!,!;!;1v;ix=128,m12=1,si=0"; // Bar, Beatsin @@ -7043,7 +6882,7 @@ static const char _data_FX_MODE_MIDNOISE[] PROGMEM = "Midnoise@Fade rate,Max. le // * NOISEFIRE // ////////////////////// // I am the god of hellfire. . . Volume (only) reactive fire routine. Oh, look how short this is. -uint16_t mode_noisefire(void) { // Noisefire. By Andrew Tuline. +void mode_noisefire(void) { // Noisefire. By Andrew Tuline. CRGBPalette16 myPal = CRGBPalette16(CHSV(0,255,2), CHSV(0,255,4), CHSV(0,255,8), CHSV(0, 255, 8), // Fire palette definition. Lower value = darker. CHSV(0, 255, 16), CRGB::Red, CRGB::Red, CRGB::Red, CRGB::DarkOrange, CRGB::DarkOrange, CRGB::Orange, CRGB::Orange, @@ -7061,8 +6900,6 @@ uint16_t mode_noisefire(void) { // Noisefire. By Andrew Tuline. SEGMENT.setPixelColor(i, ColorFromPalette(myPal, index, volumeSmth*2, LINEARBLEND)); // Use my own palette. } - - return FRAMETIME; } // mode_noisefire() static const char _data_FX_MODE_NOISEFIRE[] PROGMEM = "Noisefire@!,!;;;01v;m12=2,si=0"; // Circle, Beatsin @@ -7070,7 +6907,7 @@ static const char _data_FX_MODE_NOISEFIRE[] PROGMEM = "Noisefire@!,!;;;01v;m12=2 /////////////////////// // * Noisemeter // /////////////////////// -uint16_t mode_noisemeter(void) { // Noisemeter. By Andrew Tuline. +void mode_noisemeter(void) { // Noisemeter. By Andrew Tuline. um_data_t *um_data = getAudioData(); float volumeSmth = *(float*) um_data->u_data[0]; @@ -7092,8 +6929,6 @@ uint16_t mode_noisemeter(void) { // Noisemeter. By Andrew Tuline. SEGENV.aux0+=beatsin8_t(5,0,10); SEGENV.aux1+=beatsin8_t(4,0,10); - - return FRAMETIME; } // mode_noisemeter() static const char _data_FX_MODE_NOISEMETER[] PROGMEM = "Noisemeter@Fade rate,Width;!,!;!;1v;ix=128,m12=2,si=0"; // Circle, Beatsin @@ -7101,8 +6936,8 @@ static const char _data_FX_MODE_NOISEMETER[] PROGMEM = "Noisemeter@Fade rate,Wid ////////////////////// // * PIXELWAVE // ////////////////////// -uint16_t mode_pixelwave(void) { // Pixelwave. By Andrew Tuline. - if (SEGLEN <= 1) return mode_static(); +void mode_pixelwave(void) { // Pixelwave. By Andrew Tuline. + if (SEGLEN <= 1) mode_static(); // even with 1D effect we have to take logic for 2D segments for allocation as fill_solid() fills whole segment if (SEGENV.call == 0) { @@ -7122,8 +6957,6 @@ uint16_t mode_pixelwave(void) { // Pixelwave. By Andrew Tuline. for (unsigned i = SEGLEN - 1; i > SEGLEN/2; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); //move to the left for (unsigned i = 0; i < SEGLEN/2; i++) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); // move to the right } - - return FRAMETIME; } // mode_pixelwave() static const char _data_FX_MODE_PIXELWAVE[] PROGMEM = "Pixelwave@!,Sensitivity;!,!;!;1v;ix=64,m12=2,si=0"; // Circle, Beatsin @@ -7136,9 +6969,9 @@ typedef struct Plasphase { int16_t thatphase; } plasphase; -uint16_t mode_plasmoid(void) { // Plasmoid. By Andrew Tuline. +void mode_plasmoid(void) { // Plasmoid. By Andrew Tuline. // even with 1D effect we have to take logic for 2D segments for allocation as fill_solid() fills whole segment - if (!SEGENV.allocateData(sizeof(plasphase))) return mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(plasphase))) mode_static(); //allocation failed Plasphase* plasmoip = reinterpret_cast(SEGENV.data); um_data_t *um_data = getAudioData(); @@ -7159,8 +6992,6 @@ uint16_t mode_plasmoid(void) { // Plasmoid. By Andrew Tuline. SEGMENT.addPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0), thisbright)); } - - return FRAMETIME; } // mode_plasmoid() static const char _data_FX_MODE_PLASMOID[] PROGMEM = "Plasmoid@Phase,# of pixels;!,!;!;01v;sx=128,ix=128,m12=0,si=0"; // Pixels, Beatsin @@ -7169,8 +7000,8 @@ static const char _data_FX_MODE_PLASMOID[] PROGMEM = "Plasmoid@Phase,# of pixels // * PUDDLES // ////////////////////// // Puddles/Puddlepeak By Andrew Tuline. Merged by @dedehai -uint16_t mode_puddles_base(bool peakdetect) { - if (SEGLEN <= 1) return mode_static(); +void mode_puddles_base(bool peakdetect) { + if (SEGLEN <= 1) mode_static(); unsigned size = 0; uint8_t fadeVal = map(SEGMENT.speed, 0, 255, 224, 254); unsigned pos = hw_random16(SEGLEN); // Set a random starting position. @@ -7201,17 +7032,15 @@ uint16_t mode_puddles_base(bool peakdetect) { for (unsigned i=0; i 210 results in a alternating pattern, this could be fixed by mapping but some may like it (very old bug) } - - return FRAMETIME; } // mode_blurz() static const char _data_FX_MODE_BLURZ[] PROGMEM = "Blurz@Fade rate,Blur;!,Color mix;!;1f;m12=0,si=0"; // Pixels, Beatsin @@ -7280,7 +7105,7 @@ static const char _data_FX_MODE_BLURZ[] PROGMEM = "Blurz@Fade rate,Blur;!,Color ///////////////////////// // ** DJLight // ///////////////////////// -uint16_t mode_DJLight(void) { // Written by ??? Adapted by Will Tatam. +void mode_DJLight(void) { // Written by ??? Adapted by Will Tatam. // No need to prevent from executing on single led strips, only mid will be set (mid = 0) const int mid = SEGLEN / 2; @@ -7302,8 +7127,6 @@ uint16_t mode_DJLight(void) { // Written by ??? Adapted by Wil for (int i = SEGLEN - 1; i > mid; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); // move to the left for (int i = 0; i < mid; i++) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); // move to the right } - - return FRAMETIME; } // mode_DJLight() static const char _data_FX_MODE_DJLIGHT[] PROGMEM = "DJ Light@Speed;;;01f;m12=2,si=0"; // Circle, Beatsin @@ -7311,8 +7134,8 @@ static const char _data_FX_MODE_DJLIGHT[] PROGMEM = "DJ Light@Speed;;;01f;m12=2, //////////////////// // ** Freqmap // //////////////////// -uint16_t mode_freqmap(void) { // Map FFT_MajorPeak to SEGLEN. Would be better if a higher framerate. - if (SEGLEN <= 1) return mode_static(); +void mode_freqmap(void) { // Map FFT_MajorPeak to SEGLEN. Would be better if a higher framerate. + if (SEGLEN <= 1) mode_static(); // Start frequency = 60 Hz and log10(60) = 1.78 // End frequency = MAX_FREQUENCY in Hz and lo10(MAX_FREQUENCY) = MAX_FREQ_LOG10 @@ -7335,8 +7158,6 @@ uint16_t mode_freqmap(void) { // Map FFT_MajorPeak to SEGLEN. uint8_t bright = (uint8_t)my_magnitude; SEGMENT.setPixelColor(locn, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(SEGMENT.intensity+pixCol, false, PALETTE_SOLID_WRAP, 0), bright)); - - return FRAMETIME; } // mode_freqmap() static const char _data_FX_MODE_FREQMAP[] PROGMEM = "Freqmap@Fade rate,Starting color;!,!;!;1f;m12=0,si=0"; // Pixels, Beatsin @@ -7344,7 +7165,7 @@ static const char _data_FX_MODE_FREQMAP[] PROGMEM = "Freqmap@Fade rate,Starting /////////////////////// // ** Freqmatrix // /////////////////////// -uint16_t mode_freqmatrix(void) { // Freqmatrix. By Andreas Pleschung. +void mode_freqmatrix(void) { // Freqmatrix. By Andreas Pleschung. // No need to prevent from executing on single led strips, we simply change pixel 0 each time and avoid the shift um_data_t *um_data = getAudioData(); float FFT_MajorPeak = *(float*)um_data->u_data[4]; @@ -7387,8 +7208,6 @@ uint16_t mode_freqmatrix(void) { // Freqmatrix. By Andreas Plesch // if SEGLEN equals 1 this loop won't execute for (int i = SEGLEN - 1; i > 0; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); //move to the left } - - return FRAMETIME; } // mode_freqmatrix() static const char _data_FX_MODE_FREQMATRIX[] PROGMEM = "Freqmatrix@Speed,Sound effect,Low bin,High bin,Sensitivity;;;01f;m12=3,si=0"; // Corner, Beatsin @@ -7400,7 +7219,7 @@ static const char _data_FX_MODE_FREQMATRIX[] PROGMEM = "Freqmatrix@Speed,Sound e // End frequency = 5120 Hz and lo10(5120) = 3.71 // SEGMENT.speed select faderate // SEGMENT.intensity select colour index -uint16_t mode_freqpixels(void) { // Freqpixel. By Andrew Tuline. +void mode_freqpixels(void) { // Freqpixel. By Andrew Tuline. um_data_t *um_data = getAudioData(); float FFT_MajorPeak = *(float*)um_data->u_data[4]; float my_magnitude = *(float*)um_data->u_data[5] / 16.0f; @@ -7421,8 +7240,6 @@ uint16_t mode_freqpixels(void) { // Freqpixel. By Andrew Tuline. unsigned locn = hw_random16(0,SEGLEN); SEGMENT.setPixelColor(locn, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(SEGMENT.intensity+pixCol, false, PALETTE_SOLID_WRAP, 0), (uint8_t)my_magnitude)); } - - return FRAMETIME; } // mode_freqpixels() static const char _data_FX_MODE_FREQPIXELS[] PROGMEM = "Freqpixels@Fade rate,Starting color and # of pixels;!,!,;!;1f;m12=0,si=0"; // Pixels, Beatsin @@ -7442,7 +7259,7 @@ static const char _data_FX_MODE_FREQPIXELS[] PROGMEM = "Freqpixels@Fade rate,Sta // // As a compromise between speed and accuracy we are currently sampling with 10240Hz, from which we can then determine with a 512bin FFT our max frequency is 5120Hz. // Depending on the music stream you have you might find it useful to change the frequency mapping. -uint16_t mode_freqwave(void) { // Freqwave. By Andreas Pleschung. +void mode_freqwave(void) { // Freqwave. By Andreas Pleschung. // As before, this effect can also work on single pixels, we just lose the shifting effect um_data_t *um_data = getAudioData(); float FFT_MajorPeak = *(float*)um_data->u_data[4]; @@ -7484,8 +7301,6 @@ uint16_t mode_freqwave(void) { // Freqwave. By Andreas Pleschun for (unsigned i = SEGLEN - 1; i > SEGLEN/2; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); //move to the left for (unsigned i = 0; i < SEGLEN/2; i++) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); // move to the right } - - return FRAMETIME; } // mode_freqwave() static const char _data_FX_MODE_FREQWAVE[] PROGMEM = "Freqwave@Speed,Sound effect,Low bin,High bin,Pre-amp;;;01f;m12=2,si=0"; // Circle, Beatsin @@ -7493,7 +7308,7 @@ static const char _data_FX_MODE_FREQWAVE[] PROGMEM = "Freqwave@Speed,Sound effec ////////////////////// // ** Noisemove // ////////////////////// -uint16_t mode_noisemove(void) { // Noisemove. By: Andrew Tuline +void mode_noisemove(void) { // Noisemove. By: Andrew Tuline um_data_t *um_data = getAudioData(); uint8_t *fftResult = (uint8_t*)um_data->u_data[2]; @@ -7507,8 +7322,6 @@ uint16_t mode_noisemove(void) { // Noisemove. By: Andrew Tuli locn = map(locn, 7500, 58000, 0, SEGLEN-1); // Map that to the length of the strand, and ensure we don't go over. SEGMENT.setPixelColor(locn, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i*64, false, PALETTE_SOLID_WRAP, 0), uint8_t(fftResult[i % 16]*4))); } - - return FRAMETIME; } // mode_noisemove() static const char _data_FX_MODE_NOISEMOVE[] PROGMEM = "Noisemove@Move speed,Fade rate;!,!;!;01f;m12=0,si=0"; // Pixels, Beatsin @@ -7516,7 +7329,7 @@ static const char _data_FX_MODE_NOISEMOVE[] PROGMEM = "Noisemove@Move speed,Fade ////////////////////// // ** Rocktaves // ////////////////////// -uint16_t mode_rocktaves(void) { // Rocktaves. Same note from each octave is same colour. By: Andrew Tuline +void mode_rocktaves(void) { // Rocktaves. Same note from each octave is same colour. By: Andrew Tuline um_data_t *um_data = getAudioData(); float FFT_MajorPeak = *(float*) um_data->u_data[4]; float my_magnitude = *(float*) um_data->u_data[5] / 16.0f; @@ -7542,8 +7355,6 @@ uint16_t mode_rocktaves(void) { // Rocktaves. Same note from eac unsigned i = map(beatsin8_t(8+octCount*4, 0, 255, 0, octCount*8), 0, 255, 0, SEGLEN-1); i = constrain(i, 0U, SEGLEN-1U); SEGMENT.addPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette((uint8_t)frTemp, false, PALETTE_SOLID_WRAP, 0), volTemp)); - - return FRAMETIME; } // mode_rocktaves() static const char _data_FX_MODE_ROCKTAVES[] PROGMEM = "Rocktaves@;!,!;!;01f;m12=1,si=0"; // Bar, Beatsin @@ -7552,10 +7363,10 @@ static const char _data_FX_MODE_ROCKTAVES[] PROGMEM = "Rocktaves@;!,!;!;01f;m12= // ** Waterfall // /////////////////////// // Combines peak detection with FFT_MajorPeak and FFT_Magnitude. -uint16_t mode_waterfall(void) { // Waterfall. By: Andrew Tuline +void mode_waterfall(void) { // Waterfall. By: Andrew Tuline // effect can work on single pixels, we just lose the shifting effect unsigned dataSize = sizeof(uint32_t) * SEGLEN; - if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed uint32_t* pixels = reinterpret_cast(SEGENV.data); um_data_t *um_data = getAudioData(); @@ -7598,8 +7409,6 @@ uint16_t mode_waterfall(void) { // Waterfall. By: Andrew Tulin SEGMENT.setPixelColor(i, pixels[i]); } } - - return FRAMETIME; } // mode_waterfall() static const char _data_FX_MODE_WATERFALL[] PROGMEM = "Waterfall@!,Adjust color,Select bin,Volume (min);!,!;!;01f;c2=0,m12=2,si=0"; // Circles, Beatsin @@ -7608,15 +7417,15 @@ static const char _data_FX_MODE_WATERFALL[] PROGMEM = "Waterfall@!,Adjust color, ///////////////////////// // ** 2D GEQ // ///////////////////////// -uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int NUM_BANDS = map(SEGMENT.custom1, 0, 255, 1, 16); const int CENTER_BIN = map(SEGMENT.custom3, 0, 31, 0, 15); const int cols = SEG_W; const int rows = SEG_H; - if (!SEGENV.allocateData(cols*sizeof(uint16_t))) return mode_static(); //allocation failed + if (!SEGENV.allocateData(cols*sizeof(uint16_t))) mode_static(); //allocation failed uint16_t *previousBarHeight = reinterpret_cast(SEGENV.data); //array of previous bar heights per frequency band um_data_t *um_data = getAudioData(); @@ -7660,8 +7469,6 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. if (rippleTime && previousBarHeight[x]>0) previousBarHeight[x]--; //delay/ripple effect } - - return FRAMETIME; } // mode_2DGEQ() static const char _data_FX_MODE_2DGEQ[] PROGMEM = "GEQ@Fade speed,Ripple decay,# of bands,,Bin,Color bars;!,,Peaks;!;2f;c1=255,c2=64,pal=11,si=0,c3=0"; @@ -7669,8 +7476,8 @@ static const char _data_FX_MODE_2DGEQ[] PROGMEM = "GEQ@Fade speed,Ripple decay,# ///////////////////////// // ** 2D Funky plank // ///////////////////////// -uint16_t mode_2DFunkyPlank(void) { // Written by ??? Adapted by Will Tatam. - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DFunkyPlank(void) { // Written by ??? Adapted by Will Tatam. + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -7713,8 +7520,6 @@ uint16_t mode_2DFunkyPlank(void) { // Written by ??? Adapted by Wil } } } - - return FRAMETIME; } // mode_2DFunkyPlank static const char _data_FX_MODE_2DFUNKYPLANK[] PROGMEM = "Funky Plank@Scroll speed,,# of bands;;;2f;si=0"; // Beatsin @@ -7757,8 +7562,8 @@ static uint8_t akemi[] PROGMEM = { 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 }; -uint16_t mode_2DAkemi(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2DAkemi(void) { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -7817,8 +7622,6 @@ uint16_t mode_2DAkemi(void) { } } } - - return FRAMETIME; } // mode_2DAkemi static const char _data_FX_MODE_2DAKEMI[] PROGMEM = "Akemi@Color speed,Dance;Head palette,Arms & Legs,Eyes & Mouth;Face palette;2f;si=0"; //beatsin @@ -7826,8 +7629,8 @@ static const char _data_FX_MODE_2DAKEMI[] PROGMEM = "Akemi@Color speed,Dance;Hea // Distortion waves - ldirko // https://editor.soulmatelights.com/gallery/1089-distorsion-waves // adapted for WLED by @blazoncek, improvements by @dedehai -uint16_t mode_2Ddistortionwaves() { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Ddistortionwaves() { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -7898,8 +7701,6 @@ uint16_t mode_2Ddistortionwaves() { // palette mode and not filling: smear-blur to cover up palette wrapping artefacts if(!SEGMENT.check1 && SEGMENT.palette) SEGMENT.blur(200, true); - - return FRAMETIME; } static const char _data_FX_MODE_2DDISTORTIONWAVES[] PROGMEM = "Distortion Waves@!,Scale,,,,Fill,Zoom,Alt;;!;2;pal=0"; @@ -7960,8 +7761,8 @@ static void soapPixels(bool isRow, uint8_t *noise3d, CRGB *pixels) { } } -uint16_t mode_2Dsoap() { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dsoap() { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -7969,7 +7770,7 @@ uint16_t mode_2Dsoap() { const size_t segSize = SEGMENT.width() * SEGMENT.height(); // prevent reallocation if mirrored or grouped const size_t dataSize = segSize * (sizeof(uint8_t) + sizeof(CRGB)); // pixels and noise - if (!SEGENV.allocateData(dataSize + sizeof(uint32_t)*3)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize + sizeof(uint32_t)*3)) mode_static(); //allocation failed uint8_t *noise3d = reinterpret_cast(SEGENV.data); CRGB *pixels = reinterpret_cast(SEGENV.data + segSize * sizeof(uint8_t)); @@ -8003,8 +7804,6 @@ uint16_t mode_2Dsoap() { soapPixels(true, noise3d, pixels); // rows soapPixels(false, noise3d, pixels); // cols - - return FRAMETIME; } static const char _data_FX_MODE_2DSOAP[] PROGMEM = "Soap@!,Smoothness,Density;;!;2;pal=11"; @@ -8013,8 +7812,8 @@ static const char _data_FX_MODE_2DSOAP[] PROGMEM = "Soap@!,Smoothness,Density;;! //Octopus (https://editor.soulmatelights.com/gallery/671-octopus) //Stepko and Sutaburosu // adapted for WLED by @blazoncek -uint16_t mode_2Doctopus() { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Doctopus() { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -8027,7 +7826,7 @@ uint16_t mode_2Doctopus() { } map_t; const size_t dataSize = SEGMENT.width() * SEGMENT.height() * sizeof(map_t); // prevent reallocation if mirrored or grouped - if (!SEGENV.allocateData(dataSize + 2)) return mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize + 2)) mode_static(); //allocation failed map_t *rMap = reinterpret_cast(SEGENV.data); uint8_t *offsX = reinterpret_cast(SEGENV.data + dataSize); @@ -8063,7 +7862,6 @@ uint16_t mode_2Doctopus() { SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, SEGENV.step / 2 - radius, intensity)); } } - return FRAMETIME; } static const char _data_FX_MODE_2DOCTOPUS[] PROGMEM = "Octopus@!,,Offset X,Offset Y,Legs,fasttan;;!;2;"; @@ -8071,8 +7869,8 @@ static const char _data_FX_MODE_2DOCTOPUS[] PROGMEM = "Octopus@!,,Offset X,Offse //Waving Cell //@Stepko (https://editor.soulmatelights.com/gallery/1704-wavingcells) // adapted for WLED by @blazoncek, improvements by @dedehai -uint16_t mode_2Dwavingcell() { - if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up +void mode_2Dwavingcell() { + if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -8089,7 +7887,6 @@ uint16_t mode_2Dwavingcell() { } } SEGMENT.blur(SEGMENT.intensity); - return FRAMETIME; } static const char _data_FX_MODE_2DWAVINGCELL[] PROGMEM = "Waving Cell@!,Blur,Amplitude 1,Amplitude 2,Amplitude 3,,Flow;;!;2;ix=0"; @@ -8102,15 +7899,15 @@ static const char _data_FX_MODE_2DWAVINGCELL[] PROGMEM = "Waving Cell@!,Blur,Amp by DedeHai (Damian Schneider) */ #define NUMBEROFSOURCES 8 -uint16_t mode_particlevortex(void) { +void mode_particlevortex(void) { if (SEGLEN == 1) - return mode_static(); + mode_static(); ParticleSystem2D *PartSys = nullptr; uint32_t i, j; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, NUMBEROFSOURCES)) - return mode_static(); // allocation failed + mode_static(); // allocation failed #ifdef ESP8266 PartSys->setMotionBlur(180); #else @@ -8128,7 +7925,7 @@ uint16_t mode_particlevortex(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) uint32_t spraycount = min(PartSys->numSources, (uint32_t)(1 + (SEGMENT.custom1 >> 5))); // number of sprays to display, 1-8 @@ -8205,7 +8002,6 @@ uint16_t mode_particlevortex(void) { } } PartSys->update(); //update all particles and render to frame - return FRAMETIME; } #undef NUMBEROFSOURCES static const char _data_FX_MODE_PARTICLEVORTEX[] PROGMEM = "PS Vortex@Rotation Speed,Particle Speed,Arms,Flip,Nozzle,Smear,Direction,Random Flip;;!;2;pal=27,c1=200,c2=0,c3=0"; @@ -8217,13 +8013,13 @@ static const char _data_FX_MODE_PARTICLEVORTEX[] PROGMEM = "PS Vortex@Rotation S */ #define NUMBEROFSOURCES 8 -uint16_t mode_particlefireworks(void) { +void mode_particlefireworks(void) { ParticleSystem2D *PartSys = nullptr; uint32_t numRockets; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, NUMBEROFSOURCES)) - return mode_static(); // allocation failed + mode_static(); // allocation failed PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) PartSys->setWallHardness(120); // ground bounce is fixed @@ -8237,7 +8033,7 @@ uint16_t mode_particlefireworks(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) numRockets = map(SEGMENT.speed, 0 , 255, 4, min(PartSys->numSources, (uint32_t)NUMBEROFSOURCES)); @@ -8349,7 +8145,6 @@ uint16_t mode_particlefireworks(void) { } } PartSys->update(); // update and render - return FRAMETIME; } #undef NUMBEROFSOURCES static const char _data_FX_MODE_PARTICLEFIREWORKS[] PROGMEM = "PS Fireworks@Launches,Explosion Size,Fuse,Blur,Gravity,Cylinder,Ground,Fast;;!;2;pal=11,ix=50,c1=40,c2=0,c3=12"; @@ -8361,7 +8156,7 @@ static const char _data_FX_MODE_PARTICLEFIREWORKS[] PROGMEM = "PS Fireworks@Laun by DedeHai (Damian Schneider) */ #define NUMBEROFSOURCES 1 -uint16_t mode_particlevolcano(void) { +void mode_particlevolcano(void) { ParticleSystem2D *PartSys = nullptr; PSsettings2D volcanosettings; volcanosettings.asByte = 0b00000100; // PS settings for volcano movement: bounceX is enabled @@ -8370,7 +8165,7 @@ uint16_t mode_particlevolcano(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, NUMBEROFSOURCES)) // init, no additional data needed - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->setBounceY(true); PartSys->setGravity(); // enable with default gforce @@ -8391,7 +8186,7 @@ uint16_t mode_particlevolcano(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! numSprays = min(PartSys->numSources, (uint32_t)NUMBEROFSOURCES); // number of volcanoes @@ -8423,7 +8218,6 @@ uint16_t mode_particlevolcano(void) { PartSys->enableParticleCollisions(false); PartSys->update(); // update and render - return FRAMETIME; } #undef NUMBEROFSOURCES static const char _data_FX_MODE_PARTICLEVOLCANO[] PROGMEM = "PS Volcano@Speed,Intensity,Move,Bounce,Spread,AgeColor,Walls,Collide;;!;2;pal=35,sx=100,ix=190,c1=0,c2=160,c3=6,o1=1"; @@ -8433,21 +8227,21 @@ static const char _data_FX_MODE_PARTICLEVOLCANO[] PROGMEM = "PS Volcano@Speed,In realistic fire effect using particles. heat based and using perlin-noise for wind by DedeHai (Damian Schneider) */ -uint16_t mode_particlefire(void) { +void mode_particlefire(void) { ParticleSystem2D *PartSys = nullptr; uint32_t i; // index variable uint32_t numFlames; // number of flames: depends on fire width. for a fire width of 16 pixels, about 25-30 flames give good results if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, SEGMENT.vWidth(), 4)) //maximum number of source (PS may limit based on segment size); need 4 additional bytes for time keeping (uint32_t lastcall) - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D SEGENV.aux0 = hw_random16(); // aux0 is wind position (index) in the perlin noise } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setWrapX(SEGMENT.check2); @@ -8460,9 +8254,7 @@ uint16_t mode_particlefire(void) { uint32_t period = strip.now - *lastcall; if (period < (uint32_t)map(SEGMENT.speed, 0, 99, 50, 10)) { // limit to 90FPS - 20FPS SEGMENT.call--; //skipping a frame, decrement the counter (on call0, this is never executed as lastcall is 0, so its fine to not check if >0) - //still need to render the frame or flickering will occur in transitions - PartSys->updateFire(SEGMENT.intensity, true); // render the fire without updating particles (render only) - return FRAMETIME; //do not update this frame + return; //do not update this frame } *lastcall = strip.now; } @@ -8528,9 +8320,7 @@ uint16_t mode_particlefire(void) { PartSys->flameEmit(PartSys->sources[j]); } - PartSys->updateFire(SEGMENT.intensity, false); // update and render the fire - - return FRAMETIME; + PartSys->updateFire(SEGMENT.intensity); // update and render the fire } static const char _data_FX_MODE_PARTICLEFIRE[] PROGMEM = "PS Fire@Speed,Intensity,Flame Height,Wind,Spread,Smooth,Cylinder,Turbulence;;!;2;pal=35,sx=110,c1=110,c2=50,c3=31,o1=1"; @@ -8541,12 +8331,12 @@ static const char _data_FX_MODE_PARTICLEFIRE[] PROGMEM = "PS Fire@Speed,Intensit Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particlepit(void) { +void mode_particlepit(void) { ParticleSystem2D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 0, 0, true, false)) // init - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->setKillOutOfBounds(true); PartSys->setGravity(); // enable with default gravity PartSys->setUsedParticles(170); // use 75% of available particles @@ -8554,7 +8344,7 @@ uint16_t mode_particlepit(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -8602,8 +8392,6 @@ uint16_t mode_particlepit(void) { PartSys->applyFriction(frictioncoefficient); PartSys->update(); // update and render - - return FRAMETIME; } static const char _data_FX_MODE_PARTICLEPIT[] PROGMEM = "PS Ballpit@Speed,Intensity,Size,Hardness,Saturation,Cylinder,Walls,Ground;;!;2;pal=11,sx=100,ix=220,c1=70,c2=180,c3=31,o3=1"; @@ -8612,14 +8400,14 @@ static const char _data_FX_MODE_PARTICLEPIT[] PROGMEM = "PS Ballpit@Speed,Intens Uses palette for particle color, spray source at top emitting particles, many config options by DedeHai (Damian Schneider) */ -uint16_t mode_particlewaterfall(void) { +void mode_particlewaterfall(void) { ParticleSystem2D *PartSys = nullptr; uint8_t numSprays; uint32_t i = 0; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 12)) // init, request 12 sources, no additional data needed - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->setGravity(); // enable with default gforce PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) @@ -8640,7 +8428,7 @@ uint16_t mode_particlewaterfall(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -8675,7 +8463,6 @@ uint16_t mode_particlewaterfall(void) { PartSys->applyFriction(1); // add just a tiny amount of friction to help smooth things PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PARTICLEWATERFALL[] PROGMEM = "PS Waterfall@Speed,Intensity,Variation,Collide,Position,Cylinder,Walls,Ground;;!;2;pal=9,sx=15,ix=200,c1=32,c2=160,o3=1"; @@ -8684,13 +8471,13 @@ static const char _data_FX_MODE_PARTICLEWATERFALL[] PROGMEM = "PS Waterfall@Spee Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particlebox(void) { +void mode_particlebox(void) { ParticleSystem2D *PartSys = nullptr; uint32_t i; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1, 0, true)) // init - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->setBounceX(true); PartSys->setBounceY(true); SEGENV.aux0 = hw_random16(); // position in perlin noise @@ -8699,7 +8486,7 @@ uint16_t mode_particlebox(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setWallHardness(min(SEGMENT.custom2, (uint8_t)200)); // wall hardness is 200 or more @@ -8762,8 +8549,6 @@ uint16_t mode_particlebox(void) { PartSys->applyFriction(1); PartSys->update(); // update and render - - return FRAMETIME; } static const char _data_FX_MODE_PARTICLEBOX[] PROGMEM = "PS Box@!,Particles,Tilt,Hardness,Size,Random,Washing Machine,Sloshing;;!;2;pal=53,ix=50,c3=1,o1=1"; @@ -8772,13 +8557,13 @@ static const char _data_FX_MODE_PARTICLEBOX[] PROGMEM = "PS Box@!,Particles,Tilt calculates slope gradient at the particle positions and applies 'downhill' force, resulting in a fuzzy perlin noise display by DedeHai (Damian Schneider) */ -uint16_t mode_particleperlin(void) { +void mode_particleperlin(void) { ParticleSystem2D *PartSys = nullptr; uint32_t i; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1, 0, true)) // init with 1 source and advanced properties - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->setKillOutOfBounds(true); // should never happen, but lets make sure there are no stray particles PartSys->setMotionBlur(230); // anable motion blur @@ -8789,7 +8574,7 @@ uint16_t mode_particleperlin(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setWrapX(SEGMENT.check1); @@ -8825,7 +8610,6 @@ uint16_t mode_particleperlin(void) { PartSys->applyFriction(2); PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PARTICLEPERLIN[] PROGMEM = "PS Fuzzy Noise@Speed,Particles,Bounce,Friction,Scale,Cylinder,Smear,Collide;;!;2;pal=64,sx=50,ix=200,c1=130,c2=30,c3=5,o3=1"; @@ -8834,7 +8618,7 @@ static const char _data_FX_MODE_PARTICLEPERLIN[] PROGMEM = "PS Fuzzy Noise@Speed by DedeHai (Damian Schneider) */ #define NUMBEROFSOURCES 8 -uint16_t mode_particleimpact(void) { +void mode_particleimpact(void) { ParticleSystem2D *PartSys = nullptr; uint32_t numMeteors; PSsettings2D meteorsettings; @@ -8842,7 +8626,7 @@ uint16_t mode_particleimpact(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, NUMBEROFSOURCES)) // init, no additional data needed - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->setKillOutOfBounds(true); PartSys->setGravity(); // enable default gravity PartSys->setBounceY(true); // always use ground bounce @@ -8857,7 +8641,7 @@ uint16_t mode_particleimpact(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -8932,7 +8716,6 @@ uint16_t mode_particleimpact(void) { } PartSys->update(); // update and render - return FRAMETIME; } #undef NUMBEROFSOURCES static const char _data_FX_MODE_PARTICLEIMPACT[] PROGMEM = "PS Impact@Launches,!,Force,Hardness,Blur,Cylinder,Walls,Collide;;!;2;pal=0,sx=32,ix=85,c1=70,c2=130,c3=0,o3=1"; @@ -8943,7 +8726,7 @@ static const char _data_FX_MODE_PARTICLEIMPACT[] PROGMEM = "PS Impact@Launches,! Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleattractor(void) { +void mode_particleattractor(void) { ParticleSystem2D *PartSys = nullptr; PSsettings2D sourcesettings; sourcesettings.asByte = 0b00001100; // PS settings for bounceY, bounceY used for source movement (it always bounces whereas particles do not) @@ -8952,7 +8735,7 @@ uint16_t mode_particleattractor(void) { PSparticle *attractor; // particle pointer to the attractor if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1, sizeof(PSparticle), true)) // init using 1 source and advanced particle settings - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->sources[0].source.hue = hw_random16(); PartSys->sources[0].source.vx = -7; // will collied with wall and get random bounce direction PartSys->sources[0].sourceFlags.collide = true; // seeded particles will collide @@ -8973,7 +8756,7 @@ uint16_t mode_particleattractor(void) { } if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -9025,7 +8808,6 @@ uint16_t mode_particleattractor(void) { PartSys->applyFriction(2); PartSys->particleMoveUpdate(PartSys->sources[0].source, PartSys->sources[0].sourceFlags, &sourcesettings); // move the source PartSys->update(); // update and render - return FRAMETIME; } //static const char _data_FX_MODE_PARTICLEATTRACTOR[] PROGMEM = "PS Attractor@Mass,Particles,Size,Collide,Friction,AgeColor,Move,Swallow;;!;2;pal=9,sx=100,ix=82,c1=1,c2=0"; static const char _data_FX_MODE_PARTICLEATTRACTOR[] PROGMEM = "PS Attractor@Mass,Particles,Size,Collide,Friction,AgeColor,Move,Swallow;;!;2;pal=9,sx=100,ix=82,c1=2,c2=0"; @@ -9035,13 +8817,13 @@ static const char _data_FX_MODE_PARTICLEATTRACTOR[] PROGMEM = "PS Attractor@Mass Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particlespray(void) { +void mode_particlespray(void) { ParticleSystem2D *PartSys = nullptr; const uint8_t hardness = 200; // collision hardness is fixed if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1)) // init, no additional data needed - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) PartSys->setBounceY(true); PartSys->setMotionBlur(200); // anable motion blur @@ -9054,7 +8836,7 @@ uint16_t mode_particlespray(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -9099,7 +8881,6 @@ uint16_t mode_particlespray(void) { } PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PARTICLESPRAY[] PROGMEM = "PS Spray@Speed,!,Left/Right,Up/Down,Angle,Gravity,Cylinder/Square,Collide;;!;2v;pal=0,sx=150,ix=150,c1=220,c2=30,c3=21"; @@ -9109,19 +8890,19 @@ static const char _data_FX_MODE_PARTICLESPRAY[] PROGMEM = "PS Spray@Speed,!,Left Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleGEQ(void) { +void mode_particleGEQ(void) { ParticleSystem2D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1)) - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->setKillOutOfBounds(true); PartSys->setUsedParticles(170); // use 2/3 of available particles } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! uint32_t i; // set particle system properties @@ -9172,7 +8953,6 @@ uint16_t mode_particleGEQ(void) { } PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PARTICLEGEQ[] PROGMEM = "PS GEQ 2D@Speed,Intensity,Diverge,Bounce,Gravity,Cylinder,Walls,Floor;;!;2f;pal=0,sx=155,ix=200,c1=0"; @@ -9184,14 +8964,14 @@ static const char _data_FX_MODE_PARTICLEGEQ[] PROGMEM = "PS GEQ 2D@Speed,Intensi by DedeHai (Damian Schneider) */ #define NUMBEROFSOURCES 16 -uint16_t mode_particlecenterGEQ(void) { +void mode_particlecenterGEQ(void) { ParticleSystem2D *PartSys = nullptr; uint8_t numSprays; uint32_t i; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, NUMBEROFSOURCES)) // init, request 16 sources - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D numSprays = min(PartSys->numSources, (uint32_t)NUMBEROFSOURCES); for (i = 0; i < numSprays; i++) { @@ -9207,7 +8987,7 @@ uint16_t mode_particlecenterGEQ(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) numSprays = min(PartSys->numSources, (uint32_t)NUMBEROFSOURCES); @@ -9245,7 +9025,6 @@ uint16_t mode_particlecenterGEQ(void) { j = (j + 1) % numSprays; } PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PARTICLECIRCULARGEQ[] PROGMEM = "PS GEQ Nova@Speed,Intensity,Rotation Speed,Color Change,Nozzle,,Direction;;!;2f;pal=13,ix=180,c1=0,c2=0,c3=8"; @@ -9253,14 +9032,14 @@ static const char _data_FX_MODE_PARTICLECIRCULARGEQ[] PROGMEM = "PS GEQ Nova@Spe Particle replacement of Ghost Rider by DedeHai (Damian Schneider), original FX by stepko adapted by Blaz Kristan (AKA blazoncek) */ #define MAXANGLESTEP 2200 //32767 means 180° -uint16_t mode_particleghostrider(void) { +void mode_particleghostrider(void) { ParticleSystem2D *PartSys = nullptr; PSsettings2D ghostsettings; ghostsettings.asByte = 0b0000011; //enable wrapX and wrapY if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1)) // init, no additional data needed - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) PartSys->sources[0].maxLife = 260; // lifetime in frames PartSys->sources[0].minLife = 250; @@ -9273,7 +9052,7 @@ uint16_t mode_particleghostrider(void) { } if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! if (SEGMENT.intensity > 0) { // spiraling if (SEGENV.aux1) { @@ -9325,7 +9104,6 @@ uint16_t mode_particleghostrider(void) { PartSys->sources[0].source.hue += (SEGMENT.custom2 - 190) >> 2; PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PARTICLEGHOSTRIDER[] PROGMEM = "PS Ghost Rider@Speed,Spiral,Blur,Color Cycle,Spread,AgeColor,Walls;;!;2;pal=1,sx=70,ix=0,c1=220,c2=30,c3=21,o1=1"; @@ -9334,12 +9112,12 @@ static const char _data_FX_MODE_PARTICLEGHOSTRIDER[] PROGMEM = "PS Ghost Rider@S Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleblobs(void) { +void mode_particleblobs(void) { ParticleSystem2D *PartSys = nullptr; if (SEGMENT.call == 0) { if (!initParticleSystem2D(PartSys, 0, 0, true, true)) //init, no additional bytes, advanced size & size control - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->setBounceX(true); PartSys->setBounceY(true); PartSys->setWallHardness(255); @@ -9351,7 +9129,7 @@ uint16_t mode_particleblobs(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setUsedParticles(map(SEGMENT.intensity, 0, 255, 25, 128)); // minimum 10%, maximum 50% of available particles (note: PS ensures at least 1) @@ -9399,8 +9177,6 @@ uint16_t mode_particleblobs(void) { PartSys->setMotionBlur(((SEGMENT.custom3) << 3) + 7); PartSys->update(); // update and render - - return FRAMETIME; } static const char _data_FX_MODE_PARTICLEBLOBS[] PROGMEM = "PS Blobs@Speed,Blobs,Size,Life,Blur,Wobble,Collide,Pulsate;;!;2v;sx=30,ix=64,c1=200,c2=130,c3=0,o3=1"; @@ -9409,13 +9185,13 @@ static const char _data_FX_MODE_PARTICLEBLOBS[] PROGMEM = "PS Blobs@Speed,Blobs, Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particlegalaxy(void) { +void mode_particlegalaxy(void) { ParticleSystem2D *PartSys = nullptr; PSsettings2D sourcesettings; sourcesettings.asByte = 0b00001100; // PS settings for bounceY, bounceY used for source movement (it always bounces whereas particles do not) if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1, 0, true)) // init using 1 source and advanced particle settings - return mode_static(); // allocation failed or not 2D + mode_static(); // allocation failed or not 2D PartSys->sources[0].source.vx = -4; // will collide with wall and get random bounce direction PartSys->sources[0].source.x = PartSys->maxX >> 1; // start in the center PartSys->sources[0].source.y = PartSys->maxY >> 1; @@ -9430,7 +9206,7 @@ uint16_t mode_particlegalaxy(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS } if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) uint8_t particlesize = SEGMENT.custom1; @@ -9499,7 +9275,6 @@ uint16_t mode_particlegalaxy(void) { } PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PARTICLEGALAXY[] PROGMEM = "PS Galaxy@!,!,Size,,Color,,Starfield,Trace;;!;2;pal=59,sx=80,c1=1,c3=4"; @@ -9516,12 +9291,12 @@ static const char _data_FX_MODE_PARTICLEGALAXY[] PROGMEM = "PS Galaxy@!,!,Size,, Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleDrip(void) { +void mode_particleDrip(void) { ParticleSystem1D *PartSys = nullptr; //uint8_t numSprays; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 4)) // init - return mode_static(); // allocation failed or single pixel + mode_static(); // allocation failed or single pixel PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) PartSys->sources[0].source.hue = hw_random16(); SEGENV.aux1 = 0xFFFF; // invalidate @@ -9530,7 +9305,7 @@ uint16_t mode_particleDrip(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -9610,7 +9385,6 @@ uint16_t mode_particleDrip(void) { } PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PARTICLEDRIP[] PROGMEM = "PS DripDrop@Speed,!,Splash,Blur,Gravity,Rain,PushSplash,Smooth;,!;!;1;pal=0,sx=150,ix=25,c1=220,c2=30,c3=21"; @@ -9621,12 +9395,12 @@ static const char _data_FX_MODE_PARTICLEDRIP[] PROGMEM = "PS DripDrop@Speed,!,Sp Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particlePinball(void) { +void mode_particlePinball(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 128, 0, true)) // init - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel PartSys->sources[0].sourceFlags.collide = true; // seeded particles will collide (if enabled) PartSys->sources[0].source.x = -1000; // shoot up from below //PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) @@ -9637,7 +9411,7 @@ uint16_t mode_particlePinball(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings //uint32_t hardness = 240 + (SEGMENT.custom1>>4); @@ -9727,7 +9501,6 @@ uint16_t mode_particlePinball(void) { //} PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PSPINBALL[] PROGMEM = "PS Pinball@Speed,!,Size,Blur,Gravity,Collide,Rolling,Position Color;,!;!;1;pal=0,ix=220,c2=0,c3=8,o1=1"; @@ -9740,12 +9513,12 @@ static const char _data_FX_MODE_PSPINBALL[] PROGMEM = "PS Pinball@Speed,!,Size,B Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleDancingShadows(void) { +void mode_particleDancingShadows(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1)) // init, one source - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel PartSys->sources[0].maxLife = 1000; //set long life (kill out of bounds is done in custom way) PartSys->sources[0].minLife = PartSys->sources[0].maxLife; } @@ -9754,7 +9527,7 @@ uint16_t mode_particleDancingShadows(void) { } if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -9846,8 +9619,6 @@ uint16_t mode_particleDancingShadows(void) { } PartSys->update(); // update and render - - return FRAMETIME; } static const char _data_FX_MODE_PARTICLEDANCINGSHADOWS[] PROGMEM = "PS Dancing Shadows@Speed,!,Blur,Color Cycle,,Smear,Position Color,Smooth;,!;!;1;sx=100,ix=180,c1=0,c2=0"; @@ -9856,20 +9627,20 @@ static const char _data_FX_MODE_PARTICLEDANCINGSHADOWS[] PROGMEM = "PS Dancing S Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleFireworks1D(void) { +void mode_particleFireworks1D(void) { ParticleSystem1D *PartSys = nullptr; uint8_t *forcecounter; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 4, 150, 4, true)) // init advanced particle system - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); PartSys->sources[0].sourceFlags.custom1 = 1; // set rocket state to standby } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -9967,7 +9738,6 @@ uint16_t mode_particleFireworks1D(void) { if (PartSys->particles[i].ttl > 20) PartSys->particles[i].ttl -= 20; //ttl is linked to brightness, this allows to use higher brightness but still a short spark lifespan else PartSys->particles[i].ttl = 0; } - return FRAMETIME; } static const char _data_FX_MODE_PS_FIREWORKS1D[] PROGMEM = "PS Fireworks 1D@Gravity,Explosion,Firing side,Blur,Color,Colorful,Trail,Smooth;,!;!;1;c2=30,o1=1"; @@ -9976,7 +9746,7 @@ static const char _data_FX_MODE_PS_FIREWORKS1D[] PROGMEM = "PS Fireworks 1D@Grav Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleSparkler(void) { +void mode_particleSparkler(void) { ParticleSystem1D *PartSys = nullptr; uint32_t numSparklers; PSsettings1D sparklersettings; @@ -9984,11 +9754,11 @@ uint16_t mode_particleSparkler(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 16, 128 ,0, true)) // init, no additional data needed - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10038,8 +9808,6 @@ uint16_t mode_particleSparkler(void) { if (PartSys->particles[i].ttl > (64 - (SEGMENT.intensity >> 2))) PartSys->particles[i].ttl -= (64 - (SEGMENT.intensity >> 2)); //ttl is linked to brightness, this allows to use higher brightness but still a short spark lifespan else PartSys->particles[i].ttl = 0; } - - return FRAMETIME; } static const char _data_FX_MODE_PS_SPARKLER[] PROGMEM = "PS Sparkler@Move,!,Saturation,Blur,Sparklers,Slide,Bounce,Large;,!;!;1;pal=0,sx=255,c1=0,c2=0,c3=6"; @@ -10048,21 +9816,21 @@ static const char _data_FX_MODE_PS_SPARKLER[] PROGMEM = "PS Sparkler@Move,!,Satu Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleHourglass(void) { +void mode_particleHourglass(void) { ParticleSystem1D *PartSys = nullptr; constexpr int positionOffset = PS_P_RADIUS_1D / 2;; // resting position offset bool* direction; uint32_t* settingTracker; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 0, 255, 8, false)) // init - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel PartSys->setBounce(true); PartSys->setWallHardness(100); } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10163,8 +9931,6 @@ uint16_t mode_particleHourglass(void) { SEGENV.aux1--; // countdown PartSys->update(); // update and render - - return FRAMETIME; } static const char _data_FX_MODE_PS_HOURGLASS[] PROGMEM = "PS Hourglass@Interval,!,Color,Blur,Gravity,Colorflip,Start,Fast Reset;,!;!;1;pal=34,sx=5,ix=200,c1=140,c2=80,c3=4,o1=1,o2=1,o3=1"; @@ -10173,12 +9939,12 @@ static const char _data_FX_MODE_PS_HOURGLASS[] PROGMEM = "PS Hourglass@Interval, Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particle1Dspray(void) { +void mode_particle1Dspray(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1)) - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); PartSys->setWallHardness(150); PartSys->setParticleSize(1); @@ -10186,7 +9952,7 @@ uint16_t mode_particle1Dspray(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10215,8 +9981,6 @@ uint16_t mode_particle1Dspray(void) { PartSys->particleFlags[i].reversegrav = PartSys->sources[0].sourceFlags.reversegrav; // update gravity direction } PartSys->update(); // update and render - - return FRAMETIME; } static const char _data_FX_MODE_PS_1DSPRAY[] PROGMEM = "PS Spray 1D@Speed(+/-),!,Position,Blur,Gravity(+/-),AgeColor,Bounce,Position Color;,!;!;1;sx=200,ix=220,c1=0,c2=0"; @@ -10225,19 +9989,19 @@ static const char _data_FX_MODE_PS_1DSPRAY[] PROGMEM = "PS Spray 1D@Speed(+/-),! Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleBalance(void) { +void mode_particleBalance(void) { ParticleSystem1D *PartSys = nullptr; uint32_t i; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 128)) // init, no additional data needed, use half of max particles - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel PartSys->setParticleSize(1); } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10297,7 +10061,6 @@ uint16_t mode_particleBalance(void) { } } PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PS_BALANCE[] PROGMEM = "PS 1D Balance@!,!,Hardness,Blur,Tilt,Position Color,Wrap,Random;,!;!;1;pal=18,c2=0,c3=4,o1=1"; @@ -10306,11 +10069,11 @@ Particle based Chase effect Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleChase(void) { +void mode_particleChase(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 191, 2, true)) // init - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel SEGENV.aux0 = 0xFFFF; // invalidate *PartSys->PSdataEnd = 1; // huedir *(PartSys->PSdataEnd + 1) = 1; // sizedir @@ -10318,7 +10081,7 @@ uint16_t mode_particleChase(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setColorByPosition(SEGMENT.check3); @@ -10394,7 +10157,6 @@ uint16_t mode_particleChase(void) { PartSys->setParticleSize(SEGMENT.custom1); // if custom1 == 0 this sets rendering size to one pixel PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PS_CHASE[] PROGMEM = "PS Chase@!,Density,Size,Hue,Blur,Playful,,Position Color;,!;!;1;pal=11,sx=50,c2=5,c3=0"; @@ -10403,12 +10165,12 @@ static const char _data_FX_MODE_PS_CHASE[] PROGMEM = "PS Chase@!,Density,Size,Hu Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleStarburst(void) { +void mode_particleStarburst(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 200, 0, true)) // init - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); PartSys->enableParticleCollisions(true, 200); PartSys->sources[0].source.ttl = 1; // set initial stanby time @@ -10417,7 +10179,7 @@ uint16_t mode_particleStarburst(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10454,7 +10216,6 @@ uint16_t mode_particleStarburst(void) { } PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PS_STARBURST[] PROGMEM = "PS Starburst@Chance,Fragments,Size,Blur,Cooling,Gravity,Colorful,Push;,!;!;1;pal=52,sx=150,ix=150,c1=120,c2=0,c3=21"; @@ -10463,19 +10224,19 @@ static const char _data_FX_MODE_PS_STARBURST[] PROGMEM = "PS Starburst@Chance,Fr Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particle1DGEQ(void) { +void mode_particle1DGEQ(void) { ParticleSystem1D *PartSys = nullptr; uint32_t numSources; uint32_t i; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 16, 255, 0, true)) // init, no additional data needed - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10527,8 +10288,6 @@ uint16_t mode_particle1DGEQ(void) { //TODO: add color control? PartSys->update(); // update and render - - return FRAMETIME; } static const char _data_FX_MODE_PS_1D_GEQ[] PROGMEM = "PS GEQ 1D@Speed,!,Size,Blur,,,,;,!;!;1f;pal=0,sx=50,ix=200,c1=0,c2=0,c3=0,o1=1,o2=1"; @@ -10537,19 +10296,19 @@ static const char _data_FX_MODE_PS_1D_GEQ[] PROGMEM = "PS GEQ 1D@Speed,!,Size,Bl Uses palette for particle color by DedeHai (Damian Schneider) */ -uint16_t mode_particleFire1D(void) { +void mode_particleFire1D(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 5)) // init - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); PartSys->setParticleSize(1); } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10593,8 +10352,6 @@ uint16_t mode_particleFire1D(void) { } PartSys->update(); // update and render - - return FRAMETIME; } static const char _data_FX_MODE_PS_FIRE1D[] PROGMEM = "PS Fire 1D@!,!,Cooling,Blur;,!;!;1;pal=35,sx=100,ix=50,c1=80,c2=100,c3=28,o1=1,o2=1"; @@ -10602,12 +10359,12 @@ static const char _data_FX_MODE_PS_FIRE1D[] PROGMEM = "PS Fire 1D@!,!,Cooling,Bl Particle based AR effect, swoop particles along the strip with selected frequency loudness by DedeHai (Damian Schneider) */ -uint16_t mode_particle1DsonicStream(void) { +void mode_particle1DsonicStream(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 255, 0, true)) // init, no additional data needed - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); PartSys->sources[0].source.x = 0; // at start //PartSys->sources[1].source.x = PartSys->maxX; // at end @@ -10616,7 +10373,7 @@ uint16_t mode_particle1DsonicStream(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10696,8 +10453,6 @@ uint16_t mode_particle1DsonicStream(void) { PartSys->particleMoveUpdate(PartSys->particles[i], PartSys->particleFlags[i], nullptr, &PartSys->advPartProps[i]); } } - - return FRAMETIME; } static const char _data_FX_MODE_PS_SONICSTREAM[] PROGMEM = "PS Sonic Stream@!,!,Color,Blur,Bin,Mod,Filter,Push;,!;!;1f;c3=0,o2=1"; @@ -10706,17 +10461,17 @@ static const char _data_FX_MODE_PS_SONICSTREAM[] PROGMEM = "PS Sonic Stream@!,!, Particle based AR effect, creates exploding particles on beats by DedeHai (Damian Schneider) */ -uint16_t mode_particle1DsonicBoom(void) { +void mode_particle1DsonicBoom(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 255, 0, true)) // init, no additional data needed - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10788,7 +10543,6 @@ uint16_t mode_particle1DsonicBoom(void) { SEGMENT.aux1 = 0; // reset edge detection PartSys->update(); // update and render (needs to be done before manipulation for initial particle spacing to be right) - return FRAMETIME; } static const char _data_FX_MODE_PS_SONICBOOM[] PROGMEM = "PS Sonic Boom@!,!,Color,Position,Bin,Mod,Filter,Blur;,!;!;1f;c2=63,c3=0,o2=1"; @@ -10796,17 +10550,17 @@ static const char _data_FX_MODE_PS_SONICBOOM[] PROGMEM = "PS Sonic Boom@!,!,Colo Particles bound by springs by DedeHai (Damian Schneider) */ -uint16_t mode_particleSpringy(void) { +void mode_particleSpringy(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 128, 0, true)) // init with advanced properties (used for spring forces) - return mode_static(); // allocation failed or is single pixel + mode_static(); // allocation failed or is single pixel SEGENV.aux0 = SEGENV.aux1 = 0xFFFF; // invalidate settings } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - return mode_static(); // something went wrong, no data! + mode_static(); // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setMotionBlur(220 * SEGMENT.check1); // anable motion blur @@ -10957,7 +10711,6 @@ uint16_t mode_particleSpringy(void) { } } PartSys->update(); // update and render - return FRAMETIME; } static const char _data_FX_MODE_PS_SPRINGY[] PROGMEM = "PS Springy@Stiffness,Damping,Density,Hue,Mode,Smear,XL,AR;,!;!;1f;pal=54,c2=0,c3=23"; @@ -11095,7 +10848,7 @@ void WS2812FX::setupEffectData() { addEffect(FX_MODE_SOLID_GLITTER, &mode_solid_glitter, _data_FX_MODE_SOLID_GLITTER); addEffect(FX_MODE_MULTI_COMET, &mode_multi_comet, _data_FX_MODE_MULTI_COMET); #ifdef WLED_PS_DONT_REPLACE_1D_FX - addEffect(FX_MODE_ROLLINGBALLS, &rolling_balls, _data_FX_MODE_ROLLINGBALLS); + addEffect(FX_MODE_ROLLINGBALLS, &mode_rolling_balls, _data_FX_MODE_ROLLINGBALLS); addEffect(FX_MODE_STARBURST, &mode_starburst, _data_FX_MODE_STARBURST); addEffect(FX_MODE_DANCING_SHADOWS, &mode_dancing_shadows, _data_FX_MODE_DANCING_SHADOWS); #endif diff --git a/wled00/FX.h b/wled00/FX.h index bcbab69a59..bda87fa157 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -823,13 +823,13 @@ class Segment { // main "strip" class (108 bytes) class WS2812FX { - typedef uint16_t (*mode_ptr)(); // pointer to mode function + typedef void (*mode_ptr)(); // pointer to mode function typedef void (*show_callback)(); // pre show callback typedef struct ModeData { uint8_t _id; // mode (effect) id mode_ptr _fcn; // mode (effect) function const char *_data; // mode (effect) name and its UI control data - ModeData(uint8_t id, uint16_t (*fcn)(void), const char *data) : _id(id), _fcn(fcn), _data(data) {} + ModeData(uint8_t id, void (*fcn)(void), const char *data) : _id(id), _fcn(fcn), _data(data) {} } mode_data_t; public: diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 8834d89fa2..41534e8042 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1285,7 +1285,6 @@ void WS2812FX::service() { if (nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC)) { doShow = true; - unsigned frameDelay = FRAMETIME; if (!seg.freeze) { //only run effect function if not frozen // Effect blending @@ -1293,7 +1292,7 @@ void WS2812FX::service() { seg.beginDraw(prog); // set up parameters for get/setPixelColor() (will also blend colors and palette if blend style is FADE) _currentSegment = &seg; // set current segment for effect functions (SEGMENT & SEGENV) // workaround for on/off transition to respect blending style - frameDelay = (*_mode[seg.mode])(); // run new/current mode (needed for bri workaround) + _mode[seg.mode](); // run new/current mode (needed for bri workaround) seg.call++; // if segment is in transition and no old segment exists we don't need to run the old mode // (blendSegments() takes care of On/Off transitions and clipping) @@ -1304,14 +1303,13 @@ void WS2812FX::service() { segO->beginDraw(prog); // set up palette & colors (also sets draw dimensions), parent segment has transition progress _currentSegment = segO; // set current segment // workaround for on/off transition to respect blending style - frameDelay = min(frameDelay, (unsigned)(*_mode[segO->mode])()); // run old mode (needed for bri workaround; semaphore!!) - segO->call++; // increment old mode run counter + _mode[segO->mode](); // run old mode (needed for bri workaround; semaphore!!) + segO->call++; // increment old mode run counter Segment::modeBlend(false); // unset semaphore } - if (seg.isInTransition() && frameDelay > FRAMETIME) frameDelay = FRAMETIME; // force faster updates during transition } - seg.next_time = nowUp + frameDelay; + seg.next_time = nowUp + FRAMETIME; } _segment_index++; } diff --git a/wled00/FXparticleSystem.cpp b/wled00/FXparticleSystem.cpp index 626d936b9a..ad72187bd4 100644 --- a/wled00/FXparticleSystem.cpp +++ b/wled00/FXparticleSystem.cpp @@ -79,9 +79,8 @@ void ParticleSystem2D::update(void) { } // update function for fire animation -void ParticleSystem2D::updateFire(const uint8_t intensity,const bool renderonly) { - if (!renderonly) - fireParticleupdate(); +void ParticleSystem2D::updateFire(const uint8_t intensity) { + fireParticleupdate(); fireIntesity = intensity > 0 ? intensity : 1; // minimum of 1, zero checking is used in render function render(); } diff --git a/wled00/FXparticleSystem.h b/wled00/FXparticleSystem.h index 6a22109a93..92c32673f5 100644 --- a/wled00/FXparticleSystem.h +++ b/wled00/FXparticleSystem.h @@ -143,7 +143,7 @@ class ParticleSystem2D { ParticleSystem2D(const uint32_t width, const uint32_t height, const uint32_t numberofparticles, const uint32_t numberofsources, const bool isadvanced = false, const bool sizecontrol = false); // constructor // note: memory is allcated in the FX function, no deconstructor needed void update(void); //update the particles according to set options and render to the matrix - void updateFire(const uint8_t intensity, const bool renderonly); // update function for fire, if renderonly is set, particles are not updated (required to fix transitions with frameskips) + void updateFire(const uint8_t intensity); // update function for fire, if renderonly is set, particles are not updated (required to fix transitions with frameskips) void updateSystem(void); // call at the beginning of every FX, updates pointers and dimensions void particleMoveUpdate(PSparticle &part, PSparticleFlags &partFlags, PSsettings2D *options = NULL, PSadvancedParticle *advancedproperties = NULL); // move function // particle emitters From 1e73a6a3a6122f0839d2ac0b91c326318447486b Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 24 Jan 2026 16:02:46 +0100 Subject: [PATCH 2/7] fix missing return by adding FS_FALLBACK_STATIC macro --- wled00/FX.cpp | 368 ++++++++++++++++++------------------ wled00/FX_fcn.cpp | 4 +- wled00/FXparticleSystem.cpp | 12 +- wled00/FXparticleSystem.h | 2 +- 4 files changed, 198 insertions(+), 188 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 82cc671f8f..ddffeb039a 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -14,6 +14,8 @@ #include "FX.h" #include "fcn_declare.h" +#define FX_FALLBACK_STATIC { mode_static(); return; } + #if !(defined(WLED_DISABLE_PARTICLESYSTEM2D) && defined(WLED_DISABLE_PARTICLESYSTEM1D)) #include "FXparticleSystem.h" // include particle system code only if at least one system is enabled #ifdef WLED_DISABLE_PARTICLESYSTEM2D @@ -259,7 +261,7 @@ static const char _data_FX_MODE_STROBE_RAINBOW[] PROGMEM = "Strobe Rainbow@!;,!; * if (bool rev == true) then LEDs are turned off in reverse order */ void color_wipe(bool rev, bool useRandomColors) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; uint32_t cycleTime = 750 + (255 - SEGMENT.speed)*150; uint32_t perc = strip.now % cycleTime; unsigned prog = (perc * 65535) / cycleTime; @@ -383,7 +385,7 @@ static const char _data_FX_MODE_RANDOM_COLOR[] PROGMEM = "Random Colors@!,Fade t * to new random colors. */ void mode_dynamic(void) { - if (!SEGENV.allocateData(SEGLEN)) mode_static(); //allocation failed + if (!SEGENV.allocateData(SEGLEN)) FX_FALLBACK_STATIC; //allocation failed if(SEGENV.call == 0) { //SEGMENT.fill(BLACK); @@ -464,7 +466,7 @@ static const char _data_FX_MODE_FADE[] PROGMEM = "Fade@!;!,!;!;01"; * Scan mode parent function */ void scan(bool dual) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; uint32_t cycleTime = 750 + (255 - SEGMENT.speed)*150; uint32_t perc = strip.now % cycleTime; int prog = (perc * 65535) / cycleTime; @@ -686,7 +688,7 @@ static const char _data_FX_MODE_TWINKLE[] PROGMEM = "Twinkle@!,!;!,!;!;;m12=0"; */ void dissolve(uint32_t color) { unsigned dataSize = sizeof(uint32_t) * SEGLEN; - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed uint32_t* pixels = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { @@ -849,7 +851,7 @@ static const char _data_FX_MODE_MULTI_STROBE[] PROGMEM = "Strobe Mega@!,!;!,!;!; * Android loading circle, refactored by @dedehai */ void mode_android(void) { - if (!SEGENV.allocateData(sizeof(uint32_t))) mode_static(); + if (!SEGENV.allocateData(sizeof(uint32_t))) FX_FALLBACK_STATIC; uint32_t* counter = reinterpret_cast(SEGENV.data); unsigned size = SEGENV.aux1 >> 1; // upper 15 bit unsigned shrinking = SEGENV.aux1 & 0x01; // lowest bit @@ -1047,7 +1049,7 @@ static const char _data_FX_MODE_COLORFUL[] PROGMEM = "Colorful@!,Saturation;1,2, * Emulates a traffic light. */ void mode_traffic_light(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; for (unsigned i=0; i < SEGLEN; i++) SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); uint32_t mdelay = 500; @@ -1078,7 +1080,7 @@ static const char _data_FX_MODE_TRAFFIC_LIGHT[] PROGMEM = "Traffic Light@!,US st */ #define FLASH_COUNT 4 void mode_chase_flash(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; unsigned now = strip.now; // save time for delay calculation bool advance = true; unsigned flash_step = SEGENV.aux1 % ((FLASH_COUNT * 2) + 1); @@ -1116,7 +1118,7 @@ static const char _data_FX_MODE_CHASE_FLASH[] PROGMEM = "Chase Flash@!;Bg,Fx;!"; * Prim flashes running, followed by random color. */ void mode_chase_flash_random(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; unsigned now = strip.now; // save time for delay calculation bool advance = true; if (now < SEGENV.step) { @@ -1204,7 +1206,7 @@ static const char _data_FX_MODE_RUNNING_RANDOM[] PROGMEM = "Stream@!,Zone size;; * K.I.T.T. */ void mode_larson_scanner(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; const unsigned speed = FRAMETIME * map(SEGMENT.speed, 0, 255, 96, 2); // map into useful range const unsigned pixels = SEGLEN / speed; // how many pixels to advance per frame @@ -1260,7 +1262,7 @@ static const char _data_FX_MODE_DUAL_LARSON_SCANNER[] PROGMEM = "Scanner Dual@!, * Firing comets from one end. "Lighthouse" */ void mode_comet(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; unsigned counter = (strip.now * ((SEGMENT.speed >>2) +1)) & 0xFFFF; unsigned index = (counter * SEGLEN) >> 16; if (SEGENV.call == 0) SEGENV.aux0 = index; @@ -1285,7 +1287,7 @@ static const char _data_FX_MODE_COMET[] PROGMEM = "Lighthouse@!,Fade rate;!,!;!" * Fireworks function. */ void mode_fireworks() { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; const uint16_t width = SEGMENT.is2D() ? SEG_W : SEGLEN; const uint16_t height = SEG_H; @@ -1325,7 +1327,7 @@ static const char _data_FX_MODE_FIREWORKS[] PROGMEM = "Fireworks@,Frequency;!,!; //Twinkling LEDs running. Inspired by https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Rain.h void mode_rain() { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; const unsigned width = SEG_W; const unsigned height = SEG_H; SEGENV.step += FRAMETIME; @@ -1389,7 +1391,7 @@ static const char _data_FX_MODE_FIRE_FLICKER[] PROGMEM = "Fire Flicker@!,!;!;!;0 * Gradient run base function */ void gradient_base(bool loading) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; uint16_t counter = strip.now * ((SEGMENT.speed >> 2) + 1); uint16_t pp = (counter * SEGLEN) >> 16; if (SEGENV.call == 0) pp = 0; @@ -1432,7 +1434,7 @@ static const char _data_FX_MODE_LOADING[] PROGMEM = "Loading@!,Fade;!,!;!;;ix=16 * Two dots running */ void mode_two_dots() { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; unsigned delay = 1 + (FRAMETIME<<3) / SEGLEN; // longer segments should change faster uint32_t it = strip.now / map(SEGMENT.speed, 0, 255, delay<<4, delay); unsigned offset = it % SEGLEN; @@ -1543,7 +1545,7 @@ static const char _data_FX_MODE_FAIRY[] PROGMEM = "Fairy@!,# of flashers;!,!;!"; */ void mode_fairytwinkle() { unsigned dataSize = sizeof(flasher) * SEGLEN; - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed Flasher* flashers = reinterpret_cast(SEGENV.data); unsigned now16 = strip.now & 0xFFFF; uint16_t PRNG16 = 5100 + strip.getCurrSegmentId(); @@ -1776,7 +1778,7 @@ void mode_multi_comet(void) { uint32_t cycleTime = 10 + (uint32_t)(255 - SEGMENT.speed); uint32_t it = strip.now / cycleTime; if (SEGENV.step == it) return; - if (!SEGENV.allocateData(sizeof(uint16_t) * MAX_COMETS)) mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(uint16_t) * MAX_COMETS)) FX_FALLBACK_STATIC; //allocation failed SEGMENT.fade_out(SEGMENT.intensity/2 + 128); @@ -1854,7 +1856,7 @@ void mode_oscillate(void) { constexpr unsigned numOscillators = 3; constexpr unsigned dataSize = sizeof(oscillator) * numOscillators; - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed Oscillator* oscillators = reinterpret_cast(SEGENV.data); @@ -1901,7 +1903,7 @@ static const char _data_FX_MODE_OSCILLATE[] PROGMEM = "Oscillate"; void mode_lightning(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; unsigned ledstart = hw_random16(SEGLEN); // Determine starting location of flash unsigned ledlen = 1 + hw_random16(SEGLEN -ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1) uint8_t bri = 255/hw_random8(1, 3); @@ -2009,7 +2011,7 @@ static const char _data_FX_MODE_COLORWAVES[] PROGMEM = "Colorwaves@!,Hue;!;!;;pa //eight colored dots, weaving in and out of sync with each other void mode_juggle(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; SEGMENT.fadeToBlackBy(192 - (3*SEGMENT.intensity/4)); CRGB fastled_col; @@ -2152,9 +2154,9 @@ static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Shift,Size,Rotation // feel of your fire: COOLING (used in step 1 above) (Speed = COOLING), and SPARKING (used // in step 3 above) (Effect Intensity = Sparking). void mode_fire_2012() { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; const unsigned strips = SEGMENT.nrOfVStrips(); - if (!SEGENV.allocateData(strips * SEGLEN)) mode_static(); //allocation failed + if (!SEGENV.allocateData(strips * SEGLEN)) FX_FALLBACK_STATIC; //allocation failed byte* heat = SEGENV.data; const uint32_t it = strip.now >> 5; //div 32 @@ -2299,7 +2301,7 @@ static const char _data_FX_MODE_NOISE16_4[] PROGMEM = "Noise 4@!;!;!;;pal=26"; //based on https://gist.github.com/kriegsman/5408ecd397744ba0393e void mode_colortwinkle() { unsigned dataSize = (SEGLEN+7) >> 3; //1 bit per LED - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed //limit update rate if (strip.now - SEGENV.step < FRAMETIME_FIXED) return; @@ -2374,8 +2376,8 @@ static const char _data_FX_MODE_LAKE[] PROGMEM = "Lake@!;Fx;!"; // send a meteor from begining to to the end of the strip with a trail that randomly decays. // adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain void mode_meteor() { - if (SEGLEN <= 1) mode_static(); - if (!SEGENV.allocateData(SEGLEN)) mode_static(); //allocation failed + if (SEGLEN <= 1) FX_FALLBACK_STATIC; + if (!SEGENV.allocateData(SEGLEN)) FX_FALLBACK_STATIC; //allocation failed const bool meteorSmooth = SEGMENT.check3; byte* trail = SEGENV.data; @@ -2442,7 +2444,7 @@ static const char _data_FX_MODE_METEOR[] PROGMEM = "Meteor@!,Trail,,,,Gradient,, //Railway Crossing / Christmas Fairy lights void mode_railway() { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; unsigned dur = (256 - SEGMENT.speed) * 40; uint16_t rampdur = (dur * SEGMENT.intensity) >> 8; if (SEGENV.step > dur) @@ -2491,7 +2493,7 @@ static void ripple_base(uint8_t blurAmount = 0) { unsigned maxRipples = min(1 + (int)(SEGLEN >> 2), MAX_RIPPLES); // 56 max for 16 segment ESP8266 unsigned dataSize = sizeof(ripple) * maxRipples; - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed Ripple* ripples = reinterpret_cast(SEGENV.data); @@ -2541,7 +2543,7 @@ static void ripple_base(uint8_t blurAmount = 0) { void mode_ripple(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; if(SEGMENT.custom1 || SEGMENT.check2) // blur or overlay SEGMENT.fade_out(250); else @@ -2553,7 +2555,7 @@ static const char _data_FX_MODE_RIPPLE[] PROGMEM = "Ripple@!,Wave #,Blur,,,,Over void mode_ripple_rainbow(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; if (SEGENV.call ==0) { SEGENV.aux0 = hw_random8(); SEGENV.aux1 = hw_random8(); @@ -2731,14 +2733,14 @@ void mode_halloween_eyes() uint32_t blinkEndTime; }; - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; const unsigned maxWidth = strip.isMatrix ? SEG_W : SEGLEN; const unsigned HALLOWEEN_EYE_SPACE = MAX(2, strip.isMatrix ? SEG_W>>4: SEGLEN>>5); const unsigned HALLOWEEN_EYE_WIDTH = HALLOWEEN_EYE_SPACE/2; unsigned eyeLength = (2*HALLOWEEN_EYE_WIDTH) + HALLOWEEN_EYE_SPACE; - if (eyeLength >= maxWidth) mode_static(); //bail if segment too short + if (eyeLength >= maxWidth) FX_FALLBACK_STATIC; //bail if segment too short - if (!SEGENV.allocateData(sizeof(EyeData))) mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(EyeData))) FX_FALLBACK_STATIC; //allocation failed EyeData& data = *reinterpret_cast(SEGENV.data); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); //fill background @@ -2910,7 +2912,7 @@ static const char _data_FX_MODE_TRI_STATIC_PATTERN[] PROGMEM = "Solid Pattern Tr static void spots_base(uint16_t threshold) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); unsigned maxZones = SEGLEN >> 2; @@ -2963,12 +2965,12 @@ typedef struct Ball { * Bouncing Balls Effect */ void mode_bouncing_balls(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; //allocate segment data const unsigned strips = SEGMENT.nrOfVStrips(); // adapt for 2D const size_t maxNumBalls = 16; unsigned dataSize = sizeof(ball) * maxNumBalls; - if (!SEGENV.allocateData(dataSize * strips)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize * strips)) FX_FALLBACK_STATIC; //allocation failed Ball* balls = reinterpret_cast(SEGENV.data); @@ -3051,7 +3053,7 @@ static void mode_rolling_balls(void) { //allocate segment data const unsigned maxNumBalls = 16; // 255/16 + 1 unsigned dataSize = sizeof(rball_t) * maxNumBalls; - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed rball_t *balls = reinterpret_cast(SEGENV.data); @@ -3176,7 +3178,7 @@ static void mode_pacman(void) { // Allocate segment data unsigned dataSize = sizeof(pacmancharacters_t) * (numGhosts + maxPowerDots + 1); // +1 is the PacMan character - if (SEGLEN <= 16 + (2*numGhosts) || !SEGENV.allocateData(dataSize)) mode_static(); + if (SEGLEN <= 16 + (2*numGhosts) || !SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; pacmancharacters_t *character = reinterpret_cast(SEGENV.data); // Calculate when blue ghosts start blinking. @@ -3332,7 +3334,7 @@ static const char _data_FX_MODE_PACMAN[] PROGMEM = "PacMan@Speed,# of PowerDots, * Sinelon stolen from FASTLED examples */ static void sinelon_base(bool dual, bool rainbow=false) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; SEGMENT.fade_out(SEGMENT.intensity); unsigned pos = beatsin16_t(SEGMENT.speed/10,0,SEGLEN-1); if (SEGENV.call == 0) SEGENV.aux0 = pos; @@ -3431,13 +3433,13 @@ typedef struct Spark { * modified from https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Popcorn.h */ void mode_popcorn(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; //allocate segment data unsigned strips = SEGMENT.nrOfVStrips(); unsigned usablePopcorns = maxNumPopcorn; if (usablePopcorns * strips * sizeof(spark) > FAIR_DATA_PER_SEG) usablePopcorns = FAIR_DATA_PER_SEG / (strips * sizeof(spark)) + 1; // at least 1 popcorn per vstrip unsigned dataSize = sizeof(spark) * usablePopcorns; // on a matrix 64x64 this could consume a little less than 27kB when Bar expansion is used - if (!SEGENV.allocateData(dataSize * strips)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize * strips)) FX_FALLBACK_STATIC; //allocation failed Spark* popcorn = reinterpret_cast(SEGENV.data); @@ -3606,7 +3608,7 @@ typedef struct particle { } star; void mode_starburst(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; unsigned maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640 unsigned segs = strip.getActiveSegmentsNum(); if (segs <= (strip.getMaxSegments() /2)) maxData *= 2; //ESP8266: 512 if <= 8 segs ESP32: 1280 if <= 16 segs @@ -3617,7 +3619,7 @@ void mode_starburst(void) { if (numStars > maxStars) numStars = maxStars; unsigned dataSize = sizeof(star) * numStars; - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed uint32_t it = strip.now; @@ -3725,7 +3727,7 @@ static const char _data_FX_MODE_STARBURST[] PROGMEM = "Fireworks Starburst@Chanc */ void mode_exploding_fireworks(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; const int cols = SEGMENT.is2D() ? SEG_W : 1; const int rows = SEGMENT.is2D() ? SEG_H : SEGLEN; @@ -3738,7 +3740,7 @@ void mode_exploding_fireworks(void) unsigned numSparks = min(5 + ((rows*cols) >> 1), maxSparks); unsigned dataSize = sizeof(spark) * numSparks; - if (!SEGENV.allocateData(dataSize + sizeof(float))) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize + sizeof(float))) FX_FALLBACK_STATIC; //allocation failed float *dying_gravity = reinterpret_cast(SEGENV.data + dataSize); if (dataSize != SEGENV.aux1) { //reset to flare if sparks were reallocated (it may be good idea to reset segment if bounds change) @@ -3861,12 +3863,12 @@ static const char _data_FX_MODE_EXPLODING_FIREWORKS[] PROGMEM = "Fireworks 1D@Gr */ void mode_drip(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; //allocate segment data unsigned strips = SEGMENT.nrOfVStrips(); const int maxNumDrops = 4; unsigned dataSize = sizeof(spark) * maxNumDrops; - if (!SEGENV.allocateData(dataSize * strips)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize * strips)) FX_FALLBACK_STATIC; //allocation failed Spark* drops = reinterpret_cast(SEGENV.data); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); @@ -3954,10 +3956,10 @@ typedef struct Tetris { } tetris; void mode_tetrix(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; unsigned strips = SEGMENT.nrOfVStrips(); // allow running on virtual strips (columns in 2D segment) unsigned dataSize = sizeof(tetris); - if (!SEGENV.allocateData(dataSize * strips)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize * strips)) FX_FALLBACK_STATIC; //allocation failed Tetris* drops = reinterpret_cast(SEGENV.data); //if (SEGENV.call == 0) SEGMENT.fill(SEGCOLOR(1)); // will fill entire segment (1D or 2D), then use drop->step = 0 below @@ -4252,7 +4254,7 @@ static const char _data_FX_MODE_PACIFICA[] PROGMEM = "Pacifica@!,Angle;;!;;pal=5 * Mode simulates a gradual sunrise */ void mode_sunrise() { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; //speed 0 - static sun //speed 1 - 60: sunrise time in minutes //speed 60 - 120 : sunset time in minutes - 60; @@ -4358,7 +4360,7 @@ void mode_noisepal(void) { // Slow noise pale //#define scale 30 unsigned dataSize = sizeof(CRGBPalette16) * 2; //allocate space for 2 Palettes (2 * 16 * 3 = 96 bytes) - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed CRGBPalette16* palettes = reinterpret_cast(SEGENV.data); @@ -4448,7 +4450,7 @@ static const char _data_FX_MODE_FLOW[] PROGMEM = "Flow@!,Zones;;!;;m12=1"; //ver */ void mode_chunchun(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; SEGMENT.fade_out(254); // add a bit of trail unsigned counter = strip.now * (6 + (SEGMENT.speed >> 4)); unsigned numBirds = 2 + (SEGLEN >> 3); // 2 + 1/8 of a segment @@ -4498,13 +4500,13 @@ typedef struct Spotlight { */ void mode_dancing_shadows(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; unsigned numSpotlights = map(SEGMENT.intensity, 0, 255, 2, SPOT_MAX_COUNT); // 49 on 32 segment ESP32, 17 on 16 segment ESP8266 bool initialize = SEGENV.aux0 != numSpotlights; SEGENV.aux0 = numSpotlights; unsigned dataSize = sizeof(spotlight) * numSpotlights; - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed Spotlight* spotlights = reinterpret_cast(SEGENV.data); SEGMENT.fill(BLACK); @@ -4635,7 +4637,7 @@ static const char _data_FX_MODE_WASHING_MACHINE[] PROGMEM = "Washing Machine@!,! */ void mode_image(void) { #ifndef WLED_ENABLE_GIF - mode_static(); + FX_FALLBACK_STATIC; #else renderImageToSegment(SEGMENT); #endif @@ -4653,7 +4655,7 @@ static const char _data_FX_MODE_IMAGE[] PROGMEM = "Image@!,Blur,;;;12;sx=128,ix= void mode_blends(void) { unsigned pixelLen = SEGLEN > UINT8_MAX ? UINT8_MAX : SEGLEN; unsigned dataSize = sizeof(uint32_t) * (pixelLen + 1); // max segment length of 56 pixels on 16 segment ESP8266 - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed uint32_t* pixels = reinterpret_cast(SEGENV.data); uint8_t blendSpeed = map(SEGMENT.intensity, 0, UINT8_MAX, 10, 128); unsigned shift = (strip.now * ((SEGMENT.speed >> 3) +1)) >> 8; @@ -4701,7 +4703,7 @@ void mode_tv_simulator(void) { int nr, ng, nb, r, g, b, i, hue; uint8_t sat, bri, j; - if (!SEGENV.allocateData(sizeof(tvSim))) mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(tvSim))) FX_FALLBACK_STATIC; //allocation failed TvSim* tvSimulator = reinterpret_cast(SEGENV.data); uint8_t colorSpeed = map(SEGMENT.speed, 0, UINT8_MAX, 1, 20); @@ -4913,7 +4915,7 @@ void mode_aurora(void) { AuroraWave* waves; SEGENV.aux1 = map(SEGMENT.intensity, 0, 255, 2, W_MAX_COUNT); // aux1 = Wavecount if (!SEGENV.allocateData(sizeof(AuroraWave) * SEGENV.aux1)) { - mode_static(); + FX_FALLBACK_STATIC; } waves = reinterpret_cast(SEGENV.data); @@ -4954,7 +4956,7 @@ static const char _data_FX_MODE_AURORA[] PROGMEM = "Aurora@!,!;1,2,3;!;;sx=24,pa // 16 bit perlinmove. Use Perlin Noise instead of sinewaves for movement. By Andrew Tuline. // Controls are speed, # of pixels, faderate. void mode_perlinmove(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; SEGMENT.fade_out(255-SEGMENT.custom1); for (int i = 0; i < SEGMENT.intensity/16 + 1; i++) { unsigned locn = perlin16(strip.now*128/(260-SEGMENT.speed)+i*15000, strip.now*128/(260-SEGMENT.speed)); // Get a new pixel location from moving noise. @@ -4986,7 +4988,7 @@ static const char _data_FX_MODE_WAVESINS[] PROGMEM = "Wavesins@!,Brightness vari ////////////////////////////// // By: ldirko https://editor.soulmatelights.com/gallery/392-flow-led-stripe , modifed by: Andrew Tuline, fixed by @DedeHai void mode_FlowStripe(void) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; const int hl = SEGLEN * 10 / 13; uint8_t hue = strip.now / (SEGMENT.speed+1); uint32_t t = strip.now / (SEGMENT.intensity/8+1); @@ -5007,7 +5009,7 @@ static const char _data_FX_MODE_FLOWSTRIPE[] PROGMEM = "Flow Stripe@Hue speed,Ef by DedeHai (Damian Schneider), based on idea from @Charming-Lime (#4905) */ void mode_shimmer() { - if(!SEGENV.allocateData(sizeof(uint32_t))) { mode_static(); } + if(!SEGENV.allocateData(sizeof(uint32_t))) { FX_FALLBACK_STATIC; } uint32_t* lastTime = reinterpret_cast(SEGENV.data); uint32_t radius = (SEGMENT.custom1 * SEGLEN >> 7) + 1; // [1, 2*SEGLEN+1] pixels @@ -5079,7 +5081,7 @@ static const char _data_FX_MODE_SHIMMER[] PROGMEM = "Shimmer@Speed,Interval,Size // Black hole void mode_2DBlackHole(void) { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5111,7 +5113,7 @@ static const char _data_FX_MODE_2DBLACKHOLE[] PROGMEM = "Black Hole@Fade rate,Ou // 2D Colored Bursts // //////////////////////////// void mode_2DColoredBursts() { // By: ldirko https://editor.soulmatelights.com/gallery/819-colored-bursts , modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5161,7 +5163,7 @@ static const char _data_FX_MODE_2DCOLOREDBURSTS[] PROGMEM = "Colored Bursts@Spee // 2D DNA // ///////////////////// void mode_2Ddna(void) { // dna originally by by ldirko at https://pastebin.com/pCkkkzcs. Updated by Preyy. WLED conversion by Andrew Tuline. - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5179,7 +5181,7 @@ static const char _data_FX_MODE_2DDNA[] PROGMEM = "DNA@Scroll speed,Blur,,,,Smea // 2D DNA Spiral // ///////////////////////// void mode_2DDNASpiral() { // By: ldirko https://editor.soulmatelights.com/gallery/512-dna-spiral-variation , modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5225,7 +5227,7 @@ static const char _data_FX_MODE_2DDNASPIRAL[] PROGMEM = "DNA Spiral@Scroll speed // 2D Drift // ///////////////////////// void mode_2DDrift() { // By: Stepko https://editor.soulmatelights.com/gallery/884-drift , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5253,7 +5255,7 @@ static const char _data_FX_MODE_2DDRIFT[] PROGMEM = "Drift@Rotation speed,Blur,, // 2D Firenoise // ////////////////////////// void mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline. Yet another short routine. - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5285,7 +5287,7 @@ static const char _data_FX_MODE_2DFIRENOISE[] PROGMEM = "Firenoise@X scale,Y sca // 2D Frizzles // ////////////////////////////// void mode_2DFrizzles(void) { // By: Stepko https://editor.soulmatelights.com/gallery/640-color-frizzles , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5310,11 +5312,11 @@ typedef struct Cell { void mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https://natureofcode.com/book/chapter-7-cellular-automata/ // and https://github.com/DougHaber/nlife-color , Modified By: Brandon Butler - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W, rows = SEG_H; const unsigned maxIndex = cols * rows; - if (!SEGENV.allocateData(SEGMENT.length() * sizeof(Cell))) mode_static(); // allocation failed + if (!SEGENV.allocateData(SEGMENT.length() * sizeof(Cell))) FX_FALLBACK_STATIC; // allocation failed Cell *cells = reinterpret_cast (SEGENV.data); @@ -5464,7 +5466,7 @@ static const char _data_FX_MODE_2DGAMEOFLIFE[] PROGMEM = "Game Of Life@!,,Blur,, // 2D Hiphotic // ///////////////////////// void mode_2DHiphotic() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5494,12 +5496,12 @@ typedef struct Julia { } julia; void mode_2DJulia(void) { // An animated Julia set by Andrew Tuline. - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; - if (!SEGENV.allocateData(sizeof(julia))) mode_static(); + if (!SEGENV.allocateData(sizeof(julia))) FX_FALLBACK_STATIC; Julia* julias = reinterpret_cast(SEGENV.data); float reAl; @@ -5599,7 +5601,7 @@ static const char _data_FX_MODE_2DJULIA[] PROGMEM = "Julia@,Max iterations per p // 2D Lissajous // ////////////////////////////// void mode_2DLissajous(void) { // By: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5626,14 +5628,14 @@ static const char _data_FX_MODE_2DLISSAJOUS[] PROGMEM = "Lissajous@X frequency,F // 2D Matrix // /////////////////////// void mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi, and softhack007. - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; const auto XY = [&](int x, int y) { return (x%cols) + (y%rows) * cols; }; unsigned dataSize = (SEGMENT.length()+7) >> 3; //1 bit per LED for trails - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed if (SEGENV.call == 0) { SEGMENT.fill(BLACK); @@ -5695,7 +5697,7 @@ static const char _data_FX_MODE_2DMATRIX[] PROGMEM = "Matrix@!,Spawning rate,Tra // 2D Metaballs // ///////////////////////// void mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have one of the dimensions be 2 or less. Adapted by Andrew Tuline. - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5752,7 +5754,7 @@ static const char _data_FX_MODE_2DMETABALLS[] PROGMEM = "Metaballs@!;;!;2"; // 2D Noise // ////////////////////// void mode_2Dnoise(void) { // By Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5773,7 +5775,7 @@ static const char _data_FX_MODE_2DNOISE[] PROGMEM = "Noise2D@!,Scale;;!;2"; // 2D Plasma Ball // ////////////////////////////// void mode_2DPlasmaball(void) { // By: Stepko https://editor.soulmatelights.com/gallery/659-plasm-ball , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5809,7 +5811,7 @@ static const char _data_FX_MODE_2DPLASMABALL[] PROGMEM = "Plasma Ball@Speed,,Fad //////////////////////////////// void mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https://editor.soulmatelights.com/gallery/762-polar-lights , Modified by: Andrew Tuline & @dedehai (palette support) - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5841,7 +5843,7 @@ static const char _data_FX_MODE_2DPOLARLIGHTS[] PROGMEM = "Polar Lights@!,Scale, // 2D Pulser // ///////////////////////// void mode_2DPulser(void) { // By: ldirko https://editor.soulmatelights.com/gallery/878-pulse-test , modifed by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5861,7 +5863,7 @@ static const char _data_FX_MODE_2DPULSER[] PROGMEM = "Pulser@!,Blur;;!;2"; // 2D Sindots // ///////////////////////// void mode_2DSindots(void) { // By: ldirko https://editor.soulmatelights.com/gallery/597-sin-dots , modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5890,7 +5892,7 @@ static const char _data_FX_MODE_2DSINDOTS[] PROGMEM = "Sindots@!,Dot distance,Fa // custom3 affects the blur amount. void mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://gist.github.com/kriegsman/368b316c55221134b160 // Modifed by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -5919,12 +5921,12 @@ static const char _data_FX_MODE_2DSQUAREDSWIRL[] PROGMEM = "Squared Swirl@,Fade, // 2D Sun Radiation // ////////////////////////////// void mode_2DSunradiation(void) { // By: ldirko https://editor.soulmatelights.com/gallery/599-sun-radiation , modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; - if (!SEGENV.allocateData(sizeof(byte)*(cols+2)*(rows+2))) mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(byte)*(cols+2)*(rows+2))) FX_FALLBACK_STATIC; //allocation failed byte *bump = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { @@ -5968,7 +5970,7 @@ static const char _data_FX_MODE_2DSUNRADIATION[] PROGMEM = "Sun Radiation@Varian // 2D Tartan // ///////////////////////// void mode_2Dtartan(void) { // By: Elliott Kember https://editor.soulmatelights.com/gallery/3-tartan , Modified by: Andrew Tuline - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6005,7 +6007,7 @@ static const char _data_FX_MODE_2DTARTAN[] PROGMEM = "Tartan@X scale,Y scale,,,S // 2D spaceships // ///////////////////////// void mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [https://editor.soulmatelights.com/gallery/639-space-ships], adapted by Blaz Kristan (AKA blazoncek) - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6046,7 +6048,7 @@ static const char _data_FX_MODE_2DSPACESHIPS[] PROGMEM = "Spaceships@!,Blur,,,,S //// Crazy bees by stepko (c)12.02.21 [https://editor.soulmatelights.com/gallery/651-crazy-bees], adapted by Blaz Kristan (AKA blazoncek), improved by @dedehai #define MAX_BEES 5 void mode_2Dcrazybees(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6069,7 +6071,7 @@ void mode_2Dcrazybees(void) { }; } bee_t; - if (!SEGENV.allocateData(sizeof(bee_t)*MAX_BEES)) mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(bee_t)*MAX_BEES)) FX_FALLBACK_STATIC; //allocation failed bee_t *bee = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { @@ -6118,7 +6120,7 @@ static const char _data_FX_MODE_2DCRAZYBEES[] PROGMEM = "Crazy Bees@!,Blur,,,,Sm //// Ghost Rider by stepko (c)2021 [https://editor.soulmatelights.com/gallery/716-ghost-rider], adapted by Blaz Kristan (AKA blazoncek) #define LIGHTERS_AM 64 // max lighters (adequate for 32x32 matrix) void mode_2Dghostrider(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6136,7 +6138,7 @@ void mode_2Dghostrider(void) { int8_t Vspeed; } lighter_t; - if (!SEGENV.allocateData(sizeof(lighter_t))) mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(lighter_t))) FX_FALLBACK_STATIC; //allocation failed lighter_t *lighter = reinterpret_cast(SEGENV.data); const size_t maxLighters = min(cols + rows, LIGHTERS_AM); @@ -6205,7 +6207,7 @@ static const char _data_FX_MODE_2DGHOSTRIDER[] PROGMEM = "Ghost Rider@Fade rate, //// Floating Blobs by stepko (c)2021 [https://editor.soulmatelights.com/gallery/573-blobs], adapted by Blaz Kristan (AKA blazoncek) #define MAX_BLOBS 8 void mode_2Dfloatingblobs(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6220,7 +6222,7 @@ void mode_2Dfloatingblobs(void) { size_t Amount = (SEGMENT.intensity>>5) + 1; // NOTE: be sure to update MAX_BLOBS if you change this - if (!SEGENV.allocateData(sizeof(blob_t))) mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(blob_t))) FX_FALLBACK_STATIC; //allocation failed blob_t *blob = reinterpret_cast(SEGENV.data); if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) { @@ -6301,7 +6303,7 @@ static const char _data_FX_MODE_2DBLOBS[] PROGMEM = "Blobs@!,# blobs,Blur,Trail; // 2D Scrolling text // //////////////////////////// void mode_2Dscrollingtext(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6450,7 +6452,7 @@ static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Off //////////////////////////// //// Drift Rose by stepko (c)2021 [https://editor.soulmatelights.com/gallery/1369-drift-rose-pattern], adapted by Blaz Kristan (AKA blazoncek) improved by @dedehai void mode_2Ddriftrose(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6476,13 +6478,13 @@ static const char _data_FX_MODE_2DDRIFTROSE[] PROGMEM = "Drift Rose@Fade,Blur,,, ///////////////////////////// // Plasma Rotozoomer by ldirko (c)2020 [https://editor.soulmatelights.com/gallery/457-plasma-rotozoomer], adapted for WLED by Blaz Kristan (AKA blazoncek) void mode_2Dplasmarotozoom() { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; unsigned dataSize = SEGMENT.length() + sizeof(float); - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed float *a = reinterpret_cast(SEGENV.data); byte *plasma = reinterpret_cast(SEGENV.data+sizeof(float)); @@ -6532,7 +6534,7 @@ void mode_ripplepeak(void) { // * Ripple peak. By Andrew Tuline. unsigned maxRipples = 16; unsigned dataSize = sizeof(Ripple) * maxRipples; - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed Ripple* ripples = reinterpret_cast(SEGENV.data); um_data_t *um_data = getAudioData(); @@ -6601,7 +6603,7 @@ static const char _data_FX_MODE_RIPPLEPEAK[] PROGMEM = "Ripple Peak@Fade rate,Ma ///////////////////////// // By: Mark Kriegsman https://gist.github.com/kriegsman/5adca44e14ad025e6d3b , modified by Andrew Tuline void mode_2DSwirl(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6638,7 +6640,7 @@ static const char _data_FX_MODE_2DSWIRL[] PROGMEM = "Swirl@!,Sensitivity,Blur;,B ///////////////////////// // By: Stepko, https://editor.soulmatelights.com/gallery/652-wave , modified by Andrew Tuline void mode_2DWaverly(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -6682,10 +6684,10 @@ typedef struct Gravity { // Gravcenter base function for Gravcenter (0), Gravcentric (1), Gravimeter (2), Gravfreq (3) (merged by @dedehai) void mode_gravcenter_base(unsigned mode) { - if (SEGLEN == 1) mode_static(); + if (SEGLEN == 1) FX_FALLBACK_STATIC; const unsigned dataSize = sizeof(gravity); - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed Gravity* gravcen = reinterpret_cast(SEGENV.data); um_data_t *um_data = getAudioData(); @@ -6820,7 +6822,7 @@ static const char _data_FX_MODE_JUGGLES[] PROGMEM = "Juggles@!,# of balls;!,!;!; void mode_matripix(void) { // Matripix. By Andrew Tuline. // effect can work on single pixels, we just lose the shifting effect unsigned dataSize = sizeof(uint32_t) * SEGLEN; - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed uint32_t* pixels = reinterpret_cast(SEGENV.data); um_data_t *um_data = getAudioData(); @@ -6852,7 +6854,7 @@ static const char _data_FX_MODE_MATRIPIX[] PROGMEM = "Matripix@!,Brightness;!,!; // * MIDNOISE // ////////////////////// void mode_midnoise(void) { // Midnoise. By Andrew Tuline. - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; // Changing xdist to SEGENV.aux0 and ydist to SEGENV.aux1. um_data_t *um_data = getAudioData(); @@ -6937,7 +6939,7 @@ static const char _data_FX_MODE_NOISEMETER[] PROGMEM = "Noisemeter@Fade rate,Wid // * PIXELWAVE // ////////////////////// void mode_pixelwave(void) { // Pixelwave. By Andrew Tuline. - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; // even with 1D effect we have to take logic for 2D segments for allocation as fill_solid() fills whole segment if (SEGENV.call == 0) { @@ -6971,7 +6973,7 @@ typedef struct Plasphase { void mode_plasmoid(void) { // Plasmoid. By Andrew Tuline. // even with 1D effect we have to take logic for 2D segments for allocation as fill_solid() fills whole segment - if (!SEGENV.allocateData(sizeof(plasphase))) mode_static(); //allocation failed + if (!SEGENV.allocateData(sizeof(plasphase))) FX_FALLBACK_STATIC; //allocation failed Plasphase* plasmoip = reinterpret_cast(SEGENV.data); um_data_t *um_data = getAudioData(); @@ -7001,7 +7003,7 @@ static const char _data_FX_MODE_PLASMOID[] PROGMEM = "Plasmoid@Phase,# of pixels ////////////////////// // Puddles/Puddlepeak By Andrew Tuline. Merged by @dedehai void mode_puddles_base(bool peakdetect) { - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; unsigned size = 0; uint8_t fadeVal = map(SEGMENT.speed, 0, 255, 224, 254); unsigned pos = hw_random16(SEGLEN); // Set a random starting position. @@ -7049,9 +7051,9 @@ static const char _data_FX_MODE_PUDDLES[] PROGMEM = "Puddles@Fade rate,Puddle si // * PIXELS // ////////////////////// void mode_pixels(void) { // Pixels. By Andrew Tuline. - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; - if (!SEGENV.allocateData(32*sizeof(uint8_t))) mode_static(); //allocation failed + if (!SEGENV.allocateData(32*sizeof(uint8_t))) FX_FALLBACK_STATIC; //allocation failed uint8_t *myVals = reinterpret_cast(SEGENV.data); // Used to store a pile of samples because WLED frame rate and WLED sample rate are not synchronized. Frame rate is too low. um_data_t *um_data; @@ -7075,7 +7077,7 @@ static const char _data_FX_MODE_PIXELS[] PROGMEM = "Pixels@Fade rate,# of pixels // ** Blurz // ////////////////////// void mode_blurz(void) { // Blurz. By Andrew Tuline. - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; // even with 1D effect we have to take logic for 2D segments for allocation as fill_solid() fills whole segment um_data_t *um_data = getAudioData(); @@ -7135,7 +7137,7 @@ static const char _data_FX_MODE_DJLIGHT[] PROGMEM = "DJ Light@Speed;;;01f;m12=2, // ** Freqmap // //////////////////// void mode_freqmap(void) { // Map FFT_MajorPeak to SEGLEN. Would be better if a higher framerate. - if (SEGLEN <= 1) mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; // Start frequency = 60 Hz and log10(60) = 1.78 // End frequency = MAX_FREQUENCY in Hz and lo10(MAX_FREQUENCY) = MAX_FREQ_LOG10 @@ -7366,7 +7368,7 @@ static const char _data_FX_MODE_ROCKTAVES[] PROGMEM = "Rocktaves@;!,!;!;01f;m12= void mode_waterfall(void) { // Waterfall. By: Andrew Tuline // effect can work on single pixels, we just lose the shifting effect unsigned dataSize = sizeof(uint32_t) * SEGLEN; - if (!SEGENV.allocateData(dataSize)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize)) FX_FALLBACK_STATIC; //allocation failed uint32_t* pixels = reinterpret_cast(SEGENV.data); um_data_t *um_data = getAudioData(); @@ -7418,14 +7420,14 @@ static const char _data_FX_MODE_WATERFALL[] PROGMEM = "Waterfall@!,Adjust color, // ** 2D GEQ // ///////////////////////// void mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int NUM_BANDS = map(SEGMENT.custom1, 0, 255, 1, 16); const int CENTER_BIN = map(SEGMENT.custom3, 0, 31, 0, 15); const int cols = SEG_W; const int rows = SEG_H; - if (!SEGENV.allocateData(cols*sizeof(uint16_t))) mode_static(); //allocation failed + if (!SEGENV.allocateData(cols*sizeof(uint16_t))) FX_FALLBACK_STATIC; //allocation failed uint16_t *previousBarHeight = reinterpret_cast(SEGENV.data); //array of previous bar heights per frequency band um_data_t *um_data = getAudioData(); @@ -7477,7 +7479,7 @@ static const char _data_FX_MODE_2DGEQ[] PROGMEM = "GEQ@Fade speed,Ripple decay,# // ** 2D Funky plank // ///////////////////////// void mode_2DFunkyPlank(void) { // Written by ??? Adapted by Will Tatam. - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -7563,7 +7565,7 @@ static uint8_t akemi[] PROGMEM = { }; void mode_2DAkemi(void) { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -7630,7 +7632,7 @@ static const char _data_FX_MODE_2DAKEMI[] PROGMEM = "Akemi@Color speed,Dance;Hea // https://editor.soulmatelights.com/gallery/1089-distorsion-waves // adapted for WLED by @blazoncek, improvements by @dedehai void mode_2Ddistortionwaves() { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -7762,7 +7764,7 @@ static void soapPixels(bool isRow, uint8_t *noise3d, CRGB *pixels) { } void mode_2Dsoap() { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -7770,7 +7772,7 @@ void mode_2Dsoap() { const size_t segSize = SEGMENT.width() * SEGMENT.height(); // prevent reallocation if mirrored or grouped const size_t dataSize = segSize * (sizeof(uint8_t) + sizeof(CRGB)); // pixels and noise - if (!SEGENV.allocateData(dataSize + sizeof(uint32_t)*3)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize + sizeof(uint32_t)*3)) FX_FALLBACK_STATIC; //allocation failed uint8_t *noise3d = reinterpret_cast(SEGENV.data); CRGB *pixels = reinterpret_cast(SEGENV.data + segSize * sizeof(uint8_t)); @@ -7813,7 +7815,7 @@ static const char _data_FX_MODE_2DSOAP[] PROGMEM = "Soap@!,Smoothness,Density;;! //Stepko and Sutaburosu // adapted for WLED by @blazoncek void mode_2Doctopus() { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -7826,7 +7828,7 @@ void mode_2Doctopus() { } map_t; const size_t dataSize = SEGMENT.width() * SEGMENT.height() * sizeof(map_t); // prevent reallocation if mirrored or grouped - if (!SEGENV.allocateData(dataSize + 2)) mode_static(); //allocation failed + if (!SEGENV.allocateData(dataSize + 2)) FX_FALLBACK_STATIC; //allocation failed map_t *rMap = reinterpret_cast(SEGENV.data); uint8_t *offsX = reinterpret_cast(SEGENV.data + dataSize); @@ -7870,7 +7872,7 @@ static const char _data_FX_MODE_2DOCTOPUS[] PROGMEM = "Octopus@!,,Offset X,Offse //@Stepko (https://editor.soulmatelights.com/gallery/1704-wavingcells) // adapted for WLED by @blazoncek, improvements by @dedehai void mode_2Dwavingcell() { - if (!strip.isMatrix || !SEGMENT.is2D()) mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -7901,13 +7903,13 @@ static const char _data_FX_MODE_2DWAVINGCELL[] PROGMEM = "Waving Cell@!,Blur,Amp #define NUMBEROFSOURCES 8 void mode_particlevortex(void) { if (SEGLEN == 1) - mode_static(); + FX_FALLBACK_STATIC; ParticleSystem2D *PartSys = nullptr; uint32_t i, j; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, NUMBEROFSOURCES)) - mode_static(); // allocation failed + FX_FALLBACK_STATIC; // allocation failed #ifdef ESP8266 PartSys->setMotionBlur(180); #else @@ -7925,7 +7927,7 @@ void mode_particlevortex(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) uint32_t spraycount = min(PartSys->numSources, (uint32_t)(1 + (SEGMENT.custom1 >> 5))); // number of sprays to display, 1-8 @@ -8019,7 +8021,7 @@ void mode_particlefireworks(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, NUMBEROFSOURCES)) - mode_static(); // allocation failed + FX_FALLBACK_STATIC; // allocation failed PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) PartSys->setWallHardness(120); // ground bounce is fixed @@ -8033,7 +8035,7 @@ void mode_particlefireworks(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) numRockets = map(SEGMENT.speed, 0 , 255, 4, min(PartSys->numSources, (uint32_t)NUMBEROFSOURCES)); @@ -8165,7 +8167,7 @@ void mode_particlevolcano(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, NUMBEROFSOURCES)) // init, no additional data needed - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->setBounceY(true); PartSys->setGravity(); // enable with default gforce @@ -8186,7 +8188,7 @@ void mode_particlevolcano(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! numSprays = min(PartSys->numSources, (uint32_t)NUMBEROFSOURCES); // number of volcanoes @@ -8234,14 +8236,14 @@ void mode_particlefire(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, SEGMENT.vWidth(), 4)) //maximum number of source (PS may limit based on segment size); need 4 additional bytes for time keeping (uint32_t lastcall) - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D SEGENV.aux0 = hw_random16(); // aux0 is wind position (index) in the perlin noise } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setWrapX(SEGMENT.check2); @@ -8336,7 +8338,7 @@ void mode_particlepit(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 0, 0, true, false)) // init - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->setKillOutOfBounds(true); PartSys->setGravity(); // enable with default gravity PartSys->setUsedParticles(170); // use 75% of available particles @@ -8344,7 +8346,7 @@ void mode_particlepit(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -8407,7 +8409,7 @@ void mode_particlewaterfall(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 12)) // init, request 12 sources, no additional data needed - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->setGravity(); // enable with default gforce PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) @@ -8428,7 +8430,7 @@ void mode_particlewaterfall(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -8477,7 +8479,7 @@ void mode_particlebox(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1, 0, true)) // init - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->setBounceX(true); PartSys->setBounceY(true); SEGENV.aux0 = hw_random16(); // position in perlin noise @@ -8486,7 +8488,7 @@ void mode_particlebox(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setWallHardness(min(SEGMENT.custom2, (uint8_t)200)); // wall hardness is 200 or more @@ -8563,7 +8565,7 @@ void mode_particleperlin(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1, 0, true)) // init with 1 source and advanced properties - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->setKillOutOfBounds(true); // should never happen, but lets make sure there are no stray particles PartSys->setMotionBlur(230); // anable motion blur @@ -8574,7 +8576,7 @@ void mode_particleperlin(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setWrapX(SEGMENT.check1); @@ -8626,7 +8628,7 @@ void mode_particleimpact(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, NUMBEROFSOURCES)) // init, no additional data needed - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->setKillOutOfBounds(true); PartSys->setGravity(); // enable default gravity PartSys->setBounceY(true); // always use ground bounce @@ -8641,7 +8643,7 @@ void mode_particleimpact(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -8735,7 +8737,7 @@ void mode_particleattractor(void) { PSparticle *attractor; // particle pointer to the attractor if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1, sizeof(PSparticle), true)) // init using 1 source and advanced particle settings - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->sources[0].source.hue = hw_random16(); PartSys->sources[0].source.vx = -7; // will collied with wall and get random bounce direction PartSys->sources[0].sourceFlags.collide = true; // seeded particles will collide @@ -8756,7 +8758,7 @@ void mode_particleattractor(void) { } if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -8823,7 +8825,7 @@ void mode_particlespray(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1)) // init, no additional data needed - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) PartSys->setBounceY(true); PartSys->setMotionBlur(200); // anable motion blur @@ -8836,7 +8838,7 @@ void mode_particlespray(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -8895,14 +8897,14 @@ void mode_particleGEQ(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1)) - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->setKillOutOfBounds(true); PartSys->setUsedParticles(170); // use 2/3 of available particles } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! uint32_t i; // set particle system properties @@ -8971,7 +8973,7 @@ void mode_particlecenterGEQ(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, NUMBEROFSOURCES)) // init, request 16 sources - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D numSprays = min(PartSys->numSources, (uint32_t)NUMBEROFSOURCES); for (i = 0; i < numSprays; i++) { @@ -8987,7 +8989,7 @@ void mode_particlecenterGEQ(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) numSprays = min(PartSys->numSources, (uint32_t)NUMBEROFSOURCES); @@ -9039,7 +9041,7 @@ void mode_particleghostrider(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1)) // init, no additional data needed - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) PartSys->sources[0].maxLife = 260; // lifetime in frames PartSys->sources[0].minLife = 250; @@ -9052,7 +9054,7 @@ void mode_particleghostrider(void) { } if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! if (SEGMENT.intensity > 0) { // spiraling if (SEGENV.aux1) { @@ -9117,7 +9119,7 @@ void mode_particleblobs(void) { if (SEGMENT.call == 0) { if (!initParticleSystem2D(PartSys, 0, 0, true, true)) //init, no additional bytes, advanced size & size control - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->setBounceX(true); PartSys->setBounceY(true); PartSys->setWallHardness(255); @@ -9129,7 +9131,7 @@ void mode_particleblobs(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setUsedParticles(map(SEGMENT.intensity, 0, 255, 25, 128)); // minimum 10%, maximum 50% of available particles (note: PS ensures at least 1) @@ -9191,7 +9193,7 @@ void mode_particlegalaxy(void) { sourcesettings.asByte = 0b00001100; // PS settings for bounceY, bounceY used for source movement (it always bounces whereas particles do not) if (SEGMENT.call == 0) { // initialization if (!initParticleSystem2D(PartSys, 1, 0, true)) // init using 1 source and advanced particle settings - mode_static(); // allocation failed or not 2D + FX_FALLBACK_STATIC; // allocation failed or not 2D PartSys->sources[0].source.vx = -4; // will collide with wall and get random bounce direction PartSys->sources[0].source.x = PartSys->maxX >> 1; // start in the center PartSys->sources[0].source.y = PartSys->maxY >> 1; @@ -9206,7 +9208,7 @@ void mode_particlegalaxy(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS } if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) uint8_t particlesize = SEGMENT.custom1; @@ -9296,7 +9298,7 @@ void mode_particleDrip(void) { //uint8_t numSprays; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 4)) // init - mode_static(); // allocation failed or single pixel + FX_FALLBACK_STATIC; // allocation failed or single pixel PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) PartSys->sources[0].source.hue = hw_random16(); SEGENV.aux1 = 0xFFFF; // invalidate @@ -9305,7 +9307,7 @@ void mode_particleDrip(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -9400,7 +9402,7 @@ void mode_particlePinball(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 128, 0, true)) // init - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel PartSys->sources[0].sourceFlags.collide = true; // seeded particles will collide (if enabled) PartSys->sources[0].source.x = -1000; // shoot up from below //PartSys->setKillOutOfBounds(true); // out of bounds particles dont return (except on top, taken care of by gravity setting) @@ -9411,7 +9413,7 @@ void mode_particlePinball(void) { PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings //uint32_t hardness = 240 + (SEGMENT.custom1>>4); @@ -9518,7 +9520,7 @@ void mode_particleDancingShadows(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1)) // init, one source - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel PartSys->sources[0].maxLife = 1000; //set long life (kill out of bounds is done in custom way) PartSys->sources[0].minLife = PartSys->sources[0].maxLife; } @@ -9527,7 +9529,7 @@ void mode_particleDancingShadows(void) { } if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -9633,14 +9635,14 @@ void mode_particleFireworks1D(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 4, 150, 4, true)) // init advanced particle system - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); PartSys->sources[0].sourceFlags.custom1 = 1; // set rocket state to standby } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -9754,11 +9756,11 @@ void mode_particleSparkler(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 16, 128 ,0, true)) // init, no additional data needed - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -9823,14 +9825,14 @@ void mode_particleHourglass(void) { uint32_t* settingTracker; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 0, 255, 8, false)) // init - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel PartSys->setBounce(true); PartSys->setWallHardness(100); } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -9944,7 +9946,7 @@ void mode_particle1Dspray(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1)) - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); PartSys->setWallHardness(150); PartSys->setParticleSize(1); @@ -9952,7 +9954,7 @@ void mode_particle1Dspray(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -9995,13 +9997,13 @@ void mode_particleBalance(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 128)) // init, no additional data needed, use half of max particles - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel PartSys->setParticleSize(1); } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10073,7 +10075,7 @@ void mode_particleChase(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 191, 2, true)) // init - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel SEGENV.aux0 = 0xFFFF; // invalidate *PartSys->PSdataEnd = 1; // huedir *(PartSys->PSdataEnd + 1) = 1; // sizedir @@ -10081,7 +10083,7 @@ void mode_particleChase(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setColorByPosition(SEGMENT.check3); @@ -10170,7 +10172,7 @@ void mode_particleStarburst(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 200, 0, true)) // init - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); PartSys->enableParticleCollisions(true, 200); PartSys->sources[0].source.ttl = 1; // set initial stanby time @@ -10179,7 +10181,7 @@ void mode_particleStarburst(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10231,12 +10233,12 @@ void mode_particle1DGEQ(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 16, 255, 0, true)) // init, no additional data needed - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10301,14 +10303,14 @@ void mode_particleFire1D(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 5)) // init - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); PartSys->setParticleSize(1); } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10364,7 +10366,7 @@ void mode_particle1DsonicStream(void) { if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 255, 0, true)) // init, no additional data needed - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); PartSys->sources[0].source.x = 0; // at start //PartSys->sources[1].source.x = PartSys->maxX; // at end @@ -10373,7 +10375,7 @@ void mode_particle1DsonicStream(void) { else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10465,13 +10467,13 @@ void mode_particle1DsonicBoom(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 255, 0, true)) // init, no additional data needed - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel PartSys->setKillOutOfBounds(true); } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) @@ -10554,13 +10556,13 @@ void mode_particleSpringy(void) { ParticleSystem1D *PartSys = nullptr; if (SEGMENT.call == 0) { // initialization if (!initParticleSystem1D(PartSys, 1, 128, 0, true)) // init with advanced properties (used for spring forces) - mode_static(); // allocation failed or is single pixel + FX_FALLBACK_STATIC; // allocation failed or is single pixel SEGENV.aux0 = SEGENV.aux1 = 0xFFFF; // invalidate settings } else PartSys = reinterpret_cast(SEGENV.data); // if not first call, just set the pointer to the PS if (PartSys == nullptr) - mode_static(); // something went wrong, no data! + FX_FALLBACK_STATIC; // something went wrong, no data! // Particle System settings PartSys->updateSystem(); // update system properties (dimensions and data pointers) PartSys->setMotionBlur(220 * SEGMENT.check1); // anable motion blur diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 41534e8042..925b9ad8b1 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1303,8 +1303,8 @@ void WS2812FX::service() { segO->beginDraw(prog); // set up palette & colors (also sets draw dimensions), parent segment has transition progress _currentSegment = segO; // set current segment // workaround for on/off transition to respect blending style - _mode[segO->mode](); // run old mode (needed for bri workaround; semaphore!!) - segO->call++; // increment old mode run counter + _mode[segO->mode](); // run old mode (needed for bri workaround; semaphore!!) + segO->call++; // increment old mode run counter Segment::modeBlend(false); // unset semaphore } } diff --git a/wled00/FXparticleSystem.cpp b/wled00/FXparticleSystem.cpp index ad72187bd4..fd6ce4c4ed 100644 --- a/wled00/FXparticleSystem.cpp +++ b/wled00/FXparticleSystem.cpp @@ -1095,7 +1095,11 @@ bool allocateParticleSystemMemory2D(uint32_t numparticles, uint32_t numsources, // initialize Particle System, allocate additional bytes if needed (pointer to those bytes can be read from particle system class: PSdataEnd) bool initParticleSystem2D(ParticleSystem2D *&PartSys, uint32_t requestedsources, uint32_t additionalbytes, bool advanced, bool sizecontrol) { PSPRINT("PS 2D init "); - if (!strip.isMatrix) return false; // only for 2D + if (!strip.isMatrix) { + errorFlag = ERR_NOT_IMPL; // TODO: need a better error code if more codes are added + SEGMENT.deallocateData(); // deallocate any data to make sure data is null (there is no valid PS in data and data can only be checked for null) + return false; // only for 2D + } uint32_t cols = SEGMENT.virtualWidth(); uint32_t rows = SEGMENT.virtualHeight(); uint32_t pixels = cols * rows; @@ -1843,7 +1847,11 @@ bool allocateParticleSystemMemory1D(const uint32_t numparticles, const uint32_t // initialize Particle System, allocate additional bytes if needed (pointer to those bytes can be read from particle system class: PSdataEnd) // note: percentofparticles is in uint8_t, for example 191 means 75%, (deafaults to 255 or 100% meaning one particle per pixel), can be more than 100% (but not recommended, can cause out of memory) bool initParticleSystem1D(ParticleSystem1D *&PartSys, const uint32_t requestedsources, const uint8_t fractionofparticles, const uint32_t additionalbytes, const bool advanced) { - if (SEGLEN == 1) return false; // single pixel not supported + if (SEGLEN == 1) { + errorFlag = ERR_NOT_IMPL; // TODO: need a better error code if more codes are added + SEGMENT.deallocateData(); // deallocate any data to make sure data is null (there is no valid PS in data and data can only be checked for null) + return false; // single pixel not supported + } uint32_t numparticles = calculateNumberOfParticles1D(fractionofparticles, advanced); uint32_t numsources = calculateNumberOfSources1D(requestedsources); bool allocsuccess = false; diff --git a/wled00/FXparticleSystem.h b/wled00/FXparticleSystem.h index 92c32673f5..b272a159f6 100644 --- a/wled00/FXparticleSystem.h +++ b/wled00/FXparticleSystem.h @@ -20,7 +20,7 @@ #define PS_P_MAXSPEED 120 // maximum speed a particle can have (vx/vy is int8), limiting below 127 to avoid overflows in collisions due to rounding errors #define MAX_MEMIDLE 10 // max idle time (in frames) before memory is deallocated (if deallocated during an effect, it will crash!) -//#define WLED_DEBUG_PS // note: enabling debug uses ~3k of flash +#define WLED_DEBUG_PS // note: enabling debug uses ~3k of flash #ifdef WLED_DEBUG_PS #define PSPRINT(x) Serial.print(x) From 564652e738784afcfbd93b5d84d176b3c13c7472 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 24 Jan 2026 16:33:45 +0100 Subject: [PATCH 3/7] add FX_FALLBACK_STATIC also to user_fx --- usermods/user_fx/README.md | 10 ++++++---- usermods/user_fx/user_fx.cpp | 6 ++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/usermods/user_fx/README.md b/usermods/user_fx/README.md index 3d592fd071..704226a7d2 100644 --- a/usermods/user_fx/README.md +++ b/usermods/user_fx/README.md @@ -76,12 +76,14 @@ The first line of the code imports the [wled.h](https://github.com/wled/WLED/blo ### Static Effect Definition The next code block is the `mode_static` definition. This is usually left as `SEGMENT.fill(SEGCOLOR(0));` to leave all pixels off if the effect fails to load, but in theory one could use this as a 'fallback effect' to take on a different behavior, such as displaying some other color instead of leaving the pixels off. +`FX_FALLBACK_STATIC` is a macro that calls `mode_static()` and then returns. + ### User Effect Definitions Pre-loaded in this template is an example 2D Effect called "Diffusion Fire". (This is the name that would be shown in the UI once the binary is compiled and run on your device, as defined in the metadata string.) -The effect starts off by checking to see if the segment that the effect is being applied to is a 2D Matrix, and if it is not, then it returns the static effect which displays no pattern: +The effect starts off by checking to see if the segment that the effect is being applied to is a 2D Matrix, and if it is not, then it runs the static effect which displays no pattern: ```cpp if (!strip.isMatrix || !SEGMENT.is2D()) - mode_static(); // not a 2D set-up + FX_FALLBACK_STATIC; // not a 2D set-up ``` The next code block contains several constant variable definitions which essentially serve to extract the dimensions of the user's 2D matrix and allow WLED to interpret the matrix as a 1D coordinate system (WLED must do this for all 2D animations): ```cpp @@ -128,7 +130,7 @@ unsigned dataSize = cols * rows; // SEGLEN (virtual length) is equivalent to vW ```cpp if (!SEGENV.allocateData(dataSize)) - mode_static(); // allocation failed + FX_FALLBACK_STATIC; // allocation failed ``` * Upon the first call, this section allocates a persistent data buffer tied to the segment environment (`SEGENV.data`). All subsequent calls simply ensure that the data is still valid. * The syntax `SEGENV.allocateData(n)` requests a buffer of size n bytes (1 byte per pixel here). @@ -303,7 +305,7 @@ static uint16_t sinelon_base(bool dual, bool rainbow=false) { * Notice that it has some optional flags; these parameters will allow us to easily define the effect in different ways in the UI. ```cpp - if (SEGLEN <= 1) return mode_static(); + if (SEGLEN <= 1) FX_FALLBACK_STATIC; ``` * If segment length ≤ 1, there’s nothing to animate. Just show static mode. diff --git a/usermods/user_fx/user_fx.cpp b/usermods/user_fx/user_fx.cpp index fddeb174f8..e94d2a6e8b 100644 --- a/usermods/user_fx/user_fx.cpp +++ b/usermods/user_fx/user_fx.cpp @@ -7,6 +7,8 @@ static void mode_static(void) { SEGMENT.fill(SEGCOLOR(0)); } +#define FX_FALLBACK_STATIC { mode_static(); return; } + ///////////////////////// // User FX functions // ///////////////////////// @@ -14,7 +16,7 @@ static void mode_static(void) { // Diffusion Fire: fire effect intended for 2D setups smaller than 16x16 static void mode_diffusionfire(void) { if (!strip.isMatrix || !SEGMENT.is2D()) - return mode_static(); // not a 2D set-up + FX_FALLBACK_STATIC; // not a 2D set-up const int cols = SEG_W; const int rows = SEG_H; @@ -28,7 +30,7 @@ static void mode_diffusionfire(void) { unsigned dataSize = cols * rows; // SEGLEN (virtual length) is equivalent to vWidth()*vHeight() for 2D if (!SEGENV.allocateData(dataSize)) - return mode_static(); // allocation failed + FX_FALLBACK_STATIC; // allocation failed if (SEGENV.call == 0) { SEGMENT.fill(BLACK); From 058f86292570f0c49719818b38b2da506d898280 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 24 Jan 2026 16:35:43 +0100 Subject: [PATCH 4/7] revert debug --- wled00/FXparticleSystem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/FXparticleSystem.h b/wled00/FXparticleSystem.h index b272a159f6..92c32673f5 100644 --- a/wled00/FXparticleSystem.h +++ b/wled00/FXparticleSystem.h @@ -20,7 +20,7 @@ #define PS_P_MAXSPEED 120 // maximum speed a particle can have (vx/vy is int8), limiting below 127 to avoid overflows in collisions due to rounding errors #define MAX_MEMIDLE 10 // max idle time (in frames) before memory is deallocated (if deallocated during an effect, it will crash!) -#define WLED_DEBUG_PS // note: enabling debug uses ~3k of flash +//#define WLED_DEBUG_PS // note: enabling debug uses ~3k of flash #ifdef WLED_DEBUG_PS #define PSPRINT(x) Serial.print(x) From 59b8f37926a688a1211c65e092fafe47cc11ddf4 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 24 Jan 2026 16:40:31 +0100 Subject: [PATCH 5/7] fixup readme --- usermods/user_fx/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/usermods/user_fx/README.md b/usermods/user_fx/README.md index 704226a7d2..894c450360 100644 --- a/usermods/user_fx/README.md +++ b/usermods/user_fx/README.md @@ -299,7 +299,7 @@ We will break this effect down step by step. (This effect was originally one of the FastLED example effects; more information on FastLED can be found [here](https://fastled.io/).) ```cpp -static uint16_t sinelon_base(bool dual, bool rainbow=false) { +static sinelon_base(bool dual, bool rainbow=false) { ``` * The first line of code defines `sinelon base` as static helper function. This is how all effects are initially defined. * Notice that it has some optional flags; these parameters will allow us to easily define the effect in different ways in the UI. @@ -395,18 +395,18 @@ Finally, we return the `FRAMETIME`, as with all effect functions: The last part of this effect has the Wrapper functions for different Sinelon modes. Notice that there are three different modes that we can define from the single effect definition by leveraging the arguments in the function: ```cpp -uint16_t mode_sinelon(void) { - return sinelon_base(false); +mode_sinelon(void) { + sinelon_base(false); } // Calls sinelon_base with dual = false and rainbow = false -uint16_t mode_sinelon_dual(void) { - return sinelon_base(true); +mode_sinelon_dual(void) { + sinelon_base(true); } // Calls sinelon_base with dual = true and rainbow = false -uint16_t mode_sinelon_rainbow(void) { - return sinelon_base(false, true); +mode_sinelon_rainbow(void) { + sinelon_base(false, true); } // Calls sinelon_base with dual = false and rainbow = true ``` From e35720eee8b5a06f64e5477877cbc99f04e53c0d Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 24 Jan 2026 16:41:50 +0100 Subject: [PATCH 6/7] remove old comment --- wled00/FXparticleSystem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/FXparticleSystem.h b/wled00/FXparticleSystem.h index 92c32673f5..afe683c0b1 100644 --- a/wled00/FXparticleSystem.h +++ b/wled00/FXparticleSystem.h @@ -143,7 +143,7 @@ class ParticleSystem2D { ParticleSystem2D(const uint32_t width, const uint32_t height, const uint32_t numberofparticles, const uint32_t numberofsources, const bool isadvanced = false, const bool sizecontrol = false); // constructor // note: memory is allcated in the FX function, no deconstructor needed void update(void); //update the particles according to set options and render to the matrix - void updateFire(const uint8_t intensity); // update function for fire, if renderonly is set, particles are not updated (required to fix transitions with frameskips) + void updateFire(const uint8_t intensity); // update function for fire void updateSystem(void); // call at the beginning of every FX, updates pointers and dimensions void particleMoveUpdate(PSparticle &part, PSparticleFlags &partFlags, PSsettings2D *options = NULL, PSadvancedParticle *advancedproperties = NULL); // move function // particle emitters From 65627bc69873b5b872c8a1363ccfdf89ee356e7a Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Sat, 24 Jan 2026 16:50:29 +0100 Subject: [PATCH 7/7] remove return values also from animartrix --- .../usermod_v2_animartrix.cpp | 156 ++++++------------ 1 file changed, 52 insertions(+), 104 deletions(-) diff --git a/usermods/usermod_v2_animartrix/usermod_v2_animartrix.cpp b/usermods/usermod_v2_animartrix/usermod_v2_animartrix.cpp index d2968f2fbd..a90828d233 100644 --- a/usermods/usermod_v2_animartrix/usermod_v2_animartrix.cpp +++ b/usermods/usermod_v2_animartrix/usermod_v2_animartrix.cpp @@ -85,266 +85,214 @@ class ANIMartRIXMod:public ANIMartRIX { }; ANIMartRIXMod anim; -uint16_t mode_Module_Experiment10() { +void mode_Module_Experiment10() { anim.initEffect(); anim.Module_Experiment10(); - return FRAMETIME; } -uint16_t mode_Module_Experiment9() { +void mode_Module_Experiment9() { anim.initEffect(); anim.Module_Experiment9(); - return FRAMETIME; } -uint16_t mode_Module_Experiment8() { +void mode_Module_Experiment8() { anim.initEffect(); anim.Module_Experiment8(); - return FRAMETIME; } -uint16_t mode_Module_Experiment7() { +void mode_Module_Experiment7() { anim.initEffect(); anim.Module_Experiment7(); - return FRAMETIME; } -uint16_t mode_Module_Experiment6() { +void mode_Module_Experiment6() { anim.initEffect(); anim.Module_Experiment6(); - return FRAMETIME; } -uint16_t mode_Module_Experiment5() { +void mode_Module_Experiment5() { anim.initEffect(); anim.Module_Experiment5(); - return FRAMETIME; } -uint16_t mode_Module_Experiment4() { +void mode_Module_Experiment4() { anim.initEffect(); anim.Module_Experiment4(); - return FRAMETIME; } -uint16_t mode_Zoom2() { +void mode_Zoom2() { anim.initEffect(); anim.Zoom2(); - return FRAMETIME; } -uint16_t mode_Module_Experiment3() { +void mode_Module_Experiment3() { anim.initEffect(); anim.Module_Experiment3(); - return FRAMETIME; } -uint16_t mode_Module_Experiment2() { +void mode_Module_Experiment2() { anim.initEffect(); anim.Module_Experiment2(); - return FRAMETIME; } -uint16_t mode_Module_Experiment1() { +void mode_Module_Experiment1() { anim.initEffect(); anim.Module_Experiment1(); - return FRAMETIME; } -uint16_t mode_Parametric_Water() { +void mode_Parametric_Water() { anim.initEffect(); anim.Parametric_Water(); - return FRAMETIME; } -uint16_t mode_Water() { +void mode_Water() { anim.initEffect(); anim.Water(); - return FRAMETIME; } -uint16_t mode_Complex_Kaleido_6() { +void mode_Complex_Kaleido_6() { anim.initEffect(); anim.Complex_Kaleido_6(); - return FRAMETIME; } -uint16_t mode_Complex_Kaleido_5() { +void mode_Complex_Kaleido_5() { anim.initEffect(); anim.Complex_Kaleido_5(); - return FRAMETIME; } -uint16_t mode_Complex_Kaleido_4() { +void mode_Complex_Kaleido_4() { anim.initEffect(); anim.Complex_Kaleido_4(); - return FRAMETIME; } -uint16_t mode_Complex_Kaleido_3() { +void mode_Complex_Kaleido_3() { anim.initEffect(); anim.Complex_Kaleido_3(); - return FRAMETIME; } -uint16_t mode_Complex_Kaleido_2() { +void mode_Complex_Kaleido_2() { anim.initEffect(); anim.Complex_Kaleido_2(); - return FRAMETIME; } -uint16_t mode_Complex_Kaleido() { +void mode_Complex_Kaleido() { anim.initEffect(); anim.Complex_Kaleido(); - return FRAMETIME; } -uint16_t mode_SM10() { +void mode_SM10() { anim.initEffect(); anim.SM10(); - return FRAMETIME; } -uint16_t mode_SM9() { +void mode_SM9() { anim.initEffect(); anim.SM9(); - return FRAMETIME; } -uint16_t mode_SM8() { +void mode_SM8() { anim.initEffect(); anim.SM8(); - return FRAMETIME; } -// uint16_t mode_SM7() { +// void mode_SM7() { // anim.initEffect(); // anim.SM7(); // -// return FRAMETIME; // } -uint16_t mode_SM6() { +void mode_SM6() { anim.initEffect(); anim.SM6(); - return FRAMETIME; } -uint16_t mode_SM5() { +void mode_SM5() { anim.initEffect(); anim.SM5(); - return FRAMETIME; } -uint16_t mode_SM4() { +void mode_SM4() { anim.initEffect(); anim.SM4(); - return FRAMETIME; } -uint16_t mode_SM3() { +void mode_SM3() { anim.initEffect(); anim.SM3(); - return FRAMETIME; } -uint16_t mode_SM2() { +void mode_SM2() { anim.initEffect(); anim.SM2(); - return FRAMETIME; } -uint16_t mode_SM1() { +void mode_SM1() { anim.initEffect(); anim.SM1(); - return FRAMETIME; } -uint16_t mode_Big_Caleido() { +void mode_Big_Caleido() { anim.initEffect(); anim.Big_Caleido(); - return FRAMETIME; } -uint16_t mode_RGB_Blobs5() { +void mode_RGB_Blobs5() { anim.initEffect(); anim.RGB_Blobs5(); - return FRAMETIME; } -uint16_t mode_RGB_Blobs4() { +void mode_RGB_Blobs4() { anim.initEffect(); anim.RGB_Blobs4(); - return FRAMETIME; } -uint16_t mode_RGB_Blobs3() { +void mode_RGB_Blobs3() { anim.initEffect(); anim.RGB_Blobs3(); - return FRAMETIME; } -uint16_t mode_RGB_Blobs2() { +void mode_RGB_Blobs2() { anim.initEffect(); anim.RGB_Blobs2(); - return FRAMETIME; } -uint16_t mode_RGB_Blobs() { +void mode_RGB_Blobs() { anim.initEffect(); anim.RGB_Blobs(); - return FRAMETIME; } -uint16_t mode_Polar_Waves() { +void mode_Polar_Waves() { anim.initEffect(); anim.Polar_Waves(); - return FRAMETIME; } -uint16_t mode_Slow_Fade() { +void mode_Slow_Fade() { anim.initEffect(); anim.Slow_Fade(); - return FRAMETIME; } -uint16_t mode_Zoom() { +void mode_Zoom() { anim.initEffect(); anim.Zoom(); - return FRAMETIME; } -uint16_t mode_Hot_Blob() { +void mode_Hot_Blob() { anim.initEffect(); anim.Hot_Blob(); - return FRAMETIME; } -uint16_t mode_Spiralus2() { +void mode_Spiralus2() { anim.initEffect(); anim.Spiralus2(); - return FRAMETIME; } -uint16_t mode_Spiralus() { +void mode_Spiralus() { anim.initEffect(); anim.Spiralus(); - return FRAMETIME; } -uint16_t mode_Yves() { +void mode_Yves() { anim.initEffect(); anim.Yves(); - return FRAMETIME; } -uint16_t mode_Scaledemo1() { +void mode_Scaledemo1() { anim.initEffect(); anim.Scaledemo1(); - return FRAMETIME; } -uint16_t mode_Lava1() { +void mode_Lava1() { anim.initEffect(); anim.Lava1(); - return FRAMETIME; } -uint16_t mode_Caleido3() { +void mode_Caleido3() { anim.initEffect(); anim.Caleido3(); - return FRAMETIME; } -uint16_t mode_Caleido2() { +void mode_Caleido2() { anim.initEffect(); anim.Caleido2(); - return FRAMETIME; } -uint16_t mode_Caleido1() { +void mode_Caleido1() { anim.initEffect(); anim.Caleido1(); - return FRAMETIME; } -uint16_t mode_Distance_Experiment() { +void mode_Distance_Experiment() { anim.initEffect(); anim.Distance_Experiment(); - return FRAMETIME; } -uint16_t mode_Center_Field() { +void mode_Center_Field() { anim.initEffect(); anim.Center_Field(); - return FRAMETIME; } -uint16_t mode_Waves() { +void mode_Waves() { anim.initEffect(); anim.Waves(); - return FRAMETIME; } -uint16_t mode_Chasing_Spirals() { +void mode_Chasing_Spirals() { anim.initEffect(); anim.Chasing_Spirals(); - return FRAMETIME; } -uint16_t mode_Rotating_Blob() { +void mode_Rotating_Blob() { anim.initEffect(); anim.Rotating_Blob(); - return FRAMETIME; }