FX improvements and cleanup (#4145)

Improvements & merges of FX

- Scrolling Text: Gradient Palette support added
- Waving Cell: Improved with higher temporal resolution (smoother at lower speeds) and added additional mode setting and optional blurring
- Julia: added blur option
- Squared Swirl: added fade option

- Added smearing option to:
    - DNA
    - DNA Spiral
    - Drift
    - Drift Rose
    - Crazy Bees
    - Ripple
    - Colored Bursts
    - Frizzles
    - Lissajous
    - Sindots
    - Spaceships

- Added palette support to:
    - Crazy Bees
    - Polar Lights
    - Drift Rose

- Changed default palette handling (no more special treatment for some FX)
- Merged puddles and puddlepeak
- Merged Gravcenter, Gravcentric, Gravfreq and Gravimeter (saves 1.2k of flash)
- Merged meteor and meteor smooth
- Renamed police_base into mode_two_dots as that was just an alias
- Added 'Traffic Light' palette (originally defined in Polar Lights FX)
-  Firenoise: removed local palette, use fire palette -> slight change in looks (+bugfix)
- Some code cleanup (removed unused / commented stuff)
- Moved dev info for AR to the top so ist easier to find as a reference, also added link to KB there
This commit is contained in:
Damian Schneider 2024-12-20 14:13:53 +01:00 committed by GitHub
parent ff26f54bfd
commit 07cc3aa5c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 335 additions and 456 deletions

File diff suppressed because it is too large Load Diff

View File

@ -208,7 +208,7 @@ extern byte realtimeMode; // used in getMappedPixelIndex()
#define FX_MODE_COLORTWINKLE 74 #define FX_MODE_COLORTWINKLE 74
#define FX_MODE_LAKE 75 #define FX_MODE_LAKE 75
#define FX_MODE_METEOR 76 #define FX_MODE_METEOR 76
#define FX_MODE_METEOR_SMOOTH 77 //#define FX_MODE_METEOR_SMOOTH 77 // merged with meteor
#define FX_MODE_RAILWAY 78 #define FX_MODE_RAILWAY 78
#define FX_MODE_RIPPLE 79 #define FX_MODE_RIPPLE 79
#define FX_MODE_TWINKLEFOX 80 #define FX_MODE_TWINKLEFOX 80
@ -420,6 +420,7 @@ typedef struct Segment {
uint8_t _reserved : 4; uint8_t _reserved : 4;
}; };
}; };
uint8_t _default_palette; // palette number that gets assigned to pal0
unsigned _dataLen; unsigned _dataLen;
static unsigned _usedSegmentData; static unsigned _usedSegmentData;
static uint8_t _segBri; // brightness of segment for current effect static uint8_t _segBri; // brightness of segment for current effect
@ -493,6 +494,7 @@ typedef struct Segment {
aux1(0), aux1(0),
data(nullptr), data(nullptr),
_capabilities(0), _capabilities(0),
_default_palette(0),
_dataLen(0), _dataLen(0),
_t(nullptr) _t(nullptr)
{ {
@ -670,9 +672,9 @@ typedef struct Segment {
inline void fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c, bool soft = false) { fillCircle(cx, cy, radius, RGBW32(c.r,c.g,c.b,0), soft); } inline void fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c, bool soft = false) { fillCircle(cx, cy, radius, RGBW32(c.r,c.g,c.b,0), soft); }
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c, bool soft = false); void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c, bool soft = false);
inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, bool soft = false) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0), soft); } // automatic inline inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, bool soft = false) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0), soft); } // automatic inline
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2 = 0, int8_t rotate = 0); void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2 = 0, int8_t rotate = 0, bool usePalGrad = false);
inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0)); } // automatic inline inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0)); } // automatic inline
inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2, int8_t rotate = 0) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0), RGBW32(c2.r,c2.g,c2.b,0), rotate); } // automatic inline inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2, int8_t rotate = 0, bool usePalGrad = false) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0), RGBW32(c2.r,c2.g,c2.b,0), rotate, usePalGrad); } // automatic inline
void wu_pixel(uint32_t x, uint32_t y, CRGB c); void wu_pixel(uint32_t x, uint32_t y, CRGB c);
inline void fill_solid(CRGB c) { fill(RGBW32(c.r,c.g,c.b,0)); } inline void fill_solid(CRGB c) { fill(RGBW32(c.r,c.g,c.b,0)); }
#else #else
@ -707,9 +709,9 @@ typedef struct Segment {
inline void fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c, bool soft = false) {} inline void fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c, bool soft = false) {}
inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c, bool soft = false) {} inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c, bool soft = false) {}
inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, bool soft = false) {} inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, bool soft = false) {}
inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t = 0, int8_t = 0) {} inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t = 0, int8_t = 0, bool = false) {}
inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color) {} inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color) {}
inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2, int8_t rotate = 0) {} inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2, int8_t rotate = 0, bool usePalGrad = false) {}
inline void wu_pixel(uint32_t x, uint32_t y, CRGB c) {} inline void wu_pixel(uint32_t x, uint32_t y, CRGB c) {}
#endif #endif
} segment; } segment;

