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) 
   22   #define FRONT_LOGIC_PIN 6 
   23  #elif defined(REELTWO_RP2040) 
   24   #define FRONT_LOGIC_PIN 15 
   25   #define FRONT_LOGIC_CLOCK_PIN 2 
   27   #define FRONT_LOGIC_PIN 15 
   28   #define FRONT_LOGIC_CLOCK_PIN 2 
   30   #error Unsupported platform 
   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) 
   44   #define REAR_LOGIC_PIN 6 
   45  #elif defined(REELTWO_RP2040) 
   46   #define REAR_LOGIC_PIN  33 
   47   #define REAR_LOGIC_CLOCK_PIN  32 
   49   #define REAR_LOGIC_PIN  33 
   50   #define REAR_LOGIC_CLOCK_PIN  32 
   52   #error Unsupported platform 
  117     static constexpr 
byte LEIA = 3;
 
  129     static constexpr 
byte TEXT = 15;
 
  136     static constexpr 
byte FIRE = 22;
 
  163             (
long int)seq * 10000L +
 
  164             (
long int)colorVal * 1000L +
 
  165             (
long int)speedScale * 100 +
 
  186         long defaultEffect = 0) :
 
  211 template <
template<u
int8_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>
 
  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
 
  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;
 
  234         FastLED.addLeds<CHIPSET, DATA_PIN, GRB>(fLED, count);
 
  235         fill_solid(fLED, _count, CRGB(0,0,0));
 
  236     #elif USE_LEDLIB == 1 
  239         numBytes = count * 3;
 
  240         pixels = (uint8_t*)&fLED;
 
  241         memset(fLED, 
'\0', 
sizeof(fLED));
 
  253         Adafruit_NeoPixel::show();
 
  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
 
  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;
 
  277         FastLED.addLeds<CHIPSET, DATA_PIN, CLOCK_PIN, RGB_ORDER>(fLED, count);
 
  278         fill_solid(fLED, _count, CRGB(0,0,0));
 
  287 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
  288 class LogicEngineFLDPCB0 : 
public FastLEDPCB<WS2812B, DATA_PIN, 96, 8, 88, 8, 10>
 
  291     static inline const byte* getLEDMap()
 
  295         static const byte sLEDmap[] PROGMEM =
 
  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
 
  313 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
  314 class LogicEngineFLDPCB1 : 
public FastLEDPCB<WS2812B, DATA_PIN, 80, 0, 80, 8, 10>
 
  317     static inline const byte* getLEDMap()
 
  321         static const byte sLEDmap[] PROGMEM =
 
  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
 
  339 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
  340 class LogicEngineFLDPCB2 : 
public FastLEDPCB<SK6812, DATA_PIN, 80, 0, 80, 8, 10>
 
  343     static inline const byte* getLEDMap()
 
  347         static const byte sLEDmap[] PROGMEM =
 
  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
 
  365 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
  366 class LogicEngineFLDPCB2Inverted : 
public FastLEDPCB<SK6812, DATA_PIN, 80, 0, 80, 8, 10>
 
  369     static inline const byte* getLEDMap()
 
  373         static const byte sLEDmap[] PROGMEM =
 
  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
 
  391 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
  392 class AstroPixelFLDPCB0 : 
public FastLEDPCB<WS2812B, DATA_PIN, 90, 0, 90, 9, 10>
 
  395     static inline const byte* getLEDMap()
 
  399         static const byte sLEDmap[] PROGMEM =
 
  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
 
  416 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
  417 class LogicEngineRLDPCB0 : 
public FastLEDPCB<WS2812B, DATA_PIN, 80, 0, 80, 16, 4>
 
  420     static inline const byte* getLEDMap()
 
  424         static const byte sLEDmap[] PROGMEM =
 
  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
 
  438 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
  439 class LogicEngineRLDPCBSUPER : 
public FastLEDPCB<WS2812B, DATA_PIN, 256, 0, 255, 32, 8>
 
  442     static inline const byte* getLEDMap()
 
  444         static const byte sLEDmap[] PROGMEM =
 
  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
 
  460 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
  461 class LogicEngineRLDPCB1 : 
