Skip to content

Commit

Permalink
Merge branch 'chromadeck' into daniel/chromadeck/next_work
Browse files Browse the repository at this point in the history
  • Loading branch information
Unreal-Dan committed Dec 12, 2023
2 parents 357cdcf + 0087063 commit 5ff4b49
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 122 deletions.
3 changes: 3 additions & 0 deletions VortexEngine/src/Leds/LedTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ typedef uint64_t LedMap;
// convert a map to the first Led position in the map
inline LedPos mapGetFirstLed(LedMap map)
{
if (map == MAP_LED(LED_MULTI)) {
return LED_MULTI;
}
LedPos pos = LED_FIRST;
while (map && pos < LED_COUNT) {
if (map & 1) {
Expand Down
4 changes: 4 additions & 0 deletions VortexEngine/src/Log/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include "VortexLib.h"
#endif

#ifdef VORTEX_EMBEDDED
#include <Arduino.h>
#endif

#if LOGGING_LEVEL > 0
void InfoMsg(const char *msg, ...)
{
Expand Down
1 change: 1 addition & 0 deletions VortexEngine/src/Menus/MenuList/ColorSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ bool ColorSelect::init()
return false;
}
if (cur->isMultiLed()) {
m_targetLeds = MAP_LED(LED_MULTI);
m_ledSelected = true;
}
m_state = STATE_INIT;
Expand Down
156 changes: 102 additions & 54 deletions VortexEngine/src/Menus/MenuList/Randomizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ bool Randomizer::init()
}
// grab the multi ld pattern colorset crc if it's present
Mode *cur = Modes::curMode();
#if VORTEX_SLIM == 0
if (cur->hasMultiLed()) {
ByteStream ledData;
Pattern *pat = cur->getPattern(LED_MULTI);
Expand All @@ -43,6 +44,7 @@ bool Randomizer::init()
}
m_multiRandCtx.seed(ledData.recalcCRC());
}
#endif
// initialize the randomseed of each led with the
// CRC of the colorset on the respective LED
for (LedPos l = LED_FIRST; l < LED_COUNT; ++l) {
Expand Down Expand Up @@ -70,6 +72,7 @@ Menu::MenuAction Randomizer::run()
showRandomizationSelect();
return MENU_CONTINUE;
}
#if VORTEX_SLIM == 0
// if they are trying to randomize a multi-led pattern just convert
// the pattern to all singles with the same colorset upon entry
if (m_previewMode.isMultiLed() && m_targetLeds != MAP_LED(LED_MULTI)) {
Expand All @@ -83,6 +86,7 @@ Menu::MenuAction Randomizer::run()
m_previewMode.setPattern(newID);
m_previewMode.init();
}
#endif
// if the user fast-clicks 3 times then toggle automode
if (g_pButtonM->onRelease() && g_pButtonM->onConsecutivePresses(AUTO_CYCLE_RANDOMIZER_CLICKS)) {
// toggle the auto cycle flag
Expand Down Expand Up @@ -132,6 +136,23 @@ void Randomizer::onLongClick()
leaveMenu(true);
}

bool Randomizer::reRoll()
{
#if VORTEX_SLIM == 0
if (m_targetLeds == MAP_LED(LED_MULTI)) {
if (!reRollMulti()) {
return false;
}
}
#endif
if (!reRollSingles()) {
return false;
}
// initialize the mode with the new pattern and colorset
m_previewMode.init();
return true;
}

void Randomizer::showRandomizationSelect()
{
// show iterating rainbow if they are randomizing color, otherwise 0 sat if they
Expand All @@ -145,6 +166,78 @@ void Randomizer::showRandomizationSelect()
Menus::showSelection();
}

#if VORTEX_SLIM == 0
bool Randomizer::reRollMulti()
{
if (m_flags & RANDOMIZE_PATTERN) {
// TODO: Roll custom multi pattern?
//if (m_advanced) {
// if (!rollCustomPattern(ctx, &m_previewMode, pos)) {
// ERROR_LOG("Failed to roll custom pattern");
// return false;
// }
//}
if (!m_previewMode.setPattern(rollMultiLedPatternID(m_multiRandCtx), LED_MULTI)) {
ERROR_LOG("Failed to select pattern");
return false;
}
}
if (m_flags & RANDOMIZE_COLORSET) {
if (!m_previewMode.setColorset(rollColorset(m_multiRandCtx), LED_MULTI)) {
ERROR_LOG("Failed to roll new colorset");
return false;
}
}
return true;
}

PatternID Randomizer::rollMultiLedPatternID(Random &ctx)
{
return (PatternID)ctx.next8(PATTERN_MULTI_FIRST, PATTERN_MULTI_LAST);
}
#endif

bool Randomizer::reRollSingles()
{
// re-roll each led position with it's respective random context
MAP_FOREACH_LED(m_targetLeds) {
Random &ctx = m_singlesRandCtx[pos];
if (m_flags & RANDOMIZE_PATTERN) {
// in advanced mode, when not randomizing the multi position, use a
// special function to randomize totally custom led pattern timings
if (m_advanced) {
if (!rollCustomPattern(ctx, &m_previewMode, pos)) {
ERROR_LOG("Failed to roll custom pattern");
return false;
}
} else {
if (!m_previewMode.setPattern(rollSingleLedPatternID(ctx), pos)) {
ERROR_LOG("Failed to select pattern");
return false;
}
}
}
if (m_flags & RANDOMIZE_COLORSET) {
if (!m_previewMode.setColorset(rollColorset(ctx), pos)) {
ERROR_LOG("Failed to roll new colorset");
return false;
}
}
}
return true;
}

PatternID Randomizer::rollSingleLedPatternID(Random &ctx)
{
PatternID newPat;
// the random range begin/end
do {
// continuously re-randomize the pattern so we don't get undesirable patterns
newPat = (PatternID)ctx.next8(PATTERN_SINGLE_FIRST, PATTERN_SINGLE_LAST);
} while (newPat == PATTERN_SOLID || newPat == PATTERN_RIBBON || newPat == PATTERN_MINIRIBBON);
return newPat;
}

Colorset Randomizer::rollColorset(Random &ctx)
{
Colorset randomSet;
Expand Down Expand Up @@ -194,7 +287,7 @@ Colorset Randomizer::rollColorset(Random &ctx)
return randomSet;
}

bool Randomizer::rollPattern(Random &ctx, Mode *pMode, LedPos pos)
bool Randomizer::rollCustomPattern(Random &ctx, Mode *pMode, LedPos pos)
{
PatternArgs args;
// pick a random type of randomizer to use then use
Expand Down Expand Up @@ -233,10 +326,10 @@ void Randomizer::traditionalPattern(Random &ctx, PatternArgs &outArgs)
// call next8 explicitly in this order because the order they
// are called is undefined when called as parameters to another function.
// ex: f(a,b,c) may call in the order a,b,c or c,b,a depending on compiler.
// So different compilers may produce different results,
// So different compilers may produce different results,
// but like this it is explicit
uint8_t off = ctx.next8(8, 60); // off duration 0 -> 60
uint8_t on = ctx.next8(1, 20); // on duration 1 -> 20
uint8_t on = ctx.next8(1, 20); // on duration 1 -> 20
outArgs.init(on, off);
}

Expand All @@ -245,11 +338,11 @@ void Randomizer::gapPattern(Random &ctx, PatternArgs &outArgs)
// call next8 explicitly in this order because the order they
// are called is undefined when called as parameters to another function.
// ex: f(a,b,c) may call in the order a,b,c or c,b,a depending on compiler.
// So different compilers may produce different results,
// So different compilers may produce different results,
// but like this it is explicit
uint8_t gap = ctx.next8(40, 100); // gap duration 40 -> 100
uint8_t off = ctx.next8(0, 6); // off duration 0 -> 6
uint8_t on = ctx.next8(1, 10); // on duration 1 -> 10
uint8_t on = ctx.next8(1, 10); // on duration 1 -> 10
outArgs.init(on, off, gap);
}

