mirror of
https://github.com/qmk/qmk_firmware.git
synced 2024-12-15 14:13:27 +00:00
815cecfbff
Co-authored-by: Drashna Jaelre <drashna@live.com> Co-authored-by: Richard Baptist <richard@remote.com>
351 lines
11 KiB
C
351 lines
11 KiB
C
// Copyright 2023 Your Name (@rpbaptist)
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "rpbaptist.h"
|
|
|
|
uint32_t transport_user_config = 0;
|
|
|
|
void user_config_sync(uint8_t initiator2target_buffer_size, const void* initiator2target_buffer, uint8_t target2initiator_buffer_size, void* target2initiator_buffer) {
|
|
if (initiator2target_buffer_size == sizeof(transport_user_config)) {
|
|
memcpy(&transport_user_config, initiator2target_buffer, initiator2target_buffer_size);
|
|
}
|
|
}
|
|
|
|
#ifdef OLED_ENABLE
|
|
const char* rgb_matrix_anim_oled_text(uint8_t mode) {
|
|
switch (mode) {
|
|
case RGB_MATRIX_TYPING_HEATMAP:
|
|
return PSTR("Heat ");
|
|
case RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS:
|
|
return PSTR("Nexus");
|
|
case RGB_MATRIX_SOLID_REACTIVE_SIMPLE:
|
|
return PSTR("Ease ");
|
|
case RGB_MATRIX_SOLID_COLOR:
|
|
return PSTR("Solid");
|
|
case RGB_MATRIX_BREATHING:
|
|
return PSTR("Fade ");
|
|
case RGB_MATRIX_CYCLE_ALL:
|
|
return PSTR("Cycle");
|
|
case RGB_MATRIX_RAINBOW_PINWHEELS:
|
|
return PSTR("Wheel");
|
|
case RGB_MATRIX_CYCLE_LEFT_RIGHT:
|
|
return PSTR("Wave ");
|
|
default:
|
|
return PSTR("");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
extern led_config_t g_led_config;
|
|
|
|
void rgb_matrix_layer_helper(uint8_t hue, uint8_t sat, uint8_t val, uint8_t led_min, uint8_t led_max) {
|
|
HSV hsv = {hue, sat, val};
|
|
if (hsv.v > rgb_matrix_get_val()) {
|
|
hsv.v = rgb_matrix_get_val();
|
|
}
|
|
|
|
RGB rgb = hsv_to_rgb(hsv);
|
|
for (uint8_t i = 0; i < led_max; i++) {
|
|
if (HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) {
|
|
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
|
}
|
|
}
|
|
}
|
|
|
|
extern user_config_t user_config;
|
|
|
|
bool rgb_matrix_in_idle(void) {
|
|
return (user_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == user_config.rgb_matrix_idle_mode);
|
|
}
|
|
|
|
bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
|
|
if (user_config.rgb_layer_indicator && !rgb_matrix_in_idle()) {
|
|
switch (get_highest_layer(layer_state | default_layer_state)) {
|
|
case _GAMING_EXT:
|
|
rgb_matrix_layer_helper(HSV_PURPLE, led_min, led_max);
|
|
break;
|
|
case _SYM:
|
|
rgb_matrix_layer_helper(HSV_YELLOW, led_min, led_max);
|
|
break;
|
|
case _NAV:
|
|
rgb_matrix_layer_helper(HSV_SPRINGGREEN, led_min, led_max);
|
|
break;
|
|
case _UTIL:
|
|
rgb_matrix_layer_helper(HSV_PINK, led_min, led_max);
|
|
break;
|
|
case _NUMPAD:
|
|
rgb_matrix_layer_helper(HSV_CORAL, led_min, led_max);
|
|
break;
|
|
case _GAMING:
|
|
case _WASD:
|
|
rgb_matrix_layer_helper(HSV_RED, led_min, led_max);
|
|
break;
|
|
default:
|
|
rgb_matrix_layer_helper(THEME_HSV, led_min, led_max);
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void rgb_matrix_turn_off_underglow(void) {
|
|
rgb_matrix_layer_helper(0, 0, 0, 0, 54);
|
|
}
|
|
|
|
uint8_t rgb_matrix_speed_for_mode(uint8_t mode) {
|
|
switch (mode) {
|
|
case RGB_MATRIX_SOLID_REACTIVE_SIMPLE:
|
|
case RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS:
|
|
return RGB_MATRIX_ANIMATION_SPEED_FAST;
|
|
case RGB_MATRIX_BREATHING:
|
|
case RGB_MATRIX_CYCLE_LEFT_RIGHT:
|
|
case RGB_MATRIX_RAINBOW_PINWHEELS:
|
|
return RGB_MATRIX_ANIMATION_SPEED_SLOW;
|
|
case RGB_MATRIX_CYCLE_ALL:
|
|
return RGB_MATRIX_ANIMATION_SPEED_SLOWER;
|
|
default:
|
|
return RGB_MATRIX_ANIMATION_SPEED_MEDIUM;
|
|
}
|
|
}
|
|
|
|
bool rgb_matrix_mode_active(uint8_t mode) {
|
|
return (mode == RGB_MATRIX_SOLID_REACTIVE_SIMPLE || mode == RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS || mode == RGB_MATRIX_TYPING_HEATMAP);
|
|
}
|
|
|
|
void rgb_matrix_update_current_mode(uint8_t mode) {
|
|
rgb_matrix_config.speed = rgb_matrix_speed_for_mode(mode);
|
|
rgb_matrix_mode_noeeprom(mode);
|
|
}
|
|
|
|
void rgb_matrix_update_dynamic_mode(uint8_t mode) {
|
|
uint8_t speed;
|
|
speed = rgb_matrix_speed_for_mode(mode);
|
|
|
|
if (rgb_matrix_mode_active(mode)) {
|
|
user_config.rgb_matrix_active_speed = speed;
|
|
user_config.rgb_matrix_active_mode = mode;
|
|
} else {
|
|
user_config.rgb_matrix_idle_speed = speed;
|
|
user_config.rgb_matrix_idle_mode = mode;
|
|
}
|
|
}
|
|
|
|
void rgb_matrix_update_mode(uint8_t mode) {
|
|
if (user_config.rgb_matrix_idle_anim) {
|
|
rgb_matrix_update_dynamic_mode(mode);
|
|
}
|
|
if (rgb_matrix_mode_active(mode) || !user_config.rgb_matrix_idle_anim) {
|
|
rgb_matrix_update_current_mode(mode);
|
|
}
|
|
}
|
|
|
|
uint8_t get_rgb_matrix_active_mode(void) {
|
|
if (user_config.rgb_matrix_idle_anim) {
|
|
return user_config.rgb_matrix_active_mode;
|
|
} else {
|
|
return rgb_matrix_get_mode();
|
|
}
|
|
}
|
|
|
|
void rgb_matrix_toggle_active_mode(void) {
|
|
switch (get_rgb_matrix_active_mode()) {
|
|
case RGB_MATRIX_SOLID_REACTIVE_SIMPLE:
|
|
rgb_matrix_update_mode(RGB_MATRIX_TYPING_HEATMAP);
|
|
break;
|
|
case RGB_MATRIX_TYPING_HEATMAP:
|
|
rgb_matrix_update_mode(RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS);
|
|
break;
|
|
default:
|
|
rgb_matrix_update_mode(RGB_MATRIX_SOLID_REACTIVE_SIMPLE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
uint8_t get_rgb_matrix_idle_mode(void) {
|
|
if (user_config.rgb_matrix_idle_anim) {
|
|
return user_config.rgb_matrix_idle_mode;
|
|
} else {
|
|
return rgb_matrix_get_mode();
|
|
}
|
|
}
|
|
|
|
void rgb_matrix_toggle_simple_passive_mode(void) {
|
|
switch (get_rgb_matrix_idle_mode()) {
|
|
case RGB_MATRIX_SOLID_COLOR:
|
|
rgb_matrix_update_mode(RGB_MATRIX_BREATHING);
|
|
break;
|
|
case RGB_MATRIX_BREATHING:
|
|
rgb_matrix_update_mode(RGB_MATRIX_CYCLE_ALL);
|
|
break;
|
|
default:
|
|
rgb_matrix_update_mode(RGB_MATRIX_SOLID_COLOR);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void rgb_matrix_toggle_color_passive_mode(void) {
|
|
switch (get_rgb_matrix_idle_mode()) {
|
|
case RGB_MATRIX_RAINBOW_PINWHEELS:
|
|
rgb_matrix_update_mode(RGB_MATRIX_CYCLE_LEFT_RIGHT);
|
|
break;
|
|
default:
|
|
rgb_matrix_update_mode(RGB_MATRIX_RAINBOW_PINWHEELS);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void rgb_matrix_toggle_underglow_layer_indicator(void) {
|
|
user_config.rgb_layer_indicator ^= 1;
|
|
if (user_config.rgb_layer_indicator) {
|
|
layer_state_set(layer_state); // This is needed to immediately set the layer color (looks better)
|
|
} else {
|
|
rgb_matrix_turn_off_underglow();
|
|
}
|
|
}
|
|
|
|
void rgb_matrix_toggle_idle_animation_change(void) {
|
|
user_config.rgb_matrix_idle_anim ^= 1;
|
|
if (user_config.rgb_matrix_idle_anim) {
|
|
rgb_matrix_update_mode(user_config.rgb_matrix_active_mode);
|
|
} else {
|
|
rgb_matrix_update_current_mode(user_config.rgb_matrix_idle_mode);
|
|
}
|
|
}
|
|
|
|
void rgb_matrix_set_gaming_defaults(void) {
|
|
if (!user_config.rgb_layer_indicator) {
|
|
user_config.rgb_layer_indicator = true;
|
|
}
|
|
user_config.rgb_matrix_idle_timeout = GAMING_IDLE_TIMEOUT;
|
|
rgb_matrix_update_mode(RGB_MATRIX_RAINBOW_PINWHEELS);
|
|
rgb_matrix_update_mode(RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS);
|
|
}
|
|
|
|
void rgb_matrix_set_typing_defaults(void) {
|
|
user_config.rgb_matrix_idle_timeout = IDLE_TIMEOUT;
|
|
rgb_matrix_update_mode(RGB_MATRIX_TYPING_PASSIVE);
|
|
rgb_matrix_update_mode(RGB_MATRIX_TYPING_ACTIVE);
|
|
}
|
|
|
|
void rgb_matrix_set_defaults(void) {
|
|
rgb_matrix_enable_noeeprom();
|
|
rgb_matrix_sethsv_noeeprom(THEME_HSV);
|
|
|
|
user_config.rgb_layer_indicator = true;
|
|
user_config.rgb_matrix_idle_anim = true;
|
|
|
|
rgb_matrix_set_typing_defaults();
|
|
|
|
rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_REACTIVE_SIMPLE);
|
|
}
|
|
|
|
void matrix_scan_rgb(void) {
|
|
if (user_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == user_config.rgb_matrix_active_mode && last_input_activity_elapsed() > user_config.rgb_matrix_idle_timeout) {
|
|
if (user_config.rgb_layer_indicator) {
|
|
rgb_matrix_turn_off_underglow();
|
|
}
|
|
rgb_matrix_update_current_mode(user_config.rgb_matrix_idle_mode);
|
|
}
|
|
}
|
|
|
|
void user_transport_sync(void) {
|
|
// Keep track of the last state, so that we can tell if we need to propagate to slave
|
|
static uint32_t last_config = 0, last_sync = 0;
|
|
|
|
// Check if the state values are different
|
|
// or if sync timer elapsed
|
|
if (memcmp(&user_config, &last_config, sizeof(transport_user_config)) || (timer_elapsed32(last_sync) > 250)) {
|
|
memcpy(&last_config, &user_config, sizeof(transport_user_config));
|
|
|
|
if (transaction_rpc_send(USER_CONFIG_SYNC, sizeof(transport_user_config), &transport_user_config)) {
|
|
last_sync = timer_read32();
|
|
}
|
|
}
|
|
}
|
|
|
|
void user_transport_update(void) {
|
|
if (is_keyboard_master()) {
|
|
transport_user_config = user_config.raw;
|
|
user_transport_sync();
|
|
} else {
|
|
user_config.raw = transport_user_config;
|
|
}
|
|
}
|
|
|
|
void housekeeping_task_user(void) {
|
|
static bool has_ran_yet;
|
|
if (!has_ran_yet) {
|
|
has_ran_yet = true;
|
|
startup_user();
|
|
}
|
|
matrix_scan_rgb();
|
|
|
|
// Update config to slave
|
|
user_transport_update();
|
|
}
|
|
|
|
void eeconfig_init_user(void) {
|
|
user_config.raw = 0;
|
|
user_config.rgb_layer_indicator = true;
|
|
user_config.rgb_matrix_idle_anim = true;
|
|
|
|
rgb_matrix_enable();
|
|
rgb_matrix_sethsv(THEME_HSV);
|
|
rgb_matrix_mode(RGB_MATRIX_SOLID_REACTIVE_SIMPLE);
|
|
|
|
eeconfig_update_user(user_config.raw);
|
|
}
|
|
|
|
void keyboard_post_init_user(void) {
|
|
set_single_persistent_default_layer(_COLEMAKDH);
|
|
rgb_matrix_set_defaults();
|
|
|
|
// Register user config sync
|
|
transaction_register_rpc(USER_CONFIG_SYNC, user_config_sync);
|
|
}
|
|
|
|
bool process_record_user_rgb_matrix(uint16_t keycode, keyrecord_t* record) {
|
|
if (user_config.rgb_matrix_idle_anim) {
|
|
if (rgb_matrix_get_mode() == user_config.rgb_matrix_idle_mode) {
|
|
rgb_matrix_update_current_mode(user_config.rgb_matrix_active_mode);
|
|
if (!user_config.rgb_layer_indicator) {
|
|
rgb_matrix_turn_off_underglow();
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (keycode) {
|
|
case RGB_RST:
|
|
if (record->event.pressed) {
|
|
rgb_matrix_set_defaults();
|
|
}
|
|
break;
|
|
case RGB_UND: // Toggle separate underglow status
|
|
if (record->event.pressed) {
|
|
rgb_matrix_toggle_underglow_layer_indicator();
|
|
}
|
|
break;
|
|
case RGB_IDL: // Toggle idle/heatmap animation
|
|
if (record->event.pressed) {
|
|
rgb_matrix_toggle_idle_animation_change();
|
|
}
|
|
break;
|
|
case RGB_ATG:
|
|
if (record->event.pressed) {
|
|
rgb_matrix_toggle_active_mode();
|
|
}
|
|
break;
|
|
case RGB_PST:
|
|
if (record->event.pressed) {
|
|
rgb_matrix_toggle_simple_passive_mode();
|
|
}
|
|
break;
|
|
case RGB_PCT:
|
|
if (record->event.pressed) {
|
|
rgb_matrix_toggle_color_passive_mode();
|
|
}
|
|
break;
|
|
}
|
|
return true;
|
|
}
|