public FastLEDPCB<WS2812B, DATA_PIN, 96, 0, 96, 24, 4>
 
  464     static inline const byte* getLEDMap()
 
  467         static const byte sLEDmap[] PROGMEM =
 
  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
 
  479 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
  480 class LogicEngineRLDPCB2 : 
public FastLEDPCB<SK6812, DATA_PIN, 96, 0, 96, 24, 4>
 
  483     static inline const byte* getLEDMap()
 
  486         static const byte sLEDmap[] PROGMEM =
 
  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
 
  498 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
  499 class LogicEngineRLDPCB2Inverted : 
public FastLEDPCB<SK6812, DATA_PIN, 96, 0, 96, 24, 4>
 
  502     static inline const byte* getLEDMap()
 
  506         static const byte sLEDmap[] PROGMEM =
 
  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
 
  518 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
  519 class AstroPixelRLDPCB0 : 
public FastLEDPCB<WS2812B, DATA_PIN, 108, 0, 108, 27, 4>
 
  522     static inline const byte* getLEDMap()
 
  525         static const byte sLEDmap[] PROGMEM =
 
  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   
 
  537 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN, u
int8_t CLOCK_PIN = REAR_LOGIC_CLOCK_PIN>
 
  539 class LogicEngineRLDPCB3 : 
public FastLEDPCBClock<SK9822, DATA_PIN, CLOCK_PIN, BGR, 112, 0, 112, 28, 4>
 
  542     static inline const byte* getLEDMap()
 
  545         static const byte sLEDmap[] PROGMEM =
 
  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
 
  557 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN, u
int8_t CLOCK_PIN = REAR_LOGIC_CLOCK_PIN>
 
  558 class LogicEngineRLDPCB3Inverted : 
public FastLEDPCBClock<SK9822, DATA_PIN, CLOCK_PIN, BGR, 112, 0, 112, 28, 4>
 
  561     static inline const byte* getLEDMap()
 
  565         static const byte sLEDmap[] PROGMEM =
 
  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
 
  602     typedef const char* (*LogicMessageSelector)(
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);
 
  613         fDisplayEffectVal = inputNum;
 
  618         selectEffect(sequence(seq, colorVal, speedScale, numSeconds));
 
  623         setTextMessage(text);
 
  624         selectEffect(sequence(TEXT, colorVal, speedScale, numSeconds));
 
  629         setTextMessage(text);
 
  630         selectEffect(sequence(TEXTSCROLLLEFT, colorVal, speedScale, numSeconds));
 
  635         setTextMessage(text);
 
  636         selectEffect(sequence(TEXTSCROLLRIGHT, colorVal, speedScale, numSeconds));
 
  641         setTextMessage(text);
 
  642         selectEffect(sequence(TEXTSCROLLUP, colorVal, speedScale, numSeconds));
 
  647         int length = strlen(cmd);
 
  648         if (*cmd++ == 
'L' && *cmd++ == 
'E')
 
  650             long int cmdvalue = 0;
 
  655                 unsigned reqId = *c++ - 
