Skip to content

Commit

Permalink
RGB matrix updates and refactor
Browse files Browse the repository at this point in the history
* Update RGB matrix defaults
* Refactor user indicator function
* Decouple prng function from effect
* Use updated rgb_t and hsv_t structs
* Use LED limits for Candy Rain
* Add Candy Pulse RGB matrix effect
* Add Pixel Mosaic RGB matrix effect
  • Loading branch information
filterpaper committed Jan 26, 2025
1 parent 96053e9 commit d85cfcb
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 75 deletions.
8 changes: 5 additions & 3 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@

#ifdef RGB_MATRIX_ENABLE
# define RGB_MATRIX_KEYPRESSES
# define ENABLE_RGB_MATRIX_CANDY_TAP
# define ENABLE_RGB_MATRIX_CANDY_RAIN
# define RGB_MATRIX_DEFAULT_SPD 96
# define RGB_MATRIX_DEFAULT_HUE 180
# define ENABLE_RGB_MATRIX_CUSTOM_CANDY_TAP
# define ENABLE_RGB_MATRIX_CUSTOM_CANDY_RAIN
# define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_CUSTOM_CANDY_TAP
# define DEF_MODE RGB_MATRIX_DEFAULT_MODE
# define DEF_MODE RGB_MATRIX_CUSTOM_CANDY_TAP
# define CMK_MODE RGB_MATRIX_CUSTOM_CANDY_RAIN
#endif

Expand Down
50 changes: 24 additions & 26 deletions features/rgb_matrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
#include QMK_KEYBOARD_H
#include <lib/lib8tion/lib8tion.h>

#define RGB_DPINK 115, 20, 45
#define RGB_DTEAL 5, 35, 35
#define RGB_FLUOR 75, 122, 22
#define RGB_CAPS RGB_DPINK
#define HSV_SWAP HSV_TEAL
#define RGB_DTEAL 5, 35, 35
#define RGB_FLUOR 75, 122, 22
#define HSV_SWAP HSV_TEAL
#define HSV_CAPS HSV_PINK

#ifdef CONVERT_TO_KB2040
// Map keys to KB2040 LEDs on each side
Expand All @@ -18,7 +17,7 @@ led_config_t g_led_config = { {
{ 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1 }
}, {
{109, 48}, {115, 48}
{0, 48}, {224, 48}
}, {
0x0f, 0xf0 // Flags for masking mod bits
} };
Expand All @@ -31,39 +30,38 @@ layer_state_t layer_state_set_user(layer_state_t const state) {
}


static RGB hsv_to_rgb_glow(HSV hsv) {
static rgb_t hsv_to_rgb_glow(hsv_t hsv) {
// Return glowing RGB values
hsv.v = scale8(abs8(sin8(scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8)) - 128) * 2, hsv.v);
hsv.v = scale8(abs8(sin8(scale16by8(g_rgb_timer, rgb_matrix_config.speed / 4)) - 128) * 2, hsv.v);
return hsv_to_rgb(hsv);
}


