RSeries astromech firmware
LogicEngine.h
Go to the documentation of this file.
1 #ifndef LOGICENGINE_H
2 #define LOGICENGINE_H
3 
4 #include "ReelTwo.h"
5 #include "core/LEDPixelEngine.h"
6 #include "core/SetupEvent.h"
7 #include "core/AnimatedEvent.h"
8 #include "core/CommandEvent.h"
9 #include "core/JawaEvent.h"
10 #include "core/PeakValueProvider.h"
11 #include "core/Font.h"
12 
13 #ifndef FRONT_LOGIC_PIN
14  #if defined(REELTWO_TEENSY)
15  #define FRONT_LOGIC_PIN 21
16  #elif defined(REELTWO_ZERO)
17  #define FRONT_LOGIC_PIN 5
18  #elif defined(REELTWO_AVR_MEGA)
19  #define FRONT_LOGIC_PIN 5
20  #elif defined(REELTWO_AVR)
21  /* Pro Mini only supports either front or rear logic */
22  #define FRONT_LOGIC_PIN 6
23  #elif defined(REELTWO_RP2040)
24  #define FRONT_LOGIC_PIN 15
25  #define FRONT_LOGIC_CLOCK_PIN 2
26  #elif defined(ESP32)
27  #define FRONT_LOGIC_PIN 15
28  #define FRONT_LOGIC_CLOCK_PIN 2
29  #else
30  #error Unsupported platform
31  #endif
32 #endif
33 
34 #ifndef REAR_LOGIC_PIN
35  #if defined(REELTWO_TEENSY)
36  #define REAR_LOGIC_PIN 22
37  #elif defined(REELTWO_ZERO)
38  #define REAR_LOGIC_PIN 3
39  #elif defined(REELTWO_AVR_MEGA)
40  #define REAR_LOGIC_PIN 6
41  #define REAR_LOGIC_CLOCK_PIN 7
42  #elif defined(REELTWO_AVR)
43  /* Pro Mini only supports either front or rear logic */
44  #define REAR_LOGIC_PIN 6
45  #elif defined(REELTWO_RP2040)
46  #define REAR_LOGIC_PIN 33
47  #define REAR_LOGIC_CLOCK_PIN 32
48  #elif defined(ESP32)
49  #define REAR_LOGIC_PIN 33
50  #define REAR_LOGIC_CLOCK_PIN 32
51  #else
52  #error Unsupported platform
53  #endif
54 #endif
55 
68 struct LEDStatus
69 {
73  byte fColorNum;
74 
79 };
80 
88 {
89 public:
90  static constexpr byte FRONT_FADE = 1;
91  static constexpr byte FRONT_DELAY = 10;
92  static constexpr byte FRONT_HUE = 0;
93 
94  static constexpr byte REAR_FADE = 3;
95  static constexpr byte REAR_DELAY = 40;
96  static constexpr byte REAR_HUE = 0;
97 
98  static constexpr byte FRONT_PAL = 0;
99  static constexpr byte REAR_PAL = 1;
100 
101  static constexpr byte FRONT_PSI_PAL = 4;
102  static constexpr byte REAR_PSI_PAL = 5;
103 
104  static constexpr byte FRONT_BRI = 160; //changed from 180 to bring down default current draw under 500mA
105  static constexpr byte REAR_BRI = 140; //changed from 180 to bring down default current draw under 500mA
106 
107  static constexpr byte MAX_BRIGHTNESS = 225; //can go up to 255, but why? this limit keeps current and heat down, and not noticeably dimmer than 255
108  static constexpr byte MIN_BRIGHTNESS = 1; //minimum brightness for standard logic patterns that adjustment pots can go down to
109 
110  static constexpr uint32_t NORMVAL = 0;
111  static constexpr byte PAL_COUNT = 6;
112 
113  /* Values should match array offsets in LogicEffectDefaultSelector() */
114  static constexpr byte NORMAL = 0;
115  static constexpr byte ALARM = 1;
116  static constexpr byte FAILURE = 2;
117  static constexpr byte LEIA = 3;
118  static constexpr byte MARCH = 4;
119  static constexpr byte SOLIDCOLOR = 5;
120  static constexpr byte FLASHCOLOR = 6;
121  static constexpr byte FLIPFLOPCOLOR = 7;
122  static constexpr byte FLIPFLOPALTCOLOR = 8;
123  static constexpr byte COLORSWAP = 9;
124  static constexpr byte RAINBOW = 10;
125  static constexpr byte REDALERT = 11;
126  static constexpr byte MICBRIGHT = 12;
127  static constexpr byte MICRAINBOW = 13;
128  static constexpr byte LIGHTSOUT = 14;
129  static constexpr byte TEXT = 15;
130  static constexpr byte TEXTSCROLLLEFT = 16;
131  static constexpr byte TEXTSCROLLRIGHT = 17;
132  static constexpr byte TEXTSCROLLUP = 18;
133  static constexpr byte ROAMINGPIXEL = 19;
134  static constexpr byte HORIZONTALSCANLINE = 20;
135  static constexpr byte VERTICALSCANLINE = 21;
136  static constexpr byte FIRE = 22;
137  static constexpr byte PSICOLORWIPE = 23;
138  static constexpr byte PULSE = 24;
139  static constexpr byte RANDOM = 99;
140  // static constexpr byte TESTROW = 90;
141  // static constexpr byte TESTCOL = 91;
142 
143  enum ColorVal
144  {
145  kRed = 1,
146  kOrange = 2,
147  kYellow = 3,
148  kGreen = 4,
149  kCyan = 5,
150  kBlue = 6,
151  kPurple = 7,
152  kMagenta = 8,
153  kPink = 9,
155  };
156 
160  static long sequence(byte seq, ColorVal colorVal = kDefault, uint8_t speedScale = 0, uint8_t numSeconds = 0)
161  {
162  return(
163  (long int)seq * 10000L +
164  (long int)colorVal * 1000L +
165  (long int)speedScale * 100 +
166  numSeconds);
167  }
168 };
169 
177 {
178 public:
181  byte fade,
182  byte hue,
183  byte delay,
184  byte palNum,
185  byte bri,
186  long defaultEffect = 0) :
187  fFade(fade),
188  fHue(hue),
189  fDelay(delay),
190  fPalNum(palNum),
191  fBri(bri),
192  fDefaultEffect(defaultEffect)
193  {
194  }
195 
196  byte fFade;
197  byte fHue;
198  byte fDelay;
199  byte fPalNum;
200  byte fBri;
202 };
203 
205 //
206 // HARDWARE PCB DEFINITIONS
207 //
209 
210 #if USE_LEDLIB == 0
211 template <template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN,
213  unsigned _count = 1, unsigned _start = 0, unsigned _end = 1, unsigned _width = 1, unsigned _height = 1>
214 class FastLEDPCB
215 #elif USE_LEDLIB == 1
217 template <LEDChipset CHIPSET, uint8_t DATA_PIN,
218  unsigned _count = 1, unsigned _start = 0, unsigned _end = 1, unsigned _width = 1, unsigned _height = 1>
219 class FastLEDPCB : private Adafruit_NeoPixel
220 #else
221  #error Unsupported
222 #endif
223 {
224 public:
225  static const int count = _count;
226  static const int start = _start;
227  static const int end = _end;
228  static const int width = _width;
229  static const int height = _height;
230 
231  void init()
232  {
233  #if USE_LEDLIB == 0
234  FastLED.addLeds<CHIPSET, DATA_PIN, GRB>(fLED, count);
235  fill_solid(fLED, _count, CRGB(0,0,0));
236  #elif USE_LEDLIB == 1
237  // Avoid call to malloc()
238  updateType(CHIPSET);
239  numBytes = count * 3;
240  pixels = (uint8_t*)&fLED;
241  memset(fLED, '\0', sizeof(fLED));
242  setPin(DATA_PIN);
244  #else
245  #error Not supported
246  #endif
247  }
248 
249 #if USE_LEDLIB == 1
250  void show()
251  {
253  Adafruit_NeoPixel::show();
255  }
256 #endif
257 
258  CRGB fLED[count];
259  LEDStatus fLEDStatus[count];
260 };
261 
262 #if USE_LEDLIB == 0
263 template <ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER,
265  unsigned _count, unsigned _start, unsigned _end, unsigned _width, unsigned _height>
266 class FastLEDPCBClock
267 {
268 public:
269  static const int count = _count;
270  static const int start = _start;
271  static const int end = _end;
272  static const int width = _width;
273  static const int height = _height;
274 
275  void init()
276  {
277  FastLED.addLeds<CHIPSET, DATA_PIN, CLOCK_PIN, RGB_ORDER>(fLED, count);
278  fill_solid(fLED, _count, CRGB(0,0,0));
279  }
280 
281  CRGB fLED[count];
282  LEDStatus fLEDStatus[count];
283 };
284 #endif
285 
287 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
288 class LogicEngineFLDPCB0 : public FastLEDPCB<WS2812B, DATA_PIN, 96, 8, 88, 8, 10>
289 {
290 public:
291  static inline const byte* getLEDMap()
292  {
293  //Originals (with Naboo logo on backs of Front and Rear Logic)
294  //mapping for FLD boards from first run (with 48 LEDs per PCB)
295  static const byte sLEDmap[] PROGMEM =
296  {
297  15,14,13,12,11,10, 9, 8,
298  16,17,18,19,20,21,22,23,
299  31,30,29,28,27,26,25,24,
300  32,33,34,35,36,37,38,39,
301  47,46,45,44,43,42,41,40,
302  88,89,90,91,92,93,94,95,
303  87,86,85,84,83,82,81,80,
304  72,73,74,75,76,77,78,79,
305  71,70,69,68,67,66,65,64,
306  56,57,58,59,60,61,62,63
307  };
308  return sLEDmap;
309  }
310 };
311 
313 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
314 class LogicEngineFLDPCB1 : public FastLEDPCB<WS2812B, DATA_PIN, 80, 0, 80, 8, 10>
315 {
316 public:
317  static inline const byte* getLEDMap()
318  {
319  //2014 Version (with Kenny & McQuarry art on Rear, C3PO on Fronts)
320  //mapping for newer FLD PCBs (40 LEDs per PCB, lower FLD upside-down)...
321  static const byte sLEDmap[] PROGMEM =
322  {
323  0, 1, 2, 3, 4, 5, 6, 7,
324  15,14,13,12,11,10, 9, 8,
325  16,17,18,19,20,21,22,23,
326  31,30,29,28,27,26,25,24,
327  32,33,34,35,36,37,38,39,
328  79,78,77,76,75,74,73,72,
329  64,65,66,67,68,69,70,71,
330  63,62,61,60,59,58,57,56,
331  48,49,50,51,52,53,54,55,
332  47,46,45,44,43,42,41,40
333  };
334  return sLEDmap;
335  }
336 };
337 
339 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
340 class LogicEngineFLDPCB2 : public FastLEDPCB<SK6812, DATA_PIN, 80, 0, 80, 8, 10>
341 {
342 public:
343  static inline const byte* getLEDMap()
344  {
345  //2014 Version (with Kenny & McQuarry art on Rear, C3PO on Fronts)
346  //mapping for newer FLD PCBs (40 LEDs per PCB, lower FLD upside-down)...
347  static const byte sLEDmap[] PROGMEM =
348  {
349  0, 1, 2, 3, 4, 5, 6, 7,
350  15,14,13,12,11,10, 9, 8,
351  16,17,18,19,20,21,22,23,
352  31,30,29,28,27,26,25,24,
353  32,33,34,35,36,37,38,39,
354  79,78,77,76,75,74,73,72,
355  64,65,66,67,68,69,70,71,
356  63,62,61,60,59,58,57,56,
357  48,49,50,51,52,53,54,55,
358  47,46,45,44,43,42,41,40
359  };
360  return sLEDmap;
361  }
362 };
363 
365 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
366 class LogicEngineFLDPCB2Inverted : public FastLEDPCB<SK6812/*SK6812CUSTOM*/, DATA_PIN, 80, 0, 80, 8, 10>
367 {
368 public:
369  static inline const byte* getLEDMap()
370  {
371  //2014 Version (with Kenny & McQuarry art on Rear, C3PO on Fronts)
372  //mapping for newer FLD PCBs (40 LEDs per PCB, lower FLD upside-down)...
373  static const byte sLEDmap[] PROGMEM =
374  {
375  40,41,42,43,44,45,46,47,
376  55,54,53,52,51,50,49,48,
377  56,57,58,59,60,61,62,63,
378  71,70,69,68,67,66,65,64,
379  72,73,74,75,76,77,78,79,
380  39,38,37,36,35,34,33,32,
381  24,25,26,27,28,29,30,31,
382  23,22,21,20,19,18,17,16,
383  8, 9,10,11,12,13,14,15,
384  7, 6, 5, 4, 3, 2, 1, 0
385  };
386  return sLEDmap;
387  }
388 };
389 
391 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
392 class AstroPixelFLDPCB0 : public FastLEDPCB<WS2812B, DATA_PIN, 90, 0, 90, 9, 10>
393 {
394 public:
395  static inline const byte* getLEDMap()
396  {
397  // 2022 AstroPixel boards by Darren Poulson
398  // Neopixel FLD boards, First Release. 9x5 LEDs per board
399  static const byte sLEDmap[] PROGMEM =
400  {
401  0, 1, 2, 3, 4, 5, 6, 7, 8,
402  17,16,15,14,13,12,11,10, 9,
403  18,19,20,21,22,23,24,25,26,
404  35,34,33,32,31,30,29,28,27,
405  36,37,38,39,40,41,42,43,44,
406  45,46,47,48,49,50,51,52,53,
407  62,61,60,59,58,57,56,55,54,
408  63,64,65,66,67,68,69,70,71,
409  80,79,78,77,76,75,74,73,72,
410  81,82,83,84,85,86,87,88,89
411  };
412  return sLEDmap;
413  }
414 };
416 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
417 class LogicEngineRLDPCB0 : public FastLEDPCB<WS2812B, DATA_PIN, 80, 0, 80, 16, 4>
418 {
419 public:
420  static inline const byte* getLEDMap()
421  {
422  //Originals (with Naboo logo on backs of Front and Rear Logic)
423  //mapping for first RLD (two PCBs soldered together)
424  static const byte sLEDmap[] PROGMEM =
425  {
426  0, 1, 2, 3, 4, 5, 6, 7, 48,49,50,51,52,53,54,55,
427  15,14,13,12,11,10, 9, 8, 63,62,61,60,59,58,57,56,
428  16,17,18,19,20,21,22,23, 64,65,66,67,68,69,70,71,
429  31,30,29,28,27,26,25,24, 79,78,77,76,75,74,73,72,
430  32,33,34,35,36,37,38,39, 80,81,82,83,84,85,86,87,
431  47,46,45,44,43,42,41,40, 95,94,93,92,91,90,89,88
432  };
433  return sLEDmap;
434  }
435 };
436 
438 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
439 class LogicEngineRLDPCBSUPER : public FastLEDPCB<WS2812B, DATA_PIN, 256, 0, 255, 32, 8>
440 {
441 public:
442  static inline const byte* getLEDMap()
443  {
444  static const byte sLEDmap[] PROGMEM =
445  {
446  0, 15, 16, 31, 32, 47, 48, 63, 64, 79, 80, 95, 96,111,112,127,128,143,144,159,160,175,176,191,192,207,208,223,224,239,240,255,
447  1, 14, 17, 30, 33, 46, 49, 62, 65, 78, 81, 94, 97,110,113,126,129,142,145,158,161,174,177,190,193,206,209,222,225,238,241,254,
448  2, 13, 18, 29, 34, 45, 50, 61, 66, 77, 82, 93, 98,109,114,125,130,141,146,157,162,173,178,189,194,205,210,221,226,237,242,253,
449  3, 12, 19, 28, 35, 44, 51, 60, 67, 76, 83, 92, 99,108,115,124,131,140,147,156,163,172,179,188,195,204,211,220,227,236,243,252,
450  4, 11, 20, 27, 36, 43, 52, 59, 68, 75, 84, 91,100,107,116,123,132,139,148,155,164,171,180,187,196,203,212,219,228,235,244,251,
451  5, 10, 21, 26, 37, 42, 53, 58, 69, 74, 85, 90,101,106,117,122,133,138,149,154,165,170,181,186,197,202,213,218,229,234,245,250,
452  6, 9, 22, 25, 38, 41, 54, 57, 70, 73, 86, 89,102,105,118,121,134,137,150,153,166,169,182,185,198,201,214,217,230,233,246,249,
453  7, 8, 23, 24, 39, 40, 55, 56, 71, 72, 87, 88,103,104,119,120,135,136,151,152,167,168,183,184,199,200,215,216,231,232,247,248
454  };
455  return sLEDmap;
456  }
457 };
458 
460 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
461 class LogicEngineRLDPCB1 : public FastLEDPCB<WS2812B, DATA_PIN, 96, 0, 96, 24, 4>
462 {
463 public:
464  static inline const byte* getLEDMap()
465  {
466  //2014 Version (with Kenny & McQuarry art on Rear, C3PO on Fronts)
467  static const byte sLEDmap[] PROGMEM =
468  {
469  0, 1, 2,28, 3,27, 4,26, 5,25, 6, 7, 8, 9,22,10,21,11,20,12,19,13,14,15,
470  31,30,29,32,33,34,35,36,37,38,39,24,23,40,41,42,43,44,45,46,47,18,17,16,
471  64,65,66,63,62,61,60,59,58,57,56,71,72,55,54,53,52,51,50,49,48,77,78,79,
472  95,94,93,67,92,68,91,69,90,70,89,88,87,86,73,85,74,84,75,83,76,82,81,80
473  };
474  return sLEDmap;
475  }
476 };
477 
479 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
480 class LogicEngineRLDPCB2 : public FastLEDPCB<SK6812, DATA_PIN, 96, 0, 96, 24, 4>
481 {
482 public:
483  static inline const byte* getLEDMap()
484  {
485  // 2016 Version (with Deathstar plans on back of Rear Logic)
486  static const byte sLEDmap[] PROGMEM =
487  {
488  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,
489  47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,
490  48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,
491  95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72
492  };
493  return sLEDmap;
494  }
495 };
496 
498 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
499 class LogicEngineRLDPCB2Inverted : public FastLEDPCB<SK6812, DATA_PIN, 96, 0, 96, 24, 4>
500 {
501 public:
502  static inline const byte* getLEDMap()
503  {
504  // 2016 Version (with Deathstar plans on back of Rear Logic)
505  //oops installed upside down
506  static const byte sLEDmap[] PROGMEM =
507  {
508  72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
509  71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,
510  24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
511  23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
512  };
513  return sLEDmap;
514  }
515 };
516 
518 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
519 class AstroPixelRLDPCB0 : public FastLEDPCB<WS2812B, DATA_PIN, 108, 0, 108, 27, 4>
520 {
521 public:
522  static inline const byte* getLEDMap()
523  {
524  // 2022 AstroPixel boards by Darren Poulson
525  static const byte sLEDmap[] PROGMEM =
526  {
527  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,
528  53, 52, 51, 50, 49, 48, 47, 46, 45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,
529  54, 55, 56, 57, 58, 59, 60, 61, 62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
530  107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81
531  };
532  return sLEDmap;
533  }
534 };
535 
536 #if USE_LEDLIB == 0
537 template <uint8_t DATA_PIN = REAR_LOGIC_PIN, uint8_t CLOCK_PIN = REAR_LOGIC_CLOCK_PIN>
539 class LogicEngineRLDPCB3 : public FastLEDPCBClock<SK9822, DATA_PIN, CLOCK_PIN, BGR, 112, 0, 112, 28, 4>
540 {
541 public:
542  static inline const byte* getLEDMap()
543  {
544  // 2020 Version (with Grant Imahara on back of Rear Logic)
545  static const byte sLEDmap[] PROGMEM =
546  {
547  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
548  55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28,
549  56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
550  111,110,109,108,107,106,105, 104,103,102,101,100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84
551  };
552  return sLEDmap;
553  }
554 };
555 
557 template <uint8_t DATA_PIN = REAR_LOGIC_PIN, uint8_t CLOCK_PIN = REAR_LOGIC_CLOCK_PIN>
558 class LogicEngineRLDPCB3Inverted : public FastLEDPCBClock<SK9822, DATA_PIN, CLOCK_PIN, BGR, 112, 0, 112, 28, 4>
559 {
560 public:
561  static inline const byte* getLEDMap()
562  {
563  // 2020 Version (with Grant Imahara on back of Rear Logic)
564  //oops installed upside down
565  static const byte sLEDmap[] PROGMEM =
566  {
567  84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104, 105,106,107,108,109,110,111,
568  83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56,
569  28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
570  27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
571  };
572  return sLEDmap;
573  }
574 };
575 #endif
576 
578 {
579 public:
580  virtual ~LogicEffectObject() {}
581 };
582 
598 {
599 public:
600  typedef bool (*LogicEffect)(LogicEngineRenderer& renderer);
601  typedef LogicEffect (*LogicEffectSelector)(unsigned effectVal);
602  typedef const char* (*LogicMessageSelector)(unsigned index);
603  typedef PROGMEMString (*LogicPMessageSelector)(unsigned index);
604  typedef byte (*LogicRenderGlyph)(char ch, byte fontNum, const CRGB fontColors[], int x, int y, CRGB* leds, const byte* ledMap, int w, int h, byte* glyphHeight);
605 
607  {
608  return ColorVal(random(10));
609  }
610 
611  void selectEffect(long inputNum)
612  {
613  fDisplayEffectVal = inputNum;
614  }
615 
616  inline void selectSequence(byte seq, ColorVal colorVal = kDefault, uint8_t speedScale = 0, uint8_t numSeconds = 0)
617  {
618  selectEffect(sequence(seq, colorVal, speedScale, numSeconds));
619  }
620 
621  inline void selectTextCenter(const char* text, ColorVal colorVal = kDefault, uint8_t speedScale = 0, uint8_t numSeconds = 0)
622  {
623  setTextMessage(text);
624  selectEffect(sequence(TEXT, colorVal, speedScale, numSeconds));
625  }
626 
627  inline void selectScrollTextLeft(const char* text, ColorVal colorVal = kDefault, uint8_t speedScale = 0, uint8_t numSeconds = 0)
628  {
629  setTextMessage(text);
630  selectEffect(sequence(TEXTSCROLLLEFT, colorVal, speedScale, numSeconds));
631  }
632 
633  inline void selectScrollTextRight(const char* text, ColorVal colorVal = kDefault, uint8_t speedScale = 0, uint8_t numSeconds = 0)
634  {
635  setTextMessage(text);
636  selectEffect(sequence(TEXTSCROLLRIGHT, colorVal, speedScale, numSeconds));
637  }
638 
639  inline void selectScrollTextUp(const char* text, ColorVal colorVal = kDefault, uint8_t speedScale = 0, uint8_t numSeconds = 0)
640  {
641  setTextMessage(text);
642  selectEffect(sequence(TEXTSCROLLUP, colorVal, speedScale, numSeconds));
643  }
644 
645  virtual void handleCommand(const char* cmd)
646  {
647  int length = strlen(cmd);
648  if (*cmd++ == 'L' && *cmd++ == 'E')
649  {
650  long int cmdvalue = 0;
651  const char* c = cmd;
652  if (length >= 9)
653  {
654  // Command has id.
655  unsigned reqId = *c++ - '0';
656  if (reqId != getID()) {
657  return;
658  }
659  }
660  while (*c >= '0' && *c <= '9')
661  {
662  cmdvalue = cmdvalue * 10 + (*c++ - '0');
663  }
664  selectEffect(cmdvalue);
665  }
666  }
667 
668  virtual void setup() override
669  {
670  restoreSettings();
671  calculateAllColors(fSettings.fPalNum, fSettings.fBri);
672  for (unsigned i = 0; i < count(); i++)
673  {
674  unsigned index = mapLED(i);
675  LEDStatus* ledStatus = &fLEDStatus[index];
676  ledStatus->fColorNum = random8(fTotalColorsWBIZ);
677  ledStatus->fColorPause = random8();
678  updateMappedLED(index, fSettings.fHue);
679  }
680  fStatusMillis = millis();
681  fDisplayEffectVal = fSettings.fDefaultEffect;
682  }
683 
684  virtual void animate() override
685  {
686  uint32_t currentMillis = millis();
687  if (fLastMillis + 10L > currentMillis)
688  return;
689  fLastMillis = currentMillis;
690  if (currentMillis - fStatusMillis >= fStatusDelay)
691  {
692  fStatusMillis = currentMillis;
693  fFlipFlop = !fFlipFlop;
694  }
695  int selectSequence = (fDisplayEffectVal % 100000000L) / 10000L;
696  int selectLength = (fDisplayEffectVal % 100);
697 
698  // byte peakVal = fPeakSource->getPeakValue();
699  if (hasEffectChanged())
700  {
701  setEffectObject(NULL);
702  restoreSettings();
703  calculateAllColors(fSettings.fPalNum, fSettings.fBri);
704  fStatusDelay = getDefaultEffectDelay();
705  fEffectStartMillis = currentMillis;
706  if (fEffectSelector != NULL)
707  {
708  fLogicEffect = fEffectSelector(selectSequence);
709  }
710  }
711  fEffectMillis = currentMillis - fEffectStartMillis;
712 
713  bool continueEffect = (fLogicEffect != NULL) ? fLogicEffect(*this) : false;
714  fPreviousEffectVal = fDisplayEffectVal;
715  if (!continueEffect || (selectLength > 0 && unsigned(selectLength) * 1000L < fEffectMillis))
716  {
717  if (selectSequence == RANDOM)
718  {
719  // Select next random sequence
720  fPreviousEffectVal = ~fDisplayEffectVal;
721  }
722  else
723  {
724  selectEffect(fSettings.fDefaultEffect); //go back to normal operation if its time
725  }
726  }
727  fPreviousEffect = fDisplayEffect;
728  #if USE_LEDLIB == 0
729  AnimatedEvent::setLoopDoneCallback([]() { FastLED.show(); });
730  #elif USE_LEDLIB == 1
731  show();
732  #else
733  #error Unsupported
734  #endif
735  }
736 
737  inline bool hasEffectChanged()
738  {
739  return (fPreviousEffectVal != fDisplayEffectVal);
740  }
741 
742  inline void resetEffect() {
743  fPreviousEffectVal = ~fDisplayEffectVal;
744  }
745 
746  inline bool hasEffectChangedType()
747  {
748  return (fPreviousEffect != fDisplayEffect);
749  }
750 
751  inline unsigned getID() const
752  {
753  return fID;
754  }
755 
756  static int getNextID()
757  {
758  static int sID;
759  return ++sID;
760  }
761 
762  inline int getEffectColor()
763  {
764  int selectColor = (fDisplayEffectVal % 10000) / 1000;
765  return selectColor;
766  }
767 
768  inline int getEffectHue()
769  {
770  return mapSelectColorToHue(getEffectColor());
771  }
772 
773  inline int getEffectSpeed()
774  {
775  int selectSpeed = (fDisplayEffectVal % 1000) / 100;
776  return selectSpeed;
777  }
778 
779  inline int getEffectLength()
780  {
781  int selectLength = (fDisplayEffectVal % 100);
782  return selectLength;
783  }
784 
785  inline int getEffectTextMsg()
786  {
787  int selectTextMsg = (fDisplayEffectVal % 100000000) / 10000000;
788  return selectTextMsg;
789  }
790 
791  inline unsigned getEffectDuration()
792  {
793  return fEffectMillis;
794  }
795 
796  inline byte getHue()
797  {
798  return fSettings.fHue;
799  }
800 
801  inline void setHue(byte hue)
802  {
803  fSettings.fHue = hue;
804  }
805 
806  inline byte getFade()
807  {
808  return fSettings.fFade;
809  }
810 
811  inline void setFade(byte fade)
812  {
813  fSettings.fFade = fade;
814  }
815 
816  inline byte getDelay()
817  {
818  return fSettings.fDelay;
819  }
820 
821  inline void setDelay(byte delay)
822  {
823  fSettings.fDelay = delay;
824  }
825 
826  inline byte getBrightness()
827  {
828  return fSettings.fBri;
829  }
830 
831  inline void setBrightness(byte bri)
832  {
833  fSettings.fBri = bri;
834  }
835 
836  inline bool getEffectFlip()
837  {
838  return fFlipFlop;
839  }
840 
841  inline void setEffectFlip(bool flip)
842  {
843  fFlipFlop = flip;
844  }
845 
847  {
848  return fEffectObject;
849  }
850 
851  inline uint32_t getEffectData()
852  {
853  return fEffectData;
854  }
855 
857  {
858  if (fEffectObject != NULL)
859  delete fEffectObject;
860  fEffectObject = obj;
861  }
862 
863  inline void setEffectData(uint32_t data)
864  {
865  fEffectData = data;
866  }
867 
868  inline uint32_t getEffectData2()
869  {
870  return fEffectData2;
871  }
872 
873  inline void setEffectData2(uint32_t data)
874  {
875  fEffectData2 = data;
876  }
877 
878  inline void setEffectWidthRange(float percent)
879  {
880  fEffectRange = max(min(1.0f, percent), 0.0f);
881  }
882 
883  inline int getEffectMsgWidth()
884  {
885  return fEffectMsgWidth;
886  }
887 
888  inline int getEffectMsgHeight()
889  {
890  return fEffectMsgHeight;
891  }
892 
893  inline byte getPeakValue()
894  {
895  return (fPeakSource != NULL) ? fPeakSource->getPeakValue() : 0;
896  }
897 
898  static constexpr uint32_t getDefaultEffectDelay()
899  {
900  return 1500;
901  }
902 
903  inline void setEffectDelay(uint32_t effectDelay)
904  {
905  fStatusDelay = effectDelay;
906  }
907 
908  inline int width() const
909  {
910  return fWidth;
911  }
912 
913  inline int height() const
914  {
915  return fHeight;
916  }
917 
918  inline unsigned count() const
919  {
920  return fLEDCount;
921  }
922 
923  inline unsigned mapLED(unsigned index)
924  {
925  return pgm_read_byte(&fLEDMap[index]);
926  }
927 
929  {
930  fEffectSelector = selector;
931  }
932 
933  void setMessageSelector(LogicMessageSelector selector)
934  {
935  fMessageSelector = selector;
936  }
937 
938  void setPMessageSelector(LogicPMessageSelector selector)
939  {
940  fPMessageSelector = selector;
941  }
942 
944  {
945  fPeakSource = &provider;
946  };
947 
948  void set(unsigned index, const struct CRGB& val)
949  {
950  fLED[pgm_read_byte(&fLEDMap[fLEDStart + index])] = val;
951  }
952 
953  void setHSV(unsigned index, uint8_t hue, uint8_t sat, uint8_t val)
954  {
955  fLED[pgm_read_byte(&fLEDMap[fLEDStart + index])].setHSV(hue, sat, val);
956  }
957 
959  {
960  defaultSettings();
961  }
962 
964  {
965  if (++fSettings.fPalNum == PAL_COUNT)
966  fSettings.fPalNum = 0;
967  calculateAllColors(fSettings.fPalNum, fSettings.fBri);
968  }
969 
970  unsigned getCurrentPalette()
971  {
972  return fSettings.fPalNum;
973  }
974 
975  void setPaletteHue(byte palNum, byte hue)
976  {
977  fSettings.fPalNum = palNum;
978  fSettings.fHue = hue;
979  calculateAllColors(fSettings.fPalNum, fSettings.fBri);
980  }
981 
983  {
984  int blackX = int(fEffectRange * width());
985  if (blackX < width())
986  {
987  CRGB blackColor = { 0, 0, 0 };
988  for (int x = blackX; x < width(); x++)
989  {
990  for (int y = 0; y < height(); y++)
991  {
992  fLED[pgm_read_byte(&fLEDMap[y * width() + x])] = blackColor;
993  }
994  }
995  }
996  }
997 
999  {
1000  updateDisplay(fSettings.fBri);
1001  }
1002 
1004  {
1005  updateDisplay((fPeakSource != NULL) ? fPeakSource->getPeakValue() : fSettings.fBri);
1006  }
1007 
1008  void updateDisplay(byte bri)
1009  {
1010  for (unsigned i = fLEDStart; i < fLEDEnd; i++)
1011  updateMappedLED(mapLED(i), fSettings.fHue, bri);
1012  clearBlockedPortion();
1013  }
1014 
1015  void updateDisplaySplitHalf(byte topBri, byte bottomBri)
1016  {
1017  for (unsigned i = fLEDStart; i < count() / 2; i++)
1018  updateMappedLED(mapLED(i), fSettings.fHue, topBri);
1019  for (unsigned i = count() / 2; i < fLEDEnd; i++)
1020  updateMappedLED(mapLED(i), fSettings.fHue, bottomBri);
1021  clearBlockedPortion();
1022  }
1023 
1024  void updateDisplaySplitRowThirds(byte topBri, byte bottomBri)
1025  {
1026  if (width() % 3 == 0)
1027  {
1028  /* row splits evenly into thirds */
1029  bool flip = false;
1030  unsigned index = fLEDStart;
1031  unsigned third = width() / 3;
1032  for (byte row = 0; row < height() * 3; row++)
1033  {
1034  for (byte col = 0; col < third && index < fLEDEnd; col++, index++)
1035  updateMappedLED(mapLED(index), fSettings.fHue, (!flip) ? topBri : bottomBri);
1036  flip = !flip;
1037  }
1038  }
1039  else
1040  {
1041  /* split half instead */
1042  for (unsigned i = fLEDStart; i < count() / 2; i++)
1043  updateMappedLED(mapLED(i), fSettings.fHue, topBri);
1044  for (unsigned i = count() / 2; i < fLEDEnd; i++)
1045  updateMappedLED(mapLED(i), fSettings.fHue, bottomBri);
1046  }
1047  clearBlockedPortion();
1048  }
1049 
1050  unsigned measureText(const char* txt, int &outWidth, int &outHeight)
1051  {
1052  char ch;
1053  int len = 0;
1054  int textWidth = 0;
1055  byte glyphHeight = 0;
1056  outWidth = 0;
1057  outHeight = 0;
1058  fRenderGlyph(' ', fEffectFontNum, NULL, 0, 0, NULL, NULL, 0, 0, &glyphHeight);
1059  while ((ch = *txt++) != '\0')
1060  {
1061  len++;
1062  if (ch == '\n')
1063  {
1064  outWidth = max(outWidth, textWidth);
1065  outHeight += glyphHeight;
1066  textWidth = 0;
1067  continue;
1068  }
1069  textWidth += fRenderGlyph(ch, fEffectFontNum, NULL, 0, 0, NULL, NULL, 0, 0, NULL);
1070  }
1071  outWidth = max(outWidth, textWidth);
1072  outHeight = (outWidth > 0) ? outHeight + glyphHeight : 0;
1073  return len;
1074  }
1075 
1076  unsigned measureText(PROGMEMString ptxt, int &outWidth, int &outHeight)
1077  {
1078  char ch;
1079  int len = 0;
1080  int textWidth = 0;
1081  byte glyphHeight = 0;
1082  const char* txt = (const char*)ptxt;
1083  outWidth = 0;
1084  outHeight = 0;
1085  fRenderGlyph(' ', fEffectFontNum, NULL, 0, 0, NULL, NULL, 0, 0, &glyphHeight);
1086  while ((ch = pgm_read_byte(txt++)) != '\0')
1087  {
1088  len++;
1089  if (ch == '\n')
1090  {
1091  outWidth = max(outWidth, textWidth);
1092  outHeight += glyphHeight;
1093  textWidth = 0;
1094  continue;
1095  }
1096  textWidth += fRenderGlyph(ch, fEffectFontNum, NULL, 0, 0, NULL, NULL, 0, 0, NULL);
1097  }
1098  outWidth = max(outWidth, textWidth);
1099  outHeight = (outWidth > 0) ? outHeight + glyphHeight : 0;
1100  return len;
1101  }
1102 
1103  inline byte getEffectFontNum()
1104  {
1105  return fEffectFontNum;
1106  }
1107 
1108  inline void setEffectFontNum(byte fontNum)
1109  {
1110  fEffectFontNum = fontNum;
1111  /* Recalculate lengths if text is set */
1112  if (fEffectMsgText != NULL)
1113  {
1114  fEffectMsgLen = measureText(fEffectMsgText, fEffectMsgWidth, fEffectMsgHeight);
1115  }
1116  else if (fEffectMsgTextP != NULL)
1117  {
1118  fEffectMsgLen = measureText(fEffectMsgTextP, fEffectMsgWidth, fEffectMsgHeight);
1119  }
1120  }
1121 
1122  inline void setTextMessage(const char* msg)
1123  {
1124  fEffectMsgLen = fEffectMsgWidth = 0;
1125  fEffectMsgText = msg;
1126  fEffectMsgTextP = NULL;
1127  if (fEffectMsgText != NULL)
1128  fEffectMsgLen = measureText(fEffectMsgText, fEffectMsgWidth, fEffectMsgHeight);
1129  }
1130 
1131  void setupTextMessage(int selectTextMsg)
1132  {
1133  fEffectMsgLen = fEffectMsgWidth = 0;
1134  if (selectTextMsg != 0)
1135  {
1136  /* Look for hard coded message */
1137  fEffectMsgTextP = (fPMessageSelector != NULL) ? fPMessageSelector(selectTextMsg) : NULL;
1138  if (fEffectMsgTextP == NULL)
1139  fEffectMsgText = (fMessageSelector != NULL) ? fMessageSelector(selectTextMsg) : NULL;
1140  if (fEffectMsgTextP == NULL && fEffectMsgText == NULL)
1141  fEffectMsgTextP = F("STAR WARS");
1142  }
1143  if (fEffectMsgText != NULL)
1144  {
1145  fEffectMsgLen = measureText(fEffectMsgText, fEffectMsgWidth, fEffectMsgHeight);
1146  }
1147  else if (fEffectMsgTextP != NULL)
1148  {
1149  fEffectMsgLen = measureText(fEffectMsgTextP, fEffectMsgWidth, fEffectMsgHeight);
1150  }
1151  }
1152 
1153  void clear()
1154  {
1155  #if USE_LEDLIB == 0
1156  fill_solid(fLED, count(), CRGB(0,0,0));
1157  #elif USE_LEDLIB == 1
1158  int numToFill = count();
1159  CRGB* leds = fLED;
1160  CRGB color = CRGB(0, 0, 0);
1161  for (int i = 0; i < numToFill; i++)
1162  *leds++ = color;
1163  #endif
1164  }
1165 
1166  void renderText(int x, int y, byte effectHue)
1167  {
1168  CRGB fontColors[3];
1169 
1170  byte hue = fAllColors[0].h + effectHue;
1171  byte sat = fAllColors[0].s;
1172  fontColors[0].setHSV(hue, sat, 1); /* dimmest */
1173  fontColors[1].setHSV(hue, sat, 16);
1174  fontColors[2].setHSV(hue, sat, 64); /* brightest */
1175  clear();
1176  int startx = x;
1177  for (int i = 0; i < fEffectMsgLen; i++)
1178  {
1179  char ch = 0;
1180  if (fEffectMsgText != NULL)
1181  ch = fEffectMsgText[i];
1182  if (fEffectMsgTextP != NULL)
1183  ch = pgm_read_byte(&((const char*)fEffectMsgTextP)[i]);
1184  if (ch == '\n')
1185  {
1186  x = startx;
1187  y += 5;
1188  }
1189  else if (x < width())
1190  {
1191  int adv = fRenderGlyph(ch, fEffectFontNum, fontColors, x, y, fLED, fLEDMap, fWidth, fHeight, NULL);
1192  x += adv;
1193  }
1194  if (y >= height())
1195  break;
1196  }
1197  }
1198 
1200  {
1201  return fLEDStatus;
1202  }
1203 
1204  inline CRGB* getUnmappedLEDs()
1205  {
1206  return fLED;
1207  }
1208 
1209  void setPixel(int x, int y, byte effectHue, byte bri)
1210  {
1211  if (unsigned(x) < unsigned(fEffectRange * width()) && unsigned(y) < unsigned(height()))
1212  {
1213  fLED[pgm_read_byte(&fLEDMap[y * width() + x])].setHSV(
1214  fAllColors[0].h + effectHue, fAllColors[0].s, bri);
1215  }
1216  }
1217 
1218  void setPixelRGB(int x, int y, const struct CRGB& val)
1219  {
1220  if (unsigned(x) < unsigned(fEffectRange * width()) && unsigned(y) < unsigned(height()))
1221  {
1222  fLED[pgm_read_byte(&fLEDMap[y * width() + x])] = val;
1223  }
1224  }
1225 
1226  void setPixelRGB(int x, int y, uint8_t r, uint8_t g, uint8_t b)
1227  {
1228  CRGB color;
1229  color.r = (r / 255.0) * MAX_BRIGHTNESS / 2;
1230  color.g = (g / 255.0) * MAX_BRIGHTNESS / 2;
1231  color.b = (b / 255.0) * MAX_BRIGHTNESS / 2;
1232  setPixelRGB(x, y, color);
1233  }
1234 
1235  //function to calculate all colors based on the chosen colorPalNum
1236  //this will get called during setup(), and also if we've remotely commanded to change color palettes
1237  //NEW: added a "bright" parameter, to allow front and rear brightness to be adjusted independantly
1238  void calculateAllColors(byte colorPalNum, byte brightVal)
1239  {
1240  //we define both all palettes, in case the user wants to try out rear colors on the front etc
1241  // note that these are not RGB colors, they're HSV
1242  // for help calculating HSV color values see http://joymonkey.com/logic/
1243  static const HSVColor keyColors[PAL_COUNT][4] PROGMEM = {
1244  { {170, 255, 0} , {170, 255, 85} , {170, 255, 170} , {170, 0, 170} } , //front colors
1245  { { 90, 235, 0} , { 75, 255, 250} , { 30, 255, 184} , { 0, 255, 250} } , //rear colors (hues: 87=bright green, 79=yellow green, 45=orangey yellow, 0=red)
1246  { { 0, 255, 0} , { 0, 255, 0} , { 0, 255, 100} , { 0, 255, 250} } , //monotone (black to solid red)
1247  { { 0, 255, 0} , { 0, 255, 250} , { 40, 255, 0} , { 40, 255, 250} } , //dual color red and yellow
1248  { {165, 50, 248} , {166, 181, 226} , {165, 223, 89} , {255, 255, 214} } , //blue and red
1249  { {87, 206, 105} , { 79, 255, 214} , { 43, 255, 250} , { 25, 255, 214} } //yellow and green
1250  };
1251  //take a set of 4 key colors from keyColors[3][4][3] and generate 16 colors
1252  // 328P will only have one set of full colors, Teensy will have two
1253  for (byte kcol = 0; kcol < 4; kcol++)
1254  {
1255  //go through each Key color
1256  const HSVColor* wc = &keyColors[colorPalNum][kcol];
1257  HSVColor workColor = {
1258  pgm_read_byte(&wc->h),
1259  pgm_read_byte(&wc->s),
1260  pgm_read_byte(&wc->v)
1261  };
1262  byte tnum = kcol + fTweens * kcol;
1263  HSVColor* tc = &fAllColors[tnum];
1264  tc->h = workColor.h;
1265  tc->s = workColor.s;
1266  //Value (V) is adjusted down to whatever brightness setting we've specified
1267  brightVal = min(brightVal, (byte)MAX_BRIGHTNESS);
1268  tc->v = map8(workColor.v, MIN_BRIGHTNESS, brightVal);
1269  if (tnum + 1 != fTotalColors)
1270  {
1271  const HSVColor* hsvptr = &keyColors[colorPalNum][kcol + 1];
1272  for (byte el = 0; el < 3; el++)
1273  {
1274  //loop through H, S and V from this key to the next
1275  int perStep = int(pgm_read_byte(&hsvptr->c[el]) - workColor.c[el]) / (fTweens + 1);
1276  if (perStep != 0)
1277  {
1278  for (byte tweenCount = 1; tweenCount <= fTweens; tweenCount++)
1279  {
1280  byte val = workColor.c[el] + tweenCount * perStep;
1281  tc[tweenCount].c[el] = (el == 2) ?
1282  map8(val, MIN_BRIGHTNESS, brightVal) : val;
1283  }
1284  }
1285  else
1286  {
1287  //tweens for this element (h,s or v) don't change between this key and the next, fill em up
1288  for (byte tweenCount = 1; tweenCount <= fTweens; tweenCount++)
1289  {
1290  tc[tweenCount].c[el] = (el == 2) ?
1291  map8(workColor.c[el], MIN_BRIGHTNESS, brightVal) : workColor.c[el];
1292  }
1293  }
1294  }
1295  }
1296  }
1297  }
1298 
1300  {
1301  calculateAllColors(fSettings.fPalNum, fSettings.fBri);
1302  }
1303 
1304  void updateMappedLED(unsigned index, byte hueVal, byte briVal = 255)
1305  {
1306  LEDStatus* ledStatus = &fLEDStatus[index];
1307  if (ledStatus->fColorPause != 0)
1308  {
1309  ledStatus->fColorPause--; //reduce the LEDs pause number and check back next loop
1310  }
1311  else
1312  {
1313  ledStatus->fColorNum++;
1314  if (ledStatus->fColorNum >= fTotalColorsWBIZ)
1315  ledStatus->fColorNum = 0; //bring it back to color zero
1316  byte realColor = actualColorNum(ledStatus->fColorNum);
1317  ledStatus->fColorPause =
1318  (ledStatus->fColorNum % 5 == 0) ?
1319  random8(fSettings.fDelay) : //color is a key, assign random pause
1320  fSettings.fFade; //color is a tween, assign a quick pause
1321 
1322  HSVColor* myColor = &fAllColors[realColor];
1323  fLED[index].setHSV(myColor->h + hueVal, myColor->s,
1324  (briVal == 255) ? myColor->v : map8(briVal, 0, myColor->v));
1325  }
1326  }
1327 
1328  virtual void jawaCommand(char cmd, int arg, int value) override
1329  {
1330  UNUSED_ARG(value)
1331  switch (cmd)
1332  {
1333  case 'A':
1334  case 'D':
1335  selectEffect(NORMVAL);
1336  break;
1337  case 'C':
1338  // TODO Message scroll speed
1339  break;
1340  case 'F':
1341  fSettings.fFade = arg;
1342  break;
1343  case 'G':
1344  fSettings.fDelay = arg;
1345  break;
1346  case 'H':
1347  fSettings.fHue = arg;
1348  break;
1349  case 'J':
1350  fSettings.fBri = arg;
1351  calculateAllColors();
1352  break;
1353  case 'P':
1354  switch (arg)
1355  {
1356  case 60:
1357  // Latin
1358  break;
1359  case 61:
1360  // Aurabesh
1361  break;
1362  case 70:
1363  defaultSettings();
1364  break;
1365  case 71:
1366  // Load from persistent
1367  break;
1368  case 72:
1369  // Save to persistent
1370  break;
1371  case 73:
1372  // Cycle to next color palette
1373  if (++fSettings.fPalNum >= PAL_COUNT)
1374  fSettings.fPalNum = 0;
1375  calculateAllColors();
1376  break;
1377  }
1378  break;
1379  case 'R':
1380  // Random sequence
1381  selectSequence(RANDOM);
1382  break;
1383  case 'W':
1384  // Wait number of seconds and then revert to default
1385  fDisplayEffectVal = (fDisplayEffectVal / 100) * 100 + arg;
1386  break;
1387  case 'Z':
1388  selectEffect(TEXTSCROLLLEFT);
1389  break;
1390  }
1391  }
1392 
1393  virtual void jawaCommand(char cmd, const char* arg) override
1394  {
1395  switch (cmd)
1396  {
1397  case 'M':
1398  setTextMessage(arg);
1399  break;
1400  }
1401  }
1402 
1404  {
1405  return fSettings;
1406  }
1407 
1408  inline void changeSettings(LogicEngineSettings& newSettings)
1409  {
1410  fSettings = newSettings;
1411  }
1412 
1413  virtual void changeDefaultSettings(LogicEngineSettings& settings) = 0;
1414 
1415  static inline int mapSelectColorToHue(unsigned selectColor)
1416  {
1417  static const byte sEffectHue[] PROGMEM = {
1418  0,0,26,42,85,128,170,202,213,228
1419  };
1420  return (selectColor < SizeOfArray(sEffectHue)) ? pgm_read_byte(&sEffectHue[selectColor]) : 0;
1421  }
1422 
1423 protected:
1425  union HSVColor
1426  {
1427  struct
1428  {
1429  byte h;
1430  byte s;
1431  byte v;
1432  };
1433  byte c[3];
1434  };
1435 
1437  byte id,
1438  byte tweens,
1439  byte totalColors,
1440  byte totalColorsWBIZ,
1441  unsigned width,
1442  unsigned height,
1443  unsigned count,
1444  unsigned start,
1445  unsigned end,
1446  CRGB* led,
1447  HSVColor* allColors,
1448  LEDStatus* ledStatus,
1449  const byte* ledMap,
1450  LogicRenderGlyph renderGlyph) :
1451  fID((id == 0) ? getNextID() : id),
1452  fWidth(width),
1453  fHeight(height),
1454  fLEDCount(count),
1455  fLEDStart(start),
1456  fLEDEnd(end),
1457  fTweens(tweens),
1458  fTotalColors(totalColors),
1459  fTotalColorsWBIZ(totalColorsWBIZ),
1460  fLED(led),
1461  fAllColors(allColors),
1462  fLEDStatus(ledStatus),
1463  fLEDMap(ledMap),
1464  fRenderGlyph(renderGlyph)
1465  {
1466  JawaID addr = kJawaOther;
1467  switch (fID)
1468  {
1469  case 1:
1470  addr = kJawaTFLD;
1471  break;
1472  case 2:
1473  addr = kJawaRFLD;
1474  break;
1475  }
1476  setJawaAddress(addr);
1477  }
1478 
1479 #if USE_LEDLIB == 1
1480  virtual void show() = 0;
1481 #endif
1482 
1483  virtual void defaultSettings() = 0;
1484 
1486  LogicEffectSelector fEffectSelector = NULL;
1487  LogicMessageSelector fMessageSelector = NULL;
1488  LogicPMessageSelector fPMessageSelector = NULL;
1489 
1490  static uint16_t sLastEventCount;
1491 
1492 private:
1493  byte fID;
1494  int fWidth;
1495  int fHeight;
1496  unsigned fLEDCount;
1497  unsigned fLEDStart;
1498  unsigned fLEDEnd;
1499  byte fTweens;
1500  byte fTotalColors;
1501  byte fTotalColorsWBIZ;
1502  CRGB* fLED;
1503  HSVColor* fAllColors;
1504  LEDStatus* fLEDStatus;
1505  const byte* fLEDMap;
1506  byte fMaxBrightness = MAX_BRIGHTNESS;
1507 
1508  byte fDisplayEffect = 0;
1509  byte fPreviousEffect = ~0;
1510 
1511  uint32_t fLastMillis = 0;
1512  uint32_t fStatusMillis = 0;
1513  uint32_t fStatusDelay = 0;
1514  bool fFlipFlop = false;
1515 
1516  long fDisplayEffectVal = NORMVAL;
1517  long fPreviousEffectVal = ~fDisplayEffectVal;
1518  uint32_t fEffectStartMillis = 0;
1519  unsigned int fEffectMillis = 0;
1520  LogicEffect fLogicEffect;
1521  PeakValueProvider* fPeakSource = NULL;
1522 
1523  LogicEffectObject* fEffectObject = NULL;
1524  uint32_t fEffectData = 0;
1525  uint32_t fEffectData2 = 0;
1526  float fEffectRange = 1.0;
1527  int fEffectMsgStartX;
1528  int fEffectMsgLen;
1529  int fEffectMsgWidth;
1530  int fEffectMsgHeight;
1531  bool fEffectMsgTransition;
1532  byte fEffectFontNum = 0;
1533  const char* fEffectMsgText = NULL;
1534  PROGMEMString fEffectMsgTextP = NULL;
1535  LogicRenderGlyph fRenderGlyph;
1536 
1537  inline int actualColorNum(int x) const
1538  {
1539  return (x >= fTotalColors) ? (fTotalColors - 2) - (x - fTotalColors) : x;
1540  }
1541 };
1542 
1544 
1548 
1549 LogicEffect LogicEffectDefaultSelector(unsigned effectVal);
1550 
1552 
1554 template <typename PCB, LogicRenderGlyph renderGlyph, byte TWEENS = 14>
1555 class LogicEngineDisplay : public LogicEngineRenderer
1556 {
1557 public:
1558  LogicEngineDisplay(LogicEngineSettings& defaults, byte id = 0, LogicEffectSelector selector = NULL) :
1560  id,
1561  TWEENS,
1562  TOTALCOLORS,
1563  TOTALCOLORSWBIZ,
1564  fPCB.width,
1565  fPCB.height,
1566  fPCB.count,
1567  fPCB.start,
1568  fPCB.end,
1569  fPCB.fLED,
1570  fAllColorsStorage,
1571  fPCB.fLEDStatus,
1572  fPCB.getLEDMap(),
1573  renderGlyph),
1574  fDefaults(&defaults)
1575  {
1576  defaultSettings();
1577  fEffectSelector = (selector == NULL) ? LogicEffectDefaultSelector : selector;
1578  fPCB.init();
1579  }
1580 
1581 #if USE_LEDLIB == 1
1582  virtual void show() override
1583  {
1584  fPCB.show();
1585  }
1586 #endif
1587 
1588  virtual void defaultSettings() override
1589  {
1590  fSettings = *fDefaults;
1591  }
1592 
1593  virtual void changeDefaultSettings(LogicEngineSettings& settings) override
1594  {
1595  fSettings = *fDefaults = settings;
1596  }
1597 
1598  static const unsigned TOTALCOLORS = (4 + (TWEENS * 3));
1599  static const unsigned TOTALCOLORSWBIZ = ((TOTALCOLORS * 2) - 2); // total colors with bizarro colors
1600 
1601 protected:
1602  PCB fPCB;
1603  HSVColor fAllColorsStorage[TOTALCOLORS];
1604  LogicEngineSettings* fDefaults;
1605 };
1606 
1608 //
1609 // Animation Effects
1610 //
1612 
1613 static bool LogicEffectNormal(LogicEngineRenderer& r)
1614 {
1615  if (r.hasEffectChanged())
1616  {
1617  r.calculateAllColors();
1618  }
1619  r.updateDisplay();
1620  return true;
1621 }
1622 
1623 static bool LogicAlarmEffect(LogicEngineRenderer& r)
1624 {
1625  if (r.hasEffectChanged())
1626  {
1627  // Brighter if id matches FLD
1628  r.setPaletteHue(2, (r.getID() == 1) ? 170 : 72);
1629  r.setEffectDelay(250 * (r.getEffectSpeed() + 1));
1630  }
1631  if (r.getEffectFlip())
1632  {
1633  if (r.getEffectColor() == 0)
1634  {
1635  r.restoreSettings();
1636  }
1637  else
1638  {
1639  r.setPaletteHue(2, r.getEffectHue());
1640  }
1641  }
1642  else
1643  {
1644  r.setPaletteHue(2, 0);
1645  }
1646  r.updateDisplayPeak();
1647  return true;
1648 }
1649 
1650 static bool LogicLeiaEffect(LogicEngineRenderer& r)
1651 {
1652  // for the Leia message we'll change both logics to hologram
1653  // colors (palette 2 with a hue shift of 60) then we'll do
1654  // something with the microphone
1655  if (r.hasEffectChanged())
1656  {
1657  r.setPaletteHue(2, 60);
1658  }
1659  byte peakVal = min(int(r.getPeakValue()), 100);
1660  // if (peakVal > 127)
1661  {
1662  //shift the hue very slightly
1663  r.setHue(60 + map(peakVal,0,100,0,20));
1664  r.setBrightness(map(peakVal,0,100,50,LogicEngineDefaults::MAX_BRIGHTNESS));
1665  r.calculateAllColors();
1666  r.updateDisplay(255);
1667  }
1668  // else
1669  // {
1670  // r.setHue(60);
1671  // r.updateDisplay(127);
1672  // }
1673  // Effect ends after 34 seconds
1674  return r.getEffectDuration() < 34000;
1675 }
1676 
1677 static bool LogicMarchEffect(LogicEngineRenderer& r)
1678 {
1679  uint32_t effectMillis = r.getEffectDuration();
1680  if (r.hasEffectChanged())
1681  {
1682  r.setPaletteHue(2, r.getEffectHue());
1683  r.setEffectDelay(150 * (r.getEffectSpeed() + 1));
1684  }
1685  //Imperial March (non-beep version) can be divided into a few distinct segments...
1686  //note: version used (from Padawan sound archive) includes 500ms of silence at start
1687  static const unsigned int sMarchSegment[] =
1688  {
1689  0, // 0-09800 (9800) = intro
1690  9800, // 09800-14500 (4700)
1691  14500, // 14500-19300 (4800) //notes every 700ms
1692  19300, // 19300-28800 (9500)
1693  28800, // 28800-38300 (9500)
1694  38300, // 38300-45300 (7000)
1695  45300, // 45300-48300 (3000) = wind down
1696  48300 // 48300 end
1697  };
1698  //change color hue for each marchSegment...
1699  for (byte i = 1; i < SizeOfArray(sMarchSegment); i++)
1700  {
1701  if (effectMillis > sMarchSegment[i-1] && effectMillis < sMarchSegment[i])
1702  {
1703  if (r.getEffectColor() == 0)
1704  {
1705  // switch colors on segments if no specific color set
1706  r.setHue((i - 1) * 32);
1707  }
1708  if (i == 7)
1709  r.setEffectDelay(175); //make the flipflop really fast for the last segment
1710  }
1711  }
1712  //alternate brightness of sections(re-uses the flipFlop value from our statusLED)...
1713  bool flipflop = r.getEffectFlip();
1714  r.updateDisplaySplitRowThirds((!flipflop) ? 50 : 255, (!flipflop) ? 255 : 50);
1715  // Effect ends after 48.3 seconds
1716  return (effectMillis < 48300);
1717 }
1718 
1719 static bool LogicFailureEffect(LogicEngineRenderer& r)
1720 {
1721  uint32_t effectMillis = r.getEffectDuration();
1722  if (r.hasEffectChanged())
1723  {
1724  //start off with Fade and Delay settings low (logic patterns fast), slow
1725  // them down towards the end and then fade out
1726  r.setFade(0);
1727  r.setDelay(0);
1728  }
1729  // FAILUREduration is 10000 milliseconds by default, and the effect sequence
1730  // should be roughly timed to the "128 screa-3.mp3" file
1731  // 0-1800 = scream
1732  //1800-5500 = glitch
1733  //5500-6500 = fade out
1734  if (effectMillis > 1800 && effectMillis < 6000)
1735  {
1736  //during this 'glitch' period, we'll cycle the color hues
1737  r.setHue(r.getHue() + 1);
1738  }
1739  else if (effectMillis > 6000 && effectMillis < 8000)
1740  {
1741  //briVal starts at around 255, and drops down to 0 as we approach 6500 millis.
1742  //this portion lasts 1000 millis, so we'll scale brightness of both logics
1743  // to a value related to this period
1744  r.setBrightness(map(effectMillis - 6000, 2000, 0 , 0, 255));
1745  }
1746  r.updateDisplay();
1747  // Effect ends after 18 seconds
1748  return (effectMillis < 18000);
1749 }
1750 
1751 static bool LogicSolidColorEffect(LogicEngineRenderer& r)
1752 {
1753  if (r.hasEffectChanged())
1754  {
1755  r.setPaletteHue(2, r.getEffectHue());
1756  }
1757  r.updateDisplay();
1758  return true;
1759 }
1760 
1761 static bool LogicFlipFlopEffect(LogicEngineRenderer& r)
1762 {
1763  if (r.hasEffectChanged())
1764  {
1765  r.setPaletteHue(2, r.getEffectHue());
1766  r.setEffectDelay(200 * (r.getEffectSpeed() + 1));
1767  }
1768  bool flipflop = r.getEffectFlip();
1769  r.updateDisplaySplitHalf((!flipflop) ? 50 : 255, (!flipflop) ? 255 : 50);
1770  return true;
1771 }
1772 
1773 static bool LogicFlipFlopAltEffect(LogicEngineRenderer& r)
1774 {
1775  if (r.hasEffectChanged())
1776  {
1777  r.setPaletteHue(2, r.getEffectHue());
1778  r.setEffectDelay(200 * (r.getEffectSpeed() + 1));
1779  }
1780  bool flipflop = r.getEffectFlip();
1781  r.updateDisplaySplitRowThirds((!flipflop) ? 50 : 255, (!flipflop) ? 255 : 50);
1782  return true;
1783 }
1784 
1786 
1787 static bool LogicFlashEffect(LogicEngineRenderer& r)
1788 {
1789  if (r.hasEffectChanged())
1790  {
1791  //change both palettes to selected color
1792  r.setPaletteHue(2, r.getEffectHue());
1793  r.setEffectDelay(250 * (r.getEffectSpeed() + 1));
1794  }
1795  r.updateDisplay(r.getEffectFlip() ? 255 : 50);
1796  return true;
1797 }
1798 
1800 
1801 static bool LogicColorSwapEffect(LogicEngineRenderer& r)
1802 {
1803  if (r.hasEffectChanged())
1804  {
1805  r.setPaletteHue(2, 0);
1806  r.setEffectDelay(350 * (r.getEffectSpeed() + 1)); //we'll flipflop hues
1807  }
1808  byte effectHue = r.getEffectHue();
1809  if (!r.getEffectFlip())
1810  {
1811  if (r.getEffectHue() >= 128)
1812  {
1813  r.setHue(effectHue - 128);
1814  }
1815  else
1816  {
1817  r.setHue(effectHue + 128);
1818  }
1819  }
1820  else
1821  {
1822  r.setHue(effectHue);
1823  }
1824  r.updateDisplay();
1825  return true;
1826 }
1827 
1829 
1830 static bool LogicPSIColorWipeEffect(LogicEngineRenderer& r)
1831 {
1832  int altColor = r.kDefault;
1833  int effectColor = r.getEffectColor();
1834  if (effectColor == r.kRed) altColor = r.kBlue;
1835  else if (effectColor == r.kBlue) altColor = r.kRed;
1836  else if (effectColor == r.kYellow) altColor = r.kGreen;
1837  else if (effectColor == r.kGreen) altColor = r.kYellow;
1838  else if (effectColor == r.kCyan) altColor = r.kOrange;
1839  else if (effectColor == r.kOrange) altColor = r.kCyan;
1840  else if (effectColor == r.kPurple) altColor = r.kMagenta;
1841  else if (effectColor == r.kPink) altColor = r.kBlue;
1842  if (r.hasEffectChanged())
1843  {
1844  r.setPaletteHue(2, r.getEffectHue());
1845  r.setEffectData(0);
1846  r.setEffectDelay(50 * (r.getEffectSpeed()+1));
1848  }
1849  if (r.getEffectFlip())
1850  {
1851  int y;
1852  int x = r.getEffectData() & 0xFF;
1853  int px = (r.getEffectData() >> 8) & 0xFF;
1854  int dir = (r.getEffectData() >> 16) & 0x1;
1855  // px contains previous row in case we want to erase it
1856  // if (px != x)
1857  // for (y = 0; y < r.height(); y++)
1858  // r.setPixel(px, y, r.getEffectHue(), 0);
1859  for (y = 0; y < r.height(); y++)
1860  r.setPixel(x, y, (dir) ? r.mapSelectColorToHue(altColor) : r.getEffectHue(), 200);
1861  px = x;
1862  x += (!dir) ? 1 : -1;
1863  int pdir = dir;
1864  if (x >= r.width())
1865  {
1866  dir = 1;
1867  x--;
1868  }
1869  else if (x < 0)
1870  {
1871  dir = 0;
1872  x = 0;
1873  }
1874  if (pdir != dir)
1875  {
1876  r.setEffectDelay(1000+2000*random(3));
1877  }
1878  //decide if we're going to get 'stuck'
1879  else if (random(100) <= 5)
1880  {
1881  r.setEffectDelay(1000+2000*random(3));
1882  }
1883  else
1884  {
1885  r.setEffectDelay(50 * (r.getEffectSpeed()+1));
1886  }
1887  r.setEffectData((uint32_t(dir)<<16L) | ((uint32_t(px)<<8L)) | x);
1888  r.setEffectFlip(false);
1889  }
1890  return true;
1891 }
1892 
1894 
1895 static bool LogicRainbowEffect(LogicEngineRenderer& r)
1896 {
1897  if (r.hasEffectChanged())
1898  {
1899  r.setPaletteHue(2, r.getEffectHue());
1900  r.setEffectDelay(200 * (r.getEffectSpeed() + 1)); //speed of hue swap
1902  }
1903  if (r.getEffectFlip() != r.getEffectData())
1904  {
1905  r.setHue(r.getHue() + 20);
1907  }
1908  r.updateDisplay();
1909  return true;
1910 }
1911 
1913 
1914 static bool LogicRedAlertEffect(LogicEngineRenderer& r)
1915 {
1916  if (r.hasEffectChanged())
1917  {
1918  r.calculateAllColors();
1919  }
1920  if (r.getPeakValue() < r.getEffectSpeed() * 256 / 10)
1921  {
1922  r.restoreSettings();
1923  r.calculateAllColors();
1924  }
1925  else
1926  {
1927  // show color while loud
1928  r.setPaletteHue(2, r.getEffectHue());
1929  }
1930  r.updateDisplay();
1931  return true;
1932 }
1933 
1935 
1936 static bool LogicMicBrightEffect(LogicEngineRenderer& r)
1937 {
1938  if (r.hasEffectChanged())
1939  {
1940  r.calculateAllColors();
1941  }
1942  byte peakVal = r.getPeakValue();
1943  int speedVal = r.getEffectSpeed() * 256 / 10;
1944  if (peakVal < speedVal)
1945  {
1946  r.setBrightness(speedVal);
1947  }
1948  else
1949  {
1950  r.setBrightness(peakVal);
1951  }
1952  if (r.getEffectColor() == 0)
1953  {
1954  // use default colors
1955  r.restoreSettings(); // reset to defaults for a clean slate
1956  r.calculateAllColors();
1957  }
1958  else
1959  {
1960  // show color
1961  r.setPaletteHue(2, r.getEffectHue());
1962  }
1963  r.updateDisplay();
1964  return true;
1965 }
1966 
1968 
1969 static bool LogicMicRainbowEffect(LogicEngineRenderer& r)
1970 {
1971  if (r.hasEffectChanged())
1972  {
1973  r.setPaletteHue(2, r.getEffectHue());
1974  }
1975  r.setHue(r.getPeakValue() + r.getEffectHue() - 256);
1976  r.updateDisplay();
1977  return true;
1978 }
1979 
1981 
1982 static bool LogicTextEffect(LogicEngineRenderer& r)
1983 {
1984  if (r.hasEffectChanged())
1985  {
1986  r.setBrightness(0);
1987  r.setPaletteHue(2, r.getEffectHue());
1990  r.setEffectData(false);
1991  }
1992  if (r.getEffectData2() && r.getEffectDuration() < 2000)
1993  {
1994  r.updateDisplay(0);
1995  }
1996  else if (!r.getEffectData())
1997  {
1998  int x = r.width() / 2 - r.getEffectMsgWidth() / 2;
1999  r.renderText(x, 0, r.getEffectHue());
2000  r.setEffectData(true);
2001  }
2002  return true;
2003 }
2004 
2006 
2007 static bool LogicTextScrollLeftEffect(LogicEngineRenderer& r)
2008 {
2009  if (r.hasEffectChanged())
2010  {
2011  r.setBrightness(0);
2012  r.setPaletteHue(2, r.getEffectHue());
2014  r.setEffectData(r.width());
2015  r.setEffectDelay(50 * (r.getEffectSpeed() + 1));
2017  }
2018  if (r.getEffectData2() && r.getEffectDuration() < 2000)
2019  {
2020  r.updateDisplay(0);
2021  }
2022  else if (r.getEffectFlip())
2023  {
2024  // scrolling text
2025  int x = int(r.getEffectData());
2026  r.renderText(x, 0, r.getEffectHue());
2027  x -= 1;
2028  if (x + r.getEffectMsgWidth() <= 0)
2029  {
2030  x = r.width();
2031  return false;
2032  }
2033  r.setEffectData(x);
2034  r.setEffectFlip(false);
2035  }
2036  return true;
2037 }
2038 
2040 
2041 static bool LogicTextScrollRightEffect(LogicEngineRenderer& r)
2042 {
2043  if (r.hasEffectChanged())
2044  {
2045  r.setBrightness(0);
2046  r.setPaletteHue(2, r.getEffectHue());
2049  r.setEffectDelay(50 * (r.getEffectSpeed() + 1));
2051  }
2052  if (r.getEffectData2() && r.getEffectDuration() < 2000)
2053  {
2054  r.updateDisplay(0);
2055  }
2056  else if (r.getEffectFlip())
2057  {
2058  // scrolling text
2059  int x = int(r.getEffectData());
2060  r.renderText(x, 0, r.getEffectHue());
2061  x += 1;
2062  if (x > r.width())
2063  {
2064  x = -r.getEffectMsgWidth();
2065  return false;
2066  }
2067  r.setEffectData(x);
2068  r.setEffectFlip(false);
2069  }
2070  return true;
2071 }
2072 
2074 
2075 static bool LogicTextScrollUpEffect(LogicEngineRenderer& r)
2076 {
2077  if (r.hasEffectChanged())
2078  {
2079  r.setBrightness(0);
2080  r.setPaletteHue(2, r.getEffectHue());
2082  r.setEffectData(r.height());
2083  r.setEffectDelay(50 * (r.getEffectSpeed() + 1));
2085  }
2086  if (r.getEffectData2() && r.getEffectDuration() < 2000)
2087  {
2088  r.updateDisplay(0);
2089  }
2090  else if (r.getEffectFlip())
2091  {
2092  // scrolling text
2093  int x = r.width() / 2 - r.getEffectMsgWidth() / 2;
2094  int y = int(r.getEffectData());
2095  r.renderText(x, y, r.getEffectHue());
2096  y -= 1;
2097  if (y + r.getEffectMsgHeight() <= 0)
2098  {
2099  y = r.height();
2100  return false;
2101  }
2102  r.setEffectData(y);
2103  r.setEffectFlip(false);
2104  }
2105  return true;
2106 }
2108 
2109 static bool LogicRoamingPixelEffect(LogicEngineRenderer& r)
2110 {
2111  if (r.hasEffectChanged())
2112  {
2113  r.setBrightness(0);
2114  r.setPaletteHue(2, r.getEffectHue());
2116  r.setEffectData(0);
2117  r.setEffectDelay(50 * (r.getEffectSpeed()));
2119  }
2120  if (r.getEffectData2() && r.getEffectDuration() < 2000)
2121  {
2122  r.updateDisplay(0);
2123  }
2124  else if (r.getEffectFlip())
2125  {
2126  uint32_t xy = r.getEffectData();
2127  int x = int(xy >> 16);
2128  int y = int(xy & 0xFFFFL);
2129  r.setPixel(x, y, r.getEffectHue(), 200);
2130  x += 1;
2131  if (x > r.width())
2132  {
2133  for (x = 0; x < r.width(); x++)
2134  r.setPixel(x, y, r.getEffectHue(), 0);
2135  x = 0;
2136  y += 1;
2137  }
2138  if (y >= r.height())
2139  {
2140  x = 0; y = 0;
2141  }
2142  r.setEffectData((uint32_t(x)<<16L) | ((uint32_t(y)&0XFFFF)));
2143  r.setEffectFlip(false);
2144  }
2145  return true;
2146 }
2147 
2149 
2150 static bool LogicHorizontalScanLineEffect(LogicEngineRenderer& r)
2151 {
2152  if (r.hasEffectChanged())
2153  {
2154  r.setBrightness(0);
2155  r.setPaletteHue(2, r.getEffectHue());
2157  r.setEffectData(0);
2158  r.setEffectDelay(50 * (r.getEffectSpeed()+1));
2160  }
2161  if (r.getEffectData2() && r.getEffectDuration() < 2000)
2162  {
2163  r.updateDisplay(0);
2164  }
2165  else if (r.getEffectFlip())
2166  {
2167  int x;
2168  int y = r.getEffectData() & 0xFF;
2169  int py = (r.getEffectData() >> 8) & 0xFF;
2170  int dir = (r.getEffectData() >> 16) & 0x1;
2171  if (py != y)
2172  for (x = 0; x < r.width(); x++)
2173  r.setPixel(x, py, r.getEffectHue(), 0);
2174  for (x = 0; x < r.width(); x++)
2175  r.setPixel(x, y, r.getEffectHue(), 200);
2176  py = y;
2177  y += (!dir) ? 1 : -1;
2178  if (y >= r.height())
2179  {
2180  dir = 1;
2181  y--;
2182  }
2183  else if (y < 0)
2184  {
2185  dir = 0;
2186  y = 0;
2187  }
2188  r.setEffectData((uint32_t(dir)<<16L) | ((uint32_t(py)<<8L)) | y);
2189  r.setEffectFlip(false);
2190  }
2191  return true;
2192 }
2193 
2195 
2196 static bool LogicVerticalScanLineEffect(LogicEngineRenderer& r)
2197 {
2198  if (r.hasEffectChanged())
2199  {
2200  r.setBrightness(0);
2201  r.setPaletteHue(2, r.getEffectHue());
2203  r.setEffectData(0);
2204  r.setEffectDelay(50 * (r.getEffectSpeed()+1));
2206  }
2207  if (r.getEffectData2() && r.getEffectDuration() < 2000)
2208  {
2209  r.updateDisplay(0);
2210  }
2211  else if (r.getEffectFlip())
2212  {
2213  int y;
2214  int x = r.getEffectData() & 0xFF;
2215  int px = (r.getEffectData() >> 8) & 0xFF;
2216  int dir = (r.getEffectData() >> 16) & 0x1;
2217  if (px != x)
2218  for (y = 0; y < r.height(); y++)
2219  r.setPixel(px, y, r.getEffectHue(), 0);
2220  for (y = 0; y < r.height(); y++)
2221  r.setPixel(x, y, r.getEffectHue(), 200);
2222  px = x;
2223  x += (!dir) ? 1 : -1;
2224  if (x >= r.width())
2225  {
2226  dir = 1;
2227  x--;
2228  }
2229  else if (x < 0)
2230  {
2231  dir = 0;
2232  x = 0;
2233  }
2234  r.setEffectData((uint32_t(dir)<<16L) | ((uint32_t(px)<<8L)) | x);
2235  r.setEffectFlip(false);
2236  }
2237  return true;
2238 }
2239 
2241 
2242 static bool LogicFireEffect(LogicEngineRenderer& r)
2243 {
2244  static const unsigned char sValueMask[10][24] PROGMEM = {
2245  {32 , 0 , 0 , 0 , 0 , 0 , 0 , 32 , 32 , 0 , 0 , 0 , 0 , 0 , 0 , 32, 32 , 0 , 0 , 0 , 0 , 0 , 0 , 32 },
2246  {64 , 0 , 0 , 0 , 0 , 0 , 0 , 64 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 64, 64 , 0 , 0 , 0 , 0 , 0 , 0 , 64 },
2247  {96 , 32 , 0 , 0 , 0 , 0 , 32 , 96 , 96 , 32 , 0 , 0 , 0 , 0 , 32 , 96, 32 , 0 , 0 , 0 , 0 , 0 , 32 , 96 },
2248  {128, 64 , 32 , 0 , 0 , 32 , 64 , 128, 128, 64 , 32 , 0 , 0 , 32 , 64 , 128, 64 , 32 , 0 , 0 , 0 , 32 , 64 , 128},
2249  {160, 96 , 64 , 32 , 32 , 64 , 96 , 160, 160, 96 , 64 , 32 , 32 , 64 , 96 , 160, 96 , 64 , 32 , 32 , 64 , 96 , 160, 160},
2250  {160, 96 , 64 , 32 , 32 , 64 , 96 , 160, 160, 96 , 64 , 32 , 32 , 64 , 96 , 160, 96 , 64 , 32 , 32 , 64 , 96 , 160, 160},
2251  {192, 128, 96 , 64 , 64 , 96 , 128, 192, 192, 128, 96 , 64 , 64 , 96 , 128, 192, 192, 128 , 96 , 64 , 64 , 96 , 128, 192},
2252  {255, 160, 128, 96 , 96 , 128, 160, 255, 255, 160, 128, 96 , 96 , 128, 160, 255, 255, 160 , 128, 96 , 96 , 128, 160, 255},
2253  {255, 192, 160, 128, 128, 160, 192, 255, 255, 192, 160, 128, 128, 160, 192, 255, 255, 192 , 160, 128 ,128 , 160, 192, 255},
2254  {255, 192, 160, 128, 128, 160, 192, 255, 255, 192, 160, 128, 128, 160, 192, 255, 255, 192 , 160, 128 ,128 , 160, 192, 255},
2255  };
2256 
2257  static const unsigned char sHueMask[10][24] PROGMEM = {
2258  {1 , 11, 19, 25, 25, 22, 11, 1 , 1 , 11, 19, 25, 25, 22, 11, 1, 1 , 1 , 11, 19, 25, 25, 22, 11 },
2259  {1 , 8 , 13, 19, 25, 19, 8 , 1 , 1 , 8 , 13, 19, 25, 19, 8 , 1, 1 , 1 , 8 , 13, 19, 25, 19, 8 },
2260  {1 , 8 , 13, 16, 19, 16, 8 , 1 , 1 , 8 , 13, 16, 19, 16, 8 , 1, 1 , 1 , 8 , 13, 16, 19, 16, 8 },
2261  {1 , 5 , 11, 13, 13, 13, 5 , 1 , 1 , 5 , 11, 13, 13, 13, 5 , 1, 1 , 1 , 5 , 11, 13, 13, 13, 5 },
2262  {1 , 5 , 11, 11, 11, 11, 5 , 1 , 1 , 5 , 11, 11, 11, 11, 5 , 1, 1 , 1 , 5 , 11, 11, 11, 11, 5 },
2263  {1 , 5 , 11, 11, 11, 11, 5 , 1 , 1 , 5 , 11, 11, 11, 11, 5 , 1, 1 , 1 , 5 , 11, 11, 11, 11, 5 },
2264  {0 , 1 , 5 , 8 , 8 , 5 , 1 , 0 , 0 , 1 , 5 , 8 , 8 , 5 , 1 , 0, 0 , 1 , 5 , 8 , 8 , 5 , 1 , 0 },
2265  {0 , 0 , 1 , 5 , 5 , 1 , 0 , 0 , 0 , 0 , 1 , 5 , 5 , 1 , 0 , 0, 0 , 0 , 1 , 5 , 5 , 1 , 0 , 0 },
2266  {0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0, 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 },
2267  {0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0, 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 },
2268  };
2269 
2270  int count = r.count();
2271  int width = r.width();
2272  int height = r.height();
2273  CRGB* leds = r.getUnmappedLEDs();
2274  LEDStatus* ledStatus = r.getUnmappedLEDStatus();
2275  if (r.hasEffectChanged())
2276  {
2277  r.setBrightness(0);
2278  r.setPaletteHue(2, r.getEffectHue());
2280  r.setEffectData(0);
2281  r.setEffectDelay(100 * (r.getEffectSpeed() + 1));
2283  for (int i = 0; i < count; i++)
2284  {
2285  ledStatus[i].fColorNum = 0;
2286  ledStatus[i].fColorPause = 0;
2287  }
2288  /* Generate line */
2289  for (uint8_t x = 0; x < width; x++)
2290  {
2291  ledStatus[x].fColorPause = random(64, 255);
2292  }
2293  }
2294  if (r.getEffectFlip())
2295  {
2296  int pcnt = r.getEffectData();
2297  if (pcnt >= 100)
2298  {
2299  /* shift up */
2300  for (uint8_t y = height - 1; y > 0; y--)
2301  {
2302  for (uint8_t x = 0; x < width; x++)
2303  {
2304  ledStatus[r.mapLED(y*width+x)].fColorNum = ledStatus[r.mapLED((y-1)*width+x)].fColorNum;
2305  }
2306  }
2307  for (uint8_t x = 0; x < width; x++)
2308  {
2309  ledStatus[r.mapLED(x)].fColorNum = ledStatus[x].fColorPause;
2310  }
2311  /* Generate line */
2312  for (uint8_t x = 0; x < width; x++)
2313  {
2314  ledStatus[x].fColorPause = random(64, 255);
2315  }
2316  }
2317  int nextv;
2318 
2319  //each row interpolates with the one before it
2320  int heightm1 = height - 1;
2321  for (byte y = heightm1; y > 0; y--)
2322  {
2323  for (byte x = 0; x < width; x++)
2324  {
2325  nextv = (((100.0-pcnt) * ledStatus[r.mapLED(y*width+x)].fColorNum +
2326  pcnt * ledStatus[r.mapLED((y-1)*width+x)].fColorNum) / 100.0) - pgm_read_byte(&sValueMask[y][x]);
2327  leds[r.mapLED((heightm1-y)*width+x)].setHSV(pgm_read_byte(&sHueMask[y][x]), 255, (uint8_t)max(0, nextv));
2328  }
2329  }
2330 
2331  //first row interpolates with the "next" line
2332  for (byte x = 0; x < width; x++)
2333  {
2334  leds[r.mapLED(heightm1*width+x)].setHSV(pgm_read_byte(&sHueMask[0][x]), 255,
2335  (uint8_t)(((100.0-pcnt) * ledStatus[r.mapLED(x)].fColorNum + pcnt * ledStatus[x].fColorPause)/100.0));
2336  }
2337  pcnt += 20;
2338  r.setEffectData(pcnt);
2339  r.setEffectFlip(false);
2340  }
2341  return true;
2342 }
2343 
2345 
2346 static bool LogicLightsOutEffect(LogicEngineRenderer& r)
2347 {
2348  if (r.hasEffectChanged())
2349  {
2350  r.setBrightness(0);
2351  r.setPaletteHue(2, r.getEffectHue());
2352  }
2353  r.updateDisplay(0);
2354  return true;
2355 }
2356 
2357 static bool LogicPulseEffect(LogicEngineRenderer& r)
2358 {
2359  if (r.hasEffectChanged())
2360  {
2361  r.setBrightness(0);
2362  r.setPaletteHue(2, r.getEffectHue());
2364  r.setEffectData(0);
2365  r.setEffectDelay(70 * (r.getEffectSpeed()+1));
2367  }
2368  if (r.getEffectData2() && r.getEffectDuration() < 2000)
2369  {
2370  r.updateDisplay(0);
2371  }
2372  else if (r.getEffectFlip())
2373  {
2374  float xmid = r.width()/2;
2375  float ymid = r.height()/2;
2376  int dy;
2377  int dx;
2378  int x = r.getEffectData() & 0xFF;
2379  int px = (r.getEffectData() >> 8) & 0xFF;
2380  int dir = (r.getEffectData() >> 16) & 0x1;
2381 
2382  for (dy = 0; dy < r.height(); dy++) {
2383  for (dx = 0; dx < r.width(); dx++) {
2384  if ((dy+px >= ymid && dy-px <= ymid) && (dx+px >= xmid && dx-px <= xmid))
2385  {
2386  r.setPixel(dx, dy, r.getEffectHue(), 150);
2387  } else {
2388  r.setPixel(dx, dy, r.getEffectHue(), 0);
2389  }
2390  }
2391  }
2392  px += (!dir) ? 1 : -1;
2393  if (px > r.width()/2 || px < 1) {
2394  dir = !dir;
2395  }
2396  r.setEffectData((uint32_t(dir)<<16L) | ((uint32_t(px)<<8L)) | x);
2397  r.setEffectFlip(false);
2398  }
2399  return true;
2400 }
2401 
2403 
2404 LogicEffect LogicEffectDefaultSelector(unsigned selectSequence)
2405 {
2406  static const LogicEffect sLogicEffects[] = {
2407  LogicEffectNormal,
2408  LogicAlarmEffect,
2409  LogicFailureEffect,
2410  LogicLeiaEffect,
2411  LogicMarchEffect,
2412  LogicSolidColorEffect,
2413  LogicFlashEffect,
2414  LogicFlipFlopEffect,
2415  LogicFlipFlopAltEffect,
2416  LogicColorSwapEffect,
2417  LogicRainbowEffect,
2418  LogicRedAlertEffect,
2419  LogicMicBrightEffect,
2420  LogicMicRainbowEffect,
2421  LogicLightsOutEffect,
2422  LogicTextEffect,
2423  LogicTextScrollLeftEffect,
2424  LogicTextScrollRightEffect,
2425  LogicTextScrollUpEffect,
2426  LogicRoamingPixelEffect,
2427  LogicHorizontalScanLineEffect,
2428  LogicVerticalScanLineEffect,
2429  LogicFireEffect,
2430  LogicPSIColorWipeEffect,
2431  LogicPulseEffect,
2432  };
2433  if (selectSequence == LogicEngineDefaults::RANDOM)
2434  selectSequence = random(SizeOfArray(sLogicEffects));
2435  if (selectSequence > SizeOfArray(sLogicEffects))
2436  selectSequence = 0;
2437  return LogicEffect(sLogicEffects[selectSequence]);
2438 }
2439 
2441 //
2442 // Text Rendering
2443 //
2445 
2446 byte getlsbposm1(byte x)
2447 {
2448  for (int i = 0; i < 8; i++)
2449  if (x & (1<<i))
2450  return 8-i;
2451  return 0;
2452 }
2453 
2458 };
2459 
2460 template <LogicStaggerType staggerType>
2461 byte LogicRenderGlyph4Pt(char ch, byte fontNum, const CRGB fontColors[], int x, int y, CRGB* leds, const byte* ledMap, int w, int h, byte* outGlyphHeight)
2462 {
2463  UNUSED_ARG(fontNum)
2464  byte dstWidth = w;
2465  byte dstHeight = h;
2466  byte dstRowBytes = w;
2467  byte advance;
2468  byte glyphRowBytes;
2469  byte glyphHeight = 4;
2470  byte glyphBitmap[2*8]; // max size 2 bytes wide 8 bytes high
2472  bool found = font->getLetter(ch, glyphBitmap, glyphRowBytes, advance);
2473  if (!found)
2474  {
2475  // try upper-case if lower-case is missing
2476  if (ch >= 'a' && ch < 'z')
2477  found = font->getLetter('A'+(ch-'a'), glyphBitmap, glyphRowBytes, advance);
2478  // try lower-case if upper-case is missing
2479  else if (ch >= 'A' && ch < 'Z')
2480  found = font->getLetter('a'+(ch-'A'), glyphBitmap, glyphRowBytes, advance);
2481  }
2482  if (outGlyphHeight != NULL)
2483  *outGlyphHeight = glyphHeight;
2484  // render from baseline
2485  int starty = y;
2486  y += glyphHeight - 1;
2487  while (glyphHeight > 0 && y >= 0)
2488  {
2489  int adv = advance;
2490  byte* s = &glyphBitmap[(y-starty) * glyphRowBytes];
2491  if (ledMap != NULL && y < dstHeight)
2492  {
2493  for (byte rb = 0; rb < glyphRowBytes; rb++)
2494  {
2495  byte i = 6;
2496  byte b = *s++;
2497  byte m = 0b11000000;
2498  int xx = x;
2499  while (adv > 0 && m != 0 && xx < dstWidth)
2500  {
2501  if ((b & m) != 0 && xx >= 0)
2502  {
2503  leds[pgm_read_byte(&ledMap[y * dstRowBytes + xx])] = fontColors[((b >> i) & 3)-1];
2504  }
2505  adv--;
2506  m >>= 2;
2507  i -= 2;
2508  xx++;
2509  }
2510  }
2511  }
2512  x += (staggerType == LogicStaggerType::kOdd) ? (y&1) : (staggerType == LogicStaggerType::kEven) ? ((y&1) ^ 1) : 0;
2513  glyphHeight--;
2514  y--;
2515  }
2516  return advance + 1;
2517 }
2518 
2519 static byte LogicRenderGlyph5Pt(char ch, byte fontNum, const CRGB fontColors[], int x, int y, CRGB* leds, const byte* ledMap, int w, int h, byte* outGlyphHeight)
2520 {
2521  byte dstRowBytes = w;
2522  byte glyphRowBytes = 1;
2523  byte glyphHeight = 5;
2524  byte glyphBitmap[2*8]; // max size 2 bytes wide 8 bytes high
2525  Font8x5* font = (fontNum == 1) ? AurabeshFont8x5::instance() : LatinFont8x5::instance();
2526  bool found = font->getLetter(ch, glyphBitmap);
2527  if (!found)
2528  {
2529  // try upper-case if lower-case is missing
2530  if (ch >= 'a' && ch < 'z')
2531  found = font->getLetter('A'+(ch-'a'), glyphBitmap);
2532  // try lower-case if upper-case is missing
2533  else if (ch >= 'A' && ch < 'Z')
2534  found = font->getLetter('a'+(ch-'A'), glyphBitmap);
2535  }
2536  // calculate glyph advance
2537  byte advance = 0;
2538  for (int i = 0; i < glyphHeight; i++)
2539  {
2540  byte b = glyphBitmap[i * glyphRowBytes];
2541  for (byte i = 0; i < 8; i++)
2542  {
2543  if (b & (1<<i))
2544  {
2545  advance = max((int)advance, 8-i);
2546  break;
2547  }
2548  }
2549  }
2550  if (advance == 0)
2551  advance = 4;
2552 
2553  if (outGlyphHeight != NULL)
2554  *outGlyphHeight = glyphHeight;
2555  // render from baseline
2556  int starty = y;
2557  y += glyphHeight - 1;
2558  while (glyphHeight > 0 && y >= 0)
2559  {
2560  int adv = advance;
2561  byte* s = &glyphBitmap[(y-starty) * glyphRowBytes];
2562  if (ledMap != NULL && y < h)
2563  {
2564  for (byte rb = 0; rb < glyphRowBytes; rb++)
2565  {
2566  byte i = 7;
2567  byte b = *s++;
2568  byte m = 0b10000000;
2569  int xx = x;
2570  while (adv > 0 && m != 0 && xx < w)
2571  {
2572  if ((b & m) != 0 && xx >= 0)
2573  {
2574  leds[pgm_read_byte(&ledMap[y * dstRowBytes + xx])] = fontColors[2];
2575  }
2576  adv--;
2577  m >>= 1;
2578  i -= 1;
2579  xx++;
2580  }
2581  }
2582  }
2583  glyphHeight--;
2584  y--;
2585  }
2586  return advance + 1;
2587 }
2588 
2590 //
2591 // Convenience types
2592 //
2594 
2606 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
2607 using AstroPixelFLD = LogicEngineDisplay<AstroPixelFLDPCB0<DATA_PIN>, LogicRenderGlyph5Pt>;
2619 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
2620 using AstroPixelRLD = LogicEngineDisplay<AstroPixelRLDPCB0<DATA_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kNone>>;
2632 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
2633 using LogicEngineNabooFLD = LogicEngineDisplay<LogicEngineFLDPCB0<DATA_PIN>, LogicRenderGlyph5Pt>;
2645 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
2646 using LogicEngineNabooRLD = LogicEngineDisplay<LogicEngineRLDPCB0<DATA_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kEven>>;
2647 
2659 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
2660 using LogicEngineKennyFLD = LogicEngineDisplay<LogicEngineFLDPCB1<DATA_PIN>, LogicRenderGlyph5Pt>;
2672 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
2673 using LogicEngineKennyRLD = LogicEngineDisplay<LogicEngineRLDPCB1<DATA_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kEven>>;
2674 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
2686 using LogicEngineSuperRLD = LogicEngineDisplay<LogicEngineRLDPCBSUPER<DATA_PIN>, LogicRenderGlyph5Pt>;
2687 
2699 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
2700 using LogicEngineDeathStarFLD = LogicEngineDisplay<LogicEngineFLDPCB2<DATA_PIN>, LogicRenderGlyph5Pt>;
2701 
2713 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
2714 using LogicEngineDeathStarFLDInverted = LogicEngineDisplay<LogicEngineFLDPCB2Inverted<DATA_PIN>, LogicRenderGlyph5Pt>;
2715 
2727 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
2728 using LogicEngineDeathStarRLD = LogicEngineDisplay<LogicEngineRLDPCB2<DATA_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kEven>>;
2740 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
2741 using LogicEngineDeathStarRLDStaggerOdd = LogicEngineDisplay<LogicEngineRLDPCB2<DATA_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kOdd>>;
2753 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
2754 using LogicEngineDeathStarRLDInverted = LogicEngineDisplay<LogicEngineRLDPCB2Inverted<DATA_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kEven>>;
2766 template <uint8_t DATA_PIN = REAR_LOGIC_PIN>
2767 using LogicEngineDeathStarRLDInvertedStaggerOdd = LogicEngineDisplay<LogicEngineRLDPCB2Inverted<DATA_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kOdd>>;
2768 
2780 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
2781 using LogicEngineCurvedFLD = LogicEngineDisplay<LogicEngineFLDPCB2<DATA_PIN>, LogicRenderGlyph5Pt>;
2782 
2794 template <uint8_t DATA_PIN = FRONT_LOGIC_PIN>
2795 using LogicEngineCurvedFLDInverted = LogicEngineDisplay<LogicEngineFLDPCB2Inverted<DATA_PIN>, LogicRenderGlyph5Pt>;
2796 
2797 #if USE_LEDLIB == 0
2798 
2809 template <uint8_t DATA_PIN = REAR_LOGIC_PIN, uint8_t CLOCK_PIN = REAR_LOGIC_CLOCK_PIN>
2810 using LogicEngineCurvedRLD = LogicEngineDisplay<LogicEngineRLDPCB3<DATA_PIN, CLOCK_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kNone>>;
2822 template <uint8_t DATA_PIN = REAR_LOGIC_PIN, uint8_t CLOCK_PIN = REAR_LOGIC_CLOCK_PIN>
2823 using LogicEngineCurvedRLDInverted = LogicEngineDisplay<LogicEngineRLDPCB3Inverted<DATA_PIN, CLOCK_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kNone>>;
2824 #endif
2825 
2826 static LogicEngineSettings LogicEngineFLDDefault(
2833 
2834 static LogicEngineSettings LogicEngineRLDDefault(
2841 
2843 
2844 #endif
LogicEngineRenderer::LogicEffect
bool(* LogicEffect)(LogicEngineRenderer &renderer)
Definition: LogicEngine.h:600
LogicEngineDeathStarRLDInverted
2016 Version Rear Logic PCB with Deathstar Plans on back. Mounted upside down.
LEDPixelEngine.h
LogicEngineRenderer::setEffectDelay
void setEffectDelay(uint32_t effectDelay)
Definition: LogicEngine.h:903
TEENSY_PROP_NEOPIXEL_SETUP
#define TEENSY_PROP_NEOPIXEL_SETUP()
Definition: ReelTwo.h:163
LogicEngineRenderer::updateDisplayPeak
void updateDisplayPeak()
Definition: LogicEngine.h:1003
LogicEngineSettings::fBri
byte fBri
Definition: LogicEngine.h:200
LogicEngineNabooRLD
Original Rear Logic PCB with Naboo logo on back.
LogicEngineSettings::fDelay
byte fDelay
Definition: LogicEngine.h:198
LogicEngineDefaults::kCyan
@ kCyan
Definition: LogicEngine.h:149
kOdd
@ kOdd
Definition: LogicEngine.h:2457
LogicEffectDefaultSelector
LogicEffect LogicEffectDefaultSelector(unsigned effectVal)
Definition: LogicEngine.h:2404
LogicEngineDefaults::FRONT_PAL
static constexpr byte FRONT_PAL
Definition: LogicEngine.h:98
LogicEngineSuperRLD
Super sized rear logic panel 32x8.
LogicEngineSettings
Current settings for LogicEngine hardware.
Definition: LogicEngine.h:176
kJawaOther
@ kJawaOther
Definition: JawaEvent.h:17
JawaID
JawaID
Definition: JawaEvent.h:6
LogicEngineRenderer::getID
unsigned getID() const
Definition: LogicEngine.h:751
LogicEngineRenderer::setEffectFontNum
void setEffectFontNum(byte fontNum)
Definition: LogicEngine.h:1108
CommandEvent
Base class for all command enabled devices. CommandEvent::handleCommand() is called for each device e...
Definition: CommandEvent.h:17
LogicEngineRenderer::LogicEngineRenderer
LogicEngineRenderer(byte id, byte tweens, byte totalColors, byte totalColorsWBIZ, unsigned width, unsigned height, unsigned count, unsigned start, unsigned end, CRGB *led, HSVColor *allColors, LEDStatus *ledStatus, const byte *ledMap, LogicRenderGlyph renderGlyph)
Definition: LogicEngine.h:1436
LogicEngineRenderer::getEffectObject
LogicEffectObject * getEffectObject()
Definition: LogicEngine.h:846
LogicEngineDefaults::ColorVal
ColorVal
Definition: LogicEngine.h:143
LogicEngineDeathStarFLD
2016 Version Front Logic PCB with Deathstar Plans on back
LogicEngineDefaults::MAX_BRIGHTNESS
static constexpr byte MAX_BRIGHTNESS
Definition: LogicEngine.h:107
LogicEngineDeathStarFLDInverted
LogicEngineDisplay< LogicEngineFLDPCB2Inverted< DATA_PIN >, LogicRenderGlyph5Pt > LogicEngineDeathStarFLDInverted
Definition: LogicEngine.h:2714
LogicEngineDefaults::SOLIDCOLOR
static constexpr byte SOLIDCOLOR
Definition: LogicEngine.h:119
LogicEngineDefaults::TEXT
static constexpr byte TEXT
Definition: LogicEngine.h:129
LogicEngineRenderer
Base class renderer for both front and rear RSeries logics.
Definition: LogicEngine.h:597
LogicEngineDefaults::FLIPFLOPCOLOR
static constexpr byte FLIPFLOPCOLOR
Definition: LogicEngine.h:121
LogicEngineDefaults::NORMAL
static constexpr byte NORMAL
Definition: LogicEngine.h:114
LogicEngineRenderer::LogicRenderGlyph
byte(* LogicRenderGlyph)(char ch, byte fontNum, const CRGB fontColors[], int x, int y, CRGB *leds, const byte *ledMap, int w, int h, byte *glyphHeight)
Definition: LogicEngine.h:604
LogicEngineRenderer::changePalette
void changePalette()
Definition: LogicEngine.h:963
AstroPixelRLD
2022 AstroPixel Rear Logic Display
LogicEngineRenderer::getEffectData
uint32_t getEffectData()
Definition: LogicEngine.h:851
ReelTwo.h
SetupEvent.h
LogicEngineDefaults::ALARM
static constexpr byte ALARM
Definition: LogicEngine.h:115
LogicEngineRenderer::selectScrollTextLeft
void selectScrollTextLeft(const char *text, ColorVal colorVal=kDefault, uint8_t speedScale=0, uint8_t numSeconds=0)
Definition: LogicEngine.h:627
LogicEngineDeathStarRLD
2016 Version Rear Logic PCB with Deathstar Plans on back
AstroPixelFLD
2022 AstroPixel Front Logic Display
LogicEngineRenderer::selectTextCenter
void selectTextCenter(const char *text, ColorVal colorVal=kDefault, uint8_t speedScale=0, uint8_t numSeconds=0)
Definition: LogicEngine.h:621
AnimatedEvent
Base class for all animated devices. AnimatedEvent::animate() is called for each device once through ...
Definition: AnimatedEvent.h:18
LogicEngineRenderer::getEffectMsgHeight
int getEffectMsgHeight()
Definition: LogicEngine.h:888
LogicRenderGlyph4Pt
byte LogicRenderGlyph4Pt(char ch, byte fontNum, const CRGB fontColors[], int x, int y, CRGB *leds, const byte *ledMap, int w, int h, byte *outGlyphHeight)
Definition: LogicEngine.h:2461
LogicEngineDeathStarRLDInvertedStaggerOdd
2016 Version Rear Logic PCB with Deathstar Plans on back. Mounted upside down.
SetupEvent
Base class for all devices that require setup that cannot happen in the constructor....
Definition: SetupEvent.h:15
Font8x5::getLetter
virtual bool getLetter(const char inChar, byte *outBuffer)=0
LogicEngineRenderer::getNextID
static int getNextID()
Definition: LogicEngine.h:756
kNone
@ kNone
Definition: LogicEngine.h:2455
LogicEngineRenderer::calculateAllColors
void calculateAllColors()
Definition: LogicEngine.h:1299
LogicEngineDefaults::REAR_HUE
static constexpr byte REAR_HUE
Definition: LogicEngine.h:96
LogicEngineRenderer::setDelay
void setDelay(byte delay)
Definition: LogicEngine.h:821
LogicEngineDefaults::sequence
static long sequence(byte seq, ColorVal colorVal=kDefault, uint8_t speedScale=0, uint8_t numSeconds=0)
Calculate sequence value given four parameters.
Definition: LogicEngine.h:160
LogicEngineDefaults
Default settings for LogicEngine hardware.
Definition: LogicEngine.h:87
LogicEngineDefaults::REAR_PSI_PAL
static constexpr byte REAR_PSI_PAL
Definition: LogicEngine.h:102
AnimatedEvent.h
LogicEngineDefaults::kMagenta
@ kMagenta
Definition: LogicEngine.h:152
LogicEngineRenderer::setPaletteHue
void setPaletteHue(byte palNum, byte hue)
Definition: LogicEngine.h:975
LogicEngineRenderer::setEffectFlip
void setEffectFlip(bool flip)
Definition: LogicEngine.h:841
LogicEngineDefaults::COLORSWAP
static constexpr byte COLORSWAP
Definition: LogicEngine.h:123
LogicEngineRenderer::getEffectData2
uint32_t getEffectData2()
Definition: LogicEngine.h:868
LogicEngineRenderer::setPMessageSelector
void setPMessageSelector(LogicPMessageSelector selector)
Definition: LogicEngine.h:938
LogicEngineDefaults::NORMVAL
static constexpr uint32_t NORMVAL
Definition: LogicEngine.h:110
FontVar4Pt
Base class for variable width 4pt fonts.
Definition: Font.h:98
LogicEngineRenderer::getPeakValue
byte getPeakValue()
Definition: LogicEngine.h:893
LogicEngineRenderer::setPeakValueProvider
void setPeakValueProvider(PeakValueProvider &provider)
Definition: LogicEngine.h:943
LogicEngineSettings::LogicEngineSettings
LogicEngineSettings()
Definition: LogicEngine.h:179
LogicEngineDefaults::kBlue
@ kBlue
Definition: LogicEngine.h:150
LogicEngineRenderer::getEffectMsgWidth
int getEffectMsgWidth()
Definition: LogicEngine.h:883
LogicEngineRenderer::setHSV
void setHSV(unsigned index, uint8_t hue, uint8_t sat, uint8_t val)
Definition: LogicEngine.h:953
LogicEngineDefaults::FLASHCOLOR
static constexpr byte FLASHCOLOR
Definition: LogicEngine.h:120
LogicEngineRenderer::count
unsigned count() const
Definition: LogicEngine.h:918
LogicEngineRenderer::selectScrollTextRight
void selectScrollTextRight(const char *text, ColorVal colorVal=kDefault, uint8_t speedScale=0, uint8_t numSeconds=0)
Definition: LogicEngine.h:633
LogicEngineDefaults::HORIZONTALSCANLINE
static constexpr byte HORIZONTALSCANLINE
Definition: LogicEngine.h:134
LogicEngineDefaults::kYellow
@ kYellow
Definition: LogicEngine.h:147
LogicEngineSettings::LogicEngineSettings
LogicEngineSettings(byte fade, byte hue, byte delay, byte palNum, byte bri, long defaultEffect=0)
Definition: LogicEngine.h:180
kJawaRFLD
@ kJawaRFLD
Definition: JawaEvent.h:11
LogicEngineRenderer::setPixel
void setPixel(int x, int y, byte effectHue, byte bri)
Definition: LogicEngine.h:1209
TEENSY_PROP_NEOPIXEL_BEGIN
#define TEENSY_PROP_NEOPIXEL_BEGIN()
Definition: ReelTwo.h:166
LogicEngineRenderer::measureText
unsigned measureText(PROGMEMString ptxt, int &outWidth, int &outHeight)
Definition: LogicEngine.h:1076
LogicEngineDefaults::TEXTSCROLLRIGHT
static constexpr byte TEXTSCROLLRIGHT
Definition: LogicEngine.h:131
LogicEngineRenderer::updateDisplay
void updateDisplay(byte bri)
Definition: LogicEngine.h:1008
LogicEngineDefaults::REDALERT
static constexpr byte REDALERT
Definition: LogicEngine.h:125
LogicEngineRenderer::getEffectFontNum
byte getEffectFontNum()
Definition: LogicEngine.h:1103
LogicEngineRenderer::resetEffect
void resetEffect()
Definition: LogicEngine.h:742
LogicEngineDefaults::MIN_BRIGHTNESS
static constexpr byte MIN_BRIGHTNESS
Definition: LogicEngine.h:108
LogicEngineDefaults::kDefault
@ kDefault
Definition: LogicEngine.h:154
PeakValueProvider.h
LogicEngineRenderer::mapSelectColorToHue
static int mapSelectColorToHue(unsigned selectColor)
Definition: LogicEngine.h:1415
LogicEngineDefaults::FRONT_FADE
static constexpr byte FRONT_FADE
Definition: LogicEngine.h:90
FontVar4Pt::getLetter
virtual bool getLetter(const char inChar, byte *outBuffer, byte &rowBytes, byte &advance)
LogicEngineRenderer::setEffectWidthRange
void setEffectWidthRange(float percent)
Definition: LogicEngine.h:878
LogicEngineDefaults::LIGHTSOUT
static constexpr byte LIGHTSOUT
Definition: LogicEngine.h:128
LogicEngineDefaults::kOrange
@ kOrange
Definition: LogicEngine.h:146
LogicEngineRenderer::getEffectFlip
bool getEffectFlip()
Definition: LogicEngine.h:836
LogicEngineDefaults::MICRAINBOW
static constexpr byte MICRAINBOW
Definition: LogicEngine.h:127
LogicEngineRenderer::renderText
void renderText(int x, int y, byte effectHue)
Definition: LogicEngine.h:1166
LogicEngineRenderer::updateDisplaySplitHalf
void updateDisplaySplitHalf(byte topBri, byte bottomBri)
Definition: LogicEngine.h:1015
PeakValueProvider
Base class peak value providers, currently only microphone amplitude.
Definition: PeakValueProvider.h:13
LogicEngineRenderer::setup
virtual void setup() override
Subclasses must implement this function to perform any necessary setup that cannot happen in the cons...
Definition: LogicEngine.h:668
LogicEngineRenderer::hasEffectChanged
bool hasEffectChanged()
Definition: LogicEngine.h:737
LogicEngineCurvedFLD
2020 Version Front Logic PCB for curved logics
LogicEngineRenderer::jawaCommand
virtual void jawaCommand(char cmd, const char *arg) override
Subclasses should override this method to handle commands.
Definition: LogicEngine.h:1393
LogicEngineRenderer::clear
void clear()
Definition: LogicEngine.h:1153
LogicEngineRenderer::clearBlockedPortion
void clearBlockedPortion()
Definition: LogicEngine.h:982
LogicEngineRenderer::mapLED
unsigned mapLED(unsigned index)
Definition: LogicEngine.h:923
LogicEngineCurvedRLD
2020 Version Rear Logic PCB for curved logics
LatinFont8x5::instance
static Font8x5 * instance()
Definition: Font.h:534
LogicEngineRenderer::jawaCommand
virtual void jawaCommand(char cmd, int arg, int value) override
Subclasses should override this method to handle commands specifying a value.
Definition: LogicEngine.h:1328
LogicEffectObject
Definition: LogicEngine.h:577
LogicEngineCurvedRLDInverted
2020 Version Rear Logic PCB for curved logics. Mounted upside down.
LogicEngineRenderer::measureText
unsigned measureText(const char *txt, int &outWidth, int &outHeight)
Definition: LogicEngine.h:1050
LogicRenderGlyph
LogicEngineRenderer::LogicRenderGlyph LogicRenderGlyph
Definition: LogicEngine.h:1547
LogicEngineRenderer::fSettings
LogicEngineSettings fSettings
Definition: LogicEngine.h:1485
LogicEngineDefaults::MICBRIGHT
static constexpr byte MICBRIGHT
Definition: LogicEngine.h:126
JawaEvent
Base class for all devices implementing JAWA lite support.
Definition: JawaEvent.h:31
LogicEngineRenderer::getEffectTextMsg
int getEffectTextMsg()
Definition: LogicEngine.h:785
kJawaTFLD
@ kJawaTFLD
Definition: JawaEvent.h:9
LogicEngineRenderer::updateDisplay
void updateDisplay()
Definition: LogicEngine.h:998
LogicEngineRenderer::animate
virtual void animate() override
Subclasses must implement this function to run through a single frame of animation/activity.
Definition: LogicEngine.h:684
LogicEngineRenderer::getUnmappedLEDStatus
LEDStatus * getUnmappedLEDStatus()
Definition: LogicEngine.h:1199
LogicEngineDefaults::RAINBOW
static constexpr byte RAINBOW
Definition: LogicEngine.h:124
Font.h
LogicEngineRenderer::getFade
byte getFade()
Definition: LogicEngine.h:806
LogicEngineDefaults::FRONT_HUE
static constexpr byte FRONT_HUE
Definition: LogicEngine.h:92
LogicEngineRenderer::setBrightness
void setBrightness(byte bri)
Definition: LogicEngine.h:831
LogicEngineRenderer::changeSettings
void changeSettings(LogicEngineSettings &newSettings)
Definition: LogicEngine.h:1408
LogicEngineRenderer::updateDisplaySplitRowThirds
void updateDisplaySplitRowThirds(byte topBri, byte bottomBri)
Definition: LogicEngine.h:1024
LogicEngineRenderer::set
void set(unsigned index, const struct CRGB &val)
Definition: LogicEngine.h:948
LogicEngineSettings::fPalNum
byte fPalNum
Definition: LogicEngine.h:199
LogicEngineDefaults::kRed
@ kRed
Definition: LogicEngine.h:145
LogicEngineRenderer::restoreSettings
void restoreSettings()
Definition: LogicEngine.h:958
LEDStatus::fColorNum
byte fColorNum
Color number.
Definition: LogicEngine.h:73
LogicEngineSettings::fHue
byte fHue
Definition: LogicEngine.h:197
JawaEvent.h
LogicEngineRenderer::selectEffect
void selectEffect(long inputNum)
Definition: LogicEngine.h:611
LogicEngineRenderer::getHue
byte getHue()
Definition: LogicEngine.h:796
LogicEngineRenderer::setupTextMessage
void setupTextMessage(int selectTextMsg)
Definition: LogicEngine.h:1131
LogicEngineDefaults::kPink
@ kPink
Definition: LogicEngine.h:153
LogicEngineDefaults::TEXTSCROLLUP
static constexpr byte TEXTSCROLLUP
Definition: LogicEngine.h:132
LogicEngineRenderer::setPixelRGB
void setPixelRGB(int x, int y, uint8_t r, uint8_t g, uint8_t b)
Definition: LogicEngine.h:1226
LogicEngineRenderer::getEffectSpeed
int getEffectSpeed()
Definition: LogicEngine.h:773
LEDStatus
Current color number and pause value for a single LED.
Definition: LogicEngine.h:68
LogicEffect
LogicEngineRenderer::LogicEffect LogicEffect
Definition: LogicEngine.h:1545
LogicEngineRenderer::hasEffectChangedType
bool hasEffectChangedType()
Definition: LogicEngine.h:746
LogicEngineRenderer::setTextMessage
void setTextMessage(const char *msg)
Definition: LogicEngine.h:1122
LogicEngineDefaults::REAR_BRI
static constexpr byte REAR_BRI
Definition: LogicEngine.h:105
LogicEngineRenderer::updateMappedLED
void updateMappedLED(unsigned index, byte hueVal, byte briVal=255)
Definition: LogicEngine.h:1304
LogicEffectSelector
LogicEngineRenderer::LogicEffectSelector LogicEffectSelector
Definition: LogicEngine.h:1546
LogicEngineRenderer::setMessageSelector
void setMessageSelector(LogicMessageSelector selector)
Definition: LogicEngine.h:933
LogicEngineRenderer::getSettings
LogicEngineSettings getSettings()
Definition: LogicEngine.h:1403
LogicEngineRenderer::handleCommand
virtual void handleCommand(const char *cmd)
Subclasses should implement this function to process commands specific to their device.
Definition: LogicEngine.h:645
LogicEngineRenderer::setFade
void setFade(byte fade)
Definition: LogicEngine.h:811
LogicEngineDefaults::REAR_PAL
static constexpr byte REAR_PAL
Definition: LogicEngine.h:99
LogicEngineRenderer::setLogicEffectSelector
void setLogicEffectSelector(LogicEffectSelector selector)
Definition: LogicEngine.h:928
LogicEngineRenderer::getDelay
byte getDelay()
Definition: LogicEngine.h:816
LogicEngineDefaults::FLIPFLOPALTCOLOR
static constexpr byte FLIPFLOPALTCOLOR
Definition: LogicEngine.h:122
LogicEngineDefaults::VERTICALSCANLINE
static constexpr byte VERTICALSCANLINE
Definition: LogicEngine.h:135
LogicEngineRenderer::height
int height() const
Definition: LogicEngine.h:913
LogicEngineRenderer::setEffectObject
void setEffectObject(LogicEffectObject *obj)
Definition: LogicEngine.h:856
PROGMEMString
const typedef __FlashStringHelper * PROGMEMString
Definition: ReelTwo.h:235
LogicEngineDefaults::kPurple
@ kPurple
Definition: LogicEngine.h:151
LogicEngineRenderer::width
int width() const
Definition: LogicEngine.h:908
LogicEffectObject::~LogicEffectObject
virtual ~LogicEffectObject()
Definition: LogicEngine.h:580
LogicEngineRenderer::setHue
void setHue(byte hue)
Definition: LogicEngine.h:801
LogicEngineDefaults::REAR_DELAY
static constexpr byte REAR_DELAY
Definition: LogicEngine.h:95
getlsbposm1
byte getlsbposm1(byte x)
Definition: LogicEngine.h:2446
LogicEngineRenderer::calculateAllColors
void calculateAllColors(byte colorPalNum, byte brightVal)
Definition: LogicEngine.h:1238
LogicEngineRenderer::getDefaultEffectDelay
static constexpr uint32_t getDefaultEffectDelay()
Definition: LogicEngine.h:898
UNUSED_ARG
#define UNUSED_ARG(arg)
Definition: ReelTwo.h:25
LogicEngineDefaults::LEIA
static constexpr byte LEIA
Definition: LogicEngine.h:117
LogicEngineDefaults::MARCH
static constexpr byte MARCH
Definition: LogicEngine.h:118
LatinFontVar4pt::instance
static FontVar4Pt * instance()
Definition: Font.h:142
CommandEvent.h
LogicEngineRenderer::getEffectColor
int getEffectColor()
Definition: LogicEngine.h:762
LogicEngineRenderer::setEffectData2
void setEffectData2(uint32_t data)
Definition: LogicEngine.h:873
LogicEngineDefaults::REAR_FADE
static constexpr byte REAR_FADE
Definition: LogicEngine.h:94
LogicEngineCurvedFLDInverted
LogicEngineDisplay< LogicEngineFLDPCB2Inverted< DATA_PIN >, LogicRenderGlyph5Pt > LogicEngineCurvedFLDInverted
Definition: LogicEngine.h:2795
LEDStatus::fColorPause
byte fColorPause
Pause value.
Definition: LogicEngine.h:78
LogicEngineDefaults::PSICOLORWIPE
static constexpr byte PSICOLORWIPE
Definition: LogicEngine.h:137
LogicEngineDefaults::RANDOM
static constexpr byte RANDOM
Definition: LogicEngine.h:139
kEven
@ kEven
Definition: LogicEngine.h:2456
LogicEngineDefaults::FRONT_PSI_PAL
static constexpr byte FRONT_PSI_PAL
Definition: LogicEngine.h:101
LogicEngineRenderer::selectSequence
void selectSequence(byte seq, ColorVal colorVal=kDefault, uint8_t speedScale=0, uint8_t numSeconds=0)
Definition: LogicEngine.h:616
LogicEngineSettings::fFade
byte fFade
Definition: LogicEngine.h:196
LogicEngineRenderer::sLastEventCount
static uint16_t sLastEventCount
Definition: LogicEngine.h:1490
LogicEngineRenderer::getEffectDuration
unsigned getEffectDuration()
Definition: LogicEngine.h:791
LogicEngineKennyFLD
2014 Version Front Logic PCB with C3PO on back
SizeOfArray
#define SizeOfArray(arr)
Definition: ReelTwo.h:213
LogicEngineRenderer::selectScrollTextUp
void selectScrollTextUp(const char *text, ColorVal colorVal=kDefault, uint8_t speedScale=0, uint8_t numSeconds=0)
Definition: LogicEngine.h:639
LogicStaggerType
LogicStaggerType
Definition: LogicEngine.h:2454
LogicEngineRenderer::getUnmappedLEDs
CRGB * getUnmappedLEDs()
Definition: LogicEngine.h:1204
Font8x5
Base class for 8x5 fonts.
Definition: Font.h:48
LogicEngineDeathStarRLDStaggerOdd
2016 Version Rear Logic PCB with Deathstar Plans on back. LEDs are staggered on odd rows
LogicEngineDefaults::FRONT_DELAY
static constexpr byte FRONT_DELAY
Definition: LogicEngine.h:91
LogicEngineDefaults::kGreen
@ kGreen
Definition: LogicEngine.h:148
LogicEngineRenderer::LogicEffectSelector
LogicEffect(* LogicEffectSelector)(unsigned effectVal)
Definition: LogicEngine.h:601
LogicEngineDefaults::PAL_COUNT
static constexpr byte PAL_COUNT
Definition: LogicEngine.h:111
LogicEngineNabooFLD
Original Front Logic PCB with Naboo logo on back.
LogicEngineRenderer::getCurrentPalette
unsigned getCurrentPalette()
Definition: LogicEngine.h:970
LogicEngineRenderer::randomColor
ColorVal randomColor()
Definition: LogicEngine.h:606
LogicEngineDefaults::PULSE
static constexpr byte PULSE
Definition: LogicEngine.h:138
LogicEngineRenderer::getEffectLength
int getEffectLength()
Definition: LogicEngine.h:779
LogicEngineRenderer::setPixelRGB
void setPixelRGB(int x, int y, const struct CRGB &val)
Definition: LogicEngine.h:1218
LogicEngineSettings::fDefaultEffect
long fDefaultEffect
Definition: LogicEngine.h:201
LogicEngineDefaults::FIRE
static constexpr byte FIRE
Definition: LogicEngine.h:136
LogicEngineRenderer::getBrightness
byte getBrightness()
Definition: LogicEngine.h:826
USE_LEDLIB
#define USE_LEDLIB
Definition: LEDPixelEngine.h:8
LogicEngineKennyRLD
2014 Version Rear Logic PCB with Kenny & McQuarry art on back
LogicEngineDefaults::ROAMINGPIXEL
static constexpr byte ROAMINGPIXEL
Definition: LogicEngine.h:133
AnimatedEvent::setLoopDoneCallback
void setLoopDoneCallback(AnimatedLoopDone loopProc)
Definition: AnimatedEvent.h:69
LogicEngineRenderer::setEffectData
void setEffectData(uint32_t data)
Definition: LogicEngine.h:863
AurabeshFont8x5::instance
static Font8x5 * instance()
Definition: Font.h:889
LogicEngineRenderer::getEffectHue
int getEffectHue()
Definition: LogicEngine.h:768
LogicEngineDefaults::FRONT_BRI
static constexpr byte FRONT_BRI
Definition: LogicEngine.h:104
LogicEngineDefaults::TEXTSCROLLLEFT
static constexpr byte TEXTSCROLLLEFT
Definition: LogicEngine.h:130
TEENSY_PROP_NEOPIXEL_END
#define TEENSY_PROP_NEOPIXEL_END()
Definition: ReelTwo.h:169
LogicEngineDefaults::FAILURE
static constexpr byte FAILURE
Definition: LogicEngine.h:116