Add optional compile flag

This commit is contained in:
Blaz Kristan 2023-09-02 20:20:51 +02:00
parent 6f9bcf1858
commit c2f5846a8e
3 changed files with 42 additions and 5 deletions

View File

@ -419,14 +419,20 @@ typedef struct Segment {
static CRGBPalette16 _randomPalette; // actual random palette
static CRGBPalette16 _newRandomPalette; // target random palette
static unsigned long _lastPaletteChange; // last random palette change time in millis()
#ifndef WLED_DISABLE_MODE_BLEND
static bool _modeBlend; // mode/effect blending semaphore
#endif
// transition data, valid only if transitional==true, holds values during transition (72 bytes)
struct Transition {
#ifndef WLED_DISABLE_MODE_BLEND
tmpsegd_t _segT; // previous segment environment
uint8_t _modeT; // previous mode/effect
#else
uint32_t _colorT[NUM_COLORS];
#endif
uint8_t _briT; // temporary brightness
uint8_t _cctT; // temporary CCT
uint8_t _modeT; // previous mode/effect
CRGBPalette16 _palT; // temporary palette
uint8_t _prevPaletteBlends; // number of previous palette blends (there are max 255 belnds possible)
unsigned long _start; // must accommodate millis()
@ -522,7 +528,9 @@ typedef struct Segment {
static uint16_t getUsedSegmentData(void) { return _usedSegmentData; }
static void addUsedSegmentData(int len) { _usedSegmentData += len; }
#ifndef WLED_DISABLE_MODE_BLEND
static void modeBlend(bool blend) { _modeBlend = blend; }
#endif
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);
@ -552,8 +560,10 @@ typedef struct Segment {
void startTransition(uint16_t dur); // transition has to start before actual segment values change
void stopTransition(void);
void handleTransition(void);
#ifndef WLED_DISABLE_MODE_BLEND
void swapSegenv(tmpsegd_t &tmpSegD);
void restoreSegenv(tmpsegd_t &tmpSegD);
#endif
uint16_t progress(void); //transition progression between 0-65535
uint8_t currentBri(uint8_t briNew, bool useCct = false);
uint8_t currentMode(uint8_t modeNew);

View File

@ -222,8 +222,10 @@ void /*IRAM_ATTR*/ Segment::setPixelColorXY(int x, int y, uint32_t col)
uint16_t xX = (x+g), yY = (y+j);
if (xX >= width() || yY >= height()) continue; // we have reached one dimension's end
#ifndef WLED_DISABLE_MODE_BLEND
// if blending modes, blend with underlying pixel
if (_modeBlend) tmpCol = color_blend(strip.getPixelColorXY(start + xX, startY + yY), col, 0xFFFFU - progress(), true);
#endif
strip.setPixelColorXY(start + xX, startY + yY, tmpCol);

View File

@ -81,7 +81,9 @@ CRGBPalette16 Segment::_randomPalette = CRGBPalette16(DEFAULT_COLOR);
CRGBPalette16 Segment::_newRandomPalette = CRGBPalette16(DEFAULT_COLOR);
unsigned long Segment::_lastPaletteChange = 0; // perhaps it should be per segment
#ifndef WLED_DISABLE_MODE_BLEND
bool Segment::_modeBlend = false;
#endif
// copy constructor
Segment::Segment(const Segment &orig) {
@ -116,7 +118,9 @@ Segment& Segment::operator= (const Segment &orig) {
transitional = false; // copied segment cannot be in transition
if (name) delete[] name;
if (_t) {
#ifndef WLED_DISABLE_MODE_BLEND
if (_t->_segT._dataT) free(_t->_segT._dataT);
#endif
delete _t;
}
deallocateData();
@ -144,7 +148,9 @@ Segment& Segment::operator= (Segment &&orig) noexcept {
if (name) { delete[] name; name = nullptr; } // free old name
deallocateData(); // free old runtime data
if (_t) {
#ifndef WLED_DISABLE_MODE_BLEND
if (_t->_segT._dataT) free(_t->_segT._dataT);
#endif
delete _t;
_t = nullptr;
}
@ -298,12 +304,13 @@ void Segment::startTransition(uint16_t dur) {
if (!_t) return; // failed to allocate data
//DEBUG_PRINTF("-- Started transition: %p\n", this);
swapSegenv(_t->_segT);
CRGBPalette16 _palT = CRGBPalette16(DEFAULT_COLOR); loadPalette(_palT, palette);
_t->_palT = _palT;
_t->_modeT = mode;
_t->_briT = on ? opacity : 0;
_t->_cctT = cct;
#ifndef WLED_DISABLE_MODE_BLEND
swapSegenv(_t->_segT);
_t->_modeT = mode;
_t->_segT._optionsT |= 0b0000000001000000; // mark old segment transitional
_t->_segT._dataLenT = 0;
_t->_segT._dataT = nullptr;
@ -315,6 +322,9 @@ void Segment::startTransition(uint16_t dur) {
_t->_segT._dataLenT = _dataLen;
}
}
#else
for (size_t i=0; i<NUM_COLORS; i++) _t->_colorT[i] = colors[i];
#endif
transitional = true; // setOption(SEG_OPTION_TRANSITIONAL, true);
}
@ -323,11 +333,13 @@ void Segment::stopTransition() {
transitional = false; // finish transitioning segment
//DEBUG_PRINTF("-- Stopping transition: %p\n", this);
if (_t) {
#ifndef WLED_DISABLE_MODE_BLEND
if (_t->_segT._dataT && _t->_segT._dataLenT > 0) {
//DEBUG_PRINTF("-- Released duplicate data (%d): %p\n", _t->_segT._dataLenT, _t->_segT._dataT);
free(_t->_segT._dataT);
_t->_segT._dataT = nullptr;
}
#endif
delete _t;
_t = nullptr;
}
@ -348,6 +360,7 @@ uint16_t Segment::progress() {
return 0xFFFFU;
}
#ifndef WLED_DISABLE_MODE_BLEND
void Segment::swapSegenv(tmpsegd_t &tmpSeg) {
if (!_t) return;
//DEBUG_PRINTF("-- Saving temp seg: %p (%p)\n", this, tmpSeg);
@ -419,6 +432,7 @@ void Segment::restoreSegenv(tmpsegd_t &tmpSeg) {
_dataLen = tmpSeg._dataLenT;
//DEBUG_PRINTF("-- temp seg data: %p (%d,%p)\n", this, _dataLen, data);
}
#endif
uint8_t Segment::currentBri(uint8_t briNew, bool useCct) {
uint32_t prog = progress();
@ -430,13 +444,19 @@ uint8_t Segment::currentBri(uint8_t briNew, bool useCct) {
}
uint8_t Segment::currentMode(uint8_t newMode) {
#ifndef WLED_DISABLE_MODE_BLEND
uint16_t prog = progress(); // implicit check for transitional & _t in progress()
if (prog < 0xFFFFU) return _t->_modeT;
#endif
return newMode;
}
uint32_t Segment::currentColor(uint8_t slot, uint32_t colorNew) {
#ifndef WLED_DISABLE_MODE_BLEND
return transitional && _t ? color_blend(_t->_segT._colorT[slot], colorNew, progress(), true) : colorNew;
#else
return transitional && _t ? color_blend(_t->_colorT[slot], colorNew, progress(), true) : colorNew;
#endif
}
CRGBPalette16 &Segment::currentPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
@ -552,7 +572,6 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) {
// if we have a valid mode & is not reserved
if (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4)) {
if (fx != mode) {
if (!transitional) { DEBUG_PRINT(F("-- Started mode transition. ")); DEBUG_PRINTLN(opacity);}
if (fadeTransition) startTransition(strip.getTransition()); // set effect transitions
mode = fx;
// load default values from effect string
@ -744,12 +763,16 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
uint16_t indexMir = stop - indexSet + start - 1;
indexMir += offset; // offset/phase
if (indexMir >= stop) indexMir -= len; // wrap
#ifndef WLED_DISABLE_MODE_BLEND
if (_modeBlend) tmpCol = color_blend(strip.getPixelColor(indexMir), col, 0xFFFFU - progress(), true);
#endif
strip.setPixelColor(indexMir, tmpCol);
}
indexSet += offset; // offset/phase
if (indexSet >= stop) indexSet -= len; // wrap
#ifndef WLED_DISABLE_MODE_BLEND
if (_modeBlend) tmpCol = color_blend(strip.getPixelColor(indexSet), col, 0xFFFFU - progress(), true);
#endif
strip.setPixelColor(indexSet, tmpCol);
}
}
@ -1216,8 +1239,9 @@ void WS2812FX::service() {
// The blending will largely depend on the effect behaviour since actual output (LEDs) may be
// overwritten by later effect. To enable seamless blending for every effect, additional LED buffer
// would need to be allocated for each effect and then blended together for each pixel.
uint8_t tmpMode = seg.currentMode(seg.mode); // this will return old mode while in transition
[[maybe_unused]] uint8_t tmpMode = seg.currentMode(seg.mode); // this will return old mode while in transition
delay = (*_mode[seg.mode])(); // run new/current mode
#ifndef WLED_DISABLE_MODE_BLEND
if (seg.mode != tmpMode) {
Segment::tmpsegd_t _tmpSegData;
Segment::modeBlend(true); // set semaphore
@ -1227,6 +1251,7 @@ void WS2812FX::service() {
delay = MIN(delay,d2); // use shortest delay
Segment::modeBlend(false); // unset semaphore
}
#endif
if (seg.mode != FX_MODE_HALLOWEEN_EYES) seg.call++;
if (seg.transitional && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition
}