Expand All @@ -258,11 +351,11 @@ void Randomizer::dashPattern(Random &ctx, PatternArgs &outArgs)
// call next8 explicitly in this order because the order they
// are called is undefined when called as parameters to another function.
// ex: f(a,b,c) may call in the order a,b,c or c,b,a depending on compiler.
// So different compilers may produce different results,
// So different compilers may produce different results,
// but like this it is explicit
uint8_t dash = ctx.next8(20, 30); // dash duration 20 -> 30
uint8_t gap = ctx.next8(20, 30); // need gap 20 -> 30
uint8_t off = ctx.next8(0, 10); // off duration 0 -> 10
uint8_t off = ctx.next8(0, 10); // off duration 0 -> 10
uint8_t on = ctx.next8(1, 10); // on duration 1 -> 10
outArgs.init(on, off, gap, dash);
}
Expand All @@ -272,57 +365,12 @@ void Randomizer::crushPattern(Random &ctx, PatternArgs &outArgs)
// call next8 explicitly in this order because the order they
// are called is undefined when called as parameters to another function.
// ex: f(a,b,c) may call in the order a,b,c or c,b,a depending on compiler.
// So different compilers may produce different results,
// So different compilers may produce different results,
// but like this it is explicit
uint8_t group = ctx.next8(0, 8); // groupsize 0 to 8
uint8_t dash = 0; // dash 0
uint8_t dash = 0; // dash 0
uint8_t gap = ctx.next8(20, 40); // need gap 20 -> 40
uint8_t off = ctx.next8(0, 10); // off duration 0 -> 5
uint8_t on = ctx.next8(1, 10); // on duration 1 -> 10
outArgs.init(on, off, gap, dash, group);
}

