Segment API
- moved all drawing logic to segment - moved transitions to segment Conditional 2D compile. Rearranged effect IDs. Implemented dynamic effect arrays.
This commit is contained in:
parent
f0992d56c1
commit
d9f2c2b968
@ -251,6 +251,7 @@ private:
|
||||
* Sort either the modes or the palettes using quicksort.
|
||||
*/
|
||||
void re_sortModes(const char **modeNames, byte *indexes, int count, int numSkip) {
|
||||
if (!modeNames) return;
|
||||
listBeingSorted = modeNames;
|
||||
qsort(indexes + numSkip, count - numSkip, sizeof(byte), re_qstringCmp);
|
||||
listBeingSorted = nullptr;
|
||||
@ -777,7 +778,7 @@ public:
|
||||
for (byte i=0; i<strip.getMaxSegments(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) continue;
|
||||
seg.setCCT(currentCCT, i);
|
||||
seg.setCCT(currentCCT);
|
||||
}
|
||||
// } else {
|
||||
// Segment& seg = strip.getSegment(strip.getMainSegmentId());
|
||||
|
1086
wled00/FX.cpp
1086
wled00/FX.cpp
File diff suppressed because it is too large
Load Diff
431
wled00/FX.h
431
wled00/FX.h
@ -87,10 +87,10 @@ uint32_t color_add(uint32_t,uint32_t);
|
||||
#define MIN_SHOW_DELAY (_frametime < 16 ? 8 : 15)
|
||||
|
||||
#define NUM_COLORS 3 /* number of colors per segment */
|
||||
#define SEGMENT strip.getSegment(strip.getCurrSegmentId())
|
||||
#define SEGENV strip.getSegmentRuntime(strip.getCurrSegmentId())
|
||||
#define SEGMENT strip._segments[strip.getCurrSegmentId()]
|
||||
#define SEGENV strip._segment_runtimes[strip.getCurrSegmentId()]
|
||||
#define SEGCOLOR(x) strip.segColor(x)
|
||||
#define SEGLEN strip.segLen()
|
||||
#define SEGLEN strip._virtualSegmentLength
|
||||
#define SPEED_FORMULA_L (5U + (50U*(255U - SEGMENT.speed))/SEGLEN)
|
||||
|
||||
// some common colors
|
||||
@ -246,125 +246,143 @@ uint32_t color_add(uint32_t,uint32_t);
|
||||
#define FX_MODE_TV_SIMULATOR 116
|
||||
#define FX_MODE_DYNAMIC_SMOOTH 117
|
||||
// new 2D effects
|
||||
#define FX_MODE_SPACESHIPS 118
|
||||
#define FX_MODE_CRAZYBEES 119
|
||||
#define FX_MODE_GHOST_RIDER 120
|
||||
#define FX_MODE_BLOBS 121
|
||||
#define FX_MODE_SCROLL_TEXT 122
|
||||
#define FX_MODE_DRIFT_ROSE 123
|
||||
#define FX_MODE_2DSPACESHIPS 118
|
||||
#define FX_MODE_2DCRAZYBEES 119
|
||||
#define FX_MODE_2DGHOSTRIDER 120
|
||||
#define FX_MODE_2DBLOBS 121
|
||||
#define FX_MODE_2DSCROLLTEXT 122
|
||||
#define FX_MODE_2DDRIFTROSE 123
|
||||
// WLED-SR effects (non SR compatible IDs)
|
||||
#define FX_MODE_2DBLACKHOLE 124 // non audio
|
||||
#define FX_MODE_2DDNASPIRAL 125 // non audio
|
||||
#define FX_MODE_2DHIPHOTIC 126 // non audio
|
||||
#define FX_MODE_2DPLASMABALL 127 // non audio
|
||||
#define FX_MODE_2DSINDOTS 128 // non audio
|
||||
#define FX_MODE_2DFRIZZLES 129 // non audio
|
||||
#define FX_MODE_2DLISSAJOUS 130 // non audio
|
||||
#define FX_MODE_2DPOLARLIGHTS 131 // non audio
|
||||
#define FX_MODE_2DTARTAN 132 // non audio
|
||||
#define FX_MODE_2DGAMEOFLIFE 133 // non audio
|
||||
#define FX_MODE_2DJULIA 134 // non audio
|
||||
#define FX_MODE_2DCOLOREDBURSTS 135 // non audio
|
||||
#define FX_MODE_2DSUNRADIATION 136 // non audio
|
||||
#define FX_MODE_2DNOISE 137 // non audio
|
||||
#define FX_MODE_2DFIRENOISE 138 // non audio
|
||||
#define FX_MODE_2DSQUAREDSWIRL 139 // non audio
|
||||
#define FX_MODE_2DDNA 140 // non audio
|
||||
#define FX_MODE_2DMATRIX 141 // non audio
|
||||
#define FX_MODE_2DMETABALLS 142 // non audio
|
||||
#define FX_MODE_2DPULSER 143 // non audio
|
||||
#define FX_MODE_2DDRIFT 144 // non audio
|
||||
#define FX_MODE_2DWAVERLY 145 // audio enhanced
|
||||
#define FX_MODE_2DSWIRL 146 // audio enhanced
|
||||
#define FX_MODE_2DAKEMI 147 // audio enhanced
|
||||
#define FX_MODE_PIXELWAVE 160 // audio enhanced
|
||||
#define FX_MODE_JUGGLES 161 // audio enhanced
|
||||
#define FX_MODE_MATRIPIX 162 // audio enhanced
|
||||
#define FX_MODE_GRAVIMETER 163 // audio enhanced
|
||||
#define FX_MODE_PLASMOID 164 // audio enhanced
|
||||
#define FX_MODE_PUDDLES 165 // audio enhanced
|
||||
#define FX_MODE_MIDNOISE 166 // audio enhanced
|
||||
#define FX_MODE_NOISEMETER 167 // audio enhanced
|
||||
#define FX_MODE_NOISEFIRE 168 // audio enhanced
|
||||
#define FX_MODE_PUDDLEPEAK 169 // audio enhanced
|
||||
#define FX_MODE_RIPPLEPEAK 170 // audio enhanced
|
||||
#define FX_MODE_GRAVCENTER 171 // audio enhanced
|
||||
#define FX_MODE_GRAVCENTRIC 172 // audio enhanced
|
||||
|
||||
// WLED-SR effects
|
||||
#ifndef USERMOD_AUDIOREACTIVE
|
||||
|
||||
#define FX_MODE_2DBLACKHOLE 124 // non audio
|
||||
#define FX_MODE_2DDNASPIRAL 125 // non audio
|
||||
#define FX_MODE_2DHIPHOTIC 126 // non audio
|
||||
#define FX_MODE_2DPLASMABALL 127 // non audio
|
||||
#define FX_MODE_2DSINDOTS 128 // non audio
|
||||
#define FX_MODE_PIXELWAVE 129 // audio enhanced
|
||||
#define FX_MODE_JUGGLES 130 // audio enhanced
|
||||
#define FX_MODE_MATRIPIX 131 // audio enhanced
|
||||
#define FX_MODE_GRAVIMETER 132 // audio enhanced
|
||||
#define FX_MODE_PLASMOID 133 // audio enhanced
|
||||
#define FX_MODE_PUDDLES 134 // audio enhanced
|
||||
#define FX_MODE_MIDNOISE 135 // audio enhanced
|
||||
#define FX_MODE_NOISEMETER 136 // audio enhanced
|
||||
#define FX_MODE_2DFRIZZLES 137 // non audio
|
||||
#define FX_MODE_2DLISSAJOUS 138 // non audio
|
||||
#define FX_MODE_2DPOLARLIGHTS 139 // non audio
|
||||
#define FX_MODE_2DTARTAN 140 // non audio
|
||||
#define FX_MODE_2DGAMEOFLIFE 141 // non audio
|
||||
#define FX_MODE_2DJULIA 142 // non audio
|
||||
#define FX_MODE_NOISEFIRE 143 // audio enhanced
|
||||
#define FX_MODE_PUDDLEPEAK 144 // audio enhanced
|
||||
#define FX_MODE_2DCOLOREDBURSTS 145 // non audio
|
||||
#define FX_MODE_2DSUNRADIATION 146 // non audio
|
||||
#define FX_MODE_2DNOISE 147 // non audio
|
||||
#define FX_MODE_RIPPLEPEAK 148 // audio enhanced
|
||||
#define FX_MODE_2DFIRENOISE 149 // non audio
|
||||
#define FX_MODE_2DSQUAREDSWIRL 150 // non audio
|
||||
#define FX_MODE_2DDNA 151 // non audio
|
||||
#define FX_MODE_2DMATRIX 152 // non audio
|
||||
#define FX_MODE_2DMETABALLS 153 // non audio
|
||||
#define FX_MODE_2DPULSER 154 // non audio
|
||||
#define FX_MODE_2DDRIFT 155 // non audio
|
||||
#define FX_MODE_2DWAVERLY 156 // audio enhanced
|
||||
#define FX_MODE_GRAVCENTER 157 // audio enhanced
|
||||
#define FX_MODE_GRAVCENTRIC 158 // audio enhanced
|
||||
#define FX_MODE_2DSWIRL 159 // audio enhanced
|
||||
#define FX_MODE_2DAKEMI 160 // audio enhanced
|
||||
|
||||
#define MODE_COUNT 161
|
||||
#define MODE_COUNT 173
|
||||
|
||||
#else
|
||||
|
||||
#define FX_MODE_PIXELS 128
|
||||
#define FX_MODE_PIXELWAVE 129 // audio enhanced
|
||||
#define FX_MODE_JUGGLES 130 // audio enhanced
|
||||
#define FX_MODE_MATRIPIX 131 // audio enhanced
|
||||
#define FX_MODE_GRAVIMETER 132 // audio enhanced
|
||||
#define FX_MODE_PLASMOID 133 // audio enhanced
|
||||
#define FX_MODE_PUDDLES 134 // audio enhanced
|
||||
#define FX_MODE_MIDNOISE 135 // audio enhanced
|
||||
#define FX_MODE_NOISEMETER 136 // audio enhanced
|
||||
#define FX_MODE_FREQWAVE 137
|
||||
#define FX_MODE_FREQMATRIX 138
|
||||
#define FX_MODE_2DGEQ 139
|
||||
#define FX_MODE_WATERFALL 140
|
||||
#define FX_MODE_FREQPIXELS 141
|
||||
#define FX_MODE_BINMAP 142
|
||||
#define FX_MODE_NOISEFIRE 143 // audio enhanced
|
||||
#define FX_MODE_PUDDLEPEAK 144 // audio enhanced
|
||||
#define FX_MODE_NOISEMOVE 145
|
||||
#define FX_MODE_2DNOISE 146 // non audio
|
||||
#define FX_MODE_PIXELS 173
|
||||
// #define FX_MODE_PIXELWAVE 129 // audio enhanced
|
||||
// #define FX_MODE_JUGGLES 130 // audio enhanced
|
||||
// #define FX_MODE_MATRIPIX 131 // audio enhanced
|
||||
// #define FX_MODE_GRAVIMETER 132 // audio enhanced
|
||||
// #define FX_MODE_PLASMOID 133 // audio enhanced
|
||||
// #define FX_MODE_PUDDLES 134 // audio enhanced
|
||||
// #define FX_MODE_MIDNOISE 135 // audio enhanced
|
||||
// #define FX_MODE_NOISEMETER 136 // audio enhanced
|
||||
#define FX_MODE_FREQWAVE 174
|
||||
#define FX_MODE_FREQMATRIX 175
|
||||
#define FX_MODE_2DGEQ 148
|
||||
#define FX_MODE_WATERFALL 176
|
||||
#define FX_MODE_FREQPIXELS 177
|
||||
#define FX_MODE_BINMAP 178
|
||||
// #define FX_MODE_NOISEFIRE 143 // audio enhanced
|
||||
// #define FX_MODE_PUDDLEPEAK 144 // audio enhanced
|
||||
#define FX_MODE_NOISEMOVE 179
|
||||
// #define FX_MODE_2DNOISE 146 // non audio
|
||||
//#define FX_MODE_PERLINMOVE 147 // moved to 53
|
||||
#define FX_MODE_RIPPLEPEAK 148 // audio enhanced
|
||||
#define FX_MODE_2DFIRENOISE 149 // non audio
|
||||
#define FX_MODE_2DSQUAREDSWIRL 150 // non audio
|
||||
// #define FX_MODE_RIPPLEPEAK 148 // audio enhanced
|
||||
// #define FX_MODE_2DFIRENOISE 149 // non audio
|
||||
// #define FX_MODE_2DSQUAREDSWIRL 150 // non audio
|
||||
//#define FX_MODE_2DFIRE2012 151 // implemented in native Fire2012
|
||||
#define FX_MODE_2DDNA 152 // non audio
|
||||
#define FX_MODE_2DMATRIX 153 // non audio
|
||||
#define FX_MODE_2DMETABALLS 154 // non audio
|
||||
#define FX_MODE_FREQMAP 155
|
||||
#define FX_MODE_GRAVCENTER 156 // audio enhanced
|
||||
#define FX_MODE_GRAVCENTRIC 157 // audio enhanced
|
||||
#define FX_MODE_GRAVFREQ 158
|
||||
#define FX_MODE_DJLIGHT 159
|
||||
#define FX_MODE_2DFUNKYPLANK 160
|
||||
// #define FX_MODE_2DDNA 152 // non audio
|
||||
// #define FX_MODE_2DMATRIX 153 // non audio
|
||||
// #define FX_MODE_2DMETABALLS 154 // non audio
|
||||
#define FX_MODE_FREQMAP 180
|
||||
// #define FX_MODE_GRAVCENTER 156 // audio enhanced
|
||||
// #define FX_MODE_GRAVCENTRIC 157 // audio enhanced
|
||||
#define FX_MODE_GRAVFREQ 181
|
||||
#define FX_MODE_DJLIGHT 182
|
||||
#define FX_MODE_2DFUNKYPLANK 149
|
||||
//#define FX_MODE_2DCENTERBARS 161 // obsolete by X & Y mirroring
|
||||
#define FX_MODE_2DPULSER 162 // non audio
|
||||
#define FX_MODE_BLURZ 163
|
||||
#define FX_MODE_2DDRIFT 164 // non audio
|
||||
#define FX_MODE_2DWAVERLY 165 // audio enhanced
|
||||
#define FX_MODE_2DSUNRADIATION 166 // non audio
|
||||
#define FX_MODE_2DCOLOREDBURSTS 167 // non audio
|
||||
#define FX_MODE_2DJULIA 168 // non audio
|
||||
#define FX_MODE_2DPOOLNOISE 169 // reserved in JSON_mode_names
|
||||
#define FX_MODE_2DTWISTER 170 // reserved in JSON_mode_names
|
||||
#define FX_MODE_2DCAELEMENTATY 171 // reserved in JSON_mode_names
|
||||
#define FX_MODE_2DGAMEOFLIFE 172 // non audio
|
||||
#define FX_MODE_2DTARTAN 173 // non audio
|
||||
#define FX_MODE_2DPOLARLIGHTS 174 // non audio
|
||||
#define FX_MODE_2DSWIRL 175 // audio enhanced
|
||||
#define FX_MODE_2DLISSAJOUS 176 // non audio
|
||||
#define FX_MODE_2DFRIZZLES 177 // non audio
|
||||
#define FX_MODE_2DPLASMABALL 178 // non audio
|
||||
// #define FX_MODE_2DPULSER 162 // non audio
|
||||
#define FX_MODE_BLURZ 183
|
||||
// #define FX_MODE_2DDRIFT 164 // non audio
|
||||
// #define FX_MODE_2DWAVERLY 165 // audio enhanced
|
||||
// #define FX_MODE_2DSUNRADIATION 166 // non audio
|
||||
// #define FX_MODE_2DCOLOREDBURSTS 167 // non audio
|
||||
// #define FX_MODE_2DJULIA 168 // non audio
|
||||
#define FX_MODE_2DPOOLNOISE 150 // reserved in JSON_mode_names
|
||||
#define FX_MODE_2DTWISTER 151 // reserved in JSON_mode_names
|
||||
#define FX_MODE_2DCAELEMENTATY 152 // reserved in JSON_mode_names
|
||||
// #define FX_MODE_2DGAMEOFLIFE 172 // non audio
|
||||
// #define FX_MODE_2DTARTAN 173 // non audio
|
||||
// #define FX_MODE_2DPOLARLIGHTS 174 // non audio
|
||||
// #define FX_MODE_2DSWIRL 175 // audio enhanced
|
||||
// #define FX_MODE_2DLISSAJOUS 176 // non audio
|
||||
// #define FX_MODE_2DFRIZZLES 177 // non audio
|
||||
// #define FX_MODE_2DPLASMABALL 178 // non audio
|
||||
//#define FX_MODE_FLOWSTRIPE 179 // moved to 114
|
||||
#define FX_MODE_2DHIPHOTIC 180 // non audio
|
||||
#define FX_MODE_2DSINDOTS 181 // non audio
|
||||
#define FX_MODE_2DDNASPIRAL 182 // non audio
|
||||
#define FX_MODE_2DBLACKHOLE 183 // non audio
|
||||
// #define FX_MODE_2DHIPHOTIC 180 // non audio
|
||||
// #define FX_MODE_2DSINDOTS 181 // non audio
|
||||
// #define FX_MODE_2DDNASPIRAL 182 // non audio
|
||||
// #define FX_MODE_2DBLACKHOLE 183 // non audio
|
||||
//#define FX_MODE_WAVESINS 184 // moved to 48
|
||||
#define FX_MODE_ROCKTAVES 185
|
||||
#define FX_MODE_2DAKEMI 186 // audio enhanced
|
||||
#define FX_MODE_ROCKTAVES 184
|
||||
// #define FX_MODE_2DAKEMI 186 // audio enhanced
|
||||
//#define FX_MODE_CUSTOMEFFECT 187 //WLEDSR Custom Effects
|
||||
|
||||
#define MODE_COUNT 187
|
||||
#define MODE_COUNT 185
|
||||
#endif
|
||||
|
||||
struct Segment;
|
||||
|
||||
// color transitions
|
||||
typedef struct ColorTransition { // 20 bytes
|
||||
uint32_t colorOld[NUM_COLORS];
|
||||
uint8_t briOld;
|
||||
uint8_t cctOld;
|
||||
uint32_t transitionStart;
|
||||
uint16_t transitionDur;
|
||||
|
||||
void startTransition(Segment *seg, uint16_t dur, uint8_t oldBri, uint8_t oldCct, uint32_t *oldCol);
|
||||
void handleTransition(Segment *seg, uint8_t &newBri, uint8_t &newCct, uint32_t *newCol);
|
||||
uint16_t progress(); //transition progression between 0-65535
|
||||
uint8_t currentBri(uint8_t briNew, bool useCct = false);
|
||||
uint32_t currentColor(uint8_t slot, uint32_t colorNew) {
|
||||
return color_blend(colorOld[slot], colorNew, progress(), true);
|
||||
}
|
||||
} color_transition;
|
||||
|
||||
|
||||
// segment parameters
|
||||
typedef struct Segment { // 35 (36 in memory) bytes
|
||||
typedef struct Segment { // 40 (44 in memory) bytes
|
||||
uint16_t start; // start index / start X coordinate 2D (left)
|
||||
uint16_t stop; // stop index / stop X coordinate 2D (right); segment is invalid if stop == 0
|
||||
uint16_t offset;
|
||||
@ -382,6 +400,8 @@ typedef struct Segment { // 35 (36 in memory) bytes
|
||||
uint16_t startY; // start Y coodrinate 2D (top)
|
||||
uint16_t stopY; // stop Y coordinate 2D (bottom)
|
||||
char *name;
|
||||
color_transition transition;
|
||||
|
||||
inline bool getOption(uint8_t n) { return ((options >> n) & 0x01); }
|
||||
inline bool isSelected() { return getOption(0); }
|
||||
inline bool isActive() { return stop > start; }
|
||||
@ -390,22 +410,71 @@ typedef struct Segment { // 35 (36 in memory) bytes
|
||||
inline uint16_t length() { return width(); }
|
||||
inline uint16_t groupLength() { return grouping + spacing; }
|
||||
inline uint8_t getLightCapabilities() { return _capabilities; }
|
||||
bool setColor(uint8_t slot, uint32_t c, uint8_t segn); //returns true if changed
|
||||
void setCCT(uint16_t k, uint8_t segn);
|
||||
void setOpacity(uint8_t o, uint8_t segn);
|
||||
void setOption(uint8_t n, bool val, uint8_t segn = 255);
|
||||
|
||||
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
|
||||
void setCCT(uint16_t k);
|
||||
void setOpacity(uint8_t o);
|
||||
void setOption(uint8_t n, bool val);
|
||||
uint8_t differs(Segment& b);
|
||||
void refreshLightCapabilities();
|
||||
|
||||
// 1D strip
|
||||
uint16_t virtualLength();
|
||||
void setPixelColor(int n, uint32_t c); // set relative pixel within segment with color
|
||||
void setPixelColor(int n, byte r, byte g, byte b, byte w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } // automatically inline
|
||||
void setPixelColor(int n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); } // automatically inline
|
||||
void setPixelColor(float i, uint32_t c, bool aa = true);
|
||||
void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); }
|
||||
void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, c.red, c.green, c.blue, 0, aa); }
|
||||
uint32_t getPixelColor(uint16_t i);
|
||||
// 1D support functions (some implement 2D as well)
|
||||
void blur(uint8_t);
|
||||
void fill(uint32_t c);
|
||||
void fade_out(uint8_t r);
|
||||
void fadeToBlackBy(uint8_t fadeBy);
|
||||
void blendPixelColor(uint16_t n, uint32_t color, uint8_t blend);
|
||||
void addPixelColor(uint16_t n, uint32_t color);
|
||||
uint8_t get_random_wheel_index(uint8_t pos);
|
||||
uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255);
|
||||
uint32_t color_wheel(uint8_t pos);
|
||||
|
||||
// 2D matrix
|
||||
uint16_t virtualWidth();
|
||||
uint16_t virtualHeight();
|
||||
// 1D strip
|
||||
uint16_t virtualLength();
|
||||
uint8_t differs(Segment& b);
|
||||
void refreshLightCapabilities();
|
||||
uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment (for leds[])
|
||||
void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
|
||||
void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline
|
||||
void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, c.red, c.green, c.blue); } // automatically inline
|
||||
void setPixelColorXY(float x, float y, uint32_t c, bool aa = true);
|
||||
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); }
|
||||
void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, c.red, c.green, c.blue, 0, aa); }
|
||||
uint32_t getPixelColorXY(uint16_t x, uint16_t y);
|
||||
// 2D support functions
|
||||
void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend);
|
||||
void addPixelColorXY(uint16_t x, uint16_t y, uint32_t color);
|
||||
void blur1d(CRGB* leds, fract8 blur_amount);
|
||||
void blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds=nullptr); // 1D box blur (with weight)
|
||||
void blur2d(CRGB* leds, fract8 blur_amount);
|
||||
void blurRow(uint16_t row, fract8 blur_amount, CRGB* leds=nullptr);
|
||||
void blurCol(uint16_t col, fract8 blur_amount, CRGB* leds=nullptr);
|
||||
void moveX(CRGB *leds, int8_t delta);
|
||||
void moveY(CRGB *leds, int8_t delta);
|
||||
void move(uint8_t dir, uint8_t delta, CRGB *leds=nullptr);
|
||||
void fill_solid(CRGB* leds, CRGB c);
|
||||
void fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB c);
|
||||
void fadeToBlackBy(CRGB* leds, uint8_t fadeBy);
|
||||
void nscale8(CRGB* leds, uint8_t scale);
|
||||
void setPixels(CRGB* leds);
|
||||
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds = nullptr);
|
||||
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color, CRGB *leds = nullptr);
|
||||
void wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c);
|
||||
inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) { drawLine(x0, y0, x1, y1, CRGB(byte(c>>16), byte(c>>8), byte(c))); }
|
||||
inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t c) { drawCharacter(chr, x, y, w, h, CRGB(byte(c>>16), byte(c>>8), byte(c))); }
|
||||
} segment;
|
||||
|
||||
|
||||
// segment runtime parameters
|
||||
typedef struct Segment_runtime { // 28 bytes
|
||||
typedef struct Segment_runtime { // 23 (24 in memory) bytes
|
||||
unsigned long next_time; // millis() of next update
|
||||
uint32_t step; // custom "step" var
|
||||
uint32_t call; // call counter
|
||||
@ -429,25 +498,9 @@ typedef struct Segment_runtime { // 28 bytes
|
||||
} segment_runtime;
|
||||
|
||||
|
||||
// color transitions
|
||||
typedef struct ColorTransition { // 12 bytes
|
||||
uint32_t colorOld = 0;
|
||||
uint32_t transitionStart;
|
||||
uint16_t transitionDur;
|
||||
uint8_t segment = 0xFF; //lower 6 bits: the segment this transition is for (255 indicates transition not in use/available) upper 2 bits: color channel
|
||||
uint8_t briOld = 0;
|
||||
|
||||
static void startTransition(uint8_t oldBri, uint32_t oldCol, uint8_t segn, uint8_t slot);
|
||||
uint8_t currentBri(bool turningOff = false, uint8_t slot = 0);
|
||||
uint16_t progress(bool allowEnd = false); //transition progression between 0-65535
|
||||
uint32_t currentColor(uint32_t colorNew) {
|
||||
return color_blend(colorOld, colorNew, progress(true), true);
|
||||
}
|
||||
} color_transition;
|
||||
|
||||
|
||||
// main "strip" class
|
||||
class WS2812FX {
|
||||
class WS2812FX { // 96 bytes
|
||||
typedef uint16_t (*mode_ptr)(void); // pointer to mode function
|
||||
typedef void (*show_callback)(void); // pre show callback
|
||||
|
||||
@ -457,7 +510,10 @@ class WS2812FX {
|
||||
|
||||
WS2812FX() {
|
||||
WS2812FX::instance = this;
|
||||
setupEffectData();
|
||||
_mode = new mode_ptr[_modeCount];
|
||||
_modeData = new const char*[_modeCount];
|
||||
if (_mode && _modeData) setupEffectData();
|
||||
else _modeCount = 1; // only Solid will work
|
||||
_brightness = DEFAULT_BRIGHTNESS;
|
||||
currentPalette = CRGBPalette16(CRGB::Black);
|
||||
targetPalette = CloudColors_p;
|
||||
@ -467,15 +523,16 @@ class WS2812FX {
|
||||
resetSegments();
|
||||
}
|
||||
|
||||
~WS2812FX() {
|
||||
delete[] _mode;
|
||||
delete[] _modeData;
|
||||
}
|
||||
|
||||
static WS2812FX* getInstance(void) { return instance; }
|
||||
|
||||
void
|
||||
finalizeInit(),
|
||||
service(void),
|
||||
blur(uint8_t),
|
||||
fill(uint32_t c, uint8_t seg=255),
|
||||
fade_out(uint8_t r),
|
||||
fadeToBlackBy(uint8_t fadeBy),
|
||||
setMode(uint8_t segid, uint8_t m),
|
||||
setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
setColor(uint8_t slot, uint32_t c),
|
||||
@ -490,21 +547,18 @@ class WS2812FX {
|
||||
resetSegments(),
|
||||
makeAutoSegments(bool forceReset = false),
|
||||
fixInvalidSegments(),
|
||||
setPixelColor(int n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = false),
|
||||
blendPixelColor(uint16_t n, uint32_t color, uint8_t blend),
|
||||
setPixelColor(int n, uint32_t c),
|
||||
show(void),
|
||||
setTargetFps(uint8_t fps),
|
||||
deserializeMap(uint8_t n=0);
|
||||
|
||||
void addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name) { if (id < _modeCount) { _mode[id] = mode_fn; _modeData[id] = mode_name;} }
|
||||
void setupEffectData(void); // defined in FX.cpp
|
||||
void fill(uint32_t c) { for (int i = 0; i < _length; i++) setPixelColor(i, c); } // fill whole strip with color (inline)
|
||||
void addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name); // add effect to the list; defined in FX.cpp
|
||||
void setupEffectData(void); // add default effects to the list; defined in FX.cpp
|
||||
|
||||
// outsmart the compiler :) by correctly overloading
|
||||
inline void setPixelColor(int n, uint32_t c) {setPixelColor(n, byte(c>>16), byte(c>>8), byte(c), byte(c>>24));}
|
||||
inline void setPixelColor(int n, CRGB c) {setPixelColor(n, c.red, c.green, c.blue);}
|
||||
inline void setPixelColor(float i, uint32_t c, bool aa=true) {setPixelColor(i, byte(c>>16), byte(c>>8), byte(c), byte(c>>24), aa);}
|
||||
inline void setPixelColor(float i, CRGB c, bool aa=true) {setPixelColor(i, c.red, c.green, c.blue, 0, aa);}
|
||||
inline void setPixelColor(int n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColor(int n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); }
|
||||
inline void trigger(void) { _triggered = true; } // Forces the next frame to be computed on all active segments.
|
||||
inline void setShowCallback(show_callback cb) { _callback = cb; }
|
||||
inline void setTransition(uint16_t t) { _transitionDur = t; }
|
||||
@ -531,8 +585,7 @@ class WS2812FX {
|
||||
getLastActiveSegmentId(void),
|
||||
setPixelSegment(uint8_t n),
|
||||
gamma8(uint8_t),
|
||||
gamma8_cal(uint8_t, float),
|
||||
get_random_wheel_index(uint8_t);
|
||||
gamma8_cal(uint8_t, float);
|
||||
|
||||
inline uint8_t getBrightness(void) { return _brightness; }
|
||||
inline uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; }
|
||||
@ -541,31 +594,21 @@ class WS2812FX {
|
||||
inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; }
|
||||
inline uint8_t getTargetFps() { return _targetFps; }
|
||||
inline uint8_t getModeCount() { return _modeCount; }
|
||||
inline uint8_t sin_gap(uint16_t in) {
|
||||
if (in & 0x100) return 0;
|
||||
return sin8(in + 192); // correct phase shift of sine so that it starts and stops at 0
|
||||
}
|
||||
|
||||
int8_t
|
||||
tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec);
|
||||
|
||||
uint16_t
|
||||
ablMilliampsMax,
|
||||
currentMilliamps,
|
||||
triwave16(uint16_t),
|
||||
getLengthPhysical(void),
|
||||
getFps();
|
||||
|
||||
inline uint16_t getFrameTime(void) { return _frametime; }
|
||||
inline uint16_t getMinShowDelay(void) { return MIN_SHOW_DELAY; }
|
||||
inline uint16_t getLengthTotal(void) { return _length; }
|
||||
inline uint16_t segLen(void) { return _virtualSegmentLength; }
|
||||
inline uint16_t getTransition(void) { return _transitionDur; }
|
||||
|
||||
uint32_t
|
||||
now,
|
||||
timebase,
|
||||
color_wheel(uint8_t),
|
||||
color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255),
|
||||
currentColor(uint32_t colorNew, uint8_t tNr),
|
||||
gamma32(uint32_t),
|
||||
getPixelColor(uint16_t);
|
||||
@ -574,7 +617,7 @@ class WS2812FX {
|
||||
inline uint32_t segColor(uint8_t i) { return _colors_t[i]; }
|
||||
|
||||
const char *
|
||||
getModeData(uint8_t id = 0) { return id<_modeCount ? _modeData[id] : nullptr; }
|
||||
getModeData(uint8_t id = 0) { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); }
|
||||
|
||||
const char **
|
||||
getModeDataSrc(void) { return _modeData; }
|
||||
@ -589,6 +632,8 @@ class WS2812FX {
|
||||
bool
|
||||
isMatrix = false;
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
#define WLED_MAX_PANELS 64
|
||||
uint8_t
|
||||
hPanels = 1,
|
||||
vPanels = 1;
|
||||
@ -599,7 +644,6 @@ class WS2812FX {
|
||||
matrixWidth = DEFAULT_LED_COUNT,
|
||||
matrixHeight = 1;
|
||||
|
||||
#define WLED_MAX_PANELS 64
|
||||
typedef struct panel_bitfield_t {
|
||||
unsigned char
|
||||
bottomStart : 1, // starts at bottom?
|
||||
@ -610,41 +654,15 @@ class WS2812FX {
|
||||
Panel
|
||||
matrix = {0,0,0,0},
|
||||
panel[WLED_MAX_PANELS] = {{0,0,0,0}};
|
||||
#endif
|
||||
|
||||
void
|
||||
setUpMatrix(),
|
||||
setPixelColorXY(int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = false),
|
||||
blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend),
|
||||
addPixelColorXY(uint16_t x, uint16_t y, uint32_t color),
|
||||
blur1d(CRGB* leds, fract8 blur_amount),
|
||||
blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds=nullptr), // 1D box blur (with weight)
|
||||
blur2d(CRGB* leds, fract8 blur_amount),
|
||||
blurRow(uint16_t row, fract8 blur_amount, CRGB* leds=nullptr),
|
||||
blurCol(uint16_t col, fract8 blur_amount, CRGB* leds=nullptr),
|
||||
moveX(CRGB *leds, int8_t delta),
|
||||
moveY(CRGB *leds, int8_t delta),
|
||||
move(uint8_t dir, uint8_t delta, CRGB *leds=nullptr),
|
||||
fill_solid(CRGB* leds, CRGB c),
|
||||
fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB c),
|
||||
fadeToBlackBy(CRGB* leds, uint8_t fadeBy),
|
||||
nscale8(CRGB* leds, uint8_t scale),
|
||||
setPixels(CRGB* leds),
|
||||
drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds = nullptr),
|
||||
drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color, CRGB *leds = nullptr),
|
||||
wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c);
|
||||
setPixelColorXY(int x, int y, uint32_t c);
|
||||
|
||||
// outsmart the compiler :) by correctly overloading
|
||||
inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColorXY(x, y, byte(c>>16), byte(c>>8), byte(c), byte(c>>24)); }
|
||||
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, c.red, c.green, c.blue, 0); }
|
||||
inline void setPixelColorXY(float x, float y, uint32_t c, bool aa=true) { setPixelColorXY(x, y, byte(c>>16), byte(c>>8), byte(c), byte(c>>24), aa); }
|
||||
inline void setPixelColorXY(float x, float y, CRGB c, bool aa=true) { setPixelColorXY(x, y, c.red, c.green, c.blue, 0, aa); }
|
||||
inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) { drawLine(x0, y0, x1, y1, CRGB(byte(c>>16), byte(c>>8), byte(c))); }
|
||||
inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t c) { drawCharacter(chr, x, y, w, h, CRGB(byte(c>>16), byte(c>>8), byte(c))); }
|
||||
|
||||
uint16_t
|
||||
XY(uint16_t, uint16_t),
|
||||
get2DPixelIndex(uint16_t x, uint16_t y, uint8_t seg=255);
|
||||
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline
|
||||
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, c.red, c.green, c.blue); }
|
||||
|
||||
uint32_t
|
||||
getPixelColorXY(uint16_t, uint16_t);
|
||||
@ -654,8 +672,20 @@ class WS2812FX {
|
||||
CRGBPalette16 currentPalette;
|
||||
CRGBPalette16 targetPalette;
|
||||
|
||||
uint32_t _colors_t[3];
|
||||
uint16_t _virtualSegmentLength;
|
||||
|
||||
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 27 bytes per element
|
||||
// start, stop, offset, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[], capabilities, custom 1, custom 2, custom 3
|
||||
{0, 7, 0, DEFAULT_SPEED, DEFAULT_INTENSITY, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}, 0, DEFAULT_C1, DEFAULT_C2, DEFAULT_C3, 0, 1}
|
||||
};
|
||||
friend class Segment;
|
||||
|
||||
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element
|
||||
friend class Segment_runtime;
|
||||
|
||||
private:
|
||||
uint16_t _length, _virtualSegmentLength;
|
||||
uint16_t _length;
|
||||
uint16_t _rand16seed;
|
||||
uint8_t _brightness;
|
||||
uint16_t _usedSegmentData = 0;
|
||||
@ -671,9 +701,8 @@ class WS2812FX {
|
||||
_triggered;
|
||||
|
||||
uint8_t _modeCount = MODE_COUNT;
|
||||
// TODO: allocate memory using new or malloc()
|
||||
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
|
||||
const char *_modeData[MODE_COUNT]; // mode (effect) name and its slider control data array
|
||||
mode_ptr *_mode; // SRAM footprint: 4 bytes per element
|
||||
const char **_modeData; // mode (effect) name and its slider control data array
|
||||
|
||||
show_callback _callback = nullptr;
|
||||
|
||||
@ -683,26 +712,12 @@ class WS2812FX {
|
||||
uint32_t _lastPaletteChange = 0;
|
||||
uint32_t _lastShow = 0;
|
||||
|
||||
uint32_t _colors_t[3];
|
||||
uint8_t _bri_t;
|
||||
bool _no_rgb = false;
|
||||
|
||||
uint8_t _segment_index = 0;
|
||||
uint8_t _segment_index_palette_last = 99;
|
||||
uint8_t _mainSegment;
|
||||
|
||||
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 27 bytes per element
|
||||
// start, stop, offset, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[], capabilities, custom 1, custom 2, custom 3
|
||||
{0, 7, 0, DEFAULT_SPEED, DEFAULT_INTENSITY, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}, 0, DEFAULT_C1, DEFAULT_C2, DEFAULT_C3, 0, 1}
|
||||
};
|
||||
friend class Segment;
|
||||
|
||||
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element
|
||||
friend class Segment_runtime;
|
||||
|
||||
ColorTransition transitions[MAX_NUM_TRANSITIONS]; //12 bytes per element
|
||||
friend class ColorTransition;
|
||||
|
||||
void
|
||||
estimateCurrentAndLimitBri(void),
|
||||
load_gradient_palette(uint8_t),
|
||||
|
@ -26,23 +26,6 @@
|
||||
#include "FX.h"
|
||||
#include "palettes.h"
|
||||
|
||||
#ifdef SEGMENT
|
||||
#undef SEGMENT
|
||||
#endif
|
||||
#ifdef SEGCOLOR
|
||||
#undef SEGCOLOR
|
||||
#endif
|
||||
#ifdef SEGENV
|
||||
#undef SEGENV
|
||||
#endif
|
||||
#ifdef SEGLEN
|
||||
#undef SEGLEN
|
||||
#endif
|
||||
#define SEGMENT _segments[_segment_index]
|
||||
#define SEGCOLOR(x) _colors_t[x]
|
||||
#define SEGENV _segment_runtimes[_segment_index]
|
||||
#define SEGLEN _virtualSegmentLength
|
||||
|
||||
// setUpMatrix() - constructs ledmap array from matrix of panels with WxH pixels
|
||||
// this converts physical (possibly irregular) LED arrangement into well defined
|
||||
// array of logical pixels: fist entry corresponds to left-topmost logical pixel
|
||||
@ -52,6 +35,7 @@
|
||||
// but ledmap takes care of that. ledmap is constructed upon initialization
|
||||
// so matrix should disable regular ledmap processing
|
||||
void WS2812FX::setUpMatrix() {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
// erase old ledmap, just in case.
|
||||
if (customMappingTable != nullptr) delete[] customMappingTable;
|
||||
customMappingTable = nullptr;
|
||||
@ -63,7 +47,7 @@ void WS2812FX::setUpMatrix() {
|
||||
|
||||
// safety check
|
||||
if (matrixWidth * matrixHeight > MAX_LEDS) {
|
||||
matrixWidth = getLengthTotal();
|
||||
matrixWidth = _length;
|
||||
matrixHeight = 1;
|
||||
isMatrix = false;
|
||||
return;
|
||||
@ -111,93 +95,112 @@ void WS2812FX::setUpMatrix() {
|
||||
#endif
|
||||
} else {
|
||||
// memory allocation error
|
||||
matrixWidth = getLengthTotal();
|
||||
matrixWidth = _length;
|
||||
matrixHeight = 1;
|
||||
isMatrix = false;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// not a matrix set up
|
||||
matrixWidth = getLengthTotal();
|
||||
matrixWidth = _length;
|
||||
matrixHeight = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// absolute matrix version of setPixelColor()
|
||||
void IRAM_ATTR WS2812FX::setPixelColorXY(int x, int y, uint32_t col)
|
||||
{
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (!isMatrix) return; // not a matrix set-up
|
||||
uint16_t index = y * matrixWidth + x;
|
||||
if (index >= _length) return;
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
busses.setPixelColor(index, col);
|
||||
#endif
|
||||
}
|
||||
|
||||
// returns RGBW values of pixel
|
||||
uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
uint16_t index = (y * matrixWidth + x);
|
||||
if (index >= _length) return 0;
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
return busses.getPixelColor(index);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Segment:: routines
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// XY(x,y) - gets pixel index within current segment (often used to reference leds[] array element)
|
||||
uint16_t IRAM_ATTR WS2812FX::XY(uint16_t x, uint16_t y) {
|
||||
uint16_t width = SEGMENT.virtualWidth(); // segment width in logical pixels
|
||||
uint16_t height = SEGMENT.virtualHeight(); // segment height in logical pixels
|
||||
uint16_t IRAM_ATTR Segment::XY(uint16_t x, uint16_t y) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
uint16_t width = virtualWidth(); // segment width in logical pixels
|
||||
uint16_t height = virtualHeight(); // segment height in logical pixels
|
||||
return (x%width) + (y%height) * width;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// get2DPixelIndex(x,y,seg) - returns an index of segment pixel in a matrix layout
|
||||
// index still needs to undergo ledmap processing to represent actual physical pixel
|
||||
// matrix is always organized by matrixHeight number of matrixWidth pixels from top to bottom, left to right
|
||||
// so: pixel at get2DPixelIndex(5,6) in a 2D segment with [start=10, stop=19, startY=20, stopY=29 : 10x10 pixels]
|
||||
// corresponds to pixel with logical index of 847 (0 based) if a 2D segment belongs to a 32x32 matrix.
|
||||
// math: (matrixWidth * (startY + y)) + start + x => (32 * (20+6)) + 10 + 5 = 847
|
||||
uint16_t IRAM_ATTR WS2812FX::get2DPixelIndex(uint16_t x, uint16_t y, uint8_t seg) {
|
||||
if (seg == 255) seg = _segment_index;
|
||||
x %= _segments[seg].width(); // just in case constrain x (wrap around)
|
||||
y %= _segments[seg].height(); // just in case constrain y (wrap around)
|
||||
return ((_segments[seg].startY + y) * matrixWidth) + _segments[seg].start + x;
|
||||
}
|
||||
|
||||
void IRAM_ATTR WS2812FX::setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w)
|
||||
void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col)
|
||||
{
|
||||
if (!isMatrix) return; // not a matrix set-up
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (!strip.isMatrix) return; // not a matrix set-up
|
||||
|
||||
uint8_t _bri_t = getOption(SEG_OPTION_TRANSITIONAL) ? transition.briOld : opacity;
|
||||
if (_bri_t < 255) {
|
||||
r = scale8(r, _bri_t);
|
||||
g = scale8(g, _bri_t);
|
||||
b = scale8(b, _bri_t);
|
||||
w = scale8(w, _bri_t);
|
||||
byte r = scale8(R(col), _bri_t);
|
||||
byte g = scale8(G(col), _bri_t);
|
||||
byte b = scale8(B(col), _bri_t);
|
||||
byte w = scale8(W(col), _bri_t);
|
||||
col = RGBW32(r, g, b, w);
|
||||
}
|
||||
uint32_t col = RGBW32(r, g, b, w);
|
||||
|
||||
if (SEGMENT.getOption(SEG_OPTION_REVERSED) ) x = SEGMENT.virtualWidth() - x - 1;
|
||||
if (SEGMENT.getOption(SEG_OPTION_REVERSED_Y)) y = SEGMENT.virtualHeight() - y - 1;
|
||||
if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
||||
if (getOption(SEG_OPTION_REVERSED) ) x = virtualWidth() - x - 1;
|
||||
if (getOption(SEG_OPTION_REVERSED_Y)) y = virtualHeight() - y - 1;
|
||||
if (getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
||||
|
||||
x *= SEGMENT.groupLength(); // expand to physical pixels
|
||||
y *= SEGMENT.groupLength(); // expand to physical pixels
|
||||
if (x >= SEGMENT.width() || y >= SEGMENT.height()) return; // if pixel would fall out of segment just exit
|
||||
x *= groupLength(); // expand to physical pixels
|
||||
y *= groupLength(); // expand to physical pixels
|
||||
if (x >= width() || y >= height()) return; // if pixel would fall out of segment just exit
|
||||
|
||||
for (uint8_t j = 0; j < SEGMENT.grouping; j++) { // groupping vertically
|
||||
for (uint8_t g = 0; g < SEGMENT.grouping; g++) { // groupping horizontally
|
||||
uint16_t index, xX = (x+g), yY = (y+j);
|
||||
if (xX >= SEGMENT.width() || yY >= SEGMENT.height()) continue; // we have reached one dimension's end
|
||||
for (int j = 0; j < grouping; j++) { // groupping vertically
|
||||
for (int g = 0; g < grouping; g++) { // groupping horizontally
|
||||
uint16_t xX = (x+g), yY = (y+j);
|
||||
if (xX >= width() || yY >= height()) continue; // we have reached one dimension's end
|
||||
|
||||
index = get2DPixelIndex(xX, yY);
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
busses.setPixelColor(index, col);
|
||||
strip.setPixelColorXY(start + xX, startY + yY, col);
|
||||
|
||||
if (SEGMENT.getOption(SEG_OPTION_MIRROR)) { //set the corresponding horizontally mirrored pixel
|
||||
index = SEGMENT.getOption(SEG_OPTION_TRANSPOSED) ? get2DPixelIndex(xX, SEGMENT.height() - yY - 1) : get2DPixelIndex(SEGMENT.width() - xX - 1, yY);
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
busses.setPixelColor(index, col);
|
||||
if (getOption(SEG_OPTION_MIRROR)) { //set the corresponding horizontally mirrored pixel
|
||||
if (getOption(SEG_OPTION_TRANSPOSED)) strip.setPixelColorXY(start + xX, startY + height() - yY - 1, col);
|
||||
else strip.setPixelColorXY(start + width() - xX - 1, startY + yY, col);
|
||||
}
|
||||
if (SEGMENT.getOption(SEG_OPTION_MIRROR_Y)) { //set the corresponding vertically mirrored pixel
|
||||
index = SEGMENT.getOption(SEG_OPTION_TRANSPOSED) ? get2DPixelIndex(SEGMENT.width() - xX - 1, yY) : get2DPixelIndex(xX, SEGMENT.height() - yY - 1);
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
busses.setPixelColor(index, col);
|
||||
if (getOption(SEG_OPTION_MIRROR_Y)) { //set the corresponding vertically mirrored pixel
|
||||
if (getOption(SEG_OPTION_TRANSPOSED)) strip.setPixelColorXY(start + width() - xX - 1, startY + yY, col);
|
||||
else strip.setPixelColorXY(start + xX, startY + height() - yY - 1, col);
|
||||
}
|
||||
if (SEGMENT.getOption(SEG_OPTION_MIRROR_Y) && SEGMENT.getOption(SEG_OPTION_MIRROR)) { //set the corresponding vertically AND horizontally mirrored pixel
|
||||
index = get2DPixelIndex(SEGMENT.width() - xX - 1, SEGMENT.height() - yY - 1);
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
busses.setPixelColor(index, col);
|
||||
if (getOption(SEG_OPTION_MIRROR_Y) && getOption(SEG_OPTION_MIRROR)) { //set the corresponding vertically AND horizontally mirrored pixel
|
||||
strip.setPixelColorXY(width() - xX - 1, height() - yY - 1, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// anti-aliased version of setPixelColorXY()
|
||||
void /*IRAM_ATTR*/ WS2812FX::setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w, bool aa)
|
||||
void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
|
||||
{
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (!strip.isMatrix) return; // not a matrix set-up
|
||||
if (x<0.0f || x>1.0f || y<0.0f || y>1.0f) return; // not normalized
|
||||
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
|
||||
float fX = x * (cols-1);
|
||||
float fY = y * (rows-1);
|
||||
@ -216,80 +219,59 @@ void /*IRAM_ATTR*/ WS2812FX::setPixelColorXY(float x, float y, byte r, byte g, b
|
||||
uint32_t cXRYB = getPixelColorXY(xR, yB);
|
||||
|
||||
if (xL!=xR && yT!=yB) {
|
||||
// blend TL pixel
|
||||
cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, uint8_t(sqrtf(dL*dT)*255.0f));
|
||||
setPixelColorXY(xL, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT));
|
||||
// blend TR pixel
|
||||
cXRYT = color_blend(RGBW32(r,g,b,w), cXRYT, uint8_t(sqrtf(dR*dT)*255.0f));
|
||||
setPixelColorXY(xR, yT, R(cXRYT), G(cXRYT), B(cXRYT), W(cXRYT));
|
||||
// blend BL pixel
|
||||
cXLYB = color_blend(RGBW32(r,g,b,w), cXLYB, uint8_t(sqrtf(dL*dB)*255.0f));
|
||||
setPixelColorXY(xL, yB, R(cXLYB), G(cXLYB), B(cXLYB), W(cXLYB));
|
||||
// blend BR pixel
|
||||
cXRYB = color_blend(RGBW32(r,g,b,w), cXRYB, uint8_t(sqrtf(dR*dB)*255.0f));
|
||||
setPixelColorXY(xR, yB, R(cXRYB), G(cXRYB), B(cXRYB), W(cXRYB));
|
||||
setPixelColorXY(xL, yT, color_blend(col, cXLYT, uint8_t(sqrtf(dL*dT)*255.0f))); // blend TL pixel
|
||||
setPixelColorXY(xR, yT, color_blend(col, cXRYT, uint8_t(sqrtf(dR*dT)*255.0f))); // blend TR pixel
|
||||
setPixelColorXY(xL, yB, color_blend(col, cXLYB, uint8_t(sqrtf(dL*dB)*255.0f))); // blend BL pixel
|
||||
setPixelColorXY(xR, yB, color_blend(col, cXRYB, uint8_t(sqrtf(dR*dB)*255.0f))); // blend BR pixel
|
||||
} else if (xR!=xL && yT==yB) {
|
||||
// blend L pixel
|
||||
cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, uint8_t(dL*255.0f));
|
||||
setPixelColorXY(xR, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT));
|
||||
// blend R pixel
|
||||
cXRYT = color_blend(RGBW32(r,g,b,w), cXRYT, uint8_t(dR*255.0f));
|
||||
setPixelColorXY(xR, yT, R(cXRYT), G(cXRYT), B(cXRYT), W(cXRYT));
|
||||
setPixelColorXY(xR, yT, color_blend(col, cXLYT, uint8_t(dL*255.0f))); // blend L pixel
|
||||
setPixelColorXY(xR, yT, color_blend(col, cXRYT, uint8_t(dR*255.0f))); // blend R pixel
|
||||
} else if (xR==xL && yT!=yB) {
|
||||
// blend T pixel
|
||||
cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, uint8_t(dT*255.0f));
|
||||
setPixelColorXY(xR, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT));
|
||||
// blend B pixel
|
||||
cXLYB = color_blend(RGBW32(r,g,b,w), cXLYB, uint8_t(dB*255.0f));
|
||||
setPixelColorXY(xL, yB, R(cXLYB), G(cXLYB), B(cXLYB), W(cXLYB));
|
||||
setPixelColorXY(xR, yT, color_blend(col, cXLYT, uint8_t(dT*255.0f))); // blend T pixel
|
||||
setPixelColorXY(xL, yB, color_blend(col, cXLYB, uint8_t(dB*255.0f))); // blend B pixel
|
||||
} else {
|
||||
// exact match (x & y land on a pixel)
|
||||
setPixelColorXY(xL, yT, r, g, b, w);
|
||||
setPixelColorXY(xL, yT, col); // exact match (x & y land on a pixel)
|
||||
}
|
||||
} else {
|
||||
setPixelColorXY(uint16_t(roundf(fX)), uint16_t(roundf(fY)), r, g, b, w);
|
||||
setPixelColorXY(uint16_t(roundf(fX)), uint16_t(roundf(fY)), col);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// returns RGBW values of pixel
|
||||
uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) {
|
||||
uint16_t index;
|
||||
if (SEGLEN) {
|
||||
if (SEGMENT.getOption(SEG_OPTION_REVERSED) ) x = SEGMENT.virtualWidth() - x - 1;
|
||||
if (SEGMENT.getOption(SEG_OPTION_REVERSED_Y)) y = SEGMENT.virtualHeight() - y - 1;
|
||||
if (SEGMENT.getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
||||
|
||||
x *= SEGMENT.groupLength(); // expand to physical pixels
|
||||
y *= SEGMENT.groupLength(); // expand to physical pixels
|
||||
if (x >= SEGMENT.width() || y >= SEGMENT.height()) return 0;
|
||||
|
||||
index = get2DPixelIndex(x, y);
|
||||
} else {
|
||||
index = y * matrixWidth + x;
|
||||
}
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
|
||||
return busses.getPixelColor(index);
|
||||
uint32_t Segment::getPixelColorXY(uint16_t x, uint16_t y) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (getOption(SEG_OPTION_REVERSED) ) x = virtualWidth() - x - 1;
|
||||
if (getOption(SEG_OPTION_REVERSED_Y)) y = virtualHeight() - y - 1;
|
||||
if (getOption(SEG_OPTION_TRANSPOSED)) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
||||
x *= groupLength(); // expand to physical pixels
|
||||
y *= groupLength(); // expand to physical pixels
|
||||
if (x >= width() || y >= height()) return 0;
|
||||
return strip.getPixelColorXY(start + x, startY + y);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Blends the specified color with the existing pixel color.
|
||||
*/
|
||||
void WS2812FX::blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) {
|
||||
// Blends the specified color with the existing pixel color.
|
||||
void Segment::blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds the specified color with the existing pixel color perserving color balance.
|
||||
*/
|
||||
void WS2812FX::addPixelColorXY(uint16_t x, uint16_t y, uint32_t color) {
|
||||
// Adds the specified color with the existing pixel color perserving color balance.
|
||||
void Segment::addPixelColorXY(uint16_t x, uint16_t y, uint32_t color) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
setPixelColorXY(x, y, color_add(getPixelColorXY(x,y), color));
|
||||
#endif
|
||||
}
|
||||
|
||||
// blurRow: perform a blur on a row of a rectangular matrix
|
||||
void WS2812FX::blurRow(uint16_t row, fract8 blur_amount, CRGB* leds) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::blurRow(uint16_t row, fract8 blur_amount, CRGB* leds) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
|
||||
if (row >= rows) return;
|
||||
// blur one row
|
||||
@ -311,12 +293,14 @@ void WS2812FX::blurRow(uint16_t row, fract8 blur_amount, CRGB* leds) {
|
||||
else setPixelColorXY(x, row, cur);
|
||||
carryover = part;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// blurCol: perform a blur on a column of a rectangular matrix
|
||||
void WS2812FX::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
|
||||
if (col >= cols) return;
|
||||
// blur one column
|
||||
@ -338,6 +322,7 @@ void WS2812FX::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) {
|
||||
else setPixelColorXY(col, i, cur);
|
||||
carryover = part;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// blur1d: one-dimensional blur filter. Spreads light to 2 line neighbors.
|
||||
@ -354,17 +339,20 @@ void WS2812FX::blurCol(uint16_t col, fract8 blur_amount, CRGB* leds) {
|
||||
// eventually all the way to black; this is by design so that
|
||||
// it can be used to (slowly) clear the LEDs to black.
|
||||
|
||||
void WS2812FX::blur1d(CRGB* leds, fract8 blur_amount) {
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::blur1d(CRGB* leds, fract8 blur_amount) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t rows = virtualHeight();
|
||||
for (uint16_t y = 0; y < rows; y++) blurRow(y, blur_amount, leds);
|
||||
#endif
|
||||
}
|
||||
|
||||
// 1D Box blur (with added weight - blur_amount: [0=no blur, 255=max blur])
|
||||
void WS2812FX::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
const uint16_t dim1 = vertical ? rows : cols;
|
||||
const uint16_t dim2 = vertical ? cols : rows;
|
||||
void Segment::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
const uint16_t dim1 = vertical ? rows : cols;
|
||||
const uint16_t dim2 = vertical ? cols : rows;
|
||||
if (i >= dim2) return;
|
||||
const float seep = blur_amount/255.f;
|
||||
const float keep = 3.f - 2.f*seep;
|
||||
@ -392,63 +380,65 @@ void WS2812FX::blur1d(uint16_t i, bool vertical, fract8 blur_amount, CRGB* leds)
|
||||
if (leds) leds[XY(x,y)] = tmp[j];
|
||||
else setPixelColorXY(x, y, tmp[j]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::blur2d(CRGB* leds, fract8 blur_amount) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::blur2d(CRGB* leds, fract8 blur_amount) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
for (uint16_t i = 0; i < rows; i++) blurRow(i, blur_amount, leds); // blur all rows
|
||||
for (uint16_t k = 0; k < cols; k++) blurCol(k, blur_amount, leds); // blur all columns
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::moveX(CRGB *leds, int8_t delta) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::moveX(CRGB *leds, int8_t delta) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
if (!delta) return;
|
||||
if (delta > 0) {
|
||||
for (uint8_t y = 0; y < rows; y++) for (uint8_t x = 0; x < cols-1; x++) {
|
||||
if (x + delta >= cols) break;
|
||||
if (leds) leds[XY(x, y)] = leds[XY((x + delta)%cols, y)];
|
||||
else setPixelColorXY(x, y, getPixelColorXY((x + delta)%cols, y));
|
||||
}
|
||||
} else {
|
||||
for (uint8_t y = 0; y < rows; y++) for (int16_t x = cols-1; x >= 0; x--) {
|
||||
if (x + delta < 0) {
|
||||
if (leds) leds[XY(x, y)] = leds[XY(cols + delta, y)];
|
||||
else setPixelColorXY(x, y, getPixelColorXY(cols + delta, y));
|
||||
} else {
|
||||
if (leds) leds[XY(x, y)] = leds[XY(x + delta, y)];
|
||||
else setPixelColorXY(x, y, getPixelColorXY(x + delta, y));
|
||||
}
|
||||
if (x + delta < 0) break;
|
||||
if (leds) leds[XY(x, y)] = leds[XY(x + delta, y)];
|
||||
else setPixelColorXY(x, y, getPixelColorXY(x + delta, y));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::moveY(CRGB *leds, int8_t delta) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::moveY(CRGB *leds, int8_t delta) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
if (!delta) return;
|
||||
if (delta > 0) {
|
||||
for (uint8_t x = 0; x < cols; x++) for (uint8_t y = 0; y < rows-1; y++) {
|
||||
if (leds) leds[XY(x, y)] = leds[XY(x, (y + delta)%rows)];
|
||||
else setPixelColorXY(x, y, getPixelColorXY(x, (y + delta)%rows));
|
||||
if (y + delta >= rows) break;
|
||||
if (leds) leds[XY(x, y)] = leds[XY(x, (y + delta))];
|
||||
else setPixelColorXY(x, y, getPixelColorXY(x, (y + delta)));
|
||||
}
|
||||
} else {
|
||||
for (uint8_t x = 0; x < cols; x++) for (int16_t y = rows-1; y >= 0; y--) {
|
||||
if (y + delta < 0) {
|
||||
if (leds) leds[XY(x, y)] = leds[XY(x, rows + delta)];
|
||||
else setPixelColorXY(x, y, getPixelColorXY(x, rows + delta));
|
||||
} else {
|
||||
if (leds) leds[XY(x, y)] = leds[XY(x, y + delta)];
|
||||
else setPixelColorXY(x, y, getPixelColorXY(x, y + delta));
|
||||
}
|
||||
if (y + delta < 0) break;
|
||||
if (leds) leds[XY(x, y)] = leds[XY(x, y + delta)];
|
||||
else setPixelColorXY(x, y, getPixelColorXY(x, y + delta));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// move() - move all pixels in desired direction delta number of pixels
|
||||
// @param dir direction: 0=left, 1=left-up, 2=up, 3=right-up, 4=right, 5=right-down, 6=down, 7=left-down
|
||||
// @param delta number of pixels to move
|
||||
void WS2812FX::move(uint8_t dir, uint8_t delta, CRGB *leds) {
|
||||
void Segment::move(uint8_t dir, uint8_t delta, CRGB *leds) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (delta==0) return;
|
||||
switch (dir) {
|
||||
case 0: moveX(leds, delta); break;
|
||||
@ -460,21 +450,25 @@ void WS2812FX::move(uint8_t dir, uint8_t delta, CRGB *leds) {
|
||||
case 6: moveY(leds,-delta); break;
|
||||
case 7: moveX(leds, delta); moveY(leds,-delta); break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::fill_solid(CRGB* leds, CRGB color) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::fill_solid(CRGB* leds, CRGB color) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
|
||||
if (leds) leds[XY(x,y)] = color;
|
||||
else setPixelColorXY(x, y, color);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// by stepko, taken from https://editor.soulmatelights.com/gallery/573-blobs
|
||||
void WS2812FX::fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
for (int16_t y = -radius; y <= radius; y++) {
|
||||
for (int16_t x = -radius; x <= radius; x++) {
|
||||
if (x * x + y * y <= radius * radius &&
|
||||
@ -483,31 +477,39 @@ void WS2812FX::fill_circle(CRGB* leds, uint16_t cx, uint16_t cy, uint8_t radius,
|
||||
leds[XY(cx + x, cy + y)] += col;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::fadeToBlackBy(CRGB* leds, uint8_t fadeBy) {
|
||||
void Segment::fadeToBlackBy(CRGB* leds, uint8_t fadeBy) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
nscale8(leds, 255 - fadeBy);
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::nscale8(CRGB* leds, uint8_t scale) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::nscale8(CRGB* leds, uint8_t scale) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
|
||||
if (leds) leds[XY(x,y)].nscale8(scale);
|
||||
else setPixelColorXY(x, y, CRGB(getPixelColorXY(x, y)).nscale8(scale));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::setPixels(CRGB* leds) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::setPixels(CRGB* leds) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) setPixelColorXY(x, y, leds[XY(x,y)]);
|
||||
#endif
|
||||
}
|
||||
|
||||
//line function
|
||||
void WS2812FX::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c, CRGB *leds) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
if (x0 >= cols || x1 >= cols || y0 >= rows || y1 >= rows) return;
|
||||
const int16_t dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
|
||||
const int16_t dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
|
||||
@ -520,8 +522,10 @@ void WS2812FX::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB
|
||||
if (e2 >-dx) { err -= dy; x0 += sx; }
|
||||
if (e2 < dy) { err += dx; y0 += sy; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
// font curtesy of https://github.com/idispatch/raster-fonts
|
||||
static const unsigned char console_font_6x8[] PROGMEM = {
|
||||
|
||||
@ -6672,19 +6676,21 @@ static const unsigned char console_font_5x8[] PROGMEM = {
|
||||
0x00, /* 00000 */
|
||||
0x00, /* 00000 */
|
||||
};
|
||||
#endif
|
||||
|
||||
// draws a raster font character on canvas
|
||||
// only supports 5x8 and 6x8 fonts ATM
|
||||
void WS2812FX::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color, CRGB *leds) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color, CRGB *leds) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
|
||||
if (w<5 || w>6 || h!=8) return;
|
||||
for (uint8_t i = 0; i<h; i++) { // character height
|
||||
int16_t y0 = y + i;
|
||||
if (y0 < 0) continue; // drawing off-screen
|
||||
if (y0 >= rows) break; // drawing off-screen
|
||||
uint8_t bits;
|
||||
uint8_t bits = 0;
|
||||
switch (w) {
|
||||
case 5: bits = pgm_read_byte_near(&console_font_5x8[(chr * 8) + i]); break;
|
||||
case 6: bits = pgm_read_byte_near(&console_font_6x8[(chr * 8) + i]); break;
|
||||
@ -6697,10 +6703,12 @@ void WS2812FX::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define WU_WEIGHT(a,b) ((uint8_t) (((a)*(b)+(a)+(b))>>8))
|
||||
void WS2812FX::wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c) { //awesome wu_pixel procedure by reddit u/sutaburosu
|
||||
void Segment::wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c) { //awesome wu_pixel procedure by reddit u/sutaburosu
|
||||
#ifndef WLED_DISABLE_2D
|
||||
// extract the fractional parts and derive their inverses
|
||||
uint8_t xx = x & 0xff, yy = y & 0xff, ix = 255 - xx, iy = 255 - yy;
|
||||
// calculate the intensities for each affected pixel
|
||||
@ -6713,5 +6721,6 @@ void WS2812FX::wu_pixel(CRGB *leds, uint32_t x, uint32_t y, CRGB c) { //awe
|
||||
leds[xy].g = qadd8(leds[xy].g, c.g * wu[i] >> 8);
|
||||
leds[xy].b = qadd8(leds[xy].b, c.b * wu[i] >> 8);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#undef WU_WEIGHT
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -199,7 +199,7 @@ void handleAnalog(uint8_t b)
|
||||
if (aRead == 0) {
|
||||
seg.setOption(SEG_OPTION_ON, 0); // off
|
||||
} else {
|
||||
seg.setOpacity(aRead, macroDoublePress[b]);
|
||||
seg.setOpacity(aRead);
|
||||
seg.setOption(SEG_OPTION_ON, 1);
|
||||
}
|
||||
// this will notify clients of update (websockets,mqtt,etc)
|
||||
|
@ -91,6 +91,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
Bus::setCCTBlend(strip.cctBlending);
|
||||
strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
// 2D Matrix Settings
|
||||
JsonObject matrix = hw_led[F("matrix")];
|
||||
if (!matrix.isNull()) {
|
||||
@ -125,6 +126,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
|
||||
strip.setUpMatrix();
|
||||
}
|
||||
#endif
|
||||
|
||||
JsonArray ins = hw_led["ins"];
|
||||
|
||||
@ -620,6 +622,7 @@ void serializeConfig() {
|
||||
hw_led["fps"] = strip.getTargetFps();
|
||||
hw_led[F("rgbwm")] = Bus::getAutoWhiteMode(); // global override
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
// 2D Matrix Settings
|
||||
if (strip.isMatrix) {
|
||||
JsonObject matrix = hw_led.createNestedObject(F("matrix"));
|
||||
@ -641,6 +644,7 @@ void serializeConfig() {
|
||||
pnl["s"] = strip.panel[i].serpentine;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
||||
|
||||
|
@ -51,7 +51,7 @@ uint32_t color_add(uint32_t c1, uint32_t c2)
|
||||
|
||||
void setRandomColor(byte* rgb)
|
||||
{
|
||||
lastRandomIndex = strip.get_random_wheel_index(lastRandomIndex);
|
||||
lastRandomIndex = strip.getMainSegment().get_random_wheel_index(lastRandomIndex);
|
||||
colorHStoRGB(lastRandomIndex*256,255,rgb);
|
||||
}
|
||||
|
||||
|
@ -226,9 +226,9 @@ void changeColor(uint32_t c, int16_t cct=-1)
|
||||
if (isRGB) mask |= 0x00FFFFFF; // RGB
|
||||
if (hasW) mask |= 0xFF000000; // white
|
||||
if (hasW && !wSlider && (c & 0xFF000000)) { // segment has white channel & white channel is auto calculated & white specified
|
||||
seg.setColor(0, c | 0xFFFFFF, i); // for accurate/brighter mode we fake white (since button may not set white color to 0xFFFFFF)
|
||||
} else if (c & mask) seg.setColor(0, c & mask, i); // only apply if not black
|
||||
if (isCCT && cct >= 0) seg.setCCT(cct, i);
|
||||
seg.setColor(0, c | 0xFFFFFF); // for accurate/brighter mode we fake white (since button may not set white color to 0xFFFFFF)
|
||||
} else if (c & mask) seg.setColor(0, c & mask); // only apply if not black
|
||||
if (isCCT && cct >= 0) seg.setCCT(cct);
|
||||
}
|
||||
setValuesFromFirstSelectedSeg();
|
||||
} else {
|
||||
@ -243,9 +243,9 @@ void changeColor(uint32_t c, int16_t cct=-1)
|
||||
if (isRGB) mask |= 0x00FFFFFF; // RGB
|
||||
if (hasW) mask |= 0xFF000000; // white
|
||||
if (hasW && !wSlider && (c & 0xFF000000)) { // segment has white channel & white channel is auto calculated & white specified
|
||||
seg.setColor(0, c | 0xFFFFFF, i); // for accurate/brighter mode we fake white (since button may not set white color to 0xFFFFFF)
|
||||
} else if (c & mask) seg.setColor(0, c & mask, i); // only apply if not black
|
||||
if (isCCT && cct >= 0) seg.setCCT(cct, i);
|
||||
seg.setColor(0, c | 0xFFFFFF); // for accurate/brighter mode we fake white (since button may not set white color to 0xFFFFFF)
|
||||
} else if (c & mask) seg.setColor(0, c & mask); // only apply if not black
|
||||
if (isCCT && cct >= 0) seg.setCCT(cct);
|
||||
setValuesFromMainSeg();
|
||||
}
|
||||
stateChanged = true;
|
||||
|
@ -72,7 +72,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
uint16_t spc = elem[F("spc")] | seg.spacing;
|
||||
uint16_t of = seg.offset;
|
||||
|
||||
if (spc>0 && spc!=seg.spacing) strip.fill(BLACK, id); // clear spacing gaps
|
||||
if (spc>0 && spc!=seg.spacing) seg.fill(BLACK); // clear spacing gaps
|
||||
|
||||
uint16_t len = 1;
|
||||
if (stop > start) len = stop - start;
|
||||
@ -88,18 +88,18 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
|
||||
byte segbri = seg.opacity;
|
||||
if (getVal(elem["bri"], &segbri)) {
|
||||
if (segbri > 0) seg.setOpacity(segbri, id);
|
||||
seg.setOption(SEG_OPTION_ON, segbri, id);
|
||||
if (segbri > 0) seg.setOpacity(segbri);
|
||||
seg.setOption(SEG_OPTION_ON, segbri);
|
||||
}
|
||||
|
||||
bool on = elem["on"] | seg.getOption(SEG_OPTION_ON);
|
||||
if (elem["on"].is<const char*>() && elem["on"].as<const char*>()[0] == 't') on = !on;
|
||||
seg.setOption(SEG_OPTION_ON, on, id);
|
||||
seg.setOption(SEG_OPTION_ON, on);
|
||||
bool frz = elem["frz"] | seg.getOption(SEG_OPTION_FREEZE);
|
||||
if (elem["frz"].is<const char*>() && elem["frz"].as<const char*>()[0] == 't') frz = !seg.getOption(SEG_OPTION_FREEZE);
|
||||
seg.setOption(SEG_OPTION_FREEZE, frz, id);
|
||||
seg.setOption(SEG_OPTION_FREEZE, frz);
|
||||
|
||||
seg.setCCT(elem["cct"] | seg.cct, id);
|
||||
seg.setCCT(elem["cct"] | seg.cct);
|
||||
|
||||
JsonArray colarr = elem["col"];
|
||||
if (!colarr.isNull())
|
||||
@ -115,7 +115,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
if (hexCol == nullptr) { //Kelvin color temperature (or invalid), e.g 2400
|
||||
int kelvin = colarr[i] | -1;
|
||||
if (kelvin < 0) continue;
|
||||
if (kelvin == 0) seg.setColor(i, 0, id);
|
||||
if (kelvin == 0) seg.setColor(i, 0);
|
||||
if (kelvin > 0) colorKtoRGB(kelvin, brgbw);
|
||||
colValid = true;
|
||||
} else { //HEX string, e.g. "FFAA00"
|
||||
@ -132,7 +132,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
|
||||
if (!colValid) continue;
|
||||
|
||||
seg.setColor(i, RGBW32(rgbw[0],rgbw[1],rgbw[2],rgbw[3]), id);
|
||||
seg.setColor(i, RGBW32(rgbw[0],rgbw[1],rgbw[2],rgbw[3]));
|
||||
if (seg.mode == FX_MODE_STATIC) strip.trigger(); //instant refresh
|
||||
}
|
||||
}
|
||||
@ -152,10 +152,12 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
seg.setOption(SEG_OPTION_SELECTED, elem[F("sel")] | seg.getOption(SEG_OPTION_SELECTED));
|
||||
seg.setOption(SEG_OPTION_REVERSED, elem["rev"] | seg.getOption(SEG_OPTION_REVERSED));
|
||||
seg.setOption(SEG_OPTION_MIRROR , elem[F("mi")] | seg.getOption(SEG_OPTION_MIRROR ));
|
||||
#ifndef WLED_DISABLE_2D
|
||||
// 2D options
|
||||
seg.setOption(SEG_OPTION_REVERSED_Y, elem[F("rY")] | seg.getOption(SEG_OPTION_REVERSED_Y));
|
||||
seg.setOption(SEG_OPTION_MIRROR_Y , elem[F("mY")] | seg.getOption(SEG_OPTION_MIRROR_Y ));
|
||||
seg.setOption(SEG_OPTION_TRANSPOSED, elem[F("tp")] | seg.getOption(SEG_OPTION_TRANSPOSED));
|
||||
#endif
|
||||
|
||||
byte fx = seg.mode;
|
||||
if (getVal(elem["fx"], &fx, 1, strip.getModeCount())) { //load effect ('r' random, '~' inc/dec, 1-255 exact value)
|
||||
@ -173,7 +175,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
|
||||
JsonArray iarr = elem[F("i")]; //set individual LEDs
|
||||
if (!iarr.isNull()) {
|
||||
uint8_t oldSegId = strip.setPixelSegment(id);
|
||||
//uint8_t oldSegId = strip.setPixelSegment(id);
|
||||
|
||||
// set brightness immediately and disable transition
|
||||
transitionDelayTemp = 0;
|
||||
@ -183,7 +185,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
// freeze and init to black
|
||||
if (!seg.getOption(SEG_OPTION_FREEZE)) {
|
||||
seg.setOption(SEG_OPTION_FREEZE, true);
|
||||
strip.fill(0);
|
||||
seg.fill(0);
|
||||
}
|
||||
|
||||
uint16_t start = 0, stop = 0;
|
||||
@ -215,16 +217,16 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
if (set < 2) stop = start + 1;
|
||||
for (uint16_t i = start; i < stop; i++) {
|
||||
if (strip.gammaCorrectCol) {
|
||||
strip.setPixelColor(i, strip.gamma8(rgbw[0]), strip.gamma8(rgbw[1]), strip.gamma8(rgbw[2]), strip.gamma8(rgbw[3]));
|
||||
seg.setPixelColor(i, strip.gamma8(rgbw[0]), strip.gamma8(rgbw[1]), strip.gamma8(rgbw[2]), strip.gamma8(rgbw[3]));
|
||||
} else {
|
||||
strip.setPixelColor(i, rgbw[0], rgbw[1], rgbw[2], rgbw[3]);
|
||||
seg.setPixelColor(i, rgbw[0], rgbw[1], rgbw[2], rgbw[3]);
|
||||
}
|
||||
}
|
||||
if (!set) start++;
|
||||
set = 0;
|
||||
}
|
||||
}
|
||||
strip.setPixelSegment(oldSegId);
|
||||
//strip.setPixelSegment(oldSegId);
|
||||
strip.trigger();
|
||||
}
|
||||
// send UDP if not in preset and something changed that is not just selection
|
||||
@ -249,10 +251,10 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
|
||||
if (bri && !onBefore) { // unfreeze all segments when turning on
|
||||
for (uint8_t s=0; s < strip.getMaxSegments(); s++) {
|
||||
strip.getSegment(s).setOption(SEG_OPTION_FREEZE, false, s);
|
||||
strip.getSegment(s).setOption(SEG_OPTION_FREEZE, false);
|
||||
}
|
||||
if (realtimeMode && !realtimeOverride && useMainSegmentOnly) { // keep live segment frozen if live
|
||||
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, true, strip.getMainSegmentId());
|
||||
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,7 +306,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
realtimeOverride = root[F("lor")] | realtimeOverride;
|
||||
if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS;
|
||||
if (realtimeMode && useMainSegmentOnly) {
|
||||
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, !realtimeOverride, strip.getMainSegmentId());
|
||||
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, !realtimeOverride);
|
||||
}
|
||||
|
||||
if (root.containsKey("live")) {
|
||||
@ -520,11 +522,13 @@ void serializeInfo(JsonObject root)
|
||||
leds[F("maxseg")] = strip.getMaxSegments();
|
||||
//leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (strip.isMatrix) {
|
||||
JsonObject matrix = leds.createNestedObject("matrix");
|
||||
matrix["w"] = strip.matrixWidth;
|
||||
matrix["h"] = strip.matrixHeight;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t totalLC = 0;
|
||||
JsonArray lcarr = leds.createNestedArray(F("seglc"));
|
||||
|
@ -41,8 +41,8 @@ void applyValuesToSelectedSegs()
|
||||
if (effectCurrent != selsegPrev.mode) {strip.setMode(i, effectCurrent); stateChanged = true;}
|
||||
uint32_t col0 = RGBW32( col[0], col[1], col[2], col[3]);
|
||||
uint32_t col1 = RGBW32(colSec[0], colSec[1], colSec[2], colSec[3]);
|
||||
if (col0 != selsegPrev.colors[0]) {seg.setColor(0, col0, i); stateChanged = true;}
|
||||
if (col1 != selsegPrev.colors[1]) {seg.setColor(1, col1, i); stateChanged = true;}
|
||||
if (col0 != selsegPrev.colors[0]) {seg.setColor(0, col0); stateChanged = true;}
|
||||
if (col1 != selsegPrev.colors[1]) {seg.setColor(1, col1); stateChanged = true;}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ void parseLxJson(int lxValue, byte segId, bool secondary)
|
||||
} else {
|
||||
DEBUG_PRINT(F("LX: segment "));
|
||||
DEBUG_PRINTLN(segId);
|
||||
strip.getSegment(segId).setColor(secondary, RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3]), segId);
|
||||
strip.getSegment(segId).setColor(secondary, RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -554,6 +554,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
releaseJSONBufferLock();
|
||||
}
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
//2D panels
|
||||
if (subPage == 10)
|
||||
{
|
||||
@ -577,6 +578,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
}
|
||||
strip.setUpMatrix(); // will check limits
|
||||
}
|
||||
#endif
|
||||
|
||||
lastEditTime = millis();
|
||||
if (subPage != 2 && !doReboot) serializeConfig(); //do not save if factory reset or LED settings (which are saved after LED re-init)
|
||||
@ -664,9 +666,9 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
pos = req.indexOf(F("SB=")); //Segment brightness/opacity
|
||||
if (pos > 0) {
|
||||
byte segbri = getNumVal(&req, pos);
|
||||
selseg.setOption(SEG_OPTION_ON, segbri, selectedSeg);
|
||||
selseg.setOption(SEG_OPTION_ON, segbri);
|
||||
if (segbri) {
|
||||
selseg.setOpacity(segbri, selectedSeg);
|
||||
selseg.setOpacity(segbri);
|
||||
}
|
||||
}
|
||||
|
||||
@ -769,7 +771,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
if (pos > 0) {
|
||||
colorFromDecOrHexString(tmpCol, (char*)req.substring(pos + 3).c_str());
|
||||
uint32_t col2 = RGBW32(tmpCol[0], tmpCol[1], tmpCol[2], tmpCol[3]);
|
||||
selseg.setColor(2, col2, selectedSeg); // defined above (SS= or main)
|
||||
selseg.setColor(2, col2); // defined above (SS= or main)
|
||||
stateChanged = true;
|
||||
if (!singleSegment) strip.setColor(2, col2); // will set color to all active & selected segments
|
||||
}
|
||||
@ -798,14 +800,14 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
if (col0Changed) {
|
||||
stateChanged = true;
|
||||
uint32_t colIn0 = RGBW32(colIn[0], colIn[1], colIn[2], colIn[3]);
|
||||
selseg.setColor(0, colIn0, selectedSeg);
|
||||
selseg.setColor(0, colIn0);
|
||||
if (!singleSegment) strip.setColor(0, colIn0); // will set color to all active & selected segments
|
||||
}
|
||||
|
||||
if (col1Changed) {
|
||||
stateChanged = true;
|
||||
uint32_t colIn1 = RGBW32(colInSec[0], colInSec[1], colInSec[2], colInSec[3]);
|
||||
selseg.setColor(1, colIn1, selectedSeg);
|
||||
selseg.setColor(1, colIn1);
|
||||
if (!singleSegment) strip.setColor(1, colIn1); // will set color to all active & selected segments
|
||||
}
|
||||
|
||||
@ -925,7 +927,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
realtimeOverride = getNumVal(&req, pos);
|
||||
if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS;
|
||||
if (realtimeMode && useMainSegmentOnly) {
|
||||
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, !realtimeOverride, strip.getMainSegmentId());
|
||||
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, !realtimeOverride);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ void realtimeLock(uint32_t timeoutMs, byte md)
|
||||
Segment& mainseg = strip.getMainSegment();
|
||||
start = mainseg.start;
|
||||
stop = mainseg.stop;
|
||||
mainseg.setOption(SEG_OPTION_FREEZE, true, strip.getMainSegmentId());
|
||||
mainseg.setOption(SEG_OPTION_FREEZE, true);
|
||||
} else {
|
||||
start = 0;
|
||||
stop = strip.getLengthTotal();
|
||||
@ -156,7 +156,7 @@ void realtimeLock(uint32_t timeoutMs, byte md)
|
||||
// if WLED was off and using main segment only, freeze non-main segments so they stay off
|
||||
if (useMainSegmentOnly && bri == 0) {
|
||||
for (uint8_t s=0; s < strip.getMaxSegments(); s++) {
|
||||
strip.getSegment(s).setOption(SEG_OPTION_FREEZE, true, s);
|
||||
strip.getSegment(s).setOption(SEG_OPTION_FREEZE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,7 +183,7 @@ void exitRealtime() {
|
||||
realtimeMode = REALTIME_MODE_INACTIVE; // inform UI immediately
|
||||
realtimeIP[0] = 0;
|
||||
if (useMainSegmentOnly) { // unfreeze live segment again
|
||||
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, false, strip.getMainSegmentId());
|
||||
strip.getMainSegment().setOption(SEG_OPTION_FREEZE, false);
|
||||
}
|
||||
updateInterfaces(CALL_MODE_WS_SEND);
|
||||
}
|
||||
@ -351,8 +351,8 @@ void handleNotifications()
|
||||
strip.setSegment(id, start, stop, selseg.grouping, selseg.spacing, offset);
|
||||
continue;
|
||||
}
|
||||
for (uint8_t j = 0; j<4; j++) selseg.setOption(j, (udpIn[9 +ofs] >> j) & 0x01, id); //only take into account mirrored, selected, on, reversed
|
||||
selseg.setOpacity(udpIn[10+ofs], id);
|
||||
for (uint8_t j = 0; j<4; j++) selseg.setOption(j, (udpIn[9 +ofs] >> j) & 0x01); //only take into account mirrored, selected, on, reversed
|
||||
selseg.setOpacity(udpIn[10+ofs]);
|
||||
if (applyEffects) {
|
||||
strip.setMode(id, udpIn[11+ofs]);
|
||||
selseg.speed = udpIn[12+ofs];
|
||||
@ -360,10 +360,10 @@ void handleNotifications()
|
||||
selseg.palette = udpIn[14+ofs];
|
||||
}
|
||||
if (receiveNotificationColor || !someSel) {
|
||||
selseg.setColor(0, RGBW32(udpIn[15+ofs],udpIn[16+ofs],udpIn[17+ofs],udpIn[18+ofs]), id);
|
||||
selseg.setColor(1, RGBW32(udpIn[19+ofs],udpIn[20+ofs],udpIn[21+ofs],udpIn[22+ofs]), id);
|
||||
selseg.setColor(2, RGBW32(udpIn[23+ofs],udpIn[24+ofs],udpIn[25+ofs],udpIn[26+ofs]), id);
|
||||
selseg.setCCT(udpIn[27+ofs], id);
|
||||
selseg.setColor(0, RGBW32(udpIn[15+ofs],udpIn[16+ofs],udpIn[17+ofs],udpIn[18+ofs]));
|
||||
selseg.setColor(1, RGBW32(udpIn[19+ofs],udpIn[20+ofs],udpIn[21+ofs],udpIn[22+ofs]));
|
||||
selseg.setColor(2, RGBW32(udpIn[23+ofs],udpIn[24+ofs],udpIn[25+ofs],udpIn[26+ofs]));
|
||||
selseg.setCCT(udpIn[27+ofs]);
|
||||
}
|
||||
//setSegment() also properly resets segments
|
||||
if (receiveSegmentBounds) {
|
||||
|
@ -238,14 +238,13 @@ uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLe
|
||||
char lineBuffer[256];
|
||||
//strcpy_P(lineBuffer, (const char*)pgm_read_dword(&(WS2812FX::_modeData[mode])));
|
||||
strcpy_P(lineBuffer, strip.getModeData(mode));
|
||||
if (strlen(lineBuffer) > 0) {
|
||||
size_t j = 0;
|
||||
for (; j < maxLen; j++) {
|
||||
if (lineBuffer[j] == '\0' || lineBuffer[j] == '@') break;
|
||||
dest[j] = lineBuffer[j];
|
||||
}
|
||||
dest[j] = 0; // terminate string
|
||||
size_t len = strlen(lineBuffer);
|
||||
size_t j = 0;
|
||||
for (; j < maxLen && j < len; j++) {
|
||||
if (lineBuffer[j] == '\0' || lineBuffer[j] == '@') break;
|
||||
dest[j] = lineBuffer[j];
|
||||
}
|
||||
dest[j] = 0; // terminate string
|
||||
return strlen(dest);
|
||||
} else return 0;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2207041
|
||||
#define VERSION 2207081
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
@ -152,19 +152,19 @@ using PSRAMDynamicJsonDocument = BasicJsonDocument<PSRAM_Allocator>;
|
||||
#define PSRAMDynamicJsonDocument DynamicJsonDocument
|
||||
#endif
|
||||
|
||||
#include "const.h"
|
||||
#include "fcn_declare.h"
|
||||
#include "html_ui.h"
|
||||
#ifdef WLED_ENABLE_SIMPLE_UI
|
||||
#include "html_simple.h"
|
||||
#include "html_simple.h"
|
||||
#endif
|
||||
#include "html_settings.h"
|
||||
#include "html_other.h"
|
||||
#include "FX.h"
|
||||
#include "ir_codes.h"
|
||||
#include "const.h"
|
||||
#include "NodeStruct.h"
|
||||
#include "pin_manager.h"
|
||||
#include "bus_manager.h"
|
||||
#include "FX.h"
|
||||
|
||||
#ifndef CLIENT_SSID
|
||||
#define CLIENT_SSID DEFAULT_CLIENT_SSID
|
||||
|
@ -636,6 +636,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
if (subPage == 10) // 2D matrices
|
||||
{
|
||||
sappend('v',SET_F("SOMP"),strip.isMatrix);
|
||||
#ifndef WLED_DISABLE_2D
|
||||
oappend(SET_F("resetPanels();"));
|
||||
if (strip.isMatrix) {
|
||||
sappend('v',SET_F("PH"),strip.panelH);
|
||||
@ -660,5 +661,8 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
pO[l] = 'S'; sappend('c',pO,strip.panel[i].serpentine);
|
||||
}
|
||||
}
|
||||
#else
|
||||
oappend(SET_F("gId(\"somp\").remove(1);")); // remove 2D option from dropdown
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user