~ruther/qmk_firmware

357a888d805c21c9cb4917f55d558195e8b85db5 — Drashna Jaelre 5 years ago 7f56569
[Keymap] Drashna's Keymap Update - Display Edition (#9282)

OLED Display fixes
Add support for RGBLIGHT Layers
Add gaming layer to corn and kyria
RGBLight Startup Animation fixes and improvements (uses matrix_scan now!)
Pimoroni Trackball support added (IT'S RGB!!!)
Fix issues due to code changes
M keyboards/crkbd/keymaps/drashna/keymap.c => keyboards/crkbd/keymaps/drashna/keymap.c +11 -1
@@ 121,7 121,17 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
}

#ifdef OLED_DRIVER_ENABLE
oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_270; }
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
#    ifndef SPLIT_KEYBOARD
    if (is_master) {
#    endif
        return OLED_ROTATION_270;
#    ifndef SPLIT_KEYBOARD
    }  else {
        return rotation;
    }
#    endif
}
#endif

uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {

M keyboards/kyria/keymaps/drashna/config.h => keyboards/kyria/keymaps/drashna/config.h +1 -0
@@ 32,6 32,7 @@
#    define RGBLIGHT_SAT_STEP 8
#    define RGBLIGHT_VAL_STEP 8
#    define RGBLIGHT_SPLIT
#    define RGBLIGHT_LAYERS
#endif

// If you are using an Elite C rev3 on the slave side, uncomment the lines below:

M keyboards/kyria/keymaps/drashna/keymap.c => keyboards/kyria/keymaps/drashna/keymap.c +47 -1
@@ 23,7 23,7 @@ uint8_t is_master;
  LAYOUT_wrapper( \
      KC_ESC,  K01,     K02,     K03,     K04,     K05,                                             K06,     K07,     K08,     K09,     K0A,     KC_MINS, \
   LALT_T(KC_TAB), K11, K12,     K13,     K14,     K15,                                             K16,     K17,     K18,     K19,     K1A, RALT_T(KC_QUOT), \
      OS_LSFT, CTL_T(K21), K22,  K23,     K24,     K25,  KC_NO, MEH(KC_MINS),  TG(_DIABLO), KC_NO,  K26,     K27,     K28,     K29, RCTL_T(K2A), OS_RSFT, \
      OS_LSFT, CTL_T(K21), K22,  K23,     K24,     K25,  TG(_GAMEPAD), MEH(KC_MINS),  TG(_DIABLO), KC_CAPS,  K26,     K27,     K28,     K29, RCTL_T(K2A), OS_RSFT, \
                                 KC_MUTE, OS_LALT, KC_GRV,  KC_SPC,  BK_LWER,     DL_RAIS, KC_ENT,  OS_RGUI, UC(0x03A8), UC(0x2E2E) \
    )
/* Re-pass though to allow templates to be used */


@@ 85,6 85,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
        KC_LSFT, ___________________BLANK___________________, _______, _______,   _______, _______, ___________________BLANK___________________, KC_RSFT,
                                   _______, _______, KC_LALT, _______, _______,   _______, _______, KC_RGUI, _______, _______
    ),

    [_GAMEPAD] = LAYOUT_wrapper(
        KC_ESC,  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_V,    _______, _______,   _______, LALT(KC_PSCR), _______, _______, _______, _______, _______, _______,
                                  _______, MAGIC_TOGGLE_NKRO, KC_V,     KC_SPC,  KC_H,   _______, _______, _______, _______, _______
    ),

    [_DIABLO] = LAYOUT_wrapper(
        KC_ESC,  KC_S,    KC_I,    KC_F,    KC_M,    KC_T,                                          KC_F9,   KC_F10,  KC_F11,  KC_F12,  KC_NO,   KC_NO,
        KC_TAB,  KC_1,    KC_2,    KC_3,    KC_4,    KC_G,                                          KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,


@@ 172,3 180,41 @@ void encoder_update_user(uint8_t index, bool clockwise) {
    }
}
#endif

