HitLib 1.5.0
VEX V5 LED animation library for PROS
Loading...
Searching...
No Matches
led_strand.hpp
Go to the documentation of this file.
1#pragma once
2#include "led_profile.hpp"
3#include "platform.hpp"
4#include <cstddef>
5#include <cstdint>
6#include <utility>
7#include <vector>
8
13
14namespace hitlib {
15
16// ============================================================================
17
53class LedStrand {
54public:
55
56 // ========================================================================
59
70 struct ExpanderPort {
71 uint8_t smartPort;
72 uint8_t adiPort;
73 };
74
79 uint32_t color;
80 uint8_t width;
81 };
82
101 struct Speed {
102 uint8_t pixels;
103 uint16_t stepMs;
104
107 constexpr Speed(int pixelsPerStep = 1, uint16_t ms = 0)
108 : pixels((uint8_t)pixelsPerStep), stepMs(ms) {}
109
111 static constexpr Speed everyMs(uint16_t ms, uint8_t pixelsPerStep = 1) {
112 return Speed(pixelsPerStep, ms);
113 }
114 };
115
138 using LevelFn = double (*)();
139
154
169 struct GaugeStop {
170 double at;
171 uint32_t color;
172 };
173
177 enum class GaugeStyle : uint8_t {
180 };
181
185 enum class GaugeBlend : uint8_t {
189 };
190
200 uint8_t start;
201 uint8_t width;
203 uint32_t color = 0xFFFFFF;
204 uint32_t color2 = 0x0000FF;
205 uint32_t bgColor = 0x000000;
206 uint8_t runLength = 5;
208 uint32_t onMs = 250;
209 uint32_t offMs = 250;
210 bool seamless = true;
213 bool invert = false;
214
215 // ---- TWINKLE only ----
216
218 std::vector<uint32_t> palette;
219 uint8_t densityPct = 30;
220 uint8_t fadeStep = 16;
221
222 // ---- BITSCROLL only ----
223
224 uint8_t segmentWidth = 3;
225 uint8_t spacing = 5;
226 bool repeating = true;
227
228 // ---- GAUGE only, ignored by every other kind ----
229
232 LevelFn read = nullptr;
233 double emptyAt = 0.0;
234 double fullAt = 100.0;
235 bool wrap = false;
236 uint8_t smoothing = 0;
242 std::vector<GaugeStop> stops;
243 };
244
267 struct MusicTrack {
268 const uint8_t* samples;
269 uint16_t frameCount;
270 uint16_t frameMs;
271 };
272
273 // ========================================================================
274 // Custom animations (Compositions)
275 // ========================================================================
276
283
284 static constexpr uint8_t MAX_LAYERS = 8;
285 static constexpr uint8_t MAX_DRIVERS = 8;
286 static constexpr uint8_t MAX_BINDINGS = 4;
287 static constexpr uint8_t CURVE_POINTS = 17;
288
297 enum class LayerKind : uint8_t {
299 };
300
310 enum class LayerBlend : uint8_t {
317 };
318
320 enum class DriverKind : uint8_t {
325 };
326
327 enum class LfoShape : uint8_t { TRIANGLE, SAW, RAMP_DOWN, SQUARE, SINE };
328
330 enum class LayerParam : uint8_t {
332 };
333
335 struct LayerSpan {
336 uint8_t start;
337 uint8_t width;
342 uint8_t stride;
350 };
351
353 struct LayerMix { LayerBlend blend; uint8_t opacity; };
354
367 struct Binding {
369 uint8_t driver;
370 int16_t atZero;
371 int16_t atFull;
372 const uint8_t* curve;
373 };
374
375 struct LayerPaint { uint32_t color; uint32_t color2; uint32_t bgColor; };
378 struct LayerMotion { uint8_t runLength; Speed speed; bool invert; bool bounce; bool seamless; };
379 struct LayerFlash { uint32_t onMs; uint32_t offMs; };
380
393 struct LayerTime {
394 uint32_t loopMs;
395 uint32_t startMs;
396 uint32_t endMs;
397 uint16_t fadeInMs;
398 uint16_t fadeOutMs;
400 };
401
403 const uint32_t* palette;
405 uint8_t densityPct;
406 uint8_t fadeStep;
407 };
408
415
427
450 struct LayerFrames {
451 const uint8_t* data;
452 const uint16_t* index;
453 const uint32_t* palette;
455 uint8_t width;
456 uint8_t count;
457 uint16_t frameMs;
460 const uint8_t* scroll;
461 };
462
493
504 struct Driver {
505 const char* name;
507 uint8_t value;
509 double emptyAt;
510 double fullAt;
511 bool wrap;
512 uint8_t smoothing;
514 uint8_t sensitivity;
515 bool loop;
517 uint32_t periodMs;
518 uint8_t phasePct;
519 };
520
529 struct Composition {
530 const char* name;
531 const Layer* layers;
532 uint8_t layerCount;
534 uint8_t driverCount;
535 uint32_t loopMs;
536 uint32_t bgColor;
537 };
538
540
542
543 // ========================================================================
546
556 LedStrand(uint8_t adiPort, uint8_t length, uint32_t refreshMs = 20);
557
570 LedStrand(ExpanderPort port, uint8_t length, uint32_t refreshMs = 20);
571
586 LedStrand(uint8_t smartPort, uint8_t adiPort, uint8_t length, uint32_t refreshMs);
587
589
590 // ========================================================================
593
601 void init();
602
609 void tick();
610
612
613 // ========================================================================
619
623 void off();
624
630 void setColor(uint32_t color);
631
644 void pulse(uint32_t color, uint8_t runLength, Speed speed,
645 uint32_t bgColor = 0x000000, bool invert = false, bool bounce = false);
646
663 void flash(uint32_t color, uint32_t onMs, uint32_t offMs, uint32_t bgColor = 0x000000);
664
676 void flow(uint32_t color1, uint32_t color2, Speed speed, bool invert = false,
677 bool seamless = true);
678
684 void rainbow(Speed speed);
685
697 void twinkle(const std::vector<uint32_t>& colors, uint8_t densityPct = 30,
698 uint8_t fadeStep = 16, uint32_t bgColor = 0x000000);
699
713 void bitscroll(const std::vector<BitScrollSegment>& segments, Speed speed,
714 bool invert = false, uint32_t bgColor = 0x000000, bool bounce = false,
715 uint8_t spacing = 5, bool repeating = true);
716
718
719 // ========================================================================
736
764 void levelFill(uint32_t color, uint32_t color2 = 0x000000, bool gradient = false,
765 uint32_t bgColor = 0x000000, bool invert = false);
766
777 void setLevel(uint8_t level);
778
780 uint8_t getLevel() const { return levelValue; }
781
830 void levelSource(LevelFn read, double emptyAt, double fullAt, bool wrap = false,
831 uint8_t smoothing = 0);
832
840
842 bool levelSourceActive() const { return levelRead != nullptr; }
843
869 void musicSync(const MusicTrack& track, uint32_t color, uint32_t color2 = 0x000000,
870 bool gradient = false, uint32_t bgColor = 0x000000, bool invert = false,
871 uint8_t sensitivity = 100, bool loop = false);
872
878 void musicSeek(uint32_t positionMs);
879
885 void musicPause(bool paused = true);
886
888 bool musicPlaying() const { return musicTrack != nullptr && !musicPaused; }
889
891 uint32_t musicPositionMs() const;
892
898 void setSensitivity(uint8_t pct);
899
901
902 // ========================================================================
910
927 void spliceMask(uint8_t sections, bool invert = false, bool alternating = false,
928 uint32_t altPeriodMs = 100, uint32_t bgColor = 0x000000,
929 bool useOverlay = false);
930
960 void spliceMaskCustom(const std::vector<SpliceRegion>& regions);
961
976 void setRegionLevel(uint8_t regionIdx, uint8_t level);
977
1004 static SpliceRegion motorHeatGauge(uint8_t start, uint8_t width, LevelFn read = nullptr);
1005
1010
1012
1013 // ========================================================================
1019
1021 void overlaySetColor(uint32_t color);
1022
1024 void overlayPulse(uint32_t color, uint8_t runLength, Speed speed,
1025 uint32_t bgColor = 0x000000);
1026
1028 void overlayFlash(uint32_t color, uint32_t onMs, uint32_t offMs,
1029 uint32_t bgColor = 0x000000);
1030
1040 void overlayFlow(uint32_t color1, uint32_t color2, Speed speed, bool seamless = true);
1041
1044
1046 void overlayTwinkle(const std::vector<uint32_t>& colors, uint8_t densityPct = 30,
1047 uint8_t fadeStep = 16, uint32_t bgColor = 0x000000);
1048
1056 void overlayBitscroll(const std::vector<BitScrollSegment>& segments, Speed speed,
1057 bool invert = false, uint32_t bgColor = 0x000000,
1058 uint8_t spacing = 5, bool repeating = true);
1059
1061
1062 // ========================================================================
1065
1075 void setBrightness(uint8_t pct);
1076
1080 uint8_t getBrightness() const { return brightnessPct; }
1081
1083
1084 // ========================================================================
1087
1094 void attachProfile(const Profile* profile);
1095
1100
1109 void activateMode(uint8_t modeIdx);
1110
1121 void activateModeTimed(uint8_t modeIdx, uint32_t durationMs);
1122
1128 void deactivateMode(uint8_t modeIdx);
1129
1131
1132 // ========================================================================
1133 // ========================================================================
1142
1160 void compose(const Composition& comp);
1161
1164
1166 bool composing() const { return composition != nullptr; }
1167
1180 void setDriverLevel(uint8_t driverIdx, uint8_t value);
1181
1183 uint8_t getDriverLevel(uint8_t driverIdx) const;
1184
1187
1196 void composeMusicSeek(uint32_t positionMs);
1197
1205 void composeMusicPause(bool paused = true);
1206
1208 uint32_t composeMusicPositionMs() const;
1209
1211
1212 // ========================================================================
1215
1217 uint8_t getLength() const { return length; }
1218
1220
1221 // ========================================================================
1222 // Maximum supported LEDs per strand.
1223 static constexpr uint8_t MAX_LEDS = 64;
1224
1225private:
1226 // LedGroup sets refreshMs to the interval it actually ticks the strand at.
1227 friend class LedGroup;
1228
1229 // ---- Hardware ----
1230 uint8_t adiPort;
1231 uint8_t smartPort = 0;
1232 uint8_t length;
1233 uint32_t refreshMs;
1234 platform::AdiLed* led = nullptr;
1235 platform::Mutex mutex;
1236
1237 // The last frame actually written to the strip, and when. flushBuffer()
1238 // skips a frame identical to it, since the pixels hold what they were
1239 // sent, and every write costs a 12 ms slot on the shared ADI.
1240 uint32_t lastSent[MAX_LEDS] = {0};
1241 uint32_t lastSentMs = 0;
1242 bool lastSentValid = false;
1243
1244 // Called by LedGroup, which ticks the strand at its own interval: every
1245 // duration converted to ticks after this counts at that rate.
1246 void setRefreshMs(uint32_t ms);
1247
1248 enum class AnimMode : uint8_t { STATIC, SHIFT, TWINKLE, FLASH, LEVEL };
1249
1250 // Paces a moving animation: due() is true once every `hold` refresh
1251 // ticks. A hold of 1 - what a bare-number Speed gives - moves on every
1252 // tick, which is all `speed` could do before it could be slower.
1253 struct StepPacer {
1254 uint16_t hold = 1;
1255 uint16_t counter = 0;
1256 void reset(uint16_t ticks) { hold = ticks ? ticks : 1; counter = 0; }
1257 void restart() { counter = 0; }
1258 bool due() {
1259 if (++counter < hold) return false;
1260 counter = 0;
1261 return true;
1262 }
1263 };
1264
1265 // Base buffer
1266 AnimMode animMode = AnimMode::STATIC;
1267 int shiftStep = 0;
1268 uint8_t shiftVariant = 0; // pixels per step, pre-reversed for invert
1269 StepPacer shiftPacer; // SHIFT, and both bounces
1270 std::vector<uint32_t> buffer;
1271
1272 // Pulse bounce
1273 uint8_t pulseRunLen = 0;
1274 uint32_t pulseColor = 0;
1275 uint32_t pulseBg = 0;
1276 uint8_t pulseSpeed = 1;
1277 int16_t pulseOffset = 0;
1278 int8_t pulseDir = 1;
1279
1280 // Flash - whole-strip blink driven by tick counts rather than a shifting
1281 // buffer, so the lit and blank halves can have independent durations.
1282 uint32_t flashColor = 0;
1283 uint32_t flashBgColor = 0;
1284 uint16_t flashOnTicks = 1;
1285 uint16_t flashOffTicks = 1;
1286 uint16_t flashCounter = 0;
1287 bool flashLit = true;
1288
1289 // Bitscroll bounce
1290 std::vector<uint32_t> bitscrollMaster;
1291 int16_t bounceScrollPos = 0;
1292 int8_t bounceScrollDir = 1;
1293 uint8_t bounceSpeed = 1;
1294
1295 // Twinkle - per-pixel fade state for one buffer. A struct rather than loose
1296 // members because three different buffers animate this way: the base
1297 // strand, the overlay, and any number of custom regions.
1298 struct TwinkleState {
1299 std::vector<uint8_t> level;
1300 std::vector<uint8_t> target;
1301 std::vector<uint8_t> colorIdx;
1302 std::vector<uint8_t> holdTicks;
1303 std::vector<uint32_t> palette;
1304 uint8_t densityPct = 30;
1305 uint8_t fadeStep = 16;
1306 uint32_t bgColor = 0x000000;
1307
1308 void reset(uint8_t width, const std::vector<uint32_t>& colors, uint8_t density,
1309 uint8_t fade, uint32_t bg);
1310 };
1311 static void advanceTwinkleInto(TwinkleState& t, std::vector<uint32_t>& buf);
1312
1313 // advanceTwinkleInto() split in two, so a custom-animation layer can take
1314 // the per-pixel brightness in @c t.level as coverage and blend it over
1315 // whatever is beneath instead of over a single background color.
1316 // advanceTwinkleInto() is exactly these two in sequence.
1317 static void stepTwinkle(TwinkleState& t, uint8_t width);
1318 static void paintTwinkleInto(const TwinkleState& t, std::vector<uint32_t>& buf, uint8_t width);
1319
1320 TwinkleState twinkleState;
1321
1322 // Level meter - buffer holds the meter's colors across the whole strip and
1323 // levelValue picks how much of it is revealed, so changing the level costs
1324 // nothing until flush time.
1325 uint8_t levelValue = 0;
1326 uint32_t levelBg = 0x000000;
1327 bool levelInvert = false;
1328
1329 // Live fill source - a reader polled once per tick plus the range that
1330 // maps what it returns onto 0-255. levelPrimed exists so the first sample
1331 // after levelSource() lands instantly instead of the bar crawling up to it
1332 // from empty through the smoothing filter.
1333 LevelFn levelRead = nullptr;
1334 double levelEmptyAt = 0.0;
1335 double levelFullAt = 100.0;
1336 bool levelWrap = false;
1337 uint8_t levelSmooth = 0;
1338 bool levelPrimed = false;
1339
1340 // Music sync - playback is a wall-clock anchor rather than a tick counter,
1341 // so a strand that misses a tick (or refreshes slowly) stays in step with
1342 // the music instead of drifting behind it.
1343 const MusicTrack* musicTrack = nullptr;
1344 uint32_t musicAnchorMs = 0; // millis() that corresponds to position 0
1345 uint32_t musicPausedAt = 0; // position held while paused
1346 bool musicPaused = false;
1347 bool musicLoop = false;
1348 uint8_t musicSensitivity = 100;
1349
1350 // Splice mask
1351 enum class SpliceMode : uint8_t { SPLIT, CUSTOM };
1352
1353 // Runtime animation state for one CUSTOM-mode region, a scaled-down
1354 // version of the overlay buffer (buffer + shift step/speed), but one per
1355 // region instead of shared.
1356 struct SpliceRegionState {
1357 uint8_t start = 0;
1358 std::vector<uint32_t> buffer;
1359 int shiftStep = 0;
1360 uint8_t shiftSpeed = 0;
1361 StepPacer shiftPacer;
1362 // Index in the vector the caller passed to spliceMaskCustom(), which
1363 // is what setRegionLevel() addresses. Not the index in spliceRegions:
1364 // SOLID and OFF regions never get a state, so the two disagree.
1365 uint8_t userIdx = 0;
1366 // GAUGE - a per-region copy of the strand-wide meter's state, so each
1367 // segment follows its own reading at its own range and smoothing.
1368 bool gauge = false;
1369 LevelFn levelRead = nullptr;
1370 double levelEmptyAt = 0.0;
1371 double levelFullAt = 100.0;
1372 bool levelWrap = false;
1373 uint8_t levelSmooth = 0;
1374 uint8_t levelValue = 0;
1375 bool levelPrimed = false;
1376 bool gaugeInvert = false;
1377 GaugeStyle gaugeStyle = GaugeStyle::HEAT;
1378 GaugeBlend gaugeBlend = GaugeBlend::LERP;
1379 uint32_t gaugeBg = 0x000000;
1380 // The scale, resolved onto the 0-255 axis levelValue lives on, so a
1381 // tick only has to bracket a byte rather than redo the mapping.
1382 std::vector<std::pair<uint8_t, uint32_t>> gaugeStops;
1383 // FLASH regions blink their whole buffer on a tick timer instead of
1384 // shifting it, mirroring the strand-wide flash state.
1385 bool flashing = false;
1386 uint32_t flashColor = 0;
1387 uint32_t flashBgColor = 0;
1388 uint16_t flashOnTicks = 1;
1389 uint16_t flashOffTicks = 1;
1390 uint16_t flashCounter = 0;
1391 bool flashLit = true;
1392 // TWINKLE regions repaint their buffer every tick rather than shifting
1393 // it, the same way the strand-wide twinkle does.
1394 bool twinkling = false;
1395 TwinkleState twinkle;
1396 };
1397
1398 bool spliceActive = false;
1399 SpliceMode spliceMode = SpliceMode::SPLIT;
1400 uint8_t spliceSections = 0;
1401 bool spliceInvert = false;
1402 bool spliceAlternating = false;
1403 uint32_t spliceAltMs = 100;
1404 uint32_t spliceBgColor = 0x000000;
1405 bool spliceUseOverlay = false;
1406 bool spliceAltPhase = false;
1407 uint32_t spliceLastToggleMs = 0;
1408 std::vector<bool> spliceShowAnim;
1409 std::vector<uint32_t> splicePixelBg;
1410 std::vector<bool> splicePixelUseOverlay;
1411 std::vector<int16_t> splicePixelRegionIdx; // CUSTOM mode: index into spliceRegions, or -1
1412 std::vector<SpliceRegionState> spliceRegions; // CUSTOM mode only
1413 // Bumped whenever the mask is replaced. advanceSpliceRegions() releases
1414 // the mutex to run a gauge's reader (user code, which may call back in),
1415 // and compares this afterwards to notice that the regions it was walking
1416 // are gone.
1417 uint32_t spliceGeneration = 0;
1418
1419 // Overlay buffer
1420 AnimMode overlayAnimMode = AnimMode::STATIC;
1421 int overlayShiftStep = 0;
1422 uint8_t overlayShiftSpeed = 0;
1423 StepPacer overlayShiftPacer;
1424 std::vector<uint32_t> overlayBuffer;
1425
1426 // Overlay flash - mirrors the base flash state above.
1427 uint32_t overlayFlashColor = 0;
1428 uint32_t overlayFlashBgColor = 0;
1429 uint16_t overlayFlashOnTicks = 1;
1430 uint16_t overlayFlashOffTicks = 1;
1431 uint16_t overlayFlashCounter = 0;
1432 bool overlayFlashLit = true;
1433
1434 // Overlay twinkle - mirrors the base twinkle state above.
1435 TwinkleState overlayTwinkleState;
1436
1437 // Brightness
1438 uint8_t brightnessPct = 100;
1439
1440 // Profile state
1441 struct ModeEntry {
1442 uint8_t modeIdx;
1443 bool persistent;
1444 uint32_t endMs;
1445 };
1446 const Profile* activeProfile = nullptr;
1447 std::vector<ModeEntry> modeStack;
1448 int16_t lastModeIdx = -1;
1449
1450 // Internal implementations (no lock)
1451 void setColorNL(uint32_t color);
1452 void pulseNL(uint32_t color, uint8_t runLen, Speed speed, uint32_t bg, bool invert, bool bounce);
1453 void flashNL(uint32_t color, uint32_t onMs, uint32_t offMs, uint32_t bg);
1454 void flowNL(uint32_t c1, uint32_t c2, Speed speed, bool invert, bool seamless);
1455 void rainbowNL(Speed speed);
1456 void twinkleNL(const std::vector<uint32_t>& colors, uint8_t densityPct,
1457 uint8_t fadeStep, uint32_t bgColor);
1458 void bitscrollNL(const std::vector<BitScrollSegment>& segments, Speed speed, bool invert,
1459 uint32_t bgColor, bool bounce, uint8_t spacing, bool repeating);
1460
1461 void overlaySetColorNL(uint32_t color);
1462 void overlayPulseNL(uint32_t color, uint8_t runLen, Speed speed, uint32_t bg);
1463 void overlayFlashNL(uint32_t color, uint32_t onMs, uint32_t offMs, uint32_t bg);
1464 void overlayFlowNL(uint32_t c1, uint32_t c2, Speed speed, bool seamless);
1465 void overlayRainbowNL(Speed speed);
1466 void overlayTwinkleNL(const std::vector<uint32_t>& colors, uint8_t densityPct,
1467 uint8_t fadeStep, uint32_t bgColor);
1468 void overlayBitscrollNL(const std::vector<BitScrollSegment>& segments, Speed speed,
1469 bool invert, uint32_t bgColor, uint8_t spacing, bool repeating);
1470
1471 void levelFillNL(uint32_t color, uint32_t color2, bool gradient, uint32_t bg, bool invert);
1472
1473 // One tile of a bitscroll pattern: the lit runs and the gaps between them.
1474 // `contentLen` comes back as the size up to the last lit pixel, i.e.
1475 // without the trailing gap, which only separates one tile from the next.
1476 static std::vector<uint32_t> buildBitscrollUnit(const std::vector<BitScrollSegment>& segments,
1477 uint32_t bgColor, uint8_t spacing,
1478 size_t& contentLen);
1479 // The same tile, from a plain array rather than a vector, because a custom
1480 // animation's segments live in a flash-resident table with no vector to
1481 // hand over. @p coverage, when given, comes back the same length as the
1482 // returned unit: 255 for a lit pixel and 0 for a gap, filled in the same
1483 // loop so it cannot drift from the colors. The vector overload forwards
1484 // here.
1485 static std::vector<uint32_t> buildBitscrollUnit(const BitScrollSegment* segments,
1486 uint8_t count, uint32_t bgColor,
1487 uint8_t spacing, size_t& contentLen,
1488 std::vector<uint8_t>* coverage = nullptr);
1489 // Lay one tile into `buf` across `width` pixels - tiled when `repeating`,
1490 // a single copy on `bgColor` when not - and return the per-step shift that
1491 // scrolls it. Shared by the base, overlay, and per-region bitscrolls.
1492 static uint8_t fillBitscrollBuffer(std::vector<uint32_t>& buf,
1493 const std::vector<uint32_t>& unit, size_t contentLen,
1494 uint8_t width, uint32_t bgColor, uint8_t speed,
1495 bool invert, bool repeating);
1496
1497 void advanceLevel();
1498 void advanceFlash();
1499 void advanceOverlayFlash();
1500 void advancePulseBounce();
1501 void advanceBitscrollBounce();
1502 void fillBitscrollFromMaster();
1503 void advanceSpliceAlternating(uint32_t nowMs);
1504 void advanceSpliceRegions();
1505 void paintGaugeRegion(SpliceRegionState& state);
1506 void rebuildSpliceMask();
1507
1508 void shiftBuffer();
1509 void shiftOverlayBuffer();
1510 void flushBuffer(uint32_t now); // called with the mutex held; gives it back
1511 uint32_t levelPixel(uint8_t i, uint32_t full, uint8_t frac) const;
1512 uint8_t sampleMusicNL(uint32_t positionMs) const;
1513 uint8_t mapLevelNL(double raw) const;
1514 uint8_t smoothLevelNL(uint8_t target) const;
1515
1516 // The mapping and smoothing above, with the range passed in rather than
1517 // read off the strand, so a gauge region can reuse them for its own.
1518 static uint8_t mapLevelTo(double raw, double emptyAt, double fullAt, bool wrap);
1519 static uint8_t smoothLevelTo(uint8_t target, uint8_t current, uint8_t smoothing, bool wrap);
1520 static uint32_t gaugeColorAt(const SpliceRegionState& state, uint8_t level);
1521
1522 // gaugeColorAt()'s scale lookup, with the stops passed in rather than read
1523 // off a region, so a custom-animation layer can carry its own scale.
1524 // gaugeColorAt() is a thin wrapper over this.
1525 static uint32_t scaleColorAt(const std::pair<uint8_t, uint32_t>* stops, uint8_t count,
1526 GaugeBlend blend, uint32_t bgColor, uint8_t level);
1527
1528 // sampleMusicNL()'s body, with the track and playback options passed in
1529 // rather than read off the strand, so a custom-animation driver can play a
1530 // track of its own. sampleMusicNL() is a thin wrapper over this.
1531 static uint8_t sampleTrackNL(const MusicTrack* track, uint32_t positionMs,
1532 uint8_t sensitivity, bool loop);
1533
1534 // One color from a two-color ramp: genGradient()'s loop body, extracted so
1535 // a custom-animation layer can sample a gradient without building the
1536 // whole buffer. genGradient() is written in terms of this, so the two can
1537 // never disagree.
1538 static uint32_t gradientPixel(uint32_t c1, uint32_t c2, uint8_t i, uint8_t len,
1539 bool seamless);
1540
1541 // Blend @p fg over @p bg by @p level (0-255), and the NeoPixel-style hue
1542 // wheel. Private statics rather than file-local helpers so the custom
1543 // animation evaluator in led_custom.cpp can reach the same bodies the
1544 // presets use.
1545 static uint32_t lerpColor(uint32_t bg, uint32_t fg, uint8_t level);
1546 static uint32_t wheel(uint8_t pos);
1547
1548 int16_t computeEffectiveMode() const;
1549 void pruneExpired(uint32_t now);
1550 uint32_t applyBrightness(uint32_t color) const;
1551 uint16_t msToTicks(uint32_t ms) const;
1553 uint16_t stepTicks(Speed s) const { return s.stepMs ? msToTicks(s.stepMs) : 1; }
1554
1556 static std::vector<uint32_t> genGradient(uint32_t c1, uint32_t c2, uint8_t len,
1557 bool seamless = false);
1558 static std::vector<uint32_t> genRainbow(uint8_t len);
1559
1560 // ========================================================================
1561 // Custom animation state and evaluator (src/led_custom.cpp)
1562 // ========================================================================
1563
1570 static constexpr uint32_t COVER_OPAQUE = 0xFF000000u;
1571
1575 struct Resolved {
1576 uint8_t start;
1577 uint8_t width;
1578 uint8_t runLength;
1579 uint8_t speed;
1580 uint8_t densityPct;
1581 uint8_t opacity;
1582 uint8_t level;
1583 uint8_t mix;
1584 };
1585
1588 struct LayerState {
1589 uint16_t shiftAcc = 0;
1590 int16_t bouncePos = 0;
1591 int8_t bounceDir = 1;
1592 uint16_t flashCounter = 0;
1593 bool flashLit = true;
1594 bool wasOpen = false;
1595 uint16_t frameIdx = 0;
1596 uint16_t frameCounter = 0;
1597 StepPacer step;
1598 uint16_t scratchAt = 0;
1599 uint16_t scratchLen = 0;
1600 uint16_t contentLen = 0;
1601 uint8_t maxSpan = 0;
1602 TwinkleState twinkle;
1605 std::vector<std::pair<uint8_t, uint32_t>> stops;
1606 };
1607
1608 const Composition* composition = nullptr;
1609 uint32_t composeAnchorMs = 0;
1614 uint32_t composeGeneration = 0;
1615 uint32_t composeMusicPausedAt = 0;
1616 bool composeMusicPaused = false;
1617
1618 std::vector<LayerState> layerStates;
1624 std::vector<uint32_t> composeArena;
1625 uint8_t driverValue[MAX_DRIVERS] = {0};
1626 bool driverPrimed[MAX_DRIVERS] = {false};
1627
1628 void advanceComposition(uint32_t nowMs);
1629 void dropCompositionNL();
1630 uint32_t composeClockNL(uint32_t nowMs) const;
1631 bool evalDriversNL(const Composition& c, uint32_t nowMs);
1632 void resolveLayerNL(const Composition& c, const Layer& l, Resolved& p) const;
1633 uint8_t resolveSpan(const Resolved& p, const LayerState& st) const;
1634 uint8_t motionRing(const Layer& l, uint8_t span) const;
1635 void prepareLayerNL(const Layer& l, LayerState& st, uint8_t span, uint16_t& arenaAt);
1636 void buildLayerNL(const Layer& l, LayerState& st);
1637 void resetLayerStateNL(const Layer& l, LayerState& st, uint8_t ring);
1638 void advanceLayerNL(const Layer& l, LayerState& st, const Resolved& p, uint8_t ring);
1639 uint32_t layerPixel(const Layer& l, const LayerState& st, const Resolved& p,
1640 uint8_t k, uint8_t span) const;
1641 void compositeLayerNL(const Layer& l, const LayerState& st, const Resolved& p,
1642 uint8_t span, uint8_t alpha);
1643 void decodeFrameNL(const Layer& l, LayerState& st);
1644
1645 static uint8_t nominalSpan(const Layer& l, uint8_t len);
1646 static uint8_t applyCurve(const uint8_t* curve, uint8_t v);
1647 static uint8_t layerWindowAlpha(const Layer& l, uint32_t t, uint32_t period);
1648 static uint8_t shiftFor(uint8_t speed, uint8_t ring, bool invert);
1649 static uint8_t lfoValue(const Driver& d, uint32_t nowMs);
1650 static uint32_t blendPixel(LayerBlend m, uint32_t dst, uint32_t src, uint8_t a);
1651 static uint32_t addSat(uint32_t a, uint32_t b);
1652 static uint32_t screenColor(uint32_t a, uint32_t b);
1653 static uint32_t mulColor(uint32_t a, uint32_t b);
1654 static uint8_t luma(uint32_t c);
1655};
1656
1657} // namespace hitlib
void spliceMask(uint8_t sections, bool invert=false, bool alternating=false, uint32_t altPeriodMs=100, uint32_t bgColor=0x000000, bool useOverlay=false)
Apply a splice mask that overrides alternating equal-width bins.
void restartComposition()
Restart the composition's timeline, and every layer, from zero.
void flow(uint32_t color1, uint32_t color2, Speed speed, bool invert=false, bool seamless=true)
Scroll a two-color gradient across the strip.
void composeMusicSeek(uint32_t positionMs)
Seek every MUSIC driver in this composition.
void flash(uint32_t color, uint32_t onMs, uint32_t offMs, uint32_t bgColor=0x000000)
Blink the whole strip on and off.
void setDriverLevel(uint8_t driverIdx, uint8_t value)
Set a CONSTANT driver's value - the composition's setLevel().
SpliceRegionAnimKind
What a custom splice mask region shows.
Definition led_strand.hpp:151
@ BITSCROLL
Definition led_strand.hpp:152
@ FLASH
Definition led_strand.hpp:152
@ FLOW
Definition led_strand.hpp:152
@ PULSE
Definition led_strand.hpp:152
@ TWINKLE
Definition led_strand.hpp:152
@ GAUGE
Definition led_strand.hpp:152
@ OFF
Definition led_strand.hpp:152
@ SOLID
Definition led_strand.hpp:152
@ RAINBOW
Definition led_strand.hpp:152
void levelFill(uint32_t color, uint32_t color2=0x000000, bool gradient=false, uint32_t bgColor=0x000000, bool invert=false)
Configure the strip as a level meter, and take manual control of it.
LedStrand(uint8_t smartPort, uint8_t adiPort, uint8_t length, uint32_t refreshMs)
Construct a strand on an ADI expander port, from four numbers.
void detachProfile()
Detach the active profile and turn the strand off.
void musicSeek(uint32_t positionMs)
Jump playback to a position in the song.
void spliceMaskCustom(const std::vector< SpliceRegion > &regions)
Apply a splice mask made of independently placed/sized regions, each running its own animation.
void setSensitivity(uint8_t pct)
Change the gain applied to envelope samples without restarting.
void tick()
Advance one animation frame.
LedStrand(uint8_t adiPort, uint8_t length, uint32_t refreshMs=20)
Construct a strand on a standard ADI port.
void overlayPulse(uint32_t color, uint8_t runLength, Speed speed, uint32_t bgColor=0x000000)
Animate a moving run in the overlay buffer.
DriverKind
Where a driver's 0-255 comes from.
Definition led_strand.hpp:320
@ SENSOR
A LevelFn, mapped and smoothed exactly as levelSource() does.
Definition led_strand.hpp:322
@ CONSTANT
A byte the robot's own code moves, see setDriverLevel().
Definition led_strand.hpp:321
@ MUSIC
A baked MusicTrack, sampled exactly as musicSync() does.
Definition led_strand.hpp:323
@ LFO
A free-running shape on a period, off the wall clock.
Definition led_strand.hpp:324
uint32_t musicPositionMs() const
Current playback position in milliseconds.
void overlaySetColor(uint32_t color)
Set the overlay buffer to a solid color.
static constexpr uint8_t CURVE_POINTS
Knots in a Binding curve.
Definition led_strand.hpp:287
void setBrightness(uint8_t pct)
Set global brightness for this strand.
void attachProfile(const Profile *profile)
Attach a Profile and reset the mode stack.
void musicSync(const MusicTrack &track, uint32_t color, uint32_t color2=0x000000, bool gradient=false, uint32_t bgColor=0x000000, bool invert=false, uint8_t sensitivity=100, bool loop=false)
Fill the meter from a baked music envelope, and start playing it.
bool levelSourceActive() const
Whether a levelSource() reader is currently driving the meter.
Definition led_strand.hpp:842
void setLevel(uint8_t level)
Set how full the meter is.
void twinkle(const std::vector< uint32_t > &colors, uint8_t densityPct=30, uint8_t fadeStep=16, uint32_t bgColor=0x000000)
Spawn randomly fading sparkles from a color palette.
static SpliceRegion motorHeatGauge(uint8_t start, uint8_t width, LevelFn read=nullptr)
A GAUGE region pre-loaded with the V5 motor's own heat schedule.
void init()
Initialize the hardware LED object.
static constexpr uint8_t MAX_LAYERS
Layers in one Composition.
Definition led_strand.hpp:284
void clearSpliceMask()
Remove the active splice mask, whichever kind is active.
void deactivateMode(uint8_t modeIdx)
Remove a mode from the stack immediately.
LayerKind
What one layer of a Composition draws.
Definition led_strand.hpp:297
@ FRAMES
Definition led_strand.hpp:298
@ METER
Definition led_strand.hpp:298
void clearComposition()
Stop playing a composition and leave the strand dark.
uint8_t getDriverLevel(uint8_t driverIdx) const
What a driver last read. Useful for checking a binding.
void overlayRainbow(Speed speed)
Scroll a rainbow in the overlay buffer.
void off()
Turn all LEDs off (set to black).
void activateModeTimed(uint8_t modeIdx, uint32_t durationMs)
Push a timed mode onto the mode stack.
uint8_t getBrightness() const
Return the current brightness percentage.
Definition led_strand.hpp:1080
void compose(const Composition &comp)
Play a Composition as this strand's base animation.
void composeMusicPause(bool paused=true)
Pause or resume every MUSIC driver in this composition.
double(*)() LevelFn
Signature for the reader a fill meter follows, see levelSource().
Definition led_strand.hpp:138
uint32_t composeMusicPositionMs() const
Position of this composition's music clock, in milliseconds.
void rainbow(Speed speed)
Scroll a full HSV rainbow across the strip.
void bitscroll(const std::vector< BitScrollSegment > &segments, Speed speed, bool invert=false, uint32_t bgColor=0x000000, bool bounce=false, uint8_t spacing=5, bool repeating=true)
Scroll a pattern of colored segments across the strip.
void overlayTwinkle(const std::vector< uint32_t > &colors, uint8_t densityPct=30, uint8_t fadeStep=16, uint32_t bgColor=0x000000)
Sparkle random pixels of the overlay buffer (see twinkle()).
uint8_t getLength() const
Return the number of LEDs in this strand.
Definition led_strand.hpp:1217
void clearLevelSource()
Stop following a levelSource() reader, leaving the fill where it is.
static constexpr uint8_t MAX_BINDINGS
Bindings on one Layer.
Definition led_strand.hpp:286
void activateMode(uint8_t modeIdx)
Push a persistent mode onto the mode stack.
void levelSource(LevelFn read, double emptyAt, double fullAt, bool wrap=false, uint8_t smoothing=0)
Point the meter at a live value and let it follow it on its own.
LedStrand(ExpanderPort port, uint8_t length, uint32_t refreshMs=20)
Construct a strand on an ADI expander port.
void setColor(uint32_t color)
Set all LEDs to a solid color.
void musicPause(bool paused=true)
Pause or resume playback, holding the meter where it is.
void overlayFlow(uint32_t color1, uint32_t color2, Speed speed, bool seamless=true)
Scroll a gradient in the overlay buffer.
bool composing() const
Whether a composition is currently driving the base buffer.
Definition led_strand.hpp:1166
static constexpr uint8_t MAX_DRIVERS
Drivers in one Composition.
Definition led_strand.hpp:285
GaugeStyle
How a GAUGE region turns its level into pixels.
Definition led_strand.hpp:177
@ HEAT
The whole region shows one color, picked off the scale.
Definition led_strand.hpp:178
@ BAR
The region fills proportionally, like a miniature levelFill().
Definition led_strand.hpp:179
void pulse(uint32_t color, uint8_t runLength, Speed speed, uint32_t bgColor=0x000000, bool invert=false, bool bounce=false)
Animate a run of color moving across a background.
LayerParam
A layer parameter a driver is allowed to move, once per tick.
Definition led_strand.hpp:330
@ WIDTH
Definition led_strand.hpp:331
@ OPACITY
Definition led_strand.hpp:331
@ SPEED
Definition led_strand.hpp:331
@ RUN_LENGTH
Definition led_strand.hpp:331
@ START
Definition led_strand.hpp:331
@ NONE
Definition led_strand.hpp:331
@ DENSITY
Definition led_strand.hpp:331
@ MIX
Definition led_strand.hpp:331
@ LEVEL
Definition led_strand.hpp:331
void overlayFlash(uint32_t color, uint32_t onMs, uint32_t offMs, uint32_t bgColor=0x000000)
Blink the overlay buffer on and off (see flash()).
void setRegionLevel(uint8_t regionIdx, uint8_t level)
Set how full a hand-driven GAUGE region is.
LayerBlend
How a layer lands on what the layers below it already drew.
Definition led_strand.hpp:310
@ MULTIPLY
Per-channel a*b/255 - a tint or a vignette.
Definition led_strand.hpp:315
@ MASK
This layer's brightness is how much of the layers below survives.
Definition led_strand.hpp:316
@ OVER
Replace, coverage ignored. What a splice region does today.
Definition led_strand.hpp:311
@ KEY
Replace where this layer covers; let the layers below through where it does not.
Definition led_strand.hpp:312
@ ADD
Saturating add - accents, glows, sparks.
Definition led_strand.hpp:313
@ SCREEN
255 - (255-a)(255-b)/255. Brightens without clipping.
Definition led_strand.hpp:314
friend class LedGroup
Definition led_strand.hpp:1227
void overlayBitscroll(const std::vector< BitScrollSegment > &segments, Speed speed, bool invert=false, uint32_t bgColor=0x000000, uint8_t spacing=5, bool repeating=true)
Scroll a repeating bit pattern in the overlay buffer (see bitscroll()).
bool musicPlaying() const
Whether a MusicTrack is attached and not paused.
Definition led_strand.hpp:888
LfoShape
Definition led_strand.hpp:327
@ SAW
Definition led_strand.hpp:327
@ SQUARE
Definition led_strand.hpp:327
@ RAMP_DOWN
Definition led_strand.hpp:327
@ TRIANGLE
Definition led_strand.hpp:327
@ SINE
Definition led_strand.hpp:327
static constexpr uint8_t MAX_LEDS
Definition led_strand.hpp:1223
GaugeBlend
How a GAUGE region moves between two stops.
Definition led_strand.hpp:185
@ STEP
Hold each stop's color until the next one is reached (a reading exactly on a stop has reached it).
Definition led_strand.hpp:187
@ LERP
Blend smoothly, so a rising reading slides between colors.
Definition led_strand.hpp:186
uint8_t getLevel() const
Return the meter's current level (0-255).
Definition led_strand.hpp:780
A WS2812B strip on one ADI port, either the brain's own or an ADI expander's.
Definition platform.hpp:99
Non-recursive mutex, blocking take.
Definition platform.hpp:80
Profile and mode descriptors for the hitlib event-driven animation system.
Definition led_group.hpp:12
The handful of OS and hardware calls HitLib needs, kept apart from any one SDK so the library builds ...
Ties one driver to one parameter of one layer.
Definition led_strand.hpp:367
const uint8_t * curve
CURVE_POINTS bytes, or nullptr.
Definition led_strand.hpp:372
LayerParam param
NONE is an unused slot.
Definition led_strand.hpp:368
int16_t atFull
Definition led_strand.hpp:371
int16_t atZero
Definition led_strand.hpp:370
uint8_t driver
Index into Composition::drivers.
Definition led_strand.hpp:369
One colored segment in a bitscroll pattern.
Definition led_strand.hpp:78
uint32_t color
Segment color (0xRRGGBB).
Definition led_strand.hpp:79
uint8_t width
Width in pixels.
Definition led_strand.hpp:80
A named, reusable custom animation: layers over a driver table and a clock.
Definition led_strand.hpp:529
uint8_t driverCount
Definition led_strand.hpp:534
const Driver * drivers
Definition led_strand.hpp:533
const Layer * layers
Drawn in order; layer 0 is the bottom.
Definition led_strand.hpp:531
uint32_t bgColor
What the frame starts as, under layer 0.
Definition led_strand.hpp:536
uint8_t layerCount
Definition led_strand.hpp:532
uint32_t loopMs
0 means the timeline never wraps.
Definition led_strand.hpp:535
const char * name
Definition led_strand.hpp:530
One thing a composition watches, reduced to a byte per tick.
Definition led_strand.hpp:504
uint8_t value
CONSTANT's byte, moved by setDriverLevel().
Definition led_strand.hpp:507
uint32_t periodMs
Definition led_strand.hpp:517
bool wrap
Definition led_strand.hpp:511
LfoShape shape
LFO.
Definition led_strand.hpp:516
bool loop
Definition led_strand.hpp:515
double emptyAt
Definition led_strand.hpp:509
uint8_t sensitivity
Definition led_strand.hpp:514
DriverKind kind
Definition led_strand.hpp:506
double fullAt
Definition led_strand.hpp:510
uint8_t phasePct
Offset into the period, so two LFOs can differ.
Definition led_strand.hpp:518
LevelFn read
SENSOR. nullptr leaves the driver at 0.
Definition led_strand.hpp:508
uint8_t smoothing
0-99, as in levelSource().
Definition led_strand.hpp:512
const MusicTrack * track
MUSIC. Must outlive the strand.
Definition led_strand.hpp:513
const char * name
Definition led_strand.hpp:505
A port on an ADI expander: the Smart Port the expander is plugged into, and the ADI port on it.
Definition led_strand.hpp:70
uint8_t adiPort
ADI port on the expander (1–8).
Definition led_strand.hpp:72
uint8_t smartPort
Smart Port the expander is connected to (1–21).
Definition led_strand.hpp:71
One color on a GAUGE region's scale.
Definition led_strand.hpp:169
uint32_t color
Color shown at that reading (0xRRGGBB).
Definition led_strand.hpp:171
double at
Reading this color belongs to, in the source's units.
Definition led_strand.hpp:170
Definition led_strand.hpp:379
uint32_t offMs
Definition led_strand.hpp:379
uint32_t onMs
Definition led_strand.hpp:379
A hand-drawn pixel strip: x = pixel, y = frame.
Definition led_strand.hpp:450
const uint8_t * data
Definition led_strand.hpp:451
uint16_t frameMs
How long each frame holds.
Definition led_strand.hpp:457
uint8_t count
Frames.
Definition led_strand.hpp:456
const uint16_t * index
Byte offset of each frame in data.
Definition led_strand.hpp:452
const uint8_t * scroll
One flag per frame: non-zero scrolls that frame.
Definition led_strand.hpp:460
uint8_t width
Pixels per frame.
Definition led_strand.hpp:455
uint8_t paletteCount
Definition led_strand.hpp:454
const uint32_t * palette
Index 0 is transparent whatever color it names.
Definition led_strand.hpp:453
Definition led_strand.hpp:416
GaugeStyle style
GAUGE: whole-span color, or a bar.
Definition led_strand.hpp:419
GaugeBlend blend
Definition led_strand.hpp:420
double fullAt
Definition led_strand.hpp:425
uint8_t level
Starting level; bind LayerParam::LEVEL to move it.
Definition led_strand.hpp:417
uint8_t stopCount
Definition led_strand.hpp:423
const GaugeStop * stops
The scale, in the driver's own units.
Definition led_strand.hpp:421
double emptyAt
Units stops are given in.
Definition led_strand.hpp:424
bool gradient
METER: lay color -> color2 across the span.
Definition led_strand.hpp:418
How a layer lands. opacity is 0-255 and is bindable.
Definition led_strand.hpp:353
uint8_t opacity
Definition led_strand.hpp:353
LayerBlend blend
Definition led_strand.hpp:353
speed.pixels is what a LayerParam::SPEED binding moves; the time between steps stays the layer's own.
Definition led_strand.hpp:378
uint8_t runLength
Definition led_strand.hpp:378
bool invert
Definition led_strand.hpp:378
bool bounce
Definition led_strand.hpp:378
Speed speed
Definition led_strand.hpp:378
bool seamless
Definition led_strand.hpp:378
Definition led_strand.hpp:375
uint32_t color
Definition led_strand.hpp:375
uint32_t bgColor
Definition led_strand.hpp:375
uint32_t color2
Definition led_strand.hpp:375
Definition led_strand.hpp:409
bool repeating
Tile across the span, or scroll one copy.
Definition led_strand.hpp:413
uint8_t segmentCount
Definition led_strand.hpp:411
uint8_t spacing
Background pixels between runs.
Definition led_strand.hpp:412
const BitScrollSegment * segments
The lit runs, in order.
Definition led_strand.hpp:410
Which pixels a layer owns.
Definition led_strand.hpp:335
uint8_t width
Pixels.
Definition led_strand.hpp:337
bool continuous
With stride, sample the animation at the strand-wide pixel index rather than restarting it in each re...
Definition led_strand.hpp:349
uint8_t start
First pixel.
Definition led_strand.hpp:336
uint8_t stride
0 draws one span; otherwise repeat it every N pixels.
Definition led_strand.hpp:342
Definition led_strand.hpp:402
const uint32_t * palette
Colors sparks are drawn from. nullptr leaves the span dark.
Definition led_strand.hpp:403
uint8_t densityPct
Share of the span lit at once (0-100). Bindable.
Definition led_strand.hpp:405
uint8_t fadeStep
Brightness step per tick, so bigger is faster.
Definition led_strand.hpp:406
uint8_t paletteCount
Definition led_strand.hpp:404
When a layer is on, inside the composition's loop.
Definition led_strand.hpp:393
bool retrigger
Restart this layer's motion each time its window opens.
Definition led_strand.hpp:399
uint32_t loopMs
This layer's own clock; 0 uses the composition's.
Definition led_strand.hpp:394
uint16_t fadeOutMs
Definition led_strand.hpp:398
uint32_t endMs
0 with a non-zero startMs means "to the loop point".
Definition led_strand.hpp:396
uint16_t fadeInMs
Definition led_strand.hpp:397
uint32_t startMs
Definition led_strand.hpp:395
One layer of a Composition: what it draws, where, when, what moves it, and how it lands on the layers...
Definition led_strand.hpp:478
LayerFrames frames
Definition led_strand.hpp:491
LayerPattern pattern
Definition led_strand.hpp:489
LayerFlash flash
Definition led_strand.hpp:486
LayerTime time
Definition led_strand.hpp:487
LayerMix mix
Definition led_strand.hpp:482
LayerKind kind
Definition led_strand.hpp:480
LayerSparkle sparkle
Definition led_strand.hpp:488
const char * name
Shown nowhere on the robot; it is what makes the export readable.
Definition led_strand.hpp:479
Binding bindings[MAX_BINDINGS]
Definition led_strand.hpp:483
LayerPaint paint
Definition led_strand.hpp:484
LayerGauge gauge
Definition led_strand.hpp:490
LayerMotion motion
Definition led_strand.hpp:485
LayerSpan span
Definition led_strand.hpp:481
A song's intensity envelope, baked ahead of time into one 8-bit sample per frame.
Definition led_strand.hpp:267
uint16_t frameCount
Number of samples in samples.
Definition led_strand.hpp:269
uint16_t frameMs
Milliseconds between consecutive samples.
Definition led_strand.hpp:270
const uint8_t * samples
Intensity 0-255, one entry per frame.
Definition led_strand.hpp:268
How fast a moving animation travels: so many pixels, so often.
Definition led_strand.hpp:101
constexpr Speed(int pixelsPerStep=1, uint16_t ms=0)
pixelsPerStep pixels every ms milliseconds; with no ms, that many pixels on every refresh tick.
Definition led_strand.hpp:107
uint16_t stepMs
Milliseconds between steps. 0 steps on every refresh tick.
Definition led_strand.hpp:103
uint8_t pixels
Pixels moved per step.
Definition led_strand.hpp:102
static constexpr Speed everyMs(uint16_t ms, uint8_t pixelsPerStep=1)
pixelsPerStep pixels (default one) every ms milliseconds.
Definition led_strand.hpp:111
One independently placed override region for a custom splice mask.
Definition led_strand.hpp:199
bool wrap
Cycle past fullAt instead of pinning at it.
Definition led_strand.hpp:235
GaugeStyle style
Whole-region color, or a bar.
Definition led_strand.hpp:237
uint8_t fadeStep
Brightness step per tick, so bigger is faster.
Definition led_strand.hpp:220
uint32_t color
Foreground color (SOLID/PULSE/FLASH/FLOW/BITSCROLL).
Definition led_strand.hpp:203
uint32_t bgColor
PULSE/FLASH/TWINKLE/BITSCROLL background, and a GAUGE BAR's unlit part.
Definition led_strand.hpp:205
Speed speed
PULSE/FLOW/RAINBOW/BITSCROLL motion, see Speed.
Definition led_strand.hpp:207
bool repeating
Tile the pattern across the region, or scroll one copy.
Definition led_strand.hpp:226
std::vector< GaugeStop > stops
The scale, in the reading's own units.
Definition led_strand.hpp:242
uint8_t start
First pixel index covered by this region.
Definition led_strand.hpp:200
bool invert
Reverse direction: a BITSCROLL scrolls the other way, a GAUGE BAR fills from the far end of the regio...
Definition led_strand.hpp:213
uint32_t color2
FLOW end color.
Definition led_strand.hpp:204
std::vector< uint32_t > palette
Colors sparks are drawn from. An empty palette leaves the region dark.
Definition led_strand.hpp:218
uint8_t spacing
Background pixels between runs.
Definition led_strand.hpp:225
bool seamless
FLOW only.
Definition led_strand.hpp:210
uint32_t onMs
FLASH lit duration (ms).
Definition led_strand.hpp:208
uint8_t segmentWidth
Pixels per lit run.
Definition led_strand.hpp:224
SpliceRegionAnimKind kind
What this region shows.
Definition led_strand.hpp:202
uint8_t smoothing
0-99, as in levelSource().
Definition led_strand.hpp:236
uint8_t densityPct
Share of the region lit at once (0-100).
Definition led_strand.hpp:219
double fullAt
Reading at the top of it.
Definition led_strand.hpp:234
double emptyAt
Reading at the bottom of the scale.
Definition led_strand.hpp:233
uint8_t width
Number of pixels covered.
Definition led_strand.hpp:201
uint8_t runLength
PULSE run length.
Definition led_strand.hpp:206
LevelFn read
Value this gauge follows, polled once per tick.
Definition led_strand.hpp:232
GaugeBlend blend
Blend between stops, or hold each.
Definition led_strand.hpp:238
uint32_t offMs
FLASH blank duration (ms).
Definition led_strand.hpp:209
An immutable, statically-allocated collection of ProfileMode entries.
Definition led_profile.hpp:68