- Update README.md - add garland description - Add new animation - Dolphinsmcspr-patch-1
@ -0,0 +1,118 @@ | |||||
#if GARLAND_SUPPORT | |||||
#include <vector> | |||||
#include "../anim.h" | |||||
#include "../color.h" | |||||
#include "../palette.h" | |||||
//------------------------------------------------------------------------------ | |||||
class AnimDolphins : public Anim { | |||||
public: | |||||
AnimDolphins() : Anim("Dolphins") { | |||||
cycleFactor = 3; | |||||
} | |||||
void SetupImpl() override { | |||||
dolphins.clear(); | |||||
for (int i = 0; i < 4; ++i) | |||||
dolphins.emplace_back(palette, numLeds); | |||||
} | |||||
void Run() override { | |||||
for (int i = 0; i < numLeds; ++i) { | |||||
leds[i] = 0; | |||||
seq[i] = 0; | |||||
} | |||||
// Run dolphins animation. Fill seq (accupied space) | |||||
for (auto& d : dolphins) | |||||
d.Run(leds, seq); | |||||
// Try to recreate dolphins that have been done | |||||
for (auto& d : dolphins) { | |||||
if (d.done) { | |||||
for (int i = 1; i < 5; ++i) { | |||||
Dolphin new_dolphin(palette, numLeds); | |||||
if (new_dolphin.HaveEnoughSpace(seq)) { | |||||
std::swap(d, new_dolphin); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
private: | |||||
struct Dolphin { | |||||
bool done = false; | |||||
int len = secureRandom(10, 20); | |||||
int speed = secureRandom(1, 3); | |||||
int dir = 1; | |||||
int head = 0; | |||||
int start; | |||||
Color color; | |||||
std::vector<Color> points; | |||||
Dolphin(Palette* pal, uint16_t numLeds) : start(secureRandom(0, numLeds - len)), color(pal->getRndInterpColor()), points(len) { | |||||
// 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; | |||||
for (int i = 0; i < halflen; ++i) { | |||||
points[i] = points[len-i-1] = Color((byte)(color.r * i / halflen), (byte)(color.g * i / halflen), (byte)(color.b * i / halflen)); | |||||
// DEBUG_MSG_P(PSTR("[GARLAND] Dolphin i=%d cr = %d cg = %d cb = %d\n"), i, points[i].r, points[i].g, points[i].b); | |||||
} | |||||
if (len > halflen * 2) { | |||||
points[halflen] = color; | |||||
} | |||||
} | |||||
bool Run(Color* leds, byte* seq) { | |||||
if (done) | |||||
return false; | |||||
int p = 0; | |||||
for (int i = 0; i < len; ++i) { | |||||
p = head - i; | |||||
if (p >= 0 && p < len) { | |||||
leds[start + p * dir] = points[i]; | |||||
} | |||||
} | |||||
head += speed; | |||||
// if tail moved out of len then dolphin is done | |||||
if (p >= len) { | |||||
done = true; | |||||
return false; | |||||
} | |||||
else { | |||||
// dolphin accupy space for future movement | |||||
int s = p < 0 ? 0 : p; | |||||
for (int i = s; i < len; ++i) { | |||||
seq[start + i * dir] = 1; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
// 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) { | |||||
if (seq[start + i * dir] != 0) { | |||||
// DEBUG_MSG_P(PSTR("[GARLAND] Dolphin chaven't enouhg space to move.\n")); | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
}; | |||||
std::vector<Dolphin> dolphins; | |||||
}; | |||||
#endif // GARLAND_SUPPORT |
@ -0,0 +1,92 @@ | |||||
#if GARLAND_SUPPORT | |||||
#include <vector> | |||||
#include "../anim.h" | |||||
#include "../color.h" | |||||
#include "../palette.h" | |||||
//------------------------------------------------------------------------------ | |||||
class AnimSalut : public Anim { | |||||
public: | |||||
AnimSalut() : Anim("Salut") { | |||||
} | |||||
void SetupImpl() override { | |||||
shots.clear(); | |||||
// There can be more then one shot at the moment | |||||
// but looks like one is enough | |||||
// for (int i = 0; i < 3; ++i) | |||||
shots.emplace_back(palette, numLeds); | |||||
} | |||||
void Run() override { | |||||
for (int i = 0; i < numLeds; ++i) leds[i] = 0; | |||||
for (auto& c : shots) { | |||||
if (!c.Run(leds)) { | |||||
Shot new_shot(palette, numLeds); | |||||
std::swap(c, new_shot); | |||||
} | |||||
} | |||||
} | |||||
private: | |||||
struct Shot { | |||||
private: | |||||
struct Spark { | |||||
bool done = false; | |||||
float speed = ((float)secureRandom(1, 25)) / 10; | |||||
float speed_dec = ((float)secureRandom(1, 3)) / 10; | |||||
float pos; | |||||
int dir; | |||||
Color color; | |||||
uint16_t numLeds; | |||||
Spark(int pos, Palette* pal, uint16_t numLeds) : pos(pos), dir(secureRandom(10) > 5 ? -1 : 1), color(pal->getRndInterpColor()), numLeds(numLeds) {} | |||||
void Run(Color* leds) { | |||||
if (pos >= 0 && pos < numLeds) { | |||||
leds[(int)pos] = color; | |||||
if (speed > 0) { | |||||
pos += speed * dir; | |||||
speed -= speed_dec; | |||||
} else { | |||||
color.fade(5); | |||||
if (color.empty()) { | |||||
if (secureRandom(10) > 8) | |||||
leds[(int)pos] = 0xFFFFFF; | |||||
done = true; | |||||
} | |||||
} | |||||
} else { | |||||
done = true; | |||||
} | |||||
} | |||||
}; | |||||
public: | |||||
int spark_num = secureRandom(30, 40); | |||||
int center; | |||||
std::vector<Spark> sparks; | |||||
Shot(Palette* pal, uint16_t numLeds) : center(secureRandom(15, numLeds - 15)) { | |||||
// DEBUG_MSG_P(PSTR("[GARLAND] Shot created center = %d spark_num = %d\n"), center, spark_num); | |||||
sparks.reserve(spark_num); | |||||
for (int i = 0; i < spark_num; ++i) { | |||||
sparks.emplace_back(center, pal, numLeds); | |||||
} | |||||
} | |||||
bool Run(Color* leds) { | |||||
bool done = true; | |||||
for (auto& s : sparks) { | |||||
if (!s.done) { | |||||
done = false; | |||||
s.Run(leds); | |||||
} | |||||
} | |||||
return !done; | |||||
} | |||||
}; | |||||
std::vector<Shot> shots; | |||||
}; | |||||
#endif // GARLAND_SUPPORT |