diff --git a/keyboards/9key/keymaps/bcat/keymap.c b/keyboards/9key/keymaps/bcat/keymap.c index 5c08a42a5..944a48c0d 100644 --- a/keyboards/9key/keymaps/bcat/keymap.c +++ b/keyboards/9key/keymaps/bcat/keymap.c @@ -16,22 +16,21 @@ #include QMK_KEYBOARD_H -enum layer { - LAYER_DEFAULT, - LAYER_FUNCTION, -}; +#include "bcat.h" -#define LY_FUNC MO(LAYER_FUNCTION) -#define KY_LOCK LCA(KC_L) /* Cinnamon lock screen */ +#define KY_LOCK LGUI(KC_L) /* Chrome OS: Lock screen */ +#define KY_MICM LSG(KC_1) /* Meet Shortcuts: Mute mic */ +#define KY_MICU LSG(KC_2) /* Meet Shortcuts: Unmute mic */ +#define KY_RHAND LSG(KC_3) /* Meet Shortcuts: Raise/lower hand */ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // clang-format off [LAYER_DEFAULT] = LAYOUT( - KC_MPLY, KC_VOLU, KC_MSTP, - KC_MPRV, KC_VOLD, KC_MNXT, - KY_LOCK, KC_MUTE, LY_FUNC + KC_MPLY, KC_VOLU, KY_RHAND, + KY_LOCK, KC_VOLD, KY_MICU, + LY_FN1, KC_MUTE, KY_MICM ), - [LAYER_FUNCTION] = LAYOUT( + [LAYER_FUNCTION_1] = LAYOUT( EEP_RST, _______, RESET, _______, _______, _______, _______, _______, _______ diff --git a/keyboards/9key/keymaps/bcat/readme.md b/keyboards/9key/keymaps/bcat/readme.md index 2dee51de8..d38ae5463 100644 --- a/keyboards/9key/keymaps/bcat/readme.md +++ b/keyboards/9key/keymaps/bcat/readme.md @@ -1,5 +1,5 @@ # bcat's 9-Key layout -This is a super simple PCB-mount macropad with nine keys, used at work for -media keys and quick access to screen lock on Linux (Cinnamon desktop -environment). +This is a super simple PCB-mount macropad with nine keys, used on my +work-from-home Chromebox for media/volume control and to activate some global +shortcuts for Google Meet. diff --git a/keyboards/eco/keymaps/bcat/config.h b/keyboards/eco/keymaps/bcat/config.h index dffdc7b40..f2d51c324 100644 --- a/keyboards/eco/keymaps/bcat/config.h +++ b/keyboards/eco/keymaps/bcat/config.h @@ -16,6 +16,8 @@ #pragma once +#define BCAT_ORTHO_LAYERS + /* WS2812B RGB LED strip hand wired to Elite-C. */ #define RGB_DI_PIN B7 #define RGBLED_NUM 15 diff --git a/keyboards/eco/keymaps/bcat/keymap.c b/keyboards/eco/keymaps/bcat/keymap.c index d46a7d416..8c50a9ed5 100644 --- a/keyboards/eco/keymaps/bcat/keymap.c +++ b/keyboards/eco/keymaps/bcat/keymap.c @@ -18,21 +18,6 @@ #include "bcat.h" -enum layer { - LAYER_DEFAULT, - LAYER_LOWER, - LAYER_RAISE, - LAYER_ADJUST, -}; - -#define LY_LWR MO(LAYER_LOWER) -#define LY_RSE MO(LAYER_RAISE) - -#define KY_CSPC LCTL(KC_SPC) -#define KY_ZMIN LCTL(KC_EQL) -#define KY_ZMOUT LCTL(KC_MINS) -#define KY_ZMRST LCTL(KC_0) - const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // clang-format off /* Default layer: http://www.keyboard-layout-editor.com/#/gists/2c11371c7a5f7cd08a0132631d3d3281 */ @@ -58,12 +43,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), /* Adjust layer: http://www.keyboard-layout-editor.com/#/gists/b18aafa0327d7e83eaf485546c067a21 */ [LAYER_ADJUST] = LAYOUT( - _______, NK_TOGG, KC_MPLY, KC_VOLU, KC_MSTP, _______, _______, _______, EEP_RST, RESET, _______, _______, _______, _______, + _______, _______, KC_MPLY, KC_VOLU, KC_MSTP, _______, _______, _______, EEP_RST, RESET, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_VOLD, KC_MNXT, _______, _______, _______, RGB_RMOD, RGB_VAD, RGB_VAI, RGB_MOD, RGB_SPI, _______, _______, _______, _______, KC_MUTE, _______, _______, _______, _______, RGB_HUI, RGB_SAD, RGB_SAI, RGB_HUD, RGB_SPD, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_TOG, _______, _______, _______, _______, _______ ), // clang-format on }; - -layer_state_t layer_state_set_keymap(layer_state_t state) { return update_tri_layer_state(state, LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST); } diff --git a/keyboards/eco/keymaps/bcat/readme.md b/keyboards/eco/keymaps/bcat/readme.md index 85e261551..fd9e1bea7 100644 --- a/keyboards/eco/keymaps/bcat/readme.md +++ b/keyboards/eco/keymaps/bcat/readme.md @@ -39,6 +39,6 @@ nothing really useful to bind them to anyway. ## Adjust layer -![Adjust layer layout](https://i.imgur.com/J2rOshm.png) +![Adjust layer layout](https://i.imgur.com/63vm0ke.png) ([KLE](http://www.keyboard-layout-editor.com/#/gists/b18aafa0327d7e83eaf485546c067a21)) diff --git a/keyboards/keebio/bdn9/keymaps/bcat/keymap.c b/keyboards/keebio/bdn9/keymaps/bcat/keymap.c index c64f702b2..2028deb4f 100644 --- a/keyboards/keebio/bdn9/keymaps/bcat/keymap.c +++ b/keyboards/keebio/bdn9/keymaps/bcat/keymap.c @@ -16,21 +16,16 @@ #include QMK_KEYBOARD_H -enum layer { - LAYER_FIRST, - LAYER_SECOND, -}; - -#define LY_SECND MO(LAYER_SECOND) +#include "bcat.h" const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // clang-format off - [LAYER_FIRST] = LAYOUT( - KC_MUTE, LY_SECND, BL_BRTG, + [LAYER_DEFAULT] = LAYOUT( + KC_MUTE, LY_FN1, BL_BRTG, KC_F4, KC_F5, KC_F6, KC_F1, KC_F2, KC_F3 ), - [LAYER_SECOND] = LAYOUT( + [LAYER_FUNCTION_1] = LAYOUT( EEP_RST, _______, RESET, KC_F10, KC_F11, KC_F12, KC_F7, KC_F8, KC_F9 diff --git a/keyboards/keebio/quefrency/keymaps/bcat/keymap.c b/keyboards/keebio/quefrency/keymaps/bcat/keymap.c index d28a5083a..3dd48623f 100644 --- a/keyboards/keebio/quefrency/keymaps/bcat/keymap.c +++ b/keyboards/keebio/quefrency/keymaps/bcat/keymap.c @@ -16,12 +16,7 @@ #include QMK_KEYBOARD_H -enum layer { - LAYER_DEFAULT, - LAYER_FUNCTION, -}; - -#define LY_FN MO(LAYER_FUNCTION) +#include "bcat.h" const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // clang-format off @@ -31,12 +26,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, KC_PGUP, KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, - KC_LCTL, KC_LGUI, KC_LALT, LY_FN, KC_SPC, KC_SPC, XXXXXXX, KC_RALT, LY_FN, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + KC_LCTL, KC_LGUI, KC_LALT, LY_FN1, KC_SPC, KC_SPC, XXXXXXX, KC_RALT, LY_FN1, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT ), /* Function layer: http://www.keyboard-layout-editor.com/#/gists/59636898946da51f91fb290f8e078b4d */ - [LAYER_FUNCTION] = LAYOUT_65( + [LAYER_FUNCTION_1] = LAYOUT_65( _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_DEL, RGB_HUI, - KC_CAPS, NK_TOGG, KC_MPLY, KC_VOLU, KC_MSTP, _______, EEP_RST, RESET, KC_PSCR, KC_SLCK, KC_PAUS, _______, _______, _______, RGB_SAI, + KC_CAPS, _______, KC_MPLY, KC_VOLU, KC_MSTP, _______, EEP_RST, RESET, KC_PSCR, KC_SLCK, KC_PAUS, _______, _______, _______, RGB_SAI, _______, _______, KC_MPRV, KC_VOLD, KC_MNXT, _______, _______, _______, _______, _______, _______, _______, RGB_TOG, RGB_SAD, _______, KC_APP, _______, KC_MUTE, _______, _______, _______, _______, _______, _______, _______, _______, RGB_VAI, RGB_HUD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_RMOD, RGB_VAD, RGB_MOD diff --git a/keyboards/keebio/quefrency/keymaps/bcat/readme.md b/keyboards/keebio/quefrency/keymaps/bcat/readme.md index 914aa84b6..59a691654 100644 --- a/keyboards/keebio/quefrency/keymaps/bcat/readme.md +++ b/keyboards/keebio/quefrency/keymaps/bcat/readme.md @@ -12,6 +12,6 @@ ESDF cluster), and RGB controls in the function layer (on the arrow/nav keys). ## Function layer -![Function layer layout](https://i.imgur.com/Fzshl0F.png) +![Function layer layout](https://i.imgur.com/7oCdN86.png) ([KLE](http://www.keyboard-layout-editor.com/#/gists/59636898946da51f91fb290f8e078b4d)) diff --git a/keyboards/lily58/keymaps/bcat/config.h b/keyboards/lily58/keymaps/bcat/config.h index dbe724d56..2ee0071bd 100644 --- a/keyboards/lily58/keymaps/bcat/config.h +++ b/keyboards/lily58/keymaps/bcat/config.h @@ -16,4 +16,6 @@ #pragma once +#define BCAT_ORTHO_LAYERS + #define EE_HANDS diff --git a/keyboards/lily58/keymaps/bcat/keymap.c b/keyboards/lily58/keymaps/bcat/keymap.c index 69af2ca00..a0856d0fd 100644 --- a/keyboards/lily58/keymaps/bcat/keymap.c +++ b/keyboards/lily58/keymaps/bcat/keymap.c @@ -18,20 +18,9 @@ #include "bcat.h" -enum layer { - LAYER_DEFAULT, - LAYER_LOWER, - LAYER_RAISE, - LAYER_ADJUST, -}; - -#define LY_LWR MO(LAYER_LOWER) -#define LY_RSE MO(LAYER_RAISE) - -#define KY_CSPC LCTL(KC_SPC) -#define KY_ZMIN LCTL(KC_EQL) -#define KY_ZMOUT LCTL(KC_MINS) -#define KY_ZMRST LCTL(KC_0) +#if defined(OLED_ENABLE) +# include "bcat_oled.h" +#endif const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // clang-format off @@ -62,7 +51,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* Adjust layer: http://www.keyboard-layout-editor.com/#/gists/8f6a3f08350a9bbe1d414b22bca4e6c7 */ [LAYER_ADJUST] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, NK_TOGG, KC_MPLY, KC_VOLU, KC_MSTP, _______, EEP_RST, RESET, _______, _______, _______, _______, + _______, _______, KC_MPLY, KC_VOLU, KC_MSTP, _______, EEP_RST, RESET, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_VOLD, KC_MNXT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ @@ -70,4 +59,16 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // clang-format on }; -layer_state_t layer_state_set_keymap(layer_state_t state) { return update_tri_layer_state(state, LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST); } +#if defined(OLED_ENABLE) +oled_rotation_t oled_init_user(oled_rotation_t rotation) { return is_keyboard_master() ? OLED_ROTATION_270 : OLED_ROTATION_180; } + +void oled_task_keymap(const oled_keyboard_state_t *keyboard_state) { + render_oled_layers(); + oled_advance_page(/*clearPageRemainder=*/false); + render_oled_indicators(keyboard_state->leds); + oled_advance_page(/*clearPageRemainder=*/false); + oled_advance_page(/*clearPageRemainder=*/false); + render_oled_wpm(keyboard_state->wpm); + render_oled_pet(/*col=*/0, /*line=*/12, keyboard_state); +} +#endif diff --git a/keyboards/lily58/keymaps/bcat/readme.md b/keyboards/lily58/keymaps/bcat/readme.md index de03526a8..8b0e77e1b 100644 --- a/keyboards/lily58/keymaps/bcat/readme.md +++ b/keyboards/lily58/keymaps/bcat/readme.md @@ -37,6 +37,6 @@ back/forward navigation keys. ## Adjust layer -![Adjust layer layout](https://i.imgur.com/Q3PGsiK.png) +![Adjust layer layout](https://i.imgur.com/XC2eR2M.png) ([KLE](http://www.keyboard-layout-editor.com/#/gists/8f6a3f08350a9bbe1d414b22bca4e6c7)) diff --git a/keyboards/lily58/keymaps/bcat/rules.mk b/keyboards/lily58/keymaps/bcat/rules.mk index c87b447c1..62d1007a5 100644 --- a/keyboards/lily58/keymaps/bcat/rules.mk +++ b/keyboards/lily58/keymaps/bcat/rules.mk @@ -1 +1,3 @@ +BCAT_OLED_PET = luna + BOOTLOADER = atmel-dfu # Elite-C diff --git a/layouts/community/60_ansi_split_bs_rshift/bcat/keymap.c b/layouts/community/60_ansi_split_bs_rshift/bcat/keymap.c index 6bfafc332..b40148e99 100644 --- a/layouts/community/60_ansi_split_bs_rshift/bcat/keymap.c +++ b/layouts/community/60_ansi_split_bs_rshift/bcat/keymap.c @@ -16,14 +16,7 @@ #include QMK_KEYBOARD_H -enum layer { - LAYER_DEFAULT, - LAYER_FUNCTION_1, - LAYER_FUNCTION_2, -}; - -#define LY_FN1 MO(LAYER_FUNCTION_1) -#define LY_FN2 MO(LAYER_FUNCTION_2) +#include "bcat.h" const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // clang-format off @@ -48,7 +41,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* Function 2 layer: http://www.keyboard-layout-editor.com/#/gists/6e1068e4f91bbacccaf5ac0acbeec79c */ [LAYER_FUNCTION_2] = LAYOUT_60_ansi_split_bs_rshift( _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_DEL, - _______, NK_TOGG, KC_MPLY, KC_VOLU, KC_MSTP, BL_BRTG, EEP_RST, RESET, _______, _______, _______, RGB_VAI, _______, _______, + _______, _______, KC_MPLY, KC_VOLU, KC_MSTP, BL_BRTG, EEP_RST, RESET, _______, _______, _______, RGB_VAI, _______, _______, _______, _______, KC_MPRV, KC_VOLD, KC_MNXT, BL_INC, _______, RGB_SPI, RGB_HUI, RGB_SAI, RGB_RMOD, RGB_MOD, RGB_TOG, _______, _______, _______, KC_MUTE, _______, BL_DEC, _______, RGB_SPD, RGB_HUD, RGB_SAD, RGB_VAD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ diff --git a/layouts/community/60_ansi_split_bs_rshift/bcat/readme.md b/layouts/community/60_ansi_split_bs_rshift/bcat/readme.md index 2d578aa3d..f6bcda919 100644 --- a/layouts/community/60_ansi_split_bs_rshift/bcat/readme.md +++ b/layouts/community/60_ansi_split_bs_rshift/bcat/readme.md @@ -19,6 +19,6 @@ layout](https://github.com/qmk/qmk_firmware/tree/master/layouts/community/60_tsa ## Function 2 layer -![Function 2 layer layout](https://i.imgur.com/vJaCzVo.png) +![Function 2 layer layout](https://i.imgur.com/DW03vvJ.png) ([KLE](http://www.keyboard-layout-editor.com/#/gists/6e1068e4f91bbacccaf5ac0acbeec79c)) diff --git a/layouts/community/60_tsangan_hhkb/bcat/keymap.c b/layouts/community/60_tsangan_hhkb/bcat/keymap.c index 05e6462d9..9ec75f3c4 100644 --- a/layouts/community/60_tsangan_hhkb/bcat/keymap.c +++ b/layouts/community/60_tsangan_hhkb/bcat/keymap.c @@ -16,14 +16,7 @@ #include QMK_KEYBOARD_H -enum layer { - LAYER_DEFAULT, - LAYER_FUNCTION_1, - LAYER_FUNCTION_2, -}; - -#define LY_FN1 MO(LAYER_FUNCTION_1) -#define LY_FN2 MO(LAYER_FUNCTION_2) +#include "bcat.h" const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // clang-format off @@ -46,7 +39,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* Function 2 layer: http://www.keyboard-layout-editor.com/#/gists/65ac939caec878401603bc36290852d4 */ [LAYER_FUNCTION_2] = LAYOUT_60_tsangan_hhkb( _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_DEL, - _______, NK_TOGG, KC_MPLY, KC_VOLU, KC_MSTP, BL_BRTG, EEP_RST, RESET, _______, _______, _______, RGB_VAI, _______, _______, + _______, _______, KC_MPLY, KC_VOLU, KC_MSTP, BL_BRTG, EEP_RST, RESET, _______, _______, _______, RGB_VAI, _______, _______, _______, _______, KC_MPRV, KC_VOLD, KC_MNXT, BL_INC, _______, RGB_SPI, RGB_HUI, RGB_SAI, RGB_RMOD, RGB_MOD, RGB_TOG, _______, _______, _______, KC_MUTE, _______, BL_DEC, _______, RGB_SPD, RGB_HUD, RGB_SAD, RGB_VAD, _______, _______, _______, _______, _______, _______, _______, _______, _______ diff --git a/layouts/community/60_tsangan_hhkb/bcat/readme.md b/layouts/community/60_tsangan_hhkb/bcat/readme.md index b7a3cde5d..c8d0d72dd 100644 --- a/layouts/community/60_tsangan_hhkb/bcat/readme.md +++ b/layouts/community/60_tsangan_hhkb/bcat/readme.md @@ -39,6 +39,6 @@ and/or blockers, so there aren't switches installed in those positions. ## Function 2 layer -![Function 2 layer layout](https://i.imgur.com/vdNpFae.png) +![Function 2 layer layout](https://i.imgur.com/4Jdw9eL.png) ([KLE](http://www.keyboard-layout-editor.com/#/gists/65ac939caec878401603bc36290852d4)) diff --git a/layouts/community/65_ansi_blocker_split_bs/bcat/keymap.c b/layouts/community/65_ansi_blocker_split_bs/bcat/keymap.c index c91a1b0ea..c099d36e2 100644 --- a/layouts/community/65_ansi_blocker_split_bs/bcat/keymap.c +++ b/layouts/community/65_ansi_blocker_split_bs/bcat/keymap.c @@ -16,12 +16,7 @@ #include QMK_KEYBOARD_H -enum layer { - LAYER_DEFAULT, - LAYER_FUNCTION, -}; - -#define LY_FN MO(LAYER_FUNCTION) +#include "bcat.h" const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // clang-format off @@ -31,13 +26,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, KC_PGUP, KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, - KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, LY_FN, KC_LEFT, KC_DOWN, KC_RGHT + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, LY_FN1, KC_LEFT, KC_DOWN, KC_RGHT ), /* Function layer: http://www.keyboard-layout-editor.com/#/gists/f29128427f674c43777f045e363d1b44 */ - [LAYER_FUNCTION] = LAYOUT_65_ansi_blocker_split_bs( + [LAYER_FUNCTION_1] = LAYOUT_65_ansi_blocker_split_bs( _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_DEL, _______, - KC_CAPS, NK_TOGG, KC_MPLY, KC_VOLU, KC_MSTP, _______, EEP_RST, RESET, KC_PSCR, KC_SLCK, KC_PAUS, _______, _______, _______, _______, + KC_CAPS, _______, KC_MPLY, KC_VOLU, KC_MSTP, _______, EEP_RST, RESET, KC_PSCR, KC_SLCK, KC_PAUS, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_VOLD, KC_MNXT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_APP, _______, KC_MUTE, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ diff --git a/layouts/community/65_ansi_blocker_split_bs/bcat/readme.md b/layouts/community/65_ansi_blocker_split_bs/bcat/readme.md index 0726cbece..5777c7c38 100644 --- a/layouts/community/65_ansi_blocker_split_bs/bcat/readme.md +++ b/layouts/community/65_ansi_blocker_split_bs/bcat/readme.md @@ -12,6 +12,6 @@ keys, an HHKB-style (split) backspace, and media controls in the function layer ## Function layer -![Function layer layout](https://i.imgur.com/CsxfVfd.png) +![Function layer layout](https://i.imgur.com/s4hS9ZK.png) ([KLE](http://www.keyboard-layout-editor.com/#/gists/f29128427f674c43777f045e363d1b44)) diff --git a/layouts/community/split_3x6_3/bcat/config.h b/layouts/community/split_3x6_3/bcat/config.h index b8743429c..556fb90d5 100644 --- a/layouts/community/split_3x6_3/bcat/config.h +++ b/layouts/community/split_3x6_3/bcat/config.h @@ -16,12 +16,13 @@ #pragma once +#define BCAT_ORTHO_LAYERS + #if defined(KEYBOARD_crkbd_rev1) # define EE_HANDS -# if defined(RGB_MATRIX_ENABLE) -/* Limit max RGB LED current to avoid tripping controller fuse. */ -# undef RGB_MATRIX_MAXIMUM_BRIGHTNESS -# define RGB_MATRIX_MAXIMUM_BRIGHTNESS 150 +# if defined(OLED_ENABLE) +# undef OLED_FONT_H +# define OLED_FONT_H "lib/glcdfont.c" # endif #endif diff --git a/layouts/community/split_3x6_3/bcat/keymap.c b/layouts/community/split_3x6_3/bcat/keymap.c index 4f68c8f84..cfac93d1e 100644 --- a/layouts/community/split_3x6_3/bcat/keymap.c +++ b/layouts/community/split_3x6_3/bcat/keymap.c @@ -18,20 +18,9 @@ #include "bcat.h" -enum layer { - LAYER_DEFAULT, - LAYER_LOWER, - LAYER_RAISE, - LAYER_ADJUST, -}; - -#define LY_LWR MO(LAYER_LOWER) -#define LY_RSE MO(LAYER_RAISE) - -#define KY_CSPC LCTL(KC_SPC) -#define KY_ZMIN LCTL(KC_EQL) -#define KY_ZMOUT LCTL(KC_MINS) -#define KY_ZMRST LCTL(KC_0) +#if defined(OLED_ENABLE) +# include "bcat_oled.h" +#endif const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // clang-format off @@ -58,7 +47,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), /* Adjust layer: http://www.keyboard-layout-editor.com/#/gists/77e7572e077b36a23eb2086017e16fee */ [LAYER_ADJUST] = LAYOUT_split_3x6_3( - _______, NK_TOGG, KC_MPLY, KC_VOLU, KC_MSTP, _______, EEP_RST, RESET, _______, _______, _______, _______, + _______, _______, KC_MPLY, KC_VOLU, KC_MSTP, _______, EEP_RST, RESET, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_VOLD, KC_MNXT, _______, RGB_RMOD, RGB_VAD, RGB_VAI, RGB_MOD, RGB_SPI, _______, _______, _______, _______, KC_MUTE, _______, _______, RGB_HUI, RGB_SAD, RGB_SAI, RGB_HUD, RGB_SPD, _______, _______, _______, _______, RGB_TOG, _______, _______ @@ -66,4 +55,16 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // clang-format on }; -layer_state_t layer_state_set_keymap(layer_state_t state) { return update_tri_layer_state(state, LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST); } +#if defined(OLED_ENABLE) +oled_rotation_t oled_init_user(oled_rotation_t rotation) { return is_keyboard_master() ? OLED_ROTATION_270 : OLED_ROTATION_180; } + +void oled_task_keymap(const oled_keyboard_state_t *keyboard_state) { + render_oled_layers(); + oled_advance_page(/*clearPageRemainder=*/false); + render_oled_indicators(keyboard_state->leds); + oled_advance_page(/*clearPageRemainder=*/false); + oled_advance_page(/*clearPageRemainder=*/false); + render_oled_wpm(keyboard_state->wpm); + render_oled_pet(/*col=*/0, /*line=*/12, keyboard_state); +} +#endif diff --git a/layouts/community/split_3x6_3/bcat/readme.md b/layouts/community/split_3x6_3/bcat/readme.md index c4bf891c4..b7b5d3de7 100644 --- a/layouts/community/split_3x6_3/bcat/readme.md +++ b/layouts/community/split_3x6_3/bcat/readme.md @@ -117,7 +117,7 @@ better location. ## Adjust layer -![Adjust layer layout](https://i.imgur.com/fZouko5.png) +![Adjust layer layout](https://i.imgur.com/Q4rN6cQ.png) ([KLE](http://www.keyboard-layout-editor.com/#/gists/77e7572e077b36a23eb2086017e16fee)) diff --git a/layouts/community/split_3x6_3/bcat/rules.mk b/layouts/community/split_3x6_3/bcat/rules.mk index 5ee614b19..29e52b92d 100644 --- a/layouts/community/split_3x6_3/bcat/rules.mk +++ b/layouts/community/split_3x6_3/bcat/rules.mk @@ -1,5 +1,9 @@ +BCAT_OLED_PET = luna + ifeq ($(strip $(KEYBOARD)), crkbd/rev1) BOOTLOADER = atmel-dfu # Elite-C + OLED_ENABLE = yes # dual 128x32 OLED screens + OLED_DRIVER = SSD1306 RGB_MATRIX_ENABLE = yes # per-key RGB and underglow endif diff --git a/users/bcat/bcat.c b/users/bcat/bcat.c index f21d282e4..3a407cfac 100644 --- a/users/bcat/bcat.c +++ b/users/bcat/bcat.c @@ -16,16 +16,15 @@ #include "bcat.h" -#if defined(RGBLIGHT_ENABLE) -/* Adjust RGB static hue ranges for shorter gradients than default. */ -const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 127, 63, 31, 15}; -#endif +#include "quantum.h" static int8_t alt_tab_layer = -1; +__attribute__((weak)) void process_record_oled(uint16_t keycode, const keyrecord_t *record) {} __attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; } bool process_record_user(uint16_t keycode, keyrecord_t *record) { + process_record_oled(keycode, record); if (!process_record_keymap(keycode, record)) { return false; } @@ -51,6 +50,9 @@ __attribute__((weak)) layer_state_t layer_state_set_keymap(layer_state_t state) layer_state_t layer_state_set_user(layer_state_t state) { state = layer_state_set_keymap(state); +#if defined(BCAT_ORTHO_LAYERS) + state = update_tri_layer_state(state, LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST); +#endif if (alt_tab_layer >= 0 && !layer_state_cmp(state, alt_tab_layer)) { unregister_code(KC_LALT); alt_tab_layer = -1; diff --git a/users/bcat/bcat.h b/users/bcat/bcat.h index 0dae774ec..4a88acba7 100644 --- a/users/bcat/bcat.h +++ b/users/bcat/bcat.h @@ -16,9 +16,43 @@ #pragma once -#include "quantum.h" +#include +#include "keymap.h" + +/* Layer numbers shared across keymaps. */ +enum user_layer { + /* Base layers: */ + LAYER_DEFAULT, + +#if defined(BCAT_ORTHO_LAYERS) + /* Function layers for ortho (and ergo) boards: */ + LAYER_LOWER, + LAYER_RAISE, + LAYER_ADJUST, +#else + /* Function layers for traditional boards: */ + LAYER_FUNCTION_1, + LAYER_FUNCTION_2, +#endif +}; + +/* Custom keycodes shared across keymaps. */ enum user_keycode { MC_ALTT = SAFE_RANGE, KEYMAP_SAFE_RANGE, }; + +/* Keycode aliases shared across keymaps. */ +#define KY_CSPC LCTL(KC_SPC) +#define KY_ZMIN LCTL(KC_EQL) +#define KY_ZMOUT LCTL(KC_MINS) +#define KY_ZMRST LCTL(KC_0) + +#if defined(BCAT_ORTHO_LAYERS) +# define LY_LWR MO(LAYER_LOWER) +# define LY_RSE MO(LAYER_RAISE) +#else +# define LY_FN1 MO(LAYER_FUNCTION_1) +# define LY_FN2 MO(LAYER_FUNCTION_2) +#endif diff --git a/users/bcat/bcat_oled.c b/users/bcat/bcat_oled.c new file mode 100644 index 000000000..390c9127b --- /dev/null +++ b/users/bcat/bcat_oled.c @@ -0,0 +1,216 @@ +/* Copyright 2021 Jonathan Rascher + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "bcat_oled.h" + +#include "quantum.h" +#include "bcat.h" + +#if defined(BCAT_OLED_PET) +# include "bcat_oled_pet.h" +#endif + +#define TRIANGLE_UP 0x1e +#define TRIANGLE_DOWN 0x1f + +#if defined(BCAT_OLED_PET) +static bool oled_pet_should_jump = false; +#endif + +/* Should be overridden by the keymap to render the OLED contents. For split + * keyboards, this function is only called on the master side. + */ +__attribute__((weak)) void oled_task_keymap(const oled_keyboard_state_t *keyboard_state) {} + +bool oled_task_user(void) { +#if defined(SPLIT_KEYBOARD) + if (is_keyboard_master()) { +#endif + /* Custom OLED timeout implementation that only considers user activity. + * Allows the OLED to turn off in the middle of a continuous animation. + */ + static const uint16_t TIMEOUT_MILLIS = 60000 /* 1 min */; + + if (last_input_activity_elapsed() < TIMEOUT_MILLIS) { + if (!is_oled_on()) { + oled_on(); + } + oled_keyboard_state_t keyboard_state = { + .mods = get_mods(), + .leds = host_keyboard_led_state(), + .wpm = get_current_wpm(), + }; + oled_task_keymap(&keyboard_state); + } else if (is_oled_on()) { + oled_off(); + } +#if defined(SPLIT_KEYBOARD) + } else { + /* Display logo embedded at standard location in the OLED font on the + * slave side. By default, this is a "QMK firmware" logo, but many + * keyboards substitute their own logo. Occupies 21x3 character cells. + * + * Since the slave display buffer never changes, we don't need to worry + * about oled_render incorrectly turning the OLED on. Instead, we rely + * on SPLIT_OLED_ENABLE to propagate OLED on/off status from master. + */ + static const char PROGMEM logo[] = { + // clang-format off + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, + 0x00, + // clang-format on + }; + + oled_write_P(logo, /*invert=*/false); + } +#endif + + return false; +} + +void render_oled_layers(void) { + oled_advance_char(); + oled_advance_char(); +#if defined(BCAT_ORTHO_LAYERS) + oled_write_char(IS_LAYER_ON(LAYER_LOWER) ? TRIANGLE_DOWN : ' ', /*invert=*/false); + oled_advance_char(); + oled_write_char(IS_LAYER_ON(LAYER_RAISE) ? TRIANGLE_UP : ' ', /*invert=*/false); +#else + switch (get_highest_layer(layer_state)) { + case LAYER_FUNCTION_1: + oled_write_P(PSTR("FN1"), /*invert=*/false); + break; + case LAYER_FUNCTION_2: + oled_write_P(PSTR("FN2"), /*invert=*/false); + break; + default: + oled_write_P(PSTR(" "), /*invert=*/false); + break; + } +#endif +} + +void render_oled_indicators(led_t leds) { + oled_advance_char(); + oled_advance_char(); + oled_write_P(leds.num_lock ? PSTR("NUM") : PSTR(" "), /*invert=*/false); + oled_advance_char(); + oled_advance_char(); + oled_write_P(leds.caps_lock ? PSTR("CAP") : PSTR(" "), /*invert=*/false); + oled_advance_char(); + oled_advance_char(); + oled_write_P(leds.scroll_lock ? PSTR("SCR") : PSTR(" "), /*invert=*/false); +} + +void render_oled_wpm(uint8_t wpm) { + static const uint16_t UPDATE_MILLIS = 100; + static uint32_t update_timeout = 0; + + if (timer_expired32(timer_read32(), update_timeout)) { + oled_advance_char(); + oled_advance_char(); + oled_write_P(wpm > 0 ? PSTR("WPM") : PSTR(" "), /*invert=*/false); + if (wpm > 0) { + oled_advance_char(); + oled_advance_char(); + oled_write(get_u8_str(wpm, ' '), /*invert=*/false); + } else { + oled_advance_page(/*clearPageRemainder=*/true); + } + + update_timeout = timer_read32() + UPDATE_MILLIS; + } +} + +#if defined(BCAT_OLED_PET) +void process_record_oled(uint16_t keycode, const keyrecord_t *record) { + switch (keycode) { + case KC_SPACE: + if (oled_pet_can_jump()) { + oled_pet_should_jump = record->event.pressed; + } + break; + default: + break; + } +} + +static void redraw_oled_pet(uint8_t col, uint8_t line, bool jumping, oled_pet_state_t state) { + oled_set_cursor(col, line); + if (jumping) { + oled_write_raw_P(oled_pet_frame(state), oled_pet_frame_bytes()); + oled_set_cursor(col, line + oled_pet_frame_lines()); + oled_advance_page(/*clearPageRemainder=*/true); + } else { + oled_advance_page(/*clearPageRemainder=*/true); + oled_write_raw_P(oled_pet_frame(state), oled_pet_frame_bytes()); + } +} + +void render_oled_pet(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state) { + /* Current animation to draw. We track changes to avoid redrawing the same + * frame repeatedly, allowing oled_pet_post_render to draw over the + * animation frame. + */ + static oled_pet_state_t state = 0; + static bool state_changed = true; + + /* Minimum time until the pet comes down after jumping. */ + static const uint16_t JUMP_MILLIS = 200; + static bool jumping = false; + + /* Time until the next animation or jump state change. */ + static uint32_t update_timeout = 0; + static uint32_t jump_timeout = 0; + + /* If the user pressed the jump key, immediately redraw instead of waiting + * for the animation frame to update. That way, the pet appears to respond + * to jump commands quickly rather than lagging. If the user released the + * jump key, wait for the jump timeout to avoid overly brief jumps. + */ + bool redraw = state_changed; + if (oled_pet_should_jump && !jumping) { + redraw = true; + jumping = true; + jump_timeout = timer_read32() + JUMP_MILLIS; + } else if (!oled_pet_should_jump && jumping && timer_expired32(timer_read32(), jump_timeout)) { + redraw = true; + jumping = false; + } + + /* Draw the actual animation, then move the cursor to the end of the + * rendered area. (Note that we take up an extra line to account for + * jumping, which shifts the animation up or down a line.) + */ + if (redraw) { + redraw_oled_pet(col, line, jumping, state); + } + oled_pet_post_render(col, line + !jumping, keyboard_state, redraw); + oled_set_cursor(col, line + oled_pet_frame_lines() + 1); + + /* If the update timer expired, recompute the pet's animation state. */ + if (timer_expired32(timer_read32(), update_timeout)) { + oled_pet_state_t new_state = oled_pet_next_state(state, keyboard_state); + state_changed = new_state != state; + state = new_state; + update_timeout = timer_read32() + oled_pet_update_millis(keyboard_state); + } else { + state_changed = false; + } +} +#endif diff --git a/users/bcat/bcat_oled.h b/users/bcat/bcat_oled.h new file mode 100644 index 000000000..f617e1f06 --- /dev/null +++ b/users/bcat/bcat_oled.h @@ -0,0 +1,55 @@ +/* Copyright 2021 Jonathan Rascher + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +#include "led.h" + +/* Keyboard status passed to the oled_task_keymap function and used by the + * various keyboard pet implementations. + */ +typedef struct { + uint8_t mods; + led_t leds; + uint8_t wpm; +} oled_keyboard_state_t; + +/* Note: Functions below assume a vertical OLED that is 32px (5 chars) wide. */ + +/* Renders layer status at the cursor. Occupies 5x1 character cells. */ +void render_oled_layers(void); + +/* Renders LED indicators (Num/Caps/Scroll Lock) at the cursor. Occupies 5x3 + * character cells. + */ +void render_oled_indicators(led_t leds); + +/* Renders calculated WPM count at the cursor. Occupies 5x2 character cells. */ +void render_oled_wpm(uint8_t wpm); + +#if defined(BCAT_OLED_PET) +/* Renders an animated critter at the cursor that can respond to keystrokes, + * typing speed, etc. Should be about 5 character cells wide, but exact height + * varies depending on the specific OLED pet implementation linked in. + * + * The rendered image will be one line taller than the OLED pet's animation + * frame height to accommodate pets that "jump" when the spacebar is pressed. + */ +void render_oled_pet(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state); +#endif diff --git a/users/bcat/bcat_oled_pet.h b/users/bcat/bcat_oled_pet.h new file mode 100644 index 000000000..ba8227ab6 --- /dev/null +++ b/users/bcat/bcat_oled_pet.h @@ -0,0 +1,73 @@ +/* Copyright 2021 Jonathan Rascher + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Common interface for an OLED pet (animated critter that reacts to typing). + * Please link exactly one accompanying .c file to implement these functions. + */ + +#pragma once + +#include +#include + +#include "bcat_oled.h" + +/* Opaque token representing a single frame of the OLED pet animation. + * Different pet implementations have different valid state values, but the + * zero value must always represent the default state of the pet at startup. + */ +typedef uint16_t oled_pet_state_t; + +/* Returns the number of bytes used to represent the animation frame (in + * oled_write_raw_P format). Note that every state the pet supports is expected + * to have the same frame size. + */ +uint16_t oled_pet_frame_bytes(void); + +/* Returns the number of lines of the OLED occupied by the animation. Note that + * every state the pet supports is expected to have the same frame size. The + * returned value does not include the one line of padding that render_oled_pet + * uses to account for "jumping". + */ +uint8_t oled_pet_frame_lines(void); + +/* Returns whether or not the OLED pet should "jump" when the spacebar is + * pressed. (The render_oled_pet implementation shifts the animation frame up + * one line when this happens.) + */ +bool oled_pet_can_jump(void); + +/* Returns the delay before the next animation frame should be displayed. */ +uint16_t oled_pet_update_millis(const oled_keyboard_state_t *keyboard_state); + +/* Returns the state of the pet to be animated on the next animation tick. */ +oled_pet_state_t oled_pet_next_state(oled_pet_state_t state, const oled_keyboard_state_t *keyboard_state); + +/* Called after the OLED pet is rendered during each OLED task invocation. + * Receives the same keyboard state as render_oled_pet. The redraw param + * indicates whether or not an OLED frame was just redrawn, allowing a specific + * pet implementation to draw custom things atop its animation frames. + * + * When this function is called, the cursor will be in an unspecified location, + * not necessarily the top-left corner of the OLED pet. + */ +void oled_pet_post_render(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state, bool redraw); + +/* Returns a PROGMEM pointer to the specified frame buffer for the specified + * state. The animation frame has length given by oled_pet_frame_bytes and is + * formatted as expected by oled_write_raw_P. + */ +const char *oled_pet_frame(oled_pet_state_t state); diff --git a/users/bcat/bcat_oled_pet_isda.c b/users/bcat/bcat_oled_pet_isda.c new file mode 100644 index 000000000..98abddb13 --- /dev/null +++ b/users/bcat/bcat_oled_pet_isda.c @@ -0,0 +1,134 @@ +/* Copyright 2018 sparrow666 + * Copyright 2021 Jonathan Rascher + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* OLED pet "Isda" (animated unicorn) featuring artwork by OpenGameArt user + * sparrow666, licensed under GPL v2.0. + * + * The animation is 32x72 pixels (9 lines tall). + * + * Runs faster the quicker you type. Shows LED indicator (Num/Caps/Scroll Lock) + * status in the bottom-right corner. + * + * Named after the goddess Ehlonna's personal unicorn in the first D&D campaign + * I ever played. :) + * + * Artwork source: https://opengameart.org/content/unicorn-2 + */ + +#include "bcat_oled_pet.h" + +#include +#include + +#include "bcat_oled.h" +#include "led.h" +#include "oled_driver.h" +#include "progmem.h" + +#define NUM_FRAMES 4 +#define FRAME_BYTES 288 /* (32 pixel) * (72 pixel) / (8 pixel/byte) */ + +uint16_t oled_pet_frame_bytes(void) { return FRAME_BYTES; } +uint8_t oled_pet_frame_lines(void) { return 9 /* (72 pixel) / (8 pixel/line) */; } +bool oled_pet_can_jump(void) { return false; } + +uint16_t oled_pet_update_millis(const oled_keyboard_state_t *keyboard_state) { + static const uint16_t MIN_MILLIS = 75; + static const uint16_t MAX_MILLIS = 300; + static const uint8_t MAX_WPM = 150; + uint8_t wpm = keyboard_state->wpm; + if (wpm > MAX_WPM) { + wpm = MAX_WPM; + } + return MAX_MILLIS - (MAX_MILLIS - MIN_MILLIS) * wpm / MAX_WPM; +} + +oled_pet_state_t oled_pet_next_state(oled_pet_state_t state, const oled_keyboard_state_t *keyboard_state) { + /* When the user stops typing, cycle the animation to frame 0 and stop. */ + return state != 0 || keyboard_state->wpm > 0 ? (state + 1) % NUM_FRAMES : 0; +} + +void oled_pet_post_render(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state, bool redraw) { + /* Draws LED indicator status in the bottom-right corner of the OLED pet, + * atop the animation frame. Redrawn only when necessary, e.g., when LED + * status changes or the animation itself updated (which overwrites any + * previously drawn indicators). + */ + static led_t prev_leds = {.raw = 0}; + led_t leds = keyboard_state->leds; + if (redraw || leds.raw != prev_leds.raw) { + oled_set_cursor(col + 4, line + 4); + oled_write_char(leds.num_lock ? 'N' : ' ', /*invert=*/false); + oled_set_cursor(col + 4, line + 6); + oled_write_char(leds.caps_lock ? 'C' : ' ', /*invert=*/false); + oled_set_cursor(col + 4, line + 8); + oled_write_char(leds.scroll_lock ? 'S' : ' ', /*invert=*/false); + prev_leds = leds; + } +} + +const char *oled_pet_frame(oled_pet_state_t state) { + static const char PROGMEM FRAMES[NUM_FRAMES][FRAME_BYTES] = { + // clang-format off + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88, 0xd0, 0x78, 0x04, 0x28, 0x70, 0x60, 0x90, 0x88, 0xc4, 0x22, 0x19, 0x04, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x84, 0x8c, 0x08, 0x01, 0x01, 0x02, 0x02, 0x04, 0x88, 0xf0, 0x00, + 0xc0, 0xe0, 0xe0, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0xff, 0xff, 0xff, 0x7f, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0x3c, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x03, 0xc6, 0x3c, 0x00, 0x80, 0x70, 0x1c, 0x0f, 0x03, 0x0f, 0x3f, 0xff, 0xff, 0xfc, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x80, 0xe0, 0xf8, 0xfe, 0x7f, 0x1f, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x0e, 0x30, 0x40, 0x47, 0x4f, 0x77, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0xa0, 0xf0, 0x08, 0x50, 0xe0, 0xc0, 0x20, 0x10, 0x88, 0x44, 0x32, 0x09, 0x06, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x11, 0x03, 0x02, 0x04, 0x04, 0x08, 0x10, 0xe0, 0x00, + 0xc0, 0xe0, 0xe0, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x3f, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00, + 0x00, 0x1f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x03, 0x00, 0x00, 0x80, 0xc0, 0x20, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0x3c, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x03, 0xc6, 0x3c, 0x00, 0x80, 0x70, 0x18, 0x0f, 0x03, 0x0f, 0x3f, 0xff, 0xff, 0xfc, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x38, 0x07, 0xc0, 0x38, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x7f, 0xff, 0xff, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x20, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x0f, 0x0f, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0xa0, 0xf0, 0x08, 0x50, 0xe0, 0xc0, 0x20, 0x10, 0x88, 0x44, 0x32, 0x09, 0x06, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x11, 0x03, 0x02, 0x04, 0x04, 0x08, 0x10, 0xe0, 0x00, + 0xc0, 0xc0, 0xc0, 0x20, 0x20, 0x10, 0x08, 0x04, 0x03, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x3f, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00, + 0x00, 0x1f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x03, 0x00, 0x00, 0x80, 0xc0, 0x20, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x03, 0xc3, 0xfe, 0xfe, 0xfc, 0x7c, 0x1c, 0x0c, 0x0c, 0x08, 0x10, 0x60, 0x83, 0x07, 0x18, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x71, 0x0e, 0x80, 0x70, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x0f, 0x3f, 0x7f, 0x7f, 0x78, 0xe0, 0x90, 0x88, 0x66, 0x11, 0x08, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xa0, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88, 0xd0, 0x78, 0x04, 0x28, 0x70, 0x60, 0x90, 0x88, 0xc4, 0x22, 0x19, 0x04, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x84, 0x8c, 0x08, 0x01, 0x01, 0x02, 0x02, 0x04, 0x88, 0xf0, 0x00, + 0xc0, 0xe0, 0xe0, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0xff, 0xff, 0xff, 0x7f, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0xfc, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x03, 0xc6, 0xfc, 0xfc, 0xfc, 0x7c, 0x18, 0x08, 0x08, 0x08, 0x30, 0xc0, 0x03, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0xf8, 0xff, 0xff, 0x3f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x70, 0x80, 0x1f, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3e, 0x3f, 0x3f, 0x1f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0c, 0x09, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + // clang-format on + }; + return FRAMES[state]; +} diff --git a/users/bcat/bcat_oled_pet_luna.c b/users/bcat/bcat_oled_pet_luna.c new file mode 100644 index 000000000..f0397c9c0 --- /dev/null +++ b/users/bcat/bcat_oled_pet_luna.c @@ -0,0 +1,168 @@ +/* Copyright 2021 HellSingCoder + * Copyright 2021 Jonathan Rascher + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* OLED pet "Luna" (animated doggo) originally by HellSingCoder + * (https://www.simonepellegrino.com/) and licensed under GPL v2.0, adapted to + * fit the OLED pet framework in bcat's userspace. + * + * The animation is 32x24 pixels (3 lines tall). + * + * Walks or runs in response to typing speed. Sneaks when Ctrl is pressed and + * barks when Caps Lock is on. Jumps when space is pressed. + * + * Original source: + * https://github.com/qmk/qmk_firmware/blob/6dfe915e26d7147e6c2bed495d3b01cf5b21e6ec/keyboards/sofle/keymaps/helltm/keymap.c + */ + +#include "bcat_oled_pet.h" + +#include +#include + +#include "bcat_oled.h" +#include "keycode.h" +#include "progmem.h" + +enum image { + IMAGE_IDLE, + IMAGE_WALK, + IMAGE_RUN, + IMAGE_SNEAK, + IMAGE_BARK, +}; + +typedef union { + oled_pet_state_t raw; + struct { + uint8_t image; + uint8_t frame; + }; +} luna_state_t; + +#define NUM_FRAMES 2 +#define FRAME_BYTES 96 /* (32 pixel) * (24 pixel) / (8 pixel/byte) */ + +uint16_t oled_pet_frame_bytes(void) { return FRAME_BYTES; } +uint8_t oled_pet_frame_lines(void) { return 3 /* (24 pixel) / (8 pixel/line) */; } +bool oled_pet_can_jump(void) { return true; } + +uint16_t oled_pet_update_millis(const oled_keyboard_state_t *keyboard_state) { return 200; } + +oled_pet_state_t oled_pet_next_state(oled_pet_state_t state, const oled_keyboard_state_t *keyboard_state) { + luna_state_t luna_state = {.raw = state}; + if (keyboard_state->leds.caps_lock) { + luna_state.image = IMAGE_BARK; + } else if (keyboard_state->mods & MOD_MASK_CTRL) { + luna_state.image = IMAGE_SNEAK; + } else if (keyboard_state->wpm >= 100) { + luna_state.image = IMAGE_RUN; + } else if (keyboard_state->wpm >= 25) { + luna_state.image = IMAGE_WALK; + } else { + luna_state.image = IMAGE_IDLE; + } + luna_state.frame = (luna_state.frame + 1) % NUM_FRAMES; + return luna_state.raw; +} + +void oled_pet_post_render(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state, bool redraw) {} + +const char *oled_pet_frame(oled_pet_state_t state) { + static const char PROGMEM IDLE_FRAMES[NUM_FRAMES][FRAME_BYTES] = { + // clang-format off + { + 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, + }, + { + 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, + }, + // clang-format on + }; + static const char PROGMEM WALK_FRAMES[NUM_FRAMES][FRAME_BYTES] = { + // clang-format off + { + 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, + }, + { + 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, + }, + // clang-format on + }; + static const char PROGMEM RUN_FRAMES[NUM_FRAMES][FRAME_BYTES] = { + // clang-format off + { + 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, + }, + { + 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, + }, + // clang-format on + }; + static const char PROGMEM SNEAK_FRAMES[NUM_FRAMES][FRAME_BYTES] = { + // clang-format off + { + 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, + }, + { + 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, + }, + // clang-format on + }; + static const char PROGMEM BARK_FRAMES[NUM_FRAMES][FRAME_BYTES] = { + // clang-format off + { + 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, + }, + { + 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, + }, + // clang-format on + }; + luna_state_t luna_state = {.raw = state}; + switch (luna_state.image) { + case IMAGE_WALK: + return WALK_FRAMES[luna_state.frame]; + case IMAGE_RUN: + return RUN_FRAMES[luna_state.frame]; + case IMAGE_SNEAK: + return SNEAK_FRAMES[luna_state.frame]; + case IMAGE_BARK: + return BARK_FRAMES[luna_state.frame]; + default: + return IDLE_FRAMES[luna_state.frame]; + } +} diff --git a/users/bcat/bcat_rgblight.c b/users/bcat/bcat_rgblight.c new file mode 100644 index 000000000..cd6222262 --- /dev/null +++ b/users/bcat/bcat_rgblight.c @@ -0,0 +1,22 @@ +/* Copyright 2021 Jonathan Rascher + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "progmem.h" + +/* Adjust RGB static hue ranges for shorter gradients than default. */ +const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 127, 63, 31, 15}; diff --git a/users/bcat/compile.sh b/users/bcat/compile.sh new file mode 100755 index 000000000..81551f0ec --- /dev/null +++ b/users/bcat/compile.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +set -o errexit -o nounset + +usage () { + printf "\ +usage: ./users/bcat/compile.sh [-c] [-j N] + +Compiles all keyboards for which bcat maintains keymaps. + +optional arguments: + -c performs a clean build + -j N runs N make tasks in parallel + -v shows verbose output +" +} + +compile () { + local keyboard=$1 layout=${2:-} + FORCE_LAYOUT="$layout" SILENT="$opt_silent" make -j "$opt_parallel" "$keyboard":bcat +} + +opt_parallel=1 +opt_silent=true + +while getopts :chj:v opt; do + case $opt in + c) opt_clean=1 ;; + j) opt_parallel=$OPTARG ;; + v) opt_silent=false ;; + h) usage; exit 0 ;; + \?) usage >&2; exit 2 ;; + esac +done + +if [[ -n ${opt_clean:-} ]]; then + SILENT="$opt_silent" make clean +fi + +compile 9key +compile ai03/polaris 60_tsangan_hhkb +compile cannonkeys/an_c 60_tsangan_hhkb +compile cannonkeys/instant60 60_tsangan_hhkb +compile crkbd/rev1 split_3x6_3 +compile dz60 60_ansi_split_bs_rshift +compile dz60 60_tsangan_hhkb +compile eco/rev2 +compile kbdfans/kbd67/hotswap 65_ansi_blocker_split_bs +compile keebio/bdn9/rev1 +compile keebio/quefrency/rev1 +compile lily58/rev1 diff --git a/users/bcat/config.h b/users/bcat/config.h index 5bb93f383..7bb5d71ba 100644 --- a/users/bcat/config.h +++ b/users/bcat/config.h @@ -14,6 +14,12 @@ * along with this program. If not, see . */ +/* Enable NKRO by default. All my devices support this, and it enables me to + * dispense with the NK_TOGG key, thus saving firmware space by not compiling + * magic keycode support. + */ +#define FORCE_NKRO + /* Wait between tap_code register and unregister to fix flaky media keys. */ #undef TAP_CODE_DELAY @@ -31,6 +37,22 @@ */ #define TAPPING_FORCE_HOLD +#if defined(OLED_ENABLE) +/* The built-in OLED timeout wakes the OLED screen every time the buffer is + * updated, even if no user activity has occurred recently. This prevents the + * OLED from ever turning off during a continuously running animation. To avoid + * this, we disable the default timeout and implement our own in + * oled_task_user. + */ +# undef OLED_TIMEOUT +# define OLED_DISABLE_TIMEOUT + +# if defined(SPLIT_KEYBOARD) +/* Sync OLED on/off state between halves of split keyboards. */ +# define SPLIT_OLED_ENABLE +# endif +#endif + #if defined(RGB_MATRIX_ENABLE) /* Turn off per-key RGB when the host goes to sleep. */ # define RGB_DISABLE_WHEN_USB_SUSPENDED @@ -46,9 +68,42 @@ # define RGB_MATRIX_VAL_STEP 17 # define RGB_MATRIX_SPD_STEP 17 -/* Turn on additional RGB animations. */ +/* Enable specific per-key animation modes. */ +# define ENABLE_RGB_MATRIX_ALPHAS_MODS +# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT +# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL +# define ENABLE_RGB_MATRIX_BAND_SAT +# define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT +# define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL +# define ENABLE_RGB_MATRIX_BAND_VAL +# define ENABLE_RGB_MATRIX_BREATHING +# define ENABLE_RGB_MATRIX_CYCLE_ALL +# define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT +# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN +# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL +# define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL +# define ENABLE_RGB_MATRIX_CYCLE_SPIRAL +# define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN +# define ENABLE_RGB_MATRIX_DUAL_BEACON +# define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT +# define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN +# define ENABLE_RGB_MATRIX_HUE_BREATHING +# define ENABLE_RGB_MATRIX_HUE_PENDULUM +# define ENABLE_RGB_MATRIX_HUE_WAVE +# define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS +# define ENABLE_RGB_MATRIX_PIXEL_FRACTAL +# define ENABLE_RGB_MATRIX_PIXEL_RAIN +# define ENABLE_RGB_MATRIX_RAINBOW_BEACON +# define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON +# define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS +# define ENABLE_RGB_MATRIX_RAINDROPS + +/* Enable additional per-key animation modes that require a copy of the + * framebuffer (with accompanying storage cost). + */ # define RGB_MATRIX_FRAMEBUFFER_EFFECTS -# define RGB_MATRIX_KEYPRESSES +# define ENABLE_RGB_MATRIX_DIGITAL_RAIN +# define ENABLE_RGB_MATRIX_TYPING_HEATMAP #endif #if defined(RGBLIGHT_ENABLE) @@ -64,8 +119,18 @@ # define RGBLIGHT_SAT_STEP 17 # define RGBLIGHT_VAL_STEP 17 -/* Turn on additional RGB animations. */ -# define RGBLIGHT_ANIMATIONS +/* Enable specific underglow animation modes. (Skip TWINKLE because it seems to + * be broken on ARM: https://github.com/qmk/qmk_firmware/issues/15345.) + */ +# define RGBLIGHT_EFFECT_ALTERNATING +# define RGBLIGHT_EFFECT_BREATHING +# define RGBLIGHT_EFFECT_CHRISTMAS +# define RGBLIGHT_EFFECT_KNIGHT +# define RGBLIGHT_EFFECT_RAINBOW_MOOD +# define RGBLIGHT_EFFECT_RAINBOW_SWIRL +# define RGBLIGHT_EFFECT_RGB_TEST +# define RGBLIGHT_EFFECT_SNAKE +# define RGBLIGHT_EFFECT_STATIC_GRADIENT #endif #if defined(BACKLIGHT_ENABLE) @@ -77,3 +142,9 @@ # define BACKLIGHT_LEVELS 7 #endif + +/* Turn off unused config options to reduce firmware size. */ +#define LAYER_STATE_8BIT +#define NO_ACTION_ONESHOT +#undef LOCKING_RESYNC_ENABLE +#undef LOCKING_SUPPORT_ENABLE diff --git a/users/bcat/readme.md b/users/bcat/readme.md index 1922f95f4..bb73a53bf 100644 --- a/users/bcat/readme.md +++ b/users/bcat/readme.md @@ -6,6 +6,8 @@ keyboard-specific keymaps for boards without standard layout support. I derive my keymaps from two canonical ones (preferred for typing and gaming, respectively). +You can build all keymaps I maintain at once using `./users/bcat/compile.sh`. + ## Canonical keymaps * [Split 3x6 + 3 thumb diff --git a/users/bcat/rules.mk b/users/bcat/rules.mk index 12c9a89bf..bb4bb11d8 100644 --- a/users/bcat/rules.mk +++ b/users/bcat/rules.mk @@ -1,7 +1,10 @@ -SRC += bcat.c - -# Enable Bootmagic Lite to consistently reset to bootloader and clear EEPROM. -BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +# Enable Bootmagic Lite for keyboards that don't have an easily accessible +# reset button, but keep it disabled for all others to reduce firmware size. +ifneq ($(filter $(strip $(KEYBOARD)),ai03/polaris dz60 kbdfans/kbd67/hotswap),) + BOOTMAGIC_ENABLE = yes +else + BOOTMAGIC_ENABLE = no +endif # Enable media keys on all keyboards. EXTRAKEY_ENABLE = yes @@ -16,21 +19,49 @@ NKRO_ENABLE = yes # Enable link-time optimization to reduce binary size. LTO_ENABLE = yes -# Disable unused build options on all keyboards. +# Include common utilities shared across all our keymaps. +SRC += bcat.c + +# Include additional utilities that extend optional QMK features only enabled +# on some keyboards. +ifeq ($(strip $(OLED_ENABLE)), yes) + SRC += bcat_oled.c + WPM_ENABLE = yes # for WPM and animated "keyboard pet" widgets + + # OLED pets (animated critters that react to typing) take up a lot of + # firmware space, so only compile one, and only if requested. + BCAT_OLED_PET ?= no + ifneq ($(strip $(BCAT_OLED_PET)), no) + SRC += bcat_oled_pet_$(strip $(BCAT_OLED_PET)).c + OPT_DEFS += -DBCAT_OLED_PET + endif +endif + +ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) + SRC += bcat_rgblight.c +endif + +# Disable unwanted build options on all keyboards. (Mouse keys are turned off +# due to https://github.com/qmk/qmk_firmware/issues/8323, and the rest are +# turned off to reduce firmware size.) COMMAND_ENABLE = no CONSOLE_ENABLE = no MOUSEKEY_ENABLE = no TERMINAL_ENABLE = no -# Disable unused hardware options on all keyboards. +# Disable unwanted hardware options on all keyboards. (Some keyboards turn +# these features on by default even though they aren't actually required.) MIDI_ENABLE = no SLEEP_LED_ENABLE = no # Disable other unused options on all keyboards. AUTO_SHIFT_ENABLE = no COMBO_ENABLE = no +GRAVE_ESC_ENABLE = no KEY_LOCK_ENABLE = no LEADER_ENABLE = no +MAGIC_ENABLE = no +SPACE_CADET_ENABLE = no SWAP_HANDS_ENABLE = no TAP_DANCE_ENABLE = no UCIS_ENABLE = no