Merge branch 'main' into gif-fix
This commit is contained in:
468
wled00/FX.h
468
wled00/FX.h
@@ -2,24 +2,10 @@
|
||||
WS2812FX.h - Library for WS2812 LED effects.
|
||||
Harm Aldick - 2016
|
||||
www.aldick.org
|
||||
LICENSE
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Harm Aldick
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Licensed under the EUPL v. 1.2 or later
|
||||
Adapted from code originally licensed under the MIT license
|
||||
|
||||
Modified for WLED
|
||||
*/
|
||||
@@ -30,6 +16,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "const.h"
|
||||
#include "bus_manager.h"
|
||||
|
||||
#define FASTLED_INTERNAL //remove annoying pragma messages
|
||||
#define USE_GET_MILLISECOND_TIMER
|
||||
@@ -56,16 +43,35 @@
|
||||
#define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b))))
|
||||
#endif
|
||||
|
||||
extern bool realtimeRespectLedMaps; // used in getMappedPixelIndex()
|
||||
extern byte realtimeMode; // used in getMappedPixelIndex()
|
||||
|
||||
/* Not used in all effects yet */
|
||||
#define WLED_FPS 42
|
||||
#define FRAMETIME_FIXED (1000/WLED_FPS)
|
||||
//#define FRAMETIME _frametime
|
||||
#define FRAMETIME strip.getFrameTime()
|
||||
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#define MIN_FRAME_DELAY 2 // minimum wait between repaints, to keep other functions like WiFi alive
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
#define MIN_FRAME_DELAY 3 // S2/C3 are slower than normal esp32, and only have one core
|
||||
#else
|
||||
#define MIN_FRAME_DELAY 8 // 8266 legacy MIN_SHOW_DELAY
|
||||
#endif
|
||||
#define FPS_UNLIMITED 0
|
||||
|
||||
// FPS calculation (can be defined as compile flag for debugging)
|
||||
#ifndef FPS_CALC_AVG
|
||||
#define FPS_CALC_AVG 7 // average FPS calculation over this many frames (moving average)
|
||||
#endif
|
||||
#ifndef FPS_MULTIPLIER
|
||||
#define FPS_MULTIPLIER 1 // dev option: multiplier to get sub-frame FPS without floats
|
||||
#endif
|
||||
#define FPS_CALC_SHIFT 7 // bit shift for fixed point math
|
||||
|
||||
/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of
|
||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||
#ifdef ESP8266
|
||||
#define MAX_NUM_SEGMENTS 12
|
||||
#define MAX_NUM_SEGMENTS 16
|
||||
/* How much data bytes all segments combined may allocate */
|
||||
#define MAX_SEGMENT_DATA 5120
|
||||
#else
|
||||
@@ -73,11 +79,7 @@
|
||||
#define MAX_NUM_SEGMENTS 32
|
||||
#endif
|
||||
#if defined(ARDUINO_ARCH_ESP32S2)
|
||||
#if defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
||||
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*1024 // 32k by default
|
||||
#else
|
||||
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*768 // 24k by default
|
||||
#endif
|
||||
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*768 // 24k by default (S2 is short on free RAM)
|
||||
#else
|
||||
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*1280 // 40k by default
|
||||
#endif
|
||||
@@ -87,16 +89,14 @@
|
||||
assuming each segment uses the same amount of data. 256 for ESP8266, 640 for ESP32. */
|
||||
#define FAIR_DATA_PER_SEG (MAX_SEGMENT_DATA / strip.getMaxSegments())
|
||||
|
||||
#define MIN_SHOW_DELAY (_frametime < 16 ? 8 : 15)
|
||||
|
||||
#define NUM_COLORS 3 /* number of colors per segment */
|
||||
#define SEGMENT strip._segments[strip.getCurrSegmentId()]
|
||||
#define SEGENV strip._segments[strip.getCurrSegmentId()]
|
||||
//#define SEGCOLOR(x) strip._segments[strip.getCurrSegmentId()].currentColor(x, strip._segments[strip.getCurrSegmentId()].colors[x])
|
||||
//#define SEGLEN strip._segments[strip.getCurrSegmentId()].virtualLength()
|
||||
#define SEGCOLOR(x) strip.segColor(x) /* saves us a few kbytes of code */
|
||||
#define SEGPALETTE strip._currentPalette
|
||||
#define SEGLEN strip._virtualSegmentLength /* saves us a few kbytes of code */
|
||||
#define SEGCOLOR(x) Segment::getCurrentColor(x)
|
||||
#define SEGPALETTE Segment::getCurrentPalette()
|
||||
#define SEGLEN Segment::vLength()
|
||||
#define SEG_W Segment::vWidth()
|
||||
#define SEG_H Segment::vHeight()
|
||||
#define SPEED_FORMULA_L (5U + (50U*(255U - SEGMENT.speed))/SEGLEN)
|
||||
|
||||
// some common colors
|
||||
@@ -111,6 +111,10 @@
|
||||
#define PURPLE (uint32_t)0x400080
|
||||
#define ORANGE (uint32_t)0xFF3000
|
||||
#define PINK (uint32_t)0xFF1493
|
||||
#define GREY (uint32_t)0x808080
|
||||
#define GRAY GREY
|
||||
#define DARKGREY (uint32_t)0x333333
|
||||
#define DARKGRAY DARKGREY
|
||||
#define ULTRAWHITE (uint32_t)0xFFFFFFFF
|
||||
#define DARKSLATEGRAY (uint32_t)0x2F4F4F
|
||||
#define DARKSLATEGREY DARKSLATEGRAY
|
||||
@@ -180,14 +184,14 @@
|
||||
#define FX_MODE_TWO_DOTS 50
|
||||
#define FX_MODE_FAIRYTWINKLE 51 //was Two Areas prior to 0.13.0-b6 (use "Two Dots" with full intensity)
|
||||
#define FX_MODE_RUNNING_DUAL 52
|
||||
#define FX_MODE_IMAGE 53 // was Halloween before 0.14
|
||||
#define FX_MODE_IMAGE 53
|
||||
#define FX_MODE_TRICOLOR_CHASE 54
|
||||
#define FX_MODE_TRICOLOR_WIPE 55
|
||||
#define FX_MODE_TRICOLOR_FADE 56
|
||||
#define FX_MODE_LIGHTNING 57
|
||||
#define FX_MODE_ICU 58
|
||||
#define FX_MODE_MULTI_COMET 59
|
||||
#define FX_MODE_DUAL_LARSON_SCANNER 60
|
||||
#define FX_MODE_DUAL_LARSON_SCANNER 60 // candidate for removal (use Scanner with with check 1)
|
||||
#define FX_MODE_RANDOM_CHASE 61
|
||||
#define FX_MODE_OSCILLATE 62
|
||||
#define FX_MODE_PRIDE_2015 63
|
||||
@@ -204,7 +208,7 @@
|
||||
#define FX_MODE_COLORTWINKLE 74
|
||||
#define FX_MODE_LAKE 75
|
||||
#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_RIPPLE 79
|
||||
#define FX_MODE_TWINKLEFOX 80
|
||||
@@ -325,7 +329,8 @@ typedef enum mapping1D2D {
|
||||
M12_Pixels = 0,
|
||||
M12_pBar = 1,
|
||||
M12_pArc = 2,
|
||||
M12_pCorner = 3
|
||||
M12_pCorner = 3,
|
||||
M12_sPinwheel = 4
|
||||
} mapping1D2D_t;
|
||||
|
||||
// segment, 80 bytes
|
||||
@@ -368,6 +373,7 @@ typedef struct Segment {
|
||||
};
|
||||
uint8_t startY; // start Y coodrinate 2D (top); there should be no more than 255 rows
|
||||
uint8_t stopY; // stop Y coordinate 2D (bottom); there should be no more than 255 rows
|
||||
// note: two bytes of padding are added here
|
||||
char *name;
|
||||
|
||||
// runtime data
|
||||
@@ -396,7 +402,7 @@ typedef struct Segment {
|
||||
uint32_t _stepT;
|
||||
uint32_t _callT;
|
||||
uint8_t *_dataT;
|
||||
uint16_t _dataLenT;
|
||||
unsigned _dataLenT;
|
||||
TemporarySegmentData()
|
||||
: _dataT(nullptr) // just in case...
|
||||
, _dataLenT(0)
|
||||
@@ -414,14 +420,20 @@ typedef struct Segment {
|
||||
uint8_t _reserved : 4;
|
||||
};
|
||||
};
|
||||
uint16_t _dataLen;
|
||||
static uint16_t _usedSegmentData;
|
||||
|
||||
// perhaps this should be per segment, not static
|
||||
uint8_t _default_palette; // palette number that gets assigned to pal0
|
||||
unsigned _dataLen;
|
||||
static unsigned _usedSegmentData;
|
||||
static uint8_t _segBri; // brightness of segment for current effect
|
||||
static unsigned _vLength; // 1D dimension used for current effect
|
||||
static unsigned _vWidth, _vHeight; // 2D dimensions used for current effect
|
||||
static uint32_t _currentColors[NUM_COLORS]; // colors used for current effect
|
||||
static bool _colorScaled; // color has been scaled prior to setPixelColor() call
|
||||
static CRGBPalette16 _currentPalette; // palette used for current effect (includes transition, used in color_from_palette())
|
||||
static CRGBPalette16 _randomPalette; // actual random palette
|
||||
static CRGBPalette16 _newRandomPalette; // target random palette
|
||||
static uint16_t _lastPaletteChange; // last random palette change time in millis()/1000
|
||||
static uint16_t _lastPaletteBlend; // blend palette according to set Transition Delay in millis()%0xFFFF
|
||||
static uint16_t _transitionprogress; // current transition progress 0 - 0xFFFF
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
static bool _modeBlend; // mode/effect blending semaphore
|
||||
#endif
|
||||
@@ -448,6 +460,8 @@ typedef struct Segment {
|
||||
{}
|
||||
} *_t;
|
||||
|
||||
[[gnu::hot]] void _setPixelColorXY_raw(int& x, int& y, uint32_t& col); // set pixel without mapping (internal use only)
|
||||
|
||||
public:
|
||||
|
||||
Segment(uint16_t sStart=0, uint16_t sStop=30) :
|
||||
@@ -480,6 +494,7 @@ typedef struct Segment {
|
||||
aux1(0),
|
||||
data(nullptr),
|
||||
_capabilities(0),
|
||||
_default_palette(0),
|
||||
_dataLen(0),
|
||||
_t(nullptr)
|
||||
{
|
||||
@@ -516,154 +531,187 @@ typedef struct Segment {
|
||||
#endif
|
||||
|
||||
inline bool getOption(uint8_t n) const { return ((options >> n) & 0x01); }
|
||||
inline bool isSelected(void) const { return selected; }
|
||||
inline bool isInTransition(void) const { return _t != nullptr; }
|
||||
inline bool isActive(void) const { return stop > start; }
|
||||
inline bool is2D(void) const { return (width()>1 && height()>1); }
|
||||
inline bool hasRGB(void) const { return _isRGB; }
|
||||
inline bool hasWhite(void) const { return _hasW; }
|
||||
inline bool isCCT(void) const { return _isCCT; }
|
||||
inline uint16_t width(void) const { return isActive() ? (stop - start) : 0; } // segment width in physical pixels (length if 1D)
|
||||
inline uint16_t height(void) const { return stopY - startY; } // segment height (if 2D) in physical pixels (it *is* always >=1)
|
||||
inline uint16_t length(void) const { return width() * height(); } // segment length (count) in physical pixels
|
||||
inline uint16_t groupLength(void) const { return grouping + spacing; }
|
||||
inline uint8_t getLightCapabilities(void) const { return _capabilities; }
|
||||
inline bool isSelected() const { return selected; }
|
||||
inline bool isInTransition() const { return _t != nullptr; }
|
||||
inline bool isActive() const { return stop > start; }
|
||||
inline bool is2D() const { return (width()>1 && height()>1); }
|
||||
inline bool hasRGB() const { return _isRGB; }
|
||||
inline bool hasWhite() const { return _hasW; }
|
||||
inline bool isCCT() const { return _isCCT; }
|
||||
inline uint16_t width() const { return isActive() ? (stop - start) : 0; } // segment width in physical pixels (length if 1D)
|
||||
inline uint16_t height() const { return stopY - startY; } // segment height (if 2D) in physical pixels (it *is* always >=1)
|
||||
inline uint16_t length() const { return width() * height(); } // segment length (count) in physical pixels
|
||||
inline uint16_t groupLength() const { return grouping + spacing; }
|
||||
inline uint8_t getLightCapabilities() const { return _capabilities; }
|
||||
inline void deactivate() { setGeometry(0,0); }
|
||||
|
||||
static uint16_t getUsedSegmentData(void) { return _usedSegmentData; }
|
||||
static void addUsedSegmentData(int len) { _usedSegmentData += len; }
|
||||
inline static unsigned getUsedSegmentData() { return Segment::_usedSegmentData; }
|
||||
inline static void addUsedSegmentData(int len) { Segment::_usedSegmentData += len; }
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
static void modeBlend(bool blend) { _modeBlend = blend; }
|
||||
inline static void modeBlend(bool blend) { _modeBlend = blend; }
|
||||
#endif
|
||||
static void handleRandomPalette();
|
||||
inline static unsigned vLength() { return Segment::_vLength; }
|
||||
inline static unsigned vWidth() { return Segment::_vWidth; }
|
||||
inline static unsigned vHeight() { return Segment::_vHeight; }
|
||||
inline static uint32_t getCurrentColor(unsigned i) { return Segment::_currentColors[i]; } // { return i < 3 ? Segment::_currentColors[i] : 0; }
|
||||
inline static const CRGBPalette16 &getCurrentPalette() { return Segment::_currentPalette; }
|
||||
inline static uint8_t getCurrentBrightness() { return Segment::_segBri; }
|
||||
static void handleRandomPalette();
|
||||
|
||||
void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1);
|
||||
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
|
||||
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 setPalette(uint8_t pal);
|
||||
uint8_t differs(Segment& b) const;
|
||||
void refreshLightCapabilities(void);
|
||||
void beginDraw(); // set up parameters for current effect
|
||||
void setGeometry(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1, uint8_t m12=0);
|
||||
Segment &setColor(uint8_t slot, uint32_t c);
|
||||
Segment &setCCT(uint16_t k);
|
||||
Segment &setOpacity(uint8_t o);
|
||||
Segment &setOption(uint8_t n, bool val);
|
||||
Segment &setMode(uint8_t fx, bool loadDefaults = false);
|
||||
Segment &setPalette(uint8_t pal);
|
||||
uint8_t differs(const Segment& b) const;
|
||||
void refreshLightCapabilities();
|
||||
|
||||
// runtime data functions
|
||||
inline uint16_t dataSize(void) const { return _dataLen; }
|
||||
inline uint16_t dataSize() const { return _dataLen; }
|
||||
bool allocateData(size_t len); // allocates effect data buffer in heap and clears it
|
||||
void deallocateData(void); // deallocates (frees) effect data buffer from heap
|
||||
void resetIfRequired(void); // sets all SEGENV variables to 0 and clears data buffer
|
||||
void deallocateData(); // deallocates (frees) effect data buffer from heap
|
||||
void resetIfRequired(); // sets all SEGENV variables to 0 and clears data buffer
|
||||
/**
|
||||
* 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(void) { reset = true; } // setOption(SEG_OPTION_RESET, true)
|
||||
inline Segment &markForReset() { reset = true; return *this; } // setOption(SEG_OPTION_RESET, true)
|
||||
|
||||
// transition functions
|
||||
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
||||
void stopTransition(void); // ends transition mode by destroying transition structure
|
||||
void handleTransition(void);
|
||||
void stopTransition(); // ends transition mode by destroying transition structure (does nothing if not in transition)
|
||||
inline void handleTransition() { updateTransitionProgress(); if (progress() == 0xFFFFU) stopTransition(); }
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
void swapSegenv(tmpsegd_t &tmpSegD); // copies segment data into specifed buffer, if buffer is not a transition buffer, segment data is overwritten from transition buffer
|
||||
void restoreSegenv(tmpsegd_t &tmpSegD); // restores segment data from buffer, if buffer is not transition buffer, changed values are copied to transition buffer
|
||||
#endif
|
||||
uint16_t progress(void); // transition progression between 0-65535
|
||||
uint8_t currentBri(bool useCct = false); // current segment brightness/CCT (blended while in transition)
|
||||
uint8_t currentMode(void); // currently active effect/mode (while in transition)
|
||||
uint32_t currentColor(uint8_t slot); // currently active segment color (blended while in transition)
|
||||
[[gnu::hot]] void updateTransitionProgress(); // set current progression of transition
|
||||
inline uint16_t progress() const { return _transitionprogress; }; // transition progression between 0-65535
|
||||
[[gnu::hot]] uint8_t currentBri(bool useCct = false) const; // current segment brightness/CCT (blended while in transition)
|
||||
uint8_t currentMode() const; // currently active effect/mode (while in transition)
|
||||
[[gnu::hot]] uint32_t currentColor(uint8_t slot) const; // currently active segment color (blended while in transition)
|
||||
CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal);
|
||||
CRGBPalette16 ¤tPalette(CRGBPalette16 &tgt, uint8_t paletteID);
|
||||
|
||||
// 1D strip
|
||||
uint16_t virtualLength(void) const;
|
||||
void setPixelColor(int n, uint32_t c); // set relative pixel within segment with color
|
||||
[[gnu::hot]] uint16_t virtualLength() const;
|
||||
[[gnu::hot]] void setPixelColor(int n, uint32_t c); // set relative pixel within segment with color
|
||||
inline void setPixelColor(unsigned n, uint32_t c) { setPixelColor(int(n), c); }
|
||||
inline void setPixelColor(int n, byte r, byte g, byte b, byte w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColor(int n, CRGB c) { setPixelColor(n, RGBW32(c.r,c.g,c.b,0)); }
|
||||
#ifdef WLED_USE_AA_PIXELS
|
||||
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 getPixelColor(int i);
|
||||
#endif
|
||||
[[gnu::hot]] uint32_t getPixelColor(int i) const;
|
||||
// 1D support functions (some implement 2D as well)
|
||||
void blur(uint8_t);
|
||||
void blur(uint8_t, bool smear = false);
|
||||
void fill(uint32_t c);
|
||||
void fade_out(uint8_t r);
|
||||
void fadeToBlackBy(uint8_t fadeBy);
|
||||
inline void blendPixelColor(int n, uint32_t color, uint8_t blend) { setPixelColor(n, color_blend(getPixelColor(n), color, blend)); }
|
||||
inline void blendPixelColor(int n, CRGB c, uint8_t blend) { blendPixelColor(n, RGBW32(c.r,c.g,c.b,0), blend); }
|
||||
inline void addPixelColor(int n, uint32_t color, bool fast = false) { setPixelColor(n, color_add(getPixelColor(n), color, fast)); }
|
||||
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); }
|
||||
inline void addPixelColor(int n, CRGB c, bool fast = false) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), fast); }
|
||||
inline void addPixelColor(int n, uint32_t color, bool preserveCR = true) { setPixelColor(n, color_add(getPixelColor(n), color, preserveCR)); }
|
||||
inline void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool preserveCR = true) { addPixelColor(n, RGBW32(r,g,b,w), preserveCR); }
|
||||
inline void addPixelColor(int n, CRGB c, bool preserveCR = true) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), preserveCR); }
|
||||
inline void fadePixelColor(uint16_t n, uint8_t fade) { setPixelColor(n, color_fade(getPixelColor(n), fade, true)); }
|
||||
uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255);
|
||||
uint32_t color_wheel(uint8_t pos);
|
||||
[[gnu::hot]] uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255) const;
|
||||
[[gnu::hot]] uint32_t color_wheel(uint8_t pos) const;
|
||||
|
||||
// 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
|
||||
blur2D(0, blur_amount, smear);
|
||||
}
|
||||
inline void blurRows(fract8 blur_amount, bool smear = false) { // blur all rows
|
||||
blur2D(blur_amount, 0, smear);
|
||||
}
|
||||
|
||||
// 2D matrix
|
||||
uint16_t virtualWidth(void) const; // segment width in virtual pixels (accounts for groupping and spacing)
|
||||
uint16_t virtualHeight(void) const; // segment height in virtual pixels (accounts for groupping and spacing)
|
||||
uint16_t nrOfVStrips(void) const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
|
||||
[[gnu::hot]] unsigned virtualWidth() const; // segment width in virtual pixels (accounts for groupping and spacing)
|
||||
[[gnu::hot]] unsigned virtualHeight() const; // segment height in virtual pixels (accounts for groupping and spacing)
|
||||
inline unsigned nrOfVStrips() const { // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
|
||||
#ifndef WLED_DISABLE_2D
|
||||
return (is2D() && map1D2D == M12_pBar) ? virtualWidth() : 1;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
#ifndef WLED_DISABLE_2D
|
||||
uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment
|
||||
void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
|
||||
[[gnu::hot]] uint16_t XY(int x, int y); // support function to get relative index within segment
|
||||
[[gnu::hot]] void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
|
||||
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)); }
|
||||
inline void setPixelColorXY(unsigned x, unsigned y, CRGB c) { setPixelColorXY(int(x), int(y), RGBW32(c.r,c.g,c.b,0)); }
|
||||
#ifdef WLED_USE_AA_PIXELS
|
||||
void setPixelColorXY(float x, float y, uint32_t c, bool aa = true);
|
||||
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); }
|
||||
uint32_t getPixelColorXY(uint16_t x, uint16_t y);
|
||||
#endif
|
||||
[[gnu::hot]] uint32_t getPixelColorXY(int x, int y) const;
|
||||
// 2D support functions
|
||||
inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, 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); }
|
||||
inline void addPixelColorXY(int x, int y, uint32_t color, bool fast = false) { setPixelColorXY(x, y, color_add(getPixelColorXY(x,y), color, fast)); }
|
||||
inline void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColorXY(x, y, RGBW32(r,g,b,w), fast); }
|
||||
inline void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), fast); }
|
||||
inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), fade, true)); }
|
||||
void box_blur(uint16_t i, bool vertical, fract8 blur_amount); // 1D box blur (with weight)
|
||||
void blurRow(uint16_t row, fract8 blur_amount);
|
||||
void blurCol(uint16_t col, fract8 blur_amount);
|
||||
void moveX(int8_t delta, bool wrap = false);
|
||||
void moveY(int8_t delta, bool wrap = false);
|
||||
void move(uint8_t dir, uint8_t delta, bool wrap = false);
|
||||
void draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c);
|
||||
void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c);
|
||||
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c);
|
||||
inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.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, int8_t rotate = 0);
|
||||
inline void addPixelColorXY(int x, int y, uint32_t color, bool preserveCR = true) { setPixelColorXY(x, y, color_add(getPixelColorXY(x,y), color, preserveCR)); }
|
||||
inline void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool preserveCR = true) { addPixelColorXY(x, y, RGBW32(r,g,b,w), preserveCR); }
|
||||
inline void addPixelColorXY(int x, int y, CRGB c, bool preserveCR = true) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), preserveCR); }
|
||||
inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), fade, true)); }
|
||||
//void box_blur(unsigned r = 1U, bool smear = false); // 2D box blur
|
||||
void blur2D(uint8_t blur_x, uint8_t blur_y, bool smear = false);
|
||||
void moveX(int delta, bool wrap = false);
|
||||
void moveY(int delta, bool wrap = false);
|
||||
void move(unsigned dir, unsigned 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 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
|
||||
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, 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 blur1d(fract8 blur_amount); // blur all rows in 1 dimension
|
||||
inline void blur2d(fract8 blur_amount) { blur(blur_amount); }
|
||||
inline void fill_solid(CRGB c) { fill(RGBW32(c.r,c.g,c.b,0)); }
|
||||
void nscale8(uint8_t scale);
|
||||
#else
|
||||
inline uint16_t XY(uint16_t x, uint16_t y) { return x; }
|
||||
inline uint16_t XY(int x, int y) { return x; }
|
||||
inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(x, c); }
|
||||
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColor(int(x), c); }
|
||||
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColor(x, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0)); }
|
||||
inline void setPixelColorXY(unsigned x, unsigned y, CRGB c) { setPixelColor(int(x), RGBW32(c.r,c.g,c.b,0)); }
|
||||
#ifdef WLED_USE_AA_PIXELS
|
||||
inline void setPixelColorXY(float x, float y, uint32_t c, bool aa = true) { setPixelColor(x, c, aa); }
|
||||
inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColor(x, RGBW32(r,g,b,w), aa); }
|
||||
inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0), aa); }
|
||||
inline uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(x); }
|
||||
#endif
|
||||
inline uint32_t getPixelColorXY(int x, int y) { return getPixelColor(x); }
|
||||
inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t c, uint8_t blend) { blendPixelColor(x, c, blend); }
|
||||
inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColor(x, RGBW32(c.r,c.g,c.b,0), blend); }
|
||||
inline void addPixelColorXY(int x, int y, uint32_t color, bool fast = false) { addPixelColor(x, color, fast); }
|
||||
inline void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(x, RGBW32(r,g,b,w), fast); }
|
||||
inline void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColor(x, RGBW32(c.r,c.g,c.b,0), fast); }
|
||||
inline void addPixelColorXY(int x, int y, uint32_t color, bool saturate = false) { addPixelColor(x, color, saturate); }
|
||||
inline void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool saturate = false) { addPixelColor(x, RGBW32(r,g,b,w), saturate); }
|
||||
inline void addPixelColorXY(int x, int y, CRGB c, bool saturate = false) { addPixelColor(x, RGBW32(c.r,c.g,c.b,0), saturate); }
|
||||
inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { fadePixelColor(x, fade); }
|
||||
inline void box_blur(uint16_t i, bool vertical, fract8 blur_amount) {}
|
||||
inline void blurRow(uint16_t row, fract8 blur_amount) {}
|
||||
inline void blurCol(uint16_t col, fract8 blur_amount) {}
|
||||
inline void moveX(int8_t delta, bool wrap = false) {}
|
||||
inline void moveY(int8_t delta, bool wrap = false) {}
|
||||
//inline void box_blur(unsigned i, bool vertical, fract8 blur_amount) {}
|
||||
inline void blur2D(uint8_t blur_x, uint8_t blur_y, bool smear = false) {}
|
||||
inline void blurRow(int row, fract8 blur_amount, bool smear = false) {}
|
||||
inline void blurCol(int col, fract8 blur_amount, bool smear = false) {}
|
||||
inline void moveX(int delta, bool wrap = false) {}
|
||||
inline void moveY(int delta, bool wrap = false) {}
|
||||
inline void move(uint8_t dir, uint8_t delta, bool wrap = false) {}
|
||||
inline void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c) {}
|
||||
inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) {}
|
||||
inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) {}
|
||||
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 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) {}
|
||||
inline 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) {}
|
||||
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 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 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) {}
|
||||
#endif
|
||||
} segment;
|
||||
@@ -671,8 +719,8 @@ typedef struct Segment {
|
||||
|
||||
// main "strip" class
|
||||
class WS2812FX { // 96 bytes
|
||||
typedef uint16_t (*mode_ptr)(void); // pointer to mode function
|
||||
typedef void (*show_callback)(void); // pre show callback
|
||||
typedef uint16_t (*mode_ptr)(); // pointer to mode function
|
||||
typedef void (*show_callback)(); // pre show callback
|
||||
typedef struct ModeData {
|
||||
uint8_t _id; // mode (effect) id
|
||||
mode_ptr _fcn; // mode (effect) function
|
||||
@@ -694,10 +742,13 @@ class WS2812FX { // 96 bytes
|
||||
#ifndef WLED_DISABLE_2D
|
||||
panels(1),
|
||||
#endif
|
||||
// semi-private (just obscured) used in effect functions through macros
|
||||
_currentPalette(CRGBPalette16(CRGB::Black)),
|
||||
_colors_t{0,0,0},
|
||||
_virtualSegmentLength(0),
|
||||
#ifdef WLED_AUTOSEGMENTS
|
||||
autoSegments(true),
|
||||
#else
|
||||
autoSegments(false),
|
||||
#endif
|
||||
correctWB(false),
|
||||
cctFromRgb(false),
|
||||
// true private variables
|
||||
_suspend(false),
|
||||
_length(DEFAULT_LED_COUNT),
|
||||
@@ -705,7 +756,7 @@ class WS2812FX { // 96 bytes
|
||||
_transitionDur(750),
|
||||
_targetFps(WLED_FPS),
|
||||
_frametime(FRAMETIME_FIXED),
|
||||
_cumulativeFps(2),
|
||||
_cumulativeFps(50 << FPS_CALC_SHIFT),
|
||||
_isServicing(false),
|
||||
_isOffRefreshRequired(false),
|
||||
_hasWhiteChannel(false),
|
||||
@@ -715,16 +766,9 @@ class WS2812FX { // 96 bytes
|
||||
customMappingTable(nullptr),
|
||||
customMappingSize(0),
|
||||
_lastShow(0),
|
||||
_lastServiceShow(0),
|
||||
_segment_index(0),
|
||||
_mainSegment(0),
|
||||
_queuedChangesSegId(255),
|
||||
_qStart(0),
|
||||
_qStop(0),
|
||||
_qStartY(0),
|
||||
_qStopY(0),
|
||||
_qGrouping(0),
|
||||
_qSpacing(0),
|
||||
_qOffset(0)
|
||||
_mainSegment(0)
|
||||
{
|
||||
WS2812FX::instance = this;
|
||||
_mode.reserve(_modeCount); // allocate memory to prevent initial fragmentation (does not increase size())
|
||||
@@ -744,112 +788,105 @@ class WS2812FX { // 96 bytes
|
||||
customPalettes.clear();
|
||||
}
|
||||
|
||||
static WS2812FX* getInstance(void) { return instance; }
|
||||
static WS2812FX* getInstance() { return instance; }
|
||||
|
||||
void
|
||||
#ifdef WLED_DEBUG
|
||||
printSize(), // prints memory usage for strip components
|
||||
#endif
|
||||
finalizeInit(), // initialises strip components
|
||||
service(void), // executes effect functions when due and calls strip.show()
|
||||
setMode(uint8_t segid, uint8_t m), // sets effect/mode for given segment (high level API)
|
||||
setColor(uint8_t slot, uint32_t c), // sets color (in slot) for given segment (high level API)
|
||||
service(), // executes effect functions when due and calls strip.show()
|
||||
setCCT(uint16_t k), // sets global CCT (either in relative 0-255 value or in K)
|
||||
setBrightness(uint8_t b, bool direct = false), // sets strip brightness
|
||||
setRange(uint16_t i, uint16_t i2, uint32_t col), // used for clock overlay
|
||||
purgeSegments(void), // removes inactive segments from RAM (may incure penalty and memory fragmentation but reduces vector footprint)
|
||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 1, uint8_t spacing = 0, uint16_t offset = UINT16_MAX, uint16_t startY=0, uint16_t stopY=1),
|
||||
setMainSegmentId(uint8_t n),
|
||||
purgeSegments(), // removes inactive segments from RAM (may incure penalty and memory fragmentation but reduces vector footprint)
|
||||
setMainSegmentId(unsigned n = 0),
|
||||
resetSegments(), // marks all segments for reset
|
||||
makeAutoSegments(bool forceReset = false), // will create segments based on configured outputs
|
||||
fixInvalidSegments(), // fixes incorrect segment configuration
|
||||
setPixelColor(unsigned n, uint32_t c), // paints absolute strip pixel with index n and color c
|
||||
show(void), // initiates LED output
|
||||
setTargetFps(uint8_t fps),
|
||||
addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name), // add effect to the list; defined in FX.cpp
|
||||
setupEffectData(void); // add default effects to the list; defined in FX.cpp
|
||||
show(), // initiates LED output
|
||||
setTargetFps(unsigned fps),
|
||||
setupEffectData(); // add default effects to the list; defined in FX.cpp
|
||||
|
||||
inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); }
|
||||
inline void resetTimebase() { timebase = 0UL - millis(); }
|
||||
inline void restartRuntime() { for (Segment &seg : _segments) { seg.markForReset().resetIfRequired(); } }
|
||||
inline void setTransitionMode(bool t) { for (Segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); }
|
||||
inline void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColor(unsigned n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColor(unsigned n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); }
|
||||
inline void fill(uint32_t c) { for (unsigned i = 0; i < getLengthTotal(); i++) setPixelColor(i, c); } // fill whole strip with color (inline)
|
||||
inline void trigger(void) { _triggered = true; } // Forces the next frame to be computed on all active segments.
|
||||
inline void trigger() { _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; } // sets transition time (in ms)
|
||||
inline void appendSegment(const Segment &seg = Segment()) { if (_segments.size() < getMaxSegments()) _segments.push_back(seg); }
|
||||
inline void suspend(void) { _suspend = true; } // will suspend (and canacel) strip.service() execution
|
||||
inline void resume(void) { _suspend = false; } // will resume strip.service() execution
|
||||
inline void suspend() { _suspend = true; } // will suspend (and canacel) strip.service() execution
|
||||
inline void resume() { _suspend = false; } // will resume strip.service() execution
|
||||
|
||||
bool
|
||||
paletteFade,
|
||||
checkSegmentAlignment(void),
|
||||
hasRGBWBus(void),
|
||||
hasCCTBus(void),
|
||||
// return true if the strip is being sent pixel updates
|
||||
isUpdating(void),
|
||||
deserializeMap(uint8_t n=0);
|
||||
checkSegmentAlignment(),
|
||||
hasRGBWBus() const,
|
||||
hasCCTBus() const,
|
||||
deserializeMap(unsigned n = 0);
|
||||
|
||||
inline bool isServicing(void) { return _isServicing; } // returns true if strip.service() is executing
|
||||
inline bool hasWhiteChannel(void) { return _hasWhiteChannel; } // returns true if strip contains separate white chanel
|
||||
inline bool isOffRefreshRequired(void) { return _isOffRefreshRequired; } // returns true if strip requires regular updates (i.e. TM1814 chipset)
|
||||
inline bool isSuspended(void) { return _suspend; } // returns true if strip.service() execution is suspended
|
||||
inline bool needsUpdate(void) { return _triggered; } // returns true if strip received a trigger() request
|
||||
inline bool isUpdating() const { return !BusManager::canAllShow(); } // return true if the strip is being sent pixel updates
|
||||
inline bool isServicing() const { return _isServicing; } // returns true if strip.service() is executing
|
||||
inline bool hasWhiteChannel() const { return _hasWhiteChannel; } // returns true if strip contains separate white chanel
|
||||
inline bool isOffRefreshRequired() const { return _isOffRefreshRequired; } // returns true if strip requires regular updates (i.e. TM1814 chipset)
|
||||
inline bool isSuspended() const { return _suspend; } // returns true if strip.service() execution is suspended
|
||||
inline bool needsUpdate() const { return _triggered; } // returns true if strip received a trigger() request
|
||||
|
||||
uint8_t
|
||||
paletteBlend,
|
||||
cctBlending,
|
||||
getActiveSegmentsNum(void),
|
||||
getFirstSelectedSegId(void),
|
||||
getLastActiveSegmentId(void),
|
||||
getActiveSegsLightCapabilities(bool selectedOnly = false);
|
||||
getActiveSegmentsNum() const,
|
||||
getFirstSelectedSegId() const,
|
||||
getLastActiveSegmentId() const,
|
||||
getActiveSegsLightCapabilities(bool selectedOnly = false) const,
|
||||
addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name); // add effect to the list; defined in FX.cpp;
|
||||
|
||||
inline uint8_t getBrightness(void) { return _brightness; } // returns current strip 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; } // returns current segment index (only valid while strip.isServicing())
|
||||
inline uint8_t getMainSegmentId(void) { return _mainSegment; } // returns main segment index
|
||||
inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } // will only return built-in palette count
|
||||
inline uint8_t getTargetFps() { return _targetFps; } // returns rough FPS value for las 2s interval
|
||||
inline uint8_t getModeCount() { return _modeCount; } // returns number of registered modes/effects
|
||||
inline uint8_t getBrightness() const { return _brightness; } // returns current strip brightness
|
||||
inline static constexpr unsigned getMaxSegments() { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value)
|
||||
inline uint8_t getSegmentsNum() const { return _segments.size(); } // returns currently present segments
|
||||
inline uint8_t getCurrSegmentId() const { return _segment_index; } // returns current segment index (only valid while strip.isServicing())
|
||||
inline uint8_t getMainSegmentId() const { return _mainSegment; } // returns main segment index
|
||||
inline uint8_t getPaletteCount() const { return 13 + GRADIENT_PALETTE_COUNT + customPalettes.size(); }
|
||||
inline uint8_t getTargetFps() const { return _targetFps; } // returns rough FPS value for las 2s interval
|
||||
inline uint8_t getModeCount() const { return _modeCount; } // returns number of registered modes/effects
|
||||
|
||||
uint16_t
|
||||
getLengthPhysical(void),
|
||||
getLengthTotal(void), // will include virtual/nonexistent pixels in matrix
|
||||
getFps(),
|
||||
getMappedPixelIndex(uint16_t index);
|
||||
getLengthPhysical() const,
|
||||
getLengthTotal() const; // will include virtual/nonexistent pixels in matrix
|
||||
|
||||
inline uint16_t getFrameTime(void) { return _frametime; } // returns amount of time a frame should take (in ms)
|
||||
inline uint16_t getMinShowDelay(void) { return MIN_SHOW_DELAY; } // returns minimum amount of time strip.service() can be delayed (constant)
|
||||
inline uint16_t getLength(void) { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H)
|
||||
inline uint16_t getTransition(void) { return _transitionDur; } // returns currently set transition time (in ms)
|
||||
inline uint16_t getFps() const { return (millis() - _lastShow > 2000) ? 0 : (FPS_MULTIPLIER * _cumulativeFps) >> FPS_CALC_SHIFT; } // Returns the refresh rate of the LED strip (_cumulativeFps is stored in fixed point)
|
||||
inline uint16_t getFrameTime() const { return _frametime; } // returns amount of time a frame should take (in ms)
|
||||
inline uint16_t getMinShowDelay() const { return MIN_FRAME_DELAY; } // returns minimum amount of time strip.service() can be delayed (constant)
|
||||
inline uint16_t getLength() const { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H)
|
||||
inline uint16_t getTransition() const { return _transitionDur; } // returns currently set transition time (in ms)
|
||||
inline uint16_t getMappedPixelIndex(uint16_t index) const { // convert logical address to physical
|
||||
if (index < customMappingSize && (realtimeMode == REALTIME_MODE_INACTIVE || realtimeRespectLedMaps)) index = customMappingTable[index];
|
||||
return index;
|
||||
};
|
||||
|
||||
uint32_t
|
||||
now,
|
||||
timebase,
|
||||
getPixelColor(uint16_t);
|
||||
unsigned long now, timebase;
|
||||
uint32_t getPixelColor(unsigned) const;
|
||||
|
||||
inline uint32_t getLastShow(void) { return _lastShow; } // returns millis() timestamp of last strip.show() call
|
||||
inline uint32_t segColor(uint8_t i) { return _colors_t[i]; } // returns currently valid color (for slot i) AKA SEGCOLOR(); may be blended between two colors while in transition
|
||||
inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call
|
||||
|
||||
const char *
|
||||
getModeData(uint8_t id = 0) { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); }
|
||||
const char *getModeData(unsigned id = 0) const { return (id && id < _modeCount) ? _modeData[id] : PSTR("Solid"); }
|
||||
inline const char **getModeDataSrc() { return &(_modeData[0]); } // vectors use arrays for underlying data
|
||||
|
||||
const char **
|
||||
getModeDataSrc(void) { return &(_modeData[0]); } // vectors use arrays for underlying data
|
||||
|
||||
Segment& getSegment(uint8_t id);
|
||||
inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; } // returns reference to first segment that is "selected"
|
||||
inline Segment& getMainSegment(void) { return _segments[getMainSegmentId()]; } // returns reference to main segment
|
||||
inline Segment* getSegments(void) { return &(_segments[0]); } // returns pointer to segment vector structure (warning: use carefully)
|
||||
Segment& getSegment(unsigned id);
|
||||
inline Segment& getFirstSelectedSeg() { return _segments[getFirstSelectedSegId()]; } // returns reference to first segment that is "selected"
|
||||
inline Segment& getMainSegment() { return _segments[getMainSegmentId()]; } // returns reference to main segment
|
||||
inline Segment* getSegments() { return &(_segments[0]); } // returns pointer to segment vector structure (warning: use carefully)
|
||||
|
||||
// 2D support (panels)
|
||||
bool
|
||||
isMatrix;
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
#define WLED_MAX_PANELS 64
|
||||
#define WLED_MAX_PANELS 18
|
||||
uint8_t
|
||||
panels;
|
||||
|
||||
@@ -885,18 +922,18 @@ class WS2812FX { // 96 bytes
|
||||
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)); }
|
||||
|
||||
inline uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(isMatrix ? y * Segment::maxWidth + x : x);}
|
||||
inline uint32_t getPixelColorXY(int x, int y) const { return getPixelColor(isMatrix ? y * Segment::maxWidth + x : x); }
|
||||
|
||||
// end 2D support
|
||||
|
||||
void loadCustomPalettes(void); // loads custom palettes from JSON
|
||||
CRGBPalette16 _currentPalette; // palette used for current effect (includes transition)
|
||||
void loadCustomPalettes(); // loads custom palettes from JSON
|
||||
std::vector<CRGBPalette16> customPalettes; // TODO: move custom palettes out of WS2812FX class
|
||||
|
||||
// using public variables to reduce code size increase due to inline function getSegment() (with bounds checking)
|
||||
// and color transitions
|
||||
uint32_t _colors_t[3]; // color used for effect (includes transition)
|
||||
uint16_t _virtualSegmentLength;
|
||||
struct {
|
||||
bool autoSegments : 1;
|
||||
bool correctWB : 1;
|
||||
bool cctFromRgb : 1;
|
||||
};
|
||||
|
||||
std::vector<segment> _segments;
|
||||
friend class Segment;
|
||||
@@ -930,17 +967,10 @@ class WS2812FX { // 96 bytes
|
||||
uint16_t customMappingSize;
|
||||
|
||||
unsigned long _lastShow;
|
||||
unsigned long _lastServiceShow;
|
||||
|
||||
uint8_t _segment_index;
|
||||
uint8_t _mainSegment;
|
||||
uint8_t _queuedChangesSegId;
|
||||
uint16_t _qStart, _qStop, _qStartY, _qStopY;
|
||||
uint8_t _qGrouping, _qSpacing;
|
||||
uint16_t _qOffset;
|
||||
/*
|
||||
void
|
||||
setUpSegmentFromQueuedChanges(void);
|
||||
*/
|
||||
};
|
||||
|
||||
extern const char JSON_mode_names[];
|
||||
|
||||
Reference in New Issue
Block a user