@@ -457,58 +457,82 @@ void Segment::handleRandomPalette() {
457457 nblendPaletteTowardPalette (_randomPalette, _newRandomPalette, 48 );
458458}
459459
460- // segId is given when called from network callback, changes are queued if that segment is currently in its effect function
461460void Segment::setGeometry (uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y, uint8_t m12) {
462- // return if neither bounds nor grouping have changed
463- bool boundsUnchanged = (start == i1 && stop == i2);
461+ // Sanitise inputs
462+ if (i2 < i1) { // For any values, this means "stop"; we do i2 before i1 for this case
463+ i2 = 0 ;
464+ } else {
465+ // Clamp i2 to maximum length
466+ if (i2 > Segment::maxWidth*Segment::maxHeight) {
467+ i2 = MIN (i2,strip.getLengthTotal ());
468+ } else if (i2 > Segment::maxWidth) {
469+ i2 = Segment::maxWidth;
470+ } else if (i2 < 1 ) {
471+ i2 = 1 ;
472+ }
473+ }
474+ // If i1 is invalid, use old value
475+ // Valid range is inside maxWidth, or in trailing segment range
476+ if ((i1 >= Segment::maxWidth) && (i1 < Segment::maxWidth*Segment::maxHeight || i1 >= strip.getLengthTotal ())) {
477+ i1 = start;
478+ }
479+
464480 #ifndef WLED_DISABLE_2D
465- if (Segment::maxHeight>1 ) boundsUnchanged &= (startY == i1Y && stopY == i2Y); // 2D
481+ if (Segment::maxHeight>1 ) { // 2D
482+ if (i1Y >= Segment::maxHeight) i1Y = startY;
483+ if (i2Y > Segment::maxHeight) {
484+ i2Y = Segment::maxHeight;
485+ } else if (i2Y < 1 ) {
486+ i2Y = 1 ;
487+ }
488+ if (i2Y < i1Y) {
489+ i2 = 0 ; // stop
490+ }
491+ } else
466492 #endif
493+ {
494+ i1Y = 0 ;
495+ i2Y = 1 ;
496+ }
467497
498+ if (grp == 0 ) { grp = 1 ; spc = 0 ; } // prevent assignment of 0
499+ if (ofs == UINT16_MAX) ofs = offset;
468500 m12 = constrain (m12, 0 , 7 );
469- if (stop) fill (BLACK); // turn off LEDs in segment before changing geometry
470- if (m12 != map1D2D) map1D2D = m12;
471- /*
472- if (boundsUnchanged
473- && (!grp || (grouping == grp && spacing == spc))
474- && (m12 == map1D2D)
475- ) return;
476- */
477- stateChanged = true ; // send UDP/WS broadcast
478501
479- if (grp) { // prevent assignment of 0
480- grouping = grp;
481- spacing = spc;
482- } else {
483- grouping = 1 ;
484- spacing = 0 ;
502+ // Final safety check
503+ if ((i1 >= i2) || (i1Y >= i2Y)) {
504+ i2 = 0 ; // disable segment
485505 }
486- if (ofs < UINT16_MAX) offset = ofs;
487506
488- DEBUG_PRINTF_P (PSTR (" Segment geometry: %d,%d -> %d,%d\n " ), (int )i1, (int )i2, (int )i1Y, (int )i2Y);
507+ // Inputs are ok, check if anything has changed
508+ bool boundsUnchanged = (start == i1 && stop == i2)
509+ #ifndef WLED_DISABLE_2D
510+ && ((Segment::maxHeight <= 1 ) || (startY == i1Y && stopY == i2Y))
511+ #endif
512+ && (grouping == grp)
513+ && (spacing == spc)
514+ && (offset == ofs)
515+ && (m12 == map1D2D);
516+
489517 if (boundsUnchanged) return ;
518+
519+ DEBUG_PRINTF_P (PSTR (" Segment geometry: (%d,%d),(%d,%d) -> (%d,%d),(%d,%d)\n " ), start, stop, startY, stopY, (int )i1, (int )i2, (int )i1Y, (int )i2Y);
520+
521+ if (stop > 0 ) fill (BLACK); // turn off LEDs in segment before changing geometry
522+
523+ stateChanged = true ; // send UDP/WS broadcast
490524 markForReset ();
491525
492- // apply change immediately
493- if (i2 <= i1) { // disable segment
494- stop = 0 ;
495- return ;
496- }
497- if (i1 < Segment::maxWidth || (i1 >= Segment::maxWidth*Segment::maxHeight && i1 < strip.getLengthTotal ())) start = i1; // Segment::maxWidth equals strip.getLengthTotal() for 1D
498- stop = i2 > Segment::maxWidth*Segment::maxHeight ? MIN (i2,strip.getLengthTotal ()) : (i2 > Segment::maxWidth ? Segment::maxWidth : MAX (1 ,i2));
499- startY = 0 ;
500- stopY = 1 ;
501- #ifndef WLED_DISABLE_2D
502- if (Segment::maxHeight>1 ) { // 2D
503- if (i1Y < Segment::maxHeight) startY = i1Y;
504- stopY = i2Y > Segment::maxHeight ? Segment::maxHeight : MAX (1 ,i2Y);
505- }
506- #endif
507- // safety check
508- if (start >= stop || startY >= stopY) {
509- stop = 0 ;
510- return ;
511- }
526+ // apply change
527+ start = i1;
528+ stop = i2;
529+ startY = i1Y;
530+ stopY = i2Y;
531+ grouping = grp;
532+ spacing = spc;
533+ offset = ofs;
534+ map1D2D = m12;
535+
512536 refreshLightCapabilities ();
513537}
514538
@@ -532,7 +556,7 @@ Segment &Segment::setCCT(uint16_t k) {
532556 k = (k - 1900 ) >> 5 ;
533557 }
534558 if (cct != k) {
535- // DEBUGFX_PRINTF_P (PSTR("- Starting CCT transition: %d\n"), k);
559+ DEBUG_PRINTF_P (PSTR (" - Starting CCT transition: %d\n " ), k);
536560 startTransition (strip.getTransition ()); // start transition prior to change
537561 cct = k;
538562 stateChanged = true ; // send UDP/WS broadcast
@@ -542,7 +566,7 @@ Segment &Segment::setCCT(uint16_t k) {
542566
543567Segment &Segment::setOpacity (uint8_t o) {
544568 if (opacity != o) {
545- // DEBUGFX_PRINTF_P (PSTR("- Starting opacity transition: %d\n"), o);
569+ DEBUG_PRINTF_P (PSTR (" - Starting opacity transition: %d\n " ), o);
546570 startTransition (strip.getTransition ()); // start transition prior to change
547571 opacity = o;
548572 stateChanged = true ; // send UDP/WS broadcast
0 commit comments