summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keyboards/9key/keymaps/bcat/keymap.c19
-rw-r--r--keyboards/9key/keymaps/bcat/readme.md6
-rw-r--r--keyboards/eco/keymaps/bcat/config.h2
-rw-r--r--keyboards/eco/keymaps/bcat/keymap.c19
-rw-r--r--keyboards/eco/keymaps/bcat/readme.md2
-rw-r--r--keyboards/keebio/bdn9/keymaps/bcat/keymap.c13
-rw-r--r--keyboards/keebio/quefrency/keymaps/bcat/keymap.c13
-rw-r--r--keyboards/keebio/quefrency/keymaps/bcat/readme.md2
-rw-r--r--keyboards/lily58/keymaps/bcat/config.h2
-rw-r--r--keyboards/lily58/keymaps/bcat/keymap.c33
-rw-r--r--keyboards/lily58/keymaps/bcat/readme.md2
-rw-r--r--keyboards/lily58/keymaps/bcat/rules.mk2
-rw-r--r--keyboards/reviung53/config.h138
-rw-r--r--keyboards/reviung53/info.json68
-rw-r--r--keyboards/reviung53/keymaps/default/keymap.c55
-rw-r--r--keyboards/reviung53/keymaps/default/readme.md1
-rw-r--r--keyboards/reviung53/keymaps/via/keymap.c55
-rw-r--r--keyboards/reviung53/keymaps/via/readme.md3
-rw-r--r--keyboards/reviung53/keymaps/via/rules.mk1
-rw-r--r--keyboards/reviung53/readme.md27
-rw-r--r--keyboards/reviung53/reviung53.c4
-rw-r--r--keyboards/reviung53/reviung53.h30
-rw-r--r--keyboards/reviung53/rules.mk19
-rw-r--r--layouts/community/60_ansi_split_bs_rshift/bcat/keymap.c11
-rw-r--r--layouts/community/60_ansi_split_bs_rshift/bcat/readme.md2
-rw-r--r--layouts/community/60_tsangan_hhkb/bcat/keymap.c11
-rw-r--r--layouts/community/60_tsangan_hhkb/bcat/readme.md2
-rw-r--r--layouts/community/65_ansi_blocker_split_bs/bcat/keymap.c13
-rw-r--r--layouts/community/65_ansi_blocker_split_bs/bcat/readme.md2
-rw-r--r--layouts/community/split_3x6_3/bcat/config.h9
-rw-r--r--layouts/community/split_3x6_3/bcat/keymap.c33
-rw-r--r--layouts/community/split_3x6_3/bcat/readme.md2
-rw-r--r--layouts/community/split_3x6_3/bcat/rules.mk4
-rw-r--r--users/bcat/bcat.c10
-rw-r--r--users/bcat/bcat.h36
-rw-r--r--users/bcat/bcat_oled.c216
-rw-r--r--users/bcat/bcat_oled.h55
-rw-r--r--users/bcat/bcat_oled_pet.h73
-rw-r--r--users/bcat/bcat_oled_pet_isda.c134
-rw-r--r--users/bcat/bcat_oled_pet_luna.c168
-rw-r--r--users/bcat/bcat_rgblight.c22
-rwxr-xr-xusers/bcat/compile.sh51
-rw-r--r--users/bcat/config.h79
-rw-r--r--users/bcat/readme.md2
-rw-r--r--users/bcat/rules.mk43
45 files changed, 1360 insertions, 134 deletions
diff --git a/keyboards/9key/keymaps/bcat/keymap.c b/keyboards/9key/keymaps/bcat/keymap.c
index 5c08a42a56..944a48c0d3 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 2dee51de8b..d38ae5463b 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 dffdc7b40a..f2d51c324a 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 d46a7d416b..8c50a9ed55 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 85e2615512..fd9e1bea73 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 c64f702b20..2028deb4f1 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 d28a5083ac..3dd48623fa 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 914aa84b6b..59a691654d 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 dbe724d56b..2ee0071bda 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 69af2ca003..a0856d0fdd 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 de03526a8b..8b0e77e1b7 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 c87b447c1e..62d1007a54 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/keyboards/reviung53/config.h b/keyboards/reviung53/config.h
new file mode 100644
index 0000000000..d73e6eab8a
--- /dev/null
+++ b/keyboards/reviung53/config.h
@@ -0,0 +1,138 @@
+// Copyright 2021 gtips (@gtips)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0x4E94
+#define PRODUCT_ID 0x4E09
+#define DEVICE_VER 0x0001
+#define MANUFACTURER gtips
+#define PRODUCT reviung53
+
+/* key matrix size */
+#define MATRIX_ROWS 7
+#define MATRIX_COLS 8
+
+/*
+ * Keyboard Matrix Assignments
+ *
+ * Change this to how you wired your keyboard
+ * COLS: AVR pins used for columns, left to right
+ * ROWS: AVR pins used for rows, top to bottom
+ * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
+ * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
+ *
+ */
+#define MATRIX_ROW_PINS { D0, D4, C6, D7, E6, B4, B5 }
+#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3, B2, B6 }
+#define UNUSED_PINS
+
+/* COL2ROW, ROW2COL */
+#define DIODE_DIRECTION COL2ROW
+
+/*
+ * Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN.
+ */
+// #define SOFT_SERIAL_PIN D0
+
+//#define LED_NUM_LOCK_PIN B0
+//#define LED_CAPS_LOCK_PIN B1
+//#define LED_SCROLL_LOCK_PIN B2
+//#define LED_COMPOSE_PIN B3
+//#define LED_KANA_PIN B4
+
+//#define BACKLIGHT_PIN B7
+//#define BACKLIGHT_LEVELS 3
+//#define BACKLIGHT_BREATHING
+
+#define RGB_DI_PIN D3
+#ifdef RGB_DI_PIN
+#define RGBLED_NUM 10
+#define RGBLIGHT_HUE_STEP 16
+#define RGBLIGHT_SAT_STEP 16
+#define RGBLIGHT_VAL_STEP 16
+#define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
+#define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
+/*== all animations enable ==*/
+#define RGBLIGHT_ANIMATIONS
+/*== or choose animations ==*/
+//# define RGBLIGHT_EFFECT_BREATHING
+//# define RGBLIGHT_EFFECT_RAINBOW_MOOD
+//# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+//# define RGBLIGHT_EFFECT_SNAKE
+//# define RGBLIGHT_EFFECT_KNIGHT
+//# define RGBLIGHT_EFFECT_CHRISTMAS
+//# define RGBLIGHT_EFFECT_STATIC_GRADIENT
+//# define RGBLIGHT_EFFECT_RGB_TEST
+//# define RGBLIGHT_EFFECT_ALTERNATING
+/*== customize breathing effect ==*/
+/*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/
+//# define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64
+/*==== use exp() and sin() ====*/
+//# define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7
+//# define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255
+#endif
+
+/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
+#define DEBOUNCE 5
+
+/* define if matrix has ghost (lacks anti-ghosting diodes) */
+//#define MATRIX_HAS_GHOST
+
+/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
+#define LOCKING_SUPPORT_ENABLE
+/* Locking resynchronize hack */
+#define LOCKING_RESYNC_ENABLE
+
+/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
+ * This is useful for the Windows task manager shortcut (ctrl+shift+esc).
+ */
+//#define GRAVE_ESC_CTRL_OVERRIDE
+
+/*
+ * Force NKRO
+ *
+ * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
+ * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
+ * makefile for this to work.)
+ *
+ * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
+ * until the next keyboard reset.
+ *
+ * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
+ * fully operational during normal computer usage.
+ *
+ * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
+ * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
+ * bootmagic, NKRO mode will always be enabled until it is toggled again during a
+ * power-up.
+ *
+ */
+//#define FORCE_NKRO
+
+/*
+ * Feature disable options
+ * These options are also useful to firmware size reduction.
+ */
+
+/* disable debug print */
+//#define NO_DEBUG
+
+/* disable print */
+//#define NO_PRINT
+
+/* disable action features */
+//#define NO_ACTION_LAYER
+//#define NO_ACTION_TAPPING
+//#define NO_ACTION_ONESHOT
+
+/* disable these deprecated features by default */
+#define NO_ACTION_MACRO
+#define NO_ACTION_FUNCTION
+
+/* Bootmagic Lite key configuration */
+//#define BOOTMAGIC_LITE_ROW 0
+//#define BOOTMAGIC_LITE_COLUMN 0
diff --git a/keyboards/reviung53/info.json b/keyboards/reviung53/info.json
new file mode 100644
index 0000000000..ff63de5bc8
--- /dev/null
+++ b/keyboards/reviung53/info.json
@@ -0,0 +1,68 @@
+{
+ "keyboard_name": "reviung53",
+ "url": "",
+ "maintainer": "gtips",
+ "layouts": {
+ "LAYOUT_reviung53": {
+ "layout": [
+ {"label": "k02", "x":2.25, "y":0},
+ {"label": "k03", "x":3.5, "y":0},
+ {"label": "k04", "x":4.5, "y":0},
+ {"label": "k05", "x":5.5, "y":0},
+ {"label": "k06", "x":6.5, "y":0},
+ {"label": "k07", "x":7.75, "y":0},
+ {"label": "k40", "x":8.75, "y":0},
+ {"label": "k41", "x":9.75, "y":0},
+ {"label": "k42", "x":10.75, "y":0},
+ {"label": "k43", "x":12, "y":0},
+
+ {"label": "k10", "x":0, "y":1.25, "w":1.5},
+ {"label": "k11", "x":1.5, "y":1.25},
+ {"label": "k12", "x":2.5, "y":1.25},
+ {"label": "k13", "x":3.5, "y":1.25},
+ {"label": "k14", "x":4.5, "y":1.25},
+ {"label": "k15", "x":5.5, "y":1.25},
+ {"label": "k16", "x":6.5, "y":1.25},
+ {"label": "k17", "x":7.5, "y":1.25},
+ {"label": "k44", "x":8.5, "y":1.25},
+ {"label": "k45", "x":9.5, "y":1.25},
+ {"label": "k46", "x":10.5, "y":1.25},
+ {"label": "k47", "x":11.5, "y":1.25, "w":1.5},
+
+ {"label": "k20", "x":0, "y":2.25, "w":1.75},
+ {"label": "k21", "x":1.75, "y":2.25},
+ {"label": "k22", "x":2.75, "y":2.25},
+ {"label": "k23", "x":3.75, "y":2.25},
+ {"label": "k24", "x":4.75, "y":2.25},
+ {"label": "k25", "x":5.75, "y":2.25},
+ {"label": "k26", "x":6.75, "y":2.25},
+ {"label": "k27", "x":7.75, "y":2.25},
+ {"label": "k50", "x":8.75, "y":2.25},
+ {"label": "k51", "x":9.75, "y":2.25},
+ {"label": "k52", "x":10.75, "y":2.25},
+ {"label": "k53", "x":11.75, "y":2.25, "w":1.25},
+
+ {"label": "k30", "x":0, "y":3.25, "w":2.25},
+ {"label": "k31", "x":2.25, "y":3.25},
+ {"label": "k32", "x":3.25, "y":3.25},
+ {"label": "k33", "x":4.25, "y":3.25},
+ {"label": "k34", "x":5.25, "y":3.25},
+ {"label": "k35", "x":6.25, "y":3.25},
+ {"label": "k36", "x":7.25, "y":3.25},
+ {"label": "k37", "x":8.25, "y":3.25},
+ {"label": "k54", "x":9.25, "y":3.25},
+ {"label": "k55", "x":10.25, "y":3.25},
+ {"label": "k56", "x":11.25, "y":3.25, "w":1.75},
+
+ {"label": "k60", "x":0, "y":4.25, "w":1.5},
+ {"label": "k61", "x":1.5, "y":4.25, "w":1.25},
+ {"label": "k62", "x":2.75, "y":4.25, "w":1.25},
+ {"label": "k63", "x":4, "y":4.25, "w":2.75},
+ {"label": "k64", "x":6.75, "y":4.25, "w":2.25},
+ {"label": "k65", "x":9, "y":4.25, "w":1.25},
+ {"label": "k66", "x":10.25, "y":4.25, "w":1.25},
+ {"label": "k67", "x":11.5, "y":4.25, "w":1.5}
+ ]
+ }
+ }
+}
diff --git a/keyboards/reviung53/keymaps/default/keymap.c b/keyboards/reviung53/keymaps/default/keymap.c
new file mode 100644
index 0000000000..a8d95d70d5
--- /dev/null
+++ b/keyboards/reviung53/keymaps/default/keymap.c
@@ -0,0 +1,55 @@
+// Copyright 2021 gtips (@gtips)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+// Defines names for use in layer keycodes and the keymap
+enum layer_names {
+ _BASE,
+ _LOWER,
+ _RAISE,
+ _ADJUST
+};
+
+#define LOWER MO(_LOWER)
+#define RAISE MO(_RAISE)
+#define ADJUST MO(_ADJUST)
+
+#define SF_SS RSFT_T(KC_SLSH)
+#define SP_LO LT(LOWER, KC_SPC)
+#define SP_RA LT(RAISE, KC_SPC)
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE] = LAYOUT_reviung53(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_DEL,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, SF_SS,
+ KC_LCTL, KC_LGUI, KC_LALT, SP_LO, SP_RA, KC_LALT, KC_RGUI, KC_RCTL
+ ),
+ [_LOWER] = LAYOUT_reviung53(
+ KC_GESC, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_PAUS, KC_SLCK, KC_PSCR, _______,
+ _______, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______,
+ _______, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, XXXXXXX, KC_QUOT,
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_HOME, KC_END, KC_PGUP, KC_PGDN, KC_SLSH,
+ _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+ [_RAISE] = LAYOUT_reviung53(
+ KC_TILD, KC_F9, KC_F10, KC_F11, KC_F12, KC_MUTE, KC_VOLU, KC_VOLD, KC_MPLY, _______,
+ _______, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______,
+ _______, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_DQUO,
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_QUES,
+ _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+ [_ADJUST] = LAYOUT_reviung53(
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RESET,
+ RGB_VAI, RGB_SAI, RGB_HUI, RGB_MOD, XXXXXXX, RGB_TOG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ RGB_VAD, RGB_SAD, RGB_HUD, RGB_RMOD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX
+ ),
+};
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+ return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
+}
diff --git a/keyboards/reviung53/keymaps/default/readme.md b/keyboards/reviung53/keymaps/default/readme.md
new file mode 100644
index 0000000000..1e473c9a74
--- /dev/null
+++ b/keyboards/reviung53/keymaps/default/readme.md
@@ -0,0 +1 @@
+# The default keymap for reviung53
diff --git a/keyboards/reviung53/keymaps/via/keymap.c b/keyboards/reviung53/keymaps/via/keymap.c
new file mode 100644
index 0000000000..a8d95d70d5
--- /dev/null
+++ b/keyboards/reviung53/keymaps/via/keymap.c
@@ -0,0 +1,55 @@
+// Copyright 2021 gtips (@gtips)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+// Defines names for use in layer keycodes and the keymap
+enum layer_names {
+ _BASE,
+ _LOWER,
+ _RAISE,
+ _ADJUST
+};
+
+#define LOWER MO(_LOWER)
+#define RAISE MO(_RAISE)
+#define ADJUST MO(_ADJUST)
+
+#define SF_SS RSFT_T(KC_SLSH)
+#define SP_LO LT(LOWER, KC_SPC)
+#define SP_RA LT(RAISE, KC_SPC)
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE] = LAYOUT_reviung53(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_DEL,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, SF_SS,
+ KC_LCTL, KC_LGUI, KC_LALT, SP_LO, SP_RA, KC_LALT, KC_RGUI, KC_RCTL
+ ),
+ [_LOWER] = LAYOUT_reviung53(
+ KC_GESC, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_PAUS, KC_SLCK, KC_PSCR, _______,
+ _______, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______,
+ _______, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, XXXXXXX, KC_QUOT,
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_HOME, KC_END, KC_PGUP, KC_PGDN, KC_SLSH,
+ _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+ [_RAISE] = LAYOUT_reviung53(
+ KC_TILD, KC_F9, KC_F10, KC_F11, KC_F12, KC_MUTE, KC_VOLU, KC_VOLD, KC_MPLY, _______,
+ _______, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______,
+ _______, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_DQUO,
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_QUES,
+ _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+ [_ADJUST] = LAYOUT_reviung53(
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RESET,
+ RGB_VAI, RGB_SAI, RGB_HUI, RGB_MOD, XXXXXXX, RGB_TOG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ RGB_VAD, RGB_SAD, RGB_HUD, RGB_RMOD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX
+ ),
+};
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+ return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
+}
diff --git a/keyboards/reviung53/keymaps/via/readme.md b/keyboards/reviung53/keymaps/via/readme.md
new file mode 100644
index 0000000000..9b299ba286
--- /dev/null
+++ b/keyboards/reviung53/keymaps/via/readme.md
@@ -0,0 +1,3 @@
+# The default keymap for reviung53
+
+For use with VIA configurator and compatible keymap editors. \ No newline at end of file
diff --git a/keyboards/reviung53/keymaps/via/rules.mk b/keyboards/reviung53/keymaps/via/rules.mk
new file mode 100644
index 0000000000..1e5b99807c
--- /dev/null
+++ b/keyboards/reviung53/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/reviung53/readme.md b/keyboards/reviung53/readme.md
new file mode 100644
index 0000000000..a2bfbcdbc2
--- /dev/null
+++ b/keyboards/reviung53/readme.md
@@ -0,0 +1,27 @@
+# reviung53
+
+![reviung53](https://github.com/gtips/reviung/blob/master/reviung53/image/reviung53-04.jpg)
+
+The REVIUNG53 is 53-key keyboard.
+
+* Keyboard Maintainer: [gtips](https://github.com/gtips)
+* Hardware Supported: REVIUNG53 PCB.
+* Hardware Availability: [PCB & Case Data](https://github.com/gtips/reviung/tree/master/reviung53)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make reviung53:default
+
+Flashing example for this keyboard:
+
+ make reviung53:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader in 3 ways:
+
+* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
+* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
+* **Keycode in layout**: Press the key mapped to `RESET` if it is available
diff --git a/keyboards/reviung53/reviung53.c b/keyboards/reviung53/reviung53.c
new file mode 100644
index 0000000000..e2190aeccf
--- /dev/null
+++ b/keyboards/reviung53/reviung53.c
@@ -0,0 +1,4 @@
+// Copyright 2021 gtips (@gtips)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "reviung53.h"
diff --git a/keyboards/reviung53/reviung53.h b/keyboards/reviung53/reviung53.h
new file mode 100644
index 0000000000..89ebc45c18
--- /dev/null
+++ b/keyboards/reviung53/reviung53.h
@@ -0,0 +1,30 @@
+// Copyright 2021 gtips (@gtips)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "quantum.h"
+
+/* This is a shortcut to help you visually see your layout.
+ *
+ * The first section contains all of the arguments representing the physical
+ * layout of the board and position of the keys.
+ *
+ * The second converts the arguments into a two-dimensional array which
+ * represents the switch matrix.
+ */
+#define LAYOUT_reviung53( \
+ K02, K03, K04, K05, K06, K07, K40, K41, K42, K43, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K44, K45, K46, K47, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K50, K51, K52, K53, \
+ K30, K31, K32, K33, K34, K35, K36, K37, K54, K55, K56,\
+ K60, K61, K62, K63, K64, K65, K66, K67 \
+) { \
+ { KC_NO, KC_NO, K02, K03, K04, K05, K06, K07 }, \
+ { K10, K11, K12, K13, K14, K15, K16, K17 }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27 }, \
+ { K30, K31, K32, K33, K34, K35, K36, K37 }, \
+ { K40, K41, K42, K43, K44, K45, K46, K47 }, \
+ { K50, K51, K52, K53, K54, K55, K56, KC_NO }, \
+ { K60, K61, K62, K63, K64, K65, K66, K67 } \
+}
diff --git a/keyboards/reviung53/rules.mk b/keyboards/reviung53/rules.mk
new file mode 100644
index 0000000000..90670e4b9e
--- /dev/null
+++ b/keyboards/reviung53/rules.mk
@@ -0,0 +1,19 @@
+# MCU name
+MCU = atmega32u4
+
+# Bootloader selection
+BOOTLOADER = caterina
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
+MOUSEKEY_ENABLE = no # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = no # Console for debug
+COMMAND_ENABLE = no # Commands for debug and configuration
+# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+NKRO_ENABLE = no # USB Nkey Rollover
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
+AUDIO_ENABLE = no # Audio output
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 6bfafc3325..b40148e995 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 2d578aa3d3..f6bcda9197 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 05e6462d90..9ec75f3c4d 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 b7a3cde5d2..c8d0d72dd0 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 c91a1b0ead..c099d36e25 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 0726cbecee..5777c7c38f 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 b8743429cf..556fb90d5f 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 4f68c8f843..cfac93d1e3 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 c4bf891c40..b7b5d3de7d 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 5ee614b192..29e52b92db 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 f21d282e43..3a407cfac0 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 0dae774ec5..4a88acba7d 100644
--- a/users/bcat/bcat.h
+++ b/users/bcat/bcat.h
@@ -16,9 +16,43 @@
#pragma once
-#include "quantum.h"
+#include <stdbool.h>
+#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 0000000000..390c9127b4
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 0000000000..f617e1f064
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#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 0000000000..ba8227ab61
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+/* 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 <stdbool.h>
+#include <stdint.h>
+
+#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 0000000000..98abddb13b
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+/* 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 <stdbool.h>
+#include <stdint.h>
+
+#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 0000000000..f0397c9c05
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+/* 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 <stdbool.h>
+#include <stdint.h>
+
+#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 0000000000..cd6222262b
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdint.h>
+
+#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 0000000000..81551f0ec0
--- /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 5bb93f3833..7bb5d71bae 100644
--- a/users/bcat/config.h
+++ b/users/bcat/config.h
@@ -14,6 +14,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/* 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 1922f95f4a..bb73a53bf8 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 12c9a89bf4..bb4bb11d88 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