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.

811 lines
25 KiB

  1. /* Copyright 2021 customMK
  2. *
  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. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "evo70.h"
  17. #include <stdbool.h>
  18. #include "matrix.h"
  19. #include OLED_FONT_H
  20. //If Bongo cat not undefined, Scroll wheel will be enabled,
  21. //but for scroll wheel to work, you must also set MOUSEKEY_ENABLE = yes
  22. //in rules.mk
  23. #define BONGOCAT
  24. /* Placement information for display elements */
  25. #define ENC_DISPLAY_X 0
  26. #define ENC_DISPLAY_Y 0
  27. #define LAYER_DISPLAY_X 5
  28. #define LAYER_DISPLAY_Y 19
  29. #define CAPSLOCK_DISPLAY_X 80
  30. #define CAPSLOCK_DISPLAY_Y 19
  31. #define NUMLOCK_DISPLAY_X 105
  32. #define NUMLOCK_DISPLAY_Y 19
  33. /* Encoder Parameters */
  34. static bool OLED_awakened = false;
  35. static bool OLED_redraw = false;
  36. static bool startup_complete = false;
  37. static bool startup_delay = false;
  38. static bool starting_up = false;
  39. #define ENCODER_MATRIX_ROW 5
  40. #define ENCODER_MATRIX_COL 6
  41. #define ENC_SPLASH 0
  42. #define ENC_VOLUME 1
  43. #define ENC_MEDIA 2
  44. #define ENC_CUSTOM 3
  45. #define ENC_BL_BRIGHT 4
  46. #define ENC_BL_BREATH 5
  47. #define ENC_RGB_BRIGHT 6
  48. #define ENC_RGB_MODE 7
  49. #define ENC_RGB_COLOR 8
  50. #define ENC_SCROLL 9
  51. #ifdef BONGOCAT
  52. #define ENC_BONGO 9
  53. #endif //bongocat
  54. extern matrix_row_t matrix[MATRIX_ROWS];
  55. char* enc_mode_str[] = {
  56. #ifdef BONGOCAT
  57. /* Splash */ "",
  58. "Volume",
  59. "Media Control",
  60. "Custom",
  61. "Backlight Brightness",
  62. "Backlight Breathing",
  63. "Underglow Brightness",
  64. "Underglow Mode",
  65. "Underglow Color",
  66. "" // Bongo Cat
  67. };
  68. uint16_t enc_cw[] = { KC_VOLU, KC_VOLU, KC_MEDIA_NEXT_TRACK, KC_VOLU, 0, 0, 0, 0, 0, KC_VOLU };
  69. uint16_t enc_ccw[] = { KC_VOLD, KC_VOLD, KC_MEDIA_PREV_TRACK, KC_VOLD, 0, 0, 0, 0, 0, KC_VOLD };
  70. #else
  71. /* Splash */ "",
  72. "Volume",
  73. "Media Control",
  74. "Custom",
  75. "Backlight Brightness",
  76. "Backlight Breathing",
  77. "Underglow Brightness",
  78. "Underglow Mode",
  79. "Underglow Color",
  80. "Scroll Wheel"
  81. };
  82. uint16_t enc_cw[] = { KC_VOLU, KC_VOLU, KC_MEDIA_NEXT_TRACK, KC_VOLU, 0, 0, 0, 0, 0, KC_WH_U };
  83. uint16_t enc_ccw[] = { KC_VOLD, KC_VOLD, KC_MEDIA_PREV_TRACK, KC_VOLD, 0, 0, 0, 0, 0, KC_WH_D };
  84. #endif //bongocat
  85. uint8_t num_enc_modes = 10;
  86. uint8_t enc_mode_str_startpos[] = {0, 49, 28, 49, 7, 10, 7, 25, 22, 31};
  87. uint8_t prev_layer = 255;
  88. uint8_t prev_capslock = 255;
  89. uint8_t prev_numlock = 255;
  90. typedef union {
  91. uint32_t raw;
  92. struct {
  93. uint8_t enc_mode;
  94. uint8_t breathingperiod;
  95. bool oled_is_on : 1;
  96. };
  97. } user_config_t;
  98. user_config_t user_config;
  99. /* OLED Draw Functions */
  100. /* TODO: Reimplement using Quantum Painter when available */
  101. static void draw_line_h(uint8_t x, uint8_t y, uint8_t len, bool on) {
  102. for (uint8_t i = 0; i < len; i++) {
  103. oled_write_pixel(i + x, y, on);
  104. }
  105. }
  106. static void draw_line_v(uint8_t x, uint8_t y, uint8_t len, bool on) {
  107. for (uint8_t i = 0; i < len; i++) {
  108. oled_write_pixel(x, i + y, on);
  109. }
  110. }
  111. void draw_rect_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, bool on) {
  112. uint8_t tempHeight;
  113. draw_line_h(x + 1, y, width - 2, on);
  114. draw_line_h(x + 1, y + height - 1, width - 2, on);
  115. tempHeight = height - 2;
  116. if (tempHeight < 1) return;
  117. draw_line_v(x, y + 1, tempHeight, on);
  118. draw_line_v(x + width - 1, y + 1, tempHeight, on);
  119. }
  120. void write_char_at_pixel_xy(uint8_t x, uint8_t y, const char data, bool invert) {
  121. uint8_t i, j, temp;
  122. uint8_t cast_data = (uint8_t)data;
  123. const uint8_t *glyph = &font[((uint8_t)cast_data - OLED_FONT_START) * OLED_FONT_WIDTH];
  124. temp = pgm_read_byte(glyph);
  125. for (i = 0; i < OLED_FONT_WIDTH ; i++) {
  126. for (j = 0; j < OLED_FONT_HEIGHT; j++) {
  127. if (temp & 0x01) {
  128. oled_write_pixel(x + i, y + j, !invert);
  129. } else {
  130. oled_write_pixel(x + i, y + j, invert);
  131. }
  132. temp >>= 1;
  133. }
  134. temp = pgm_read_byte(++glyph);
  135. }
  136. }
  137. void write_chars_at_pixel_xy(uint8_t x, uint8_t y, const char *data, bool invert) {
  138. uint8_t c = data[0];
  139. uint8_t offset = 0;
  140. while (c != 0) {
  141. write_char_at_pixel_xy(x + offset, y, c, invert);
  142. data++;
  143. c = data[0];
  144. offset += 6;
  145. }
  146. }
  147. void draw_rect_filled_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, bool on) {
  148. for (int i = x; i < x + width; i++) {
  149. if (i == x || i == (x + width - 1))
  150. draw_line_v(i, y + 1, height - 2, on);
  151. else
  152. draw_line_v(i, y, height, on);
  153. }
  154. }
  155. void draw_text_rectangle(uint8_t x, uint8_t y, uint8_t width, char* str, bool filled) {
  156. if (filled) {
  157. draw_rect_filled_soft(x, y, width, 11, true);
  158. write_chars_at_pixel_xy(x+3, y+2, str, true);
  159. } else {
  160. draw_rect_soft(x, y, width, 11, true);
  161. write_chars_at_pixel_xy(x+3, y+2, str, false);
  162. }
  163. }
  164. void draw_keyboard_layer(void){
  165. uint8_t highest_layer;
  166. highest_layer = get_highest_layer(layer_state);
  167. draw_rect_filled_soft(LAYER_DISPLAY_X + highest_layer*12, LAYER_DISPLAY_Y, 11, 11, true);
  168. write_char_at_pixel_xy(LAYER_DISPLAY_X+3, LAYER_DISPLAY_Y+2, '0', highest_layer == 0);
  169. write_char_at_pixel_xy(LAYER_DISPLAY_X+3+12, LAYER_DISPLAY_Y+2, '1', highest_layer == 1);
  170. write_char_at_pixel_xy(LAYER_DISPLAY_X+3+24, LAYER_DISPLAY_Y+2, '2', highest_layer == 2);
  171. write_char_at_pixel_xy(LAYER_DISPLAY_X+3+36, LAYER_DISPLAY_Y+2, '3', highest_layer == 3);
  172. draw_line_h(0, 14, 128, true);
  173. }
  174. static const uint8_t splash[] PROGMEM = {
  175. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  176. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  177. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00,
  178. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  179. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1c, 0x06, 0x02, 0x02,
  180. 0x03, 0x03, 0x83, 0x83, 0x83, 0x83, 0x03, 0x03, 0x03, 0x03, 0x83, 0x83, 0x83, 0x83, 0x83, 0x03,
  181. 0x03, 0x03, 0x83, 0x83, 0x83, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x83, 0x83, 0x83, 0x83, 0x03,
  182. 0x02, 0x02, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  183. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  184. 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
  185. 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0xf8, 0xfe, 0x87, 0xe1, 0xbf, 0x9f, 0x00, 0x00,
  186. 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00,
  187. 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
  188. 0x00, 0x00, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xe0, 0xc0, 0xf8, 0x7f, 0x0f, 0xff, 0xff, 0x00, 0x00,
  189. 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0xc0, 0xf0, 0xf8, 0x3c, 0x1f, 0x0f, 0x03, 0x01, 0x00, 0x00,
  190. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  191. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xc7, 0x83,
  192. 0x83, 0x8f, 0xc6, 0xc0, 0xfe, 0xff, 0xc7, 0xc0, 0xf0, 0xff, 0xff, 0x81, 0xc0, 0xe0, 0x70, 0x9e,
  193. 0x8f, 0xbf, 0xf8, 0xf0, 0x80, 0xc1, 0xe3, 0x7f, 0xff, 0xff, 0x83, 0x83, 0x83, 0xc1, 0xfc, 0xfe,
  194. 0xff, 0x83, 0x83, 0xdf, 0xff, 0x7e, 0x18, 0x18, 0xfe, 0xff, 0xfb, 0x1c, 0x06, 0xff, 0xff, 0xff,
  195. 0x3c, 0x0e, 0xe7, 0xff, 0xff, 0x80, 0xc0, 0xe0, 0x60, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
  196. 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0x0f, 0x0f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
  197. 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0x03, 0x03, 0x0f, 0x3f, 0x7c, 0xf8, 0xe0, 0x80, 0x00, 0x00,
  198. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  199. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
  200. 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01,
  201. 0x03, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01,
  202. 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
  203. 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x38, 0x20, 0x40, 0x40,
  204. 0x40, 0x40, 0x43, 0x43, 0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x43, 0x40, 0x40,
  205. 0x40, 0x40, 0x43, 0x43, 0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x43, 0x43, 0x43, 0x40,
  206. 0x40, 0x40, 0x60, 0x30, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  207. uint16_t startup_timer = 0;
  208. bool redrawn_splash = false;
  209. #ifdef BONGOCAT
  210. #define ANIM_FRAME_DURATION 75
  211. #define IDLE_FRAMES 5
  212. #define IDLE_TIMEOUT 750
  213. #define SLEEP_TIMEOUT 15000
  214. static const uint8_t bongofont[] PROGMEM = {
  215. 0xC1, 0xC1, 0xC2, 0x04, 0x08, 0x10,
  216. 0xC0, 0x38, 0x04, 0x03, 0x00, 0x00,
  217. 0xA0, 0x22, 0x24, 0x14, 0x12, 0x12,
  218. 0xA0, 0x21, 0x22, 0x12, 0x11, 0x11,
  219. 0x83, 0x7C, 0x41, 0x41, 0x40, 0x40,
  220. 0x82, 0x82, 0x84, 0x08, 0x10, 0x20,
  221. 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
  222. 0x80, 0x70, 0x19, 0x06, 0x00, 0x00,
  223. 0x80, 0x70, 0x0C, 0x03, 0x00, 0x00,
  224. 0x80, 0x00, 0x30, 0x30, 0x00, 0xC0,
  225. 0x80, 0x00, 0x30, 0x30, 0x00, 0x00,
  226. 0x49, 0x88, 0x08, 0x08, 0x08, 0x00,
  227. 0x44, 0x84, 0x04, 0x04, 0x00, 0x00,
  228. 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
  229. 0x40, 0x40, 0x20, 0x20, 0x20, 0x20,
  230. 0x3C, 0xC2, 0x01, 0x01, 0x02, 0x02,
  231. 0x35, 0x01, 0x8A, 0x7C, 0x00, 0x00,
  232. 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
  233. 0x20, 0x21, 0x22, 0x12, 0x11, 0x11,
  234. 0x20, 0x20, 0x10, 0x10, 0x10, 0x10,
  235. 0x1E, 0xE1, 0x00, 0x00, 0x01, 0x01,
  236. 0x1C, 0xE2, 0x01, 0x01, 0x02, 0x02,
  237. 0x18, 0x64, 0x82, 0x02, 0x02, 0x02,
  238. 0x18, 0x60, 0x80, 0x00, 0x00, 0x00,
  239. 0x18, 0x18, 0x1B, 0x03, 0x00, 0x40,
  240. 0x18, 0x06, 0x05, 0x98, 0x99, 0x84,
  241. 0x12, 0x0B, 0x08, 0x08, 0x08, 0x08,
  242. 0x11, 0x09, 0x08, 0x08, 0x08, 0x08,
  243. 0x10, 0x10, 0xD0, 0x11, 0x0F, 0x21,
  244. 0x10, 0x10, 0x10, 0x11, 0x0F, 0x01,
  245. 0x10, 0x08, 0x08, 0x04, 0x04, 0x04,
  246. 0x10, 0x08, 0x04, 0x02, 0x02, 0x04,
  247. 0x0C, 0x30, 0x40, 0x80, 0x00, 0x00,
  248. 0x0C, 0x0C, 0x0D, 0x01, 0x00, 0x40,
  249. 0x08, 0xE8, 0x08, 0x07, 0x10, 0x24,
  250. 0x08, 0x30, 0x40, 0x80, 0x00, 0x00,
  251. 0x08, 0x08, 0x08, 0x07, 0x00, 0x00,
  252. 0x08, 0x08, 0x04, 0x02, 0x02, 0x02,
  253. 0x08, 0x04, 0x02, 0x01, 0x01, 0x02,
  254. 0x05, 0x05, 0x09, 0x09, 0x10, 0x10,
  255. 0x04, 0x38, 0x40, 0x80, 0x00, 0x00,
  256. 0x04, 0x04, 0x08, 0x08, 0x10, 0x10,
  257. 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  258. 0x04, 0x04, 0x02, 0x01, 0x00, 0x00,
  259. 0x02, 0x02, 0x81, 0x80, 0x80, 0x00,
  260. 0x02, 0x02, 0x04, 0x04, 0x08, 0x08,
  261. 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
  262. 0x02, 0x02, 0x01, 0x00, 0x00, 0x00,
  263. 0x01, 0xE1, 0x1A, 0x06, 0x09, 0x31,
  264. 0x01, 0x01, 0x02, 0x04, 0x08, 0x10,
  265. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  266. 0x00, 0x80, 0x80, 0x00, 0x00, 0x00,
  267. 0x00, 0x80, 0x40, 0x40, 0x20, 0x20,
  268. 0x00, 0x00, 0x80, 0x80, 0x40, 0x40,
  269. 0x00, 0x00, 0x60, 0x60, 0x00, 0x81,
  270. 0x00, 0x00, 0x01, 0x01, 0x00, 0x40,
  271. 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
  272. 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
  273. 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
  274. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  275. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  276. static const uint8_t bongo_line_x[] = {51, 49, 48, 57};
  277. static const uint8_t bongo_line_y[] = {0, 8, 16, 24};
  278. static const uint8_t bongo_line_len[] = {5, 7, 8, 6};
  279. const uint8_t bongo_line_data[8][26] PROGMEM = {
  280. { //idle1
  281. 60, 52, 19, 30, 35,
  282. 22, 47, 51, 60, 9, 0, 17,
  283. 1, 57, 33, 3, 27, 41, 29, 50,
  284. 45, 36, 60, 60, 60, 60},
  285. { //idle2
  286. 60, 52, 19, 30, 35,
  287. 22, 47, 51, 60, 9, 0, 17,
  288. 1, 57, 33, 3, 27, 41, 29, 50,
  289. 45, 36, 60, 60, 60, 60},
  290. { //idle3
  291. 60, 53, 14, 31, 23,
  292. 15, 43, 60, 60, 54, 5, 13,
  293. 7, 56, 24, 2, 26, 39, 29, 50,
  294. 45, 36, 60, 60, 60, 60},
  295. { //idle4
  296. 6, 52, 19, 38, 32,
  297. 20, 47, 51, 60, 9, 0, 17,
  298. 8, 57, 33, 3, 27, 41, 29, 50,
  299. 45, 36, 60, 60, 60, 60},
  300. { //idle5
  301. 60, 52, 19, 37, 40,
  302. 21, 47, 51, 60, 9, 0, 17,
  303. 8, 57, 33, 3, 27, 41, 29, 50,
  304. 45, 36, 60, 60, 60, 60},
  305. { //prep
  306. 6, 52, 19, 38, 32,
  307. 20, 44, 51, 60, 10, 48, 16,
  308. 8, 25, 4, 18, 27, 42, 46, 50,
  309. 60, 60, 60, 60, 60, 60},
  310. { //tap1
  311. 6, 52, 19, 38, 32,
  312. 20, 44, 51, 60, 10, 49, 17,
  313. 8, 25, 4, 18, 27, 41, 28, 11,
  314. 60, 60, 60, 60, 58, 59},
  315. { //tap2
  316. 6, 52, 19, 38, 32,
  317. 20, 47, 51, 60, 10, 48, 16,
  318. 8, 60, 55, 3, 27, 42, 46, 50,
  319. 45, 34, 12, 60, 60, 60}
  320. };
  321. enum anin_states { sleep, idle, prep, tap };
  322. uint8_t anim_state = idle;
  323. uint32_t idle_timeout_timer = 0;
  324. uint32_t anim_timer = 0;
  325. uint8_t current_idle_frame = 0;
  326. uint8_t current_tap_frame = 6;
  327. uint8_t last_bongo_frame = 12;
  328. void write_bongochar_at_pixel_xy(uint8_t x, uint8_t y, uint8_t data, bool invert) {
  329. uint8_t i, j, temp;
  330. for (i = 0; i < 6 ; i++) { // 6 = font width
  331. temp = pgm_read_byte(&bongofont[data * 6]+i);
  332. for (j = 0; j < 8; j++) { // 8 = font height
  333. if (temp & 0x01) {
  334. oled_write_pixel(x + i, y + j, !invert);
  335. } else {
  336. oled_write_pixel(x + i, y + j, invert);
  337. }
  338. temp >>= 1;
  339. }
  340. }
  341. }
  342. bool is_key_down(void) {
  343. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  344. if (matrix[i] > 0) {
  345. return true;
  346. }
  347. }
  348. return false;
  349. }
  350. void eval_anim_state(void) {
  351. bool key_down;
  352. key_down = is_key_down();
  353. switch (anim_state) {
  354. case sleep:
  355. if(key_down) { anim_state = tap; }
  356. break;
  357. case idle:
  358. if(key_down) { anim_state = tap; }
  359. else if (timer_elapsed32(idle_timeout_timer) >= SLEEP_TIMEOUT) //prep to idle
  360. {
  361. anim_state = sleep;
  362. current_idle_frame = 0;
  363. }
  364. break;
  365. case prep:
  366. if(key_down) { anim_state = tap; }
  367. else if (timer_elapsed32(idle_timeout_timer) >= IDLE_TIMEOUT) //prep to idle
  368. {
  369. anim_state = idle;
  370. current_idle_frame = 0;
  371. }
  372. break;
  373. case tap:
  374. if (!key_down)
  375. {
  376. anim_state = prep;
  377. idle_timeout_timer = timer_read32();
  378. }
  379. break;
  380. default:
  381. break;
  382. }
  383. }
  384. void draw_bongo_table(void) {
  385. //draws the table edge for bongocat, this edge doesn't change during the animation
  386. uint8_t i;
  387. uint8_t y = 31;
  388. uint8_t j = 0;
  389. for (i = 17; i < 57; i++) {
  390. oled_write_pixel(i, y, true); //every five horizontal pixels, move up one pixel to make a diagonal line
  391. if (j == 4) {
  392. --y;
  393. j=0;
  394. } else {
  395. j++;
  396. }
  397. }
  398. y=15;
  399. j=0;
  400. for (i = 91; i < 128; i++) {
  401. oled_write_pixel(i, y, true); //every four horizontal pixels, move up one pixel to make a diagonal line
  402. if (j == 3) {
  403. --y;
  404. j=0;
  405. } else {
  406. j++;
  407. }
  408. }
  409. }
  410. void draw_bongocat_frame(int framenumber) {
  411. //only redraw if the animation frame has changed
  412. if (framenumber != last_bongo_frame) {
  413. last_bongo_frame = framenumber;
  414. uint8_t i, j, current_bongochar = 0;
  415. for (i = 0; i < 4; i++) {
  416. for (j = 0; j < bongo_line_len[i]; j++) {
  417. write_bongochar_at_pixel_xy(bongo_line_x[i] + j*6, bongo_line_y[i], pgm_read_byte(&bongo_line_data[framenumber][current_bongochar]), false);
  418. current_bongochar++;
  419. }
  420. }
  421. }
  422. }
  423. bool is_new_tap(void) {
  424. static matrix_row_t old_matrix[] = { 0, 0, 0, 0, 0, 0 };
  425. bool new_tap = false;
  426. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  427. if (matrix[i] > old_matrix[i]) { // more 1's detected, there was a new tap
  428. new_tap = true;
  429. }
  430. old_matrix[i] = matrix[i];
  431. }
  432. return new_tap;
  433. }
  434. void draw_bongocat(void) {
  435. static bool already_tapped = false;
  436. if (is_new_tap()) {
  437. already_tapped = false;
  438. };
  439. eval_anim_state();
  440. switch (anim_state) {
  441. case sleep:
  442. draw_bongocat_frame(4);
  443. break;
  444. case idle:
  445. draw_bongocat_frame(4 - current_idle_frame);
  446. if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) {
  447. current_idle_frame = (current_idle_frame + 1) % 5;
  448. anim_timer = timer_read32();
  449. }
  450. break;
  451. case prep:
  452. draw_bongocat_frame(5);
  453. already_tapped = false;
  454. break;
  455. case tap:
  456. draw_bongocat_frame(current_tap_frame);
  457. if (already_tapped == false) {
  458. if (current_tap_frame == 6) {
  459. current_tap_frame = 7;
  460. }
  461. else {
  462. current_tap_frame = 6;
  463. }
  464. }
  465. already_tapped = true;
  466. break;
  467. default:
  468. draw_bongocat_frame(4);
  469. already_tapped = false;
  470. break;
  471. }
  472. }
  473. #endif //BONGOCAT
  474. void draw_splash(void) {
  475. uint8_t i, j, k, temp;
  476. uint16_t count;
  477. count = 0;
  478. temp = pgm_read_byte(&splash[count]);
  479. for (i = 0; i < 4 ; i++) {
  480. for (j = 0; j < 128; j++) {
  481. for (k = 0; k < 8; k++) {
  482. if (temp & 0x01) {
  483. oled_write_pixel(j, (i * 8) + k, true);
  484. } else {
  485. oled_write_pixel(j, (i * 8) + k, false);
  486. }
  487. temp >>= 1;
  488. }
  489. temp = pgm_read_byte(&splash[++count]);
  490. }
  491. }
  492. }
  493. void draw_media_arrow(uint8_t x, uint8_t y, bool fwd) {
  494. draw_line_v(x, y, 7, true);
  495. draw_line_v(x+4, y, 7, true);
  496. draw_line_v(x+2, y+2, 3, true);
  497. if (fwd) {
  498. draw_line_v(x+1, y+1, 5, true);
  499. oled_write_pixel(x+3, y+3, true);
  500. } else {
  501. draw_line_v(x+3, y+1, 5, true);
  502. oled_write_pixel(x+1, y+3, true);
  503. }
  504. }
  505. void draw_enc_mode(void){
  506. write_chars_at_pixel_xy(enc_mode_str_startpos[user_config.enc_mode], ENC_DISPLAY_Y + 2, enc_mode_str[user_config.enc_mode], false);
  507. if (user_config.enc_mode == ENC_MEDIA) {
  508. draw_media_arrow(enc_mode_str_startpos[user_config.enc_mode] - 16, ENC_DISPLAY_Y + 2, false);
  509. draw_media_arrow(enc_mode_str_startpos[user_config.enc_mode] + 88, ENC_DISPLAY_Y + 2, true);
  510. }
  511. }
  512. void draw_keyboard_locks(void) {
  513. led_t led_state = host_keyboard_led_state();
  514. draw_text_rectangle(CAPSLOCK_DISPLAY_X, CAPSLOCK_DISPLAY_Y, 5 + (3 * 6), "CAP", led_state.caps_lock);
  515. draw_text_rectangle(NUMLOCK_DISPLAY_X, NUMLOCK_DISPLAY_Y, 5 + (3 * 6), "NUM", led_state.num_lock);
  516. }
  517. /* Encoder handling functions */
  518. __attribute__((weak)) void set_custom_encoder_mode_user(bool custom_encoder_mode) {}
  519. void update_custom_encoder_mode_user(void) {
  520. #ifdef BONGOCAT
  521. set_custom_encoder_mode_user((user_config.enc_mode == ENC_CUSTOM) || (user_config.enc_mode == ENC_SPLASH) || (user_config.enc_mode == ENC_BONGO));
  522. #else
  523. set_custom_encoder_mode_user((user_config.enc_mode == ENC_CUSTOM) || (user_config.enc_mode == ENC_SPLASH));
  524. #endif
  525. }
  526. void update_kb_eeprom(void) {
  527. eeconfig_update_kb(user_config.raw);
  528. }
  529. void update_breathing(void);
  530. void matrix_init_kb(void) {
  531. user_config.raw = eeconfig_read_kb();
  532. if (user_config.enc_mode == 0xFF) { //EEPROM was cleared
  533. user_config.enc_mode = 0;
  534. user_config.oled_is_on = true;
  535. user_config.breathingperiod = 1;
  536. update_kb_eeprom();
  537. }
  538. startup_delay = true;
  539. update_custom_encoder_mode_user();
  540. matrix_init_user();
  541. }
  542. void handle_encoder_switch_process_record(keyrecord_t *record) {
  543. static uint32_t encoder_press_timer = 0;
  544. if (record->event.pressed) {
  545. if (!user_config.oled_is_on) {
  546. oled_on();
  547. user_config.oled_is_on = true;
  548. OLED_awakened = true;
  549. OLED_redraw = true;
  550. update_kb_eeprom();
  551. }
  552. encoder_press_timer = timer_read32();
  553. } else {
  554. if (OLED_awakened == true) {
  555. OLED_awakened = false;
  556. } else {
  557. if (timer_elapsed32(encoder_press_timer) < 300) {
  558. if (get_mods() & MOD_MASK_SHIFT) {
  559. user_config.enc_mode = (user_config.enc_mode + (num_enc_modes- 1)) % num_enc_modes;
  560. } else {
  561. user_config.enc_mode = (user_config.enc_mode + 1) % num_enc_modes;
  562. }
  563. OLED_redraw = true;
  564. update_custom_encoder_mode_user();
  565. update_kb_eeprom();
  566. } else {
  567. OLED_redraw = false;
  568. oled_clear();
  569. user_config.oled_is_on = false;
  570. update_kb_eeprom();
  571. }
  572. }
  573. }
  574. }
  575. bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
  576. if (record->event.key.row == ENCODER_MATRIX_ROW && record->event.key.col == ENCODER_MATRIX_COL){
  577. handle_encoder_switch_process_record(record);
  578. }
  579. return process_record_user(keycode, record);
  580. }
  581. void update_breathing(void) {
  582. if (user_config.breathingperiod == 1) {
  583. breathing_disable();
  584. }
  585. else {
  586. breathing_period_set(user_config.breathingperiod);
  587. breathing_enable();
  588. }
  589. update_kb_eeprom();
  590. }
  591. void backlight_breath_change(bool increase) { //increase period or decrease period
  592. if ((increase) && (user_config.breathingperiod < 15)) {
  593. user_config.breathingperiod++;
  594. update_breathing();
  595. }
  596. if (!increase) {
  597. if (user_config.breathingperiod > 2) {
  598. user_config.breathingperiod--;
  599. update_breathing();
  600. }
  601. else {
  602. user_config.breathingperiod = 1;
  603. update_breathing();
  604. }
  605. }
  606. }
  607. bool encoder_update_kb(uint8_t index, bool clockwise) {
  608. if (!encoder_update_user(index, clockwise)) return false;
  609. switch (user_config.enc_mode) {
  610. case ENC_RGB_MODE :
  611. if (clockwise) {
  612. rgblight_step();
  613. } else {
  614. rgblight_step_reverse();
  615. }
  616. break;
  617. case ENC_RGB_BRIGHT :
  618. if (clockwise) {
  619. rgblight_increase_val();
  620. } else {
  621. rgblight_decrease_val();
  622. }
  623. break;
  624. case ENC_BL_BRIGHT :
  625. if (clockwise) {
  626. backlight_increase();
  627. } else {
  628. backlight_decrease();
  629. }
  630. break;
  631. case ENC_BL_BREATH :
  632. backlight_breath_change(clockwise);
  633. break;
  634. case ENC_RGB_COLOR :
  635. if (clockwise) {
  636. rgblight_increase_hue();
  637. } else {
  638. rgblight_decrease_hue();
  639. }
  640. break;
  641. default:
  642. if (clockwise) {
  643. tap_code(enc_cw[user_config.enc_mode]);
  644. } else {
  645. tap_code(enc_ccw[user_config.enc_mode]);
  646. }
  647. }
  648. return true;
  649. }
  650. void matrix_scan_kb(void) {
  651. matrix_scan_user();
  652. led_t current_led_state = host_keyboard_led_state();
  653. uint8_t current_layer = get_highest_layer(layer_state);
  654. if (startup_delay) {
  655. startup_timer = timer_read();
  656. startup_delay = false;
  657. startup_complete = false;
  658. starting_up = true;
  659. OLED_redraw = false;
  660. }
  661. else if (starting_up) {
  662. if (timer_elapsed(startup_timer) >= 200) {
  663. update_breathing();
  664. startup_complete = true;
  665. starting_up = false;
  666. if (user_config.oled_is_on) {
  667. oled_on();
  668. OLED_redraw = true;
  669. } else
  670. {
  671. oled_clear();
  672. user_config.oled_is_on = false;
  673. }
  674. }
  675. }
  676. if (startup_complete) {
  677. if (user_config.enc_mode == ENC_SPLASH) {
  678. if (user_config.oled_is_on && OLED_redraw) {
  679. draw_splash();
  680. }
  681. }
  682. #ifdef BONGOCAT
  683. else if (user_config.enc_mode == ENC_BONGO) {
  684. if (user_config.oled_is_on) {
  685. if (OLED_redraw) {
  686. oled_clear();
  687. last_bongo_frame = 12; //force a redraw
  688. draw_bongo_table();
  689. OLED_redraw = false;
  690. }
  691. draw_bongocat();
  692. }
  693. }
  694. #endif //BONGOCAT
  695. else {
  696. if (user_config.oled_is_on && (
  697. OLED_redraw
  698. || (prev_layer != current_layer)
  699. || (prev_capslock != current_led_state.caps_lock)
  700. || (prev_numlock != current_led_state.num_lock))) {
  701. prev_layer = current_layer;
  702. prev_capslock = current_led_state.caps_lock;
  703. prev_numlock = current_led_state.num_lock;
  704. oled_clear();
  705. draw_keyboard_layer();
  706. draw_keyboard_locks();
  707. draw_enc_mode();
  708. }
  709. }
  710. OLED_redraw = false;
  711. }
  712. }