'0';
 
  656                 if (reqId != getID()) {
 
  660             while (*c >= 
'0' && *c <= 
'9')
 
  662                 cmdvalue = cmdvalue * 10 + (*c++ - 
'0');
 
  664             selectEffect(cmdvalue);
 
  671         calculateAllColors(fSettings.fPalNum, fSettings.fBri);
 
  672         for (
unsigned i = 0; i < count(); i++)
 
  674             unsigned index = mapLED(i);
 
  675             LEDStatus* ledStatus = &fLEDStatus[index];
 
  676             ledStatus->
fColorNum = random8(fTotalColorsWBIZ);
 
  678             updateMappedLED(index, fSettings.fHue);
 
  680         fStatusMillis = millis();
 
  681         fDisplayEffectVal = fSettings.fDefaultEffect;
 
  686         uint32_t currentMillis = millis();
 
  687         if (fLastMillis + 10L > currentMillis)
 
  689         fLastMillis = currentMillis;
 
  690         if (currentMillis - fStatusMillis >= fStatusDelay)
 
  692             fStatusMillis = currentMillis;
 
  693             fFlipFlop = !fFlipFlop;
 
  695         int selectSequence = (fDisplayEffectVal % 100000000L) / 10000L;
 
  696         int selectLength = (fDisplayEffectVal % 100);
 
  699         if (hasEffectChanged())
 
  701             setEffectObject(NULL);
 
  703             calculateAllColors(fSettings.fPalNum, fSettings.fBri);
 
  704             fStatusDelay = getDefaultEffectDelay();
 
  705             fEffectStartMillis = currentMillis;
 
  706             if (fEffectSelector != NULL)
 
  708                 fLogicEffect = fEffectSelector(selectSequence);
 
  711         fEffectMillis = currentMillis - fEffectStartMillis;
 
  713         bool continueEffect = (fLogicEffect != NULL) ? fLogicEffect(*
this) : 
false;
 
  714         fPreviousEffectVal = fDisplayEffectVal;
 
  715         if (!continueEffect || (selectLength > 0 && 
unsigned(selectLength) * 1000L < fEffectMillis))
 
  717             if (selectSequence == RANDOM)
 
  720                 fPreviousEffectVal = ~fDisplayEffectVal;
 
  724                 selectEffect(fSettings.fDefaultEffect); 
 
  727         fPreviousEffect = fDisplayEffect;
 
  730     #elif USE_LEDLIB == 1 
  739         return (fPreviousEffectVal != fDisplayEffectVal);
 
  743             fPreviousEffectVal = ~fDisplayEffectVal;
 
  748         return (fPreviousEffect != fDisplayEffect);
 
  764         int selectColor = (fDisplayEffectVal % 10000) / 1000;
 
  770         return mapSelectColorToHue(getEffectColor());
 
  775         int selectSpeed = (fDisplayEffectVal % 1000) / 100;
 
  781         int selectLength = (fDisplayEffectVal % 100);
 
  787         int selectTextMsg = (fDisplayEffectVal % 100000000) / 10000000;
 
  788         return selectTextMsg;
 
  793         return fEffectMillis;
 
  798         return fSettings.fHue;
 
  803         fSettings.fHue = hue;
 
  808         return fSettings.fFade;
 
  813         fSettings.fFade = fade;
 
  818         return fSettings.fDelay;
 
  823         fSettings.fDelay = delay;
 
  828         return fSettings.fBri;
 
  833         fSettings.fBri = bri;
 
  848         return fEffectObject;
 
  858         if (fEffectObject != NULL)
 
  859             delete fEffectObject;
 
  880         fEffectRange = max(min(1.0f, percent), 0.0f);
 
  885         return fEffectMsgWidth;
 
  890         return fEffectMsgHeight;
 
  895         return (fPeakSource != NULL) ? fPeakSource->getPeakValue() : 0;
 
  905         fStatusDelay = effectDelay;
 
  925         return pgm_read_byte(&fLEDMap[index]);
 
  930         fEffectSelector = selector;
 
  935         fMessageSelector = selector;
 
  940         fPMessageSelector = selector;
 
  945         fPeakSource = &provider;
 
  948     void set(
unsigned index, 
const struct CRGB& val)
 
  950         fLED[pgm_read_byte(&fLEDMap[fLEDStart + index])] = val;
 
  953     void setHSV(
unsigned index, uint8_t hue, uint8_t sat, uint8_t val)
 
  955         fLED[pgm_read_byte(&fLEDMap[fLEDStart + index])].setHSV(hue, sat, val);
 
  965         if (++fSettings.fPalNum == PAL_COUNT)
 
  966             fSettings.fPalNum = 0;
 
  967         calculateAllColors(fSettings.fPalNum, fSettings.fBri);
 
  972         return fSettings.fPalNum;
 
  977         fSettings.fPalNum = palNum;
 
  978         fSettings.fHue = hue;
 
  979         calculateAllColors(fSettings.fPalNum, fSettings.fBri);
 
  984         int blackX = int(fEffectRange * width());
 
  985         if (blackX < width())
 
  987             CRGB blackColor = { 0, 0, 0 };
 
  988             for (
int x = blackX; x < width(); x++)
 
  990                 for (
int y = 0; y < height(); y++)
 
  992                     fLED[pgm_read_byte(&fLEDMap[y * width() + x])] = blackColor;
 
 1000         updateDisplay(fSettings.fBri);
 
 1005         updateDisplay((fPeakSource != NULL) ? fPeakSource->getPeakValue() : fSettings.fBri);
 
 1010         for (
unsigned i = fLEDStart; i < fLEDEnd; i++)
 
 1011             updateMappedLED(mapLED(i), fSettings.fHue, bri); 
 
 1012         clearBlockedPortion();
 
 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();
 
 1026         if (width() % 3 == 0)
 
 1030             unsigned index = fLEDStart;
 
 1031             unsigned third = width() / 3;
 
 1032             for (
byte row = 0; row < height() * 3; row++)
 
 1034                 for (
byte col = 0; col < third && index < fLEDEnd; col++, index++)
 
 1035                     updateMappedLED(mapLED(index), fSettings.fHue, (!flip) ? topBri : bottomBri);
 
 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);
 
 1047         clearBlockedPortion();
 
 1055         byte glyphHeight = 0;
 
 1058         fRenderGlyph(
' ', fEffectFontNum, NULL, 0, 0, NULL, NULL, 0, 0, &glyphHeight);
 
 1059         while ((ch = *txt++) != 
'\0')
 
 1064                 outWidth = max(outWidth, textWidth);
 
 1065                 outHeight += glyphHeight;
 
 1069             textWidth += fRenderGlyph(ch, fEffectFontNum, NULL, 0, 0, NULL, NULL, 0, 0, NULL);
 
 1071         outWidth = max(outWidth, textWidth);
 
 1072         outHeight = (outWidth > 0) ? outHeight + glyphHeight : 0;
 
 1081         byte glyphHeight = 0;
 
 1082         const char* txt = (
const char*)ptxt;
 
 1085         fRenderGlyph(
' ', fEffectFontNum, NULL, 0, 0, NULL, NULL, 0, 0, &glyphHeight);
 
 1086         while ((ch = pgm_read_byte(txt++)) != 
'\0')
 
 1091                 outWidth = max(outWidth, textWidth);
 
 1092                 outHeight += glyphHeight;
 
 1096             textWidth += fRenderGlyph(ch, fEffectFontNum, NULL, 0, 0, NULL, NULL, 0, 0, NULL);
 
 1098         outWidth = max(outWidth, textWidth);
 
 1099         outHeight = (outWidth > 0) ? outHeight + glyphHeight : 0;
 
 1105         return fEffectFontNum;
 
 1110         fEffectFontNum = fontNum;
 
 1112         if (fEffectMsgText != NULL)
 
 1114             fEffectMsgLen = measureText(fEffectMsgText, fEffectMsgWidth, fEffectMsgHeight);
 
 1116         else if (fEffectMsgTextP != NULL)
 
 1118             fEffectMsgLen = measureText(fEffectMsgTextP, fEffectMsgWidth, fEffectMsgHeight);
 
 1124         fEffectMsgLen = fEffectMsgWidth = 0;
 
 1125         fEffectMsgText = msg;
 
 1126         fEffectMsgTextP = NULL;
 
 1127         if (fEffectMsgText != NULL)
 
 1128             fEffectMsgLen = measureText(fEffectMsgText, fEffectMsgWidth, fEffectMsgHeight);
 
 1133         fEffectMsgLen = fEffectMsgWidth = 0;
 
 1134         if (selectTextMsg != 0)
 
 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");
 
 1143         if (fEffectMsgText != NULL)
 
 1145             fEffectMsgLen = measureText(fEffectMsgText, fEffectMsgWidth, fEffectMsgHeight);
 
 1147         else if (fEffectMsgTextP != NULL)
 
 1149             fEffectMsgLen = measureText(fEffectMsgTextP, fEffectMsgWidth, fEffectMsgHeight);
 
 1156         fill_solid(fLED, count(), CRGB(0,0,0));
 
 1157     #elif USE_LEDLIB == 1 
 1158         int numToFill = count();
 
 1160         CRGB color = CRGB(0, 0, 0);
 
 1161         for (
int i = 0; i < numToFill; i++)
 
 1170         byte hue = fAllColors[0].h + effectHue;
 
 1171         byte sat = fAllColors[0].s;
 
 1172         fontColors[0].setHSV(hue, sat, 1);  
 
 1173         fontColors[1].setHSV(hue, sat, 16);
 
 1174         fontColors[2].setHSV(hue, sat, 64); 
 
 1177         for (
int i = 0; i < fEffectMsgLen; i++)
 
 1180             if (fEffectMsgText != NULL)
 
 1181                 ch = fEffectMsgText[i];
 
 1182             if (fEffectMsgTextP != NULL)
 
 1183                 ch = pgm_read_byte(&((
const char*)fEffectMsgTextP)[i]);
 
 1189             else if (x < width())
 
 1191                 int adv = fRenderGlyph(ch, fEffectFontNum, fontColors, x, y, fLED, fLEDMap, fWidth, fHeight, NULL);
 
 1211         if (
unsigned(x) < 
unsigned(fEffectRange * width()) && 
unsigned(y) < 
unsigned(height()))
 
 1213             fLED[pgm_read_byte(&fLEDMap[y * width() + x])].setHSV(
 
 1214                 fAllColors[0].h + effectHue, fAllColors[0].s, bri);
 
 1220         if (
unsigned(x) < 
unsigned(fEffectRange * width()) && 
unsigned(y) < 
unsigned(height()))
 
 1222             fLED[pgm_read_byte(&fLEDMap[y * width() + x])] = val;
 
 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);
 
 1243         static const HSVColor keyColors[PAL_COUNT][4] PROGMEM = {
 
 1244           { {170, 255,   0} , {170, 255,  85} , {170, 255, 170} , {170,   0, 170}  } , 
 
 1245           { { 90, 235,   0} , { 75, 255, 250} , { 30, 255, 184} , {  0, 255, 250}  } , 
 
 1246           { {  0, 255,   0} , {  0, 255,   0} , {  0, 255, 100} , {  0, 255, 250}  } , 
 
 1247           { {  0, 255,   0} , {  0, 255, 250} , { 40, 255,   0} , { 40, 255, 250}  } , 
 
 1248           { {165, 50,  248} , {166, 181, 226} , {165, 223,  89} , {255, 255, 214}  } ,  
 
 1249           { {87, 206,  105} , { 79, 255, 214} , { 43, 255, 250} , { 25, 255, 214}  }    
 
 1253         for (
byte kcol = 0; kcol < 4; kcol++)
 
 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)
 
 1262             byte tnum = kcol + fTweens * kcol;
 
 1263             HSVColor* tc = &fAllColors[tnum];
 
 1264             tc->h = workColor.h;
 
 1265             tc->s = workColor.s;
 
 1267             brightVal = min(brightVal, (
byte)MAX_BRIGHTNESS);
 
 1268             tc->v = map8(workColor.v, MIN_BRIGHTNESS, brightVal);
 
 1269             if (tnum + 1 != fTotalColors)
 
 1271                 const HSVColor* hsvptr = &keyColors[colorPalNum][kcol + 1];
 
 1272                 for (
byte el = 0; el < 3; el++)
 
 1275                     int perStep = int(pgm_read_byte(&hsvptr->c[el]) - workColor.c[el]) / (fTweens + 1);
 
 1278                         for (
byte tweenCount = 1; tweenCount <= fTweens; tweenCount++)
 
 1280                             byte val = workColor.c[el] + tweenCount * perStep;
 
 1281                             tc[tweenCount].c[el] = (el == 2) ?
 
 1282                                 map8(val, MIN_BRIGHTNESS, brightVal) : val;
 
 1288                         for (
byte tweenCount = 1; tweenCount <= fTweens; tweenCount++)
 
 1290                             tc[tweenCount].c[el] = (el == 2) ?
 
 1291                                 map8(workColor.c[el], MIN_BRIGHTNESS, brightVal) : workColor.c[el];
 
 1301         calculateAllColors(fSettings.fPalNum, fSettings.fBri);
 
 1306         LEDStatus* ledStatus = &fLEDStatus[index];
 
 1314             if (ledStatus->
fColorNum >= fTotalColorsWBIZ)
 
 1316             byte realColor = actualColorNum(ledStatus->
fColorNum);
 
 1319                     random8(fSettings.fDelay) : 
 
 1322             HSVColor* myColor = &fAllColors[realColor];
 
 1323             fLED[index].setHSV(myColor->h + hueVal, myColor->s,
 
 1324                 (briVal == 255) ? myColor->v : map8(briVal, 0, myColor->v));
 
 1335                 selectEffect(NORMVAL);
 
 1341                 fSettings.fFade = arg;
 
 1344                 fSettings.fDelay = arg;
 
 1347                 fSettings.fHue = arg;
 
 1350                 fSettings.fBri = arg;
 
 1351                 calculateAllColors();
 
 1373                         if (++fSettings.fPalNum >= PAL_COUNT)
 
 1374                             fSettings.fPalNum = 0;
 
 1375                         calculateAllColors();
 
 1381                 selectSequence(RANDOM);
 
 1385                 fDisplayEffectVal = (fDisplayEffectVal / 100) * 100 + arg;
 
 1388                 selectEffect(TEXTSCROLLLEFT);
 
 1398                 setTextMessage(arg);
 
 1410         fSettings = newSettings;
 
 1417         static const byte sEffectHue[] PROGMEM = {
 
 1418             0,0,26,42,85,128,170,202,213,228
 
 1420         return (selectColor < 
SizeOfArray(sEffectHue)) ? pgm_read_byte(&sEffectHue[selectColor]) : 0;
 
 1440         byte totalColorsWBIZ,
 
 1447         HSVColor* allColors,
 
 1451             fID((id == 0) ? getNextID() : id),
 
 1458             fTotalColors(totalColors),
 
 1459             fTotalColorsWBIZ(totalColorsWBIZ),
 
 1461             fAllColors(allColors),
 
 1462             fLEDStatus(ledStatus),
 
 1464             fRenderGlyph(renderGlyph)
 
 1476         setJawaAddress(addr);
 
 1480     virtual void show() = 0;
 
 1483     virtual void defaultSettings() = 0;
 
 1487     LogicMessageSelector fMessageSelector = NULL;
 
 1488     LogicPMessageSelector fPMessageSelector = NULL;
 
 1501     byte fTotalColorsWBIZ;
 
 1503     HSVColor* fAllColors;
 
 1505     const byte* fLEDMap;
 
 1506     byte fMaxBrightness = MAX_BRIGHTNESS;
 
 1508     byte fDisplayEffect = 0;
 
 1509     byte fPreviousEffect = ~0;
 
 1511     uint32_t fLastMillis = 0;
 
 1512     uint32_t fStatusMillis = 0;
 
 1513     uint32_t fStatusDelay = 0;
 
 1514     bool fFlipFlop = 
false;
 
 1516     long fDisplayEffectVal = NORMVAL;
 
 1517     long fPreviousEffectVal = ~fDisplayEffectVal;
 
 1518     uint32_t fEffectStartMillis = 0;
 
 1519     unsigned int fEffectMillis = 0;
 
 1524     uint32_t fEffectData = 0;
 
 1525     uint32_t fEffectData2 = 0;
 
 1526     float fEffectRange = 1.0;
 
 1527     int fEffectMsgStartX;
 
 1529     int fEffectMsgWidth;
 
 1530     int fEffectMsgHeight;
 
 1531     bool fEffectMsgTransition;
 
 1532     byte fEffectFontNum = 0;
 
 1533     const char* fEffectMsgText = NULL;
 
 1537     inline int actualColorNum(
int x)
 const 
 1539         return (x >= fTotalColors) ? (fTotalColors - 2) - (x - fTotalColors) : x;
 
 1554 template <
typename PCB, LogicRenderGlyph renderGlyph, 
byte TWEENS = 14>
 
 1574         fDefaults(&defaults)
 
 1582     virtual void show()
 override 
 1588     virtual void defaultSettings()
 override 
 1590         fSettings = *fDefaults;
 
 1595         fSettings = *fDefaults = settings;
 
 1598     static const unsigned TOTALCOLORS = (4 + (TWEENS * 3));
 
 1599     static const unsigned TOTALCOLORSWBIZ = ((TOTALCOLORS * 2) - 2); 
 
 1603     HSVColor fAllColorsStorage[TOTALCOLORS];
 
 1663         r.
setHue(60 + map(peakVal,0,100,0,20));
 
 1687     static const unsigned int sMarchSegment[] =
 
 1699     for (
byte i = 1; i < 
SizeOfArray(sMarchSegment); i++)
 
 1701         if (effectMillis > sMarchSegment[i-1] && effectMillis < sMarchSegment[i])
 
 1716     return (effectMillis < 48300);
 
 1734     if (effectMillis > 1800 && effectMillis < 6000)
 
 1739     else if (effectMillis > 6000 && effectMillis < 8000)
 
 1744         r.
setBrightness(map(effectMillis - 6000, 2000, 0 , 0, 255));
 
 1748     return (effectMillis < 18000);
 
 1813             r.
setHue(effectHue - 128);
 
 1817             r.
setHue(effectHue + 128);
 
 1834     if (effectColor == r.
kRed) altColor = r.
kBlue;
 
 1835     else if (effectColor == r.
kBlue) altColor = r.
kRed;
 
 1841     else if (effectColor == r.
kPink) altColor = r.
kBlue;
 
 1859         for (y = 0; y < r.
height(); y++)
 
 1862         x += (!dir) ? 1 : -1;
 
 1879         else if (random(100) <= 5)
 
 1887         r.
setEffectData((uint32_t(dir)<<16L) | ((uint32_t(px)<<8L)) | x);
 
 1944     if (peakVal < speedVal)
 
 2127         int x = int(xy >> 16);
 
 2128         int y = int(xy & 0xFFFFL);
 
 2133             for (x = 0; x < r.
width(); x++)
 
 2142         r.
setEffectData((uint32_t(x)<<16L) | ((uint32_t(y)&0XFFFF)));
 
 2172             for (x = 0; x < r.
width(); x++)
 
 2174         for (x = 0; x < r.
width(); x++)
 
 2177         y += (!dir) ? 1 : -1;
 
 2188         r.
setEffectData((uint32_t(dir)<<16L) | ((uint32_t(py)<<8L)) | y);
 
 2218             for (y = 0; y < r.
height(); y++)
 
 2220         for (y = 0; y < r.
height(); y++)
 
 2223         x += (!dir) ? 1 : -1;
 
 2234         r.
setEffectData((uint32_t(dir)<<16L) | ((uint32_t(px)<<8L)) | x);
 
 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},
 
 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  },
 
 2270     int count = r.