#ifdef RGBLIGHT_LAYERS
const rgblight_segment_t PROGMEM shift_layers[] = RGBLIGHT_LAYER_SEGMENTS(
    {  8, 1, 120, 255, 255},
    { 18, 1, 120, 255, 255}
);
const rgblight_segment_t PROGMEM control_layers[] = RGBLIGHT_LAYER_SEGMENTS(
    {  6, 1, 0, 255, 255},
    { 16, 1, 0, 255, 255}
);
const rgblight_segment_t PROGMEM alt_layers[] = RGBLIGHT_LAYER_SEGMENTS(
    {  2, 1, 240, 255, 255},
    { 17, 1, 250, 255, 255}
);
const rgblight_segment_t PROGMEM gui_layers[] = RGBLIGHT_LAYER_SEGMENTS(
    {  7, 1, 51, 255, 255},
    { 12, 1, 51, 255, 255}
);

const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(
    shift_layers,
    control_layers,
    alt_layers,
    gui_layers
);

void keyboard_post_init_keymap(void) {
    rgblight_layers = my_rgb_layers;
}

void matrix_scan_keymap(void) {
        uint8_t mods = mod_config(get_mods()|get_oneshot_mods());
        rgblight_set_layer_state(0, mods & MOD_MASK_SHIFT);
        rgblight_set_layer_state(1, mods & MOD_MASK_CTRL);
        rgblight_set_layer_state(2, mods & MOD_MASK_ALT);
        rgblight_set_layer_state(3, mods & MOD_MASK_GUI);
}
#endif

M keyboards/kyria/keymaps/drashna/rules.mk => keyboards/kyria/keymaps/drashna/rules.mk +3 -3
@@ 1,17 1,17 @@
OLED_DRIVER_ENABLE = yes   # Enables the use of OLED displays
ENCODER_ENABLE = yes       # ENables the use of one or more encoders
RGBLIGHT_ENABLE = yes      # Enable keyboard RGB underglow
RGBLIGHT_STARTUP_ANIMATION = no
RGBLIGHT_STARTUP_ANIMATION = yes

BOOTMAGIC_ENABLE = no      # Virtual DIP switch configuration
MOUSEKEY_ENABLE = no      # Mouse keys
MOUSEKEY_ENABLE = no       # Mouse keys
EXTRAKEY_ENABLE = yes      # Audio control and System control
CONSOLE_ENABLE = no        # Console for debug
COMMAND_ENABLE = no        # Commands for debug and configuration
NKRO_ENABLE = no           # USB Nkey Rollover
BACKLIGHT_ENABLE = no      # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE = no           # MIDI support
UNICODE_ENABLE = yes       # Unicode
UNICODE_ENABLE = no        # Unicode
BLUETOOTH_ENABLE = no      # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE = no          # Audio output on port C6
FAUXCLICKY_ENABLE = no     # Use buzzer to emulate clicky switches

M layouts/community/ergodox/drashna/config.h => layouts/community/ergodox/drashna/config.h +4 -1
@@ 15,7 15,7 @@
#define PRODUCT DrashnaDox - Hacked ErgoDox EZ Hybrid Monstrosity

#undef DEBOUNCE
#define DEBOUNCE 60
#define DEBOUNCE 15

#define TAPPING_TERM_PER_KEY



@@ 30,3 30,6 @@
#        undef RGBLIGHT_SLEEP
#    endif
#endif

#define PIMORONI_TRACKBALL_INVERT_X
#define PIMORONI_TRACKBALL_INVERT_Y

M layouts/community/ergodox/drashna/keymap.c => layouts/community/ergodox/drashna/keymap.c +55 -3
@@ 10,7 10,11 @@
extern rgblight_config_t rgblight_config;
#endif

enum more_custom_keycodes { KC_SWAP_NUM = NEW_SAFE_RANGE };
enum more_custom_keycodes {
    KC_SWAP_NUM = NEW_SAFE_RANGE,
    PM_SCROLL,
    PM_PRECISION,
};

// define layer change stuff for underglow indicator
bool skip_leds = false;