View File

@ -280,7 +280,7 @@ void Segment::blur2D(uint8_t blur_x, uint8_t blur_y, bool smear) {
uint32_t last; uint32_t last;
if (blur_x) { if (blur_x) {
const uint8_t keepx = smear ? 255 : 255 - blur_x; const uint8_t keepx = smear ? 255 : 255 - blur_x;
const uint8_t seepx = blur_x >> (1 + smear); const uint8_t seepx = blur_x >> 1;
for (unsigned row = 0; row < rows; row++) { // blur rows (x direction) for (unsigned row = 0; row < rows; row++) { // blur rows (x direction)
uint32_t carryover = BLACK; uint32_t carryover = BLACK;
uint32_t curnew = BLACK; uint32_t curnew = BLACK;
@ -303,7 +303,7 @@ void Segment::blur2D(uint8_t blur_x, uint8_t blur_y, bool smear) {
} }
if (blur_y) { if (blur_y) {
const uint8_t keepy = smear ? 255 : 255 - blur_y; const uint8_t keepy = smear ? 255 : 255 - blur_y;
const uint8_t seepy = blur_y >> (1 + smear); const uint8_t seepy = blur_y >> 1;
for (unsigned col = 0; col < cols; col++) { for (unsigned col = 0; col < cols; col++) {
uint32_t carryover = BLACK; uint32_t carryover = BLACK;
uint32_t curnew = BLACK; uint32_t curnew = BLACK;
@ -618,7 +618,7 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint3
// draws a raster font character on canvas // draws a raster font character on canvas
// only supports: 4x6=24, 5x8=40, 5x12=60, 6x8=48 and 7x9=63 fonts ATM // only supports: 4x6=24, 5x8=40, 5x12=60, 6x8=48 and 7x9=63 fonts ATM
void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2, int8_t rotate) { void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2, int8_t rotate, bool usePalGrad) {
if (!isActive()) return; // not active if (!isActive()) return; // not active
if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported
chr -= 32; // align with font table entries chr -= 32; // align with font table entries
@ -626,6 +626,7 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w,
CRGB col = CRGB(color); CRGB col = CRGB(color);
CRGBPalette16 grad = CRGBPalette16(col, col2 ? CRGB(col2) : col); CRGBPalette16 grad = CRGBPalette16(col, col2 ? CRGB(col2) : col);
if(usePalGrad) grad = SEGPALETTE; // selected palette as gradient
//if (w<5 || w>6 || h!=8) return; //if (w<5 || w>6 || h!=8) return;
for (int i = 0; i<h; i++) { // character height for (int i = 0; i<h; i++) { // character height

View File

@ -201,19 +201,7 @@ CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0; if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0;
if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // TODO remove strip dependency by moving customPalettes out of strip if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // TODO remove strip dependency by moving customPalettes out of strip
//default palette. Differs depending on effect //default palette. Differs depending on effect
if (pal == 0) switch (mode) { if (pal == 0) pal = _default_palette; //load default palette set in FX _data, party colors as default
case FX_MODE_FIRE_2012 : pal = 35; break; // heat palette
case FX_MODE_COLORWAVES : pal = 26; break; // landscape 33
case FX_MODE_FILLNOISE8 : pal = 9; break; // ocean colors
case FX_MODE_NOISE16_1 : pal = 20; break; // Drywet
case FX_MODE_NOISE16_2 : pal = 43; break; // Blue cyan yellow
case FX_MODE_NOISE16_3 : pal = 35; break; // heat palette
case FX_MODE_NOISE16_4 : pal = 26; break; // landscape 33
case FX_MODE_GLITTER : pal = 11; break; // rainbow colors
case FX_MODE_SUNRISE : pal = 35; break; // heat palette
case FX_MODE_RAILWAY : pal = 3; break; // prim + sec
case FX_MODE_2DSOAP : pal = 11; break; // rainbow colors
}
switch (pal) { switch (pal) {
case 0: //default palette. Exceptions for specific effects above case 0: //default palette. Exceptions for specific effects above
targetPalette = PartyColors_p; break; targetPalette = PartyColors_p; break;
@ -585,9 +573,9 @@ Segment &Segment::setMode(uint8_t fx, bool loadDefaults) {
if (modeBlending) startTransition(strip.getTransition()); // set effect transitions if (modeBlending) startTransition(strip.getTransition()); // set effect transitions
#endif #endif
mode = fx; mode = fx;
int sOpt;
// load default values from effect string // load default values from effect string
if (loadDefaults) { if (loadDefaults) {
int sOpt;
sOpt = extractModeDefaults(fx, "sx"); speed = (sOpt >= 0) ? sOpt : DEFAULT_SPEED; sOpt = extractModeDefaults(fx, "sx"); speed = (sOpt >= 0) ? sOpt : DEFAULT_SPEED;
sOpt = extractModeDefaults(fx, "ix"); intensity = (sOpt >= 0) ? sOpt : DEFAULT_INTENSITY; sOpt = extractModeDefaults(fx, "ix"); intensity = (sOpt >= 0) ? sOpt : DEFAULT_INTENSITY;
sOpt = extractModeDefaults(fx, "c1"); custom1 = (sOpt >= 0) ? sOpt : DEFAULT_C1; sOpt = extractModeDefaults(fx, "c1"); custom1 = (sOpt >= 0) ? sOpt : DEFAULT_C1;
@ -604,6 +592,9 @@ Segment &Segment::setMode(uint8_t fx, bool loadDefaults) {
sOpt = extractModeDefaults(fx, "mY"); if (sOpt >= 0) mirror_y = (bool)sOpt; // NOTE: setting this option is a risky business sOpt = extractModeDefaults(fx, "mY"); if (sOpt >= 0) mirror_y = (bool)sOpt; // NOTE: setting this option is a risky business
sOpt = extractModeDefaults(fx, "pal"); if (sOpt >= 0) setPalette(sOpt); //else setPalette(0); sOpt = extractModeDefaults(fx, "pal"); if (sOpt >= 0) setPalette(sOpt); //else setPalette(0);
} }
sOpt = extractModeDefaults(fx, "pal"); // always extract 'pal' to set _default_palette
if(sOpt <= 0) sOpt = 6; // partycolors if zero or not set
_default_palette = sOpt; // _deault_palette is loaded into pal0 in loadPalette() (if selected)
markForReset(); markForReset();
stateChanged = true; // send UDP/WS broadcast stateChanged = true; // send UDP/WS broadcast
} }
@ -1140,7 +1131,7 @@ void Segment::blur(uint8_t blur_amount, bool smear) {
} }
#endif #endif
uint8_t keep = smear ? 255 : 255 - blur_amount; uint8_t keep = smear ? 255 : 255 - blur_amount;
uint8_t seep = blur_amount >> (1 + smear); uint8_t seep = blur_amount >> 1;
unsigned vlength = vLength(); unsigned vlength = vLength();
uint32_t carryover = BLACK; uint32_t carryover = BLACK;
uint32_t lastnew; uint32_t lastnew;
@ -1848,5 +1839,5 @@ const char JSON_palette_names[] PROGMEM = R"=====([
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura", "Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura",
"Aurora","Atlantica","C9 2","C9 New","Temperature","Aurora 2","Retro Clown","Candy","Toxy Reaf","Fairy Reaf", "Aurora","Atlantica","C9 2","C9 New","Temperature","Aurora 2","Retro Clown","Candy","Toxy Reaf","Fairy Reaf",
"Semi Blue","Pink Candy","Red Reaf","Aqua Flash","Yelblu Hot","Lite Light","Red Flash","Blink Red","Red Shift","Red Tide", "Semi Blue","Pink Candy","Red Reaf","Aqua Flash","Yelblu Hot","Lite Light","Red Flash","Blink Red","Red Shift","Red Tide",
"Candy2" "Candy2","Traffic Light"
])====="; ])=====";

View File

@ -5,7 +5,7 @@
* Readability defines and their associated numerical values + compile-time constants * Readability defines and their associated numerical values + compile-time constants
*/ */
#define GRADIENT_PALETTE_COUNT 58 #define GRADIENT_PALETTE_COUNT 59
// You can define custom product info from build flags. // You can define custom product info from build flags.
// This is useful to allow API consumer to identify what type of WLED version // This is useful to allow API consumer to identify what type of WLED version

View File

@ -435,7 +435,7 @@ static void decodeIR44(uint32_t code)
case IR44_DIY2 : presetFallback(2, FX_MODE_BREATH, 0); break; case IR44_DIY2 : presetFallback(2, FX_MODE_BREATH, 0); break;
case IR44_DIY3 : presetFallback(3, FX_MODE_FIRE_FLICKER, 0); break; case IR44_DIY3 : presetFallback(3, FX_MODE_FIRE_FLICKER, 0); break;
case IR44_DIY4 : presetFallback(4, FX_MODE_RAINBOW, 0); break; case IR44_DIY4 : presetFallback(4, FX_MODE_RAINBOW, 0); break;
case IR44_DIY5 : presetFallback(5, FX_MODE_METEOR_SMOOTH, 0); break; case IR44_DIY5 : presetFallback(5, FX_MODE_METEOR, 0); break;
case IR44_DIY6 : presetFallback(6, FX_MODE_RAIN, 0); break; case IR44_DIY6 : presetFallback(6, FX_MODE_RAIN, 0); break;
case IR44_AUTO : changeEffect(FX_MODE_STATIC); break; case IR44_AUTO : changeEffect(FX_MODE_STATIC); break;
case IR44_FLASH : changeEffect(FX_MODE_PALETTE); break; case IR44_FLASH : changeEffect(FX_MODE_PALETTE); break;

View File

@ -1,5 +1,6 @@
/* /*
* Color palettes for FastLED effects (65-73). * Color palettes for FastLED effects (65-73).
* 4 bytes per color: index, red, green, blue
*/ */
// From ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb // From ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb
@ -844,6 +845,12 @@ const byte candy2_gp[] PROGMEM = {
211, 39, 33, 34, 211, 39, 33, 34,
255, 1, 1, 1}; 255, 1, 1, 1};
const byte trafficlight_gp[] PROGMEM = {
0, 0, 0, 0, //black
85, 0, 255, 0, //green
170, 255, 255, 0, //yellow
255, 255, 0, 0}; //red
// array of fastled palettes (palette 6 - 12) // array of fastled palettes (palette 6 - 12)
const TProgmemRGBPalette16 *const fastledPalettes[] PROGMEM = { const TProgmemRGBPalette16 *const fastledPalettes[] PROGMEM = {
&PartyColors_p, //06-00 Party &PartyColors_p, //06-00 Party
@ -917,7 +924,8 @@ const byte* const gGradientPalettes[] PROGMEM = {
blink_red_gp, //67-54 Blink Red blink_red_gp, //67-54 Blink Red
red_shift_gp, //68-55 Red Shift red_shift_gp, //68-55 Red Shift
red_tide_gp, //69-56 Red Tide red_tide_gp, //69-56 Red Tide
candy2_gp //70-57 Candy2 candy2_gp, //70-57 Candy2
trafficlight_gp //71-58 Traffic Light
}; };
#endif #endif