diff --git a/wled00/FX.h b/wled00/FX.h index fbdfe7c0..d52bcc2b 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -380,6 +380,7 @@ typedef struct Segment { }; uint8_t grouping, spacing; uint8_t opacity; + bool needsBlank; // WLEDMM indicates that Segment needs to be blanked (due to change of mirror / reverse / transpose / spacing) uint32_t colors[NUM_COLORS]; uint8_t cct; //0==1900K, 255==10091K uint8_t custom1, custom2; // custom FX parameters/sliders @@ -489,6 +490,7 @@ typedef struct Segment { grouping(1), spacing(0), opacity(255), + needsBlank(false), colors{DEFAULT_COLOR,BLACK,BLACK}, cct(127), custom1(DEFAULT_C1), @@ -598,6 +600,7 @@ typedef struct Segment { * Safe to call from interrupts and network requests. */ inline void markForReset(void) { reset = true; } // setOption(SEG_OPTION_RESET, true) + inline void markForBlank(void) { needsBlank = true; } // WLEDMM serialize "blank" requests, avoid parallel drawing from different task void setUpLeds(void); // set up leds[] array for loseless getPixelColor() // transition functions diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 4a194d5c..e94e6e6a 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -277,7 +277,16 @@ void Segment::resetIfRequired() { next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; reset = false; // setOption(SEG_OPTION_RESET, false); startFrame(); // WLEDMM update cached propoerties + if (isActive()) fill(BLACK); // WLEDMM start clean + DEBUG_PRINTLN("Segment reset"); + } else if (needsBlank) { + startFrame(); // WLEDMM update cached propoerties + if (isActive()) { + fill(BLACK); // WLEDMM start clean + DEBUG_PRINTLN("Segment blanked"); + } } + needsBlank = false; } void Segment::setUpLeds() { @@ -510,7 +519,7 @@ void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t stateChanged = true; // send UDP/WS broadcast - if (stop>start) fill(BLACK); //turn old segment range off // WLEDMM stop > start + if (stop>start) markForBlank(); //turn old segment range off // WLEDMM stop > start if (i2 <= i1) { //disable segment stop = 0; markForReset(); @@ -2310,6 +2319,7 @@ void WS2812FX::restartRuntime(bool doReset) { seg.markForReset(); // seg.resetIfRequired(); // WLEDMM calling this function from webserver context will cause troubles } else { seg.next_time = 0; seg.step = 0; + seg.markForBlank(); } } } diff --git a/wled00/json.cpp b/wled00/json.cpp index 7d355e79..28467a17 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -172,7 +172,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) if (map1D2D != M12_jMap && seg.jMap) seg.deletejMap(); - if ((spc>0 && spc!=seg.spacing) || seg.map1D2D!=map1D2D) seg.fill(BLACK); // clear spacing gaps // WLEDMM softhack007: this line sometimes crashes with "Stack canary watchpoint triggered (async_tcp)" + if ((spc>0 && spc!=seg.spacing) || seg.map1D2D!=map1D2D) seg.markForBlank(); // clear spacing gaps // WLEDMM softhack007: this line sometimes crashes with "Stack canary watchpoint triggered (async_tcp)" seg.map1D2D = constrain(map1D2D, 0, 7); seg.soundSim = constrain(soundSim, 0, 1); @@ -289,7 +289,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) seg.reverse_y = elem["rY"] | seg.reverse_y; seg.mirror_y = elem["mY"] | seg.mirror_y; seg.transpose = elem[F("tp")] | seg.transpose; - if (seg.is2D() && (seg.map1D2D == M12_pArc || seg.map1D2D == M12_sCircle) && (reverse != seg.reverse || reverse_y != seg.reverse_y || mirror != seg.mirror || mirror_y != seg.mirror_y)) seg.fill(BLACK); // clear entire segment (in case of Arc 1D to 2D expansion) WLEDMM: also Circle + if (seg.is2D() && (seg.map1D2D == M12_pArc || seg.map1D2D == M12_sCircle) && (reverse != seg.reverse || reverse_y != seg.reverse_y || mirror != seg.mirror || mirror_y != seg.mirror_y)) seg.markForBlank(); // clear entire segment (in case of Arc 1D to 2D expansion) WLEDMM: also Circle #endif byte fx = seg.mode; @@ -386,6 +386,13 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) if (seg.differs(prev) & 0x7F) { stateChanged = true; if ((seg.on == false) && (prev.on == true) && (prev.freeze == false)) prev.fill(BLACK); // WLEDMM: force BLACK if segment was turned off + else if (prev.isActive()) prev.fill(BLACK); // WLEDMM fingers crossed + seg.markForBlank(); // WLEDMM + } + else if ((seg.grouping != prev.grouping) || (seg.spacing != prev.spacing) || (seg.transpose != prev.transpose)) { + // WLEDMM blank if grouping / spacing changed + seg.markForBlank(); + if (prev.isActive()) prev.fill(BLACK); // WLEDMM fingers crossed } if (iAmGroot) suspendStripService = false; // WLEDMM release lock