@@ 33,7 37,7 @@ bool skip_leds = false;
      LALT_T(KC_TAB), K01, K02, K03,      K04,     K05,     TG(_DIABLO),         TG(_DIABLO), K06,     K07,     K08,     K09,     K0A,     KC_BSLS, \
      KC_C1R3, K11,    K12,     K13,      K14,     K15,                                       K16,     K17,     K18,     K19,     K1A, RALT_T(KC_QUOT), \
      KC_MLSF, CTL_T(K21), K22, K23,      K24,     K25,     TG(_GAMEPAD),       TG(_GAMEPAD), K26,     K27,     K28,     K29,  RCTL_T(K2A), KC_MRSF, \
      KC_GRV,  OS_MEH, OS_HYPR, KC_LBRC, KC_RBRC,                                            KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT, UC(0x2E2E),        \
      KC_GRV,  OS_MEH, OS_HYPR, KC_LBRC, KC_RBRC,                                            KC_BTN1, KC_BTN3, KC_BTN2,   PM_SCROLL, PM_PRECISION,        \
                                                  OS_LALT, OS_LGUI,                 OS_RGUI, CTL_T(KC_ESCAPE),                                      \
                                                           KC_APP,                  KC_MENU,                                                        \
                              KC_SPC, LT(_LOWER, KC_BSPC), OS_LWR,                  OS_RSE, LT(_RAISE, KC_DEL), KC_ENT                              \


@@ 281,7 285,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

  [_ADJUST] = LAYOUT_ergodox_pretty_wrapper(
             KC_MAKE, _______, _______, _______, _______, _______, UC_MOD,                  KC_NUKE, _________________ADJUST_R1_________________, KC_RST,
             VRSN,    _________________ADJUST_L1_________________, _______,                 _______, _______, _______, _______, _______, _______, EEP_RST,
             VRSN,    _________________ADJUST_L1_________________, _______,                 _______, _________________ADJUST_R1_________________, EEP_RST,
             _______, _________________ADJUST_L2_________________,                                   _________________ADJUST_R2_________________, RGB_IDL,
             _______, _________________ADJUST_L3_________________, _______,                 _______, _________________ADJUST_R3_________________, TG(_MODS),
             _______, _______, _______, _______, _______,                                                     _______, _______, _______, _______, _______,


@@ 293,6 297,26 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
};
// clang-format on

#ifdef PIMORONI_TRACKBALL_ENABLE
void run_trackball_cleanup(void) {
    if (trackball_is_scrolling()) {
        trackball_set_rgbw(RGB_CYAN, 0x00);
    } else if (trackball_get_precision() != 1.0) {
        trackball_set_rgbw(RGB_GREEN, 0x00);
    } else {
        trackball_set_rgbw(RGB_MAGENTA, 0x00);
    }
}

void keyboard_post_init_keymap(void) {
    // trackball_set_precision(1.5);
    trackball_set_rgbw(RGB_MAGENTA, 0x00);
}
void shutdown_keymap(void) {
    trackball_set_rgbw(RGB_RED, 0x00);
}
#endif

bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case KC_1:


@@ 321,6 345,34 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
                eeconfig_update_user(userspace_config.raw);
            }
            break;
#ifdef PIMORONI_TRACKBALL_ENABLE
        case PM_SCROLL:
            trackball_set_scrolling(record->event.pressed);
            run_trackball_cleanup();
            break;
        case PM_PRECISION:
            if (record->event.pressed) {
                trackball_set_precision(1.5);
            } else {
                trackball_set_precision(1);
            }
            run_trackball_cleanup();
            break;
#if     !defined(MOUSEKEY_ENABLE) && defined(POINTING_DEVICE_ENABLE)
        case KC_BTN1 ... KC_BTN3:
        {
            report_mouse_t currentReport = pointing_device_get_report();
            if (record->event.pressed) {
                currentReport.buttons |= (1 << (keycode - KC_BTN1));  // this is defined in report.h
            } else {
                currentReport.buttons &= ~(1 << (keycode - KC_BTN1));
            }
            pointing_device_set_report(currentReport);
            pointing_device_send();
            break;
        }
#    endif
#endif
    }
    // switch (keycode) {
    //  case KC_P00:

