~ruther/qmk_firmware

48eda75c838b786d688bb5066de851ee86937ad6 — ridingqwerty 5 years ago 3951f33 + 2a7c715
Merge pull request #7762 from CurryFurious/userspace_curry

Adding custom userspace & 2 keymaps
A keyboards/crkbd/keymaps/curry/config.h => keyboards/crkbd/keymaps/curry/config.h +31 -0
@@ 0,0 1,31 @@
#pragma once

#define EE_HANDS
#define USE_SERIAL_PD2

#define OLED_DISABLE_TIMEOUT
#define TAPPING_TERM_PER_KEY

#ifdef RGBLIGHT_ENABLE
#    undef RGBLED_NUM
#    define RGBLED_NUM 27

#    define RGBLIGHT_HUE_STEP 8
#    define RGBLIGHT_SAT_STEP 8
#    define RGBLIGHT_VAL_STEP 5
#    define RGBLIGHT_LIMIT_VAL 120
#endif

#ifdef RGB_MATRIX_ENABLE
#    define RGB_MATRIX_KEYPRESSES  // reacts to keypresses
// #   define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses)
// #   define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
#    define RGB_DISABLE_WHEN_USB_SUSPENDED true  // turn off effects when suspended
// #   define RGB_MATRIX_LED_PROCESS_LIMIT (DRIVER_LED_TOTAL + 4) / 5 // limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness)
// #   define RGB_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness)
#    define RGB_MATRIX_MAXIMUM_BRIGHTNESS 120  // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255
#    define RGB_MATRIX_HUE_STEP 8
#    define RGB_MATRIX_SAT_STEP 8
#    define RGB_MATRIX_VAL_STEP 5
#    define RGB_MATRIX_SPD_STEP 10
#endif

A keyboards/crkbd/keymaps/curry/keymap.c => keyboards/crkbd/keymaps/curry/keymap.c +62 -0
@@ 0,0 1,62 @@
#include "curry.h"

#define LAYOUT_crkbd_base( \
        K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, \
        K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, \
        K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A  \
    ) \
    LAYOUT_wrapper( \
        KC_GESC, K01, K02, K03, K04, K05,      K06, K07, K08, K09, K0A, KC_MINS, \
        M_LCTL,  K11, K12, K13, K14, K15,      K16, K17, K18, K19, K1A, M_RALT,  \
        OS_LSFT, K21, K22, K23, K24, K25,      K26, K27, K28, K29, K2A, OS_RSFT, \
                KC_GRV, OS_LALT, SP_LWER,     ET_RAIS, KC_BSPC, OS_RGUI                                      \
    )
#define LAYOUT_crkbd_base_wrapper(...)       LAYOUT_crkbd_base(__VA_ARGS__)

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [_QWERTY] = LAYOUT_crkbd_base_wrapper(
        _________________QWERTY_L1_________________, _________________QWERTY_R1_________________,
        _________________QWERTY_L2_________________, _________________QWERTY_R2_________________,
        _________________QWERTY_L3_________________, _________________QWERTY_R3_________________
    ),

    [_COLEMAK] = LAYOUT_crkbd_base_wrapper(
        _________________COLEMAK_L1________________, _________________COLEMAK_R1________________,
        _________________COLEMAK_L2________________, _________________COLEMAK_R2________________,
        _________________COLEMAK_L3________________, _________________COLEMAK_R3________________
    ),

    [_DVORAK] = LAYOUT_crkbd_base_wrapper(
        _________________DVORAK_L1_________________, _________________DVORAK_R1_________________,
        _________________DVORAK_L2_________________, _________________DVORAK_R2_________________,
        _________________DVORAK_L3_________________, _________________DVORAK_R3_________________
    ),

    [_MODS] = LAYOUT_wrapper(
        _______, ___________________BLANK___________________,       ___________________BLANK___________________, _______,
        _______, ___________________BLANK___________________,       ___________________BLANK___________________, _______,
        KC_LSFT, ___________________BLANK___________________,       ___________________BLANK___________________, KC_RSFT,
                                   _______, _______, _______,       _______, _______, _______
    ),

    [_LOWER] = LAYOUT_wrapper(
        _______, _________________LOWER_L1__________________,       _________________LOWER_R1__________________, KC_PIPE,
        KC_F11,  _________________LOWER_L2__________________,       _________________LOWER_R2__________________, KC_F12,
        _______, _________________LOWER_L3__________________,       _________________LOWER_R3__________________, _______,
                                   _______, _______, _______,       _______, _______, _______
    ),

    [_RAISE] = LAYOUT_wrapper( \
        _______, _________________RAISE_L1__________________,       _________________RAISE_R1__________________, _______,
        _______, _________________RAISE_L2__________________,       _________________RAISE_R2__________________, KC_BSLS,
        _______, _________________RAISE_L3__________________,       _________________RAISE_R3__________________, _______,
                                   _______, _______, _______,       _______, _______, _______
    ),

    [_ADJUST] = LAYOUT_wrapper( \
        KC_MAKE, _________________ADJUST_L1_________________,       _________________ADJUST_R1_________________, KC_RESET,
        VRSN,    _________________ADJUST_L2_________________,       _________________ADJUST_R2_________________, EEP_RST,
        MG_NKRO, _________________ADJUST_L3_________________,       _________________ADJUST_R3_________________, RGB_IDL,
                                   _______, _______, _______,       _______, TG_MODS, _______
    )
};

A keyboards/crkbd/keymaps/curry/rules.mk => keyboards/crkbd/keymaps/curry/rules.mk +23 -0
@@ 0,0 1,23 @@
# Build Options
#   change to "no" to disable the options, or define them in the Makefile in
#   the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE            = no  # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE             = no  # Mouse keys(+4700)
EXTRAKEY_ENABLE             = yes # Audio control and System control(+450)
CONSOLE_ENABLE              = no  # Console for debug(+400)
COMMAND_ENABLE              = no  # Commands for debug and configuration
NKRO_ENABLE                 = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE            = no  # Enable keyboard backlight functionality
MIDI_ENABLE                 = no  # MIDI controls
AUDIO_ENABLE                = no  # Audio output on port C6
UNICODE_ENABLE              = no  # Unicode
BLUETOOTH_ENABLE            = no  # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE             = no  # Enable WS2812 RGB underlight.
SWAP_HANDS_ENABLE           = no  # Enable one-hand typing
RGB_MATRIX_ENABLE           = WS2812
TAP_DANCE_ENABLE            = yes      # Enable Tap Dance.
OLED_DRIVER_ENABLE          = yes
BOOTLOADER                  = atmel-dfu
SLEEP_LED_ENABLE            = no    # Breathing sleep LED during USB suspend
SPLIT_TRANSPORT             = mirror

A keyboards/lily58/keymaps/curry/config.h => keyboards/lily58/keymaps/curry/config.h +7 -0
@@ 0,0 1,7 @@
#pragma once

#define EE_HANDS
#define USE_SERIAL_PD2

#define OLED_DISABLE_TIMEOUT
#define TAPPING_TERM_PER_KEY

A keyboards/lily58/keymaps/curry/keymap.c => keyboards/lily58/keymaps/curry/keymap.c +71 -0
@@ 0,0 1,71 @@
#include "curry.h"

#define LAYOUT_lily58_base( \
        K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, \
        K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, \
        K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A,  \
        K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A  \
    ) \
    LAYOUT_wrapper( \
        KC_ESC,  K01, K02, K03, K04, K05,                    K06, K07, K08, K09, K0A, KC_GRV, \
        KC_TAB,  K11, K12, K13, K14, K15,                    K16, K17, K18, K19, K1A, KC_BSLS,  \
        KC_LCTL, K21, K22, K23, K24, K25,                    K26, K27, K28, K29, K2A, KC_QUOT, \
        OS_LSFT, K31, K32, K33, K34, K35, KC_LBRC, KC_RBRC,  K36, K37, K38, K39, K3A, OS_RSFT, \
                OS_LGUI, OS_LALT, LOWER, KC_SPC,  KC_ENT,  RAISE, KC_BSPC, OS_RGUI \
    )
