diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 18d61b2167..6f32d86542 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -3763,7 +3763,7 @@ void mode_exploding_fireworks(void) if (SEGENV.aux0 == 0) { //init flare flare->pos = 0; flare->posX = SEGMENT.is2D() ? hw_random16(2,cols-3) : (SEGMENT.intensity > hw_random8()); // will enable random firing side on 1D - unsigned peakHeight = 75 + hw_random8(180); //0-255 + unsigned peakHeight = 84 + hw_random8(146); // 33% to 90% of 256 peakHeight = (peakHeight * (rows -1)) >> 8; flare->vel = sqrtf(-2.0f * gravity * peakHeight); flare->velX = SEGMENT.is2D() ? (hw_random8(9)-4)/64.0f : 0; // no X velocity on 1D @@ -3800,6 +3800,7 @@ void mode_exploding_fireworks(void) // initialize sparks if (SEGENV.aux0 == 2) { + int colIndex = hw_random8(); // single color: one index shared by all sparks for (unsigned i = 1; i < nSparks; i++) { sparks[i].pos = flare->pos; sparks[i].posX = flare->posX; @@ -3808,7 +3809,7 @@ void mode_exploding_fireworks(void) sparks[i].velX = SEGMENT.is2D() ? (float(hw_random16(20001)) / 10000.0f) - 1.0f : 0; // from -1 to 1 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 = hw_random8(); + sparks[i].colIndex = SEGMENT.check1 ? colIndex : hw_random8(); // single color: share one index; otherwise random per spark sparks[i].vel *= flare->pos/rows; // proportional to height sparks[i].velX *= SEGMENT.is2D() ? flare->posX/cols : 0; // proportional to width sparks[i].vel *= -gravity *50; @@ -3835,9 +3836,11 @@ void mode_exploding_fireworks(void) c = color_blend(spColor, WHITE, uint8_t((prog - 300)*5)); } else if (prog > 45) { //fade from spark color to black c = color_blend(BLACK, spColor, uint8_t(prog - 45)); - unsigned cooling = (300 - prog) >> 5; - c.g = qsub8(c.g, cooling); - c.b = qsub8(c.b, cooling * 2); + if (!SEGMENT.check1) { // without single color, shift toward red/orange as sparks cool + unsigned cooling = (300 - prog) >> 5; + c.g = qsub8(c.g, cooling); + c.b = qsub8(c.b, cooling * 2); + } } if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(int(sparks[i].posX), rows - int(sparks[i].pos) - 1, c); else SEGMENT.setPixelColor(int(sparks[i].posX) ? rows - int(sparks[i].pos) - 1 : int(sparks[i].pos), c); @@ -3856,7 +3859,7 @@ void mode_exploding_fireworks(void) } } #undef MAX_SPARKS -static const char _data_FX_MODE_EXPLODING_FIREWORKS[] PROGMEM = "Fireworks 1D@Gravity,Firing side;!,!;!;12;pal=11,ix=128"; +static const char _data_FX_MODE_EXPLODING_FIREWORKS[] PROGMEM = "Fireworks 1D@Gravity,Firing side,,,,Single Color;!,!;!;12;pal=11,ix=128"; #endif // WLED_PS_DONT_REPLACE_x_FX /* diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index e538b342f6..d695c48f02 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -2099,5 +2099,5 @@ const char JSON_palette_names[] PROGMEM = R"=====([ "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", "Semi Blue","Pink Candy","Red Reaf","Aqua Flash","Yelblu Hot","Lite Light","Red Flash","Blink Red","Red Shift","Red Tide", -"Candy2","Traffic Light" +"Candy2","Traffic Light","Fireworks" ])====="; diff --git a/wled00/const.h b/wled00/const.h index e49dd2900a..4e4cf1ae3e 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -7,7 +7,7 @@ */ constexpr size_t FASTLED_PALETTE_COUNT = 7; // 6-12 = sizeof(fastledPalettes) / sizeof(fastledPalettes[0]); -constexpr size_t GRADIENT_PALETTE_COUNT = 59; // 13-72 = sizeof(gGradientPalettes) / sizeof(gGradientPalettes[0]); +constexpr size_t GRADIENT_PALETTE_COUNT = 60; // 13-73 = sizeof(gGradientPalettes) / sizeof(gGradientPalettes[0]); constexpr size_t DYNAMIC_PALETTE_COUNT = 6; // 0- 5 = dynamic palettes (0=default(virtual),1=random,2=primary,3=primary+secondary,4=primary+secondary+tertiary,5=primary+secondary(+tertiary if not black) constexpr size_t FIXED_PALETTE_COUNT = DYNAMIC_PALETTE_COUNT + FASTLED_PALETTE_COUNT + GRADIENT_PALETTE_COUNT; // total number of fixed palettes #ifndef ESP8266 diff --git a/wled00/data/index.js b/wled00/data/index.js index b34260287e..d01b42bff7 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -2812,7 +2812,7 @@ function loadPalettesData() { if (lsPalData) { try { var d = JSON.parse(lsPalData); - if (d && d.vid == lastinfo.vid) { + if (d && d.vid == lastinfo.vid && d.pcount == lJson.length) { palettesData = d.p; redrawPalPrev(); return resolve(); @@ -2824,7 +2824,8 @@ function loadPalettesData() { getPalettesData(0, () => { localStorage.setItem("wledPalx", JSON.stringify({ p: palettesData, - vid: lastinfo.vid + vid: lastinfo.vid, + pcount: lJson.length })); redrawPalPrev(); setTimeout(resolve, 99); // delay optional diff --git a/wled00/palettes.cpp b/wled00/palettes.cpp index bcbdcf22d7..c67bbbcc76 100644 --- a/wled00/palettes.cpp +++ b/wled00/palettes.cpp @@ -759,6 +759,24 @@ const byte trafficlight_gp[] PROGMEM = { 170, 255, 255, 0, //yellow 255, 255, 0, 0}; //red +// Fireworks palette: colors sized by real-world frequency +// red/blue ~22%, green ~18%, violet ~15%, orange ~11%, white ~7%, yellow ~5% +const byte fireworks_gp[] PROGMEM = { + 0, 255, 0, 0, // red (start) + 55, 255, 0, 0, // red (end) + 56, 0, 0, 220, // blue (start) + 112, 0, 0, 220, // blue (end) + 113, 0, 210, 0, // green (start) + 158, 0, 210, 0, // green (end) + 159, 148, 0, 211, // violet (start) + 197, 148, 0, 211, // violet (end) + 198, 255, 80, 0, // orange (start) + 224, 255, 80, 0, // orange (end) + 225, 255, 255, 255, // white (start) + 243, 255, 255, 255, // white (end) + 244, 255, 210, 0, // yellow (start) + 255, 255, 210, 0}; // yellow (end) + const byte Aurora2_gp[] PROGMEM = { 0, 17, 177, 13, //Greenish 64, 121, 242, 5, //Greenish @@ -863,5 +881,6 @@ const uint8_t* const gGradientPalettes[] PROGMEM = { red_shift_gp, //68-55 Red Shift red_tide_gp, //69-56 Red Tide candy2_gp, //70-57 Candy2 - trafficlight_gp //71-58 Traffic Light + trafficlight_gp, //71-58 Traffic Light + fireworks_gp //72-59 Fireworks }; \ No newline at end of file