M layouts/community/ergodox/drashna/rules.mk => layouts/community/ergodox/drashna/rules.mk +8 -6
@@ 1,18 1,20 @@
BOOTMAGIC_ENABLE   = lite
TAP_DANCE_ENABLE   = yes
COMMAND_ENABLE     = no  # Commands for debug and configuration
CONSOLE_ENABLE     =
CONSOLE_ENABLE     = no
SPACE_CADET_ENABLE = no

ifeq ($(strip $(KEYBOARD)), ergodox_ez)
    RGBLIGHT_ENABLE    = yes
    RGB_MATRIX_ENABLE  = yes
    RGBLIGHT_TWINKLE   = no
    INDICATOR_LIGHTS   = no
    RGBLIGHT_ENABLE            = yes
    RGB_MATRIX_ENABLE          = yes
    RGBLIGHT_TWINKLE           = no
    INDICATOR_LIGHTS           = no
    RGBLIGHT_STARTUP_ANIMATION = yes
    PIMORONI_TRACKBALL_ENABLE  = yes
    MOUSEKEY_ENABLE            = no
endif

UNICODE_ENABLE     = yes
UNICODE_ENABLE     = no
UNICDOEMAP_ENABLE  = no



M layouts/community/ortho_5x12/drashna/rules.mk => layouts/community/ortho_5x12/drashna/rules.mk +6 -5
@@ 7,9 7,10 @@ TAP_DANCE_ENABLE  = no
NKRO_ENABLE       = yes

ifeq ($(strip $(KEYBOARD)), fractal)
    RGB_MATRIX_ENABLE   = no
    AUDIO_ENABLE        = yes
    RGBLIGHT_ENABLE     = yes
    RGBLIGHT_TWINKLE    = yes
    BOOTLOADER          = qmk-dfu
    RGB_MATRIX_ENABLE           = no
    AUDIO_ENABLE                = yes
    RGBLIGHT_ENABLE             = yes
    RGBLIGHT_TWINKLE            = yes
    RGBLIGHT_STARTUP_ANIMATION  = yes
    BOOTLOADER                  = qmk-dfu
endif

M users/drashna/.gitlab-ci.yml => users/drashna/.gitlab-ci.yml +2 -3
@@ 7,16 7,15 @@ QMK Firmware:
    GIT_SUBMODULE_STRATEGY: recursive
  tags:
    - linux
  image: ubuntu:18.10
  image: qmkfm/base_container
  before_script:
    - apt-get update -qy
    - apt-get install -y build-essential avr-libc binutils-arm-none-eabi binutils-avr dfu-programmer dfu-util gcc gcc-arm-none-eabi git libnewlib-arm-none-eabi gcc-avr python3 unzip wget zip
    - avr-gcc --version
    - uname -a
  script:
    - make test:all
    - make planck/rev6:default planck/rev5:default
    - make keebio/iris/rev2:drashna keebio/iris/rev2:drashna_old ergodox_ez:drashna ergodox_ez:drashna_glow keebio/viterbi/rev1:drashna orthodox/rev1:drashna orthodox/rev3:drashna crkbd:drashna planck/light:drashna planck/rev6:drashna fractal:drashna primekb/prime_m:drashna -j2 --output-sync
    - make all:drashna -j2
  artifacts:
    name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
    paths:

M users/drashna/config.h => users/drashna/config.h +4 -3
@@ 1,7 1,7 @@
#pragma once

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

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


@@ 98,8 98,9 @@
#    define ONESHOT_TIMEOUT 3000
#endif  // !ONESHOT_TIMEOUT

#ifndef QMK_KEYS_PER_SCAN
#    define QMK_KEYS_PER_SCAN 4
#ifdef QMK_KEYS_PER_SCAN
#    undef QMK_KEYS_PER_SCAN
#    define QMK_KEYS_PER_SCAN 1
#endif  // !QMK_KEYS_PER_SCAN

// this makes it possible to do rolling combos (zx) with keys that

