mirror of
https://github.com/wled/WLED.git
synced 2025-07-19 00:36:36 +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 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 SEGCOLOR(x) Segment::getCurrentColor(x)
|
||||
#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)
|
||||
|
||||
// some common colors
|
||||
@ -421,7 +421,9 @@ typedef struct Segment {
|
||||
uint16_t _dataLen;
|
||||
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 _randomPalette; // actual random palette
|
||||
static CRGBPalette16 _newRandomPalette; // target random palette
|
||||
@ -534,14 +536,20 @@ typedef struct Segment {
|
||||
inline uint16_t groupLength() const { return grouping + spacing; }
|
||||
inline uint8_t getLightCapabilities() const { return _capabilities; }
|
||||
|
||||
inline static uint16_t getUsedSegmentData() { return _usedSegmentData; }
|
||||
inline static void addUsedSegmentData(int len) { _usedSegmentData += len; }
|
||||
inline static uint16_t getUsedSegmentData() { return Segment::_usedSegmentData; }
|
||||
inline static void addUsedSegmentData(int len) { Segment::_usedSegmentData += len; }
|
||||
#ifndef WLED_DISABLE_MODE_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; }
|
||||
|
||||
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);
|
||||
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
|
||||
void setCCT(uint16_t k);
|
||||
@ -578,12 +586,11 @@ typedef struct Segment {
|
||||
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);
|
||||
void setCurrentPalette();
|
||||
|
||||
// 1D strip
|
||||
[[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); }
|
||||
[[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, 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, CRGB c) { setPixelColor(n, RGBW32(c.r,c.g,c.b,0)); }
|
||||
#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)
|
||||
#ifndef WLED_DISABLE_2D
|
||||
[[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); }
|
||||
[[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, 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, 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)); }
|
||||
@ -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)); }
|
||||
void box_blur(unsigned r = 1U, bool smear = false); // 2D box blur
|
||||
void blur2D(uint8_t blur_amount, bool smear = false);
|
||||
void blurRow(uint32_t row, fract8 blur_amount, bool smear = false);
|
||||
void blurCol(uint32_t col, fract8 blur_amount, bool smear = false);
|
||||
void blurRow(int row, 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 moveY(int8_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 fill_solid(CRGB c) { fill(RGBW32(c.r,c.g,c.b,0)); }
|
||||
#else
|
||||
inline uint16_t XY(uint16_t x, uint16_t 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 uint16_t XY(int x, int y) { return x; }
|
||||
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, 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, 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)); }
|
||||
@ -680,8 +687,8 @@ typedef struct Segment {
|
||||
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 blur2D(uint8_t blur_amount, bool smear = false) {}
|
||||
inline void blurRow(uint32_t row, fract8 blur_amount, bool smear = false) {}
|
||||
inline void blurCol(uint32_t col, fract8 blur_amount, 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(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) {}
|
||||
@ -727,9 +734,6 @@ class WS2812FX { // 96 bytes
|
||||
autoSegments(false),
|
||||
correctWB(false),
|
||||
cctFromRgb(false),
|
||||
// semi-private (just obscured) used in effect functions through macros
|
||||
_colors_t{0,0,0},
|
||||
_virtualSegmentLength(0),
|
||||
// true private variables
|
||||
_suspend(false),
|
||||
_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;
|
||||
|
||||
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 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
|
||||
@ -855,7 +859,6 @@ class WS2812FX { // 96 bytes
|
||||
uint32_t getPixelColor(unsigned) const;
|
||||
|
||||
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 *
|
||||
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;
|
||||
};
|
||||
|
||||
// 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;
|
||||
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)
|
||||
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)
|
||||
unsigned height = virtualHeight(); // segment height in logical pixels (is always >= 1)
|
||||
return isActive() ? (x%width) + (y%height) * width : 0;
|
||||
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)
|
||||
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 (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
||||
|
||||
uint8_t _bri_t = currentBri();
|
||||
if (_bri_t < 255) {
|
||||
col = color_fade(col, _bri_t);
|
||||
}
|
||||
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)
|
||||
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 (reverse_y) y = virtualHeight() - y - 1;
|
||||
// if color is unscaled
|
||||
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
|
||||
x *= 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 (x<0.0f || x>1.0f || y<0.0f || y>1.0f) return; // not normalized
|
||||
|
||||
const unsigned cols = virtualWidth();
|
||||
const unsigned rows = virtualHeight();
|
||||
|
||||
float fX = x * (cols-1);
|
||||
float fY = y * (rows-1);
|
||||
float fX = x * (vWidth()-1);
|
||||
float fY = y * (vHeight()-1);
|
||||
if (aa) {
|
||||
unsigned xL = 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
|
||||
uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const {
|
||||
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
|
||||
if (reverse ) x = virtualWidth() - x - 1;
|
||||
if (reverse_y) y = virtualHeight() - y - 1;
|
||||
int vW = vWidth();
|
||||
int vH = vHeight();
|
||||
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
|
||||
x *= 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
|
||||
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
|
||||
const unsigned cols = virtualWidth();
|
||||
const unsigned rows = virtualHeight();
|
||||
const int cols = vWidth();
|
||||
const int rows = vHeight();
|
||||
|
||||
if (row >= rows) return;
|
||||
// blur one row
|
||||
@ -287,7 +287,7 @@ void Segment::blurRow(uint32_t row, fract8 blur_amount, bool smear){
|
||||
uint32_t lastnew;
|
||||
uint32_t last;
|
||||
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 part = color_fade(cur, seep);
|
||||
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
|
||||
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
|
||||
const unsigned cols = virtualWidth();
|
||||
const unsigned rows = virtualHeight();
|
||||
const int cols = vWidth();
|
||||
const int rows = vHeight();
|
||||
|
||||
if (col >= cols) return;
|
||||
// blur one column
|
||||
@ -319,7 +319,7 @@ void Segment::blurCol(uint32_t col, fract8 blur_amount, bool smear) {
|
||||
uint32_t lastnew;
|
||||
uint32_t last;
|
||||
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 part = color_fade(cur, seep);
|
||||
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) {
|
||||
if (!isActive() || blur_amount == 0) return; // not active
|
||||
const unsigned cols = virtualWidth();
|
||||
const unsigned rows = virtualHeight();
|
||||
const unsigned cols = vWidth();
|
||||
const unsigned rows = vHeight();
|
||||
|
||||
const uint8_t keep = smear ? 255 : 255 - blur_amount;
|
||||
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 (radius > 3) radius = 3;
|
||||
const unsigned d = (1 + 2*radius) * (1 + 2*radius); // averaging divisor
|
||||
const unsigned cols = virtualWidth();
|
||||
const unsigned rows = virtualHeight();
|
||||
const unsigned cols = vWidth();
|
||||
const unsigned rows = vHeight();
|
||||
uint16_t *tmpRSum = new uint16_t[cols*rows];
|
||||
uint16_t *tmpGSum = 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) {
|
||||
if (!isActive()) return; // not active
|
||||
const int cols = virtualWidth();
|
||||
const int rows = virtualHeight();
|
||||
if (!delta || abs(delta) >= cols) return;
|
||||
uint32_t newPxCol[cols];
|
||||
for (int y = 0; y < rows; y++) {
|
||||
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)
|
||||
if (!delta || abs(delta) >= vW) return;
|
||||
uint32_t newPxCol[vW];
|
||||
for (int y = 0; y < vH; y++) {
|
||||
if (delta > 0) {
|
||||
for (int x = 0; x < cols-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 = 0; x < vW-delta; x++) newPxCol[x] = getPixelColorXY((x + delta), y);
|
||||
for (int x = vW-delta; x < vW; x++) newPxCol[x] = getPixelColorXY(wrap ? (x + delta) - vW : x, y);
|
||||
} else {
|
||||
for (int x = cols-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 = 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) + 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) {
|
||||
if (!isActive()) return; // not active
|
||||
const int cols = virtualWidth();
|
||||
const int rows = virtualHeight();
|
||||
if (!delta || abs(delta) >= rows) return;
|
||||
uint32_t newPxCol[rows];
|
||||
for (int x = 0; x < cols; x++) {
|
||||
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)
|
||||
if (!delta || abs(delta) >= vH) return;
|
||||
uint32_t newPxCol[vH];
|
||||
for (int x = 0; x < vW; x++) {
|
||||
if (delta > 0) {
|
||||
for (int y = 0; y < rows-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 = 0; y < vH-delta; y++) newPxCol[y] = getPixelColorXY(x, (y + delta));
|
||||
for (int y = vH-delta; y < vH; y++) newPxCol[y] = getPixelColorXY(x, wrap ? (y + delta) - vH : y);
|
||||
} else {
|
||||
for (int y = rows-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 = 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) + 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++;
|
||||
}
|
||||
} else {
|
||||
// pre-scale color for all pixels
|
||||
col = color_fade(col, currentBri());
|
||||
// Bresenham’s Algorithm
|
||||
int d = 3 - (2*radius);
|
||||
int y = radius, x = 0;
|
||||
while (y >= x) {
|
||||
setPixelColorXY(cx+x, cy+y, col);
|
||||
setPixelColorXY(cx-x, cy+y, col);
|
||||
setPixelColorXY(cx+x, cy-y, col);
|
||||
setPixelColorXY(cx-x, cy-y, col);
|
||||
setPixelColorXY(cx+y, cy+x, col);
|
||||
setPixelColorXY(cx-y, cy+x, col);
|
||||
setPixelColorXY(cx+y, cy-x, col);
|
||||
setPixelColorXY(cx-y, cy-x, col);
|
||||
setPixelColorXY(cx+x, cy+y, col, false);
|
||||
setPixelColorXY(cx-x, cy+y, col, false);
|
||||
setPixelColorXY(cx+x, cy-y, col, false);
|
||||
setPixelColorXY(cx-x, cy-y, col, false);
|
||||
setPixelColorXY(cx+y, cy+x, col, false);
|
||||
setPixelColorXY(cx-y, cy+x, col, false);
|
||||
setPixelColorXY(cx+y, cy-x, col, false);
|
||||
setPixelColorXY(cx-y, cy-x, col, false);
|
||||
x++;
|
||||
if (d > 0) {
|
||||
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
|
||||
void Segment::fillCircle(uint16_t cx, uint16_t cy, uint8_t radius, uint32_t col, bool soft) {
|
||||
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
|
||||
if (soft) drawCircle(cx, cy, radius, col, soft);
|
||||
// pre-scale color for all pixels
|
||||
col = color_fade(col, currentBri());
|
||||
// fill it
|
||||
const int cols = virtualWidth();
|
||||
const int rows = virtualHeight();
|
||||
for (int y = -radius; y <= radius; y++) {
|
||||
for (int x = -radius; x <= radius; x++) {
|
||||
if (x * x + y * y <= radius * radius &&
|
||||
int(cx)+x>=0 && int(cy)+y>=0 &&
|
||||
int(cx)+x<cols && int(cy)+y<rows)
|
||||
setPixelColorXY(cx + x, cy + y, col);
|
||||
int(cx)+x >= 0 && int(cy)+y >= 0 &&
|
||||
int(cx)+x < vW && int(cy)+y < vH)
|
||||
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
|
||||
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
|
||||
const int cols = virtualWidth();
|
||||
const int rows = virtualHeight();
|
||||
if (x0 >= cols || x1 >= cols || y0 >= rows || y1 >= rows) return;
|
||||
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)
|
||||
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 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
|
||||
}
|
||||
} else {
|
||||
// pre-scale color for all pixels
|
||||
c = color_fade(c, currentBri());
|
||||
// Bresenham's algorithm
|
||||
int err = (dx>dy ? dx : -dy)/2; // error direction
|
||||
for (;;) {
|
||||
setPixelColorXY(x0, y0, c);
|
||||
setPixelColorXY(x0, y0, c, false);
|
||||
if (x0==x1 && y0==y1) break;
|
||||
int e2 = err;
|
||||
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 (chr < 32 || chr > 126) return; // only ASCII 32-126 supported
|
||||
chr -= 32; // align with font table entries
|
||||
const int cols = virtualWidth();
|
||||
const int rows = virtualHeight();
|
||||
const int font = w*h;
|
||||
|
||||
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
|
||||
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
|
||||
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::maxWidth = DEFAULT_LED_COUNT;
|
||||
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::_randomPalette = 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::_lastPaletteBlend = 0; //in millis (lowest 16 bits only)
|
||||
uint16_t Segment::_lastPaletteBlend = 0; // in millis (lowest 16 bits only)
|
||||
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
bool Segment::_modeBlend = false;
|
||||
@ -437,7 +440,21 @@ uint32_t IRAM_ATTR_YN Segment::currentColor(uint8_t slot) const {
|
||||
#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);
|
||||
unsigned prog = progress();
|
||||
if (strip.paletteFade && prog < 0xFFFFU) {
|
||||
@ -698,20 +715,21 @@ uint16_t IRAM_ATTR Segment::virtualLength() const {
|
||||
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
|
||||
#ifndef WLED_DISABLE_2D
|
||||
int vStrip = 0;
|
||||
#endif
|
||||
int vL = vLength();
|
||||
// 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()
|
||||
if (i >= virtualLength()) {
|
||||
if (i >= vL) {
|
||||
// check if this is a virtual strip
|
||||
#ifndef WLED_DISABLE_2D
|
||||
vStrip = i>>16; // hack to allow running on virtual strips (2D segment columns/rows)
|
||||
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
|
||||
return;
|
||||
#endif
|
||||
@ -719,22 +737,24 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (is2D()) {
|
||||
int vH = virtualHeight(); // segment height in logical pixels
|
||||
int vW = virtualWidth();
|
||||
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)
|
||||
// pre-scale color for all pixels
|
||||
col = color_fade(col, currentBri());
|
||||
switch (map1D2D) {
|
||||
case M12_Pixels:
|
||||
// use all available pixels as a long strip
|
||||
setPixelColorXY(i % vW, i / vW, col);
|
||||
setPixelColorXY(i % vW, i / vW, col, false);
|
||||
break;
|
||||
case M12_pBar:
|
||||
// expand 1D effect vertically or have it play on virtual strips
|
||||
if (vStrip > 0) setPixelColorXY(vStrip - 1, vH - i - 1, col);
|
||||
else for (int x = 0; x < vW; x++) setPixelColorXY(x, 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, false);
|
||||
break;
|
||||
case M12_pArc:
|
||||
// expand in circular fashion from center
|
||||
if (i == 0)
|
||||
setPixelColorXY(0, 0, col);
|
||||
setPixelColorXY(0, 0, col, false);
|
||||
else {
|
||||
float r = i;
|
||||
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 y = roundf(cos_t(rad) * r);
|
||||
// exploit symmetry
|
||||
setPixelColorXY(x, y, col);
|
||||
setPixelColorXY(y, x, col);
|
||||
setPixelColorXY(x, y, col, false);
|
||||
setPixelColorXY(y, x, col, false);
|
||||
}
|
||||
// Bresenham’s Algorithm (may not fill every pixel)
|
||||
//int d = 3 - (2*i);
|
||||
@ -762,8 +782,8 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
||||
}
|
||||
break;
|
||||
case M12_pCorner:
|
||||
for (int x = 0; x <= i; x++) setPixelColorXY(x, i, col);
|
||||
for (int y = 0; y < i; y++) setPixelColorXY(i, y, col);
|
||||
for (int x = 0; x <= i; x++) setPixelColorXY(x, i, col, false);
|
||||
for (int y = 0; y < i; y++) setPixelColorXY(i, y, col, false);
|
||||
break;
|
||||
case M12_sPinwheel: {
|
||||
// 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 y = posy / Fixed_Scale;
|
||||
// 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;
|
||||
lastY = y;
|
||||
// advance to next position
|
||||
@ -813,12 +833,12 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
||||
}
|
||||
}
|
||||
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) {
|
||||
// we have a vertical or horizontal 1D segment (WARNING: virtual...() may be transposed)
|
||||
int x = 0, y = 0;
|
||||
if (virtualHeight()>1) y = i;
|
||||
if (virtualWidth() >1) x = i;
|
||||
if (vHeight() > 1) y = i;
|
||||
if (vWidth() > 1) x = i;
|
||||
setPixelColorXY(x, y, col);
|
||||
return;
|
||||
}
|
||||
@ -826,10 +846,8 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col)
|
||||
#endif
|
||||
|
||||
unsigned len = length();
|
||||
uint8_t _bri_t = currentBri();
|
||||
if (_bri_t < 255) {
|
||||
col = color_fade(col, _bri_t);
|
||||
}
|
||||
// if color is unscaled
|
||||
if (unScaled) col = color_fade(col, currentBri());
|
||||
|
||||
// expand pixel (taking into account start, grouping, spacing [and offset])
|
||||
i = i * groupLength();
|
||||
@ -907,8 +925,8 @@ uint32_t IRAM_ATTR_YN Segment::getPixelColor(int i) const
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (is2D()) {
|
||||
int vH = virtualHeight(); // segment height in logical pixels
|
||||
int vW = virtualWidth();
|
||||
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)
|
||||
switch (map1D2D) {
|
||||
case M12_Pixels:
|
||||
return getPixelColorXY(i % vW, i / vW);
|
||||
@ -961,7 +979,7 @@ uint32_t IRAM_ATTR_YN Segment::getPixelColor(int i) const
|
||||
}
|
||||
#endif
|
||||
|
||||
if (reverse) i = virtualLength() - i - 1;
|
||||
if (reverse) i = vLength() - i - 1;
|
||||
i *= groupLength();
|
||||
i += start;
|
||||
// offset/phase
|
||||
@ -1050,11 +1068,13 @@ void Segment::refreshLightCapabilities() {
|
||||
*/
|
||||
void Segment::fill(uint32_t c) {
|
||||
if (!isActive()) return; // not active
|
||||
const int cols = is2D() ? virtualWidth() : virtualLength();
|
||||
const int rows = virtualHeight(); // will be 1 for 1D
|
||||
const int cols = is2D() ? vWidth() : vLength();
|
||||
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++) {
|
||||
if (is2D()) setPixelColorXY(x, y, c);
|
||||
else setPixelColor(x, c);
|
||||
if (is2D()) setPixelColorXY(x, y, c, false);
|
||||
else setPixelColor(x, c, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1063,8 +1083,8 @@ void Segment::fill(uint32_t c) {
|
||||
*/
|
||||
void Segment::fade_out(uint8_t rate) {
|
||||
if (!isActive()) return; // not active
|
||||
const int cols = is2D() ? virtualWidth() : virtualLength();
|
||||
const int rows = virtualHeight(); // will be 1 for 1D
|
||||
const int cols = is2D() ? vWidth() : vLength();
|
||||
const int rows = vHeight(); // will be 1 for 1D
|
||||
|
||||
rate = (255-rate) >> 1;
|
||||
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()
|
||||
void Segment::fadeToBlackBy(uint8_t fadeBy) {
|
||||
if (!isActive() || fadeBy == 0) return; // optimization - no scaling to apply
|
||||
const int cols = is2D() ? virtualWidth() : virtualLength();
|
||||
const int rows = virtualHeight(); // will be 1 for 1D
|
||||
const int cols = is2D() ? vWidth() : vLength();
|
||||
const int rows = vHeight(); // will be 1 for 1D
|
||||
|
||||
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));
|
||||
@ -1126,7 +1146,7 @@ void Segment::blur(uint8_t blur_amount, bool smear) {
|
||||
#endif
|
||||
uint8_t keep = smear ? 255 : 255 - blur_amount;
|
||||
uint8_t seep = blur_amount >> (1 + smear);
|
||||
unsigned vlength = virtualLength();
|
||||
unsigned vlength = vLength();
|
||||
uint32_t carryover = BLACK;
|
||||
uint32_t lastnew;
|
||||
uint32_t last;
|
||||
@ -1140,8 +1160,7 @@ void Segment::blur(uint8_t blur_amount, bool smear) {
|
||||
uint32_t prev = color_add(lastnew, part);
|
||||
// optimization: only set pixel if color has changed
|
||||
if (last != prev) setPixelColor(i - 1, prev);
|
||||
} else // first pixel
|
||||
setPixelColor(i, curnew);
|
||||
} else setPixelColor(i, curnew); // first pixel
|
||||
lastnew = curnew;
|
||||
last = cur; // save original value for comparison on next iteration
|
||||
carryover = part;
|
||||
@ -1156,7 +1175,7 @@ void Segment::blur(uint8_t blur_amount, bool smear) {
|
||||
*/
|
||||
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"
|
||||
uint8_t w = W(currentColor(0));
|
||||
uint8_t w = W(getCurrentColor(0));
|
||||
pos = 255 - pos;
|
||||
if (pos < 85) {
|
||||
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
|
||||
*/
|
||||
uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) const {
|
||||
|
||||
uint32_t color = currentColor(mcol);
|
||||
uint32_t color = getCurrentColor(mcol < NUM_COLORS ? mcol : 0);
|
||||
// default palette or no RGB support on segment
|
||||
if ((palette == 0 && mcol < NUM_COLORS) || !_isRGB) {
|
||||
color = gamma32(color);
|
||||
return (pbri == 255) ? color : color_fade(color, pbri, true);
|
||||
return color_fade(color, pbri, true);
|
||||
}
|
||||
|
||||
const int vL = vLength();
|
||||
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)
|
||||
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
|
||||
palcol.w = gamma8(W(color));
|
||||
palcol.w = W(color);
|
||||
|
||||
return palcol.color32;
|
||||
}
|
||||
@ -1359,11 +1377,6 @@ void WS2812FX::service() {
|
||||
|
||||
if (!seg.freeze) { //only run effect function if not frozen
|
||||
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 cctFromRgb is true we implicitly calculate WW and CW from RGB values
|
||||
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
|
||||
// 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
|
||||
seg.beginDraw(); // set up parameters for get/setPixelColor()
|
||||
delay = (*_mode[seg.mode])(); // run new/current mode
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (modeBlending && seg.mode != tmpMode) {
|
||||
Segment::tmpsegd_t _tmpSegData;
|
||||
Segment::modeBlend(true); // set semaphore
|
||||
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
|
||||
seg.restoreSegenv(_tmpSegData); // restore mode state (will also update transitional state)
|
||||
delay = MIN(delay,d2); // use shortest delay
|
||||
@ -1397,7 +1411,6 @@ void WS2812FX::service() {
|
||||
}
|
||||
_segment_index++;
|
||||
}
|
||||
_virtualSegmentLength = 0;
|
||||
_isServicing = false;
|
||||
_triggered = false;
|
||||
|
||||
|
@ -416,18 +416,18 @@ void realtimeLock(uint32_t timeoutMs, byte md)
|
||||
start = mainseg.start;
|
||||
stop = mainseg.stop;
|
||||
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 {
|
||||
start = 0;
|
||||
stop = strip.getLengthTotal();
|
||||
}
|
||||
// clear strip/segment
|
||||
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 (briT == 0 && !realtimeMode && !realtimeOverride) {
|
||||
@ -510,12 +510,10 @@ void handleNotifications()
|
||||
rgbUdp.read(lbuf, packetSize);
|
||||
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_HYPERION);
|
||||
if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return;
|
||||
unsigned id = 0;
|
||||
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);
|
||||
id++; if (id >= totalLen) break;
|
||||
}
|
||||
if (!(realtimeMode && useMainSegmentOnly)) strip.show();
|
||||
return;
|
||||
@ -595,17 +593,11 @@ void handleNotifications()
|
||||
|
||||
unsigned id = (tpmPayloadFrameSize/3)*(packetNum-1); //start LED
|
||||
unsigned totalLen = strip.getLengthTotal();
|
||||
for (size_t i = 6; i < tpmPayloadFrameSize + 4U; i += 3)
|
||||
{
|
||||
if (id < totalLen)
|
||||
{
|
||||
if (useMainSegmentOnly) strip.getMainSegment().beginDraw(); // set up parameters for get/setPixelColor()
|
||||
for (size_t i = 6; i < tpmPayloadFrameSize + 4U && id < totalLen; i += 3, id++) {
|
||||
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;
|
||||
strip.show();
|
||||
}
|
||||
@ -629,6 +621,7 @@ void handleNotifications()
|
||||
if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return;
|
||||
|
||||
unsigned totalLen = strip.getLengthTotal();
|
||||
if (useMainSegmentOnly) strip.getMainSegment().beginDraw(); // set up parameters for get/setPixelColor()
|
||||
if (udpIn[0] == 1 && packetSize > 5) //warls
|
||||
{
|
||||
for (size_t i = 2; i < packetSize -3; i += 4)
|
||||
@ -637,39 +630,29 @@ void handleNotifications()
|
||||
}
|
||||
} else if (udpIn[0] == 2 && packetSize > 4) //drgb
|
||||
{
|
||||
unsigned id = 0;
|
||||
for (size_t i = 2; i < packetSize -2; i += 3)
|
||||
for (size_t i = 2, id = 0; i < packetSize -2 && id < totalLen; i += 3, id++)
|
||||
{
|
||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
||||
|
||||
id++; if (id >= totalLen) break;
|
||||
}
|
||||
} else if (udpIn[0] == 3 && packetSize > 6) //drgbw
|
||||
{
|
||||
unsigned id = 0;
|
||||
for (size_t i = 2; i < packetSize -3; i += 4)
|
||||
for (size_t i = 2, id = 0; i < packetSize -3 && id < totalLen; i += 4, id++)
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
id++;
|
||||
}
|
||||
} else if (udpIn[0] == 5 && packetSize > 8) //dnrgbw
|
||||
{
|
||||
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]);
|
||||
id++;
|
||||
}
|
||||
}
|
||||
strip.show();
|
||||
@ -705,8 +688,7 @@ void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
w = gamma8(w);
|
||||
}
|
||||
if (useMainSegmentOnly) {
|
||||
Segment &seg = strip.getMainSegment();
|
||||
if (pix<seg.length()) seg.setPixelColor(pix, r, g, b, w);
|
||||
strip.getMainSegment().setPixelColor(pix, r, g, b, w); // this expects that strip.getMainSegment().beginDraw() has been called in handleNotification()
|
||||
} else {
|
||||
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);
|
||||
|
||||
if (subPage <0 || subPage >10) return;
|
||||
char nS[32];
|
||||
|
||||
if (subPage == SUBPAGE_MENU)
|
||||
{
|
||||
@ -259,8 +260,6 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
||||
|
||||
if (subPage == SUBPAGE_LEDS)
|
||||
{
|
||||
char nS[32];
|
||||
|
||||
appendGPIOinfo(settingsScript);
|
||||
|
||||
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)
|
||||
{
|
||||
[[maybe_unused]] char nS[32];
|
||||
printSetFormValue(settingsScript,PSTR("UP"),udpPort);
|
||||
printSetFormValue(settingsScript,PSTR("U2"),udpPort2);
|
||||
#ifndef WLED_DISABLE_ESPNOW
|
||||
|
Loading…
x
Reference in New Issue
Block a user