bool rgb_matrix_indicators_user(void) {
if (host_keyboard_led_state().caps_lock) {
rgb_matrix_set_color_all(RGB_CAPS);
bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
rgb_t rgb = {};

if (get_highest_layer(layer_state) > CMK) {
rgb = hsv_to_rgb((hsv_t){(get_highest_layer(layer_state) - 1) * 85, 255, rgb_matrix_config.hsv.v});
}

#ifdef SWAP_HANDS_ENABLE
if (is_swap_hands_on()) {
RGB const rgb = hsv_to_rgb_glow((HSV){HSV_SWAP});
rgb_matrix_set_color_all(rgb.r, rgb.g, rgb.b);
#ifdef CONVERT_TO_KB2040
else if (get_mods() & g_led_config.flags[led_min]) {
rgb = hsv_to_rgb((hsv_t){(get_mods() >> 4 | get_mods()) * 16, 255, rgb_matrix_config.hsv.v});
}
#endif

#ifdef CONVERT_TO_KB2040
if (get_mods()) {
uint8_t const mods = get_mods();
RGB const rgb = hsv_to_rgb((HSV){(mods >> 4 | mods) * 16, 255, rgb_matrix_config.hsv.v});
for (uint8_t i = 0; i < RGB_MATRIX_LED_COUNT; ++i) {
if (g_led_config.flags[i] & mods) rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
#ifdef SWAP_HANDS_ENABLE
else if (is_swap_hands_on()) {
rgb = hsv_to_rgb_glow((hsv_t){HSV_SWAP});
}
#endif

if (get_highest_layer(layer_state) > CMK) {
uint8_t const layer = get_highest_layer(layer_state);
RGB const rgb = hsv_to_rgb((HSV){(layer - 1) * 80, 255, rgb_matrix_config.hsv.v});
rgb_matrix_set_color_all(rgb.r, rgb.g, rgb.b);
else if (host_keyboard_led_state().caps_lock) {
rgb = hsv_to_rgb_glow((hsv_t){HSV_CAPS});
}

if (rgb.r || rgb.g || rgb.b) {
for (uint8_t i = led_min; i < led_max; ++i) rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}

return false;
Expand Down
149 changes: 103 additions & 46 deletions features/rgb_matrix_user.inc
Original file line number Diff line number Diff line change
@@ -1,95 +1,152 @@
// Copyright @filterpaper
// SPDX-License-Identifier: GPL-2.0+

/*
https://www.pcg-random.org/posts/bob-jenkins-small-prng-passes-practrand.html
#define rot(x,k) (((x)<<(k))|((x)>>(8-(k))))
uint8_t jsf8(void) { // Bob Jenkin's fast prng
static uint8_t a = 161, b = 62, c = 21, d = 97, t;

#if (defined(ENABLE_RGB_MATRIX_CUSTOM_CANDY_RAIN) || defined(ENABLE_RGB_MATRIX_CUSTOM_CANDY_PULSE)) && defined(RGB_MATRIX_CUSTOM_EFFECT_IMPLS)
// Adapted 8-bit version of Bob Jenkin's small PRNG
// https://www.pcg-random.org/posts/bob-jenkins-small-prng-passes-practrand.html

# define prng_max(x) ((uint16_t)(prng() * (uint16_t)(x)) >> 8)
# define prng_min_max(x, y) (prng_max((y) - (x)) + (x))
# define rot(x, k) (((x) << (k)) | ((x) >> (8 - (k))))
static uint8_t a = 7, b, c, d, t;

static uint8_t prng(void) {
t = a - rot(b, 1);
a = b ^ rot(c, 4);
b = c + d;
c = d + t;
d = t + a;
return d;
}
uint8_t jsf8_max(uint8_t max) {
return ((uint16_t)jsf8() * (uint16_t)max) >> 8;
}
uint8_t jsf8_min_max(uint8_t min, uint8_t max) {
return jsf8_max(max - min) + min;

static void prng_init(const uint8_t seed) {
a = 83, b = c = d = seed;
for (uint8_t i = 0; i < 32; ++i) (void)prng();
}
*/

#endif


#ifdef ENABLE_RGB_MATRIX_CANDY_TAP
#ifdef ENABLE_RGB_MATRIX_CUSTOM_CANDY_TAP
RGB_MATRIX_EFFECT(CANDY_TAP)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS

static bool CANDY_TAP(effect_params_t* params) {
HSV CANDY_TAP_math(HSV hsv, uint16_t offset) {
hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 8) >> 4);
hsv_t CANDY_TAP_math(hsv_t hsv, uint16_t offset) {
hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed / 16, 1));
hsv.v = scale8(255 - offset, hsv.v);
return hsv;
}
return effect_runner_reactive(params, &CANDY_TAP_math);
}

# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
#endif // ENABLE_RGB_MATRIX_CANDY_TAP
#endif // ENABLE_RGB_MATRIX_CUSTOM_CANDY_TAP


#ifdef ENABLE_RGB_MATRIX_CANDY_SPLASH
#ifdef ENABLE_RGB_MATRIX_CUSTOM_CANDY_SPLASH
RGB_MATRIX_EFFECT(CANDY_SPLASH)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS

static bool CANDY_SPLASH(effect_params_t* params) {
HSV CANDY_WIDE_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
hsv_t CANDY_SPLASH_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
uint16_t effect = tick + dist * 5;
if (effect > 255) effect = 255;
hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 8) >> 4);
hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed / 16, 1));
hsv.v = qadd8(hsv.v, 255 - effect);
return hsv;
}
return effect_runner_reactive_splash(0, params, &CANDY_WIDE_math);
return effect_runner_reactive_splash(0, params, &CANDY_SPLASH_math);
}

# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
#endif // ENABLE_RGB_MATRIX_CANDY_SPLASH
#endif // ENABLE_RGB_MATRIX_CUSTOM_CANDY_SPLASH


#ifdef ENABLE_RGB_MATRIX_CANDY_RAIN
#ifdef ENABLE_RGB_MATRIX_CUSTOM_CANDY_RAIN
RGB_MATRIX_EFFECT(CANDY_RAIN)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS

