diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index a8545113..9491e134 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -249,7 +249,7 @@ void IRAM_ATTR __attribute__((hot)) Segment::setPixelColorXY_fast(int x, int y, } #if 0 // this is still a dangerous optimization - if ((i < UINT_MAX) && sameColor && (call > 0) && (!transitional) && (mode != FX_MODE_2DSCROLLTEXT) && (ledsrgb[i] == CRGB(scaled_col))) return; // WLEDMM looks like nothing to do + if ((i < UINT_MAX) && sameColor && (call > 0) && (!transitional) && (!freeze) && (mode != FX_MODE_2DSCROLLTEXT) && (ledsrgb[i] == CRGB(scaled_col))) return; // WLEDMM looks like nothing to do #endif // handle reverse and transpose @@ -311,7 +311,7 @@ void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col) //WLEDMM: } #if 0 // this is a dangerous optimization - if ((i < UINT_MAX) && sameColor && (call > 0) && (!transitional) && (mode != FX_MODE_2DSCROLLTEXT) && (ledsrgb[i] == CRGB(col))) return; // WLEDMM looks like nothing to do + if ((i < UINT_MAX) && sameColor && (call > 0) && (!transitional) && (!freeze) && (mode != FX_MODE_2DSCROLLTEXT) && (ledsrgb[i] == CRGB(col))) return; // WLEDMM looks like nothing to do #endif if (reverse ) x = cols - x - 1; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index eb0c97e8..75d7c828 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -945,8 +945,7 @@ void IRAM_ATTR_YN WLED_O2_ATTR __attribute__((hot)) Segment::setPixelColor(int i int vStrip = i>>16; // hack to allow running on virtual strips (2D segment columns/rows) #endif i &= 0xFFFF; - - if (i >= virtualLength() || i<0) return; // if pixel would fall out of segment just exit + if (unsigned(i) >= virtualLength()) return; // if pixel would fall out of segment just exit //WLEDMM unsigned(i)>SEGLEN also catches "i<0" #ifndef WLED_DISABLE_2D if (is2D()) { @@ -1914,7 +1913,7 @@ void WS2812FX::service() { if(nowUp >= seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC)) // WLEDMM ">=" instead of ">" { if (seg.grouping == 0) seg.grouping = 1; //sanity check - if (!seg.freeze) doShow = true; + if ((!seg.freeze) || _triggered) doShow = true; // WLEDMM "triggered" overrules "freeze" uint16_t frameDelay = FRAMETIME; // WLEDMM avoid name clash with "delay" function if (!seg.freeze) { //only run effect function if not frozen @@ -1950,6 +1949,8 @@ void WS2812FX::service() { } _segment_index++; } + if (_triggered) doShow = true; // WLEDMM "triggered" always means "show" + _virtualSegmentLength = 0; busses.setSegmentCCT(-1); if(doShow) { diff --git a/wled00/json.cpp b/wled00/json.cpp index c51deefa..f9f9f5c4 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -329,6 +329,8 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) uint8_t oldMap1D2D = seg.map1D2D; seg.map1D2D = M12_Pixels; // no mapping // WLEDMM begin - we need to init segment caches before putting any pixels + auto oldLock = suspendStripService; // remember pevious lock status + suspendStripService = true; if (strip.isServicing()) { USER_PRINTLN(F("deserializeSegment() image: strip is still drawing effects.")); strip.waitUntilIdle(); @@ -350,6 +352,8 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) start = 0, stop = 0; set = 0; //0 nothing set, 1 start set, 2 range set + seg.startFrame(); // WLEDMM do it again, to be sure that all segment properties get cached + unsigned seg_len = seg.calc_virtualLength(); // WLEDMM prevent out-of-bounds writing for (size_t i = 0; i < iarr.size(); i++) { if(iarr[i].is()) { if (!set) { @@ -375,12 +379,16 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) if (set < 2 || stop <= start) stop = start + 1; uint32_t c = gamma32(RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3])); - while (start < stop) seg.setPixelColor(start++, c); + while (start < stop) { + if (unsigned(start) < seg_len) seg.setPixelColor(start, c); // WLEDMM don't write out-of-bounds + start++; + } set = 0; } } seg.map1D2D = oldMap1D2D; // restore mapping strip.trigger(); // force segment update + suspendStripService = oldLock; // restore previous lock status } // send UDP/WS if segment options changed (except selection; will also deselect current preset) uint8_t diffresult = seg.differs(prev) & 0x7F;