Merge remote-tracking branch 'upstream/mdev' into mdev
This commit is contained in:
168
wled00/FX.h
168
wled00/FX.h
@@ -33,7 +33,7 @@
|
||||
|
||||
bool canUseSerial(void); // WLEDMM implemented in wled_serial.cpp
|
||||
void strip_wait_until_idle(String whoCalledMe); // WLEDMM implemented in FX_fcn.cpp
|
||||
bool strip_uses_global_leds(void); // WLEDMM implemented in FX_fcn.cpp
|
||||
bool strip_uses_global_leds(void) __attribute__((pure)); // WLEDMM implemented in FX_fcn.cpp
|
||||
|
||||
#define FASTLED_INTERNAL //remove annoying pragma messages
|
||||
#define USE_GET_MILLISECOND_TIMER
|
||||
@@ -87,11 +87,13 @@ bool strip_uses_global_leds(void); // WLEDMM implemented in FX_fcn.
|
||||
#ifndef MAX_NUM_SEGMENTS
|
||||
#define MAX_NUM_SEGMENTS 32
|
||||
#endif
|
||||
#ifndef MAX_SEGMENT_DATA
|
||||
#if defined(ARDUINO_ARCH_ESP32S2)
|
||||
#define MAX_SEGMENT_DATA 24576
|
||||
#else
|
||||
#define MAX_SEGMENT_DATA 32767
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* How much data bytes each segment should max allocate to leave enough space for other segments,
|
||||
@@ -348,10 +350,10 @@ bool strip_uses_global_leds(void); // WLEDMM implemented in FX_fcn.
|
||||
#define FX_MODE_STARBURST_AR 192 // WLED-SR audioreactive fireworks starburst
|
||||
// #define FX_MODE_PALETTE_AR 193 // WLED-SR audioreactive palette
|
||||
#define FX_MODE_FIREWORKS_AR 194 // WLED-SR audioreactive fireworks
|
||||
#define FX_MODE_GEQLASER 195 // WLED-MM GEQ Laser
|
||||
#define FX_MODE_2DSNOWFALL 196 // WLED-MM Snowfall
|
||||
|
||||
#define MODE_COUNT 197
|
||||
#define FX_MODE_GEQLASER 195 // WLED-MM GEQ Laser
|
||||
#define FX_MODE_2DPAINTBRUSH 196 // WLED-MM Paintbrush
|
||||
#define FX_MODE_2DSNOWFALL 197 // WLED-MM Snowfall
|
||||
#define MODE_COUNT 198
|
||||
|
||||
typedef enum mapping1D2D {
|
||||
M12_Pixels = 0,
|
||||
@@ -435,6 +437,21 @@ typedef struct Segment {
|
||||
static size_t _usedSegmentData; // WLEDMM uint16_t is too small
|
||||
void setPixelColorXY_fast(int x, int y,uint32_t c, uint32_t scaled_col, int cols, int rows); // set relative pixel within segment with color - faster, but no error checking!!!
|
||||
|
||||
bool _isSimpleSegment = false; // simple = no grouping or spacing - mirror, transpose or reverse allowed
|
||||
bool _isSuperSimpleSegment = false; // superSimple = no grouping or spacing, no mirror - only transpose or reverse allowed
|
||||
#ifdef WLEDMM_FASTPATH
|
||||
// WLEDMM cache some values that won't change while drawing a frame
|
||||
bool _isValid2D = false;
|
||||
uint8_t _brightness = 255; // final pixel brightness - including transitions and segment opacity
|
||||
bool _firstFill = true; // dirty HACK support
|
||||
uint16_t _2dWidth = 0; // virtualWidth
|
||||
uint16_t _2dHeight = 0; // virtualHeight
|
||||
|
||||
void setPixelColorXY_slow(int x, int y, uint32_t c); // set relative pixel within segment with color - full slow version
|
||||
#else
|
||||
void setPixelColorXY_slow(int x, int y, uint32_t c) { setPixelColorXY(x,y,c); } // not FASTPATH - slow is the normal
|
||||
#endif
|
||||
|
||||
// perhaps this should be per segment, not static
|
||||
static CRGBPalette16 _currentPalette; // palette used for current effect (includes transition, used in color_from_palette())
|
||||
|
||||
@@ -578,7 +595,7 @@ typedef struct Segment {
|
||||
void setCCT(uint16_t k);
|
||||
void setOpacity(uint8_t o);
|
||||
void setOption(uint8_t n, bool val);
|
||||
void setMode(uint8_t fx, bool loadDefaults = false);
|
||||
void setMode(uint8_t fx, bool loadDefaults = false, bool sliderDefaultsOnly = false);
|
||||
void setPalette(uint8_t pal);
|
||||
uint8_t differs(Segment& b) const;
|
||||
void refreshLightCapabilities(void);
|
||||
@@ -588,6 +605,7 @@ typedef struct Segment {
|
||||
bool allocateData(size_t len);
|
||||
void deallocateData(void);
|
||||
void resetIfRequired(void);
|
||||
void startFrame(void); // cache a few values that don't change while an effect is drawing
|
||||
/**
|
||||
* Flags that before the next effect is calculated,
|
||||
* the internal segment state should be reset.
|
||||
@@ -626,7 +644,7 @@ typedef struct Segment {
|
||||
void setPixelColor(float i, uint32_t c, bool aa = true);
|
||||
inline void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); }
|
||||
inline void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, RGBW32(c.r,c.g,c.b,0), aa); }
|
||||
uint32_t __attribute__((pure)) getPixelColor(int i); // WLEDMM attribute added
|
||||
uint32_t __attribute__((pure)) getPixelColor(int i) const; // WLEDMM attribute added
|
||||
// 1D support functions (some implement 2D as well)
|
||||
void blur(uint8_t, bool smear = false);
|
||||
void fill(uint32_t c);
|
||||
@@ -638,11 +656,22 @@ typedef struct Segment {
|
||||
inline void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(n, RGBW32(r,g,b,w), fast); } // automatically inline
|
||||
inline void addPixelColor(int n, CRGB c, bool fast = false) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), fast); } // automatically inline
|
||||
void fadePixelColor(uint16_t n, uint8_t fade);
|
||||
uint8_t get_random_wheel_index(uint8_t pos);
|
||||
uint8_t get_random_wheel_index(uint8_t pos) const;
|
||||
uint32_t __attribute__((pure)) color_from_palette(uint_fast16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255);
|
||||
uint32_t __attribute__((pure)) color_wheel(uint8_t pos);
|
||||
|
||||
// 2D Blur: shortcuts for bluring columns or rows only (50% faster than full 2D blur)
|
||||
inline void blurCols(fract8 blur_amount, bool smear = false) { // blur all columns
|
||||
const unsigned cols = virtualWidth();
|
||||
for (unsigned k = 0; k < cols; k++) blurCol(k, blur_amount, smear);
|
||||
}
|
||||
inline void blurRows(fract8 blur_amount, bool smear = false) { // blur all rows
|
||||
const unsigned rows = virtualHeight();
|
||||
for ( unsigned i = 0; i < rows; i++) blurRow(i, blur_amount, smear);
|
||||
}
|
||||
|
||||
// 2D matrix
|
||||
#ifndef WLEDMM_FASTPATH
|
||||
inline uint16_t virtualWidth() const { // WLEDMM use fast types, and make function inline
|
||||
uint_fast16_t groupLen = groupLength();
|
||||
uint_fast16_t vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen;
|
||||
@@ -655,22 +684,53 @@ typedef struct Segment {
|
||||
if (mirror_y) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||
return vHeight;
|
||||
}
|
||||
#else
|
||||
inline uint16_t virtualWidth() const { return(_2dWidth);} // WLEDMM get pre-calculated virtualWidth
|
||||
inline uint16_t virtualHeight() const { return(_2dHeight);} // WLEDMM get pre-calculated virtualHeight
|
||||
|
||||
uint16_t calc_virtualWidth() const {
|
||||
uint_fast16_t groupLen = groupLength();
|
||||
uint_fast16_t vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen;
|
||||
if (mirror) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||
return vWidth;
|
||||
}
|
||||
uint16_t calc_virtualHeight() const {
|
||||
uint_fast16_t groupLen = groupLength();
|
||||
uint_fast16_t vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen;
|
||||
if (mirror_y) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||
return vHeight;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t nrOfVStrips(void) const;
|
||||
void createjMap(); //WLEDMM jMap
|
||||
void deletejMap(); //WLEDMM jMap
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
inline uint16_t XY(uint_fast16_t x, uint_fast16_t y) { // support function to get relative index within segment (for leds[]) // WLEDMM inline for speed
|
||||
uint_fast16_t width = virtualWidth(); // segment width in logical pixels
|
||||
uint_fast16_t height = virtualHeight(); // segment height in logical pixels
|
||||
if (width == 0) return 0; // softhack007 avoid div/0
|
||||
if (height == 0) return (x%width); // softhack007 avoid div/0
|
||||
inline uint16_t XY(uint_fast16_t x, uint_fast16_t y) const { // support function to get relative index within segment (for leds[]) // WLEDMM inline for speed
|
||||
uint_fast16_t width = max(uint16_t(1), virtualWidth()); // segment width in logical pixels -- softhack007 avoid div/0
|
||||
uint_fast16_t height = max(uint16_t(1), virtualHeight()); // segment height in logical pixels -- softhack007 avoid div/0
|
||||
return (x%width) + (y%height) * width;
|
||||
}
|
||||
|
||||
//void setPixelColorXY_fast(int x, int y,uint32_t c); // set relative pixel within segment with color - wrapper for _fast
|
||||
#ifdef WLEDMM_FASTPATH
|
||||
// WLEDMM this is a "gateway" function - we either call _fast or fall back to "slow"
|
||||
inline void setPixelColorXY(int x, int y, uint32_t col) {
|
||||
if (!_isSimpleSegment) { // slow path
|
||||
setPixelColorXY_slow(x, y, col);
|
||||
} else { // fast path
|
||||
// some sanity checks
|
||||
if (!_isValid2D) return; // not active
|
||||
if ((unsigned(x) >= _2dWidth) || (unsigned(y) >= _2dHeight)) return; // check if (x,y) are out-of-range - due to 2's complement, this also catches negative values
|
||||
if (!_brightness && !transitional) return; // black-out
|
||||
|
||||
uint32_t scaled_col = (_brightness == 255) ? col : color_fade(col, _brightness); // calculate final color
|
||||
setPixelColorXY_fast(x, y, col, scaled_col, int(_2dWidth), int(_2dHeight)); // call "fast" function
|
||||
}
|
||||
}
|
||||
#else
|
||||
void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
|
||||
#endif
|
||||
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColorXY(int(x), int(y), c); }
|
||||
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); }
|
||||
@@ -680,7 +740,7 @@ typedef struct Segment {
|
||||
inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); }
|
||||
inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); }
|
||||
//#endif
|
||||
uint32_t __attribute__((pure)) getPixelColorXY(int x, int y);
|
||||
uint32_t __attribute__((pure)) getPixelColorXY(int x, int y) const;
|
||||
// 2D support functions
|
||||
void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend);
|
||||
inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); }
|
||||
@@ -696,13 +756,13 @@ typedef struct Segment {
|
||||
void move(uint8_t dir, uint8_t delta, bool wrap = false);
|
||||
void drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t c, bool soft = false);
|
||||
inline void drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c, bool soft = false) { drawCircle(cx, cy, radius, RGBW32(c.r,c.g,c.b,0), soft); }
|
||||
void fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t c, bool soft = false);
|
||||
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 fillCircle(unsigned cx, unsigned cy, int radius, uint32_t col, bool soft);
|
||||
inline void fillCircle(unsigned cx, unsigned cy, int 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, uint8_t depth = UINT8_MAX);
|
||||
inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, bool soft = false, uint8_t depth = UINT8_MAX) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0), soft, depth); } // automatic inline
|
||||
void drawArc(uint16_t x0, uint16_t y0, uint16_t radius, uint32_t color, uint32_t fillColor = 0);
|
||||
inline void drawArc(uint16_t x0, uint16_t y0, uint16_t radius, CRGB color, CRGB fillColor = BLACK) { drawArc(x0, y0, radius, RGBW32(color.r,color.g,color.b,0), RGBW32(fillColor.r,fillColor.g,fillColor.b,0)); } // 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);
|
||||
void drawArc(unsigned x0, unsigned y0, int radius, uint32_t color, uint32_t fillColor = 0);
|
||||
inline void drawArc(unsigned x0, unsigned y0, int radius, CRGB color, CRGB fillColor = BLACK) { drawArc(x0, y0, radius, RGBW32(color.r,color.g,color.b,0), RGBW32(fillColor.r,fillColor.g,fillColor.b,0)); } // 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, bool drawShadow = false);
|
||||
inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0), RGBW32(c2.r,c2.g,c2.b,0)); } // automatic inline
|
||||
void wu_pixel(uint32_t x, uint32_t y, CRGB c);
|
||||
//void blur1d(fract8 blur_amount); // blur all rows in 1 dimension
|
||||
@@ -746,7 +806,7 @@ typedef struct Segment {
|
||||
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 wu_pixel(uint32_t x, uint32_t y, CRGB c) {}
|
||||
#endif
|
||||
uint8_t * getAudioPalette(int pal); //WLEDMM netmindz ar palette
|
||||
uint8_t * getAudioPalette(int pal) const; //WLEDMM netmindz ar palette
|
||||
} segment;
|
||||
//static int segSize = sizeof(Segment);
|
||||
|
||||
@@ -869,64 +929,66 @@ class WS2812FX { // 96 bytes
|
||||
|
||||
bool
|
||||
checkSegmentAlignment(void),
|
||||
hasRGBWBus(void),
|
||||
hasCCTBus(void),
|
||||
hasRGBWBus(void) const,
|
||||
hasCCTBus(void) const,
|
||||
// return true if the strip is being sent pixel updates
|
||||
isUpdating(void),
|
||||
isUpdating(void) const,
|
||||
deserializeMap(uint8_t n=0),
|
||||
useLedsArray = false;
|
||||
|
||||
inline bool isServicing(void) { return _isServicing; }
|
||||
inline bool hasWhiteChannel(void) {return _hasWhiteChannel;}
|
||||
inline bool isOffRefreshRequired(void) {return _isOffRefreshRequired;}
|
||||
inline bool isServicing(void) const { return _isServicing; }
|
||||
inline bool hasWhiteChannel(void) const {return _hasWhiteChannel;}
|
||||
inline bool isOffRefreshRequired(void) const {return _isOffRefreshRequired;}
|
||||
|
||||
uint8_t
|
||||
paletteFade,
|
||||
paletteBlend,
|
||||
milliampsPerLed,
|
||||
cctBlending,
|
||||
getActiveSegmentsNum(void),
|
||||
getFirstSelectedSegId(void),
|
||||
getLastActiveSegmentId(void),
|
||||
getActiveSegsLightCapabilities(bool selectedOnly = false),
|
||||
getActiveSegmentsNum(void) const,
|
||||
getFirstSelectedSegId(void) __attribute__((pure)),
|
||||
getLastActiveSegmentId(void) const,
|
||||
getActiveSegsLightCapabilities(bool selectedOnly = false) __attribute__((pure)),
|
||||
setPixelSegment(uint8_t n);
|
||||
|
||||
inline uint8_t getBrightness(void) { return _brightness; }
|
||||
inline uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value)
|
||||
inline uint8_t getSegmentsNum(void) { return _segments.size(); } // returns currently present 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; } // will only return built-in palette count
|
||||
inline uint8_t getTargetFps() { return _targetFps; }
|
||||
inline uint8_t getModeCount() { return _modeCount; }
|
||||
inline uint8_t getBrightness(void) const { return _brightness; }
|
||||
inline uint8_t getSegmentsNum(void) const { return _segments.size(); } // returns currently present segments
|
||||
inline uint8_t getCurrSegmentId(void) const { return _segment_index; }
|
||||
inline uint8_t getMainSegmentId(void) const { return _mainSegment; }
|
||||
inline uint8_t getTargetFps() const { return _targetFps; }
|
||||
inline uint8_t getModeCount() const { return _modeCount; }
|
||||
inline static constexpr uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value)
|
||||
inline static constexpr uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } // will only return built-in palette count
|
||||
|
||||
uint16_t
|
||||
ablMilliampsMax,
|
||||
currentMilliamps,
|
||||
getLengthPhysical(void),
|
||||
__attribute__((pure)) getLengthTotal(void), // will include virtual/nonexistent pixels in matrix //WLEDMM attribute added
|
||||
getFps();
|
||||
getLengthPhysical(void) const,
|
||||
getLengthPhysical2(void) const, // WLEDMM total length including HUB75, network busses excluded
|
||||
__attribute__((pure)) getLengthTotal(void) const, // will include virtual/nonexistent pixels in matrix //WLEDMM attribute added
|
||||
getFps() const;
|
||||
|
||||
inline uint16_t getFrameTime(void) { return _frametime; }
|
||||
inline uint16_t getMinShowDelay(void) { return MIN_SHOW_DELAY; }
|
||||
inline uint16_t getLength(void) { return _length; } // 2D matrix may have less pixels than W*H
|
||||
inline uint16_t getTransition(void) { return _transitionDur; }
|
||||
inline uint16_t getFrameTime(void) const { return _frametime; }
|
||||
inline uint16_t getMinShowDelay(void) const { return MIN_SHOW_DELAY; }
|
||||
inline uint16_t getLength(void) const { return _length; } // 2D matrix may have less pixels than W*H
|
||||
inline uint16_t getTransition(void) const { return _transitionDur; }
|
||||
|
||||
uint32_t
|
||||
now,
|
||||
timebase;
|
||||
uint32_t __attribute__((pure)) getPixelColor(uint_fast16_t); // WLEDMM attribute pure = does not have side-effects
|
||||
uint32_t __attribute__((pure)) getPixelColor(uint_fast16_t) const; // WLEDMM attribute pure = does not have side-effects
|
||||
uint32_t __attribute__((pure)) getPixelColorRestored(uint_fast16_t i) const;// WLEDMM gets the original color from the driver (without downscaling by _bri)
|
||||
|
||||
inline uint32_t getLastShow(void) { return _lastShow; }
|
||||
inline uint32_t segColor(uint8_t i) { return _colors_t[i]; }
|
||||
inline uint32_t getLastShow(void) const { return _lastShow; }
|
||||
inline uint32_t segColor(uint8_t i) const { return _colors_t[i]; }
|
||||
|
||||
const char *
|
||||
getModeData(uint8_t id = 0) { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); }
|
||||
getModeData(uint8_t id = 0) const { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); }
|
||||
|
||||
const char **
|
||||
getModeDataSrc(void) { return &(_modeData[0]); } // vectors use arrays for underlying data
|
||||
|
||||
Segment& getSegment(uint8_t id);
|
||||
Segment& getSegment(uint8_t id) __attribute__((pure));
|
||||
inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; }
|
||||
inline Segment& getMainSegment(void) { return _segments[getMainSegmentId()]; }
|
||||
inline Segment* getSegments(void) { return &(_segments[0]); }
|
||||
@@ -993,7 +1055,7 @@ class WS2812FX { // 96 bytes
|
||||
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); }
|
||||
|
||||
uint32_t
|
||||
getPixelColorXY(uint16_t, uint16_t);
|
||||
getPixelColorXY(uint16_t, uint16_t) const;
|
||||
|
||||
// end 2D support
|
||||
|
||||
@@ -1008,6 +1070,8 @@ class WS2812FX { // 96 bytes
|
||||
std::vector<segment> _segments;
|
||||
friend class Segment;
|
||||
|
||||
uint32_t getPixelColorXYRestored(uint16_t x, uint16_t y) const; // WLEDMM gets the original color from the driver (without downscaling by _bri)
|
||||
|
||||
private:
|
||||
uint16_t _length;
|
||||
uint8_t _brightness;
|
||||
|
||||
Reference in New Issue
Block a user