#define LAYOUT_lily58_base_wrapper(...) LAYOUT_lily58_base(__VA_ARGS__)

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [_QWERTY] = LAYOUT_lily58_base_wrapper(
        ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________,
        _________________QWERTY_L1_________________, _________________QWERTY_R1_________________,
        _________________QWERTY_L2_________________, _________________QWERTY_R2_________________,
        _________________QWERTY_L3_________________, _________________QWERTY_R3_________________
    ),

    [_COLEMAK] = LAYOUT_lily58_base_wrapper(
        ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________,
        _________________COLEMAK_L1________________, _________________COLEMAK_R1________________,
        _________________COLEMAK_L2________________, _________________COLEMAK_R2________________,
        _________________COLEMAK_L3________________, _________________COLEMAK_R3________________
    ),

    [_DVORAK] = LAYOUT_lily58_base_wrapper(
        ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________,
        _________________DVORAK_L1_________________, _________________DVORAK_R1_________________,
        _________________DVORAK_L2_________________, _________________DVORAK_R2_________________,
        _________________DVORAK_L3_________________, _________________DVORAK_R3_________________
    ),

    [_MODS] = LAYOUT_wrapper(
        _______, ___________________BLANK___________________,                    ___________________BLANK___________________, _______,
        _______, ___________________BLANK___________________,                    ___________________BLANK___________________, _______,
        _______, ___________________BLANK___________________,                    ___________________BLANK___________________, _______,
        KC_LSFT, ___________________BLANK___________________, _______,  _______, ___________________BLANK___________________, KC_RSFT,
                                   _______, _______, _______, _______,  _______, _______, _______, _______
    ),

    [_LOWER] = LAYOUT_wrapper( \
        _______, ___________________BLANK___________________,                    ___________________BLANK___________________, _______,
        KC_F11,  _________________LOWER_L1__________________,                    _________________LOWER_R1__________________, KC_F12,
        _______, _________________LOWER_L2__________________,                    _________________LOWER_R2__________________, _______,
        _______, _________________LOWER_L3__________________, _______,  _______, _________________LOWER_R3__________________, _______,
                                   _______, _______, _______, _______,  _______, _______, _______, _______
    ),

    [_RAISE] = LAYOUT_wrapper( \
        _______, ___________________BLANK___________________,                    ___________________BLANK___________________, _______,
        _______, _________________RAISE_L1__________________,                    _________________RAISE_R1__________________, _______,
        _______, _________________RAISE_L2__________________,                    _________________RAISE_R2__________________, _______,
        _______, _________________RAISE_L3__________________, _______,  _______, _________________RAISE_R3__________________, _______,
                                   _______, _______, _______, _______,  _______, _______, _______, _______
    ),

    [_ADJUST] = LAYOUT_wrapper( \
        _______, ___________________BLANK___________________,                    ___________________BLANK___________________, _______,
        KC_MAKE, _________________ADJUST_L1_________________,                    _________________ADJUST_R1_________________, KC_RESET,
        VRSN,    _________________ADJUST_L2_________________,                    _________________ADJUST_R2_________________, EEP_RST,
        MG_NKRO, _________________ADJUST_L3_________________, _______,  _______, _________________ADJUST_R3_________________, RGB_IDL,
                                   _______, _______, _______, _______,  _______, _______, _______, _______
    ),
};

A keyboards/lily58/keymaps/curry/rules.mk => keyboards/lily58/keymaps/curry/rules.mk +21 -0
@@ 0,0 1,21 @@
# Build Options
#   change to "no" to disable the options, or define them in the Makefile in
#   the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE            = no  # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE             = no  # Mouse keys(+4700)
EXTRAKEY_ENABLE             = yes # Audio control and System control(+450)
CONSOLE_ENABLE              = no  # Console for debug(+400)
COMMAND_ENABLE              = no  # Commands for debug and configuration
NKRO_ENABLE                 = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE            = no  # Enable keyboard backlight functionality
MIDI_ENABLE                 = no  # MIDI controls
AUDIO_ENABLE                = no  # Audio output on port C6
UNICODE_ENABLE              = no  # Unicode
BLUETOOTH_ENABLE            = no  # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE             = no  # Enable WS2812 RGB underlight.
SWAP_HANDS_ENABLE           = no  # Enable one-hand typing
TAP_DANCE_ENABLE            = yes      # Enable Tap Dance.
OLED_DRIVER_ENABLE          = yes
BOOTLOADER                  = atmel-dfu
SPLIT_TRANSPORT             = mirror

A users/curry/.gitignore => users/curry/.gitignore +1 -0
@@ 0,0 1,1 @@
secrets.c

A users/curry/LICENSE.md => users/curry/LICENSE.md +14 -0
@@ 0,0 1,14 @@
Copyright 2020 Akaash Suresh casa.akaash@gmail.com @CurryFurious

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

A users/curry/README.md => users/curry/README.md +30 -0
@@ 0,0 1,30 @@
# Information

These is my userspace files, heavily influenced by @drashna's userspace structure.

# Keyboards

Main uses are for corne & lily58, supporting dfu bootloader (elite-c)

## Split Common
Is compatible with split_common when the previous two keyboards update to them. 

If you want to use these keymaps with split common code, they are on my personal github fork: [CurryFurious/qmk_firmware](https://github.com/CurryFurious/qmk_firmware)

Referenced PRs: #6260, #5998, #6001

## Keymaps
Keymap layout is similar between the two keyboards. Lily58 has a lot of open keys for custom keys as well. Keymap formatting is set up in the physical layout of the keyboard, so mapping keys should be easier.

## Tap Dances

Tap dances are enabled but none are defined, you can add them to [tapdances.c](tapdances.c). If not using tapdances, you can disable them in the keymaps.

## RGB 
RGB is implemented pretty much the same as @drashna. Only change is that I added the RGB code from the drashna's corne [keymap.c](../../keyboards/crkbd/keymaps/drashna/keymap.c), lines 313-383 into rgb_stuff.c.

## OLED
Similarly to RGB, I moved all OLED code into [oled.c](oled.c) to better clear up the keymap.c file. I haven't experimented with the kyria's 128x64 pixel screen so it probably won't work as well with it yet.

## Wrappers
Have implemented QWERTY, COLEMAK Mod DH, and DVORAK. Other macros are defined, some modified from drashna's. Drashna's [wrappers.h](../drashna/wrappers.h) has other layouts that you can copy in as you see fit, make sure to add them to the userspace_layers enum in [curry.h](curry.h)

A users/curry/config.h => users/curry/config.h +118 -0
@@ 0,0 1,118 @@
#pragma once

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

/* Set Polling rate to 1000Hz */
#define USB_POLLING_INTERVAL_MS 1

#ifdef RGBLIGHT_ENABLE
#    undef RGBLIGHT_ANIMATIONS
#    if defined(__AVR__) && !defined(__AVR_AT90USB1286__)
#        define RGBLIGHT_SLEEP
#        define RGBLIGHT_EFFECT_BREATHING
#        define RGBLIGHT_EFFECT_SNAKE
#        define RGBLIGHT_EFFECT_KNIGHT
#    else
#        define RGBLIGHT_ANIMATIONS
#    endif
#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_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
#    define RGB_DISABLE_WHEN_USB_SUSPENDED true  // turn off effects when suspended
// #   define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255
// #   define EECONFIG_RGB_MATRIX (uint32_t *)16

#    if defined(__AVR__) && !defined(__AVR_AT90USB1286__)
#        define DISABLE_RGB_MATRIX_ALPHAS_MODS
#        define DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
#        define DISABLE_RGB_MATRIX_BREATHING
#        define DISABLE_RGB_MATRIX_BAND_SAT
#        define DISABLE_RGB_MATRIX_BAND_VAL
#        define DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
#        define DISABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
#        define DISABLE_RGB_MATRIX_BAND_SPIRAL_SAT
#        define DISABLE_RGB_MATRIX_BAND_SPIRAL_VAL
#        define DISABLE_RGB_MATRIX_CYCLE_ALL
#        define DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
#        define DISABLE_RGB_MATRIX_CYCLE_UP_DOWN
#        define DISABLE_RGB_MATRIX_CYCLE_OUT_IN
// #       define DISABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
#        define DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
#        define DISABLE_RGB_MATRIX_DUAL_BEACON
#        define DISABLE_RGB_MATRIX_CYCLE_PINWHEEL
#        define DISABLE_RGB_MATRIX_CYCLE_SPIRAL
#        define DISABLE_RGB_MATRIX_RAINBOW_BEACON
#        define DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
#        define DISABLE_RGB_MATRIX_RAINDROPS
#        define DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
// #       define DISABLE_RGB_MATRIX_TYPING_HEATMAP
#        define DISABLE_RGB_MATRIX_DIGITAL_RAIN
#        define DISABLE_RGB_MATRIX_SOLID_REACTIVE
#        define DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
#        define DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
#        define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
#        define DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
#        define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
#        define DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
#        define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
#        define DISABLE_RGB_MATRIX_SPLASH
#        define DISABLE_RGB_MATRIX_MULTISPLASH
#        define DISABLE_RGB_MATRIX_SOLID_SPLASH
#        define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
#    endif  // AVR
#endif      // RGB_MATRIX_ENABLE

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

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

#ifndef QMK_KEYS_PER_SCAN
#    define QMK_KEYS_PER_SCAN 4
#endif  // !QMK_KEYS_PER_SCAN

// this makes it possible to do rolling combos (zx) with keys that
// convert to other keys on hold (z becomes ctrl when you hold it,
// and when this option isn't enabled, z rapidly followed by x
// actually sends Ctrl-x. That's bad.)
#define IGNORE_MOD_TAP_INTERRUPT
#undef PERMISSIVE_HOLD
//#define TAPPING_FORCE_HOLD
//#define RETRO_TAPPING

#define FORCE_NKRO

#ifndef TAPPING_TOGGLE
#    define TAPPING_TOGGLE 1
#endif

#ifdef TAPPING_TERM
#    undef TAPPING_TERM
#endif  // TAPPING_TERM
#if defined(KEYBOARD_ergodox_ez)
#    define TAPPING_TERM 185
#elif defined(KEYBOARD_crkbd)
#    define TAPPING_TERM 200
#else
#    define TAPPING_TERM 175
#endif

#define TAP_CODE_DELAY 5

/* Disable unused and unneeded features to reduce on firmware size */
#ifdef LOCKING_SUPPORT_ENABLE
#    undef LOCKING_SUPPORT_ENABLE
#endif
#ifdef LOCKING_RESYNC_ENABLE
#    undef LOCKING_RESYNC_ENABLE
#endif

#define OLED_FONT_H "users/curry/glcdfont.c"

A users/curry/curry.c => users/curry/curry.c +131 -0
@@ 0,0 1,131 @@
#include "curry.h"

userspace_config_t userspace_config;

#define CURRY_UNICODE_MODE 1

void bootmagic_lite(void) {
    matrix_scan();
#if defined(DEBOUNCING_DELAY) && DEBOUNCING_DELAY > 0
    wait_ms(DEBOUNCING_DELAY * 2);
#elif defined(DEBOUNCE) && DEBOUNCE > 0
    wait_ms(DEBOUNCE * 2);
#else
    wait_ms(30);
#endif
    matrix_scan();
    if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
        bootloader_jump();
    }
}

