2016-12-17 22:43:07 +00:00
/*
WS2812FX . h - Library for WS2812 LED effects .
Harm Aldick - 2016
www . aldick . org
LICENSE
The MIT License ( MIT )
2018-09-04 13:51:38 +00:00
Copyright ( c ) 2016 Harm Aldick
2016-12-17 22:43:07 +00:00
Permission is hereby granted , free of charge , to any person obtaining a copy
of this software and associated documentation files ( the " Software " ) , to deal
in the Software without restriction , including without limitation the rights
to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
copies of the Software , and to permit persons to whom the Software is
furnished to do so , subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE .
2019-02-09 15:37:20 +00:00
2018-09-04 13:51:38 +00:00
Modified for WLED
2016-12-17 22:43:07 +00:00
*/
# ifndef WS2812FX_h
# define WS2812FX_h
2022-07-17 13:58:41 +00:00
# include <vector>
2020-02-19 23:45:09 +00:00
# include "const.h"
2018-11-09 16:00:36 +00:00
# define FASTLED_INTERNAL //remove annoying pragma messages
2020-08-25 15:23:17 +00:00
# define USE_GET_MILLISECOND_TIMER
2018-11-04 19:14:23 +00:00
# include "FastLED.h"
2016-12-17 22:43:07 +00:00
2018-11-16 18:59:00 +00:00
# define DEFAULT_BRIGHTNESS (uint8_t)127
2018-09-04 13:51:38 +00:00
# define DEFAULT_MODE (uint8_t)0
2018-11-16 18:59:00 +00:00
# define DEFAULT_SPEED (uint8_t)128
2020-09-07 19:01:10 +00:00
# define DEFAULT_INTENSITY (uint8_t)128
2019-03-05 09:59:15 +00:00
# define DEFAULT_COLOR (uint32_t)0xFFAA00
2022-05-08 08:50:48 +00:00
# define DEFAULT_C1 (uint8_t)128
# define DEFAULT_C2 (uint8_t)128
2022-08-12 15:58:20 +00:00
# define DEFAULT_C3 (uint8_t)16
2018-09-04 13:51:38 +00:00
2020-11-17 21:46:17 +00:00
# ifndef MIN
2020-03-26 09:18:19 +00:00
# define MIN(a,b) ((a)<(b)?(a):(b))
2020-11-17 21:46:17 +00:00
# endif
# ifndef MAX
2020-03-26 09:18:19 +00:00
# define MAX(a,b) ((a)>(b)?(a):(b))
2020-11-17 21:46:17 +00:00
# endif
2018-09-04 13:51:38 +00:00
2022-03-25 15:36:05 +00:00
//color mangling macros
# ifndef RGBW32
# define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b))))
# endif
2019-10-03 14:33:37 +00:00
/* Not used in all effects yet */
2019-10-03 23:21:18 +00:00
# define WLED_FPS 42
2021-12-25 00:30:27 +00:00
# define FRAMETIME_FIXED (1000 / WLED_FPS)
2022-07-06 11:13:54 +00:00
# define FRAMETIME strip.getFrameTime()
2019-10-03 14:33:37 +00:00
2023-12-31 17:05:21 +00:00
/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of
2018-09-04 13:51:38 +00:00
insufficient memory , decreasing MAX_NUM_SEGMENTS may help */
2019-12-31 10:11:05 +00:00
# ifdef ESP8266
2024-03-24 16:37:11 +00:00
# define MAX_NUM_SEGMENTS 16
2021-01-08 23:35:48 +00:00
/* How much data bytes all segments combined may allocate */
2022-07-30 12:20:36 +00:00
# define MAX_SEGMENT_DATA 5120
2019-12-31 10:11:05 +00:00
# else
2021-09-08 21:10:54 +00:00
# ifndef MAX_NUM_SEGMENTS
# define MAX_NUM_SEGMENTS 32
# endif
2023-03-05 21:56:14 +00:00
# if defined(ARDUINO_ARCH_ESP32S2)
2024-03-24 16:37:11 +00:00
# define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*768 // 24k by default (S2 is short on free RAM)
2023-03-05 21:56:14 +00:00
# else
2023-12-31 17:05:21 +00:00
# define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*1280 // 40k by default
2023-03-05 21:56:14 +00:00
# endif
2019-12-31 10:11:05 +00:00
# endif
2021-09-20 19:22:50 +00:00
/* How much data bytes each segment should max allocate to leave enough space for other segments,
assuming each segment uses the same amount of data . 256 for ESP8266 , 640 for ESP32 . */
2022-07-17 13:58:41 +00:00
# define FAIR_DATA_PER_SEG (MAX_SEGMENT_DATA / strip.getMaxSegments())
2021-09-20 19:22:50 +00:00
2021-12-25 00:30:27 +00:00
# define MIN_SHOW_DELAY (_frametime < 16 ? 8 : 15)
2020-02-24 18:36:25 +00:00
2019-05-21 22:23:09 +00:00
# define NUM_COLORS 3 /* number of colors per segment */
2022-07-10 20:23:25 +00:00
# define SEGMENT strip._segments[strip.getCurrSegmentId()]
2022-07-17 13:58:41 +00:00
# define SEGENV strip._segments[strip.getCurrSegmentId()]
2022-07-30 12:20:36 +00:00
//#define SEGCOLOR(x) strip._segments[strip.getCurrSegmentId()].currentColor(x, strip._segments[strip.getCurrSegmentId()].colors[x])
2022-07-12 16:10:07 +00:00
//#define SEGLEN strip._segments[strip.getCurrSegmentId()].virtualLength()
2022-07-17 13:58:41 +00:00
# define SEGCOLOR(x) strip.segColor(x) /* saves us a few kbytes of code */
2024-05-15 13:34:53 +00:00
# define SEGPALETTE Segment::getCurrentPalette()
2022-07-17 13:58:41 +00:00
# define SEGLEN strip._virtualSegmentLength /* saves us a few kbytes of code */
2022-07-06 18:41:12 +00:00
# define SPEED_FORMULA_L (5U + (50U*(255U - SEGMENT.speed)) / SEGLEN)
2016-12-17 22:43:07 +00:00
2018-09-04 13:51:38 +00:00
// some common colors
# define RED (uint32_t)0xFF0000
# define GREEN (uint32_t)0x00FF00
# define BLUE (uint32_t)0x0000FF
# define WHITE (uint32_t)0xFFFFFF
# define BLACK (uint32_t)0x000000
# define YELLOW (uint32_t)0xFFFF00
# define CYAN (uint32_t)0x00FFFF
# define MAGENTA (uint32_t)0xFF00FF
# define PURPLE (uint32_t)0x400080
# define ORANGE (uint32_t)0xFF3000
# define PINK (uint32_t)0xFF1493
2024-05-09 22:02:28 +00:00
# define GREY (uint32_t)0x808080
# define GRAY GREY
# define DARKGREY (uint32_t)0x333333
# define DARKGRAY DARKGREY
2018-09-04 13:51:38 +00:00
# define ULTRAWHITE (uint32_t)0xFFFFFFFF
2022-08-02 16:27:32 +00:00
# define DARKSLATEGRAY (uint32_t)0x2F4F4F
2023-09-10 16:52:14 +00:00
# define DARKSLATEGREY DARKSLATEGRAY
// segment options
2022-07-06 11:13:54 +00:00
# define NO_OPTIONS (uint16_t)0x0000
2023-09-10 16:52:14 +00:00
# define TRANSPOSED (uint16_t)0x0100 // rotated 90deg & reversed
# define MIRROR_Y_2D (uint16_t)0x0080
# define REVERSE_Y_2D (uint16_t)0x0040
# define RESET_REQ (uint16_t)0x0020
# define FROZEN (uint16_t)0x0010
2022-07-06 11:13:54 +00:00
# define MIRROR (uint16_t)0x0008
# define SEGMENT_ON (uint16_t)0x0004
# define REVERSE (uint16_t)0x0002
# define SELECTED (uint16_t)0x0001
2016-12-17 22:43:07 +00:00
# define FX_MODE_STATIC 0
# define FX_MODE_BLINK 1
# define FX_MODE_BREATH 2
# define FX_MODE_COLOR_WIPE 3
# define FX_MODE_COLOR_WIPE_RANDOM 4
# define FX_MODE_RANDOM_COLOR 5
2018-09-04 13:51:38 +00:00
# define FX_MODE_COLOR_SWEEP 6
2018-03-31 22:08:50 +00:00
# define FX_MODE_DYNAMIC 7
2016-12-17 22:43:07 +00:00
# define FX_MODE_RAINBOW 8
# define FX_MODE_RAINBOW_CYCLE 9
# define FX_MODE_SCAN 10
# define FX_MODE_DUAL_SCAN 11
# define FX_MODE_FADE 12
# define FX_MODE_THEATER_CHASE 13
# define FX_MODE_THEATER_CHASE_RAINBOW 14
# define FX_MODE_RUNNING_LIGHTS 15
2019-02-05 20:53:39 +00:00
# define FX_MODE_SAW 16
# define FX_MODE_TWINKLE 17
2019-01-31 22:42:48 +00:00
# define FX_MODE_DISSOLVE 18
2023-01-18 21:56:49 +00:00
# define FX_MODE_DISSOLVE_RANDOM 19 // candidate for removal (use Dissolve with with check 3)
2016-12-17 22:43:07 +00:00
# define FX_MODE_SPARKLE 20
# define FX_MODE_FLASH_SPARKLE 21
# define FX_MODE_HYPER_SPARKLE 22
# define FX_MODE_STROBE 23
# define FX_MODE_STROBE_RAINBOW 24
# define FX_MODE_MULTI_STROBE 25
# define FX_MODE_BLINK_RAINBOW 26
2018-03-18 22:16:53 +00:00
# define FX_MODE_ANDROID 27
2016-12-17 22:43:07 +00:00
# define FX_MODE_CHASE_COLOR 28
# define FX_MODE_CHASE_RANDOM 29
# define FX_MODE_CHASE_RAINBOW 30
# define FX_MODE_CHASE_FLASH 31
# define FX_MODE_CHASE_FLASH_RANDOM 32
# define FX_MODE_CHASE_RAINBOW_WHITE 33
2018-01-10 22:57:58 +00:00
# define FX_MODE_COLORFUL 34
2017-12-13 23:12:02 +00:00
# define FX_MODE_TRAFFIC_LIGHT 35
2016-12-17 22:43:07 +00:00
# define FX_MODE_COLOR_SWEEP_RANDOM 36
# define FX_MODE_RUNNING_COLOR 37
2021-01-04 10:11:36 +00:00
# define FX_MODE_AURORA 38
2016-12-17 22:43:07 +00:00
# define FX_MODE_RUNNING_RANDOM 39
# define FX_MODE_LARSON_SCANNER 40
# define FX_MODE_COMET 41
# define FX_MODE_FIREWORKS 42
2019-02-11 22:49:04 +00:00
# define FX_MODE_RAIN 43
2021-12-07 10:03:41 +00:00
# define FX_MODE_TETRIX 44 //was Merry Christmas prior to 0.12.0 (use "Chase 2" with Red/Green)
2016-12-17 22:43:07 +00:00
# define FX_MODE_FIRE_FLICKER 45
2018-03-18 22:16:53 +00:00
# define FX_MODE_GRADIENT 46
# define FX_MODE_LOADING 47
2023-09-05 16:39:51 +00:00
# define FX_MODE_ROLLINGBALLS 48 //was Police before 0.14
2021-12-07 10:03:41 +00:00
# define FX_MODE_FAIRY 49 //was Police All prior to 0.13.0-b6 (use "Two Dots" with Red/Blue and full intensity)
2019-12-04 11:15:12 +00:00
# define FX_MODE_TWO_DOTS 50
2021-12-07 10:03:41 +00:00
# define FX_MODE_FAIRYTWINKLE 51 //was Two Areas prior to 0.13.0-b6 (use "Two Dots" with full intensity)
2021-04-10 22:50:14 +00:00
# define FX_MODE_RUNNING_DUAL 52
2022-11-14 01:29:59 +00:00
// #define FX_MODE_HALLOWEEN 53 // removed in 0.14!
2018-09-04 13:51:38 +00:00
# define FX_MODE_TRICOLOR_CHASE 54
# define FX_MODE_TRICOLOR_WIPE 55
# define FX_MODE_TRICOLOR_FADE 56
# define FX_MODE_LIGHTNING 57
# define FX_MODE_ICU 58
# define FX_MODE_MULTI_COMET 59
2024-02-17 11:58:04 +00:00
# define FX_MODE_DUAL_LARSON_SCANNER 60 // candidate for removal (use Scanner with with check 1)
2018-09-04 13:51:38 +00:00
# define FX_MODE_RANDOM_CHASE 61
# define FX_MODE_OSCILLATE 62
2018-09-10 22:20:12 +00:00
# define FX_MODE_PRIDE_2015 63
# define FX_MODE_JUGGLE 64
# define FX_MODE_PALETTE 65
# define FX_MODE_FIRE_2012 66
2018-09-08 14:21:44 +00:00
# define FX_MODE_COLORWAVES 67
# define FX_MODE_BPM 68
# define FX_MODE_FILLNOISE8 69
# define FX_MODE_NOISE16_1 70
# define FX_MODE_NOISE16_2 71
# define FX_MODE_NOISE16_3 72
# define FX_MODE_NOISE16_4 73
2018-11-04 19:14:23 +00:00
# define FX_MODE_COLORTWINKLE 74
2018-11-07 19:22:05 +00:00
# define FX_MODE_LAKE 75
2018-11-20 20:31:07 +00:00
# define FX_MODE_METEOR 76
2018-12-02 01:49:05 +00:00
# define FX_MODE_METEOR_SMOOTH 77
# define FX_MODE_RAILWAY 78
2019-01-31 22:42:48 +00:00
# define FX_MODE_RIPPLE 79
2019-08-30 13:39:34 +00:00
# define FX_MODE_TWINKLEFOX 80
2019-10-01 23:17:26 +00:00
# define FX_MODE_TWINKLECAT 81
# define FX_MODE_HALLOWEEN_EYES 82
2019-11-18 11:29:36 +00:00
# define FX_MODE_STATIC_PATTERN 83
2019-11-29 17:53:01 +00:00
# define FX_MODE_TRI_STATIC_PATTERN 84
2019-12-04 11:15:12 +00:00
# define FX_MODE_SPOTS 85
# define FX_MODE_SPOTS_FADE 86
2019-12-06 00:44:45 +00:00
# define FX_MODE_GLITTER 87
# define FX_MODE_CANDLE 88
2019-12-28 14:43:55 +00:00
# define FX_MODE_STARBURST 89
2020-01-03 11:58:31 +00:00
# define FX_MODE_EXPLODING_FIREWORKS 90
2020-01-03 22:19:40 +00:00
# define FX_MODE_BOUNCINGBALLS 91
# define FX_MODE_SINELON 92
# define FX_MODE_SINELON_DUAL 93
# define FX_MODE_SINELON_RAINBOW 94
# define FX_MODE_POPCORN 95
2020-01-12 14:04:49 +00:00
# define FX_MODE_DRIP 96
2020-01-18 23:06:17 +00:00
# define FX_MODE_PLASMA 97
2020-01-19 12:51:49 +00:00
# define FX_MODE_PERCENT 98
2020-02-15 19:07:15 +00:00
# define FX_MODE_RIPPLE_RAINBOW 99
2020-02-17 10:01:05 +00:00
# define FX_MODE_HEARTBEAT 100
2020-03-25 10:17:45 +00:00
# define FX_MODE_PACIFICA 101
2020-04-21 22:51:00 +00:00
# define FX_MODE_CANDLE_MULTI 102
2023-01-18 21:56:49 +00:00
# define FX_MODE_SOLID_GLITTER 103 // candidate for removal (use glitter)
2020-06-05 22:57:34 +00:00
# define FX_MODE_SUNRISE 104
# define FX_MODE_PHASED 105
# define FX_MODE_TWINKLEUP 106
# define FX_MODE_NOISEPAL 107
# define FX_MODE_SINEWAVE 108
# define FX_MODE_PHASEDNOISE 109
# define FX_MODE_FLOW 110
2020-06-22 10:30:31 +00:00
# define FX_MODE_CHUNCHUN 111
2020-08-22 18:54:59 +00:00
# define FX_MODE_DANCING_SHADOWS 112
2020-09-26 23:58:21 +00:00
# define FX_MODE_WASHING_MACHINE 113
2024-01-28 14:09:40 +00:00
# define FX_MODE_2DPLASMAROTOZOOM 114 // was Candy Cane prior to 0.14 (use Chase 2)
2020-12-15 12:35:50 +00:00
# define FX_MODE_BLENDS 115
2020-12-22 12:15:57 +00:00
# define FX_MODE_TV_SIMULATOR 116
2023-01-18 21:56:49 +00:00
# define FX_MODE_DYNAMIC_SMOOTH 117 // candidate for removal (check3 in dynamic)
2022-06-21 20:49:45 +00:00
2022-11-14 01:29:59 +00:00
// new 0.14 2D effects
# define FX_MODE_2DSPACESHIPS 118 //gap fill
# define FX_MODE_2DCRAZYBEES 119 //gap fill
# define FX_MODE_2DGHOSTRIDER 120 //gap fill
# define FX_MODE_2DBLOBS 121 //gap fill
# define FX_MODE_2DSCROLLTEXT 122 //gap fill
# define FX_MODE_2DDRIFTROSE 123 //gap fill
2023-04-27 15:31:55 +00:00
# define FX_MODE_2DDISTORTIONWAVES 124 //gap fill
# define FX_MODE_2DSOAP 125 //gap fill
2023-04-28 20:00:35 +00:00
# define FX_MODE_2DOCTOPUS 126 //gap fill
2023-04-29 15:04:16 +00:00
# define FX_MODE_2DWAVINGCELL 127 //gap fill
2022-11-14 01:29:59 +00:00
// WLED-SR effects (SR compatible IDs !!!)
# define FX_MODE_PIXELS 128
# define FX_MODE_PIXELWAVE 129
# define FX_MODE_JUGGLES 130
# define FX_MODE_MATRIPIX 131
# define FX_MODE_GRAVIMETER 132
# define FX_MODE_PLASMOID 133
# define FX_MODE_PUDDLES 134
# define FX_MODE_MIDNOISE 135
# define FX_MODE_NOISEMETER 136
# 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
# define FX_MODE_PUDDLEPEAK 144
# define FX_MODE_NOISEMOVE 145
# define FX_MODE_2DNOISE 146
# define FX_MODE_PERLINMOVE 147
# define FX_MODE_RIPPLEPEAK 148
# define FX_MODE_2DFIRENOISE 149
# define FX_MODE_2DSQUAREDSWIRL 150
2024-01-06 16:04:56 +00:00
// #define FX_MODE_2DFIRE2012 151
2022-11-14 01:29:59 +00:00
# define FX_MODE_2DDNA 152
# define FX_MODE_2DMATRIX 153
# define FX_MODE_2DMETABALLS 154
# define FX_MODE_FREQMAP 155
# define FX_MODE_GRAVCENTER 156
# define FX_MODE_GRAVCENTRIC 157
# define FX_MODE_GRAVFREQ 158
# define FX_MODE_DJLIGHT 159
# define FX_MODE_2DFUNKYPLANK 160
2024-01-06 16:04:56 +00:00
//#define FX_MODE_2DCENTERBARS 161
2022-11-14 01:29:59 +00:00
# define FX_MODE_2DPULSER 162
# define FX_MODE_BLURZ 163
# define FX_MODE_2DDRIFT 164
# define FX_MODE_2DWAVERLY 165
# define FX_MODE_2DSUNRADIATION 166
# define FX_MODE_2DCOLOREDBURSTS 167
# define FX_MODE_2DJULIA 168
// #define FX_MODE_2DPOOLNOISE 169 //have been removed in WLED SR in the past because of low mem but should be added back
// #define FX_MODE_2DTWISTER 170 //have been removed in WLED SR in the past because of low mem but should be added back
// #define FX_MODE_2DCAELEMENTATY 171 //have been removed in WLED SR in the past because of low mem but should be added back
# define FX_MODE_2DGAMEOFLIFE 172
# define FX_MODE_2DTARTAN 173
# define FX_MODE_2DPOLARLIGHTS 174
# define FX_MODE_2DSWIRL 175
# define FX_MODE_2DLISSAJOUS 176
# define FX_MODE_2DFRIZZLES 177
# define FX_MODE_2DPLASMABALL 178
# define FX_MODE_FLOWSTRIPE 179
# define FX_MODE_2DHIPHOTIC 180
# define FX_MODE_2DSINDOTS 181
# define FX_MODE_2DDNASPIRAL 182
# define FX_MODE_2DBLACKHOLE 183
# define FX_MODE_WAVESINS 184
# define FX_MODE_ROCKTAVES 185
# define FX_MODE_2DAKEMI 186
# define MODE_COUNT 187
2018-01-09 22:13:29 +00:00
2022-07-14 11:22:34 +00:00
typedef enum mapping1D2D {
M12_Pixels = 0 ,
2022-08-25 19:57:43 +00:00
M12_pBar = 1 ,
M12_pArc = 2 ,
2024-05-07 22:04:29 +00:00
M12_pCorner = 3 ,
M12_sPinwheel = 4
2022-07-14 11:22:34 +00:00
} mapping1D2D_t ;
2023-07-12 18:52:34 +00:00
// segment, 80 bytes
2022-07-17 13:58:41 +00:00
typedef struct Segment {
public :
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 ;
uint8_t speed ;
uint8_t intensity ;
uint8_t palette ;
uint8_t mode ;
union {
uint16_t options ; //bit pattern: msb first: [transposed mirrorY reverseY] transitional (tbd) paused needspixelstate mirrored on reverse selected
struct {
2022-08-31 12:24:02 +00:00
bool selected : 1 ; // 0 : selected
bool reverse : 1 ; // 1 : reversed
bool on : 1 ; // 2 : is On
bool mirror : 1 ; // 3 : mirrored
bool freeze : 1 ; // 4 : paused/frozen
bool reset : 1 ; // 5 : indicates that Segment runtime requires reset
2023-09-10 16:52:14 +00:00
bool reverse_y : 1 ; // 6 : reversed Y (2D)
bool mirror_y : 1 ; // 7 : mirrored Y (2D)
bool transpose : 1 ; // 8 : transposed (2D, swapped X & Y)
uint8_t map1D2D : 3 ; // 9-11 : mapping for 1D effect on 2D (0-use as strip, 1-expand vertically, 2-circular/arc, 3-rectangular/corner, ...)
uint8_t soundSim : 2 ; // 12-13 : 0-3 sound simulation types ("soft" & "hard" or "on"/"off")
2023-05-15 15:06:29 +00:00
uint8_t set : 2 ; // 14-15 : 0-3 UI segment sets/groups
2022-07-17 13:58:41 +00:00
} ;
} ;
uint8_t grouping , spacing ;
uint8_t opacity ;
uint32_t colors [ NUM_COLORS ] ;
2022-08-19 19:14:49 +00:00
uint8_t cct ; //0==1900K, 255==10091K
uint8_t custom1 , custom2 ; // custom FX parameters/sliders
2022-08-12 15:58:20 +00:00
struct {
2022-08-19 19:14:49 +00:00
uint8_t custom3 : 5 ; // reduced range slider (0-31)
bool check1 : 1 ; // checkmark 1
bool check2 : 1 ; // checkmark 2
bool check3 : 1 ; // checkmark 3
2022-08-12 15:58:20 +00:00
} ;
2022-08-19 19:14:49 +00:00
uint8_t startY ; // start Y coodrinate 2D (top); there should be no more than 255 rows
uint8_t stopY ; // stop Y coordinate 2D (bottom); there should be no more than 255 rows
2023-07-12 18:52:34 +00:00
char * name ;
2022-07-17 13:58:41 +00:00
// runtime data
unsigned long next_time ; // millis() of next update
uint32_t step ; // custom "step" var
uint32_t call ; // call counter
uint16_t aux0 ; // custom var
uint16_t aux1 ; // custom var
2023-07-12 18:52:34 +00:00
byte * data ; // effect data pointer
2022-12-16 21:31:07 +00:00
static uint16_t maxWidth , maxHeight ; // these define matrix width & height (max. segment dimensions)
2022-07-17 13:58:41 +00:00
2023-08-05 11:50:08 +00:00
typedef struct TemporarySegmentData {
2023-08-05 15:35:14 +00:00
uint16_t _optionsT ;
2023-08-05 11:50:08 +00:00
uint32_t _colorT [ NUM_COLORS ] ;
uint8_t _speedT ;
uint8_t _intensityT ;
uint8_t _custom1T , _custom2T ; // custom FX parameters/sliders
struct {
uint8_t _custom3T : 5 ; // reduced range slider (0-31)
bool _check1T : 1 ; // checkmark 1
bool _check2T : 1 ; // checkmark 2
bool _check3T : 1 ; // checkmark 3
} ;
uint16_t _aux0T ;
uint16_t _aux1T ;
2023-09-08 14:01:11 +00:00
uint32_t _stepT ;
uint32_t _callT ;
uint8_t * _dataT ;
uint16_t _dataLenT ;
TemporarySegmentData ( )
: _dataT ( nullptr ) // just in case...
, _dataLenT ( 0 )
{ }
2023-08-05 11:50:08 +00:00
} tmpsegd_t ;
2022-07-12 16:10:07 +00:00
private :
2022-07-28 21:19:58 +00:00
union {
uint8_t _capabilities ;
struct {
bool _isRGB : 1 ;
bool _hasW : 1 ;
bool _isCCT : 1 ;
bool _manualW : 1 ;
uint8_t _reserved : 4 ;
} ;
} ;
2023-07-12 18:52:34 +00:00
uint16_t _dataLen ;
2022-07-30 12:20:36 +00:00
static uint16_t _usedSegmentData ;
2022-07-17 13:58:41 +00:00
2023-08-03 20:28:53 +00:00
// perhaps this should be per segment, not static
2024-05-15 13:34:53 +00:00
static CRGBPalette16 _currentPalette ; // palette used for current effect (includes transition, used in color_from_palette())
2023-08-05 19:01:06 +00:00
static CRGBPalette16 _randomPalette ; // actual random palette
static CRGBPalette16 _newRandomPalette ; // target random palette
2024-02-06 10:06:23 +00:00
static uint16_t _lastPaletteChange ; // last random palette change time in millis()/1000
static uint16_t _lastPaletteBlend ; // blend palette according to set Transition Delay in millis()%0xFFFF
2023-09-02 18:20:51 +00:00
# ifndef WLED_DISABLE_MODE_BLEND
2023-08-05 19:01:06 +00:00
static bool _modeBlend ; // mode/effect blending semaphore
2023-09-02 18:20:51 +00:00
# endif
2023-08-03 20:28:53 +00:00
2023-07-12 18:52:34 +00:00
// transition data, valid only if transitional==true, holds values during transition (72 bytes)
2022-07-30 12:50:11 +00:00
struct Transition {
2023-09-02 18:20:51 +00:00
# ifndef WLED_DISABLE_MODE_BLEND
2023-08-12 10:45:11 +00:00
tmpsegd_t _segT ; // previous segment environment
2023-09-02 18:20:51 +00:00
uint8_t _modeT ; // previous mode/effect
# else
uint32_t _colorT [ NUM_COLORS ] ;
# endif
2022-08-31 12:24:02 +00:00
uint8_t _briT ; // temporary brightness
uint8_t _cctT ; // temporary CCT
CRGBPalette16 _palT ; // temporary palette
2024-02-06 13:47:20 +00:00
uint8_t _prevPaletteBlends ; // number of previous palette blends (there are max 255 blends possible)
2023-08-05 11:50:08 +00:00
unsigned long _start ; // must accommodate millis()
2022-07-28 21:19:58 +00:00
uint16_t _dur ;
2022-09-06 19:47:50 +00:00
Transition ( uint16_t dur = 750 )
2023-08-05 11:50:08 +00:00
: _palT ( CRGBPalette16 ( CRGB : : Black ) )
2022-09-06 19:47:50 +00:00
, _prevPaletteBlends ( 0 )
, _start ( millis ( ) )
, _dur ( dur )
{ }
2022-08-31 12:24:02 +00:00
} * _t ;
2022-07-17 13:58:41 +00:00
public :
2022-07-19 14:16:43 +00:00
Segment ( uint16_t sStart = 0 , uint16_t sStop = 30 ) :
start ( sStart ) ,
stop ( sStop ) ,
offset ( 0 ) ,
speed ( DEFAULT_SPEED ) ,
intensity ( DEFAULT_INTENSITY ) ,
palette ( 0 ) ,
mode ( DEFAULT_MODE ) ,
options ( SELECTED | SEGMENT_ON ) ,
grouping ( 1 ) ,
spacing ( 0 ) ,
opacity ( 255 ) ,
colors { DEFAULT_COLOR , BLACK , BLACK } ,
cct ( 127 ) ,
custom1 ( DEFAULT_C1 ) ,
custom2 ( DEFAULT_C2 ) ,
custom3 ( DEFAULT_C3 ) ,
2022-08-12 15:58:20 +00:00
check1 ( false ) ,
check2 ( false ) ,
check3 ( false ) ,
2022-07-19 14:16:43 +00:00
startY ( 0 ) ,
stopY ( 1 ) ,
name ( nullptr ) ,
next_time ( 0 ) ,
step ( 0 ) ,
call ( 0 ) ,
aux0 ( 0 ) ,
aux1 ( 0 ) ,
data ( nullptr ) ,
_capabilities ( 0 ) ,
2022-07-30 12:50:11 +00:00
_dataLen ( 0 ) ,
_t ( nullptr )
2022-07-19 20:14:46 +00:00
{
2023-08-08 18:40:19 +00:00
# ifdef WLED_DEBUG
//Serial.printf("-- Creating segment: %p\n", this);
# endif
2022-07-19 20:14:46 +00:00
}
2022-07-19 14:16:43 +00:00
Segment ( uint16_t sStartX , uint16_t sStopX , uint16_t sStartY , uint16_t sStopY ) : Segment ( sStartX , sStopX ) {
2022-07-17 13:58:41 +00:00
startY = sStartY ;
stopY = sStopY ;
}
Segment ( const Segment & orig ) ; // copy constructor
Segment ( Segment & & orig ) noexcept ; // move constructor
2022-07-06 11:13:54 +00:00
2022-07-17 13:58:41 +00:00
~ Segment ( ) {
2023-08-07 14:50:18 +00:00
# ifdef WLED_DEBUG
2023-12-01 23:48:49 +00:00
//Serial.printf("-- Destroying segment: %p", this);
2022-11-09 19:09:01 +00:00
//if (name) Serial.printf(" %s (%p)", name, name);
2023-12-01 23:48:49 +00:00
//if (data) Serial.printf(" %d->(%p)", (int)_dataLen, data);
2022-11-09 19:09:01 +00:00
//Serial.println();
2023-08-07 14:50:18 +00:00
# endif
2023-07-12 18:52:34 +00:00
if ( name ) { delete [ ] name ; name = nullptr ; }
2023-08-07 14:50:18 +00:00
stopTransition ( ) ;
2022-07-17 13:58:41 +00:00
deallocateData ( ) ;
}
Segment & operator = ( const Segment & orig ) ; // copy assignment
Segment & operator = ( Segment & & orig ) noexcept ; // move assignment
2022-08-03 19:36:47 +00:00
# ifdef WLED_DEBUG
2023-07-12 18:52:34 +00:00
size_t getSize ( ) const { return sizeof ( Segment ) + ( data ? _dataLen : 0 ) + ( name ? strlen ( name ) : 0 ) + ( _t ? sizeof ( Transition ) : 0 ) ; }
2022-08-03 19:36:47 +00:00
# endif
2022-08-17 18:45:30 +00:00
inline bool getOption ( uint8_t n ) const { return ( ( options > > n ) & 0x01 ) ; }
2024-09-11 15:14:59 +00:00
inline bool isSelected ( ) const { return selected ; }
inline bool isInTransition ( ) const { return _t ! = nullptr ; }
inline bool isActive ( ) const { return stop > start ; }
inline bool is2D ( ) const { return ( width ( ) > 1 & & height ( ) > 1 ) ; }
inline bool hasRGB ( ) const { return _isRGB ; }
inline bool hasWhite ( ) const { return _hasW ; }
inline bool isCCT ( ) const { return _isCCT ; }
inline uint16_t width ( ) const { return isActive ( ) ? ( stop - start ) : 0 ; } // segment width in physical pixels (length if 1D)
inline uint16_t height ( ) const { return stopY - startY ; } // segment height (if 2D) in physical pixels (it *is* always >=1)
inline uint16_t length ( ) const { return width ( ) * height ( ) ; } // segment length (count) in physical pixels
inline uint16_t groupLength ( ) const { return grouping + spacing ; }
inline uint8_t getLightCapabilities ( ) const { return _capabilities ; }
inline static uint16_t getUsedSegmentData ( ) { return _usedSegmentData ; }
inline static void addUsedSegmentData ( int len ) { _usedSegmentData + = len ; }
2023-09-02 18:20:51 +00:00
# ifndef WLED_DISABLE_MODE_BLEND
2024-09-11 15:14:59 +00:00
inline static void modeBlend ( bool blend ) { _modeBlend = blend ; }
2023-09-02 18:20:51 +00:00
# endif
2023-08-03 20:28:53 +00:00
static void handleRandomPalette ( ) ;
2024-09-11 15:14:59 +00:00
inline static const CRGBPalette16 & getCurrentPalette ( ) { return Segment : : _currentPalette ; }
2022-07-30 12:20:36 +00:00
2023-12-22 14:39:07 +00:00
void setUp ( uint16_t i1 , uint16_t i2 , uint8_t grp = 1 , uint8_t spc = 0 , uint16_t ofs = UINT16_MAX , uint16_t i1Y = 0 , uint16_t i2Y = 1 ) ;
2022-07-30 12:20:36 +00:00
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 ) ;
2022-09-29 10:49:12 +00:00
void setMode ( uint8_t fx , bool loadDefaults = false ) ;
void setPalette ( uint8_t pal ) ;
2022-08-17 18:45:30 +00:00
uint8_t differs ( Segment & b ) const ;
2024-09-11 15:14:59 +00:00
void refreshLightCapabilities ( ) ;
2022-07-17 13:58:41 +00:00
// runtime data functions
2024-09-11 15:14:59 +00:00
inline uint16_t dataSize ( ) const { return _dataLen ; }
2023-12-27 18:36:25 +00:00
bool allocateData ( size_t len ) ; // allocates effect data buffer in heap and clears it
2024-09-11 15:14:59 +00:00
void deallocateData ( ) ; // deallocates (frees) effect data buffer from heap
void resetIfRequired ( ) ; // sets all SEGENV variables to 0 and clears data buffer
2023-01-06 08:10:39 +00:00
/**
2022-07-17 13:58:41 +00:00
* Flags that before the next effect is calculated ,
2023-01-06 08:10:39 +00:00
* the internal segment state should be reset .
2022-07-17 13:58:41 +00:00
* Call resetIfRequired before calling the next effect function .
* Safe to call from interrupts and network requests .
*/
2024-09-11 15:14:59 +00:00
inline void markForReset ( ) { reset = true ; } // setOption(SEG_OPTION_RESET, true)
2022-07-17 13:58:41 +00:00
// transition functions
2024-01-04 16:40:23 +00:00
void startTransition ( uint16_t dur ) ; // transition has to start before actual segment values change
2024-09-11 15:14:59 +00:00
void stopTransition ( ) ; // ends transition mode by destroying transition structure (does nothing if not in transition)
inline void handleTransition ( ) { if ( progress ( ) = = 0xFFFFU ) stopTransition ( ) ; }
2023-09-02 18:20:51 +00:00
# ifndef WLED_DISABLE_MODE_BLEND
2023-12-27 18:36:25 +00:00
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
2023-09-02 18:20:51 +00:00
# endif
2024-09-11 15:14:59 +00:00
[ [ gnu : : hot ] ] uint16_t progress ( ) const ; // transition progression between 0-65535
[ [ gnu : : hot ] ] uint8_t currentBri ( bool useCct = false ) const ; // current segment brightness/CCT (blended while in transition)
uint8_t currentMode ( ) const ; // currently active effect/mode (while in transition)
[ [ gnu : : hot ] ] uint32_t currentColor ( uint8_t slot ) const ; // currently active segment color (blended while in transition)
2024-09-12 13:22:37 +00:00
CRGBPalette16 & loadPalette ( CRGBPalette16 & tgt , uint8_t pal ) ;
2024-09-11 15:14:59 +00:00
void setCurrentPalette ( ) ;
2022-07-17 13:58:41 +00:00
// 1D strip
2024-09-11 15:14:59 +00:00
[ [ gnu : : hot ] ] uint16_t virtualLength ( ) const ;
[ [ gnu : : hot ] ] void setPixelColor ( int n , uint32_t c ) ; // set relative pixel within segment with color
2023-10-15 11:06:40 +00:00
inline void setPixelColor ( unsigned n , uint32_t c ) { setPixelColor ( int ( n ) , c ) ; }
inline void setPixelColor ( int n , byte r , byte g , byte b , byte w = 0 ) { setPixelColor ( n , RGBW32 ( r , g , b , w ) ) ; }
inline void setPixelColor ( int n , CRGB c ) { setPixelColor ( n , RGBW32 ( c . r , c . g , c . b , 0 ) ) ; }
2024-04-13 16:25:25 +00:00
# ifdef WLED_USE_AA_PIXELS
2022-07-17 13:58:41 +00:00
void setPixelColor ( float i , uint32_t c , bool aa = true ) ;
2023-10-15 11:06:40 +00:00
inline void setPixelColor ( float i , uint8_t r , uint8_t g , uint8_t b , uint8_t w = 0 , bool aa = true ) { setPixelColor ( i , RGBW32 ( r , g , b , w ) , aa ) ; }
inline void setPixelColor ( float i , CRGB c , bool aa = true ) { setPixelColor ( i , RGBW32 ( c . r , c . g , c . b , 0 ) , aa ) ; }
2024-04-13 16:25:25 +00:00
# endif
2024-09-11 15:14:59 +00:00
[ [ gnu : : hot ] ] uint32_t getPixelColor ( int i ) const ;
2022-07-17 13:58:41 +00:00
// 1D support functions (some implement 2D as well)
2024-04-15 19:20:45 +00:00
void blur ( uint8_t , bool smear = false ) ;
2022-07-17 13:58:41 +00:00
void fill ( uint32_t c ) ;
void fade_out ( uint8_t r ) ;
void fadeToBlackBy ( uint8_t fadeBy ) ;
2023-10-15 11:06:40 +00:00
inline void blendPixelColor ( int n , uint32_t color , uint8_t blend ) { setPixelColor ( n , color_blend ( getPixelColor ( n ) , color , blend ) ) ; }
inline void blendPixelColor ( int n , CRGB c , uint8_t blend ) { blendPixelColor ( n , RGBW32 ( c . r , c . g , c . b , 0 ) , blend ) ; }
inline void addPixelColor ( int n , uint32_t color , bool fast = false ) { setPixelColor ( n , color_add ( getPixelColor ( n ) , color , fast ) ) ; }
inline void addPixelColor ( int n , byte r , byte g , byte b , byte w = 0 , bool fast = false ) { addPixelColor ( n , RGBW32 ( r , g , b , w ) , fast ) ; }
inline void addPixelColor ( int n , CRGB c , bool fast = false ) { addPixelColor ( n , RGBW32 ( c . r , c . g , c . b , 0 ) , fast ) ; }
inline void fadePixelColor ( uint16_t n , uint8_t fade ) { setPixelColor ( n , color_fade ( getPixelColor ( n ) , fade , true ) ) ; }
2024-09-11 15:14:59 +00:00
[ [ gnu : : hot ] ] uint32_t color_from_palette ( uint16_t , bool mapping , bool wrap , uint8_t mcol , uint8_t pbri = 255 ) const ;
[ [ gnu : : hot ] ] uint32_t color_wheel ( uint8_t pos ) const ;
2022-07-17 13:58:41 +00:00
2024-08-09 10:53:41 +00:00
// 2D Blur: shortcuts for bluring columns or rows only (50% faster than full 2D blur)
inline void blurCols ( fract8 blur_amount , bool smear = false ) { // blur all columns
const unsigned cols = virtualWidth ( ) ;
for ( unsigned k = 0 ; k < cols ; k + + ) blurCol ( k , blur_amount , smear ) ;
}
inline void blurRows ( fract8 blur_amount , bool smear = false ) { // blur all rows
const unsigned rows = virtualHeight ( ) ;
for ( unsigned i = 0 ; i < rows ; i + + ) blurRow ( i , blur_amount , smear ) ;
}
2022-07-17 13:58:41 +00:00
// 2D matrix
2024-09-11 15:14:59 +00:00
[ [ gnu : : hot ] ] uint16_t virtualWidth ( ) const ; // segment width in virtual pixels (accounts for groupping and spacing)
[ [ gnu : : hot ] ] uint16_t virtualHeight ( ) const ; // segment height in virtual pixels (accounts for groupping and spacing)
2024-09-12 13:22:37 +00:00
uint16_t nrOfVStrips ( ) const ; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
2022-08-03 12:23:24 +00:00
# ifndef WLED_DISABLE_2D
2024-09-11 15:14:59 +00:00
[ [ gnu : : hot ] ] uint16_t XY ( int x , int y ) ; // support function to get relative index within segment
[ [ gnu : : hot ] ] void setPixelColorXY ( int x , int y , uint32_t c ) ; // set relative pixel within segment with color
2023-10-15 11:06:40 +00:00
inline void setPixelColorXY ( unsigned x , unsigned y , uint32_t c ) { setPixelColorXY ( int ( x ) , int ( y ) , c ) ; }
inline void setPixelColorXY ( int x , int y , byte r , byte g , byte b , byte w = 0 ) { setPixelColorXY ( x , y , RGBW32 ( r , g , b , w ) ) ; }
inline void setPixelColorXY ( int x , int y , CRGB c ) { setPixelColorXY ( x , y , RGBW32 ( c . r , c . g , c . b , 0 ) ) ; }
2024-05-09 22:02:28 +00:00
inline void setPixelColorXY ( unsigned x , unsigned y , CRGB c ) { setPixelColorXY ( int ( x ) , int ( y ) , RGBW32 ( c . r , c . g , c . b , 0 ) ) ; }
2024-04-13 16:25:25 +00:00
# ifdef WLED_USE_AA_PIXELS
2022-07-17 13:58:41 +00:00
void setPixelColorXY ( float x , float y , uint32_t c , bool aa = true ) ;
2023-10-15 11:06:40 +00:00
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 ) ; }
2024-04-13 16:25:25 +00:00
# endif
2024-09-11 15:14:59 +00:00
[ [ gnu : : hot ] ] uint32_t getPixelColorXY ( int x , int y ) const ;
2022-07-17 13:58:41 +00:00
// 2D support functions
2023-10-15 11:06:40 +00:00
inline void blendPixelColorXY ( uint16_t x , uint16_t y , uint32_t color , uint8_t blend ) { setPixelColorXY ( x , y , color_blend ( getPixelColorXY ( x , y ) , color , blend ) ) ; }
inline void blendPixelColorXY ( uint16_t x , uint16_t y , CRGB c , uint8_t blend ) { blendPixelColorXY ( x , y , RGBW32 ( c . r , c . g , c . b , 0 ) , blend ) ; }
inline void addPixelColorXY ( int x , int y , uint32_t color , bool fast = false ) { setPixelColorXY ( x , y , color_add ( getPixelColorXY ( x , y ) , color , fast ) ) ; }
inline void addPixelColorXY ( int x , int y , byte r , byte g , byte b , byte w = 0 , bool fast = false ) { addPixelColorXY ( x , y , RGBW32 ( r , g , b , w ) , fast ) ; }
inline void addPixelColorXY ( int x , int y , CRGB c , bool fast = false ) { addPixelColorXY ( x , y , RGBW32 ( c . r , c . g , c . b , 0 ) , fast ) ; }
inline void fadePixelColorXY ( uint16_t x , uint16_t y , uint8_t fade ) { setPixelColorXY ( x , y , color_fade ( getPixelColorXY ( x , y ) , fade , true ) ) ; }
2024-08-14 20:15:48 +00:00
void box_blur ( unsigned r = 1U , bool smear = false ) ; // 2D box blur
void blur2D ( uint8_t blur_amount , bool smear = false ) ;
2024-04-15 19:20:45 +00:00
void blurRow ( uint32_t row , fract8 blur_amount , bool smear = false ) ;
void blurCol ( uint32_t col , fract8 blur_amount , bool smear = false ) ;
2023-04-27 15:31:55 +00:00
void moveX ( int8_t delta , bool wrap = false ) ;
void moveY ( int8_t delta , bool wrap = false ) ;
void move ( uint8_t dir , uint8_t delta , bool wrap = false ) ;
2024-05-09 22:02:28 +00:00
void drawCircle ( uint16_t cx , uint16_t cy , uint8_t radius , uint32_t c , bool soft = false ) ;
inline void drawCircle ( uint16_t cx , uint16_t cy , uint8_t radius , CRGB c , bool soft = false ) { drawCircle ( cx , cy , radius , RGBW32 ( c . r , c . g , c . b , 0 ) , soft ) ; }
void fillCircle ( uint16_t cx , uint16_t cy , uint8_t radius , uint32_t c , bool soft = false ) ;
inline void fillCircle ( uint16_t cx , uint16_t cy , uint8_t radius , CRGB c , bool soft = false ) { fillCircle ( cx , cy , radius , RGBW32 ( c . r , c . g , c . b , 0 ) , soft ) ; }
void drawLine ( uint16_t x0 , uint16_t y0 , uint16_t x1 , uint16_t y1 , uint32_t c , bool soft = false ) ;
inline void drawLine ( uint16_t x0 , uint16_t y0 , uint16_t x1 , uint16_t y1 , CRGB c , bool soft = false ) { drawLine ( x0 , y0 , x1 , y1 , RGBW32 ( c . r , c . g , c . b , 0 ) , soft ) ; } // automatic inline
2023-09-24 14:48:59 +00:00
void drawCharacter ( unsigned char chr , int16_t x , int16_t y , uint8_t w , uint8_t h , uint32_t color , uint32_t col2 = 0 , int8_t rotate = 0 ) ;
2023-10-15 11:06:40 +00:00
inline void drawCharacter ( unsigned char chr , int16_t x , int16_t y , uint8_t w , uint8_t h , CRGB c ) { drawCharacter ( chr , x , y , w , h , RGBW32 ( c . r , c . g , c . b , 0 ) ) ; } // automatic inline
inline void drawCharacter ( unsigned char chr , int16_t x , int16_t y , uint8_t w , uint8_t h , CRGB c , CRGB c2 , int8_t rotate = 0 ) { drawCharacter ( chr , x , y , w , h , RGBW32 ( c . r , c . g , c . b , 0 ) , RGBW32 ( c2 . r , c2 . g , c2 . b , 0 ) , rotate ) ; } // automatic inline
2022-08-03 12:23:24 +00:00
void wu_pixel ( uint32_t x , uint32_t y , CRGB c ) ;
2023-10-15 11:06:40 +00:00
inline void blur2d ( fract8 blur_amount ) { blur ( blur_amount ) ; }
inline void fill_solid ( CRGB c ) { fill ( RGBW32 ( c . r , c . g , c . b , 0 ) ) ; }
2022-08-03 12:23:24 +00:00
# else
2023-10-15 11:06:40 +00:00
inline uint16_t XY ( uint16_t x , uint16_t y ) { return x ; }
inline void setPixelColorXY ( int x , int y , uint32_t c ) { setPixelColor ( x , c ) ; }
2024-04-11 18:11:29 +00:00
inline void setPixelColorXY ( unsigned x , unsigned y , uint32_t c ) { setPixelColor ( int ( x ) , c ) ; }
2023-10-15 11:06:40 +00:00
inline void setPixelColorXY ( int x , int y , byte r , byte g , byte b , byte w = 0 ) { setPixelColor ( x , RGBW32 ( r , g , b , w ) ) ; }
inline void setPixelColorXY ( int x , int y , CRGB c ) { setPixelColor ( x , RGBW32 ( c . r , c . g , c . b , 0 ) ) ; }
2024-05-09 22:02:28 +00:00
inline void setPixelColorXY ( unsigned x , unsigned y , CRGB c ) { setPixelColor ( int ( x ) , RGBW32 ( c . r , c . g , c . b , 0 ) ) ; }
2024-04-13 16:25:25 +00:00
# ifdef WLED_USE_AA_PIXELS
2023-10-15 11:06:40 +00:00
inline void setPixelColorXY ( float x , float y , uint32_t c , bool aa = true ) { setPixelColor ( x , c , aa ) ; }
inline void setPixelColorXY ( float x , float y , byte r , byte g , byte b , byte w = 0 , bool aa = true ) { setPixelColor ( x , RGBW32 ( r , g , b , w ) , aa ) ; }
inline void setPixelColorXY ( float x , float y , CRGB c , bool aa = true ) { setPixelColor ( x , RGBW32 ( c . r , c . g , c . b , 0 ) , aa ) ; }
2024-04-13 16:25:25 +00:00
# endif
2024-08-14 20:15:48 +00:00
inline uint32_t getPixelColorXY ( int x , int y ) { return getPixelColor ( x ) ; }
2023-10-15 11:06:40 +00:00
inline void blendPixelColorXY ( uint16_t x , uint16_t y , uint32_t c , uint8_t blend ) { blendPixelColor ( x , c , blend ) ; }
inline void blendPixelColorXY ( uint16_t x , uint16_t y , CRGB c , uint8_t blend ) { blendPixelColor ( x , RGBW32 ( c . r , c . g , c . b , 0 ) , blend ) ; }
inline void addPixelColorXY ( int x , int y , uint32_t color , bool fast = false ) { addPixelColor ( x , color , fast ) ; }
inline void addPixelColorXY ( int x , int y , byte r , byte g , byte b , byte w = 0 , bool fast = false ) { addPixelColor ( x , RGBW32 ( r , g , b , w ) , fast ) ; }
inline void addPixelColorXY ( int x , int y , CRGB c , bool fast = false ) { addPixelColor ( x , RGBW32 ( c . r , c . g , c . b , 0 ) , fast ) ; }
inline void fadePixelColorXY ( uint16_t x , uint16_t y , uint8_t fade ) { fadePixelColor ( x , fade ) ; }
2024-08-14 20:15:48 +00:00
inline void box_blur ( unsigned i , bool vertical , fract8 blur_amount ) { }
inline void blur2D ( uint8_t blur_amount , bool smear = false ) { }
2024-04-15 19:20:45 +00:00
inline void blurRow ( uint32_t row , fract8 blur_amount , bool smear = false ) { }
inline void blurCol ( uint32_t col , fract8 blur_amount , bool smear = false ) { }
2023-10-15 11:06:40 +00:00
inline void moveX ( int8_t delta , bool wrap = false ) { }
inline void moveY ( int8_t delta , bool wrap = false ) { }
inline void move ( uint8_t dir , uint8_t delta , bool wrap = false ) { }
2024-05-09 22:02:28 +00:00
inline void drawCircle ( uint16_t cx , uint16_t cy , uint8_t radius , uint32_t c , bool soft = false ) { }
inline void drawCircle ( uint16_t cx , uint16_t cy , uint8_t radius , CRGB c , bool soft = false ) { }
inline void fillCircle ( uint16_t cx , uint16_t cy , uint8_t radius , uint32_t c , bool soft = false ) { }
inline void fillCircle ( uint16_t cx , uint16_t cy , uint8_t radius , CRGB c , bool soft = false ) { }
inline void drawLine ( uint16_t x0 , uint16_t y0 , uint16_t x1 , uint16_t y1 , uint32_t c , bool soft = false ) { }
inline void drawLine ( uint16_t x0 , uint16_t y0 , uint16_t x1 , uint16_t y1 , CRGB c , bool soft = false ) { }
2023-10-15 11:06:40 +00:00
inline void drawCharacter ( unsigned char chr , int16_t x , int16_t y , uint8_t w , uint8_t h , uint32_t color , uint32_t = 0 , int8_t = 0 ) { }
inline void drawCharacter ( unsigned char chr , int16_t x , int16_t y , uint8_t w , uint8_t h , CRGB color ) { }
inline void drawCharacter ( unsigned char chr , int16_t x , int16_t y , uint8_t w , uint8_t h , CRGB c , CRGB c2 , int8_t rotate = 0 ) { }
inline void wu_pixel ( uint32_t x , uint32_t y , CRGB c ) { }
2022-08-03 12:23:24 +00:00
# endif
2022-07-17 13:58:41 +00:00
} segment ;
2022-08-19 19:14:49 +00:00
//static int segSize = sizeof(Segment);
2022-07-06 11:13:54 +00:00
// main "strip" class
2022-07-10 20:23:25 +00:00
class WS2812FX { // 96 bytes
2024-09-11 15:14:59 +00:00
typedef uint16_t ( * mode_ptr ) ( ) ; // pointer to mode function
typedef void ( * show_callback ) ( ) ; // pre show callback
2022-07-17 13:58:41 +00:00
typedef struct ModeData {
2022-07-29 10:15:56 +00:00
uint8_t _id ; // mode (effect) id
2022-07-17 13:58:41 +00:00
mode_ptr _fcn ; // mode (effect) function
2022-07-29 10:15:56 +00:00
const char * _data ; // mode (effect) name and its UI control data
ModeData ( uint8_t id , uint16_t ( * fcn ) ( void ) , const char * data ) : _id ( id ) , _fcn ( fcn ) , _data ( data ) { }
2022-07-17 13:58:41 +00:00
} mode_data_t ;
2021-01-08 23:35:48 +00:00
static WS2812FX * instance ;
2023-01-06 08:10:39 +00:00
2016-12-17 22:43:07 +00:00
public :
2022-05-08 08:50:48 +00:00
2022-07-19 14:16:43 +00:00
WS2812FX ( ) :
paletteFade ( 0 ) ,
paletteBlend ( 0 ) ,
cctBlending ( 0 ) ,
now ( millis ( ) ) ,
timebase ( 0 ) ,
isMatrix ( false ) ,
# ifndef WLED_DISABLE_2D
2023-01-02 19:56:00 +00:00
panels ( 1 ) ,
2022-07-19 14:16:43 +00:00
# endif
2024-08-17 13:09:41 +00:00
autoSegments ( false ) ,
correctWB ( false ) ,
cctFromRgb ( false ) ,
2022-07-29 10:15:56 +00:00
// semi-private (just obscured) used in effect functions through macros
2022-07-19 14:16:43 +00:00
_colors_t { 0 , 0 , 0 } ,
_virtualSegmentLength ( 0 ) ,
2022-07-29 10:15:56 +00:00
// true private variables
2023-12-22 14:39:07 +00:00
_suspend ( false ) ,
2022-07-19 14:16:43 +00:00
_length ( DEFAULT_LED_COUNT ) ,
_brightness ( DEFAULT_BRIGHTNESS ) ,
_transitionDur ( 750 ) ,
2022-08-24 21:04:51 +00:00
_targetFps ( WLED_FPS ) ,
_frametime ( FRAMETIME_FIXED ) ,
2022-07-19 14:16:43 +00:00
_cumulativeFps ( 2 ) ,
_isServicing ( false ) ,
_isOffRefreshRequired ( false ) ,
_hasWhiteChannel ( false ) ,
_triggered ( false ) ,
_modeCount ( MODE_COUNT ) ,
_callback ( nullptr ) ,
customMappingTable ( nullptr ) ,
customMappingSize ( 0 ) ,
_lastShow ( 0 ) ,
_segment_index ( 0 ) ,
2024-08-05 14:42:21 +00:00
_mainSegment ( 0 )
2022-07-19 14:16:43 +00:00
{
2021-01-08 23:35:48 +00:00
WS2812FX : : instance = this ;
2022-08-08 08:21:11 +00:00
_mode . reserve ( _modeCount ) ; // allocate memory to prevent initial fragmentation (does not increase size())
_modeData . reserve ( _modeCount ) ; // allocate memory to prevent initial fragmentation (does not increase size())
if ( _mode . capacity ( ) < = 1 | | _modeData . capacity ( ) < = 1 ) _modeCount = 1 ; // memory allocation failed only show Solid
2022-07-17 13:58:41 +00:00
else setupEffectData ( ) ;
2016-12-17 22:43:07 +00:00
}
2022-07-10 20:23:25 +00:00
~ WS2812FX ( ) {
2022-07-19 14:16:43 +00:00
if ( customMappingTable ) delete [ ] customMappingTable ;
2022-07-17 13:58:41 +00:00
_mode . clear ( ) ;
_modeData . clear ( ) ;
2022-07-19 14:16:43 +00:00
_segments . clear ( ) ;
2023-01-02 20:24:02 +00:00
# ifndef WLED_DISABLE_2D
2023-01-02 19:56:00 +00:00
panel . clear ( ) ;
2023-01-02 20:24:02 +00:00
# endif
2022-07-29 10:15:56 +00:00
customPalettes . clear ( ) ;
2022-07-10 20:23:25 +00:00
}
2024-09-11 15:14:59 +00:00
static WS2812FX * getInstance ( ) { return instance ; }
2022-07-06 11:13:54 +00:00
2016-12-17 22:43:07 +00:00
void
2022-08-03 19:36:47 +00:00
# ifdef WLED_DEBUG
2024-01-04 16:40:23 +00:00
printSize ( ) , // prints memory usage for strip components
2022-08-03 19:36:47 +00:00
# endif
2024-01-04 16:40:23 +00:00
finalizeInit ( ) , // initialises strip components
2024-09-11 15:14:59 +00:00
service ( ) , // executes effect functions when due and calls strip.show()
2024-01-04 16:40:23 +00:00
setMode ( uint8_t segid , uint8_t m ) , // sets effect/mode for given segment (high level API)
setColor ( uint8_t slot , uint32_t c ) , // sets color (in slot) for given segment (high level API)
setCCT ( uint16_t k ) , // sets global CCT (either in relative 0-255 value or in K)
setBrightness ( uint8_t b , bool direct = false ) , // sets strip brightness
setRange ( uint16_t i , uint16_t i2 , uint32_t col ) , // used for clock overlay
2024-09-11 15:14:59 +00:00
purgeSegments ( ) , // removes inactive segments from RAM (may incure penalty and memory fragmentation but reduces vector footprint)
2022-07-17 13:58:41 +00:00
setSegment ( uint8_t n , uint16_t start , uint16_t stop , uint8_t grouping = 1 , uint8_t spacing = 0 , uint16_t offset = UINT16_MAX , uint16_t startY = 0 , uint16_t stopY = 1 ) ,
2022-02-20 21:24:11 +00:00
setMainSegmentId ( uint8_t n ) ,
2024-01-04 16:40:23 +00:00
resetSegments ( ) , // marks all segments for reset
makeAutoSegments ( bool forceReset = false ) , // will create segments based on configured outputs
fixInvalidSegments ( ) , // fixes incorrect segment configuration
setPixelColor ( unsigned n , uint32_t c ) , // paints absolute strip pixel with index n and color c
2024-09-11 15:14:59 +00:00
show ( ) , // initiates LED output
2023-10-15 11:06:40 +00:00
setTargetFps ( uint8_t fps ) ,
2024-09-11 15:14:59 +00:00
setupEffectData ( ) ; // add default effects to the list; defined in FX.cpp
2023-10-15 11:06:40 +00:00
2024-01-04 16:40:23 +00:00
inline void restartRuntime ( ) { for ( Segment & seg : _segments ) seg . markForReset ( ) ; }
2023-10-15 11:06:40 +00:00
inline void setTransitionMode ( bool t ) { for ( Segment & seg : _segments ) seg . startTransition ( t ? _transitionDur : 0 ) ; }
2024-01-04 16:40:23 +00:00
inline void setColor ( uint8_t slot , uint8_t r , uint8_t g , uint8_t b , uint8_t w = 0 ) { setColor ( slot , RGBW32 ( r , g , b , w ) ) ; }
2023-12-28 22:32:47 +00:00
inline void setPixelColor ( unsigned n , uint8_t r , uint8_t g , uint8_t b , uint8_t w = 0 ) { setPixelColor ( n , RGBW32 ( r , g , b , w ) ) ; }
2024-01-04 16:40:23 +00:00
inline void setPixelColor ( unsigned n , CRGB c ) { setPixelColor ( n , c . red , c . green , c . blue ) ; }
inline void fill ( uint32_t c ) { for ( unsigned i = 0 ; i < getLengthTotal ( ) ; i + + ) setPixelColor ( i , c ) ; } // fill whole strip with color (inline)
2024-09-11 15:14:59 +00:00
inline void trigger ( ) { _triggered = true ; } // Forces the next frame to be computed on all active segments.
2024-01-04 16:40:23 +00:00
inline void setShowCallback ( show_callback cb ) { _callback = cb ; }
inline void setTransition ( uint16_t t ) { _transitionDur = t ; } // sets transition time (in ms)
2023-07-13 11:08:36 +00:00
inline void appendSegment ( const Segment & seg = Segment ( ) ) { if ( _segments . size ( ) < getMaxSegments ( ) ) _segments . push_back ( seg ) ; }
2024-09-11 15:14:59 +00:00
inline void suspend ( ) { _suspend = true ; } // will suspend (and canacel) strip.service() execution
inline void resume ( ) { _suspend = false ; } // will resume strip.service() execution
2022-03-25 15:36:05 +00:00
2018-11-24 10:52:23 +00:00
bool
2023-11-27 12:27:52 +00:00
paletteFade ,
2024-09-11 15:14:59 +00:00
checkSegmentAlignment ( ) ,
hasRGBWBus ( ) const ,
hasCCTBus ( ) const ,
isUpdating ( ) const , // return true if the strip is being sent pixel updates
2023-06-30 19:12:59 +00:00
deserializeMap ( uint8_t n = 0 ) ;
2018-11-24 10:52:23 +00:00
2024-09-11 15:14:59 +00:00
inline bool isServicing ( ) const { return _isServicing ; } // returns true if strip.service() is executing
inline bool hasWhiteChannel ( ) const { return _hasWhiteChannel ; } // returns true if strip contains separate white chanel
inline bool isOffRefreshRequired ( ) const { return _isOffRefreshRequired ; } // returns true if strip requires regular updates (i.e. TM1814 chipset)
inline bool isSuspended ( ) const { return _suspend ; } // returns true if strip.service() execution is suspended
inline bool needsUpdate ( ) const { return _triggered ; } // returns true if strip received a trigger() request
2022-07-06 11:13:54 +00:00
2018-09-04 13:51:38 +00:00
uint8_t
2022-07-19 14:16:43 +00:00
paletteBlend ,
cctBlending ,
2024-09-11 15:14:59 +00:00
getActiveSegmentsNum ( ) const ,
getFirstSelectedSegId ( ) const ,
getLastActiveSegmentId ( ) const ,
2024-08-18 11:20:45 +00:00
getActiveSegsLightCapabilities ( bool selectedOnly = false ) const ,
addEffect ( uint8_t id , mode_ptr mode_fn , const char * mode_name ) ; // add effect to the list; defined in FX.cpp;
2024-08-14 20:15:48 +00:00
2024-09-11 15:14:59 +00:00
inline uint8_t getBrightness ( ) const { return _brightness ; } // returns current strip brightness
inline uint8_t getMaxSegments ( ) const { return MAX_NUM_SEGMENTS ; } // returns maximum number of supported segments (fixed value)
inline uint8_t getSegmentsNum ( ) const { return _segments . size ( ) ; } // returns currently present segments
inline uint8_t getCurrSegmentId ( ) const { return _segment_index ; } // returns current segment index (only valid while strip.isServicing())
inline uint8_t getMainSegmentId ( ) const { return _mainSegment ; } // returns main segment index
inline uint8_t getPaletteCount ( ) const { return 13 + GRADIENT_PALETTE_COUNT + customPalettes . size ( ) ; }
inline uint8_t getTargetFps ( ) const { return _targetFps ; } // returns rough FPS value for las 2s interval
inline uint8_t getModeCount ( ) const { return _modeCount ; } // returns number of registered modes/effects
2020-09-27 12:42:14 +00:00
2019-08-30 13:39:34 +00:00
uint16_t
2024-09-11 15:14:59 +00:00
getLengthPhysical ( ) const ,
getLengthTotal ( ) const , // will include virtual/nonexistent pixels in matrix
2024-08-14 20:15:48 +00:00
getFps ( ) const ,
getMappedPixelIndex ( uint16_t index ) const ;
2019-08-30 13:39:34 +00:00
2024-09-11 15:14:59 +00:00
inline uint16_t getFrameTime ( ) const { return _frametime ; } // returns amount of time a frame should take (in ms)
inline uint16_t getMinShowDelay ( ) const { return MIN_SHOW_DELAY ; } // returns minimum amount of time strip.service() can be delayed (constant)
inline uint16_t getLength ( ) const { return _length ; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H)
inline uint16_t getTransition ( ) const { return _transitionDur ; } // returns currently set transition time (in ms)
2022-06-17 16:57:32 +00:00
2016-12-17 22:43:07 +00:00
uint32_t
2020-08-25 15:23:17 +00:00
now ,
2019-10-18 10:19:52 +00:00
timebase ,
2024-08-14 20:15:48 +00:00
getPixelColor ( uint16_t ) const ;
2016-12-17 22:43:07 +00:00
2024-09-11 15:14:59 +00:00
inline uint32_t getLastShow ( ) const { return _lastShow ; } // returns millis() timestamp of last strip.show() call
2024-08-14 20:15:48 +00:00
inline uint32_t segColor ( uint8_t i ) const { return _colors_t [ i ] ; } // returns currently valid color (for slot i) AKA SEGCOLOR(); may be blended between two colors while in transition
2022-07-06 11:13:54 +00:00
2022-06-21 20:49:45 +00:00
const char *
2024-08-14 20:15:48 +00:00
getModeData ( uint8_t id = 0 ) const { return ( id & & id < _modeCount ) ? _modeData [ id ] : PSTR ( " Solid " ) ; }
2022-06-21 20:49:45 +00:00
const char * *
2024-09-11 15:14:59 +00:00
getModeDataSrc ( ) { return & ( _modeData [ 0 ] ) ; } // vectors use arrays for underlying data
2022-06-21 20:49:45 +00:00
2022-08-03 12:23:24 +00:00
Segment & getSegment ( uint8_t id ) ;
2024-09-11 15:14:59 +00:00
inline Segment & getFirstSelectedSeg ( ) { return _segments [ getFirstSelectedSegId ( ) ] ; } // returns reference to first segment that is "selected"
inline Segment & getMainSegment ( ) { return _segments [ getMainSegmentId ( ) ] ; } // returns reference to main segment
inline Segment * getSegments ( ) { return & ( _segments [ 0 ] ) ; } // returns pointer to segment vector structure (warning: use carefully)
2018-09-04 13:51:38 +00:00
2022-07-06 11:13:54 +00:00
// 2D support (panels)
2022-05-08 08:50:48 +00:00
bool
2022-07-19 14:16:43 +00:00
isMatrix ;
2022-05-08 08:50:48 +00:00
2022-07-10 20:23:25 +00:00
# ifndef WLED_DISABLE_2D
2024-06-23 12:09:18 +00:00
# define WLED_MAX_PANELS 18
2022-05-08 08:50:48 +00:00
uint8_t
2023-01-02 19:56:00 +00:00
panels ;
2022-05-08 08:50:48 +00:00
2023-01-02 19:56:00 +00:00
typedef struct panel_t {
uint16_t xOffset ; // x offset relative to the top left of matrix in LEDs
uint16_t yOffset ; // y offset relative to the top left of matrix in LEDs
uint8_t width ; // width of the panel
uint8_t height ; // height of the panel
union {
uint8_t options ;
struct {
bool bottomStart : 1 ; // starts at bottom?
bool rightStart : 1 ; // starts on right?
bool vertical : 1 ; // is vertical?
bool serpentine : 1 ; // is serpentine?
} ;
} ;
2023-03-05 21:56:14 +00:00
panel_t ( )
: xOffset ( 0 )
, yOffset ( 0 )
, width ( 8 )
, height ( 8 )
, options ( 0 )
{ }
2022-05-08 08:50:48 +00:00
} Panel ;
2023-01-02 19:56:00 +00:00
std : : vector < Panel > panel ;
2022-07-10 20:23:25 +00:00
# endif
2022-05-08 08:50:48 +00:00
2024-01-04 16:40:23 +00:00
void setUpMatrix ( ) ; // sets up automatic matrix ledmap from panel configuration
2022-05-08 08:50:48 +00:00
2022-06-23 15:42:02 +00:00
// outsmart the compiler :) by correctly overloading
2023-12-28 22:32:47 +00:00
inline void setPixelColorXY ( int x , int y , uint32_t c ) { setPixelColor ( ( unsigned ) ( y * Segment : : maxWidth + x ) , c ) ; }
2023-10-12 14:15:16 +00:00
inline void setPixelColorXY ( int x , int y , byte r , byte g , byte b , byte w = 0 ) { setPixelColorXY ( x , y , RGBW32 ( r , g , b , w ) ) ; }
inline void setPixelColorXY ( int x , int y , CRGB c ) { setPixelColorXY ( x , y , RGBW32 ( c . r , c . g , c . b , 0 ) ) ; }
2022-05-08 08:50:48 +00:00
2024-08-14 20:15:48 +00:00
inline uint32_t getPixelColorXY ( int x , int y ) const { return getPixelColor ( isMatrix ? y * Segment : : maxWidth + x : x ) ; }
2022-05-08 08:50:48 +00:00
2022-07-06 11:13:54 +00:00
// end 2D support
2022-05-08 08:50:48 +00:00
2024-09-11 15:14:59 +00:00
void loadCustomPalettes ( ) ; // loads custom palettes from JSON
2022-07-29 10:15:56 +00:00
std : : vector < CRGBPalette16 > customPalettes ; // TODO: move custom palettes out of WS2812FX class
2019-10-01 23:17:26 +00:00
2024-08-17 13:09:41 +00:00
struct {
bool autoSegments : 1 ;
bool correctWB : 1 ;
bool cctFromRgb : 1 ;
} ;
2022-07-17 13:58:41 +00:00
// using public variables to reduce code size increase due to inline function getSegment() (with bounds checking)
// and color transitions
2022-07-28 21:19:58 +00:00
uint32_t _colors_t [ 3 ] ; // color used for effect (includes transition)
2022-07-10 20:23:25 +00:00
uint16_t _virtualSegmentLength ;
2022-07-29 10:15:56 +00:00
std : : vector < segment > _segments ;
2022-07-10 20:23:25 +00:00
friend class Segment ;
2022-07-06 11:13:54 +00:00
private :
2023-12-22 14:39:07 +00:00
volatile bool _suspend ;
2022-07-10 20:23:25 +00:00
uint16_t _length ;
2023-06-30 19:12:59 +00:00
uint8_t _brightness ;
2022-07-19 14:16:43 +00:00
uint16_t _transitionDur ;
2022-08-24 21:04:51 +00:00
uint8_t _targetFps ;
uint16_t _frametime ;
2022-07-19 14:16:43 +00:00
uint16_t _cumulativeFps ;
// will require only 1 byte
2022-07-28 21:19:58 +00:00
struct {
bool _isServicing : 1 ;
bool _isOffRefreshRequired : 1 ; //periodic refresh is required for the strip to remain off.
bool _hasWhiteChannel : 1 ;
bool _triggered : 1 ;
} ;
2022-07-29 10:15:56 +00:00
uint8_t _modeCount ;
2022-07-17 13:58:41 +00:00
std : : vector < mode_ptr > _mode ; // SRAM footprint: 4 bytes per element
std : : vector < const char * > _modeData ; // mode (effect) name and its slider control data array
2022-07-19 14:16:43 +00:00
show_callback _callback ;
2016-12-17 22:43:07 +00:00
2022-07-19 14:16:43 +00:00
uint16_t * customMappingTable ;
uint16_t customMappingSize ;
2023-01-06 08:10:39 +00:00
2023-07-12 18:52:34 +00:00
unsigned long _lastShow ;
2023-01-06 08:10:39 +00:00
2022-07-19 14:16:43 +00:00
uint8_t _segment_index ;
2022-02-20 21:24:11 +00:00
uint8_t _mainSegment ;
2016-12-17 22:43:07 +00:00
} ;
2019-02-10 22:05:06 +00:00
2021-12-28 17:09:52 +00:00
extern const char JSON_mode_names [ ] ;
extern const char JSON_palette_names [ ] ;
2016-12-17 22:43:07 +00:00
# endif