1 #define FASTLED_INTERNAL
2 #define __PROG_TYPES_COMPAT__
8 FASTLED_NAMESPACE_BEGIN
13 const struct CRGB& color)
15 for(
int i = 0; i < numToFill; i++) {
21 const struct CHSV& hsvColor)
23 for(
int i = 0; i < numToFill; i++) {
24 targetArray[i] = hsvColor;
43 for(
int i = 0; i < numToFill; i++) {
57 for(
int i = 0; i < numToFill; i++) {
64 void fill_gradient_RGB(
CRGB* leds,
65 uint16_t startpos,
CRGB startcolor,
66 uint16_t endpos,
CRGB endcolor )
69 if( endpos < startpos ) {
72 endcolor = startcolor;
82 rdistance87 = (endcolor.r - startcolor.r) << 7;
83 gdistance87 = (endcolor.g - startcolor.g) << 7;
84 bdistance87 = (endcolor.b - startcolor.b) << 7;
86 uint16_t pixeldistance = endpos - startpos;
87 int16_t divisor = pixeldistance ? pixeldistance : 1;
89 saccum87 rdelta87 = rdistance87 / divisor;
90 saccum87 gdelta87 = gdistance87 / divisor;
91 saccum87 bdelta87 = bdistance87 / divisor;
97 accum88 r88 = startcolor.r << 8;
98 accum88 g88 = startcolor.g << 8;
99 accum88 b88 = startcolor.b << 8;
100 for( uint16_t i = startpos; i <= endpos; i++) {
101 leds[i] =
CRGB( r88 >> 8, g88 >> 8, b88 >> 8);
111 fill_gradient( FastLED[0].leds(), FastLED[0].size(), c1, c2);
116 fill_gradient( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3);
121 fill_gradient( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3, c4);
124 void fill_gradient_RGB(
const CRGB& c1,
const CRGB& c2)
126 fill_gradient_RGB( FastLED[0].leds(), FastLED[0].size(), c1, c2);
129 void fill_gradient_RGB(
const CRGB& c1,
const CRGB& c2,
const CRGB& c3)
131 fill_gradient_RGB( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3);
134 void fill_gradient_RGB(
const CRGB& c1,
const CRGB& c2,
const CRGB& c3,
const CRGB& c4)
136 fill_gradient_RGB( FastLED[0].leds(), FastLED[0].size(), c1, c2, c3, c4);
143 void fill_gradient_RGB(
CRGB* leds, uint16_t numLeds,
const CRGB& c1,
const CRGB& c2)
145 uint16_t last = numLeds - 1;
146 fill_gradient_RGB( leds, 0, c1, last, c2);
150 void fill_gradient_RGB(
CRGB* leds, uint16_t numLeds,
const CRGB& c1,
const CRGB& c2,
const CRGB& c3)
152 uint16_t half = (numLeds / 2);
153 uint16_t last = numLeds - 1;
154 fill_gradient_RGB( leds, 0, c1, half, c2);
155 fill_gradient_RGB( leds, half, c2, last, c3);
158 void fill_gradient_RGB(
CRGB* leds, uint16_t numLeds,
const CRGB& c1,
const CRGB& c2,
const CRGB& c3,
const CRGB& c4)
160 uint16_t onethird = (numLeds / 3);
161 uint16_t twothirds = ((numLeds * 2) / 3);
162 uint16_t last = numLeds - 1;
163 fill_gradient_RGB( leds, 0, c1, onethird, c2);
164 fill_gradient_RGB( leds, onethird, c2, twothirds, c3);
165 fill_gradient_RGB( leds, twothirds, c3, last, c4);
171 void nscale8_video(
CRGB* leds, uint16_t num_leds, uint8_t scale)
173 for( uint16_t i = 0; i < num_leds; i++) {
178 void fade_video(
CRGB* leds, uint16_t num_leds, uint8_t fadeBy)
180 nscale8_video( leds, num_leds, 255 - fadeBy);
183 void fadeLightBy(
CRGB* leds, uint16_t num_leds, uint8_t fadeBy)
185 nscale8_video( leds, num_leds, 255 - fadeBy);
189 void fadeToBlackBy(
CRGB* leds, uint16_t num_leds, uint8_t fadeBy)
191 nscale8( leds, num_leds, 255 - fadeBy);
194 void fade_raw(
CRGB* leds, uint16_t num_leds, uint8_t fadeBy)
196 nscale8( leds, num_leds, 255 - fadeBy);
199 void nscale8_raw(
CRGB* leds, uint16_t num_leds, uint8_t scale)
201 nscale8( leds, num_leds, scale);
204 void nscale8(
CRGB* leds, uint16_t num_leds, uint8_t scale)
206 for( uint16_t i = 0; i < num_leds; i++) {
211 void fadeUsingColor(
CRGB* leds, uint16_t numLeds,
const CRGB& colormask)
218 for( uint16_t i = 0; i < numLeds; i++) {
221 leds[i].b =
scale8 ( leds[i].b, fb);
228 if( amountOfOverlay == 0) {
232 if( amountOfOverlay == 255) {
237 fract8 amountOfKeep = 255 - amountOfOverlay;
253 void nblend(
CRGB* existing,
CRGB* overlay, uint16_t count,
fract8 amountOfOverlay)
255 for( uint16_t i = count; i; i--) {
256 nblend( *existing, *overlay, amountOfOverlay);
265 nblend( nu, p2, amountOfP2);
271 for( uint16_t i = 0; i < count; i++) {
272 dest[i] = blend(src1[i], src2[i], amountOfsrc2);
279 CHSV& nblend(
CHSV& existing,
const CHSV& overlay,
fract8 amountOfOverlay, TGradientDirectionCode directionCode)
281 if( amountOfOverlay == 0) {
285 if( amountOfOverlay == 255) {
290 fract8 amountOfKeep = 255 - amountOfOverlay;
292 uint8_t huedelta8 = overlay.hue - existing.hue;
294 if( directionCode == SHORTEST_HUES ) {
295 directionCode = FORWARD_HUES;
296 if( huedelta8 > 127) {
297 directionCode = BACKWARD_HUES;
301 if( directionCode == LONGEST_HUES ) {
302 directionCode = FORWARD_HUES;
303 if( huedelta8 < 128) {
304 directionCode = BACKWARD_HUES;
308 if( directionCode == FORWARD_HUES) {
309 existing.hue = existing.hue +
scale8( huedelta8, amountOfOverlay);
313 huedelta8 = -huedelta8;
314 existing.hue = existing.hue -
scale8( huedelta8, amountOfOverlay);
329 void nblend(
CHSV* existing,
CHSV* overlay, uint16_t count,
fract8 amountOfOverlay, TGradientDirectionCode directionCode )
331 if(existing == overlay)
return;
332 for( uint16_t i = count; i; i--) {
333 nblend( *existing, *overlay, amountOfOverlay, directionCode);
339 CHSV blend(
const CHSV& p1,
const CHSV& p2,
fract8 amountOfP2, TGradientDirectionCode directionCode )
342 nblend( nu, p2, amountOfP2, directionCode);
346 CHSV* blend(
const CHSV* src1,
const CHSV* src2,
CHSV* dest, uint16_t count,
fract8 amountOfsrc2, TGradientDirectionCode directionCode )
348 for( uint16_t i = 0; i < count; i++) {
349 dest[i] = blend(src1[i], src2[i], amountOfsrc2, directionCode);
358 uint16_t XY( uint8_t, uint8_t);
374 void blur1d(
CRGB* leds, uint16_t numLeds,
fract8 blur_amount)
376 uint8_t keep = 255 - blur_amount;
377 uint8_t seep = blur_amount >> 1;
378 CRGB carryover = CRGB::Black;
379 for( uint16_t i = 0; i < numLeds; i++) {
385 if( i) leds[i-1] += part;
391 void blur2d(
CRGB* leds, uint8_t width, uint8_t height,
fract8 blur_amount)
393 blurRows(leds, width, height, blur_amount);
394 blurColumns(leds, width, height, blur_amount);
398 void blurRows(
CRGB* leds, uint8_t width, uint8_t height,
fract8 blur_amount)
400 for( uint8_t row = 0; row < height; row++) {
401 CRGB* rowbase = leds + (row * width);
402 blur1d( rowbase, width, blur_amount);
407 void blurColumns(
CRGB* leds, uint8_t width, uint8_t height,
fract8 blur_amount)
410 uint8_t keep = 255 - blur_amount;
411 uint8_t seep = blur_amount >> 1;
412 for( uint8_t col = 0; col < width; col++) {
413 CRGB carryover = CRGB::Black;
414 for( uint8_t i = 0; i < height; i++) {
415 CRGB cur = leds[XY(col,i)];
420 if( i) leds[XY(col,i-1)] += part;
421 leds[XY(col,i)] = cur;
440 CRGB HeatColor( uint8_t temperature)
451 uint8_t heatramp = t192 & 0x3F;
459 heatcolor.b = heatramp;
461 }
else if( t192 & 0x40 ) {
464 heatcolor.g = heatramp;
469 heatcolor.r = heatramp;
482 inline uint8_t lsrX4( uint8_t dividend)
__attribute__((always_inline));
483 inline uint8_t lsrX4( uint8_t dividend)
497 CRGB ColorFromPalette(
const CRGBPalette16& pal, uint8_t index, uint8_t brightness, TBlendType blendType)
500 uint8_t hi4 = lsrX4(index);
501 uint8_t lo4 = index & 0x0F;
507 uint8_t hi4XsizeofCRGB = hi4 *
sizeof(
CRGB);
509 const CRGB* entry = (
CRGB*)( (uint8_t*)(&(pal[0])) + hi4XsizeofCRGB);
511 uint8_t blend = lo4 && (blendType != NOBLEND);
513 uint8_t red1 = entry->red;
514 uint8_t green1 = entry->green;
515 uint8_t blue1 = entry->blue;
526 uint8_t f2 = lo4 << 4;
527 uint8_t f1 = 255 - f2;
530 uint8_t red2 = entry->red;
535 uint8_t green2 = entry->green;
540 uint8_t blue2 = entry->blue;
548 if( brightness != 255) {
555 #if !(FASTLED_SCALE8_FIXED==1)
561 #if !(FASTLED_SCALE8_FIXED==1)
567 #if !(FASTLED_SCALE8_FIXED==1)
579 return CRGB( red1, green1, blue1);
582 CRGB ColorFromPalette(
const TProgmemRGBPalette16& pal, uint8_t index, uint8_t brightness, TBlendType blendType)
585 uint8_t hi4 = lsrX4(index);
586 uint8_t lo4 = index & 0x0F;
588 CRGB entry = FL_PGM_READ_DWORD_NEAR( &(pal[0]) + hi4 );
591 uint8_t red1 = entry.red;
592 uint8_t green1 = entry.green;
593 uint8_t blue1 = entry.blue;
595 uint8_t blend = lo4 && (blendType != NOBLEND);
600 entry = FL_PGM_READ_DWORD_NEAR( &(pal[0]) );
602 entry = FL_PGM_READ_DWORD_NEAR( &(pal[1]) + hi4 );
605 uint8_t f2 = lo4 << 4;
606 uint8_t f1 = 255 - f2;
608 uint8_t red2 = entry.red;
613 uint8_t green2 = entry.green;
618 uint8_t blue2 = entry.blue;
626 if( brightness != 255) {
633 #if !(FASTLED_SCALE8_FIXED==1)
639 #if !(FASTLED_SCALE8_FIXED==1)
645 #if !(FASTLED_SCALE8_FIXED==1)
657 return CRGB( red1, green1, blue1);
661 CRGB ColorFromPalette(
const CRGBPalette32& pal, uint8_t index, uint8_t brightness, TBlendType blendType)
671 uint8_t lo3 = index & 0x07;
677 uint8_t hi5XsizeofCRGB = hi5 *
sizeof(
CRGB);
679 const CRGB* entry = (
CRGB*)( (uint8_t*)(&(pal[0])) + hi5XsizeofCRGB);
681 uint8_t red1 = entry->red;
682 uint8_t green1 = entry->green;
683 uint8_t blue1 = entry->blue;
685 uint8_t blend = lo3 && (blendType != NOBLEND);
695 uint8_t f2 = lo3 << 5;
696 uint8_t f1 = 255 - f2;
698 uint8_t red2 = entry->red;
703 uint8_t green2 = entry->green;
708 uint8_t blue2 = entry->blue;
717 if( brightness != 255) {
724 #if !(FASTLED_SCALE8_FIXED==1)
730 #if !(FASTLED_SCALE8_FIXED==1)
736 #if !(FASTLED_SCALE8_FIXED==1)
748 return CRGB( red1, green1, blue1);
752 CRGB ColorFromPalette(
const TProgmemRGBPalette32& pal, uint8_t index, uint8_t brightness, TBlendType blendType)
762 uint8_t lo3 = index & 0x07;
764 CRGB entry = FL_PGM_READ_DWORD_NEAR( &(pal[0]) + hi5);
766 uint8_t red1 = entry.red;
767 uint8_t green1 = entry.green;
768 uint8_t blue1 = entry.blue;
770 uint8_t blend = lo3 && (blendType != NOBLEND);
775 entry = FL_PGM_READ_DWORD_NEAR( &(pal[0]) );
777 entry = FL_PGM_READ_DWORD_NEAR( &(pal[1]) + hi5 );
780 uint8_t f2 = lo3 << 5;
781 uint8_t f1 = 255 - f2;
783 uint8_t red2 = entry.red;
788 uint8_t green2 = entry.green;
793 uint8_t blue2 = entry.blue;
801 if( brightness != 255) {
808 #if !(FASTLED_SCALE8_FIXED==1)
814 #if !(FASTLED_SCALE8_FIXED==1)
820 #if !(FASTLED_SCALE8_FIXED==1)
832 return CRGB( red1, green1, blue1);
837 CRGB ColorFromPalette(
const CRGBPalette256& pal, uint8_t index, uint8_t brightness, TBlendType)
839 const CRGB* entry = &(pal[0]) + index;
841 uint8_t red = entry->red;
842 uint8_t green = entry->green;
843 uint8_t blue = entry->blue;
845 if( brightness != 255) {
853 return CRGB( red, green, blue);
857 CHSV ColorFromPalette(
const struct CHSVPalette16& pal, uint8_t index, uint8_t brightness, TBlendType blendType)
860 uint8_t hi4 = lsrX4(index);
861 uint8_t lo4 = index & 0x0F;
864 const CHSV* entry = &(pal[0]) + hi4;
866 uint8_t hue1 = entry->hue;
867 uint8_t sat1 = entry->sat;
868 uint8_t val1 = entry->val;
870 uint8_t blend = lo4 && (blendType != NOBLEND);
880 uint8_t f2 = lo4 << 4;
881 uint8_t f1 = 255 - f2;
883 uint8_t hue2 = entry->hue;
884 uint8_t sat2 = entry->sat;
885 uint8_t val2 = entry->val;
898 if( sat1 == 0 || val1 == 0) {
904 if( sat2 == 0 || val2 == 0) {
921 uint8_t deltaHue = (uint8_t)(hue2 - hue1);
922 if( deltaHue & 0x80 ) {
924 hue1 -=
scale8( 255 - deltaHue, f2);
927 hue1 +=
scale8( deltaHue, f2);
933 if( brightness != 255) {
937 return CHSV( hue1, sat1, val1);
941 CHSV ColorFromPalette(
const struct CHSVPalette32& pal, uint8_t index, uint8_t brightness, TBlendType blendType)
951 uint8_t lo3 = index & 0x07;
953 uint8_t hi5XsizeofCHSV = hi5 *
sizeof(
CHSV);
954 const CHSV* entry = (
CHSV*)( (uint8_t*)(&(pal[0])) + hi5XsizeofCHSV);
956 uint8_t hue1 = entry->hue;
957 uint8_t sat1 = entry->sat;
958 uint8_t val1 = entry->val;
960 uint8_t blend = lo3 && (blendType != NOBLEND);
970 uint8_t f2 = lo3 << 5;
971 uint8_t f1 = 255 - f2;
973 uint8_t hue2 = entry->hue;
974 uint8_t sat2 = entry->sat;
975 uint8_t val2 = entry->val;
988 if( sat1 == 0 || val1 == 0) {
994 if( sat2 == 0 || val2 == 0) {
1011 uint8_t deltaHue = (uint8_t)(hue2 - hue1);
1012 if( deltaHue & 0x80 ) {
1014 hue1 -=
scale8( 255 - deltaHue, f2);
1017 hue1 +=
scale8( deltaHue, f2);
1023 if( brightness != 255) {
1027 return CHSV( hue1, sat1, val1);
1030 CHSV ColorFromPalette(
const struct CHSVPalette256& pal, uint8_t index, uint8_t brightness, TBlendType)
1032 CHSV hsv = *( &(pal[0]) + index );
1034 if( brightness != 255) {
1044 for(
int i = 0; i < 256; i++) {
1045 destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal16, i);
1051 for(
int i = 0; i < 256; i++) {
1052 destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal16, i);
1059 for( uint8_t i = 0; i < 16; i++) {
1061 destpal32[j+0] = srcpal16[i];
1062 destpal32[j+1] = srcpal16[i];
1068 for( uint8_t i = 0; i < 16; i++) {
1070 destpal32[j+0] = srcpal16[i];
1071 destpal32[j+1] = srcpal16[i];
1077 for(
int i = 0; i < 256; i++) {
1078 destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal32, i);
1084 for(
int i = 0; i < 256; i++) {
1085 destpal256[(uint8_t)(i)] = ColorFromPalette( srcpal32, i);
1105 uint8_t changes = 0;
1107 p1 = (uint8_t*)current.entries;
1108 p2 = (uint8_t*)target.entries;
1111 for( uint8_t i = 0; i < totalChannels; i++) {
1113 if( p1[i] == p2[i] ) {
continue; }
1116 if( p1[i] < p2[i] ) { p1[i]++; changes++; }
1120 if( p1[i] > p2[i] ) {
1122 if( p1[i] > p2[i] ) { p1[i]--; }
1126 if( changes >= maxChanges) {
break; }
1131 uint8_t applyGamma_video( uint8_t brightness,
float gamma)
1135 orig = (float)(brightness) / (255.0);
1136 adj = pow( orig, gamma) * (255.0);
1137 uint8_t result = (uint8_t)(adj);
1138 if( (brightness > 0) && (result == 0)) {
1144 CRGB applyGamma_video(
const CRGB& orig,
float gamma)
1147 adj.r = applyGamma_video( orig.r, gamma);
1148 adj.g = applyGamma_video( orig.g, gamma);
1149 adj.b = applyGamma_video( orig.b, gamma);
1153 CRGB applyGamma_video(
const CRGB& orig,
float gammaR,
float gammaG,
float gammaB)
1156 adj.r = applyGamma_video( orig.r, gammaR);
1157 adj.g = applyGamma_video( orig.g, gammaG);
1158 adj.b = applyGamma_video( orig.b, gammaB);
1162 CRGB& napplyGamma_video(
CRGB& rgb,
float gamma)
1164 rgb = applyGamma_video( rgb, gamma);
1168 CRGB& napplyGamma_video(
CRGB& rgb,
float gammaR,
float gammaG,
float gammaB)
1170 rgb = applyGamma_video( rgb, gammaR, gammaG, gammaB);
1174 void napplyGamma_video(
CRGB* rgbarray, uint16_t count,
float gamma)
1176 for( uint16_t i = 0; i < count; i++) {
1177 rgbarray[i] = applyGamma_video( rgbarray[i], gamma);
1181 void napplyGamma_video(
CRGB* rgbarray, uint16_t count,
float gammaR,
float gammaG,
float gammaB)
1183 for( uint16_t i = 0; i < count; i++) {
1184 rgbarray[i] = applyGamma_video( rgbarray[i], gammaR, gammaG, gammaB);
1189 FASTLED_NAMESPACE_END
Representation of an RGB pixel (Red, Green, Blue)
LIB8STATIC_ALWAYS_INLINE void cleanup_R1()
Clean up the r1 register after a series of *LEAVING_R1_DIRTY calls.
uint16_t accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
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 If you are doing several 'scale...
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 i...
uint8_t fract8
ANSI unsigned short _Fract.
CRGB & nscale8_video(uint8_t scaledown)
scale down a RGB to N 256ths of it's current brightness, using 'video' dimming rules, which means that unless the scale factor is ZERO each channel is guaranteed NOT to dim down to zero.
void fill_rainbow(struct CRGB *pFirstLED, int numToFill, uint8_t initialhue, uint8_t deltahue)
fill_rainbow - fill a range of LEDs with a rainbow of colors, at full saturation and full value (brig...
CRGB & nscale8(uint8_t scaledown)
scale down a RGB to N 256ths of it's current brightness, using 'plain math' dimming rules...
void fill_gradient(T *targetArray, uint16_t startpos, CHSV startcolor, uint16_t endpos, CHSV endcolor, TGradientDirectionCode directionCode=SHORTEST_HUES)
fill_gradient - fill an array of colors with a smooth HSV gradient between two specified HSV colors...
central include file for FastLED, defines the CFastLED class/object
__attribute__((always_inline)) inline void swapbits8(bitswap_type in
Do an 8byte by 8bit rotation.
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 ...
Representation of an HSV pixel (hue, saturation, value (aka brightness)).
FASTLED_NAMESPACE_BEGIN void fill_solid(struct CRGB *leds, int numToFill, const struct CRGB &color)
fill_solid - fill a range of LEDs with a solid color Example: fill_solid( leds, NUM_LEDS, CRGB(50,0,200));
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 If you are doing several 'scale8's in...