__attribute__((weak)) void keyboard_pre_init_keymap(void) {}

void keyboard_pre_init_user(void) {
    userspace_config.raw = eeconfig_read_user();
    keyboard_pre_init_keymap();
}

__attribute__((weak)) void matrix_init_keymap(void) {}

// Call user matrix init, set default RGB colors and then
// call the keymap's init function
void matrix_init_user(void) {
#if (defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE))
    set_unicode_input_mode(CURRY_UNICODE_MODE);
    get_unicode_input_mode();
#endif  // UNICODE_ENABLE
    matrix_init_keymap();
}

__attribute__((weak)) void keyboard_post_init_keymap(void) {}

void keyboard_post_init_user(void) {
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
    keyboard_post_init_rgb();
#endif
    keyboard_post_init_keymap();
}

__attribute__((weak)) void shutdown_keymap(void) {}

void rgb_matrix_update_pwm_buffers(void);

// On RESET, set all RGB to red, shutdown the keymap.
void shutdown_user(void) {
#ifdef RGBLIGHT_ENABLE
    rgblight_enable_noeeprom();
    rgblight_mode_noeeprom(1);
    rgblight_setrgb_red();
#endif  // RGBLIGHT_ENABLE
#ifdef RGB_MATRIX_ENABLE
    rgb_matrix_set_color_all(0xFF, 0x00, 0x00);
    rgb_matrix_update_pwm_buffers();
#endif  // RGB_MATRIX_ENABLE
    shutdown_keymap();
}

__attribute__((weak)) void suspend_power_down_keymap(void) {}

void suspend_power_down_user(void) { suspend_power_down_keymap(); }

__attribute__((weak)) void suspend_wakeup_init_keymap(void) {}

void suspend_wakeup_init_user(void) { suspend_wakeup_init_keymap(); }

__attribute__((weak)) void matrix_scan_keymap(void) {}

// No global matrix scan code, so just run keymap's matrix
// scan function
void matrix_scan_user(void) {
    static bool has_ran_yet;
    if (!has_ran_yet) {
        has_ran_yet = true;
        startup_user();
    }

#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
    matrix_scan_rgb();
#endif  // RGBLIGHT_ENABLE

    matrix_scan_keymap();
}

__attribute__((weak)) layer_state_t layer_state_set_keymap(layer_state_t state) { return state; }

// On Layer change, run keymap's layer change check
layer_state_t layer_state_set_user(layer_state_t state) {
    state = update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST);
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
    state = layer_state_set_rgb(state);
#endif  // RGBLIGHT_ENABLE
    return layer_state_set_keymap(state);
}

__attribute__((weak)) layer_state_t default_layer_state_set_keymap(layer_state_t state) { return state; }

// Runs state check and changes underglow color and animation
layer_state_t default_layer_state_set_user(layer_state_t state) {
    return default_layer_state_set_keymap(state);
}

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

// Any custom LED code goes here.
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;
    eeconfig_update_user(userspace_config.raw);
#if (defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE))
    set_unicode_input_mode(CURRY_UNICODE_MODE);
    get_unicode_input_mode();
#else
    eeprom_update_byte(EECONFIG_UNICODEMODE, CURRY_UNICODE_MODE);
#endif
    eeconfig_init_keymap();
    keyboard_init();
}

A users/curry/curry.h => users/curry/curry.h +53 -0
@@ 0,0 1,53 @@
#pragma once

#include QMK_KEYBOARD_H

#include "version.h"
#include "eeprom.h"
#include "wrappers.h"
#include "process_records.h"

#ifdef TAP_DANCE_ENABLE
#    include "tap_dances.h"
#endif  // TAP_DANCE_ENABLE
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
#    include "rgb_stuff.h"
#endif
#if defined(KEYBOARD_lily58_rev1) & defined(PROTOCOL_LUFA)
#    include "lufa.h"
#    include "split_util.h"
#endif

/* Define layer names */
enum userspace_layers {
    _QWERTY  = 0,
    _COLEMAK,
    _DVORAK,
    _MODS,
    _LOWER,
    _RAISE,
    _ADJUST,
};

void          matrix_init_keymap(void);
void          shutdown_keymap(void);
void          suspend_power_down_keymap(void);
void          suspend_wakeup_init_keymap(void);
void          matrix_scan_keymap(void);
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);

// clang-format off
typedef union {
    uint32_t raw;
    struct {
        bool    rgb_layer_change     :1;
        bool    nuke_switch          :1;
        bool    rgb_matrix_idle_anim :1;
    };
} userspace_config_t;
// clang-format on

extern userspace_config_t userspace_config;

A users/curry/glcdfont.c => users/curry/glcdfont.c +241 -0
@@ 0,0 1,241 @@
#pragma once

#ifdef __AVR__
#    include <avr/io.h>
#    include <avr/pgmspace.h>
#elif defined(ESP8266)
#    include <pgmspace.h>
#else
#    define PROGMEM
#endif

// Corne 8x6 font with QMK Firmware Logo
// Online editor: https://helixfonteditor.netlify.com/

// clang-format off
const unsigned char font[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00,
0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
0x00, 0x18, 0x3C, 0x18, 0x00, 0x00,
0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00,
0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
0x18, 0x24, 0x24, 0x1C, 0x78, 0x00,
0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
0x7C, 0x18, 0x24, 0x24, 0x18, 0x00,
0x18, 0x24, 0x24, 0x18, 0x7C, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00,
0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0,
0xF0, 0xF8, 0xF8, 0x18, 0x00, 0xC0,
0xF0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xC0, 0x80, 0x00, 0x00, 0x00, 0x00,
0x80, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0x80,
0x00, 0x00, 0x00, 0xE0, 0xE0, 0xC0,
0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0x00,
0x00, 0xE0, 0xE0, 0xC0, 0xC0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0x80,
0x00, 0x00, 0x00, 0x00, 0x80, 0xC0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xC0, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xE0, 0xF0, 0xF0, 0xF0, 0xE0, 0xEC,
0xEE, 0xF7, 0xF3, 0x70, 0x20, 0x00,
0x7C, 0x7C, 0x7C, 0x7E, 0x00, 0x7E,
0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x00,
0x00, 0x80, 0xC0, 0xE0, 0x7E, 0x5B,
0x4F, 0x5B, 0xFE, 0xC0, 0x00, 0x00,
0xC0, 0x00, 0xDC, 0xD7, 0xDE, 0xDE,
0xDE, 0xD7, 0xDC, 0x00, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF8, 0xFC, 0xFE,
0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x1F, 0x07, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0x81, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
0xC3, 0xC3, 0xC3, 0x00, 0x00, 0xFF,
0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x81, 0xFF, 0xFF,
0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00,
0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF,
0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
0x9D, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
0x1C, 0x9D, 0xDF, 0xDF, 0xDF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F,
0x7F, 0x7F, 0x3F, 0x1E, 0x0C, 0x00,
0x1F, 0x1F, 0x1F, 0x3F, 0x00, 0x3F,
0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x00,
0x30, 0x7B, 0x7F, 0x78, 0x30, 0x20,
0x20, 0x30, 0x78, 0x7F, 0x3B, 0x00,
0x03, 0x00, 0x0F, 0x7F, 0x0F, 0x0F,
0x0F, 0x7F, 0x0F, 0x00, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x0F, 0x1F,
0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x1F,
0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x3F,
0x3F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F,
0x7F, 0x7C, 0x78, 0x78, 0x38, 0x1C,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x03, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x03, 0x01,
0x00, 0x00, 0x00, 0x07, 0x07, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0x07, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x07,
0x07, 0x00, 0x00, 0x00, 0x01, 0x03,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x03, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

A users/curry/oled.c => users/curry/oled.c +162 -0
@@ 0,0 1,162 @@
#include "curry.h"

#ifdef OLED_DRIVER_ENABLE
#define KEYLOGGER_LENGTH 5
static uint32_t oled_timer                       = 0;
static char     keylog_str[KEYLOGGER_LENGTH + 1] = {"\n"};
static uint16_t log_timer                        = 0;
// clang-format off
static const char PROGMEM code_to_name[0xFF] = {
//   0    1    2    3    4    5    6    7    8    9    A    B    c    D    E    F
    ' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',  // 0x
    'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2',  // 1x
    '3', '4', '5', '6', '7', '8', '9', '0',  20,  19,  27,  26,  22, '-', '=', '[',  // 2x
    ']','\\', '#', ';','\'', '`', ',', '.', '/', 128, ' ', ' ', ' ', ' ', ' ', ' ',  // 3x
    ' ', ' ', ' ', ' ', ' ', ' ', 'P', 'S', ' ', ' ', ' ', ' ',  16, ' ', ' ', ' ',  // 4x
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',  // 5x
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',  // 6x
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',  // 7x
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',  // 8x
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',  // 9x
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',  // Ax
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',  // Bx
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',  // Cx
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',  // Dx
    'C', 'S', 'A', 'C', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',  // Ex
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '        // Fx
};

void add_keylog(uint16_t keycode);

oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_270; }

