diff --git a/wled00/colors.cpp b/wled00/colors.cpp index f741e7a6..f1bbea0a 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -102,6 +102,40 @@ uint32_t WLED_O2_ATTR IRAM_ATTR_YN __attribute__((hot)) color_fade(uint32_t c1, uint32_t wg = (((c1 >> 8) & TWO_CHANNEL_MASK) * amount) & ~TWO_CHANNEL_MASK; // scale white and green return (rb | wg) + addRemains; } + +// +// overwrite FastLed colorFromPalette with an optimized version created by dedehai (https://github.com/Aircoookie/WLED/pull/4138) +// +// 1:1 replacement of fastled function optimized for ESP, slightly faster, more accurate and uses less flash (~ -200bytes) +CRGB IRAM_ATTR_YN __attribute__((hot)) 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 + } + unsigned hi4 = byte(index) >> 4; + const CRGB* entry = (CRGB*)((uint8_t*)(&(pal[0])) + (hi4 * sizeof(CRGB))); + unsigned red1 = entry->r; + unsigned green1 = entry->g; + unsigned blue1 = entry->b; + if (blendType != NOBLEND) { + if (hi4 == 15) entry = &(pal[0]); + else ++entry; + unsigned f2 = ((index & 0x0F) << 4) + 1; // +1 so we scale by 256 as a max value, then result can just be shifted by 8 + unsigned f1 = (257 - f2); // f2 is 1 minimum, so this is 256 max + red1 = (red1 * f1 + (unsigned)entry->r * f2) >> 8; + green1 = (green1 * f1 + (unsigned)entry->g * f2) >> 8; + blue1 = (blue1 * f1 + (unsigned)entry->b * f2) >> 8; + } + if (brightness < 255) { // note: zero checking could be done to return black but that is hardly ever used so it is omitted + uint32_t scale = brightness + 1; // adjust for rounding (bitshift) + red1 = (red1 * scale) >> 8; + green1 = (green1 * scale) >> 8; + blue1 = (blue1 * scale) >> 8; + } + return RGBW32(red1,green1,blue1,0); + //return CRGB(red1,green1,blue1); +} + #endif void setRandomColor(byte* rgb) diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 188c10ee..c5e95604 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -51,9 +51,16 @@ bool getJsonValue(const JsonVariant& element, DestType& destination, const Defau //colors.cpp #if !defined(ARDUINO_ARCH_ESP32) || !defined(WLEDMM_FASTPATH) || defined(WLEDMM_SAVE_FLASH) // WLEDMM: color utils moved into colorTools.hpp, so the compiler may inline these functions (faster) +#if !defined(FASTLED_VERSION) // pull in FastLED if we don't have it yet (we need the CRGB type) + #define FASTLED_INTERNAL + #include +#endif uint32_t __attribute__((const)) color_blend(uint32_t,uint32_t,uint_fast16_t,bool b16=false); // WLEDMM: added attribute const uint32_t __attribute__((const)) color_add(uint32_t,uint32_t, bool fast=false); // WLEDMM: added attribute const uint32_t __attribute__((const)) color_fade(uint32_t c1, uint8_t amount, bool video=false); +#undef ColorFromPalette // overwrite any existing override +CRGB __attribute__((hot,const)) ColorFromPaletteWLED(const CRGBPalette16& pal, unsigned index, uint8_t brightness=255, TBlendType blendType=LINEARBLEND); +#define ColorFromPalette ColorFromPaletteWLED // override fastled function #else #include "colorTools.hpp" #endif