Skip to content

Commit

Permalink
Allocate segment data based on currently active segments (Aircoookie#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Aircoookie authored Sep 20, 2021
1 parent baf49b8 commit 8fae964
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 26 deletions.
40 changes: 25 additions & 15 deletions wled00/FX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2614,7 +2614,7 @@ uint16_t WS2812FX::mode_glitter()



//each needs 11 bytes
//each needs 12 bytes
//Spark type is used for popcorn, 1D fireworks, and drip
typedef struct Spark {
float pos;
Expand All @@ -2629,7 +2629,7 @@ typedef struct Spark {
*/
uint16_t WS2812FX::mode_popcorn(void) {
//allocate segment data
uint16_t maxNumPopcorn = 22; // max 22 on 18 segment ESP8266
uint16_t maxNumPopcorn = 21; // max 21 on 16 segment ESP8266
uint16_t dataSize = sizeof(spark) * maxNumPopcorn;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed

Expand Down Expand Up @@ -2688,7 +2688,7 @@ uint16_t WS2812FX::candle(bool multi)
if (multi)
{
//allocate segment data
uint16_t dataSize = (SEGLEN -1) *3; // max length of segment on 18 segment ESP8266 is 75 pixels
uint16_t dataSize = (SEGLEN -1) *3; //max. 1365 pixels (ESP8266)
if (!SEGENV.allocateData(dataSize)) return candle(false); //allocation failed
}

Expand Down Expand Up @@ -2776,13 +2776,11 @@ uint16_t WS2812FX::mode_candle_multi()
/ Speed sets frequency of new starbursts, intensity is the intensity of the burst
*/
#ifdef ESP8266
#define STARBURST_MAX_FRAG 4
#define STARBURST_MAX_STARS 6
#define STARBURST_MAX_FRAG 8 //52 bytes / star
#else
#define STARBURST_MAX_FRAG 10
#define STARBURST_MAX_STARS 11
#define STARBURST_MAX_FRAG 10 //60 bytes / star
#endif
//each needs 18+STARBURST_MAX_FRAG*4 bytes
//each needs 20+STARBURST_MAX_FRAG*4 bytes
typedef struct particle {
CRGB color;
uint32_t birth =0;
Expand All @@ -2793,8 +2791,14 @@ typedef struct particle {
} star;

uint16_t WS2812FX::mode_starburst(void) {
uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640
uint8_t segs = 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

uint8_t numStars = 1 + (SEGLEN >> 3);
if (numStars > STARBURST_MAX_STARS) numStars = STARBURST_MAX_STARS; // 11 * 58 * 32 = 19k (ESP32), 6 * 34 * 18 = 4k (ESP8266)
if (numStars > maxStars) numStars = maxStars;
uint16_t dataSize = sizeof(star) * numStars;

if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
Expand Down Expand Up @@ -2902,18 +2906,24 @@ uint16_t WS2812FX::mode_starburst(void) {
* Exploding fireworks effect
* adapted from: http://www.anirama.com/1000leds/1d-fireworks/
*/
#ifdef ESP8266
#define MAX_SPARKS 20 // number of fragments
#else
#define MAX_SPARKS 58 // number of fragments
#endif
uint16_t WS2812FX::mode_exploding_fireworks(void)
{
//allocate segment data
uint16_t numSparks = min(2 + (SEGLEN >> 1), MAX_SPARKS); // max 58 for 32 segment ESP32, 20 for 18 segment ESP8266
uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640
uint8_t segs = 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

uint16_t numSparks = min(2 + (SEGLEN >> 1), maxSparks);
uint16_t dataSize = sizeof(spark) * numSparks;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed

if (dataSize != SEGENV.aux1) { //reset to flare if sparks were reallocated
SEGENV.aux0 = 0;
SEGENV.aux1 = dataSize;
}

fill(BLACK);

bool actuallyReverse = SEGMENT.getOption(SEG_OPTION_REVERSED);
Expand Down
5 changes: 5 additions & 0 deletions wled00/FX.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
#define MAX_SEGMENT_DATA 20480
#endif

/* How much data bytes each segment should max allocate to leave enough space for other segments,
assuming each segment uses the same amount of data. 256 for ESP8266, 640 for ESP32. */
#define FAIR_DATA_PER_SEG (MAX_SEGMENT_DATA / MAX_NUM_SEGMENTS)

#define LED_SKIP_AMOUNT 1
#define MIN_SHOW_DELAY 15

Expand Down Expand Up @@ -657,6 +661,7 @@ class WS2812FX {
getModeCount(void),
getPaletteCount(void),
getMaxSegments(void),
getActiveSegmentsNum(void),
//getFirstSelectedSegment(void),
getMainSegmentId(void),
gamma8(uint8_t),
Expand Down
26 changes: 15 additions & 11 deletions wled00/FX_fcn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,25 +129,20 @@ void WS2812FX::finalizeInit(uint16_t countPixels)

if (autoSegments) {
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) {
_segments[i].start = segStarts[i];
_segments[i].stop = segStops [i];
setSegment(i, segStarts[i], segStops[i]);
}
} else {
//expand the main seg to the entire length, but only if there are no other segments
uint8_t mainSeg = getMainSegmentId();
bool isMultipleSegs = false;
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (i != mainSeg && _segments[i].isActive()) isMultipleSegs = true;
}
if (!isMultipleSegs) {
_segments[mainSeg].start = 0; _segments[mainSeg].stop = _length;

if (getActiveSegmentsNum() < 2) {
setSegment(mainSeg, 0, _length);
} else {
//there are multiple segments, leave them, but prune length to total
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].start > _length) _segments[i].stop = 0;
if (_segments[i].stop > _length) _segments[i].stop = _length;
if (_segments[i].start >= _length) setSegment(i, 0, 0);
if (_segments[i].stop > _length) setSegment(i, _segments[i].start, _length);
}
}
}
Expand Down Expand Up @@ -545,6 +540,15 @@ uint8_t WS2812FX::getMainSegmentId(void) {
return 0;
}

uint8_t WS2812FX::getActiveSegmentsNum(void) {
uint8_t c = 0;
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isActive()) c++;
}
return c;
}

uint32_t WS2812FX::getColor(void) {
return _segments[getMainSegmentId()].colors[0];
}
Expand Down

0 comments on commit 8fae964

Please sign in to comment.