Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Keymap] Update bcat's keymaps/userspace to share logic, add OLED functionality, and set up one of my macropads for WFH #14702

Merged
merged 23 commits into from
Dec 27, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8084c71
Add script to build all bcat keymaps at once
bcat Jun 20, 2021
8083630
Move userspace RGB to separate source file
bcat Jun 20, 2021
fb73247
Move layer handling logic into userspace
bcat Jun 20, 2021
0e27a3e
Move keycap aliases into userspace
bcat Jun 20, 2021
38eaf30
Add OLED userspace library and Lily58 OLED setup
bcat Jun 20, 2021
2c940d5
Add Luna keyboard pet, generic OLED pet framework
bcat Jun 20, 2021
d42d567
Use OLED on bcat's Crkbd
bcat Jun 20, 2021
eed58f2
Remove vestigial NK_TOGG keybindings
bcat Jun 20, 2021
0f0f71d
Add post-render hook to OLED pet API
bcat Jun 21, 2021
a68cdac
Add Isda keyboard pet
bcat Jun 21, 2021
45d6909
Replace OLED timeout implementation with custom
bcat Jun 23, 2021
bc95ebb
Move keyboard state for OLED functions into struct
bcat Jun 23, 2021
e07d941
Enable continuously running OLED pet (for Luna)
bcat Jun 26, 2021
23930f6
Sync OLED state; enable Bootmagic only when needed
bcat Oct 4, 2021
bf46471
Update 9-Key macropad keymap for working from home
bcat Oct 4, 2021
e0f292e
Remove includes redundant with quantum.h
bcat Oct 5, 2021
2ab419b
Simplify BCAT_OLED_PET makefile logic
bcat Oct 5, 2021
aada1c1
Swap some keys on my 9-Key macropad around
bcat Oct 8, 2021
d13f869
Inline spurious variable in OLED code
bcat Nov 24, 2021
1d18c9d
Remove max brightness that's now set by default
bcat Nov 24, 2021
cfcffdd
Enable specific RGBLIGHT modes instead of default
bcat Nov 28, 2021
0b9ae7b
Reenable RGB_MATRIX animations after #15018
bcat Nov 28, 2021
a3efc6b
Use new get_u8_str function for WPM display
bcat Nov 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move keyboard state for OLED functions into struct
No change in firmware size, but makes keymaps read a little nicer and
enables more functionality in OLED pets.
  • Loading branch information