count();
 
 2271     int width = r.
width();
 
 2283         for (
int i = 0; i < count; i++)
 
 2289         for (uint8_t x = 0; x < width; x++)
 
 2300             for (uint8_t y = height - 1; y > 0; y--)
 
 2302                 for (uint8_t x = 0; x < width; x++)
 
 2307             for (uint8_t x = 0; x < width; x++)
 
 2312             for (uint8_t x = 0; x < width; x++)
 
 2320         int heightm1 = height - 1;
 
 2321         for (
byte y = heightm1; y > 0; y--)
 
 2323             for (
byte x = 0; x < width; x++)
 
 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));
 
 2332         for (
byte x = 0; x < width; x++)
 
 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));
 
 2374         float xmid = r.
width()/2;
 
 2375         float ymid = r.
height()/2;
 
 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)) 
 
 2392         px += (!dir) ? 1 : -1;
 
 2393         if (px > r.
width()/2 || px < 1) {
 
 2396         r.
setEffectData((uint32_t(dir)<<16L) | ((uint32_t(px)<<8L)) | x);
 
 2412         LogicSolidColorEffect,
 
 2414         LogicFlipFlopEffect,
 
 2415         LogicFlipFlopAltEffect,
 
 2416         LogicColorSwapEffect,
 
 2418         LogicRedAlertEffect,
 
 2419         LogicMicBrightEffect,
 
 2420         LogicMicRainbowEffect,
 
 2421         LogicLightsOutEffect,
 
 2423         LogicTextScrollLeftEffect,
 
 2424         LogicTextScrollRightEffect,
 
 2425         LogicTextScrollUpEffect,
 
 2426         LogicRoamingPixelEffect,
 
 2427         LogicHorizontalScanLineEffect,
 
 2428         LogicVerticalScanLineEffect,
 
 2430         LogicPSIColorWipeEffect,
 
 2434         selectSequence = random(
SizeOfArray(sLogicEffects));
 
 2437     return LogicEffect(sLogicEffects[selectSequence]);
 
 2448     for (
int i = 0; i < 8; i++)
 
 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)
 
 2466     byte dstRowBytes = w;
 
 2469     byte glyphHeight = 4;
 
 2470     byte glyphBitmap[2*8];  
 
 2472     bool found = font->