void add_keylog(uint16_t keycode) {
    if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) || (keycode >= QK_MODS && keycode <= QK_MODS_MAX)) {
        keycode = keycode & 0xFF;
    } else if (keycode > 0xFF) {
        keycode = 0;
    }

    for (uint8_t i = (KEYLOGGER_LENGTH - 1); i > 0; --i) {
        keylog_str[i] = keylog_str[i - 1];
    }

    if (keycode < (sizeof(code_to_name) / sizeof(char))) {
        keylog_str[0] = pgm_read_byte(&code_to_name[keycode]);
    }

    log_timer = timer_read();
}

void render_keylogger_status(void) {
    oled_write_P(PSTR("Keys"), false);
    oled_write(keylog_str, false);
}

void render_default_layer_state(void) {
    oled_write_P(PSTR("Lyout"), false);
    switch (get_highest_layer(default_layer_state)) {
        case _QWERTY:
            oled_write_P(PSTR(" QRTY"), false);
            break;
        case _COLEMAK:
            oled_write_P(PSTR(" COLE"), false);
            break;
        case _DVORAK:
            oled_write_P(PSTR(" DVRK"), false);
            break;
    }
}

void render_layer_state(void) {
    oled_write_P(PSTR("LAYER"), false);
    oled_write_P(PSTR("Lower"), layer_state_is(_LOWER));
    oled_write_P(PSTR("Raise"), layer_state_is(_RAISE));
    oled_write_P(PSTR(" Mods"), layer_state_is(_MODS));
}

void render_keylock_status(uint8_t led_usb_state) {
    oled_write_P(PSTR("Lock:"), false);
    oled_write_P(PSTR(" "), false);
    oled_write_P(PSTR("N"), led_usb_state & (1 << USB_LED_NUM_LOCK));
    oled_write_P(PSTR("C"), led_usb_state & (1 << USB_LED_CAPS_LOCK));
    oled_write_ln_P(PSTR("S"), led_usb_state & (1 << USB_LED_SCROLL_LOCK));
}

void render_mod_status(uint8_t modifiers) {
    oled_write_P(PSTR("Mods:"), false);
    oled_write_P(PSTR(" "), false);
    oled_write_P(PSTR("S"), (modifiers & MOD_MASK_SHIFT));
    oled_write_P(PSTR("C"), (modifiers & MOD_MASK_CTRL));
    oled_write_P(PSTR("A"), (modifiers & MOD_MASK_ALT));
    oled_write_P(PSTR("G"), (modifiers & MOD_MASK_GUI));
}

void render_bootmagic_status(void) {
    /* Show Ctrl-Gui Swap options */
    static const char PROGMEM logo[][2][3] = {
        {{0x97, 0x98, 0}, {0xb7, 0xb8, 0}},
        {{0x95, 0x96, 0}, {0xb5, 0xb6, 0}},
    };
    oled_write_P(PSTR("BTMGK"), false);
    oled_write_P(PSTR(" "), false);
    oled_write_P(logo[0][0], !keymap_config.swap_lctl_lgui);
    oled_write_P(logo[1][0], keymap_config.swap_lctl_lgui);
    oled_write_P(PSTR(" "), false);
    oled_write_P(logo[0][1], !keymap_config.swap_lctl_lgui);
    oled_write_P(logo[1][1], keymap_config.swap_lctl_lgui);
    oled_write_P(PSTR(" NKRO"), keymap_config.nkro);
}

void render_user_status(void) {
    oled_write_P(PSTR("USER:"), false);
    oled_write_P(PSTR(" Anim"), userspace_config.rgb_matrix_idle_anim);
    oled_write_P(PSTR(" Layr"), userspace_config.rgb_layer_change);
    oled_write_P(PSTR(" Nuke"), userspace_config.nuke_switch);
}

void render_status_main(void) {
    /* Show Keyboard Layout  */
    render_default_layer_state();
    render_keylock_status(host_keyboard_leds());
    render_bootmagic_status();
    render_user_status();

    render_keylogger_status();
}

void render_status_secondary(void) {
    /* Show Keyboard Layout  */
    render_default_layer_state();
    render_layer_state();
    render_mod_status(get_mods() | get_oneshot_mods());

    render_keylogger_status();
}

void oled_task_user(void) {
    if (timer_elapsed32(oled_timer) > 30000) {
        oled_off();
        return;
    }
#    ifndef SPLIT_KEYBOARD
    else {
        oled_on();
    }
#    endif
    if (is_keyboard_master()) {
        render_status_main();  // Renders the current keyboard state (layer, lock, caps, scroll, etc)
    } else {
        render_status_secondary();
    }
}

bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
    if (record->event.pressed) {
        oled_timer = timer_read32();
        add_keylog(keycode);
    }
    return true;
}

#endif

A users/curry/process_records.c => users/curry/process_records.c +85 -0
@@ 0,0 1,85 @@
#include "curry.h"

uint16_t copy_paste_timer;

__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; }

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed);
    switch (keycode) {
        case KC_MAKE:
            if (!record->event.pressed) {
                uint8_t temp_mod = mod_config(get_mods());
                uint8_t temp_osm = mod_config(get_oneshot_mods());
                clear_mods();
                clear_oneshot_mods();
                send_string_with_delay_P(PSTR("make " QMK_KEYBOARD ":" QMK_KEYMAP), TAP_CODE_DELAY);
                if ((temp_mod | temp_osm) & MOD_MASK_SHIFT) {
                    send_string_with_delay_P(PSTR(":flash"), TAP_CODE_DELAY);
                }
                if ((temp_mod | temp_osm) & MOD_MASK_CTRL) {
                    send_string_with_delay_P(PSTR(" -j8 --output-sync"), TAP_CODE_DELAY);
                }
#ifdef RGB_MATRIX_SPLIT_RIGHT
                send_string_with_delay_P(PSTR(" RGB_MATRIX_SPLIT_RIGHT=yes"), TAP_CODE_DELAY);
#    ifndef OLED_DRIVER_ENABLE
                send_string_with_delay_P(PSTR(" OLED_DRIVER_ENABLE=no"), TAP_CODE_DELAY);
#    endif
#endif
                send_string_with_delay_P(PSTR(SS_TAP(X_ENTER)), TAP_CODE_DELAY);
            }

            break;

        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_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
                    register_code(KC_LCTL);
                    tap_code(KC_C);
                    unregister_code(KC_LCTL);
                } else {  // Tap, paste
                    register_code(KC_LCTL);
                    tap_code(KC_V);
                    unregister_code(KC_LCTL);
                }
            }
            break;
#ifdef UNICODE_ENABLE
        case UC_FLIP:  // (ノಠ痊ಠ)ノ彡┻━┻
            if (record->event.pressed) {
                send_unicode_hex_string("0028 30CE 0CA0 75CA 0CA0 0029 30CE 5F61 253B 2501 253B");
            }
            break;
        case UC_TABL:  // ┬─┬ノ( º _ ºノ)
            if (record->event.pressed) {
                send_unicode_hex_string("252C 2500 252C 30CE 0028 0020 00BA 0020 005F 0020 00BA 30CE 0029");
            }
            break;
        case UC_SHRG:  // ¯\_(ツ)_/¯
            if (record->event.pressed) {
                send_unicode_hex_string("00AF 005C 005F 0028 30C4 0029 005F 002F 00AF");
            }
            break;
        case UC_DISA:  // ಠ_ಠ
            if (record->event.pressed) {
                send_unicode_hex_string("0CA0 005F 0CA0");
            }
            break;
#endif
    }
    return process_record_keymap(keycode, record) &&
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
           process_record_user_rgb(keycode, record) &&
#endif  // RGBLIGHT_ENABLE
           process_record_secrets(keycode, record);
}

A users/curry/process_records.h => users/curry/process_records.h +104 -0
@@ 0,0 1,104 @@
#pragma once
#include "curry.h"

#if defined(KEYMAP_SAFE_RANGE)
#    define PLACEHOLDER_SAFE_RANGE KEYMAP_SAFE_RANGE
#else
#    define PLACEHOLDER_SAFE_RANGE SAFE_RANGE
#endif

