~ruther/qmk_firmware

1c43410e266429c97786c9f9217ab9708bb2754d — Drashna Jaelre 3 years ago a311938
[Keymap] Updates to drashna Keymaps and Userspace (#17543)

M keyboards/bastardkb/charybdis/4x6/keymaps/drashna/config.h => keyboards/bastardkb/charybdis/4x6/keymaps/drashna/config.h +19 -3
@@ 18,10 18,10 @@

#undef MATRIX_COL_PINS
#define MATRIX_COL_PINS \
    { B0, B1, B10, B3, B4, B5 }
    { B0, B1, B12, B3, B4, B5 }
#undef MATRIX_COL_PINS_RIGHT
#define MATRIX_COL_PINS_RIGHT \
    { B0, B1, B10, B3, B4, B5 }
    { B0, B1, B12, B3, B4, B5 }

#undef MATRIX_ROW_PINS
#define MATRIX_ROW_PINS \


@@ 30,8 30,12 @@
#define MATRIX_ROW_PINS_RIGHT \
    { B15, A2, B8, A8, B9 }

#define UNUSED_PINS { B6, C14, C15 }

#define DIODE_DIRECTION ROW2COL
#define SPLIT_HAND_PIN A3
#undef MASTER_RIGHT
// #define USB_VBUS_PIN B10

#undef RGB_DI_PIN
#define RGB_DI_PIN A1


@@ 46,6 50,13 @@

#define DEBUG_LED_PIN     C13

#define AUDIO_PIN          B7
#define AUDIO_PWM_DRIVER   PWMD4
#define AUDIO_PWM_CHANNEL  2
#define AUDIO_PWM_PAL_MODE 2
#define AUDIO_STATE_TIMER  GPTD3
#define AUDIO_INIT_DELAY

#undef SOFT_SERIAL_PIN
// #define SERIAL_USART_FULL_DUPLEX  // Enable full duplex operation mode.
#define SERIAL_USART_TX_PIN      A9


@@ 77,9 88,12 @@
#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR    64

#undef PMW3360_CS_PIN
#define PMW3360_CS_PIN                       B14
#define PMW3360_CS_PIN                       A15  // b14
#define PMW3360_CS_MODE 3
#define PMW3360_CS_DIVISOR 64
#define PMW3360_LIFTOFF_DISTANCE 0b1111
#undef ROTATIONAL_TRANSFORM_ANGLE
#define ROTATIONAL_TRANSFORM_ANGLE -65

#define CHARYBDIS_MINIMUM_DEFAULT_DPI     1200
#define CHARYBDIS_DEFAULT_DPI_CONFIG_STEP 400


@@ 90,3 104,5 @@

#undef RGB_MATRIX_MAXIMUM_BRIGHTNESS
#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 150

#define CHARYBDIS_CONFIG_SYNC

M keyboards/bastardkb/charybdis/4x6/keymaps/drashna/halconf.h => keyboards/bastardkb/charybdis/4x6/keymaps/drashna/halconf.h +2 -1
@@ 16,11 16,12 @@
#pragma once

#define HAL_USE_PWM     TRUE
#define HAL_USE_PAL     TRUE
#define HAL_USE_GPT     TRUE
#define HAL_USE_SERIAL  TRUE
// #define HAL_USE_I2C     TRUE
#define HAL_USE_SPI     TRUE
#define SPI_USE_WAIT    TRUE
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
// #define HAL_USE_GPT     TRUE

#include_next <halconf.h>

M keyboards/bastardkb/charybdis/4x6/keymaps/drashna/keymap.c => keyboards/bastardkb/charybdis/4x6/keymaps/drashna/keymap.c +48 -20
@@ 26,8 26,8 @@
     KC_ESC,  ________________NUMBER_LEFT________________,            ________________NUMBER_RIGHT_______________, UC_CLUE, \
     SH_TT,   K01,    K02,      K03,     K04,     K05,                K06,     K07,     K08,     K09,     K0A,     SH_TT, \
     LALT_T(KC_TAB), K11, K12,  K13,     K14,     K15,                K16,     K17,     K18,     K19,     K1A,     RALT_T(K1B), \
     OS_LSFT, CTL_T(K21), K22,  K23,     K24,     K25,                K26,     K27,     K28,     K29, RCTL_T(K2A), OS_RSFT, \
                                   KC_GRV, OS_LALT, OS_LGUI,    TT(_MOUSE),  KC_ENT, \
     OS_LSFT,CTL_T(K21),ALT_T(K22),GUI_T(K23),K24,K25,                K26,K27,RGUI_T(K28),RALT_T(K29),RCTL_T(K2A), OS_RSFT, \
                           SFT_T(KC_GRV), UC_IRNY, OS_LGUI,    TT(_MOUSE),  KC_ENT, \
                                           KC_SPC, BK_LWER,     DL_RAIS \
    )



@@ 58,38 58,36 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
        _________________DVORAK_L3_________________, _________________DVORAK_R3_________________
    ),



    [_MOUSE] = LAYOUT_charybdis_4x6(
        _______, _______, _______, _______, _______, _______,   DRGSCRL, DPI_RMOD,DPI_MOD, S_D_RMOD,S_D_MOD, SNP_TOG,
        _______, _______, _______, _______, _______, _______,   KC_WH_U, _______, _______, _______, _______, _______,
        _______, _______, _______, _______, _______, _______,   KC_WH_D, KC_BTN1, KC_BTN3, KC_BTN2, KC_BTN6, SNIPING,
        _______, _______, _______, _______, _______, _______,   KC_BTN7, KC_BTN4, KC_BTN5, KC_BTN8, _______, _______,
                                   _______, _______, _______,    _______, _______,
                                           _______, _______,      _______
    ),
    [_GAMEPAD] = LAYOUT_charybdis_4x6(
        KC_ESC,  KC_NO,   KC_1,    KC_2,    KC_3,    KC_4,       _______, _______, _______, _______, _______, _______,
        KC_F1,   KC_K,    KC_Q,    KC_W,    KC_E,    KC_R,       _______, _______, _______, _______, _______, _______,
        KC_TAB,  KC_G,    KC_A,    KC_S,    KC_D,    KC_F,       _______, _______, _______, _______, _______, _______,
        KC_LCTL, KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_H,       _______, _______, _______, _______, _______, _______,
                                   _______, _______, _______,    _______, _______,
                                           _______, _______,      _______
                                   KC_V,    _______, _______,    _______, TG_GAME,
                                           KC_SPC, KC_H,          _______
    ),
    [_DIABLO] = LAYOUT_charybdis_4x6(
        KC_ESC,  KC_V,    KC_D,    KC_LALT, KC_NO,   KC_NO,      KC_F9,   KC_F10,  KC_F11,  KC_F12,  KC_NO,   KC_NO,
        KC_TAB,  KC_S,    KC_I,    KC_F,    KC_M,    KC_T,       _______, _______, _______, _______, _______, _______,
        KC_Q,    KC_1,    KC_2,    KC_3,    KC_4,    KC_G,       _______, _______, _______, _______, _______, _______,
        KC_LCTL, KC_D3_1, KC_D3_2, KC_D3_3, KC_D3_4, KC_Z,       _______, _______, _______, _______, _______, _______,
                                   _______, _______, _______,    _______, _______,
                                           _______, _______,      _______
                                   KC_G,    _______, _______,    TO(_DIABLOII), TG_DBLO,
                                           KC_LSFT, KC_LCTL,      _______
    ),
    [_DIABLOII] = LAYOUT_charybdis_4x6(
        KC_ESC,  KC_1,    KC_2,    KC_3,    KC_4,    KC_GRV,     _______, _______, _______, _______, _______, _______,
        KC_TAB,  KC_A,    KC_T,    KC_Q,    KC_I,    KC_M,       _______, _______, _______, _______, _______, _______,
        KC_S,    KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,      _______, _______, _______, _______, _______, _______,
        KC_LCTL, KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,     _______, _______, _______, _______, _______, _______,
                                   _______, _______, _______,    _______, _______,
                           KC_DIABLO_CLEAR, _______, _______,    _______, TG(_DIABLOII),
                               SFT_T(KC_SPACE),  ALT_T(KC_Q),      _______
    ),
    [_MOUSE] = LAYOUT_charybdis_4x6(
        _______, _______, _______, _______, _______, _______,   _______, _______, _______, _______, _______, _______,
        _______, _______, _______, _______, _______, _______,   KC_WH_U, DPI_RMOD,DPI_MOD, S_D_RMOD,S_D_MOD, _______,
        _______, _______, _______, _______, _______, _______,   KC_WH_D, KC_BTN1, KC_BTN3, KC_BTN2, KC_BTN6, SNIPING,
        _______, _______, _______, _______, _______, _______,   KC_BTN7, KC_BTN4, KC_BTN5, KC_BTN8, DRGSCRL, _______,
                                   _______, SNIPING, SNIPING,    _______, _______,
                                           _______, _______,      _______
    ),



@@ 112,18 110,26 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    ),

    [_ADJUST] = LAYOUT_charybdis_4x6_wrapper(
        QK_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_NOMODE, KC_NOMODE,KC_BLOCKS,KC_REGIONAL,_______,_______, QK_BOOT,
        QK_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_SUPER, KC_NOMODE,KC_BLOCKS,KC_REGIONAL,TG_GAME,TG_DBLO, QK_BOOT,
        VRSN,    _________________ADJUST_L1_________________,    _________________ADJUST_R1_________________, EE_CLR,
        KEYLOCK, _________________ADJUST_L2_________________,    _________________ADJUST_R2_________________, TG_MODS,
        UC_MOD,  _________________ADJUST_L3_________________,    _________________ADJUST_R3_________________, KC_MPLY,
                                   QK_RBT, AUTO_CTN, _______,    KC_NUKE, _______,
                                   QK_RBT, AUTO_CTN, _______,    _______, KC_NUKE,
                                           _______, _______,      _______
    )
};
// clang-format on


void matrix_init_keyemap(void) { setPinInputHigh(A0); }
void matrix_init_keymap(void) {
    setPinInputHigh(A0);
#ifdef RGB_MATRIX_ENABLE
     g_led_config.flags[53] = g_led_config.flags[54] = g_led_config.flags[55] =
        g_led_config.flags[0] = g_led_config.flags[1] = g_led_config.flags[2] = g_led_config.flags[3] =
        g_led_config.flags[29] = g_led_config.flags[30] = g_led_config.flags[31] = g_led_config.flags[32] =
        LED_FLAG_MODIFIER;
#endif
}

void matrix_scan_keymap(void) {
    if (!readPin(A0)) {


@@ 144,3 150,25 @@ void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
        __asm__ volatile("nop" ::: "memory");
    }
}


#ifdef SWAP_HANDS_ENABLE
const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
    /* Left hand, matrix positions */
    {{0, 5}, {1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}},
    {{0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6}, {5, 6}},
    {{0, 7}, {1, 7}, {2, 7}, {3, 7}, {4, 7}, {5, 7}},
    {{0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}},
    {{2, 9}, {4, 9}, {5, 9}, {1, 9}, {0, 9}, {3, 9}},
    /* Right hand, matrix positions */
    {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}},
    {{0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}},
    {{0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2}, {5, 2}},
    {{0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3}},
    {{0, 4}, {3, 4}, {2, 4}, {5, 4}, {4, 4}, {2, 4}},
    };

#    ifdef ENCODER_MAP_ENABLE
const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS] = {1, 0};
#    endif
#endif

M keyboards/bastardkb/charybdis/4x6/keymaps/drashna/mcuconf.h => keyboards/bastardkb/charybdis/4x6/keymaps/drashna/mcuconf.h +9 -10
@@ 17,19 17,18 @@
#pragma once

#include_next "mcuconf.h"
#undef STM32_I2C_USE_I2C1
#define STM32_I2C_USE_I2C1 TRUE

// #undef STM32_I2C_I2C1_RX_DMA_STREAM
// #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
#undef STM32_I2C_I2C1_TX_DMA_STREAM
#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1)
#undef STM32_PWM_USE_ADVANCED
#define STM32_PWM_USE_ADVANCED TRUE

#undef STM32_PWM_USE_TIM1
#define STM32_PWM_USE_TIM1 TRUE

#undef STM32_PWM_USE_TIM2
#define STM32_PWM_USE_TIM2 TRUE

#undef STM32_PWM_USE_TIM3
#define STM32_PWM_USE_TIM3 TRUE
#undef STM32_PWM_USE_TIM4
#define STM32_PWM_USE_TIM4 TRUE

#undef STM32_SPI_USE_SPI1
#define STM32_SPI_USE_SPI1 TRUE


@@ 37,8 36,8 @@
#undef STM32_SERIAL_USE_USART1
#define STM32_SERIAL_USE_USART1 TRUE

#undef STM32_GPT_USE_TIM4
#define STM32_GPT_USE_TIM4 TRUE
#undef STM32_GPT_USE_TIM3
#define STM32_GPT_USE_TIM3 TRUE

#undef STM32_ST_USE_TIMER
#define STM32_ST_USE_TIMER 5

M keyboards/bastardkb/charybdis/4x6/keymaps/drashna/rules.mk => keyboards/bastardkb/charybdis/4x6/keymaps/drashna/rules.mk +24 -15
@@ 1,24 1,33 @@
# MCU name
MCU = STM32F411
BOARD = BLACKPILL_STM32_F411

# Bootloader selection
BOOTLOADER = stm32-dfu
# BOOTLOADER := tinyuf2
BOOTLOADER := tinyuf2

LTO_ENABLE := no
BOOTMAGIC_ENABLE      = yes # Enable Bootmagic Lite
MOUSEKEY_ENABLE       = yes # Mouse keys
EXTRAKEY_ENABLE       = yes # Audio control and System control
CONSOLE_ENABLE        = yes # Console for debug
COMMAND_ENABLE        = no  # Commands for debug and configuration
NKRO_ENABLE           = yes # Enable N-Key Rollover
RGBLIGHT_ENABLE       = no  # Enable keyboard RGB underglow
AUDIO_ENABLE          = yes # Audio output
AUDIO_SUPPORTED       = yes # is set to no in kb, needs to be forcibly enabled

BOOTMAGIC_ENABLE = yes     # Enable Bootmagic Lite
KEYBOARD_SHARED_EP = yes
MOUSE_SHARED_EP = yes
KEYBOARD_SHARED_EP    = yes
MOUSE_SHARED_EP       = yes

