Browse Source

graland: update anim code with clear rands and auto counters

pull/2600/head
Dmitry Blinov 5 months ago
parent
commit
548e5995f6
17 changed files with 84 additions and 76 deletions
  1. +17
    -1
      code/espurna/garland.cpp
  2. +7
    -1
      code/espurna/garland/anim.h
  3. +3
    -6
      code/espurna/garland/animations/anim_assemble.h
  4. +7
    -11
      code/espurna/garland/animations/anim_comets.h
  5. +3
    -3
      code/espurna/garland/animations/anim_crossing.h
  6. +8
    -12
      code/espurna/garland/animations/anim_dolphins.h
  7. +3
    -6
      code/espurna/garland/animations/anim_fly.h
  8. +5
    -5
      code/espurna/garland/animations/anim_fountain.h
  9. +10
    -10
      code/espurna/garland/animations/anim_glow.h
  10. +2
    -2
      code/espurna/garland/animations/anim_pixiedust.h
  11. +2
    -2
      code/espurna/garland/animations/anim_randcyc.h
  12. +3
    -3
      code/espurna/garland/animations/anim_randrun.h
  13. +5
    -5
      code/espurna/garland/animations/anim_salut.h
  14. +1
    -1
      code/espurna/garland/animations/anim_sparkr.h
  15. +4
    -4
      code/espurna/garland/animations/anim_spread.h
  16. +2
    -2
      code/espurna/garland/animations/anim_stars.h
  17. +2
    -2
      code/espurna/garland/animations/anim_start.h

+ 17
- 1
code/espurna/garland.cpp View File

