diff --git a/usermods/Animated_Staircase/Animated_Staircase.h b/usermods/Animated_Staircase/Animated_Staircase.h index 5aa64631..0a545613 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.h +++ b/usermods/Animated_Staircase/Animated_Staircase.h @@ -103,7 +103,7 @@ class Animated_Staircase : public Usermod { void updateSegments() { mainSegmentId = strip.getMainSegmentId(); - WS2812FX::Segment* segments = strip.getSegments(); + Segment* segments = strip.getSegments(); for (int i = 0; i < MAX_NUM_SEGMENTS; i++, segments++) { if (!segments->isActive()) { maxSegmentId = i - 1; @@ -290,7 +290,7 @@ class Animated_Staircase : public Usermod { } } else { // Restore segment options - WS2812FX::Segment* segments = strip.getSegments(); + Segment* segments = strip.getSegments(); for (int i = 0; i < MAX_NUM_SEGMENTS; i++, segments++) { if (!segments->isActive()) { maxSegmentId = i - 1; diff --git a/usermods/EleksTube_IPS/TFTs.h b/usermods/EleksTube_IPS/TFTs.h index 0d52d46e..e614704f 100644 --- a/usermods/EleksTube_IPS/TFTs.h +++ b/usermods/EleksTube_IPS/TFTs.h @@ -355,7 +355,7 @@ public: // Color in grayscale bitmaps if Segment 1 exists // TODO If secondary and tertiary are black, color all in primary, // else color first three from Seg 1 color slots and last three from Seg 2 color slots - WS2812FX::Segment& seg1 = strip.getSegment(tubeSegment); + Segment& seg1 = strip.getSegment(tubeSegment); if (seg1.isActive()) { digitColor = strip.getPixelColor(seg1.start + digit); dimming = seg1.opacity; diff --git a/usermods/EleksTube_IPS/usermod_elekstube_ips.h b/usermods/EleksTube_IPS/usermod_elekstube_ips.h index 06c6ecc8..0f7d92e7 100644 --- a/usermods/EleksTube_IPS/usermod_elekstube_ips.h +++ b/usermods/EleksTube_IPS/usermod_elekstube_ips.h @@ -63,7 +63,7 @@ class ElekstubeIPSUsermod : public Usermod { if (!toki.isTick()) return; updateLocalTime(); - WS2812FX::Segment& seg1 = strip.getSegment(tfts.tubeSegment); + Segment& seg1 = strip.getSegment(tfts.tubeSegment); if (seg1.isActive()) { bool update = false; if (seg1.opacity != lastBri) update = true; diff --git a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h index 08d551be..238ec7d9 100644 --- a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h +++ b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h @@ -96,7 +96,7 @@ class StairwayWipeUsermod : public Usermod { resetTimebase(); //make sure wipe starts from beginning //set wipe direction - WS2812FX::Segment& seg = strip.getSegment(0); + Segment& seg = strip.getSegment(0); bool doReverse = (userVar0 == 2); seg.setOption(1, doReverse); diff --git a/usermods/stairway_wipe_basic/wled06_usermod.ino b/usermods/stairway_wipe_basic/wled06_usermod.ino index eeece443..c1264ebf 100644 --- a/usermods/stairway_wipe_basic/wled06_usermod.ino +++ b/usermods/stairway_wipe_basic/wled06_usermod.ino @@ -89,7 +89,7 @@ void startWipe() resetTimebase(); //make sure wipe starts from beginning //set wipe direction - WS2812FX::Segment& seg = strip.getSegment(0); + Segment& seg = strip.getSegment(0); bool doReverse = (userVar0 == 2); seg.setOption(1, doReverse); diff --git a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h index 34cace3c..85854c32 100644 --- a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h +++ b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h @@ -528,12 +528,12 @@ public: stateChanged = true; if (applyToAll) { for (byte i=0; i> 8); cycleTime += FRAMETIME*2; - uint32_t it = now / cycleTime; - uint32_t rem = now % cycleTime; + uint32_t it = strip.now / cycleTime; + uint32_t rem = strip.now % cycleTime; bool on = false; if (it != SEGENV.step //new iteration, force on state for one frame, even if set time is too brief @@ -66,9 +66,9 @@ uint16_t WS2812FX::blink(uint32_t color1, uint32_t color2, bool strobe, bool do_ if (color == color1 && do_palette) { for(uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } - } else fill(color); + } else strip.fill(color); return FRAMETIME; } @@ -77,7 +77,7 @@ uint16_t WS2812FX::blink(uint32_t color1, uint32_t color2, bool strobe, bool do_ /* * Normal blinking. 50% on/off time. */ -uint16_t WS2812FX::mode_blink(void) { +uint16_t mode_blink(void) { return blink(SEGCOLOR(0), SEGCOLOR(1), false, true); } static const char *_data_FX_MODE_BLINK PROGMEM = "Blink@!,;!,!,;!"; @@ -86,8 +86,8 @@ static const char *_data_FX_MODE_BLINK PROGMEM = "Blink@!,;!,!,;!"; /* * Classic Blink effect. Cycling through the rainbow. */ -uint16_t WS2812FX::mode_blink_rainbow(void) { - return blink(color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), false, false); +uint16_t mode_blink_rainbow(void) { + return blink(strip.color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), false, false); } static const char *_data_FX_MODE_BLINK_RAINBOW PROGMEM = "Blink Rainbow@Frequency,Blink duration;!,!,;!"; @@ -95,7 +95,7 @@ static const char *_data_FX_MODE_BLINK_RAINBOW PROGMEM = "Blink Rainbow@Frequenc /* * Classic Strobe effect. */ -uint16_t WS2812FX::mode_strobe(void) { +uint16_t mode_strobe(void) { return blink(SEGCOLOR(0), SEGCOLOR(1), true, true); } static const char *_data_FX_MODE_STROBE PROGMEM = "Strobe@!,;!,!,;!"; @@ -104,8 +104,8 @@ static const char *_data_FX_MODE_STROBE PROGMEM = "Strobe@!,;!,!,;!"; /* * Classic Strobe effect. Cycling through the rainbow. */ -uint16_t WS2812FX::mode_strobe_rainbow(void) { - return blink(color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), true, false); +uint16_t mode_strobe_rainbow(void) { + return blink(strip.color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), true, false); } static const char *_data_FX_MODE_STROBE_RAINBOW PROGMEM = "Strobe Rainbow@!,;,!,;!"; @@ -115,9 +115,9 @@ static const char *_data_FX_MODE_STROBE_RAINBOW PROGMEM = "Strobe Rainbow@!,;,!, * LEDs are turned on (color1) in sequence, then turned off (color2) in sequence. * if (bool rev == true) then LEDs are turned off in reverse order */ -uint16_t WS2812FX::color_wipe(bool rev, bool useRandomColors) { +uint16_t color_wipe(bool rev, bool useRandomColors) { uint32_t cycleTime = 750 + (255 - SEGMENT.speed)*150; - uint32_t perc = now % cycleTime; + uint32_t perc = strip.now % cycleTime; uint16_t prog = (perc * 65535) / cycleTime; bool back = (prog > 32767); if (back) { @@ -133,11 +133,11 @@ uint16_t WS2812FX::color_wipe(bool rev, bool useRandomColors) { SEGENV.step = 3; } if (SEGENV.step == 1) { //if flag set, change to new random color - SEGENV.aux1 = get_random_wheel_index(SEGENV.aux0); + SEGENV.aux1 = strip.get_random_wheel_index(SEGENV.aux0); SEGENV.step = 2; } if (SEGENV.step == 3) { - SEGENV.aux0 = get_random_wheel_index(SEGENV.aux1); + SEGENV.aux0 = strip.get_random_wheel_index(SEGENV.aux1); SEGENV.step = 0; } } @@ -148,19 +148,19 @@ uint16_t WS2812FX::color_wipe(bool rev, bool useRandomColors) { rem /= (SEGMENT.intensity +1); if (rem > 255) rem = 255; - uint32_t col1 = useRandomColors? color_wheel(SEGENV.aux1) : SEGCOLOR(1); + uint32_t col1 = useRandomColors? strip.color_wheel(SEGENV.aux1) : SEGCOLOR(1); for (uint16_t i = 0; i < SEGLEN; i++) { uint16_t index = (rev && back)? SEGLEN -1 -i : i; - uint32_t col0 = useRandomColors? color_wheel(SEGENV.aux0) : color_from_palette(index, true, PALETTE_SOLID_WRAP, 0); + uint32_t col0 = useRandomColors? strip.color_wheel(SEGENV.aux0) : strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0); if (i < ledIndex) { - setPixelColor(index, back? col1 : col0); + strip.setPixelColor(index, back? col1 : col0); } else { - setPixelColor(index, back? col0 : col1); - if (i == ledIndex) setPixelColor(index, color_blend(back? col0 : col1, back? col1 : col0, rem)); + strip.setPixelColor(index, back? col0 : col1); + if (i == ledIndex) strip.setPixelColor(index, color_blend(back? col0 : col1, back? col1 : col0, rem)); } } return FRAMETIME; @@ -170,7 +170,7 @@ uint16_t WS2812FX::color_wipe(bool rev, bool useRandomColors) { /* * Lights all LEDs one after another. */ -uint16_t WS2812FX::mode_color_wipe(void) { +uint16_t mode_color_wipe(void) { return color_wipe(false, false); } static const char *_data_FX_MODE_COLOR_WIPE PROGMEM = "Wipe@!,!;!,!,;!"; @@ -179,7 +179,7 @@ static const char *_data_FX_MODE_COLOR_WIPE PROGMEM = "Wipe@!,!;!,!,;!"; /* * Lights all LEDs one after another. Turns off opposite */ -uint16_t WS2812FX::mode_color_sweep(void) { +uint16_t mode_color_sweep(void) { return color_wipe(true, false); } static const char *_data_FX_MODE_COLOR_SWEEP PROGMEM = "Sweep@!,!;!,!,;!"; @@ -189,7 +189,7 @@ static const char *_data_FX_MODE_COLOR_SWEEP PROGMEM = "Sweep@!,!;!,!,;!"; * Turns all LEDs after each other to a random color. * Then starts over with another color. */ -uint16_t WS2812FX::mode_color_wipe_random(void) { +uint16_t mode_color_wipe_random(void) { return color_wipe(false, true); } static const char *_data_FX_MODE_COLOR_WIPE_RANDOM PROGMEM = "Wipe Random@!,;1,2,3;!"; @@ -198,7 +198,7 @@ static const char *_data_FX_MODE_COLOR_WIPE_RANDOM PROGMEM = "Wipe Random@!,;1,2 /* * Random color introduced alternating from start and end of strip. */ -uint16_t WS2812FX::mode_color_sweep_random(void) { +uint16_t mode_color_sweep_random(void) { return color_wipe(true, true); } static const char *_data_FX_MODE_COLOR_SWEEP_RANDOM PROGMEM = "Sweep Random"; @@ -208,10 +208,10 @@ static const char *_data_FX_MODE_COLOR_SWEEP_RANDOM PROGMEM = "Sweep Random"; * Lights all LEDs in one random color up. Then switches them * to the next random color. */ -uint16_t WS2812FX::mode_random_color(void) { +uint16_t mode_random_color(void) { uint32_t cycleTime = 200 + (255 - SEGMENT.speed)*50; - uint32_t it = now / cycleTime; - uint32_t rem = now % cycleTime; + uint32_t it = strip.now / cycleTime; + uint32_t rem = strip.now % cycleTime; uint16_t fadedur = (cycleTime * SEGMENT.intensity) >> 8; uint32_t fade = 255; @@ -227,11 +227,11 @@ uint16_t WS2812FX::mode_random_color(void) { if (it != SEGENV.step) //new color { SEGENV.aux1 = SEGENV.aux0; - SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0); //aux0 will store our random color wheel index + SEGENV.aux0 = strip.get_random_wheel_index(SEGENV.aux0); //aux0 will store our random color wheel index SEGENV.step = it; } - fill(color_blend(color_wheel(SEGENV.aux1), color_wheel(SEGENV.aux0), fade)); + strip.fill(color_blend(strip.color_wheel(SEGENV.aux1), strip.color_wheel(SEGENV.aux0), fade)); return FRAMETIME; } static const char *_data_FX_MODE_RANDOM_COLOR PROGMEM = "Random Colors@!,Fade time;1,2,3;!"; @@ -241,7 +241,7 @@ static const char *_data_FX_MODE_RANDOM_COLOR PROGMEM = "Random Colors@!,Fade ti * Lights every LED in a random color. Changes all LED at the same time * to new random colors. */ -uint16_t WS2812FX::dynamic(boolean smooth=false) { +uint16_t dynamic(boolean smooth=false) { if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed if(SEGENV.call == 0) { @@ -249,7 +249,7 @@ uint16_t WS2812FX::dynamic(boolean smooth=false) { } uint32_t cycleTime = 50 + (255 - SEGMENT.speed)*15; - uint32_t it = now / cycleTime; + uint32_t it = strip.now / cycleTime; if (it != SEGENV.step && SEGMENT.speed != 0) //new color { for (uint16_t i = 0; i < SEGLEN; i++) { @@ -260,11 +260,11 @@ uint16_t WS2812FX::dynamic(boolean smooth=false) { if (smooth) { for (uint16_t i = 0; i < SEGLEN; i++) { - blendPixelColor(i, color_wheel(SEGENV.data[i]),16); + strip.blendPixelColor(i, strip.color_wheel(SEGENV.data[i]),16); } } else { for (uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_wheel(SEGENV.data[i])); + strip.setPixelColor(i, strip.color_wheel(SEGENV.data[i])); } } return FRAMETIME; @@ -274,7 +274,7 @@ uint16_t WS2812FX::dynamic(boolean smooth=false) { /* * Original effect "Dynamic" */ -uint16_t WS2812FX::mode_dynamic(void) { +uint16_t mode_dynamic(void) { return dynamic(false); } static const char *_data_FX_MODE_DYNAMIC PROGMEM = "Dynamic@!,!;1,2,3;!"; @@ -283,7 +283,7 @@ static const char *_data_FX_MODE_DYNAMIC PROGMEM = "Dynamic@!,!;1,2,3;!"; /* * effect "Dynamic" with smoth color-fading */ -uint16_t WS2812FX::mode_dynamic_smooth(void) { +uint16_t mode_dynamic_smooth(void) { return dynamic(true); } static const char *_data_FX_MODE_DYNAMIC_SMOOTH PROGMEM = "Dynamic Smooth"; @@ -292,9 +292,9 @@ static const char *_data_FX_MODE_DYNAMIC_SMOOTH PROGMEM = "Dynamic Smooth"; /* * Does the "standby-breathing" of well known i-Devices. */ -uint16_t WS2812FX::mode_breath(void) { +uint16_t mode_breath(void) { uint16_t var = 0; - uint16_t counter = (now * ((SEGMENT.speed >> 3) +10)); + uint16_t counter = (strip.now * ((SEGMENT.speed >> 3) +10)); counter = (counter >> 2) + (counter >> 4); //0-16384 + 0-2048 if (counter < 16384) { if (counter > 8192) counter = 8192 - (counter - 8192); @@ -303,7 +303,7 @@ uint16_t WS2812FX::mode_breath(void) { uint8_t lum = 30 + var; for(uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); + strip.setPixelColor(i, color_blend(SEGCOLOR(1), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); } return FRAMETIME; @@ -314,12 +314,12 @@ static const char *_data_FX_MODE_BREATH PROGMEM = "Breathe@!,;!,!;!"; /* * Fades the LEDs between two colors */ -uint16_t WS2812FX::mode_fade(void) { - uint16_t counter = (now * ((SEGMENT.speed >> 3) +10)); - uint8_t lum = triwave16(counter) >> 8; +uint16_t mode_fade(void) { + uint16_t counter = (strip.now * ((SEGMENT.speed >> 3) +10)); + uint8_t lum = strip.triwave16(counter) >> 8; for(uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); + strip.setPixelColor(i, color_blend(SEGCOLOR(1), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum)); } return FRAMETIME; @@ -330,15 +330,15 @@ static const char *_data_FX_MODE_FADE PROGMEM = "Fade@!,;!,!,;!"; /* * Scan mode parent function */ -uint16_t WS2812FX::scan(bool dual) +uint16_t scan(bool dual) { uint32_t cycleTime = 750 + (255 - SEGMENT.speed)*150; - uint32_t perc = now % cycleTime; + uint32_t perc = strip.now % cycleTime; uint16_t prog = (perc * 65535) / cycleTime; uint16_t size = 1 + ((SEGMENT.intensity * SEGLEN) >> 9); uint16_t ledIndex = (prog * ((SEGLEN *2) - size *2)) >> 16; - fill(SEGCOLOR(1)); + strip.fill(SEGCOLOR(1)); int led_offset = ledIndex - (SEGLEN - size); led_offset = abs(led_offset); @@ -346,12 +346,12 @@ uint16_t WS2812FX::scan(bool dual) if (dual) { for (uint16_t j = led_offset; j < led_offset + size; j++) { uint16_t i2 = SEGLEN -1 -j; - setPixelColor(i2, color_from_palette(i2, true, PALETTE_SOLID_WRAP, (SEGCOLOR(2))? 2:0)); + strip.setPixelColor(i2, strip.color_from_palette(i2, true, PALETTE_SOLID_WRAP, (SEGCOLOR(2))? 2:0)); } } for (uint16_t j = led_offset; j < led_offset + size; j++) { - setPixelColor(j, color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(j, strip.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); } return FRAMETIME; @@ -361,7 +361,7 @@ uint16_t WS2812FX::scan(bool dual) /* * Runs a single pixel back and forth. */ -uint16_t WS2812FX::mode_scan(void) { +uint16_t mode_scan(void) { return scan(false); } static const char *_data_FX_MODE_SCAN PROGMEM = "Scan@!,# of dots;!,!,;!"; @@ -370,7 +370,7 @@ static const char *_data_FX_MODE_SCAN PROGMEM = "Scan@!,# of dots;!,!,;!"; /* * Runs two pixel back and forth in opposite directions. */ -uint16_t WS2812FX::mode_dual_scan(void) { +uint16_t mode_dual_scan(void) { return scan(true); } static const char *_data_FX_MODE_DUAL_SCAN PROGMEM = "Scan Dual@!,# of dots;!,!,;!"; @@ -379,14 +379,14 @@ static const char *_data_FX_MODE_DUAL_SCAN PROGMEM = "Scan Dual@!,# of dots;!,!, /* * Cycles all LEDs at once through a rainbow. */ -uint16_t WS2812FX::mode_rainbow(void) { - uint16_t counter = (now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF; +uint16_t mode_rainbow(void) { + uint16_t counter = (strip.now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF; counter = counter >> 8; if (SEGMENT.intensity < 128){ - fill(color_blend(color_wheel(counter),WHITE,128-SEGMENT.intensity)); + strip.fill(color_blend(strip.color_wheel(counter),WHITE,128-SEGMENT.intensity)); } else { - fill(color_wheel(counter)); + strip.fill(strip.color_wheel(counter)); } return FRAMETIME; @@ -397,14 +397,14 @@ static const char *_data_FX_MODE_RAINBOW PROGMEM = "Colorloop@!,Saturation;1,2,3 /* * Cycles a rainbow over the entire string of LEDs. */ -uint16_t WS2812FX::mode_rainbow_cycle(void) { - uint16_t counter = (now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF; +uint16_t mode_rainbow_cycle(void) { + uint16_t counter = (strip.now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF; counter = counter >> 8; for(uint16_t i = 0; i < SEGLEN; i++) { //intensity/29 = 0 (1/16) 1 (1/8) 2 (1/4) 3 (1/2) 4 (1) 5 (2) 6 (4) 7 (8) 8 (16) uint8_t index = (i * (16 << (SEGMENT.intensity /29)) / SEGLEN) + counter; - setPixelColor(i, color_wheel(index)); + strip.setPixelColor(i, strip.color_wheel(index)); } return FRAMETIME; @@ -412,11 +412,40 @@ uint16_t WS2812FX::mode_rainbow_cycle(void) { static const char *_data_FX_MODE_RAINBOW_CYCLE PROGMEM = "Rainbow@!,Size;1,2,3;!"; +/* + * Alternating pixels running function. + */ +uint16_t running(uint32_t color1, uint32_t color2, bool theatre = false) { + uint8_t width = (theatre ? 3 : 1) + (SEGMENT.intensity >> 4); // window + uint32_t cycleTime = 50 + (255 - SEGMENT.speed); + uint32_t it = strip.now / cycleTime; + bool usePalette = color1 == SEGCOLOR(0); + + for(uint16_t i = 0; i < SEGLEN; i++) { + uint32_t col = color2; + if (usePalette) color1 = strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0); + if (theatre) { + if ((i % width) == SEGENV.aux0) col = color1; + } else { + int8_t pos = (i % (width<<1)); + if ((pos < SEGENV.aux0-width) || ((pos >= SEGENV.aux0) && (pos < SEGENV.aux0+width))) col = color1; + } + strip.setPixelColor(i,col); + } + + if (it != SEGENV.step) { + SEGENV.aux0 = (SEGENV.aux0 +1) % (theatre ? width : (width<<1)); + SEGENV.step = it; + } + return FRAMETIME; +} + + /* * Theatre-style crawling lights. * Inspired by the Adafruit examples. */ -uint16_t WS2812FX::mode_theater_chase(void) { +uint16_t mode_theater_chase(void) { return running(SEGCOLOR(0), SEGCOLOR(1), true); } static const char *_data_FX_MODE_THEATER_CHASE PROGMEM = "Theater@!,Gap size;!,!,;!"; @@ -426,8 +455,8 @@ static const char *_data_FX_MODE_THEATER_CHASE PROGMEM = "Theater@!,Gap size;!,! * Theatre-style crawling lights with rainbow effect. * Inspired by the Adafruit examples. */ -uint16_t WS2812FX::mode_theater_chase_rainbow(void) { - return running(color_wheel(SEGENV.step), SEGCOLOR(1), true); +uint16_t mode_theater_chase_rainbow(void) { + return running(strip.color_wheel(SEGENV.step), SEGCOLOR(1), true); } static const char *_data_FX_MODE_THEATER_CHASE_RAINBOW PROGMEM = "Theater Rainbow@!,Gap size;1,2,3;!"; @@ -435,9 +464,9 @@ static const char *_data_FX_MODE_THEATER_CHASE_RAINBOW PROGMEM = "Theater Rainbo /* * Running lights effect with smooth sine transition base. */ -uint16_t WS2812FX::running_base(bool saw, bool dual=false) { +uint16_t running_base(bool saw, bool dual=false) { uint8_t x_scale = SEGMENT.intensity >> 2; - uint32_t counter = (now * SEGMENT.speed) >> 9; + uint32_t counter = (strip.now * SEGMENT.speed) >> 9; for(uint16_t i = 0; i < SEGLEN; i++) { uint16_t a = i*x_scale - counter; @@ -451,15 +480,15 @@ uint16_t WS2812FX::running_base(bool saw, bool dual=false) { } a = 255 - a; } - uint8_t s = dual ? sin_gap(a) : sin8(a); - uint32_t ca = color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s); + uint8_t s = dual ? strip.sin_gap(a) : sin8(a); + uint32_t ca = color_blend(SEGCOLOR(1), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s); if (dual) { uint16_t b = (SEGLEN-1-i)*x_scale - counter; - uint8_t t = sin_gap(b); - uint32_t cb = color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), t); + uint8_t t = strip.sin_gap(b); + uint32_t cb = color_blend(SEGCOLOR(1), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), t); ca = color_blend(ca, cb, 127); } - setPixelColor(i, ca); + strip.setPixelColor(i, ca); } return FRAMETIME; } @@ -469,7 +498,7 @@ uint16_t WS2812FX::running_base(bool saw, bool dual=false) { * Running lights in opposite directions. * Idea: Make the gap width controllable with a third slider in the future */ -uint16_t WS2812FX::mode_running_dual(void) { +uint16_t mode_running_dual(void) { return running_base(false, true); } static const char *_data_FX_MODE_RUNNING_DUAL PROGMEM = "Running Dual"; @@ -478,7 +507,7 @@ static const char *_data_FX_MODE_RUNNING_DUAL PROGMEM = "Running Dual"; /* * Running lights effect with smooth sine transition. */ -uint16_t WS2812FX::mode_running_lights(void) { +uint16_t mode_running_lights(void) { return running_base(false); } static const char *_data_FX_MODE_RUNNING_LIGHTS PROGMEM = "Running@!,Wave width;!,!,;!"; @@ -487,7 +516,7 @@ static const char *_data_FX_MODE_RUNNING_LIGHTS PROGMEM = "Running@!,Wave width; /* * Running lights effect with sawtooth transition. */ -uint16_t WS2812FX::mode_saw(void) { +uint16_t mode_saw(void) { return running_base(true); } static const char *_data_FX_MODE_SAW PROGMEM = "Saw@!,Width;!,!,;!"; @@ -497,14 +526,14 @@ static const char *_data_FX_MODE_SAW PROGMEM = "Saw@!,Width;!,!,;!"; * Blink several LEDs in random colors on, reset, repeat. * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ -uint16_t WS2812FX::mode_twinkle(void) { - const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); +uint16_t mode_twinkle(void) { + const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); const uint16_t rows = SEGMENT.virtualHeight(); - fill(SEGCOLOR(1)); + strip.fill(SEGCOLOR(1)); uint32_t cycleTime = 20 + (255 - SEGMENT.speed)*5; - uint32_t it = now / cycleTime; + uint32_t it = strip.now / cycleTime; if (it != SEGENV.step) { uint16_t maxOn = map(SEGMENT.intensity, 0, 255, 1, cols*rows-1); // make sure at least one LED is on @@ -525,9 +554,9 @@ uint16_t WS2812FX::mode_twinkle(void) { uint32_t p = ((uint32_t)cols*rows * (uint32_t)PRNG16) >> 16; uint16_t j = p % cols; uint16_t k = p / cols; - uint32_t col = color_from_palette(map(p, 0, cols*rows, 0, 255), false, PALETTE_SOLID_WRAP, 0); - if (isMatrix) setPixelColorXY(j, k, col); - else setPixelColor(j, col); + uint32_t col = strip.color_from_palette(map(p, 0, cols*rows, 0, 255), false, PALETTE_SOLID_WRAP, 0); + if (strip.isMatrix) strip.setPixelColorXY(j, k, col); + else strip.setPixelColor(j, col); } return FRAMETIME; @@ -538,8 +567,8 @@ static const char *_data_FX_MODE_TWINKLE PROGMEM = "Twinkle@!,;!,!,;!"; /* * Dissolve function */ -uint16_t WS2812FX::dissolve(uint32_t color) { - bool wa = (SEGCOLOR(1) != 0 && _brightness < 255); //workaround, can't compare getPixel to color if not full brightness +uint16_t dissolve(uint32_t color) { + bool wa = (SEGCOLOR(1) != 0 && strip.getBrightness() < 255); //workaround, can't compare getPixel to color if not full brightness for (uint16_t j = 0; j <= SEGLEN / 15; j++) { @@ -548,15 +577,15 @@ uint16_t WS2812FX::dissolve(uint32_t color) { { uint16_t i = random16(SEGLEN); if (SEGENV.aux0) { //dissolve to primary/palette - if (getPixelColor(i) == SEGCOLOR(1) || wa) { + if (strip.getPixelColor(i) == SEGCOLOR(1) || wa) { if (color == SEGCOLOR(0)) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); - } else { setPixelColor(i, color); } + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + } else { strip.setPixelColor(i, color); } break; //only spawn 1 new pixel per frame per 50 LEDs } } else { //dissolve to secondary - if (getPixelColor(i) != SEGCOLOR(1)) { setPixelColor(i, SEGCOLOR(1)); break; } + if (strip.getPixelColor(i) != SEGCOLOR(1)) { strip.setPixelColor(i, SEGCOLOR(1)); break; } } } } @@ -575,7 +604,7 @@ uint16_t WS2812FX::dissolve(uint32_t color) { /* * Blink several LEDs on and then off */ -uint16_t WS2812FX::mode_dissolve(void) { +uint16_t mode_dissolve(void) { return dissolve(SEGCOLOR(0)); } static const char *_data_FX_MODE_DISSOLVE PROGMEM = "Dissolve@Repeat speed,Dissolve speed;!,!,;!"; @@ -584,8 +613,8 @@ static const char *_data_FX_MODE_DISSOLVE PROGMEM = "Dissolve@Repeat speed,Disso /* * Blink several LEDs on and then off in random colors */ -uint16_t WS2812FX::mode_dissolve_random(void) { - return dissolve(color_wheel(random8())); +uint16_t mode_dissolve_random(void) { + return dissolve(strip.color_wheel(random8())); } static const char *_data_FX_MODE_DISSOLVE_RANDOM PROGMEM = "Dissolve Rnd@Repeat speed,Dissolve speed;,!,;!"; @@ -594,12 +623,12 @@ static const char *_data_FX_MODE_DISSOLVE_RANDOM PROGMEM = "Dissolve Rnd@Repeat * Blinks one LED at a time. * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ -uint16_t WS2812FX::mode_sparkle(void) { +uint16_t mode_sparkle(void) { for(uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } uint32_t cycleTime = 10 + (255 - SEGMENT.speed)*2; - uint32_t it = now / cycleTime; + uint32_t it = strip.now / cycleTime; if (it != SEGENV.step) { SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index @@ -607,8 +636,8 @@ uint16_t WS2812FX::mode_sparkle(void) { SEGENV.step = it; } - if (isMatrix) setPixelColorXY(SEGENV.aux0, SEGENV.aux1, SEGCOLOR(0)); - else setPixelColor(SEGENV.aux0, SEGCOLOR(0)); + if (strip.isMatrix) strip.setPixelColorXY(SEGENV.aux0, SEGENV.aux1, SEGCOLOR(0)); + else strip.setPixelColor(SEGENV.aux0, SEGCOLOR(0)); return FRAMETIME; } static const char *_data_FX_MODE_SPARKLE PROGMEM = "Sparkle@!,;!,!,;!"; @@ -618,17 +647,17 @@ static const char *_data_FX_MODE_SPARKLE PROGMEM = "Sparkle@!,;!,!,;!"; * Lights all LEDs in the color. Flashes single col 1 pixels randomly. (List name: Sparkle Dark) * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ -uint16_t WS2812FX::mode_flash_sparkle(void) { +uint16_t mode_flash_sparkle(void) { for(uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } - if (now - SEGENV.aux0 > SEGENV.step) { + if (strip.now - SEGENV.aux0 > SEGENV.step) { if(random8((255-SEGMENT.intensity) >> 4) == 0) { - if (isMatrix) setPixelColorXY(random16(SEGLEN), random16(0,SEGMENT.virtualHeight()-1), SEGCOLOR(1)); - else setPixelColor(random16(SEGLEN), SEGCOLOR(1)); //flash + if (strip.isMatrix) strip.setPixelColorXY(random16(SEGLEN), random16(0,SEGMENT.virtualHeight()-1), SEGCOLOR(1)); + else strip.setPixelColor(random16(SEGLEN), SEGCOLOR(1)); //flash } - SEGENV.step = now; + SEGENV.step = strip.now; SEGENV.aux0 = 255-SEGMENT.speed; } return FRAMETIME; @@ -640,19 +669,19 @@ static const char *_data_FX_MODE_FLASH_SPARKLE PROGMEM = "Sparkle Dark@!,!;Bg,Fx * Like flash sparkle. With more flash. * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ -uint16_t WS2812FX::mode_hyper_sparkle(void) { +uint16_t mode_hyper_sparkle(void) { for(uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } - if (now - SEGENV.aux0 > SEGENV.step) { + if (strip.now - SEGENV.aux0 > SEGENV.step) { if(random8((255-SEGMENT.intensity) >> 4) == 0) { for(uint16_t i = 0; i < MAX(1, SEGLEN/3); i++) { - if (isMatrix) setPixelColorXY(random16(SEGLEN), random16(0,SEGMENT.virtualHeight()), SEGCOLOR(1)); - else setPixelColor(random16(SEGLEN), SEGCOLOR(1)); + if (strip.isMatrix) strip.setPixelColorXY(random16(SEGLEN), random16(0,SEGMENT.virtualHeight()), SEGCOLOR(1)); + else strip.setPixelColor(random16(SEGLEN), SEGCOLOR(1)); } } - SEGENV.step = now; + SEGENV.step = strip.now; SEGENV.aux0 = 255-SEGMENT.speed; } return FRAMETIME; @@ -663,26 +692,26 @@ static const char *_data_FX_MODE_HYPER_SPARKLE PROGMEM = "Sparkle+@!,!;Bg,Fx,;!" /* * Strobe effect with different strobe count and pause, controlled by speed. */ -uint16_t WS2812FX::mode_multi_strobe(void) { +uint16_t mode_multi_strobe(void) { for(uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } SEGENV.aux0 = 50 + 20*(uint16_t)(255-SEGMENT.speed); uint16_t count = 2 * ((SEGMENT.intensity / 10) + 1); if(SEGENV.aux1 < count) { if((SEGENV.aux1 & 1) == 0) { - fill(SEGCOLOR(0)); + strip.fill(SEGCOLOR(0)); SEGENV.aux0 = 15; } else { SEGENV.aux0 = 50; } } - if (now - SEGENV.aux0 > SEGENV.step) { + if (strip.now - SEGENV.aux0 > SEGENV.step) { SEGENV.aux1++; if (SEGENV.aux1 > count) SEGENV.aux1 = 0; - SEGENV.step = now; + SEGENV.step = strip.now; } return FRAMETIME; @@ -693,10 +722,10 @@ static const char *_data_FX_MODE_MULTI_STROBE PROGMEM = "Strobe Mega@!,!;!,!,;!" /* * Android loading circle */ -uint16_t WS2812FX::mode_android(void) { +uint16_t mode_android(void) { for(uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } if (SEGENV.aux1 > ((float)SEGMENT.intensity/255.0)*(float)SEGLEN) @@ -724,15 +753,15 @@ uint16_t WS2812FX::mode_android(void) { if (a + SEGENV.aux1 < SEGLEN) { for(uint16_t i = a; i < a+SEGENV.aux1; i++) { - setPixelColor(i, SEGCOLOR(0)); + strip.setPixelColor(i, SEGCOLOR(0)); } } else { for(uint16_t i = a; i < SEGLEN; i++) { - setPixelColor(i, SEGCOLOR(0)); + strip.setPixelColor(i, SEGCOLOR(0)); } for(uint16_t i = 0; i < SEGENV.aux1 - (SEGLEN -a); i++) { - setPixelColor(i, SEGCOLOR(0)); + strip.setPixelColor(i, SEGCOLOR(0)); } } SEGENV.step = a; @@ -747,8 +776,8 @@ static const char *_data_FX_MODE_ANDROID PROGMEM = "Android@!,Width;!,!,;!"; * color1 = background color * color2 and color3 = colors of two adjacent leds */ -uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do_palette) { - uint16_t counter = now * ((SEGMENT.speed >> 2) + 1); +uint16_t chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do_palette) { + uint16_t counter = strip.now * ((SEGMENT.speed >> 2) + 1); uint16_t a = counter * SEGLEN >> 16; bool chase_random = (SEGMENT.mode == FX_MODE_CHASE_RANDOM); @@ -756,9 +785,9 @@ uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, bool if (a < SEGENV.step) //we hit the start again, choose new color for Chase random { SEGENV.aux1 = SEGENV.aux0; //store previous random color - SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0); + SEGENV.aux0 = strip.get_random_wheel_index(SEGENV.aux0); } - color1 = color_wheel(SEGENV.aux0); + color1 = strip.color_wheel(SEGENV.aux0); } SEGENV.step = a; @@ -774,40 +803,40 @@ uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, bool if (do_palette) { for(uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } - } else fill(color1); + } else strip.fill(color1); //if random, fill old background between a and end if (chase_random) { - color1 = color_wheel(SEGENV.aux1); + color1 = strip.color_wheel(SEGENV.aux1); for (uint16_t i = a; i < SEGLEN; i++) - setPixelColor(i, color1); + strip.setPixelColor(i, color1); } //fill between points a and b with color2 if (a < b) { for (uint16_t i = a; i < b; i++) - setPixelColor(i, color2); + strip.setPixelColor(i, color2); } else { for (uint16_t i = a; i < SEGLEN; i++) //fill until end - setPixelColor(i, color2); + strip.setPixelColor(i, color2); for (uint16_t i = 0; i < b; i++) //fill from start until b - setPixelColor(i, color2); + strip.setPixelColor(i, color2); } //fill between points b and c with color2 if (b < c) { for (uint16_t i = b; i < c; i++) - setPixelColor(i, color3); + strip.setPixelColor(i, color3); } else { for (uint16_t i = b; i < SEGLEN; i++) //fill until end - setPixelColor(i, color3); + strip.setPixelColor(i, color3); for (uint16_t i = 0; i < c; i++) //fill from start until c - setPixelColor(i, color3); + strip.setPixelColor(i, color3); } return FRAMETIME; @@ -817,7 +846,7 @@ uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, bool /* * Bicolor chase, more primary color. */ -uint16_t WS2812FX::mode_chase_color(void) { +uint16_t mode_chase_color(void) { return chase(SEGCOLOR(1), (SEGCOLOR(2)) ? SEGCOLOR(2) : SEGCOLOR(0), SEGCOLOR(0), true); } static const char *_data_FX_MODE_CHASE_COLOR PROGMEM = "Chase@!,Width;!,!,!;!"; @@ -826,7 +855,7 @@ static const char *_data_FX_MODE_CHASE_COLOR PROGMEM = "Chase@!,Width;!,!,!;!"; /* * Primary running followed by random color. */ -uint16_t WS2812FX::mode_chase_random(void) { +uint16_t mode_chase_random(void) { return chase(SEGCOLOR(1), (SEGCOLOR(2)) ? SEGCOLOR(2) : SEGCOLOR(0), SEGCOLOR(0), false); } static const char *_data_FX_MODE_CHASE_RANDOM PROGMEM = "Chase Random@!,Width;!,,!;!"; @@ -835,11 +864,11 @@ static const char *_data_FX_MODE_CHASE_RANDOM PROGMEM = "Chase Random@!,Width;!, /* * Primary, secondary running on rainbow. */ -uint16_t WS2812FX::mode_chase_rainbow(void) { +uint16_t mode_chase_rainbow(void) { uint8_t color_sep = 256 / SEGLEN; if (color_sep == 0) color_sep = 1; // correction for segments longer than 256 LEDs uint8_t color_index = SEGENV.call & 0xFF; - uint32_t color = color_wheel(((SEGENV.step * color_sep) + color_index) & 0xFF); + uint32_t color = strip.color_wheel(((SEGENV.step * color_sep) + color_index) & 0xFF); return chase(color, SEGCOLOR(0), SEGCOLOR(1), false); } @@ -849,11 +878,11 @@ static const char *_data_FX_MODE_CHASE_RAINBOW PROGMEM = "Chase Rainbow@!,Width; /* * Primary running on rainbow. */ -uint16_t WS2812FX::mode_chase_rainbow_white(void) { +uint16_t mode_chase_rainbow_white(void) { uint16_t n = SEGENV.step; uint16_t m = (SEGENV.step + 1) % SEGLEN; - uint32_t color2 = color_wheel(((n * 256 / SEGLEN) + (SEGENV.call & 0xFF)) & 0xFF); - uint32_t color3 = color_wheel(((m * 256 / SEGLEN) + (SEGENV.call & 0xFF)) & 0xFF); + uint32_t color2 = strip.color_wheel(((n * 256 / SEGLEN) + (SEGENV.call & 0xFF)) & 0xFF); + uint32_t color3 = strip.color_wheel(((m * 256 / SEGLEN) + (SEGENV.call & 0xFF)) & 0xFF); return chase(SEGCOLOR(0), color2, color3, false); } @@ -863,7 +892,7 @@ static const char *_data_FX_MODE_CHASE_RAINBOW_WHITE PROGMEM = "Rainbow Runner@! /* * Red - Amber - Green - Blue lights running */ -uint16_t WS2812FX::mode_colorful(void) { +uint16_t mode_colorful(void) { uint8_t numColors = 4; //3, 4, or 5 uint32_t cols[9]{0x00FF0000,0x00EEBB00,0x0000EE00,0x000077CC}; if (SEGMENT.intensity > 160 || SEGMENT.palette) { //palette or color @@ -874,7 +903,7 @@ uint16_t WS2812FX::mode_colorful(void) { uint16_t fac = 80; if (SEGMENT.palette == 52) {numColors = 5; fac = 61;} //C9 2 has 5 colors for (uint8_t i = 0; i < numColors; i++) { - cols[i] = color_from_palette(i*fac, false, true, 255); + cols[i] = strip.color_from_palette(i*fac, false, true, 255); } } } else if (SEGMENT.intensity < 80) //pastel (easter) colors @@ -887,7 +916,7 @@ uint16_t WS2812FX::mode_colorful(void) { for (uint8_t i = numColors; i < numColors*2 -1; i++) cols[i] = cols[i-numColors]; uint32_t cycleTime = 50 + (8 * (uint32_t)(255 - SEGMENT.speed)); - uint32_t it = now / cycleTime; + uint32_t it = strip.now / cycleTime; if (it != SEGENV.step) { if (SEGMENT.speed > 0) SEGENV.aux0++; @@ -897,7 +926,7 @@ uint16_t WS2812FX::mode_colorful(void) { for (uint16_t i = 0; i < SEGLEN; i+= numColors) { - for (uint16_t j = 0; j < numColors; j++) setPixelColor(i + j, cols[SEGENV.aux0 + j]); + for (uint16_t j = 0; j < numColors; j++) strip.setPixelColor(i + j, cols[SEGENV.aux0 + j]); } return FRAMETIME; @@ -908,27 +937,27 @@ static const char *_data_FX_MODE_COLORFUL PROGMEM = "Colorful@!,Saturation;1,2,3 /* * Emulates a traffic light. */ -uint16_t WS2812FX::mode_traffic_light(void) { +uint16_t mode_traffic_light(void) { for(uint16_t i=0; i < SEGLEN; i++) - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); uint32_t mdelay = 500; for (int i = 0; i < SEGLEN-2 ; i+=3) { switch (SEGENV.aux0) { - case 0: setPixelColor(i, 0x00FF0000); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break; - case 1: setPixelColor(i, 0x00FF0000); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed)); setPixelColor(i+1, 0x00EECC00); break; - case 2: setPixelColor(i+2, 0x0000FF00); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break; - case 3: setPixelColor(i+1, 0x00EECC00); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed));break; + case 0: strip.setPixelColor(i, 0x00FF0000); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break; + case 1: strip.setPixelColor(i, 0x00FF0000); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed)); strip.setPixelColor(i+1, 0x00EECC00); break; + case 2: strip.setPixelColor(i+2, 0x0000FF00); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break; + case 3: strip.setPixelColor(i+1, 0x00EECC00); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed));break; } } - if (now - SEGENV.step > mdelay) + if (strip.now - SEGENV.step > mdelay) { SEGENV.aux0++; if (SEGENV.aux0 == 1 && SEGMENT.intensity > 140) SEGENV.aux0 = 2; //skip Red + Amber, to get US-style sequence if (SEGENV.aux0 > 3) SEGENV.aux0 = 0; - SEGENV.step = now; + SEGENV.step = strip.now; } return FRAMETIME; @@ -940,11 +969,11 @@ static const char *_data_FX_MODE_TRAFFIC_LIGHT PROGMEM = "Traffic Light@!,;,!,;! * Sec flashes running on prim. */ #define FLASH_COUNT 4 -uint16_t WS2812FX::mode_chase_flash(void) { +uint16_t mode_chase_flash(void) { uint8_t flash_step = SEGENV.call % ((FLASH_COUNT * 2) + 1); for(uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } uint16_t delay = 10 + ((30 * (uint16_t)(255 - SEGMENT.speed)) / SEGLEN); @@ -952,8 +981,8 @@ uint16_t WS2812FX::mode_chase_flash(void) { if(flash_step % 2 == 0) { uint16_t n = SEGENV.step; uint16_t m = (SEGENV.step + 1) % SEGLEN; - setPixelColor( n, SEGCOLOR(1)); - setPixelColor( m, SEGCOLOR(1)); + strip.setPixelColor( n, SEGCOLOR(1)); + strip.setPixelColor( m, SEGCOLOR(1)); delay = 20; } else { delay = 30; @@ -969,11 +998,11 @@ static const char *_data_FX_MODE_CHASE_FLASH PROGMEM = "Chase Flash@!,;Bg,Fx,!;! /* * Prim flashes running, followed by random color. */ -uint16_t WS2812FX::mode_chase_flash_random(void) { +uint16_t mode_chase_flash_random(void) { uint8_t flash_step = SEGENV.call % ((FLASH_COUNT * 2) + 1); for(uint16_t i = 0; i < SEGENV.step; i++) { - setPixelColor(i, color_wheel(SEGENV.aux0)); + strip.setPixelColor(i, strip.color_wheel(SEGENV.aux0)); } uint16_t delay = 1 + ((10 * (uint16_t)(255 - SEGMENT.speed)) / SEGLEN); @@ -981,19 +1010,19 @@ uint16_t WS2812FX::mode_chase_flash_random(void) { uint16_t n = SEGENV.step; uint16_t m = (SEGENV.step + 1) % SEGLEN; if(flash_step % 2 == 0) { - setPixelColor( n, SEGCOLOR(0)); - setPixelColor( m, SEGCOLOR(0)); + strip.setPixelColor( n, SEGCOLOR(0)); + strip.setPixelColor( m, SEGCOLOR(0)); delay = 20; } else { - setPixelColor( n, color_wheel(SEGENV.aux0)); - setPixelColor( m, SEGCOLOR(1)); + strip.setPixelColor( n, strip.color_wheel(SEGENV.aux0)); + strip.setPixelColor( m, SEGCOLOR(1)); delay = 30; } } else { SEGENV.step = (SEGENV.step + 1) % SEGLEN; if (SEGENV.step == 0) { - SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0); + SEGENV.aux0 = strip.get_random_wheel_index(SEGENV.aux0); } } return delay; @@ -1001,39 +1030,10 @@ uint16_t WS2812FX::mode_chase_flash_random(void) { static const char *_data_FX_MODE_CHASE_FLASH_RANDOM PROGMEM = "Chase Flash Rnd@!,;,Fx,;!"; -/* - * Alternating pixels running function. - */ -uint16_t WS2812FX::running(uint32_t color1, uint32_t color2, bool theatre) { - uint8_t width = (theatre ? 3 : 1) + (SEGMENT.intensity >> 4); // window - uint32_t cycleTime = 50 + (255 - SEGMENT.speed); - uint32_t it = now / cycleTime; - bool usePalette = color1 == SEGCOLOR(0); - - for(uint16_t i = 0; i < SEGLEN; i++) { - uint32_t col = color2; - if (usePalette) color1 = color_from_palette(i, true, PALETTE_SOLID_WRAP, 0); - if (theatre) { - if ((i % width) == SEGENV.aux0) col = color1; - } else { - int8_t pos = (i % (width<<1)); - if ((pos < SEGENV.aux0-width) || ((pos >= SEGENV.aux0) && (pos < SEGENV.aux0+width))) col = color1; - } - setPixelColor(i,col); - } - - if (it != SEGENV.step) { - SEGENV.aux0 = (SEGENV.aux0 +1) % (theatre ? width : (width<<1)); - SEGENV.step = it; - } - return FRAMETIME; -} - - /* * Alternating color/sec pixels running. */ -uint16_t WS2812FX::mode_running_color(void) { +uint16_t mode_running_color(void) { return running(SEGCOLOR(0), SEGCOLOR(1)); } static const char *_data_FX_MODE_RUNNING_COLOR PROGMEM = "Chase 2@!,Width;!,!,;!"; @@ -1042,7 +1042,7 @@ static const char *_data_FX_MODE_RUNNING_COLOR PROGMEM = "Chase 2@!,Width;!,!,;! /* * Alternating red/white pixels running. */ -uint16_t WS2812FX::mode_candy_cane(void) { +uint16_t mode_candy_cane(void) { return running(RED, WHITE); } static const char *_data_FX_MODE_CANDY_CANE PROGMEM = "Candy Cane@!,Width;;"; @@ -1051,7 +1051,7 @@ static const char *_data_FX_MODE_CANDY_CANE PROGMEM = "Candy Cane@!,Width;;"; /* * Alternating orange/purple pixels running. */ -uint16_t WS2812FX::mode_halloween(void) { +uint16_t mode_halloween(void) { return running(PURPLE, ORANGE); } static const char *_data_FX_MODE_HALLOWEEN PROGMEM = "Halloween@!,Width;;"; @@ -1060,9 +1060,9 @@ static const char *_data_FX_MODE_HALLOWEEN PROGMEM = "Halloween@!,Width;;"; /* * Random colored pixels running. ("Stream") */ -uint16_t WS2812FX::mode_running_random(void) { +uint16_t mode_running_random(void) { uint32_t cycleTime = 25 + (3 * (uint32_t)(255 - SEGMENT.speed)); - uint32_t it = now / cycleTime; + uint32_t it = strip.now / cycleTime; if (SEGENV.call == 0) SEGENV.aux0 = random16(); // random seed for PRNG on start uint8_t zoneSize = ((255-SEGMENT.intensity) >> 4) +1; @@ -1084,7 +1084,7 @@ uint16_t WS2812FX::mode_running_random(void) { } z = 0; } - setPixelColor(i, color_wheel(PRNG16 >> 8)); + strip.setPixelColor(i, strip.color_wheel(PRNG16 >> 8)); z++; } @@ -1094,20 +1094,11 @@ uint16_t WS2812FX::mode_running_random(void) { static const char *_data_FX_MODE_RUNNING_RANDOM PROGMEM = "Stream"; -/* - * K.I.T.T. - */ -uint16_t WS2812FX::mode_larson_scanner(void){ - return larson_scanner(false); -} -static const char *_data_FX_MODE_LARSON_SCANNER PROGMEM = "Scanner"; - - -uint16_t WS2812FX::larson_scanner(bool dual) { - uint16_t counter = now * ((SEGMENT.speed >> 2) +8); +uint16_t larson_scanner(bool dual) { + uint16_t counter = strip.now * ((SEGMENT.speed >> 2) +8); uint16_t index = counter * SEGLEN >> 16; - fade_out(SEGMENT.intensity); + strip.fade_out(SEGMENT.intensity); if (SEGENV.step > index && SEGENV.step - index > SEGLEN/2) { SEGENV.aux0 = !SEGENV.aux0; @@ -1115,19 +1106,19 @@ uint16_t WS2812FX::larson_scanner(bool dual) { for (uint16_t i = SEGENV.step; i < index; i++) { uint16_t j = (SEGENV.aux0)?i:SEGLEN-1-i; - setPixelColor( j, color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor( j, strip.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); } if (dual) { uint32_t c; if (SEGCOLOR(2) != 0) { c = SEGCOLOR(2); } else { - c = color_from_palette(index, true, PALETTE_SOLID_WRAP, 0); + c = strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0); } for (uint16_t i = SEGENV.step; i < index; i++) { uint16_t j = (SEGENV.aux0)?SEGLEN-1-i:i; - setPixelColor(j, c); + strip.setPixelColor(j, c); } } @@ -1136,24 +1127,33 @@ uint16_t WS2812FX::larson_scanner(bool dual) { } +/* + * K.I.T.T. + */ +uint16_t mode_larson_scanner(void){ + return larson_scanner(false); +} +static const char *_data_FX_MODE_LARSON_SCANNER PROGMEM = "Scanner"; + + /* * Firing comets from one end. "Lighthouse" */ -uint16_t WS2812FX::mode_comet(void) { - uint16_t counter = now * ((SEGMENT.speed >>2) +1); +uint16_t mode_comet(void) { + uint16_t counter = strip.now * ((SEGMENT.speed >>2) +1); uint16_t index = (counter * SEGLEN) >> 16; if (SEGENV.call == 0) SEGENV.aux0 = index; - fade_out(SEGMENT.intensity); + strip.fade_out(SEGMENT.intensity); - setPixelColor( index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor( index, strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); if (index > SEGENV.aux0) { for (uint16_t i = SEGENV.aux0; i < index ; i++) { - setPixelColor( i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor( i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } } else if (index < SEGENV.aux0 && index < 10) { for (uint16_t i = 0; i < index ; i++) { - setPixelColor( i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor( i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } } SEGENV.aux0 = index++; @@ -1166,11 +1166,11 @@ static const char *_data_FX_MODE_COMET PROGMEM = "Lighthouse@!,Fade rate;!,!,!;! /* * Fireworks function. */ -uint16_t WS2812FX::mode_fireworks() { - const uint16_t width = isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); +uint16_t mode_fireworks() { + const uint16_t width = strip.isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); const uint16_t height = SEGMENT.virtualHeight(); - fade_out(0); + strip.fade_out(0); if (SEGENV.call == 0) { SEGENV.aux0 = UINT16_MAX; @@ -1179,19 +1179,19 @@ uint16_t WS2812FX::mode_fireworks() { bool valid1 = (SEGENV.aux0 < width*height); bool valid2 = (SEGENV.aux1 < width*height); uint32_t sv1 = 0, sv2 = 0; - if (valid1) sv1 = isMatrix ? getPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width) : getPixelColor(SEGENV.aux0); // get spark color - if (valid2) sv2 = isMatrix ? getPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width) : getPixelColor(SEGENV.aux1); - if (!SEGENV.step) blur(16); - if (valid1) { if (isMatrix) setPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width, sv1); else setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur - if (valid2) { if (isMatrix) setPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width, sv2); else setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur + if (valid1) sv1 = strip.isMatrix ? strip.getPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width) : strip.getPixelColor(SEGENV.aux0); // get spark color + if (valid2) sv2 = strip.isMatrix ? strip.getPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width) : strip.getPixelColor(SEGENV.aux1); + if (!SEGENV.step) strip.blur(16); + if (valid1) { if (strip.isMatrix) strip.setPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width, sv1); else strip.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur + if (valid2) { if (strip.isMatrix) strip.setPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width, sv2); else strip.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur for (uint16_t i=0; i> 1)) == 0) { uint16_t index = random16(width*height); uint16_t j = index % width, k = index / width; - uint32_t col = color_from_palette(random8(), false, false, 0); - if (isMatrix) setPixelColorXY(j, k, col); - else setPixelColor(index, col); + uint32_t col = strip.color_from_palette(random8(), false, false, 0); + if (strip.isMatrix) strip.setPixelColorXY(j, k, col); + else strip.setPixelColor(index, col); SEGENV.aux1 = SEGENV.aux0; // old spark SEGENV.aux0 = index; // remember where spark occured } @@ -1202,24 +1202,24 @@ static const char *_data_FX_MODE_FIREWORKS PROGMEM = "Fireworks@,Frequency=192;! //Twinkling LEDs running. Inspired by https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Rain.h -uint16_t WS2812FX::mode_rain() +uint16_t mode_rain() { const uint16_t width = SEGMENT.virtualWidth(); const uint16_t height = SEGMENT.virtualHeight(); SEGENV.step += FRAMETIME; if (SEGENV.step > SPEED_FORMULA_L) { SEGENV.step = 1; - if (isMatrix) { - move(6,1); // move all pixels down + if (strip.isMatrix) { + strip.move(6,1); // move all pixels down SEGENV.aux0 = (SEGENV.aux0 % width) + (SEGENV.aux0 / width + 1) * width; SEGENV.aux1 = (SEGENV.aux1 % width) + (SEGENV.aux1 / width + 1) * width; } else { //shift all leds left - uint32_t ctemp = getPixelColor(0); + uint32_t ctemp = strip.getPixelColor(0); for(uint16_t i = 0; i < SEGLEN - 1; i++) { - setPixelColor(i, getPixelColor(i+1)); + strip.setPixelColor(i, strip.getPixelColor(i+1)); } - setPixelColor(SEGLEN -1, ctemp); // wrap around + strip.setPixelColor(SEGLEN -1, ctemp); // wrap around SEGENV.aux0++; // increase spark index SEGENV.aux1++; } @@ -1236,9 +1236,9 @@ static const char *_data_FX_MODE_RAIN PROGMEM = "Rain@!,Spawning rate=128;!,!,;" /* * Fire flicker function */ -uint16_t WS2812FX::mode_fire_flicker(void) { +uint16_t mode_fire_flicker(void) { uint32_t cycleTime = 40 + (255 - SEGMENT.speed); - uint32_t it = now / cycleTime; + uint32_t it = strip.now / cycleTime; if (SEGENV.step == it) return FRAMETIME; byte w = (SEGCOLOR(0) >> 24); @@ -1250,9 +1250,9 @@ uint16_t WS2812FX::mode_fire_flicker(void) { for(uint16_t i = 0; i < SEGLEN; i++) { byte flicker = random8(lum); if (SEGMENT.palette == 0) { - setPixelColor(i, MAX(r - flicker, 0), MAX(g - flicker, 0), MAX(b - flicker, 0), MAX(w - flicker, 0)); + strip.setPixelColor(i, MAX(r - flicker, 0), MAX(g - flicker, 0), MAX(b - flicker, 0), MAX(w - flicker, 0)); } else { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, 255 - flicker)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, 255 - flicker)); } } @@ -1265,8 +1265,8 @@ static const char *_data_FX_MODE_FIRE_FLICKER PROGMEM = "Fire Flicker@!,!;!,,;!" /* * Gradient run base function */ -uint16_t WS2812FX::gradient_base(bool loading) { - uint16_t counter = now * ((SEGMENT.speed >> 2) + 1); +uint16_t gradient_base(bool loading) { + uint16_t counter = strip.now * ((SEGMENT.speed >> 2) + 1); uint16_t pp = counter * SEGLEN >> 16; if (SEGENV.call == 0) pp = 0; float val; //0.0 = sec 1.0 = pri @@ -1284,7 +1284,7 @@ uint16_t WS2812FX::gradient_base(bool loading) { val = MIN(abs(pp-i),MIN(abs(p1-i),abs(p2-i))); } val = (brd > val) ? val/brd * 255 : 255; - setPixelColor(i, color_blend(SEGCOLOR(0), color_from_palette(i, true, PALETTE_SOLID_WRAP, 1), val)); + strip.setPixelColor(i, color_blend(SEGCOLOR(0), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1), val)); } return FRAMETIME; @@ -1294,7 +1294,7 @@ uint16_t WS2812FX::gradient_base(bool loading) { /* * Gradient run */ -uint16_t WS2812FX::mode_gradient(void) { +uint16_t mode_gradient(void) { return gradient_base(false); } static const char *_data_FX_MODE_GRADIENT PROGMEM = "Gradient@!,Spread=16;!,!,;!"; @@ -1303,17 +1303,17 @@ static const char *_data_FX_MODE_GRADIENT PROGMEM = "Gradient@!,Spread=16;!,!,;! /* * Gradient run with hard transition */ -uint16_t WS2812FX::mode_loading(void) { +uint16_t mode_loading(void) { return gradient_base(true); } static const char *_data_FX_MODE_LOADING PROGMEM = "Loading@!,Fade=16;!,!,;!"; //American Police Light with all LEDs Red and Blue -uint16_t WS2812FX::police_base(uint32_t color1, uint32_t color2) +uint16_t police_base(uint32_t color1, uint32_t color2) { uint16_t delay = 1 + (FRAMETIME<<3) / SEGLEN; // longer segments should change faster - uint32_t it = now / map(SEGMENT.speed, 0, 255, delay<<4, delay); + uint32_t it = strip.now / map(SEGMENT.speed, 0, 255, delay<<4, delay); uint16_t offset = it % SEGLEN; uint16_t width = ((SEGLEN*(SEGMENT.intensity+1))>>9); //max width is half the strip @@ -1321,26 +1321,26 @@ uint16_t WS2812FX::police_base(uint32_t color1, uint32_t color2) for (uint16_t i = 0; i < width; i++) { uint16_t indexR = (offset + i) % SEGLEN; uint16_t indexB = (offset + i + (SEGLEN>>1)) % SEGLEN; - setPixelColor(indexR, color1); - setPixelColor(indexB, color2); + strip.setPixelColor(indexR, color1); + strip.setPixelColor(indexB, color2); } return FRAMETIME; } //Police Lights Red and Blue -uint16_t WS2812FX::mode_police() +uint16_t mode_police() { - fill(SEGCOLOR(1)); + strip.fill(SEGCOLOR(1)); return police_base(RED, BLUE); } static const char *_data_FX_MODE_POLICE PROGMEM = "Police@!,Width;,Bg,;0"; //Police Lights with custom colors -uint16_t WS2812FX::mode_two_dots() +uint16_t mode_two_dots() { - fill(SEGCOLOR(2)); + strip.fill(SEGCOLOR(2)); uint32_t color2 = (SEGCOLOR(1) == SEGCOLOR(2)) ? SEGCOLOR(0) : SEGCOLOR(1); return police_base(SEGCOLOR(0), color2); @@ -1361,12 +1361,12 @@ typedef struct Flasher { #define FLASHERS_PER_ZONE 6 #define MAX_SHIMMER 92 -uint16_t WS2812FX::mode_fairy() { +uint16_t mode_fairy() { //set every pixel to a 'random' color from palette (using seed so it doesn't change between frames) - uint16_t PRNG16 = 5100 + _segment_index; + uint16_t PRNG16 = 5100 + strip.getCurrSegmentId(); for (uint16_t i = 0; i < SEGLEN; i++) { PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; //next 'random' number - setPixelColor(i, color_from_palette(PRNG16 >> 8, false, false, 0)); + strip.setPixelColor(i, strip.color_from_palette(PRNG16 >> 8, false, false, 0)); } //amount of flasher pixels depending on intensity (0: none, 255: every LED) @@ -1377,7 +1377,7 @@ uint16_t WS2812FX::mode_fairy() { uint16_t dataSize = sizeof(flasher) * numFlashers; if (!SEGENV.allocateData(dataSize)) return FRAMETIME; //allocation failed Flasher* flashers = reinterpret_cast(SEGENV.data); - uint16_t now16 = now & 0xFFFF; + uint16_t now16 = strip.now & 0xFFFF; //Up to 11 flashers in one brightness zone, afterwards a new zone for every 6 flashers uint16_t zones = numFlashers/FLASHERS_PER_ZONE; @@ -1411,7 +1411,7 @@ uint16_t WS2812FX::mode_fairy() { } } if (stateTime > 255) stateTime = 255; //for flasher brightness calculation, fades in first 255 ms of state - //flasherBri[f - firstFlasher] = (flashers[f].stateOn) ? 255-gamma8((510 - stateTime) >> 1) : gamma8((510 - stateTime) >> 1); + //flasherBri[f - firstFlasher] = (flashers[f].stateOn) ? 255-strip.gamma8((510 - stateTime) >> 1) : strip.gamma8((510 - stateTime) >> 1); flasherBri[f - firstFlasher] = (flashers[f].stateOn) ? stateTime : 255 - (stateTime >> 0); flasherBriSum += flasherBri[f - firstFlasher]; } @@ -1423,10 +1423,10 @@ uint16_t WS2812FX::mode_fairy() { uint8_t bri = (flasherBri[f - firstFlasher] * globalPeakBri) / 255; PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; //next 'random' number uint16_t flasherPos = f*flasherDistance; - setPixelColor(flasherPos, color_blend(SEGCOLOR(1), color_from_palette(PRNG16 >> 8, false, false, 0), bri)); + strip.setPixelColor(flasherPos, color_blend(SEGCOLOR(1), strip.color_from_palette(PRNG16 >> 8, false, false, 0), bri)); for (uint16_t i = flasherPos+1; i < flasherPos+flasherDistance && i < SEGLEN; i++) { PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; //next 'random' number - setPixelColor(i, color_from_palette(PRNG16 >> 8, false, false, 0, globalPeakBri)); + strip.setPixelColor(i, strip.color_from_palette(PRNG16 >> 8, false, false, 0, globalPeakBri)); } } } @@ -1436,15 +1436,15 @@ static const char *_data_FX_MODE_FAIRY PROGMEM = "Fairy"; /* - * Fairytwinkle. Like Colortwinkle, but starting from all lit and not relying on getPixelColor + * Fairytwinkle. Like Colortwinkle, but starting from all lit and not relying on strip.getPixelColor * Warning: Uses 4 bytes of segment data per pixel */ -uint16_t WS2812FX::mode_fairytwinkle() { +uint16_t mode_fairytwinkle() { uint16_t dataSize = sizeof(flasher) * SEGLEN; if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed Flasher* flashers = reinterpret_cast(SEGENV.data); - uint16_t now16 = now & 0xFFFF; - uint16_t PRNG16 = 5100 + _segment_index; + uint16_t now16 = strip.now & 0xFFFF; + uint16_t PRNG16 = 5100 + strip.getCurrSegmentId(); uint16_t riseFallTime = 400 + (255-SEGMENT.speed)*3; uint16_t maxDur = riseFallTime/100 + ((255 - SEGMENT.intensity) >> 2) + 13 + ((255 - SEGMENT.intensity) >> 1); @@ -1471,14 +1471,14 @@ uint16_t WS2812FX::mode_fairytwinkle() { if (flashers[f].stateOn && flashers[f].stateDur > maxDur) flashers[f].stateDur = maxDur; //react more quickly on intensity change if (stateTime > riseFallTime) stateTime = riseFallTime; //for flasher brightness calculation, fades in first 255 ms of state uint8_t fadeprog = 255 - ((stateTime * 255) / riseFallTime); - uint8_t flasherBri = (flashers[f].stateOn) ? 255-gamma8(fadeprog) : gamma8(fadeprog); + uint8_t flasherBri = (flashers[f].stateOn) ? 255-strip.gamma8(fadeprog) : strip.gamma8(fadeprog); uint16_t lastR = PRNG16; uint16_t diff = 0; while (diff < 0x4000) { //make sure colors of two adjacent LEDs differ enough PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; //next 'random' number diff = (PRNG16 > lastR) ? PRNG16 - lastR : lastR - PRNG16; } - setPixelColor(f, color_blend(SEGCOLOR(1), color_from_palette(PRNG16 >> 8, false, false, 0), flasherBri)); + strip.setPixelColor(f, color_blend(SEGCOLOR(1), strip.color_from_palette(PRNG16 >> 8, false, false, 0), flasherBri)); } return FRAMETIME; } @@ -1488,9 +1488,9 @@ static const char *_data_FX_MODE_FAIRYTWINKLE PROGMEM = "Fairy Twinkle"; /* * Tricolor chase function */ -uint16_t WS2812FX::tricolor_chase(uint32_t color1, uint32_t color2) { +uint16_t tricolor_chase(uint32_t color1, uint32_t color2) { uint32_t cycleTime = 50 + ((255 - SEGMENT.speed)<<1); - uint32_t it = now / cycleTime; // iterator + uint32_t it = strip.now / cycleTime; // iterator uint8_t width = (1 + (SEGMENT.intensity>>4)); // value of 1-16 for each colour uint8_t index = it % (width*3); @@ -1498,10 +1498,10 @@ uint16_t WS2812FX::tricolor_chase(uint32_t color1, uint32_t color2) { if (index > (width*3)-1) index = 0; uint32_t color = color1; - if (index > (width<<1)-1) color = color_from_palette(i, true, PALETTE_SOLID_WRAP, 1); + if (index > (width<<1)-1) color = strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1); else if (index > width-1) color = color2; - setPixelColor(SEGLEN - i -1, color); + strip.setPixelColor(SEGLEN - i -1, color); } return FRAMETIME; } @@ -1510,7 +1510,7 @@ uint16_t WS2812FX::tricolor_chase(uint32_t color1, uint32_t color2) { /* * Tricolor chase mode */ -uint16_t WS2812FX::mode_tricolor_chase(void) { +uint16_t mode_tricolor_chase(void) { return tricolor_chase(SEGCOLOR(2), SEGCOLOR(0)); } static const char *_data_FX_MODE_TRICOLOR_CHASE PROGMEM = "Chase 3@!,Size;1,2,3;0"; @@ -1519,22 +1519,22 @@ static const char *_data_FX_MODE_TRICOLOR_CHASE PROGMEM = "Chase 3@!,Size;1,2,3; /* * ICU mode */ -uint16_t WS2812FX::mode_icu(void) { +uint16_t mode_icu(void) { uint16_t dest = SEGENV.step & 0xFFFF; uint8_t space = (SEGMENT.intensity >> 3) +2; - fill(SEGCOLOR(1)); + strip.fill(SEGCOLOR(1)); byte pindex = map(dest, 0, SEGLEN-SEGLEN/space, 0, 255); - uint32_t col = color_from_palette(pindex, false, false, 0); + uint32_t col = strip.color_from_palette(pindex, false, false, 0); - setPixelColor(dest, col); - setPixelColor(dest + SEGLEN/space, col); + strip.setPixelColor(dest, col); + strip.setPixelColor(dest + SEGLEN/space, col); if(SEGENV.aux0 == dest) { // pause between eye movements if(random8(6) == 0) { // blink once in a while - setPixelColor(dest, SEGCOLOR(1)); - setPixelColor(dest + SEGLEN/space, SEGCOLOR(1)); + strip.setPixelColor(dest, SEGCOLOR(1)); + strip.setPixelColor(dest + SEGLEN/space, SEGCOLOR(1)); return 200; } SEGENV.aux0 = random16(SEGLEN-SEGLEN/space); @@ -1549,8 +1549,8 @@ uint16_t WS2812FX::mode_icu(void) { dest--; } - setPixelColor(dest, col); - setPixelColor(dest + SEGLEN/space, col); + strip.setPixelColor(dest, col); + strip.setPixelColor(dest + SEGLEN/space, col); return SPEED_FORMULA_L; } @@ -1560,36 +1560,36 @@ static const char *_data_FX_MODE_ICU PROGMEM = "ICU"; /* * Custom mode by Aircoookie. Color Wipe, but with 3 colors */ -uint16_t WS2812FX::mode_tricolor_wipe(void) +uint16_t mode_tricolor_wipe(void) { uint32_t cycleTime = 1000 + (255 - SEGMENT.speed)*200; - uint32_t perc = now % cycleTime; + uint32_t perc = strip.now % cycleTime; uint16_t prog = (perc * 65535) / cycleTime; uint16_t ledIndex = (prog * SEGLEN * 3) >> 16; uint16_t ledOffset = ledIndex; for (uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 2)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2)); } if(ledIndex < SEGLEN) { //wipe from 0 to 1 for (uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, (i > ledOffset)? SEGCOLOR(0) : SEGCOLOR(1)); + strip.setPixelColor(i, (i > ledOffset)? SEGCOLOR(0) : SEGCOLOR(1)); } } else if (ledIndex < SEGLEN*2) { //wipe from 1 to 2 ledOffset = ledIndex - SEGLEN; for (uint16_t i = ledOffset +1; i < SEGLEN; i++) { - setPixelColor(i, SEGCOLOR(1)); + strip.setPixelColor(i, SEGCOLOR(1)); } } else //wipe from 2 to 0 { ledOffset = ledIndex - SEGLEN*2; for (uint16_t i = 0; i <= ledOffset; i++) { - setPixelColor(i, SEGCOLOR(0)); + strip.setPixelColor(i, SEGCOLOR(0)); } } @@ -1603,9 +1603,9 @@ static const char *_data_FX_MODE_TRICOLOR_WIPE PROGMEM = "Tri Wipe@!,;1,2,3;0"; * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/TriFade.h * Modified by Aircoookie */ -uint16_t WS2812FX::mode_tricolor_fade(void) +uint16_t mode_tricolor_fade(void) { - uint16_t counter = now * ((SEGMENT.speed >> 3) +1); + uint16_t counter = strip.now * ((SEGMENT.speed >> 3) +1); uint32_t prog = (counter * 768) >> 16; uint32_t color1 = 0, color2 = 0; @@ -1629,13 +1629,13 @@ uint16_t WS2812FX::mode_tricolor_fade(void) for(uint16_t i = 0; i < SEGLEN; i++) { uint32_t color; if (stage == 2) { - color = color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), color2, stp); + color = color_blend(strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), color2, stp); } else if (stage == 1) { - color = color_blend(color1, color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), stp); + color = color_blend(color1, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), stp); } else { color = color_blend(color1, color2, stp); } - setPixelColor(i, color); + strip.setPixelColor(i, color); } return FRAMETIME; @@ -1647,14 +1647,14 @@ static const char *_data_FX_MODE_TRICOLOR_FADE PROGMEM = "Tri Fade"; * Creates random comets * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/MultiComet.h */ -uint16_t WS2812FX::mode_multi_comet(void) +uint16_t mode_multi_comet(void) { uint32_t cycleTime = 10 + (uint32_t)(255 - SEGMENT.speed); - uint32_t it = now / cycleTime; + uint32_t it = strip.now / cycleTime; if (SEGENV.step == it) return FRAMETIME; if (!SEGENV.allocateData(sizeof(uint16_t) * 8)) return mode_static(); //allocation failed - fade_out(SEGMENT.intensity); + strip.fade_out(SEGMENT.intensity); uint16_t* comets = reinterpret_cast(SEGENV.data); @@ -1663,10 +1663,10 @@ uint16_t WS2812FX::mode_multi_comet(void) uint16_t index = comets[i]; if (SEGCOLOR(2) != 0) { - setPixelColor(index, i % 2 ? color_from_palette(index, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(2)); + strip.setPixelColor(index, i % 2 ? strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(2)); } else { - setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(index, strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); } comets[i]++; } else { @@ -1686,7 +1686,7 @@ static const char *_data_FX_MODE_MULTI_COMET PROGMEM = "Multi Comet"; * Creates two Larson scanners moving in opposite directions * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/DualLarson.h */ -uint16_t WS2812FX::mode_dual_larson_scanner(void){ +uint16_t mode_dual_larson_scanner(void){ return larson_scanner(true); } static const char *_data_FX_MODE_DUAL_LARSON_SCANNER PROGMEM = "Scanner Dual"; @@ -1696,7 +1696,7 @@ static const char *_data_FX_MODE_DUAL_LARSON_SCANNER PROGMEM = "Scanner Dual"; * Running random pixels ("Stream 2") * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/RandomChase.h */ -uint16_t WS2812FX::mode_random_chase(void) +uint16_t mode_random_chase(void) { if (SEGENV.call == 0) { SEGENV.step = RGBW32(random8(), random8(), random8(), 0); @@ -1704,7 +1704,7 @@ uint16_t WS2812FX::mode_random_chase(void) } uint16_t prevSeed = random16_get_seed(); // save seed so we can restore it at the end of the function uint32_t cycleTime = 25 + (3 * (uint32_t)(255 - SEGMENT.speed)); - uint32_t it = now / cycleTime; + uint32_t it = strip.now / cycleTime; uint32_t color = SEGENV.step; random16_set_seed(SEGENV.aux0); @@ -1713,7 +1713,7 @@ uint16_t WS2812FX::mode_random_chase(void) uint8_t g = random8(6) != 0 ? (color >> 8 & 0xFF) : random8(); uint8_t b = random8(6) != 0 ? (color & 0xFF) : random8(); color = RGBW32(r, g, b, 0); - setPixelColor(i, r, g, b); + strip.setPixelColor(i, r, g, b); if (i == SEGLEN -1 && SEGENV.aux1 != (it & 0xFFFF)) { //new first color in next frame SEGENV.step = color; SEGENV.aux0 = random16_get_seed(); @@ -1739,7 +1739,7 @@ typedef struct Oscillator { /* / Oscillating bars of color, updated with standard framerate */ -uint16_t WS2812FX::mode_oscillate(void) +uint16_t mode_oscillate(void) { uint8_t numOscillators = 3; uint16_t dataSize = sizeof(oscillator) * numOscillators; @@ -1756,7 +1756,7 @@ uint16_t WS2812FX::mode_oscillate(void) } uint32_t cycleTime = 20 + (2 * (uint32_t)(255 - SEGMENT.speed)); - uint32_t it = now / cycleTime; + uint32_t it = strip.now / cycleTime; for(uint8_t i = 0; i < numOscillators; i++) { // if the counter has increased, move the oscillator by the random step @@ -1782,7 +1782,7 @@ uint16_t WS2812FX::mode_oscillate(void) color = (color == BLACK) ? SEGCOLOR(j) : color_blend(color, SEGCOLOR(j), 128); } } - setPixelColor(i, color); + strip.setPixelColor(i, color); } SEGENV.step = it; @@ -1792,7 +1792,7 @@ static const char *_data_FX_MODE_OSCILLATE PROGMEM = "Oscillate"; //TODO -uint16_t WS2812FX::mode_lightning(void) +uint16_t mode_lightning(void) { uint16_t ledstart = random16(SEGLEN); // Determine starting location of flash uint16_t ledlen = 1 + random16(SEGLEN -ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1) @@ -1807,12 +1807,12 @@ uint16_t WS2812FX::mode_lightning(void) SEGENV.aux0 = 200; //200ms delay after leader } - fill(SEGCOLOR(1)); + strip.fill(SEGCOLOR(1)); if (SEGENV.aux1 > 3 && !(SEGENV.aux1 & 0x01)) { //flash on even number >2 for (int i = ledstart; i < ledstart + ledlen; i++) { - setPixelColor(i,color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, bri)); + strip.setPixelColor(i,strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, bri)); } SEGENV.aux1--; @@ -1838,7 +1838,7 @@ static const char *_data_FX_MODE_LIGHTNING PROGMEM = "Lightning"; // Pride2015 // Animated, ever-changing rainbows. // by Mark Kriegsman: https://gist.github.com/kriegsman/964de772d64c502760e5 -uint16_t WS2812FX::mode_pride_2015(void) +uint16_t mode_pride_2015(void) { uint16_t duration = 10 + SEGMENT.speed; uint16_t sPseudotime = SEGENV.step; @@ -1869,10 +1869,10 @@ uint16_t WS2812FX::mode_pride_2015(void) bri8 += (255 - brightdepth); CRGB newcolor = CHSV( hue8, sat8, bri8); - fastled_col = col_to_crgb(getPixelColor(i)); + fastled_col = CRGB(strip.getPixelColor(i)); nblend(fastled_col, newcolor, 64); - setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } SEGENV.step = sPseudotime; SEGENV.aux0 = sHue16; @@ -1882,15 +1882,15 @@ static const char *_data_FX_MODE_PRIDE_2015 PROGMEM = "Pride 2015@!,;;"; //eight colored dots, weaving in and out of sync with each other -uint16_t WS2812FX::mode_juggle(void){ - fade_out(SEGMENT.intensity); +uint16_t mode_juggle(void){ + strip.fade_out(SEGMENT.intensity); CRGB fastled_col; byte dothue = 0; for ( byte i = 0; i < 8; i++) { uint16_t index = 0 + beatsin88((128 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1); - fastled_col = col_to_crgb(getPixelColor(index)); - fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(currentPalette, dothue, 255); - setPixelColor(index, fastled_col.red, fastled_col.green, fastled_col.blue); + fastled_col = CRGB(strip.getPixelColor(index)); + fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(strip.currentPalette, dothue, 255); + strip.setPixelColor(index, fastled_col.red, fastled_col.green, fastled_col.blue); dothue += 32; } return FRAMETIME; @@ -1898,23 +1898,23 @@ uint16_t WS2812FX::mode_juggle(void){ static const char *_data_FX_MODE_JUGGLE PROGMEM = "Juggle@!=16,Trail=240;!,!,;!"; -uint16_t WS2812FX::mode_palette() +uint16_t mode_palette() { uint16_t counter = 0; if (SEGMENT.speed != 0) { - counter = (now * ((SEGMENT.speed >> 3) +1)) & 0xFFFF; + counter = (strip.now * ((SEGMENT.speed >> 3) +1)) & 0xFFFF; counter = counter >> 8; } - bool noWrap = (paletteBlend == 2 || (paletteBlend == 0 && SEGMENT.speed == 0)); + bool noWrap = (strip.paletteBlend == 2 || (strip.paletteBlend == 0 && SEGMENT.speed == 0)); for (uint16_t i = 0; i < SEGLEN; i++) { uint8_t colorIndex = (i * 255 / SEGLEN) - counter; if (noWrap) colorIndex = map(colorIndex, 0, 255, 0, 240); //cut off blend at palette "end" - setPixelColor(i, color_from_palette(colorIndex, false, true, 255)); + strip.setPixelColor(i, strip.color_from_palette(colorIndex, false, true, 255)); } return FRAMETIME; } @@ -1949,12 +1949,12 @@ static const char *_data_FX_MODE_PALETTE PROGMEM = "Palette@!,;1,2,3;!"; // There are two main parameters you can play with to control the look and // feel of your fire: COOLING (used in step 1 above) (Speed = COOLING), and SPARKING (used // in step 3 above) (Effect Intensity = Sparking). -uint16_t WS2812FX::mode_fire_2012() +uint16_t mode_fire_2012() { - const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : 1; - const uint16_t rows = isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); + const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1; + const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); - uint32_t it = now >> 5; //div 32 + uint32_t it = strip.now >> 5; //div 32 uint16_t q = cols>>2; // a quarter of flames if (!SEGENV.allocateData(cols*rows)) return mode_static(); //allocation failed @@ -1994,9 +1994,9 @@ uint16_t WS2812FX::mode_fire_2012() for (uint16_t f = 0; f < cols; f++) { // Step 4. Map from heat cells to LED colors for (uint16_t j = 0; j < rows; j++) { - CRGB color = ColorFromPalette(currentPalette, /*MIN(*/heat[j+rows*f]/*,240)*/, 255, LINEARBLEND); - if (isMatrix) setPixelColorXY(f, rows -j -1, color); - else setPixelColor(j, color); + CRGB color = ColorFromPalette(strip.currentPalette, /*MIN(*/heat[j+rows*f]/*,240)*/, 255, LINEARBLEND); + if (strip.isMatrix) strip.setPixelColorXY(f, rows -j -1, color); + else strip.setPixelColor(j, color); } } return FRAMETIME; @@ -2007,7 +2007,7 @@ static const char *_data_FX_MODE_FIRE_2012 PROGMEM = "Fire 2012@Cooling=120,Spar // ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb // This function draws color waves with an ever-changing, // widely-varying set of parameters, using a color palette. -uint16_t WS2812FX::mode_colorwaves() +uint16_t mode_colorwaves() { uint16_t duration = 10 + SEGMENT.speed; uint16_t sPseudotime = SEGENV.step; @@ -2043,11 +2043,11 @@ uint16_t WS2812FX::mode_colorwaves() uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536; bri8 += (255 - brightdepth); - CRGB newcolor = ColorFromPalette(currentPalette, hue8, bri8); - fastled_col = col_to_crgb(getPixelColor(i)); + CRGB newcolor = ColorFromPalette(strip.currentPalette, hue8, bri8); + fastled_col = CRGB(strip.getPixelColor(i)); nblend(fastled_col, newcolor, 128); - setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } SEGENV.step = sPseudotime; SEGENV.aux0 = sHue16; @@ -2057,28 +2057,28 @@ static const char *_data_FX_MODE_COLORWAVES PROGMEM = "Colorwaves"; // colored stripes pulsing at a defined Beats-Per-Minute (BPM) -uint16_t WS2812FX::mode_bpm() +uint16_t mode_bpm() { CRGB fastled_col; - uint32_t stp = (now / 20) & 0xFF; + uint32_t stp = (strip.now / 20) & 0xFF; uint8_t beat = beatsin8(SEGMENT.speed, 64, 255); for (uint16_t i = 0; i < SEGLEN; i++) { - fastled_col = ColorFromPalette(currentPalette, stp + (i * 2), beat - stp + (i * 10)); - setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + fastled_col = ColorFromPalette(strip.currentPalette, stp + (i * 2), beat - stp + (i * 10)); + strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; } static const char *_data_FX_MODE_BPM PROGMEM = "Bpm@!=64,;1,2,3;!"; -uint16_t WS2812FX::mode_fillnoise8() +uint16_t mode_fillnoise8() { if (SEGENV.call == 0) SEGENV.step = random16(12345); CRGB fastled_col; for (uint16_t i = 0; i < SEGLEN; i++) { uint8_t index = inoise8(i * SEGLEN, SEGENV.step + i * SEGLEN); - fastled_col = ColorFromPalette(currentPalette, index, 255, LINEARBLEND); - setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + fastled_col = ColorFromPalette(strip.currentPalette, index, 255, LINEARBLEND); + strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } SEGENV.step += beatsin8(SEGMENT.speed, 1, 6); //10,1,4 @@ -2087,7 +2087,7 @@ uint16_t WS2812FX::mode_fillnoise8() static const char *_data_FX_MODE_FILLNOISE8 PROGMEM = "Fill Noise"; -uint16_t WS2812FX::mode_noise16_1() +uint16_t mode_noise16_1() { uint16_t scale = 320; // the "zoom factor" for the noise CRGB fastled_col; @@ -2107,8 +2107,8 @@ uint16_t WS2812FX::mode_noise16_1() uint8_t index = sin8(noise * 3); // map LED color based on noise data - fastled_col = ColorFromPalette(currentPalette, index, 255, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. - setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + fastled_col = ColorFromPalette(strip.currentPalette, index, 255, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. + strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; @@ -2116,7 +2116,7 @@ uint16_t WS2812FX::mode_noise16_1() static const char *_data_FX_MODE_NOISE16_1 PROGMEM = "Noise 1"; -uint16_t WS2812FX::mode_noise16_2() +uint16_t mode_noise16_2() { uint16_t scale = 1000; // the "zoom factor" for the noise CRGB fastled_col; @@ -2132,8 +2132,8 @@ uint16_t WS2812FX::mode_noise16_2() uint8_t index = sin8(noise * 3); // map led color based on noise data - fastled_col = ColorFromPalette(currentPalette, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. - setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + fastled_col = ColorFromPalette(strip.currentPalette, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. + strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; @@ -2141,7 +2141,7 @@ uint16_t WS2812FX::mode_noise16_2() static const char *_data_FX_MODE_NOISE16_2 PROGMEM = "Noise 2"; -uint16_t WS2812FX::mode_noise16_3() +uint16_t mode_noise16_3() { uint16_t scale = 800; // the "zoom factor" for the noise CRGB fastled_col; @@ -2160,8 +2160,8 @@ uint16_t WS2812FX::mode_noise16_3() uint8_t index = sin8(noise * 3); // map led color based on noise data - fastled_col = ColorFromPalette(currentPalette, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. - setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + fastled_col = ColorFromPalette(strip.currentPalette, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. + strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; @@ -2170,14 +2170,14 @@ static const char *_data_FX_MODE_NOISE16_3 PROGMEM = "Noise 3"; //https://github.com/aykevl/ledstrip-spark/blob/master/ledstrip.ino -uint16_t WS2812FX::mode_noise16_4() +uint16_t mode_noise16_4() { CRGB fastled_col; - uint32_t stp = (now * SEGMENT.speed) >> 7; + uint32_t stp = (strip.now * SEGMENT.speed) >> 7; for (uint16_t i = 0; i < SEGLEN; i++) { int16_t index = inoise16(uint32_t(i) << 12, stp); - fastled_col = ColorFromPalette(currentPalette, index); - setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + fastled_col = ColorFromPalette(strip.currentPalette, index); + strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; } @@ -2185,20 +2185,21 @@ static const char *_data_FX_MODE_NOISE16_4 PROGMEM = "Noise 4"; //based on https://gist.github.com/kriegsman/5408ecd397744ba0393e -uint16_t WS2812FX::mode_colortwinkle() +uint16_t mode_colortwinkle() { - const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : 1; - const uint16_t rows = isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); + const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1; + const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); uint16_t dataSize = (cols*rows+7) >> 3; //1 bit per LED if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB fastled_col, prev; - fract8 fadeUpAmount = _brightness>28 ? 8 + (SEGMENT.speed>>2) : 68-_brightness, fadeDownAmount = _brightness>28 ? 8 + (SEGMENT.speed>>3) : 68-_brightness; + 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 (uint16_t i = 0; i < rows*cols; i++) { uint16_t j = i % cols, k = i / cols; - fastled_col = col_to_crgb(isMatrix ? getPixelColorXY(j, k) : getPixelColor(i)); + fastled_col = CRGB(strip.isMatrix ? strip.getPixelColorXY(j, k) : strip.getPixelColor(i)); prev = fastled_col; uint16_t index = i >> 3; uint8_t bitNum = i & 0x07; @@ -2213,19 +2214,19 @@ uint16_t WS2812FX::mode_colortwinkle() bitWrite(SEGENV.data[index], bitNum, false); } - if (isMatrix) setPixelColorXY(j, k, fastled_col); - else setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + if (strip.isMatrix) strip.setPixelColorXY(j, k, fastled_col); + else strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); - uint32_t col = isMatrix ? getPixelColorXY(j, k) : getPixelColor(i); - if (col_to_crgb(col) == prev) { //fix "stuck" pixels + uint32_t col = strip.isMatrix ? strip.getPixelColorXY(j, k) : strip.getPixelColor(i); + if (CRGB(col) == prev) { //fix "stuck" pixels fastled_col += fastled_col; - if (isMatrix) setPixelColorXY(j, k, fastled_col); - else setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + if (strip.isMatrix) strip.setPixelColorXY(j, k, fastled_col); + else strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } } else { fastled_col.nscale8(255 - fadeDownAmount); - if (isMatrix) setPixelColorXY(j, k, fastled_col); - else setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + if (strip.isMatrix) strip.setPixelColorXY(j, k, fastled_col); + else strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } } @@ -2234,14 +2235,14 @@ uint16_t WS2812FX::mode_colortwinkle() for (uint8_t times = 0; times < 5; times++) { //attempt to spawn a new pixel 5 times uint16_t i = random16(rows*cols); uint16_t j = i % cols, k = i / cols; - uint32_t col = isMatrix ? getPixelColorXY(j, k) : getPixelColor(i); + uint32_t col = strip.isMatrix ? strip.getPixelColorXY(j, k) : strip.getPixelColor(i); if (col == 0) { - fastled_col = ColorFromPalette(currentPalette, random8(), 64, NOBLEND); + fastled_col = ColorFromPalette(strip.currentPalette, random8(), 64, NOBLEND); uint16_t index = i >> 3; uint8_t bitNum = i & 0x07; bitWrite(SEGENV.data[index], bitNum, true); - if (isMatrix) setPixelColorXY(j, k, fastled_col); - else setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + if (strip.isMatrix) strip.setPixelColorXY(j, k, fastled_col); + else strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); break; //only spawn 1 new pixel per frame per 50 LEDs } } @@ -2253,7 +2254,7 @@ static const char *_data_FX_MODE_COLORTWINKLE PROGMEM = "Colortwinkles@Fade spee //Calm effect, like a lake at night -uint16_t WS2812FX::mode_lake() { +uint16_t mode_lake() { uint8_t sp = SEGMENT.speed/10; int wave1 = beatsin8(sp +2, -64,64); int wave2 = beatsin8(sp +1, -64,64); @@ -2264,8 +2265,8 @@ uint16_t WS2812FX::mode_lake() { { int index = cos8((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2; uint8_t lum = (index > wave3) ? index - wave3 : 0; - fastled_col = ColorFromPalette(currentPalette, map(index,0,255,0,240), lum, LINEARBLEND); - setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); + fastled_col = ColorFromPalette(strip.currentPalette, map(index,0,255,0,240), lum, LINEARBLEND); + strip.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } return FRAMETIME; } @@ -2275,13 +2276,13 @@ static const char *_data_FX_MODE_LAKE PROGMEM = "Lake@!,;1,2,3;!"; // meteor effect // send a meteor from begining to to the end of the strip with a trail that randomly decays. // adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain -uint16_t WS2812FX::mode_meteor() { +uint16_t mode_meteor() { if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed byte* trail = SEGENV.data; byte meteorSize= 1+ SEGLEN / 10; - uint16_t counter = now * ((SEGMENT.speed >> 2) +8); + uint16_t counter = strip.now * ((SEGMENT.speed >> 2) +8); uint16_t in = counter * SEGLEN >> 16; // fade all leds to colors[1] in LEDs one step @@ -2290,7 +2291,7 @@ uint16_t WS2812FX::mode_meteor() { { byte meteorTrailDecay = 128 + random8(127); trail[i] = scale8(trail[i], meteorTrailDecay); - setPixelColor(i, color_from_palette(trail[i], false, true, 255)); + strip.setPixelColor(i, strip.color_from_palette(trail[i], false, true, 255)); } } @@ -2302,7 +2303,7 @@ uint16_t WS2812FX::mode_meteor() { } trail[index] = 240; - setPixelColor(index, color_from_palette(trail[index], false, true, 255)); + strip.setPixelColor(index, strip.color_from_palette(trail[index], false, true, 255)); } return FRAMETIME; @@ -2313,7 +2314,7 @@ static const char *_data_FX_MODE_METEOR PROGMEM = "Meteor@!,Trail length;!,!,;!" // smooth meteor effect // send a meteor from begining to to the end of the strip with a trail that randomly decays. // adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain -uint16_t WS2812FX::mode_meteor_smooth() { +uint16_t mode_meteor_smooth() { if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed byte* trail = SEGENV.data; @@ -2329,7 +2330,7 @@ uint16_t WS2812FX::mode_meteor_smooth() { trail[i] += change; if (trail[i] > 245) trail[i] = 0; if (trail[i] > 240) trail[i] = 240; - setPixelColor(i, color_from_palette(trail[i], false, true, 255)); + strip.setPixelColor(i, strip.color_from_palette(trail[i], false, true, 255)); } } @@ -2339,7 +2340,7 @@ uint16_t WS2812FX::mode_meteor_smooth() { if(in + j >= SEGLEN) { index = (in + j - SEGLEN); } - setPixelColor(index, color_blend(getPixelColor(index), color_from_palette(240, false, true, 255), 48)); + strip.setPixelColor(index, color_blend(strip.getPixelColor(index), strip.color_from_palette(240, false, true, 255), 48)); trail[index] = 240; } @@ -2350,7 +2351,7 @@ static const char *_data_FX_MODE_METEOR_SMOOTH PROGMEM = "Meteor Smooth@!,Trail //Railway Crossing / Christmas Fairy lights -uint16_t WS2812FX::mode_railway() +uint16_t mode_railway() { uint16_t dur = 40 + (255 - SEGMENT.speed) * 10; uint16_t rampdur = (dur * SEGMENT.intensity) >> 8; @@ -2369,10 +2370,10 @@ uint16_t WS2812FX::mode_railway() if (SEGENV.aux0) pos = 255 - pos; for (uint16_t i = 0; i < SEGLEN; i += 2) { - setPixelColor(i, color_from_palette(255 - pos, false, false, 255)); + strip.setPixelColor(i, strip.color_from_palette(255 - pos, false, false, 255)); if (i < SEGLEN -1) { - setPixelColor(i + 1, color_from_palette(pos, false, false, 255)); + strip.setPixelColor(i + 1, strip.color_from_palette(pos, false, false, 255)); } } SEGENV.step += FRAMETIME; @@ -2397,7 +2398,7 @@ typedef struct Ripple { #else #define MAX_RIPPLES 100 #endif -uint16_t WS2812FX::ripple_base(bool rainbow) +uint16_t ripple_base(bool rainbow) { uint16_t maxRipples = min(1 + (SEGLEN >> 2), MAX_RIPPLES); // 56 max for 16 segment ESP8266 uint16_t dataSize = sizeof(ripple) * maxRipples; @@ -2420,9 +2421,9 @@ uint16_t WS2812FX::ripple_base(bool rainbow) } else { SEGENV.aux0--; } - fill(color_blend(color_wheel(SEGENV.aux0),BLACK,235)); + strip.fill(color_blend(strip.color_wheel(SEGENV.aux0),BLACK,235)); } else { - fill(SEGCOLOR(1)); + strip.fill(SEGCOLOR(1)); } //draw wave @@ -2433,7 +2434,7 @@ uint16_t WS2812FX::ripple_base(bool rainbow) { uint8_t rippledecay = (SEGMENT.speed >> 4) +1; //faster decay if faster propagation uint16_t rippleorigin = ripples[i].pos; - uint32_t col = color_from_palette(ripples[i].color, false, false, 255); + uint32_t col = strip.color_from_palette(ripples[i].color, false, false, 255); uint16_t propagation = ((ripplestate/rippledecay -1) * SEGMENT.speed); int16_t propI = propagation >> 8; uint8_t propF = propagation & 0xFF; @@ -2445,12 +2446,12 @@ uint16_t WS2812FX::ripple_base(bool rainbow) uint8_t mag = scale8(cubicwave8((propF>>2)+(v-left)*64), amp); if (v < SEGLEN && v >= 0) { - setPixelColor(v, color_blend(getPixelColor(v), col, mag)); + strip.setPixelColor(v, color_blend(strip.getPixelColor(v), col, mag)); } int16_t w = left + propI*2 + 3 -(v-left); if (w < SEGLEN && w >= 0) { - setPixelColor(w, color_blend(getPixelColor(w), col, mag)); + strip.setPixelColor(w, color_blend(strip.getPixelColor(w), col, mag)); } } ripplestate += rippledecay; @@ -2470,13 +2471,13 @@ uint16_t WS2812FX::ripple_base(bool rainbow) #undef MAX_RIPPLES -uint16_t WS2812FX::mode_ripple(void) { +uint16_t mode_ripple(void) { return ripple_base(false); } static const char *_data_FX_MODE_RIPPLE PROGMEM = "Ripple"; -uint16_t WS2812FX::mode_ripple_rainbow(void) { +uint16_t mode_ripple_rainbow(void) { return ripple_base(true); } static const char *_data_FX_MODE_RIPPLE_RAINBOW PROGMEM = "Ripple Rainbow"; @@ -2492,7 +2493,7 @@ static const char *_data_FX_MODE_RIPPLE_RAINBOW PROGMEM = "Ripple Rainbow"; // incandescent bulbs change color as they get dim down. #define COOL_LIKE_INCANDESCENT 1 -CRGB WS2812FX::twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat) +CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat) { // Overall twinkle speed (changed) uint16_t ticks = ms / SEGENV.aux0; @@ -2529,7 +2530,7 @@ CRGB WS2812FX::twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat) uint8_t hue = slowcycle8 - salt; CRGB c; if (bright > 0) { - c = ColorFromPalette(currentPalette, hue, bright, NOBLEND); + c = ColorFromPalette(strip.currentPalette, hue, bright, NOBLEND); if(COOL_LIKE_INCANDESCENT == 1) { // This code takes a pixel, and if its in the 'fading down' // part of the cycle, it adjusts the color a little bit like the @@ -2552,7 +2553,7 @@ CRGB WS2812FX::twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat) // "CalculateOneTwinkle" on each pixel. It then displays // either the twinkle color of the background color, // whichever is brighter. -uint16_t WS2812FX::twinklefox_base(bool cat) +uint16_t twinklefox_base(bool cat) { // "PRNG16" is the pseudorandom number generator // It MUST be reset to the same starting value each time @@ -2565,8 +2566,7 @@ uint16_t WS2812FX::twinklefox_base(bool cat) else SEGENV.aux0 = 22 + ((100 - SEGMENT.speed) >> 1); // Set up the background color, "bg". - CRGB bg; - bg = col_to_crgb(SEGCOLOR(1)); + CRGB bg = CRGB(SEGCOLOR(1)); uint8_t bglight = bg.getAverageLight(); if (bglight > 64) { bg.nscale8_video(16); // very bright, so scale to 1/16th @@ -2585,7 +2585,7 @@ uint16_t WS2812FX::twinklefox_base(bool cat) PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number // use that number as clock speed adjustment factor (in 8ths, from 8/8ths to 23/8ths) uint8_t myspeedmultiplierQ5_3 = ((((PRNG16 & 0xFF)>>4) + (PRNG16 & 0x0F)) & 0x0F) + 0x08; - uint32_t myclock30 = (uint32_t)((now * myspeedmultiplierQ5_3) >> 3) + myclockoffset16; + uint32_t myclock30 = (uint32_t)((strip.now * myspeedmultiplierQ5_3) >> 3) + myclockoffset16; uint8_t myunique8 = PRNG16 >> 8; // get 'salt' value for this pixel // We now have the adjusted 'clock' for this pixel, now we call @@ -2598,29 +2598,29 @@ uint16_t WS2812FX::twinklefox_base(bool cat) if (deltabright >= 32 || (!bg)) { // If the new pixel is significantly brighter than the background color, // use the new color. - setPixelColor(i, c.red, c.green, c.blue); + strip.setPixelColor(i, c.red, c.green, c.blue); } 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 - setPixelColor(i, color_blend(crgb_to_col(bg), crgb_to_col(c), deltabright * 8)); + strip.setPixelColor(i, color_blend(RGBW32(bg.r,bg.g,bg.b,0), RGBW32(c.r,c.g,c.b,0), deltabright * 8)); } else { // if the new pixel is not at all brighter than the background color, // just use the background color. - setPixelColor(i, bg.r, bg.g, bg.b); + strip.setPixelColor(i, bg.r, bg.g, bg.b); } } return FRAMETIME; } -uint16_t WS2812FX::mode_twinklefox() +uint16_t mode_twinklefox() { return twinklefox_base(false); } static const char *_data_FX_MODE_TWINKLEFOX PROGMEM = "Twinklefox"; -uint16_t WS2812FX::mode_twinklecat() +uint16_t mode_twinklecat() { return twinklefox_base(true); } @@ -2631,12 +2631,12 @@ static const char *_data_FX_MODE_TWINKLECAT PROGMEM = "Twinklecat"; #define HALLOWEEN_EYE_SPACE (2*MAX(1,SEGLEN>>5)) #define HALLOWEEN_EYE_WIDTH MAX(1,SEGLEN>>5) -uint16_t WS2812FX::mode_halloween_eyes() +uint16_t mode_halloween_eyes() { uint16_t eyeLength = (2*HALLOWEEN_EYE_WIDTH) + HALLOWEEN_EYE_SPACE; if (eyeLength > SEGLEN) return mode_static(); //bail if segment too short - fill(SEGCOLOR(1)); //fill background + strip.fill(SEGCOLOR(1)); //fill background uint8_t state = SEGENV.aux1 >> 8; uint16_t stateTime = SEGENV.call; @@ -2645,7 +2645,7 @@ uint16_t WS2812FX::mode_halloween_eyes() if (state == 0) { //spawn eyes SEGENV.aux0 = random16(0, SEGLEN - eyeLength); //start pos SEGENV.aux1 = random8(); //color - if (isMatrix) SEGMENT.offset = random16(SEGMENT.virtualHeight()-1); // a hack: reuse offset since it is not used in matrices + if (strip.isMatrix) SEGMENT.offset = random16(SEGMENT.virtualHeight()-1); // a hack: reuse offset since it is not used in matrices state = 1; } @@ -2653,22 +2653,22 @@ uint16_t WS2812FX::mode_halloween_eyes() uint16_t startPos = SEGENV.aux0; uint16_t start2ndEye = startPos + HALLOWEEN_EYE_WIDTH + HALLOWEEN_EYE_SPACE; - uint32_t fadestage = (now - SEGENV.step)*255 / stateTime; + uint32_t fadestage = (strip.now - SEGENV.step)*255 / stateTime; if (fadestage > 255) fadestage = 255; - uint32_t c = color_blend(color_from_palette(SEGENV.aux1 & 0xFF, false, false, 0), SEGCOLOR(1), fadestage); + uint32_t c = color_blend(strip.color_from_palette(SEGENV.aux1 & 0xFF, false, false, 0), SEGCOLOR(1), fadestage); for (uint16_t i = 0; i < HALLOWEEN_EYE_WIDTH; i++) { - if (isMatrix) { - setPixelColorXY(startPos + i, SEGMENT.offset, c); - setPixelColorXY(start2ndEye + i, SEGMENT.offset, c); + if (strip.isMatrix) { + strip.setPixelColorXY(startPos + i, SEGMENT.offset, c); + strip.setPixelColorXY(start2ndEye + i, SEGMENT.offset, c); } else { - setPixelColor(startPos + i, c); - setPixelColor(start2ndEye + i, c); + strip.setPixelColor(startPos + i, c); + strip.setPixelColor(start2ndEye + i, c); } } } - if (now - SEGENV.step > stateTime) { + if (strip.now - SEGENV.step > stateTime) { state++; if (state > 2) state = 0; @@ -2678,7 +2678,7 @@ uint16_t WS2812FX::mode_halloween_eyes() uint16_t eyeOffTimeBase = (255 - SEGMENT.speed)*10; stateTime = eyeOffTimeBase + random16(eyeOffTimeBase); } - SEGENV.step = now; + SEGENV.step = strip.now; SEGENV.call = stateTime; } @@ -2690,7 +2690,7 @@ static const char *_data_FX_MODE_HALLOWEEN_EYES PROGMEM = "Halloween Eyes@Durati //Speed slider sets amount of LEDs lit, intensity sets unlit -uint16_t WS2812FX::mode_static_pattern() +uint16_t mode_static_pattern() { uint16_t lit = 1 + SEGMENT.speed; uint16_t unlit = 1 + SEGMENT.intensity; @@ -2698,7 +2698,7 @@ uint16_t WS2812FX::mode_static_pattern() uint16_t cnt = 0; for (uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, (drawingLit) ? color_from_palette(i, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(1)); + strip.setPixelColor(i, (drawingLit) ? strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(1)); cnt++; if (cnt >= ((drawingLit) ? lit : unlit)) { cnt = 0; @@ -2711,7 +2711,7 @@ uint16_t WS2812FX::mode_static_pattern() static const char *_data_FX_MODE_STATIC_PATTERN PROGMEM = "Solid Pattern@Fg size,Bg size;Fg,Bg,;!=0"; -uint16_t WS2812FX::mode_tri_static_pattern() +uint16_t mode_tri_static_pattern() { uint8_t segSize = (SEGMENT.intensity >> 5) +1; uint8_t currSeg = 0; @@ -2719,11 +2719,11 @@ uint16_t WS2812FX::mode_tri_static_pattern() for (uint16_t i = 0; i < SEGLEN; i++) { if ( currSeg % 3 == 0 ) { - setPixelColor(i, SEGCOLOR(0)); + strip.setPixelColor(i, SEGCOLOR(0)); } else if( currSeg % 3 == 1) { - setPixelColor(i, SEGCOLOR(1)); + strip.setPixelColor(i, SEGCOLOR(1)); } else { - setPixelColor(i, (SEGCOLOR(2) > 0 ? SEGCOLOR(2) : WHITE)); + strip.setPixelColor(i, (SEGCOLOR(2) > 0 ? SEGCOLOR(2) : WHITE)); } currSegCount += 1; if (currSegCount >= segSize) { @@ -2737,9 +2737,9 @@ uint16_t WS2812FX::mode_tri_static_pattern() static const char *_data_FX_MODE_TRI_STATIC_PATTERN PROGMEM = "Solid Pattern Tri@,Size;1,2,3;!=0"; -uint16_t WS2812FX::spots_base(uint16_t threshold) +uint16_t spots_base(uint16_t threshold) { - fill(SEGCOLOR(1)); + strip.fill(SEGCOLOR(1)); uint16_t maxZones = SEGLEN >> 2; uint16_t zones = 1 + ((SEGMENT.intensity * maxZones) >> 8); @@ -2751,11 +2751,11 @@ uint16_t WS2812FX::spots_base(uint16_t threshold) uint16_t pos = offset + z * zoneLen; for (uint16_t i = 0; i < zoneLen; i++) { - uint16_t wave = triwave16((i * 0xFFFF) / zoneLen); + uint16_t wave = strip.triwave16((i * 0xFFFF) / zoneLen); if (wave > threshold) { uint16_t index = 0 + pos + i; uint8_t s = (wave - threshold)*255 / (0xFFFF - threshold); - setPixelColor(index, color_blend(color_from_palette(index, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255-s)); + strip.setPixelColor(index, color_blend(strip.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255-s)); } } } @@ -2765,7 +2765,7 @@ uint16_t WS2812FX::spots_base(uint16_t threshold) //Intensity slider sets number of "lights", speed sets LEDs per light -uint16_t WS2812FX::mode_spots() +uint16_t mode_spots() { return spots_base((255 - SEGMENT.speed) << 8); } @@ -2773,10 +2773,10 @@ static const char *_data_FX_MODE_SPOTS PROGMEM = "Spots@Spread,Width;!,!,;!"; //Intensity slider sets number of "lights", LEDs per light fade in and out -uint16_t WS2812FX::mode_spots_fade() +uint16_t mode_spots_fade() { - uint16_t counter = now * ((SEGMENT.speed >> 2) +8); - uint16_t t = triwave16(counter); + uint16_t counter = strip.now * ((SEGMENT.speed >> 2) +8); + uint16_t t = strip.triwave16(counter); uint16_t tr = (t >> 1) + (t >> 2); return spots_base(tr); } @@ -2793,7 +2793,7 @@ typedef struct Ball { /* * Bouncing Balls Effect */ -uint16_t WS2812FX::mode_bouncing_balls(void) { +uint16_t mode_bouncing_balls(void) { //allocate segment data uint16_t maxNumBalls = 16; uint16_t dataSize = sizeof(ball) * maxNumBalls; @@ -2815,7 +2815,7 @@ uint16_t WS2812FX::mode_bouncing_balls(void) { } bool hasCol2 = SEGCOLOR(2); - fill(hasCol2 ? BLACK : SEGCOLOR(1)); + strip.fill(hasCol2 ? BLACK : SEGCOLOR(1)); for (uint8_t i = 0; i < numBalls; i++) { float timeSinceLastBounce = (time - balls[i].lastBounceTime)/((255-SEGMENT.speed)*8/256 +1); @@ -2835,13 +2835,13 @@ uint16_t WS2812FX::mode_bouncing_balls(void) { uint32_t color = SEGCOLOR(0); if (SEGMENT.palette) { - color = color_wheel(i*(256/MAX(numBalls, 8))); + color = strip.color_wheel(i*(256/MAX(numBalls, 8))); } else if (hasCol2) { color = SEGCOLOR(i % NUM_COLORS); } uint16_t pos = round(balls[i].height * (SEGLEN - 1)); - setPixelColor(pos, color); + strip.setPixelColor(pos, color); } return FRAMETIME; @@ -2852,31 +2852,31 @@ static const char *_data_FX_MODE_BOUNCINGBALLS PROGMEM = "Bouncing Balls@Gravity /* * Sinelon stolen from FASTLED examples */ -uint16_t WS2812FX::sinelon_base(bool dual, bool rainbow=false) { - fade_out(SEGMENT.intensity); +uint16_t sinelon_base(bool dual, bool rainbow=false) { + strip.fade_out(SEGMENT.intensity); uint16_t pos = beatsin16(SEGMENT.speed/10,0,SEGLEN-1); if (SEGENV.call == 0) SEGENV.aux0 = pos; - uint32_t color1 = color_from_palette(pos, true, false, 0); + uint32_t color1 = strip.color_from_palette(pos, true, false, 0); uint32_t color2 = SEGCOLOR(2); if (rainbow) { - color1 = color_wheel((pos & 0x07) * 32); + color1 = strip.color_wheel((pos & 0x07) * 32); } - setPixelColor(pos, color1); + strip.setPixelColor(pos, color1); if (dual) { - if (!color2) color2 = color_from_palette(pos, true, false, 0); + if (!color2) color2 = strip.color_from_palette(pos, true, false, 0); if (rainbow) color2 = color1; //rainbow - setPixelColor(SEGLEN-1-pos, color2); + strip.setPixelColor(SEGLEN-1-pos, color2); } if (SEGENV.aux0 != pos) { if (SEGENV.aux0 < pos) { for (uint16_t i = SEGENV.aux0; i < pos ; i++) { - setPixelColor(i, color1); - if (dual) setPixelColor(SEGLEN-1-i, color2); + strip.setPixelColor(i, color1); + if (dual) strip.setPixelColor(SEGLEN-1-i, color2); } } else { for (uint16_t i = SEGENV.aux0; i > pos ; i--) { - setPixelColor(i, color1); - if (dual) setPixelColor(SEGLEN-1-i, color2); + strip.setPixelColor(i, color1); + if (dual) strip.setPixelColor(SEGLEN-1-i, color2); } } SEGENV.aux0 = pos; @@ -2886,37 +2886,37 @@ uint16_t WS2812FX::sinelon_base(bool dual, bool rainbow=false) { } -uint16_t WS2812FX::mode_sinelon(void) { +uint16_t mode_sinelon(void) { return sinelon_base(false); } static const char *_data_FX_MODE_SINELON PROGMEM = "Sinelon"; -uint16_t WS2812FX::mode_sinelon_dual(void) { +uint16_t mode_sinelon_dual(void) { return sinelon_base(true); } static const char *_data_FX_MODE_SINELON_DUAL PROGMEM = "Sinelon Dual"; -uint16_t WS2812FX::mode_sinelon_rainbow(void) { +uint16_t mode_sinelon_rainbow(void) { return sinelon_base(false, true); } static const char *_data_FX_MODE_SINELON_RAINBOW PROGMEM = "Sinelon Rainbow"; //Rainbow with glitter, inspired by https://gist.github.com/kriegsman/062e10f7f07ba8518af6 -uint16_t WS2812FX::mode_glitter() +uint16_t mode_glitter() { mode_palette(); - if (isMatrix) { + if (strip.isMatrix) { uint16_t height = SEGMENT.virtualHeight(); uint16_t width = SEGMENT.virtualWidth(); for (uint16_t i = 0; i random8()) setPixelColorXY(random16(width-1), i, ULTRAWHITE); + if (SEGMENT.intensity > random8()) strip.setPixelColorXY(random16(width-1), i, ULTRAWHITE); } } else - if (SEGMENT.intensity > random8()) setPixelColor(random16(SEGLEN), ULTRAWHITE); + if (SEGMENT.intensity > random8()) strip.setPixelColor(random16(SEGLEN), ULTRAWHITE); return FRAMETIME; } @@ -2936,9 +2936,9 @@ typedef struct Spark { * POPCORN * modified from https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Popcorn.h */ -uint16_t WS2812FX::mode_popcorn(void) { - const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : 1; - const uint16_t rows = isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); +uint16_t mode_popcorn(void) { + const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1; + const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); //allocate segment data uint16_t maxNumPopcorn = 21; // max 21 on 16 segment ESP8266 @@ -2951,7 +2951,7 @@ uint16_t WS2812FX::mode_popcorn(void) { gravity *= rows; //SEGLEN bool hasCol2 = SEGCOLOR(2); - fill(hasCol2 ? BLACK : SEGCOLOR(1)); + strip.fill(hasCol2 ? BLACK : SEGCOLOR(1)); uint8_t numPopcorn = SEGMENT.intensity*maxNumPopcorn/255; if (numPopcorn == 0) numPopcorn = 1; @@ -2980,13 +2980,13 @@ uint16_t WS2812FX::mode_popcorn(void) { } } if (popcorn[i].pos >= 0.0f) { // draw now active popcorn (either active before or just popped) - uint32_t col = color_wheel(popcorn[i].colIndex); + uint32_t col = strip.color_wheel(popcorn[i].colIndex); if (!SEGMENT.palette && popcorn[i].colIndex < NUM_COLORS) col = SEGCOLOR(popcorn[i].colIndex); uint16_t ledIndex = popcorn[i].pos; if (ledIndex < rows) { - if (isMatrix) setPixelColorXY(uint16_t(popcorn[i].posX), rows - 1 - ledIndex, col); - else setPixelColor(ledIndex, col); + if (strip.isMatrix) strip.setPixelColorXY(uint16_t(popcorn[i].posX), rows - 1 - ledIndex, col); + else strip.setPixelColor(ledIndex, col); } } } @@ -3000,7 +3000,7 @@ static const char *_data_FX_MODE_POPCORN PROGMEM = "Popcorn"; //Inspired by https://github.com/avanhanegem/ArduinoCandleEffectNeoPixel //and https://cpldcpu.wordpress.com/2016/01/05/reverse-engineering-a-real-candle/ -uint16_t WS2812FX::candle(bool multi) +uint16_t candle(bool multi) { if (multi) { @@ -3060,12 +3060,12 @@ uint16_t WS2812FX::candle(bool multi) } if (i > 0) { - setPixelColor(i, color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s)); + strip.setPixelColor(i, color_blend(SEGCOLOR(1), strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s)); SEGENV.data[d] = s; SEGENV.data[d+1] = s_target; SEGENV.data[d+2] = fadeStep; } else { for (uint16_t j = 0; j < SEGLEN; j++) { - setPixelColor(j, color_blend(SEGCOLOR(1), color_from_palette(j, true, PALETTE_SOLID_WRAP, 0), s)); + strip.setPixelColor(j, color_blend(SEGCOLOR(1), strip.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0), s)); } SEGENV.aux0 = s; SEGENV.aux1 = s_target; SEGENV.step = fadeStep; @@ -3076,14 +3076,14 @@ uint16_t WS2812FX::candle(bool multi) } -uint16_t WS2812FX::mode_candle() +uint16_t mode_candle() { return candle(false); } static const char *_data_FX_MODE_CANDLE PROGMEM = "Candle@Flicker rate=96,Flicker intensity=224;!,!,;0"; -uint16_t WS2812FX::mode_candle_multi() +uint16_t mode_candle_multi() { return candle(true); } @@ -3110,9 +3110,9 @@ typedef struct particle { float fragment[STARBURST_MAX_FRAG]; } star; -uint16_t WS2812FX::mode_starburst(void) { +uint16_t mode_starburst(void) { uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640 - uint8_t segs = getActiveSegmentsNum(); + uint8_t segs = strip.getActiveSegmentsNum(); if (segs <= (MAX_NUM_SEGMENTS /2)) maxData *= 2; //ESP8266: 512 if <= 8 segs ESP32: 1280 if <= 16 segs if (segs <= (MAX_NUM_SEGMENTS /4)) maxData *= 2; //ESP8266: 1024 if <= 4 segs ESP32: 2560 if <= 8 segs uint16_t maxStars = maxData / sizeof(star); //ESP8266: max. 4/9/19 stars/seg, ESP32: max. 10/21/42 stars/seg @@ -3140,7 +3140,7 @@ uint16_t WS2812FX::mode_starburst(void) { uint16_t startPos = random16(SEGLEN-1); float multiplier = (float)(random8())/255.0 * 1.0; - stars[j].color = col_to_crgb(color_wheel(random8())); + stars[j].color = CRGB(strip.color_wheel(random8())); stars[j].pos = startPos; stars[j].vel = maxSpeed * (float)(random8())/255.0 * multiplier; stars[j].birth = it; @@ -3155,7 +3155,7 @@ uint16_t WS2812FX::mode_starburst(void) { } } - fill(SEGCOLOR(1)); + strip.fill(SEGCOLOR(1)); for (int j=0; j particleIgnition + particleFadeTime) { fade = 1.0f; // Black hole, all faded out stars[j].birth = 0; - c = col_to_crgb(SEGCOLOR(1)); + c = CRGB(SEGCOLOR(1)); } else { age -= particleIgnition; fade = (age / particleFadeTime); // Fading star byte f = 254.5f*fade; - c = col_to_crgb(color_blend(crgb_to_col(c), SEGCOLOR(1), f)); + c = CRGB(color_blend(RGBW32(c.r,c.g,c.b,0), SEGCOLOR(1), f)); } } - float particleSize = (1.0 - fade) * 2; + float particleSize = (1.0f - fade) * 2.0f; for (uint8_t index=0; index < STARBURST_MAX_FRAG*2; index++) { bool mirrored = index & 0x1; @@ -3212,7 +3212,7 @@ uint16_t WS2812FX::mode_starburst(void) { if (start == end) end++; if (end > SEGLEN) end = SEGLEN; for (int p = start; p < end; p++) { - setPixelColor(p, c.r, c.g, c.b); + strip.setPixelColor(p, c.r, c.g, c.b); } } } @@ -3228,14 +3228,14 @@ static const char *_data_FX_MODE_STARBURST PROGMEM = "Fireworks Starburst"; * adapted from: http://www.anirama.com/1000leds/1d-fireworks/ * adapted for 2D WLED by blazoncek (Blaz Kristan) */ -uint16_t WS2812FX::mode_exploding_fireworks(void) +uint16_t mode_exploding_fireworks(void) { - const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : 1; - const uint16_t rows = isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); + const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1; + const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); //allocate segment data uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640 - uint8_t segs = getActiveSegmentsNum(); + uint8_t segs = strip.getActiveSegmentsNum(); if (segs <= (MAX_NUM_SEGMENTS /2)) maxData *= 2; //ESP8266: 512 if <= 8 segs ESP32: 1280 if <= 16 segs if (segs <= (MAX_NUM_SEGMENTS /4)) maxData *= 2; //ESP8266: 1024 if <= 4 segs ESP32: 2560 if <= 8 segs int maxSparks = maxData / sizeof(spark); //ESP8266: max. 21/42/85 sparks/seg, ESP32: max. 53/106/213 sparks/seg @@ -3251,8 +3251,8 @@ uint16_t WS2812FX::mode_exploding_fireworks(void) SEGENV.aux1 = dataSize; } - //fill(BLACK); - fade_out(252); + //strip.fill(BLACK); + strip.fade_out(252); Spark* sparks = reinterpret_cast(SEGENV.data); Spark* flare = sparks; //first spark is flare data @@ -3263,11 +3263,11 @@ uint16_t WS2812FX::mode_exploding_fireworks(void) if (SEGENV.aux0 < 2) { //FLARE if (SEGENV.aux0 == 0) { //init flare flare->pos = 0; - flare->posX = isMatrix ? random16(2,cols-1) : (SEGMENT.intensity > random8()); // will enable random firing side on 1D + flare->posX = strip.isMatrix ? random16(2,cols-1) : (SEGMENT.intensity > random8()); // will enable random firing side on 1D uint16_t peakHeight = 75 + random8(180); //0-255 peakHeight = (peakHeight * (rows -1)) >> 8; flare->vel = sqrt(-2.0f * gravity * peakHeight); - flare->velX = isMatrix ? (random8(8)-4)/32.f : 0; // no X velocity on 1D + flare->velX = strip.isMatrix ? (random8(8)-4)/32.f : 0; // no X velocity on 1D flare->col = 255; //brightness SEGENV.aux0 = 1; } @@ -3275,12 +3275,12 @@ uint16_t WS2812FX::mode_exploding_fireworks(void) // launch if (flare->vel > 12 * gravity) { // flare - if (isMatrix) setPixelColorXY(int(flare->posX), rows - uint16_t(flare->pos) - 1, flare->col, flare->col, flare->col); - else setPixelColor(int(flare->posX) ? rows - int(flare->pos) - 1 : int(flare->pos), flare->col, flare->col, flare->col); + if (strip.isMatrix) strip.setPixelColorXY(int(flare->posX), rows - uint16_t(flare->pos) - 1, flare->col, flare->col, flare->col); + else strip.setPixelColor(int(flare->posX) ? rows - int(flare->pos) - 1 : int(flare->pos), flare->col, flare->col, flare->col); flare->pos += flare->vel; flare->posX += flare->velX; flare->pos = constrain(flare->pos, 0, rows-1); - flare->posX = constrain(flare->posX, 0, cols-isMatrix); + flare->posX = constrain(flare->posX, 0, cols-strip.isMatrix); flare->vel += gravity; flare->col -= 2; } else { @@ -3303,12 +3303,12 @@ uint16_t WS2812FX::mode_exploding_fireworks(void) sparks[i].posX = flare->posX; sparks[i].vel = (float(random16(0, 20000)) / 10000.0f) - 0.9f; // from -0.9 to 1.1 sparks[i].vel *= rows<32 ? 0.5f : 1; // reduce velocity for smaller strips - sparks[i].velX = isMatrix ? (float(random16(0, 4000)) / 10000.0f) - 0.2f : 0; // from -0.2 to 0.2 + sparks[i].velX = strip.isMatrix ? (float(random16(0, 4000)) / 10000.0f) - 0.2f : 0; // from -0.2 to 0.2 sparks[i].col = 345;//abs(sparks[i].vel * 750.0); // set colors before scaling velocity to keep them bright //sparks[i].col = constrain(sparks[i].col, 0, 345); sparks[i].colIndex = random8(); sparks[i].vel *= flare->pos/rows; // proportional to height - sparks[i].velX *= isMatrix ? flare->posX/cols : 0; // proportional to width + sparks[i].velX *= strip.isMatrix ? flare->posX/cols : 0; // proportional to width sparks[i].vel *= -gravity *50; } //sparks[1].col = 345; // this will be our known spark @@ -3321,27 +3321,27 @@ uint16_t WS2812FX::mode_exploding_fireworks(void) sparks[i].pos += sparks[i].vel; sparks[i].posX += sparks[i].velX; sparks[i].vel += *dying_gravity; - sparks[i].velX += isMatrix ? *dying_gravity : 0; + sparks[i].velX += strip.isMatrix ? *dying_gravity : 0; if (sparks[i].col > 3) sparks[i].col -= 4; if (sparks[i].pos > 0 && sparks[i].pos < rows) { - if (isMatrix && !(sparks[i].posX >= 0 && sparks[i].posX < cols)) continue; + if (strip.isMatrix && !(sparks[i].posX >= 0 && sparks[i].posX < cols)) continue; uint16_t prog = sparks[i].col; - uint32_t spColor = (SEGMENT.palette) ? color_wheel(sparks[i].colIndex) : SEGCOLOR(0); + uint32_t spColor = (SEGMENT.palette) ? strip.color_wheel(sparks[i].colIndex) : SEGCOLOR(0); CRGB c = CRGB::Black; //HeatColor(sparks[i].col); if (prog > 300) { //fade from white to spark color - c = col_to_crgb(color_blend(spColor, WHITE, (prog - 300)*5)); + c = CRGB(color_blend(spColor, WHITE, (prog - 300)*5)); } else if (prog > 45) { //fade from spark color to black - c = col_to_crgb(color_blend(BLACK, spColor, prog - 45)); + c = CRGB(color_blend(BLACK, spColor, prog - 45)); uint8_t cooling = (300 - prog) >> 5; c.g = qsub8(c.g, cooling); c.b = qsub8(c.b, cooling * 2); } - if (isMatrix) setPixelColorXY(int(sparks[i].posX), rows - int(sparks[i].pos) - 1, c.red, c.green, c.blue); - else setPixelColor(int(sparks[i].posX) ? rows - int(sparks[i].pos) - 1 : int(sparks[i].pos), c.red, c.green, c.blue); + if (strip.isMatrix) strip.setPixelColorXY(int(sparks[i].posX), rows - int(sparks[i].pos) - 1, c.red, c.green, c.blue); + else strip.setPixelColor(int(sparks[i].posX) ? rows - int(sparks[i].pos) - 1 : int(sparks[i].pos), c.red, c.green, c.blue); } } - blur(16); + strip.blur(16); *dying_gravity *= .8f; // as sparks burn out they fall slower } else { SEGENV.aux0 = 6 + random8(10); //wait for this many frames @@ -3363,17 +3363,17 @@ static const char *_data_FX_MODE_EXPLODING_FIREWORKS PROGMEM = "Fireworks 1D@Gra * Drip Effect * ported of: https://www.youtube.com/watch?v=sru2fXh4r7k */ -uint16_t WS2812FX::mode_drip(void) +uint16_t mode_drip(void) { - const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : 1; - const uint16_t rows = isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); + const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1; + const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); //allocate segment data uint8_t numDrops = 4; uint16_t dataSize = sizeof(spark) * numDrops; if (!SEGENV.allocateData(dataSize * cols)) return mode_static(); //allocation failed - fill(SEGCOLOR(1)); + strip.fill(SEGCOLOR(1)); Spark* drops = reinterpret_cast(SEGENV.data); @@ -3395,14 +3395,14 @@ uint16_t WS2812FX::mode_drip(void) } uint32_t col = color_blend(BLACK, SEGCOLOR(0), sourcedrop); - if (isMatrix) setPixelColorXY(k, 0, col); - else setPixelColor(rows-1, col);// water source + if (strip.isMatrix) strip.setPixelColorXY(k, 0, col); + else strip.setPixelColor(rows-1, col);// water source if (drops[idx].colIndex == 1) { if (drops[idx].col > 255) drops[idx].col = 255; col = color_blend(BLACK,SEGCOLOR(0),drops[idx].col); - if (isMatrix) setPixelColorXY(k, rows - 1 - uint16_t(drops[idx].pos), col); - else setPixelColor(uint16_t(drops[idx].pos), col); + if (strip.isMatrix) strip.setPixelColorXY(k, rows - 1 - uint16_t(drops[idx].pos), col); + else strip.setPixelColor(uint16_t(drops[idx].pos), col); drops[idx].col += map(SEGMENT.speed, 0, 255, 1, 6); // swelling @@ -3420,14 +3420,14 @@ uint16_t WS2812FX::mode_drip(void) for (uint16_t i = 1; i < 7 - drops[idx].colIndex; i++) { // some minor math so we don't expand bouncing droplets uint16_t pos = constrain(uint16_t(drops[idx].pos) +i, 0, rows-1); //this is BAD, returns a pos >= SEGLEN occasionally col = color_blend(BLACK, SEGCOLOR(0), drops[idx].col/i); - if (isMatrix) setPixelColorXY(k, rows - 1 - pos, col); - else setPixelColor(pos, col); //spread pixel with fade while falling + if (strip.isMatrix) strip.setPixelColorXY(k, rows - 1 - pos, col); + else strip.setPixelColor(pos, col); //spread pixel with fade while falling } if (drops[idx].colIndex > 2) { // during bounce, some water is on the floor col = color_blend(SEGCOLOR(0), BLACK, drops[idx].col); - if (isMatrix) setPixelColorXY(k, rows - 1, col); - else setPixelColor(0, col); + if (strip.isMatrix) strip.setPixelColorXY(k, rows - 1, col); + else strip.setPixelColor(0, col); } } else { // we hit bottom if (drops[idx].colIndex > 2) { // already hit once, so back to forming @@ -3463,7 +3463,7 @@ typedef struct Tetris { uint32_t col; } tetris; -uint16_t WS2812FX::mode_tetrix(void) { +uint16_t mode_tetrix(void) { uint16_t dataSize = sizeof(tetris); if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -3473,14 +3473,14 @@ uint16_t WS2812FX::mode_tetrix(void) { if (SEGENV.call == 0 || SEGENV.aux1 >= SEGLEN) { SEGENV.aux1 = 0; // reset brick stack size SEGENV.step = 0; - fill(SEGCOLOR(1)); + strip.fill(SEGCOLOR(1)); return 250; // short wait } if (SEGENV.step == 0) { //init drop->speed = 0.0238 * (SEGMENT.speed ? (SEGMENT.speed>>2)+1 : random8(6,64)); // set speed drop->pos = SEGLEN; // start at end of segment (no need to subtract 1) - drop->col = color_from_palette(random8(0,15)<<4,false,false,0); // limit color choices so there is enough HUE gap + drop->col = strip.color_from_palette(random8(0,15)<<4,false,false,0); // limit color choices so there is enough HUE gap SEGENV.step = 1; // drop state (0 init, 1 forming, 2 falling) SEGENV.aux0 = (SEGMENT.intensity ? (SEGMENT.intensity>>5)+1 : random8(1,5)) * (1+(SEGLEN>>6)); // size of brick } @@ -3495,7 +3495,7 @@ uint16_t WS2812FX::mode_tetrix(void) { if (drop->pos > SEGENV.aux1) { // fall until top of stack drop->pos -= drop->speed; // may add gravity as: speed += gravity if (int(drop->pos) < SEGENV.aux1) drop->pos = SEGENV.aux1; - for (uint16_t i=int(drop->pos); ipos)+SEGENV.aux0 ? drop->col : SEGCOLOR(1)); + for (uint16_t i=int(drop->pos); ipos)+SEGENV.aux0 ? drop->col : SEGCOLOR(1)); } else { // we hit bottom SEGENV.step = 0; // go back to init SEGENV.aux1 += SEGENV.aux0; // increase the stack size @@ -3511,7 +3511,7 @@ static const char *_data_FX_MODE_TETRIX PROGMEM = "Tetrix@!=224,Width=0;!,!,;!=1 / Plasma Effect / adapted from https://github.com/atuline/FastLED-Demos/blob/master/plasma/plasma.ino */ -uint16_t WS2812FX::mode_plasma(void) { +uint16_t mode_plasma(void) { // initialize phases on start if (SEGENV.call == 0) { SEGENV.aux0 = random8(0,2); // add a bit of randomness @@ -3523,8 +3523,8 @@ uint16_t WS2812FX::mode_plasma(void) { uint8_t colorIndex = cubicwave8((i*(2+ 3*(SEGMENT.speed >> 5))+thisPhase) & 0xFF)/2 // factor=23 // Create a wave and add a phase change and add another wave with its own phase change. + cos8((i*(1+ 2*(SEGMENT.speed >> 5))+thatPhase) & 0xFF)/2; // factor=15 // Hey, you can even change the frequencies if you wish. uint8_t thisBright = qsub8(colorIndex, beatsin8(7,0, (128 - (SEGMENT.intensity>>1)))); - CRGB color = ColorFromPalette(currentPalette, colorIndex, thisBright, LINEARBLEND); - setPixelColor(i, color.red, color.green, color.blue); + CRGB color = ColorFromPalette(strip.currentPalette, colorIndex, thisBright, LINEARBLEND); + strip.setPixelColor(i, color.red, color.green, color.blue); } return FRAMETIME; @@ -3536,7 +3536,7 @@ static const char *_data_FX_MODE_PLASMA PROGMEM = "Plasma@Phase,;1,2,3;!"; * Percentage display * Intesity values from 0-100 turn on the leds. */ -uint16_t WS2812FX::mode_percent(void) { +uint16_t mode_percent(void) { uint8_t percent = MAX(0, MIN(200, SEGMENT.intensity)); uint16_t active_leds = (percent < 100) ? SEGLEN * percent / 100.0 @@ -3548,19 +3548,19 @@ uint16_t WS2812FX::mode_percent(void) { if (percent < 100) { for (uint16_t i = 0; i < SEGLEN; i++) { if (i < SEGENV.step) { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } else { - setPixelColor(i, SEGCOLOR(1)); + strip.setPixelColor(i, SEGCOLOR(1)); } } } else { for (uint16_t i = 0; i < SEGLEN; i++) { if (i < (SEGLEN - SEGENV.step)) { - setPixelColor(i, SEGCOLOR(1)); + strip.setPixelColor(i, SEGCOLOR(1)); } else { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(i, strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } } } @@ -3582,28 +3582,28 @@ static const char *_data_FX_MODE_PERCENT PROGMEM = "Percent@,% of fill;!,!,;!"; * Modulates the brightness similar to a heartbeat * tries to draw an ECG aproximation on a 2D matrix */ -uint16_t WS2812FX::mode_heartbeat(void) { +uint16_t mode_heartbeat(void) { uint8_t bpm = 40 + (SEGMENT.speed >> 3); uint32_t msPerBeat = (60000L / bpm); uint32_t secondBeat = (msPerBeat / 3); uint32_t bri_lower = SEGENV.aux1; - unsigned long beatTimer = now - SEGENV.step; + unsigned long beatTimer = strip.now - SEGENV.step; bri_lower = bri_lower * 2042 / (2048 + SEGMENT.intensity); SEGENV.aux1 = bri_lower; if ((beatTimer > secondBeat) && !SEGENV.aux0) { // time for the second beat? - SEGENV.aux1 = isMatrix ? UINT16_MAX*3L/4 : UINT16_MAX; //3/4 bri + SEGENV.aux1 = strip.isMatrix ? UINT16_MAX*3L/4 : UINT16_MAX; //3/4 bri SEGENV.aux0 = 1; } if (beatTimer > msPerBeat) { // time to reset the beat timer? SEGENV.aux1 = UINT16_MAX; //full bri SEGENV.aux0 = 0; - SEGENV.step = now; + SEGENV.step = strip.now; } for (uint16_t i = 0; i < SEGLEN; i++) { - setPixelColor(i, color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255 - (SEGENV.aux1 >> 8))); + strip.setPixelColor(i, color_blend(strip.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255 - (SEGENV.aux1 >> 8))); } return FRAMETIME; @@ -3635,9 +3635,25 @@ static const char *_data_FX_MODE_HEARTBEAT PROGMEM = "Heartbeat@!,!;!,!,;!"; // // Modified for WLED, based on https://github.com/FastLED/FastLED/blob/master/examples/Pacifica/Pacifica.ino // -uint16_t WS2812FX::mode_pacifica() +// Add one layer of waves into the led array +CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff) { - uint32_t nowOld = now; + uint16_t ci = cistart; + uint16_t waveangle = ioff; + uint16_t wavescale_half = (wavescale >> 1) + 20; + + waveangle += ((120 + SEGMENT.intensity) * i); //original 250 * i + uint16_t s16 = sin16(waveangle) + 32768; + uint16_t cs = scale16(s16, wavescale_half) + wavescale_half; + ci += (cs * i); + uint16_t sindex16 = sin16(ci) + 32768; + uint8_t sindex8 = scale16(sindex16, 240); + return ColorFromPalette(p, sindex8, bri, LINEARBLEND); +} + +uint16_t mode_pacifica() +{ + uint32_t nowOld = strip.now; CRGBPalette16 pacifica_palette_1 = { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117, @@ -3650,17 +3666,17 @@ uint16_t WS2812FX::mode_pacifica() 0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF }; if (SEGMENT.palette) { - pacifica_palette_1 = currentPalette; - pacifica_palette_2 = currentPalette; - pacifica_palette_3 = currentPalette; + pacifica_palette_1 = strip.currentPalette; + pacifica_palette_2 = strip.currentPalette; + pacifica_palette_3 = strip.currentPalette; } // Increment the four "color index start" counters, one for each wave layer. // Each is incremented at a different speed, and the speeds vary over time. uint16_t sCIStart1 = SEGENV.aux0, sCIStart2 = SEGENV.aux1, sCIStart3 = SEGENV.step, sCIStart4 = SEGENV.step >> 16; uint32_t deltams = (FRAMETIME >> 2) + ((FRAMETIME * SEGMENT.speed) >> 7); - uint64_t deltat = (now >> 2) + ((now * SEGMENT.speed) >> 7); - now = deltat; + uint64_t deltat = (strip.now >> 2) + ((strip.now * SEGMENT.speed) >> 7); + strip.now = deltat; uint16_t speedfactor1 = beatsin16(3, 179, 269); uint16_t speedfactor2 = beatsin16(4, 179, 269); @@ -3675,7 +3691,7 @@ uint16_t WS2812FX::mode_pacifica() SEGENV.step = sCIStart4; SEGENV.step = (SEGENV.step << 16) + sCIStart3; // Clear out the LED array to a dim background blue-green - //fill(132618); + //strip.fill(132618); uint8_t basethreshold = beatsin8( 9, 55, 65); uint8_t wave = beat8( 7 ); @@ -3703,45 +3719,28 @@ uint16_t WS2812FX::mode_pacifica() c.green = scale8(c.green, 200); c |= CRGB( 2, 5, 7); - setPixelColor(i, c.red, c.green, c.blue); + strip.setPixelColor(i, c.red, c.green, c.blue); } - now = nowOld; + strip.now = nowOld; return FRAMETIME; } static const char *_data_FX_MODE_PACIFICA PROGMEM = "Pacifica"; -// Add one layer of waves into the led array -CRGB WS2812FX::pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff) -{ - uint16_t ci = cistart; - uint16_t waveangle = ioff; - uint16_t wavescale_half = (wavescale >> 1) + 20; - - waveangle += ((120 + SEGMENT.intensity) * i); //original 250 * i - uint16_t s16 = sin16(waveangle) + 32768; - uint16_t cs = scale16(s16, wavescale_half) + wavescale_half; - ci += (cs * i); - uint16_t sindex16 = sin16(ci) + 32768; - uint8_t sindex8 = scale16(sindex16, 240); - return ColorFromPalette(p, sindex8, bri, LINEARBLEND); -} - - //Solid colour background with glitter -uint16_t WS2812FX::mode_solid_glitter() +uint16_t mode_solid_glitter() { - fill(SEGCOLOR(0)); + strip.fill(SEGCOLOR(0)); - if (isMatrix) { + if (strip.isMatrix) { uint16_t height = SEGMENT.virtualHeight(); uint16_t width = SEGMENT.virtualWidth(); for (uint16_t i = 0; i random8()) setPixelColorXY(random16(width-1), i, ULTRAWHITE); + if (SEGMENT.intensity > random8()) strip.setPixelColorXY(random16(width-1), i, ULTRAWHITE); } } else - if (SEGMENT.intensity > random8()) setPixelColor(random16(SEGLEN), ULTRAWHITE); + if (SEGMENT.intensity > random8()) strip.setPixelColor(random16(SEGLEN), ULTRAWHITE); return FRAMETIME; } @@ -3751,7 +3750,7 @@ static const char *_data_FX_MODE_SOLID_GLITTER PROGMEM = "Solid Glitter@,!;!,,;0 /* * Mode simulates a gradual sunrise */ -uint16_t WS2812FX::mode_sunrise() { +uint16_t mode_sunrise() { //speed 0 - static sun //speed 1 - 60: sunrise time in minutes //speed 60 - 120 : sunset time in minutes - 60; @@ -3761,14 +3760,14 @@ uint16_t WS2812FX::mode_sunrise() { SEGENV.aux0 = SEGMENT.speed; } - fill(0); + strip.fill(0); uint16_t stage = 0xFFFF; uint32_t s10SinceStart = (millis() - SEGENV.step) /100; //tenths of seconds if (SEGMENT.speed > 120) { //quick sunrise and sunset - uint16_t counter = (now >> 1) * (((SEGMENT.speed -120) >> 1) +1); - stage = triwave16(counter); + uint16_t counter = (strip.now >> 1) * (((SEGMENT.speed -120) >> 1) +1); + stage = strip.triwave16(counter); } else if (SEGMENT.speed) { //sunrise uint8_t durMins = SEGMENT.speed; if (durMins > 60) durMins -= 60; @@ -3781,19 +3780,19 @@ uint16_t WS2812FX::mode_sunrise() { for (uint16_t i = 0; i <= SEGLEN/2; i++) { //default palette is Fire - uint32_t c = color_from_palette(0, false, true, 255); //background + uint32_t c = strip.color_from_palette(0, false, true, 255); //background - uint16_t wave = triwave16((i * stage) / SEGLEN); + uint16_t wave = strip.triwave16((i * stage) / SEGLEN); wave = (wave >> 8) + ((wave * SEGMENT.intensity) >> 15); if (wave > 240) { //clipped, full white sun - c = color_from_palette( 240, false, true, 255); + c = strip.color_from_palette( 240, false, true, 255); } else { //transition - c = color_from_palette(wave, false, true, 255); + c = strip.color_from_palette(wave, false, true, 255); } - setPixelColor(i, c); - setPixelColor(SEGLEN - i - 1, c); + strip.setPixelColor(i, c); + strip.setPixelColor(SEGLEN - i - 1, c); } return FRAMETIME; @@ -3804,14 +3803,14 @@ static const char *_data_FX_MODE_SUNRISE PROGMEM = "Sunrise@Time [min]=60,;;0"; /* * Effects by Andrew Tuline */ -uint16_t WS2812FX::phased_base(uint8_t moder) { // We're making sine waves here. By Andrew Tuline. +uint16_t phased_base(uint8_t moder) { // We're making sine waves here. By Andrew Tuline. uint8_t allfreq = 16; // Base frequency. float *phase = reinterpret_cast(&SEGENV.step); // Phase change value gets calculated (float fits into unsigned long). uint8_t cutOff = (255-SEGMENT.intensity); // You can change the number of pixels. AKA INTENSITY (was 192). uint8_t modVal = 5;//SEGMENT.fft1/8+1; // You can change the modulus. AKA FFT1 (was 5). - uint8_t index = now/64; // Set color rotation speed + uint8_t index = strip.now/64; // Set color rotation speed *phase += SEGMENT.speed/32.0; // You can change the speed of the wave. AKA SPEED (was .4) for (int i = 0; i < SEGLEN; i++) { @@ -3821,7 +3820,7 @@ uint16_t WS2812FX::phased_base(uint8_t moder) { // We're making val += *phase * (i % modVal +1) /2; // This sets the varying phase change of the waves. By Andrew Tuline. uint8_t b = cubicwave8(val); // Now we make an 8 bit sinewave. b = (b > cutOff) ? (b - cutOff) : 0; // A ternary operator to cutoff the light. - setPixelColor(i, color_blend(SEGCOLOR(1), color_from_palette(index, false, false, 0), b)); + strip.setPixelColor(i, color_blend(SEGCOLOR(1), strip.color_from_palette(index, false, false, 0), b)); index += 256 / SEGLEN; if (SEGLEN > 256) index ++; // Correction for segments longer than 256 LEDs } @@ -3830,32 +3829,32 @@ uint16_t WS2812FX::phased_base(uint8_t moder) { // We're making } -uint16_t WS2812FX::mode_phased(void) { +uint16_t mode_phased(void) { return phased_base(0); } static const char *_data_FX_MODE_PHASED PROGMEM = "Phased"; -uint16_t WS2812FX::mode_phased_noise(void) { +uint16_t mode_phased_noise(void) { return phased_base(1); } static const char *_data_FX_MODE_PHASEDNOISE PROGMEM = "Phased Noise"; -uint16_t WS2812FX::mode_twinkleup(void) { // A very short twinkle routine with fade-in and dual controls. By Andrew Tuline. - const uint16_t cols = isMatrix ? SEGMENT.virtualWidth() : 1; - const uint16_t rows = isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); +uint16_t mode_twinkleup(void) { // A very short twinkle routine with fade-in and dual controls. By Andrew Tuline. + const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1; + const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); random16_set_seed(535); // The randomizer needs to be re-set each time through the loop in order for the same 'random' numbers to be the same each time through. for (int i = 0; i SEGMENT.intensity) pixBri = 0; - uint32_t col = color_blend(SEGCOLOR(1), color_from_palette(random8()+now/100, false, PALETTE_SOLID_WRAP, 0), pixBri); - if (isMatrix) setPixelColorXY(j, k, col); - else setPixelColor(i, col); + uint32_t col = color_blend(SEGCOLOR(1), strip.color_from_palette(random8() + strip.now/100, false, PALETTE_SOLID_WRAP, 0), pixBri); + if (strip.isMatrix) strip.setPixelColorXY(j, k, col); + else strip.setPixelColor(i, col); } return FRAMETIME; @@ -3864,7 +3863,7 @@ static const char *_data_FX_MODE_TWINKLEUP PROGMEM = "Twinkleup@!,Intensity;!,!, // Peaceful noise that's slow and with gradually changing palettes. Does not support WLED palettes or default colours or controls. -uint16_t WS2812FX::mode_noisepal(void) { // Slow noise palette by Andrew Tuline. +uint16_t mode_noisepal(void) { // Slow noise palette by Andrew Tuline. uint16_t scale = 15 + (SEGMENT.intensity >> 2); //default was 30 //#define scale 30 @@ -3887,12 +3886,12 @@ uint16_t WS2812FX::mode_noisepal(void) { // S //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. - if (SEGMENT.palette > 0) palettes[0] = currentPalette; + if (SEGMENT.palette > 0) palettes[0] = strip.currentPalette; for(int i = 0; i < SEGLEN; i++) { uint8_t 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. - setPixelColor(i, color.red, color.green, color.blue); + strip.setPixelColor(i, color.red, color.green, color.blue); } SEGENV.aux0 += beatsin8(10,1,4); // Moving along the distance. Vary it a bit with a sine wave. @@ -3905,10 +3904,10 @@ static const char *_data_FX_MODE_NOISEPAL PROGMEM = "Noise Pal"; // Sine waves that have controllable phase change speed, frequency and cutoff. By Andrew Tuline. // SEGMENT.speed ->Speed, SEGMENT.intensity -> Frequency (SEGMENT.fft1 -> Color change, SEGMENT.fft2 -> PWM cutoff) // -uint16_t WS2812FX::mode_sinewave(void) { // Adjustable sinewave. By Andrew Tuline +uint16_t mode_sinewave(void) { // Adjustable sinewave. By Andrew Tuline //#define qsuba(x, b) ((x>b)?x-b:0) // Analog Unsigned subtraction macro. if result <0, then => 0 - uint16_t colorIndex = now /32;//(256 - SEGMENT.fft1); // Amount of colour change. + uint16_t colorIndex = strip.now /32;//(256 - SEGMENT.fft1); // Amount of colour change. SEGENV.step += SEGMENT.speed/16; // Speed of animation. uint16_t freq = SEGMENT.intensity/4;//SEGMENT.fft2/8; // Frequency of the signal. @@ -3916,7 +3915,7 @@ uint16_t WS2812FX::mode_sinewave(void) { // Adjustable sinewave. By for (int i=0; i> 2) +1); + counter = strip.now * ((SEGMENT.speed >> 2) +1); counter = counter >> 8; } @@ -3943,7 +3942,7 @@ uint16_t WS2812FX::mode_flow(void) uint16_t zoneLen = SEGLEN / zones; uint16_t offset = (SEGLEN - zones * zoneLen) >> 1; - fill(color_from_palette(-counter, false, true, 255)); + strip.fill(strip.color_from_palette(-counter, false, true, 255)); for (uint16_t z = 0; z < zones; z++) { @@ -3953,7 +3952,7 @@ uint16_t WS2812FX::mode_flow(void) uint8_t colorIndex = (i * 255 / zoneLen) - counter; uint16_t led = (z & 0x01) ? i : (zoneLen -1) -i; if (SEGMENT.getOption(SEG_OPTION_REVERSED)) led = (zoneLen -1) -led; - setPixelColor(pos + led, color_from_palette(colorIndex, false, true, 255)); + strip.setPixelColor(pos + led, strip.color_from_palette(colorIndex, false, true, 255)); } } @@ -3966,10 +3965,10 @@ static const char *_data_FX_MODE_FLOW PROGMEM = "Flow"; * Dots waving around in a sine/pendulum motion. * Little pixel birds flying in a circle. By Aircoookie */ -uint16_t WS2812FX::mode_chunchun(void) +uint16_t mode_chunchun(void) { - fill(SEGCOLOR(1)); - uint16_t counter = now*(6 + (SEGMENT.speed >> 4)); + strip.fill(SEGCOLOR(1)); + uint16_t counter = strip.now * (6 + (SEGMENT.speed >> 4)); uint16_t numBirds = 2 + (SEGLEN >> 3); // 2 + 1/8 of a segment uint16_t span = (SEGMENT.intensity << 8) / numBirds; @@ -3978,8 +3977,8 @@ uint16_t WS2812FX::mode_chunchun(void) counter -= span; uint16_t megumin = sin16(counter) + 0x8000; uint16_t bird = uint32_t(megumin * SEGLEN) >> 16; - uint32_t c = color_from_palette((i * 255)/ numBirds, false, false, 0); // no palette wrapping - setPixelColor(bird, c); + uint32_t c = strip.color_from_palette((i * 255)/ numBirds, false, false, 0); // no palette wrapping + strip.setPixelColor(bird, c); } return FRAMETIME; } @@ -4016,7 +4015,7 @@ typedef struct Spotlight { * * By Steve Pomeroy @xxv */ -uint16_t WS2812FX::mode_dancing_shadows(void) +uint16_t mode_dancing_shadows(void) { uint8_t numSpotlights = map(SEGMENT.intensity, 0, 255, 2, SPOT_MAX_COUNT); // 49 on 32 segment ESP32, 17 on 16 segment ESP8266 bool initialize = SEGENV.aux0 != numSpotlights; @@ -4026,7 +4025,7 @@ uint16_t WS2812FX::mode_dancing_shadows(void) if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed Spotlight* spotlights = reinterpret_cast(SEGENV.data); - fill(BLACK); + strip.fill(BLACK); unsigned long time = millis(); bool respawn = false; @@ -4068,19 +4067,19 @@ uint16_t WS2812FX::mode_dancing_shadows(void) spotlights[i].type = random8(SPOT_TYPES_COUNT); } - uint32_t color = color_from_palette(spotlights[i].colorIdx, false, false, 0); + uint32_t color = strip.color_from_palette(spotlights[i].colorIdx, false, false, 0); int start = spotlights[i].position; if (spotlights[i].width <= 1) { if (start >= 0 && start < SEGLEN) { - blendPixelColor(start, color, 128); + strip.blendPixelColor(start, color, 128); } } else { switch (spotlights[i].type) { case SPOT_TYPE_SOLID: for (uint8_t j = 0; j < spotlights[i].width; j++) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - blendPixelColor(start + j, color, 128); + strip.blendPixelColor(start + j, color, 128); } } break; @@ -4088,8 +4087,7 @@ uint16_t WS2812FX::mode_dancing_shadows(void) case SPOT_TYPE_GRADIENT: for (uint8_t j = 0; j < spotlights[i].width; j++) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - blendPixelColor(start + j, color, - cubicwave8(map(j, 0, spotlights[i].width - 1, 0, 255))); + strip.blendPixelColor(start + j, color, cubicwave8(map(j, 0, spotlights[i].width - 1, 0, 255))); } } break; @@ -4097,8 +4095,7 @@ uint16_t WS2812FX::mode_dancing_shadows(void) case SPOT_TYPE_2X_GRADIENT: for (uint8_t j = 0; j < spotlights[i].width; j++) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - blendPixelColor(start + j, color, - cubicwave8(2 * map(j, 0, spotlights[i].width - 1, 0, 255))); + strip.blendPixelColor(start + j, color, cubicwave8(2 * map(j, 0, spotlights[i].width - 1, 0, 255))); } } break; @@ -4106,7 +4103,7 @@ uint16_t WS2812FX::mode_dancing_shadows(void) case SPOT_TYPE_2X_DOT: for (uint8_t j = 0; j < spotlights[i].width; j += 2) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - blendPixelColor(start + j, color, 128); + strip.blendPixelColor(start + j, color, 128); } } break; @@ -4114,7 +4111,7 @@ uint16_t WS2812FX::mode_dancing_shadows(void) case SPOT_TYPE_3X_DOT: for (uint8_t j = 0; j < spotlights[i].width; j += 3) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - blendPixelColor(start + j, color, 128); + strip.blendPixelColor(start + j, color, 128); } } break; @@ -4122,7 +4119,7 @@ uint16_t WS2812FX::mode_dancing_shadows(void) case SPOT_TYPE_4X_DOT: for (uint8_t j = 0; j < spotlights[i].width; j += 4) { if ((start + j) >= 0 && (start + j) < SEGLEN) { - blendPixelColor(start + j, color, 128); + strip.blendPixelColor(start + j, color, 128); } } break; @@ -4139,8 +4136,8 @@ static const char *_data_FX_MODE_DANCING_SHADOWS PROGMEM = "Dancing Shadows@!,# Imitates a washing machine, rotating same waves forward, then pause, then backward. By Stefan Seegel */ -uint16_t WS2812FX::mode_washing_machine(void) { - float speed = tristate_square8(now >> 7, 90, 15); +uint16_t mode_washing_machine(void) { + float speed = strip.tristate_square8(strip.now >> 7, 90, 15); float quot = 32.0f - ((float)SEGMENT.speed / 16.0f); speed /= quot; @@ -4148,7 +4145,7 @@ uint16_t WS2812FX::mode_washing_machine(void) { for (int i=0; i> 7)); - setPixelColor(i, color_from_palette(col, false, PALETTE_SOLID_WRAP, 3)); + strip.setPixelColor(i, strip.color_from_palette(col, false, PALETTE_SOLID_WRAP, 3)); } return FRAMETIME; @@ -4160,22 +4157,22 @@ static const char *_data_FX_MODE_WASHING_MACHINE PROGMEM = "Washing Machine"; Blends random colors across palette Modified, originally by Mark Kriegsman https://gist.github.com/kriegsman/1f7ccbbfa492a73c015e */ -uint16_t WS2812FX::mode_blends(void) { +uint16_t mode_blends(void) { uint16_t pixelLen = SEGLEN > UINT8_MAX ? UINT8_MAX : SEGLEN; uint16_t dataSize = sizeof(uint32_t) * (pixelLen + 1); // max segment length of 56 pixels on 16 segment ESP8266 if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed uint32_t* pixels = reinterpret_cast(SEGENV.data); uint8_t blendSpeed = map(SEGMENT.intensity, 0, UINT8_MAX, 10, 128); - uint8_t shift = (now * ((SEGMENT.speed >> 3) +1)) >> 8; + uint8_t shift = (strip.now * ((SEGMENT.speed >> 3) +1)) >> 8; for (int i = 0; i < pixelLen; i++) { - pixels[i] = color_blend(pixels[i], color_from_palette(shift + quadwave8((i + 1) * 16), false, PALETTE_SOLID_WRAP, 255), blendSpeed); + pixels[i] = color_blend(pixels[i], strip.color_from_palette(shift + quadwave8((i + 1) * 16), false, PALETTE_SOLID_WRAP, 255), blendSpeed); shift += 3; } uint16_t offset = 0; for (int i = 0; i < SEGLEN; i++) { - setPixelColor(i, pixels[offset++]); + strip.setPixelColor(i, pixels[offset++]); if (offset > pixelLen) offset = 0; } @@ -4209,7 +4206,7 @@ typedef struct TvSim { uint16_t pb = 0; } tvSim; -uint16_t WS2812FX::mode_tv_simulator(void) { +uint16_t mode_tv_simulator(void) { uint16_t nr, ng, nb, r, g, b, i, hue; uint8_t sat, bri, j; @@ -4266,9 +4263,9 @@ uint16_t WS2812FX::mode_tv_simulator(void) { } } // Apply gamma correction, further expand to 16/16/16 - nr = (uint8_t)gamma8(tvSimulator->actualColorR) * 257; // New R/G/B - ng = (uint8_t)gamma8(tvSimulator->actualColorG) * 257; - nb = (uint8_t)gamma8(tvSimulator->actualColorB) * 257; + nr = (uint8_t)strip.gamma8(tvSimulator->actualColorR) * 257; // New R/G/B + ng = (uint8_t)strip.gamma8(tvSimulator->actualColorG) * 257; + nb = (uint8_t)strip.gamma8(tvSimulator->actualColorB) * 257; if (SEGENV.aux0 == 0) { // initialize next iteration SEGENV.aux0 = 1; @@ -4297,7 +4294,7 @@ uint16_t WS2812FX::mode_tv_simulator(void) { // set strip color for (i = 0; i < SEGLEN; i++) { - setPixelColor(i, r >> 8, g >> 8, b >> 8); // Quantize to 8-bit + strip.setPixelColor(i, r >> 8, g >> 8, b >> 8); // Quantize to 8-bit } // if total duration has passed, remember last color and restart the loop @@ -4413,7 +4410,7 @@ class AuroraWave { }; }; -uint16_t WS2812FX::mode_aurora(void) { +uint16_t mode_aurora(void) { //aux1 = Wavecount //aux2 = Intensity in last loop @@ -4434,7 +4431,7 @@ uint16_t WS2812FX::mode_aurora(void) { waves = reinterpret_cast(SEGENV.data); for(int i = 0; i < SEGENV.aux1; i++) { - waves[i].init(SEGLEN, col_to_crgb(color_from_palette(random8(), false, false, random(0, 3)))); + waves[i].init(SEGLEN, CRGB(strip.color_from_palette(random8(), false, false, random(0, 3)))); } } else { waves = reinterpret_cast(SEGENV.data); @@ -4446,7 +4443,7 @@ uint16_t WS2812FX::mode_aurora(void) { if(!(waves[i].stillAlive())) { //If a wave dies, reinitialize it starts over. - waves[i].init(SEGLEN, col_to_crgb(color_from_palette(random8(), false, false, random(0, 3)))); + waves[i].init(SEGLEN, CRGB(strip.color_from_palette(random8(), false, false, random(0, 3)))); } } @@ -4468,7 +4465,7 @@ uint16_t WS2812FX::mode_aurora(void) { } } - setPixelColor(i, mixedRgb[0], mixedRgb[1], mixedRgb[2]); + strip.setPixelColor(i, mixedRgb[0], mixedRgb[1], mixedRgb[2]); } return FRAMETIME; @@ -4482,13 +4479,13 @@ static const char *_data_FX_MODE_AURORA PROGMEM = "Aurora@!=24,!;1,2,3;!=50"; ///////////////////////// // 16 bit perlinmove. Use Perlin Noise instead of sinewaves for movement. By Andrew Tuline. // Controls are speed, # of pixels, faderate. -uint16_t WS2812FX::mode_perlinmove(void) { +uint16_t mode_perlinmove(void) { - fade_out(255-SEGMENT.custom1); + strip.fade_out(255-SEGMENT.custom1); for (uint16_t i = 0; i < SEGMENT.intensity/16 + 1; i++) { uint16_t locn = inoise16(millis()*128/(260-SEGMENT.speed)+i*15000, millis()*128/(260-SEGMENT.speed)); // Get a new pixel location from moving noise. uint16_t pixloc = map(locn, 50*256, 192*256, 0, SEGLEN-1); // Map that to the length of the strand, and ensure we don't go over. - setPixelColor(pixloc, color_from_palette(pixloc%255, false, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(pixloc, strip.color_from_palette(pixloc%255, false, PALETTE_SOLID_WRAP, 0)); } return FRAMETIME; @@ -4500,11 +4497,11 @@ static const char *_data_FX_MODE_PERLINMOVE PROGMEM = "Perlin Move@!,# of pixels // Waveins // ///////////////////////// // Uses beatsin8() + phase shifting. By: Andrew Tuline -uint16_t WS2812FX::mode_wavesins(void) { +uint16_t mode_wavesins(void) { for (uint16_t i = 0; i < SEGLEN; i++) { uint8_t bri = sin8(millis()/4 + i * SEGMENT.intensity); - setPixelColor(i, ColorFromPalette(currentPalette, beatsin8(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * SEGMENT.custom3), bri, LINEARBLEND)); + strip.setPixelColor(i, ColorFromPalette(strip.currentPalette, beatsin8(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * SEGMENT.custom3), bri, LINEARBLEND)); } return FRAMETIME; @@ -4516,7 +4513,7 @@ static const char *_data_FX_MODE_WAVESINS PROGMEM = "Wavesins@Speed,Brightness v // Flow Stripe // ////////////////////////////// // By: ldirko https://editor.soulmatelights.com/gallery/392-flow-led-stripe , modifed by: Andrew Tuline -uint16_t WS2812FX::mode_FlowStripe(void) { +uint16_t mode_FlowStripe(void) { const uint16_t hl = SEGLEN * 10 / 13; uint8_t hue = millis() / (SEGMENT.speed+1); @@ -4527,7 +4524,7 @@ uint16_t WS2812FX::mode_FlowStripe(void) { c = sin8(c); c = sin8(c / 2 + t); byte b = sin8(c + t/8); - setPixelColor(i, CHSV(b + hue, 255, 255)); + strip.setPixelColor(i, CHSV(b + hue, 255, 255)); } return FRAMETIME; @@ -4537,11 +4534,12 @@ static const char *_data_FX_MODE_FLOWSTRIPE PROGMEM = "Flow Stripe@Hue speed,Eff /////////////////////////////////////////////////////////////////////////////// //*************************** 2D routines *********************************** +#define XY(x,y) strip.XY(x,y) // Black hole -uint16_t WS2812FX::mode_2DBlackHole(void) { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4554,10 +4552,10 @@ uint16_t WS2812FX::mode_2DBlackHole(void) { // By: Stepko https://edi // initialize on first call if (SEGENV.call == 0) { - fill_solid(leds, CRGB::Black); + strip.fill_solid(leds, CRGB::Black); } - fadeToBlackBy(leds, 16 + (SEGMENT.speed>>3)); // create fading trails + strip.fadeToBlackBy(leds, 16 + (SEGMENT.speed>>3)); // create fading trails float t = (float)(millis())/128; // timebase // outer stars for (byte i = 0; i < 8; i++) { @@ -4574,9 +4572,9 @@ uint16_t WS2812FX::mode_2DBlackHole(void) { // By: Stepko https://edi // central white dot leds[XY(cols/2,rows/2)] = CHSV(0,0,255); // blur everything a bit - blur2d(leds, 16); + strip.blur2d(leds, 16); - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } // mode_2DBlackHole() static const char *_data_FX_MODE_2DBLACKHOLE PROGMEM = "2D Black Hole@Fade rate,Outer Y freq.,Outer X freq.,Inner X freq.,Inner Y freq.;;"; @@ -4585,8 +4583,8 @@ static const char *_data_FX_MODE_2DBLACKHOLE PROGMEM = "2D Black Hole@Fade rate, //////////////////////////// // 2D Colored Bursts // //////////////////////////// -uint16_t WS2812FX::mode_2DColoredBursts() { // By: ldirko https://editor.soulmatelights.com/gallery/819-colored-bursts , modified by: Andrew Tuline - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.soulmatelights.com/gallery/819-colored-bursts , modified by: Andrew Tuline + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4596,7 +4594,7 @@ uint16_t WS2812FX::mode_2DColoredBursts() { // By: ldirko https:/ CRGB *leds = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { - fill_solid(leds, CRGB::Black); + strip.fill_solid(leds, CRGB::Black); //for (uint16_t i = 0; i < w*h; i++) leds[i] = CRGB::Black; SEGENV.aux0 = 0; // start with red hue } @@ -4607,14 +4605,14 @@ uint16_t WS2812FX::mode_2DColoredBursts() { // By: ldirko https:/ byte numLines = SEGMENT.intensity/16 + 1; SEGENV.aux0++; // hue - fadeToBlackBy(leds, 40); + strip.fadeToBlackBy(leds, 40); for (byte i = 0; i < numLines; i++) { byte x1 = beatsin8(2 + SEGMENT.speed/16, 0, (cols - 1)); 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(currentPalette, i * 255 / numLines + (SEGENV.aux0&0xFF), 255, LINEARBLEND); + CRGB color = ColorFromPalette(strip.currentPalette, i * 255 / numLines + (SEGENV.aux0&0xFF), 255, LINEARBLEND); byte xsteps = abs8(x1 - y1) + 1; byte ysteps = abs8(x2 - y2) + 1; @@ -4633,9 +4631,9 @@ uint16_t WS2812FX::mode_2DColoredBursts() { // By: ldirko https:/ leds[XY(y1, y2)] += CRGB::White; } } - blur2d(leds, 4); + strip.blur2d(leds, 4); - setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. + strip.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. return FRAMETIME; } // mode_2DColoredBursts() static const char *_data_FX_MODE_2DCOLOREDBURSTS PROGMEM = "2D Colored Bursts@Speed,# of lines;;!"; @@ -4644,8 +4642,8 @@ static const char *_data_FX_MODE_2DCOLOREDBURSTS PROGMEM = "2D Colored Bursts@Sp ///////////////////// // 2D DNA // ///////////////////// -uint16_t WS2812FX::mode_2Ddna(void) { // dna originally by by ldirko at https://pastebin.com/pCkkkzcs. Updated by Preyy. WLED conversion by Andrew Tuline. - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pastebin.com/pCkkkzcs. Updated by Preyy. WLED conversion by Andrew Tuline. + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4654,17 +4652,17 @@ uint16_t WS2812FX::mode_2Ddna(void) { // dna originally by by ldirko at if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) fill_solid(leds, 0); + if (SEGENV.call == 0) strip.fill_solid(leds, 0); - fadeToBlackBy(leds, 64); + strip.fadeToBlackBy(leds, 64); for(int i = 0; i < cols; i++) { - leds[XY(i, beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4))] = ColorFromPalette(currentPalette, i*5+millis()/17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND); - leds[XY(i, beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4+128))] = ColorFromPalette(currentPalette,i*5+128+millis()/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND); // 180 degrees (128) out of phase + leds[XY(i, beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4))] = ColorFromPalette(strip.currentPalette, i*5+millis()/17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND); + leds[XY(i, beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4+128))] = ColorFromPalette(strip.currentPalette,i*5+128+millis()/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND); // 180 degrees (128) out of phase } - blur2d(leds, SEGMENT.intensity/8); + strip.blur2d(leds, SEGMENT.intensity/8); - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } // mode_2Ddna() static const char *_data_FX_MODE_2DDNA PROGMEM = "2D DNA@Scroll speed,Blur;;!"; @@ -4673,8 +4671,8 @@ static const char *_data_FX_MODE_2DDNA PROGMEM = "2D DNA@Scroll speed,Blur;;!"; ///////////////////////// // 2D DNA Spiral // ///////////////////////// -uint16_t WS2812FX::mode_2DDNASpiral() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , modified by: Andrew Tuline - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , modified by: Andrew Tuline + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4684,7 +4682,7 @@ uint16_t WS2812FX::mode_2DDNASpiral() { // By: ldirko https://edi CRGB *leds = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { - fill_solid(leds, CRGB::Black); + strip.fill_solid(leds, CRGB::Black); SEGENV.aux0 = 0; // hue } @@ -4692,7 +4690,7 @@ uint16_t WS2812FX::mode_2DDNASpiral() { // By: ldirko https://edi uint8_t freq = SEGMENT.intensity/8; uint32_t ms = millis() / 20; - nscale8(leds, 120); + strip.nscale8(leds, 120); for (uint16_t i = 0; i < rows; i++) { uint16_t x = beatsin8(speeds, 0, cols - 1, 0, i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, i * freq + 128); @@ -4704,7 +4702,7 @@ uint16_t WS2812FX::mode_2DDNASpiral() { // By: ldirko https://edi for (byte k = 1; k <= steps; k++) { byte dx = lerp8by8(x, x1, k * 255 / steps); uint16_t index = XY(dx, i); - leds[index] += ColorFromPalette(currentPalette, SEGENV.aux0, 255, LINEARBLEND); + leds[index] += ColorFromPalette(strip.currentPalette, SEGENV.aux0, 255, LINEARBLEND); leds[index] %= (k * 255 / steps); //for draw gradient line } leds[XY(x, i)] += CRGB::DarkSlateGray; @@ -4712,7 +4710,7 @@ uint16_t WS2812FX::mode_2DDNASpiral() { // By: ldirko https://edi } } - setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. + strip.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. return FRAMETIME; } // mode_2DDNASpiral() static const char *_data_FX_MODE_2DDNASPIRAL PROGMEM = "2D DNA Spiral@Scroll speed,Blur;;!"; @@ -4721,8 +4719,8 @@ static const char *_data_FX_MODE_2DDNASPIRAL PROGMEM = "2D DNA Spiral@Scroll spe ///////////////////////// // 2D Drift // ///////////////////////// -uint16_t WS2812FX::mode_2DDrift() { // By: Stepko https://editor.soulmatelights.com/gallery/884-drift , Modified by: Andrew Tuline - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmatelights.com/gallery/884-drift , Modified by: Andrew Tuline + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4733,9 +4731,9 @@ uint16_t WS2812FX::mode_2DDrift() { // By: Stepko https://editor. if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); - fadeToBlackBy(leds, 128); + strip.fadeToBlackBy(leds, 128); const uint16_t maxDim = MAX(cols, rows)/2; unsigned long t = millis() / (32 - (SEGMENT.speed>>3)); @@ -4743,11 +4741,11 @@ uint16_t WS2812FX::mode_2DDrift() { // By: Stepko https://editor. float angle = radians(t * (maxDim - i)); uint16_t myX = (cols>>1) + (uint16_t)(sin_t(angle) * i) + (cols%2); uint16_t myY = (rows>>1) + (uint16_t)(cos_t(angle) * i) + (rows%2); - leds[XY(myX,myY)] = ColorFromPalette(currentPalette, (i * 20) + (t / 20), 255, LINEARBLEND); + leds[XY(myX,myY)] = ColorFromPalette(strip.currentPalette, (i * 20) + (t / 20), 255, LINEARBLEND); } - blur2d(leds, SEGMENT.intensity>>3); + strip.blur2d(leds, SEGMENT.intensity>>3); - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } // mode_2DDrift() static const char *_data_FX_MODE_2DDRIFT PROGMEM = "2D Drift@Rotation speed,Blur amount;;!"; @@ -4756,8 +4754,8 @@ static const char *_data_FX_MODE_2DDRIFT PROGMEM = "2D Drift@Rotation speed,Blur ////////////////////////// // 2D Firenoise // ////////////////////////// -uint16_t WS2812FX::mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline. Yet another short routine. - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline. Yet another short routine. + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4766,13 +4764,13 @@ uint16_t WS2812FX::mode_2Dfirenoise(void) { // firenoise2d. By And if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); uint16_t xscale = SEGMENT.intensity*4; uint32_t yscale = SEGMENT.speed*8; uint8_t indexx = 0; - currentPalette = CRGBPalette16( CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0), + strip.currentPalette = CRGBPalette16( CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0), CRGB::Red, CRGB::Red, CRGB::Red, CRGB::DarkOrange, CRGB::DarkOrange,CRGB::DarkOrange, CRGB::Orange, CRGB::Orange, CRGB::Yellow, CRGB::Orange, CRGB::Yellow, CRGB::Yellow); @@ -4780,11 +4778,11 @@ uint16_t WS2812FX::mode_2Dfirenoise(void) { // firenoise2d. By And for (uint16_t j=0; j < cols; j++) { for (uint16_t i=0; i < rows; i++) { indexx = inoise8(j*yscale*rows/255, i*xscale+millis()/4); // We're moving along our Perlin map. - leds[XY(j,i)] = ColorFromPalette(currentPalette, min(i*(indexx)>>4, 255), i*255/cols, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. + leds[XY(j,i)] = ColorFromPalette(strip.currentPalette, min(i*(indexx)>>4, 255), i*255/cols, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. } // for i } // for j - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } // mode_2Dfirenoise() static const char *_data_FX_MODE_2DFIRENOISE PROGMEM = "2D Firenoise@X scale,Y scale;;"; @@ -4793,8 +4791,8 @@ static const char *_data_FX_MODE_2DFIRENOISE PROGMEM = "2D Firenoise@X scale,Y s ////////////////////////////// // 2D Frizzles // ////////////////////////////// -uint16_t WS2812FX::mode_2DFrizzles(void) { // By: Stepko https://editor.soulmatelights.com/gallery/640-color-frizzles , Modified by: Andrew Tuline - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2DFrizzles(void) { // By: Stepko https://editor.soulmatelights.com/gallery/640-color-frizzles , Modified by: Andrew Tuline + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4803,15 +4801,15 @@ uint16_t WS2812FX::mode_2DFrizzles(void) { // By: Stepko https:/ if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); - fadeToBlackBy(leds, 16); + strip.fadeToBlackBy(leds, 16); for (byte i = 8; i > 0; i--) { - leds[XY(beatsin8(SEGMENT.speed/8 + i, 0, cols - 1), beatsin8(SEGMENT.intensity/8 - i, 0, rows - 1))] += ColorFromPalette(currentPalette, beatsin8(12, 0, 255), 255, LINEARBLEND); + leds[XY(beatsin8(SEGMENT.speed/8 + i, 0, cols - 1), beatsin8(SEGMENT.intensity/8 - i, 0, rows - 1))] += ColorFromPalette(strip.currentPalette, beatsin8(12, 0, 255), 255, LINEARBLEND); } - blur2d(leds, 16); + strip.blur2d(leds, 16); - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } // mode_2DFrizzles() static const char *_data_FX_MODE_2DFRIZZLES PROGMEM = "2D Frizzles@X frequency,Y frequency;;!"; @@ -4825,8 +4823,8 @@ typedef struct ColorCount { int8_t count; } colorCount; -uint16_t WS2812FX::mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https://natureofcode.com/book/chapter-7-cellular-automata/ and https://github.com/DougHaber/nlife-color - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https://natureofcode.com/book/chapter-7-cellular-automata/ and https://github.com/DougHaber/nlife-color + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4839,10 +4837,10 @@ uint16_t WS2812FX::mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired CRGB backgroundColor = SEGCOLOR(1); - if (SEGENV.call == 0 || now - *resetMillis > 5000) { - *resetMillis = now; + if (SEGENV.call == 0 || strip.now - *resetMillis > 5000) { + *resetMillis = strip.now; - random16_set_seed(now); //seed the random generator + random16_set_seed(strip.now); //seed the random generator //give the leds random state and colors (based on intensity, colors from palette or all posible colors are chosen) for (int x = 0; x < cols; x++) for (int y = 0; y < rows; y++) { @@ -4850,10 +4848,10 @@ uint16_t WS2812FX::mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired if (state == 0) leds[XY(x,y)] = backgroundColor; else - leds[XY(x,y)] = (CRGB)color_from_palette(random8(), false, PALETTE_SOLID_WRAP, 0); + leds[XY(x,y)] = (CRGB)strip.color_from_palette(random8(), false, PALETTE_SOLID_WRAP, 0); } - fill_solid(prevLeds, CRGB::Black); + strip.fill_solid(prevLeds, CRGB::Black); SEGENV.aux1 = 0; SEGENV.aux0 = 0xFFFF; @@ -4909,12 +4907,12 @@ uint16_t WS2812FX::mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired // check if we had same CRC and reset if needed // same CRC would mean image did not change or was repeating itself - if (!(crc == SEGENV.aux0 || crc == SEGENV.aux1)) *resetMillis = now; //if no repetition avoid reset + if (!(crc == SEGENV.aux0 || crc == SEGENV.aux1)) *resetMillis = strip.now; //if no repetition avoid reset // remeber last two SEGENV.aux1 = SEGENV.aux0; SEGENV.aux0 = crc; - setPixels(leds); + strip.setPixels(leds); return (SEGMENT.getOption(SEG_OPTION_TRANSITIONAL)) ? FRAMETIME : FRAMETIME_FIXED * (128-(SEGMENT.speed>>1)); // update only when appropriate time passes (in 42 FPS slots) } // mode_2Dgameoflife() static const char *_data_FX_MODE_2DGAMEOFLIFE PROGMEM = "2D Game Of Life@!,;!,!;!"; @@ -4923,16 +4921,16 @@ static const char *_data_FX_MODE_2DGAMEOFLIFE PROGMEM = "2D Game Of Life@!,;!,!; ///////////////////////// // 2D Hiphotic // ///////////////////////// -uint16_t WS2812FX::mode_2DHiphotic() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , Modified by: Andrew Tuline - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2DHiphotic() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , Modified by: Andrew Tuline + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - const uint32_t a = now / 8; + const uint32_t a = strip.now / 8; for (uint16_t x = 0; x < cols; x++) { for (uint16_t y = 0; y < rows; y++) { - setPixelColorXY(x, y, color_from_palette(sin8(cos8(x * SEGMENT.speed/16 + a / 3) + sin8(y * SEGMENT.intensity/16 + a / 4) + a), false, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColorXY(x, y, strip.color_from_palette(sin8(cos8(x * SEGMENT.speed/16 + a / 3) + sin8(y * SEGMENT.intensity/16 + a / 4) + a), false, PALETTE_SOLID_WRAP, 0)); } } @@ -4955,8 +4953,8 @@ typedef struct Julia { float xymag; } julia; -uint16_t WS2812FX::mode_2DJulia(void) { // An animated Julia set by Andrew Tuline. - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2DJulia(void) { // An animated Julia set by Andrew Tuline. + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5043,9 +5041,9 @@ uint16_t WS2812FX::mode_2DJulia(void) { // An animated // We color each pixel based on how long it takes to get to infinity, or black if it never gets there. if (iter == maxIterations) { - setPixelColorXY(i, j, 0); + strip.setPixelColorXY(i, j, 0); } else { - setPixelColorXY(i, j, color_from_palette(iter*255/maxIterations, false, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColorXY(i, j, strip.color_from_palette(iter*255/maxIterations, false, PALETTE_SOLID_WRAP, 0)); } x += dx; } @@ -5061,24 +5059,24 @@ static const char *_data_FX_MODE_2DJULIA PROGMEM = "2D Julia@,Max iterations per ////////////////////////////// // 2D Lissajous // ////////////////////////////// -uint16_t WS2812FX::mode_2DLissajous(void) { // By: Andrew Tuline - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2DLissajous(void) { // By: Andrew Tuline + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - fadeToBlackBy(SEGMENT.intensity); - //fade_out(SEGMENT.intensity); + strip.fadeToBlackBy(SEGMENT.intensity); + //strip.fade_out(SEGMENT.intensity); //for (int i=0; i < 4*(cols+rows); i ++) { for (int i=0; i < 256; i ++) { //float xlocn = float(sin8(now/4+i*(SEGMENT.speed>>5))) / 255.0f; //float ylocn = float(cos8(now/4+i*2)) / 255.0f; - uint8_t xlocn = sin8(now/2+i*(SEGMENT.speed>>5)); - uint8_t ylocn = cos8(now/2+i*2); + uint8_t xlocn = sin8(strip.now/2+i*(SEGMENT.speed>>5)); + uint8_t ylocn = cos8(strip.now/2+i*2); xlocn = map(xlocn,0,255,0,cols-1); ylocn = map(ylocn,0,255,0,rows-1); - setPixelColorXY(xlocn, ylocn, color_from_palette(now/100+i, false, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColorXY(xlocn, ylocn, strip.color_from_palette(strip.now/100+i, false, PALETTE_SOLID_WRAP, 0)); } return FRAMETIME; @@ -5089,8 +5087,8 @@ static const char *_data_FX_MODE_2DLISSAJOUS PROGMEM = "2D Lissajous@X frequency /////////////////////// // 2D Matrix // /////////////////////// -uint16_t WS2812FX::mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi. - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi. + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5099,7 +5097,7 @@ uint16_t WS2812FX::mode_2Dmatrix(void) { // Matrix2D. By Jeremy if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); uint8_t fade = map(SEGMENT.custom1, 0, 255, 50, 250); // equals trail size uint8_t speed = (256-SEGMENT.speed) >> map(MIN(rows, 150), 0, 150, 0, 3); // slower speeds for small displays @@ -5114,8 +5112,8 @@ uint16_t WS2812FX::mode_2Dmatrix(void) { // Matrix2D. By Jeremy trailColor = CRGB(27,130,39); } - if (now - SEGENV.step >= speed) { - SEGENV.step = now; + if (strip.now - SEGENV.step >= speed) { + SEGENV.step = strip.now; for (int16_t row=rows-1; row>=0; row--) { for (int16_t col=0; col(SEGENV.data); - if (SEGENV.call == 0) fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); - fadeToBlackBy(leds, 15); + strip.fadeToBlackBy(leds, 15); byte t1 = millis() / (257 - SEGMENT.speed); // 20; byte t2 = sin8(t1) / 4 * 2; for (uint16_t i = 0; i < 13; i++) { byte x = sin8(t1 + i * SEGMENT.intensity/8)*(cols-1)/255; // max index now 255x15/255=15! byte y = sin8(t2 + i * SEGMENT.intensity/8)*(rows-1)/255; // max index now 255x15/255=15! - leds[XY(x, y)] = ColorFromPalette(currentPalette, i * 255 / 13, 255, LINEARBLEND); + leds[XY(x, y)] = ColorFromPalette(strip.currentPalette, i * 255 / 13, 255, LINEARBLEND); } - blur2d(leds, 16); + strip.blur2d(leds, 16); - setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. + strip.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. return FRAMETIME; } // mode_2DSindots() static const char *_data_FX_MODE_2DSINDOTS PROGMEM = "2D Sindots@Speed,Dot distance;;!"; @@ -5404,9 +5403,9 @@ static const char *_data_FX_MODE_2DSINDOTS PROGMEM = "2D Sindots@Speed,Dot dista // 2D Squared Swirl // ////////////////////////////// // custom3 affects the blur amount. -uint16_t WS2812FX::mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://gist.github.com/kriegsman/368b316c55221134b160 +uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://gist.github.com/kriegsman/368b316c55221134b160 // Modifed by: Andrew Tuline - if (!isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5415,13 +5414,13 @@ uint16_t WS2812FX::mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); const uint8_t kBorderWidth = 2; - fadeToBlackBy(leds, 24); + strip.fadeToBlackBy(leds, 24); uint8_t blurAmount = SEGMENT.custom3>>4; - blur2d(leds, blurAmount); + strip.blur2d(leds, blurAmount); // Use two out-of-sync sine waves uint8_t i = beatsin8(19, kBorderWidth, cols-kBorderWidth); @@ -5433,11 +5432,11 @@ uint16_t WS2812FX::mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. uint16_t ms = millis(); - leds[XY(i, m)] += ColorFromPalette(currentPalette, ms/29, 255, LINEARBLEND); - leds[XY(j, n)] += ColorFromPalette(currentPalette, ms/41, 255, LINEARBLEND); - leds[XY(k, p)] += ColorFromPalette(currentPalette, ms/73, 255, LINEARBLEND); + leds[XY(i, m)] += ColorFromPalette(strip.currentPalette, ms/29, 255, LINEARBLEND); + leds[XY(j, n)] += ColorFromPalette(strip.currentPalette, ms/41, 255, LINEARBLEND); + leds[XY(k, p)] += ColorFromPalette(strip.currentPalette, ms/73, 255, LINEARBLEND); - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } // mode_2Dsquaredswirl() static const char *_data_FX_MODE_2DSQUAREDSWIRL PROGMEM = "2D Squared Swirl@,,,,Blur;,,;!"; @@ -5446,8 +5445,8 @@ static const char *_data_FX_MODE_2DSQUAREDSWIRL PROGMEM = "2D Squared Swirl@,,,, ////////////////////////////// // 2D Sun Radiation // ////////////////////////////// -uint16_t WS2812FX::mode_2DSunradiation(void) { // By: ldirko https://editor.soulmatelights.com/gallery/599-sun-radiation , modified by: Andrew Tuline - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2DSunradiation(void) { // By: ldirko https://editor.soulmatelights.com/gallery/599-sun-radiation , modified by: Andrew Tuline + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5457,7 +5456,7 @@ uint16_t WS2812FX::mode_2DSunradiation(void) { // By: ldirko h CRGB *leds = reinterpret_cast(SEGENV.data); byte *bump = reinterpret_cast(SEGENV.data + dataSize); - if (SEGENV.call == 0) fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); unsigned long t = millis() / 4; int index = 0; @@ -5488,7 +5487,7 @@ uint16_t WS2812FX::mode_2DSunradiation(void) { // By: ldirko h yindex += (cols + 2); } - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } // mode_2DSunradiation() static const char *_data_FX_MODE_2DSUNRADIATION PROGMEM = "2D Sun Radiation@Variance,Brightness;;"; @@ -5497,8 +5496,8 @@ static const char *_data_FX_MODE_2DSUNRADIATION PROGMEM = "2D Sun Radiation@Vari ///////////////////////// // 2D Tartan // ///////////////////////// -uint16_t WS2812FX::mode_2Dtartan(void) { // By: Elliott Kember https://editor.soulmatelights.com/gallery/3-tartan , Modified by: Andrew Tuline - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.soulmatelights.com/gallery/3-tartan , Modified by: Andrew Tuline + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5507,7 +5506,7 @@ uint16_t WS2812FX::mode_2Dtartan(void) { // By: Elliott Kember https:/ if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); uint8_t hue; int offsetX = beatsin16(3, -360, 360); @@ -5517,13 +5516,13 @@ uint16_t WS2812FX::mode_2Dtartan(void) { // By: Elliott Kember https:/ for (uint16_t y = 0; y < rows; y++) { uint16_t index = XY(x, y); hue = x * beatsin16(10, 1, 10) + offsetY; - leds[index] = ColorFromPalette(currentPalette, hue, sin8(x * SEGMENT.speed + offsetX) * sin8(x * SEGMENT.speed + offsetX) / 255, LINEARBLEND); + leds[index] = ColorFromPalette(strip.currentPalette, hue, sin8(x * SEGMENT.speed + offsetX) * sin8(x * SEGMENT.speed + offsetX) / 255, LINEARBLEND); hue = y * 3 + offsetX; - leds[index] += ColorFromPalette(currentPalette, hue, sin8(y * SEGMENT.intensity + offsetY) * sin8(y * SEGMENT.intensity + offsetY) / 255, LINEARBLEND); + leds[index] += ColorFromPalette(strip.currentPalette, hue, sin8(y * SEGMENT.intensity + offsetY) * sin8(y * SEGMENT.intensity + offsetY) / 255, LINEARBLEND); } } - setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. + strip.setPixels(leds); // Use this ONLY if we're going to display via leds[x] method. return FRAMETIME; } // mode_2DTartan() static const char *_data_FX_MODE_2DTARTAN PROGMEM = "2D Tartan@X scale,Y scale;;!"; @@ -5532,8 +5531,8 @@ static const char *_data_FX_MODE_2DTARTAN PROGMEM = "2D Tartan@X scale,Y scale;; ///////////////////////// // 2D spaceships // ///////////////////////// -uint16_t WS2812FX::mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [https://editor.soulmatelights.com/gallery/639-space-ships], adapted by Blaz Kristan - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [https://editor.soulmatelights.com/gallery/639-space-ships], adapted by Blaz Kristan + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5542,9 +5541,9 @@ uint16_t WS2812FX::mode_2Dspaceships(void) { //// Space ships by stepko (c)05 if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); - uint32_t tb = now >> 12; // every ~4s + uint32_t tb = strip.now >> 12; // every ~4s if (tb > SEGENV.step) { int8_t dir = ++SEGENV.aux0; dir += (int)random8(3)-1; @@ -5554,12 +5553,12 @@ uint16_t WS2812FX::mode_2Dspaceships(void) { //// Space ships by stepko (c)05 SEGENV.step = tb + random8(4); } - fadeToBlackBy(leds, map(SEGMENT.speed, 0, 255, 248, 16)); - move(SEGENV.aux0, 1, leds); + strip.fadeToBlackBy(leds, map(SEGMENT.speed, 0, 255, 248, 16)); + strip.move(SEGENV.aux0, 1, leds); for (byte i = 0; i < 8; i++) { byte x = beatsin8(12 + i, 2, cols - 3); byte y = beatsin8(15 + i, 2, rows - 3); - CRGB color = ColorFromPalette(currentPalette, beatsin8(12 + i, 0, 255), 255); + CRGB color = ColorFromPalette(strip.currentPalette, beatsin8(12 + i, 0, 255), 255); leds[XY(x, y)] += color; if (cols > 24 || rows > 24) { leds[XY(x + 1, y)] += color; @@ -5568,9 +5567,9 @@ uint16_t WS2812FX::mode_2Dspaceships(void) { //// Space ships by stepko (c)05 leds[XY(x, y - 1)] += color; } } - blur2d(leds, SEGMENT.intensity>>3); + strip.blur2d(leds, SEGMENT.intensity>>3); - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } static const char *_data_FX_MODE_SPACESHIPS PROGMEM = "2D Spaceships@!,Blur;!,!,!;!"; @@ -5581,8 +5580,8 @@ static const char *_data_FX_MODE_SPACESHIPS PROGMEM = "2D Spaceships@!,Blur;!,!, ///////////////////////// //// Crazy bees by stepko (c)12.02.21 [https://editor.soulmatelights.com/gallery/651-crazy-bees], adapted by Blaz Kristan #define MAX_BEES 5 -uint16_t WS2812FX::mode_2Dcrazybees(void) { - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Dcrazybees(void) { + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5611,7 +5610,7 @@ uint16_t WS2812FX::mode_2Dcrazybees(void) { bee_t *bee = reinterpret_cast(SEGENV.data + dataSize); if (SEGENV.call == 0) { - fill_solid(leds, CRGB::Black); + strip.fill_solid(leds, CRGB::Black); for (byte i = 0; i < n; i++) { bee[i].posX = random8(0, cols); bee[i].posY = random8(0, rows); @@ -5622,7 +5621,7 @@ uint16_t WS2812FX::mode_2Dcrazybees(void) { if (millis() > SEGENV.step) { SEGENV.step = millis() + (FRAMETIME * 8 / ((SEGMENT.speed>>5)+1)); - fadeToBlackBy(leds, 32); + strip.fadeToBlackBy(leds, 32); for (byte i = 0; i < n; i++) { leds[XY(bee[i].aimX + 1, bee[i].aimY)] += CHSV(bee[i].hue, 255, 255); @@ -5644,9 +5643,9 @@ uint16_t WS2812FX::mode_2Dcrazybees(void) { bee[i].aimed(cols, rows); } } - blur2d(leds, SEGMENT.intensity>>4); + strip.blur2d(leds, SEGMENT.intensity>>4); - setPixels(leds); + strip.setPixels(leds); } return FRAMETIME; } @@ -5658,8 +5657,8 @@ static const char *_data_FX_MODE_CRAZYBEES PROGMEM = "2D Crazy Bees@!,Blur;;"; ///////////////////////// //// Ghost Rider by stepko (c)2021 [https://editor.soulmatelights.com/gallery/716-ghost-rider], adapted by Blaz Kristan #define LIGHTERS_AM 64 // max lighters (adequate for 32x32 matrix) -uint16_t WS2812FX::mode_2Dghostrider(void) { - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Dghostrider(void) { + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5687,8 +5686,8 @@ uint16_t WS2812FX::mode_2Dghostrider(void) { if (SEGENV.call == 0 || SEGENV.aux0 != cols || SEGENV.aux1 != rows) { SEGENV.aux0 = cols; SEGENV.aux1 = rows; - fill_solid(leds, CRGB::Black); - randomSeed(now); + strip.fill_solid(leds, CRGB::Black); + randomSeed(strip.now); lighter->angleSpeed = random8(0,20) - 10; lighter->Vspeed = 5; lighter->gPosX = (cols/2) * 10; @@ -5703,10 +5702,10 @@ uint16_t WS2812FX::mode_2Dghostrider(void) { if (millis() > SEGENV.step) { SEGENV.step = millis() + 1024 / (cols+rows); - fadeToBlackBy(leds, (SEGMENT.speed>>2)+64); + strip.fadeToBlackBy(leds, (SEGMENT.speed>>2)+64); CRGB color = CRGB::White; - wu_pixel(leds, lighter->gPosX * 256 / 10, lighter->gPosY * 256 / 10, color); + strip.wu_pixel(leds, lighter->gPosX * 256 / 10, lighter->gPosY * 256 / 10, color); lighter->gPosX += lighter->Vspeed * sin_t(radians(lighter->gAngle)); lighter->gPosY += lighter->Vspeed * cos_t(radians(lighter->gAngle)); @@ -5734,12 +5733,12 @@ uint16_t WS2812FX::mode_2Dghostrider(void) { lighter->lightersPosX[i] += -7 * sin_t(radians(lighter->Angle[i])); lighter->lightersPosY[i] += -7 * cos_t(radians(lighter->Angle[i])); } - wu_pixel(leds, lighter->lightersPosX[i] * 256 / 10, lighter->lightersPosY[i] * 256 / 10, ColorFromPalette(currentPalette, (256 - lighter->time[i]))); + strip.wu_pixel(leds, lighter->lightersPosX[i] * 256 / 10, lighter->lightersPosY[i] * 256 / 10, ColorFromPalette(strip.currentPalette, (256 - lighter->time[i]))); } - blur2d(leds, SEGMENT.intensity>>3); + strip.blur2d(leds, SEGMENT.intensity>>3); } - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } static const char *_data_FX_MODE_GHOST_RIDER PROGMEM = "2D Ghost Rider@Fade rate,Blur;!,!,!;!"; @@ -5750,8 +5749,8 @@ static const char *_data_FX_MODE_GHOST_RIDER PROGMEM = "2D Ghost Rider@Fade rate //////////////////////////// //// Floating Blobs by stepko (c)2021 [https://editor.soulmatelights.com/gallery/573-blobs], adapted by Blaz Kristan #define MAX_BLOBS 8 -uint16_t WS2812FX::mode_2Dfloatingblobs(void) { - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Dfloatingblobs(void) { + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5774,7 +5773,7 @@ uint16_t WS2812FX::mode_2Dfloatingblobs(void) { if (SEGENV.call == 0 || SEGENV.aux0 != cols || SEGENV.aux1 != rows) { SEGENV.aux0 = cols; SEGENV.aux1 = rows; - fill_solid(leds, CRGB::Black); + strip.fill_solid(leds, CRGB::Black); for (byte i = 0; i < MAX_BLOBS; i++) { blob->r[i] = cols>15 ? random8(1, cols/8.f) : 1; blob->sX[i] = (float) random8(3, cols) / (float)(256 - SEGMENT.speed); // speed x @@ -5788,7 +5787,7 @@ uint16_t WS2812FX::mode_2Dfloatingblobs(void) { } } - fadeToBlackBy(leds, 20); + strip.fadeToBlackBy(leds, 20); // Bounce balls around for (byte i = 0; i < Amount; i++) { @@ -5807,9 +5806,9 @@ uint16_t WS2812FX::mode_2Dfloatingblobs(void) { blob->grow[i] = true; } } - CRGB c = ColorFromPalette(currentPalette, blob->color[i]); + CRGB c = ColorFromPalette(strip.currentPalette, blob->color[i]); //if (!SEGMENT.palette) c = SEGCOLOR(0); - if (blob->r[i] > 1.f) fill_circle(leds, blob->y[i], blob->x[i], blob->r[i], c); + if (blob->r[i] > 1.f) strip.fill_circle(leds, blob->y[i], blob->x[i], blob->r[i], c); else leds[XY(blob->y[i], blob->x[i])] += c; // move x if (blob->x[i] + blob->r[i] >= cols - 1) blob->x[i] += (blob->sX[i] * ((cols - 1 - blob->x[i]) / blob->r[i] + 0.005f)); @@ -5838,11 +5837,11 @@ uint16_t WS2812FX::mode_2Dfloatingblobs(void) { blob->y[i] = rows - 1.01f; } } - blur2d(leds, cols+rows); + strip.blur2d(leds, cols+rows); if (SEGENV.step < millis()) SEGENV.step = millis() + 2000; // change colors every 2 seconds - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } #undef MAX_BLOBS @@ -5852,8 +5851,8 @@ static const char *_data_FX_MODE_BLOBS PROGMEM = "2D Blobs@!,# blobs;!,!,!;!"; //////////////////////////// // 2D Scrolling text // //////////////////////////// -uint16_t WS2812FX::mode_2Dscrollingtext(void) { - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Dscrollingtext(void) { + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5886,12 +5885,12 @@ uint16_t WS2812FX::mode_2Dscrollingtext(void) { SEGENV.step = millis() + map(SEGMENT.speed, 0, 255, 10*FRAMETIME_FIXED, 2*FRAMETIME_FIXED); } - fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color + strip.fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color for (uint16_t i = 0; i < numberOfLetters; i++) { if (int(cols) - int(SEGENV.aux0) + letterWidth*(i+1) < 0) continue; // don't draw characters off-screen if (text[i]<32 || text[i]>126) continue; // skip non-ANSII characters (may add UTF translation at some point) - drawCharacter(text[i], int(cols) - int(SEGENV.aux0) + letterWidth*i, yoffset, letterWidth, letterHeight, color_from_palette(SEGENV.aux1, false, PALETTE_SOLID_WRAP, 0)); + strip.drawCharacter(text[i], int(cols) - int(SEGENV.aux0) + letterWidth*i, yoffset, letterWidth, letterHeight, strip.color_from_palette(SEGENV.aux1, false, PALETTE_SOLID_WRAP, 0)); } return FRAMETIME; @@ -5903,8 +5902,8 @@ static const char *_data_FX_MODE_SCROLL_TEXT PROGMEM = "2D Scrolling Text@!,Y Of // 2D Drift Rose // //////////////////////////// //// Drift Rose by stepko (c)2021 [https://editor.soulmatelights.com/gallery/1369-drift-rose-pattern], adapted by Blaz Kristan -uint16_t WS2812FX::mode_2Ddriftrose(void) { - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Ddriftrose(void) { + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5918,18 +5917,18 @@ uint16_t WS2812FX::mode_2Ddriftrose(void) { CRGB *leds = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { - fill_solid(leds, CRGB::Black); + strip.fill_solid(leds, CRGB::Black); } - fadeToBlackBy(leds, 32+(SEGMENT.speed>>3)); + strip.fadeToBlackBy(leds, 32+(SEGMENT.speed>>3)); for (byte i = 1; i < 37; i++) { uint32_t x = (CX + (sin_t(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f; uint32_t y = (CY + (cos_t(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f; - wu_pixel(leds, x, y, CHSV(i * 10, 255, 255)); + strip.wu_pixel(leds, x, y, CHSV(i * 10, 255, 255)); } - blur2d(leds, (SEGMENT.intensity>>4)+1); + strip.blur2d(leds, (SEGMENT.intensity>>4)+1); - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } static const char *_data_FX_MODE_DRIFT_ROSE PROGMEM = "2D Drift Rose@Fade,Blur;;"; @@ -5987,7 +5986,7 @@ static const char *_data_FX_MODE_DRIFT_ROSE PROGMEM = "2D Drift Rose@Fade,Blur;; ///////////////////////////////// // * Ripple Peak // ///////////////////////////////// -uint16_t WS2812FX::mode_ripplepeak(void) { // * Ripple peak. By Andrew Tuline. +uint16_t mode_ripplepeak(void) { // * Ripple peak. By Andrew Tuline. // This currently has no controls. #define maxsteps 16 // Case statement wouldn't allow a variable. @@ -6023,8 +6022,8 @@ uint16_t WS2812FX::mode_ripplepeak(void) { // * Ripple peak. By A *binNum = SEGMENT.custom2; // Select a bin. *maxVol = SEGMENT.custom3/2; // Our volume comparator. - fade_out(240); // Lower frame rate means less effective fading than FastLED - fade_out(240); + strip.fade_out(240); // Lower frame rate means less effective fading than FastLED + strip.fade_out(240); for (uint16_t i = 0; i < SEGMENT.intensity/16; i++) { // Limit the number of ripples. if (samplePeak) ripples[i].state = 255; @@ -6044,7 +6043,7 @@ uint16_t WS2812FX::mode_ripplepeak(void) { // * Ripple peak. By A break; case 0: - setPixelColor(ripples[i].pos, color_blend(SEGCOLOR(1), color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0)); + strip.setPixelColor(ripples[i].pos, color_blend(SEGCOLOR(1), strip.color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0)); ripples[i].state++; break; @@ -6053,8 +6052,8 @@ uint16_t WS2812FX::mode_ripplepeak(void) { // * Ripple peak. By A break; default: // Middle of the ripples. - setPixelColor((ripples[i].pos + ripples[i].state + SEGLEN) % SEGLEN, color_blend(SEGCOLOR(1), color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0/ripples[i].state*2)); - setPixelColor((ripples[i].pos - ripples[i].state + SEGLEN) % SEGLEN, color_blend(SEGCOLOR(1), color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0/ripples[i].state*2)); + strip.setPixelColor((ripples[i].pos + ripples[i].state + SEGLEN) % SEGLEN, color_blend(SEGCOLOR(1), strip.color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0/ripples[i].state*2)); + strip.setPixelColor((ripples[i].pos - ripples[i].state + SEGLEN) % SEGLEN, color_blend(SEGCOLOR(1), strip.color_from_palette(ripples[i].color, false, PALETTE_SOLID_WRAP, 0), SEGENV.aux0/ripples[i].state*2)); ripples[i].state++; // Next step. break; } // switch step @@ -6069,8 +6068,8 @@ static const char *_data_FX_MODE_RIPPLEPEAK PROGMEM = " ♪ Ripple Peak@Fade rat // * 2D Swirl // ///////////////////////// // By: Mark Kriegsman https://gist.github.com/kriegsman/5adca44e14ad025e6d3b , modified by Andrew Tuline -uint16_t WS2812FX::mode_2DSwirl(void) { - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2DSwirl(void) { + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -6079,11 +6078,11 @@ uint16_t WS2812FX::mode_2DSwirl(void) { if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed CRGB *leds = reinterpret_cast(SEGENV.data); - if (SEGENV.call == 0) fill_solid(leds, CRGB::Black); + if (SEGENV.call == 0) strip.fill_solid(leds, CRGB::Black); const uint8_t borderWidth = 2; - blur2d(leds, SEGMENT.custom1); + strip.blur2d(leds, SEGMENT.custom1); uint8_t i = beatsin8( 27*SEGMENT.speed/255, borderWidth, cols - borderWidth); uint8_t j = beatsin8( 41*SEGMENT.speed/255, borderWidth, rows - borderWidth); @@ -6110,14 +6109,14 @@ uint16_t WS2812FX::mode_2DSwirl(void) { int tmpSound = (soundAgc) ? rawSampleAgc : sample; - leds[XY( i, j)] += ColorFromPalette(currentPalette, (ms / 11 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 11, 200, 255); - leds[XY( j, i)] += ColorFromPalette(currentPalette, (ms / 13 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 13, 200, 255); - leds[XY(ni, nj)] += ColorFromPalette(currentPalette, (ms / 17 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 17, 200, 255); - leds[XY(nj, ni)] += ColorFromPalette(currentPalette, (ms / 29 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 29, 200, 255); - leds[XY( i, nj)] += ColorFromPalette(currentPalette, (ms / 37 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 37, 200, 255); - leds[XY(ni, j)] += ColorFromPalette(currentPalette, (ms / 41 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 41, 200, 255); + leds[XY( i, j)] += ColorFromPalette(strip.currentPalette, (ms / 11 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 11, 200, 255); + leds[XY( j, i)] += ColorFromPalette(strip.currentPalette, (ms / 13 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 13, 200, 255); + leds[XY(ni, nj)] += ColorFromPalette(strip.currentPalette, (ms / 17 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 17, 200, 255); + leds[XY(nj, ni)] += ColorFromPalette(strip.currentPalette, (ms / 29 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 29, 200, 255); + leds[XY( i, nj)] += ColorFromPalette(strip.currentPalette, (ms / 37 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 37, 200, 255); + leds[XY(ni, j)] += ColorFromPalette(strip.currentPalette, (ms / 41 + sampleAvg*4), tmpSound * SEGMENT.intensity / 64, LINEARBLEND); //CHSV( ms / 41, 200, 255); - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } // mode_2DSwirl() static const char *_data_FX_MODE_2DSWIRL PROGMEM = " ♪ 2D Swirl@!,Sensitivity=64,Blur;,Bg Swirl;!"; @@ -6127,8 +6126,8 @@ static const char *_data_FX_MODE_2DSWIRL PROGMEM = " ♪ 2D Swirl@!,Sensitivity= // * 2D Waverly // ///////////////////////// // By: Stepko, https://editor.soulmatelights.com/gallery/652-wave , modified by Andrew Tuline -uint16_t WS2812FX::mode_2DWaverly(void) { - if (!isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2DWaverly(void) { + if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -6138,7 +6137,7 @@ uint16_t WS2812FX::mode_2DWaverly(void) { CRGB *leds = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { - fill_solid(leds, CRGB::Black); + strip.fill_solid(leds, CRGB::Black); } um_data_t *um_data; @@ -6150,7 +6149,7 @@ uint16_t WS2812FX::mode_2DWaverly(void) { sampleAgc = *(float*) um_data->u_data[2]; } - fadeToBlackBy(leds, SEGMENT.speed); + strip.fadeToBlackBy(leds, SEGMENT.speed); long t = millis() / 2; for (uint16_t i = 0; i < cols; i++) { @@ -6163,13 +6162,13 @@ uint16_t WS2812FX::mode_2DWaverly(void) { uint16_t thisMax = map(thisVal, 0, 512, 0, rows); for (uint16_t j = 0; j < thisMax; j++) { - leds[XY(i, j)] += ColorFromPalette(currentPalette, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND); - leds[XY((cols - 1) - i, (rows - 1) - j)] += ColorFromPalette(currentPalette, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND); + leds[XY(i, j)] += ColorFromPalette(strip.currentPalette, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND); + leds[XY((cols - 1) - i, (rows - 1) - j)] += ColorFromPalette(strip.currentPalette, map(j, 0, thisMax, 250, 0), 255, LINEARBLEND); } } - blur2d(leds, 16); + strip.blur2d(leds, 16); - setPixels(leds); + strip.setPixels(leds); return FRAMETIME; } // mode_2DWaverly() static const char *_data_FX_MODE_2DWAVERLY PROGMEM = " ♪ 2D Waverly@Amplification,Sensitivity=64;;!"; @@ -6189,7 +6188,7 @@ typedef struct Gravity { /////////////////////// // * GRAVCENTER // /////////////////////// -uint16_t WS2812FX::mode_gravcenter(void) { // Gravcenter. By Andrew Tuline. +uint16_t mode_gravcenter(void) { // Gravcenter. By Andrew Tuline. const uint16_t dataSize = sizeof(gravity); if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -6209,7 +6208,7 @@ uint16_t WS2812FX::mode_gravcenter(void) { // Gravcenter. By Andr //tmpSound = map(sample, 50, 190, 0, 255); } - fade_out(240); + strip.fade_out(240); float segmentSampleAvg = tmpSound * (float)SEGMENT.intensity / 255.0f; segmentSampleAvg *= 0.125; // divide by 8, to compensate for later "sensitivty" upscaling @@ -6220,8 +6219,8 @@ uint16_t WS2812FX::mode_gravcenter(void) { // Gravcenter. By Andr for (int i=0; i= gravcen->topLED) @@ -6230,8 +6229,8 @@ uint16_t WS2812FX::mode_gravcenter(void) { // Gravcenter. By Andr gravcen->topLED--; if (gravcen->topLED >= 0) { - setPixelColor(gravcen->topLED+SEGLEN/2, color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); - setPixelColor(SEGLEN/2-1-gravcen->topLED, color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(gravcen->topLED+SEGLEN/2, strip.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(SEGLEN/2-1-gravcen->topLED, strip.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); } gravcen->gravityCounter = (gravcen->gravityCounter + 1) % gravity; @@ -6243,7 +6242,7 @@ static const char *_data_FX_MODE_GRAVCENTER PROGMEM = " ♪ Gravcenter@Rate of f /////////////////////// // * GRAVCENTRIC // /////////////////////// -uint16_t WS2812FX::mode_gravcentric(void) { // Gravcentric. By Andrew Tuline. +uint16_t mode_gravcentric(void) { // Gravcentric. By Andrew Tuline. uint16_t dataSize = sizeof(gravity); if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -6263,8 +6262,8 @@ uint16_t WS2812FX::mode_gravcentric(void) { // Gravcentric. //tmpSound = map(sample, 50, 190, 0, 255); } - fade_out(240); - fade_out(240); // twice? really? + strip.fade_out(240); + strip.fade_out(240); // twice? really? float segmentSampleAvg = tmpSound * (float)SEGMENT.intensity / 255.0; segmentSampleAvg *= 0.125f; // divide by 8, to compensate for later "sensitivty" upscaling @@ -6275,8 +6274,8 @@ uint16_t WS2812FX::mode_gravcentric(void) { // Gravcentric. for (int i=0; i= gravcen->topLED) @@ -6285,8 +6284,8 @@ uint16_t WS2812FX::mode_gravcentric(void) { // Gravcentric. gravcen->topLED--; if (gravcen->topLED >= 0) { - setPixelColor(gravcen->topLED+SEGLEN/2, CRGB::Gray); - setPixelColor(SEGLEN/2-1-gravcen->topLED, CRGB::Gray); + strip.setPixelColor(gravcen->topLED+SEGLEN/2, CRGB::Gray); + strip.setPixelColor(SEGLEN/2-1-gravcen->topLED, CRGB::Gray); } gravcen->gravityCounter = (gravcen->gravityCounter + 1) % gravity; @@ -6299,7 +6298,7 @@ static const char *_data_FX_MODE_GRAVCENTRIC PROGMEM = " ♪ Gravcentric@Rate of // * GRAVIMETER // /////////////////////// #ifndef SR_DEBUG_AGC -uint16_t WS2812FX::mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. +uint16_t mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. uint16_t dataSize = sizeof(gravity); if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -6319,7 +6318,7 @@ uint16_t WS2812FX::mode_gravimeter(void) { // Gravmeter. By Andre //tmpSound = map(sample, 50, 190, 0, 255); } - fade_out(240); + strip.fade_out(240); float segmentSampleAvg = tmpSound * (float)SEGMENT.intensity / 255.0; segmentSampleAvg *= 0.25; // divide by 4, to compensate for later "sensitivty" upscaling @@ -6330,7 +6329,7 @@ uint16_t WS2812FX::mode_gravimeter(void) { // Gravmeter. By Andre for (int i=0; i= gravcen->topLED) @@ -6339,7 +6338,7 @@ uint16_t WS2812FX::mode_gravimeter(void) { // Gravmeter. By Andre gravcen->topLED--; if (gravcen->topLED > 0) { - setPixelColor(gravcen->topLED, color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(gravcen->topLED, strip.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); } gravcen->gravityCounter = (gravcen->gravityCounter + 1) % gravity; @@ -6349,7 +6348,7 @@ static const char *_data_FX_MODE_GRAVIMETER PROGMEM = " ♪ Gravimeter@Rate of f #else // This an abuse of the gravimeter effect for AGC debugging // instead of sound volume, it uses the AGC gain multiplier as input -uint16_t WS2812FX::mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. +uint16_t mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. uint16_t dataSize = sizeof(gravity); if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -6371,7 +6370,7 @@ uint16_t WS2812FX::mode_gravimeter(void) { // Gravmeter. By Andre inputLevel = (uint8_t*)um_data->u_data[17]; } - fade_out(240); + strip.fade_out(240); //TODO: implement inputLevel as a global or slider *inputLevel = SEGMENT.custom1; @@ -6400,7 +6399,7 @@ uint16_t WS2812FX::mode_gravimeter(void) { // Gravmeter. By Andre { for (int i=0; i= gravcen->topLED) @@ -6409,7 +6408,7 @@ uint16_t WS2812FX::mode_gravimeter(void) { // Gravmeter. By Andre gravcen->topLED--; if (gravcen->topLED > 0) { - setPixelColor(gravcen->topLED, color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); + strip.setPixelColor(gravcen->topLED, strip.color_from_palette(millis(), false, PALETTE_SOLID_WRAP, 0)); } gravcen->gravityCounter = (gravcen->gravityCounter + 1) % gravity; @@ -6422,7 +6421,7 @@ static const char *_data_FX_MODE_GRAVIMETER PROGMEM = " ♪ Gravimeter@Rate of f ////////////////////// // * JUGGLES // ////////////////////// -uint16_t WS2812FX::mode_juggles(void) { // Juggles. By Andrew Tuline. +uint16_t mode_juggles(void) { // Juggles. By Andrew Tuline. um_data_t *um_data; float sampleAgc = 0.0f; if (usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { @@ -6434,11 +6433,11 @@ uint16_t WS2812FX::mode_juggles(void) { // Juggles. By Andrew //sampleAgc = map(sample, 50, 190, 0, 255); } - fade_out(224); + strip.fade_out(224); uint16_t my_sampleAgc = fmax(fmin(sampleAgc, 255.0), 0); for (uint8_t i=0; i>1)); + strip.fade_out(64+(SEGMENT.speed>>1)); for (uint16_t i=0; i = gravcen->topLED) @@ -7238,8 +7237,8 @@ uint16_t WS2812FX::mode_gravfreq(void) { // Gravfreq. By Andrew gravcen->topLED--; if (gravcen->topLED >= 0) { - setPixelColor(gravcen->topLED+SEGLEN/2, CRGB::Gray); - setPixelColor(SEGLEN/2-1-gravcen->topLED, CRGB::Gray); + strip.setPixelColor(gravcen->topLED+SEGLEN/2, CRGB::Gray); + strip.setPixelColor(SEGLEN/2-1-gravcen->topLED, CRGB::Gray); } gravcen->gravityCounter = (gravcen->gravityCounter + 1) % gravity; @@ -7251,7 +7250,7 @@ static const char *_data_FX_MODE_GRAVFREQ PROGMEM = " ♫ Gravfreq@Rate of fall, ////////////////////// // ** Noisemove // ////////////////////// -uint16_t WS2812FX::mode_noisemove(void) { // Noisemove. By: Andrew Tuline +uint16_t mode_noisemove(void) { // Noisemove. By: Andrew Tuline uint8_t *fftResult = nullptr; um_data_t *um_data; if (usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { @@ -7261,13 +7260,13 @@ uint16_t WS2812FX::mode_noisemove(void) { // Noisemove. By: A } if (!fftResult) return mode_static(); - fade_out(224); // Just in case something doesn't get faded. + strip.fade_out(224); // Just in case something doesn't get faded. uint8_t numBins = map(SEGMENT.intensity,0,255,0,16); // Map slider to fftResult bins. for (int i=0; i> 2) +2)) & 0xFFFF; + uint16_t counter = (strip.now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF; counter = counter >> 8; const float lightFactor = 0.15f; @@ -7573,7 +7572,7 @@ uint16_t WS2812FX::mode_2DAkemi(void) { for (uint16_t y=0; y < rows; y++) for (uint16_t x=0; x < cols; x++) { CRGB color; CRGB soundColor = ORANGE; - CRGB faceColor = color_wheel(counter); + CRGB faceColor = strip.color_wheel(counter); CRGB armsAndLegsColor = SEGCOLOR(1) > 0 ? SEGCOLOR(1) : 0xFFE0A0; //default warmish white 0xABA8FF; //0xFF52e5;// uint8_t ak = pgm_read_byte_near(akemi + ((y * 32)/rows) * 32 + (x * 32)/cols); // akemi[(y * 32)/rows][(x * 32)/cols] switch (ak) { @@ -7590,10 +7589,10 @@ uint16_t WS2812FX::mode_2DAkemi(void) { } if (SEGMENT.intensity > 128 && fftResult && fftResult[0] > 128) { //dance if base is high - setPixelColorXY(x, 0, BLACK); - setPixelColorXY(x, y+1, color); + strip.setPixelColorXY(x, 0, BLACK); + strip.setPixelColorXY(x, y+1, color); } else - setPixelColorXY(x, y, color); + strip.setPixelColorXY(x, y, color); } //add geq left and right @@ -7601,11 +7600,11 @@ uint16_t WS2812FX::mode_2DAkemi(void) { for (uint16_t x=0; x < cols/8; x++) { uint16_t band = x * cols/8; uint16_t barHeight = map(fftResult[band], 0, 255, 0, 17*rows/32); - CRGB color = color_from_palette((band * 35), false, PALETTE_SOLID_WRAP, 0); + CRGB color = strip.color_from_palette((band * 35), false, PALETTE_SOLID_WRAP, 0); for (uint16_t y=0; y < barHeight; y++) { - setPixelColorXY(x, rows/2-y, color); - setPixelColorXY(cols-1-x, rows/2-y, color); + strip.setPixelColorXY(x, rows/2-y, color); + strip.setPixelColorXY(cols-1-x, rows/2-y, color); } } } @@ -7621,230 +7620,230 @@ static const char *_data_RESERVED PROGMEM = "Reserved"; void WS2812FX::setupEffectData() { // fill reserved word in case there will be any gaps in the array for (byte i=0; i> n) & 0x01); } + inline bool isSelected() { return getOption(0); } + inline bool isActive() { return stop > start; } + inline uint16_t width() { return stop - start; } + inline uint16_t height() { return stopY - startY; } + inline uint16_t length() { return width(); } + inline uint16_t groupLength() { return grouping + spacing; } + inline uint8_t getLightCapabilities() { return _capabilities; } + bool setColor(uint8_t slot, uint32_t c, uint8_t segn); //returns true if changed + void setCCT(uint16_t k, uint8_t segn); + void setOpacity(uint8_t o, uint8_t segn); + void setOption(uint8_t n, bool val, uint8_t segn = 255); + // 2D matrix + uint16_t virtualWidth(); + uint16_t virtualHeight(); + // 1D strip + uint16_t virtualLength(); + uint8_t differs(Segment& b); + void refreshLightCapabilities(); +} segment; - // pre show callback - typedef void (*show_callback) (void); + +// segment runtime parameters +typedef struct Segment_runtime { // 28 bytes + unsigned long next_time; // millis() of next update + uint32_t step; // custom "step" var + uint32_t call; // call counter + uint16_t aux0; // custom var + uint16_t aux1; // custom var + byte* data = nullptr; + + bool allocateData(uint16_t len); + void deallocateData(); + void resetIfRequired(); + /** + * Flags that before the next effect is calculated, + * the internal segment state should be reset. + * Call resetIfRequired before calling the next effect function. + * Safe to call from interrupts and network requests. + */ + inline void markForReset() { _requiresReset = true; } + private: + uint16_t _dataLen = 0; + bool _requiresReset = false; +} segment_runtime; + + +// color transitions +typedef struct ColorTransition { // 12 bytes + uint32_t colorOld = 0; + uint32_t transitionStart; + uint16_t transitionDur; + uint8_t segment = 0xFF; //lower 6 bits: the segment this transition is for (255 indicates transition not in use/available) upper 2 bits: color channel + uint8_t briOld = 0; + + static void startTransition(uint8_t oldBri, uint32_t oldCol, uint8_t segn, uint8_t slot); + uint8_t currentBri(bool turningOff = false, uint8_t slot = 0); + uint16_t progress(bool allowEnd = false); //transition progression between 0-65535 + uint32_t currentColor(uint32_t colorNew) { + return color_blend(colorOld, colorNew, progress(true), true); + } +} color_transition; + + +// main "strip" class +class WS2812FX { + typedef uint16_t (*mode_ptr)(void); // pointer to mode function + typedef void (*show_callback)(void); // pre show callback static WS2812FX* instance; public: - // segment parameters - typedef struct Segment { // 35 (36 in memory) bytes - uint16_t start; // start index / start X coordinate 2D (left) - uint16_t stop; // stop index / stop X coordinate 2D (right); segment is invalid if stop == 0 - uint16_t offset; - uint8_t speed; - uint8_t intensity; - uint8_t palette; - uint8_t mode; - uint16_t options; //bit pattern: msb first: [transposed mirrorY reverseY] transitional (tbd) paused needspixelstate mirrored on reverse selected - uint8_t grouping, spacing; - uint8_t opacity; - uint32_t colors[NUM_COLORS]; - uint8_t cct; //0==1900K, 255==10091K - uint8_t _capabilities; - uint8_t custom1, custom2, custom3; // custom FX parameters - uint16_t startY; // start Y coodrinate 2D (top) - uint16_t stopY; // stop Y coordinate 2D (bottom) - char *name; - inline bool getOption(uint8_t n) { return ((options >> n) & 0x01); } - inline bool isSelected() { return getOption(0); } - inline bool isActive() { return stop > start; } - inline uint16_t width() { return stop - start; } - inline uint16_t height() { return stopY - startY; } - inline uint16_t length() { return width(); } - inline uint16_t groupLength() { return grouping + spacing; } - inline uint8_t getLightCapabilities() { return _capabilities; } - bool setColor(uint8_t slot, uint32_t c, uint8_t segn) { //returns true if changed - if (slot >= NUM_COLORS || segn >= MAX_NUM_SEGMENTS) return false; - if (c == colors[slot]) return false; - uint8_t b = (slot == 1) ? cct : opacity; - ColorTransition::startTransition(b, colors[slot], instance->_transitionDur, segn, slot); - colors[slot] = c; return true; - } - void setCCT(uint16_t k, uint8_t segn) { - if (segn >= MAX_NUM_SEGMENTS) return; - if (k > 255) { //kelvin value, convert to 0-255 - if (k < 1900) k = 1900; - if (k > 10091) k = 10091; - k = (k - 1900) >> 5; - } - if (cct == k) return; - ColorTransition::startTransition(cct, colors[1], instance->_transitionDur, segn, 1); - cct = k; - } - void setOpacity(uint8_t o, uint8_t segn) { - if (segn >= MAX_NUM_SEGMENTS) return; - if (opacity == o) return; - ColorTransition::startTransition(opacity, colors[0], instance->_transitionDur, segn, 0); - opacity = o; - } - void setOption(uint8_t n, bool val, uint8_t segn = 255) { - bool prevOn = false; - if (n == SEG_OPTION_ON) { - prevOn = getOption(SEG_OPTION_ON); - if (!val && prevOn) { //fade off - ColorTransition::startTransition(opacity, colors[0], instance->_transitionDur, segn, 0); - } - } - if (val) options |= 0x01 << n; - else options &= ~(0x01 << n); - if (n == SEG_OPTION_ON && val && !prevOn) { //fade on - ColorTransition::startTransition(0, colors[0], instance->_transitionDur, segn, 0); - } - } - // 2D matrix - uint16_t virtualWidth() { - uint16_t groupLen = groupLength(); - uint16_t vWidth = ((getOption(SEG_OPTION_TRANSPOSED) ? height() : width()) + groupLen - 1) / groupLen; - if (getOption(SEG_OPTION_MIRROR)) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED - return vWidth; - } - uint16_t virtualHeight() { - uint16_t groupLen = groupLength(); - uint16_t vHeight = ((getOption(SEG_OPTION_TRANSPOSED) ? width() : height()) + groupLen - 1) / groupLen; - if (getOption(SEG_OPTION_MIRROR_Y)) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED - return vHeight; - } - // 1D strip - uint16_t virtualLength() { - uint16_t groupLen = groupLength(); - uint16_t vLength = (length() + groupLen - 1) / groupLen; - if (getOption(SEG_OPTION_MIRROR)) vLength = (vLength + 1) /2; // divide by 2 if mirror, leave at least a single LED - return vLength; - } - uint8_t differs(Segment& b); - void refreshLightCapabilities(); - } segment; - - // segment runtime parameters - typedef struct Segment_runtime { // 28 bytes - unsigned long next_time; // millis() of next update - uint32_t step; // custom "step" var - uint32_t call; // call counter - uint16_t aux0; // custom var - uint16_t aux1; // custom var - byte* data = nullptr; - bool allocateData(uint16_t len){ - if (data && _dataLen == len) return true; //already allocated - deallocateData(); - if (WS2812FX::instance->_usedSegmentData + len > MAX_SEGMENT_DATA) return false; //not enough memory - // if possible use SPI RAM on ESP32 - #if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM) - if (psramFound()) - data = (byte*) ps_malloc(len); - else - #endif - data = (byte*) malloc(len); - if (!data) return false; //allocation failed - WS2812FX::instance->_usedSegmentData += len; - _dataLen = len; - memset(data, 0, len); - return true; - } - void deallocateData(){ - free(data); - data = nullptr; - WS2812FX::instance->_usedSegmentData -= _dataLen; - _dataLen = 0; - } - - /** - * If reset of this segment was request, clears runtime - * settings of this segment. - * Must not be called while an effect mode function is running - * because it could access the data buffer and this method - * may free that data buffer. - */ - void resetIfRequired() { - if (_requiresReset) { - next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; - deallocateData(); - _requiresReset = false; - } - } - - /** - * Flags that before the next effect is calculated, - * the internal segment state should be reset. - * Call resetIfRequired before calling the next effect function. - * Safe to call from interrupts and network requests. - */ - inline void markForReset() { _requiresReset = true; } - private: - uint16_t _dataLen = 0; - bool _requiresReset = false; - } segment_runtime; - - typedef struct ColorTransition { // 12 bytes - uint32_t colorOld = 0; - uint32_t transitionStart; - uint16_t transitionDur; - uint8_t segment = 0xFF; //lower 6 bits: the segment this transition is for (255 indicates transition not in use/available) upper 2 bits: color channel - uint8_t briOld = 0; - static void startTransition(uint8_t oldBri, uint32_t oldCol, uint16_t dur, uint8_t segn, uint8_t slot) { - if (segn >= MAX_NUM_SEGMENTS || slot >= NUM_COLORS || dur == 0) return; - if (instance->_brightness == 0) return; //do not need transitions if master bri is off - if (!instance->_segments[segn].getOption(SEG_OPTION_ON)) return; //not if segment is off either - uint8_t tIndex = 0xFF; //none found - uint16_t tProgression = 0; - uint8_t s = segn + (slot << 6); //merge slot and segment into one byte - - for (uint8_t i = 0; i < MAX_NUM_TRANSITIONS; i++) { - uint8_t tSeg = instance->transitions[i].segment; - //see if this segment + color already has a running transition - if (tSeg == s) { - tIndex = i; break; - } - if (tSeg == 0xFF) { //free transition - tIndex = i; tProgression = 0xFFFF; - } - } - - if (tIndex == 0xFF) { //no slot found yet - for (uint8_t i = 0; i < MAX_NUM_TRANSITIONS; i++) { - //find most progressed transition to overwrite - uint16_t prog = instance->transitions[i].progress(); - if (prog > tProgression) { - tIndex = i; tProgression = prog; - } - } - } - - ColorTransition& t = instance->transitions[tIndex]; - if (t.segment == s) //this is an active transition on the same segment+color - { - bool wasTurningOff = (oldBri == 0); - t.briOld = t.currentBri(wasTurningOff, slot); - t.colorOld = t.currentColor(oldCol); - } else { - t.briOld = oldBri; - t.colorOld = oldCol; - uint8_t prevSeg = t.segment & 0x3F; - if (prevSeg < MAX_NUM_SEGMENTS) instance->_segments[prevSeg].setOption(SEG_OPTION_TRANSITIONAL, false); - } - t.transitionDur = dur; - t.transitionStart = millis(); - t.segment = s; - instance->_segments[segn].setOption(SEG_OPTION_TRANSITIONAL, true); - //refresh immediately, required for Solid mode - if (instance->_segment_runtimes[segn].next_time > t.transitionStart + 22) instance->_segment_runtimes[segn].next_time = t.transitionStart; - } - uint16_t progress(bool allowEnd = false) { //transition progression between 0-65535 - uint32_t timeNow = millis(); - if (timeNow - transitionStart > transitionDur) { - if (allowEnd) { - uint8_t segn = segment & 0x3F; - if (segn < MAX_NUM_SEGMENTS) instance->_segments[segn].setOption(SEG_OPTION_TRANSITIONAL, false); - segment = 0xFF; - } - return 0xFFFF; - } - uint32_t elapsed = timeNow - transitionStart; - uint32_t prog = elapsed * 0xFFFF / transitionDur; - return (prog > 0xFFFF) ? 0xFFFF : prog; - } - uint32_t currentColor(uint32_t colorNew) { - return instance->color_blend(colorOld, colorNew, progress(true), true); - } - uint8_t currentBri(bool turningOff = false, uint8_t slot = 0) { - uint8_t segn = segment & 0x3F; - if (segn >= MAX_NUM_SEGMENTS) return 0; - uint8_t briNew = instance->_segments[segn].opacity; - if (slot == 0) { - if (!instance->_segments[segn].getOption(SEG_OPTION_ON) || turningOff) briNew = 0; - } else { //transition slot 1 brightness for CCT transition - briNew = instance->_segments[segn].cct; - } - uint32_t prog = progress() + 1; - return ((briNew * prog) + (briOld * (0x10000 - prog))) >> 16; - } - } color_transition; - WS2812FX() { WS2812FX::instance = this; setupEffectData(); @@ -614,6 +471,8 @@ class WS2812FX { resetSegments(); } + static WS2812FX* getInstance(void) { return instance; } + void finalizeInit(), service(void), @@ -627,11 +486,8 @@ class WS2812FX { setCCT(uint16_t k), setBrightness(uint8_t b, bool direct = false), setRange(uint16_t i, uint16_t i2, uint32_t col), - setShowCallback(show_callback cb), - setTransition(uint16_t t), setTransitionMode(bool t), calcGammaTable(float), - trigger(void), setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 0, uint8_t spacing = 0, uint16_t offset = UINT16_MAX, uint16_t startY=0, uint16_t stopY=0), setMainSegmentId(uint8_t n), restartRuntime(), @@ -640,6 +496,7 @@ class WS2812FX { fixInvalidSegments(), setPixelColor(int n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = false), + blendPixelColor(uint16_t n, uint32_t color, uint8_t blend), show(void), setTargetFps(uint8_t fps), deserializeMap(uint8_t n=0); @@ -652,6 +509,9 @@ class WS2812FX { inline void setPixelColor(int n, CRGB c) {setPixelColor(n, c.red, c.green, c.blue);} inline void setPixelColor(float i, uint32_t c, bool aa=true) {setPixelColor(i, byte(c>>16), byte(c>>8), byte(c), byte(c>>24), aa);} inline void setPixelColor(float i, CRGB c, bool aa=true) {setPixelColor(i, c.red, c.green, c.blue, 0, aa);} + inline void trigger(void) { _triggered = true; } // Forces the next frame to be computed on all active segments. + inline void setShowCallback(show_callback cb) { _callback = cb; } + inline void setTransition(uint16_t t) { _transitionDur = t; } bool gammaCorrectBri = false, @@ -662,24 +522,28 @@ class WS2812FX { // return true if the strip is being sent pixel updates isUpdating(void); + inline bool hasWhiteChannel(void) {return _hasWhiteChannel;} + inline bool isOffRefreshRequired(void) {return _isOffRefreshRequired;} + uint8_t paletteFade = 0, paletteBlend = 0, milliampsPerLed = 55, cctBlending = 0, - getBrightness(void), - getPaletteCount(void), - getMaxSegments(void), getActiveSegmentsNum(void), getFirstSelectedSegId(void), - getMainSegmentId(void), getLastActiveSegmentId(void), - getTargetFps(void), setPixelSegment(uint8_t n), gamma8(uint8_t), gamma8_cal(uint8_t, float), get_random_wheel_index(uint8_t); + inline uint8_t getBrightness(void) { return _brightness; } + inline uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; } + inline uint8_t getCurrSegmentId(void) { return _segment_index; } + inline uint8_t getMainSegmentId(void) { return _mainSegment; } + inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } + inline uint8_t getTargetFps() { return _targetFps; } inline uint8_t getModeCount() { return _modeCount; } inline uint8_t sin_gap(uint16_t in) { if (in & 0x100) return 0; @@ -693,165 +557,39 @@ class WS2812FX { ablMilliampsMax, currentMilliamps, triwave16(uint16_t), - getLengthTotal(void), getLengthPhysical(void), getFps(); - inline uint16_t getMinShowDelay() { return MIN_SHOW_DELAY; } + inline uint16_t getFrameTime(void) { return _frametime; } + inline uint16_t getMinShowDelay(void) { return MIN_SHOW_DELAY; } + inline uint16_t getLengthTotal(void) { return _length; } + inline uint16_t segLen(void) { return _virtualSegmentLength; } uint32_t now, timebase, color_wheel(uint8_t), color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255), - color_blend(uint32_t,uint32_t,uint16_t,bool b16=false), - color_add(uint32_t,uint32_t), currentColor(uint32_t colorNew, uint8_t tNr), gamma32(uint32_t), - getLastShow(void), getPixelColor(uint16_t); + inline uint32_t getLastShow(void) { return _lastShow; } + inline uint32_t segColor(uint8_t i) { return _colors_t[i]; } + const char * getModeData(uint8_t id = 0) { return id<_modeCount ? _modeData[id] : nullptr; } const char ** getModeDataSrc(void) { return _modeData; } - WS2812FX::Segment - &getSegment(uint8_t n), - &getFirstSelectedSeg(void), - &getMainSegment(void); + inline Segment& getSegment(uint8_t id) { return _segments[id >= MAX_NUM_SEGMENTS ? getMainSegmentId() : id]; } + inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; } + inline Segment& getMainSegment(void) { return _segments[getMainSegmentId()]; } + inline Segment* getSegments(void) { return _segments; } + inline Segment_runtime& getSegmentRuntime(uint8_t id) { return _segment_runtimes[id >= MAX_NUM_SEGMENTS ? getMainSegmentId() : id]; } - WS2812FX::Segment* - getSegments(void); - - // builtin modes - uint16_t - mode_static(void), - mode_blink(void), - mode_blink_rainbow(void), - mode_strobe(void), - mode_strobe_rainbow(void), - mode_color_wipe(void), - mode_color_sweep(void), - mode_color_wipe_random(void), - mode_color_sweep_random(void), - mode_random_color(void), - mode_dynamic(void), - mode_breath(void), - mode_fade(void), - mode_scan(void), - mode_dual_scan(void), - mode_theater_chase(void), - mode_theater_chase_rainbow(void), - mode_rainbow(void), - mode_rainbow_cycle(void), - mode_running_lights(void), - mode_saw(void), - mode_twinkle(void), - mode_dissolve(void), - mode_dissolve_random(void), - mode_sparkle(void), - mode_flash_sparkle(void), - mode_hyper_sparkle(void), - mode_multi_strobe(void), - mode_android(void), - mode_chase_color(void), - mode_chase_random(void), - mode_chase_rainbow(void), - mode_chase_flash(void), - mode_chase_flash_random(void), - mode_chase_rainbow_white(void), - mode_colorful(void), - mode_traffic_light(void), - mode_running_color(void), - mode_aurora(void), - mode_running_random(void), - mode_larson_scanner(void), - mode_comet(void), - mode_fireworks(void), - mode_rain(void), - mode_tetrix(void), - mode_halloween(void), - mode_fire_flicker(void), - mode_gradient(void), - mode_loading(void), - mode_police(void), - mode_fairy(void), - mode_two_dots(void), - mode_fairytwinkle(void), - mode_running_dual(void), - mode_bicolor_chase(void), - mode_tricolor_chase(void), - mode_tricolor_wipe(void), - mode_tricolor_fade(void), - mode_lightning(void), - mode_icu(void), - mode_multi_comet(void), - mode_dual_larson_scanner(void), - mode_random_chase(void), - mode_oscillate(void), - mode_fire_2012(void), - mode_pride_2015(void), - mode_bpm(void), - mode_juggle(void), - mode_palette(void), - mode_colorwaves(void), - mode_fillnoise8(void), - mode_noise16_1(void), - mode_noise16_2(void), - mode_noise16_3(void), - mode_noise16_4(void), - mode_colortwinkle(void), - mode_lake(void), - mode_meteor(void), - mode_meteor_smooth(void), - mode_railway(void), - mode_ripple(void), - mode_twinklefox(void), - mode_twinklecat(void), - mode_halloween_eyes(void), - mode_static_pattern(void), - mode_tri_static_pattern(void), - mode_spots(void), - mode_spots_fade(void), - mode_glitter(void), - mode_candle(void), - mode_starburst(void), - mode_exploding_fireworks(void), - mode_bouncing_balls(void), - mode_sinelon(void), - mode_sinelon_dual(void), - mode_sinelon_rainbow(void), - mode_popcorn(void), - mode_drip(void), - mode_plasma(void), - mode_percent(void), - mode_ripple_rainbow(void), - mode_heartbeat(void), - mode_pacifica(void), - mode_candle_multi(void), - mode_solid_glitter(void), - mode_sunrise(void), - mode_phased(void), - mode_twinkleup(void), - mode_noisepal(void), - mode_sinewave(void), - mode_phased_noise(void), - mode_flow(void), - mode_chunchun(void), - mode_dancing_shadows(void), - mode_washing_machine(void), - mode_candy_cane(void), - mode_blends(void), - mode_tv_simulator(void), - mode_dynamic_smooth(void), - // non-audio transfered from WLED-SR - mode_perlinmove(void), - mode_wavesins(void), - mode_FlowStripe(void); - -// 2D support (panels) + // 2D support (panels) bool isMatrix = false; @@ -915,119 +653,12 @@ class WS2812FX { uint32_t getPixelColorXY(uint16_t, uint16_t); -// end 2D support + // end 2D support - // 2D modes - uint16_t - mode_2Dspaceships(void), - mode_2Dcrazybees(void), - mode_2Dghostrider(void), - mode_2Dfloatingblobs(void), - mode_2Dscrollingtext(void), - mode_2Ddriftrose(void); - - // WLED-SR modes -#ifndef USERMOD_AUDIOREACTIVE - uint16_t - mode_2Dnoise(void), - mode_2Dfirenoise(void), - mode_2Dsquaredswirl(void), - mode_2Ddna(void), - mode_2Dmatrix(void), - mode_2Dmetaballs(void), - mode_2DPulser(void), - mode_2Dgameoflife(void), - mode_2Dtartan(void), - mode_2DPolarLights(void), - mode_2DSwirl(void), - mode_2DLissajous(void), - mode_2DFrizzles(void), - mode_2DPlasmaball(void), - mode_2DHiphotic(void), - mode_2DSindots(void), - mode_2DDNASpiral(void), - mode_2DBlackHole(void), - mode_2DSunradiation(void), - mode_2DWaverly(void), - mode_2DDrift(void), - mode_2DColoredBursts(void), - mode_2DJulia(void), - mode_gravimeter(void), - mode_gravcenter(void), - mode_gravcentric(void), - mode_juggles(void), - mode_matripix(void), - mode_midnoise(void), - mode_noisemeter(void), - mode_noisefire(void), - mode_pixelwave(void), - mode_plasmoid(void), - mode_puddles(void), - mode_puddlepeak(void), - mode_ripplepeak(void), - mode_2DAkemi(void); -#else - uint16_t - mode_pixels(void), - mode_pixelwave(void), - mode_juggles(void), - mode_matripix(void), - mode_gravimeter(void), - mode_plasmoid(void), - mode_puddles(void), - mode_midnoise(void), - mode_noisemeter(void), - mode_freqwave(void), - mode_freqmatrix(void), - mode_2DGEQ(void), - mode_waterfall(void), - mode_freqpixels(void), - mode_binmap(void), - mode_noisefire(void), - mode_puddlepeak(void), - mode_noisemove(void), - mode_2Dnoise(void), - mode_ripplepeak(void), - mode_2Dfirenoise(void), - mode_2Dsquaredswirl(void), - mode_2Ddna(void), - mode_2Dmatrix(void), - mode_2Dmetaballs(void), - mode_freqmap(void), - mode_gravcenter(void), - mode_gravcentric(void), - mode_gravfreq(void), - mode_DJLight(void), - mode_2DFunkyPlank(void), - mode_2DPulser(void), - mode_blurz(void), - mode_2Dgameoflife(void), - mode_2Dtartan(void), - mode_2DPolarLights(void), - mode_2DSwirl(void), - mode_2DLissajous(void), - mode_2DFrizzles(void), - mode_2DPlasmaball(void), - mode_2DHiphotic(void), - mode_2DSindots(void), - mode_2DDNASpiral(void), - mode_2DBlackHole(void), - mode_rocktaves(void), - mode_2DAkemi(void), - mode_2DSunradiation(void), - mode_2DWaverly(void), - mode_2DDrift(void), - mode_2DColoredBursts(void), - mode_2DJulia(void), - mode_customEffect(void); //WLEDSR Custom Effects -#endif - - private: - uint32_t crgb_to_col(CRGB fastled); - CRGB col_to_crgb(uint32_t); CRGBPalette16 currentPalette; CRGBPalette16 targetPalette; + private: uint16_t _length, _virtualSegmentLength; uint16_t _rand16seed; uint8_t _brightness; @@ -1050,38 +681,6 @@ class WS2812FX { show_callback _callback = nullptr; - // mode helper functions - uint16_t - blink(uint32_t, uint32_t, bool strobe, bool), - candle(bool), - color_wipe(bool, bool), - dynamic(bool), - scan(bool), - fireworks_base(CRGB*), - running_base(bool,bool), - larson_scanner(bool), - sinelon_base(bool,bool), - dissolve(uint32_t), - chase(uint32_t, uint32_t, uint32_t, bool), - gradient_base(bool), - ripple_base(bool), - police_base(uint32_t, uint32_t), - running(uint32_t, uint32_t, bool theatre=false), - tricolor_chase(uint32_t, uint32_t), - twinklefox_base(bool), - spots_base(uint16_t), - phased_base(uint8_t); - - CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat); - CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff); - - void - blendPixelColor(uint16_t n, uint32_t color, uint8_t blend), - startTransition(uint8_t oldBri, uint32_t oldCol, uint16_t dur, uint8_t segn, uint8_t slot), - estimateCurrentAndLimitBri(void), - load_gradient_palette(uint8_t), - handle_palette(void); - uint16_t* customMappingTable = nullptr; uint16_t customMappingSize = 0; @@ -1100,18 +699,21 @@ class WS2812FX { // start, stop, offset, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[], capabilities, custom 1, custom 2, custom 3 {0, 7, 0, DEFAULT_SPEED, DEFAULT_INTENSITY, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}, 0, DEFAULT_C1, DEFAULT_C2, DEFAULT_C3, 0, 1} }; + friend class Segment; + segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element friend class Segment_runtime; ColorTransition transitions[MAX_NUM_TRANSITIONS]; //12 bytes per element friend class ColorTransition; + void + estimateCurrentAndLimitBri(void), + load_gradient_palette(uint8_t), + handle_palette(void); + uint16_t transitionProgress(uint8_t tNr); - - public: - inline bool hasWhiteChannel(void) {return _hasWhiteChannel;} - inline bool isOffRefreshRequired(void) {return _isOffRefreshRequired;} }; extern const char JSON_mode_names[]; diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 72aa875c..b592fa86 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -110,15 +110,6 @@ void WS2812FX::setUpMatrix() { uint16_t IRAM_ATTR WS2812FX::XY(uint16_t x, uint16_t y) { uint16_t width = SEGMENT.virtualWidth(); // segment width in logical pixels uint16_t height = SEGMENT.virtualHeight(); // segment height in logical pixels -/* - if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) { - uint16_t t; - // swap X & Y if segment transposed - t = x; x = y; y = t; - // swap width & height if segment transposed - t = width; width = height; height = t; - } -*/ return (x%width) + (y%height) * width; } @@ -294,13 +285,13 @@ void WS2812FX::blurRow(uint16_t row, fract8 blur_amount, CRGB* leds) { uint8_t seep = blur_amount >> 1; CRGB carryover = CRGB::Black; for (uint16_t x = 0; x < cols; x++) { - CRGB cur = leds ? leds[XY(x,row)] : col_to_crgb(getPixelColorXY(x, row)); + CRGB cur = leds ? leds[XY(x,row)] : CRGB(getPixelColorXY(x, row)); CRGB part = cur; part.nscale8(seep); cur.nscale8(keep); cur += carryover; if (x) { - CRGB prev = (leds ? leds[XY(x-1,row)] : col_to_crgb(getPixelColorXY(x-1, row))) + part; + CRGB prev = (leds ? leds[XY(x-1,row)] : CRGB(getPixelColorXY(x-1, row))) + part; if (leds) leds[XY(x-1,row)] = prev; else setPixelColorXY(x-1, row, prev); } @@ -321,13 +312,13 @@ void WS2812FX::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) { uint8_t seep = blur_amount >> 1; CRGB carryover = CRGB::Black; for (uint16_t i = 0; i < rows; i++) { - CRGB cur = leds ? leds[XY(col,i)] : col_to_crgb(getPixelColorXY(col, i)); + CRGB cur = leds ? leds[XY(col,i)] : CRGB(getPixelColorXY(col, i)); CRGB part = cur; part.nscale8(seep); cur.nscale8(keep); cur += carryover; if (i) { - CRGB prev = (leds ? leds[XY(col,i-1)] : col_to_crgb(getPixelColorXY(col, i-1))) + part; + CRGB prev = (leds ? leds[XY(col,i-1)] : CRGB(getPixelColorXY(col, i-1))) + part; if (leds) leds[XY(col,i-1)] = prev; else setPixelColorXY(col, i-1, prev); } @@ -374,9 +365,9 @@ void WS2812FX::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds) uint16_t yp = vertical ? y-1 : y; uint16_t xn = vertical ? x : x+1; uint16_t yn = vertical ? y+1 : y; - CRGB curr = leds ? leds[XY(x,y)] : col_to_crgb(getPixelColorXY(x,y)); - CRGB prev = (xp<0 || yp<0) ? CRGB::Black : (leds ? leds[XY(xp,yp)] : col_to_crgb(getPixelColorXY(xp,yp))); - CRGB next = ((vertical && yn>=dim1) || (!vertical && xn>=dim1)) ? CRGB::Black : (leds ? leds[XY(xn,yn)] : col_to_crgb(getPixelColorXY(xn,yn))); + CRGB curr = leds ? leds[XY(x,y)] : CRGB(getPixelColorXY(x,y)); + CRGB prev = (xp<0 || yp<0) ? CRGB::Black : (leds ? leds[XY(xp,yp)] : CRGB(getPixelColorXY(xp,yp))); + CRGB next = ((vertical && yn>=dim1) || (!vertical && xn>=dim1)) ? CRGB::Black : (leds ? leds[XY(xn,yn)] : CRGB(getPixelColorXY(xn,yn))); uint16_t r, g, b; r = (curr.r*keep + (prev.r + next.r)*seep) / 3; g = (curr.g*keep + (prev.g + next.g)*seep) / 3; @@ -491,7 +482,7 @@ void WS2812FX::nscale8(CRGB* leds, uint8_t scale) { const uint16_t rows = SEGMENT.virtualHeight(); for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { if (leds) leds[XY(x,y)].nscale8(scale); - else setPixelColorXY(x, y, col_to_crgb(getPixelColorXY(x, y)).nscale8(scale)); + else setPixelColorXY(x, y, CRGB(getPixelColorXY(x, y)).nscale8(scale)); } } diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 31761cc9..be9aaa7b 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -69,6 +69,253 @@ #error "Max segments must be at least max number of busses!" #endif + +bool Segment::setColor(uint8_t slot, uint32_t c, uint8_t segn) { //returns true if changed + if (slot >= NUM_COLORS || segn >= MAX_NUM_SEGMENTS) return false; + if (c == colors[slot]) return false; + uint8_t b = (slot == 1) ? cct : opacity; + ColorTransition::startTransition(b, colors[slot], segn, slot); + colors[slot] = c; return true; +} + +void Segment::setCCT(uint16_t k, uint8_t segn) { + if (segn >= MAX_NUM_SEGMENTS) return; + if (k > 255) { //kelvin value, convert to 0-255 + if (k < 1900) k = 1900; + if (k > 10091) k = 10091; + k = (k - 1900) >> 5; + } + if (cct == k) return; + ColorTransition::startTransition(cct, colors[1], segn, 1); + cct = k; +} + +void Segment::setOpacity(uint8_t o, uint8_t segn) { + if (segn >= MAX_NUM_SEGMENTS) return; + if (opacity == o) return; + ColorTransition::startTransition(opacity, colors[0], segn, 0); + opacity = o; +} + +void Segment::setOption(uint8_t n, bool val, uint8_t segn) { + bool prevOn = false; + if (n == SEG_OPTION_ON) { + prevOn = getOption(SEG_OPTION_ON); + if (!val && prevOn) { //fade off + ColorTransition::startTransition(opacity, colors[0], segn, 0); + } + } + if (val) options |= 0x01 << n; + else options &= ~(0x01 << n); + if (n == SEG_OPTION_ON && val && !prevOn) { //fade on + ColorTransition::startTransition(0, colors[0], segn, 0); + } +} + +// 2D matrix +uint16_t Segment::virtualWidth() { + uint16_t groupLen = groupLength(); + uint16_t vWidth = ((getOption(SEG_OPTION_TRANSPOSED) ? height() : width()) + groupLen - 1) / groupLen; + if (getOption(SEG_OPTION_MIRROR)) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED + return vWidth; +} + +uint16_t Segment::virtualHeight() { + uint16_t groupLen = groupLength(); + uint16_t vHeight = ((getOption(SEG_OPTION_TRANSPOSED) ? width() : height()) + groupLen - 1) / groupLen; + if (getOption(SEG_OPTION_MIRROR_Y)) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED + return vHeight; +} + +// 1D strip +uint16_t Segment::virtualLength() { + uint16_t groupLen = groupLength(); + uint16_t vLength = (length() + groupLen - 1) / groupLen; + if (getOption(SEG_OPTION_MIRROR)) vLength = (vLength + 1) /2; // divide by 2 if mirror, leave at least a single LED + return vLength; +} + +uint8_t Segment::differs(Segment& b) { + uint8_t d = 0; + if (start != b.start) d |= SEG_DIFFERS_BOUNDS; + if (stop != b.stop) d |= SEG_DIFFERS_BOUNDS; + if (offset != b.offset) d |= SEG_DIFFERS_GSO; + if (grouping != b.grouping) d |= SEG_DIFFERS_GSO; + if (spacing != b.spacing) d |= SEG_DIFFERS_GSO; + if (opacity != b.opacity) d |= SEG_DIFFERS_BRI; + if (mode != b.mode) d |= SEG_DIFFERS_FX; + if (speed != b.speed) d |= SEG_DIFFERS_FX; + if (intensity != b.intensity) d |= SEG_DIFFERS_FX; + if (palette != b.palette) d |= SEG_DIFFERS_FX; + if (custom1 != b.custom1) d |= SEG_DIFFERS_FX; + if (custom2 != b.custom2) d |= SEG_DIFFERS_FX; + if (custom3 != b.custom3) d |= SEG_DIFFERS_FX; + if (startY != b.startY) d |= SEG_DIFFERS_BOUNDS; + if (stopY != b.stopY) d |= SEG_DIFFERS_BOUNDS; + + //bit pattern: msb first: [transposed mirrorY reverseY] transitional (tbd) paused needspixelstate mirrored on reverse selected + if ((options & 0b11100101110) != (b.options & 0b11100101110)) d |= SEG_DIFFERS_OPT; + if ((options & 0x01) != (b.options & 0x01)) d |= SEG_DIFFERS_SEL; + + for (uint8_t i = 0; i < NUM_COLORS; i++) if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL; + + return d; +} + +void Segment::refreshLightCapabilities() { + if (!isActive()) { + _capabilities = 0; return; + } + uint8_t capabilities = 0; + + for (uint8_t b = 0; b < busses.getNumBusses(); b++) { + Bus *bus = busses.getBus(b); + if (bus == nullptr || bus->getLength()==0) break; + if (!bus->isOk()) continue; + if (bus->getStart() >= stop) continue; + if (bus->getStart() + bus->getLength() <= start) continue; + + uint8_t type = bus->getType(); + if (type != TYPE_ANALOG_1CH && (cctFromRgb || type != TYPE_ANALOG_2CH)) capabilities |= 0x01; // segment supports RGB (full color) + if (bus->isRgbw()) capabilities |= 0x02; // segment supports white channel + if (!cctFromRgb) { + switch (type) { + case TYPE_ANALOG_5CH: + case TYPE_ANALOG_2CH: + capabilities |= 0x04; //segment supports white CCT + } + } + if (correctWB && type != TYPE_ANALOG_1CH) capabilities |= 0x04; //white balance correction (uses CCT slider) + uint8_t aWM = Bus::getAutoWhiteMode()<255 ? Bus::getAutoWhiteMode() : bus->getAWMode(); + bool whiteSlider = (aWM == RGBW_MODE_DUAL || aWM == RGBW_MODE_MANUAL_ONLY); // white slider allowed + if (bus->isRgbw() && (whiteSlider || !(capabilities & 0x01))) capabilities |= 0x08; // allow white channel adjustments (AWM allows or is not RGB) + } + _capabilities = capabilities; +} + + +bool Segment_runtime::allocateData(uint16_t len){ + if (data && _dataLen == len) return true; //already allocated + WS2812FX *instance = WS2812FX::getInstance(); + deallocateData(); + if (instance->_usedSegmentData + len > MAX_SEGMENT_DATA) return false; //not enough memory + // if possible use SPI RAM on ESP32 + #if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM) + if (psramFound()) + data = (byte*) ps_malloc(len); + else + #endif + data = (byte*) malloc(len); + if (!data) return false; //allocation failed + instance->_usedSegmentData += len; + _dataLen = len; + memset(data, 0, len); + return true; +} + +void Segment_runtime::deallocateData(){ + free(data); + data = nullptr; + WS2812FX::getInstance()->_usedSegmentData -= _dataLen; + _dataLen = 0; +} + +/** + * If reset of this segment was request, clears runtime + * settings of this segment. + * Must not be called while an effect mode function is running + * because it could access the data buffer and this method + * may free that data buffer. + */ +void Segment_runtime::resetIfRequired() { + if (_requiresReset) { + next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; + deallocateData(); + _requiresReset = false; + } +} + +void ColorTransition::startTransition(uint8_t oldBri, uint32_t oldCol, uint8_t segn, uint8_t slot) { + WS2812FX *instance = WS2812FX::getInstance(); + if (segn >= MAX_NUM_SEGMENTS || slot >= NUM_COLORS || instance->_transitionDur == 0) return; + if (instance->_brightness == 0) return; //do not need transitions if master bri is off + if (!instance->_segments[segn].getOption(SEG_OPTION_ON)) return; //not if segment is off either + uint8_t tIndex = 0xFF; //none found + uint16_t tProgression = 0; + uint8_t s = segn + (slot << 6); //merge slot and segment into one byte + + for (uint8_t i = 0; i < MAX_NUM_TRANSITIONS; i++) { + uint8_t tSeg = instance->transitions[i].segment; + //see if this segment + color already has a running transition + if (tSeg == s) { + tIndex = i; break; + } + if (tSeg == 0xFF) { //free transition + tIndex = i; tProgression = 0xFFFF; + } + } + + if (tIndex == 0xFF) { //no slot found yet + for (uint8_t i = 0; i < MAX_NUM_TRANSITIONS; i++) { + //find most progressed transition to overwrite + uint16_t prog = instance->transitions[i].progress(); + if (prog > tProgression) { + tIndex = i; tProgression = prog; + } + } + } + + ColorTransition& t = instance->transitions[tIndex]; + if (t.segment == s) //this is an active transition on the same segment+color + { + bool wasTurningOff = (oldBri == 0); + t.briOld = t.currentBri(wasTurningOff, slot); + t.colorOld = t.currentColor(oldCol); + } else { + t.briOld = oldBri; + t.colorOld = oldCol; + uint8_t prevSeg = t.segment & 0x3F; + if (prevSeg < MAX_NUM_SEGMENTS) instance->_segments[prevSeg].setOption(SEG_OPTION_TRANSITIONAL, false); + } + t.transitionDur = instance->_transitionDur; + t.transitionStart = millis(); + t.segment = s; + instance->_segments[segn].setOption(SEG_OPTION_TRANSITIONAL, true); + //refresh immediately, required for Solid mode + if (instance->_segment_runtimes[segn].next_time > t.transitionStart + 22) instance->_segment_runtimes[segn].next_time = t.transitionStart; +} + +uint16_t ColorTransition::progress(bool allowEnd) { //transition progression between 0-65535 + WS2812FX *instance = WS2812FX::getInstance(); + uint32_t timeNow = millis(); + if (timeNow - transitionStart > transitionDur) { + if (allowEnd) { + uint8_t segn = segment & 0x3F; + if (segn < MAX_NUM_SEGMENTS) instance->_segments[segn].setOption(SEG_OPTION_TRANSITIONAL, false); + segment = 0xFF; + } + return 0xFFFF; + } + uint32_t elapsed = timeNow - transitionStart; + uint32_t prog = elapsed * 0xFFFF / transitionDur; + return (prog > 0xFFFF) ? 0xFFFF : prog; +} + +uint8_t ColorTransition::currentBri(bool turningOff, uint8_t slot) { + WS2812FX *instance = WS2812FX::getInstance(); + uint8_t segn = segment & 0x3F; + if (segn >= MAX_NUM_SEGMENTS) return 0; + uint8_t briNew = instance->_segments[segn].opacity; + if (slot == 0) { + if (!instance->_segments[segn].getOption(SEG_OPTION_ON) || turningOff) briNew = 0; + } else { //transition slot 1 brightness for CCT transition + briNew = instance->_segments[segn].cct; + } + uint32_t prog = progress() + 1; + return ((briNew * prog) + (briOld * (0x10000 - prog))) >> 16; +} + + //do not call this method from system context (network callback) void WS2812FX::finalizeInit(void) { @@ -149,8 +396,11 @@ void WS2812FX::service() { uint16_t delay = FRAMETIME; if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen - SEGLEN = SEGMENT.virtualLength(); - _bri_t = SEGMENT.opacity; _colors_t[0] = SEGMENT.colors[0]; _colors_t[1] = SEGMENT.colors[1]; _colors_t[2] = SEGMENT.colors[2]; + _virtualSegmentLength = SEGMENT.virtualLength(); + _bri_t = SEGMENT.opacity; + _colors_t[0] = SEGMENT.colors[0]; + _colors_t[1] = SEGMENT.colors[1]; + _colors_t[2] = SEGMENT.colors[2]; uint8_t _cct_t = SEGMENT.cct; if (!SEGMENT.getOption(SEG_OPTION_ON)) _bri_t = 0; for (uint8_t t = 0; t < MAX_NUM_TRANSITIONS; t++) { @@ -166,14 +416,14 @@ void WS2812FX::service() { } handle_palette(); - delay = (this->*_mode[SEGMENT.mode])(); // effect function (NOTE: may add SEGMENT and SEGENV to parameters) + delay = (*_mode[SEGMENT.mode])(); if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++; } SEGENV.next_time = nowUp + delay; } } - SEGLEN = 0; + _virtualSegmentLength = 0; busses.setSegmentCCT(-1); if(doShow) { yield(); @@ -187,7 +437,7 @@ void /*IRAM_ATTR*/ WS2812FX::setPixelColor(float i, byte r, byte g, byte b, byte { if (i<0.0f || i>1.0f) return; // not normalized - float fC = i * (SEGLEN-1); + float fC = i * (_virtualSegmentLength-1); if (aa) { uint16_t iL = roundf(fC-0.49f); uint16_t iR = roundf(fC+0.49f); @@ -213,8 +463,8 @@ void /*IRAM_ATTR*/ WS2812FX::setPixelColor(float i, byte r, byte g, byte b, byte void IRAM_ATTR WS2812FX::setPixelColor(int i, byte r, byte g, byte b, byte w) { - uint8_t segIdx = SEGLEN ? _segment_index : _mainSegment; - if (isMatrix && SEGLEN) { + uint8_t segIdx = _virtualSegmentLength ? _segment_index : _mainSegment; + if (isMatrix && _virtualSegmentLength) { // map linear pixel into 2D segment area (even for 1D segments, expanding vertically) uint16_t h = _segments[segIdx].virtualHeight(); // segment height in logical pixels for (uint16_t y = 0; y < h; y++) { // expand 1D effect vertically @@ -223,9 +473,9 @@ void IRAM_ATTR WS2812FX::setPixelColor(int i, byte r, byte g, byte b, byte w) return; } - if (SEGLEN || (realtimeMode && useMainSegmentOnly)) { + if (_virtualSegmentLength || (realtimeMode && useMainSegmentOnly)) { //color_blend(getpixel, col, _bri_t); (pseudocode for future blending of segments) - if (SEGLEN && _bri_t < 255) { // SEGLEN!=0 -> from segment/FX + if (_virtualSegmentLength && _bri_t < 255) { // _virtualSegmentLength!=0 -> from segment/FX r = scale8(r, _bri_t); g = scale8(g, _bri_t); b = scale8(b, _bri_t); @@ -392,22 +642,11 @@ uint16_t WS2812FX::getFps() { return _cumulativeFps +1; } -uint8_t WS2812FX::getTargetFps() { - return _targetFps; -} - void WS2812FX::setTargetFps(uint8_t fps) { if (fps > 0 && fps <= 120) _targetFps = fps; _frametime = 1000 / _targetFps; } -/** - * Forces the next frame to be computed on all active segments. - */ -void WS2812FX::trigger() { - _triggered = true; -} - void WS2812FX::setMode(uint8_t segid, uint8_t m) { if (segid >= MAX_NUM_SEGMENTS) return; @@ -420,11 +659,6 @@ void WS2812FX::setMode(uint8_t segid, uint8_t m) { } } -uint8_t WS2812FX::getPaletteCount() -{ - return 13 + GRADIENT_PALETTE_COUNT; -} - //applies to all active and selected segments void WS2812FX::setColor(uint8_t slot, uint32_t c) { if (slot >= NUM_COLORS) return; @@ -465,14 +699,6 @@ void WS2812FX::setBrightness(uint8_t b, bool direct) { } } -uint8_t WS2812FX::getBrightness(void) { - return _brightness; -} - -uint8_t WS2812FX::getMaxSegments(void) { - return MAX_NUM_SEGMENTS; -} - uint8_t WS2812FX::getFirstSelectedSegId(void) { for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) @@ -499,10 +725,6 @@ void WS2812FX::setMainSegmentId(uint8_t n) { return; } -uint8_t WS2812FX::getMainSegmentId(void) { - return _mainSegment; -} - uint8_t WS2812FX::getLastActiveSegmentId(void) { for (uint8_t i = MAX_NUM_SEGMENTS -1; i > 0; i--) { if (_segments[i].isActive()) return i; @@ -532,7 +754,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) //} i += SEGMENT.start; - if (SEGLEN) { + if (_virtualSegmentLength) { /* offset/phase */ i += SEGMENT.offset; if (i >= SEGMENT.stop) i -= SEGMENT.length(); @@ -544,31 +766,6 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) return busses.getPixelColor(i); } -WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) { - if (id >= MAX_NUM_SEGMENTS) return _segments[getMainSegmentId()]; - return _segments[id]; -} - -WS2812FX::Segment& WS2812FX::getFirstSelectedSeg(void) { - return _segments[getFirstSelectedSegId()]; -} - -WS2812FX::Segment& WS2812FX::getMainSegment(void) { - return _segments[getMainSegmentId()]; -} - -WS2812FX::Segment* WS2812FX::getSegments(void) { - return _segments; -} - -uint32_t WS2812FX::getLastShow(void) { - return _lastShow; -} - -uint16_t WS2812FX::getLengthTotal(void) { - return _length; -} - uint16_t WS2812FX::getLengthPhysical(void) { uint16_t len = 0; for (uint8_t b = 0; b < busses.getNumBusses(); b++) { @@ -579,64 +776,6 @@ uint16_t WS2812FX::getLengthPhysical(void) { return len; } -uint8_t WS2812FX::Segment::differs(Segment& b) { - uint8_t d = 0; - if (start != b.start) d |= SEG_DIFFERS_BOUNDS; - if (stop != b.stop) d |= SEG_DIFFERS_BOUNDS; - if (offset != b.offset) d |= SEG_DIFFERS_GSO; - if (grouping != b.grouping) d |= SEG_DIFFERS_GSO; - if (spacing != b.spacing) d |= SEG_DIFFERS_GSO; - if (opacity != b.opacity) d |= SEG_DIFFERS_BRI; - if (mode != b.mode) d |= SEG_DIFFERS_FX; - if (speed != b.speed) d |= SEG_DIFFERS_FX; - if (intensity != b.intensity) d |= SEG_DIFFERS_FX; - if (palette != b.palette) d |= SEG_DIFFERS_FX; - if (custom1 != b.custom1) d |= SEG_DIFFERS_FX; - if (custom2 != b.custom2) d |= SEG_DIFFERS_FX; - if (custom3 != b.custom3) d |= SEG_DIFFERS_FX; - if (startY != b.startY) d |= SEG_DIFFERS_BOUNDS; - if (stopY != b.stopY) d |= SEG_DIFFERS_BOUNDS; - - //bit pattern: msb first: [transposed mirrorY reverseY] transitional (tbd) paused needspixelstate mirrored on reverse selected - if ((options & 0b11100101110) != (b.options & 0b11100101110)) d |= SEG_DIFFERS_OPT; - if ((options & 0x01) != (b.options & 0x01)) d |= SEG_DIFFERS_SEL; - - for (uint8_t i = 0; i < NUM_COLORS; i++) if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL; - - return d; -} - -void WS2812FX::Segment::refreshLightCapabilities() { - if (!isActive()) { - _capabilities = 0; return; - } - uint8_t capabilities = 0; - - for (uint8_t b = 0; b < busses.getNumBusses(); b++) { - Bus *bus = busses.getBus(b); - if (bus == nullptr || bus->getLength()==0) break; - if (!bus->isOk()) continue; - if (bus->getStart() >= stop) continue; - if (bus->getStart() + bus->getLength() <= start) continue; - - uint8_t type = bus->getType(); - if (type != TYPE_ANALOG_1CH && (cctFromRgb || type != TYPE_ANALOG_2CH)) capabilities |= 0x01; // segment supports RGB (full color) - if (bus->isRgbw()) capabilities |= 0x02; // segment supports white channel - if (!cctFromRgb) { - switch (type) { - case TYPE_ANALOG_5CH: - case TYPE_ANALOG_2CH: - capabilities |= 0x04; //segment supports white CCT - } - } - if (correctWB && type != TYPE_ANALOG_1CH) capabilities |= 0x04; //white balance correction (uses CCT slider) - uint8_t aWM = Bus::getAutoWhiteMode()<255 ? Bus::getAutoWhiteMode() : bus->getAWMode(); - bool whiteSlider = (aWM == RGBW_MODE_DUAL || aWM == RGBW_MODE_MANUAL_ONLY); // white slider allowed - if (bus->isRgbw() && (whiteSlider || !(capabilities & 0x01))) capabilities |= 0x08; // allow white channel adjustments (AWM allows or is not RGB) - } - _capabilities = capabilities; -} - //used for JSON API info.leds.rgbw. Little practical use, deprecate with info.leds.rgbw. //returns if there is an RGBW bus (supports RGB and White, not only white) //not influenced by auto-white mode, also true if white slider does not affect output white channel @@ -847,7 +986,7 @@ uint8_t WS2812FX::setPixelSegment(uint8_t n) uint8_t prevSegId = _segment_index; if (n < MAX_NUM_SEGMENTS) { _segment_index = n; - SEGLEN = SEGMENT.virtualLength(); + _virtualSegmentLength = SEGMENT.virtualLength(); } return prevSegId; } @@ -863,16 +1002,6 @@ void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col) } } -void WS2812FX::setShowCallback(show_callback cb) -{ - _callback = cb; -} - -void WS2812FX::setTransition(uint16_t t) -{ - _transitionDur = t; -} - void WS2812FX::setTransitionMode(bool t) { unsigned long waitMax = millis() + 20; //refresh after 20 ms if transition enabled @@ -885,51 +1014,6 @@ void WS2812FX::setTransitionMode(bool t) } } -/* - * color blend function - */ -uint32_t IRAM_ATTR WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) { - if(blend == 0) return color1; - uint16_t blendmax = b16 ? 0xFFFF : 0xFF; - if(blend == blendmax) return color2; - uint8_t shift = b16 ? 16 : 8; - - uint32_t w1 = W(color1); - uint32_t r1 = R(color1); - uint32_t g1 = G(color1); - uint32_t b1 = B(color1); - - uint32_t w2 = W(color2); - uint32_t r2 = R(color2); - uint32_t g2 = G(color2); - uint32_t b2 = B(color2); - - uint32_t w3 = ((w2 * blend) + (w1 * (blendmax - blend))) >> shift; - uint32_t r3 = ((r2 * blend) + (r1 * (blendmax - blend))) >> shift; - uint32_t g3 = ((g2 * blend) + (g1 * (blendmax - blend))) >> shift; - uint32_t b3 = ((b2 * blend) + (b1 * (blendmax - blend))) >> shift; - - return RGBW32(r3, g3, b3, w3); -} - -/* - * color add function that preserves ratio - * idea: https://github.com/Aircoookie/WLED/pull/2465 by https://github.com/Proto-molecule - */ -uint32_t WS2812FX::color_add(uint32_t c1, uint32_t c2) -{ - uint32_t r = R(c1) + R(c2); - uint32_t g = G(c1) + G(c2); - uint32_t b = B(c1) + B(c2); - uint32_t w = W(c1) + W(c2); - uint16_t max = r; - if (g > max) max = g; - if (b > max) max = b; - if (w > max) max = w; - if (max < 256) return RGBW32(r, g, b, w); - else return RGBW32(r * 255 / max, g * 255 / max, b * 255 / max, w * 255 / max); -} - /* * Fills segment with color */ @@ -998,8 +1082,8 @@ void WS2812FX::fadeToBlackBy(uint8_t fadeBy) { const uint16_t rows = SEGMENT.virtualHeight(); // will be 1 for 1D for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { - if (isMatrix) setPixelColorXY(x, y, col_to_crgb(getPixelColorXY(x,y)).nscale8(255-fadeBy)); - else setPixelColor(x, col_to_crgb(getPixelColor(x)).nscale8(255-fadeBy)); + if (isMatrix) setPixelColorXY(x, y, CRGB(getPixelColorXY(x,y)).nscale8(255-fadeBy)); + else setPixelColor(x, CRGB(getPixelColor(x)).nscale8(255-fadeBy)); } } @@ -1019,9 +1103,9 @@ void WS2812FX::blur(uint8_t blur_amount) uint8_t keep = 255 - blur_amount; uint8_t seep = blur_amount >> 1; CRGB carryover = CRGB::Black; - for(uint16_t i = 0; i < SEGLEN; i++) + for(uint16_t i = 0; i < _virtualSegmentLength; i++) { - CRGB cur = col_to_crgb(getPixelColor(i)); + CRGB cur = CRGB(getPixelColor(i)); CRGB part = cur; part.nscale8(seep); cur.nscale8(keep); @@ -1038,7 +1122,7 @@ void WS2812FX::blur(uint8_t blur_amount) } } -uint16_t IRAM_ATTR WS2812FX::triwave16(uint16_t in) +uint16_t WS2812FX::triwave16(uint16_t in) { if (in < 0x8000) return in *2; return 0xFFFF - (in - 0x8000)*2; @@ -1105,22 +1189,6 @@ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) { } -uint32_t IRAM_ATTR WS2812FX::crgb_to_col(CRGB fastled) -{ - return RGBW32(fastled.red, fastled.green, fastled.blue, 0); -} - - -CRGB IRAM_ATTR WS2812FX::col_to_crgb(uint32_t color) -{ - CRGB fastled_col; - fastled_col.red = R(color); - fastled_col.green = G(color); - fastled_col.blue = B(color); - return fastled_col; -} - - void WS2812FX::load_gradient_palette(uint8_t index) { byte i = constrain(index, 0, GRADIENT_PALETTE_COUNT -1); @@ -1176,22 +1244,22 @@ void WS2812FX::handle_palette(void) _lastPaletteChange = millis(); } break;} case 2: {//primary color only - CRGB prim = col_to_crgb(SEGCOLOR(0)); + CRGB prim = CRGB(SEGCOLOR(0)); targetPalette = CRGBPalette16(prim); break;} case 3: {//primary + secondary - CRGB prim = col_to_crgb(SEGCOLOR(0)); - CRGB sec = col_to_crgb(SEGCOLOR(1)); + CRGB prim = CRGB(SEGCOLOR(0)); + CRGB sec = CRGB(SEGCOLOR(1)); targetPalette = CRGBPalette16(prim,prim,sec,sec); break;} case 4: {//primary + secondary + tertiary - CRGB prim = col_to_crgb(SEGCOLOR(0)); - CRGB sec = col_to_crgb(SEGCOLOR(1)); - CRGB ter = col_to_crgb(SEGCOLOR(2)); + CRGB prim = CRGB(SEGCOLOR(0)); + CRGB sec = CRGB(SEGCOLOR(1)); + CRGB ter = CRGB(SEGCOLOR(2)); targetPalette = CRGBPalette16(ter,sec,prim); break;} case 5: {//primary + secondary (+tert if not off), more distinct - CRGB prim = col_to_crgb(SEGCOLOR(0)); - CRGB sec = col_to_crgb(SEGCOLOR(1)); + CRGB prim = CRGB(SEGCOLOR(0)); + CRGB sec = CRGB(SEGCOLOR(1)); if (SEGCOLOR(2)) { - CRGB ter = col_to_crgb(SEGCOLOR(2)); + CRGB ter = CRGB(SEGCOLOR(2)); targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,ter,ter,ter,ter,ter,prim); } else { targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,sec,sec,sec); @@ -1227,7 +1295,7 @@ void WS2812FX::handle_palette(void) /* * Gets a single color from the currently selected palette. - * @param i Palette Index (if mapping is true, the full palette will be SEGLEN long, if false, 255). Will wrap around automatically. + * @param i Palette Index (if mapping is true, the full palette will be _virtualSegmentLength long, if false, 255). Will wrap around automatically. * @param mapping if true, LED position in segment is considered for color * @param wrap FastLED palettes will usally wrap back to the start smoothly. Set false to get a hard edge * @param mcol If the default palette 0 is selected, return the standard color 0, 1 or 2 instead. If >2, Party palette is used instead @@ -1243,12 +1311,12 @@ uint32_t IRAM_ATTR WS2812FX::color_from_palette(uint16_t i, bool mapping, bool w } uint8_t paletteIndex = i; - if (mapping && SEGLEN > 1) paletteIndex = (i*255)/(SEGLEN -1); + if (mapping && _virtualSegmentLength > 1) paletteIndex = (i*255)/(_virtualSegmentLength -1); if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end" CRGB fastled_col; fastled_col = ColorFromPalette(currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND); - return crgb_to_col(fastled_col); + return RGBW32(fastled_col.r, fastled_col.g, fastled_col.b, 0); } @@ -1302,7 +1370,7 @@ void WS2812FX::deserializeMap(uint8_t n) { } //gamma 2.8 lookup table used for color correction -byte gammaT[] = { +static byte gammaT[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, @@ -1321,7 +1389,7 @@ byte gammaT[] = { 215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 }; uint8_t WS2812FX::gamma8_cal(uint8_t b, float gamma) { - return (int)(pow((float)b / 255.0, gamma) * 255 + 0.5); + return (int)(powf((float)b / 255.0f, gamma) * 255.0f + 0.5f); } void WS2812FX::calcGammaTable(float gamma) diff --git a/wled00/button.cpp b/wled00/button.cpp index 4c11e9b0..0d224b73 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -195,7 +195,7 @@ void handleAnalog(uint8_t b) colorHStoRGB(aRead*256,255,col); } else { // otherwise use "double press" for segment selection - WS2812FX::Segment& seg = strip.getSegment(macroDoublePress[b]); + Segment& seg = strip.getSegment(macroDoublePress[b]); if (aRead == 0) { seg.setOption(SEG_OPTION_ON, 0); // off } else { diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 25cce032..ee00e84b 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -1,9 +1,54 @@ #include "wled.h" /* - * Color conversion methods + * Color conversion & utility methods */ +/* + * color blend function + */ +uint32_t IRAM_ATTR color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) { + if(blend == 0) return color1; + uint16_t blendmax = b16 ? 0xFFFF : 0xFF; + if(blend == blendmax) return color2; + uint8_t shift = b16 ? 16 : 8; + + uint32_t w1 = W(color1); + uint32_t r1 = R(color1); + uint32_t g1 = G(color1); + uint32_t b1 = B(color1); + + uint32_t w2 = W(color2); + uint32_t r2 = R(color2); + uint32_t g2 = G(color2); + uint32_t b2 = B(color2); + + uint32_t w3 = ((w2 * blend) + (w1 * (blendmax - blend))) >> shift; + uint32_t r3 = ((r2 * blend) + (r1 * (blendmax - blend))) >> shift; + uint32_t g3 = ((g2 * blend) + (g1 * (blendmax - blend))) >> shift; + uint32_t b3 = ((b2 * blend) + (b1 * (blendmax - blend))) >> shift; + + return RGBW32(r3, g3, b3, w3); +} + +/* + * color add function that preserves ratio + * idea: https://github.com/Aircoookie/WLED/pull/2465 by https://github.com/Proto-molecule + */ +uint32_t color_add(uint32_t c1, uint32_t c2) +{ + uint32_t r = R(c1) + R(c2); + uint32_t g = G(c1) + G(c2); + uint32_t b = B(c1) + B(c2); + uint32_t w = W(c1) + W(c2); + uint16_t max = r; + if (g > max) max = g; + if (b > max) max = b; + if (w > max) max = w; + if (max < 256) return RGBW32(r, g, b, w); + else return RGBW32(r * 255 / max, g * 255 / max, b * 255 / max, w * 255 / max); +} + void setRandomColor(byte* rgb) { lastRandomIndex = strip.get_random_wheel_index(lastRandomIndex); diff --git a/wled00/const.h b/wled00/const.h index bba1a79f..84c17815 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -5,6 +5,8 @@ * Readability defines and their associated numerical values + compile-time constants */ +#define GRADIENT_PALETTE_COUNT 58 + //Defaults #define DEFAULT_CLIENT_SSID "Your_Network" #define DEFAULT_AP_PASS "wled1234" diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 3cf5b895..c1c5e445 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -58,6 +58,9 @@ bool getJsonValue(const JsonVariant& element, DestType& destination, const Defau //colors.cpp +uint32_t color_blend(uint32_t,uint32_t,uint16_t,bool b16=false); +uint32_t color_add(uint32_t,uint32_t); + inline uint32_t colorFromRgbw(byte* rgbw) { return uint32_t((byte(rgbw[3]) << 24) | (byte(rgbw[0]) << 16) | (byte(rgbw[1]) << 8) | (byte(rgbw[2]))); } void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb void colorKtoRGB(uint16_t kelvin, byte* rgb); @@ -129,7 +132,7 @@ void handleIR(); void deserializeSegment(JsonObject elem, byte it, byte presetId = 0); bool deserializeState(JsonObject root, byte callMode = CALL_MODE_DIRECT_CHANGE, byte presetId = 0); -void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset = false, bool segmentBounds = true); +void serializeSegment(JsonObject& root, Segment& seg, byte id, bool forPreset = false, bool segmentBounds = true); void serializeState(JsonObject root, bool forPreset = false, bool includeBri = true, bool segmentBounds = true); void serializeInfo(JsonObject root); void serializeModeNames(JsonArray arr, const char *qstring); diff --git a/wled00/ir.cpp b/wled00/ir.cpp index 7937bee2..eaebfc32 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -90,7 +90,7 @@ void changeEffect(uint8_t fx) { if (irApplyToAllSelected) { for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); + Segment& seg = strip.getSegment(i); if (!seg.isActive() || !seg.isSelected()) continue; strip.setMode(i, fx); } @@ -106,7 +106,7 @@ void changePalette(uint8_t pal) { if (irApplyToAllSelected) { for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); + Segment& seg = strip.getSegment(i); if (!seg.isActive() || !seg.isSelected()) continue; seg.palette = pal; } @@ -125,7 +125,7 @@ void changeEffectSpeed(int8_t amount) effectSpeed = (byte)constrain(new_val,0,255); if (irApplyToAllSelected) { for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); + Segment& seg = strip.getSegment(i); if (!seg.isActive() || !seg.isSelected()) continue; seg.speed = effectSpeed; } @@ -135,7 +135,7 @@ void changeEffectSpeed(int8_t amount) setValuesFromMainSeg(); } } else { // if Effect == "solid Color", change the hue of the primary color - WS2812FX::Segment& sseg = irApplyToAllSelected ? strip.getFirstSelectedSeg() : strip.getMainSegment(); + Segment& sseg = irApplyToAllSelected ? strip.getFirstSelectedSeg() : strip.getMainSegment(); CRGB fastled_col; fastled_col.red = R(sseg.colors[0]); fastled_col.green = G(sseg.colors[0]); @@ -148,7 +148,7 @@ void changeEffectSpeed(int8_t amount) hsv2rgb_rainbow(prim_hsv, fastled_col); if (irApplyToAllSelected) { for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); + Segment& seg = strip.getSegment(i); if (!seg.isActive() || !seg.isSelected()) continue; seg.colors[0] = RGBW32(fastled_col.red, fastled_col.green, fastled_col.blue, W(sseg.colors[0])); } @@ -172,7 +172,7 @@ void changeEffectIntensity(int8_t amount) effectIntensity = (byte)constrain(new_val,0,255); if (irApplyToAllSelected) { for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); + Segment& seg = strip.getSegment(i); if (!seg.isActive() || !seg.isSelected()) continue; seg.intensity = effectIntensity; } @@ -182,7 +182,7 @@ void changeEffectIntensity(int8_t amount) setValuesFromMainSeg(); } } else { // if Effect == "solid Color", change the saturation of the primary color - WS2812FX::Segment& sseg = irApplyToAllSelected ? strip.getFirstSelectedSeg() : strip.getMainSegment(); + Segment& sseg = irApplyToAllSelected ? strip.getFirstSelectedSeg() : strip.getMainSegment(); CRGB fastled_col; fastled_col.red = R(sseg.colors[0]); fastled_col.green = G(sseg.colors[0]); @@ -193,7 +193,7 @@ void changeEffectIntensity(int8_t amount) hsv2rgb_rainbow(prim_hsv, fastled_col); if (irApplyToAllSelected) { for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); + Segment& seg = strip.getSegment(i); if (!seg.isActive() || !seg.isSelected()) continue; seg.colors[0] = RGBW32(fastled_col.red, fastled_col.green, fastled_col.blue, W(sseg.colors[0])); } @@ -215,7 +215,7 @@ void changeColor(uint32_t c, int16_t cct=-1) if (irApplyToAllSelected) { // main segment may not be selected! for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); + Segment& seg = strip.getSegment(i); if (!seg.isActive() || !seg.isSelected()) continue; byte capabilities = seg.getLightCapabilities(); uint32_t mask = 0; @@ -233,7 +233,7 @@ void changeColor(uint32_t c, int16_t cct=-1) setValuesFromFirstSelectedSeg(); } else { byte i = strip.getMainSegmentId(); - WS2812FX::Segment& seg = strip.getSegment(i); + Segment& seg = strip.getSegment(i); byte capabilities = seg.getLightCapabilities(); uint32_t mask = 0; bool isRGB = GET_BIT(capabilities, 0); // is segment RGB capable @@ -253,7 +253,7 @@ void changeColor(uint32_t c, int16_t cct=-1) void changeWhite(int8_t amount, int16_t cct=-1) { - WS2812FX::Segment& seg = irApplyToAllSelected ? strip.getFirstSelectedSeg() : strip.getMainSegment(); + Segment& seg = irApplyToAllSelected ? strip.getFirstSelectedSeg() : strip.getMainSegment(); byte r = R(seg.colors[0]); byte g = G(seg.colors[0]); byte b = B(seg.colors[0]); @@ -424,7 +424,7 @@ void decodeIR24CT(uint32_t code) void decodeIR40(uint32_t code) { - WS2812FX::Segment& seg = irApplyToAllSelected ? strip.getFirstSelectedSeg() : strip.getMainSegment(); + Segment& seg = irApplyToAllSelected ? strip.getFirstSelectedSeg() : strip.getMainSegment(); byte r = R(seg.colors[0]); byte g = G(seg.colors[0]); byte b = B(seg.colors[0]); diff --git a/wled00/json.cpp b/wled00/json.cpp index 9ce83b38..6a7ee85b 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -11,8 +11,8 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) byte id = elem["id"] | it; if (id >= strip.getMaxSegments()) return; - WS2812FX::Segment& seg = strip.getSegment(id); - WS2812FX::Segment prev = seg; //make a backup so we can tell if something changed + Segment& seg = strip.getSegment(id); + Segment prev = seg; //make a backup so we can tell if something changed uint16_t start = elem["start"] | seg.start; int stop = elem["stop"] | -1; @@ -327,7 +327,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) //apply all selected segments //bool didSet = false; for (byte s = 0; s < strip.getMaxSegments(); s++) { - WS2812FX::Segment &sg = strip.getSegment(s); + Segment &sg = strip.getSegment(s); if (sg.isActive()) { if (sg.isSelected()) { deserializeSegment(segVar, s, presetId); @@ -396,7 +396,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) return stateResponse; } -void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset, bool segmentBounds) +void serializeSegment(JsonObject& root, Segment& seg, byte id, bool forPreset, bool segmentBounds) { root["id"] = id; if (segmentBounds) { @@ -494,7 +494,7 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme bool selectedSegmentsOnly = root[F("sc")] | false; JsonArray seg = root.createNestedArray("seg"); for (byte s = 0; s < strip.getMaxSegments(); s++) { - WS2812FX::Segment &sg = strip.getSegment(s); + Segment &sg = strip.getSegment(s); if (selectedSegmentsOnly && !sg.isSelected()) continue; if (sg.isActive()) { JsonObject seg0 = seg.createNestedObject(); diff --git a/wled00/led.cpp b/wled00/led.cpp index 9ad85532..b43053be 100644 --- a/wled00/led.cpp +++ b/wled00/led.cpp @@ -8,7 +8,7 @@ void setValuesFromMainSeg() { setValuesFromSegment(strip.getMainSegment void setValuesFromFirstSelectedSeg() { setValuesFromSegment(strip.getFirstSelectedSegId()); } void setValuesFromSegment(uint8_t s) { - WS2812FX::Segment& seg = strip.getSegment(s); + Segment& seg = strip.getSegment(s); col[0] = R(seg.colors[0]); col[1] = G(seg.colors[0]); col[2] = B(seg.colors[0]); @@ -30,9 +30,9 @@ void applyValuesToSelectedSegs() { // copy of first selected segment to tell if value was updated uint8_t firstSel = strip.getFirstSelectedSegId(); - WS2812FX::Segment selsegPrev = strip.getSegment(firstSel); + Segment selsegPrev = strip.getSegment(firstSel); for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); + Segment& seg = strip.getSegment(i); if (i != firstSel && (!seg.isActive() || !seg.isSelected())) continue; if (effectSpeed != selsegPrev.speed) {seg.speed = effectSpeed; stateChanged = true;} diff --git a/wled00/palettes.h b/wled00/palettes.h index c9bdf3f6..5e524059 100644 --- a/wled00/palettes.h +++ b/wled00/palettes.h @@ -13,8 +13,6 @@ #ifndef PalettesWLED_h #define PalettesWLED_h -#define GRADIENT_PALETTE_COUNT 58 - const byte ib_jul01_gp[] PROGMEM = { 0, 194, 1, 1, 94, 1, 29, 18, diff --git a/wled00/set.cpp b/wled00/set.cpp index a1e23621..c1edc811 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -612,7 +612,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) } } - WS2812FX::Segment& selseg = strip.getSegment(selectedSeg); + Segment& selseg = strip.getSegment(selectedSeg); pos = req.indexOf(F("SV=")); //segment selected if (pos > 0) { byte t = getNumVal(&req, pos); @@ -823,7 +823,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) // apply to main and all selected segments to prevent #1618. for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); + Segment& seg = strip.getSegment(i); if (i != selectedSeg && (singleSegment || !seg.isActive() || !seg.isSelected())) continue; // skip non main segments if not applying to all if (fxModeChanged) strip.setMode(i, effectIn); if (speedChanged) seg.speed = speedIn; diff --git a/wled00/udp.cpp b/wled00/udp.cpp index b80d1fdf..f14ad146 100644 --- a/wled00/udp.cpp +++ b/wled00/udp.cpp @@ -28,7 +28,7 @@ void notify(byte callMode, bool followUp) default: return; } byte udpOut[WLEDPACKETSIZE]; - WS2812FX::Segment& mainseg = strip.getMainSegment(); + Segment& mainseg = strip.getMainSegment(); udpOut[0] = 0; //0: wled notifier protocol 1: WARLS protocol udpOut[1] = callMode; udpOut[2] = bri; @@ -92,7 +92,7 @@ void notify(byte callMode, bool followUp) udpOut[39] = strip.getMaxSegments(); udpOut[40] = UDP_SEG_SIZE; //size of each loop iteration (one segment) for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment &selseg = strip.getSegment(i); + Segment &selseg = strip.getSegment(i); uint16_t ofs = 41 + i*UDP_SEG_SIZE; //start of segment offset byte udpOut[0 +ofs] = i; udpOut[1 +ofs] = selseg.start >> 8; @@ -143,7 +143,7 @@ void realtimeLock(uint32_t timeoutMs, byte md) if (!realtimeMode && !realtimeOverride) { uint16_t stop, start; if (useMainSegmentOnly) { - WS2812FX::Segment& mainseg = strip.getMainSegment(); + Segment& mainseg = strip.getMainSegment(); start = mainseg.start; stop = mainseg.stop; mainseg.setOption(SEG_OPTION_FREEZE, true, strip.getMainSegmentId()); @@ -343,7 +343,7 @@ void handleNotifications() uint16_t ofs = 41 + i*udpIn[40]; //start of segment offset byte uint8_t id = udpIn[0 +ofs]; if (id > strip.getMaxSegments()) break; - WS2812FX::Segment& selseg = strip.getSegment(id); + Segment& selseg = strip.getSegment(id); uint16_t start = (udpIn[1+ofs] << 8 | udpIn[2+ofs]); uint16_t stop = (udpIn[3+ofs] << 8 | udpIn[4+ofs]); uint16_t offset = (udpIn[7+ofs] << 8 | udpIn[8+ofs]); @@ -378,7 +378,7 @@ void handleNotifications() // simple effect sync, applies to all selected segments if (applyEffects && (version < 11 || !receiveSegmentOptions)) { for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); + Segment& seg = strip.getSegment(i); if (!seg.isActive() || !seg.isSelected()) continue; if (udpIn[8] < strip.getModeCount()) strip.setMode(i, udpIn[8]); seg.speed = udpIn[9]; diff --git a/wled00/wled_eeprom.cpp b/wled00/wled_eeprom.cpp index 11f514fc..32ba9f50 100644 --- a/wled00/wled_eeprom.cpp +++ b/wled00/wled_eeprom.cpp @@ -418,7 +418,7 @@ void deEEP() { segObj[F("ix")] = EEPROM.read(i+16); segObj["pal"] = EEPROM.read(i+17); } else { - WS2812FX::Segment* seg = strip.getSegments(); + Segment* seg = strip.getSegments(); memcpy(seg, EEPROM.getDataPtr() +i+2, 240); if (ver == 2) { //versions before 2004230 did not have opacity for (byte j = 0; j < strip.getMaxSegments(); j++)