EEPROM_DRIVER = spi
WS2812_DRIVER = pwm
SERIAL_DRIVER = usart

MOUSEKEY_ENABLE = yes
NKRO_ENABLE = yes
CONSOLE_ENABLE = yes
EEPROM_DRIVER         = spi
WS2812_DRIVER         = pwm
SERIAL_DRIVER         = usart
AUDIO_DRIVER          = pwm_hardware
BACKLIGHT_DRIVER      = pwm

AUTOCORRECTION_ENABLE = yes

DEBOUNCE_TYPE = asym_eager_defer_pk
CAPS_WORD_ENABLE      = yes
SWAP_HANDS_ENABLE     = yes
TAP_DANCE_ENABLE      = yes
DEBOUNCE_TYPE         = asym_eager_defer_pk
WPM_ENABLE            = yes
LTO_ENABLE            = no

M keyboards/handwired/tractyl_manuform/5x6_right/keymaps/drashna/config.h => keyboards/handwired/tractyl_manuform/5x6_right/keymaps/drashna/config.h +0 -5
@@ 28,8 28,3 @@
#define CHARYBDIS_SNIPING_DPI_CONFIG_STEP 200

#define ENCODER_DEFAULT_POS 0x3

#define SECURE_UNLOCK_SEQUENCE \
    {                          \
        { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 } \
    }