@ -650,7 +650,7 @@ void Anim::glowSetUp() {
braFreq = secureRandom(20, 60);
}
void Anim::glowForEachLed(int i) {
void Anim::glowForEachLed(uint16_t i) {
int8 bra = braPhase + i * braFreq;
bra = BRA_OFFSET + (abs(bra) >> BRA_AMP_SHIFT);
leds[i] = leds[i].brightness(bra);
@ -660,6 +660,14 @@ void Anim::glowRun() {
braPhase += braPhaseSpd;
}
void Anim::flashRandomLeds(uint16_t deciPercent) {
int numLedsToFlash = numLeds * deciPercent / 1000;
for (int i = 0; i < numLedsToFlash; ++i) {
int ind = secureRandom(numLeds);
leds[ind] = sparkleColor;
}
}
unsigned int Anim::rng() {
static unsigned int y = 0;
y += micros(); // seeded with changing number
@ -675,6 +683,14 @@ byte Anim::rngb() {
return static_cast<byte>(rng());
}
bool fiftyFifty() {
return secureRandom(2) == 0;
}
int randDir() {
return secureRandom(2) == 0 ? -1 : 1;
}
} // namespace
//------------------------------------------------------------------------------


+ 7
- 1
code/espurna/garland/anim.h View File

@ -65,11 +65,14 @@ protected:
//glow animation - must be called for each LED after it's BASIC color is set
//note this overwrites the LED color, so the glow assumes that color will be stored elsewhere (not in leds[])
//or computed each time regardless previous leds[] value
void glowForEachLed(int i);
void glowForEachLed(uint16_t i);
//glow animation - must be called at the end of each animaton run
void glowRun();
//flash some random LEDs
void flashRandomLeds(uint16_t deciPercent);
//random number helpers for animations
static unsigned int rng();
static byte rngb();
@ -77,3 +80,6 @@ protected:
private:
const char* _name;
};
bool fiftyFifty();
int randDir();

+ 3
- 6
code/espurna/garland/animations/anim_assemble.h View File

@ -20,13 +20,10 @@ class AnimAssemble : public Anim {
cycleFactor = 2;
}
void SetupImpl() override {
inc = 1 + (rngb() >> 5);
if (secureRandom(10) > 5) {
inc = -inc;
}
inc = (1 + (rngb() >> 5)) * randDir();
int p = 0;
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
leds[i] = 0;
Color c = palette->getCachedPalColor((byte)p);
ledstmp[i] = c;
@ -56,7 +53,7 @@ class AnimAssemble : public Anim {
}
} else if (phase == Phases::Glow) {
if (pos < numLeds/2) {
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
leds[i] = ledstmp[i];
glowForEachLed(i);
}


+ 7
- 11
code/espurna/garland/animations/anim_comets.h View File

@ -18,14 +18,14 @@ class AnimComets : public Anim {
c = {palette, numLeds};
}
} else {
for (int i = 0; i < 4; ++i) {
for (auto i = 0; i < 4; ++i) {
comets.emplace_back(palette, numLeds);
}
}
}
void Run() override {
for (int i = 0; i < numLeds; ++i) leds[i] = 0;
for (auto i = 0; i < numLeds; ++i) leds[i] = 0;
for (auto& c : comets) {
int tail = c.head + c.len * -c.dir;
@ -34,7 +34,7 @@ class AnimComets : public Anim {
c = {palette, numLeds};
}
for (int l = 0; l < c.len; ++l) {
for (auto l = 0; l < c.len; ++l) {
int p = c.head + l * -c.dir;
if (p >= 0 && p < numLeds) {
leds[p] = c.points[l];
@ -46,21 +46,17 @@ class AnimComets : public Anim {
private:
struct Comet {
float head;
int dir = randDir();
int len = secureRandom(10, 20);
float speed = ((float)secureRandom(4, 10)) / 10;
float head;
Color color;
int dir = 1;
std::unique_ptr<Color[]> points;
Comet(Palette* pal, uint16_t numLeds) : head(secureRandom(0, numLeds / 2)), color(pal->getRndInterpColor()) {
Comet(Palette* pal, uint16_t numLeds) : head(dir ? secureRandom(0, numLeds / 2) : secureRandom(numLeds / 2, numLeds)), color(pal->getRndInterpColor()) {
// DEBUG_MSG_P(PSTR("[GARLAND] Comet created head = %d len = %d speed = %g cr = %d cg = %d cb = %d\n"), head, len, speed, color.r, color.g, color.b);
if (secureRandom(10) > 5) {
head = numLeds - head;
dir = -1;
}
points.reset(new Color[len]);
for (int i = 0; i < len; ++i) {
for (auto i = 0; i < len; ++i) {
points[i] = {
(byte)(color.r * (len - i) / len),
(byte)(color.g * (len - i) / len),


+ 3
- 3
code/espurna/garland/animations/anim_crossing.h View File

@ -32,10 +32,10 @@ class AnimCrossing : public Anim {
ColorWave generateWave(int dir) {
unsigned int waveLen = secureRandom(10, 50);
bool cleanColors = secureRandom(10) > 5;
bool startEmpty = secureRandom(10) > 5;
bool cleanColors = fiftyFifty();
bool startEmpty = fiftyFifty();
float speed = secureRandom(5, 20) / 10.0;
byte fade = secureRandom(10) > 5 ? 0 : palette->bright() ? secureRandom(180, 220) : 120;
byte fade = fiftyFifty() ? 0 : palette->bright() ? secureRandom(180, 220) : 120;
Palette* wavePal = &pals[secureRandom(palsNum)];
return ColorWave(numLeds, wavePal, waveLen, cleanColors, fade, speed, dir, startEmpty);


+ 8
- 12
code/espurna/garland/animations/anim_dolphins.h View File

@ -19,14 +19,14 @@ class AnimDolphins : public Anim {
d = {palette, numLeds};
}
} else {
for (int i = 0; i < 4; ++i) {
for (auto i = 0; i < 4; ++i) {
dolphins.emplace_back(palette, numLeds);
}
}
}
void Run() override {
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
leds[i] = 0;
seq[i] = 0;
}
@ -54,22 +54,18 @@ class AnimDolphins : public Anim {
bool done = false;
int len = secureRandom(10, 20);
int speed = secureRandom(1, 3);
int dir = 1;
int dir = randDir();
int head = 0;
int start;
Color color;
std::unique_ptr<Color[]> points;
Dolphin(Palette* pal, uint16_t numLeds) : start(secureRandom(0, numLeds - len)), color(pal->getRndInterpColor()) {
Dolphin(Palette* pal, uint16_t numLeds) : start(head ? secureRandom(0, numLeds - len) : secureRandom(len, numLeds)), color(pal->getRndInterpColor()) {
// DEBUG_MSG_P(PSTR("[GARLAND] Dolphin created start = %d len = %d dir = %d cr = %d cg = %d cb = %d\n"), start, len, dir, color.r, color.g, color.b);
if (secureRandom(10) > 5) {
start = numLeds - start;
dir = -1;
}
int halflen = len / 2;
points.reset(new Color[len]);
for (int i = 0; i < len; ++i) {
for (auto i = 0; i < len; ++i) {
int nth = (i > halflen) ? (len - i) : i;
points[i] = {
(byte)(color.r * nth / halflen),
@ -83,7 +79,7 @@ class AnimDolphins : public Anim {
return false;
int p = 0;
for (int i = 0; i < len; ++i) {
for (auto i = 0; i < len; ++i) {
p = head - i;
if (p >= 0 && p < len) {
leds[start + p * dir] = points[i];
@ -100,7 +96,7 @@ class AnimDolphins : public Anim {
else {
// dolphin occupy space for future movement
int s = p < 0 ? 0 : p;
for (int i = s; i < len; ++i) {
for (auto i = s; i < len; ++i) {
seq[start + i * dir] = 1;
}
}
@ -110,7 +106,7 @@ class AnimDolphins : public Anim {
// Decide that dolphin have ehough space if seq of len before it is empty
bool HaveEnoughSpace(byte* seq) {
for (int i = 0; i < len; ++i) {
for (auto i = 0; i < len; ++i) {
if (seq[start + i * dir] != 0) {
// DEBUG_MSG_P(PSTR("[GARLAND] Dolphin chaven't enouhg space to move.\n"));
return false;


+ 3
- 6
code/espurna/garland/animations/anim_fly.h View File

@ -14,10 +14,7 @@ class AnimFly : public Anim {
//length of particle tail
pos = secureRandom(2, 15);
//probability of the tail
inc = secureRandom(5, 15);
if (secureRandom(10) > 5) {
inc = -inc;
}
inc = secureRandom(5, 15) * randDir();
phase = 0;
}
@ -25,12 +22,12 @@ class AnimFly : public Anim {
byte launchpos;
if (inc > 0) {
launchpos = numLeds - 1;
for (int i = 1; i < numLeds; i++) {
for (auto i = 1; i < numLeds; i++) {
leds[i - 1] = leds[i];
}
} else {
launchpos = 0;
for (int i = numLeds - 2; i >= 0; i--) {
for (auto i = numLeds - 2; i >= 0; i--) {
leds[i + 1] = leds[i];
}
}


+ 5
- 5
code/espurna/garland/animations/anim_fountain.h View File

@ -15,12 +15,12 @@ class AnimFountain : public Anim {
void SetupImpl() override {
fountains.clear();
for (int i = 0; i < 3; ++i)
for (auto i = 0; i < 3; ++i)
fountains.emplace_back(palette, numLeds);
}
void Run() override {
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
leds[i] = 0;
seq[i] = 0;
}
@ -61,7 +61,7 @@ class AnimFountain : public Anim {
// DEBUG_MSG_P(PSTR("[GARLAND] Fountain created start = %d len = %d dir = %d cr = %d cg = %d cb = %d\n"), start, len, dir, color.r, color.g, color.b);
points.reset(new Color[len]);
for (int i = 0; i < len; ++i) {
for (auto i = 0; i < len; ++i) {
points[i] = {pal->getRndInterpColor()};
// DEBUG_MSG_P(PSTR("[GARLAND] Fountain i=%d cr = %d cg = %d cb = %d\n"), i, points[i].r, points[i].g, points[i].b);
}
@ -72,7 +72,7 @@ class AnimFountain : public Anim {
return false;
int p = 0;
for (int i = 0; i < len; ++i) {
for (auto i = 0; i < len; ++i) {
p = head - i;
if (p >= 0 && p < len) {
if (dir == 1) {
@ -106,7 +106,7 @@ class AnimFountain : public Anim {
// Decide that fountain have ehough space if seq of len before it is empty
bool HaveEnoughSpace(byte* seq) {
for (int i = 0; i < len; ++i) {
for (auto i = 0; i < len; ++i) {
if (seq[start + i] != 0 && seq[start - i] != 0) {
// DEBUG_MSG_P(PSTR("[GARLAND] Fountain chaven't enouhg space to move.\n"));
return false;


+ 10
- 10
code/espurna/garland/animations/anim_glow.h View File

@ -8,6 +8,7 @@ class AnimGlow : public Anim {
private:
float colorInterp;
float colorInterpSpeed;
uint16_t flashDeciPercent;
public:
AnimGlow() : Anim("Glow") {
}
@ -19,6 +20,7 @@ class AnimGlow : public Anim {
colorInterp = 0;
colorInterpSpeed = ((float)secureRandom(10, 20)) / 1000;
flashDeciPercent = fiftyFifty() ? 0 : secureRandom(5, 20);
glowSetUp();
}
@ -31,18 +33,16 @@ class AnimGlow : public Anim {
curColor = palette->getContrastColor(prevColor);
}
if (inc > 0) {
for (int i = 0; i < numLeds; ++i) {
leds[i] = actualColor;
glowForEachLed(i);
}
} else {
for (int i = numLeds - 1 ; i >= 0; --i) {
leds[i] = actualColor;
glowForEachLed(i);
}
for (auto i = 0; i < numLeds; ++i) {
auto j = inc > 0 ? i : numLeds - i - 1;
leds[j] = actualColor;
glowForEachLed(j);
}
glowRun();
if (flashDeciPercent) {
flashRandomLeds(flashDeciPercent);
}
}
};


+ 2
- 2
code/espurna/garland/animations/anim_pixiedust.h View File

@ -27,7 +27,7 @@ class AnimPixieDust : public Anim {
void Run() override {
if (inc > 0) {
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
leds[i] = (i > phase) ? prevColor : curColor;
glowForEachLed(i);
}
@ -38,7 +38,7 @@ class AnimPixieDust : public Anim {
curColor = palette->getRndInterpColor();
}
} else {
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
leds[i] = (i < phase) ? prevColor : curColor;
glowForEachLed(i);
}


+ 2
- 2
code/espurna/garland/animations/anim_randcyc.h View File

@ -10,12 +10,12 @@ class AnimRandCyc : public Anim {
}
void SetupImpl() override {
for (int i = 0; i < numLeds; ++i)
for (auto i = 0; i < numLeds; ++i)
seq[i] = rngb();
}
void Run() override {
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
leds[i] = palette->getCachedPalColor(seq[i]);
seq[i] += rngb() >> 6;
}


+ 3
- 3
code/espurna/garland/animations/anim_randrun.h View File

@ -18,9 +18,9 @@ class AnimRandRun : public Anim {
pos = 0;
speed = ((float)secureRandom(20, 90)) / 100;
DEBUG_MSG_P(PSTR("[GARLAND] speed = %d\n"), (unsigned int)(speed*100));
dir = secureRandom(10) > 5 ? -1 : 1;
dir = randDir();
for (int i = 0; i < numLeds; ++i)
for (auto i = 0; i < numLeds; ++i)
ledstmp[i] = palette->getRndInterpColor();
glowSetUp();
@ -31,7 +31,7 @@ class AnimRandRun : public Anim {
if (pos >= numLeds) pos -= numLeds;
if (pos < 0) pos += numLeds;
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
int j = i + pos;
if (j >= numLeds) j -= numLeds;
leds[i] = ledstmp[j];


+ 5
- 5
code/espurna/garland/animations/anim_salut.h View File

@ -25,7 +25,7 @@ class AnimSalut : public Anim {
}
void Run() override {
for (int i = 0; i < numLeds; ++i) leds[i] = 0;
for (auto i = 0; i < numLeds; ++i) leds[i] = 0;
for (auto& c : shots) {
if (!c.Run(leds)) {
@ -42,11 +42,11 @@ class AnimSalut : public Anim {
float speed = ((float)secureRandom(1, 25)) / 10;
float speed_dec = ((float)secureRandom(1, 3)) / 10;
float pos;
int dir;
int dir = randDir();
Color color;
uint16_t numLeds;
Spark() = default;
Spark(int pos, Palette* pal, uint16_t numLeds) : pos(pos), dir(secureRandom(10) > 5 ? -1 : 1), color(pal->getRndInterpColor()), numLeds(numLeds) {}
Spark(int pos, Palette* pal, uint16_t numLeds) : pos(pos), color(pal->getRndInterpColor()), numLeds(numLeds) {}
void Run(Color* leds) {
if (pos >= 0 && pos < numLeds) {
leds[(int)pos] = color;
@ -74,13 +74,13 @@ class AnimSalut : public Anim {
// DEBUG_MSG_P(PSTR("[GARLAND] Shot created center = %d spark_num = %d\n"), center, spark_num);
int center = secureRandom(15, numLeds - 15);
sparks.reset(new Spark[spark_num]);
for (int i = 0; i < spark_num; ++i) {
for (auto i = 0; i < spark_num; ++i) {
sparks[i] = {center, pal, numLeds};
}
}
bool Run(Color* leds) {
bool done = true;
for (int i = 0; i < spark_num; ++i) {
for (auto i = 0; i < spark_num; ++i) {
if (!sparks[i].done) {
done = false;
sparks[i].Run(leds);


+ 1
- 1
code/espurna/garland/animations/anim_sparkr.h View File

@ -21,7 +21,7 @@ class AnimSparkr : public Anim {
}
void Run() override {
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
byte pos = seq[i];
leds[pos] = (i > phase) ? prevColor
: (i == phase) ? sparkleColor


+ 4
- 4
code/espurna/garland/animations/anim_spread.h View File

@ -13,7 +13,7 @@ class AnimSpread : public Anim {
int GeneratePos() {
int pos = -1;
for (int i = 0; i < numTries; ++i) {
for (auto i = 0; i < numTries; ++i) {
pos = secureRandom(0, numLeds);
for (int j = pos - maxWidth; j < pos + maxWidth; ++j) {
if (j >= 0 && j < numLeds && seq[j] > 0) {
@ -35,15 +35,15 @@ class AnimSpread : public Anim {
fade_ind = secureRandom(1, 20);
inc = secureRandom(2, 4);
// DEBUG_MSG_P(PSTR("[GARLAND] AnimSpread inc = %d, fade_inc = %d\n"), inc, fade_ind);
for (int i = 0; i < numLeds; ++i)
for (auto i = 0; i < numLeds; ++i)
seq[i] = 0;
}
void Run() override {
for (int i = 0; i < numLeds; ++i)
for (auto i = 0; i < numLeds; ++i)
leds[i] = 0;
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
if (!ledstmp[i].empty()) {
byte width = maxWidth - seq[i];
for (int j = i - width; j <= (i + width); j++) {


+ 2
- 2
code/espurna/garland/animations/anim_stars.h View File

@ -18,12 +18,12 @@ class AnimStars : public Anim {
inc = secureRandom(2, 5);
//reset all phases
for (int i = 0; i < numLeds; ++i)
for (auto i = 0; i < numLeds; ++i)
seq[i] = 255;
}
void Run() override {
for (int i = 0; i < numLeds; i++) {
for (auto i = 0; i < numLeds; i++) {
byte phi = seq[i];
if (phi < 254) {
Color col = ledstmp[i];


+ 2
- 2
code/espurna/garland/animations/anim_start.h View File

@ -17,11 +17,11 @@ class AnimStart : public Anim {
leds[phase].r = 255;
leds[phase].g = 255;
leds[phase].b = 255;
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
leds[i].fade(50);
}
} else if (phase >= numLeds) {
for (int i = 0; i < numLeds; ++i) {
for (auto i = 0; i < numLeds; ++i) {
short r = numLeds + 255 - phase + rngb();
r = min(r, (short)255);
leds[i].r = (byte)max(r, (short)0);


Loading…
Cancel
Save