static uint8_t a, b, c, d, t;
static uint8_t prng(void) {
# define rot(x,k) (((x) << (k)) | ((x) >> (8 - (k))))
t = a - rot(b, 1); a = b ^ rot(c, 4);
b = c + d; c = d + t; d = t + a;
return d;
}
static void prng_seed(const uint8_t seed) {
a = 161, b = c = d = seed;
for (uint8_t i = 0; i < 32; ++i) (void)prng();
static bool CANDY_RAIN(effect_params_t* params) {
static uint16_t index = RGB_MATRIX_LED_COUNT + 1;
static uint32_t timer = 0;

if (params->iter == 0) {
if (params->init) prng_init(g_rgb_timer);
else if (g_rgb_timer > timer) {
index = prng_max(RGB_MATRIX_LED_COUNT);
timer = g_rgb_timer + (1280 - scale16by8(1024, rgb_matrix_config.speed));
}
}

RGB_MATRIX_USE_LIMITS(led_min, led_max);
if (led_min <= index && index < led_max && HAS_ANY_FLAGS(g_led_config.flags[index], params->flags)) {
hsv_t hsv = prng_max(2) ? (hsv_t){} : (hsv_t){prng(), prng_min_max(127, 255), rgb_matrix_config.hsv.v};
rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(index, rgb.r, rgb.g, rgb.b);
index = RGB_MATRIX_LED_COUNT + 1;
}
return rgb_matrix_check_finished_leds(led_max);
}
#define prng_max(x) ((prng() * (x)) >> 8)
#define prng_min_max(x,y) (prng_max((y) - (x)) + (x))

static bool CANDY_RAIN(effect_params_t* params) {
static uint32_t wait_timer = 0;

void rain_candy(uint8_t led_index) {
if (!HAS_ANY_FLAGS(g_led_config.flags[led_index], params->flags)) return;
HSV hsv = prng() & 2 ? (HSV){0, 0, 0} : (HSV){prng(), prng_min_max(127, 255), rgb_matrix_config.hsv.v};
RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(led_index, rgb.r, rgb.g, rgb.b);
wait_timer = g_rgb_timer + (320 - rgb_matrix_config.speed);
# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
#endif // ENABLE_RGB_MATRIX_CUSTOM_CANDY_RAIN


#ifdef ENABLE_RGB_MATRIX_CUSTOM_CANDY_PULSE
RGB_MATRIX_EFFECT(CANDY_PULSE)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS

bool CANDY_PULSE(effect_params_t* params) {
static uint16_t offset[RGB_MATRIX_LED_COUNT];

hsv_t CANDY_PULSE_maths(hsv_t hsv, uint8_t i, uint8_t time) {
hsv.h = scale16by8(offset[i] + (g_rgb_timer / 2), qadd8(rgb_matrix_config.speed / 16, 1));
hsv.v = scale8(abs8(sin8(hsv.h) - 128) * 2, hsv.v);
return hsv;
}

if ((params->iter == 0) && params->init) {
prng_init(g_rgb_timer);
for (uint8_t i = 0; i < RGB_MATRIX_LED_COUNT; ++i) offset[i] = prng() << 8 | prng();
}

if (params->init) prng_seed(timer_read());
return effect_runner_i(params, &CANDY_PULSE_maths);
}

# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
#endif // ENABLE_RGB_MATRIX_CUSTOM_CANDY_PULSE


#ifdef ENABLE_RGB_MATRIX_CUSTOM_PIXEL_MOSAIC
RGB_MATRIX_EFFECT(PIXEL_MOSAIC)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS

static bool PIXEL_MOSAIC(effect_params_t* params) {
static bool run_effect = false;
static uint32_t run_timer = 0;

if (params->iter == 0) {
if (params->init) random16_set_seed(g_rgb_timer);
else if (g_rgb_timer > run_timer) {
run_effect = true;
timer = g_rgb_timer + (1280 - scale16by8(1024, rgb_matrix_config.speed));
}
}

RGB_MATRIX_USE_LIMITS(led_min, led_max);
if (g_rgb_timer > wait_timer) {
rain_candy(prng_max(RGB_MATRIX_LED_COUNT));
if (run_effect) {
for (uint8_t i = led_min; i < led_max; ++i) {
hsv_t hsv = (hsv_t){random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v};
rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
run_effect = rgb_matrix_check_finished_leds(led_max);
}

return rgb_matrix_check_finished_leds(led_max);
}

# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
#endif // ENABLE_RGB_MATRIX_CANDY_RAIN
#endif // ENABLE_RGB_MATRIX_CUSTOM_PIXEL_MOSAIC

0 comments on commit d85cfcb

Please sign in to comment.