getLetter(ch, glyphBitmap, glyphRowBytes, advance);
 
 2476         if (ch >= 
'a' && ch < 
'z')
 
 2477             found = font->
getLetter(
'A'+(ch-
'a'), glyphBitmap, glyphRowBytes, advance);
 
 2479         else if (ch >= 
'A' && ch < 
'Z')
 
 2480             found = font->
getLetter(
'a'+(ch-
'A'), glyphBitmap, glyphRowBytes, advance);
 
 2482     if (outGlyphHeight != NULL)
 
 2483         *outGlyphHeight = glyphHeight;
 
 2486     y += glyphHeight - 1;
 
 2487     while (glyphHeight > 0 && y >= 0)
 
 2490         byte* s = &glyphBitmap[(y-starty) * glyphRowBytes];
 
 2491         if (ledMap != NULL && y < dstHeight)
 
 2493             for (
byte rb = 0; rb < glyphRowBytes; rb++)
 
 2497                 byte m = 0b11000000;
 
 2499                 while (adv > 0 && m != 0 && xx < dstWidth)
 
 2501                     if ((b & m) != 0 && xx >= 0)
 
 2503                         leds[pgm_read_byte(&ledMap[y * dstRowBytes + xx])] = fontColors[((b >> i) & 3)-1];
 
 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)
 
 2521     byte dstRowBytes = w;
 
 2522     byte glyphRowBytes = 1;
 
 2523     byte glyphHeight = 5;
 
 2524     byte glyphBitmap[2*8];  
 
 2526     bool found = font->
