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.

118 lines
3.5 KiB

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