diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 9389c1ae..f36d22e2 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5410,4 +5410,75 @@ uint16_t WS2812FX::mode_2DAkemi(void) { } */ return FRAMETIME; -} // mode_2DAkemi \ No newline at end of file +} // mode_2DAkemi + +///////////////////////// +// 2D spaceships // +///////////////////////// +uint16_t WS2812FX::mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [https://editor.soulmatelights.com/gallery/639-space-ships], adapted by Blaz Kristan + if (!isMatrix) return mode_static(); // not a 2D set-up + + uint16_t width = SEGMENT.virtualWidth(); + uint16_t height = SEGMENT.virtualHeight(); + uint16_t dataSize = sizeof(CRGB) * width * height; + + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + CRGB *leds = reinterpret_cast(SEGENV.data); + + if (SEGENV.call == 0) fill_solid(leds, CRGB::Black); + + uint32_t tb = now >> 12; // every ~4s + if (tb != SEGENV.step) { + if (SEGENV.aux0 >= 7) SEGENV.aux0 = 0; + else SEGENV.aux0++; + SEGENV.step = tb; + } + + fadeToBlackBy(leds, SEGMENT.speed>>4); + switch (SEGENV.aux0) { + case 0: + moveX(leds, 1); + break; + case 1: + moveX(leds, 1); + moveY(leds, -1); + break; + case 2: + moveY(leds, -1); + break; + case 3: + moveX(leds, -1); + moveY(leds, -1); + break; + case 4: + moveX(leds, -1); + break; + case 5: + moveX(leds, -1); + moveY(leds, 1); + break; + case 6: + moveY(leds, 1); + break; + case 7: + moveX(leds, 1); + moveY(leds, 1); + break; + } + for (byte i = 0; i < 8; i++) { + byte x = beatsin8(12 + i, 2, width - 3); + byte y = beatsin8(15 + i, 2, height - 3); + CRGB color = ColorFromPalette(currentPalette, beatsin8(12 + i, 0, 255), 255); + leds[XY(x, y)] += color; + if (width > 24 || height > 24) { + leds[XY(x + 1, y)] += color; + leds[XY(x - 1, y)] += color; + leds[XY(x, y + 1)] += color; + leds[XY(x, y - 1)] += color; + } + } + blur2d(leds, SEGMENT.intensity>>3); + + setPixels(leds); + return FRAMETIME; +} \ No newline at end of file diff --git a/wled00/FX.h b/wled00/FX.h index 86a6f6bf..7b77dcfe 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -261,8 +261,9 @@ #define FX_MODE_SUN_RADIATION 138 #define FX_MODE_TARTAN 139 #define FX_MODE_WAVERLY 140 +#define FX_MODE_SPACESHIPS 141 -#define MODE_COUNT 141 +#define MODE_COUNT 142 class WS2812FX { @@ -650,6 +651,7 @@ class WS2812FX { _mode[FX_MODE_TARTAN] = &WS2812FX::mode_2Dtartan; _mode[FX_MODE_WAVERLY] = &WS2812FX::mode_2DWaverly; _mode[FX_MODE_AKEMI] = &WS2812FX::mode_2DAkemi; + _mode[FX_MODE_SPACESHIPS] = &WS2812FX::mode_2Dspaceships; _brightness = DEFAULT_BRIGHTNESS; currentPalette = CRGBPalette16(CRGB::Black); @@ -910,6 +912,8 @@ class WS2812FX { blur2d(CRGB* leds, fract8 blur_amount), blurRow(uint16_t row, fract8 blur_amount, CRGB* leds=nullptr), blurCol(uint16_t col, fract8 blur_amount, CRGB* leds=nullptr), + moveX(CRGB *leds, int8_t delta), + moveY(CRGB *leds, int8_t delta), fill_solid(CRGB* leds, const struct CRGB& color), fadeToBlackBy(CRGB* leds, uint8_t fadeBy), nscale8(CRGB* leds, uint8_t scale), @@ -949,7 +953,8 @@ class WS2812FX { mode_2DSunradiation(void), mode_2Dtartan(void), mode_2DWaverly(void), - mode_2DAkemi(void); + mode_2DAkemi(void), + mode_2Dspaceships(void); // end 2D support diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 5bff5260..3924d3b5 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -262,6 +262,47 @@ void WS2812FX::blur2d(CRGB* leds, fract8 blur_amount) { for (uint16_t k = 0; k < width; k++) blurCol(k, blur_amount, leds); // blur all columns } +void WS2812FX::moveX(CRGB *leds, int8_t delta) { + uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN + uint16_t height = SEGMENT.virtualHeight(); + if (delta) { + if (delta > 0) { + for (uint8_t y = 0; y < height; y++) { + for (uint8_t x = 0; x < width; x++) { + leds[XY(x, y)] = leds[XY(x + delta, y)]; + } + } + } else { + for (uint8_t y = 0; y < height; y++) { + for (uint8_t x = width - 1; x > 0; x--) { + leds[XY(x, y)] = leds[XY(x + delta, y)]; + } + } + } + } +} + +void WS2812FX::moveY(CRGB *leds, int8_t delta) { + uint16_t width = SEGMENT.virtualWidth(); // same as SEGLEN + uint16_t height = SEGMENT.virtualHeight(); + if (delta) { + if (delta > 0) { + for (uint8_t x = 0; x < height; x++) { + for (uint8_t y = 0; y < width; y++) { + leds[XY(x, y)] = leds[XY(x, y + delta)]; + } + } + } else { + for (uint8_t x = 0; x < height; x++) { + for (uint8_t y = width - 1; y > 0; y--) { + leds[XY(x, y)] = leds[XY(x, y + delta)]; + } + } + } + } +} + + //ewowi20210628: new functions moved from colorutils: add segment awareness void WS2812FX::fill_solid(CRGB* leds, const struct CRGB& color) { diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 26ffc5c6..9cfd8e49 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1455,6 +1455,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([ "2D Sun Radiation@Variance,Brightness;;", "2D Tartan@X scale,Y scale;;!", "2D Waverly@Fade rate,Sensitivity;;!", +"2D Spaceships@Fade rate,Blur;!,!,!;!" ])====="; const char JSON_palette_names[] PROGMEM = R"=====([