1#define FASTLED_INTERNAL
2#define __PROG_TYPES_COMPAT__
20 if (amountOfOverlay == 0) {
24 if (amountOfOverlay == 255) {
31 fract8 amountOfKeep = 255 - amountOfOverlay;
43 existing.red =
blend8(existing.red, overlay.red, amountOfOverlay);
44 existing.green =
blend8(existing.green, overlay.green, amountOfOverlay);
45 existing.blue =
blend8(existing.blue, overlay.blue, amountOfOverlay);
53 for (uint16_t i = count; i; --i) {
54 nblend(*existing, *overlay, amountOfOverlay);
62 nblend(nu, p2, amountOfP2);
68 for (uint16_t i = 0; i < count; ++i) {
69 dest[i] =
blend(src1[i], src2[i], amountOfsrc2);
76 if (amountOfOverlay == 0) {
80 if (amountOfOverlay == 255) {
85 fract8 amountOfKeep = 255 - amountOfOverlay;
87 uint8_t huedelta8 = overlay.hue - existing.hue;
91 if (huedelta8 > 127) {
98 if (huedelta8 < 128) {
104 existing.hue = existing.hue +
scale8(huedelta8, amountOfOverlay);
107 huedelta8 = -huedelta8;
108 existing.hue = existing.hue -
scale8(huedelta8, amountOfOverlay);
123 if (existing == overlay)
125 for (uint16_t i = count; i; --i) {
126 nblend(*existing, *overlay, amountOfOverlay, directionCode);
135 nblend(nu, p2, amountOfP2, directionCode);
141 for (uint16_t i = 0; i < count; ++i) {
142 dest[i] =
blend(src1[i], src2[i], amountOfsrc2, directionCode);
148 for (uint16_t i = 0; i < num_leds; ++i) {
170 for (uint16_t i = 0; i < num_leds; ++i) {
181 for (uint16_t i = 0; i < numLeds; ++i) {
209 uint8_t heatramp = t192 & 0x3F;
217 heatcolor.b = heatramp;
219 }
else if (t192 & 0x40) {
222 heatcolor.g = heatramp;
227 heatcolor.r = heatramp;
239inline uint8_t
lsrX4(uint8_t dividend) __attribute__((always_inline));
240inline uint8_t
lsrX4(uint8_t dividend) {
255 uint8_t index_5bit = (index >> 11);
257 uint8_t
offset = (uint8_t)(index >> 3);
259 const CRGB *entry = &(pal[0]) + index_5bit;
260 uint8_t red1 = entry->red;
261 uint8_t green1 = entry->green;
262 uint8_t blue1 = entry->blue;
266 if (index_5bit == 31) {
274 uint8_t f1 = 255 -
offset;
280 uint8_t red2 = entry->red;
281 uint8_t green2 = entry->green;
282 uint8_t blue2 = entry->blue;
296 return CRGB(red1, green1, blue1);
301 if (blendType == LINEARBLEND_NOWRAP) {
302 index =
map8(index, 0, 239);
307 uint8_t hi4 =
lsrX4(index);
308 uint8_t lo4 = index & 0x0F;
314 uint8_t hi4XsizeofCRGB = hi4 *
sizeof(
CRGB);
316 const CRGB *entry = (
CRGB *)((uint8_t *)(&(pal[0])) + hi4XsizeofCRGB);
318 uint8_t
blend = lo4 && (blendType != NOBLEND);
320 uint8_t red1 = entry->red;
321 uint8_t green1 = entry->green;
322 uint8_t blue1 = entry->blue;
332 uint8_t f2 = lo4 << 4;
333 uint8_t f1 = 255 - f2;
336 uint8_t red2 = entry->red;
341 uint8_t green2 = entry->green;
346 uint8_t blue2 = entry->blue;
362#if !(FASTLED_SCALE8_FIXED == 1)
368#if !(FASTLED_SCALE8_FIXED == 1)
374#if !(FASTLED_SCALE8_FIXED == 1)
386 return CRGB(red1, green1, blue1);
392 uint8_t index_4bit = index >> 12;
394 uint8_t
offset = (uint8_t)(index >> 4);
396 const CRGB *entry = &(pal[0]) + index_4bit;
397 uint8_t red1 = entry->red;
398 uint8_t green1 = entry->green;
399 uint8_t blue1 = entry->blue;
403 if (index_4bit == 15) {
411 uint8_t f1 = 255 -
offset;
417 uint8_t red2 = entry->red;
418 uint8_t green2 = entry->green;
419 uint8_t blue2 = entry->blue;
434 return CRGB(red1, green1, blue1);
439 if (blendType == LINEARBLEND_NOWRAP) {
440 index =
map8(index, 0, 239);
445 uint8_t hi4 =
lsrX4(index);
446 uint8_t lo4 = index & 0x0F;
450 uint8_t red1 = entry.red;
451 uint8_t green1 = entry.green;
452 uint8_t blue1 = entry.blue;
454 uint8_t
blend = lo4 && (blendType != NOBLEND);
464 uint8_t f2 = lo4 << 4;
465 uint8_t f1 = 255 - f2;
467 uint8_t red2 = entry.red;
472 uint8_t green2 = entry.green;
477 uint8_t blue2 = entry.blue;
493#if !(FASTLED_SCALE8_FIXED == 1)
499#if !(FASTLED_SCALE8_FIXED == 1)
505#if !(FASTLED_SCALE8_FIXED == 1)
517 return CRGB(red1, green1, blue1);
522 if (blendType == LINEARBLEND_NOWRAP) {
523 index =
map8(index, 0, 247);
535 uint8_t lo3 = index & 0x07;
541 uint8_t hi5XsizeofCRGB = hi5 *
sizeof(
CRGB);
543 const CRGB *entry = (
CRGB *)((uint8_t *)(&(pal[0])) + hi5XsizeofCRGB);
545 uint8_t red1 = entry->red;
546 uint8_t green1 = entry->green;
547 uint8_t blue1 = entry->blue;
549 uint8_t
blend = lo3 && (blendType != NOBLEND);
559 uint8_t f2 = lo3 << 5;
560 uint8_t f1 = 255 - f2;
562 uint8_t red2 = entry->red;
567 uint8_t green2 = entry->green;
572 uint8_t blue2 = entry->blue;
588#if !(FASTLED_SCALE8_FIXED == 1)
594#if !(FASTLED_SCALE8_FIXED == 1)
600#if !(FASTLED_SCALE8_FIXED == 1)
612 return CRGB(red1, green1, blue1);
617 if (blendType == LINEARBLEND_NOWRAP) {
618 index =
map8(index, 0, 247);
630 uint8_t lo3 = index & 0x07;
634 uint8_t red1 = entry.red;
635 uint8_t green1 = entry.green;
636 uint8_t blue1 = entry.blue;
638 uint8_t
blend = lo3 && (blendType != NOBLEND);
648 uint8_t f2 = lo3 << 5;
649 uint8_t f1 = 255 - f2;
651 uint8_t red2 = entry.red;
656 uint8_t green2 = entry.green;
661 uint8_t blue2 = entry.blue;
677#if !(FASTLED_SCALE8_FIXED == 1)
683#if !(FASTLED_SCALE8_FIXED == 1)
689#if !(FASTLED_SCALE8_FIXED == 1)
701 return CRGB(red1, green1, blue1);
706 const CRGB *entry = &(pal[0]) + index;
708 uint8_t red = entry->red;
709 uint8_t green = entry->green;
710 uint8_t blue = entry->blue;
720 return CRGB(red, green, blue);
726 uint8_t index_8bit = index >> 8;
728 uint8_t
offset = index & 0xff;
730 const CRGB *entry = &(pal[0]) + index_8bit;
731 uint8_t red1 = entry->red;
732 uint8_t green1 = entry->green;
733 uint8_t blue1 = entry->blue;
737 if (index_8bit == 255) {
745 uint8_t f1 = 255 -
offset;
751 uint8_t red2 = entry->red;
752 uint8_t green2 = entry->green;
753 uint8_t blue2 = entry->blue;
768 return CRGB(red1, green1, blue1);
773 if (blendType == LINEARBLEND_NOWRAP) {
774 index =
map8(index, 0, 239);
779 uint8_t hi4 =
lsrX4(index);
780 uint8_t lo4 = index & 0x0F;
783 const CHSV *entry = &(pal[0]) + hi4;
785 uint8_t hue1 = entry->hue;
786 uint8_t sat1 = entry->sat;
787 uint8_t val1 = entry->val;
789 uint8_t
blend = lo4 && (blendType != NOBLEND);
799 uint8_t f2 = lo4 << 4;
800 uint8_t f1 = 255 - f2;
802 uint8_t hue2 = entry->hue;
803 uint8_t sat2 = entry->sat;
804 uint8_t val2 = entry->val;
817 if (sat1 == 0 || val1 == 0) {
823 if (sat2 == 0 || val2 == 0) {
839 uint8_t deltaHue = (uint8_t)(hue2 - hue1);
840 if (deltaHue & 0x80) {
842 hue1 -=
scale8(256 - deltaHue, f2);
845 hue1 +=
scale8(deltaHue, f2);
855 return CHSV(hue1, sat1, val1);
860 if (blendType == LINEARBLEND_NOWRAP) {
861 index =
map8(index, 0, 247);
873 uint8_t lo3 = index & 0x07;
875 uint8_t hi5XsizeofCHSV = hi5 *
sizeof(
CHSV);
876 const CHSV *entry = (
CHSV *)((uint8_t *)(&(pal[0])) + hi5XsizeofCHSV);
878 uint8_t hue1 = entry->hue;
879 uint8_t sat1 = entry->sat;
880 uint8_t val1 = entry->val;
882 uint8_t
blend = lo3 && (blendType != NOBLEND);
892 uint8_t f2 = lo3 << 5;
893 uint8_t f1 = 255 - f2;
895 uint8_t hue2 = entry->hue;
896 uint8_t sat2 = entry->sat;
897 uint8_t val2 = entry->val;
910 if (sat1 == 0 || val1 == 0) {
916 if (sat2 == 0 || val2 == 0) {
932 uint8_t deltaHue = (uint8_t)(hue2 - hue1);
933 if (deltaHue & 0x80) {
935 hue1 -=
scale8(256 - deltaHue, f2);
938 hue1 +=
scale8(deltaHue, f2);
948 return CHSV(hue1, sat1, val1);
953 CHSV hsv = *(&(pal[0]) + index);
963 class CRGBPalette256 &destpal256) {
964 for (
int i = 0; i < 256; ++i) {
970 class CHSVPalette256 &destpal256) {
971 for (
int i = 0; i < 256; ++i) {
977 class CRGBPalette32 &destpal32) {
978 for (uint8_t i = 0; i < 16; ++i) {
980 destpal32[j + 0] = srcpal16[i];
981 destpal32[j + 1] = srcpal16[i];
986 class CHSVPalette32 &destpal32) {
987 for (uint8_t i = 0; i < 16; ++i) {
989 destpal32[j + 0] = srcpal16[i];
990 destpal32[j + 1] = srcpal16[i];
995 class CRGBPalette256 &destpal256) {
996 for (
int i = 0; i < 256; ++i) {
1002 class CHSVPalette256 &destpal256) {
1003 for (
int i = 0; i < 256; ++i) {
1010void SetupPartyColors(CRGBPalette16& pal)
1018 uint8_t maxChanges) {
1021 uint8_t changes = 0;
1023 p1 = (uint8_t *)current.entries;
1024 p2 = (uint8_t *)target.entries;
1026 const uint8_t totalChannels =
sizeof(CRGBPalette16);
1027 for (uint8_t i = 0; i < totalChannels; ++i) {
1029 if (p1[i] == p2[i]) {
1034 if (p1[i] < p2[i]) {
1041 if (p1[i] > p2[i]) {
1044 if (p1[i] > p2[i]) {
1050 if (changes >= maxChanges) {
1060 adj = pow(orig, gamma) * (255.0);
1061 uint8_t result = (uint8_t)(adj);
1096 for (uint16_t i = 0; i < count; ++i) {
1102 float gammaG,
float gammaB) {
1103 for (uint16_t i = 0; i < count; ++i) {
UISlider scale("Scale", 1.0f, 0.0f, 1.0f, 0.01f)
central include file for FastLED, defines the CFastLED class/object
UISlider brightness("Brightness", 255, 0, 255, 1)
uint32_t TProgmemRGBPalette32[32]
CRGBPalette32 entries stored in PROGMEM memory.
uint32_t TProgmemRGBPalette16[16]
CRGBPalette16 entries stored in PROGMEM memory.
UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f)
#define FL_PGM_READ_DWORD_NEAR(x)
Read a double word (32-bit) from PROGMEM memory.
Utility functions for color fill, palettes, blending, and more.
void fill_gradient(T *targetArray, uint16_t startpos, CHSV startcolor, uint16_t endpos, CHSV endcolor, TGradientDirectionCode directionCode=SHORTEST_HUES)
Fill a range of LEDs with a smooth HSV gradient between two HSV colors.
uint8_t fract8
ANSI: unsigned short _Fract.
LIB8STATIC uint8_t map8(uint8_t in, uint8_t rangeStart, uint8_t rangeEnd)
Map from one full-range 8-bit value into a narrower range of 8-bit values, possibly a range of hues.
LIB8STATIC uint8_t blend8(uint8_t a, uint8_t b, uint8_t amountOfB)
Blend a variable proportion (0-255) of one byte to another.
@ HUE_PURPLE
Purple (270°)
LIB8STATIC_ALWAYS_INLINE void cleanup_R1()
Clean up the r1 register after a series of *LEAVING_R1_DIRTY calls.
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_LEAVING_R1_DIRTY(uint8_t i, fract8 scale)
This version of scale8() does not clean up the R1 register on AVR.
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video_LEAVING_R1_DIRTY(uint8_t i, fract8 scale)
This version of scale8_video() does not clean up the R1 register on AVR.
LIB8STATIC void nscale8x3(uint8_t &r, uint8_t &g, uint8_t &b, fract8 scale)
Scale three one-byte values by a fourth one, which is treated as the numerator of a fraction whose de...
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video(uint8_t i, fract8 scale)
The "video" version of scale8() guarantees that the output will be only be zero if one or both of the...
LIB8STATIC void nscale8x3_video(uint8_t &r, uint8_t &g, uint8_t &b, fract8 scale)
Scale three one-byte values by a fourth one, which is treated as the numerator of a fraction whose de...
LIB8STATIC_ALWAYS_INLINE uint8_t scale8(uint8_t i, fract8 scale)
Scale one byte by a second one, which is treated as the numerator of a fraction whose denominator is ...
void fadeUsingColor(CRGB *leds, uint16_t numLeds, const CRGB &colormask)
TGradientDirectionCode
Hue direction for calculating fill gradients.
@ SHORTEST_HUES
Hue goes whichever way is shortest.
@ LONGEST_HUES
Hue goes whichever way is longest.
@ FORWARD_HUES
Hue always goes clockwise around the color wheel.
@ BACKWARD_HUES
Hue always goes counter-clockwise around the color wheel.
void UpscalePalette(const class CRGBPalette16 &srcpal16, class CRGBPalette256 &destpal256)
CRGB ColorFromPaletteExtended(const CRGBPalette32 &pal, uint16_t index, uint8_t brightness, TBlendType blendType)
uint8_t applyGamma_video(uint8_t brightness, float gamma)
CRGB ColorFromPalette(const CRGBPalette16 &pal, uint8_t index, uint8_t brightness, TBlendType blendType)
CRGB HeatColor(uint8_t temperature)
uint8_t lsrX4(uint8_t dividend)
Helper function to divide a number by 16, aka four logical shift right (LSR)'s.
void fadeToBlackBy(CRGB *leds, uint16_t num_leds, uint8_t fadeBy)
CRGB blend(const CRGB &p1, const CRGB &p2, fract8 amountOfP2)
void nblendPaletteTowardPalette(CRGBPalette16 ¤t, CRGBPalette16 &target, uint8_t maxChanges)
CRGB & nblend(CRGB &existing, const CRGB &overlay, fract8 amountOfOverlay)
void fade_raw(CRGB *leds, uint16_t num_leds, uint8_t fadeBy)
void fadeLightBy(CRGB *leds, uint16_t num_leds, uint8_t fadeBy)
void nscale8(CRGB *leds, uint16_t num_leds, uint8_t scale)
CRGB & napplyGamma_video(CRGB &rgb, float gamma)
void fade_video(CRGB *leds, uint16_t num_leds, uint8_t fadeBy)
void nscale8_video(CRGB *leds, uint16_t num_leds, uint8_t scale)
Implements a simple red square effect for 2D LED grids.
Representation of an HSV pixel (hue, saturation, value (aka brightness)).
Representation of an RGB pixel (Red, Green, Blue)