PatternID Randomizer::rollPatternID(Random &ctx)
{
PatternID newPat;
// the random range begin/end
do {
// continuously re-randomize the pattern so we don't get undesirable patterns
newPat = (PatternID)ctx.next8(PATTERN_SINGLE_FIRST, PATTERN_SINGLE_LAST);
} while (newPat == PATTERN_SOLID || newPat == PATTERN_RIBBON || newPat == PATTERN_MINIRIBBON);
return newPat;
}

bool Randomizer::reRoll()
{
MAP_FOREACH_LED(m_targetLeds) {
// grab local reference to the target random context
Random &ctx = m_singlesRandCtx[pos];
if (m_flags & RANDOMIZE_PATTERN) {
// roll a new pattern
if (m_advanced) {
if (!rollPattern(ctx, &m_previewMode, pos)) {
ERROR_LOG("Failed to roll new pattern");
return false;
}
} else {
if (!m_previewMode.setPattern(rollPatternID(ctx), pos)) {
ERROR_LOG("Failed to roll new pattern");
return false;
}
}
}
if (m_flags & RANDOMIZE_COLORSET) {
// roll a new colorset
if (!m_previewMode.setColorset(rollColorset(ctx), pos)) {
ERROR_LOG("Failed to roll new colorset");
return false;
}
}
}
// initialize the mode with the new pattern and colorset
m_previewMode.init();
DEBUG_LOGF("Randomized Led %u set with randomization technique %u, %u colors, and Pattern number %u",
pos, randType, randomSet.numColors(), newPat);
return true;
}
20 changes: 16 additions & 4 deletions VortexEngine/src/Menus/MenuList/Randomizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ class Randomizer : public Menu
bool reRoll();

private:
// random context for each led and led multi (LED_COUNT + 1)
// random context for each single led
Random m_singlesRandCtx[LED_COUNT];
#if VORTEX_SLIM == 0
// random context for the multi led position
Random m_multiRandCtx;
#endif

