diff --git a/wled00/FX.h b/wled00/FX.h index d9426624..fc8f16b9 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -395,6 +395,12 @@ typedef struct Segment { uint16_t _dataLen; static uint16_t _usedSegmentData; + // perhaps this should be per segment, not static + static CRGBPalette16 _randomPalette; + static CRGBPalette16 _newRandomPalette; + static unsigned long _lastPaletteChange; + static uint8_t _noOfBlendsRemaining; + // transition data, valid only if transitional==true, holds values during transition (72 bytes) struct Transition { uint32_t _colorT[NUM_COLORS]; @@ -510,6 +516,7 @@ typedef struct Segment { static uint16_t getUsedSegmentData(void) { return _usedSegmentData; } static void addUsedSegmentData(int len) { _usedSegmentData += len; } + static void handleRandomPalette(); void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1, uint8_t segId = 255); bool setColor(uint8_t slot, uint32_t c); //returns true if changed diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 74d61cb4..c76e22a2 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -77,6 +77,11 @@ uint16_t Segment::_usedSegmentData = 0U; // amount of RAM all segments use for t uint16_t Segment::maxWidth = DEFAULT_LED_COUNT; uint16_t Segment::maxHeight = 1; +CRGBPalette16 Segment::_randomPalette = CRGBPalette16(DEFAULT_COLOR); +CRGBPalette16 Segment::_newRandomPalette = CRGBPalette16(DEFAULT_COLOR); +unsigned long Segment::_lastPaletteChange = 0; // perhaps it should be per segment +uint8_t Segment::_noOfBlendsRemaining = 0; + // copy constructor Segment::Segment(const Segment &orig) { //DEBUG_PRINTLN(F("-- Copy segment constructor --")); @@ -182,10 +187,6 @@ void Segment::resetIfRequired() { } CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { - static unsigned long _lastPaletteChange = 0; // perhaps it should be per segment - static CRGBPalette16 randomPalette = CRGBPalette16(DEFAULT_COLOR); - static CRGBPalette16 prevRandomPalette = CRGBPalette16(CRGB(BLACK)); - byte tcp[72]; if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0; if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; //default palette. Differs depending on effect @@ -206,27 +207,18 @@ CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { case 0: //default palette. Exceptions for specific effects above targetPalette = PartyColors_p; break; case 1: {//periodically replace palette with a random one. Transition palette change in 500ms - uint32_t timeSinceLastChange = millis() - _lastPaletteChange; + unsigned long timeSinceLastChange = millis() - _lastPaletteChange; if (timeSinceLastChange > randomPaletteChangeTime * 1000U) { - prevRandomPalette = randomPalette; - randomPalette = CRGBPalette16( + _randomPalette = _newRandomPalette; + _newRandomPalette = CRGBPalette16( CHSV(random8(), random8(160, 255), random8(128, 255)), CHSV(random8(), random8(160, 255), random8(128, 255)), CHSV(random8(), random8(160, 255), random8(128, 255)), CHSV(random8(), random8(160, 255), random8(128, 255))); _lastPaletteChange = millis(); - timeSinceLastChange = 0; - } - if (timeSinceLastChange <= 250) { - targetPalette = prevRandomPalette; - // there needs to be 255 palette blends (48) for full blend but that is too resource intensive - // so 128 is a compromise (we need to perform full blend of the two palettes as each segment can have random - // palette selected but only 2 static palettes are used) - size_t noOfBlends = ((128U * timeSinceLastChange) / 250U); - for (size_t i=0; i245) { targetPalette = strip.customPalettes[255-pal]; // we checked bounds above } else { + byte tcp[72]; memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[pal-13])), 72); targetPalette.loadDynamicGradientPalette(tcp); } @@ -353,6 +346,17 @@ void Segment::handleTransition() { } } +// relies on WS2812FX::service() to call it max every 8ms or more (MIN_SHOW_DELAY) +void Segment::handleRandomPalette() { + if (_noOfBlendsRemaining > 0) { + // there needs to be 255 palette blends (48) for full blend + size_t noOfBlends = 3; // blending time ~850ms when MIN_SHOW_DELAY>10 + if (noOfBlends > _noOfBlendsRemaining) noOfBlends = _noOfBlendsRemaining; + for (size_t i=0; i