mirror of
https://github.com/wled/WLED.git
synced 2025-07-10 04:16:36 +00:00
Merge branch '0_15' into blending-styles
This commit is contained in:
commit
e1598a9966
@ -12,6 +12,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// To give the container access to a device serial port, you can uncomment one of the following lines.
|
||||||
|
// Note: If running on Windows, you will have to do some additional steps:
|
||||||
|
// https://stackoverflow.com/questions/68527888/how-can-i-use-a-usb-com-port-inside-of-a-vscode-development-container
|
||||||
|
//
|
||||||
|
// You can explicitly just forward the port you want to connect to. Replace `/dev/ttyACM0` with the serial port for
|
||||||
|
// your device. This will only work if the device is plugged in from the start without reconnecting. Adding the
|
||||||
|
// `dialout` group is needed if read/write permisions for the port are limitted to the dialout user.
|
||||||
|
// "runArgs": ["--device=/dev/ttyACM0", "--group-add", "dialout"],
|
||||||
|
//
|
||||||
|
// Alternatively, you can give more comprehensive access to the host system. This will expose all the host devices to
|
||||||
|
// the container. Adding the `dialout` group is needed if read/write permisions for the port are limitted to the
|
||||||
|
// dialout user. This could allow the container to modify unrelated serial devices, which would be a similar level of
|
||||||
|
// risk to running the build directly on the host.
|
||||||
|
// "runArgs": ["--privileged", "-v", "/dev/bus/usb:/dev/bus/usb", "--group-add", "dialout"],
|
||||||
|
|
||||||
// Set *default* container specific settings.json values on container create.
|
// Set *default* container specific settings.json values on container create.
|
||||||
"settings": {
|
"settings": {
|
||||||
"terminal.integrated.shell.linux": "/bin/bash",
|
"terminal.integrated.shell.linux": "/bin/bash",
|
||||||
|
@ -2106,14 +2106,17 @@ uint16_t mode_fire_2012() {
|
|||||||
for (unsigned stripNr=0; stripNr<strips; stripNr++)
|
for (unsigned stripNr=0; stripNr<strips; stripNr++)
|
||||||
virtualStrip::runStrip(stripNr, &heat[stripNr * SEGLEN], it);
|
virtualStrip::runStrip(stripNr, &heat[stripNr * SEGLEN], it);
|
||||||
|
|
||||||
if (SEGMENT.is2D()) SEGMENT.blur(32);
|
if (SEGMENT.is2D()) {
|
||||||
|
uint8_t blurAmount = SEGMENT.custom2 >> 2;
|
||||||
|
SEGMENT.blur(blurAmount);
|
||||||
|
}
|
||||||
|
|
||||||
if (it != SEGENV.step)
|
if (it != SEGENV.step)
|
||||||
SEGENV.step = it;
|
SEGENV.step = it;
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_FIRE_2012[] PROGMEM = "Fire 2012@Cooling,Spark rate,,,Boost;;!;1;sx=64,ix=160,m12=1"; // bars
|
static const char _data_FX_MODE_FIRE_2012[] PROGMEM = "Fire 2012@Cooling,Spark rate,,2D Blur,Boost;;!;1;sx=64,ix=160,m12=1,c2=128"; // bars
|
||||||
|
|
||||||
|
|
||||||
// ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb
|
// ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb
|
||||||
@ -7456,7 +7459,7 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma.
|
|||||||
if ((fadeoutDelay <= 1 ) || ((SEGENV.call % fadeoutDelay) == 0)) SEGMENT.fadeToBlackBy(SEGMENT.speed);
|
if ((fadeoutDelay <= 1 ) || ((SEGENV.call % fadeoutDelay) == 0)) SEGMENT.fadeToBlackBy(SEGMENT.speed);
|
||||||
|
|
||||||
for (int x=0; x < cols; x++) {
|
for (int x=0; x < cols; x++) {
|
||||||
uint8_t band = map(x, 0, cols-1, 0, NUM_BANDS - 1);
|
uint8_t band = map(x, 0, cols, 0, NUM_BANDS);
|
||||||
if (NUM_BANDS < 16) band = map(band, 0, NUM_BANDS - 1, 0, 15); // always use full range. comment out this line to get the previous behaviour.
|
if (NUM_BANDS < 16) band = map(band, 0, NUM_BANDS - 1, 0, 15); // always use full range. comment out this line to get the previous behaviour.
|
||||||
band = constrain(band, 0, 15);
|
band = constrain(band, 0, 15);
|
||||||
unsigned colorIndex = band * 17;
|
unsigned colorIndex = band * 17;
|
||||||
|
44
wled00/FX.h
44
wled00/FX.h
@ -590,17 +590,17 @@ typedef struct Segment {
|
|||||||
|
|
||||||
// transition functions
|
// transition functions
|
||||||
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
||||||
void stopTransition(void); // ends transition mode by destroying transition structure
|
void stopTransition(void); // ends transition mode by destroying transition structure (does nothing if not in transition)
|
||||||
void handleTransition(void);
|
inline void handleTransition(void) { if (progress() == 0xFFFFU) stopTransition(); }
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
void swapSegenv(tmpsegd_t &tmpSegD); // copies segment data into specifed buffer, if buffer is not a transition buffer, segment data is overwritten from transition buffer
|
void swapSegenv(tmpsegd_t &tmpSegD); // copies segment data into specifed buffer, if buffer is not a transition buffer, segment data is overwritten from transition buffer
|
||||||
void restoreSegenv(tmpsegd_t &tmpSegD); // restores segment data from buffer, if buffer is not transition buffer, changed values are copied to transition buffer
|
void restoreSegenv(tmpsegd_t &tmpSegD); // restores segment data from buffer, if buffer is not transition buffer, changed values are copied to transition buffer
|
||||||
#endif
|
#endif
|
||||||
uint16_t progress(void); // transition progression between 0-65535
|
uint16_t progress(void) const; // transition progression between 0-65535
|
||||||
uint8_t currentBri(bool useCct = false); // current segment brightness/CCT (blended while in transition)
|
uint8_t currentBri(bool useCct = false) const; // current segment brightness/CCT (blended while in transition)
|
||||||
uint8_t currentMode(void); // currently active effect/mode (while in transition)
|
uint8_t currentMode(void) const; // currently active effect/mode (while in transition)
|
||||||
uint8_t currentPalette(void); // currently active palette (while in transition)
|
uint8_t currentPalette(void) const; // currently active palette (while in transition)
|
||||||
uint32_t currentColor(uint8_t slot); // currently active segment color (blended while in transition)
|
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(void);
|
void setCurrentPalette(void);
|
||||||
|
|
||||||
@ -618,8 +618,8 @@ typedef struct Segment {
|
|||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
static inline void setClippingRect(int startX, int stopX, int startY = 0, int stopY = 1) { _clipStart = startX; _clipStop = stopX; _clipStartY = startY; _clipStopY = stopY; };
|
static inline void setClippingRect(int startX, int stopX, int startY = 0, int stopY = 1) { _clipStart = startX; _clipStop = stopX; _clipStartY = startY; _clipStopY = stopY; };
|
||||||
#endif
|
#endif
|
||||||
bool isPixelClipped(int i);
|
bool isPixelClipped(int i) const;
|
||||||
uint32_t getPixelColor(int i);
|
uint32_t getPixelColor(int i) const;
|
||||||
// 1D support functions (some implement 2D as well)
|
// 1D support functions (some implement 2D as well)
|
||||||
void blur(uint8_t, bool smear = false);
|
void blur(uint8_t, bool smear = false);
|
||||||
void fill(uint32_t c);
|
void fill(uint32_t c);
|
||||||
@ -631,8 +631,8 @@ typedef struct Segment {
|
|||||||
inline void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(n, RGBW32(r,g,b,w), fast); }
|
inline void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(n, RGBW32(r,g,b,w), fast); }
|
||||||
inline void addPixelColor(int n, CRGB c, bool fast = false) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), fast); }
|
inline void addPixelColor(int n, CRGB c, bool fast = false) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), fast); }
|
||||||
inline void fadePixelColor(uint16_t n, uint8_t fade) { setPixelColor(n, color_fade(getPixelColor(n), fade, true)); }
|
inline void fadePixelColor(uint16_t n, uint8_t fade) { setPixelColor(n, color_fade(getPixelColor(n), fade, true)); }
|
||||||
uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255);
|
uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255) const;
|
||||||
uint32_t color_wheel(uint8_t pos);
|
uint32_t color_wheel(uint8_t pos) const;
|
||||||
|
|
||||||
// 2D matrix
|
// 2D matrix
|
||||||
uint16_t virtualWidth(void) const; // segment width in virtual pixels (accounts for groupping and spacing)
|
uint16_t virtualWidth(void) const; // segment width in virtual pixels (accounts for groupping and spacing)
|
||||||
@ -650,8 +650,8 @@ typedef struct Segment {
|
|||||||
inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); }
|
inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); }
|
||||||
inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); }
|
inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); }
|
||||||
#endif
|
#endif
|
||||||
bool isPixelXYClipped(int x, int y);
|
bool isPixelXYClipped(int x, int y) const;
|
||||||
uint32_t getPixelColorXY(int x, int y);
|
uint32_t getPixelColorXY(int x, int y) const;
|
||||||
// 2D support functions
|
// 2D support functions
|
||||||
inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend)); }
|
inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend)); }
|
||||||
inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); }
|
inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); }
|
||||||
@ -761,15 +761,7 @@ class WS2812FX { // 96 bytes
|
|||||||
customMappingSize(0),
|
customMappingSize(0),
|
||||||
_lastShow(0),
|
_lastShow(0),
|
||||||
_segment_index(0),
|
_segment_index(0),
|
||||||
_mainSegment(0),
|
_mainSegment(0)
|
||||||
_queuedChangesSegId(255),
|
|
||||||
_qStart(0),
|
|
||||||
_qStop(0),
|
|
||||||
_qStartY(0),
|
|
||||||
_qStopY(0),
|
|
||||||
_qGrouping(0),
|
|
||||||
_qSpacing(0),
|
|
||||||
_qOffset(0)
|
|
||||||
{
|
{
|
||||||
WS2812FX::instance = this;
|
WS2812FX::instance = this;
|
||||||
_mode.reserve(_modeCount); // allocate memory to prevent initial fragmentation (does not increase size())
|
_mode.reserve(_modeCount); // allocate memory to prevent initial fragmentation (does not increase size())
|
||||||
@ -976,14 +968,6 @@ class WS2812FX { // 96 bytes
|
|||||||
|
|
||||||
uint8_t _segment_index;
|
uint8_t _segment_index;
|
||||||
uint8_t _mainSegment;
|
uint8_t _mainSegment;
|
||||||
uint8_t _queuedChangesSegId;
|
|
||||||
uint16_t _qStart, _qStop, _qStartY, _qStopY;
|
|
||||||
uint8_t _qGrouping, _qSpacing;
|
|
||||||
uint16_t _qOffset;
|
|
||||||
/*
|
|
||||||
void
|
|
||||||
setUpSegmentFromQueuedChanges(void);
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char JSON_mode_names[];
|
extern const char JSON_mode_names[];
|
||||||
|
@ -171,7 +171,7 @@ uint16_t IRAM_ATTR Segment::XY(int x, int y) {
|
|||||||
// if clipping start > stop the clipping range is inverted
|
// if clipping start > stop the clipping range is inverted
|
||||||
// _modeBlend==true -> old effect during transition
|
// _modeBlend==true -> old effect during transition
|
||||||
// _modeBlend==false -> new effect during transition
|
// _modeBlend==false -> new effect during transition
|
||||||
bool IRAM_ATTR Segment::isPixelXYClipped(int x, int y) {
|
bool IRAM_ATTR Segment::isPixelXYClipped(int x, int y) const {
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
if (_clipStart != _clipStop && blendingStyle > BLEND_STYLE_FADE) {
|
if (_clipStart != _clipStop && blendingStyle > BLEND_STYLE_FADE) {
|
||||||
const bool invertX = _clipStart > _clipStop;
|
const bool invertX = _clipStart > _clipStop;
|
||||||
@ -234,7 +234,7 @@ void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col)
|
|||||||
|
|
||||||
if (reverse ) x = vW - x - 1;
|
if (reverse ) x = vW - x - 1;
|
||||||
if (reverse_y) y = vH - y - 1;
|
if (reverse_y) y = vH - y - 1;
|
||||||
if (transpose) { unsigned t = x; x = y; y = t; } // 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
|
||||||
@ -318,7 +318,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// returns RGBW values of pixel
|
// returns RGBW values of pixel
|
||||||
uint32_t IRAM_ATTR Segment::getPixelColorXY(int x, int y) {
|
uint32_t IRAM_ATTR Segment::getPixelColorXY(int x, int y) const {
|
||||||
if (!isActive()) return 0; // not active
|
if (!isActive()) return 0; // not active
|
||||||
|
|
||||||
int vW = virtualWidth();
|
int vW = virtualWidth();
|
||||||
@ -346,9 +346,9 @@ uint32_t IRAM_ATTR Segment::getPixelColorXY(int x, int y) {
|
|||||||
|
|
||||||
if (x >= vW || y >= vH || x<0 || y<0 || isPixelXYClipped(x,y)) return 0; // if pixel would fall out of virtual segment just exit
|
if (x >= vW || y >= vH || x<0 || y<0 || isPixelXYClipped(x,y)) return 0; // if pixel would fall out of virtual segment just exit
|
||||||
|
|
||||||
if (reverse ) x = vW - x - 1;
|
if (reverse ) x = vW - x - 1;
|
||||||
if (reverse_y) y = vH - y - 1;
|
if (reverse_y) y = vH - y - 1;
|
||||||
if (transpose) { unsigned t = x; x = y; y = t; } // 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
|
||||||
if (x >= width() || y >= height()) return 0;
|
if (x >= width() || y >= height()) return 0;
|
||||||
|
@ -328,13 +328,8 @@ void Segment::stopTransition() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Segment::handleTransition() {
|
|
||||||
unsigned _progress = progress();
|
|
||||||
if (_progress == 0xFFFFU) stopTransition();
|
|
||||||
}
|
|
||||||
|
|
||||||
// transition progression between 0-65535
|
// transition progression between 0-65535
|
||||||
uint16_t IRAM_ATTR Segment::progress() {
|
uint16_t IRAM_ATTR Segment::progress() const {
|
||||||
if (isInTransition()) {
|
if (isInTransition()) {
|
||||||
unsigned diff = millis() - _t->_start;
|
unsigned diff = millis() - _t->_start;
|
||||||
if (_t->_dur > 0 && diff < _t->_dur) return diff * 0xFFFFU / _t->_dur;
|
if (_t->_dur > 0 && diff < _t->_dur) return diff * 0xFFFFU / _t->_dur;
|
||||||
@ -413,7 +408,7 @@ void Segment::restoreSegenv(tmpsegd_t &tmpSeg) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t IRAM_ATTR Segment::currentBri(bool useCct) {
|
uint8_t IRAM_ATTR Segment::currentBri(bool useCct) const {
|
||||||
uint32_t prog = progress();
|
uint32_t prog = progress();
|
||||||
uint32_t curBri = useCct ? cct : (on ? opacity : 0);
|
uint32_t curBri = useCct ? cct : (on ? opacity : 0);
|
||||||
if (prog < 0xFFFFU) {
|
if (prog < 0xFFFFU) {
|
||||||
@ -430,7 +425,7 @@ uint8_t IRAM_ATTR Segment::currentBri(bool useCct) {
|
|||||||
return curBri;
|
return curBri;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t IRAM_ATTR Segment::currentMode() {
|
uint8_t IRAM_ATTR Segment::currentMode() const {
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
unsigned prog = progress();
|
unsigned prog = progress();
|
||||||
if (prog == 0xFFFFU) return mode;
|
if (prog == 0xFFFFU) return mode;
|
||||||
@ -446,7 +441,7 @@ uint8_t IRAM_ATTR Segment::currentMode() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t IRAM_ATTR Segment::currentColor(uint8_t slot) {
|
uint32_t IRAM_ATTR Segment::currentColor(uint8_t slot) const {
|
||||||
if (slot >= NUM_COLORS) slot = 0;
|
if (slot >= NUM_COLORS) slot = 0;
|
||||||
uint32_t prog = progress();
|
uint32_t prog = progress();
|
||||||
if (prog == 0xFFFFU) return colors[slot];
|
if (prog == 0xFFFFU) return colors[slot];
|
||||||
@ -463,7 +458,7 @@ uint32_t IRAM_ATTR Segment::currentColor(uint8_t slot) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t IRAM_ATTR Segment::currentPalette() {
|
uint8_t IRAM_ATTR Segment::currentPalette() const {
|
||||||
unsigned prog = progress();
|
unsigned prog = progress();
|
||||||
if (prog < 0xFFFFU) {
|
if (prog < 0xFFFFU) {
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
@ -731,9 +726,11 @@ uint16_t IRAM_ATTR Segment::virtualLength() const {
|
|||||||
vLen = vH;
|
vLen = vH;
|
||||||
break;
|
break;
|
||||||
case M12_pCorner:
|
case M12_pCorner:
|
||||||
case M12_pArc:
|
|
||||||
vLen = max(vW,vH); // get the longest dimension
|
vLen = max(vW,vH); // get the longest dimension
|
||||||
break;
|
break;
|
||||||
|
case M12_pArc:
|
||||||
|
vLen = sqrt16(vH*vH + vW*vW); // use diagonal
|
||||||
|
break;
|
||||||
case M12_sPinwheel:
|
case M12_sPinwheel:
|
||||||
vLen = getPinwheelLength(vW, vH);
|
vLen = getPinwheelLength(vW, vH);
|
||||||
break;
|
break;
|
||||||
@ -751,7 +748,7 @@ uint16_t IRAM_ATTR Segment::virtualLength() const {
|
|||||||
// if clipping start > stop the clipping range is inverted
|
// if clipping start > stop the clipping range is inverted
|
||||||
// _modeBlend==true -> old effect during transition
|
// _modeBlend==true -> old effect during transition
|
||||||
// _modeBlend==false -> new effect during transition
|
// _modeBlend==false -> new effect during transition
|
||||||
bool IRAM_ATTR Segment::isPixelClipped(int i) {
|
bool IRAM_ATTR Segment::isPixelClipped(int i) const {
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
if (_clipStart != _clipStop && blendingStyle > BLEND_STYLE_FADE) {
|
if (_clipStart != _clipStop && blendingStyle > BLEND_STYLE_FADE) {
|
||||||
bool invert = _clipStart > _clipStop; // ineverted start & stop
|
bool invert = _clipStart > _clipStop; // ineverted start & stop
|
||||||
@ -804,12 +801,14 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
|
|||||||
if (i==0)
|
if (i==0)
|
||||||
setPixelColorXY(0, 0, col);
|
setPixelColorXY(0, 0, col);
|
||||||
else {
|
else {
|
||||||
float step = HALF_PI / (2.85f*i);
|
float r = i;
|
||||||
for (float rad = 0.0f; rad <= HALF_PI+step/2; rad += step) {
|
float step = HALF_PI / (2.8284f * r + 4); // we only need (PI/4)/(r/sqrt(2)+1) steps
|
||||||
// may want to try float version as well (with or without antialiasing)
|
for (float rad = 0.0f; rad <= (HALF_PI/2)+step/2; rad += step) {
|
||||||
int x = roundf(sin_t(rad) * i);
|
int x = roundf(sin_t(rad) * r);
|
||||||
int y = roundf(cos_t(rad) * i);
|
int y = roundf(cos_t(rad) * r);
|
||||||
|
// exploit symmetry
|
||||||
setPixelColorXY(x, y, col);
|
setPixelColorXY(x, y, col);
|
||||||
|
setPixelColorXY(y, x, col);
|
||||||
}
|
}
|
||||||
// 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);
|
||||||
@ -981,7 +980,7 @@ void Segment::setPixelColor(float i, uint32_t col, bool aa)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t IRAM_ATTR Segment::getPixelColor(int i)
|
uint32_t IRAM_ATTR Segment::getPixelColor(int i) const
|
||||||
{
|
{
|
||||||
if (!isActive()) return 0; // not active
|
if (!isActive()) return 0; // not active
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
@ -1161,7 +1160,7 @@ void Segment::fade_out(uint8_t rate) {
|
|||||||
const int rows = virtualHeight(); // will be 1 for 1D
|
const int rows = virtualHeight(); // will be 1 for 1D
|
||||||
|
|
||||||
rate = (255-rate) >> 1;
|
rate = (255-rate) >> 1;
|
||||||
float mappedRate = float(rate) +1.1f;
|
float mappedRate = 1.0f / (float(rate) + 1.1f);
|
||||||
|
|
||||||
uint32_t color = colors[1]; // SEGCOLOR(1); // target color
|
uint32_t color = colors[1]; // SEGCOLOR(1); // target color
|
||||||
int w2 = W(color);
|
int w2 = W(color);
|
||||||
@ -1171,15 +1170,16 @@ void Segment::fade_out(uint8_t rate) {
|
|||||||
|
|
||||||
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++) {
|
||||||
color = is2D() ? getPixelColorXY(x, y) : getPixelColor(x);
|
color = is2D() ? getPixelColorXY(x, y) : getPixelColor(x);
|
||||||
|
if (color == colors[1]) continue; // already at target color
|
||||||
int w1 = W(color);
|
int w1 = W(color);
|
||||||
int r1 = R(color);
|
int r1 = R(color);
|
||||||
int g1 = G(color);
|
int g1 = G(color);
|
||||||
int b1 = B(color);
|
int b1 = B(color);
|
||||||
|
|
||||||
int wdelta = (w2 - w1) / mappedRate;
|
int wdelta = (w2 - w1) * mappedRate;
|
||||||
int rdelta = (r2 - r1) / mappedRate;
|
int rdelta = (r2 - r1) * mappedRate;
|
||||||
int gdelta = (g2 - g1) / mappedRate;
|
int gdelta = (g2 - g1) * mappedRate;
|
||||||
int bdelta = (b2 - b1) / mappedRate;
|
int bdelta = (b2 - b1) * mappedRate;
|
||||||
|
|
||||||
// if fade isn't complete, make sure delta is at least 1 (fixes rounding issues)
|
// if fade isn't complete, make sure delta is at least 1 (fixes rounding issues)
|
||||||
wdelta += (w2 == w1) ? 0 : (w2 > w1) ? 1 : -1;
|
wdelta += (w2 == w1) ? 0 : (w2 > w1) ? 1 : -1;
|
||||||
@ -1251,7 +1251,7 @@ void Segment::blur(uint8_t blur_amount, bool smear) {
|
|||||||
* The colours are a transition r -> g -> b -> back to r
|
* The colours are a transition r -> g -> b -> back to r
|
||||||
* Inspired by the Adafruit examples.
|
* Inspired by the Adafruit examples.
|
||||||
*/
|
*/
|
||||||
uint32_t Segment::color_wheel(uint8_t pos) {
|
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(currentColor(0));
|
||||||
pos = 255 - pos;
|
pos = 255 - pos;
|
||||||
@ -1275,7 +1275,7 @@ uint32_t Segment::color_wheel(uint8_t pos) {
|
|||||||
* @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling)
|
* @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling)
|
||||||
* @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) {
|
uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) const {
|
||||||
uint32_t color = gamma32(currentColor(mcol));
|
uint32_t color = gamma32(currentColor(mcol));
|
||||||
|
|
||||||
// default palette or no RGB support on segment
|
// default palette or no RGB support on segment
|
||||||
|
@ -378,18 +378,41 @@ void BusDigital::cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
|
// 1 MHz clock
|
||||||
|
#define CLOCK_FREQUENCY 1000000UL
|
||||||
|
#else
|
||||||
|
// Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz
|
||||||
|
// https://github.com/espressif/arduino-esp32/blob/2.0.2/cores/esp32/esp32-hal-ledc.c
|
||||||
|
#ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK
|
||||||
|
#define CLOCK_FREQUENCY 40000000UL
|
||||||
|
#else
|
||||||
|
#define CLOCK_FREQUENCY 80000000UL
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
|
#define MAX_BIT_WIDTH 10
|
||||||
|
#else
|
||||||
|
#ifdef SOC_LEDC_TIMER_BIT_WIDE_NUM
|
||||||
|
// C6/H2/P4: 20 bit, S2/S3/C2/C3: 14 bit
|
||||||
|
#define MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM
|
||||||
|
#else
|
||||||
|
// ESP32: 20 bit (but in reality we would never go beyond 16 bit as the frequency would be to low)
|
||||||
|
#define MAX_BIT_WIDTH 20
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
BusPwm::BusPwm(BusConfig &bc)
|
BusPwm::BusPwm(BusConfig &bc)
|
||||||
: Bus(bc.type, bc.start, bc.autoWhite, 1, bc.reversed)
|
: Bus(bc.type, bc.start, bc.autoWhite, 1, bc.reversed)
|
||||||
{
|
{
|
||||||
if (!IS_PWM(bc.type)) return;
|
if (!IS_PWM(bc.type)) return;
|
||||||
unsigned numPins = NUM_PWM_PINS(bc.type);
|
unsigned numPins = NUM_PWM_PINS(bc.type);
|
||||||
_frequency = bc.frequency ? bc.frequency : WLED_PWM_FREQ;
|
_frequency = bc.frequency ? bc.frequency : WLED_PWM_FREQ;
|
||||||
|
// duty cycle resolution (_depth) can be extracted from this formula: CLOCK_FREQUENCY > _frequency * 2^_depth
|
||||||
|
for (_depth = MAX_BIT_WIDTH; _depth > 8; _depth--) if (((CLOCK_FREQUENCY/_frequency) >> _depth) > 0) break;
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
// duty cycle resolution (_depth) can be extracted from this formula: 1MHz > _frequency * 2^_depth
|
|
||||||
if (_frequency > 1760) _depth = 8;
|
|
||||||
else if (_frequency > 880) _depth = 9;
|
|
||||||
else _depth = 10; // WLED_PWM_FREQ <= 880Hz
|
|
||||||
analogWriteRange((1<<_depth)-1);
|
analogWriteRange((1<<_depth)-1);
|
||||||
analogWriteFreq(_frequency);
|
analogWriteFreq(_frequency);
|
||||||
#else
|
#else
|
||||||
@ -397,11 +420,6 @@ BusPwm::BusPwm(BusConfig &bc)
|
|||||||
if (_ledcStart == 255) { //no more free LEDC channels
|
if (_ledcStart == 255) { //no more free LEDC channels
|
||||||
deallocatePins(); return;
|
deallocatePins(); return;
|
||||||
}
|
}
|
||||||
// duty cycle resolution (_depth) can be extracted from this formula: 80MHz > _frequency * 2^_depth
|
|
||||||
if (_frequency > 78124) _depth = 9;
|
|
||||||
else if (_frequency > 39062) _depth = 10;
|
|
||||||
else if (_frequency > 19531) _depth = 11;
|
|
||||||
else _depth = 12; // WLED_PWM_FREQ <= 19531Hz
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (unsigned i = 0; i < numPins; i++) {
|
for (unsigned i = 0; i < numPins; i++) {
|
||||||
@ -419,7 +437,7 @@ BusPwm::BusPwm(BusConfig &bc)
|
|||||||
}
|
}
|
||||||
_data = _pwmdata; // avoid malloc() and use stack
|
_data = _pwmdata; // avoid malloc() and use stack
|
||||||
_valid = true;
|
_valid = true;
|
||||||
DEBUG_PRINTF_P(PSTR("%successfully inited PWM strip with type %u and pins %u,%u,%u,%u,%u\n"), _valid?"S":"Uns", bc.type, _pins[0], _pins[1], _pins[2], _pins[3], _pins[4]);
|
DEBUG_PRINTF_P(PSTR("%successfully inited PWM strip with type %u, frequency %u, bit depth %u and pins %u,%u,%u,%u,%u\n"), _valid?"S":"Uns", bc.type, _frequency, _depth, _pins[0], _pins[1], _pins[2], _pins[3], _pins[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BusPwm::setPixelColor(uint16_t pix, uint32_t c) {
|
void BusPwm::setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
* color blend function
|
* color blend function
|
||||||
*/
|
*/
|
||||||
uint32_t color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) {
|
uint32_t color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) {
|
||||||
if(blend == 0) return color1;
|
if (blend == 0) return color1;
|
||||||
unsigned blendmax = b16 ? 0xFFFF : 0xFF;
|
unsigned blendmax = b16 ? 0xFFFF : 0xFF;
|
||||||
if(blend == blendmax) return color2;
|
if (blend == blendmax) return color2;
|
||||||
uint8_t shift = b16 ? 16 : 8;
|
unsigned shift = b16 ? 16 : 8;
|
||||||
|
|
||||||
uint32_t w1 = W(color1);
|
uint32_t w1 = W(color1);
|
||||||
uint32_t r1 = R(color1);
|
uint32_t r1 = R(color1);
|
||||||
@ -73,22 +73,19 @@ uint32_t color_fade(uint32_t c1, uint8_t amount, bool video)
|
|||||||
uint32_t g = G(c1);
|
uint32_t g = G(c1);
|
||||||
uint32_t b = B(c1);
|
uint32_t b = B(c1);
|
||||||
uint32_t w = W(c1);
|
uint32_t w = W(c1);
|
||||||
if (video) {
|
uint32_t scale = amount + !video; // 32bit for faster calculation
|
||||||
uint32_t scale = amount; // 32bit for faster calculation
|
if (video) {
|
||||||
scaledcolor = (((r * scale) >> 8) << 16) + ((r && scale) ? 1 : 0);
|
scaledcolor = (((r * scale) >> 8) << 16) + ((r && scale) ? 1 : 0);
|
||||||
scaledcolor |= (((g * scale) >> 8) << 8) + ((g && scale) ? 1 : 0);
|
scaledcolor |= (((g * scale) >> 8) << 8) + ((g && scale) ? 1 : 0);
|
||||||
scaledcolor |= ((b * scale) >> 8) + ((b && scale) ? 1 : 0);
|
scaledcolor |= ((b * scale) >> 8) + ((b && scale) ? 1 : 0);
|
||||||
scaledcolor |= (((w * scale) >> 8) << 24) + ((w && scale) ? 1 : 0);
|
scaledcolor |= (((w * scale) >> 8) << 24) + ((w && scale) ? 1 : 0);
|
||||||
return scaledcolor;
|
} else {
|
||||||
}
|
scaledcolor = ((r * scale) >> 8) << 16;
|
||||||
else {
|
|
||||||
uint32_t scale = 1 + amount;
|
|
||||||
scaledcolor = ((r * scale) >> 8) << 16;
|
|
||||||
scaledcolor |= ((g * scale) >> 8) << 8;
|
scaledcolor |= ((g * scale) >> 8) << 8;
|
||||||
scaledcolor |= (b * scale) >> 8;
|
scaledcolor |= (b * scale) >> 8;
|
||||||
scaledcolor |= ((w * scale) >> 8) << 24;
|
scaledcolor |= ((w * scale) >> 8) << 24;
|
||||||
return scaledcolor;
|
|
||||||
}
|
}
|
||||||
|
return scaledcolor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRandomColor(byte* rgb)
|
void setRandomColor(byte* rgb)
|
||||||
@ -140,25 +137,25 @@ CRGBPalette16 generateHarmonicRandomPalette(CRGBPalette16 &basepalette)
|
|||||||
case 1: // triadic
|
case 1: // triadic
|
||||||
harmonics[0] = basehue + 113 + random8(15);
|
harmonics[0] = basehue + 113 + random8(15);
|
||||||
harmonics[1] = basehue + 233 + random8(15);
|
harmonics[1] = basehue + 233 + random8(15);
|
||||||
harmonics[2] = basehue -7 + random8(15);
|
harmonics[2] = basehue - 7 + random8(15);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // split-complementary
|
case 2: // split-complementary
|
||||||
harmonics[0] = basehue + 145 + random8(10);
|
harmonics[0] = basehue + 145 + random8(10);
|
||||||
harmonics[1] = basehue + 205 + random8(10);
|
harmonics[1] = basehue + 205 + random8(10);
|
||||||
harmonics[2] = basehue - 5 + random8(10);
|
harmonics[2] = basehue - 5 + random8(10);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // square
|
case 3: // square
|
||||||
harmonics[0] = basehue + 85 + random8(10);
|
harmonics[0] = basehue + 85 + random8(10);
|
||||||
harmonics[1] = basehue + 175 + random8(10);
|
harmonics[1] = basehue + 175 + random8(10);
|
||||||
harmonics[2] = basehue + 265 + random8(10);
|
harmonics[2] = basehue + 265 + random8(10);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // tetradic
|
case 4: // tetradic
|
||||||
harmonics[0] = basehue + 80 + random8(20);
|
harmonics[0] = basehue + 80 + random8(20);
|
||||||
harmonics[1] = basehue + 170 + random8(20);
|
harmonics[1] = basehue + 170 + random8(20);
|
||||||
harmonics[2] = basehue + random8(30)-15;
|
harmonics[2] = basehue - 15 + random8(30);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,13 +381,13 @@ bool colorFromHexString(byte* rgb, const char* in) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float minf (float v, float w)
|
static inline float minf(float v, float w)
|
||||||
{
|
{
|
||||||
if (w > v) return v;
|
if (w > v) return v;
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
float maxf (float v, float w)
|
static inline float maxf(float v, float w)
|
||||||
{
|
{
|
||||||
if (w > v) return w;
|
if (w > v) return w;
|
||||||
return v;
|
return v;
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
if (d.um_p[0]==-1) d.um_p.shift(); // remove filler
|
if (d.um_p[0]==-1) d.um_p.shift(); // remove filler
|
||||||
d.Sf.SDA.max = d.Sf.SCL.max = d.Sf.MOSI.max = d.Sf.SCLK.max = d.Sf.MISO.max = d.max_gpio;
|
d.Sf.SDA.max = d.Sf.SCL.max = d.Sf.MOSI.max = d.Sf.SCLK.max = d.Sf.MISO.max = d.max_gpio;
|
||||||
//for (let i of d.getElementsByTagName("input")) if (i.type === "number" && i.name.replace("[]","").substr(-3) === "pin") i.max = d.max_gpio;
|
//for (let i of d.getElementsByTagName("input")) if (i.type === "number" && i.name.replace("[]","").substr(-3) === "pin") i.max = d.max_gpio;
|
||||||
pinDropdowns(); // convert INPUT to SELECT for pins
|
pinDD(); // convert INPUT to SELECT for pins
|
||||||
});
|
});
|
||||||
// error event
|
// error event
|
||||||
scE.addEventListener("error", (ev) => {
|
scE.addEventListener("error", (ev) => {
|
||||||
@ -165,25 +165,25 @@
|
|||||||
urows += `<input type="${t==="int"?"number":t}" name="${k}:${f}${a?"[]":""}" ${c} oninput="check(this,'${k.substr(k.indexOf(":")+1)}')"><br>`;
|
urows += `<input type="${t==="int"?"number":t}" name="${k}:${f}${a?"[]":""}" ${c} oninput="check(this,'${k.substr(k.indexOf(":")+1)}')"><br>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function pinDropdowns() {
|
function pinDD() {
|
||||||
for (let i of d.Sf.elements) {
|
for (let i of d.Sf.elements) {
|
||||||
if (i.type === "number" && (i.name.includes("pin") || ["SDA","SCL","MOSI","MISO","SCLK"].includes(i.name))) { //select all pin select elements
|
if (i.type === "number" && (i.name.includes("pin") || ["SDA","SCL","MOSI","MISO","SCLK"].includes(i.name))) { //select all pin select elements
|
||||||
let v = parseInt(i.value);
|
let v = parseInt(i.value);
|
||||||
let sel = addDropdown(i.name,0);
|
let sel = addDD(i.name,0);
|
||||||
for (var j = -1; j <= d.max_gpio; j++) {
|
for (var j = -1; j <= d.max_gpio; j++) {
|
||||||
if (d.rsvd.includes(j)) continue;
|
if (d.rsvd.includes(j)) continue;
|
||||||
let foundPin = pins.indexOf(j);
|
let foundPin = pins.indexOf(j);
|
||||||
let txt = (j === -1) ? "unused" : `${j}`;
|
let txt = (j === -1) ? "unused" : `${j}`;
|
||||||
if (foundPin >= 0 && j !== v) txt += ` ${pinO[foundPin]=="if"?"global":pinO[foundPin]}`; // already reserved pin
|
if (foundPin >= 0 && j !== v) txt += ` ${pinO[foundPin]=="if"?"global":pinO[foundPin]}`; // already reserved pin
|
||||||
if (d.ro_gpio.includes(j)) txt += " (R/O)";
|
if (d.ro_gpio.includes(j)) txt += " (R/O)";
|
||||||
let opt = addOption(sel, txt, j);
|
let opt = addO(sel, txt, j);
|
||||||
if (j === v) opt.selected = true; // this is "our" pin
|
if (j === v) opt.selected = true; // this is "our" pin
|
||||||
else if (pins.includes(j)) opt.disabled = true; // someone else's pin
|
else if (pins.includes(j)) opt.disabled = true; // someone else's pin
|
||||||
}
|
}
|
||||||
let um = i.name.split(":")[0];
|
let um = i.name.split(":")[0];
|
||||||
d.extra.forEach((o)=>{
|
d.extra.forEach((o)=>{
|
||||||
if (o[um] && o[um].pin) o[um].pin.forEach((e)=>{
|
if (o[um] && o[um].pin) o[um].pin.forEach((e)=>{
|
||||||
let opt = addOption(sel,e[0],e[1]);
|
let opt = addO(sel,e[0],e[1]);
|
||||||
if (e[1]==v) opt.selected = true;
|
if (e[1]==v) opt.selected = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -219,7 +219,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// https://stackoverflow.com/questions/39729741/javascript-change-input-text-to-select-option
|
// https://stackoverflow.com/questions/39729741/javascript-change-input-text-to-select-option
|
||||||
function addDropdown(um,fld) {
|
function addDD(um,fld) {
|
||||||
let sel = d.createElement('select');
|
let sel = d.createElement('select');
|
||||||
if (typeof(fld) === "string") { // parameter from usermod (field name)
|
if (typeof(fld) === "string") { // parameter from usermod (field name)
|
||||||
if (fld.includes("pin")) sel.classList.add("pin");
|
if (fld.includes("pin")) sel.classList.add("pin");
|
||||||
@ -255,7 +255,8 @@
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
function addOption(sel,txt,val) {
|
var addDropdown = addDD; // backwards compatibility
|
||||||
|
function addO(sel,txt,val) {
|
||||||
if (sel===null) return; // select object missing
|
if (sel===null) return; // select object missing
|
||||||
let opt = d.createElement("option");
|
let opt = d.createElement("option");
|
||||||
opt.value = val;
|
opt.value = val;
|
||||||
@ -267,8 +268,9 @@
|
|||||||
}
|
}
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
|
var addOption = addO; // backwards compatibility
|
||||||
// https://stackoverflow.com/questions/26440494/insert-text-after-this-input-element-with-javascript
|
// https://stackoverflow.com/questions/26440494/insert-text-after-this-input-element-with-javascript
|
||||||
function addInfo(name,el,txt, txt2="") {
|
function addI(name,el,txt, txt2="") {
|
||||||
let obj = d.getElementsByName(name);
|
let obj = d.getElementsByName(name);
|
||||||
if (!obj.length) return;
|
if (!obj.length) return;
|
||||||
if (typeof el === "string" && obj[0]) obj[0].placeholder = el;
|
if (typeof el === "string" && obj[0]) obj[0].placeholder = el;
|
||||||
@ -277,9 +279,10 @@
|
|||||||
if (txt2!="") obj[el].insertAdjacentHTML('beforebegin', txt2 + ' '); //add pre texts
|
if (txt2!="") obj[el].insertAdjacentHTML('beforebegin', txt2 + ' '); //add pre texts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var addInfo = addI; // backwards compatibility
|
||||||
// add Help Button
|
// add Help Button
|
||||||
function addHB(um) {
|
function addHB(um) {
|
||||||
addInfo(um + ':help',0,`<button onclick="location.href='https://kno.wled.ge/usermods/${um}'" type="button">?</button>`);
|
addI(um + ':help',0,`<button onclick="location.href='https://kno.wled.ge/usermods/${um}'" type="button">?</button>`);
|
||||||
}
|
}
|
||||||
// load settings and insert values into DOM
|
// load settings and insert values into DOM
|
||||||
function ldS() {
|
function ldS() {
|
||||||
|
@ -857,20 +857,19 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
|||||||
uint16_t spcI = selseg.spacing;
|
uint16_t spcI = selseg.spacing;
|
||||||
pos = req.indexOf(F("&S=")); //segment start
|
pos = req.indexOf(F("&S=")); //segment start
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
startI = getNumVal(&req, pos);
|
startI = std::abs(getNumVal(&req, pos));
|
||||||
}
|
}
|
||||||
pos = req.indexOf(F("S2=")); //segment stop
|
pos = req.indexOf(F("S2=")); //segment stop
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
stopI = getNumVal(&req, pos);
|
stopI = std::abs(getNumVal(&req, pos));
|
||||||
}
|
}
|
||||||
pos = req.indexOf(F("GP=")); //segment grouping
|
pos = req.indexOf(F("GP=")); //segment grouping
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
grpI = getNumVal(&req, pos);
|
grpI = std::max(1,getNumVal(&req, pos));
|
||||||
if (grpI == 0) grpI = 1;
|
|
||||||
}
|
}
|
||||||
pos = req.indexOf(F("SP=")); //segment spacing
|
pos = req.indexOf(F("SP=")); //segment spacing
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
spcI = getNumVal(&req, pos);
|
spcI = std::max(0,getNumVal(&req, pos));
|
||||||
}
|
}
|
||||||
strip.setSegment(selectedSeg, startI, stopI, grpI, spcI, UINT16_MAX, startY, stopY);
|
strip.setSegment(selectedSeg, startI, stopI, grpI, spcI, UINT16_MAX, startY, stopY);
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ void sappends(char stype, const char* key, char* val)
|
|||||||
|
|
||||||
bool oappendi(int i)
|
bool oappendi(int i)
|
||||||
{
|
{
|
||||||
char s[11];
|
char s[12]; // 32bit signed number can have 10 digits plus - sign
|
||||||
sprintf(s, "%d", i);
|
sprintf(s, "%d", i);
|
||||||
return oappend(s);
|
return oappend(s);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user