bcat committed Dec 2, 2021
commit bc95ebb56a10c22f494bd977f2da3f7ec9e05454
13 changes: 4 additions & 9 deletions keyboards/lily58/keymaps/bcat/keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
#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(void) {
void oled_task_keymap(const oled_keyboard_state_t *keyboard_state) {
if (is_keyboard_master()) {
uint8_t mods = get_mods();
led_t leds = host_keyboard_led_state();
uint8_t wpm = get_current_wpm();

render_oled_layers();
oled_advance_page(/*clearPageRemainder=*/false);
render_oled_indicators(leds);
render_oled_indicators(keyboard_state->leds);
oled_advance_page(/*clearPageRemainder=*/false);
oled_advance_page(/*clearPageRemainder=*/false);
render_oled_wpm(wpm);

render_oled_pet(/*col=*/0, /*line=*/12, mods, leds, wpm);
render_oled_wpm(keyboard_state->wpm);
render_oled_pet(/*col=*/0, /*line=*/12, keyboard_state);
} else {
render_oled_logo();
}
Expand Down
13 changes: 4 additions & 9 deletions layouts/community/split_3x6_3/bcat/keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
#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(void) {
void oled_task_keymap(const oled_keyboard_state_t *keyboard_state) {
if (is_keyboard_master()) {
uint8_t mods = get_mods();
led_t leds = host_keyboard_led_state();
uint8_t wpm = get_current_wpm();

render_oled_layers();
oled_advance_page(/*clearPageRemainder=*/false);
render_oled_indicators(leds);
render_oled_indicators(keyboard_state->leds);
oled_advance_page(/*clearPageRemainder=*/false);
oled_advance_page(/*clearPageRemainder=*/false);
render_oled_wpm(wpm);

render_oled_pet(/*col=*/0, /*line=*/12, mods, leds, wpm);
render_oled_wpm(keyboard_state->wpm);
render_oled_pet(/*col=*/0, /*line=*/12, keyboard_state);
} else {
render_oled_logo();
}
Expand Down
22 changes: 15 additions & 7 deletions users/bcat/bcat_oled.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@
#include <stdbool.h>
#include <stdint.h>

#include "action_util.h"
#include "bcat.h"
#include "host.h"
#include "keycode.h"
#include "led.h"
#include "oled_driver.h"
#include "progmem.h"
#include "quantum.h"
#include "timer.h"
#include "wpm.h"

#if defined(BCAT_OLED_PET)
# include "bcat_oled_pet.h"
Expand All @@ -38,7 +41,7 @@
static bool oled_pet_should_jump = false;
#endif

__attribute__((weak)) void oled_task_keymap(void) {}
__attribute__((weak)) void oled_task_keymap(const oled_keyboard_state_t *keyboard_state) {}

bool oled_task_user(void) {
static const uint16_t TIMEOUT_MILLIS = 60000 /* 1 min */;
Expand All @@ -51,7 +54,12 @@ bool oled_task_user(void) {
if (!on) {
oled_on();
}
oled_task_keymap();
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 (on) {
oled_off();
}
Expand Down Expand Up @@ -158,7 +166,7 @@ static void redraw_oled_pet(uint8_t col, uint8_t line, bool jumping, oled_pet_st
}
}

void render_oled_pet(uint8_t col, uint8_t line, uint8_t mods, led_t leds, uint8_t wpm) {
void render_oled_pet(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state) {
/* Whether or not the animation state or frame has changed since the pet
* was last drawn. We track this to avoid redrawing the same frame
* repeatedly during idle. This allows the caller to draw on top of the pet
Expand Down Expand Up @@ -196,23 +204,23 @@ void render_oled_pet(uint8_t col, uint8_t line, uint8_t mods, led_t leds, uint8_
if (redraw) {
redraw_oled_pet(col, line, jumping, state, frame);
}
oled_pet_post_render(col, line, jumping, mods, leds, wpm, redraw);
oled_pet_post_render(col, line, keyboard_state, jumping, redraw);
oled_set_cursor(col, line + oled_pet_frame_lines() + 1);

/* If the update timer expired, recompute the pet's animation state and
* possibly advance to the next frame.
*/
animation_changed = false;
if (timer_expired32(timer_read32(), update_timeout)) {
oled_pet_state_t new_state = oled_pet_state(mods, leds, wpm);
oled_pet_state_t new_state = oled_pet_state(keyboard_state);
if (state != new_state) {
state = new_state;
animation_changed = true;
}
/* If the user stopped typing, cycle around to the initial frame. */
if (wpm > 0 || state != OLED_PET_IDLE || frame != 0) {
if (keyboard_state->wpm > 0 || state != OLED_PET_IDLE || frame != 0) {
frame = (frame + 1) % oled_pet_num_frames();
update_timeout = timer_read32() + oled_pet_update_millis(wpm);
update_timeout = timer_read32() + oled_pet_update_millis(keyboard_state);
animation_changed = true;
}
}
Expand Down
11 changes: 10 additions & 1 deletion users/bcat/bcat_oled.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@

#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;

/* Renders the logo embedded at the "standard" location in the OLED font at the
* cursor. By default, this is a "QMK Firmware" logo, but many keyboards put
* their own logo here instead. Occupies 21x3 character cells.
Expand Down Expand Up @@ -48,5 +57,5 @@ void render_oled_wpm(uint8_t wpm);
* 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, uint8_t mods, led_t leds, uint8_t wpm);
void render_oled_pet(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state);
#endif
20 changes: 10 additions & 10 deletions users/bcat/bcat_oled_pet.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include <stdbool.h>
#include <stdint.h>

#include "led.h"
#include "bcat_oled.h"

/* Opaque token identifying what animation state the pet is currently in. */
typedef uint8_t oled_pet_state_t;
Expand Down Expand Up @@ -56,16 +56,10 @@ uint8_t oled_pet_frame_lines(void);
bool oled_pet_can_jump(void);

/* Returns the current state to be animated based on current keyboard state. */
oled_pet_state_t oled_pet_state(uint8_t mods, led_t leds, uint8_t wpm);
oled_pet_state_t oled_pet_state(const oled_keyboard_state_t *keyboard_state);

/* Returns the delay before the next animation frame should be displayed. */
uint16_t oled_pet_update_millis(uint8_t wpm);

/* Returns a PROGMEM pointer to the specified animation 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, uint8_t frame);
uint16_t oled_pet_update_millis(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
Expand All @@ -75,4 +69,10 @@ const char *oled_pet_frame(oled_pet_state_t state, uint8_t frame);
* 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, bool jumping, uint8_t mods, led_t leds, uint8_t wpm, bool redraw);
void oled_pet_post_render(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state, bool jumping, bool redraw);

/* Returns a PROGMEM pointer to the specified animation 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, uint8_t frame);
48 changes: 27 additions & 21 deletions users/bcat/bcat_oled_pet_isda.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <stdbool.h>
#include <stdint.h>

#include "bcat_oled.h"
#include "led.h"
#include "oled_driver.h"
#include "progmem.h"
Expand All @@ -46,13 +47,36 @@ 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; }

oled_pet_state_t oled_pet_state(uint8_t mods, led_t led_state, uint8_t wpm) { return OLED_PET_IDLE; }
oled_pet_state_t oled_pet_state(const oled_keyboard_state_t *keyboard_state) { return OLED_PET_IDLE; }

uint16_t oled_pet_update_millis(uint8_t wpm) {
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;
return MAX_MILLIS - (MAX_MILLIS - MIN_MILLIS) * (wpm > MAX_WPM ? MAX_WPM : wpm) / MAX_WPM;
uint8_t wpm = keyboard_state->wpm;
if (wpm > MAX_WPM) {
wpm = MAX_WPM;
}
return MAX_MILLIS - (MAX_MILLIS - MIN_MILLIS) * wpm / MAX_WPM;
}

void oled_pet_post_render(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state, bool jumping, 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 + !jumping + 4);
oled_write_char(leds.num_lock ? 'N' : ' ', /*invert=*/false);
oled_set_cursor(col + 4, line + !jumping + 6);
oled_write_char(leds.caps_lock ? 'C' : ' ', /*invert=*/false);
oled_set_cursor(col + 4, line + !jumping + 8);
oled_write_char(leds.scroll_lock ? 'S' : ' ', /*invert=*/false);
prev_leds = leds;
}
}

const char *oled_pet_frame(oled_pet_state_t state, uint8_t frame) {
Expand Down Expand Up @@ -106,21 +130,3 @@ const char *oled_pet_frame(oled_pet_state_t state, uint8_t frame) {
};
return FRAMES[frame];
}

/* 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).
*/
void oled_pet_post_render(uint8_t col, uint8_t line, bool jumping, uint8_t mods, led_t leds, uint8_t wpm, bool redraw) {
static led_t prev_leds = {.raw = 0};
if (redraw || leds.raw != prev_leds.raw) {
oled_set_cursor(col + 4, line + !jumping + 4);
oled_write_char(leds.num_lock ? 'N' : ' ', /*invert=*/false);
oled_set_cursor(col + 4, line + !jumping + 6);
oled_write_char(leds.caps_lock ? 'C' : ' ', /*invert=*/false);
oled_set_cursor(col + 4, line + !jumping + 8);
oled_write_char(leds.scroll_lock ? 'S' : ' ', /*invert=*/false);
prev_leds = leds;
}
}
18 changes: 9 additions & 9 deletions users/bcat/bcat_oled_pet_luna.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
#include <stdbool.h>
#include <stdint.h>

#include "bcat_oled.h"
#include "keycode.h"
#include "led.h"
#include "progmem.h"

enum state {
Expand All @@ -52,23 +52,25 @@ 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; }

oled_pet_state_t oled_pet_state(uint8_t mods, led_t led_state, uint8_t wpm) {
if (led_state.caps_lock) {
oled_pet_state_t oled_pet_state(const oled_keyboard_state_t *keyboard_state) {
if (keyboard_state->leds.caps_lock) {
return OLED_PET_BARK;
}
if (mods & MOD_MASK_CTRL) {
if (keyboard_state->mods & MOD_MASK_CTRL) {
return OLED_PET_SNEAK;
}
if (wpm >= 100) {
if (keyboard_state->wpm >= 100) {
return OLED_PET_RUN;
}
if (wpm >= 25) {
if (keyboard_state->wpm >= 25) {
return OLED_PET_WALK;
}
return OLED_PET_IDLE;
}

uint16_t oled_pet_update_millis(uint8_t wpm) { return 200; }
uint16_t oled_pet_update_millis(const oled_keyboard_state_t *keyboard_state) { return 200; }

void oled_pet_post_render(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state, bool jumping, bool redraw) {}

const char *oled_pet_frame(oled_pet_state_t state, uint8_t frame) {
static const char PROGMEM IDLE_FRAMES[NUM_FRAMES][FRAME_BYTES] = {
Expand Down Expand Up @@ -154,5 +156,3 @@ const char *oled_pet_frame(oled_pet_state_t state, uint8_t frame) {
return IDLE_FRAMES[frame];
}
}

void oled_pet_post_render(uint8_t col, uint8_t line, bool jumping, uint8_t mods, led_t leds, uint8_t wpm, bool redraw) {}