enum userspace_custom_keycodes {
    VRSN = PLACEHOLDER_SAFE_RANGE,  // Prints QMK Firmware and board info
    KC_QWERTY,                      // Sets default layer to QWERTY
    KC_COLEMAK,                     // Sets default layer to COLEMAK
    KC_DVORAK,                      // Sets default layer to DVORAK
    KC_MAKE,                        // Run keyboard's customized make command
    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,                        // ಠ_ಠ
    KC_DT1,
    KC_DT2,
    KC_DT3,
    KC_DT4,
    NEW_SAFE_RANGE                  // use "NEWPLACEHOLDER for keymap specific codes
};

bool process_record_secrets(uint16_t keycode, keyrecord_t *record);
bool process_record_keymap(uint16_t keycode, keyrecord_t *record);

#define LOWER MO(_LOWER)
#define RAISE MO(_RAISE)
#define ADJUST MO(_ADJUST)
#define TG_MODS TG(_MODS)
#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 QWERTY KC_QWERTY
#define DVORAK KC_DVORAK
#define COLEMAK KC_COLEMAK

#define KC_RESET RESET
#define KC_RST KC_RESET

#ifdef SWAP_HANDS_ENABLE
#    define KC_C1R3 SH_T(KC_TAB)
#else  // SWAP_HANDS_ENABLE
#    define KC_C1R3 KC_TAB
#endif  // SWAP_HANDS_ENABLE

#define BK_LWER LT(_LOWER, KC_BSPC)
#define SP_LWER LT(_LOWER, KC_SPC)
#define DL_RAIS LT(_RAISE, KC_DEL)
#define ET_RAIS LT(_RAISE, KC_ENTER)

/* OSM keycodes, to keep things clean and easy to change */
#define KC_MLSF OSM(MOD_LSFT)
#define KC_MRSF OSM(MOD_RSFT)

#define OS_LGUI OSM(MOD_LGUI)
#define OS_RGUI OSM(MOD_RGUI)
#define OS_LSFT OSM(MOD_LSFT)
#define OS_RSFT OSM(MOD_RSFT)
#define OS_LCTL OSM(MOD_LCTL)
#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_HYPR OSM(MOD_HYPR)

#define M_LALT ALT_T(KC_TAB)
#define M_RALT RALT_T(KC_QUOT)

#define M_LCTL CTL_T(KC_TAB)
#define M_RCTL RCTL_T(KC_QUOT)

#define MT_ESC MT(MOD_LCTL, KC_ESC)

#define ALT_APP ALT_T(KC_APP)

#define MG_NKRO MAGIC_TOGGLE_NKRO

#define UC_IRNY UC(0x2E2E)
#define UC_CLUE UC(0x203D)

// KWin Window Switching
#define KC_DT1 LCTL(KC_F1)
#define KC_DT2 LCTL(KC_F2)
#define KC_DT3 LCTL(KC_F3)
#define KC_DT4 LCTL(KC_F4)

A users/curry/rgb_stuff.c => users/curry/rgb_stuff.c +471 -0
@@ 0,0 1,471 @@
#include "curry.h"
#include "rgb_stuff.h"
#include "eeprom.h"

#if defined(RGBLIGHT_ENABLE)
extern rgblight_config_t rgblight_config;
bool                     has_initialized;

void rgblight_sethsv_default_helper(uint8_t index) { rgblight_sethsv_at(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, index); }
#endif  // RGBLIGHT_ENABLE

#if defined(RGB_MATRIX_ENABLE)
static uint32_t hypno_timer;
#    if defined(SPLIT_KEYBOARD) || defined(KEYBOARD_ergodox_ez) || defined(KEYBOARD_crkbd)
#        define RGB_MATRIX_REST_MODE RGB_MATRIX_CYCLE_OUT_IN_DUAL
#    else
#        define RGB_MATRIX_REST_MODE RGB_MATRIX_CYCLE_OUT_IN
#    endif

void suspend_power_down_keymap(void) { rgb_matrix_set_suspend_state(true); }

void suspend_wakeup_init_keymap(void) { rgb_matrix_set_suspend_state(false); }

void check_default_layer(uint8_t mode, uint8_t type) {
    switch (get_highest_layer(default_layer_state)) {
        case _QWERTY:
            rgb_matrix_layer_helper(HSV_CYAN, mode, rgb_matrix_config.speed, type);
            break;
        case _COLEMAK:
            rgb_matrix_layer_helper(HSV_MAGENTA, mode, rgb_matrix_config.speed, type);
            break;
        case _DVORAK:
            rgb_matrix_layer_helper(HSV_SPRINGGREEN, mode, rgb_matrix_config.speed, type);
            break;
    }
}

void rgb_matrix_indicators_user(void) {
    if (userspace_config.rgb_layer_change &&
#    ifdef RGB_DISABLE_WHEN_USB_SUSPENDED
        !g_suspend_state &&
#    endif
#    if defined(RGBLIGHT_ENABLE)
        (!rgblight_config.enable && rgb_matrix_config.enable)
#    else
        rgb_matrix_config.enable
#    endif
    ) {
        switch (get_highest_layer(layer_state)) {
            case _RAISE:
                rgb_matrix_layer_helper(HSV_YELLOW, 0, rgb_matrix_config.speed, LED_FLAG_UNDERGLOW);
                break;
            case _LOWER:
                rgb_matrix_layer_helper(HSV_GREEN, 0, rgb_matrix_config.speed, LED_FLAG_UNDERGLOW);
                break;
            case _ADJUST:
                rgb_matrix_layer_helper(HSV_RED, 0, rgb_matrix_config.speed, LED_FLAG_UNDERGLOW);
                break;
            default: {
                check_default_layer(IS_LAYER_ON(_MODS), LED_FLAG_UNDERGLOW);
                break;
            }
        }
        check_default_layer(0, LED_FLAG_MODIFIER);
    }
}
#endif

/* Custom indicators for modifiers.
 * This allows for certain lights to be lit up, based on what mods are active, giving some visual feedback.
 * This is especially useful for One Shot Mods, since it's not always obvious if they're still lit up.
 */
#ifdef RGBLIGHT_ENABLE
#    ifdef INDICATOR_LIGHTS
void set_rgb_indicators(uint8_t this_mod, uint8_t this_led, uint8_t this_osm) {
    if (userspace_config.rgb_layer_change && get_highest_layer(layer_state) == 0) {
        if ((this_mod | this_osm) & MOD_MASK_SHIFT || this_led & (1 << USB_LED_CAPS_LOCK)) {
#        ifdef SHFT_LED1
            rgblight_sethsv_at(120, 255, 255, SHFT_LED1);
#        endif  // SHFT_LED1
#        ifdef SHFT_LED2
            rgblight_sethsv_at(120, 255, 255, SHFT_LED2);
#        endif  // SHFT_LED2
        } else {
#        ifdef SHFT_LED1
            rgblight_sethsv_default_helper(SHFT_LED1);
#        endif  // SHFT_LED1
#        ifdef SHFT_LED2
            rgblight_sethsv_default_helper(SHFT_LED2);
#        endif  // SHFT_LED2
        }
        if ((this_mod | this_osm) & MOD_MASK_CTRL) {
#        ifdef CTRL_LED1
            rgblight_sethsv_at(0, 255, 255, CTRL_LED1);
#        endif  // CTRL_LED1
#        ifdef CTRL_LED2
            rgblight_sethsv_at(0, 255, 255, CTRL_LED2);
#        endif  // CTRL_LED2
        } else {
#        ifdef CTRL_LED1
            rgblight_sethsv_default_helper(CTRL_LED1);
#        endif  // CTRL_LED1
#        ifdef CTRL_LED2
            rgblight_sethsv_default_helper(CTRL_LED2);
#        endif  // CTRL_LED2
        }
        if ((this_mod | this_osm) & MOD_MASK_GUI) {
#        ifdef GUI_LED1
            rgblight_sethsv_at(51, 255, 255, GUI_LED1);
#        endif  // GUI_LED1
#        ifdef GUI_LED2
            rgblight_sethsv_at(51, 255, 255, GUI_LED2);
#        endif  // GUI_LED2
        } else {
#        ifdef GUI_LED1
            rgblight_sethsv_default_helper(GUI_LED1);
#        endif  // GUI_LED1
#        ifdef GUI_LED2
            rgblight_sethsv_default_helper(GUI_LED2);
#        endif  // GUI_LED2
        }
        if ((this_mod | this_osm) & MOD_MASK_ALT) {
#        ifdef ALT_LED1
            rgblight_sethsv_at(240, 255, 255, ALT_LED1);
#        endif  // ALT_LED1
#        ifdef GUI_LED2
            rgblight_sethsv_at(240, 255, 255, ALT_LED2);
#        endif  // GUI_LED2
        } else {
#        ifdef GUI_LED1
            rgblight_sethsv_default_helper(ALT_LED1);
#        endif  // GUI_LED1
#        ifdef GUI_LED2
            rgblight_sethsv_default_helper(ALT_LED2);
#        endif  // GUI_LED2
        }
    }
}

/* Function for the indicators */
void matrix_scan_indicator(void) {
    if (has_initialized) {
        set_rgb_indicators(get_mods(), host_keyboard_leds(), get_oneshot_mods());
    }
}
#    endif  // INDICATOR_LIGHTS