M users/drashna/drashna.c => users/drashna/drashna.c +1 -5
@@ 113,13 113,9 @@ void shutdown_user(void) {
    rgblight_setrgb_red();
#endif  // RGBLIGHT_ENABLE
#ifdef RGB_MATRIX_ENABLE
#    ifdef __AVR__
    rgb_matrix_set_color_all(0xFF, 0x00, 0x00);
    rgb_matrix_update_pwm_buffers();
#    else
    rgb_matrix_sethsv_noeeprom(0, 255, 255);
    rgb_matrix_mode_noeeprom(1);
#    endif

#endif  // RGB_MATRIX_ENABLE
    shutdown_keymap();
}

M users/drashna/drashna.h => users/drashna/drashna.h +3 -0
@@ 34,6 34,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#if defined(OLED_DRIVER_ENABLE)
#    include "oled_stuff.h"
#endif
#if defined(PIMORONI_TRACKBALL_ENABLE)
#    include "pimoroni_trackball.h"
#endif

/* Define layer names */
enum userspace_layers {

M users/drashna/oled_stuff.c => users/drashna/oled_stuff.c +12 -5
@@ 170,6 170,13 @@ void render_bootmagic_status(void) {
        {{0x95, 0x96, 0}, {0xb5, 0xb6, 0}},
    };

    bool is_bootmagic_on;
    #ifdef OLED_DISPLAY_128X64
    is_bootmagic_on = !keymap_config.swap_lctl_lgui;
    #else
    is_bootmagic_on = keymap_config.swap_lctl_lgui;
    #endif

    oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_NAME), false);
#ifdef OLED_DISPLAY_128X64
    if (keymap_config.swap_lctl_lgui)


