From a9c211d66caed0a34e0b9e6fbb6d3f5216025661 Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Sun, 7 Feb 2021 14:45:34 +0100 Subject: [PATCH 1/2] Tetris (falling bricks) effect & Colortwinkles low brightness fix. --- wled00/FX.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++- wled00/FX.h | 9 ++++++--- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 27bd730d9..e7723182c 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -1991,7 +1991,7 @@ uint16_t WS2812FX::mode_colortwinkle() if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB fastled_col, prev; - fract8 fadeUpAmount = 8 + (SEGMENT.speed/4), fadeDownAmount = 5 + (SEGMENT.speed/7); + fract8 fadeUpAmount = _brightness>28 ? 8 + (SEGMENT.speed>>2) : 68-_brightness, fadeDownAmount = _brightness>28 ? 8 + (SEGMENT.speed>>3) : 68-_brightness; for (uint16_t i = 0; i < SEGLEN; i++) { fastled_col = col_to_crgb(getPixelColor(i)); prev = fastled_col; @@ -3144,6 +3144,59 @@ uint16_t WS2812FX::mode_drip(void) } +/* + * Tetris or Stacking (falling bricks) Effect + * by Blaz Kristan (https://github.com/blazoncek, https://blaz.at/home) + */ +typedef struct Tetris { + float pos; + float speed; + uint32_t col; +} tetris; + +uint16_t WS2812FX::mode_tetris(void) { + + uint16_t dataSize = sizeof(tetris); + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + Tetris* drop = reinterpret_cast(SEGENV.data); + + // initialize dropping on first call or segment full + if (SEGENV.call == 0 || SEGENV.aux1 >= SEGLEN) { + SEGENV.aux1 = 0; // reset brick stack size + SEGENV.step = 0; + fill(SEGCOLOR(1)); + return 250; // short wait + } + + if (SEGENV.step == 0) { //init + drop->speed = 0.0238 * (SEGMENT.speed ? (SEGMENT.speed>>4)+1 : random8(3,20)); // set speed + drop->pos = SEGLEN-1; // start at end of segment + drop->col = color_from_palette(random8(0,15)<<4,false,false,0); // limit color choices so there is enough HUE gap + SEGENV.step = 1; // drop state (0 init, 1 forming, 2 falling) + SEGENV.aux0 = (SEGMENT.intensity ? (SEGMENT.intensity>>5)+1 : random8(1,5)) * (1+(SEGLEN>>6)); // size of brick + } + + if (SEGENV.step == 1) { // forming + if (random8()>>6) { // random drop + SEGENV.step = 2; // fall + } + } + + if (SEGENV.step > 1) { // falling + if (drop->pos > SEGENV.aux1) { // fall until top of stack + drop->pos -= drop->speed; // may add gravity as: speed += gravity + if (int(drop->pos) < SEGENV.aux1) drop->pos = SEGENV.aux1; + for (uint16_t i=int(drop->pos); ipos)+SEGENV.aux0 ? drop->col : SEGCOLOR(1)); + } else { // we hit bottom + SEGENV.step = 0; // go back to init + SEGENV.aux1 += SEGENV.aux0; // increase the stack size + if (SEGENV.aux1 >= SEGLEN) return 1000; // wait for a second + } + } + return FRAMETIME; +} + + /* / Plasma Effect / adapted from https://github.com/atuline/FastLED-Demos/blob/master/plasma/plasma.ino diff --git a/wled00/FX.h b/wled00/FX.h index 27329a0af..0ee30e317 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -118,7 +118,7 @@ #define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE ) #define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED ) -#define MODE_COUNT 118 +#define MODE_COUNT 119 #define FX_MODE_STATIC 0 #define FX_MODE_BLINK 1 @@ -238,6 +238,7 @@ #define FX_MODE_BLENDS 115 #define FX_MODE_TV_SIMULATOR 116 #define FX_MODE_DYNAMIC_SMOOTH 117 +#define FX_MODE_TETRIS 118 class WS2812FX { @@ -577,6 +578,7 @@ class WS2812FX { _mode[FX_MODE_BLENDS] = &WS2812FX::mode_blends; _mode[FX_MODE_TV_SIMULATOR] = &WS2812FX::mode_tv_simulator; _mode[FX_MODE_DYNAMIC_SMOOTH] = &WS2812FX::mode_dynamic_smooth; + _mode[FX_MODE_TETRIS] = &WS2812FX::mode_tetris; _brightness = DEFAULT_BRIGHTNESS; currentPalette = CRGBPalette16(CRGB::Black); @@ -791,7 +793,8 @@ class WS2812FX { mode_candy_cane(void), mode_blends(void), mode_tv_simulator(void), - mode_dynamic_smooth(void); + mode_dynamic_smooth(void), + mode_tetris(void); private: NeoPixelWrapper *bus; @@ -891,7 +894,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([ "Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst", "Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow", "Heartbeat","Pacifica","Candle Multi", "Solid Glitter","Sunrise","Phased","Twinkleup","Noise Pal", "Sine","Phased Noise", -"Flow","Chunchun","Dancing Shadows","Washing Machine","Candy Cane","Blends","TV Simulator","Dynamic Smooth" +"Flow","Chunchun","Dancing Shadows","Washing Machine","Candy Cane","Blends","TV Simulator","Dynamic Smooth","Tetris" ])====="; From 7092f337ef8d074e38b6bdeb7e87850395ff4461 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Wed, 10 Feb 2021 00:37:05 +0100 Subject: [PATCH 2/2] Faster Tetrix mode - Replaced a letter in name (copyright) - 2x speed - Replaced Merry christmas mode --- wled00/FX.cpp | 12 ++---------- wled00/FX.h | 17 +++++++---------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index e7723182c..786ea6925 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -1001,14 +1001,6 @@ uint16_t WS2812FX::mode_running_color(void) { return running(SEGCOLOR(0), SEGCOLOR(1)); } - -/* - * Alternating red/green pixels running. - */ -uint16_t WS2812FX::mode_merry_christmas(void) { - return running(RED, GREEN); -} - /* * Alternating red/white pixels running. */ @@ -3154,7 +3146,7 @@ typedef struct Tetris { uint32_t col; } tetris; -uint16_t WS2812FX::mode_tetris(void) { +uint16_t WS2812FX::mode_tetrix(void) { uint16_t dataSize = sizeof(tetris); if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -3169,7 +3161,7 @@ uint16_t WS2812FX::mode_tetris(void) { } if (SEGENV.step == 0) { //init - drop->speed = 0.0238 * (SEGMENT.speed ? (SEGMENT.speed>>4)+1 : random8(3,20)); // set speed + drop->speed = 0.0238 * (SEGMENT.speed ? (SEGMENT.speed>>3)+1 : random8(6,40)); // set speed drop->pos = SEGLEN-1; // start at end of segment drop->col = color_from_palette(random8(0,15)<<4,false,false,0); // limit color choices so there is enough HUE gap SEGENV.step = 1; // drop state (0 init, 1 forming, 2 falling) diff --git a/wled00/FX.h b/wled00/FX.h index 0ee30e317..44c57d074 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -118,7 +118,7 @@ #define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE ) #define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED ) -#define MODE_COUNT 119 +#define MODE_COUNT 118 #define FX_MODE_STATIC 0 #define FX_MODE_BLINK 1 @@ -164,7 +164,7 @@ #define FX_MODE_COMET 41 #define FX_MODE_FIREWORKS 42 #define FX_MODE_RAIN 43 -#define FX_MODE_MERRY_CHRISTMAS 44 +#define FX_MODE_TETRIX 44 #define FX_MODE_FIRE_FLICKER 45 #define FX_MODE_GRADIENT 46 #define FX_MODE_LOADING 47 @@ -238,7 +238,6 @@ #define FX_MODE_BLENDS 115 #define FX_MODE_TV_SIMULATOR 116 #define FX_MODE_DYNAMIC_SMOOTH 117 -#define FX_MODE_TETRIS 118 class WS2812FX { @@ -502,7 +501,7 @@ class WS2812FX { _mode[FX_MODE_COMET] = &WS2812FX::mode_comet; _mode[FX_MODE_FIREWORKS] = &WS2812FX::mode_fireworks; _mode[FX_MODE_RAIN] = &WS2812FX::mode_rain; - _mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas; + _mode[FX_MODE_TETRIX] = &WS2812FX::mode_tetrix; _mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker; _mode[FX_MODE_GRADIENT] = &WS2812FX::mode_gradient; _mode[FX_MODE_LOADING] = &WS2812FX::mode_loading; @@ -578,7 +577,6 @@ class WS2812FX { _mode[FX_MODE_BLENDS] = &WS2812FX::mode_blends; _mode[FX_MODE_TV_SIMULATOR] = &WS2812FX::mode_tv_simulator; _mode[FX_MODE_DYNAMIC_SMOOTH] = &WS2812FX::mode_dynamic_smooth; - _mode[FX_MODE_TETRIS] = &WS2812FX::mode_tetris; _brightness = DEFAULT_BRIGHTNESS; currentPalette = CRGBPalette16(CRGB::Black); @@ -719,7 +717,7 @@ class WS2812FX { mode_comet(void), mode_fireworks(void), mode_rain(void), - mode_merry_christmas(void), + mode_tetrix(void), mode_halloween(void), mode_fire_flicker(void), mode_gradient(void), @@ -793,8 +791,7 @@ class WS2812FX { mode_candy_cane(void), mode_blends(void), mode_tv_simulator(void), - mode_dynamic_smooth(void), - mode_tetris(void); + mode_dynamic_smooth(void); private: NeoPixelWrapper *bus; @@ -887,14 +884,14 @@ const char JSON_mode_names[] PROGMEM = R"=====([ "Scan","Scan Dual","Fade","Theater","Theater Rainbow","Running","Saw","Twinkle","Dissolve","Dissolve Rnd", "Sparkle","Sparkle Dark","Sparkle+","Strobe","Strobe Rainbow","Strobe Mega","Blink Rainbow","Android","Chase","Chase Random", "Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Aurora","Stream", -"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","Police","Police All", +"Scanner","Lighthouse","Fireworks","Rain","Tetrix","Fire Flicker","Gradient","Loading","Police","Police All", "Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet", "Scanner Dual","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise", "Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Meteor Smooth","Railway","Ripple", "Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst", "Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow", "Heartbeat","Pacifica","Candle Multi", "Solid Glitter","Sunrise","Phased","Twinkleup","Noise Pal", "Sine","Phased Noise", -"Flow","Chunchun","Dancing Shadows","Washing Machine","Candy Cane","Blends","TV Simulator","Dynamic Smooth","Tetris" +"Flow","Chunchun","Dancing Shadows","Washing Machine","Candy Cane","Blends","TV Simulator","Dynamic Smooth" ])=====";