#    ifdef RGBLIGHT_TWINKLE
static rgblight_fadeout lights[RGBLED_NUM];

__attribute__((weak)) bool rgblight_twinkle_is_led_used_keymap(uint8_t index) { return false; }

/* This function checks for used LEDs.  This way, collisions don't occur and cause weird rendering */
bool rgblight_twinkle_is_led_used(uint8_t index) {
    switch (index) {
#        ifdef INDICATOR_LIGHTS
#            ifdef SHFT_LED1
        case SHFT_LED1:
            return true;
#            endif  // SHFT_LED1
#            ifdef SHFT_LED2
        case SHFT_LED2:
            return true;
#            endif  // SHFT_LED2
#            ifdef CTRL_LED1
        case CTRL_LED1:
            return true;
#            endif  // CTRL_LED1
#            ifdef CTRL_LED2
        case CTRL_LED2:
            return true;
#            endif  // CTRL_LED2
#            ifdef GUI_LED1
        case GUI_LED1:
            return true;
#            endif  // GUI_LED1
#            ifdef GUI_LED2
        case GUI_LED2:
            return true;
#            endif  // GUI_LED2
#            ifdef ALT_LED1
        case ALT_LED1:
            return true;
#            endif  // ALT_LED1
#            ifdef ALT_LED2
        case ALT_LED2:
            return true;
#            endif  // ALT_LED2
#        endif      // INDICATOR_LIGHTS
        default:
            return rgblight_twinkle_is_led_used_keymap(index);
    }
}

/* Handler for fading/twinkling effect */
void scan_rgblight_fadeout(void) {  // Don't effing change this function .... rgblight_sethsv is supppppper intensive
    bool litup = false;
    for (uint8_t light_index = 0; light_index < RGBLED_NUM; ++light_index) {
        if (lights[light_index].enabled && timer_elapsed(lights[light_index].timer) > 10) {
            rgblight_fadeout *light = &lights[light_index];
            litup                   = true;

            if (light->life) {
                light->life -= 1;
                if (get_highest_layer(layer_state) == 0) {
                    sethsv(light->hue + rand() % 0xF, 255, light->life, (LED_TYPE *)&led[light_index]);
                }
                light->timer = timer_read();
            } else {
                if (light->enabled && get_highest_layer(layer_state) == 0) {
                    rgblight_sethsv_default_helper(light_index);
                }
                litup = light->enabled = false;
            }
        }
    }
    if (litup && get_highest_layer(layer_state) == 0) {
        rgblight_set();
    }
}

/* Triggers a LED to fade/twinkle.
 * This function handles the selection of the LED and prepres for it to be used.
 */
void start_rgb_light(void) {
    uint8_t indices[RGBLED_NUM];
    uint8_t indices_count  = 0;
    uint8_t min_life       = 0xFF;
    uint8_t min_life_index = -1;
    for (uint8_t index = 0; index < RGBLED_NUM; ++index) {
        if (rgblight_twinkle_is_led_used(index)) {
            continue;
        }
        if (lights[index].enabled) {
            if (min_life_index == -1 || lights[index].life < min_life) {
                min_life       = lights[index].life;
                min_life_index = index;
            }
            continue;
        }

        indices[indices_count] = index;
        ++indices_count;
    }

    uint8_t light_index;
    if (!indices_count) {
        light_index = min_life_index;
    } else {
        light_index = indices[rand() % indices_count];
    }

    rgblight_fadeout *light = &lights[light_index];
    light->enabled          = true;
    light->timer            = timer_read();
    light->life             = 0xC0 + rand() % 0x40;

    light->hue = rgblight_config.hue + (rand() % 0xB4) - 0x54;

    rgblight_sethsv_at(light->hue, 255, light->life, light_index);
}
#    endif
#endif  // RGBLIGHT_ENABLE

bool process_record_user_rgb(uint16_t keycode, keyrecord_t *record) {
    uint16_t temp_keycode = keycode;
    // Filter out the actual keycode from MT and LT keys.
    if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
        temp_keycode &= 0xFF;
    }

#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
    hypno_timer = timer_read32();
    if (userspace_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == RGB_MATRIX_REST_MODE) {
        rgb_matrix_mode_noeeprom(RGB_MATRIX_TYPING_HEATMAP);
    }
#endif

    switch (temp_keycode) {
#ifdef RGBLIGHT_TWINKLE
        case KC_A ... KC_SLASH:
        case KC_F1 ... KC_F12:
        case KC_INSERT ... KC_UP:
        case KC_KP_SLASH ... KC_KP_DOT:
        case KC_F13 ... KC_F24:
        case KC_AUDIO_MUTE ... KC_MEDIA_REWIND:
            if (record->event.pressed) {
                start_rgb_light();
            }
            break;
#endif                  // RGBLIGHT_TWINKLE
        case KC_RGB_T:  // This allows me to use underglow as layer indication, or as normal
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
            if (record->event.pressed) {
                userspace_config.rgb_layer_change ^= 1;
                dprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change);
                eeconfig_update_user(userspace_config.raw);
                if (userspace_config.rgb_layer_change) {
                    layer_state_set(layer_state);  // This is needed to immediately set the layer color (looks better)
                }
            }
#endif  // RGBLIGHT_ENABLE
            break;
        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;
                dprintf("RGB Matrix Idle Animation [EEPROM]: %u\n", userspace_config.rgb_matrix_idle_anim);
                eeconfig_update_user(userspace_config.raw);
                if (userspace_config.rgb_matrix_idle_anim) {
                    rgb_matrix_mode_noeeprom(RGB_MATRIX_TYPING_HEATMAP);
                }
            }
#endif
            break;
        case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT:  // quantum_keycodes.h L400 for definitions
            if (record->event.pressed) {
                bool is_eeprom_updated = false;
#ifdef RGBLIGHT_ENABLE
                // This disables layer indication, as it's assumed that if you're changing this ... you want that disabled
                if (userspace_config.rgb_layer_change) {
                    userspace_config.rgb_layer_change = false;
                    dprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change);
                    is_eeprom_updated = true;
                }
#endif
#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
                if (userspace_config.rgb_matrix_idle_anim) {
                    userspace_config.rgb_matrix_idle_anim = false;
                    dprintf("RGB Matrix Idle Animation [EEPROM]: %u\n", userspace_config.rgb_matrix_idle_anim);
                    is_eeprom_updated = true;
                }
#endif
                if (is_eeprom_updated) {
                    eeconfig_update_user(userspace_config.raw);
                }
            }
            break;
    }
    return true;
}

void keyboard_post_init_rgb(void) {
#if defined(RGBLIGHT_ENABLE)
#    if defined(RGBLIGHT_STARTUP_ANIMATION)
    bool is_enabled = rgblight_config.enable;
    if (userspace_config.rgb_layer_change) {
        rgblight_enable_noeeprom();
    }
    if (rgblight_config.enable) {
        layer_state_set_user(layer_state);
        uint16_t old_hue = rgblight_config.hue;
        rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
        for (uint16_t i = 255; i > 0; i--) {
            rgblight_sethsv_noeeprom((i + old_hue) % 255, 255, 255);
            matrix_scan();
            wait_ms(10);
        }
    }
    if (!is_enabled) {
        rgblight_disable_noeeprom();
    }

#    endif
    layer_state_set_user(layer_state);
#endif
#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
    if (userspace_config.rgb_matrix_idle_anim) {
        rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE);
    }
#endif
}

void matrix_scan_rgb(void) {
#ifdef RGBLIGHT_ENABLE
#    ifdef RGBLIGHT_TWINKLE
    scan_rgblight_fadeout();
#    endif  // RGBLIGHT_ENABLE

#    ifdef INDICATOR_LIGHTS
    matrix_scan_indicator();
#    endif
#endif

#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
    if (userspace_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == RGB_MATRIX_TYPING_HEATMAP && timer_elapsed32(hypno_timer) > 15000) {
        rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE);
    }
#endif
}

#ifdef RGBLIGHT_ENABLE
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);
}
#endif

layer_state_t layer_state_set_rgb(layer_state_t state) {
#ifdef RGBLIGHT_ENABLE
    if (userspace_config.rgb_layer_change) {
        switch (get_highest_layer(state)) {
            case _RAISE:
                rgblight_set_hsv_and_mode(HSV_YELLOW, RGBLIGHT_MODE_BREATHING + 3);
                break;
            case _LOWER:
                rgblight_set_hsv_and_mode(HSV_GREEN, RGBLIGHT_MODE_BREATHING + 3);
                break;
            case _ADJUST:
                rgblight_set_hsv_and_mode(HSV_RED, RGBLIGHT_MODE_KNIGHT + 2);
                break;
            default:  //  for any other layers, or the default layer
            {
                uint8_t mode = get_highest_layer(state) == _MODS ? RGBLIGHT_MODE_BREATHING : RGBLIGHT_MODE_STATIC_LIGHT;
                switch (get_highest_layer(default_layer_state)) {
                    case _COLEMAK:
                        rgblight_set_hsv_and_mode(HSV_MAGENTA, mode);
                        break;
                    case _DVORAK:
                        rgblight_set_hsv_and_mode(HSV_SPRINGGREEN, mode);
                        break;
                    default:
                        rgblight_set_hsv_and_mode(HSV_CYAN, mode);
                        break;
                }
                break;
            }
        }
    }
#endif  // RGBLIGHT_ENABLE

    return state;
}

