~ruther/qmk_firmware

1d784f0f9575b70e35c9c8338b0ff80dc7316d7e — Daniel Prilik 6 years ago e337bb8
RGB Matrix: Custom effects on a kb/user level (#5338)

* Revamped custom effects approach

See docs for example usage

* push-up RGB Matrix default mode

Override default effect using RGB_MATRIX_STARTUP_MODE.
Useful on boards without EEPROM support
(*cough* Massdrop ALT/CTRL *cough*)

* update docs
4 files changed, 107 insertions(+), 13 deletions(-)

M common_features.mk
M docs/feature_rgb_matrix.md
M quantum/rgb_matrix.c
M quantum/rgb_matrix.h
M common_features.mk => common_features.mk +8 -0
@@ 178,6 178,14 @@ ifeq ($(strip $(RGB_MATRIX_ENABLE)), WS2812)
    SRC += ws2812.c
endif

ifeq ($(strip $(RGB_MATRIX_CUSTOM_KB)), yes)
    OPT_DEFS += -DRGB_MATRIX_CUSTOM_KB
endif

ifeq ($(strip $(RGB_MATRIX_CUSTOM_USER)), yes)
    OPT_DEFS += -DRGB_MATRIX_CUSTOM_USER
endif

ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
    OPT_DEFS += -DTAP_DANCE_ENABLE
    SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c

M docs/feature_rgb_matrix.md => docs/feature_rgb_matrix.md +50 -7
@@ 177,7 177,7 @@ enum rgb_matrix_effects {
    RGB_MATRIX_GRADIENT_UP_DOWN,    // Static gradient top to bottom, speed controls how much gradient changes
    RGB_MATRIX_BREATHING,           // Single hue brightness cycling animation
    RGB_MATRIX_CYCLE_ALL,           // Full keyboard solid hue cycling through full gradient
    RGB_MATRIX_CYCLE_LEFT_RIGHT,    // Full gradient scrolling left to right 
    RGB_MATRIX_CYCLE_LEFT_RIGHT,    // Full gradient scrolling left to right
    RGB_MATRIX_CYCLE_UP_DOWN,       // Full gradient scrolling top to bottom
    RGB_MATRIX_RAINBOW_MOVING_CHEVRON,  // Full gradent Chevron shapped scrolling left to right
    RGB_MATRIX_DUAL_BEACON,         // Full gradient spinning around center of keyboard


@@ 203,7 203,7 @@ enum rgb_matrix_effects {
    RGB_MATRIX_EFFECT_MAX
};
```
    

You can disable a single effect by defining `DISABLE_[EFFECT_NAME]` in your `config.h`:




@@ 236,17 236,60 @@ You can disable a single effect by defining `DISABLE_[EFFECT_NAME]` in your `con
|`#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH`         |Disables `RGB_MATRIX_SOLID_MULTISPLASH`        |


## Custom layer effects
## Custom RGB Matrix Effects

By setting `RGB_MATRIX_CUSTOM_USER` (and/or `RGB_MATRIX_CUSTOM_KB`) in `rule.mk`, new effects can be defined directly from userspace, without having to edit any QMK core files.

To declare new effects, create a new `rgb_matrix_user/kb.inc` that looks something like this:

Custom layer effects can be done by defining this in your `<keyboard>.c`:
`rgb_matrix_user.inc` should go in the root of the keymap directory.
`rgb_matrix_kb.inc` should go in the root of the keyboard directory.

```C
void rgb_matrix_indicators_kb(void) {
    rgb_matrix_set_color(index, red, green, blue);
// !!! DO NOT ADD #pragma once !!! //

// Step 1.
// Declare custom effects using the RGB_MATRIX_EFFECT macro
// (note the lack of semicolon after the macro!)
RGB_MATRIX_EFFECT(my_cool_effect)
RGB_MATRIX_EFFECT(my_cool_effect2)

// Step 2.
// Define effects inside the `RGB_MATRIX_CUSTOM_EFFECT_IMPLS` ifdef block
#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS

// e.g: A simple effect, self-contained within a single method
static bool my_cool_effect(effect_params_t* params) {
  RGB_MATRIX_USE_LIMITS(led_min, led_max);
  for (uint8_t i = led_min; i < led_max; i++) {
    rgb_matrix_set_color(i, 0xff, 0xff, 0x00);
  }
  return led_max < DRIVER_LED_TOTAL;
}

// e.g: A more complex effect, relying on external methods and state, with
// dedicated init and run methods
static uint8_t some_global_state;
static void my_cool_effect2_complex_init(effect_params_t* params) {
  some_global_state = 1;
}
static bool my_cool_effect2_complex_run(effect_params_t* params) {
  RGB_MATRIX_USE_LIMITS(led_min, led_max);
  for (uint8_t i = led_min; i < led_max; i++) {
    rgb_matrix_set_color(i, 0xff, some_global_state++, 0xff);
  }

  return led_max < DRIVER_LED_TOTAL;
}
static bool my_cool_effect2(effect_params_t* params) {
  if (params->init) my_cool_effect2_complex_init(params);
  return my_cool_effect2_complex_run(params);
}

#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
```

A similar function works in the keymap as `rgb_matrix_indicators_user`.
For inspiration and examples, check out the built-in effects under `quantum/rgb_matrix_animation/`


## Colors

M quantum/rgb_matrix.c => quantum/rgb_matrix.c +37 -6
@@ 48,6 48,19 @@
#include "rgb_matrix_animations/solid_splash_anim.h"
#include "rgb_matrix_animations/breathing_anim.h"

#if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER)
  #define RGB_MATRIX_CUSTOM_EFFECT_IMPLS
    #define RGB_MATRIX_EFFECT(name, ...)
    #ifdef RGB_MATRIX_CUSTOM_KB
      #include "rgb_matrix_kb.inc"
    #endif
    #ifdef RGB_MATRIX_CUSTOM_USER
      #include "rgb_matrix_user.inc"
    #endif
    #undef RGB_MATRIX_EFFECT
  #undef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
#endif

#ifndef RGB_DISABLE_AFTER_TIMEOUT
  #define RGB_DISABLE_AFTER_TIMEOUT 0
#endif


@@ 81,6 94,15 @@
  #define RGB_MATRIX_SPD_STEP 16
#endif

#if !defined(RGB_MATRIX_STARTUP_MODE)
  #ifndef DISABLE_RGB_MATRIX_CYCLE_ALL
    #define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT
  #else
    // fallback to solid colors if RGB_MATRIX_CYCLE_LEFT_RIGHT is disabled in userspace
    #define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_SOLID_COLOR
  #endif
#endif

bool g_suspend_state = false;

rgb_config_t rgb_matrix_config;


@@ 104,12 126,7 @@ void eeconfig_update_rgb_matrix(uint32_t val) {
void eeconfig_update_rgb_matrix_default(void) {
  dprintf("eeconfig_update_rgb_matrix_default\n");
  rgb_matrix_config.enable = 1;
#ifndef DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
  rgb_matrix_config.mode = RGB_MATRIX_CYCLE_LEFT_RIGHT;
#else
  // fallback to solid colors if RGB_MATRIX_CYCLE_LEFT_RIGHT is disabled in userspace
  rgb_matrix_config.mode = RGB_MATRIX_SOLID_COLOR;
#endif
  rgb_matrix_config.mode = RGB_MATRIX_STARTUP_MODE;
  rgb_matrix_config.hue = 0;
  rgb_matrix_config.sat = UINT8_MAX;
  rgb_matrix_config.val = RGB_MATRIX_MAXIMUM_BRIGHTNESS;


@@ 435,6 452,20 @@ static void rgb_task_render(uint8_t effect) {
#endif // DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED

#if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER)
  #define RGB_MATRIX_EFFECT(name, ...) \
    case RGB_MATRIX_CUSTOM_##name: \
      rendering = name(&rgb_effect_params); \
      break;
  #ifdef RGB_MATRIX_CUSTOM_KB
    #include "rgb_matrix_kb.inc"
  #endif
  #ifdef RGB_MATRIX_CUSTOM_USER
    #include "rgb_matrix_user.inc"
  #endif
  #undef RGB_MATRIX_EFFECT
#endif

    // Factory default magic value
    case UINT8_MAX: {
        rgb_matrix_test();

M quantum/rgb_matrix.h => quantum/rgb_matrix.h +12 -0
@@ 142,6 142,18 @@ enum rgb_matrix_effects {
  RGB_MATRIX_SOLID_MULTISPLASH,
#endif // DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED

#if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER)
  #define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_CUSTOM_##name,
  #ifdef RGB_MATRIX_CUSTOM_KB
    #include "rgb_matrix_kb.inc"
  #endif
  #ifdef RGB_MATRIX_CUSTOM_USER
    #include "rgb_matrix_user.inc"
  #endif
  #undef RGB_MATRIX_EFFECT
#endif

  RGB_MATRIX_EFFECT_MAX
};