keymap.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. // Copyright 2022 Guilherme Bermêo (bermeo.dev)
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include QMK_KEYBOARD_H
  4. // Each layer gets a name for readability, which is then used in the keymap matrix below.
  5. // The underscores don't mean anything - you can have a layer called STUFF or any other name.
  6. // Layer names don't all need to be of the same length, obviously, and you can also skip them
  7. // entirely and just use numbers.
  8. enum layers {
  9. _QWERTY,
  10. _LOWER,
  11. _RAISE,
  12. _NUMP,
  13. };
  14. uint8_t mod_state;
  15. bool isBarking = false;
  16. bool isJumping = false;
  17. bool showedJump = true;
  18. bool isSneaking = false;
  19. enum custom_keycodes {
  20. QWERTY = SAFE_RANGE,
  21. LOWER,
  22. RAISE,
  23. ADJUST,
  24. CEDILHA, // ç direct key
  25. AO, // ã direct key
  26. ASPAS, // " direct key
  27. };
  28. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {[_QWERTY] = LAYOUT_split_3x6_3(
  29. //,-----------------------------------------------------. ,-----------------------------------------------------.
  30. LCTL_T(KC_F3), KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_GRAVE,
  31. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  32. LALT_T(KC_TAB), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENTER,
  33. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  34. LSFT_T(KC_LEFT), KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, RGUI_T(KC_RIGHT),
  35. //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------|
  36. LGUI_T(KC_DOWN), MO(1), KC_SPC, KC_BSPC, MO(2), RSFT_T(KC_UP)
  37. // `--------------------------' `--------------------------'
  38. ),
  39. [_LOWER] = LAYOUT_split_3x6_3(
  40. //,-----------------------------------------------------. ,-----------------------------------------------------.
  41. LCTL_T(KC_F5), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_ESCAPE,
  42. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  43. LCTL(LGUI(KC_SPC)), KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, KC_ENT, KC_LBRC, KC_RBRC, KC_BSLS, KC_QUOT, KC_COLON, KC_ENT,
  44. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  45. LALT(KC_LEFT), KC_F1, KC_F2, KC_C, KC_V, KC_BSPC, KC_MINS, KC_EQL, KC_LT, KC_GT, KC_QUESTION, LALT(KC_RIGHT),
  46. //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------|
  47. LGUI_T(KC_PAGE_DOWN), _______, KC_SPC, LALT(KC_BSPC), TG(3), RSFT_T(KC_PAGE_UP)
  48. // `--------------------------' `--------------------------'
  49. ),
  50. [_RAISE] = LAYOUT_split_3x6_3(
  51. //,-----------------------------------------------------. ,-----------------------------------------------------.
  52. LCTL_T(KC_F4), KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_TILDE,
  53. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  54. LALT_T(KC_TAB), AO, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LCBR, KC_RCBR, KC_PIPE, ASPAS, KC_COLON, KC_ENT,
  55. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  56. LALT(KC_LEFT), XXXXXXX, XXXXXXX, CEDILHA, XXXXXXX, XXXXXXX, KC_UNDS, KC_PLUS, KC_LT, KC_GT, KC_QUESTION, LALT(KC_RIGHT),
  57. //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------|
  58. LGUI_T(KC_END), TG(3), KC_SPC, KC_DEL, _______, RSFT_T(KC_HOME)
  59. // `--------------------------' `--------------------------'
  60. ),
  61. [_NUMP] = LAYOUT_split_3x6_3(
  62. //,-----------------------------------------------------. ,-----------------------------------------------------.
  63. RGB_TOG, _______, _______, _______, _______, _______, _______, KC_P7, KC_P8, KC_P9, KC_PAST, KC_PSLS,
  64. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  65. _______, RGB_HUI, RGB_SAI, RGB_VAI, RGB_SPI, _______, _______, KC_P4, KC_P5, KC_P6, KC_PMNS, KC_ENT,
  66. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  67. _______, RGB_HUD, RGB_SAD, RGB_VAD, RGB_SPD, _______, KC_PDOT, KC_P1, KC_P2, KC_P3, KC_PPLS, KC_NO,
  68. //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------|
  69. TG(3), TG(3), TG(3), KC_BSPC, TG(3), KC_P0
  70. // `--------------------------' `--------------------------'
  71. )};
  72. //Per key lights
  73. bool rgb_matrix_indicators_user(void) {
  74. #ifdef RGB_MATRIX_ENABLE
  75. switch (get_highest_layer(layer_state)) {
  76. case _QWERTY:
  77. isSneaking = false;
  78. mod_state = get_mods();
  79. for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) {
  80. if (mod_state & MOD_MASK_SHIFT) {
  81. isBarking = true;
  82. rgb_matrix_set_color(52, 255, 255, 255);
  83. rgb_matrix_set_color(i, 255, 150, 0);
  84. } else if (mod_state & MOD_MASK_GUI || mod_state & MOD_MASK_CTRL) {
  85. isBarking = true;
  86. rgb_matrix_set_color(15, 255, 0, 0);
  87. switch (i) {
  88. case 0 ... 5: // underglow left side
  89. case 9: // cmd + T white (new tab)
  90. case 11: // cmd + F white (find)
  91. case 18: // cmd + W white (close tab)
  92. case 19: // cmd + S white (save)
  93. case 21: // cmd + Z white (undo)
  94. case 22: // cmd + A white (select all)
  95. case 27 ... 32: // underglow right side
  96. case 43: // cmd + K white (comment for desktop remote)
  97. case 48: // cmd + / white (comment line)
  98. rgb_matrix_set_color(i, 255, 255, 255); // white
  99. break;
  100. case 6: // space bar off
  101. case 24 ... 26: // left column off
  102. case 33: // backspace off
  103. case 41: // shift off
  104. case 51 ... 53: // right column off
  105. rgb_matrix_set_color(i, 0, 0, 0); //off
  106. break;
  107. }
  108. if (mod_state & MOD_MASK_GUI) {
  109. rgb_matrix_set_color(12, 255, 255, 255); // white V key
  110. rgb_matrix_set_color(15, 255, 255, 255); // white C key
  111. rgb_matrix_set_color(20, 255, 255, 255); // white X key
  112. } else {
  113. }
  114. } else if (mod_state & MOD_MASK_ALT) {
  115. isBarking = true;
  116. } else {
  117. isBarking = false;
  118. rgb_matrix_set_color(14, 0, 0, 0); // command key off
  119. }
  120. }
  121. rgb_matrix_set_color(13, 23, 181, 255); // cyan layer
  122. rgb_matrix_set_color(40, 255, 33, 0); // orange layer
  123. break;
  124. case _RAISE:
  125. isSneaking = true;
  126. for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) {
  127. switch (i) {
  128. case 7: // B key off
  129. case 8: // G key off
  130. case 11: // F key off
  131. case 12: // V key off
  132. case 16: // D key off
  133. case 19 ... 21: // S, X, Z keys off
  134. case 25: // tab key off
  135. case 26: // shift key off
  136. case 52 ... 53: // right column off
  137. rgb_matrix_set_color(i, 0, 0, 0); // off
  138. break;
  139. case 15: // Ç key
  140. case 22: // Ã key
  141. case 24: // Launch (F4)
  142. case 40: // Active layer
  143. rgb_matrix_set_color(i, 255, 255, 255); // white
  144. break;
  145. case 13: // active layer
  146. rgb_matrix_set_color(i, 0, 255, 0); // green
  147. break;
  148. case 42: // , shifted key
  149. case 47 ... 49: // . / ; shifted keys
  150. rgb_matrix_set_color(i, 255, 214, 0); // yellow
  151. break;
  152. default:
  153. rgb_matrix_set_color(i, 255, 33, 0); // orange
  154. }
  155. }
  156. break;
  157. case _LOWER:
  158. isSneaking = true;
  159. for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) {
  160. switch (i) {
  161. case 7: // Delete key
  162. case 51: // ESC key
  163. rgb_matrix_set_color(i, 255, 0, 0); // red
  164. break;
  165. case 12: // V key off
  166. case 15: // C key off
  167. case 20: // X key off
  168. case 21: // Z key off
  169. case 26: // shift key off
  170. case 52 ... 53: // right column off
  171. rgb_matrix_set_color(i, 0, 0, 0); // off
  172. break;
  173. case 11: // Right arrow key
  174. case 13: // Active layer
  175. case 16: // Up arrow key
  176. case 19: // Down arrow key
  177. case 22: // Left arrow key
  178. case 24: // Print
  179. rgb_matrix_set_color(i, 255, 255, 255); // white
  180. break;
  181. case 8: // Enter key
  182. case 40: // Activate Numpad
  183. rgb_matrix_set_color(i, 0, 255, 0); // green
  184. break;
  185. case 42: // , shifted key
  186. case 47 ... 49: // . / ; shifted keys
  187. case 25: // opens emoji dialog (on macOS)
  188. rgb_matrix_set_color(i, 255, 214, 0); // yellow
  189. break;
  190. default:
  191. rgb_matrix_set_color(i, 23, 181, 255); // cyan
  192. }
  193. }
  194. break;
  195. case _NUMP:
  196. isSneaking = true;
  197. for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) {
  198. switch (i) {
  199. case 12: // RGB speed-
  200. case 15: // RGB brigthness-
  201. case 20: // RGB saturation-
  202. case 21: // RGB hue-
  203. case 49: // Numpad -
  204. case 51: // Numpad /
  205. rgb_matrix_set_color(i, 255, 0, 0); // red
  206. break;
  207. case 8 ... 10: // G T R off
  208. case 17: // E off
  209. case 18: // W off
  210. case 23: // Q off
  211. case 25: // Tab off
  212. case 26: // LShift off
  213. case 33: // Backspace off
  214. case 35: // H off
  215. case 36: // Y off
  216. case 53: // RShift off
  217. rgb_matrix_set_color(i, 0, 0, 0); // off
  218. break;
  219. case 6: // Space bar off
  220. case 13: // Return to default layer
  221. case 16: // RGB brigthness+
  222. case 24: // RGB toggle
  223. case 37 ... 47: // Numpad numbers
  224. case 52: // Enter key
  225. rgb_matrix_set_color(i, 255, 255, 255); // white
  226. break;
  227. case 11: // RGB speed+
  228. case 19: // RGB saturation+
  229. case 22: // RGB hue+
  230. case 48: // Numpad +
  231. rgb_matrix_set_color(i, 0, 255, 0); // green
  232. break;
  233. case 34: // . numpad key
  234. rgb_matrix_set_color(i, 255, 214, 0); // yellow
  235. break;
  236. }
  237. rgb_matrix_set_color(13, 23, 181, 255); // Activate cyan layer
  238. rgb_matrix_set_color(40, 255, 33, 0); // Activate orange layer
  239. rgb_matrix_set_color(50, 0, 33, 255); // Numpad *
  240. rgb_matrix_set_color(14, 0, 255, 0); // Green layer active
  241. }
  242. }
  243. return false;
  244. };
  245. #endif
  246. #ifdef OLED_ENABLE
  247. oled_rotation_t oled_init_user(oled_rotation_t rotation) {
  248. return OLED_ROTATION_270;
  249. }
  250. /* KEYBOARD PET START */
  251. /* settings */
  252. # define MIN_WALK_SPEED 10
  253. # define MIN_RUN_SPEED 60
  254. /* advanced settings */
  255. # define ANIM_FRAME_DURATION 100 // how long each frame lasts in ms
  256. # define ANIM_SIZE 96 // number of bytes in array. If you change sprites, minimize for adequate firmware size. max is 1024
  257. /* timers */
  258. uint32_t anim_timer = 0;
  259. /* current frame */
  260. uint8_t current_frame = 0;
  261. /* status variables */
  262. int current_wpm = 0;
  263. // led_t led_usb_state;
  264. /* logic */
  265. static void render_luna(int LUNA_X, int LUNA_Y) {
  266. /* Sit */
  267. static const char PROGMEM sit[2][ANIM_SIZE] = {/* 'sit1', 32x22px */
  268. {
  269. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1c, 0x02, 0x05, 0x02, 0x24, 0x04, 0x04, 0x02, 0xa9, 0x1e, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x08, 0x68, 0x10, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x82, 0x7c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0c, 0x10, 0x10, 0x20, 0x20, 0x20, 0x28, 0x3e, 0x1c, 0x20, 0x20, 0x3e, 0x0f, 0x11, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  270. },
  271. /* 'sit2', 32x22px */
  272. {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1c, 0x02, 0x05, 0x02, 0x24, 0x04, 0x04, 0x02, 0xa9, 0x1e, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x90, 0x08, 0x18, 0x60, 0x10, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x82, 0x7c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0c, 0x10, 0x10, 0x20, 0x20, 0x20, 0x28, 0x3e, 0x1c, 0x20, 0x20, 0x3e, 0x0f, 0x11, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
  273. /* Walk */
  274. static const char PROGMEM walk[2][ANIM_SIZE] = {/* 'walk1', 32x22px */
  275. {
  276. 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x90, 0x90, 0x90, 0xa0, 0xc0, 0x80, 0x80, 0x80, 0x70, 0x08, 0x14, 0x08, 0x90, 0x10, 0x10, 0x08, 0xa4, 0x78, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x18, 0xea, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1c, 0x20, 0x20, 0x3c, 0x0f, 0x11, 0x1f, 0x03, 0x06, 0x18, 0x20, 0x20, 0x3c, 0x0c, 0x12, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  277. },
  278. /* 'walk2', 32x22px */
  279. {
  280. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x20, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x28, 0x10, 0x20, 0x20, 0x20, 0x10, 0x48, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x20, 0xf8, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x30, 0xd5, 0x20, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x20, 0x30, 0x0c, 0x02, 0x05, 0x09, 0x12, 0x1e, 0x02, 0x1c, 0x14, 0x08, 0x10, 0x20, 0x2c, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  281. }};
  282. /* Run */
  283. static const char PROGMEM run[2][ANIM_SIZE] = {/* 'run1', 32x22px */
  284. {
  285. 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x08, 0x08, 0xc8, 0xb0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x3c, 0x14, 0x04, 0x08, 0x90, 0x18, 0x04, 0x08, 0xb0, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0xc4, 0xa4, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc8, 0x58, 0x28, 0x2a, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x09, 0x04, 0x04, 0x04, 0x04, 0x02, 0x03, 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x08, 0x10, 0x26, 0x2b, 0x32, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
  286. },
  287. /* 'run2', 32x22px */
  288. {
  289. 0x00, 0x00, 0x00, 0xe0, 0x10, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x78, 0x28, 0x08, 0x10, 0x20, 0x30, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x08, 0x10, 0x11, 0xf9, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xb0, 0x50, 0x55, 0x20, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0c, 0x10, 0x20, 0x28, 0x37, 0x02, 0x1e, 0x20, 0x20, 0x18, 0x0c, 0x14, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  290. }};
  291. // /* Bark */
  292. static const char PROGMEM bark[2][ANIM_SIZE] = {/* 'bark1', 32x22px */
  293. {
  294. 0x00, 0xc0, 0x20, 0x10, 0xd0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x3c, 0x14, 0x04, 0x08, 0x90, 0x18, 0x04, 0x08, 0xb0, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x08, 0x10, 0x11, 0xf9, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc8, 0x48, 0x28, 0x2a, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0c, 0x10, 0x20, 0x28, 0x37, 0x02, 0x02, 0x04, 0x08, 0x10, 0x26, 0x2b, 0x32, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  295. },
  296. /* 'bark2', 32x22px */
  297. {
  298. 0x00, 0xe0, 0x10, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x2c, 0x14, 0x04, 0x08, 0x90, 0x18, 0x04, 0x08, 0xb0, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x08, 0x10, 0x11, 0xf9, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x48, 0x28, 0x2a, 0x10, 0x0f, 0x20, 0x4a, 0x09, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0c, 0x10, 0x20, 0x28, 0x37, 0x02, 0x02, 0x04, 0x08, 0x10, 0x26, 0x2b, 0x32, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  299. }};
  300. /* Sneak */
  301. static const char PROGMEM sneak[2][ANIM_SIZE] = {/* 'sneak1', 32x22px */
  302. {
  303. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x40, 0x80, 0x00, 0x80, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x21, 0xf0, 0x04, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 0x04, 0x04, 0x04, 0x03, 0x01, 0x00, 0x00, 0x09, 0x01, 0x80, 0x80, 0xab, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1c, 0x20, 0x20, 0x3c, 0x0f, 0x11, 0x1f, 0x02, 0x06, 0x18, 0x20, 0x20, 0x38, 0x08, 0x10, 0x18, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
  304. },
  305. /* 'sneak2', 32x22px */
  306. {
  307. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xa0, 0x20, 0x40, 0x80, 0xc0, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x41, 0xf0, 0x04, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 0x02, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x40, 0x55, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x20, 0x30, 0x0c, 0x02, 0x05, 0x09, 0x12, 0x1e, 0x04, 0x18, 0x10, 0x08, 0x10, 0x20, 0x28, 0x34, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  308. }};
  309. /* animation */
  310. void animate_luna(void) {
  311. /* jump */
  312. if (isJumping || !showedJump) {
  313. /* clear */
  314. oled_set_cursor(LUNA_X, LUNA_Y + 2);
  315. oled_write(" ", false);
  316. oled_set_cursor(LUNA_X, LUNA_Y - 1);
  317. showedJump = true;
  318. } else {
  319. /* clear */
  320. oled_set_cursor(LUNA_X, LUNA_Y - 1);
  321. oled_write(" ", false);
  322. oled_set_cursor(LUNA_X, LUNA_Y);
  323. }
  324. /* switch frame */
  325. current_frame = (current_frame + 1) % 2;
  326. /* draw */
  327. if (isBarking) {
  328. oled_write_raw_P(bark[current_frame], ANIM_SIZE);
  329. } else if (isSneaking) {
  330. oled_write_raw_P(sneak[current_frame], ANIM_SIZE);
  331. } else if (current_wpm <= MIN_WALK_SPEED) {
  332. oled_write_raw_P(sit[current_frame], ANIM_SIZE);
  333. } else if (current_wpm <= MIN_RUN_SPEED) {
  334. oled_write_raw_P(walk[current_frame], ANIM_SIZE);
  335. } else {
  336. oled_write_raw_P(run[current_frame], ANIM_SIZE);
  337. }
  338. }
  339. /* animation timer */
  340. if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) {
  341. anim_timer = timer_read32();
  342. animate_luna();
  343. }
  344. }
  345. void render_mod_status_gui_alt(uint8_t modifiers) {
  346. static const char PROGMEM gui_off_1[] = {0x85, 0x86, 0};
  347. static const char PROGMEM gui_off_2[] = {0xa5, 0xa6, 0};
  348. static const char PROGMEM gui_on_1[] = {0x8d, 0x8e, 0};
  349. static const char PROGMEM gui_on_2[] = {0xad, 0xae, 0};
  350. static const char PROGMEM alt_off_1[] = {0x87, 0x88, 0};
  351. static const char PROGMEM alt_off_2[] = {0xa7, 0xa8, 0};
  352. static const char PROGMEM alt_on_1[] = {0x8f, 0x90, 0};
  353. static const char PROGMEM alt_on_2[] = {0xaf, 0xb0, 0};
  354. // fillers between the modifier icons bleed into the icon frames
  355. static const char PROGMEM off_off_1[] = {0xc5, 0};
  356. static const char PROGMEM off_off_2[] = {0xc6, 0};
  357. static const char PROGMEM on_off_1[] = {0xc7, 0};
  358. static const char PROGMEM on_off_2[] = {0xc8, 0};
  359. static const char PROGMEM off_on_1[] = {0xc9, 0};
  360. static const char PROGMEM off_on_2[] = {0xca, 0};
  361. static const char PROGMEM on_on_1[] = {0xcb, 0};
  362. static const char PROGMEM on_on_2[] = {0xcc, 0};
  363. if (modifiers & MOD_MASK_GUI) {
  364. oled_write_P(gui_on_1, false);
  365. } else {
  366. oled_write_P(gui_off_1, false);
  367. }
  368. if ((modifiers & MOD_MASK_GUI) && (modifiers & MOD_MASK_ALT)) {
  369. oled_write_P(on_on_1, false);
  370. } else if (modifiers & MOD_MASK_GUI) {
  371. oled_write_P(on_off_1, false);
  372. } else if (modifiers & MOD_MASK_ALT) {
  373. oled_write_P(off_on_1, false);
  374. } else {
  375. oled_write_P(off_off_1, false);
  376. }
  377. if (modifiers & MOD_MASK_ALT) {
  378. oled_write_P(alt_on_1, false);
  379. } else {
  380. oled_write_P(alt_off_1, false);
  381. }
  382. if (modifiers & MOD_MASK_GUI) {
  383. oled_write_P(gui_on_2, false);
  384. } else {
  385. oled_write_P(gui_off_2, false);
  386. }
  387. if (modifiers & MOD_MASK_GUI & MOD_MASK_ALT) {
  388. oled_write_P(on_on_2, false);
  389. } else if (modifiers & MOD_MASK_GUI) {
  390. oled_write_P(on_off_2, false);
  391. } else if (modifiers & MOD_MASK_ALT) {
  392. oled_write_P(off_on_2, false);
  393. } else {
  394. oled_write_P(off_off_2, false);
  395. }
  396. if (modifiers & MOD_MASK_ALT) {
  397. oled_write_P(alt_on_2, false);
  398. } else {
  399. oled_write_P(alt_off_2, false);
  400. }
  401. }
  402. void render_mod_status_ctrl_shift(uint8_t modifiers) {
  403. static const char PROGMEM ctrl_off_1[] = {0x89, 0x8a, 0};
  404. static const char PROGMEM ctrl_off_2[] = {0xa9, 0xaa, 0};
  405. static const char PROGMEM ctrl_on_1[] = {0x91, 0x92, 0};
  406. static const char PROGMEM ctrl_on_2[] = {0xb1, 0xb2, 0};
  407. static const char PROGMEM shift_off_1[] = {0x8b, 0x8c, 0};
  408. static const char PROGMEM shift_off_2[] = {0xab, 0xac, 0};
  409. static const char PROGMEM shift_on_1[] = {0xcd, 0xce, 0};
  410. static const char PROGMEM shift_on_2[] = {0xcf, 0xd0, 0};
  411. // fillers between the modifier icons bleed into the icon frames
  412. static const char PROGMEM off_off_1[] = {0xc5, 0};
  413. static const char PROGMEM off_off_2[] = {0xc6, 0};
  414. static const char PROGMEM on_off_1[] = {0xc7, 0};
  415. static const char PROGMEM on_off_2[] = {0xc8, 0};
  416. static const char PROGMEM off_on_1[] = {0xc9, 0};
  417. static const char PROGMEM off_on_2[] = {0xca, 0};
  418. static const char PROGMEM on_on_1[] = {0xcb, 0};
  419. static const char PROGMEM on_on_2[] = {0xcc, 0};
  420. if (modifiers & MOD_MASK_CTRL) {
  421. oled_write_P(ctrl_on_1, false);
  422. } else {
  423. oled_write_P(ctrl_off_1, false);
  424. }
  425. if ((modifiers & MOD_MASK_CTRL) && (modifiers & MOD_MASK_SHIFT)) {
  426. oled_write_P(on_on_1, false);
  427. } else if (modifiers & MOD_MASK_CTRL) {
  428. oled_write_P(on_off_1, false);
  429. } else if (modifiers & MOD_MASK_SHIFT) {
  430. oled_write_P(off_on_1, false);
  431. } else {
  432. oled_write_P(off_off_1, false);
  433. }
  434. if (modifiers & MOD_MASK_SHIFT) {
  435. oled_write_P(shift_on_1, false);
  436. } else {
  437. oled_write_P(shift_off_1, false);
  438. }
  439. if (modifiers & MOD_MASK_CTRL) {
  440. oled_write_P(ctrl_on_2, false);
  441. } else {
  442. oled_write_P(ctrl_off_2, false);
  443. }
  444. if (modifiers & MOD_MASK_CTRL & MOD_MASK_SHIFT) {
  445. oled_write_P(on_on_2, false);
  446. } else if (modifiers & MOD_MASK_CTRL) {
  447. oled_write_P(on_off_2, false);
  448. } else if (modifiers & MOD_MASK_SHIFT) {
  449. oled_write_P(off_on_2, false);
  450. } else {
  451. oled_write_P(off_off_2, false);
  452. }
  453. if (modifiers & MOD_MASK_SHIFT) {
  454. oled_write_P(shift_on_2, false);
  455. } else {
  456. oled_write_P(shift_off_2, false);
  457. }
  458. }
  459. void render_layer_state(void) {
  460. static const char PROGMEM default_layer[] = {0x20, 0x94, 0x95, 0x96, 0x20, 0x20, 0xb4, 0xb5, 0xb6, 0x20, 0x20, 0xd4, 0xd5, 0xd6, 0x20, 0};
  461. static const char PROGMEM raise_layer[] = {0x20, 0x97, 0x98, 0x99, 0x20, 0x20, 0xb7, 0xb8, 0xb9, 0x20, 0x20, 0xd7, 0xd8, 0xd9, 0x20, 0};
  462. static const char PROGMEM lower_layer[] = {0x20, 0x9a, 0x9b, 0x9c, 0x20, 0x20, 0xba, 0xbb, 0xbc, 0x20, 0x20, 0xda, 0xdb, 0xdc, 0x20, 0};
  463. static const char PROGMEM nump_layer[] = {0x20, 0x9d, 0x9e, 0x9f, 0x20, 0x20, 0xbd, 0xbe, 0xbf, 0x20, 0x20, 0xdd, 0xde, 0xdf, 0x20, 0};
  464. if (layer_state_is(_NUMP)) {
  465. oled_write_P(nump_layer, false);
  466. } else if (layer_state_is(_LOWER)) {
  467. oled_write_P(lower_layer, false);
  468. } else if (layer_state_is(_RAISE)) {
  469. oled_write_P(raise_layer, false);
  470. } else {
  471. oled_write_P(default_layer, false);
  472. }
  473. }
  474. // renders on oled
  475. bool oled_task_user(void) {
  476. current_wpm = get_current_wpm();
  477. // led_usb_state = host_keyboard_led_state();
  478. if (is_keyboard_left()) {
  479. oled_set_cursor(0, 2);
  480. if (isSneaking) {
  481. render_layer_state();
  482. } else {
  483. for (size_t i = 0; i < 7; i++) {
  484. oled_write(" ", false);
  485. }
  486. }
  487. render_luna(0, 12);
  488. } else {
  489. oled_set_cursor(0, 6);
  490. render_layer_state();
  491. oled_set_cursor(0, 11);
  492. if (mod_state) {
  493. render_mod_status_gui_alt(get_mods());
  494. render_mod_status_ctrl_shift(get_mods());
  495. } else {
  496. for (size_t i = 0; i < 5; i++) {
  497. oled_write(" ", false);
  498. }
  499. }
  500. }
  501. return false;
  502. }
  503. #endif
  504. bool process_record_user(uint16_t keycode, keyrecord_t* record) {
  505. switch (keycode) {
  506. // ç key
  507. case CEDILHA:
  508. if (record->event.pressed) {
  509. register_code(KC_QUOT);
  510. unregister_code(KC_QUOT);
  511. register_code(KC_C);
  512. unregister_code(KC_C);
  513. }
  514. break;
  515. return false;
  516. // ã key
  517. case AO:
  518. if (record->event.pressed) {
  519. register_code(KC_LSFT);
  520. register_code(KC_GRV);
  521. unregister_code(KC_LSFT);
  522. unregister_code(KC_GRV);
  523. register_code(KC_A);
  524. unregister_code(KC_A);
  525. }
  526. break;
  527. return false;
  528. // direct " key
  529. case ASPAS:
  530. if (record->event.pressed) {
  531. register_code(KC_LSFT);
  532. register_code(KC_QUOT);
  533. register_code(KC_SPC);
  534. unregister_code(KC_SPC);
  535. unregister_code(KC_QUOT);
  536. unregister_code(KC_LSFT);
  537. }
  538. break;
  539. return false;
  540. // Luna jumping on space
  541. case KC_SPC:
  542. if (record->event.pressed) {
  543. isJumping = true;
  544. showedJump = false;
  545. } else {
  546. isJumping = false;
  547. }
  548. break;
  549. return false;
  550. }
  551. return true;
  552. }