#ifdef RGB_MATRIX_ENABLE
#    include "lib/lib8tion/lib8tion.h"
extern led_config_t g_led_config;

void rgb_matrix_layer_helper(uint8_t hue, uint8_t sat, uint8_t val, uint8_t mode, uint8_t speed, uint8_t led_type) {
    HSV hsv = {hue, sat, val};
    if (hsv.v > rgb_matrix_config.hsv.v) {
        hsv.v = rgb_matrix_config.hsv.v;
    }

    switch (mode) {
        case 1:  // breathing
        {
            uint16_t time = scale16by8(g_rgb_counters.tick, speed / 8);
            hsv.v         = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
            RGB rgb       = hsv_to_rgb(hsv);
            for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
                if (HAS_FLAGS(g_led_config.flags[i], led_type)) {
                    rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
                }
            }
            break;
        }
        default:  // Solid Color
        {
            RGB rgb = hsv_to_rgb(hsv);
            for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
                if (HAS_FLAGS(g_led_config.flags[i], led_type)) {
                    rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
                }
            }
            break;
        }
    }
}
#endif

A users/curry/rgb_stuff.h => users/curry/rgb_stuff.h +32 -0
@@ 0,0 1,32 @@
#pragma once
#include "quantum.h"
#ifdef RGB_MATRIX_ENABLE
#    include "rgb_matrix.h"
#endif

#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_TWINKLE)
typedef struct {
    bool     enabled;
    uint8_t  hue;
    uint16_t timer;
    uint8_t  life;
} rgblight_fadeout;
#endif

bool          process_record_user_rgb(uint16_t keycode, keyrecord_t *record);
void          keyboard_post_init_rgb(void);
void          matrix_scan_rgb(void);
layer_state_t layer_state_set_rgb(layer_state_t state);
layer_state_t default_layer_state_set_rgb(layer_state_t state);

#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_TWINKLE)
void scan_rgblight_fadeout(void);
#endif
#if defined(RGBLIGHT_ENABLE)
void rgblight_sethsv_default_helper(uint8_t index);
#endif

#ifdef RGB_MATRIX_ENABLE
void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
void rgb_matrix_layer_helper(uint8_t hue, uint8_t sat, uint8_t val, uint8_t mode, uint8_t speed, uint8_t led_type);
#endif

A users/curry/rgblight_breathe_table.h => users/curry/rgblight_breathe_table.h +118 -0
@@ 0,0 1,118 @@
#ifndef RGBLIGHT_EFFECT_BREATHE_TABLE
#define RGBLIGHT_EFFECT_BREATHE_TABLE

// clang-format off
const uint8_t rgblight_effect_breathe_table[] PROGMEM = {
/* #define RGBLIGHT_EFFECT_BREATHE_CENTER   0.00 */
/* #define RGBLIGHT_EFFECT_BREATHE_MAX      255 */

 #if RGBLIGHT_BREATHE_TABLE_SIZE == 256
  0x44,  0x45,  0x47,  0x48,  0x4a,  0x4b,  0x4c,  0x4e,
  0x4f,  0x51,  0x52,  0x54,  0x55,  0x57,  0x58,  0x5a,
  0x5c,  0x5d,  0x5f,  0x60,  0x62,  0x64,  0x65,  0x67,
  0x69,  0x6a,  0x6c,  0x6e,  0x70,  0x72,  0x73,  0x75,
  0x77,  0x79,  0x7b,  0x7c,  0x7e,  0x80,  0x82,  0x84,
  0x86,  0x88,  0x8a,  0x8b,  0x8d,  0x8f,  0x91,  0x93,
  0x95,  0x97,  0x99,  0x9b,  0x9d,  0x9f,  0xa1,  0xa3,
  0xa5,  0xa7,  0xa9,  0xaa,  0xac,  0xae,  0xb0,  0xb2,
  0xb4,  0xb6,  0xb8,  0xba,  0xbc,  0xbe,  0xbf,  0xc1,
  0xc3,  0xc5,  0xc7,  0xc9,  0xca,  0xcc,  0xce,  0xd0,
  0xd1,  0xd3,  0xd5,  0xd6,  0xd8,  0xda,  0xdb,  0xdd,
  0xde,  0xe0,  0xe1,  0xe3,  0xe4,  0xe5,  0xe7,  0xe8,
  0xe9,  0xeb,  0xec,  0xed,  0xee,  0xef,  0xf0,  0xf1,
  0xf2,  0xf3,  0xf4,  0xf5,  0xf6,  0xf7,  0xf8,  0xf8,
  0xf9,  0xfa,  0xfa,  0xfb,  0xfc,  0xfc,  0xfc,  0xfd,
  0xfd,  0xfe,  0xfe,  0xfe,  0xfe,  0xfe,  0xfe,  0xfe,
  0xfe,  0xfe,  0xfe,  0xfe,  0xfe,  0xfe,  0xfe,  0xfd,
  0xfd,  0xfc,  0xfc,  0xfc,  0xfb,  0xfa,  0xfa,  0xf9,
  0xf8,  0xf8,  0xf7,  0xf6,  0xf5,  0xf4,  0xf3,  0xf2,
  0xf1,  0xf0,  0xef,  0xee,  0xed,  0xec,  0xeb,  0xe9,
  0xe8,  0xe7,  0xe5,  0xe4,  0xe3,  0xe1,  0xe0,  0xde,
  0xdd,  0xdb,  0xda,  0xd8,  0xd6,  0xd5,  0xd3,  0xd1,
  0xd0,  0xce,  0xcc,  0xca,  0xc9,  0xc7,  0xc5,  0xc3,
  0xc1,  0xbf,  0xbe,  0xbc,  0xba,  0xb8,  0xb6,  0xb4,
  0xb2,  0xb0,  0xae,  0xac,  0xaa,  0xa9,  0xa7,  0xa5,
  0xa3,  0xa1,  0x9f,  0x9d,  0x9b,  0x99,  0x97,  0x95,
  0x93,  0x91,  0x8f,  0x8d,  0x8b,  0x8a,  0x88,  0x86,
  0x84,  0x82,  0x80,  0x7e,  0x7c,  0x7b,  0x79,  0x77,
  0x75,  0x73,  0x72,  0x70,  0x6e,  0x6c,  0x6a,  0x69,
  0x67,  0x65,  0x64,  0x62,  0x60,  0x5f,  0x5d,  0x5c,
  0x5a,  0x58,  0x57,  0x55,  0x54,  0x52,  0x51,  0x4f,
  0x4e,  0x4c,  0x4b,  0x4a,  0x48,  0x47,  0x45,  0x44
 #endif /* 256 bytes table */

 #if RGBLIGHT_BREATHE_TABLE_SIZE == 128
  0x44,  0x47,  0x4a,  0x4c,
  0x4f,  0x52,  0x55,  0x58,
  0x5c,  0x5f,  0x62,  0x65,
  0x69,  0x6c,  0x70,  0x73,
  0x77,  0x7b,  0x7e,  0x82,
  0x86,  0x8a,  0x8d,  0x91,
  0x95,  0x99,  0x9d,  0xa1,
  0xa5,  0xa9,  0xac,  0xb0,
  0xb4,  0xb8,  0xbc,  0xbf,
  0xc3,  0xc7,  0xca,  0xce,
  0xd1,  0xd5,  0xd8,  0xdb,
  0xde,  0xe1,  0xe4,  0xe7,
  0xe9,  0xec,  0xee,  0xf0,
  0xf2,  0xf4,  0xf6,  0xf8,
  0xf9,  0xfa,  0xfc,  0xfc,
  0xfd,  0xfe,  0xfe,  0xfe,
  0xfe,  0xfe,  0xfe,  0xfe,
  0xfd,  0xfc,  0xfb,  0xfa,
  0xf8,  0xf7,  0xf5,  0xf3,
  0xf1,  0xef,  0xed,  0xeb,
  0xe8,  0xe5,  0xe3,  0xe0,
  0xdd,  0xda,  0xd6,  0xd3,
  0xd0,  0xcc,  0xc9,  0xc5,
  0xc1,  0xbe,  0xba,  0xb6,
  0xb2,  0xae,  0xaa,  0xa7,
  0xa3,  0x9f,  0x9b,  0x97,
  0x93,  0x8f,  0x8b,  0x88,
  0x84,  0x80,  0x7c,  0x79,
  0x75,  0x72,  0x6e,  0x6a,
  0x67,  0x64,  0x60,  0x5d,
  0x5a,  0x57,  0x54,  0x51,
  0x4e,  0x4b,  0x48,  0x45
 #endif /* 128 bytes table */

 #if RGBLIGHT_BREATHE_TABLE_SIZE == 64
  0x44,  0x4a,
  0x4f,  0x55,
  0x5c,  0x62,
  0x69,  0x70,
  0x77,  0x7e,
  0x86,  0x8d,
  0x95,  0x9d,
  0xa5,  0xac,
  0xb4,  0xbc,
  0xc3,  0xca,
  0xd1,  0xd8,
  0xde,  0xe4,
  0xe9,  0xee,
  0xf2,  0xf6,
  0xf9,  0xfc,
  0xfd,  0xfe,
  0xfe,  0xfe,
  0xfd,  0xfb,
  0xf8,  0xf5,
  0xf1,  0xed,
  0xe8,  0xe3,
  0xdd,  0xd6,
  0xd0,  0xc9,
  0xc1,  0xba,
  0xb2,  0xaa,
  0xa3,  0x9b,
  0x93,  0x8b,
  0x84,  0x7c,
  0x75,  0x6e,
  0x67,  0x60,
  0x5a,  0x54,
  0x4e,  0x48
 #endif /* 64 bytes table */
};
// clang-format on

