diff --git a/VortexEngine/src/Leds/LedTypes.h b/VortexEngine/src/Leds/LedTypes.h index 0a6534fe8b..ad0bbf286f 100644 --- a/VortexEngine/src/Leds/LedTypes.h +++ b/VortexEngine/src/Leds/LedTypes.h @@ -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) { diff --git a/VortexEngine/src/Log/Log.cpp b/VortexEngine/src/Log/Log.cpp index 3f4660c2e4..c79ff42b06 100644 --- a/VortexEngine/src/Log/Log.cpp +++ b/VortexEngine/src/Log/Log.cpp @@ -11,6 +11,10 @@ #include "VortexLib.h" #endif +#ifdef VORTEX_EMBEDDED +#include +#endif + #if LOGGING_LEVEL > 0 void InfoMsg(const char *msg, ...) { diff --git a/VortexEngine/src/Menus/MenuList/ColorSelect.cpp b/VortexEngine/src/Menus/MenuList/ColorSelect.cpp index 62239dc41f..3fe77f265f 100644 --- a/VortexEngine/src/Menus/MenuList/ColorSelect.cpp +++ b/VortexEngine/src/Menus/MenuList/ColorSelect.cpp @@ -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; diff --git a/VortexEngine/src/Menus/MenuList/Randomizer.cpp b/VortexEngine/src/Menus/MenuList/Randomizer.cpp index fefa9754a8..8acc331a31 100644 --- a/VortexEngine/src/Menus/MenuList/Randomizer.cpp +++ b/VortexEngine/src/Menus/MenuList/Randomizer.cpp @@ -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); @@ -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) { @@ -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)) { @@ -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 @@ -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 @@ -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; @@ -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 @@ -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); } @@ -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); } @@ -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); } @@ -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; -} diff --git a/VortexEngine/src/Menus/MenuList/Randomizer.h b/VortexEngine/src/Menus/MenuList/Randomizer.h index 01af38c5c6..0575ab132f 100644 --- a/VortexEngine/src/Menus/MenuList/Randomizer.h +++ b/VortexEngine/src/Menus/MenuList/Randomizer.h @@ -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; @@ -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); diff --git a/VortexEngine/src/Patterns/Multi/HueShiftPattern.cpp b/VortexEngine/src/Patterns/Multi/HueShiftPattern.cpp index 89a593f1a5..d86a35810f 100644 --- a/VortexEngine/src/Patterns/Multi/HueShiftPattern.cpp +++ b/VortexEngine/src/Patterns/Multi/HueShiftPattern.cpp @@ -9,6 +9,8 @@ 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) @@ -16,6 +18,7 @@ HueShiftPattern::HueShiftPattern(const PatternArgs &args) : m_patternID = PATTERN_HUE_SCROLL; REGISTER_ARG(m_blinkOnDuration); REGISTER_ARG(m_blinkOffDuration); + REGISTER_ARG(m_blendDelay); setArgs(args); } @@ -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)); diff --git a/VortexEngine/src/Patterns/Multi/HueShiftPattern.h b/VortexEngine/src/Patterns/Multi/HueShiftPattern.h index f095a9082f..691b3cb2e9 100644 --- a/VortexEngine/src/Patterns/Multi/HueShiftPattern.h +++ b/VortexEngine/src/Patterns/Multi/HueShiftPattern.h @@ -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; diff --git a/VortexEngine/src/Patterns/Multi/MeteorPattern.cpp b/VortexEngine/src/Patterns/Multi/MeteorPattern.cpp index 528fb1a36f..004da9867c 100644 --- a/VortexEngine/src/Patterns/Multi/MeteorPattern.cpp +++ b/VortexEngine/src/Patterns/Multi/MeteorPattern.cpp @@ -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); + } } diff --git a/VortexEngine/src/Patterns/Multi/Sequencer/ChaserPattern.cpp b/VortexEngine/src/Patterns/Multi/Sequencer/ChaserPattern.cpp index 685950b48a..2868c09e97 100644 --- a/VortexEngine/src/Patterns/Multi/Sequencer/ChaserPattern.cpp +++ b/VortexEngine/src/Patterns/Multi/Sequencer/ChaserPattern.cpp @@ -1,5 +1,9 @@ #include "ChaserPattern.h" +// This controls the ratio of chaser dots to LED_COUNT. Default 1 chaser per 7 LEDs. Range: 1-LED_COUNT. +#define CHASER_RATIO 7 + + // This pattern aims to be a demonstration of the sequencer. // There are always many ways to implement a pattern, it's best // to choose the method that is most suitable for the pattern. @@ -7,44 +11,15 @@ ChaserPattern::ChaserPattern(const PatternArgs &args) : SequencedPattern(args) { setArgs(args); - // set the pattern ID - //m_patternID = PATTERN_CHASER; - // There are 8 steps in the chaser, so iterate 8 times and generate - // a pattern map for each step. A colorset map can also be applied - // to override certain colors for specific steps, but that's not - // what is being done here - for (uint8_t i = 0; i < 8; ++i) { - // Each step all fingers are dops except for one, so start with a - // Pattern Map that has dops on all fingers. A Pattern Map will map - // a Pattern ID to each LED on the device, then we will override a - // different entry each step with the Pattern ID for Solid0. + uint32_t numChasers = LED_COUNT / CHASER_RATIO; + if (!numChasers) { + numChasers = 1; + } + for (uint8_t i = 0; i < (LED_COUNT / numChasers); ++i) { PatternMap patMap(PATTERN_DOPS); - // Override a single finger in the pattern map with the Solid0 pattern - // which will use the 0th color from the colorset as the solid color. - // An LedMap is a bitmap that indicates which leds are turned on or off - // at any given time. This will generate an Led Map based on the current - // step index like this: - // - // step -> finger index -> target leds -> LedMap - // ----------------------------------------------------- - // 0 0 0, 1 00 00 00 00 11 - // 1 1 2, 3 00 00 00 11 00 - // 2 2 4, 5 00 00 11 00 00 - // 3 3 6, 7 00 11 00 00 00 - // 4 4 8, 9 11 00 00 00 00 - // 5 3 6, 7 00 11 00 00 00 - // 6 2 4, 5 00 00 11 00 00 - // 7 1 2, 3 00 00 00 11 00 - LedMap overrideLeds = MAP_PAIR((Pair)((i < 5) ? i : (8 - i))); - // Then this API is used to override specific positions in the Pattern Map - // with a different pattern ID, we use the Led Map generated above to tell - // setPatternAt() which indices to override with Solid0 - patMap.setPatternAt(PATTERN_SOLID, overrideLeds); - // Then finally we add this pattern mapping to the sequence in a new step - // that will last 300ms, this means all 8 steps will be 300ms each. - // The last parameter of addStep() is omitted, that parameter could be used - // to override the colorset for specific Leds on any given step. Since it - // is omitted that means this pattern will use whichever colorset is chosen - m_sequence.addStep(300, patMap); + for (uint8_t chaserCount = 0; chaserCount < numChasers; ++chaserCount) { + patMap.setPatternAt(PATTERN_SOLID, MAP_LED((i + (chaserCount * CHASER_RATIO)) % LED_COUNT)); + } + m_sequence.addStep(150, patMap); } } diff --git a/VortexEngine/src/Patterns/Multi/Sequencer/SequencedPattern.cpp b/VortexEngine/src/Patterns/Multi/Sequencer/SequencedPattern.cpp index b4bd86f151..d65e64bc7f 100644 --- a/VortexEngine/src/Patterns/Multi/Sequencer/SequencedPattern.cpp +++ b/VortexEngine/src/Patterns/Multi/Sequencer/SequencedPattern.cpp @@ -47,16 +47,27 @@ void SequencedPattern::init() m_timer.start(); - // TODO: Play first sequence step in init? + // Play first sequence step in init, if there is one + if (m_sequence.numSteps() > 0) { + playSequenceStep(m_sequence[0]); + } } // pure virtual must the play function void SequencedPattern::play() { - if (m_timer.alarm() != -1 && !m_timer.onStart()) { + if (m_timer.alarm() != -1) { m_curSequence = (m_curSequence + 1) % m_sequence.numSteps(); } - const SequenceStep &step = m_sequence[m_curSequence]; + // only index the sequence if the current sequence index is valid + if (m_curSequence < m_sequence.numSteps()) { + // play the sequence step + playSequenceStep(m_sequence[m_curSequence]); + } +} + +void SequencedPattern::playSequenceStep(const SequenceStep &step) +{ for (LedPos pos = LED_FIRST; pos < LED_COUNT; ++pos) { // the current initialized pattern for this LED SingleLedPattern *curPat = m_ledPatterns[pos]; diff --git a/VortexEngine/src/Patterns/Multi/Sequencer/SequencedPattern.h b/VortexEngine/src/Patterns/Multi/Sequencer/SequencedPattern.h index a73d6130fe..d1f6786ce3 100644 --- a/VortexEngine/src/Patterns/Multi/Sequencer/SequencedPattern.h +++ b/VortexEngine/src/Patterns/Multi/Sequencer/SequencedPattern.h @@ -32,6 +32,8 @@ class SequencedPattern : public CompoundPattern void bindSequence(const Sequence &sequence); protected: + void playSequenceStep(const SequenceStep &step); + // static data Sequence m_sequence; diff --git a/VortexEngine/src/Patterns/PatternBuilder.cpp b/VortexEngine/src/Patterns/PatternBuilder.cpp index 8579af9880..0f0b15587d 100644 --- a/VortexEngine/src/Patterns/PatternBuilder.cpp +++ b/VortexEngine/src/Patterns/PatternBuilder.cpp @@ -164,28 +164,28 @@ PatternArgs PatternBuilder::getDefaultArgs(PatternID id) // ===================== // Multi Led Patterns: #if VORTEX_SLIM == 0 - case PATTERN_HUE_SCROLL: return PatternArgs(1, 1); + case PATTERN_HUE_SCROLL: return PatternArgs(1, 1, 10); case PATTERN_THEATER_CHASE: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 28); case PATTERN_CHASER: return PatternArgs(); - case PATTERN_ZIGZAG: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 55, 1, 55); - case PATTERN_ZIPFADE: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 100, 4, 1); - case PATTERN_DRIP: return PatternArgs(STROBE_ON_DURATION, STROBE_OFF_DURATION, 250); + case PATTERN_ZIGZAG: return PatternArgs(DOPS_ON_DURATION, 3, 3, 5, 55); + case PATTERN_ZIPFADE: return PatternArgs(DOPS_ON_DURATION, 2, 75, 9, 230); + case PATTERN_DRIP: return PatternArgs(STROBE_ON_DURATION, STROBE_OFF_DURATION, 150); case PATTERN_DRIPMORPH: return PatternArgs(STROBE_ON_DURATION, STROBE_OFF_DURATION, 1); - case PATTERN_CROSSDOPS: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 100); + case PATTERN_CROSSDOPS: return PatternArgs(DOPS_ON_DURATION, 2, 25); case PATTERN_DOUBLESTROBE: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 115); - case PATTERN_METEOR: return PatternArgs(STROBE_ON_DURATION, STROBE_OFF_DURATION, 55, 75); - case PATTERN_SPARKLETRACE: return PatternArgs(5, 0, 50); - case PATTERN_VORTEXWIPE: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 130); - case PATTERN_WARP: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 150); - case PATTERN_WARPWORM: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 110); - case PATTERN_SNOWBALL: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 110); - case PATTERN_LIGHTHOUSE: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 100, 25, 5); - case PATTERN_PULSISH: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, STROBE_ON_DURATION, STROBE_OFF_DURATION, 250); - case PATTERN_FILL: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 200); - case PATTERN_BOUNCE: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 200, 10); + case PATTERN_METEOR: return PatternArgs(1, 1, 20, 130); + case PATTERN_SPARKLETRACE: return PatternArgs(1, 5, 3); + case PATTERN_VORTEXWIPE: return PatternArgs(DOPS_ON_DURATION, 3, 80); + case PATTERN_WARP: return PatternArgs(3, DOPS_OFF_DURATION, 50); + case PATTERN_WARPWORM: return PatternArgs(DOPS_ON_DURATION, 10, 100); + case PATTERN_SNOWBALL: return PatternArgs(3, 3, 33); + case PATTERN_LIGHTHOUSE: return PatternArgs(DOPS_ON_DURATION, 5, 22, 3, 3); + case PATTERN_PULSISH: return PatternArgs(DOPS_ON_DURATION, 6, 5, 1, 100); + case PATTERN_FILL: return PatternArgs(DOPS_ON_DURATION, 5, 50); + case PATTERN_BOUNCE: return PatternArgs(10, 5, 50, 10); case PATTERN_SPLITSTROBIE: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 0, 16, 3, 10, PATTERN_DOPS, PATTERN_STROBIE); case PATTERN_BACKSTROBE: return PatternArgs(DOPS_ON_DURATION, DOPS_OFF_DURATION, 0, HYPERSTROBE_ON_DURATION, HYPERSTROBE_OFF_DURATION, 10, PATTERN_DOPS, PATTERN_HYPERSTROBE); - case PATTERN_VORTEX: return PatternArgs(STROBE_ON_DURATION, STROBE_OFF_DURATION, 130); + case PATTERN_VORTEX: return PatternArgs(1, 1, 130); case PATTERN_NONE: break; default: break; #else