diff --git a/wled00/FX.cpp b/wled00/FX.cpp index f3163dc18e..f23d4a28d9 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -544,6 +544,46 @@ uint16_t mode_rainbow_cycle(void) { } static const char _data_FX_MODE_RAINBOW_CYCLE[] PROGMEM = "Rainbow@!,Size;;!"; +/* + * adds a predictable white flash across the segment + */ +uint16_t mode_shimmer() { + uint32_t segmentSize; + //gaurd against buffer overflow, should never exceed this based + //on 1000 pixles per GPIO and 10 strips + if(SEGLEN>10000) { + segmentSize = 10000; + } else { + segmentSize=SEGLEN; + } + + uint32_t shimmerSpeed = 100 + (255 - SEGMENT.speed) * 40; // [100,10300] + uint32_t shimmerSize = (SEGMENT.custom1 * segmentSize >> 9) + 1; // [1,(SEGLEN/2)+1] capped at 5001. + uint32_t cycleTime = (255 - SEGMENT.intensity) * 150 + shimmerSpeed; // [100, 48550] + uint32_t percCycle = strip.now % cycleTime; + int32_t shimmerIndex = (percCycle<<8) / shimmerSpeed * (segmentSize + 2*shimmerSize); // maxamum >124285 + + shimmerIndex -= shimmerSize << 8; + + //change direction unless reverse is checked + if(!SEGMENT.check1) { + shimmerIndex = ((segmentSize) << 8) - shimmerIndex; + } + + for (uint32_t i = 0; i < segmentSize; i++) { + + // slightly dangerous, but shimmer index is bounded to be safe + uint32_t distFromShimmerCenter = abs((int32_t)shimmerIndex - ((int32_t)i << 8)); + if (distFromShimmerCenter < (shimmerSize<<8)) { + SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(255-(distFromShimmerCenter / shimmerSize),false,PALETTE_SOLID_WRAP,0)); + } + else { + SEGMENT.setPixelColor(i,SEGCOLOR(1)); + } + } + return FRAMETIME; +} +static const char _data_FX_MODE_SHIMMER[] PROGMEM = "Shimmer@Speed,Frequency,Size,,,Reverse;Fx,Bg,Cx;!;m12;sx=231,ix=221,pal=4"; /* * Alternating pixels running function. @@ -10665,6 +10705,7 @@ void WS2812FX::setupEffectData() { addEffect(FX_MODE_DYNAMIC, &mode_dynamic, _data_FX_MODE_DYNAMIC); addEffect(FX_MODE_RAINBOW, &mode_rainbow, _data_FX_MODE_RAINBOW); addEffect(FX_MODE_RAINBOW_CYCLE, &mode_rainbow_cycle, _data_FX_MODE_RAINBOW_CYCLE); + addEffect(FX_MODE_SHIMMER, &mode_shimmer, _data_FX_MODE_SHIMMER); addEffect(FX_MODE_SCAN, &mode_scan, _data_FX_MODE_SCAN); addEffect(FX_MODE_DUAL_SCAN, &mode_dual_scan, _data_FX_MODE_DUAL_SCAN); addEffect(FX_MODE_FADE, &mode_fade, _data_FX_MODE_FADE); diff --git a/wled00/FX.h b/wled00/FX.h index 097c857caf..a0cd9219ab 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -374,7 +374,8 @@ extern byte realtimeMode; // used in getMappedPixelIndex() #define FX_MODE_PS1DSONICBOOM 215 #define FX_MODE_PS1DSPRINGY 216 #define FX_MODE_PARTICLEGALAXY 217 -#define MODE_COUNT 218 +#define FX_MODE_SHIMMER 218 +#define MODE_COUNT 219 #define BLEND_STYLE_FADE 0x00 // universal