static const int table_scale = 256 / sizeof(rgblight_effect_breathe_table);

#endif /* RGBLIGHT_EFFECT_BREATHE_TABLE */

A users/curry/rules.mk => users/curry/rules.mk +61 -0
@@ 0,0 1,61 @@
SRC += curry.c \
       process_records.c

LTO_ENABLE            = yes
SPACE_CADET_ENABLE    = no

ifneq ($(strip $(NO_SECRETS)), yes)
    ifneq ("$(wildcard $(USER_PATH)/secrets.c)","")
        SRC += secrets.c
    endif
    ifeq ($(strip $(NO_SECRETS)), lite)
        OPT_DEFS += -DNO_SECRETS
    endif
endif

ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
    SRC += tap_dances.c
endif

ifeq ($(strip $(OLED_DRIVER_ENABLE)), yes)
    SRC += oled.c
endif

ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
    SRC += rgb_stuff.c
    ifeq ($(strip $(INDICATOR_LIGHTS)), yes)
        OPT_DEFS += -DINDICATOR_LIGHTS
    endif
    ifeq ($(strip $(RGBLIGHT_TWINKLE)), yes)
        OPT_DEFS += -DRGBLIGHT_TWINKLE
    endif
    ifeq ($(strip $(RGBLIGHT_NOEEPROM)), yes)
        OPT_DEFS += -DRGBLIGHT_NOEEPROM
    endif
    ifeq ($(strip $(RGBLIGHT_STARTUP_ANIMATION)), yes)
        OPT_DEFS += -DRGBLIGHT_STARTUP_ANIMATION
    endif
endif

RGB_MATRIX_ENABLE ?= no
ifneq ($(strip $(RGB_MATRIX_ENABLE)), no)
    SRC += rgb_stuff.c
endif


ifdef CONSOLE_ENABLE
    ifeq ($(strip $(KEYLOGGER_ENABLE)), yes)
        OPT_DEFS += -DKEYLOGGER_ENABLE
    endif
endif

ifeq ($(strip $(MAKE_BOOTLOADER)), yes)
    OPT_DEFS += -DMAKE_BOOTLOADER
endif

# At least until build.mk or the like drops, this is here to prevent
# VUSB boards from enabling NKRO, as they do not support it. Ideally
# this should be handled per keyboard, but until that happens ...
ifeq ($(strip $(PROTOCOL)), VUSB)
    NKRO_ENABLE       = no
endif

A users/curry/tap_dances.c => users/curry/tap_dances.c +3 -0
@@ 0,0 1,3 @@
#include "curry.h"

qk_tap_dance_action_t tap_dance_actions[] = {};

A users/curry/tap_dances.h => users/curry/tap_dances.h +3 -0
@@ 0,0 1,3 @@
#pragma once
#include "curry.h"


A users/curry/wrappers.h => users/curry/wrappers.h +92 -0
@@ 0,0 1,92 @@
#pragma once
#include "curry.h"
/*
Since our quirky block definitions are basically a list of comma separated
arguments, we need a wrapper in order for these definitions to be
expanded before being used as arguments to the LAYOUT_xxx macro.
*/
#if (!defined(LAYOUT) && defined(KEYMAP))
#    define LAYOUT KEYMAP
#endif

// clang-format off
#define KEYMAP_wrapper(...)                  LAYOUT(__VA_ARGS__)
#define LAYOUT_wrapper(...)                  LAYOUT(__VA_ARGS__)
#define LAYOUT_ortho_4x12_wrapper(...)       LAYOUT_ortho_4x12(__VA_ARGS__)
#define LAYOUT_ortho_5x12_wrapper(...)       LAYOUT_ortho_5x12(__VA_ARGS__)

/*
Blocks for each of the four major keyboard layouts
Organized so we can quickly adapt and modify all of them
at once, rather than for each keyboard, one at a time.
And this allows for much cleaner blocks in the keymaps.
For instance Tap/Hold for Control on all of the layouts

NOTE: These are all the same length.  If you do a search/replace
  then you need to add/remove underscores to keep the
  lengths consistent.
*/

#define _________________QWERTY_L1_________________         KC_Q,    KC_W,    KC_E,    KC_R,    KC_T
#define _________________QWERTY_L2_________________         KC_A,    KC_S,    KC_D,    KC_F,    KC_G
#define _________________QWERTY_L3_________________         KC_Z,    KC_X,    KC_C,    KC_V,    KC_B

#define _________________QWERTY_R1_________________         KC_Y,    KC_U,    KC_I,    KC_O,    KC_P
#define _________________QWERTY_R2_________________         KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN
#define _________________QWERTY_R3_________________         KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLASH

#define _________________COLEMAK_L1________________         KC_Q,    KC_W,    KC_F,    KC_P,    KC_B
#define _________________COLEMAK_L2________________         KC_A,    KC_R,    KC_S,    KC_T,    KC_G
#define _________________COLEMAK_L3________________         KC_Z,    KC_X,    KC_C,    KC_D,    KC_V

#define _________________COLEMAK_R1________________         KC_J,    KC_L,    KC_U,    KC_Y,    KC_SCLN
#define _________________COLEMAK_R2________________         KC_M,    KC_N,    KC_E,    KC_I,    KC_O
#define _________________COLEMAK_R3________________         KC_K,    KC_H,    KC_COMM, KC_DOT,  KC_SLASH

#define _________________DVORAK_L1_________________         KC_QUOT, KC_COMM, KC_DOT, KC_P,     KC_Y
#define _________________DVORAK_L2_________________         KC_A,    KC_O,    KC_E,   KC_U,     KC_I
#define _________________DVORAK_L3_________________         KC_SCLN, KC_Q,    KC_J,   KC_K,     KC_X

#define _________________DVORAK_R1_________________         KC_F,    KC_G,    KC_C,    KC_R,    KC_L
#define _________________DVORAK_R2_________________         KC_D,    KC_H,    KC_T,    KC_N,    KC_S
#define _________________DVORAK_R3_________________         KC_B,    KC_M,    KC_W,    KC_V,    KC_Z


#define ________________NUMBER_LEFT________________         KC_1,    KC_2,    KC_3,    KC_4,    KC_5
#define ________________NUMBER_RIGHT_______________         KC_6,    KC_7,    KC_8,    KC_9,    KC_0

#define _________________FUNC_LEFT_________________         KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5
#define _________________FUNC_RIGHT________________         KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10

#define _________________SYM_LEFT__________________         KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC
#define _________________SYM_RIGHT_________________         KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN


#define ___________________BLANK___________________         _______, _______, _______, _______, _______


#define _________________LOWER_L1__________________         _________________FUNC_LEFT_________________
#define _________________LOWER_L2__________________         _________________SYM_LEFT__________________
#define _________________LOWER_L3__________________         KC_DT1,  KC_DT2,  KC_DT3,  KC_DT4,  _______

#define _________________LOWER_R1__________________         _________________FUNC_RIGHT________________
#define _________________LOWER_R2__________________         _________________SYM_RIGHT_________________
#define _________________LOWER_R3__________________         _______, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR

#define _________________RAISE_L1__________________         ________________NUMBER_LEFT________________
#define _________________RAISE_L2__________________         KC_PGUP, KC_PGDN, KC_HOME, KC_END,  _______
#define _________________RAISE_L3__________________         _______, _______, _______, _______, _______

#define _________________RAISE_R1__________________         ________________NUMBER_RIGHT_______________
#define _________________RAISE_R2__________________         KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT, _______
#define _________________RAISE_R3__________________         _______, KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC

#define _________________ADJUST_L1_________________         RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, RGB_TOG
#define _________________ADJUST_L2_________________         MU_TOG , CK_TOGG, AU_ON,   AU_OFF,  CG_NORM
#define _________________ADJUST_L3_________________         RGB_RMOD,RGB_HUD,RGB_SAD, RGB_VAD, KC_RGB_T

#define _________________ADJUST_R1_________________         KC_SEC1, KC_SEC2, KC_SEC3, KC_SEC4, KC_SEC5
#define _________________ADJUST_R2_________________         CG_SWAP, QWERTY,  COLEMAK, DVORAK,  XXXXXXX
#define _________________ADJUST_R3_________________         MG_NKRO, KC_MUTE, KC_VOLD, KC_VOLU, KC_MNXT

// clang-format on