// the time of the last randomization
uint32_t m_lastRandomization;
Expand Down Expand Up @@ -59,12 +62,21 @@ class Randomizer : public Menu
// show the randomization type selection
void showRandomizationSelect();

// main reRoll functions
#if VORTEX_SLIM == 0
bool reRollMulti();
PatternID rollMultiLedPatternID(Random &ctx);
#endif
bool reRollSingles();
PatternID rollSingleLedPatternID(Random &ctx);

// generate a random colorset with a random context
bool rollPattern(Random &ctx, Mode *pMode, LedPos pos);
PatternID rollPatternID(Random &ctx);
Colorset rollColorset(Random &ctx);

// random pattern generators
// roll a custom pattern by generating random arguments
bool rollCustomPattern(Random &ctx, Mode *pMode, LedPos pos);

// more specific random pattern generators that just generate patternargs
void traditionalPattern(Random &ctx, PatternArgs &outArgs);
void gapPattern(Random &ctx, PatternArgs &outArgs);
void dashPattern(Random &ctx, PatternArgs &outArgs);
Expand Down
12 changes: 10 additions & 2 deletions VortexEngine/src/Patterns/Multi/HueShiftPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ HueShiftPattern::HueShiftPattern(const PatternArgs &args) :
MultiLedPattern(args),
m_blinkOnDuration(0),
m_blinkOffDuration(0),
m_blendDelay(0),
m_delayCounter(0),
m_blinkTimer(),
m_cur(0),
m_next(0)
{
m_patternID = PATTERN_HUE_SCROLL;
REGISTER_ARG(m_blinkOnDuration);
REGISTER_ARG(m_blinkOffDuration);
REGISTER_ARG(m_blendDelay);
setArgs(args);
}

Expand Down Expand Up @@ -65,8 +68,13 @@ void HueShiftPattern::play()
// it will cause oscillation around the target hue
// because it will never reach the target hue and
// always over/under shoot
m_cur.hue += sign;
HSVColor showColor = m_cur;
// only increment every blendDelay times
++m_delayCounter;
if (m_delayCounter >= m_blendDelay) {
m_delayCounter = 0;
m_cur.hue += sign;
}
HSVColor showColor = HSVColor(m_cur.hue, 255, 255);
// set the target led with the current HSV color
for (LedPos pos = LED_FIRST; pos < LED_COUNT; ++pos) {
Leds::setIndex(pos, hsv_to_rgb_generic(showColor));
Expand Down
2 changes: 2 additions & 0 deletions VortexEngine/src/Patterns/Multi/HueShiftPattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class HueShiftPattern : public MultiLedPattern
private:
uint8_t m_blinkOnDuration;
uint8_t m_blinkOffDuration;
uint8_t m_blendDelay;
uint8_t m_delayCounter;

Timer m_blinkTimer;

Expand Down
11 changes: 6 additions & 5 deletions VortexEngine/src/Patterns/Multi/MeteorPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ void MeteorPattern::blinkOff()

void MeteorPattern::poststep()
{
// when a new meteor is created it is incerted into the stash so the blinking pattern is not interrupted
Pair target = (Pair)m_randCtx.next8(PAIR_FIRST, PAIR_LAST);
RGBColor col = m_colorset.getNext();
m_stash.setIndex(pairEven(target), col);
m_stash.setIndex(pairOdd(target), col);
for (uint8_t meteorCount = 0; meteorCount < (LED_COUNT / 2); ++meteorCount) {
// when a new meteor is created it is incerted into the stash so the blinking pattern is not interrupted
LedPos target = (LedPos)m_randCtx.next8(LED_FIRST, LED_LAST);
RGBColor col = m_colorset.getNext();
m_stash.setIndex(target, col);
}
}
Loading

0 comments on commit 5ff4b49

Please sign in to comment.