updated setPixelColor() and getPixelColor() functions

uint16_t to unsigned to make it consisten throughout the hand-down.
colorFromPaletteWLED now returns uint32_t which saves the conversion to CRGB and back to uint32_t (in most uses at least).
also added (preliminary) CRGBW struct. I tried to use it in place of uint32_t colors but it adds a lot of overhead when passing the struct so reverted to uint32_t in most places.
updated a few FX to use the CRGBW struct and also cleaned some code to improve flash useage.
This commit is contained in:
Damian Schneider 2024-09-28 15:26:14 +02:00
parent a76a895f1d
commit 7c0fe1285a
8 changed files with 129 additions and 86 deletions

View File

@ -1937,7 +1937,7 @@ uint16_t mode_juggle(void) {
for (int i = 0; i < 8; i++) {
int index = 0 + beatsin88((16 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1);
fastled_col = CRGB(SEGMENT.getPixelColor(index));
fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(SEGPALETTE, dothue, 255);
fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):CRGB(ColorFromPalette(SEGPALETTE, dothue, 255));
SEGMENT.setPixelColor(index, fastled_col);
dothue += 32;
}
@ -2282,33 +2282,33 @@ uint16_t mode_colortwinkle() {
unsigned dataSize = (SEGLEN+7) >> 3; //1 bit per LED
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
CRGB fastled_col, prev;
CRGBW col, prev;
fract8 fadeUpAmount = strip.getBrightness()>28 ? 8 + (SEGMENT.speed>>2) : 68-strip.getBrightness();
fract8 fadeDownAmount = strip.getBrightness()>28 ? 8 + (SEGMENT.speed>>3) : 68-strip.getBrightness();
for (int i = 0; i < SEGLEN; i++) {
fastled_col = SEGMENT.getPixelColor(i);
prev = fastled_col;
CRGBW cur = SEGMENT.getPixelColor(i);
prev = cur;
unsigned index = i >> 3;
unsigned bitNum = i & 0x07;
bool fadeUp = bitRead(SEGENV.data[index], bitNum);
if (fadeUp) {
CRGB incrementalColor = fastled_col;
incrementalColor.nscale8_video(fadeUpAmount);
fastled_col += incrementalColor;
CRGBW incrementalColor = color_fade(col, fadeUpAmount, true);
col = color_add(cur, incrementalColor);
if (fastled_col.red == 255 || fastled_col.green == 255 || fastled_col.blue == 255) {
if (col.r == 255 || col.g == 255 || col.b == 255) {
bitWrite(SEGENV.data[index], bitNum, false);
}
SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue);
if (SEGMENT.getPixelColor(i) == RGBW32(prev.r, prev.g, prev.b, 0)) { //fix "stuck" pixels
fastled_col += fastled_col;
SEGMENT.setPixelColor(i, fastled_col);
if (cur == prev) { //fix "stuck" pixels
color_add(col, col);
SEGMENT.setPixelColor(i, col);
}
} else {
fastled_col.nscale8(255 - fadeDownAmount);
SEGMENT.setPixelColor(i, fastled_col);
else SEGMENT.setPixelColor(i, col);
}
else {
col = color_fade(cur, 255 - fadeDownAmount);
SEGMENT.setPixelColor(i, col);
}
}
@ -2317,11 +2317,10 @@ uint16_t mode_colortwinkle() {
for (unsigned times = 0; times < 5; times++) { //attempt to spawn a new pixel 5 times
int i = random16(SEGLEN);
if (SEGMENT.getPixelColor(i) == 0) {
fastled_col = ColorFromPalette(SEGPALETTE, random8(), 64, NOBLEND);
unsigned index = i >> 3;
unsigned bitNum = i & 0x07;
bitWrite(SEGENV.data[index], bitNum, true);
SEGMENT.setPixelColor(i, fastled_col);
SEGMENT.setPixelColor(i, ColorFromPalette(SEGPALETTE, random8(), 64, NOBLEND));
break; //only spawn 1 new pixel per frame per 50 LEDs
}
}
@ -2378,8 +2377,7 @@ uint16_t mode_meteor() {
index = map(i,0,SEGLEN,0,max);
bri = trail[i];
}
uint32_t col = SEGMENT.color_from_palette(index, false, false, idx, bri); // full brightness for Fire
SEGMENT.setPixelColor(i, col);
SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, false, idx, bri)); // full brightness for Fire
}
}
@ -2392,8 +2390,7 @@ uint16_t mode_meteor() {
i = map(index,0,SEGLEN,0,max);
idx = 0;
}
uint32_t col = SEGMENT.color_from_palette(i, false, false, idx, 255); // full brightness
SEGMENT.setPixelColor(index, col);
SEGMENT.setPixelColor(index, SEGMENT.color_from_palette(i, false, false, idx, 255)); // full brightness
}
return FRAMETIME;
@ -2419,8 +2416,7 @@ uint16_t mode_meteor_smooth() {
if (/*trail[i] != 0 &&*/ random8() <= 255 - SEGMENT.intensity) {
int change = trail[i] + 4 - random8(24); //change each time between -20 and +4
trail[i] = constrain(change, 0, max);
uint32_t col = SEGMENT.check1 ? SEGMENT.color_from_palette(i, true, false, 0, trail[i]) : SEGMENT.color_from_palette(trail[i], false, true, 255);
SEGMENT.setPixelColor(i, col);
SEGMENT.setPixelColor(i, SEGMENT.check1 ? SEGMENT.color_from_palette(i, true, false, 0, trail[i]) : SEGMENT.color_from_palette(trail[i], false, true, 255));
}
}
@ -2431,8 +2427,7 @@ uint16_t mode_meteor_smooth() {
index -= SEGLEN;
}
trail[index] = max;
uint32_t col = SEGMENT.check1 ? SEGMENT.color_from_palette(index, true, false, 0, trail[index]) : SEGMENT.color_from_palette(trail[index], false, true, 255);
SEGMENT.setPixelColor(index, col);
SEGMENT.setPixelColor(index, SEGMENT.check1 ? SEGMENT.color_from_palette(index, true, false, 0, trail[index]) : SEGMENT.color_from_palette(trail[index], false, true, 255));
}
SEGENV.step += SEGMENT.speed +1;
@ -2680,7 +2675,7 @@ static uint16_t twinklefox_base(bool cat)
if (deltabright >= 32 || (!bg)) {
// If the new pixel is significantly brighter than the background color,
// use the new color.
SEGMENT.setPixelColor(i, c.red, c.green, c.blue);
SEGMENT.setPixelColor(i, c);
} else if (deltabright > 0) {
// If the new pixel is just slightly brighter than the background color,
// mix a blend of the new color and the background color
@ -2688,7 +2683,7 @@ static uint16_t twinklefox_base(bool cat)
} else {
// if the new pixel is not at all brighter than the background color,
// just use the background color.
SEGMENT.setPixelColor(i, bg.r, bg.g, bg.b);
SEGMENT.setPixelColor(i, bg);
}
}
return FRAMETIME;
@ -3532,7 +3527,7 @@ uint16_t mode_starburst(void) {
if (start == end) end++;
if (end > SEGLEN) end = SEGLEN;
for (int p = start; p < end; p++) {
SEGMENT.setPixelColor(p, c.r, c.g, c.b);
SEGMENT.setPixelColor(p, c);
}
}
}
@ -3650,17 +3645,17 @@ uint16_t mode_exploding_fireworks(void)
if (SEGMENT.is2D() && !(sparks[i].posX >= 0 && sparks[i].posX < cols)) continue;
unsigned prog = sparks[i].col;
uint32_t spColor = (SEGMENT.palette) ? SEGMENT.color_wheel(sparks[i].colIndex) : SEGCOLOR(0);
CRGB c = CRGB::Black; //HeatColor(sparks[i].col);
CRGBW c = BLACK; //HeatColor(sparks[i].col);
if (prog > 300) { //fade from white to spark color
c = CRGB(color_blend(spColor, WHITE, (prog - 300)*5));
c = color_blend(spColor, WHITE, (prog - 300)*5);
} else if (prog > 45) { //fade from spark color to black
c = CRGB(color_blend(BLACK, spColor, prog - 45));
c = color_blend(BLACK, spColor, prog - 45);
unsigned cooling = (300 - prog) >> 5;
c.g = qsub8(c.g, cooling);
c.b = qsub8(c.b, cooling * 2);
}
if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(int(sparks[i].posX), rows - int(sparks[i].pos) - 1, c.red, c.green, c.blue);
else SEGMENT.setPixelColor(int(sparks[i].posX) ? rows - int(sparks[i].pos) - 1 : int(sparks[i].pos), c.red, c.green, c.blue);
if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(int(sparks[i].posX), rows - int(sparks[i].pos) - 1, c);
else SEGMENT.setPixelColor(int(sparks[i].posX) ? rows - int(sparks[i].pos) - 1 : int(sparks[i].pos), c);
}
}
if (SEGMENT.check3) SEGMENT.blur(16);
@ -4006,7 +4001,7 @@ static CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, u
ci += (cs * i);
unsigned sindex16 = sin16(ci) + 32768;
unsigned sindex8 = scale16(sindex16, 240);
return ColorFromPalette(p, sindex8, bri, LINEARBLEND);
return CRGB(ColorFromPalette(p, sindex8, bri, LINEARBLEND));
}
uint16_t mode_pacifica()
@ -4077,7 +4072,7 @@ uint16_t mode_pacifica()
c.green = scale8(c.green, 200);
c |= CRGB( 2, 5, 7);
SEGMENT.setPixelColor(i, c.red, c.green, c.blue);
SEGMENT.setPixelColor(i, c);
}
strip.now = nowOld;
@ -4119,13 +4114,10 @@ uint16_t mode_sunrise() {
for (int i = 0; i <= SEGLEN/2; i++)
{
//default palette is Fire
uint32_t c = SEGMENT.color_from_palette(0, false, true, 255); //background
//default palette is Fire
unsigned wave = triwave16((i * stage) / SEGLEN);
wave = (wave >> 8) + ((wave * SEGMENT.intensity) >> 15);
uint32_t c;
if (wave > 240) { //clipped, full white sun
c = SEGMENT.color_from_palette( 240, false, true, 255);
} else { //transition
@ -4217,8 +4209,6 @@ uint16_t mode_noisepal(void) { // Slow noise
palettes[1] = CRGBPalette16(CHSV(baseI+random8(64), 255, random8(128,255)), CHSV(baseI+128, 255, random8(128,255)), CHSV(baseI+random8(92), 192, random8(128,255)), CHSV(baseI+random8(92), 255, random8(128,255)));
}
CRGB color;
//EVERY_N_MILLIS(10) { //(don't have to time this, effect function is only called every 24ms)
nblendPaletteTowardPalette(palettes[0], palettes[1], 48); // Blend towards the target palette over 48 iterations.
@ -4226,8 +4216,7 @@ uint16_t mode_noisepal(void) { // Slow noise
for (int i = 0; i < SEGLEN; i++) {
unsigned index = inoise8(i*scale, SEGENV.aux0+i*scale); // Get a value from the noise function. I'm using both x and y axis.
color = ColorFromPalette(palettes[0], index, 255, LINEARBLEND); // Use the my own palette.
SEGMENT.setPixelColor(i, color.red, color.green, color.blue);
SEGMENT.setPixelColor(i, ColorFromPalette(palettes[0], index, 255, LINEARBLEND)); // Use my own palette.
}
SEGENV.aux0 += beatsin8(10,1,4); // Moving along the distance. Vary it a bit with a sine wave.
@ -4314,9 +4303,8 @@ uint16_t mode_chunchun(void)
counter -= span;
unsigned megumin = sin16(counter) + 0x8000;
unsigned bird = uint32_t(megumin * SEGLEN) >> 16;
uint32_t c = SEGMENT.color_from_palette((i * 255)/ numBirds, false, false, 0); // no palette wrapping
bird = constrain(bird, 0U, SEGLEN-1U);
SEGMENT.setPixelColor(bird, c);
SEGMENT.setPixelColor(bird, SEGMENT.color_from_palette((i * 255)/ numBirds, false, false, 0)); // no palette wrapping
}
return FRAMETIME;
}
@ -4934,7 +4922,7 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (cols - 1));
byte y1 = beatsin8(5 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 24);
byte y2 = beatsin8(3 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 48 + 64);
CRGB color = ColorFromPalette(SEGPALETTE, i * 255 / numLines + (SEGENV.aux0&0xFF), 255, LINEARBLEND);
uint32_t color = ColorFromPalette(SEGPALETTE, i * 255 / numLines + (SEGENV.aux0&0xFF), 255, LINEARBLEND);
byte xsteps = abs8(x1 - y1) + 1;
byte ysteps = abs8(x2 - y2) + 1;
@ -5831,7 +5819,7 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht
for (size_t i = 0; i < 8; i++) {
int x = beatsin8(12 + i, 2, cols - 3);
int y = beatsin8(15 + i, 2, rows - 3);
CRGB color = ColorFromPalette(SEGPALETTE, beatsin8(12 + i, 0, 255), 255);
uint32_t color = ColorFromPalette(SEGPALETTE, beatsin8(12 + i, 0, 255), 255);
SEGMENT.addPixelColorXY(x, y, color);
if (cols > 24 || rows > 24) {
SEGMENT.addPixelColorXY(x+1, y, color);
@ -6725,8 +6713,7 @@ uint16_t mode_noisefire(void) { // Noisefire. By Andrew Tuline.
index = (255 - i*256/SEGLEN) * index/(256-SEGMENT.intensity); // Now we need to scale index so that it gets blacker as we get close to one of the ends.
// This is a simple y=mx+b equation that's been scaled. index/128 is another scaling.
CRGB color = ColorFromPalette(myPal, index, volumeSmth*2, LINEARBLEND); // Use the my own palette.
SEGMENT.setPixelColor(i, color);
SEGMENT.setPixelColor(i, ColorFromPalette(myPal, index, volumeSmth*2, LINEARBLEND)); // Use my own palette.
}
return FRAMETIME;
@ -7532,7 +7519,7 @@ uint16_t mode_2DAkemi(void) {
unsigned band = x * cols/8;
band = constrain(band, 0, 15);
int barHeight = map(fftResult[band], 0, 255, 0, 17*rows/32);
CRGB color = CRGB(SEGMENT.color_from_palette((band * 35), false, PALETTE_SOLID_WRAP, 0));
uint32_t color = SEGMENT.color_from_palette((band * 35), false, PALETTE_SOLID_WRAP, 0);
for (int y=0; y < barHeight; y++) {
SEGMENT.setPixelColorXY(x, rows/2-y, color);
@ -7760,8 +7747,7 @@ uint16_t mode_2Doctopus() {
//CRGB c = CHSV(SEGENV.step / 2 - radius, 255, sin8(sin8((angle * 4 - radius) / 4 + SEGENV.step) + radius - SEGENV.step * 2 + angle * (SEGMENT.custom3/3+1)));
unsigned intensity = sin8(sin8((angle * 4 - radius) / 4 + SEGENV.step/2) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1));
intensity = map((intensity*intensity) & 0xFFFF, 0, 65535, 0, 255); // add a bit of non-linearity for cleaner display
CRGB c = ColorFromPalette(SEGPALETTE, SEGENV.step / 2 - radius, intensity);
SEGMENT.setPixelColorXY(x, y, c);
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, SEGENV.step / 2 - radius, intensity));
}
}
return FRAMETIME;

View File

@ -851,10 +851,8 @@ class WS2812FX { // 96 bytes
return index;
};
uint32_t
now,
timebase,
getPixelColor(uint16_t) const;
uint32_t now, timebase;
uint32_t getPixelColor(unsigned) const;
inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call
inline uint32_t segColor(uint8_t i) const { return _colors_t[i]; } // returns currently valid color (for slot i) AKA SEGCOLOR(); may be blended between two colors while in transition

View File

@ -671,7 +671,7 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w,
case 60: bits = pgm_read_byte_near(&console_font_5x12[(chr * h) + i]); break; // 5x12 font
default: return;
}
col = ColorFromPalette(grad, (i+1)*255/h, 255, NOBLEND);
uint32_t col = ColorFromPaletteWLED(grad, (i+1)*255/h, 255, NOBLEND);
for (int j = 0; j<w; j++) { // character width
int x0, y0;
switch (rotate) {

View File

@ -1191,9 +1191,10 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_
if (mapping && virtualLength() > 1) paletteIndex = (i*255)/(virtualLength() -1);
// paletteBlend: 0 - wrap when moving, 1 - always wrap, 2 - never wrap, 3 - none (undefined)
if (!wrap && strip.paletteBlend != 3) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
CRGB fastled_col = ColorFromPalette(_currentPalette, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
CRGBW palcol = ColorFromPalette(_currentPalette, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
palcol.w = gamma8(W(color));
return RGBW32(fastled_col.r, fastled_col.g, fastled_col.b, gamma8(W(color)));
return palcol.color32;
}
@ -1419,7 +1420,7 @@ void IRAM_ATTR WS2812FX::setPixelColor(unsigned i, uint32_t col) {
BusManager::setPixelColor(i, col);
}
uint32_t IRAM_ATTR WS2812FX::getPixelColor(uint16_t i) const {
uint32_t IRAM_ATTR WS2812FX::getPixelColor(unsigned i) const {
i = getMappedPixelIndex(i);
if (i >= _length) return 0;
return BusManager::getPixelColor(i);

View File

@ -306,7 +306,7 @@ void BusDigital::setStatusPixel(uint32_t c) {
}
}
void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) {
void IRAM_ATTR BusDigital::setPixelColor(unsigned pix, uint32_t c) {
if (!_valid) return;
uint8_t cctWW = 0, cctCW = 0;
if (hasWhite()) c = autoWhiteCalc(c);
@ -342,7 +342,7 @@ void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) {
}
// returns original color if global buffering is enabled, else returns lossly restored color from bus
uint32_t IRAM_ATTR BusDigital::getPixelColor(uint16_t pix) const {
uint32_t IRAM_ATTR BusDigital::getPixelColor(unsigned pix) const {
if (!_valid) return 0;
if (_data) {
size_t offset = pix * getNumberOfChannels();
@ -501,7 +501,7 @@ BusPwm::BusPwm(BusConfig &bc)
DEBUG_PRINTF_P(PSTR("%successfully inited PWM strip with type %u, frequency %u, bit depth %u and pins %u,%u,%u,%u,%u\n"), _valid?"S":"Uns", bc.type, _frequency, _depth, _pins[0], _pins[1], _pins[2], _pins[3], _pins[4]);
}
void BusPwm::setPixelColor(uint16_t pix, uint32_t c) {
void BusPwm::setPixelColor(unsigned pix, uint32_t c) {
if (pix != 0 || !_valid) return; //only react to first pixel
if (_type != TYPE_ANALOG_3CH) c = autoWhiteCalc(c);
if (Bus::_cct >= 1900 && (_type == TYPE_ANALOG_3CH || _type == TYPE_ANALOG_4CH)) {
@ -538,7 +538,7 @@ void BusPwm::setPixelColor(uint16_t pix, uint32_t c) {
}
//does no index check
uint32_t BusPwm::getPixelColor(uint16_t pix) const {
uint32_t BusPwm::getPixelColor(unsigned pix) const {
if (!_valid) return 0;
// TODO getting the reverse from CCT is involved (a quick approximation when CCT blending is ste to 0 implemented)
switch (_type) {
@ -674,7 +674,7 @@ BusOnOff::BusOnOff(BusConfig &bc)
DEBUG_PRINTF_P(PSTR("%successfully inited On/Off strip with pin %u\n"), _valid?"S":"Uns", _pin);
}
void BusOnOff::setPixelColor(uint16_t pix, uint32_t c) {
void BusOnOff::setPixelColor(unsigned pix, uint32_t c) {
if (pix != 0 || !_valid) return; //only react to first pixel
c = autoWhiteCalc(c);
uint8_t r = R(c);
@ -684,7 +684,7 @@ void BusOnOff::setPixelColor(uint16_t pix, uint32_t c) {
_data[0] = bool(r|g|b|w) && bool(_bri) ? 0xFF : 0;
}
uint32_t BusOnOff::getPixelColor(uint16_t pix) const {
uint32_t BusOnOff::getPixelColor(unsigned pix) const {
if (!_valid) return 0;
return RGBW32(_data[0], _data[0], _data[0], _data[0]);
}
@ -734,7 +734,7 @@ BusNetwork::BusNetwork(BusConfig &bc)
DEBUG_PRINTF_P(PSTR("%successfully inited virtual strip with type %u and IP %u.%u.%u.%u\n"), _valid?"S":"Uns", bc.type, bc.pins[0], bc.pins[1], bc.pins[2], bc.pins[3]);
}
void BusNetwork::setPixelColor(uint16_t pix, uint32_t c) {
void BusNetwork::setPixelColor(unsigned pix, uint32_t c) {
if (!_valid || pix >= _len) return;
if (_hasWhite) c = autoWhiteCalc(c);
if (Bus::_cct >= 1900) c = colorBalanceFromKelvin(Bus::_cct, c); //color correction from CCT
@ -745,7 +745,7 @@ void BusNetwork::setPixelColor(uint16_t pix, uint32_t c) {
if (_hasWhite) _data[offset+3] = W(c);
}
uint32_t BusNetwork::getPixelColor(uint16_t pix) const {
uint32_t BusNetwork::getPixelColor(unsigned pix) const {
if (!_valid || pix >= _len) return 0;
unsigned offset = pix * _UDPchannels;
return RGBW32(_data[offset], _data[offset+1], _data[offset+2], (hasWhite() ? _data[offset+3] : 0));
@ -952,7 +952,7 @@ void BusManager::setStatusPixel(uint32_t c) {
}
}
void IRAM_ATTR BusManager::setPixelColor(uint16_t pix, uint32_t c) {
void IRAM_ATTR BusManager::setPixelColor(unsigned pix, uint32_t c) {
for (unsigned i = 0; i < numBusses; i++) {
unsigned bstart = busses[i]->getStart();
if (pix < bstart || pix >= bstart + busses[i]->getLength()) continue;
@ -975,7 +975,7 @@ void BusManager::setSegmentCCT(int16_t cct, bool allowWBCorrection) {
Bus::setCCT(cct);
}
uint32_t BusManager::getPixelColor(uint16_t pix) {
uint32_t BusManager::getPixelColor(unsigned pix) {
for (unsigned i = 0; i < numBusses; i++) {
unsigned bstart = busses[i]->getStart();
if (!busses[i]->containsPixel(pix)) continue;

View File

@ -82,10 +82,10 @@ class Bus {
virtual void show() = 0;
virtual bool canShow() const { return true; }
virtual void setStatusPixel(uint32_t c) {}
virtual void setPixelColor(uint16_t pix, uint32_t c) = 0;
virtual void setPixelColor(unsigned pix, uint32_t c) = 0;
virtual void setBrightness(uint8_t b) { _bri = b; };
virtual void setColorOrder(uint8_t co) {}
virtual uint32_t getPixelColor(uint16_t pix) const { return 0; }
virtual uint32_t getPixelColor(unsigned pix) const { return 0; }
virtual uint8_t getPins(uint8_t* pinArray = nullptr) const { return 0; }
virtual uint16_t getLength() const { return isOk() ? _len : 0; }
virtual uint8_t getColorOrder() const { return COL_ORDER_RGB; }
@ -203,9 +203,9 @@ class BusDigital : public Bus {
bool canShow() const override;
void setBrightness(uint8_t b) override;
void setStatusPixel(uint32_t c) override;
[[gnu::hot]] void setPixelColor(uint16_t pix, uint32_t c) override;
[[gnu::hot]] void setPixelColor(unsigned pix, uint32_t c) override;
void setColorOrder(uint8_t colorOrder) override;
[[gnu::hot]] uint32_t getPixelColor(uint16_t pix) const override;
[[gnu::hot]] uint32_t getPixelColor(unsigned pix) const override;
uint8_t getColorOrder() const override { return _colorOrder; }
uint8_t getPins(uint8_t* pinArray = nullptr) const override;
uint8_t skippedLeds() const override { return _skip; }
@ -251,8 +251,8 @@ class BusPwm : public Bus {
BusPwm(BusConfig &bc);
~BusPwm() { cleanup(); }
void setPixelColor(uint16_t pix, uint32_t c) override;
uint32_t getPixelColor(uint16_t pix) const override; //does no index check
void setPixelColor(unsigned pix, uint32_t c) override;
uint32_t getPixelColor(unsigned pix) const override; //does no index check
uint8_t getPins(uint8_t* pinArray = nullptr) const override;
uint16_t getFrequency() const override { return _frequency; }
void show() override;
@ -278,8 +278,8 @@ class BusOnOff : public Bus {
BusOnOff(BusConfig &bc);
~BusOnOff() { cleanup(); }
void setPixelColor(uint16_t pix, uint32_t c) override;
uint32_t getPixelColor(uint16_t pix) const override;
void setPixelColor(unsigned pix, uint32_t c) override;
uint32_t getPixelColor(unsigned pix) const override;
uint8_t getPins(uint8_t* pinArray) const override;
void show() override;
void cleanup() { PinManager::deallocatePin(_pin, PinOwner::BusOnOff); }
@ -298,8 +298,8 @@ class BusNetwork : public Bus {
~BusNetwork() { cleanup(); }
bool canShow() const override { return !_broadcastLock; } // this should be a return value from UDP routine if it is still sending data out
void setPixelColor(uint16_t pix, uint32_t c) override;
uint32_t getPixelColor(uint16_t pix) const override;
void setPixelColor(unsigned pix, uint32_t c) override;
uint32_t getPixelColor(unsigned pix) const override;
uint8_t getPins(uint8_t* pinArray = nullptr) const override;
void show() override;
void cleanup();
@ -384,13 +384,13 @@ class BusManager {
static void show();
static bool canAllShow();
static void setStatusPixel(uint32_t c);
[[gnu::hot]] static void setPixelColor(uint16_t pix, uint32_t c);
[[gnu::hot]] static void setPixelColor(unsigned pix, uint32_t c);
static void setBrightness(uint8_t b);
// for setSegmentCCT(), cct can only be in [-1,255] range; allowWBCorrection will convert it to K
// WARNING: setSegmentCCT() is a misleading name!!! much better would be setGlobalCCT() or just setCCT()
static void setSegmentCCT(int16_t cct, bool allowWBCorrection = false);
static inline void setMilliampsMax(uint16_t max) { _milliAmpsMax = max;}
static uint32_t getPixelColor(uint16_t pix);
[[gnu::hot]] static uint32_t getPixelColor(unsigned pix);
static inline int16_t getSegmentCCT() { return Bus::getCCT(); }
static Bus* getBus(uint8_t busNr);

View File

@ -96,7 +96,7 @@ uint32_t color_fade(uint32_t c1, uint8_t amount, bool video)
}
// 1:1 replacement of fastled function optimized for ESP, slightly faster, more accurate and uses less flash (~ -200bytes)
CRGB ColorFromPaletteWLED(const CRGBPalette16& pal, unsigned index, uint8_t brightness, TBlendType blendType)
uint32_t ColorFromPaletteWLED(const CRGBPalette16& pal, unsigned index, uint8_t brightness, TBlendType blendType)
{
if (blendType == LINEARBLEND_NOWRAP) {
index = (index*240) >> 8; // Blend range is affected by lo4 blend of values, remap to avoid wrapping
@ -121,7 +121,7 @@ CRGB ColorFromPaletteWLED(const CRGBPalette16& pal, unsigned index, uint8_t brig
green1 = (green1 * scale) >> 8;
blue1 = (blue1 * scale) >> 8;
}
return CRGB((uint8_t)red1, (uint8_t)green1, (uint8_t)blue1);
return RGBW32(red1,green1,blue1,0);
}
void setRandomColor(byte* rgb)

View File

@ -68,6 +68,64 @@ typedef struct WiFiConfig {
//colors.cpp
#define ColorFromPalette ColorFromPaletteWLED // override fastled version
// CRGBW can be used to manipulate 32bit colors faster. However: if it is passed to functions, it adds overhead compared to a uint32_t color
// use with caution and pay attention to flash size. Usually converting a uint32_t to CRGBW to extract r, g, b, w values is slower than using bitshifts
// it can be useful to avoid back and forth conversions between uint32_t and fastled CRGB
struct CRGBW {
union {
uint32_t color32; // Access as a 32-bit value (0xWWRRGGBB)
uint8_t raw[4]; // Access as an array in the order B, G, R, W
struct {
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t w;
};
};
// Default constructor
inline CRGBW() __attribute__((always_inline)) = default;
// Constructor from a 32-bit color (0xWWRRGGBB)
constexpr CRGBW(uint32_t color) __attribute__((always_inline)) : color32(color) {}
// Constructor with r, g, b, w values
constexpr CRGBW(uint8_t red, uint8_t green, uint8_t blue, uint8_t white = 0) __attribute__((always_inline)) : r(red), g(green), b(blue), w(white) {}
// Constructor from CRGB
constexpr CRGBW(CRGB rgb) __attribute__((always_inline)) : r(rgb.r), g(rgb.g), b(rgb.b), w(0) {}
// Access as an array
inline const uint8_t& operator[] (uint8_t x) const __attribute__((always_inline)) { return raw[x]; }
// Assignment from 32-bit color
inline CRGBW& operator=(uint32_t color) __attribute__((always_inline)) { color32 = color; return *this; }
// Assignment from r, g, b, w
inline CRGBW& operator=(const CRGB& rgb) __attribute__((always_inline)) { r = rgb.r; g = rgb.g; b = rgb.b; w = 0; return *this; }
// Conversion operator to uint32_t
inline operator uint32_t() const __attribute__((always_inline)) {
return color32;
}
/*
// Conversion operator to CRGB
inline operator CRGB() const __attribute__((always_inline)) {
return CRGB(r, g, b);
}
CRGBW& scale32 (uint8_t scaledown) // 32bit math
{
if (color32 == 0) return *this; // 2 extra instructions, worth it if called a lot on black (which probably is true) adding check if scaledown is zero adds much more overhead as its 8bit
uint32_t scale = scaledown + 1;
uint32_t rb = (((color32 & 0x00FF00FF) * scale) >> 8) & 0x00FF00FF; // scale red and blue
uint32_t wg = (((color32 & 0xFF00FF00) >> 8) * scale) & 0xFF00FF00; // scale white and green
color32 = rb | wg;
return *this;
}*/
};
struct CHSV32 { // 32bit HSV color with 16bit hue for more accurate conversions
union {
struct {
@ -106,7 +164,7 @@ class NeoGammaWLEDMethod {
[[gnu::hot]] uint32_t color_blend(uint32_t, uint32_t, uint16_t, bool b16=false);
[[gnu::hot]] uint32_t color_add(uint32_t, uint32_t, bool preserveCR = false);
[[gnu::hot]] uint32_t color_fade(uint32_t c1, uint8_t amount, bool video=false);
[[gnu::hot]] CRGB ColorFromPaletteWLED(const CRGBPalette16 &pal, unsigned index, uint8_t brightness = (uint8_t)255U, TBlendType blendType = LINEARBLEND);
[[gnu::hot]] uint32_t ColorFromPaletteWLED(const CRGBPalette16 &pal, unsigned index, uint8_t brightness = (uint8_t)255U, TBlendType blendType = LINEARBLEND);
CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette);
CRGBPalette16 generateRandomPalette();
inline uint32_t colorFromRgbw(byte* rgbw) { return uint32_t((byte(rgbw[3]) << 24) | (byte(rgbw[0]) << 16) | (byte(rgbw[1]) << 8) | (byte(rgbw[2]))); }