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.

110 lines
3.2 KiB

  1. /*
  2. Part of the GARLAND MODULE
  3. Copyright (C) 2020 by Dmitry Blinov <dblinov76 at gmail dot com>
  4. Inspired by https://github.com/Vasil-Pahomov/ArWs2812 (currently https://github.com/Vasil-Pahomov/Liana)
  5. */
  6. #pragma once
  7. #if GARLAND_SUPPORT
  8. #include <Arduino.h>
  9. #include <string>
  10. struct Color
  11. {
  12. byte r;
  13. byte g;
  14. byte b;
  15. inline Color() : r(0), g(0), b(0) {}
  16. // allow construction from R, G, B
  17. inline Color(uint8_t ir, uint8_t ig, uint8_t ib)
  18. : r(ir), g(ig), b(ib) {
  19. }
  20. // allow construction from 32-bit (really 24-bit) bit 0xRRGGBB color code
  21. inline Color(uint32_t colorcode)
  22. : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF) {
  23. }
  24. //interpolates between this color and provided.
  25. //x is from 0 to 1, 0 gives this color, 1 gives provided color, values between give interpolation
  26. Color interpolate(Color color, float x) const {
  27. int r0 = x * (color.r - r) + r;
  28. int g0 = x * (color.g - g) + g;
  29. int b0 = x * (color.b - b) + b;
  30. return Color(r0, g0, b0);
  31. }
  32. //creates color with decreased brightness
  33. Color brightness(byte k) const {
  34. int r0 = r * (int)k / 255;
  35. int g0 = g * (int)k / 255;
  36. int b0 = b * (int)k / 255;
  37. return Color(r0, g0, b0);
  38. }
  39. //fades (decreases all RGB channels brightness) this color by k
  40. Color& fade(byte k) {
  41. if (r>=k) { r=r-k; } else { r=0; }
  42. if (g>=k) { g=g-k; } else { g=0; }
  43. if (b>=k) { b=b-k; } else { b=0; }
  44. return *this;
  45. }
  46. //fades color separately for each channel
  47. Color& fade3(byte dr, byte dg, byte db) {
  48. if (r>=dr) { r=r-dr; } else { r=0; }
  49. if (g>=dg) { g=g-dg; } else { g=0; }
  50. if (b>=db) { b=b-db; } else { b=0; }
  51. return *this;
  52. }
  53. Color max_bright() {
  54. if (r==255 || g==255 || b==255)
  55. return Color(r, g, b);
  56. double kr = 255.0/r;
  57. double kg = 255.0/g;
  58. double kb = 255.0/b;
  59. double k1 = kr < kg ? kr : kg;
  60. double k2 = k1 < kb ? k1 : kb;
  61. int r0 = r * k2;
  62. int g0 = g * k2;
  63. int b0 = b * k2;
  64. return Color(r0, g0, b0);
  65. }
  66. //checks whether this color is visually close to given one
  67. bool isCloseTo(Color c) const {
  68. int diff = abs(r - c.r) + abs(g - c.g) + abs(b - c.b);
  69. return diff <= 220; //220 is magic number. Low values give "true" on closer colors, while higher can cause infinite loop while trying to find different color
  70. }
  71. //return value, that can be used to define how close one color to another
  72. int howCloseTo(Color c) const {
  73. return abs(r - c.r) + abs(g - c.g) + abs(b - c.b);
  74. }
  75. bool empty() const {
  76. return r == 0 && g == 0 && b == 0;
  77. }
  78. void println() const {
  79. Serial.print(("r="));Serial.print(r);Serial.print((" "));
  80. Serial.print(("g="));Serial.print(g);Serial.print( (" "));
  81. Serial.print(("b="));Serial.println(b);
  82. }
  83. String to_str() {
  84. char buf[20];
  85. sprintf(buf, "r=%hhu, g=%hhu, b=%hhu", r, g, b);
  86. return buf;
  87. }
  88. friend bool operator== (const Color &c1, const Color &c2);
  89. };
  90. #endif // GARLAND_SUPPORT