2016-12-17 23:43:07 +01:00
|
|
|
/*
|
|
|
|
WS2812FX.h - Library for WS2812 LED effects.
|
|
|
|
Harm Aldick - 2016
|
|
|
|
www.aldick.org
|
|
|
|
LICENSE
|
|
|
|
The MIT License (MIT)
|
2018-09-04 15:51:38 +02:00
|
|
|
Copyright (c) 2016 Harm Aldick
|
2016-12-17 23:43:07 +01: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 16:37:20 +01:00
|
|
|
|
2018-09-04 15:51:38 +02:00
|
|
|
Modified for WLED
|
2016-12-17 23:43:07 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef WS2812FX_h
|
|
|
|
#define WS2812FX_h
|
|
|
|
|
2022-07-17 15:58:41 +02:00
|
|
|
#include <vector>
|
|
|
|
|
2020-02-20 00:45:09 +01:00
|
|
|
#include "const.h"
|
2018-11-09 17:00:36 +01:00
|
|
|
|
|
|
|
#define FASTLED_INTERNAL //remove annoying pragma messages
|
2020-08-25 17:23:17 +02:00
|
|
|
#define USE_GET_MILLISECOND_TIMER
|
2018-11-04 20:14:23 +01:00
|
|
|
#include "FastLED.h"
|
2016-12-17 23:43:07 +01:00
|
|
|
|
2018-11-16 19:59:00 +01:00
|
|
|
#define DEFAULT_BRIGHTNESS (uint8_t)127
|
2018-09-04 15:51:38 +02:00
|
|
|
#define DEFAULT_MODE (uint8_t)0
|
2018-11-16 19:59:00 +01:00
|
|
|
#define DEFAULT_SPEED (uint8_t)128
|
2020-09-07 21:01:10 +02:00
|
|
|
#define DEFAULT_INTENSITY (uint8_t)128
|
2019-03-05 10:59:15 +01:00
|
|
|
#define DEFAULT_COLOR (uint32_t)0xFFAA00
|
2022-05-08 10:50:48 +02:00
|
|
|
#define DEFAULT_C1 (uint8_t)128
|
|
|
|
#define DEFAULT_C2 (uint8_t)128
|
2022-08-12 17:58:20 +02:00
|
|
|
#define DEFAULT_C3 (uint8_t)16
|
2018-09-04 15:51:38 +02:00
|
|
|
|
2020-11-17 22:46:17 +01:00
|
|
|
#ifndef MIN
|
2020-03-26 10:18:19 +01:00
|
|
|
#define MIN(a,b) ((a)<(b)?(a):(b))
|
2020-11-17 22:46:17 +01:00
|
|
|
#endif
|
|
|
|
#ifndef MAX
|
2020-03-26 10:18:19 +01:00
|
|
|
#define MAX(a,b) ((a)>(b)?(a):(b))
|
2020-11-17 22:46:17 +01:00
|
|
|
#endif
|
2018-09-04 15:51:38 +02:00
|
|
|
|
2022-03-25 16:36:05 +01: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 16:33:37 +02:00
|
|
|
/* Not used in all effects yet */
|
2019-10-04 01:21:18 +02:00
|
|
|
#define WLED_FPS 42
|
2021-12-25 01:30:27 +01:00
|
|
|
#define FRAMETIME_FIXED (1000/WLED_FPS)
|
2022-07-06 13:13:54 +02:00
|
|
|
//#define FRAMETIME _frametime
|
|
|
|
#define FRAMETIME strip.getFrameTime()
|
2019-10-03 16:33:37 +02:00
|
|
|
|
2019-12-31 11:11:05 +01:00
|
|
|
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
|
2018-09-04 15:51:38 +02:00
|
|
|
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
2019-12-31 11:11:05 +01:00
|
|
|
#ifdef ESP8266
|
2021-09-18 00:31:39 +02:00
|
|
|
#define MAX_NUM_SEGMENTS 16
|
2021-01-09 00:35:48 +01:00
|
|
|
/* How much data bytes all segments combined may allocate */
|
2022-07-30 14:20:36 +02:00
|
|
|
#define MAX_SEGMENT_DATA 5120
|
2019-12-31 11:11:05 +01:00
|
|
|
#else
|
2021-09-08 23:10:54 +02:00
|
|
|
#ifndef MAX_NUM_SEGMENTS
|
|
|
|
#define MAX_NUM_SEGMENTS 32
|
|
|
|
#endif
|
2023-03-05 22:56:14 +01:00
|
|
|
#if defined(ARDUINO_ARCH_ESP32S2)
|
|
|
|
#define MAX_SEGMENT_DATA 24576
|
|
|
|
#else
|
|
|
|
#define MAX_SEGMENT_DATA 32767
|
|
|
|
#endif
|
2019-12-31 11:11:05 +01:00
|
|
|
#endif
|
|
|
|
|
2021-09-20 21:22:50 +02: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 15:58:41 +02:00
|
|
|
#define FAIR_DATA_PER_SEG (MAX_SEGMENT_DATA / strip.getMaxSegments())
|
2021-09-20 21:22:50 +02:00
|
|
|
|
2021-12-25 01:30:27 +01:00
|
|
|
#define MIN_SHOW_DELAY (_frametime < 16 ? 8 : 15)
|
2020-02-24 19:36:25 +01:00
|
|
|
|
2019-05-22 00:23:09 +02:00
|
|
|
#define NUM_COLORS 3 /* number of colors per segment */
|
2022-07-10 22:23:25 +02:00
|
|
|
#define SEGMENT strip._segments[strip.getCurrSegmentId()]
|
2022-07-17 15:58:41 +02:00
|
|
|
#define SEGENV strip._segments[strip.getCurrSegmentId()]
|
2022-07-30 14:20:36 +02:00
|
|
|
//#define SEGCOLOR(x) strip._segments[strip.getCurrSegmentId()].currentColor(x, strip._segments[strip.getCurrSegmentId()].colors[x])
|
2022-07-12 18:10:07 +02:00
|
|
|
//#define SEGLEN strip._segments[strip.getCurrSegmentId()].virtualLength()
|
2022-07-17 15:58:41 +02:00
|
|
|
#define SEGCOLOR(x) strip.segColor(x) /* saves us a few kbytes of code */
|
2022-07-28 23:19:58 +02:00
|
|
|
#define SEGPALETTE strip._currentPalette
|
2022-07-17 15:58:41 +02:00
|
|
|
#define SEGLEN strip._virtualSegmentLength /* saves us a few kbytes of code */
|
2022-07-06 20:41:12 +02:00
|
|
|
#define SPEED_FORMULA_L (5U + (50U*(255U - SEGMENT.speed))/SEGLEN)
|
2016-12-17 23:43:07 +01:00
|
|
|
|
2018-09-04 15:51:38 +02: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
|
|
|
|
#define ULTRAWHITE (uint32_t)0xFFFFFFFF
|
2022-08-02 18:27:32 +02:00
|
|
|
#define DARKSLATEGRAY (uint32_t)0x2F4F4F
|
|
|
|
#define DARKSLATEGREY (uint32_t)0x2F4F4F
|
2016-12-17 23:43:07 +01:00
|
|
|
|
2018-09-04 15:51:38 +02:00
|
|
|
// options
|
2019-03-05 10:59:15 +01:00
|
|
|
// bit 7: segment is in transition mode
|
2020-08-04 18:50:16 +02:00
|
|
|
// bits 4-6: TBD
|
|
|
|
// bit 3: mirror effect within segment
|
2020-04-23 23:52:33 +02:00
|
|
|
// bit 2: segment is on
|
2019-03-05 10:59:15 +01:00
|
|
|
// bit 1: reverse segment
|
|
|
|
// bit 0: segment is selected
|
2022-07-06 13:13:54 +02:00
|
|
|
#define NO_OPTIONS (uint16_t)0x0000
|
|
|
|
#define TRANSPOSED (uint16_t)0x0400 // rotated 90deg & reversed
|
|
|
|
#define REVERSE_Y_2D (uint16_t)0x0200
|
|
|
|
#define MIRROR_Y_2D (uint16_t)0x0100
|
|
|
|
#define TRANSITIONAL (uint16_t)0x0080
|
|
|
|
#define MIRROR (uint16_t)0x0008
|
|
|
|
#define SEGMENT_ON (uint16_t)0x0004
|
|
|
|
#define REVERSE (uint16_t)0x0002
|
|
|
|
#define SELECTED (uint16_t)0x0001
|
2016-12-17 23:43:07 +01: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 15:51:38 +02:00
|
|
|
#define FX_MODE_COLOR_SWEEP 6
|
2018-04-01 00:08:50 +02:00
|
|
|
#define FX_MODE_DYNAMIC 7
|
2016-12-17 23:43:07 +01: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 21:53:39 +01:00
|
|
|
#define FX_MODE_SAW 16
|
|
|
|
#define FX_MODE_TWINKLE 17
|
2019-01-31 23:42:48 +01:00
|
|
|
#define FX_MODE_DISSOLVE 18
|
2023-01-18 22:56:49 +01:00
|
|
|
#define FX_MODE_DISSOLVE_RANDOM 19 // candidate for removal (use Dissolve with with check 3)
|
2016-12-17 23:43:07 +01: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 23:16:53 +01:00
|
|
|
#define FX_MODE_ANDROID 27
|
2016-12-17 23:43:07 +01: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 23:57:58 +01:00
|
|
|
#define FX_MODE_COLORFUL 34
|
2017-12-14 00:12:02 +01:00
|
|
|
#define FX_MODE_TRAFFIC_LIGHT 35
|
2016-12-17 23:43:07 +01:00
|
|
|
#define FX_MODE_COLOR_SWEEP_RANDOM 36
|
|
|
|
#define FX_MODE_RUNNING_COLOR 37
|
2021-01-04 11:11:36 +01:00
|
|
|
#define FX_MODE_AURORA 38
|
2016-12-17 23:43:07 +01: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 23:49:04 +01:00
|
|
|
#define FX_MODE_RAIN 43
|
2021-12-07 11:03:41 +01:00
|
|
|
#define FX_MODE_TETRIX 44 //was Merry Christmas prior to 0.12.0 (use "Chase 2" with Red/Green)
|
2016-12-17 23:43:07 +01:00
|
|
|
#define FX_MODE_FIRE_FLICKER 45
|
2018-03-18 23:16:53 +01:00
|
|
|
#define FX_MODE_GRADIENT 46
|
|
|
|
#define FX_MODE_LOADING 47
|
2022-11-14 02:29:59 +01:00
|
|
|
// #define FX_MODE_POLICE 48 // removed in 0.14!
|
2021-12-07 11:03:41 +01: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 12:15:12 +01:00
|
|
|
#define FX_MODE_TWO_DOTS 50
|
2021-12-07 11:03:41 +01:00
|
|
|
#define FX_MODE_FAIRYTWINKLE 51 //was Two Areas prior to 0.13.0-b6 (use "Two Dots" with full intensity)
|
2021-04-11 00:50:14 +02:00
|
|
|
#define FX_MODE_RUNNING_DUAL 52
|
2022-11-14 02:29:59 +01:00
|
|
|
// #define FX_MODE_HALLOWEEN 53 // removed in 0.14!
|
2018-09-04 15:51:38 +02: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
|
|
|
|
#define FX_MODE_DUAL_LARSON_SCANNER 60
|
|
|
|
#define FX_MODE_RANDOM_CHASE 61
|
|
|
|
#define FX_MODE_OSCILLATE 62
|
2018-09-11 00:20:12 +02: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 16:21:44 +02: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 20:14:23 +01:00
|
|
|
#define FX_MODE_COLORTWINKLE 74
|
2018-11-07 20:22:05 +01:00
|
|
|
#define FX_MODE_LAKE 75
|
2018-11-20 21:31:07 +01:00
|
|
|
#define FX_MODE_METEOR 76
|
2018-12-02 02:49:05 +01:00
|
|
|
#define FX_MODE_METEOR_SMOOTH 77
|
|
|
|
#define FX_MODE_RAILWAY 78
|
2019-01-31 23:42:48 +01:00
|
|
|
#define FX_MODE_RIPPLE 79
|
2019-08-30 15:39:34 +02:00
|
|
|
#define FX_MODE_TWINKLEFOX 80
|
2019-10-02 01:17:26 +02:00
|
|
|
#define FX_MODE_TWINKLECAT 81
|
|
|
|
#define FX_MODE_HALLOWEEN_EYES 82
|
2019-11-18 12:29:36 +01:00
|
|
|
#define FX_MODE_STATIC_PATTERN 83
|
2019-11-29 18:53:01 +01:00
|
|
|
#define FX_MODE_TRI_STATIC_PATTERN 84
|
2019-12-04 12:15:12 +01:00
|
|
|
#define FX_MODE_SPOTS 85
|
|
|
|
#define FX_MODE_SPOTS_FADE 86
|
2019-12-06 01:44:45 +01:00
|
|
|
#define FX_MODE_GLITTER 87
|
|
|
|
#define FX_MODE_CANDLE 88
|
2019-12-28 15:43:55 +01:00
|
|
|
#define FX_MODE_STARBURST 89
|
2020-01-03 12:58:31 +01:00
|
|
|
#define FX_MODE_EXPLODING_FIREWORKS 90
|
2020-01-03 23:19:40 +01: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 15:04:49 +01:00
|
|
|
#define FX_MODE_DRIP 96
|
2020-01-19 00:06:17 +01:00
|
|
|
#define FX_MODE_PLASMA 97
|
2020-01-19 13:51:49 +01:00
|
|
|
#define FX_MODE_PERCENT 98
|
2020-02-15 20:07:15 +01:00
|
|
|
#define FX_MODE_RIPPLE_RAINBOW 99
|
2020-02-17 11:01:05 +01:00
|
|
|
#define FX_MODE_HEARTBEAT 100
|
2020-03-25 11:17:45 +01:00
|
|
|
#define FX_MODE_PACIFICA 101
|
2020-04-22 00:51:00 +02:00
|
|
|
#define FX_MODE_CANDLE_MULTI 102
|
2023-01-18 22:56:49 +01:00
|
|
|
#define FX_MODE_SOLID_GLITTER 103 // candidate for removal (use glitter)
|
2020-06-06 00:57:34 +02: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 12:30:31 +02:00
|
|
|
#define FX_MODE_CHUNCHUN 111
|
2020-08-22 20:54:59 +02:00
|
|
|
#define FX_MODE_DANCING_SHADOWS 112
|
2020-09-27 01:58:21 +02:00
|
|
|
#define FX_MODE_WASHING_MACHINE 113
|
2022-11-14 02:29:59 +01:00
|
|
|
// #define FX_MODE_CANDY_CANE 114 // removed in 0.14!
|
2020-12-15 13:35:50 +01:00
|
|
|
#define FX_MODE_BLENDS 115
|
2020-12-22 13:15:57 +01:00
|
|
|
#define FX_MODE_TV_SIMULATOR 116
|
2023-01-18 22:56:49 +01:00
|
|
|
#define FX_MODE_DYNAMIC_SMOOTH 117 // candidate for removal (check3 in dynamic)
|
2022-06-21 22:49:45 +02:00
|
|
|
|
2022-11-14 02:29:59 +01: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 17:31:55 +02:00
|
|
|
#define FX_MODE_2DDISTORTIONWAVES 124 //gap fill
|
|
|
|
#define FX_MODE_2DSOAP 125 //gap fill
|
2023-04-28 22:00:35 +02:00
|
|
|
#define FX_MODE_2DOCTOPUS 126 //gap fill
|
2023-04-29 17:04:16 +02:00
|
|
|
#define FX_MODE_2DWAVINGCELL 127 //gap fill
|
2022-11-14 02:29:59 +01: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
|
|
|
|
#define FX_MODE_2DFIRE2012 151
|
|
|
|
#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
|
|
|
|
#define FX_MODE_2DCENTERBARS 161
|
|
|
|
#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 23:13:29 +01:00
|
|
|
|
2022-07-14 13:22:34 +02:00
|
|
|
typedef enum mapping1D2D {
|
|
|
|
M12_Pixels = 0,
|
2022-08-25 21:57:43 +02:00
|
|
|
M12_pBar = 1,
|
|
|
|
M12_pArc = 2,
|
|
|
|
M12_pCorner = 3
|
2022-07-14 13:22:34 +02:00
|
|
|
} mapping1D2D_t;
|
|
|
|
|
2023-07-12 20:52:34 +02:00
|
|
|
// segment, 80 bytes
|
2022-07-17 15:58:41 +02: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 14:24:02 +02: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
|
|
|
|
bool transitional: 1; // 6 : transitional (there is transition occuring)
|
|
|
|
bool reverse_y : 1; // 7 : reversed Y (2D)
|
|
|
|
bool mirror_y : 1; // 8 : mirrored Y (2D)
|
|
|
|
bool transpose : 1; // 9 : transposed (2D, swapped X & Y)
|
2023-04-04 17:16:50 +02:00
|
|
|
uint8_t map1D2D : 3; // 10-12 : mapping for 1D effect on 2D (0-use as strip, 1-expand vertically, 2-circular/arc, 3-rectangular/corner, ...)
|
2023-05-15 17:06:29 +02:00
|
|
|
uint8_t soundSim : 1; // 13 : 0-1 sound simulation types ("soft" & "hard" or "on"/"off")
|
|
|
|
uint8_t set : 2; // 14-15 : 0-3 UI segment sets/groups
|
2022-07-17 15:58:41 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
uint8_t grouping, spacing;
|
|
|
|
uint8_t opacity;
|
|
|
|
uint32_t colors[NUM_COLORS];
|
2022-08-19 21:14:49 +02:00
|
|
|
uint8_t cct; //0==1900K, 255==10091K
|
|
|
|
uint8_t custom1, custom2; // custom FX parameters/sliders
|
2022-08-12 17:58:20 +02:00
|
|
|
struct {
|
2022-08-19 21:14:49 +02: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 17:58:20 +02:00
|
|
|
};
|
2022-08-19 21:14:49 +02: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 20:52:34 +02:00
|
|
|
char *name;
|
2022-07-17 15:58:41 +02: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 20:52:34 +02:00
|
|
|
byte *data; // effect data pointer
|
2022-12-16 22:31:07 +01:00
|
|
|
static uint16_t maxWidth, maxHeight; // these define matrix width & height (max. segment dimensions)
|
2022-07-17 15:58:41 +02:00
|
|
|
|
2023-08-05 13:50:08 +02:00
|
|
|
typedef struct TemporarySegmentData {
|
2023-08-05 17:35:14 +02:00
|
|
|
uint16_t _optionsT;
|
2023-08-05 13:50:08 +02: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;
|
|
|
|
uint32_t _stepT;
|
|
|
|
uint32_t _callT;
|
|
|
|
uint8_t *_dataT;
|
|
|
|
uint16_t _dataLenT;
|
|
|
|
} tmpsegd_t;
|
|
|
|
|
2022-07-12 18:10:07 +02:00
|
|
|
private:
|
2022-07-28 23:19:58 +02: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 20:52:34 +02:00
|
|
|
uint16_t _dataLen;
|
2022-07-30 14:20:36 +02:00
|
|
|
static uint16_t _usedSegmentData;
|
2022-07-17 15:58:41 +02:00
|
|
|
|
2023-08-03 22:28:53 +02:00
|
|
|
// perhaps this should be per segment, not static
|
2023-08-05 21:01:06 +02:00
|
|
|
static CRGBPalette16 _randomPalette; // actual random palette
|
|
|
|
static CRGBPalette16 _newRandomPalette; // target random palette
|
|
|
|
static unsigned long _lastPaletteChange; // last random palette change time in millis()
|
2023-09-02 20:20:51 +02:00
|
|
|
#ifndef WLED_DISABLE_MODE_BLEND
|
2023-08-05 21:01:06 +02:00
|
|
|
static bool _modeBlend; // mode/effect blending semaphore
|
2023-09-02 20:20:51 +02:00
|
|
|
#endif
|
2023-08-03 22:28:53 +02:00
|
|
|
|
2023-07-12 20:52:34 +02:00
|
|
|
// transition data, valid only if transitional==true, holds values during transition (72 bytes)
|
2022-07-30 14:50:11 +02:00
|
|
|
struct Transition {
|
2023-09-02 20:20:51 +02:00
|
|
|
#ifndef WLED_DISABLE_MODE_BLEND
|
2023-08-12 12:45:11 +02:00
|
|
|
tmpsegd_t _segT; // previous segment environment
|
2023-09-02 20:20:51 +02:00
|
|
|
uint8_t _modeT; // previous mode/effect
|
|
|
|
#else
|
|
|
|
uint32_t _colorT[NUM_COLORS];
|
|
|
|
#endif
|
2022-08-31 14:24:02 +02:00
|
|
|
uint8_t _briT; // temporary brightness
|
|
|
|
uint8_t _cctT; // temporary CCT
|
|
|
|
CRGBPalette16 _palT; // temporary palette
|
2022-09-09 17:21:13 +02:00
|
|
|
uint8_t _prevPaletteBlends; // number of previous palette blends (there are max 255 belnds possible)
|
2023-08-05 13:50:08 +02:00
|
|
|
unsigned long _start; // must accommodate millis()
|
2022-07-28 23:19:58 +02:00
|
|
|
uint16_t _dur;
|
2022-09-06 21:47:50 +02:00
|
|
|
Transition(uint16_t dur=750)
|
2023-08-05 13:50:08 +02:00
|
|
|
: _palT(CRGBPalette16(CRGB::Black))
|
2022-09-06 21:47:50 +02:00
|
|
|
, _prevPaletteBlends(0)
|
|
|
|
, _start(millis())
|
|
|
|
, _dur(dur)
|
|
|
|
{}
|
2022-08-31 14:24:02 +02:00
|
|
|
} *_t;
|
2022-07-17 15:58:41 +02:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2022-07-19 16:16:43 +02: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 17:58:20 +02:00
|
|
|
check1(false),
|
|
|
|
check2(false),
|
|
|
|
check3(false),
|
2022-07-19 16:16:43 +02: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 14:50:11 +02:00
|
|
|
_dataLen(0),
|
|
|
|
_t(nullptr)
|
2022-07-19 22:14:46 +02:00
|
|
|
{
|
2023-02-15 20:36:54 +01:00
|
|
|
//refreshLightCapabilities();
|
2023-08-08 20:40:19 +02:00
|
|
|
#ifdef WLED_DEBUG
|
|
|
|
//Serial.printf("-- Creating segment: %p\n", this);
|
|
|
|
#endif
|
2022-07-19 22:14:46 +02:00
|
|
|
}
|
2022-07-19 16:16:43 +02:00
|
|
|
|
|
|
|
Segment(uint16_t sStartX, uint16_t sStopX, uint16_t sStartY, uint16_t sStopY) : Segment(sStartX, sStopX) {
|
2022-07-17 15:58:41 +02:00
|
|
|
startY = sStartY;
|
|
|
|
stopY = sStopY;
|
|
|
|
}
|
|
|
|
|
|
|
|
Segment(const Segment &orig); // copy constructor
|
|
|
|
Segment(Segment &&orig) noexcept; // move constructor
|
2022-07-06 13:13:54 +02:00
|
|
|
|
2022-07-17 15:58:41 +02:00
|
|
|
~Segment() {
|
2023-08-07 16:50:18 +02:00
|
|
|
#ifdef WLED_DEBUG
|
2023-08-08 20:40:19 +02:00
|
|
|
//Serial.printf("-- Destroying segment: %p\n", this);
|
2022-11-09 20:09:01 +01:00
|
|
|
//if (name) Serial.printf(" %s (%p)", name, name);
|
|
|
|
//if (data) Serial.printf(" %d (%p)", (int)_dataLen, data);
|
|
|
|
//Serial.println();
|
2023-08-07 16:50:18 +02:00
|
|
|
#endif
|
2023-07-12 20:52:34 +02:00
|
|
|
if (name) { delete[] name; name = nullptr; }
|
2023-08-07 16:50:18 +02:00
|
|
|
stopTransition();
|
2022-07-17 15:58:41 +02:00
|
|
|
deallocateData();
|
|
|
|
}
|
|
|
|
|
|
|
|
Segment& operator= (const Segment &orig); // copy assignment
|
|
|
|
Segment& operator= (Segment &&orig) noexcept; // move assignment
|
|
|
|
|
2022-08-03 21:36:47 +02:00
|
|
|
#ifdef WLED_DEBUG
|
2023-07-12 20:52:34 +02:00
|
|
|
size_t getSize() const { return sizeof(Segment) + (data?_dataLen:0) + (name?strlen(name):0) + (_t?sizeof(Transition):0); }
|
2022-08-03 21:36:47 +02:00
|
|
|
#endif
|
|
|
|
|
2022-08-17 20:45:30 +02:00
|
|
|
inline bool getOption(uint8_t n) const { return ((options >> n) & 0x01); }
|
|
|
|
inline bool isSelected(void) const { return selected; }
|
|
|
|
inline bool isActive(void) const { return stop > start; }
|
2022-08-22 14:35:34 +02:00
|
|
|
inline bool is2D(void) const { return (width()>1 && height()>1); }
|
2023-02-25 17:58:51 +01:00
|
|
|
inline bool hasRGB(void) const { return _isRGB; }
|
|
|
|
inline bool hasWhite(void) const { return _hasW; }
|
|
|
|
inline bool isCCT(void) const { return _isCCT; }
|
2023-07-12 20:52:34 +02:00
|
|
|
inline uint16_t width(void) const { return isActive() ? (stop - start) : 0; } // segment width in physical pixels (length if 1D)
|
|
|
|
inline uint16_t height(void) const { return stopY - startY; } // segment height (if 2D) in physical pixels (it *is* always >=1)
|
|
|
|
inline uint16_t length(void) const { return width() * height(); } // segment length (count) in physical pixels
|
2022-08-17 20:45:30 +02:00
|
|
|
inline uint16_t groupLength(void) const { return grouping + spacing; }
|
|
|
|
inline uint8_t getLightCapabilities(void) const { return _capabilities; }
|
2022-07-17 15:58:41 +02:00
|
|
|
|
2022-07-30 14:20:36 +02:00
|
|
|
static uint16_t getUsedSegmentData(void) { return _usedSegmentData; }
|
|
|
|
static void addUsedSegmentData(int len) { _usedSegmentData += len; }
|
2023-09-02 20:20:51 +02:00
|
|
|
#ifndef WLED_DISABLE_MODE_BLEND
|
2023-08-05 21:01:06 +02:00
|
|
|
static void modeBlend(bool blend) { _modeBlend = blend; }
|
2023-09-02 20:20:51 +02:00
|
|
|
#endif
|
2023-08-03 22:28:53 +02:00
|
|
|
static void handleRandomPalette();
|
2022-07-30 14:20:36 +02:00
|
|
|
|
2023-07-13 03:09:42 +02: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, uint8_t segId = 255);
|
2022-07-30 14:20:36 +02: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 12:49:12 +02:00
|
|
|
void setMode(uint8_t fx, bool loadDefaults = false);
|
|
|
|
void setPalette(uint8_t pal);
|
2022-08-17 20:45:30 +02:00
|
|
|
uint8_t differs(Segment& b) const;
|
2022-07-30 14:20:36 +02:00
|
|
|
void refreshLightCapabilities(void);
|
2022-07-17 15:58:41 +02:00
|
|
|
|
|
|
|
// runtime data functions
|
2022-08-17 20:45:30 +02:00
|
|
|
inline uint16_t dataSize(void) const { return _dataLen; }
|
2022-07-30 14:20:36 +02:00
|
|
|
bool allocateData(size_t len);
|
|
|
|
void deallocateData(void);
|
2022-07-19 16:16:43 +02:00
|
|
|
void resetIfRequired(void);
|
2023-01-06 09:10:39 +01:00
|
|
|
/**
|
2022-07-17 15:58:41 +02:00
|
|
|
* Flags that before the next effect is calculated,
|
2023-01-06 09:10:39 +01:00
|
|
|
* the internal segment state should be reset.
|
2022-07-17 15:58:41 +02:00
|
|
|
* Call resetIfRequired before calling the next effect function.
|
|
|
|
* Safe to call from interrupts and network requests.
|
|
|
|
*/
|
2022-07-29 12:15:56 +02:00
|
|
|
inline void markForReset(void) { reset = true; } // setOption(SEG_OPTION_RESET, true)
|
2022-07-17 15:58:41 +02:00
|
|
|
|
|
|
|
// transition functions
|
2022-07-30 14:20:36 +02:00
|
|
|
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
2023-08-07 16:50:18 +02:00
|
|
|
void stopTransition(void);
|
2022-07-30 14:20:36 +02:00
|
|
|
void handleTransition(void);
|
2023-09-02 20:20:51 +02:00
|
|
|
#ifndef WLED_DISABLE_MODE_BLEND
|
2023-08-12 12:45:11 +02:00
|
|
|
void swapSegenv(tmpsegd_t &tmpSegD);
|
|
|
|
void restoreSegenv(tmpsegd_t &tmpSegD);
|
2023-09-02 20:20:51 +02:00
|
|
|
#endif
|
2022-07-29 12:15:56 +02:00
|
|
|
uint16_t progress(void); //transition progression between 0-65535
|
2022-07-17 15:58:41 +02:00
|
|
|
uint8_t currentBri(uint8_t briNew, bool useCct = false);
|
2022-08-03 22:09:27 +02:00
|
|
|
uint8_t currentMode(uint8_t modeNew);
|
2022-07-30 14:20:36 +02:00
|
|
|
uint32_t currentColor(uint8_t slot, uint32_t colorNew);
|
2022-07-29 12:15:56 +02:00
|
|
|
CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal);
|
|
|
|
CRGBPalette16 ¤tPalette(CRGBPalette16 &tgt, uint8_t paletteID);
|
2022-07-17 15:58:41 +02:00
|
|
|
|
|
|
|
// 1D strip
|
2022-08-17 20:45:30 +02:00
|
|
|
uint16_t virtualLength(void) const;
|
2022-07-17 15:58:41 +02:00
|
|
|
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
|
2022-08-03 14:23:24 +02:00
|
|
|
void setPixelColor(int n, CRGB c) { setPixelColor(n, RGBW32(c.r,c.g,c.b,0)); } // automatically inline
|
2022-07-17 15:58:41 +02:00
|
|
|
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); }
|
2022-08-03 14:23:24 +02:00
|
|
|
void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, RGBW32(c.r,c.g,c.b,0), aa); }
|
2022-08-25 21:57:43 +02:00
|
|
|
uint32_t getPixelColor(int i);
|
2022-07-17 15:58:41 +02:00
|
|
|
// 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);
|
2022-08-02 18:27:32 +02:00
|
|
|
void blendPixelColor(int n, uint32_t color, uint8_t blend);
|
2022-08-03 14:23:24 +02:00
|
|
|
void blendPixelColor(int n, CRGB c, uint8_t blend) { blendPixelColor(n, RGBW32(c.r,c.g,c.b,0), blend); }
|
2023-04-27 17:31:55 +02:00
|
|
|
void addPixelColor(int n, uint32_t color, bool fast = false);
|
|
|
|
void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(n, RGBW32(r,g,b,w), fast); } // automatically inline
|
|
|
|
void addPixelColor(int n, CRGB c, bool fast = false) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), fast); } // automatically inline
|
2022-08-02 18:27:32 +02:00
|
|
|
void fadePixelColor(uint16_t n, uint8_t fade);
|
2022-07-17 15:58:41 +02:00
|
|
|
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
|
2022-08-17 20:45:30 +02:00
|
|
|
uint16_t virtualWidth(void) const;
|
|
|
|
uint16_t virtualHeight(void) const;
|
2022-08-25 21:57:43 +02:00
|
|
|
uint16_t nrOfVStrips(void) const;
|
2022-08-03 14:23:24 +02:00
|
|
|
#ifndef WLED_DISABLE_2D
|
2023-06-30 21:12:59 +02:00
|
|
|
uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment
|
2022-07-17 15:58:41 +02:00
|
|
|
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
|
2022-08-03 14:23:24 +02:00
|
|
|
void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } // automatically inline
|
2022-07-17 15:58:41 +02:00
|
|
|
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); }
|
2022-08-03 14:23:24 +02:00
|
|
|
void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); }
|
2022-07-17 15:58:41 +02:00
|
|
|
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);
|
2022-08-03 14:23:24 +02:00
|
|
|
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); }
|
2023-04-27 17:31:55 +02:00
|
|
|
void addPixelColorXY(int x, int y, uint32_t color, bool fast = false);
|
|
|
|
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); } // automatically inline
|
|
|
|
void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), fast); }
|
2022-08-02 18:27:32 +02:00
|
|
|
void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade);
|
|
|
|
void box_blur(uint16_t i, bool vertical, fract8 blur_amount); // 1D box blur (with weight)
|
2022-08-02 19:44:27 +02:00
|
|
|
void blurRow(uint16_t row, fract8 blur_amount);
|
|
|
|
void blurCol(uint16_t col, fract8 blur_amount);
|
2023-04-27 17:31:55 +02: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);
|
2023-01-06 09:10:39 +01:00
|
|
|
void draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c);
|
2022-08-02 18:27:32 +02:00
|
|
|
void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c);
|
2022-08-03 14:23:24 +02:00
|
|
|
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c);
|
|
|
|
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0)); } // automatic inline
|
2023-08-16 21:02:00 +02: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, uint8_t rotate = 0);
|
2022-08-03 14:23:24 +02:00
|
|
|
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
|
2023-08-16 21:02:00 +02:00
|
|
|
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2, uint8_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 14:23:24 +02:00
|
|
|
void wu_pixel(uint32_t x, uint32_t y, CRGB c);
|
2022-08-05 23:03:38 +02:00
|
|
|
void blur1d(fract8 blur_amount); // blur all rows in 1 dimension
|
|
|
|
void blur2d(fract8 blur_amount) { blur(blur_amount); }
|
|
|
|
void fill_solid(CRGB c) { fill(RGBW32(c.r,c.g,c.b,0)); }
|
|
|
|
void nscale8(uint8_t scale);
|
2022-08-03 14:23:24 +02:00
|
|
|
#else
|
|
|
|
uint16_t XY(uint16_t x, uint16_t y) { return x; }
|
|
|
|
void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(x, c); }
|
|
|
|
void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColor(x, RGBW32(r,g,b,w)); }
|
|
|
|
void setPixelColorXY(int x, int y, CRGB c) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0)); }
|
|
|
|
void setPixelColorXY(float x, float y, uint32_t c, bool aa = true) { setPixelColor(x, c, aa); }
|
|
|
|
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); }
|
|
|
|
void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0), aa); }
|
|
|
|
uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(x); }
|
|
|
|
void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t c, uint8_t blend) { blendPixelColor(x, c, blend); }
|
|
|
|
void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColor(x, RGBW32(c.r,c.g,c.b,0), blend); }
|
2023-04-27 17:31:55 +02:00
|
|
|
void addPixelColorXY(int x, int y, uint32_t color, bool fast = false) { addPixelColor(x, color, fast); }
|
|
|
|
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); }
|
|
|
|
void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColor(x, RGBW32(c.r,c.g,c.b,0), fast); }
|
2022-08-03 14:23:24 +02:00
|
|
|
void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { fadePixelColor(x, fade); }
|
|
|
|
void box_blur(uint16_t i, bool vertical, fract8 blur_amount) {}
|
2022-08-05 23:03:38 +02:00
|
|
|
void blurRow(uint16_t row, fract8 blur_amount) {}
|
|
|
|
void blurCol(uint16_t col, fract8 blur_amount) {}
|
2023-04-27 17:31:55 +02: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) {}
|
2022-08-03 14:23:24 +02:00
|
|
|
void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c) {}
|
|
|
|
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) {}
|
|
|
|
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) {}
|
|
|
|
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color) {}
|
|
|
|
void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color) {}
|
|
|
|
void wu_pixel(uint32_t x, uint32_t y, CRGB c) {}
|
|
|
|
#endif
|
2022-07-17 15:58:41 +02:00
|
|
|
} segment;
|
2022-08-19 21:14:49 +02:00
|
|
|
//static int segSize = sizeof(Segment);
|
2022-07-06 13:13:54 +02:00
|
|
|
|
|
|
|
// main "strip" class
|
2022-07-10 22:23:25 +02:00
|
|
|
class WS2812FX { // 96 bytes
|
2022-07-06 13:13:54 +02:00
|
|
|
typedef uint16_t (*mode_ptr)(void); // pointer to mode function
|
|
|
|
typedef void (*show_callback)(void); // pre show callback
|
2022-07-17 15:58:41 +02:00
|
|
|
typedef struct ModeData {
|
2022-07-29 12:15:56 +02:00
|
|
|
uint8_t _id; // mode (effect) id
|
2022-07-17 15:58:41 +02:00
|
|
|
mode_ptr _fcn; // mode (effect) function
|
2022-07-29 12:15:56 +02: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 15:58:41 +02:00
|
|
|
} mode_data_t;
|
2021-01-09 00:35:48 +01:00
|
|
|
|
|
|
|
static WS2812FX* instance;
|
2023-01-06 09:10:39 +01:00
|
|
|
|
2016-12-17 23:43:07 +01:00
|
|
|
public:
|
2022-05-08 10:50:48 +02:00
|
|
|
|
2022-07-19 16:16:43 +02:00
|
|
|
WS2812FX() :
|
|
|
|
paletteFade(0),
|
|
|
|
paletteBlend(0),
|
|
|
|
milliampsPerLed(55),
|
|
|
|
cctBlending(0),
|
|
|
|
ablMilliampsMax(ABL_MILLIAMPS_DEFAULT),
|
|
|
|
currentMilliamps(0),
|
|
|
|
now(millis()),
|
|
|
|
timebase(0),
|
|
|
|
isMatrix(false),
|
|
|
|
#ifndef WLED_DISABLE_2D
|
2023-01-02 20:56:00 +01:00
|
|
|
panels(1),
|
2022-07-19 16:16:43 +02:00
|
|
|
#endif
|
2022-07-29 12:15:56 +02:00
|
|
|
// semi-private (just obscured) used in effect functions through macros
|
2022-07-28 23:19:58 +02:00
|
|
|
_currentPalette(CRGBPalette16(CRGB::Black)),
|
2022-07-19 16:16:43 +02:00
|
|
|
_colors_t{0,0,0},
|
|
|
|
_virtualSegmentLength(0),
|
2022-07-29 12:15:56 +02:00
|
|
|
// true private variables
|
2022-07-19 16:16:43 +02:00
|
|
|
_length(DEFAULT_LED_COUNT),
|
|
|
|
_brightness(DEFAULT_BRIGHTNESS),
|
|
|
|
_transitionDur(750),
|
2022-08-24 23:04:51 +02:00
|
|
|
_targetFps(WLED_FPS),
|
|
|
|
_frametime(FRAMETIME_FIXED),
|
2022-07-19 16:16:43 +02: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),
|
2023-07-13 13:08:36 +02:00
|
|
|
_mainSegment(0),
|
|
|
|
_queuedChangesSegId(255),
|
|
|
|
_qStart(0),
|
|
|
|
_qStop(0),
|
|
|
|
_qStartY(0),
|
|
|
|
_qStopY(0),
|
|
|
|
_qGrouping(0),
|
|
|
|
_qSpacing(0),
|
|
|
|
_qOffset(0)
|
2022-07-19 16:16:43 +02:00
|
|
|
{
|
2021-01-09 00:35:48 +01:00
|
|
|
WS2812FX::instance = this;
|
2022-08-08 10:21:11 +02: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 15:58:41 +02:00
|
|
|
else setupEffectData();
|
2016-12-17 23:43:07 +01:00
|
|
|
}
|
|
|
|
|
2022-07-10 22:23:25 +02:00
|
|
|
~WS2812FX() {
|
2022-07-19 16:16:43 +02:00
|
|
|
if (customMappingTable) delete[] customMappingTable;
|
2022-07-17 15:58:41 +02:00
|
|
|
_mode.clear();
|
|
|
|
_modeData.clear();
|
2022-07-19 16:16:43 +02:00
|
|
|
_segments.clear();
|
2023-01-02 21:24:02 +01:00
|
|
|
#ifndef WLED_DISABLE_2D
|
2023-01-02 20:56:00 +01:00
|
|
|
panel.clear();
|
2023-01-02 21:24:02 +01:00
|
|
|
#endif
|
2022-07-29 12:15:56 +02:00
|
|
|
customPalettes.clear();
|
2022-07-10 22:23:25 +02:00
|
|
|
}
|
|
|
|
|
2022-07-06 13:13:54 +02:00
|
|
|
static WS2812FX* getInstance(void) { return instance; }
|
|
|
|
|
2016-12-17 23:43:07 +01:00
|
|
|
void
|
2022-08-03 21:36:47 +02:00
|
|
|
#ifdef WLED_DEBUG
|
|
|
|
printSize(),
|
|
|
|
#endif
|
2021-10-11 02:19:33 +02:00
|
|
|
finalizeInit(),
|
2016-12-17 23:43:07 +01:00
|
|
|
service(void),
|
2019-06-20 14:40:12 +02:00
|
|
|
setMode(uint8_t segid, uint8_t m),
|
|
|
|
setColor(uint8_t slot, uint32_t c),
|
2022-02-23 19:20:07 +01:00
|
|
|
setCCT(uint16_t k),
|
2022-03-10 20:40:48 +01:00
|
|
|
setBrightness(uint8_t b, bool direct = false),
|
2018-09-04 15:51:38 +02:00
|
|
|
setRange(uint16_t i, uint16_t i2, uint32_t col),
|
2018-09-06 02:05:56 +02:00
|
|
|
setTransitionMode(bool t),
|
2022-08-03 21:36:47 +02:00
|
|
|
purgeSegments(bool force = false),
|
2022-07-17 15:58:41 +02: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 22:24:11 +01:00
|
|
|
setMainSegmentId(uint8_t n),
|
2021-12-20 11:29:03 +01:00
|
|
|
restartRuntime(),
|
2018-09-04 15:51:38 +02:00
|
|
|
resetSegments(),
|
2022-02-10 16:09:16 +01:00
|
|
|
makeAutoSegments(bool forceReset = false),
|
2021-10-11 02:19:33 +02:00
|
|
|
fixInvalidSegments(),
|
2022-07-10 22:23:25 +02:00
|
|
|
setPixelColor(int n, uint32_t c),
|
2020-02-22 17:20:34 +01:00
|
|
|
show(void),
|
2023-02-11 18:41:30 +01:00
|
|
|
setTargetFps(uint8_t fps);
|
2016-12-17 23:43:07 +01:00
|
|
|
|
2023-03-11 15:03:28 +01:00
|
|
|
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)); }
|
|
|
|
void fill(uint32_t c) { for (int i = 0; i < getLengthTotal(); i++) setPixelColor(i, c); } // fill whole strip with color (inline)
|
2022-07-10 22:23:25 +02:00
|
|
|
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
|
2022-06-21 22:49:45 +02:00
|
|
|
|
2022-06-23 17:42:02 +02:00
|
|
|
// outsmart the compiler :) by correctly overloading
|
2022-07-10 22:23:25 +02:00
|
|
|
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); }
|
2022-07-06 13:13:54 +02:00
|
|
|
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; }
|
2023-07-13 13:08:36 +02:00
|
|
|
inline void appendSegment(const Segment &seg = Segment()) { if (_segments.size() < getMaxSegments()) _segments.push_back(seg); }
|
2022-03-25 16:36:05 +01:00
|
|
|
|
2018-11-24 11:52:23 +01:00
|
|
|
bool
|
2021-10-11 02:19:33 +02:00
|
|
|
checkSegmentAlignment(void),
|
2022-02-20 22:24:11 +01:00
|
|
|
hasRGBWBus(void),
|
|
|
|
hasCCTBus(void),
|
2020-12-10 05:29:53 +01:00
|
|
|
// return true if the strip is being sent pixel updates
|
2022-07-31 12:38:10 +02:00
|
|
|
isUpdating(void),
|
2023-06-30 21:12:59 +02:00
|
|
|
deserializeMap(uint8_t n=0);
|
2018-11-24 11:52:23 +01:00
|
|
|
|
2022-07-19 16:16:43 +02:00
|
|
|
inline bool isServicing(void) { return _isServicing; }
|
2022-07-06 13:13:54 +02:00
|
|
|
inline bool hasWhiteChannel(void) {return _hasWhiteChannel;}
|
|
|
|
inline bool isOffRefreshRequired(void) {return _isOffRefreshRequired;}
|
|
|
|
|
2018-09-04 15:51:38 +02:00
|
|
|
uint8_t
|
2022-07-19 16:16:43 +02:00
|
|
|
paletteFade,
|
|
|
|
paletteBlend,
|
|
|
|
milliampsPerLed,
|
|
|
|
cctBlending,
|
|
|
|
getActiveSegmentsNum(void),
|
2022-02-23 19:20:07 +01:00
|
|
|
getFirstSelectedSegId(void),
|
2022-02-20 22:24:11 +01:00
|
|
|
getLastActiveSegmentId(void),
|
2023-05-31 20:12:17 +02:00
|
|
|
getActiveSegsLightCapabilities(bool selectedOnly = false),
|
2022-07-30 23:58:29 +02:00
|
|
|
setPixelSegment(uint8_t n);
|
2016-12-17 23:43:07 +01:00
|
|
|
|
2022-07-06 13:13:54 +02:00
|
|
|
inline uint8_t getBrightness(void) { return _brightness; }
|
2022-07-17 15:58:41 +02:00
|
|
|
inline uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value)
|
2022-07-19 16:16:43 +02:00
|
|
|
inline uint8_t getSegmentsNum(void) { return _segments.size(); } // returns currently present segments
|
2022-07-06 13:13:54 +02:00
|
|
|
inline uint8_t getCurrSegmentId(void) { return _segment_index; }
|
|
|
|
inline uint8_t getMainSegmentId(void) { return _mainSegment; }
|
2022-11-25 17:33:29 +01:00
|
|
|
inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } // will only return built-in palette count
|
2022-07-06 13:13:54 +02:00
|
|
|
inline uint8_t getTargetFps() { return _targetFps; }
|
2022-06-26 23:01:22 +02:00
|
|
|
inline uint8_t getModeCount() { return _modeCount; }
|
2020-09-27 14:42:14 +02:00
|
|
|
|
2019-08-30 15:39:34 +02:00
|
|
|
uint16_t
|
|
|
|
ablMilliampsMax,
|
2019-12-01 01:42:52 +01:00
|
|
|
currentMilliamps,
|
2021-10-11 02:19:53 +02:00
|
|
|
getLengthPhysical(void),
|
2023-03-11 15:03:28 +01:00
|
|
|
getLengthTotal(void), // will include virtual/nonexistent pixels in matrix
|
2021-02-05 01:33:26 +01:00
|
|
|
getFps();
|
2019-08-30 15:39:34 +02:00
|
|
|
|
2022-07-06 13:13:54 +02:00
|
|
|
inline uint16_t getFrameTime(void) { return _frametime; }
|
|
|
|
inline uint16_t getMinShowDelay(void) { return MIN_SHOW_DELAY; }
|
2023-03-11 15:03:28 +01:00
|
|
|
inline uint16_t getLength(void) { return _length; } // 2D matrix may have less pixels than W*H
|
2022-07-10 22:23:25 +02:00
|
|
|
inline uint16_t getTransition(void) { return _transitionDur; }
|
2022-06-17 18:57:32 +02:00
|
|
|
|
2016-12-17 23:43:07 +01:00
|
|
|
uint32_t
|
2020-08-25 17:23:17 +02:00
|
|
|
now,
|
2019-10-18 12:19:52 +02:00
|
|
|
timebase,
|
2022-02-23 19:20:07 +01:00
|
|
|
getPixelColor(uint16_t);
|
2016-12-17 23:43:07 +01:00
|
|
|
|
2022-07-06 13:13:54 +02:00
|
|
|
inline uint32_t getLastShow(void) { return _lastShow; }
|
|
|
|
inline uint32_t segColor(uint8_t i) { return _colors_t[i]; }
|
|
|
|
|
2022-06-21 22:49:45 +02:00
|
|
|
const char *
|
2022-07-10 22:23:25 +02:00
|
|
|
getModeData(uint8_t id = 0) { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); }
|
2022-06-21 22:49:45 +02:00
|
|
|
|
|
|
|
const char **
|
2022-07-17 15:58:41 +02:00
|
|
|
getModeDataSrc(void) { return &(_modeData[0]); } // vectors use arrays for underlying data
|
2022-06-21 22:49:45 +02:00
|
|
|
|
2022-08-03 14:23:24 +02:00
|
|
|
Segment& getSegment(uint8_t id);
|
2022-07-06 13:13:54 +02:00
|
|
|
inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; }
|
2022-08-03 14:23:24 +02:00
|
|
|
inline Segment& getMainSegment(void) { return _segments[getMainSegmentId()]; }
|
|
|
|
inline Segment* getSegments(void) { return &(_segments[0]); }
|
2018-09-04 15:51:38 +02:00
|
|
|
|
2022-07-06 13:13:54 +02:00
|
|
|
// 2D support (panels)
|
2022-05-08 10:50:48 +02:00
|
|
|
bool
|
2022-07-19 16:16:43 +02:00
|
|
|
isMatrix;
|
2022-05-08 10:50:48 +02:00
|
|
|
|
2022-07-10 22:23:25 +02:00
|
|
|
#ifndef WLED_DISABLE_2D
|
|
|
|
#define WLED_MAX_PANELS 64
|
2022-05-08 10:50:48 +02:00
|
|
|
uint8_t
|
2023-01-02 20:56:00 +01:00
|
|
|
panels;
|
2022-05-08 10:50:48 +02:00
|
|
|
|
2023-01-02 20:56:00 +01: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 22:56:14 +01:00
|
|
|
panel_t()
|
|
|
|
: xOffset(0)
|
|
|
|
, yOffset(0)
|
|
|
|
, width(8)
|
|
|
|
, height(8)
|
|
|
|
, options(0)
|
|
|
|
{}
|
2022-05-08 10:50:48 +02:00
|
|
|
} Panel;
|
2023-01-02 20:56:00 +01:00
|
|
|
std::vector<Panel> panel;
|
2022-07-10 22:23:25 +02:00
|
|
|
#endif
|
2022-05-08 10:50:48 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
setUpMatrix(),
|
2022-07-10 22:23:25 +02:00
|
|
|
setPixelColorXY(int x, int y, uint32_t c);
|
2022-05-08 10:50:48 +02:00
|
|
|
|
2022-06-23 17:42:02 +02:00
|
|
|
// outsmart the compiler :) by correctly overloading
|
2022-07-10 22:23:25 +02: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)); } // automatically inline
|
2022-08-03 14:23:24 +02:00
|
|
|
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); }
|
2022-05-08 10:50:48 +02:00
|
|
|
|
|
|
|
uint32_t
|
|
|
|
getPixelColorXY(uint16_t, uint16_t);
|
|
|
|
|
2022-07-06 13:13:54 +02:00
|
|
|
// end 2D support
|
2022-05-08 10:50:48 +02:00
|
|
|
|
2022-07-29 12:15:56 +02:00
|
|
|
void loadCustomPalettes(void); // loads custom palettes from JSON
|
2022-07-28 23:19:58 +02:00
|
|
|
CRGBPalette16 _currentPalette; // palette used for current effect (includes transition)
|
2022-07-29 12:15:56 +02:00
|
|
|
std::vector<CRGBPalette16> customPalettes; // TODO: move custom palettes out of WS2812FX class
|
2019-10-02 01:17:26 +02:00
|
|
|
|
2022-07-17 15:58:41 +02:00
|
|
|
// using public variables to reduce code size increase due to inline function getSegment() (with bounds checking)
|
|
|
|
// and color transitions
|
2022-07-28 23:19:58 +02:00
|
|
|
uint32_t _colors_t[3]; // color used for effect (includes transition)
|
2022-07-10 22:23:25 +02:00
|
|
|
uint16_t _virtualSegmentLength;
|
|
|
|
|
2022-07-29 12:15:56 +02:00
|
|
|
std::vector<segment> _segments;
|
2022-07-10 22:23:25 +02:00
|
|
|
friend class Segment;
|
|
|
|
|
2022-07-06 13:13:54 +02:00
|
|
|
private:
|
2022-07-10 22:23:25 +02:00
|
|
|
uint16_t _length;
|
2023-06-30 21:12:59 +02:00
|
|
|
uint8_t _brightness;
|
2022-07-19 16:16:43 +02:00
|
|
|
uint16_t _transitionDur;
|
|
|
|
|
2022-08-24 23:04:51 +02:00
|
|
|
uint8_t _targetFps;
|
|
|
|
uint16_t _frametime;
|
2022-07-19 16:16:43 +02:00
|
|
|
uint16_t _cumulativeFps;
|
|
|
|
|
|
|
|
// will require only 1 byte
|
2022-07-28 23:19:58 +02: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 12:15:56 +02:00
|
|
|
|
|
|
|
uint8_t _modeCount;
|
2022-07-17 15:58:41 +02: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 16:16:43 +02:00
|
|
|
show_callback _callback;
|
2016-12-17 23:43:07 +01:00
|
|
|
|
2022-07-19 16:16:43 +02:00
|
|
|
uint16_t* customMappingTable;
|
|
|
|
uint16_t customMappingSize;
|
2023-01-06 09:10:39 +01:00
|
|
|
|
2023-07-12 20:52:34 +02:00
|
|
|
unsigned long _lastShow;
|
2023-01-06 09:10:39 +01:00
|
|
|
|
2022-07-19 16:16:43 +02:00
|
|
|
uint8_t _segment_index;
|
2022-02-20 22:24:11 +01:00
|
|
|
uint8_t _mainSegment;
|
2023-07-13 13:08:36 +02:00
|
|
|
uint8_t _queuedChangesSegId;
|
|
|
|
uint16_t _qStart, _qStop, _qStartY, _qStopY;
|
|
|
|
uint8_t _qGrouping, _qSpacing;
|
|
|
|
uint16_t _qOffset;
|
2022-02-20 22:24:11 +01:00
|
|
|
|
2023-06-26 22:12:32 +02:00
|
|
|
uint8_t
|
2022-07-28 23:19:58 +02:00
|
|
|
estimateCurrentAndLimitBri(void);
|
2023-07-13 13:08:36 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
setUpSegmentFromQueuedChanges(void);
|
2016-12-17 23:43:07 +01:00
|
|
|
};
|
2019-02-10 23:05:06 +01:00
|
|
|
|
2021-12-28 18:09:52 +01:00
|
|
|
extern const char JSON_mode_names[];
|
|
|
|
extern const char JSON_palette_names[];
|
|
|
|
|
2016-12-17 23:43:07 +01:00
|
|
|
#endif
|