Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.6 KiB

  1. #if GARLAND_SUPPORT
  2. #include <vector>
  3. #include "../anim.h"
  4. #include "../color.h"
  5. #include "../palette.h"
  6. //------------------------------------------------------------------------------
  7. class AnimFountain : public Anim {
  8. public:
  9. AnimFountain() : Anim("Fountain") {
  10. cycleFactor = 4;
  11. }
  12. void SetupImpl() override {
  13. fountains.clear();
  14. for (int i = 0; i < 3; ++i)
  15. fountains.emplace_back(palette, numLeds);
  16. }
  17. void Run() override {
  18. for (int i = 0; i < numLeds; ++i) {
  19. leds[i] = 0;
  20. seq[i] = 0;
  21. }
  22. // Run fountains animation. Fill seq (occupied space)
  23. for (auto& d : fountains)
  24. d.Run(leds, seq);
  25. // Try to recreate finished fountains
  26. for (auto& d : fountains) {
  27. if (d.done) {
  28. for (int i = 1; i < 5; ++i) {
  29. Fountain new_fountain(palette, numLeds);
  30. if (new_fountain.HaveEnoughSpace(seq)) {
  31. std::swap(d, new_fountain);
  32. break;
  33. }
  34. }
  35. }
  36. }
  37. }
  38. private:
  39. struct Fountain {
  40. bool done = false;
  41. int len = secureRandom(5, 10);
  42. int speed = secureRandom(1, 3);
  43. int dir = 1;
  44. int head = 0;
  45. int start;
  46. // Color color;
  47. std::vector<Color> points;
  48. Fountain(Palette* pal, uint16_t numLeds) : start(secureRandom(len, numLeds - len)), /*color(pal->getRndInterpColor()),*/ points(len) {
  49. // 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);
  50. if (secureRandom(10) > 5) {
  51. start = numLeds - start;
  52. dir = -1;
  53. }
  54. // int halflen = len / 2;
  55. for (int i = 0; i < len; ++i) {
  56. points[i] = pal->getRndInterpColor();
  57. // 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);
  58. }
  59. }
  60. bool Run(Color* leds, byte* seq) {
  61. if (done)
  62. return false;
  63. int p = 0;
  64. for (int i = 0; i < len; ++i) {
  65. p = head - i;
  66. if (p >= 0 && p < len) {
  67. if (dir == 1) {
  68. leds[start + p] = points[i];
  69. leds[start - p] = points[i];
  70. } else {
  71. leds[start + len - p] = points[i];
  72. leds[start - len + p] = points[i];
  73. }
  74. }
  75. }
  76. head += speed;
  77. // if tail moved out of len then fountain is done
  78. if (p >= len) {
  79. done = true;
  80. return false;
  81. }
  82. else {
  83. // fountain occupy space for future movement
  84. int s = p < 0 ? 0 : p;
  85. for (int i = s; i < len; ++i) {
  86. seq[start + i] = 1;
  87. seq[start - i] = 1;
  88. }
  89. }
  90. return true;
  91. }
  92. // Decide that fountain have ehough space if seq of len before it is empty
  93. bool HaveEnoughSpace(byte* seq) {
  94. for (int i = 0; i < len; ++i) {
  95. if (seq[start + i] != 0 && seq[start - i] != 0) {
  96. // DEBUG_MSG_P(PSTR("[GARLAND] Fountain chaven't enouhg space to move.\n"));
  97. return false;
  98. }
  99. }
  100. return true;
  101. }
  102. };
  103. std::vector<Fountain> fountains;
  104. };
  105. #endif // GARLAND_SUPPORT