visualizer.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. Copyright 2017 Fred Sundvik
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include "visualizer.h"
  15. #include "gfx.h"
  16. #include "math.h"
  17. #include "default_animations.h"
  18. #include "led_backlight_keyframes.h"
  19. #define ONESIDESCAN 9
  20. #define BOTHSIDESCAN 16
  21. #define FULL_ON LUMA2COLOR(255)
  22. #define THREE_QUARTER LUMA2COLOR(200)
  23. #define HALF_ON LUMA2COLOR(150)
  24. #define ONE_QUARTER LUMA2COLOR(50)
  25. #define CROSSFADE_TIME 8000
  26. bool KITT_scan_one_side_left_to_right(keyframe_animation_t* animation, visualizer_state_t* state);
  27. bool KITT_scan_one_side_right_to_left(keyframe_animation_t* animation, visualizer_state_t* state);
  28. keyframe_animation_t Fade_in_all_leds = {
  29. .num_frames = 1,
  30. .loop = false,
  31. .frame_lengths = {
  32. CROSSFADE_TIME,
  33. },
  34. .frame_functions = {
  35. led_backlight_keyframe_fade_in_all,
  36. },
  37. };
  38. /*
  39. * one set left to right. then reverse to go back.
  40. * | left side | right side | |
  41. |---|---|---|---|---|---|---|:-:|---|---|---|---|---|---|-------|
  42. | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | phase |
  43. _________________________________________________________________
  44. | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
  45. | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
  46. | 2 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 |
  47. | 1 | 2 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 |
  48. | 0 | 1 | 2 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 |
  49. | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 5 |
  50. | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 6 |
  51. | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 7 |
  52. | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 8 |
  53. | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 | 0 | 0 | 9 |
  54. | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 | 0 | 10 |
  55. | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 | 11 |
  56. | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 12 |
  57. | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 13 |
  58. | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 14 |
  59. | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 15 |
  60. | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 16 |
  61. */
  62. #ifdef MASTER_IS_ON_RIGHT /*right side*/
  63. keyframe_animation_t KITT_Scanner_animation = {
  64. .num_frames = 2,
  65. .loop = true,
  66. .frame_lengths = {
  67. CROSSFADE_TIME * BOTHSIDESCAN,
  68. CROSSFADE_TIME * BOTHSIDESCAN,
  69. },
  70. .frame_functions = {
  71. KITT_scan_one_side_left_to_right,
  72. KITT_scan_one_side_right_to_left,
  73. },
  74. };
  75. bool KITT_scan_one_side_left_to_right(keyframe_animation_t* animation, visualizer_state_t* state) {
  76. (void)state;
  77. float frame_length = animation->frame_lengths[animation->current_frame];
  78. float current_pos = frame_length - animation->time_left_in_frame;
  79. int phase = current_pos/(frame_length/BOTHSIDESCAN);
  80. int row = 0;
  81. gdispGClear(LED_DISPLAY, ONE_QUARTER);
  82. gdispGDrawPixel(LED_DISPLAY, 14-phase, row, FULL_ON);
  83. gdispGDrawPixel(LED_DISPLAY, 15-phase, row, THREE_QUARTER);
  84. gdispGDrawPixel(LED_DISPLAY, 16-phase, row, HALF_ON);
  85. gdispGDrawPixel(LED_DISPLAY, 6, row, ONE_QUARTER);
  86. return true;
  87. }
  88. bool KITT_scan_one_side_right_to_left(keyframe_animation_t* animation, visualizer_state_t* state) {
  89. (void)state;
  90. float frame_length = animation->frame_lengths[animation->current_frame];
  91. float current_pos = frame_length - animation->time_left_in_frame;
  92. int phase = current_pos/(frame_length/BOTHSIDESCAN);
  93. int row = 0;
  94. gdispGClear(LED_DISPLAY, ONE_QUARTER);
  95. gdispGDrawPixel(LED_DISPLAY, phase, row, FULL_ON);
  96. gdispGDrawPixel(LED_DISPLAY, phase-1, row, THREE_QUARTER);
  97. gdispGDrawPixel(LED_DISPLAY, phase-2, row, HALF_ON);
  98. gdispGDrawPixel(LED_DISPLAY, 6, row, ONE_QUARTER);
  99. return true;
  100. }
  101. #else /*left side*/
  102. keyframe_animation_t KITT_Scanner_animation = {
  103. .num_frames = 2,
  104. .loop = true,
  105. .frame_lengths = {
  106. CROSSFADE_TIME * BOTHSIDESCAN,
  107. CROSSFADE_TIME * BOTHSIDESCAN,
  108. },
  109. .frame_functions = {
  110. KITT_scan_one_side_left_to_right,
  111. KITT_scan_one_side_right_to_left,
  112. },
  113. };
  114. bool KITT_scan_one_side_left_to_right(keyframe_animation_t* animation, visualizer_state_t* state) {
  115. (void)state;
  116. float frame_length = animation->frame_lengths[animation->current_frame];
  117. float current_pos = frame_length - animation->time_left_in_frame;
  118. int phase = current_pos/(frame_length/BOTHSIDESCAN);
  119. int row = 0;
  120. gdispGClear(LED_DISPLAY, ONE_QUARTER);
  121. gdispGDrawPixel(LED_DISPLAY, phase, row, FULL_ON);
  122. gdispGDrawPixel(LED_DISPLAY, phase-1, row, THREE_QUARTER);
  123. gdispGDrawPixel(LED_DISPLAY, phase-2, row, HALF_ON);
  124. gdispGDrawPixel(LED_DISPLAY, 6, row, ONE_QUARTER);
  125. return true;
  126. }
  127. bool KITT_scan_one_side_right_to_left(keyframe_animation_t* animation, visualizer_state_t* state) {
  128. (void)state;
  129. float frame_length = animation->frame_lengths[animation->current_frame];
  130. float current_pos = frame_length - animation->time_left_in_frame;
  131. int phase = current_pos/(frame_length/BOTHSIDESCAN);
  132. int row = 0;
  133. gdispGClear(LED_DISPLAY, ONE_QUARTER);
  134. gdispGDrawPixel(LED_DISPLAY, (14 - phase), row, FULL_ON);
  135. gdispGDrawPixel(LED_DISPLAY, 14 - (phase-1), row, THREE_QUARTER);
  136. gdispGDrawPixel(LED_DISPLAY, 14 - (phase-2), row, HALF_ON);
  137. gdispGDrawPixel(LED_DISPLAY, 6, row, ONE_QUARTER);
  138. return true;
  139. }
  140. #endif
  141. #define RED 0
  142. #define ORANGE 21
  143. #define YELLOW 42
  144. #define SPRING_GREEN 64
  145. #define GREEN 85
  146. #define TURQUOISE 107
  147. #define CYAN 127
  148. #define OCEAN 149
  149. #define BLUE 170
  150. #define VIOLET 192
  151. #define MAGENTA 212
  152. #define RASPBERRY 234
  153. // This function should be implemented by the keymap visualizer
  154. // Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing
  155. // that the simple_visualizer assumes that you are updating
  156. // Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is
  157. // stopped. This can be done by either double buffering it or by using constant strings
  158. static void get_visualizer_layer_and_color(visualizer_state_t* state) {
  159. uint8_t saturation = 255;
  160. /* if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) {
  161. saturation = 255;
  162. } */
  163. if (state->status.layer & 0x200) {
  164. state->target_lcd_color = LCD_COLOR(GREEN, saturation, 0xFF);
  165. state->layer_text = "MOUSE";
  166. }
  167. else if (state->status.layer & 0x100) {
  168. state->target_lcd_color = LCD_COLOR(MAGENTA, saturation, 0xFF);
  169. state->layer_text = "Shortcuts Layer";
  170. }
  171. else if (state->status.layer & 0x80) {
  172. state->target_lcd_color = LCD_COLOR(VIOLET, saturation, 0xFF);
  173. state->layer_text = "Plover";
  174. start_keyframe_animation(&KITT_Scanner_animation);
  175. }
  176. else if (state->status.layer & 0x40) {
  177. state->target_lcd_color = LCD_COLOR(RASPBERRY, saturation, 0xFF);
  178. state->layer_text = "Mirrored Symbols";
  179. }
  180. else if (state->status.layer & 0x20) {
  181. state->target_lcd_color = LCD_COLOR(RED, saturation, 0xFF);
  182. state->layer_text = "Symbols";
  183. }
  184. else if (state->status.layer & 0x8) {
  185. state->target_lcd_color = LCD_COLOR(OCEAN, saturation, 0xFF);
  186. state->layer_text = "Mirrored Dvorak";
  187. }
  188. else if (state->status.layer & 0x4) {
  189. state->target_lcd_color = LCD_COLOR(BLUE, saturation, 0xFF);
  190. state->layer_text = "Dvorak";
  191. }
  192. else if (state->status.layer & 0x2) {
  193. state->target_lcd_color = LCD_COLOR(ORANGE, saturation, 0xFF);
  194. state->layer_text = "Mirrored Qwerty";
  195. }
  196. else {
  197. state->target_lcd_color = LCD_COLOR(YELLOW, saturation, 0xFF);
  198. state->layer_text = "Qwerty";
  199. stop_keyframe_animation(&KITT_Scanner_animation);
  200. start_keyframe_animation(&Fade_in_all_leds);
  201. }
  202. }