M keyboards/handwired/tractyl_manuform/5x6_right/keymaps/drashna/keymap.c => keyboards/handwired/tractyl_manuform/5x6_right/keymaps/drashna/keymap.c +10 -10
@@ 59,16 59,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
        _________________DVORAK_L3_________________, _________________DVORAK_R3_________________
    ),

    [_MOUSE] = LAYOUT_5x6_right(
        _______, _______, _______, _______, _______, _______,                        DRGSCRL, DPI_RMOD,DPI_MOD, S_D_RMOD,S_D_MOD, SNP_TOG,
        _______, _______, _______, _______, _______, _______,                        KC_WH_U, _______, _______, _______, _______, _______,
        _______, _______, _______, _______, _______, _______,                        KC_WH_D, KC_BTN1, KC_BTN3, KC_BTN2, KC_BTN6, SNIPING,
        _______, _______, _______, _______, _______, _______,                        KC_BTN7, KC_BTN4, KC_BTN5, KC_BTN8, _______, _______,
                          _______, _______,                                                            _______, _______,
                                            _______, _______,                                 KC_BTN3,
                                                     _______, _______,               _______,
                                                     _______, _______,      _______, _______
    ),
    [_GAMEPAD] = LAYOUT_5x6_right(
        KC_ESC,  KC_NO,   KC_1,    KC_2,    KC_3,    KC_4,                           _______, _______, _______, _______, _______, _______,
        KC_F1,   KC_K,    KC_Q,    KC_W,    KC_E,    KC_R,                           _______, _______, _______, _______, _______, _______,


@@ 99,6 89,16 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
                                               KC_LSFT, _______,                     _______,
                                               KC_LCTL, KC_V,               _______, _______
    ),
    [_MOUSE] = LAYOUT_5x6_right(
        _______, _______, _______, _______, _______, _______,                        DRGSCRL, DPI_RMOD,DPI_MOD, S_D_RMOD,S_D_MOD, SNP_TOG,
        _______, _______, _______, _______, _______, _______,                        KC_WH_U, _______, _______, _______, _______, _______,
        _______, _______, _______, _______, _______, _______,                        KC_WH_D, KC_BTN1, KC_BTN3, KC_BTN2, KC_BTN6, SNIPING,
        _______, _______, _______, _______, _______, _______,                        KC_BTN7, KC_BTN4, KC_BTN5, KC_BTN8, _______, _______,
                          _______, _______,                                                            _______, _______,
                                            _______, _______,                                 KC_BTN3,
                                                     _______, _______,               _______,
                                                     _______, _______,      _______, _______
    ),
    [_LOWER] = LAYOUT_5x6_right_wrapper(
        KC_F12,  _________________FUNC_LEFT_________________,                        _________________FUNC_RIGHT________________, KC_F11,
        _______, _________________LOWER_L1__________________,                        _________________LOWER_R1__________________, _______,

M users/drashna/callbacks.c => users/drashna/callbacks.c +30 -17
@@ 55,11 55,11 @@ void                       shutdown_user(void) {
    rgblight_enable_noeeprom();
    rgblight_mode_noeeprom(1);
    rgblight_setrgb_red();
#endif  // RGBLIGHT_ENABLE
#endif // RGBLIGHT_ENABLE
#ifdef RGB_MATRIX_ENABLE
    rgb_matrix_set_color_all(0xFF, 0x00, 0x00);
    rgb_matrix_update_pwm_buffers();
#endif  // RGB_MATRIX_ENABLE
#endif // RGB_MATRIX_ENABLE
#ifdef OLED_ENABLE
    oled_off();
#endif


@@ 88,7 88,7 @@ void suspend_power_down_user(void) {
__attribute__((weak)) void suspend_wakeup_init_keymap(void) {}
void                       suspend_wakeup_init_user(void) {
#ifdef OLED_ENABLE
        oled_timer_reset();
    oled_timer_reset();
#endif
    suspend_wakeup_init_keymap();
}


@@ 104,9 104,9 @@ void                       matrix_scan_user(void) {
        startup_user();
    }

#ifdef TAP_DANCE_ENABLE  // Run Diablo 3 macro checking code.
#ifdef TAP_DANCE_ENABLE // Run Diablo 3 macro checking code.
    run_diablo_macro_check();
#endif  // TAP_DANCE_ENABLE
#endif // TAP_DANCE_ENABLE
#ifdef CAPS_WORD_ENABLE
    caps_word_task();
#endif


@@ 124,8 124,10 @@ float doom_song[][2] = SONG(E1M1_DOOM);

// on layer change, no matter where the change was initiated
// Then runs keymap's layer change check
__attribute__((weak)) layer_state_t layer_state_set_keymap(layer_state_t state) { return state; }
layer_state_t                       layer_state_set_user(layer_state_t state) {
__attribute__((weak)) layer_state_t layer_state_set_keymap(layer_state_t state) {
    return state;
}
layer_state_t layer_state_set_user(layer_state_t state) {
    if (!is_keyboard_master()) {
        return state;
    }


@@ 136,7 138,7 @@ layer_state_t                       layer_state_set_user(layer_state_t state) {
#endif
#if defined(CUSTOM_RGBLIGHT)
    state = layer_state_set_rgb_light(state);
#endif  // CUSTOM_RGBLIGHT
#endif // CUSTOM_RGBLIGHT
#if defined(AUDIO_ENABLE) && !defined(__arm__)
    static bool is_gamepad_on = false;
    if (layer_state_cmp(state, _GAMEPAD) != is_gamepad_on) {


@@ 153,28 155,31 @@ layer_state_t                       layer_state_set_user(layer_state_t state) {
}

// Runs state check and changes underglow color and animation
__attribute__((weak)) layer_state_t default_layer_state_set_keymap(layer_state_t state) { return state; }
layer_state_t                       default_layer_state_set_user(layer_state_t state) {
__attribute__((weak)) layer_state_t default_layer_state_set_keymap(layer_state_t state) {
    return state;
}
layer_state_t default_layer_state_set_user(layer_state_t state) {
    if (!is_keyboard_master()) {
        return state;
    }

    state = default_layer_state_set_keymap(state);
#if 0
#    if defined(CUSTOM_RGBLIGHT) || defined(RGB_MATRIX_ENABLE)
  state = default_layer_state_set_rgb(state);
#    endif
#if defined(CUSTOM_RGBLIGHT)
    state = default_layer_state_set_rgb_light(state);
#endif
    return state;
}

__attribute__((weak)) void led_set_keymap(uint8_t usb_led) {}
void                       led_set_user(uint8_t usb_led) { led_set_keymap(usb_led); }
void                       led_set_user(uint8_t usb_led) {
    led_set_keymap(usb_led);
}

__attribute__((weak)) void eeconfig_init_keymap(void) {}
void                       eeconfig_init_user(void) {
    userspace_config.raw              = 0;
    userspace_config.rgb_layer_change = true;
    userspace_config.autocorrection   = true;
    eeconfig_update_user(userspace_config.raw);
    eeconfig_init_keymap();
}


@@ 187,8 192,8 @@ void                       matrix_slave_scan_user(void) {
    music_task();
#        endif
#        ifdef AUDIO_INIT_DELAY
    if (!is_keyboard_master()) {
        static bool delayed_tasks_run = false;
                          if (!is_keyboard_master()) {
        static bool     delayed_tasks_run  = false;
        static uint16_t delayed_task_timer = 0;
        if (!delayed_tasks_run) {
            if (!delayed_task_timer) {


@@ 214,3 219,11 @@ void                       matrix_slave_scan_user(void) {
    matrix_slave_scan_keymap();
}
#endif

__attribute__((weak)) void housekeeping_task_keymap(void) {}
void housekeeping_task_user(void) {
#if defined(SPLIT_KEYBOARD) && defined(SPLIT_TRANSACTION_IDS_USER)
    housekeeping_task_transport_sync();
#endif
    housekeeping_task_keymap();
}

M users/drashna/callbacks.h => users/drashna/callbacks.h +1 -0
@@ 16,6 16,7 @@ layer_state_t layer_state_set_keymap(layer_state_t state);
layer_state_t default_layer_state_set_keymap(layer_state_t state);
void          led_set_keymap(uint8_t usb_led);
void          eeconfig_init_keymap(void);
void          housekeeping_task_keymap(void);

#ifdef CUSTOM_UNICODE_ENABLE
void matrix_init_unicode(void);

M users/drashna/config.h => users/drashna/config.h +51 -37
@@ 4,10 4,10 @@
#pragma once

// Use custom magic number so that when switching branches, EEPROM always gets reset
#define EECONFIG_MAGIC_NUMBER   (uint16_t)0x1339
#define EECONFIG_MAGIC_NUMBER (uint16_t)0x1339

#ifdef IS_COMMAND
#undef IS_COMMAND
#    undef IS_COMMAND
#endif
#define IS_COMMAND() (((get_mods() | get_oneshot_mods()) & MOD_MASK_SHIFT) == MOD_MASK_SHIFT)



@@ 37,8 37,8 @@
// #    define WPM_LAUNCH_CONTROL
// #    define WPM_ALLOW_COUNT_REGRESSOIN
// #    define WPM_UNFILTERED
#    define WPM_SAMPLE_SECONDS      10
#    define WPM_SAMPLE_PERIODS      50
#    define WPM_SAMPLE_SECONDS 10
#    define WPM_SAMPLE_PERIODS 50
#    define WPM_ESTIMATED_WORD_SIZE 5
#endif



@@ 51,34 51,34 @@
#        define GOODBYE_SONG SONG(SONIC_RING)
#        define DEFAULT_LAYER_SONGS \
            { SONG(QWERTY_SOUND), SONG(COLEMAK_SOUND), SONG(DVORAK_SOUND), SONG(OVERWATCH_THEME) }
#        define UNICODE_SONG_MAC  SONG(MARIO_THEME)
#        define UNICODE_SONG_LNX  SONG(MARIO_POWERUP)
#        define UNICODE_SONG_WIN  SONG(MARIO_ONEUP)
#        define UNICODE_SONG_BSD  SONG(RICK_ROLL)
#        define UNICODE_SONG_MAC SONG(MARIO_THEME)
#        define UNICODE_SONG_LNX SONG(MARIO_POWERUP)
#        define UNICODE_SONG_WIN SONG(MARIO_ONEUP)
#        define UNICODE_SONG_BSD SONG(RICK_ROLL)
#        define UNICODE_SONG_WINC SONG(RICK_ROLL)
#    else
#        define STARTUP_SONG SONG(STARTUP_SOUND)
#        define GOODBYE_SONG SONG(GOODBYE_SOUND)
#        define DEFAULT_LAYER_SONGS \
            { SONG(QWERTY_SOUND), SONG(COLEMAK_SOUND), SONG(DVORAK_SOUND), SONG(WORKMAN_SOUND) }
#        define UNICODE_SONG_MAC  SONG(QWERTY_SOUND)
#        define UNICODE_SONG_LNX  SONG(COLEMAK_SOUND)
#        define UNICODE_SONG_WIN  SONG(DVORAK_SOUND)
#        define UNICODE_SONG_BSD  SONG(WORKMAN_SOUND)
#        define UNICODE_SONG_MAC SONG(QWERTY_SOUND)
#        define UNICODE_SONG_LNX SONG(COLEMAK_SOUND)
#        define UNICODE_SONG_WIN SONG(DVORAK_SOUND)
#        define UNICODE_SONG_BSD SONG(WORKMAN_SOUND)
#        define UNICODE_SONG_WINC SONG(PLOVER_GOODBYE_SOUND)
#    endif
#endif  // !AUDIO_ENABLE
#endif // !AUDIO_ENABLE

#define UNICODE_SELECTED_MODES UC_WINC, UC_MAC

#ifdef RGBLIGHT_ENABLE
#    define RGBLIGHT_SLEEP
#    define RGBLIGHT_EFFECT_TWINKLE_LIFE        250
#    define RGBLIGHT_EFFECT_TWINKLE_LIFE 250
#    define RGBLIGHT_EFFECT_TWINKLE_PROBABILITY 1 / 24
#endif  // RGBLIGHT_ENABLE
#endif // RGBLIGHT_ENABLE

#ifdef RGB_MATRIX_ENABLE
#    define RGB_MATRIX_KEYPRESSES  // reacts to keypresses (will slow down matrix scan by a lot)
#    define RGB_MATRIX_KEYPRESSES // reacts to keypresses (will slow down matrix scan by a lot)
// #   define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (not recommened)
#    define RGB_MATRIX_FRAMEBUFFER_EFFECTS
// #    define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects


@@ 179,20 179,26 @@
#        define ENABLE_RGB_MATRIX_MULTISPLASH
#        define ENABLE_RGB_MATRIX_SOLID_SPLASH
#        define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
#    endif  // AVR
#endif      // RGB_MATRIX_ENABLE
#    endif // AVR
#endif     // RGB_MATRIX_ENABLE

#ifdef OLED_ENABLE
#    ifdef SPLIT_KEYBOARD
#        define OLED_UPDATE_INTERVAL 60
#    else
#        define OLED_UPDATE_INTERVAL 15
#    ifndef OLED_UPDATE_INTERVAL
#        ifdef OLED_DRIVER_SH1107
#            define OLED_UPDATE_INTERVAL 75
#        else
#            ifdef SPLIT_KEYBOARD
#                define OLED_UPDATE_INTERVAL 60
#            else
#                define OLED_UPDATE_INTERVAL 15
#            endif
#        endif
#    endif
#    define OLED_DISABLE_TIMEOUT
#    ifdef OLED_FONT_H
#        undef OLED_FONT_H
#    endif
#    define OLED_FONT_H   "oled/drashna_font.h"
#    define OLED_FONT_H "oled/drashna_font.h"
#    define OLED_FONT_END 255
// #    define OLED_FONT_5X5
// #    define OLED_FONT_AZTECH


@@ 223,14 229,13 @@
// #define WPM_SAMPLE_PERIODS 50
// #define WPM_LAUNCH_CONTROL


#ifndef ONESHOT_TAP_TOGGLE
#    define ONESHOT_TAP_TOGGLE 2
#endif  // !ONESHOT_TAP_TOGGLE
#endif // !ONESHOT_TAP_TOGGLE

#ifndef ONESHOT_TIMEOUT
#    define ONESHOT_TIMEOUT 3000
#endif  // !ONESHOT_TIMEOUT
#endif // !ONESHOT_TIMEOUT

#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY
#define PERMISSIVE_HOLD_PER_KEY


@@ 238,7 243,6 @@
#define RETRO_TAPPING_PER_KEY
#define TAPPING_TERM_PER_KEY


#ifndef TAPPING_TOGGLE
#    define TAPPING_TOGGLE 1
#endif


@@ 255,12 259,12 @@

#ifdef CONVERT_TO_PROTON_C
// pins that are available but not present on Pro Micro
#    define A3  PAL_LINE(GPIOA, 3)
#    define A4  PAL_LINE(GPIOA, 4)
#    define A5  PAL_LINE(GPIOA, 5)
#    define A6  PAL_LINE(GPIOA, 6)
#    define A7  PAL_LINE(GPIOA, 7)
#    define A8  PAL_LINE(GPIOA, 8)
#    define A3 PAL_LINE(GPIOA, 3)
#    define A4 PAL_LINE(GPIOA, 4)
#    define A5 PAL_LINE(GPIOA, 5)
#    define A6 PAL_LINE(GPIOA, 6)
#    define A7 PAL_LINE(GPIOA, 7)
#    define A8 PAL_LINE(GPIOA, 8)
#    define A13 PAL_LINE(GPIOA, 13)
#    define A14 PAL_LINE(GPIOA, 14)
#    define A15 PAL_LINE(GPIOA, 15)


@@ 291,12 295,22 @@
#    ifndef OLED_BRIGHTNESS
#        define OLED_BRIGHTNESS 50
#    endif
#    if !defined(STM32F4XX)
#        undef OLED_UPDATE_INTERVAL
#        define OLED_UPDATE_INTERVAL 75
#    endif
#endif

#ifdef USE_I2CV1
#    define I2C1_CLOCK_SPEED 400000
#    define I2C1_DUTY_CYCLE FAST_DUTY_CYCLE_2
#endif

#define ENABLE_COMPILE_KEYCODE

#define BOTH_SHIFTS_TURNS_ON_CAPS_WORD

#ifndef SECURE_UNLOCK_SEQUENCE
#    define SECURE_UNLOCK_SEQUENCE    \
        {                             \
            {2, 1}, {2, 2}, {2, 3}, { \
                2, 4                  \
            }                         \
        }
#endif

M users/drashna/keyrecords/autocorrection/autocorrection.c => users/drashna/keyrecords/autocorrection/autocorrection.c +12 -12
@@ 52,7 52,7 @@ void autocorrect_enable(void) {
 */
void autocorrect_disable(void) {
    userspace_config.autocorrection = false;
    typo_buffer_size                 = 0;
    typo_buffer_size                = 0;
    eeconfig_update_user(userspace_config.raw);
}



@@ 62,7 62,7 @@ void autocorrect_disable(void) {
 */
void autocorrect_toggle(void) {
    userspace_config.autocorrection = !userspace_config.autocorrection;
    typo_buffer_size                 = 0;
    typo_buffer_size                = 0;
    eeconfig_update_user(userspace_config.raw);
}



@@ 98,15 98,15 @@ __attribute__((weak)) bool process_autocorrect_user(uint16_t *keycode, keyrecord
            }
            *keycode &= 0xFF; // Get the basic keycode.
            return true;
#ifndef NO_ACTION_TAPPING
#    ifndef NO_ACTION_TAPPING
        // Exclude tap-hold keys when they are held down
        // and mask for base keycode when they are tapped.
        case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
#    ifdef NO_ACTION_LAYER
#        ifdef NO_ACTION_LAYER
            // Exclude Layer Tap, if layers are disabled
            // but action tapping is still enabled.
            return false;
#    endif
#        endif
        case QK_MOD_TAP ... QK_MOD_TAP_MAX:
            // Exclude hold keycode
            if (!record->tap.count) {


@@ 114,25 114,25 @@ __attribute__((weak)) bool process_autocorrect_user(uint16_t *keycode, keyrecord
            }
            *keycode &= 0xFF;
            break;
#else
#    else
        case QK_MOD_TAP ... QK_MOD_TAP_MAX:
        case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
            // Exclude if disabled
            return false;
#endif
#    endif
        // Exclude swap hands keys when they are held down
        // and mask for base keycode when they are tapped.
        case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
#ifdef SWAP_HANDS_ENABLE
#    ifdef SWAP_HANDS_ENABLE
            if (*keycode >= 0x56F0 || !record->tap.count) {
                return false;
            }
            *keycode &= 0xFF;
            break;
#else
#    else
            // Exclude if disabled
            return false;
#endif
#    endif
    }

    // Disable autocorrect while a mod other than shift is active.


@@ 166,9 166,9 @@ __attribute__((weak)) bool apply_autocorrect(uint8_t backspaces, const char *str
 */
bool process_autocorrection(uint16_t keycode, keyrecord_t *record) {
    uint8_t mods = get_mods();
#ifndef NO_ACTION_ONESHOT
#    ifndef NO_ACTION_ONESHOT
    mods |= get_oneshot_mods();
#endif
#    endif

    if ((keycode >= AUTOCORRECT_ON && keycode <= AUTOCORRECT_TOGGLE) && record->event.pressed) {
        if (keycode == AUTOCORRECT_ON) {

M users/drashna/keyrecords/process_records.c => users/drashna/keyrecords/process_records.c +21 -15
@@ 20,8 20,12 @@ bool     host_driver_disabled = false;
 *
 * This handles the keycodes at the keymap level, useful for keyboard specific customization
 */
__attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; }
__attribute__((weak)) bool process_record_secrets(uint16_t keycode, keyrecord_t *record) { return true; }
__attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
    return true;
}
__attribute__((weak)) bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
    return true;
}

/**
 * @brief Main user keycode handler


@@ 46,10 50,10 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    // If console is enabled, it will print the matrix position and status of each key pressed
#ifdef KEYLOGGER_ENABLE
    uprintf("KL: kc: 0x%04X, col: %2u, row: %2u, pressed: %b, time: %5u, int: %b, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count);
#endif  // KEYLOGGER_ENABLE
#endif // KEYLOGGER_ENABLE
#if defined(OLED_ENABLE) && defined(CUSTOM_OLED_DRIVER)
    process_record_user_oled(keycode, record);
#endif  // OLED
#endif // OLED

    if (!(process_record_keymap(keycode, record) && process_record_secrets(keycode, record)
#ifdef CUSTOM_RGB_MATRIX


@@ 90,34 94,34 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
            }
            break;

        case VRSN:  // Prints firmware version
        case VRSN: // Prints firmware version
            if (record->event.pressed) {
                send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY);
            }
            break;

        case KC_DIABLO_CLEAR:  // reset all Diablo timers, disabling them
        case KC_DIABLO_CLEAR: // reset all Diablo timers, disabling them
#ifdef TAP_DANCE_ENABLE
            if (record->event.pressed) {
                for (uint8_t index = 0; index < 4; index++) {
                    diablo_timer[index].key_interval = 0;
                }
            }
#endif  // TAP_DANCE_ENABLE
#endif // TAP_DANCE_ENABLE
            break;

        case KC_CCCV:  // One key copy/paste
        case KC_CCCV: // One key copy/paste
            if (record->event.pressed) {
                copy_paste_timer = timer_read();
            } else {
                if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) {  // Hold, copy
                if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) { // Hold, copy
                    tap_code16(LCTL(KC_C));
                } else {  // Tap, paste
                } else { // Tap, paste
                    tap_code16(LCTL(KC_V));
                }
            }
            break;
        case KC_RGB_T:  // This allows me to use underglow as layer indication, or as normal
        case KC_RGB_T: // This allows me to use underglow as layer indication, or as normal
#if defined(CUSTOM_RGBLIGHT) || defined(CUSTOM_RGB_MATRIX)
            if (record->event.pressed) {
                userspace_config.rgb_layer_change ^= 1;


@@ 140,7 144,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
#    endif
                }
            }
#endif  // CUSTOM_RGBLIGHT
#endif // CUSTOM_RGBLIGHT
            break;

#if defined(CUSTOM_RGBLIGHT) || defined(CUSTOM_RGB_MATRIX)


@@ 160,7 164,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
            }
            return false;
            break;
        case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT:  // quantum_keycodes.h L400 for definitions
        case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // quantum_keycodes.h L400 for definitions
            if (record->event.pressed) {
                bool is_eeprom_updated;
#    if defined(CUSTOM_RGBLIGHT) && !defined(RGBLIGHT_DISABLE_KEYCODES)


@@ 200,9 204,11 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
            }
            break;
        }
     }
    }
    return true;
}

__attribute__((weak)) void post_process_record_keymap(uint16_t keycode, keyrecord_t *record) {}
void                       post_process_record_user(uint16_t keycode, keyrecord_t *record) { post_process_record_keymap(keycode, record); }
void                       post_process_record_user(uint16_t keycode, keyrecord_t *record) {
    post_process_record_keymap(keycode, record);
}

M users/drashna/keyrecords/process_records.h => users/drashna/keyrecords/process_records.h +50 -49
@@ 13,30 13,30 @@
#endif

enum userspace_custom_keycodes {
    VRSN = PLACEHOLDER_SAFE_RANGE,            // Prints QMK Firmware and board info
    KC_QWERTY,                                // Sets default layer to QWERTY
    FIRST_DEFAULT_LAYER_KEYCODE = KC_QWERTY,  // Sets default layer to QWERTY
    KC_COLEMAK_DH,                            // Sets default layer to COLEMAK
    KC_COLEMAK,                               // Sets default layer to COLEMAK
    KC_DVORAK,                                // Sets default layer to DVORAK
    LAST_DEFAULT_LAYER_KEYCODE = KC_DVORAK,   // Sets default layer to WORKMAN
    KC_DIABLO_CLEAR,                          // Clears all Diablo Timers
    KC_RGB_T,                                 // Toggles RGB Layer Indication mode
    RGB_IDL,                                  // RGB Idling animations
    KC_SECRET_1,                              // test1
    KC_SECRET_2,                              // test2
    KC_SECRET_3,                              // test3
    KC_SECRET_4,                              // test4
    KC_SECRET_5,                              // test5
    KC_CCCV,                                  // Hold to copy, tap to paste
    KC_NUKE,                                  // NUCLEAR LAUNCH DETECTED!!!
    UC_FLIP,                                  // (ಠ痊ಠ)┻━┻
    UC_TABL,                                  // ┬─┬ノ( º _ ºノ)
    UC_SHRG,                                  // ¯\_(ツ)_/¯
    UC_DISA,                                  // ಠ_ಠ
    VRSN = PLACEHOLDER_SAFE_RANGE,           // Prints QMK Firmware and board info
    KC_QWERTY,                               // Sets default layer to QWERTY
    FIRST_DEFAULT_LAYER_KEYCODE = KC_QWERTY, // Sets default layer to QWERTY
    KC_COLEMAK_DH,                           // Sets default layer to COLEMAK
    KC_COLEMAK,                              // Sets default layer to COLEMAK
    KC_DVORAK,                               // Sets default layer to DVORAK
    LAST_DEFAULT_LAYER_KEYCODE = KC_DVORAK,  // Sets default layer to WORKMAN
    KC_DIABLO_CLEAR,                         // Clears all Diablo Timers
    KC_RGB_T,                                // Toggles RGB Layer Indication mode
    RGB_IDL,                                 // RGB Idling animations
    KC_SECRET_1,                             // test1
    KC_SECRET_2,                             // test2
    KC_SECRET_3,                             // test3
    KC_SECRET_4,                             // test4
    KC_SECRET_5,                             // test5
    KC_CCCV,                                 // Hold to copy, tap to paste
    KC_NUKE,                                 // NUCLEAR LAUNCH DETECTED!!!
    UC_FLIP,                                 // (ಠ痊ಠ)┻━┻
    UC_TABL,                                 // ┬─┬ノ( º _ ºノ)
    UC_SHRG,                                 // ¯\_(ツ)_/¯
    UC_DISA,                                 // ಠ_ಠ
    UC_IRNY,
    UC_CLUE,
    KEYLOCK,                                  // Locks keyboard by unmounting driver
    KEYLOCK, // Locks keyboard by unmounting driver
    KC_NOMODE,
    KC_WIDE,
    KC_SCRIPT,


@@ 44,11 44,12 @@ enum userspace_custom_keycodes {
    KC_REGIONAL,
    KC_AUSSIE,
    KC_ZALGO,
    KC_SUPER,
    KC_ACCEL,
    AUTOCORRECT_ON,
    AUTOCORRECT_OFF,
    AUTOCORRECT_TOGGLE,
    NEW_SAFE_RANGE                            // use "NEWPLACEHOLDER for keymap specific codes
    NEW_SAFE_RANGE // use "NEWPLACEHOLDER for keymap specific codes
};

bool process_record_secrets(uint16_t keycode, keyrecord_t *record);


@@ 58,37 59,37 @@ void post_process_record_keymap(uint16_t keycode, keyrecord_t *record);
bool process_record_unicode(uint16_t keycode, keyrecord_t *record);
#endif

#define LOWER     MO(_LOWER)
#define RAISE     MO(_RAISE)
#define ADJUST    MO(_ADJUST)
#define TG_MODS   OS_TOGG
#define TG_GAME   TG(_GAMEPAD)
#define TG_DBLO   TG(_DIABLO)
#define OS_LWR    OSL(_LOWER)
#define OS_RSE    OSL(_RAISE)
#define LOWER MO(_LOWER)
#define RAISE MO(_RAISE)
#define ADJUST MO(_ADJUST)
#define TG_MODS OS_TOGG
#define TG_GAME TG(_GAMEPAD)
#define TG_DBLO TG(_DIABLO)
#define OS_LWR OSL(_LOWER)
#define OS_RSE OSL(_RAISE)

#define KC_SEC1   KC_SECRET_1
#define KC_SEC2   KC_SECRET_2
#define KC_SEC3   KC_SECRET_3
#define KC_SEC4   KC_SECRET_4
#define KC_SEC5   KC_SECRET_5
#define KC_SEC1 KC_SECRET_1
#define KC_SEC2 KC_SECRET_2
#define KC_SEC3 KC_SECRET_3
#define KC_SEC4 KC_SECRET_4
#define KC_SEC5 KC_SECRET_5

#define QWERTY    KC_QWERTY
#define DVORAK    KC_DVORAK
#define COLEMAK   KC_COLEMAK
#define QWERTY KC_QWERTY
#define DVORAK KC_DVORAK
#define COLEMAK KC_COLEMAK
#define COLEMAKDH KC_COLEMAK_DH

#define DEFLYR1   FIRST_DEFAULT_LAYER_KEYCODE
#define DEFLYR2   (FIRST_DEFAULT_LAYER_KEYCODE + 1)
#define DEFLYR3   (FIRST_DEFAULT_LAYER_KEYCODE + 2)
#define DEFLYR4   (FIRST_DEFAULT_LAYER_KEYCODE + 3)
#define DEFLYR1 FIRST_DEFAULT_LAYER_KEYCODE
#define DEFLYR2 (FIRST_DEFAULT_LAYER_KEYCODE + 1)
#define DEFLYR3 (FIRST_DEFAULT_LAYER_KEYCODE + 2)
#define DEFLYR4 (FIRST_DEFAULT_LAYER_KEYCODE + 3)
#if LAST_DEFAULT_LAYER_KEYCODE > (FIRST_DEFAULT_LAYER_KEYCODE + 3)
#    define DEFLYR5 (FIRST_DEFAULT_LAYER_KEYCODE + 4)
#    define DEFLYR6 (FIRST_DEFAULT_LAYER_KEYCODE + 5)
#    define DEFLYR7 (FIRST_DEFAULT_LAYER_KEYCODE + 6)
#    define DEFLYR8 (FIRST_DEFAULT_LAYER_KEYCODE + 7)
#    if LAST_DEFAULT_LAYER_KEYCODE > (FIRST_DEFAULT_LAYER_KEYCODE + 7)
#        define DEFLYR9  (FIRST_DEFAULT_LAYER_KEYCODE + 8)
#        define DEFLYR9 (FIRST_DEFAULT_LAYER_KEYCODE + 8)
#        define DEFLYR10 (FIRST_DEFAULT_LAYER_KEYCODE + 9)
#        define DEFLYR11 (FIRST_DEFAULT_LAYER_KEYCODE + 10)
#        define DEFLYR12 (FIRST_DEFAULT_LAYER_KEYCODE + 11)


@@ 99,9 100,9 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record);
#    define KC_C1R3 SH_T(KC_TAB)
#elif defined(DRASHNA_LP)
#    define KC_C1R3 TG(_GAMEPAD)
#else  // SWAP_HANDS_ENABLE
#else // SWAP_HANDS_ENABLE
#    define KC_C1R3 KC_TAB
#endif  // SWAP_HANDS_ENABLE
#endif // SWAP_HANDS_ENABLE

#define BK_LWER LT(_LOWER, KC_BSPC)
#define SP_LWER LT(_LOWER, KC_SPC)


@@ 120,7 121,7 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record);
#define OS_RCTL OSM(MOD_RCTL)
#define OS_LALT OSM(MOD_LALT)
#define OS_RALT OSM(MOD_RALT)
#define OS_MEH  OSM(MOD_MEH)
#define OS_MEH OSM(MOD_MEH)
#define OS_HYPR OSM(MOD_HYPR)

#define ALT_APP ALT_T(KC_APP)


@@ 138,9 139,9 @@ We use custom codes here, so we can substitute the right stuff
#    define KC_D3_2 TD(TD_D3_2)
#    define KC_D3_3 TD(TD_D3_3)
#    define KC_D3_4 TD(TD_D3_4)
#else  // TAP_DANCE_ENABLE
#else // TAP_DANCE_ENABLE
#    define KC_D3_1 KC_1
#    define KC_D3_2 KC_2
#    define KC_D3_3 KC_3
#    define KC_D3_4 KC_4
#endif  // TAP_DANCE_ENABLE
#endif // TAP_DANCE_ENABLE

M users/drashna/keyrecords/tap_dances.c => users/drashna/keyrecords/tap_dances.c +1 -1
@@ 26,7 26,7 @@ void diablo_tapdance_master(qk_tap_dance_state_t *state, void *user_data) {
    if (state->count >= (sizeof(diablo_times) / sizeof(uint8_t))) {
        diablo_timer[diablo_keys->index].key_interval = 0;
        reset_tap_dance(state);
    } else {  // else set the interval (tapdance count starts at 1, array starts at 0, so offset by one)
    } else { // else set the interval (tapdance count starts at 1, array starts at 0, so offset by one)
        diablo_timer[diablo_keys->index].key_interval = diablo_times[state->count - 1];
    }
}

M users/drashna/keyrecords/tap_dances.h => users/drashna/keyrecords/tap_dances.h +1 -1
@@ 28,4 28,4 @@ enum {
    TD_D3_3,
    TD_D3_4,
};
#endif  // TAP_DANCE_ENABLE
#endif // TAP_DANCE_ENABLE

M users/drashna/keyrecords/tapping.c => users/drashna/keyrecords/tapping.c +3 -3
@@ 29,10 29,10 @@ __attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyreco
    // Do not select the hold action when another key is pressed.
    // return false;
    switch (keycode) {
        case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
            return true;
//        case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
//            return true;
        default:
            return false;
            return true;
    }
}


M users/drashna/keyrecords/unicode.c => users/drashna/keyrecords/unicode.c +90 -45
@@ 69,7 69,7 @@ bool process_record_glyph_replacement(uint16_t keycode, keyrecord_t *record, tra
            }
            return false;
        } else if (KC_1 <= keycode && keycode <= KC_0) {
            if (is_shifted) {  // skip shifted numbers, so that we can still use symbols etc.
            if (is_shifted) { // skip shifted numbers, so that we can still use symbols etc.
                return process_record_keymap(keycode, record);
            }
            if (record->event.pressed) {


@@ 92,42 92,81 @@ DEFINE_UNICODE_RANGE_TRANSLATOR(unicode_range_translator_boxes, 0x1F170, 0x1F170
DEFINE_UNICODE_RANGE_TRANSLATOR(unicode_range_translator_regional, 0x1F1E6, 0x1F1E6, '0', '1', 0x2003);

DEFINE_UNICODE_LUT_TRANSLATOR(unicode_lut_translator_aussie,
                              0x0250,  // a
                              'q',     // b
                              0x0254,  // c
                              'p',     // d
                              0x01DD,  // e
                              0x025F,  // f
                              0x0183,  // g
                              0x0265,  // h
                              0x1D09,  // i
                              0x027E,  // j
                              0x029E,  // k
                              'l',     // l
                              0x026F,  // m
                              'u',     // n
                              'o',     // o
                              'd',     // p
                              'b',     // q
                              0x0279,  // r
                              's',     // s
                              0x0287,  // t
                              'n',     // u
                              0x028C,  // v
                              0x028D,  // w
                              0x2717,  // x
                              0x028E,  // y
                              'z',     // z
                              0x0269,  // 1
                              0x3139,  // 2
                              0x0190,  // 3
                              0x3123,  // 4
                              0x03DB,  // 5
                              '9',     // 6
                              0x3125,  // 7
                              '8',     // 8
                              '6',     // 9
                              '0'      // 0
                              0x0250, // a
                              'q',    // b
                              0x0254, // c
                              'p',    // d
                              0x01DD, // e
                              0x025F, // f
                              0x0183, // g
                              0x0265, // h
                              0x1D09, // i
                              0x027E, // j
                              0x029E, // k
                              'l',    // l
                              0x026F, // m
                              'u',    // n
                              'o',    // o
                              'd',    // p
                              'b',    // q
                              0x0279, // r
                              's',    // s
                              0x0287, // t
                              'n',    // u
                              0x028C, // v
                              0x028D, // w
                              0x2717, // x
                              0x028E, // y
                              'z',    // z
                              0x0269, // 1
                              0x3139, // 2
                              0x0190, // 3
                              0x3123, // 4
                              0x03DB, // 5
                              '9',    // 6
                              0x3125, // 7
                              '8',    // 8
                              '6',    // 9
                              '0'     // 0
);

DEFINE_UNICODE_LUT_TRANSLATOR(unicode_lut_translator_super,
                              0x1D43, // a
                              0x1D47, // b
                              0x1D9C, // c
                              0x1D48, // d
                              0x1D49, // e
                              0x1DA0, // f
                              0x1D4D, // g
                              0x02B0, // h
                              0x2071, // i
                              0x02B2, // j
                              0x1D4F, // k
                              0x1D4F, // l
                              0x1D50, // m
                              0x207F, // n
                              0x1D52, // o
                              0x1D56, // p
                              0x06F9, // q
                              0x02B3, // r
                              0x02E2, // s
                              0x1D57, // t
                              0x1D58, // u
                              0x1D5B, // v
                              0x02B7, // w
                              0x02E3, // x
                              0x02B8, // y
                              0x1DBB, // z
                              0x00B9, // 1
                              0x00B2, // 2
                              0x00B3, // 3
                              0x2074, // 4
                              0x2075, // 5
                              0x2076, // 6
                              0x2077, // 7
                              0x2078, // 8
                              0x2079, // 9
                              0x2070  // 0
);

bool process_record_aussie(uint16_t keycode, keyrecord_t *record) {


@@ 207,41 246,41 @@ bool process_record_zalgo(uint16_t keycode, keyrecord_t *record) {

bool process_record_unicode(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case UC_FLIP:  // (ノಠ痊ಠ)ノ彡┻━┻
        case UC_FLIP: // (ノಠ痊ಠ)ノ彡┻━┻
            if (record->event.pressed) {
                send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻");
            }
            break;

        case UC_TABL:  // ┬─┬ノ( º _ ºノ)
        case UC_TABL: // ┬─┬ノ( º _ ºノ)
            if (record->event.pressed) {
                send_unicode_string("┬─┬ノ( º _ ºノ)");
            }
            break;

        case UC_SHRG:  // ¯\_(ツ)_/¯
        case UC_SHRG: // ¯\_(ツ)_/¯
            if (record->event.pressed) {
                send_unicode_string("¯\\_(ツ)_/¯");
            }
            break;

        case UC_DISA:  // ಠ_ಠ
        case UC_DISA: // ಠ_ಠ
            if (record->event.pressed) {
                send_unicode_string("ಠ_ಠ");
            }
            break;

        case UC_IRNY:  // ⸮
        case UC_IRNY: // ⸮
            if (record->event.pressed) {
                register_unicode(0x2E2E);
            }
            break;
        case UC_CLUE:  // ‽
        case UC_CLUE: // ‽
            if (record->event.pressed) {
                register_unicode(0x203D);
            }
            break;
        case KC_NOMODE ... KC_ZALGO:
        case KC_NOMODE ... KC_SUPER:
            if (record->event.pressed) {
                if (typing_mode != keycode - KC_NOMODE) {
                    typing_mode = keycode - KC_NOMODE;


@@ 280,6 319,10 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record) {
                return false;
            }
        }
    } else if (typing_mode == UCTM_SUPER) {
        if (((KC_A <= keycode) && (keycode <= KC_0))) {
            return process_record_glyph_replacement(keycode, record, unicode_lut_translator_super);
        }
    } else if (typing_mode == UCTM_AUSSIE) {
        return process_record_aussie(keycode, record);
    } else if (typing_mode == UCTM_ZALGO) {


@@ 292,4 335,6 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record) {
 * @brief Initialize the default unicode mode on firmware startu
 *
 */
void matrix_init_unicode(void) { unicode_input_mode_init(); }
void matrix_init_unicode(void) {
    unicode_input_mode_init();
}

M users/drashna/keyrecords/unicode.h => users/drashna/keyrecords/unicode.h +1 -0
@@ 11,6 11,7 @@ enum unicode_typing_mode {
    UCTM_REGIONAL,
    UCTM_AUSSIE,
    UCTM_ZALGO,
    UCTM_SUPER,
};

extern uint8_t typing_mode;

M users/drashna/oled/oled_stuff.c => users/drashna/oled/oled_stuff.c +153 -92
@@ 34,7 34,7 @@ uint32_t        oled_timer                        = 0;
char            keylog_str[OLED_KEYLOGGER_LENGTH] = {0};
static uint16_t log_timer                         = 0;
#ifdef OLED_DISPLAY_VERBOSE
static const char PROGMEM display_border[3] = {0x0, 0xFF, 0x0};
const char PROGMEM display_border[3] = {0x0, 0xFF, 0x0};
#endif

deferred_token kittoken;


@@ 117,9 117,9 @@ void oled_timer_reset(void) {
 * @brief Renders keylogger buffer to oled
 *
 */
void render_keylogger_status(void) {
void render_keylogger_status(uint8_t col, uint8_t line) {
#ifdef OLED_DISPLAY_VERBOSE
    oled_set_cursor(1, 6);
    oled_set_cursor(col, line);
#endif
    oled_write_P(PSTR(OLED_RENDER_KEYLOGGER), false);
    oled_write(keylog_str, false);


@@ 132,9 132,9 @@ void render_keylogger_status(void) {
 * @brief Renders default layer state (aka layout) to oled
 *
 */
void render_default_layer_state(void) {
void render_default_layer_state(uint8_t col, uint8_t line) {
#ifdef OLED_DISPLAY_VERBOSE
    oled_set_cursor(1, 1);
    oled_set_cursor(col, line);
#endif
    oled_write_P(PSTR(OLED_RENDER_LAYOUT_NAME), false);
    switch (get_highest_layer(default_layer_state)) {


@@ 160,7 160,7 @@ void render_default_layer_state(void) {
 * @brief Renders the active layers to the OLED
 *
 */
void render_layer_state(void) {
void render_layer_state(uint8_t col, uint8_t line) {
#ifdef OLED_DISPLAY_VERBOSE
    // clang-format off
    static const char PROGMEM tri_layer_image[][3][24] = {


@@ 286,33 286,33 @@ void render_layer_state(void) {
        layer_is[2] = 5;
    }

    oled_set_cursor(1, 2);
    oled_set_cursor(col, line);
    oled_write_raw_P(tri_layer_image[layer_is[0]][0], sizeof(tri_layer_image[0][0]));
    oled_set_cursor(5, 2);
    oled_set_cursor(col + 4, line);
    oled_write_raw_P(tri_layer_image[layer_is[1]][0], sizeof(tri_layer_image[0][0]));
    oled_set_cursor(9, 2);
    oled_set_cursor(col + 8, line);
    oled_write_raw_P(tri_layer_image[layer_is[2]][0], sizeof(tri_layer_image[0][0]));
    oled_set_cursor(14, 2);
    oled_set_cursor(col + 13, line);
    oled_write_P(PSTR("Diablo2"), layer_state_is(_DIABLOII));
    oled_advance_page(true);

    oled_set_cursor(1, 3);
    oled_set_cursor(col, line + 1);
    oled_write_raw_P(tri_layer_image[layer_is[0]][1], sizeof(tri_layer_image[0][0]));
    oled_set_cursor(5, 3);
    oled_set_cursor(col + 4, line + 1);
    oled_write_raw_P(tri_layer_image[layer_is[1]][1], sizeof(tri_layer_image[0][0]));
    oled_set_cursor(9, 3);
    oled_set_cursor(col + 8, line + 1);
    oled_write_raw_P(tri_layer_image[layer_is[2]][1], sizeof(tri_layer_image[0][0]));
    oled_set_cursor(14, 3);
    oled_set_cursor(col + 13, line + 1);
    oled_write_P(PSTR("Diablo3"), layer_state_is(_DIABLO));
    oled_advance_page(true);

    oled_set_cursor(1, 4);
    oled_set_cursor(col, line + 2);
    oled_write_raw_P(tri_layer_image[layer_is[0]][2], sizeof(tri_layer_image[0][0]));
    oled_set_cursor(5, 4);
    oled_set_cursor(col + 4, line + 2);
    oled_write_raw_P(tri_layer_image[layer_is[1]][2], sizeof(tri_layer_image[0][0]));
    oled_set_cursor(9, 4);
    oled_set_cursor(col + 8, line + 2);
    oled_write_raw_P(tri_layer_image[layer_is[2]][2], sizeof(tri_layer_image[0][0]));
    oled_set_cursor(14, 4);
    oled_set_cursor(col + 13, line + 2);
    oled_write_P(PSTR("Media"), layer_state_is(_MEDIA));
#else
    oled_write_P(PSTR(OLED_RENDER_LAYER_NAME), false);


@@ 327,9 327,12 @@ void render_layer_state(void) {
 *
 * @param led_usb_state Current keyboard led state
 */
void render_keylock_status(led_t led_usb_state) {
void render_keylock_status(led_t led_usb_state, uint8_t col, uint8_t line) {
#if defined(OLED_DISPLAY_VERBOSE)
    oled_set_cursor(1, 6);
    oled_set_cursor(col, line);
#endif
#ifdef CAPS_WORD_ENABLE
    led_usb_state.caps_lock |= is_caps_word_on();
#endif
    oled_write_P(PSTR(OLED_RENDER_LOCK_NAME), false);
#if !defined(OLED_DISPLAY_VERBOSE)


@@ 348,8 351,9 @@ void render_keylock_status(led_t led_usb_state) {
 * @brief Renders the matrix scan rate to the host system
 *
 */
void render_matrix_scan_rate(uint8_t padding) {
void render_matrix_scan_rate(uint8_t padding, uint8_t col, uint8_t line) {
#ifdef DEBUG_MATRIX_SCAN_RATE
    oled_set_cursor(col, line);
    oled_write_P(PSTR("MS:"), false);
    if (padding) {
        for (uint8_t n = padding; n > 0; n--) {


@@ 365,10 369,10 @@ void render_matrix_scan_rate(uint8_t padding) {
 *
 * @param modifiers Modifiers to check against (real, weak, onesheot, etc;)
 */
void render_mod_status(uint8_t modifiers) {
void render_mod_status(uint8_t modifiers, uint8_t col, uint8_t line) {
    static const char PROGMEM mod_status[5][3] = {{0xE8, 0xE9, 0}, {0xE4, 0xE5, 0}, {0xE6, 0xE7, 0}, {0xEA, 0xEB, 0}, {0xEC, 0xED, 0}};
#if defined(OLED_DISPLAY_VERBOSE)
    oled_set_cursor(1, 5);
    oled_set_cursor(col, line);
#endif
    oled_write_P(PSTR(OLED_RENDER_MODS_NAME), false);
#if defined(OLED_DISPLAY_VERBOSE)


@@ 393,7 397,7 @@ void render_mod_status(uint8_t modifiers) {
extern bool swap_hands;
#endif

void render_bootmagic_status(void) {
void render_bootmagic_status(uint8_t col, uint8_t line) {
    /* Show Ctrl-Gui Swap options */
    static const char PROGMEM logo[][2][3] = {
        {{0x97, 0x98, 0}, {0xb7, 0xb8, 0}},


@@ 402,7 406,8 @@ void render_bootmagic_status(void) {

    bool is_bootmagic_on;
#ifdef OLED_DISPLAY_VERBOSE
    oled_set_cursor(7, 3);
    oled_set_cursor(col, line);
    //    oled_set_cursor(7, 3);
    is_bootmagic_on = !keymap_config.swap_lctl_lgui;
#else
    is_bootmagic_on = keymap_config.swap_lctl_lgui;


@@ 435,7 440,7 @@ void render_bootmagic_status(void) {
    oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_NOGUI), keymap_config.no_gui);
#endif
#ifdef OLED_DISPLAY_VERBOSE
    oled_set_cursor(7, 4);
    oled_set_cursor(col, line + 1);
    if (keymap_config.swap_lctl_lgui) {
        oled_write_P(logo[1][1], is_bootmagic_on);
    } else {


@@ 455,7 460,7 @@ void render_bootmagic_status(void) {
extern bool tap_toggling;
#endif

void render_user_status(void) {
void render_user_status(uint8_t col, uint8_t line) {
#ifdef AUDIO_ENABLE
    bool is_audio_on = false, l_is_clicky_on = false;
#    ifdef SPLIT_KEYBOARD


@@ 472,7 477,7 @@ void render_user_status(void) {
#    endif
#endif
#if defined(OLED_DISPLAY_VERBOSE)
    oled_set_cursor(1, 5);
    oled_set_cursor(col, line);
#endif
    oled_write_P(PSTR(OLED_RENDER_USER_NAME), false);
#if !defined(OLED_DISPLAY_VERBOSE)


@@ 523,9 528,27 @@ void render_user_status(void) {
#endif
}

void render_wpm(uint8_t padding) {
#ifdef WPM_ENABLE
void render_rgb_hsv(uint8_t col, uint8_t line) {
    oled_set_cursor(col, line);
    oled_write_P(PSTR("HSV: "), false);
#ifdef RGB_MATRIX_ENABLE
    oled_write(get_u8_str(rgb_matrix_get_hue(), ' '), false);
    oled_write_P(PSTR(", "), false);
    oled_write(get_u8_str(rgb_matrix_get_sat(), ' '), false);
    oled_write_P(PSTR(", "), false);
    oled_write(get_u8_str(rgb_matrix_get_val(), ' '), false);
#elif RGBLIGHT_ENABLE
    oled_write(get_u8_str(rgblight_get_hue(), ' '), false);
    oled_write_P(PSTR(", "), false);
    oled_write(get_u8_str(rgblight_get_sat(), ' '), false);
    oled_write_P(PSTR(", "), false);
    oled_write(get_u8_str(rgblight_get_val(), ' '), false);
#endif
}

void render_wpm(uint8_t padding, uint8_t col, uint8_t line) {
#ifdef WPM_ENABLE
    oled_set_cursor(col, line);
    oled_write_P(PSTR(OLED_RENDER_WPM_COUNTER), false);
    if (padding) {
        for (uint8_t n = padding; n > 0; n--) {


@@ 591,7 614,8 @@ void render_wpm_graph(uint8_t max_lines_graph, uint8_t vertical_offset) {
}

#if defined(POINTING_DEVICE_ENABLE)
void render_pointing_dpi_status(uint16_t cpi, uint8_t padding) {
void render_pointing_dpi_status(uint16_t cpi, uint8_t padding, uint8_t col, uint8_t line) {
    oled_set_cursor(col, line);
    oled_write_P(PSTR("CPI:"), false);
    if (padding) {
        for (uint8_t n = padding - 1; n > 0; n--) {


@@ 603,13 627,6 @@ void render_pointing_dpi_status(uint16_t cpi, uint8_t padding) {
}
#endif

__attribute__((weak)) void oled_driver_render_logo_right(void) {
#if defined(OLED_DISPLAY_VERBOSE)
    oled_set_cursor(0, 1);
#endif
    render_default_layer_state();
}

// WPM-responsive animation stuff here
#define OLED_SLEEP_FRAMES 2
#define OLED_SLEEP_SPEED 10 // below this wpm value your animation will idle


@@ 635,7 652,7 @@ __attribute__((weak)) void oled_driver_render_logo_right(void) {
static uint8_t animation_frame = 0;
static uint8_t animation_type  = 0;

void render_kitty(void) {
void render_kitty(uint8_t col, uint8_t line) {
    // Images credit j-inc(/James Incandenza) and pixelbenny.
    // Credit to obosob for initial animation approach.
    // heavily modified by drashna because he's a glutton for punishment


@@ 712,11 729,44 @@ void render_kitty(void) {
    // clang-format on

    for (uint8_t i = 0; i < 4; i++) {
        oled_set_cursor(1, i + 1);
        oled_set_cursor(col, line + i);
        oled_write_raw_P(animation[animation_type][animation_frame][i], OLED_ANIM_SIZE);
    }
}

void render_unicode_mode(uint8_t col, uint8_t line) {
#ifdef CUSTOM_UNICODE_ENABLE
    oled_set_cursor(col, line);
    oled_write_ln_P(PSTR("Unicode:"), false);
    switch (typing_mode) {
        case UCTM_WIDE:
            oled_write_P(PSTR("        Wide"), false);
            break;
        case UCTM_SCRIPT:
            oled_write_P(PSTR("      Script"), false);
            break;
        case UCTM_BLOCKS:
            oled_write_P(PSTR("      Blocks"), false);
            break;
        case UCTM_REGIONAL:
            oled_write_P(PSTR("    Regional"), false);
            break;
        case UCTM_AUSSIE:
            oled_write_P(PSTR("      Aussie"), false);
            break;
        case UCTM_ZALGO:
            oled_write_P(PSTR("       Zalgo"), false);
            break;
        case UCTM_NO_MODE:
            oled_write_P(PSTR("      Normal"), false);
            break;
        default:
            oled_write_P(PSTR("     Unknown"), false);
            break;
    }
#endif
}

uint32_t kitty_animation_phases(uint32_t triger_time, void *cb_arg) {
    static uint32_t anim_frame_duration = 500;
#ifdef CUSTOM_POINTING_DEVICE


@@ 748,34 798,8 @@ uint32_t kitty_animation_phases(uint32_t triger_time, void *cb_arg) {
    return anim_frame_duration;
}

void oled_driver_render_logo_left(void) {
#if defined(OLED_DISPLAY_VERBOSE)
    oled_set_cursor(0, 1);
    render_kitty();

#    if defined(KEYBOARD_handwired_tractyl_manuform)
    oled_set_cursor(7, 0);
    oled_write_P(PSTR("Tractyl"), true);
#    elif defined(KEYBOARD_bastardkb_charybdis)
    oled_set_cursor(6, 0);
    oled_write_P(PSTR("Charybdis"), true);
#    elif defined(KEYBOARD_splitkb_kyria)
    oled_set_cursor(7, 0);
    oled_write_P(PSTR("SplitKB"), true);
#    else
    oled_set_cursor(8, 0);
    oled_write_P(PSTR("Left"), true);
#    endif
    oled_set_cursor(7, 1);
#    if defined(WPM_ENABLE)
    render_wpm(1);
#    elif defined(DEBUG_MATRIX_SCAN_RATE)
    render_matrix_scan_rate(2);
#    endif
    oled_set_cursor(7, 2);
#    if (defined(KEYBOARD_bastardkb_charybdis) || defined(KEYBOARD_handwired_tractyl_manuform)) && defined(POINTING_DEVICE_ENABLE)
    render_pointing_dpi_status(charybdis_get_pointer_sniping_enabled() ? charybdis_get_pointer_sniping_dpi() : charybdis_get_pointer_default_dpi(), 1);

void render_mouse_mode(uint8_t col, uint8_t line) {
#if (defined(KEYBOARD_bastardkb_charybdis) || defined(KEYBOARD_handwired_tractyl_manuform)) && defined(POINTING_DEVICE_ENABLE)
    // credit and thanks to jaspertandy on discord for these images
    static const char PROGMEM mouse_logo[3][2][16] = {// mouse icon
                                                      {{0, 0, 0, 252, 2, 2, 2, 58, 2, 2, 2, 252, 0, 0, 0, 0}, {0, 0, 63, 96, 64, 64, 64, 64, 64, 64, 64, 96, 63, 0, 0, 0}},


@@ 785,27 809,20 @@ void oled_driver_render_logo_left(void) {
                                                      {{0, 0, 112, 136, 156, 2, 15, 1, 15, 2, 140, 68, 56, 0, 0, 0}, {0, 0, 2, 6, 15, 28, 60, 124, 60, 28, 15, 6, 2, 0, 0, 0}}};

    uint8_t image_index = 0;
#        ifdef OLED_DISPLAY_TEST
#    ifdef OLED_DISPLAY_TEST
    image_index = animation_frame;
#        else
#    else
    if (charybdis_get_pointer_sniping_enabled()) {
        image_index = 1;
    } else if (charybdis_get_pointer_dragscroll_enabled()) {
        image_index = 2;
    }
#        endif
#    endif

    oled_set_cursor(17, 1);
    oled_set_cursor(col, line);
    oled_write_raw_P(mouse_logo[image_index][0], 16);
    oled_set_cursor(17, 2);
    oled_set_cursor(col, line + 1);
    oled_write_raw_P(mouse_logo[image_index][1], 16);
#    elif defined(WPM_ENABLE) && defined(DEBUG_MATRIX_SCAN_RATE)
    render_matrix_scan_rate(2);
#    endif

    oled_set_cursor(0, 5);
#else
    render_default_layer_state();
#endif
}



@@ 823,27 840,73 @@ void render_status_right(void) {
    oled_set_cursor(8, 0);
    oled_write_P(PSTR("Right"), true);
#endif
    oled_driver_render_logo_right();
#if defined(OLED_DISPLAY_VERBOSE)
    render_default_layer_state(1, 1);
#else
    render_default_layer_state(0, 0);
#endif

    /* Show Keyboard Layout  */
    render_layer_state();
    render_mod_status(get_mods() | get_oneshot_mods());
#if !defined(OLED_DISPLAY_VERBOSE) && defined(WPM_ENABLE) && !defined(CONVERT_TO_PROTON_C)
    render_layer_state(1, 2);
    render_mod_status(get_mods() | get_oneshot_mods(), 1, 5);
#if !defined(OLED_DISPLAY_VERBOSE) && defined(WPM_ENABLE) && !defined(STM32F303xC)
    render_wpm(2);
#endif
    render_keylock_status(host_keyboard_led_state());
    render_keylock_status(host_keyboard_led_state(), 1, 6);
}

void render_status_left(void) {
    oled_driver_render_logo_left();
#if defined(OLED_DISPLAY_VERBOSE)
    render_kitty(0, 1);

#    if defined(KEYBOARD_handwired_tractyl_manuform)
    oled_set_cursor(7, 0);
    oled_write_P(PSTR("Tractyl"), true);
#    elif defined(KEYBOARD_bastardkb_charybdis)
    oled_set_cursor(6, 0);
    oled_write_P(PSTR("Charybdis"), true);
#    elif defined(KEYBOARD_splitkb_kyria)
    oled_set_cursor(7, 0);
    oled_write_P(PSTR("SplitKB"), true);
#    elif defined(KEYBOARD_handwired_fingerpunch_rockon)
    oled_set_cursor(7, 0);
    oled_write_P(PSTR("Rock On"), true);
#    else
    oled_set_cursor(8, 0);
    oled_write_P(PSTR("Left"), true);
#    endif

#    if defined(WPM_ENABLE)
    render_wpm(1, 7, 1);
#    elif defined(DEBUG_MATRIX_SCAN_RATE)
    render_matrix_scan_rate(1, 7, 1);
#    endif
#    if (defined(KEYBOARD_bastardkb_charybdis) || defined(KEYBOARD_handwired_tractyl_manuform)) && defined(POINTING_DEVICE_ENABLE)
    render_pointing_dpi_status(charybdis_get_pointer_sniping_enabled() ? charybdis_get_pointer_sniping_dpi() : charybdis_get_pointer_default_dpi(), 1, 7, 2);
    render_mouse_mode(17, 1);
#    elif defined(WPM_ENABLE) && defined(DEBUG_MATRIX_SCAN_RATE)
    render_matrix_scan_rate(1, 7, 2);
#    endif
    /* Show Keyboard Layout  */
    render_bootmagic_status(7, 3);
    render_user_status(1, 5);

    render_keylogger_status(1, 6);
#else
    render_default_layer_state(0, 0);
    /* Show Keyboard Layout  */
    render_bootmagic_status();
    render_user_status();
    render_bootmagic_status(7, 3);
    render_user_status(1, 5);

    render_keylogger_status();
    render_keylogger_status(1, 6);
#endif
}

__attribute__((weak)) void oled_render_large_display(bool side) {}
__attribute__((weak)) void oled_render_large_display(bool side) {
    if (!side) {
        render_unicode_mode(1, 14);
    }
}

__attribute__((weak)) oled_rotation_t oled_init_keymap(oled_rotation_t rotation) {
    return rotation;


@@ 895,14 958,12 @@ bool oled_task_user(void) {
#endif
        render_status_left();
#if defined(OLED_DISPLAY_128X128)
        oled_set_cursor(0, 7);
        oled_render_large_display(true);
#endif
#ifndef OLED_DISPLAY_TEST
    } else {
        render_status_right();
#    if defined(OLED_DISPLAY_128X128)
        oled_set_cursor(0, 7);
        oled_render_large_display(false);
#    endif
    }

M users/drashna/oled/oled_stuff.h => users/drashna/oled/oled_stuff.h +97 -94
@@ 18,132 18,135 @@

#include "quantum.h"
#include "oled_driver.h"
#ifdef DEFFERED_EXEC_ENABLE
extern deferred_token kittoken;
#endif

void            oled_driver_render_logo(void);
bool            process_record_user_oled(uint16_t keycode, keyrecord_t *record);
oled_rotation_t oled_init_keymap(oled_rotation_t rotation);
void            oled_timer_reset(void);
void            render_keylogger_status(void);
void            render_default_layer_state(void);
void            render_layer_state(void);
void            render_keylock_status(led_t led_usb_state);
void            render_matrix_scan_rate(uint8_t padding);
void            render_mod_status(uint8_t modifiers);
void            render_bootmagic_status(void);
void            render_user_status(void);
void            render_keylogger_status(uint8_t col, uint8_t line);
void            render_default_layer_state(uint8_t col, uint8_t line);
void            render_layer_state(uint8_t col, uint8_t line);
void            render_keylock_status(led_t led_usb_state, uint8_t col, uint8_t line);
void            render_matrix_scan_rate(uint8_t padding, uint8_t col, uint8_t line);
void            render_mod_status(uint8_t modifiers, uint8_t col, uint8_t line);
void            render_bootmagic_status(uint8_t col, uint8_t line);
void            render_user_status(uint8_t col, uint8_t line);
void            oled_driver_render_logo(void);
void            render_wpm(uint8_t padding);
void            render_pointing_dpi_status(uint16_t cpi, uint8_t padding);
void            render_wpm(uint8_t padding, uint8_t col, uint8_t line);
void            render_pointing_dpi_status(uint16_t cpi, uint8_t padding, uint8_t col, uint8_t line);
void            oled_driver_render_logo_left(void);
void            oled_driver_render_logo_right(void);
void            oled_render_large_display(bool side);
void render_wpm_graph(uint8_t max_lines_graph, uint8_t vertical_offset);
void            render_wpm_graph(uint8_t max_lines_graph, uint8_t vertical_offset);
void            render_kitty(uint8_t col, uint8_t line);
void            render_unicode_mode(uint8_t col, uint8_t line);
void            render_rgb_hsv(uint8_t col, uint8_t line);

void oled_pan_section(bool left, uint16_t y_start, uint16_t y_end, uint16_t x_start, uint16_t x_end);


#if defined(OLED_DISPLAY_128X128) || defined(OLED_DISPLAY_128X64)
#    define OLED_DISPLAY_VERBOSE

#    define OLED_RENDER_KEYLOGGER         "Keylogger: "
#    define OLED_RENDER_KEYLOGGER "Keylogger: "
#    ifndef OLED_KEYLOGGER_LENGTH
#        define OLED_KEYLOGGER_LENGTH         9
#        define OLED_KEYLOGGER_LENGTH 9
#    endif
#    define OLED_RENDER_LAYOUT_NAME       "Layout: "
#    define OLED_RENDER_LAYOUT_QWERTY     "Qwerty"
#    define OLED_RENDER_LAYOUT_NAME "Layout: "
#    define OLED_RENDER_LAYOUT_QWERTY "Qwerty"
#    define OLED_RENDER_LAYOUT_COLEMAK_DH "Colemak DH"
#    define OLED_RENDER_LAYOUT_COLEMAK    "Colemak"
#    define OLED_RENDER_LAYOUT_DVORAK     "Dvorak"
#    define OLED_RENDER_LAYOUT_WORKMAN    "Workman"
#    define OLED_RENDER_LAYOUT_NORMAN     "Norman"
#    define OLED_RENDER_LAYOUT_MALTRON    "Matron"
#    define OLED_RENDER_LAYOUT_EUCALYN    "Eucalyn"
#    define OLED_RENDER_LAYOUT_CARPLAX    "Carplax"

#    define OLED_RENDER_LAYER_NAME        "Layer:"
#    define OLED_RENDER_LAYER_LOWER       "Lower"
#    define OLED_RENDER_LAYER_RAISE       "Raise"
#    define OLED_RENDER_LAYER_ADJUST      "Adjust"
#    define OLED_RENDER_LAYER_MODS        "Mods"

#    define OLED_RENDER_LOCK_NAME         "Lock: "
#    define OLED_RENDER_LOCK_NUML         "NUM"
#    define OLED_RENDER_LOCK_CAPS         "CAPS"
#    define OLED_RENDER_LOCK_SCLK         "SCLK"

#    define OLED_RENDER_MODS_NAME         "Mods"
#    define OLED_RENDER_MODS_SFT          "Sft"
#    define OLED_RENDER_MODS_CTL          "Ctl"
#    define OLED_RENDER_MODS_ALT          "Alt"
#    define OLED_RENDER_MODS_GUI          "GUI"

#    define OLED_RENDER_BOOTMAGIC_NAME    "Boot  "
#    define OLED_RENDER_BOOTMAGIC_NKRO    "NKRO"
#    define OLED_RENDER_BOOTMAGIC_NOGUI   "nGUI"
#    define OLED_RENDER_BOOTMAGIC_GRV     "GRV"
#    define OLED_RENDER_LAYOUT_COLEMAK "Colemak"
#    define OLED_RENDER_LAYOUT_DVORAK "Dvorak"
#    define OLED_RENDER_LAYOUT_WORKMAN "Workman"
#    define OLED_RENDER_LAYOUT_NORMAN "Norman"
#    define OLED_RENDER_LAYOUT_MALTRON "Matron"
#    define OLED_RENDER_LAYOUT_EUCALYN "Eucalyn"
#    define OLED_RENDER_LAYOUT_CARPLAX "Carplax"

#    define OLED_RENDER_LAYER_NAME "Layer:"
#    define OLED_RENDER_LAYER_LOWER "Lower"
#    define OLED_RENDER_LAYER_RAISE "Raise"
#    define OLED_RENDER_LAYER_ADJUST "Adjust"
#    define OLED_RENDER_LAYER_MODS "Mods"

#    define OLED_RENDER_LOCK_NAME "Lock: "
#    define OLED_RENDER_LOCK_NUML "NUM"
#    define OLED_RENDER_LOCK_CAPS "CAPS"
#    define OLED_RENDER_LOCK_SCLK "SCLK"

#    define OLED_RENDER_MODS_NAME "Mods"
#    define OLED_RENDER_MODS_SFT "Sft"
#    define OLED_RENDER_MODS_CTL "Ctl"
#    define OLED_RENDER_MODS_ALT "Alt"
#    define OLED_RENDER_MODS_GUI "GUI"

#    define OLED_RENDER_BOOTMAGIC_NAME "Boot  "
#    define OLED_RENDER_BOOTMAGIC_NKRO "NKRO"
#    define OLED_RENDER_BOOTMAGIC_NOGUI "nGUI"
#    define OLED_RENDER_BOOTMAGIC_GRV "GRV"
#    define OLED_RENDER_BOOTMAGIC_ONESHOT "1SHT"
#    define OLED_RENDER_BOOTMAGIC_SWAP    "SWAP"
#    define OLED_RENDER_BOOTMAGIC_CAPS    "CAPS"
#    define OLED_RENDER_BOOTMAGIC_SWAP "SWAP"
#    define OLED_RENDER_BOOTMAGIC_CAPS "CAPS"

#    define OLED_RENDER_USER_NAME         "USER:"
#    define OLED_RENDER_USER_ANIM         "Anim"
#    define OLED_RENDER_USER_LAYR         "Layr"
#    define OLED_RENDER_USER_NUKE         "Nuke"
#    define OLED_RENDER_USER_NAME "USER:"
#    define OLED_RENDER_USER_ANIM "Anim"
#    define OLED_RENDER_USER_LAYR "Layr"
#    define OLED_RENDER_USER_NUKE "Nuke"

#    define OLED_RENDER_WPM_COUNTER       "WPM: "
#    define OLED_RENDER_WPM_COUNTER "WPM: "
#else
#    define OLED_RENDER_KEYLOGGER         "KLogr"
#    define OLED_RENDER_KEYLOGGER "KLogr"
#    ifndef OLED_KEYLOGGER_LENGTH
#        define OLED_KEYLOGGER_LENGTH         5
#        define OLED_KEYLOGGER_LENGTH 5
#    endif

#    define OLED_RENDER_LAYOUT_NAME       "Lyout"
#    define OLED_RENDER_LAYOUT_QWERTY     " QRTY"
#    define OLED_RENDER_LAYOUT_NAME "Lyout"
#    define OLED_RENDER_LAYOUT_QWERTY " QRTY"
#    define OLED_RENDER_LAYOUT_COLEMAK_DH " cmDH"
#    define OLED_RENDER_LAYOUT_COLEMAK    " COLE"
#    define OLED_RENDER_LAYOUT_DVORAK     " DVRK"
#    define OLED_RENDER_LAYOUT_WORKMAN    " WKMN"
#    define OLED_RENDER_LAYOUT_NORMAN     " NORM"
#    define OLED_RENDER_LAYOUT_MALTRON    " MLTN"
#    define OLED_RENDER_LAYOUT_EUCALYN    " ECLN"
#    define OLED_RENDER_LAYOUT_CARPLAX    " CRPX"

#    define OLED_RENDER_LAYER_NAME        "LAYER"
#    define OLED_RENDER_LAYER_LOWER       "Lower"
#    define OLED_RENDER_LAYER_RAISE       "Raise"
#    define OLED_RENDER_LAYER_ADJUST      "Adjst"
#    define OLED_RENDER_LAYER_MODS        " Mods"

#    define OLED_RENDER_LOCK_NAME         "Lock:"
#    define OLED_RENDER_LOCK_NUML         "NumL"
#    define OLED_RENDER_LOCK_CAPS         "CapL"
#    define OLED_RENDER_LOCK_SCLK         "ScrL"

#    define OLED_RENDER_MODS_NAME         "Mods: "
#    define OLED_RENDER_MODS_SFT          "Shft"
#    define OLED_RENDER_MODS_CTL          "Ctrl"
#    define OLED_RENDER_MODS_ALT          "Alt\n"
#    define OLED_RENDER_MODS_GUI          "GUI\n"

#    define OLED_RENDER_BOOTMAGIC_NAME    "BTMGK"
#    define OLED_RENDER_BOOTMAGIC_NKRO    "NKRO"
#    define OLED_RENDER_BOOTMAGIC_NOGUI   "nGUI"
#    define OLED_RENDER_BOOTMAGIC_GRV     "GRV"
#    define OLED_RENDER_LAYOUT_COLEMAK " COLE"
#    define OLED_RENDER_LAYOUT_DVORAK " DVRK"
#    define OLED_RENDER_LAYOUT_WORKMAN " WKMN"
#    define OLED_RENDER_LAYOUT_NORMAN " NORM"
#    define OLED_RENDER_LAYOUT_MALTRON " MLTN"
#    define OLED_RENDER_LAYOUT_EUCALYN " ECLN"
#    define OLED_RENDER_LAYOUT_CARPLAX " CRPX"

#    define OLED_RENDER_LAYER_NAME "LAYER"
#    define OLED_RENDER_LAYER_LOWER "Lower"
#    define OLED_RENDER_LAYER_RAISE "Raise"
#    define OLED_RENDER_LAYER_ADJUST "Adjst"
#    define OLED_RENDER_LAYER_MODS " Mods"

#    define OLED_RENDER_LOCK_NAME "Lock:"
#    define OLED_RENDER_LOCK_NUML "NumL"
#    define OLED_RENDER_LOCK_CAPS "CapL"
#    define OLED_RENDER_LOCK_SCLK "ScrL"

#    define OLED_RENDER_MODS_NAME "Mods: "
#    define OLED_RENDER_MODS_SFT "Shft"
#    define OLED_RENDER_MODS_CTL "Ctrl"
#    define OLED_RENDER_MODS_ALT "Alt\n"
#    define OLED_RENDER_MODS_GUI "GUI\n"

#    define OLED_RENDER_BOOTMAGIC_NAME "BTMGK"
#    define OLED_RENDER_BOOTMAGIC_NKRO "NKRO"
#    define OLED_RENDER_BOOTMAGIC_NOGUI "nGUI"
#    define OLED_RENDER_BOOTMAGIC_GRV "GRV"
#    define OLED_RENDER_BOOTMAGIC_ONESHOT "1SHT"
#    define OLED_RENDER_BOOTMAGIC_SWAP    "SWAP"
#    define OLED_RENDER_BOOTMAGIC_CAPS    "CAPS"
#    define OLED_RENDER_BOOTMAGIC_SWAP "SWAP"
#    define OLED_RENDER_BOOTMAGIC_CAPS "CAPS"

#    define OLED_RENDER_USER_NAME         "USER:"
#    define OLED_RENDER_USER_ANIM         "Anim"
#    define OLED_RENDER_USER_LAYR         "Layr"
#    define OLED_RENDER_USER_NUKE         "Nuke"
#    define OLED_RENDER_USER_NAME "USER:"
#    define OLED_RENDER_USER_ANIM "Anim"
#    define OLED_RENDER_USER_LAYR "Layr"
#    define OLED_RENDER_USER_NUKE "Nuke"

#    define OLED_RENDER_WPM_COUNTER       "WPM: "
#    define OLED_RENDER_WPM_COUNTER "WPM: "
#endif


extern char                      keylog_str[OLED_KEYLOGGER_LENGTH];
extern char keylog_str[OLED_KEYLOGGER_LENGTH];

#ifndef OLED_WPM_GRAPH_MAX_WPM
#    define OLED_WPM_GRAPH_MAX_WPM 120

M users/drashna/oled/sh110x.c => users/drashna/oled/sh110x.c +36 -22
@@ 52,7 52,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#define PAGE_ADDR 0x22
#define PAM_SETCOLUMN_LSB 0x00
#define PAM_SETCOLUMN_MSB 0x10
#define PAM_PAGE_ADDR 0xB0  // 0xb0 -- 0xb7
#define PAM_PAGE_ADDR 0xB0 // 0xb0 -- 0xb7

// Hardware Configuration Commands
#define DISPLAY_START_LINE 0x40


@@ 109,9 109,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#define I2C_DATA 0x40
#if defined(__AVR__)
#    define I2C_TRANSMIT_P(data) i2c_transmit_P((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), OLED_I2C_TIMEOUT)
#else  // defined(__AVR__)
#else // defined(__AVR__)
#    define I2C_TRANSMIT_P(data) i2c_transmit((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), OLED_I2C_TIMEOUT)
#endif  // defined(__AVR__)
#endif // defined(__AVR__)
#define I2C_TRANSMIT(data) i2c_transmit((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), OLED_I2C_TIMEOUT)
#define I2C_WRITE_REG(mode, data, size) i2c_writeReg((OLED_DISPLAY_ADDRESS << 1), mode, data, size, OLED_I2C_TIMEOUT)



@@ 122,7 122,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
// parts of the display unusable or don't get cleared correctly
// and also allows for drawing & inverting
uint8_t         oled_buffer[OLED_MATRIX_SIZE];
uint8_t *       oled_cursor;
uint8_t        *oled_cursor;
OLED_BLOCK_TYPE oled_dirty          = 0;
bool            oled_initialized    = false;
bool            oled_active         = false;


@@ 131,7 131,7 @@ bool            oled_inverted       = false;
uint8_t         oled_brightness     = OLED_BRIGHTNESS;
oled_rotation_t oled_rotation       = 0;
uint8_t         oled_rotation_width = 0;
uint8_t         oled_scroll_speed   = 0;  // this holds the speed after being remapped to ssd1306 internal values
uint8_t         oled_scroll_speed   = 0; // this holds the speed after being remapped to ssd1306 internal values
uint8_t         oled_scroll_start   = 0;
uint8_t         oled_scroll_end     = 7;
#if OLED_TIMEOUT > 0


@@ 261,8 261,12 @@ bool oled_init(oled_rotation_t rotation) {
    return true;
}

__attribute__((weak)) oled_rotation_t oled_init_kb(oled_rotation_t rotation) { return rotation; }
__attribute__((weak)) oled_rotation_t oled_init_user(oled_rotation_t rotation) { return rotation; }
__attribute__((weak)) oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
    return rotation;
}
__attribute__((weak)) oled_rotation_t oled_init_user(oled_rotation_t rotation) {
    return rotation;
}

void oled_clear(void) {
    memset(oled_buffer, 0, sizeof(oled_buffer));


@@ 299,9 303,9 @@ static void calc_bounds_90(uint8_t update_start, uint8_t *cmd_array) {
    // Only the Page Addressing Mode is supported
    uint8_t start_page   = bottom_block_top_page - (OLED_BLOCK_SIZE * update_start % OLED_DISPLAY_HEIGHT / 8);
    uint8_t start_column = OLED_BLOCK_SIZE * update_start / OLED_DISPLAY_HEIGHT * 8;
    cmd_array[0] = PAM_PAGE_ADDR | start_page;
    cmd_array[1] = PAM_SETCOLUMN_LSB | ((OLED_COLUMN_OFFSET + start_column) & 0x0f);
    cmd_array[2] = PAM_SETCOLUMN_MSB | ((OLED_COLUMN_OFFSET + start_column) >> 4 & 0x0f);
    cmd_array[0]         = PAM_PAGE_ADDR | start_page;
    cmd_array[1]         = PAM_SETCOLUMN_LSB | ((OLED_COLUMN_OFFSET + start_column) & 0x0f);
    cmd_array[2]         = PAM_SETCOLUMN_MSB | ((OLED_COLUMN_OFFSET + start_column) >> 4 & 0x0f);
}

uint8_t crot(uint8_t a, int8_t n) {


@@ 339,9 343,9 @@ void oled_render(void) {
    // Set column & page position
    static uint8_t display_start[] = {I2C_CMD, PAM_PAGE_ADDR, PAM_SETCOLUMN_LSB, PAM_SETCOLUMN_MSB};
    if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
        calc_bounds(update_start, &display_start[1]);  // Offset from I2C_CMD byte at the start
        calc_bounds(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
    } else {
        calc_bounds_90(update_start, &display_start[1]);  // Offset from I2C_CMD byte at the start
        calc_bounds_90(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
    }

    // Send column & page position


@@ 369,7 373,7 @@ void oled_render(void) {

        // For SH1106 or SH1107 the data chunk must be split into separate pieces for each page
        const uint8_t columns_in_block = (OLED_BLOCK_SIZE + OLED_DISPLAY_HEIGHT - 1) / OLED_DISPLAY_HEIGHT * 8;
        const uint8_t num_pages = OLED_BLOCK_SIZE / columns_in_block;
        const uint8_t num_pages        = OLED_BLOCK_SIZE / columns_in_block;
        for (uint8_t i = 0; i < num_pages; ++i) {
            // Send column & page position for all pages except the first one
            if (i > 0) {


@@ 414,7 418,8 @@ void oled_advance_page(bool clearPageRemainder) {
        remaining = remaining / OLED_FONT_WIDTH;

        // Write empty character until next line
        while (remaining--) oled_write_char(' ', false);
        while (remaining--)
            oled_write_char(' ', false);
    } else {
        // Next page index out of bounds?
        if (index + remaining >= OLED_MATRIX_SIZE) {


@@ 465,7 470,7 @@ void oled_write_char(const char data, bool invert) {
    _Static_assert(sizeof(font) >= ((OLED_FONT_END + 1 - OLED_FONT_START) * OLED_FONT_WIDTH), "OLED_FONT_END references outside array");

    // set the reder buffer data
    uint8_t cast_data = (uint8_t)data;  // font based on unsigned type for index
    uint8_t cast_data = (uint8_t)data; // font based on unsigned type for index
    if (cast_data < OLED_FONT_START || cast_data > OLED_FONT_END) {
        memset(oled_cursor, 0x00, OLED_FONT_WIDTH);
    } else {


@@ 610,7 615,7 @@ void oled_write_raw_P(const char *data, uint16_t size) {
        oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
    }
}
#endif  // defined(__AVR__)
#endif // defined(__AVR__)

bool oled_on(void) {
    if (!oled_initialized) {


@@ 660,7 665,9 @@ bool oled_off(void) {
    return !oled_active;
}

bool is_oled_on(void) { return oled_active; }
bool is_oled_on(void) {
    return oled_active;
}

uint8_t oled_set_brightness(uint8_t level) {
    if (!oled_initialized) {


@@ 678,7 685,9 @@ uint8_t oled_set_brightness(uint8_t level) {
    return oled_brightness;
}

uint8_t oled_get_brightness(void) { return oled_brightness; }
uint8_t oled_get_brightness(void) {
    return oled_brightness;
}

// Set the specific 8 lines rows of the screen to scroll.
// 0 is the default for start, and 7 for end, which is the entire


@@ 758,7 767,9 @@ bool oled_scroll_off(void) {
    return !oled_scrolling;
}

bool is_oled_scrolling(void) { return oled_scrolling; }
bool is_oled_scrolling(void) {
    return oled_scrolling;
}

bool oled_invert(bool invert) {
    if (!oled_initialized) {


@@ 842,6 853,9 @@ void oled_task(void) {
#endif
}


__attribute__((weak)) bool oled_task_kb(void) { return oled_task_user(); }
__attribute__((weak)) bool oled_task_user(void) { return true; }
__attribute__((weak)) bool oled_task_kb(void) {
    return oled_task_user();
}
__attribute__((weak)) bool oled_task_user(void) {
    return true;
}

M users/drashna/rgb/rgb_matrix_stuff.c => users/drashna/rgb/rgb_matrix_stuff.c +39 -21
@@ 15,7 15,7 @@ void rgb_matrix_layer_helper(uint8_t hue, uint8_t sat, uint8_t val, uint8_t mode
    }

    switch (mode) {
        case 1:  // breathing
        case 1: // breathing
        {
            uint16_t time = scale16by8(g_rgb_timer, speed / 8);
            hsv.v         = scale8(abs8(sin8(time) - 128) * 2, hsv.v);


@@ 27,7 27,7 @@ void rgb_matrix_layer_helper(uint8_t hue, uint8_t sat, uint8_t val, uint8_t mode
            }
            break;
        }
        default:  // Solid Color
        default: // Solid Color
        {
            RGB rgb = hsv_to_rgb(hsv);
            for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {


@@ 59,6 59,8 @@ void keyboard_post_init_rgb_matrix(void) {
#endif
    if (userspace_config.rgb_layer_change) {
        rgb_matrix_set_flags(LED_FLAG_UNDERGLOW | LED_FLAG_KEYLIGHT | LED_FLAG_INDICATOR);
    } else {
        rgb_matrix_set_flags(LED_FLAG_ALL);
    }
}



@@ 70,7 72,7 @@ bool process_record_user_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
    }
#endif
    switch (keycode) {
        case RGB_IDL:  // This allows me to use underglow as layer indication, or as normal
        case RGB_IDL: // This allows me to use underglow as layer indication, or as normal
#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
            if (record->event.pressed) {
                userspace_config.rgb_matrix_idle_anim ^= 1;


@@ 86,9 88,13 @@ bool process_record_user_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
    return true;
}

__attribute__((weak)) bool rgb_matrix_indicators_advanced_keymap(uint8_t led_min, uint8_t led_max) { return true; }
void                       rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
    if (!rgb_matrix_indicators_advanced_keymap(led_min, led_max)) { return; }
__attribute__((weak)) bool rgb_matrix_indicators_advanced_keymap(uint8_t led_min, uint8_t led_max) {
    return true;
}
void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
    if (!rgb_matrix_indicators_advanced_keymap(led_min, led_max)) {
        return;
    }

#if defined(RGBLIGHT_ENABLE)
    if (!userspace_config.rgb_layer_change)


@@ 96,19 102,7 @@ void                       rgb_matrix_indicators_advanced_user(uint8_t led_min, 
    if (userspace_config.rgb_layer_change)
#endif
    {
        switch (get_highest_layer(layer_state | default_layer_state)) {
            case _DEFAULT_LAYER_1:
                rgb_matrix_layer_helper(DEFAULT_LAYER_1_HSV, 0, rgb_matrix_config.speed, LED_FLAG_MODIFIER, led_min, led_max);
                break;
            case _DEFAULT_LAYER_2:
                rgb_matrix_layer_helper(DEFAULT_LAYER_2_HSV, 0, rgb_matrix_config.speed, LED_FLAG_MODIFIER, led_min, led_max);
                break;
            case _DEFAULT_LAYER_3:
                rgb_matrix_layer_helper(DEFAULT_LAYER_3_HSV, 0, rgb_matrix_config.speed, LED_FLAG_MODIFIER, led_min, led_max);
                break;
            case _DEFAULT_LAYER_4:
                rgb_matrix_layer_helper(DEFAULT_LAYER_4_HSV, 0, rgb_matrix_config.speed, LED_FLAG_MODIFIER, led_min, led_max);
                break;
        switch (get_highest_layer(layer_state & ~((layer_state_t)1 << _MOUSE))) {
            case _GAMEPAD:
                rgb_matrix_layer_helper(HSV_ORANGE, 1, rgb_matrix_config.speed, LED_FLAG_MODIFIER, led_min, led_max);
                break;


@@ 124,9 118,33 @@ void                       rgb_matrix_indicators_advanced_user(uint8_t led_min, 
            case _ADJUST:
                rgb_matrix_layer_helper(HSV_RED, 1, rgb_matrix_config.speed, LED_FLAG_MODIFIER, led_min, led_max);
                break;
            default:
                if (layer_state_is(_MOUSE)) {
                    rgb_matrix_layer_helper(HSV_PURPLE, 1, rgb_matrix_config.speed, LED_FLAG_MODIFIER, led_min, led_max);
                } else {
                    switch (get_highest_layer(default_layer_state)) {
                        case _DEFAULT_LAYER_1:
                            rgb_matrix_layer_helper(DEFAULT_LAYER_1_HSV, 0, rgb_matrix_config.speed, LED_FLAG_MODIFIER, led_min, led_max);
                            break;
                        case _DEFAULT_LAYER_2:
                            rgb_matrix_layer_helper(DEFAULT_LAYER_2_HSV, 0, rgb_matrix_config.speed, LED_FLAG_MODIFIER, led_min, led_max);
                            break;
                        case _DEFAULT_LAYER_3:
                            rgb_matrix_layer_helper(DEFAULT_LAYER_3_HSV, 0, rgb_matrix_config.speed, LED_FLAG_MODIFIER, led_min, led_max);
                            break;
                        case _DEFAULT_LAYER_4:
                            rgb_matrix_layer_helper(DEFAULT_LAYER_4_HSV, 0, rgb_matrix_config.speed, LED_FLAG_MODIFIER, led_min, led_max);
                            break;
                    }
                }
                break;
        }
    }
}

__attribute__((weak)) bool rgb_matrix_indicators_keymap(void) { return true; }
void                       rgb_matrix_indicators_user(void) { rgb_matrix_indicators_keymap(); }
__attribute__((weak)) bool rgb_matrix_indicators_keymap(void) {
    return true;
}
void rgb_matrix_indicators_user(void) {
    rgb_matrix_indicators_keymap();
}

M users/drashna/rgb/rgb_stuff.c => users/drashna/rgb/rgb_stuff.c +49 -43
@@ 1,28 1,30 @@
// Copyright 2020 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>
// SPDX-License-Identifier: GPL-2.0-or-later

#ifdef RGBLIGHT_ENABLE

#    include "drashna.h"
#    include "rgb_stuff.h"
#    include "eeprom.h"
#include "drashna.h"
#include "rgb_stuff.h"
#include "eeprom.h"

bool has_initialized;

void rgblight_sethsv_default_helper(uint8_t index) { rgblight_sethsv_at(rgblight_get_hue(), rgblight_get_sat(), rgblight_get_val(), index); }
void rgblight_sethsv_default_helper(uint8_t index) {
    rgblight_sethsv_at(rgblight_get_hue(), rgblight_get_sat(), rgblight_get_val(), index);
}
void rgblight_set_hsv_and_mode(uint8_t hue, uint8_t sat, uint8_t val, uint8_t mode) {
    rgblight_sethsv_noeeprom(hue, sat, val);
    // wait_us(175);  // Add a slight delay between color and mode to ensure it's processed correctly
    rgblight_mode_noeeprom(mode);
}

bool process_record_user_rgb_light(uint16_t keycode, keyrecord_t *record) { return true; }
bool process_record_user_rgb_light(uint16_t keycode, keyrecord_t *record) {
    return true;
}

#    if defined(RGBLIGHT_STARTUP_ANIMATION)
static bool     is_enabled;
static bool     is_rgblight_startup;
static HSV      old_hsv;
static uint8_t  old_mode;
#if defined(RGBLIGHT_STARTUP_ANIMATION)
static bool    is_enabled;
static bool    is_rgblight_startup;
static HSV     old_hsv;
static uint8_t old_mode;
deferred_token rgb_startup_token;

uint32_t rgb_startup_animation(uint32_t triger_time, void *cb_arg) {


@@ 44,10 46,10 @@ uint32_t rgb_startup_animation(uint32_t triger_time, void *cb_arg) {
    }
    return is_rgblight_startup ? 10 : 0;
}
#    endif
#endif

void keyboard_post_init_rgb_light(void) {
#    if defined(RGBLIGHT_STARTUP_ANIMATION)
#if defined(RGBLIGHT_STARTUP_ANIMATION)
    is_enabled = rgblight_is_enabled();
    if (userspace_config.rgb_layer_change) {
        layer_state_set_rgb_light(layer_state);


@@ 56,27 58,17 @@ void keyboard_post_init_rgb_light(void) {
    old_mode = rgblight_get_mode();
    rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
    is_rgblight_startup = true;
    rgb_startup_token = defer_exec(300, rgb_startup_animation, NULL);
#    endif
    rgb_startup_token   = defer_exec(300, rgb_startup_animation, NULL);
#endif
    if (userspace_config.rgb_layer_change) {
        layer_state_set_rgb_light(layer_state);
    }

}

layer_state_t layer_state_set_rgb_light(layer_state_t state) {
#    ifdef RGBLIGHT_ENABLE
#ifdef RGBLIGHT_ENABLE
    if (userspace_config.rgb_layer_change) {
        switch (get_highest_layer(state | default_layer_state)) {
            case _MOUSE:  // mouse
                if (!layer_state_cmp(state, _GAMEPAD) && !layer_state_cmp(state, _DIABLO)) {
#        if defined(RGBLIGHT_EFFECT_TWINKLE)
                    rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_TWINKLE + 5);
#        else
                    rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_BREATHING + 3);
#        endif
                }
                break;
        switch (get_highest_layer(state & ~((layer_state_t)1 << _MOUSE))) {
            case _MEDIA:
                rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_KNIGHT + 1);
                break;


@@ 84,6 76,7 @@ layer_state_t layer_state_set_rgb_light(layer_state_t state) {
                rgblight_set_hsv_and_mode(HSV_ORANGE, RGBLIGHT_MODE_SNAKE + 2);
                break;
            case _DIABLO:
            case _DIABLOII:
                rgblight_set_hsv_and_mode(HSV_RED, RGBLIGHT_MODE_BREATHING + 3);
                break;
            case _RAISE:


@@ 95,23 88,36 @@ layer_state_t layer_state_set_rgb_light(layer_state_t state) {
            case _ADJUST:
                rgblight_set_hsv_and_mode(HSV_RED, RGBLIGHT_MODE_KNIGHT + 2);
                break;
            case _DEFAULT_LAYER_1:
                rgblight_set_hsv_and_mode(DEFAULT_LAYER_1_HSV, RGBLIGHT_MODE_STATIC_LIGHT);
                break;
            case _DEFAULT_LAYER_2:
                rgblight_set_hsv_and_mode(DEFAULT_LAYER_2_HSV, RGBLIGHT_MODE_STATIC_LIGHT);
                break;
            case _DEFAULT_LAYER_3:
                rgblight_set_hsv_and_mode(DEFAULT_LAYER_3_HSV, RGBLIGHT_MODE_STATIC_LIGHT);
                break;
            case _DEFAULT_LAYER_4:
                rgblight_set_hsv_and_mode(DEFAULT_LAYER_4_HSV, RGBLIGHT_MODE_STATIC_LIGHT);
                break;
            default:
                if (layer_state_cmp(state, _MOUSE)) {
#    if defined(RGBLIGHT_EFFECT_TWINKLE)
                    rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_TWINKLE + 5);
#    else
                    rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_BREATHING + 3);
#    endif
                } else {
                    default_layer_state_set_rgb_light(default_layer_state);
                }
        }
#endif // RGBLIGHT_ENABLE
    }
#    endif  // RGBLIGHT_ENABLE

    return state;
}

#endif
layer_state_t default_layer_state_set_rgb_light(layer_state_t state) {
    switch (get_highest_layer(state)) {
        case _DEFAULT_LAYER_1:
            rgblight_set_hsv_and_mode(DEFAULT_LAYER_1_HSV, RGBLIGHT_MODE_STATIC_LIGHT);
            break;
        case _DEFAULT_LAYER_2:
            rgblight_set_hsv_and_mode(DEFAULT_LAYER_2_HSV, RGBLIGHT_MODE_STATIC_LIGHT);
            break;
        case _DEFAULT_LAYER_3:
            rgblight_set_hsv_and_mode(DEFAULT_LAYER_3_HSV, RGBLIGHT_MODE_STATIC_LIGHT);
            break;
        case _DEFAULT_LAYER_4:
            rgblight_set_hsv_and_mode(DEFAULT_LAYER_4_HSV, RGBLIGHT_MODE_STATIC_LIGHT);
            break;
    }
    return state;
}

M users/drashna/rules.mk => users/drashna/rules.mk +4 -1
@@ 3,6 3,8 @@ SRC += $(USER_PATH)/drashna.c \
        $(USER_PATH)/keyrecords/process_records.c \
        $(USER_PATH)/keyrecords/tapping.c

# TOP_SYMBOLS = yes

ifneq ($(PLATFORM),CHIBIOS)
    ifneq ($(strip $(LTO_SUPPORTED)), no)
        LTO_ENABLE        = yes


@@ 15,6 17,7 @@ GRAVE_ESC_ENABLE      = no
ifneq ($(strip $(NO_SECRETS)), yes)
    ifneq ("$(wildcard $(USER_PATH)/../../../qmk_secrets/secrets.c)","")
        SRC += $(USER_PATH)/../../../qmk_secrets/secrets.c
        $(shell touch $(USER_PATH)/../../../qmk_secrets/secrets.c)
        SECURE_ENABLE = yes
    endif
    ifeq ($(strip $(NO_SECRETS)), lite)


@@ 103,7 106,6 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
    ifeq ($(strip $(CUSTOM_POINTING_DEVICE)), yes)
        SRC += $(USER_PATH)/pointing/pointing.c
        OPT_DEFS += -DCUSTOM_POINTING_DEVICE
        OPT_DEFS += -DMOUSE_EXT_REPORT
    endif
endif



@@ 119,5 121,6 @@ endif
AUTOCORRECTION_ENABLE ?= no
ifeq ($(strip $(AUTOCORRECTION_ENABLE)), yes)
    SRC += $(USER_PATH)/keyrecords/autocorrection/autocorrection.c
    $(shell touch $(USER_PATH)/keyrecords/autocorrection/autocorrection.c)
    OPT_DEFS += -DAUTOCORRECTION_ENABLE
endif

M users/drashna/split/transport_sync.c => users/drashna/split/transport_sync.c +7 -5
@@ 55,7 55,9 @@ void user_config_sync(uint8_t initiator2target_buffer_size, const void* initiato
}

#if defined(SPLIT_WATCHDOG_TIMEOUT)
void watchdog_handler(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) { watchdog_ping_done = true; }
void watchdog_handler(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
    watchdog_ping_done = true;
}
#endif

#ifdef CUSTOM_OLED_DRIVER


@@ 97,7 99,7 @@ void user_transport_update(void) {
        user_state.tap_toggling = tap_toggling;
#endif
#ifdef UNICODE_COMMON_ENABLE
        user_state.unicode_mode = unicode_config.input_mode;
        user_state.unicode_mode        = unicode_config.input_mode;
        user_state.unicode_typing_mode = typing_mode;
#endif
#ifdef SWAP_HANDS_ENABLE


@@ 112,7 114,7 @@ void user_transport_update(void) {
        user_state.raw       = transport_user_state;
#ifdef UNICODE_COMMON_ENABLE
        unicode_config.input_mode = user_state.unicode_mode;
        typing_mode = user_state.unicode_typing_mode;
        typing_mode               = user_state.unicode_typing_mode;
#endif
#if defined(CUSTOM_POINTING_DEVICE)
        tap_toggling = user_state.tap_toggling;


@@ 216,7 218,7 @@ void user_transport_sync(void) {
            if (timer_elapsed32(watchdog_timer) > 100) {
                uint8_t any_data = 1;
                if (transaction_rpc_send(RPC_ID_USER_WATCHDOG_SYNC, sizeof(any_data), &any_data)) {
                    watchdog_ping_done = true;  // successful ping
                    watchdog_ping_done = true; // successful ping
                } else {
                    dprint("Watchdog ping failed!\n");
                }


@@ 233,7 235,7 @@ void user_transport_sync(void) {
#endif
}

void housekeeping_task_user(void) {
void housekeeping_task_transport_sync(void) {
    // Update kb_state so we can send to slave
    user_transport_update();


M users/drashna/split/transport_sync.h => users/drashna/split/transport_sync.h +8 -7
@@ 12,16 12,17 @@ extern char keylog_str[OLED_KEYLOGGER_LENGTH];
typedef union {
    uint32_t raw;
    struct {
        bool audio_enable           :1;
        bool audio_clicky_enable    :1;
        bool tap_toggling           :1;
        uint8_t unicode_mode        :3;
        bool swap_hands             :1;
        bool host_driver_disabled   :1;
        uint8_t unicode_typing_mode :3;
        bool    audio_enable         :1;
        bool    audio_clicky_enable  :1;
        bool    tap_toggling         :1;
        uint8_t unicode_mode         :3;
        bool    swap_hands           :1;
        bool    host_driver_disabled :1;
        uint8_t unicode_typing_mode  :3;
    };
} user_runtime_config_t;

extern user_runtime_config_t user_state;

void keyboard_post_init_transport_sync(void);
void housekeeping_task_transport_sync(void);