hotdox76v2.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. // Copyright 2021 JasonRen(biu)
  2. // Copyright 2022 Drashna Jael're (@Drashna Jael're)
  3. // SPDX-License-Identifier: GPL-2.0-or-later
  4. #include "hotdox76v2.h"
  5. #include <string.h>
  6. #include <transactions.h>
  7. #include "oled_font_lib/logo2.h"
  8. #include "oled_font_lib/ext_font.h"
  9. #ifdef OLED_ENABLE
  10. # define UNC (' ')
  11. typedef struct _master_to_slave_t {
  12. int cur_alp_index;
  13. char current_alp[7];
  14. } master_to_slave_t;
  15. master_to_slave_t m2s;
  16. typedef struct _slave_to_master_t {
  17. int cur_alp_index;
  18. char current_alp[7];
  19. } slave_to_master_t;
  20. slave_to_master_t s2m;
  21. oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
  22. strcpy((char *)(m2s.current_alp), "[ ]");
  23. m2s.current_alp[1] = UNC;
  24. m2s.current_alp[2] = UNC;
  25. m2s.current_alp[3] = UNC;
  26. m2s.current_alp[4] = UNC;
  27. m2s.cur_alp_index = 1;
  28. strcpy((char *)(s2m.current_alp), "[ ]");
  29. s2m.current_alp[1] = UNC;
  30. s2m.current_alp[2] = UNC;
  31. s2m.current_alp[3] = UNC;
  32. s2m.current_alp[4] = UNC;
  33. s2m.cur_alp_index = 1;
  34. if (is_keyboard_left()) {
  35. return OLED_ROTATION_180;
  36. } else {
  37. return OLED_ROTATION_0;
  38. }
  39. }
  40. void render_logo(void) {
  41. uint8_t i = 0, j = 0;
  42. for (i = 0; i < 4; ++i) {
  43. for (j = 0; j < 32; ++j) {
  44. if (is_keyboard_left()) {
  45. oled_write_raw_byte(pgm_read_byte(&logo_mouse[i * 32 + j]), i * 128 + j);
  46. } else {
  47. oled_write_raw_byte(pgm_read_byte(&logo_mouse[i * 32 + j]), i * 128 + j + 96);
  48. }
  49. }
  50. }
  51. }
  52. void render_layer_helper_fun(uint8_t start_line, const char *data, uint8_t gap_w, uint8_t l) {
  53. uint8_t j = 0, k = 0;
  54. for (j = 0; j < l; ++j) { // font index
  55. for (k = 0; k < 12; ++k) { // font byte index
  56. // base + logo_w(32) + gap_w(12) +l*font_w(12)+current_byte_index
  57. oled_write_raw_byte(pgm_read_byte(&ext_big_font[pgm_read_byte(&data[j]) - 0x20][k]), start_line * 2 * 128 + 32 + gap_w + j * 12 + k);
  58. oled_write_raw_byte(pgm_read_byte(&ext_big_font[pgm_read_byte(&data[j]) - 0x20][k + 12]), start_line * 2 * 128 + 128 + 32 + gap_w + j * 12 + k);
  59. }
  60. }
  61. for (j = 0; j < gap_w; ++j) {
  62. oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 32 + j);
  63. oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 32 + gap_w + l * 12 + j);
  64. oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 128 + 32 + j);
  65. oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 128 + 32 + gap_w + l * 12 + j);
  66. }
  67. }
  68. void render_layer(uint8_t layer) {
  69. render_layer_helper_fun(0, PSTR("LAYER:"), 12, 6);
  70. switch (layer) {
  71. case 0:
  72. render_layer_helper_fun(1, PSTR("1:HOME"), 12, 6);
  73. break;
  74. case 1:
  75. render_layer_helper_fun(1, PSTR("2:CODE"), 12, 6);
  76. break;
  77. case 2:
  78. render_layer_helper_fun(1, PSTR("3:OFFICE"), 0, 8);
  79. break;
  80. case 3:
  81. default:
  82. render_layer_helper_fun(1, PSTR("4:OTHERS"), 0, 8);
  83. break;
  84. }
  85. }
  86. void render_cur_input_helper_fun(uint8_t start_line, const char *data, uint8_t gap_w, uint8_t l) {
  87. uint8_t j = 0, k = 0;
  88. for (j = 0; j < l; ++j) { // font index
  89. for (k = 0; k < 12; ++k) { // font byte index
  90. // base + logo_w(0) + gap_w(12) +l*font_w(12)+current_byte_index
  91. oled_write_raw_byte(pgm_read_byte(&ext_big_font[data[j] - 0x20][k]), start_line * 2 * 128 + gap_w + j * 12 + k);
  92. oled_write_raw_byte(pgm_read_byte(&ext_big_font[data[j] - 0x20][12 + k]), start_line * 2 * 128 + 128 + gap_w + j * 12 + k);
  93. }
  94. }
  95. for (j = 0; j < gap_w; ++j) {
  96. oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + j);
  97. oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + gap_w + l * 12 + j);
  98. oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 128 + j);
  99. oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 128 + gap_w + l * 12 + j);
  100. }
  101. }
  102. void render_cur_input(void) {
  103. render_cur_input_helper_fun(0, "INPUTS:", 6, 7);
  104. if (is_keyboard_master()) {
  105. render_cur_input_helper_fun(1, (const char *)(m2s.current_alp), 12, 6);
  106. } else {
  107. render_cur_input_helper_fun(1, (const char *)(s2m.current_alp), 12, 6);
  108. }
  109. return;
  110. }
  111. bool oled_task_kb(void) {
  112. if (!oled_task_user()) {
  113. return false;
  114. }
  115. render_logo();
  116. if (is_keyboard_left()) {
  117. render_layer(biton32(layer_state));
  118. } else {
  119. render_cur_input();
  120. }
  121. return false;
  122. }
  123. static const char PROGMEM code_to_name[0xFF] = {
  124. // 0 1 2 3 4 5 6 7 8 9 A B c D E F
  125. UNC, UNC, UNC, UNC, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', // 0x
  126. 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', // 1x
  127. '3', '4', '5', '6', '7', '8', '9', '0', UNC, UNC, UNC, UNC, UNC, '-', '=', '[', // 2x
  128. ']', '\\', '#', ';', '\'', '`', ',', '.', '/', UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 3x
  129. UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 4x
  130. UNC, UNC, UNC, UNC, '/', '*', '-', '+', UNC, '1', '2', '3', '4', '5', '6', '7', // 5x
  131. '8', '9', '0', '.', UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 6x
  132. UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 7x
  133. UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 8x
  134. UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 9x
  135. UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Ax
  136. UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Bx
  137. UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Cx
  138. UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Dx
  139. UNC, UNC, 'A', 'W', UNC, 'S', UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Ex
  140. UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC // Fx
  141. };
  142. void get_cur_alp_hook(uint16_t keycode) {
  143. if (keycode >= 0xF0) {
  144. keycode = 0xF0;
  145. }
  146. if (m2s.cur_alp_index < 4) {
  147. m2s.current_alp[m2s.cur_alp_index] = pgm_read_byte(&code_to_name[keycode]);
  148. if (m2s.cur_alp_index == 1) {
  149. m2s.current_alp[2] = m2s.current_alp[3] = m2s.current_alp[4] = UNC;
  150. }
  151. m2s.cur_alp_index++;
  152. } else {
  153. for (uint8_t i = 2; i <= 4; ++i) {
  154. m2s.current_alp[i - 1] = m2s.current_alp[i];
  155. }
  156. m2s.current_alp[m2s.cur_alp_index] = pgm_read_byte(&code_to_name[keycode]);
  157. }
  158. }
  159. bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
  160. if (record->event.pressed) {
  161. get_cur_alp_hook(keycode);
  162. }
  163. if (!process_record_user(keycode, record)) {
  164. return false;
  165. }
  166. switch (keycode) {
  167. case TOG_OLED:
  168. if (record->event.pressed) {
  169. if (is_oled_on()) {
  170. oled_off();
  171. } else {
  172. oled_on();
  173. }
  174. }
  175. return false;
  176. default:
  177. return true;
  178. }
  179. return true;
  180. }
  181. void user_sync_alpa_slave_handler(uint8_t in_buflen, const void *in_data, uint8_t out_buflen, void *out_data) {
  182. const master_to_slave_t *m2s_p = (const master_to_slave_t *)in_data;
  183. s2m.cur_alp_index = m2s_p->cur_alp_index;
  184. for (size_t i = 0; i < 7; i++) {
  185. s2m.current_alp[i] = m2s_p->current_alp[i];
  186. }
  187. }
  188. void keyboard_post_init_kb(void) {
  189. transaction_register_rpc(KEYBOARD_CURRENT_ALPA_SYNC, user_sync_alpa_slave_handler);
  190. keyboard_post_init_user();
  191. }
  192. void housekeeping_task_kb(void) {
  193. if (is_keyboard_master()) {
  194. if (!is_oled_on()) {
  195. m2s.cur_alp_index = 1;
  196. }
  197. // Interact with slave every 200ms
  198. static uint32_t last_sync = 0;
  199. if (timer_elapsed32(last_sync) > 200) {
  200. if (transaction_rpc_exec(KEYBOARD_CURRENT_ALPA_SYNC, sizeof(m2s), &m2s, sizeof(s2m), &s2m)) {
  201. last_sync = timer_read32();
  202. dprint("Slave sync successed!\n");
  203. } else {
  204. dprint("Slave sync failed!\n");
  205. }
  206. }
  207. }
  208. }
  209. #endif
  210. #ifdef SWAP_HANDS_ENABLE
  211. __attribute__((weak))
  212. const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
  213. /* Left hand, matrix positions */
  214. {{0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6}, {5, 6}, {6, 6}},
  215. {{0, 7}, {1, 7}, {2, 7}, {3, 7}, {4, 7}, {5, 7}, {6, 7}},
  216. {{0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}},
  217. {{0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 9}, {5, 9}, {6, 9}},
  218. {{0, 10}, {1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}, {6, 10}},
  219. {{0, 11}, {1, 11}, {2, 11}, {3, 11}, {4, 11}, {5, 11}, {6, 11}},
  220. /* Right hand, matrix positions */
  221. {{0, 5}, {1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}, {6, 5}},
  222. {{0, 4}, {1, 4}, {2, 4}, {3, 4}, {4, 4}, {5, 4}, {6, 4}},
  223. {{0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3}, {6, 3}},
  224. {{0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2}, {5, 2}, {6, 2}},
  225. {{0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}},
  226. {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}
  227. };
  228. #endif