@@ 177,11 184,11 @@ void render_bootmagic_status(void) {
    oled_write_P(PSTR(" "), false);
#endif
    {
        oled_write_P(logo[1][0], false);
        oled_write_P(logo[1][0], is_bootmagic_on);
#ifdef OLED_DISPLAY_128X64
    } else {
#endif
        oled_write_P(logo[0][0], false);
        oled_write_P(logo[0][0], !is_bootmagic_on);
    }
    oled_write_P(PSTR(" "), false);
#ifdef OLED_DISPLAY_128X64


@@ 192,11 199,11 @@ void render_bootmagic_status(void) {
    if (keymap_config.swap_lctl_lgui)
#endif
    {
        oled_write_P(logo[1][1], false);
        oled_write_P(logo[1][1], is_bootmagic_on);
#ifdef OLED_DISPLAY_128X64
    } else {
#endif
        oled_write_P(logo[0][1], false);
        oled_write_P(logo[0][1], !is_bootmagic_on);
    }
    oled_write_P(PSTR(" "), false);
#ifdef OLED_DISPLAY_128X64


@@ 233,7 240,7 @@ __attribute__((weak)) void oled_driver_render_logo(void) {
}

void render_status_secondary(void) {
#if !defined(SPLIT_TRANSPORT_MIRROR) || defined(OLED_DRIVER_128x64)
#if !defined(SPLIT_TRANSPORT_MIRROR) || defined(OLED_DISPLAY_128X64)
    oled_driver_render_logo();
#endif
#ifdef SPLIT_TRANSPORT_MIRROR

A users/drashna/pimoroni_trackball.c => users/drashna/pimoroni_trackball.c +114 -0
@@ 0,0 1,114 @@
#include "pimoroni_trackball.h"
#include "i2c_master.h"

static uint8_t scrolling      = 0;
static int16_t x_offset       = 0;
static int16_t y_offset       = 0;
static int16_t h_offset       = 0;
static int16_t v_offset       = 0;
static float precisionSpeed = 1;

#ifndef I2C_TIMEOUT
#    define I2C_TIMEOUT 100
#endif
#ifndef MOUSE_DEBOUNCE
#    define MOUSE_DEBOUNCE 5
#endif

void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) {
    uint8_t data[] = {0x00, red, green, blue, white};
    i2c_transmit(TRACKBALL_WRITE, data, sizeof(data), I2C_TIMEOUT);
}

int16_t mouse_offset(uint8_t positive, uint8_t negative, int16_t scale) {
    int16_t offset    = (int16_t)positive - (int16_t)negative;
    int16_t magnitude = (int16_t)(scale * offset * offset * precisionSpeed);
    return offset < 0 ? -magnitude : magnitude;
}

void update_member(int8_t* member, int16_t* offset) {
    if (*offset > 127) {
        *member = 127;
        *offset -= 127;
    } else if (*offset < -127) {
        *member = -127;
        *offset += 127;
    } else {
        *member = *offset;
        *offset = 0;
    }
}

__attribute__((weak)) void trackball_check_click(bool pressed, report_mouse_t* mouse) {
    if (pressed) {
        mouse->buttons |= MOUSE_BTN1;
    } else {
        mouse->buttons &= ~MOUSE_BTN1;
    }
}

float trackball_get_precision(void) { return precisionSpeed; }
void    trackball_set_precision(float precision) { precisionSpeed = precision; }
bool    trackball_is_scrolling(void) { return scrolling; }
void    trackball_set_scrolling(bool scroll) { scrolling = scroll; }

__attribute__((weak)) void pointing_device_init(void) { trackball_set_rgbw(0x00,0x00,0x00,0x4F); }

void pointing_device_task(void) {
    static bool debounce;
    static uint16_t debounce_timer;
    uint8_t state[5] = {};
    if (i2c_readReg(TRACKBALL_WRITE, 0x04, state, 5, I2C_TIMEOUT) == I2C_STATUS_SUCCESS) {
        if (!state[4] && !debounce) {
            if (scrolling) {
#ifdef PIMORONI_TRACKBALL_INVERT_X
                h_offset += mouse_offset(state[2], state[3], 1);
#else
                h_offset -= mouse_offset(state[2], state[3], 1);
#endif
#ifdef PIMORONI_TRACKBALL_INVERT_Y
                v_offset += mouse_offset(state[1], state[0], 1);
#else
                v_offset -= mouse_offset(state[1], state[0], 1);
#endif
            } else {
#ifdef PIMORONI_TRACKBALL_INVERT_X
                x_offset -= mouse_offset(state[2], state[3], 5);
#else
                x_offset += mouse_offset(state[2], state[3], 5);
#endif
#ifdef PIMORONI_TRACKBALL_INVERT_Y
                y_offset -= mouse_offset(state[1], state[0], 5);
#else
                y_offset += mouse_offset(state[1], state[0], 5);
#endif
            }
        } else {
            if (state[4]) {
                debounce = true;
                debounce_timer = timer_read();
            }
        }
    }

    if (timer_elapsed(debounce_timer) > MOUSE_DEBOUNCE) debounce = false;

    report_mouse_t mouse = pointing_device_get_report();

    trackball_check_click(state[4] & (1 << 7), &mouse);


#ifndef PIMORONI_TRACKBALL_ROTATE
    update_member(&mouse.x, &x_offset);
    update_member(&mouse.y, &y_offset);
    update_member(&mouse.h, &h_offset);
    update_member(&mouse.v, &v_offset);
#else
    update_member(&mouse.x, &y_offset);
    update_member(&mouse.y, &x_offset);
    update_member(&mouse.h, &v_offset);
    update_member(&mouse.v, &h_offset);
#endif
    pointing_device_set_report(mouse);
    pointing_device_send();
}

A users/drashna/pimoroni_trackball.h => users/drashna/pimoroni_trackball.h +18 -0
@@ 0,0 1,18 @@
#pragma once

#include "quantum.h"
#include "pointing_device.h"

#ifndef TRACKBALL_ADDRESS
#    define TRACKBALL_ADDRESS 0x0A
#endif
#define TRACKBALL_WRITE ((TRACKBALL_ADDRESS << 1) | I2C_WRITE)
#define TRACKBALL_READ  ((TRACKBALL_ADDRESS << 1) | I2C_READ)

void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white);
void trackball_check_click(bool pressed, report_mouse_t *mouse);

float trackball_get_precision(void);
void    trackball_set_precision(float precision);
bool    trackball_is_scrolling(void);
void    trackball_set_scrolling(bool scroll);

M users/drashna/process_records.c => users/drashna/process_records.c +1 -1
@@ 51,7 51,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
                    clear_mods();
                    clear_oneshot_mods();
#endif
                    send_string_with_delay_P(PSTR("bin/qmk"), TAP_CODE_DELAY);
                    send_string_with_delay_P(PSTR("qmk"), TAP_CODE_DELAY);
#ifndef MAKE_BOOTLOADER
                    if ((temp_mod | temp_osm) & MOD_MASK_SHIFT)
#endif

M users/drashna/rgb_matrix_stuff.c => users/drashna/rgb_matrix_stuff.c +3 -3
@@ 12,14 12,14 @@ static uint32_t hypno_timer;

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;
    if (hsv.v > rgb_matrix_get_val()) {
        hsv.v = rgb_matrix_get_val();
    }

    switch (mode) {
        case 1:  // breathing
        {
            uint16_t time = scale16by8(g_rgb_counters.tick, speed / 8);
            uint16_t time = scale16by8(g_rgb_timer, 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++) {

M users/drashna/rgb_stuff.c => users/drashna/rgb_stuff.c +32 -145
@@ 2,136 2,13 @@
#include "rgb_stuff.h"
#include "eeprom.h"

extern rgblight_config_t rgblight_config;
bool                     has_initialized;
bool    has_initialized;

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

/* 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 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
void rgblight_sethsv_default_helper(uint8_t index) { rgblight_sethsv_at(rgblight_get_hue(), rgblight_get_sat(), rgblight_get_val(), index); }

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


@@ 170,9 47,6 @@ void start_rgb_light(void) {
    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;


@@ 197,7 71,7 @@ void start_rgb_light(void) {
    light->timer            = timer_read();
    light->life             = 0xC0 + rand() % 0x40;

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

    rgblight_sethsv_at(light->hue, 255, light->life, light_index);
}


@@ 227,39 101,52 @@ 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 uint8_t old_hue;
static uint16_t rgblight_startup_loop_timer;
#endif

void keyboard_post_init_rgb_light(void) {
#if defined(RGBLIGHT_STARTUP_ANIMATION)
    bool is_enabled = rgblight_config.enable;
    is_enabled = rgblight_is_enabled();
    if (userspace_config.rgb_layer_change) {
        rgblight_enable_noeeprom();
    }
    if (rgblight_config.enable) {
    if (rgblight_is_enabled()) {
        layer_state_set_rgb_light(layer_state);
        uint16_t old_hue = rgblight_config.hue;
        old_hue = rgblight_get_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);
        }
        is_rgblight_startup = true;
    }
    if (!is_enabled) {
        rgblight_disable_noeeprom();
    }

#endif
    layer_state_set_rgb_light(layer_state);
}

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

#    ifdef INDICATOR_LIGHTS
    matrix_scan_indicator();
#    endif
#if defined(RGBLIGHT_STARTUP_ANIMATION)
    if (is_rgblight_startup && is_keyboard_master()) {
        if (timer_elapsed(rgblight_startup_loop_timer) > 10) {
            static uint8_t counter;
            counter++;
            rgblight_sethsv_noeeprom((counter + old_hue) % 255, 255, 255);
            rgblight_startup_loop_timer = timer_read();
            if (counter == 255) {
                is_rgblight_startup = false;
                if (!is_enabled) {
                    rgblight_disable_noeeprom();
                }
                if (userspace_config.rgb_layer_change) {
                    layer_state_set_rgb_light(layer_state);
                }
            }
        }
    }
#endif
}


M users/drashna/rules.mk => users/drashna/rules.mk +7 -3
@@ 22,9 22,6 @@ 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


@@ 62,3 59,10 @@ endif
ifeq ($(strip $(OLED_DRIVER_ENABLE)), yes)
    SRC += oled_stuff.c
endif

ifeq ($(strip $(PIMORONI_TRACKBALL_ENABLE)), yes)
    POINTING_DEVICE_ENABLE := yes
    OPT_DEFS += -DPIMORONI_TRACKBALL_ENABLE
    SRC += pimoroni_trackball.c
    QUANTUM_LIB_SRC += i2c_master.c
endif