keymap.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. /* Copyright 2021 HellSingCoder
  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 QMK_KEYBOARD_H
  17. enum sofle_layers {
  18. /* _M_XYZ = Mac Os, _W_XYZ = Win/Linux */
  19. _QWERTY,
  20. _GAMING,
  21. _LOWER,
  22. _RAISE,
  23. _ADJUST,
  24. };
  25. // clang-format off
  26. enum custom_keycodes {
  27. KC_QWERTY = SAFE_RANGE,
  28. KC_GAMING,
  29. KC_LOWER,
  30. KC_RAISE,
  31. KC_ADJUST,
  32. KC_PRVWD,
  33. KC_NXTWD,
  34. KC_LSTRT,
  35. KC_LEND,
  36. KC_DLINE,
  37. KC_BSPC_DEL,
  38. KC_LAYER
  39. };
  40. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  41. /*
  42. * QWERTY
  43. * ,-----------------------------------------. ,-----------------------------------------.
  44. * | Esc | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | BS |
  45. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  46. * | Tab | Q | W | E | R | T | | Y | U | I | O | P | ` |
  47. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  48. * | Caps | A | S | D | F | G |-------. ,-------| H | J | K | L | ; | ' |
  49. * |------+------+------+------+------+------| play | | mute |------+------+------+------+------+------|
  50. * |LShift| Z | X | C | V | B |-------| |-------| N | M | , | . | / | \ |
  51. * `-----------------------------------------/ / \ \-----------------------------------------'
  52. * | LGUI | LAlt | LAYER| LCTR | /Enter / \Space \ | [ | ] | - | = |
  53. * | | | | |/ / \ \ | | | | |
  54. * `----------------------------------' '------''---------------------------'
  55. */
  56. [_QWERTY] = LAYOUT(
  57. KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC_DEL,
  58. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_GRV,
  59. KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
  60. KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_GAMING, KC_QWERTY,KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_BSLS,
  61. KC_LGUI,KC_LALT,KC_LAYER, KC_LCTL, KC_ENT, KC_SPC, KC_LBRC, KC_RBRC, KC_MINS, KC_EQL
  62. ),
  63. /*
  64. * GAMING
  65. * ,-----------------------------------------. ,-----------------------------------------.
  66. * | Esc | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | BS |
  67. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  68. * | Tab | Q | W | E | R | T | | Y | U | I | O | P | ` |
  69. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  70. * | Caps | A | S | D | F | G |-------. ,-------| H | J | K | L | Up | ' |
  71. * |------+------+------+------+------+------| play | | mute |------+------+------+------+------+------|
  72. * |LShift| Z | X | C | V | B |-------| |-------| N | M | , | Left | Down | Right|
  73. * `-----------------------------------------/ / \ \-----------------------------------------'
  74. * | LGUI | LAlt | LAYER| LCTR | /Space / \Enter \ | [ | ] | - | = |
  75. * | | | | |/ / \ \ | | | | |
  76. * `----------------------------------' '------''---------------------------'
  77. */
  78. [_GAMING] = LAYOUT(
  79. KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC_DEL,
  80. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_GRV,
  81. KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_UP, KC_QUOT,
  82. KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_MPLY, KC_MUTE,KC_N, KC_M, KC_COMM, KC_LEFT, KC_DOWN, KC_RIGHT,
  83. KC_LGUI,KC_LALT,KC_LAYER, KC_LCTL, KC_SPC, KC_ENT, KC_LBRC, KC_RBRC, KC_MINS, KC_EQL
  84. ),
  85. /* LOWER
  86. * ,-----------------------------------------. ,-----------------------------------------.
  87. * | Esc | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10 | F11 |
  88. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  89. * | Tab | | Up | | QK_BOOT| | | PWrd | NWrd | Pscr |Scroll| Pause| F12 |
  90. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  91. * | Caps | Left | Down | Rigth| | |-------. ,-------| | | Ins | Home | PUp | |
  92. * |------+------+------+------+------+------| play | | mute |------+------+------+------+------+------|
  93. * | Shift| | | | | |-------| |-------| | Menu | Del | End | PDown| |
  94. * `-----------------------------------------/ / \ \-----------------------------------------'
  95. * |MACWIN| RAlt | LAYER| RCTR | /Enter / \Space \ | | | | |
  96. * | | | | |/ / \ \ | | | | |
  97. * `----------------------------------' '------''---------------------------'
  98. */
  99. [_LOWER] = LAYOUT(
  100. _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
  101. _______, XXXXXXX, KC_UP, XXXXXXX, QK_BOOT, XXXXXXX, KC_PRVWD, KC_NXTWD, KC_PSCR, KC_SCRL, KC_PAUS, KC_F12,
  102. _______, KC_LEFT, KC_DOWN, KC_RGHT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_INS, KC_HOME, KC_PGUP, XXXXXXX,
  103. _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, XXXXXXX, KC_APP, KC_DEL, KC_END, KC_PGDN, XXXXXXX,
  104. CG_TOGG, KC_RALT, _______, KC_RCTL, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
  105. ),
  106. /* RAISE
  107. * ,----------------------------------------. ,-----------------------------------------.
  108. * | | | | | | | | | | | | | |
  109. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  110. * | Esc | Ins | Pscr | Menu | | | | | PWrd | Up | NWrd | DLine| Bspc |
  111. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  112. * | Tab | LAt | LCtl |LShift| | Caps |-------. ,-------| | Left | Down | Rigth| Del | Bspc |
  113. * |------+------+------+------+------+------| MUTE | | |------+------+------+------+------+------|
  114. * |Shift | Undo | Cut | Copy | Paste| |-------| |-------| | LStr | | LEnd | | Shift|
  115. * `-----------------------------------------/ / \ \-----------------------------------------'
  116. * | LGUI | LAlt | LCTR |LOWER | /Enter / \Space \ |RAISE | RCTR | RAlt | RGUI |
  117. * | | | | |/ / \ \ | | | | |
  118. * `----------------------------------' '------''---------------------------'
  119. */
  120. [_RAISE] = LAYOUT(
  121. _______, _______ , _______ , _______ , _______ , _______, _______, _______ , _______, _______ , _______ ,_______,
  122. _______, KC_INS, KC_PSCR, KC_APP, XXXXXXX, XXXXXXX, KC_PGUP, KC_PRVWD, KC_UP, KC_NXTWD,KC_DLINE, KC_BSPC,
  123. _______, KC_LALT, KC_LCTL, KC_LSFT, XXXXXXX, KC_CAPS, KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT, KC_DEL, KC_BSPC,
  124. _______,KC_UNDO, KC_CUT, KC_COPY, KC_PASTE, XXXXXXX, _______, _______, XXXXXXX, KC_LSTRT, XXXXXXX, KC_LEND, _______, _______,
  125. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
  126. ),
  127. /* ADJUST
  128. * ,-----------------------------------------. ,-----------------------------------------.
  129. * | | | | | | | | | | | | | |
  130. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  131. * | QK_BOOT| |QWERTY| | | | | | | | | | |
  132. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  133. * | | |MACWIN| | | |-------. ,-------| | VOLDO| MUTE | VOLUP| | |
  134. * |------+------+------+------+------+------| MUTE | | |------+------+------+------+------+------|
  135. * | | | | | | |-------| |-------| | PREV | PLAY | NEXT | | |
  136. * `-----------------------------------------/ / \ \-----------------------------------------'
  137. * | LGUI | LAlt | LCTR |LOWER | /Enter / \Space \ |RAISE | RCTR | RAlt | RGUI |
  138. * | | | | |/ / \ \ | | | | |
  139. * `----------------------------------' '------''---------------------------'
  140. */
  141. [_ADJUST] = LAYOUT(
  142. XXXXXXX , XXXXXXX, XXXXXXX , XXXXXXX , XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
  143. QK_BOOT, XXXXXXX,KC_QWERTY,XXXXXXX,CG_TOGG,XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
  144. XXXXXXX , XXXXXXX,CG_TOGG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_VOLD, KC_MUTE, KC_VOLU, XXXXXXX, XXXXXXX,
  145. XXXXXXX , XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MPRV, KC_MPLY, KC_MNXT, XXXXXXX, XXXXXXX,
  146. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
  147. )
  148. };
  149. // clang-format on
  150. #ifdef OLED_ENABLE
  151. /* 32 * 32 logo */
  152. static void render_logo(void) {
  153. static const char PROGMEM hell_logo[] = {0x00, 0x80, 0xc0, 0xc0, 0x60, 0x60, 0x30, 0x30, 0x18, 0x1c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x78, 0x1e, 0x06, 0x00, 0x0c, 0x1c, 0x18, 0x30, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x70, 0x60, 0x00, 0xc0, 0xf0, 0x3c, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x60, 0x70, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x07, 0x03, 0x01, 0x00, 0xf8, 0xf8, 0x80, 0x80, 0x80, 0xf8, 0xf8, 0x00, 0x80, 0xc0, 0xc0, 0x40, 0xc0, 0xc0, 0x80, 0x00, 0xf8, 0xf8, 0x00, 0xf8, 0xf8, 0x00, 0x08, 0x38, 0x08, 0x00, 0x38, 0x08, 0x30, 0x08, 0x38, 0x00, 0x1f, 0x1f, 0x01, 0x01, 0x01, 0x1f, 0x1f, 0x00, 0x0f, 0x1f, 0x1a, 0x12, 0x1a, 0x1b, 0x0b, 0x00, 0x1f, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  154. oled_write_raw_P(hell_logo, sizeof(hell_logo));
  155. }
  156. /* 32 * 14 os logos */
  157. static const char PROGMEM windows_logo[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xbc, 0xbe, 0xbe, 0x00, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  158. static const char PROGMEM mac_logo[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0xf8, 0xf8, 0xf8, 0xf0, 0xf6, 0xfb, 0xfb, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0f, 0x1f, 0x1f, 0x0f, 0x0f, 0x1f, 0x1f, 0x0f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  159. /* Smart Backspace Delete */
  160. bool shift_held = false;
  161. static uint16_t held_shift = 0;
  162. /* KEYBOARD PET START */
  163. /* settings */
  164. # define MIN_WALK_SPEED 10
  165. # define MIN_RUN_SPEED 40
  166. /* advanced settings */
  167. # define ANIM_FRAME_DURATION 200 // how long each frame lasts in ms
  168. # define ANIM_SIZE 96 // number of bytes in array. If you change sprites, minimize for adequate firmware size. max is 1024
  169. /* timers */
  170. uint32_t anim_timer = 0;
  171. /* current frame */
  172. uint8_t current_frame = 0;
  173. /* status variables */
  174. int current_wpm = 0;
  175. led_t led_usb_state;
  176. bool isSneaking = false;
  177. bool isJumping = false;
  178. bool showedJump = true;
  179. /* logic */
  180. static void render_luna(int LUNA_X, int LUNA_Y) {
  181. /* Sit */
  182. static const char PROGMEM sit[2][ANIM_SIZE] = {/* 'sit1', 32x22px */
  183. {
  184. 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,
  185. },
  186. /* 'sit2', 32x22px */
  187. {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}};
  188. /* Walk */
  189. static const char PROGMEM walk[2][ANIM_SIZE] = {/* 'walk1', 32x22px */
  190. {
  191. 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,
  192. },
  193. /* 'walk2', 32x22px */
  194. {
  195. 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,
  196. }};
  197. /* Run */
  198. static const char PROGMEM run[2][ANIM_SIZE] = {/* 'run1', 32x22px */
  199. {
  200. 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,
  201. },
  202. /* 'run2', 32x22px */
  203. {
  204. 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,
  205. }};
  206. /* Bark */
  207. static const char PROGMEM bark[2][ANIM_SIZE] = {/* 'bark1', 32x22px */
  208. {
  209. 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,
  210. },
  211. /* 'bark2', 32x22px */
  212. {
  213. 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,
  214. }};
  215. /* Sneak */
  216. static const char PROGMEM sneak[2][ANIM_SIZE] = {/* 'sneak1', 32x22px */
  217. {
  218. 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,
  219. },
  220. /* 'sneak2', 32x22px */
  221. {
  222. 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,
  223. }};
  224. /* animation */
  225. void animate_luna(void) {
  226. /* jump */
  227. if (isJumping || !showedJump) {
  228. /* clear */
  229. oled_set_cursor(LUNA_X, LUNA_Y + 2);
  230. oled_write(" ", false);
  231. oled_set_cursor(LUNA_X, LUNA_Y - 1);
  232. showedJump = true;
  233. } else {
  234. /* clear */
  235. oled_set_cursor(LUNA_X, LUNA_Y - 1);
  236. oled_write(" ", false);
  237. oled_set_cursor(LUNA_X, LUNA_Y);
  238. }
  239. /* switch frame */
  240. current_frame = (current_frame + 1) % 2;
  241. /* current status */
  242. if (led_usb_state.caps_lock) {
  243. oled_write_raw_P(bark[current_frame], ANIM_SIZE);
  244. } else if (isSneaking) {
  245. oled_write_raw_P(sneak[current_frame], ANIM_SIZE);
  246. } else if (current_wpm <= MIN_WALK_SPEED) {
  247. oled_write_raw_P(sit[current_frame], ANIM_SIZE);
  248. } else if (current_wpm <= MIN_RUN_SPEED) {
  249. oled_write_raw_P(walk[current_frame], ANIM_SIZE);
  250. } else {
  251. oled_write_raw_P(run[current_frame], ANIM_SIZE);
  252. }
  253. }
  254. # if OLED_TIMEOUT > 0
  255. /* the animation prevents the normal timeout from occuring */
  256. if (last_input_activity_elapsed() > OLED_TIMEOUT && last_led_activity_elapsed() > OLED_TIMEOUT) {
  257. oled_off();
  258. return;
  259. } else {
  260. oled_on();
  261. }
  262. # endif
  263. /* animation timer */
  264. if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) {
  265. anim_timer = timer_read32();
  266. animate_luna();
  267. }
  268. }
  269. /* KEYBOARD PET END */
  270. static void print_logo_narrow(void) {
  271. render_logo();
  272. /* wpm counter */
  273. uint8_t n = get_current_wpm();
  274. char wpm_str[4];
  275. oled_set_cursor(0, 14);
  276. wpm_str[3] = '\0';
  277. wpm_str[2] = '0' + n % 10;
  278. wpm_str[1] = '0' + (n /= 10) % 10;
  279. wpm_str[0] = '0' + n / 10;
  280. oled_write(wpm_str, false);
  281. oled_set_cursor(0, 15);
  282. oled_write(" wpm", false);
  283. }
  284. static void print_status_narrow(void) {
  285. /* Print current mode */
  286. oled_set_cursor(0, 0);
  287. if (keymap_config.swap_lctl_lgui) {
  288. oled_write_raw_P(mac_logo, sizeof(mac_logo));
  289. } else {
  290. oled_write_raw_P(windows_logo, sizeof(windows_logo));
  291. }
  292. oled_set_cursor(0, 3);
  293. switch (get_highest_layer(default_layer_state)) {
  294. case _QWERTY:
  295. oled_write("QWRTY", false);
  296. break;
  297. case _GAMING:
  298. oled_write("GAMES", false);
  299. break;
  300. default:
  301. oled_write("UNDEF", false);
  302. }
  303. oled_set_cursor(0, 5);
  304. /* Print current layer */
  305. oled_write("LAYER", false);
  306. oled_set_cursor(0, 6);
  307. switch (get_highest_layer(layer_state)) {
  308. case _QWERTY:
  309. oled_write("Base ", false);
  310. break;
  311. case _GAMING:
  312. oled_write("Games", false);
  313. break;
  314. case _RAISE:
  315. oled_write("Raise", false);
  316. break;
  317. case _LOWER:
  318. oled_write("Lower", false);
  319. break;
  320. case _ADJUST:
  321. oled_write("Adj ", false);
  322. break;
  323. default:
  324. oled_write("Undef", false);
  325. }
  326. /* caps lock */
  327. oled_set_cursor(0, 8);
  328. oled_write("CPSLK", led_usb_state.caps_lock);
  329. /* KEYBOARD PET RENDER START */
  330. render_luna(0, 13);
  331. /* KEYBOARD PET RENDER END */
  332. }
  333. oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_270; }
  334. bool oled_task_user(void) {
  335. /* KEYBOARD PET VARIABLES START */
  336. current_wpm = get_current_wpm();
  337. led_usb_state = host_keyboard_led_state();
  338. /* KEYBOARD PET VARIABLES END */
  339. if (is_keyboard_master()) {
  340. print_status_narrow();
  341. } else {
  342. print_logo_narrow();
  343. }
  344. return false;
  345. }
  346. #endif
  347. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  348. switch (keycode) {
  349. case KC_QWERTY:
  350. if (record->event.pressed) {
  351. set_single_persistent_default_layer(_QWERTY);
  352. }
  353. return false;
  354. case KC_GAMING:
  355. if (record->event.pressed) {
  356. set_single_persistent_default_layer(_GAMING);
  357. }
  358. return false;
  359. case KC_LOWER:
  360. if (record->event.pressed) {
  361. layer_on(_LOWER);
  362. update_tri_layer(_LOWER, _RAISE, _ADJUST);
  363. } else {
  364. layer_off(_LOWER);
  365. update_tri_layer(_LOWER, _RAISE, _ADJUST);
  366. }
  367. return false;
  368. case KC_RAISE:
  369. if (record->event.pressed) {
  370. layer_on(_RAISE);
  371. update_tri_layer(_LOWER, _RAISE, _ADJUST);
  372. } else {
  373. layer_off(_RAISE);
  374. update_tri_layer(_LOWER, _RAISE, _ADJUST);
  375. }
  376. return false;
  377. case KC_ADJUST:
  378. if (record->event.pressed) {
  379. layer_on(_ADJUST);
  380. } else {
  381. layer_off(_ADJUST);
  382. }
  383. return false;
  384. case KC_PRVWD:
  385. if (record->event.pressed) {
  386. if (keymap_config.swap_lctl_lgui) {
  387. register_mods(mod_config(MOD_LALT));
  388. register_code(KC_LEFT);
  389. } else {
  390. register_mods(mod_config(MOD_LCTL));
  391. register_code(KC_LEFT);
  392. }
  393. } else {
  394. if (keymap_config.swap_lctl_lgui) {
  395. unregister_mods(mod_config(MOD_LALT));
  396. unregister_code(KC_LEFT);
  397. } else {
  398. unregister_mods(mod_config(MOD_LCTL));
  399. unregister_code(KC_LEFT);
  400. }
  401. }
  402. break;
  403. case KC_NXTWD:
  404. if (record->event.pressed) {
  405. if (keymap_config.swap_lctl_lgui) {
  406. register_mods(mod_config(MOD_LALT));
  407. register_code(KC_RIGHT);
  408. } else {
  409. register_mods(mod_config(MOD_LCTL));
  410. register_code(KC_RIGHT);
  411. }
  412. } else {
  413. if (keymap_config.swap_lctl_lgui) {
  414. unregister_mods(mod_config(MOD_LALT));
  415. unregister_code(KC_RIGHT);
  416. } else {
  417. unregister_mods(mod_config(MOD_LCTL));
  418. unregister_code(KC_RIGHT);
  419. }
  420. }
  421. break;
  422. case KC_LSTRT:
  423. if (record->event.pressed) {
  424. if (keymap_config.swap_lctl_lgui) {
  425. /* CMD-arrow on Mac, but we have CTL and GUI swapped */
  426. register_mods(mod_config(MOD_LCTL));
  427. register_code(KC_LEFT);
  428. } else {
  429. register_code(KC_HOME);
  430. }
  431. } else {
  432. if (keymap_config.swap_lctl_lgui) {
  433. unregister_mods(mod_config(MOD_LCTL));
  434. unregister_code(KC_LEFT);
  435. } else {
  436. unregister_code(KC_HOME);
  437. }
  438. }
  439. break;
  440. case KC_LEND:
  441. if (record->event.pressed) {
  442. if (keymap_config.swap_lctl_lgui) {
  443. /* CMD-arrow on Mac, but we have CTL and GUI swapped */
  444. register_mods(mod_config(MOD_LCTL));
  445. register_code(KC_RIGHT);
  446. } else {
  447. register_code(KC_END);
  448. }
  449. } else {
  450. if (keymap_config.swap_lctl_lgui) {
  451. unregister_mods(mod_config(MOD_LCTL));
  452. unregister_code(KC_RIGHT);
  453. } else {
  454. unregister_code(KC_END);
  455. }
  456. }
  457. break;
  458. case KC_DLINE:
  459. if (record->event.pressed) {
  460. register_mods(mod_config(MOD_LCTL));
  461. register_code(KC_BSPC);
  462. } else {
  463. unregister_mods(mod_config(MOD_LCTL));
  464. unregister_code(KC_BSPC);
  465. }
  466. break;
  467. case KC_COPY:
  468. if (record->event.pressed) {
  469. register_mods(mod_config(MOD_LCTL));
  470. register_code(KC_C);
  471. } else {
  472. unregister_mods(mod_config(MOD_LCTL));
  473. unregister_code(KC_C);
  474. }
  475. return false;
  476. case KC_PASTE:
  477. if (record->event.pressed) {
  478. register_mods(mod_config(MOD_LCTL));
  479. register_code(KC_V);
  480. } else {
  481. unregister_mods(mod_config(MOD_LCTL));
  482. unregister_code(KC_V);
  483. }
  484. return false;
  485. case KC_CUT:
  486. if (record->event.pressed) {
  487. register_mods(mod_config(MOD_LCTL));
  488. register_code(KC_X);
  489. } else {
  490. unregister_mods(mod_config(MOD_LCTL));
  491. unregister_code(KC_X);
  492. }
  493. return false;
  494. break;
  495. case KC_UNDO:
  496. if (record->event.pressed) {
  497. register_mods(mod_config(MOD_LCTL));
  498. register_code(KC_Z);
  499. } else {
  500. unregister_mods(mod_config(MOD_LCTL));
  501. unregister_code(KC_Z);
  502. }
  503. return false;
  504. /* Smart Backspace Delete */
  505. case KC_RSFT:
  506. case KC_LSFT:
  507. shift_held = record->event.pressed;
  508. held_shift = keycode;
  509. break;
  510. case KC_BSPC_DEL:
  511. if (record->event.pressed) {
  512. if (shift_held) {
  513. unregister_code(held_shift);
  514. register_code(KC_DEL);
  515. } else {
  516. register_code(KC_BSPC);
  517. }
  518. } else {
  519. unregister_code(KC_DEL);
  520. unregister_code(KC_BSPC);
  521. if (shift_held) {
  522. register_code(held_shift);
  523. }
  524. }
  525. return false;
  526. /* LAYER */
  527. case KC_LAYER:
  528. if (record->event.pressed) {
  529. if (shift_held) {
  530. if (record->event.pressed) {
  531. if (get_highest_layer(default_layer_state) == _QWERTY) {
  532. set_single_persistent_default_layer(_GAMING);
  533. } else if (get_highest_layer(default_layer_state) == _GAMING) {
  534. set_single_persistent_default_layer(_QWERTY);
  535. }
  536. }
  537. } else {
  538. layer_on(_LOWER);
  539. update_tri_layer(_LOWER, _RAISE, _ADJUST);
  540. }
  541. } else {
  542. layer_off(_LOWER);
  543. update_tri_layer(_LOWER, _RAISE, _ADJUST);
  544. }
  545. return false;
  546. /* KEYBOARD PET STATUS START */
  547. case KC_LCTL:
  548. case KC_RCTL:
  549. if (record->event.pressed) {
  550. isSneaking = true;
  551. } else {
  552. isSneaking = false;
  553. }
  554. break;
  555. case KC_SPC:
  556. if (record->event.pressed) {
  557. isJumping = true;
  558. showedJump = false;
  559. } else {
  560. isJumping = false;
  561. }
  562. break;
  563. /* KEYBOARD PET STATUS END */
  564. }
  565. return true;
  566. }
  567. #ifdef ENCODER_ENABLE
  568. bool encoder_update_user(uint8_t index, bool clockwise) {
  569. if (index == 0) {
  570. if (clockwise) {
  571. if (shift_held) {
  572. tap_code(KC_MNXT);
  573. } else {
  574. tap_code(KC_RIGHT);
  575. }
  576. } else {
  577. if (shift_held) {
  578. tap_code(KC_MPRV);
  579. } else {
  580. tap_code(KC_LEFT);
  581. }
  582. }
  583. } else if (index == 1) {
  584. if (clockwise) {
  585. if (shift_held) {
  586. tap_code(KC_VOLU);
  587. } else {
  588. tap_code(KC_DOWN);
  589. }
  590. } else {
  591. if (shift_held) {
  592. tap_code(KC_VOLD);
  593. } else {
  594. tap_code(KC_UP);
  595. }
  596. }
  597. }
  598. return true;
  599. }
  600. #endif