getLetter(ch, glyphBitmap);
 
 2530         if (ch >= 
'a' && ch < 
'z')
 
 2531             found = font->
getLetter(
'A'+(ch-
'a'), glyphBitmap);
 
 2533         else if (ch >= 
'A' && ch < 
'Z')
 
 2534             found = font->
getLetter(
'a'+(ch-
'A'), glyphBitmap);
 
 2538     for (
int i = 0; i < glyphHeight; i++)
 
 2540         byte b = glyphBitmap[i * glyphRowBytes];
 
 2541         for (
byte i = 0; i < 8; i++)
 
 2545                 advance = max((
int)advance, 8-i);
 
 2553     if (outGlyphHeight != NULL)
 
 2554         *outGlyphHeight = glyphHeight;
 
 2557     y += glyphHeight - 1;
 
 2558     while (glyphHeight > 0 && y >= 0)
 
 2561         byte* s = &glyphBitmap[(y-starty) * glyphRowBytes];
 
 2562         if (ledMap != NULL && y < h)
 
 2564             for (
byte rb = 0; rb < glyphRowBytes; rb++)
 
 2568                 byte m = 0b10000000;
 
 2570                 while (adv > 0 && m != 0 && xx < w)
 
 2572                     if ((b & m) != 0 && xx >= 0)
 
 2574                         leds[pgm_read_byte(&ledMap[y * dstRowBytes + xx])] = fontColors[2];
 
 2606 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
 2607 using AstroPixelFLD = LogicEngineDisplay<AstroPixelFLDPCB0<DATA_PIN>, LogicRenderGlyph5Pt>;
 
 2619 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
 2620 using AstroPixelRLD = LogicEngineDisplay<AstroPixelRLDPCB0<DATA_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kNone>>;
 
 2632 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
 2645 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
 2646 using LogicEngineNabooRLD = LogicEngineDisplay<LogicEngineRLDPCB0<DATA_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kEven>>;
 
 2659 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
 2672 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
 2673 using LogicEngineKennyRLD = LogicEngineDisplay<LogicEngineRLDPCB1<DATA_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kEven>>;
 
 2674 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
 2699 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
 2713 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
 2727 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
 2740 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
 2753 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
 2766 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN>
 
 2780 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
 2794 template <u
int8_t DATA_PIN = FRONT_LOGIC_PIN>
 
 2809 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN, u
int8_t CLOCK_PIN = REAR_LOGIC_CLOCK_PIN>
 
 2810 using LogicEngineCurvedRLD = LogicEngineDisplay<LogicEngineRLDPCB3<DATA_PIN, CLOCK_PIN>, LogicRenderGlyph4Pt<LogicStaggerType::kNone>>;
 
 2822 template <u
int8_t DATA_PIN = REAR_LOGIC_PIN, u
int8_t CLOCK_PIN = REAR_LOGIC_CLOCK_PIN>