mirror of
https://github.com/wled/WLED.git
synced 2025-07-19 16:56:35 +00:00
Pre-calculate virtual
- move SEGCOLOR() to Segment class - add SEG_H, SEG_W macros - try to speed up virtualXxxxx() - compile warning fixes
This commit is contained in:
parent
202901b09f
commit
c842994df5
347
wled00/FX.cpp
347
wled00/FX.cpp
File diff suppressed because it is too large
Load Diff
58
wled00/FX.h
58
wled00/FX.h
@ -90,11 +90,11 @@ extern byte realtimeMode; // used in getMappedPixelIndex()
|
|||||||
#define NUM_COLORS 3 /* number of colors per segment */
|
#define NUM_COLORS 3 /* number of colors per segment */
|
||||||
#define SEGMENT strip._segments[strip.getCurrSegmentId()]
|
#define SEGMENT strip._segments[strip.getCurrSegmentId()]
|
||||||
#define SEGENV 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 SEGCOLOR(x) Segment::getCurrentColor(x)
|
||||||
//#define SEGLEN strip._segments[strip.getCurrSegmentId()].virtualLength()
|
|
||||||
#define SEGCOLOR(x) strip.segColor(x) /* saves us a few kbytes of code */
|
|
||||||
#define SEGPALETTE Segment::getCurrentPalette()
|
#define SEGPALETTE Segment::getCurrentPalette()
|
||||||
#define SEGLEN strip._virtualSegmentLength /* saves us a few kbytes of code */
|
#define SEGLEN Segment::vLength()
|
||||||
|
#define SEG_W Segment::vWidth()
|
||||||
|
#define SEG_H Segment::vHeight()
|
||||||
#define SPEED_FORMULA_L (5U + (50U*(255U - SEGMENT.speed))/SEGLEN)
|
#define SPEED_FORMULA_L (5U + (50U*(255U - SEGMENT.speed))/SEGLEN)
|
||||||
|
|
||||||
// some common colors
|
// some common colors
|
||||||
@ -421,7 +421,9 @@ typedef struct Segment {
|
|||||||
uint16_t _dataLen;
|
uint16_t _dataLen;
|
||||||
static uint16_t _usedSegmentData;
|
static uint16_t _usedSegmentData;
|
||||||
|
|
||||||
// perhaps this should be per segment, not static
|
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 CRGBPalette16 _currentPalette; // palette used for current effect (includes transition, used in color_from_palette())
|
static CRGBPalette16 _currentPalette; // palette used for current effect (includes transition, used in color_from_palette())
|
||||||
static CRGBPalette16 _randomPalette; // actual random palette
|
static CRGBPalette16 _randomPalette; // actual random palette
|
||||||
static CRGBPalette16 _newRandomPalette; // target random palette
|
static CRGBPalette16 _newRandomPalette; // target random palette
|
||||||
@ -534,14 +536,20 @@ typedef struct Segment {
|
|||||||
inline uint16_t groupLength() const { return grouping + spacing; }
|
inline uint16_t groupLength() const { return grouping + spacing; }
|
||||||
inline uint8_t getLightCapabilities() const { return _capabilities; }
|
inline uint8_t getLightCapabilities() const { return _capabilities; }
|
||||||
|
|
||||||
inline static uint16_t getUsedSegmentData() { return _usedSegmentData; }
|
inline static uint16_t getUsedSegmentData() { return Segment::_usedSegmentData; }
|
||||||
inline static void addUsedSegmentData(int len) { _usedSegmentData += len; }
|
inline static void addUsedSegmentData(int len) { Segment::_usedSegmentData += len; }
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
inline static void modeBlend(bool blend) { _modeBlend = blend; }
|
inline static void modeBlend(bool blend) { _modeBlend = blend; }
|
||||||
#endif
|
#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 const CRGBPalette16 &getCurrentPalette() { return Segment::_currentPalette; }
|
||||||
|
|
||||||
|
static void handleRandomPalette();
|
||||||
|
|
||||||
|
void beginDraw(); // set up parameters for current effect
|
||||||
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);
|
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
|
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
|
||||||
void setCCT(uint16_t k);
|
void setCCT(uint16_t k);
|
||||||
@ -578,12 +586,11 @@ typedef struct Segment {
|
|||||||
uint8_t currentMode() const; // currently active effect/mode (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)
|
[[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 &loadPalette(CRGBPalette16 &tgt, uint8_t pal);
|
||||||
void setCurrentPalette();
|
|
||||||
|
|
||||||
// 1D strip
|
// 1D strip
|
||||||
[[gnu::hot]] uint16_t virtualLength() const;
|
[[gnu::hot]] uint16_t virtualLength() const;
|
||||||
[[gnu::hot]] void setPixelColor(int n, uint32_t c); // set relative pixel within segment with color
|
[[gnu::hot]] void setPixelColor(int n, uint32_t c, bool unScaled = true); // set relative pixel within segment with color
|
||||||
inline void setPixelColor(unsigned n, uint32_t c) { setPixelColor(int(n), c); }
|
inline void setPixelColor(unsigned n, uint32_t c, bool unScaled = true) { setPixelColor(int(n), c, unScaled); }
|
||||||
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, 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)); }
|
inline void setPixelColor(int n, CRGB c) { setPixelColor(n, RGBW32(c.r,c.g,c.b,0)); }
|
||||||
#ifdef WLED_USE_AA_PIXELS
|
#ifdef WLED_USE_AA_PIXELS
|
||||||
@ -622,8 +629,8 @@ typedef struct Segment {
|
|||||||
uint16_t nrOfVStrips() const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
|
uint16_t nrOfVStrips() const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
[[gnu::hot]] uint16_t XY(int x, int y); // support function to get relative index within segment
|
[[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
|
[[gnu::hot]] void setPixelColorXY(int x, int y, uint32_t c, bool unScaled = true); // 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(unsigned x, unsigned y, uint32_t c, bool unScaled = true) { setPixelColorXY(int(x), int(y), c, unScaled); }
|
||||||
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, 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(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)); }
|
inline void setPixelColorXY(unsigned x, unsigned y, CRGB c) { setPixelColorXY(int(x), int(y), RGBW32(c.r,c.g,c.b,0)); }
|
||||||
@ -642,8 +649,8 @@ typedef struct Segment {
|
|||||||
inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), fade, true)); }
|
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 box_blur(unsigned r = 1U, bool smear = false); // 2D box blur
|
||||||
void blur2D(uint8_t blur_amount, bool smear = false);
|
void blur2D(uint8_t blur_amount, bool smear = false);
|
||||||
void blurRow(uint32_t row, fract8 blur_amount, bool smear = false);
|
void blurRow(int row, fract8 blur_amount, bool smear = false);
|
||||||
void blurCol(uint32_t col, fract8 blur_amount, bool smear = false);
|
void blurCol(int col, fract8 blur_amount, bool smear = false);
|
||||||
void moveX(int8_t delta, bool wrap = false);
|
void moveX(int8_t delta, bool wrap = false);
|
||||||
void moveY(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 move(uint8_t dir, uint8_t delta, bool wrap = false);
|
||||||
@ -660,9 +667,9 @@ typedef struct Segment {
|
|||||||
inline void blur2d(fract8 blur_amount) { blur(blur_amount); }
|
inline void blur2d(fract8 blur_amount) { blur(blur_amount); }
|
||||||
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
|
||||||
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(int x, int y, uint32_t c, bool unScaled = true) { setPixelColor(x, c, unScaled); }
|
||||||
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColor(int(x), c); }
|
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c, bool unScaled = true) { setPixelColor(int(x), c, unScaled); }
|
||||||
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, 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(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)); }
|
inline void setPixelColorXY(unsigned x, unsigned y, CRGB c) { setPixelColor(int(x), RGBW32(c.r,c.g,c.b,0)); }
|
||||||
@ -680,8 +687,8 @@ typedef struct Segment {
|
|||||||
inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { fadePixelColor(x, fade); }
|
inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { fadePixelColor(x, fade); }
|
||||||
inline void box_blur(unsigned i, bool vertical, fract8 blur_amount) {}
|
inline void box_blur(unsigned i, bool vertical, fract8 blur_amount) {}
|
||||||
inline void blur2D(uint8_t blur_amount, bool smear = false) {}
|
inline void blur2D(uint8_t blur_amount, bool smear = false) {}
|
||||||
inline void blurRow(uint32_t row, fract8 blur_amount, bool smear = false) {}
|
inline void blurRow(int row, fract8 blur_amount, bool smear = false) {}
|
||||||
inline void blurCol(uint32_t col, fract8 blur_amount, bool smear = false) {}
|
inline void blurCol(int col, fract8 blur_amount, bool smear = false) {}
|
||||||
inline void moveX(int8_t delta, bool wrap = false) {}
|
inline void moveX(int8_t delta, bool wrap = false) {}
|
||||||
inline void moveY(int8_t delta, bool wrap = false) {}
|
inline void moveY(int8_t delta, bool wrap = false) {}
|
||||||
inline void move(uint8_t dir, uint8_t delta, bool wrap = false) {}
|
inline void move(uint8_t dir, uint8_t delta, bool wrap = false) {}
|
||||||
@ -727,9 +734,6 @@ class WS2812FX { // 96 bytes
|
|||||||
autoSegments(false),
|
autoSegments(false),
|
||||||
correctWB(false),
|
correctWB(false),
|
||||||
cctFromRgb(false),
|
cctFromRgb(false),
|
||||||
// semi-private (just obscured) used in effect functions through macros
|
|
||||||
_colors_t{0,0,0},
|
|
||||||
_virtualSegmentLength(0),
|
|
||||||
// true private variables
|
// true private variables
|
||||||
_suspend(false),
|
_suspend(false),
|
||||||
_length(DEFAULT_LED_COUNT),
|
_length(DEFAULT_LED_COUNT),
|
||||||
@ -829,7 +833,7 @@ class WS2812FX { // 96 bytes
|
|||||||
addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name); // add effect to the list; defined in FX.cpp;
|
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() const { return _brightness; } // returns current strip brightness
|
inline uint8_t getBrightness() const { return _brightness; } // returns current strip brightness
|
||||||
inline uint8_t getMaxSegments() const { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value)
|
inline 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 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 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 getMainSegmentId() const { return _mainSegment; } // returns main segment index
|
||||||
@ -855,7 +859,6 @@ class WS2812FX { // 96 bytes
|
|||||||
uint32_t getPixelColor(unsigned) const;
|
uint32_t getPixelColor(unsigned) const;
|
||||||
|
|
||||||
inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call
|
inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call
|
||||||
inline uint32_t segColor(uint8_t i) const { return _colors_t[i]; } // returns currently valid color (for slot i) AKA SEGCOLOR(); may be blended between two colors while in transition
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
getModeData(uint8_t id = 0) const { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); }
|
getModeData(uint8_t id = 0) const { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); }
|
||||||
@ -922,11 +925,6 @@ class WS2812FX { // 96 bytes
|
|||||||
bool cctFromRgb : 1;
|
bool cctFromRgb : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
std::vector<segment> _segments;
|
std::vector<segment> _segments;
|
||||||
friend class Segment;
|
friend class Segment;
|
||||||
|
|
||||||
|
@ -163,23 +163,24 @@ void WS2812FX::setUpMatrix() {
|
|||||||
// XY(x,y) - gets pixel index within current segment (often used to reference leds[] array element)
|
// XY(x,y) - gets pixel index within current segment (often used to reference leds[] array element)
|
||||||
uint16_t IRAM_ATTR_YN Segment::XY(int x, int y)
|
uint16_t IRAM_ATTR_YN Segment::XY(int x, int y)
|
||||||
{
|
{
|
||||||
unsigned width = virtualWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||||
unsigned height = virtualHeight(); // segment height in logical pixels (is always >= 1)
|
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||||
return isActive() ? (x%width) + (y%height) * width : 0;
|
return isActive() ? (x%vW) + (y%vH) * vW : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col)
|
void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col, bool unScaled)
|
||||||
{
|
{
|
||||||
if (!isActive()) return; // not active
|
if (!isActive()) return; // not active
|
||||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
|
||||||
|
|
||||||
uint8_t _bri_t = currentBri();
|
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||||
if (_bri_t < 255) {
|
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||||
col = color_fade(col, _bri_t);
|
if (x >= vW|| y >= vH || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
||||||
}
|
|
||||||
|
|
||||||
if (reverse ) x = virtualWidth() - x - 1;
|
// if color is unscaled
|
||||||
if (reverse_y) y = virtualHeight() - y - 1;
|
if (unScaled) col = color_fade(col, currentBri());
|
||||||
|
|
||||||
|
if (reverse ) x = vW - x - 1;
|
||||||
|
if (reverse_y) y = vH - y - 1;
|
||||||
if (transpose) { std::swap(x,y); } // swap X & Y if segment transposed
|
if (transpose) { std::swap(x,y); } // swap X & Y if segment transposed
|
||||||
x *= groupLength(); // expand to physical pixels
|
x *= groupLength(); // expand to physical pixels
|
||||||
y *= groupLength(); // expand to physical pixels
|
y *= groupLength(); // expand to physical pixels
|
||||||
@ -221,11 +222,8 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
|
|||||||
if (!isActive()) return; // not active
|
if (!isActive()) return; // not active
|
||||||
if (x<0.0f || x>1.0f || y<0.0f || y>1.0f) return; // not normalized
|
if (x<0.0f || x>1.0f || y<0.0f || y>1.0f) return; // not normalized
|
||||||
|
|
||||||
const unsigned cols = virtualWidth();
|
float fX = x * (vWidth()-1);
|
||||||
const unsigned rows = virtualHeight();
|
float fY = y * (vHeight()-1);
|
||||||
|
|
||||||
float fX = x * (cols-1);
|
|
||||||
float fY = y * (rows-1);
|
|
||||||
if (aa) {
|
if (aa) {
|
||||||
unsigned xL = roundf(fX-0.49f);
|
unsigned xL = roundf(fX-0.49f);
|
||||||
unsigned xR = roundf(fX+0.49f);
|
unsigned xR = roundf(fX+0.49f);
|
||||||
@ -263,9 +261,11 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
|
|||||||
// returns RGBW values of pixel
|
// returns RGBW values of pixel
|
||||||
uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const {
|
uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const {
|
||||||
if (!isActive()) return 0; // not active
|
if (!isActive()) return 0; // not active
|
||||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit
|
int vW = vWidth();
|
||||||
if (reverse ) x = virtualWidth() - x - 1;
|
int vH = vHeight();
|
||||||
if (reverse_y) y = virtualHeight() - y - 1;
|
if (x >= vW || y >= vH || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit
|
||||||
|
if (reverse ) x = vW - x - 1;
|
||||||
|
if (reverse_y) y = vH - y - 1;
|
||||||
if (transpose) { std::swap(x,y); } // swap X & Y if segment transposed
|
if (transpose) { std::swap(x,y); } // swap X & Y if segment transposed
|
||||||
x *= groupLength(); // expand to physical pixels
|
x *= groupLength(); // expand to physical pixels
|
||||||
y *= groupLength(); // expand to physical pixels
|
y *= groupLength(); // expand to physical pixels
|
||||||
@ -274,10 +274,10 @@ uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// blurRow: perform a blur on a row of a rectangular matrix
|
// blurRow: perform a blur on a row of a rectangular matrix
|
||||||
void Segment::blurRow(uint32_t row, fract8 blur_amount, bool smear){
|
void Segment::blurRow(int row, fract8 blur_amount, bool smear){
|
||||||
if (!isActive() || blur_amount == 0) return; // not active
|
if (!isActive() || blur_amount == 0) return; // not active
|
||||||
const unsigned cols = virtualWidth();
|
const int cols = vWidth();
|
||||||
const unsigned rows = virtualHeight();
|
const int rows = vHeight();
|
||||||
|
|
||||||
if (row >= rows) return;
|
if (row >= rows) return;
|
||||||
// blur one row
|
// blur one row
|
||||||
@ -287,7 +287,7 @@ void Segment::blurRow(uint32_t row, fract8 blur_amount, bool smear){
|
|||||||
uint32_t lastnew;
|
uint32_t lastnew;
|
||||||
uint32_t last;
|
uint32_t last;
|
||||||
uint32_t curnew = BLACK;
|
uint32_t curnew = BLACK;
|
||||||
for (unsigned x = 0; x < cols; x++) {
|
for (int x = 0; x < cols; x++) {
|
||||||
uint32_t cur = getPixelColorXY(x, row);
|
uint32_t cur = getPixelColorXY(x, row);
|
||||||
uint32_t part = color_fade(cur, seep);
|
uint32_t part = color_fade(cur, seep);
|
||||||
curnew = color_fade(cur, keep);
|
curnew = color_fade(cur, keep);
|
||||||
@ -306,10 +306,10 @@ void Segment::blurRow(uint32_t row, fract8 blur_amount, bool smear){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// blurCol: perform a blur on a column of a rectangular matrix
|
// blurCol: perform a blur on a column of a rectangular matrix
|
||||||
void Segment::blurCol(uint32_t col, fract8 blur_amount, bool smear) {
|
void Segment::blurCol(int col, fract8 blur_amount, bool smear) {
|
||||||
if (!isActive() || blur_amount == 0) return; // not active
|
if (!isActive() || blur_amount == 0) return; // not active
|
||||||
const unsigned cols = virtualWidth();
|
const int cols = vWidth();
|
||||||
const unsigned rows = virtualHeight();
|
const int rows = vHeight();
|
||||||
|
|
||||||
if (col >= cols) return;
|
if (col >= cols) return;
|
||||||
// blur one column
|
// blur one column
|
||||||
@ -319,7 +319,7 @@ void Segment::blurCol(uint32_t col, fract8 blur_amount, bool smear) {
|
|||||||
uint32_t lastnew;
|
uint32_t lastnew;
|
||||||
uint32_t last;
|
uint32_t last;
|
||||||
uint32_t curnew = BLACK;
|
uint32_t curnew = BLACK;
|
||||||
for (unsigned y = 0; y < rows; y++) {
|
for (int y = 0; y < rows; y++) {
|
||||||
uint32_t cur = getPixelColorXY(col, y);
|
uint32_t cur = getPixelColorXY(col, y);
|
||||||
uint32_t part = color_fade(cur, seep);
|
uint32_t part = color_fade(cur, seep);
|
||||||
curnew = color_fade(cur, keep);
|
curnew = color_fade(cur, keep);
|
||||||
@ -339,8 +339,8 @@ void Segment::blurCol(uint32_t col, fract8 blur_amount, bool smear) {
|
|||||||
|
|
||||||
void Segment::blur2D(uint8_t blur_amount, bool smear) {
|
void Segment::blur2D(uint8_t blur_amount, bool smear) {
|
||||||
if (!isActive() || blur_amount == 0) return; // not active
|
if (!isActive() || blur_amount == 0) return; // not active
|
||||||
const unsigned cols = virtualWidth();
|
const unsigned cols = vWidth();
|
||||||
const unsigned rows = virtualHeight();
|
const unsigned rows = vHeight();
|
||||||
|
|
||||||
const uint8_t keep = smear ? 255 : 255 - blur_amount;
|
const uint8_t keep = smear ? 255 : 255 - blur_amount;
|
||||||
const uint8_t seep = blur_amount >> (1 + smear);
|
const uint8_t seep = blur_amount >> (1 + smear);
|
||||||
@ -391,8 +391,8 @@ void Segment::box_blur(unsigned radius, bool smear) {
|
|||||||
if (!isActive() || radius == 0) return; // not active
|
if (!isActive() || radius == 0) return; // not active
|
||||||
if (radius > 3) radius = 3;
|
if (radius > 3) radius = 3;
|
||||||
const unsigned d = (1 + 2*radius) * (1 + 2*radius); // averaging divisor
|
const unsigned d = (1 + 2*radius) * (1 + 2*radius); // averaging divisor
|
||||||
const unsigned cols = virtualWidth();
|
const unsigned cols = vWidth();
|
||||||
const unsigned rows = virtualHeight();
|
const unsigned rows = vHeight();
|
||||||
uint16_t *tmpRSum = new uint16_t[cols*rows];
|
uint16_t *tmpRSum = new uint16_t[cols*rows];
|
||||||
uint16_t *tmpGSum = new uint16_t[cols*rows];
|
uint16_t *tmpGSum = new uint16_t[cols*rows];
|
||||||
uint16_t *tmpBSum = new uint16_t[cols*rows];
|
uint16_t *tmpBSum = new uint16_t[cols*rows];
|
||||||
@ -461,37 +461,37 @@ void Segment::box_blur(unsigned radius, bool smear) {
|
|||||||
|
|
||||||
void Segment::moveX(int8_t delta, bool wrap) {
|
void Segment::moveX(int8_t delta, bool wrap) {
|
||||||
if (!isActive()) return; // not active
|
if (!isActive()) return; // not active
|
||||||
const int cols = virtualWidth();
|
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||||
const int rows = virtualHeight();
|
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||||
if (!delta || abs(delta) >= cols) return;
|
if (!delta || abs(delta) >= vW) return;
|
||||||
uint32_t newPxCol[cols];
|
uint32_t newPxCol[vW];
|
||||||
for (int y = 0; y < rows; y++) {
|
for (int y = 0; y < vH; y++) {
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
for (int x = 0; x < cols-delta; x++) newPxCol[x] = getPixelColorXY((x + delta), y);
|
for (int x = 0; x < vW-delta; x++) newPxCol[x] = getPixelColorXY((x + delta), y);
|
||||||
for (int x = cols-delta; x < cols; x++) newPxCol[x] = getPixelColorXY(wrap ? (x + delta) - cols : x, y);
|
for (int x = vW-delta; x < vW; x++) newPxCol[x] = getPixelColorXY(wrap ? (x + delta) - vW : x, y);
|
||||||
} else {
|
} else {
|
||||||
for (int x = cols-1; x >= -delta; x--) newPxCol[x] = getPixelColorXY((x + delta), y);
|
for (int x = vW-1; x >= -delta; x--) newPxCol[x] = getPixelColorXY((x + delta), y);
|
||||||
for (int x = -delta-1; x >= 0; x--) newPxCol[x] = getPixelColorXY(wrap ? (x + delta) + cols : x, y);
|
for (int x = -delta-1; x >= 0; x--) newPxCol[x] = getPixelColorXY(wrap ? (x + delta) + vW : x, y);
|
||||||
}
|
}
|
||||||
for (int x = 0; x < cols; x++) setPixelColorXY(x, y, newPxCol[x]);
|
for (int x = 0; x < vW; x++) setPixelColorXY(x, y, newPxCol[x]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Segment::moveY(int8_t delta, bool wrap) {
|
void Segment::moveY(int8_t delta, bool wrap) {
|
||||||
if (!isActive()) return; // not active
|
if (!isActive()) return; // not active
|
||||||
const int cols = virtualWidth();
|
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||||
const int rows = virtualHeight();
|
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||||
if (!delta || abs(delta) >= rows) return;
|
if (!delta || abs(delta) >= vH) return;
|
||||||
uint32_t newPxCol[rows];
|
uint32_t newPxCol[vH];
|
||||||
for (int x = 0; x < cols; x++) {
|
for (int x = 0; x < vW; x++) {
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
for (int y = 0; y < rows-delta; y++) newPxCol[y] = getPixelColorXY(x, (y + delta));
|
for (int y = 0; y < vH-delta; y++) newPxCol[y] = getPixelColorXY(x, (y + delta));
|
||||||
for (int y = rows-delta; y < rows; y++) newPxCol[y] = getPixelColorXY(x, wrap ? (y + delta) - rows : y);
|
for (int y = vH-delta; y < vH; y++) newPxCol[y] = getPixelColorXY(x, wrap ? (y + delta) - vH : y);
|
||||||
} else {
|
} else {
|
||||||
for (int y = rows-1; y >= -delta; y--) newPxCol[y] = getPixelColorXY(x, (y + delta));
|
for (int y = vH-1; y >= -delta; y--) newPxCol[y] = getPixelColorXY(x, (y + delta));
|
||||||
for (int y = -delta-1; y >= 0; y--) newPxCol[y] = getPixelColorXY(x, wrap ? (y + delta) + rows : y);
|
for (int y = -delta-1; y >= 0; y--) newPxCol[y] = getPixelColorXY(x, wrap ? (y + delta) + vH : y);
|
||||||
}
|
}
|
||||||
for (int y = 0; y < rows; y++) setPixelColorXY(x, y, newPxCol[y]);
|
for (int y = 0; y < vH; y++) setPixelColorXY(x, y, newPxCol[y]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,18 +545,20 @@ void Segment::drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t col,
|
|||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// pre-scale color for all pixels
|
||||||
|
col = color_fade(col, currentBri());
|
||||||
// Bresenham’s Algorithm
|
// Bresenham’s Algorithm
|
||||||
int d = 3 - (2*radius);
|
int d = 3 - (2*radius);
|
||||||
int y = radius, x = 0;
|
int y = radius, x = 0;
|
||||||
while (y >= x) {
|
while (y >= x) {
|
||||||
setPixelColorXY(cx+x, cy+y, col);
|
setPixelColorXY(cx+x, cy+y, col, false);
|
||||||
setPixelColorXY(cx-x, cy+y, col);
|
setPixelColorXY(cx-x, cy+y, col, false);
|
||||||
setPixelColorXY(cx+x, cy-y, col);
|
setPixelColorXY(cx+x, cy-y, col, false);
|
||||||
setPixelColorXY(cx-x, cy-y, col);
|
setPixelColorXY(cx-x, cy-y, col, false);
|
||||||
setPixelColorXY(cx+y, cy+x, col);
|
setPixelColorXY(cx+y, cy+x, col, false);
|
||||||
setPixelColorXY(cx-y, cy+x, col);
|
setPixelColorXY(cx-y, cy+x, col, false);
|
||||||
setPixelColorXY(cx+y, cy-x, col);
|
setPixelColorXY(cx+y, cy-x, col, false);
|
||||||
setPixelColorXY(cx-y, cy-x, col);
|
setPixelColorXY(cx-y, cy-x, col, false);
|
||||||
x++;
|
x++;
|
||||||
if (d > 0) {
|
if (d > 0) {
|
||||||
y--;
|
y--;
|
||||||
@ -571,17 +573,19 @@ void Segment::drawCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t col,
|
|||||||
// by stepko, taken from https://editor.soulmatelights.com/gallery/573-blobs
|
// by stepko, taken from https://editor.soulmatelights.com/gallery/573-blobs
|
||||||
void Segment::fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t col, bool soft) {
|
void Segment::fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t col, bool soft) {
|
||||||
if (!isActive() || radius == 0) return; // not active
|
if (!isActive() || radius == 0) return; // not active
|
||||||
|
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||||
|
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||||
// draw soft bounding circle
|
// draw soft bounding circle
|
||||||
if (soft) drawCircle(cx, cy, radius, col, soft);
|
if (soft) drawCircle(cx, cy, radius, col, soft);
|
||||||
|
// pre-scale color for all pixels
|
||||||
|
col = color_fade(col, currentBri());
|
||||||
// fill it
|
// fill it
|
||||||
const int cols = virtualWidth();
|
|
||||||
const int rows = virtualHeight();
|
|
||||||
for (int y = -radius; y <= radius; y++) {
|
for (int y = -radius; y <= radius; y++) {
|
||||||
for (int x = -radius; x <= radius; x++) {
|
for (int x = -radius; x <= radius; x++) {
|
||||||
if (x * x + y * y <= radius * radius &&
|
if (x * x + y * y <= radius * radius &&
|
||||||
int(cx)+x>=0 && int(cy)+y>=0 &&
|
int(cx)+x >= 0 && int(cy)+y >= 0 &&
|
||||||
int(cx)+x<cols && int(cy)+y<rows)
|
int(cx)+x < vW && int(cy)+y < vH)
|
||||||
setPixelColorXY(cx + x, cy + y, col);
|
setPixelColorXY(cx + x, cy + y, col, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -589,9 +593,9 @@ void Segment::fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t col,
|
|||||||
//line function
|
//line function
|
||||||
void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c, bool soft) {
|
void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c, bool soft) {
|
||||||
if (!isActive()) return; // not active
|
if (!isActive()) return; // not active
|
||||||
const int cols = virtualWidth();
|
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||||
const int rows = virtualHeight();
|
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||||
if (x0 >= cols || x1 >= cols || y0 >= rows || y1 >= rows) return;
|
if (x0 >= vW || x1 >= vW || y0 >= vH || y1 >= vH) return;
|
||||||
|
|
||||||
const int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1; // x distance & step
|
const int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1; // x distance & step
|
||||||
const int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; // y distance & step
|
const int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; // y distance & step
|
||||||
@ -629,10 +633,12 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint3
|
|||||||
if (steep) std::swap(x,y); // restore if steep
|
if (steep) std::swap(x,y); // restore if steep
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// pre-scale color for all pixels
|
||||||
|
c = color_fade(c, currentBri());
|
||||||
// Bresenham's algorithm
|
// Bresenham's algorithm
|
||||||
int err = (dx>dy ? dx : -dy)/2; // error direction
|
int err = (dx>dy ? dx : -dy)/2; // error direction
|
||||||
for (;;) {
|
for (;;) {
|
||||||
setPixelColorXY(x0, y0, c);
|
setPixelColorXY(x0, y0, c, false);
|
||||||
if (x0==x1 && y0==y1) break;
|
if (x0==x1 && y0==y1) break;
|
||||||
int e2 = err;
|
int e2 = err;
|
||||||
if (e2 >-dx) { err -= dy; x0 += sx; }
|
if (e2 >-dx) { err -= dy; x0 += sx; }
|
||||||
@ -653,8 +659,6 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w,
|
|||||||
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
|
||||||
const int cols = virtualWidth();
|
|
||||||
const int rows = virtualHeight();
|
|
||||||
const int font = w*h;
|
const int font = w*h;
|
||||||
|
|
||||||
CRGB col = CRGB(color);
|
CRGB col = CRGB(color);
|
||||||
@ -681,7 +685,7 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w,
|
|||||||
case 1: x0 = x + i; y0 = y + j; break; // +90 deg
|
case 1: x0 = x + i; y0 = y + j; break; // +90 deg
|
||||||
default: x0 = x + (w-1) - j; y0 = y + i; break; // no rotation
|
default: x0 = x + (w-1) - j; y0 = y + i; break; // no rotation
|
||||||
}
|
}
|
||||||
if (x0 < 0 || x0 >= cols || y0 < 0 || y0 >= rows) continue; // drawing off-screen
|
if (x0 < 0 || x0 >= (int)vWidth() || y0 < 0 || y0 >= (int)vHeight()) continue; // drawing off-screen
|
||||||
if (((bits>>(j+(8-w))) & 0x01)) { // bit set
|
if (((bits>>(j+(8-w))) & 0x01)) { // bit set
|
||||||
setPixelColorXY(x0, y0, col);
|
setPixelColorXY(x0, y0, col);
|
||||||
}
|
}
|
||||||
|
@ -83,12 +83,15 @@ static constexpr bool validatePinsAndTypes(const unsigned* types, unsigned numTy
|
|||||||
uint16_t Segment::_usedSegmentData = 0U; // amount of RAM all segments use for their data[]
|
uint16_t Segment::_usedSegmentData = 0U; // amount of RAM all segments use for their data[]
|
||||||
uint16_t Segment::maxWidth = DEFAULT_LED_COUNT;
|
uint16_t Segment::maxWidth = DEFAULT_LED_COUNT;
|
||||||
uint16_t Segment::maxHeight = 1;
|
uint16_t Segment::maxHeight = 1;
|
||||||
|
unsigned Segment::_vLength = 0;
|
||||||
|
unsigned Segment::_vWidth = 0;
|
||||||
|
unsigned Segment::_vHeight = 0;
|
||||||
|
uint32_t Segment::_currentColors[NUM_COLORS] = {0,0,0};
|
||||||
CRGBPalette16 Segment::_currentPalette = CRGBPalette16(CRGB::Black);
|
CRGBPalette16 Segment::_currentPalette = CRGBPalette16(CRGB::Black);
|
||||||
CRGBPalette16 Segment::_randomPalette = generateRandomPalette(); // was CRGBPalette16(DEFAULT_COLOR);
|
CRGBPalette16 Segment::_randomPalette = generateRandomPalette(); // was CRGBPalette16(DEFAULT_COLOR);
|
||||||
CRGBPalette16 Segment::_newRandomPalette = generateRandomPalette(); // was CRGBPalette16(DEFAULT_COLOR);
|
CRGBPalette16 Segment::_newRandomPalette = generateRandomPalette(); // was CRGBPalette16(DEFAULT_COLOR);
|
||||||
uint16_t Segment::_lastPaletteChange = 0; // perhaps it should be per segment
|
uint16_t Segment::_lastPaletteChange = 0; // perhaps it should be per segment
|
||||||
uint16_t Segment::_lastPaletteBlend = 0; //in millis (lowest 16 bits only)
|
uint16_t Segment::_lastPaletteBlend = 0; // in millis (lowest 16 bits only)
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
bool Segment::_modeBlend = false;
|
bool Segment::_modeBlend = false;
|
||||||
@ -437,7 +440,21 @@ uint32_t IRAM_ATTR_YN Segment::currentColor(uint8_t slot) const {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Segment::setCurrentPalette() {
|
// pre-calculate drawing parameters for faster access
|
||||||
|
void Segment::beginDraw() {
|
||||||
|
_vWidth = virtualWidth();
|
||||||
|
_vHeight = virtualHeight();
|
||||||
|
_vLength = virtualLength();
|
||||||
|
// adjust gamma for effects
|
||||||
|
for (unsigned i = 0; i < NUM_COLORS; i++) {
|
||||||
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
|
uint32_t col = isInTransition() ? color_blend(_t->_segT._colorT[i], colors[i], progress(), true) : colors[i];
|
||||||
|
#else
|
||||||
|
uint32_t col = isInTransition() ? color_blend(_t->_colorT[i], colors[i], progress(), true) : colors[i];
|
||||||
|
#endif
|
||||||
|
_currentColors[i] = gamma32(col);
|
||||||
|
}
|
||||||
|
// load palette into _currentPalette
|
||||||
loadPalette(_currentPalette, palette);
|
loadPalette(_currentPalette, palette);
|
||||||
unsigned prog = progress();
|
unsigned prog = progress();
|
||||||
if (strip.paletteFade && prog < 0xFFFFU) {
|
if (strip.paletteFade && prog < 0xFFFFU) {
|
||||||
@ -698,20 +715,21 @@ uint16_t IRAM_ATTR Segment::virtualLength() const {
|
|||||||
return vLength;
|
return vLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col, bool unScaled)
|
||||||
{
|
{
|
||||||
if (!isActive() || i < 0) return; // not active or invalid index
|
if (!isActive() || i < 0) return; // not active or invalid index
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
int vStrip = 0;
|
int vStrip = 0;
|
||||||
#endif
|
#endif
|
||||||
|
int vL = vLength();
|
||||||
// if the 1D effect is using virtual strips "i" will have virtual strip id stored in upper 16 bits
|
// if the 1D effect is using virtual strips "i" will have virtual strip id stored in upper 16 bits
|
||||||
// in such case "i" will be > virtualLength()
|
// in such case "i" will be > virtualLength()
|
||||||
if (i >= virtualLength()) {
|
if (i >= vL) {
|
||||||
// check if this is a virtual strip
|
// check if this is a virtual strip
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
vStrip = i>>16; // hack to allow running on virtual strips (2D segment columns/rows)
|
vStrip = i>>16; // hack to allow running on virtual strips (2D segment columns/rows)
|
||||||
i &= 0xFFFF; //truncate vstrip index
|
i &= 0xFFFF; //truncate vstrip index
|
||||||
if (i >= virtualLength()) return; // if pixel would still fall out of segment just exit
|
if (i >= vL) return; // if pixel would still fall out of segment just exit
|
||||||
#else
|
#else
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
@ -719,22 +737,24 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
|||||||
|
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
if (is2D()) {
|
if (is2D()) {
|
||||||
int vH = virtualHeight(); // segment height in logical pixels
|
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||||
int vW = virtualWidth();
|
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||||
|
// pre-scale color for all pixels
|
||||||
|
col = color_fade(col, currentBri());
|
||||||
switch (map1D2D) {
|
switch (map1D2D) {
|
||||||
case M12_Pixels:
|
case M12_Pixels:
|
||||||
// use all available pixels as a long strip
|
// use all available pixels as a long strip
|
||||||
setPixelColorXY(i % vW, i / vW, col);
|
setPixelColorXY(i % vW, i / vW, col, false);
|
||||||
break;
|
break;
|
||||||
case M12_pBar:
|
case M12_pBar:
|
||||||
// expand 1D effect vertically or have it play on virtual strips
|
// expand 1D effect vertically or have it play on virtual strips
|
||||||
if (vStrip > 0) setPixelColorXY(vStrip - 1, vH - i - 1, col);
|
if (vStrip > 0) setPixelColorXY(vStrip - 1, vH - i - 1, col, false);
|
||||||
else for (int x = 0; x < vW; x++) setPixelColorXY(x, vH - i - 1, col);
|
else for (int x = 0; x < vW; x++) setPixelColorXY(x, vH - i - 1, col, false);
|
||||||
break;
|
break;
|
||||||
case M12_pArc:
|
case M12_pArc:
|
||||||
// expand in circular fashion from center
|
// expand in circular fashion from center
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
setPixelColorXY(0, 0, col);
|
setPixelColorXY(0, 0, col, false);
|
||||||
else {
|
else {
|
||||||
float r = i;
|
float r = i;
|
||||||
float step = HALF_PI / (2.8284f * r + 4); // we only need (PI/4)/(r/sqrt(2)+1) steps
|
float step = HALF_PI / (2.8284f * r + 4); // we only need (PI/4)/(r/sqrt(2)+1) steps
|
||||||
@ -742,8 +762,8 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
|||||||
int x = roundf(sin_t(rad) * r);
|
int x = roundf(sin_t(rad) * r);
|
||||||
int y = roundf(cos_t(rad) * r);
|
int y = roundf(cos_t(rad) * r);
|
||||||
// exploit symmetry
|
// exploit symmetry
|
||||||
setPixelColorXY(x, y, col);
|
setPixelColorXY(x, y, col, false);
|
||||||
setPixelColorXY(y, x, col);
|
setPixelColorXY(y, x, col, false);
|
||||||
}
|
}
|
||||||
// Bresenham’s Algorithm (may not fill every pixel)
|
// Bresenham’s Algorithm (may not fill every pixel)
|
||||||
//int d = 3 - (2*i);
|
//int d = 3 - (2*i);
|
||||||
@ -762,8 +782,8 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case M12_pCorner:
|
case M12_pCorner:
|
||||||
for (int x = 0; x <= i; x++) setPixelColorXY(x, i, col);
|
for (int x = 0; x <= i; x++) setPixelColorXY(x, i, col, false);
|
||||||
for (int y = 0; y < i; y++) setPixelColorXY(i, y, col);
|
for (int y = 0; y < i; y++) setPixelColorXY(i, y, col, false);
|
||||||
break;
|
break;
|
||||||
case M12_sPinwheel: {
|
case M12_sPinwheel: {
|
||||||
// i = angle --> 0 - 296 (Big), 0 - 192 (Medium), 0 - 72 (Small)
|
// i = angle --> 0 - 296 (Big), 0 - 192 (Medium), 0 - 72 (Small)
|
||||||
@ -802,7 +822,7 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
|||||||
int x = posx / Fixed_Scale;
|
int x = posx / Fixed_Scale;
|
||||||
int y = posy / Fixed_Scale;
|
int y = posy / Fixed_Scale;
|
||||||
// set pixel
|
// set pixel
|
||||||
if (x != lastX || y != lastY) setPixelColorXY(x, y, col); // only paint if pixel position is different
|
if (x != lastX || y != lastY) setPixelColorXY(x, y, col, false); // only paint if pixel position is different
|
||||||
lastX = x;
|
lastX = x;
|
||||||
lastY = y;
|
lastY = y;
|
||||||
// advance to next position
|
// advance to next position
|
||||||
@ -813,12 +833,12 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (Segment::maxHeight!=1 && (width()==1 || height()==1)) {
|
} else if (Segment::maxHeight != 1 && (width() == 1 || height() == 1)) {
|
||||||
if (start < Segment::maxWidth*Segment::maxHeight) {
|
if (start < Segment::maxWidth*Segment::maxHeight) {
|
||||||
// we have a vertical or horizontal 1D segment (WARNING: virtual...() may be transposed)
|
// we have a vertical or horizontal 1D segment (WARNING: virtual...() may be transposed)
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
if (virtualHeight()>1) y = i;
|
if (vHeight() > 1) y = i;
|
||||||
if (virtualWidth() >1) x = i;
|
if (vWidth() > 1) x = i;
|
||||||
setPixelColorXY(x, y, col);
|
setPixelColorXY(x, y, col);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -826,10 +846,8 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned len = length();
|
unsigned len = length();
|
||||||
uint8_t _bri_t = currentBri();
|
// if color is unscaled
|
||||||
if (_bri_t < 255) {
|
if (unScaled) col = color_fade(col, currentBri());
|
||||||
col = color_fade(col, _bri_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// expand pixel (taking into account start, grouping, spacing [and offset])
|
// expand pixel (taking into account start, grouping, spacing [and offset])
|
||||||
i = i * groupLength();
|
i = i * groupLength();
|
||||||
@ -907,8 +925,8 @@ uint32_t IRAM_ATTR_YN Segment::getPixelColor(int i) const
|
|||||||
|
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
if (is2D()) {
|
if (is2D()) {
|
||||||
int vH = virtualHeight(); // segment height in logical pixels
|
const int vW = vWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||||
int vW = virtualWidth();
|
const int vH = vHeight(); // segment height in logical pixels (is always >= 1)
|
||||||
switch (map1D2D) {
|
switch (map1D2D) {
|
||||||
case M12_Pixels:
|
case M12_Pixels:
|
||||||
return getPixelColorXY(i % vW, i / vW);
|
return getPixelColorXY(i % vW, i / vW);
|
||||||
@ -961,7 +979,7 @@ uint32_t IRAM_ATTR_YN Segment::getPixelColor(int i) const
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (reverse) i = virtualLength() - i - 1;
|
if (reverse) i = vLength() - i - 1;
|
||||||
i *= groupLength();
|
i *= groupLength();
|
||||||
i += start;
|
i += start;
|
||||||
// offset/phase
|
// offset/phase
|
||||||
@ -1050,11 +1068,13 @@ void Segment::refreshLightCapabilities() {
|
|||||||
*/
|
*/
|
||||||
void Segment::fill(uint32_t c) {
|
void Segment::fill(uint32_t c) {
|
||||||
if (!isActive()) return; // not active
|
if (!isActive()) return; // not active
|
||||||
const int cols = is2D() ? virtualWidth() : virtualLength();
|
const int cols = is2D() ? vWidth() : vLength();
|
||||||
const int rows = virtualHeight(); // will be 1 for 1D
|
const int rows = vHeight(); // will be 1 for 1D
|
||||||
|
// pre-scale color for all pixels
|
||||||
|
c = color_fade(c, currentBri());
|
||||||
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) {
|
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) {
|
||||||
if (is2D()) setPixelColorXY(x, y, c);
|
if (is2D()) setPixelColorXY(x, y, c, false);
|
||||||
else setPixelColor(x, c);
|
else setPixelColor(x, c, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1063,8 +1083,8 @@ void Segment::fill(uint32_t c) {
|
|||||||
*/
|
*/
|
||||||
void Segment::fade_out(uint8_t rate) {
|
void Segment::fade_out(uint8_t rate) {
|
||||||
if (!isActive()) return; // not active
|
if (!isActive()) return; // not active
|
||||||
const int cols = is2D() ? virtualWidth() : virtualLength();
|
const int cols = is2D() ? vWidth() : vLength();
|
||||||
const int rows = virtualHeight(); // will be 1 for 1D
|
const int rows = vHeight(); // will be 1 for 1D
|
||||||
|
|
||||||
rate = (255-rate) >> 1;
|
rate = (255-rate) >> 1;
|
||||||
float mappedRate = 1.0f / (float(rate) + 1.1f);
|
float mappedRate = 1.0f / (float(rate) + 1.1f);
|
||||||
@ -1102,8 +1122,8 @@ void Segment::fade_out(uint8_t rate) {
|
|||||||
// fades all pixels to black using nscale8()
|
// fades all pixels to black using nscale8()
|
||||||
void Segment::fadeToBlackBy(uint8_t fadeBy) {
|
void Segment::fadeToBlackBy(uint8_t fadeBy) {
|
||||||
if (!isActive() || fadeBy == 0) return; // optimization - no scaling to apply
|
if (!isActive() || fadeBy == 0) return; // optimization - no scaling to apply
|
||||||
const int cols = is2D() ? virtualWidth() : virtualLength();
|
const int cols = is2D() ? vWidth() : vLength();
|
||||||
const int rows = virtualHeight(); // will be 1 for 1D
|
const int rows = vHeight(); // will be 1 for 1D
|
||||||
|
|
||||||
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) {
|
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) {
|
||||||
if (is2D()) setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), 255-fadeBy));
|
if (is2D()) setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), 255-fadeBy));
|
||||||
@ -1126,7 +1146,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 + smear);
|
||||||
unsigned vlength = virtualLength();
|
unsigned vlength = vLength();
|
||||||
uint32_t carryover = BLACK;
|
uint32_t carryover = BLACK;
|
||||||
uint32_t lastnew;
|
uint32_t lastnew;
|
||||||
uint32_t last;
|
uint32_t last;
|
||||||
@ -1140,8 +1160,7 @@ void Segment::blur(uint8_t blur_amount, bool smear) {
|
|||||||
uint32_t prev = color_add(lastnew, part);
|
uint32_t prev = color_add(lastnew, part);
|
||||||
// optimization: only set pixel if color has changed
|
// optimization: only set pixel if color has changed
|
||||||
if (last != prev) setPixelColor(i - 1, prev);
|
if (last != prev) setPixelColor(i - 1, prev);
|
||||||
} else // first pixel
|
} else setPixelColor(i, curnew); // first pixel
|
||||||
setPixelColor(i, curnew);
|
|
||||||
lastnew = curnew;
|
lastnew = curnew;
|
||||||
last = cur; // save original value for comparison on next iteration
|
last = cur; // save original value for comparison on next iteration
|
||||||
carryover = part;
|
carryover = part;
|
||||||
@ -1156,7 +1175,7 @@ void Segment::blur(uint8_t blur_amount, bool smear) {
|
|||||||
*/
|
*/
|
||||||
uint32_t Segment::color_wheel(uint8_t pos) const {
|
uint32_t Segment::color_wheel(uint8_t pos) const {
|
||||||
if (palette) return color_from_palette(pos, false, true, 0); // perhaps "strip.paletteBlend < 2" should be better instead of "true"
|
if (palette) return color_from_palette(pos, false, true, 0); // perhaps "strip.paletteBlend < 2" should be better instead of "true"
|
||||||
uint8_t w = W(currentColor(0));
|
uint8_t w = W(getCurrentColor(0));
|
||||||
pos = 255 - pos;
|
pos = 255 - pos;
|
||||||
if (pos < 85) {
|
if (pos < 85) {
|
||||||
return RGBW32((255 - pos * 3), 0, (pos * 3), w);
|
return RGBW32((255 - pos * 3), 0, (pos * 3), w);
|
||||||
@ -1179,20 +1198,19 @@ uint32_t Segment::color_wheel(uint8_t pos) const {
|
|||||||
* @returns Single color from palette
|
* @returns Single color from palette
|
||||||
*/
|
*/
|
||||||
uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) const {
|
uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) const {
|
||||||
|
uint32_t color = getCurrentColor(mcol < NUM_COLORS ? mcol : 0);
|
||||||
uint32_t color = currentColor(mcol);
|
|
||||||
// default palette or no RGB support on segment
|
// default palette or no RGB support on segment
|
||||||
if ((palette == 0 && mcol < NUM_COLORS) || !_isRGB) {
|
if ((palette == 0 && mcol < NUM_COLORS) || !_isRGB) {
|
||||||
color = gamma32(color);
|
return color_fade(color, pbri, true);
|
||||||
return (pbri == 255) ? color : color_fade(color, pbri, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int vL = vLength();
|
||||||
unsigned paletteIndex = i;
|
unsigned paletteIndex = i;
|
||||||
if (mapping && virtualLength() > 1) paletteIndex = (i*255)/(virtualLength() -1);
|
if (mapping && vL > 1) paletteIndex = (i*255)/(vL -1);
|
||||||
// paletteBlend: 0 - wrap when moving, 1 - always wrap, 2 - never wrap, 3 - none (undefined)
|
// paletteBlend: 0 - wrap when moving, 1 - always wrap, 2 - never wrap, 3 - none (undefined)
|
||||||
if (!wrap && strip.paletteBlend != 3) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
|
if (!wrap && strip.paletteBlend != 3) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
|
||||||
CRGBW palcol = ColorFromPalette(_currentPalette, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
|
CRGBW palcol = ColorFromPalette(_currentPalette, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
|
||||||
palcol.w = gamma8(W(color));
|
palcol.w = W(color);
|
||||||
|
|
||||||
return palcol.color32;
|
return palcol.color32;
|
||||||
}
|
}
|
||||||
@ -1359,11 +1377,6 @@ void WS2812FX::service() {
|
|||||||
|
|
||||||
if (!seg.freeze) { //only run effect function if not frozen
|
if (!seg.freeze) { //only run effect function if not frozen
|
||||||
int oldCCT = BusManager::getSegmentCCT(); // store original CCT value (actually it is not Segment based)
|
int oldCCT = BusManager::getSegmentCCT(); // store original CCT value (actually it is not Segment based)
|
||||||
_virtualSegmentLength = seg.virtualLength(); //SEGLEN
|
|
||||||
_colors_t[0] = gamma32(seg.currentColor(0));
|
|
||||||
_colors_t[1] = gamma32(seg.currentColor(1));
|
|
||||||
_colors_t[2] = gamma32(seg.currentColor(2));
|
|
||||||
seg.setCurrentPalette(); // load actual palette
|
|
||||||
// when correctWB is true we need to correct/adjust RGB value according to desired CCT value, but it will also affect actual WW/CW ratio
|
// when correctWB is true we need to correct/adjust RGB value according to desired CCT value, but it will also affect actual WW/CW ratio
|
||||||
// when cctFromRgb is true we implicitly calculate WW and CW from RGB values
|
// when cctFromRgb is true we implicitly calculate WW and CW from RGB values
|
||||||
if (cctFromRgb) BusManager::setSegmentCCT(-1);
|
if (cctFromRgb) BusManager::setSegmentCCT(-1);
|
||||||
@ -1375,13 +1388,14 @@ void WS2812FX::service() {
|
|||||||
// overwritten by later effect. To enable seamless blending for every effect, additional LED buffer
|
// overwritten by later effect. To enable seamless blending for every effect, additional LED buffer
|
||||||
// would need to be allocated for each effect and then blended together for each pixel.
|
// would need to be allocated for each effect and then blended together for each pixel.
|
||||||
[[maybe_unused]] uint8_t tmpMode = seg.currentMode(); // this will return old mode while in transition
|
[[maybe_unused]] uint8_t tmpMode = seg.currentMode(); // this will return old mode while in transition
|
||||||
|
seg.beginDraw(); // set up parameters for get/setPixelColor()
|
||||||
delay = (*_mode[seg.mode])(); // run new/current mode
|
delay = (*_mode[seg.mode])(); // run new/current mode
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
if (modeBlending && seg.mode != tmpMode) {
|
if (modeBlending && seg.mode != tmpMode) {
|
||||||
Segment::tmpsegd_t _tmpSegData;
|
Segment::tmpsegd_t _tmpSegData;
|
||||||
Segment::modeBlend(true); // set semaphore
|
Segment::modeBlend(true); // set semaphore
|
||||||
seg.swapSegenv(_tmpSegData); // temporarily store new mode state (and swap it with transitional state)
|
seg.swapSegenv(_tmpSegData); // temporarily store new mode state (and swap it with transitional state)
|
||||||
_virtualSegmentLength = seg.virtualLength(); // update SEGLEN (mapping may have changed)
|
seg.beginDraw(); // set up parameters for get/setPixelColor()
|
||||||
unsigned d2 = (*_mode[tmpMode])(); // run old mode
|
unsigned d2 = (*_mode[tmpMode])(); // run old mode
|
||||||
seg.restoreSegenv(_tmpSegData); // restore mode state (will also update transitional state)
|
seg.restoreSegenv(_tmpSegData); // restore mode state (will also update transitional state)
|
||||||
delay = MIN(delay,d2); // use shortest delay
|
delay = MIN(delay,d2); // use shortest delay
|
||||||
@ -1397,7 +1411,6 @@ void WS2812FX::service() {
|
|||||||
}
|
}
|
||||||
_segment_index++;
|
_segment_index++;
|
||||||
}
|
}
|
||||||
_virtualSegmentLength = 0;
|
|
||||||
_isServicing = false;
|
_isServicing = false;
|
||||||
_triggered = false;
|
_triggered = false;
|
||||||
|
|
||||||
|
@ -416,18 +416,18 @@ void realtimeLock(uint32_t timeoutMs, byte md)
|
|||||||
start = mainseg.start;
|
start = mainseg.start;
|
||||||
stop = mainseg.stop;
|
stop = mainseg.stop;
|
||||||
mainseg.freeze = true;
|
mainseg.freeze = true;
|
||||||
|
// if WLED was off and using main segment only, freeze non-main segments so they stay off
|
||||||
|
if (bri == 0) {
|
||||||
|
for (size_t s = 0; s < strip.getSegmentsNum(); s++) {
|
||||||
|
strip.getSegment(s).freeze = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
start = 0;
|
start = 0;
|
||||||
stop = strip.getLengthTotal();
|
stop = strip.getLengthTotal();
|
||||||
}
|
}
|
||||||
// clear strip/segment
|
// clear strip/segment
|
||||||
for (size_t i = start; i < stop; i++) strip.setPixelColor(i,BLACK);
|
for (size_t i = start; i < stop; i++) strip.setPixelColor(i,BLACK);
|
||||||
// if WLED was off and using main segment only, freeze non-main segments so they stay off
|
|
||||||
if (useMainSegmentOnly && bri == 0) {
|
|
||||||
for (size_t s=0; s < strip.getSegmentsNum(); s++) {
|
|
||||||
strip.getSegment(s).freeze = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// if strip is off (bri==0) and not already in RTM
|
// if strip is off (bri==0) and not already in RTM
|
||||||
if (briT == 0 && !realtimeMode && !realtimeOverride) {
|
if (briT == 0 && !realtimeMode && !realtimeOverride) {
|
||||||
@ -510,12 +510,10 @@ void handleNotifications()
|
|||||||
rgbUdp.read(lbuf, packetSize);
|
rgbUdp.read(lbuf, packetSize);
|
||||||
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_HYPERION);
|
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_HYPERION);
|
||||||
if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return;
|
if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return;
|
||||||
unsigned id = 0;
|
|
||||||
unsigned totalLen = strip.getLengthTotal();
|
unsigned totalLen = strip.getLengthTotal();
|
||||||
for (size_t i = 0; i < packetSize -2; i += 3)
|
if (useMainSegmentOnly) strip.getMainSegment().beginDraw(); // set up parameters for get/setPixelColor()
|
||||||
{
|
for (size_t i = 0, id = 0; i < packetSize -2 && id < totalLen; i += 3, id++) {
|
||||||
setRealtimePixel(id, lbuf[i], lbuf[i+1], lbuf[i+2], 0);
|
setRealtimePixel(id, lbuf[i], lbuf[i+1], lbuf[i+2], 0);
|
||||||
id++; if (id >= totalLen) break;
|
|
||||||
}
|
}
|
||||||
if (!(realtimeMode && useMainSegmentOnly)) strip.show();
|
if (!(realtimeMode && useMainSegmentOnly)) strip.show();
|
||||||
return;
|
return;
|
||||||
@ -595,17 +593,11 @@ void handleNotifications()
|
|||||||
|
|
||||||
unsigned id = (tpmPayloadFrameSize/3)*(packetNum-1); //start LED
|
unsigned id = (tpmPayloadFrameSize/3)*(packetNum-1); //start LED
|
||||||
unsigned totalLen = strip.getLengthTotal();
|
unsigned totalLen = strip.getLengthTotal();
|
||||||
for (size_t i = 6; i < tpmPayloadFrameSize + 4U; i += 3)
|
if (useMainSegmentOnly) strip.getMainSegment().beginDraw(); // set up parameters for get/setPixelColor()
|
||||||
{
|
for (size_t i = 6; i < tpmPayloadFrameSize + 4U && id < totalLen; i += 3, id++) {
|
||||||
if (id < totalLen)
|
|
||||||
{
|
|
||||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
||||||
id++;
|
|
||||||
}
|
}
|
||||||
else break;
|
if (tpmPacketCount == numPackets) { //reset packet count and show if all packets were received
|
||||||
}
|
|
||||||
if (tpmPacketCount == numPackets) //reset packet count and show if all packets were received
|
|
||||||
{
|
|
||||||
tpmPacketCount = 0;
|
tpmPacketCount = 0;
|
||||||
strip.show();
|
strip.show();
|
||||||
}
|
}
|
||||||
@ -629,6 +621,7 @@ void handleNotifications()
|
|||||||
if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return;
|
if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return;
|
||||||
|
|
||||||
unsigned totalLen = strip.getLengthTotal();
|
unsigned totalLen = strip.getLengthTotal();
|
||||||
|
if (useMainSegmentOnly) strip.getMainSegment().beginDraw(); // set up parameters for get/setPixelColor()
|
||||||
if (udpIn[0] == 1 && packetSize > 5) //warls
|
if (udpIn[0] == 1 && packetSize > 5) //warls
|
||||||
{
|
{
|
||||||
for (size_t i = 2; i < packetSize -3; i += 4)
|
for (size_t i = 2; i < packetSize -3; i += 4)
|
||||||
@ -637,39 +630,29 @@ void handleNotifications()
|
|||||||
}
|
}
|
||||||
} else if (udpIn[0] == 2 && packetSize > 4) //drgb
|
} else if (udpIn[0] == 2 && packetSize > 4) //drgb
|
||||||
{
|
{
|
||||||
unsigned id = 0;
|
for (size_t i = 2, id = 0; i < packetSize -2 && id < totalLen; i += 3, id++)
|
||||||
for (size_t i = 2; i < packetSize -2; i += 3)
|
|
||||||
{
|
{
|
||||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
||||||
|
|
||||||
id++; if (id >= totalLen) break;
|
|
||||||
}
|
}
|
||||||
} else if (udpIn[0] == 3 && packetSize > 6) //drgbw
|
} else if (udpIn[0] == 3 && packetSize > 6) //drgbw
|
||||||
{
|
{
|
||||||
unsigned id = 0;
|
for (size_t i = 2, id = 0; i < packetSize -3 && id < totalLen; i += 4, id++)
|
||||||
for (size_t i = 2; i < packetSize -3; i += 4)
|
|
||||||
{
|
{
|
||||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
|
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
|
||||||
|
|
||||||
id++; if (id >= totalLen) break;
|
|
||||||
}
|
}
|
||||||
} else if (udpIn[0] == 4 && packetSize > 7) //dnrgb
|
} else if (udpIn[0] == 4 && packetSize > 7) //dnrgb
|
||||||
{
|
{
|
||||||
unsigned id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00);
|
unsigned id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00);
|
||||||
for (size_t i = 4; i < packetSize -2; i += 3)
|
for (size_t i = 4; i < packetSize -2 && id < totalLen; i += 3, id++)
|
||||||
{
|
{
|
||||||
if (id >= totalLen) break;
|
|
||||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
||||||
id++;
|
|
||||||
}
|
}
|
||||||
} else if (udpIn[0] == 5 && packetSize > 8) //dnrgbw
|
} else if (udpIn[0] == 5 && packetSize > 8) //dnrgbw
|
||||||
{
|
{
|
||||||
unsigned id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00);
|
unsigned id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00);
|
||||||
for (size_t i = 4; i < packetSize -2; i += 4)
|
for (size_t i = 4; i < packetSize -2 && id < totalLen; i += 4, id++)
|
||||||
{
|
{
|
||||||
if (id >= totalLen) break;
|
|
||||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
|
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
|
||||||
id++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strip.show();
|
strip.show();
|
||||||
@ -705,8 +688,7 @@ void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w)
|
|||||||
w = gamma8(w);
|
w = gamma8(w);
|
||||||
}
|
}
|
||||||
if (useMainSegmentOnly) {
|
if (useMainSegmentOnly) {
|
||||||
Segment &seg = strip.getMainSegment();
|
strip.getMainSegment().setPixelColor(pix, r, g, b, w); // this expects that strip.getMainSegment().beginDraw() has been called in handleNotification()
|
||||||
if (pix<seg.length()) seg.setPixelColor(pix, r, g, b, w);
|
|
||||||
} else {
|
} else {
|
||||||
strip.setPixelColor(pix, r, g, b, w);
|
strip.setPixelColor(pix, r, g, b, w);
|
||||||
}
|
}
|
||||||
|
@ -152,6 +152,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
|||||||
DEBUG_PRINTF_P(PSTR("settings resp %u\n"), (unsigned)subPage);
|
DEBUG_PRINTF_P(PSTR("settings resp %u\n"), (unsigned)subPage);
|
||||||
|
|
||||||
if (subPage <0 || subPage >10) return;
|
if (subPage <0 || subPage >10) return;
|
||||||
|
char nS[32];
|
||||||
|
|
||||||
if (subPage == SUBPAGE_MENU)
|
if (subPage == SUBPAGE_MENU)
|
||||||
{
|
{
|
||||||
@ -259,8 +260,6 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
|||||||
|
|
||||||
if (subPage == SUBPAGE_LEDS)
|
if (subPage == SUBPAGE_LEDS)
|
||||||
{
|
{
|
||||||
char nS[32];
|
|
||||||
|
|
||||||
appendGPIOinfo(settingsScript);
|
appendGPIOinfo(settingsScript);
|
||||||
|
|
||||||
settingsScript.print(SET_F("d.ledTypes=")); settingsScript.print(BusManager::getLEDTypesJSONString().c_str()); settingsScript.print(";");
|
settingsScript.print(SET_F("d.ledTypes=")); settingsScript.print(BusManager::getLEDTypesJSONString().c_str()); settingsScript.print(";");
|
||||||
@ -399,7 +398,6 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
|||||||
|
|
||||||
if (subPage == SUBPAGE_SYNC)
|
if (subPage == SUBPAGE_SYNC)
|
||||||
{
|
{
|
||||||
[[maybe_unused]] char nS[32];
|
|
||||||
printSetFormValue(settingsScript,PSTR("UP"),udpPort);
|
printSetFormValue(settingsScript,PSTR("UP"),udpPort);
|
||||||
printSetFormValue(settingsScript,PSTR("U2"),udpPort2);
|
printSetFormValue(settingsScript,PSTR("U2"),udpPort2);
|
||||||
#ifndef WLED_DISABLE_ESPNOW
|
#ifndef WLED_DISABLE_ESPNOW
|
||||||
|
Loading…
x
Reference in New Issue
Block a user