~ruther/qmk_firmware

bb52119a6dfe9c6f0314d1bcd948efda59626a70 — M-AS 6 years ago b61baf4
RGB Matrix Animations: Three/six new reactive effects (wide, cross, nexus) (#5602)

* added 3 new RGB_Matrix effects

* made cross effect behavior smoother

* removed dead code

* added effect descriptions
M docs/feature_rgb_matrix.md => docs/feature_rgb_matrix.md +33 -21
@@ 189,6 189,12 @@ enum rgb_matrix_effects {
#if defined(RGB_MATRIX_KEYPRESSES) || defined(RGB_MATRIX_KEYRELEASES)
    RGB_MATRIX_SOLID_REACTIVE_SIMPLE,   // Pulses keys hit to hue & value then fades value out
    RGB_MATRIX_SOLID_REACTIVE,      // Static single hue, pulses keys hit to shifted hue then fades to current hue
    RGB_MATRIX_SOLID_REACTIVE_WIDE       // Hue & value pulse near a single key hit then fades value out
    RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE  // Hue & value pulse near multiple key hits then fades value out
    RGB_MATRIX_SOLID_REACTIVE_CROSS      // Hue & value pulse the same column and row of a single key hit then fades value out
    RGB_MATRIX_SOLID_REACTIVE_MULTICROSS // Hue & value pulse the same column and row of multiple key hits then fades value out
    RGB_MATRIX_SOLID_REACTIVE_NEXUS      // Hue & value pulse away on the same column and row of a single key hit then fades value out
    RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS // Hue & value pulse away on the same column and row of multiple key hits then fades value out
    RGB_MATRIX_SPLASH,              // Full gradient & value pulse away from a single key hit then fades value out
    RGB_MATRIX_MULTISPLASH,         // Full gradient & value pulse away from multiple key hits then fades value out
    RGB_MATRIX_SOLID_SPLASH,        // Hue & value pulse away from a single key hit then fades value out


@@ 201,27 207,33 @@ enum rgb_matrix_effects {
You can disable a single effect by defining `DISABLE_[EFFECT_NAME]` in your `config.h`:


|Define                                             |Description                                 |
|---------------------------------------------------|--------------------------------------------|
|`#define DISABLE_RGB_MATRIX_ALPHAS_MODS`           |Disables `RGB_MATRIX_ALPHAS_MODS`           |
|`#define DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN`      |Disables `RGB_MATRIX_GRADIENT_UP_DOWN`      |
|`#define DISABLE_RGB_MATRIX_BREATHING`             |Disables `RGB_MATRIX_BREATHING`             |
|`#define DISABLE_RGB_MATRIX_CYCLE_ALL`             |Disables `RGB_MATRIX_CYCLE_ALL`             |
|`#define DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT`      |Disables `RGB_MATRIX_CYCLE_LEFT_RIGHT`      |
|`#define DISABLE_RGB_MATRIX_CYCLE_UP_DOWN`         |Disables `RGB_MATRIX_CYCLE_UP_DOWN`         |
|`#define DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON`|Disables `RGB_MATRIX_RAINBOW_MOVING_CHEVRON`|
|`#define DISABLE_RGB_MATRIX_DUAL_BEACON`           |Disables `RGB_MATRIX_DUAL_BEACON`           |
|`#define DISABLE_RGB_MATRIX_RAINBOW_BEACON`        |Disables `RGB_MATRIX_RAINBOW_BEACON`        |
|`#define DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS`     |Disables `RGB_MATRIX_RAINBOW_PINWHEELS`     |
|`#define DISABLE_RGB_MATRIX_RAINDROPS`             |Disables `RGB_MATRIX_RAINDROPS`             |
|`#define DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS`   |Disables `RGB_MATRIX_JELLYBEAN_RAINDROPS`   |
|`#define DISABLE_RGB_MATRIX_DIGITAL_RAIN`          |Disables `RGB_MATRIX_DIGITAL_RAIN`          |
|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE`        |Disables `RGB_MATRIX_SOLID_REACTIVE`        |
|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE` |Disables `RGB_MATRIX_SOLID_REACTIVE_SIMPLEE`|
|`#define DISABLE_RGB_MATRIX_SPLASH`                |Disables `RGB_MATRIX_SPLASH`                |
|`#define DISABLE_RGB_MATRIX_MULTISPLASH`           |Disables `RGB_MATRIX_MULTISPLASH`           |
|`#define DISABLE_RGB_MATRIX_SOLID_SPLASH`          |Disables `RGB_MATRIX_SOLID_SPLASH`          |
|`#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH`     |Disables `RGB_MATRIX_SOLID_MULTISPLASH`     |
|Define                                                 |Description                                    |
|-------------------------------------------------------|-----------------------------------------------|
|`#define DISABLE_RGB_MATRIX_ALPHAS_MODS`               |Disables `RGB_MATRIX_ALPHAS_MODS`              |
|`#define DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN`          |Disables `RGB_MATRIX_GRADIENT_UP_DOWN`         |
|`#define DISABLE_RGB_MATRIX_BREATHING`                 |Disables `RGB_MATRIX_BREATHING`                |
|`#define DISABLE_RGB_MATRIX_CYCLE_ALL`                 |Disables `RGB_MATRIX_CYCLE_ALL`                |
|`#define DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT`          |Disables `RGB_MATRIX_CYCLE_LEFT_RIGHT`         |
|`#define DISABLE_RGB_MATRIX_CYCLE_UP_DOWN`             |Disables `RGB_MATRIX_CYCLE_UP_DOWN`            |
|`#define DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON`    |Disables `RGB_MATRIX_RAINBOW_MOVING_CHEVRON`   |
|`#define DISABLE_RGB_MATRIX_DUAL_BEACON`               |Disables `RGB_MATRIX_DUAL_BEACON`              |
|`#define DISABLE_RGB_MATRIX_RAINBOW_BEACON`            |Disables `RGB_MATRIX_RAINBOW_BEACON`           |
|`#define DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS`         |Disables `RGB_MATRIX_RAINBOW_PINWHEELS`        |
|`#define DISABLE_RGB_MATRIX_RAINDROPS`                 |Disables `RGB_MATRIX_RAINDROPS`                |
|`#define DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS`       |Disables `RGB_MATRIX_JELLYBEAN_RAINDROPS`      |
|`#define DISABLE_RGB_MATRIX_DIGITAL_RAIN`              |Disables `RGB_MATRIX_DIGITAL_RAIN`             |
|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE`            |Disables `RGB_MATRIX_SOLID_REACTIVE`           |
|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE`     |Disables `RGB_MATRIX_SOLID_REACTIVE_SIMPLE`    |
|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE`       |Disables `RGB_MATRIX_SOLID_REACTIVE_WIDE`      |
|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE`  |Disables `RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE` |
|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS`      |Disables `RGB_MATRIX_SOLID_REACTIVE_CROSS`     |
|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS` |Disables `RGB_MATRIX_SOLID_REACTIVE_MULTICROSS`|
|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS`      |Disables `RGB_MATRIX_SOLID_REACTIVE_NEXUS`     |
|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS` |Disables `RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS`|
|`#define DISABLE_RGB_MATRIX_SPLASH`                    |Disables `RGB_MATRIX_SPLASH`                   |
|`#define DISABLE_RGB_MATRIX_MULTISPLASH`               |Disables `RGB_MATRIX_MULTISPLASH`              |
|`#define DISABLE_RGB_MATRIX_SOLID_SPLASH`              |Disables `RGB_MATRIX_SOLID_SPLASH`             |
|`#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH`         |Disables `RGB_MATRIX_SOLID_MULTISPLASH`        |


## Custom layer effects

M quantum/rgb_matrix.c => quantum/rgb_matrix.c +33 -0
@@ 41,6 41,9 @@
#include "rgb_matrix_animations/digital_rain_anim.h"
#include "rgb_matrix_animations/solid_reactive_simple_anim.h"
#include "rgb_matrix_animations/solid_reactive_anim.h"
#include "rgb_matrix_animations/solid_reactive_wide.h"
#include "rgb_matrix_animations/solid_reactive_cross.h"
#include "rgb_matrix_animations/solid_reactive_nexus.h"
#include "rgb_matrix_animations/splash_anim.h"
#include "rgb_matrix_animations/solid_splash_anim.h"
#include "rgb_matrix_animations/breathing_anim.h"


@@ 380,6 383,36 @@ static void rgb_task_render(uint8_t effect) {
      rendering = rgb_matrix_solid_reactive(&rgb_effect_params);       // Max 4ms Avg 3ms
      break;
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
    case RGB_MATRIX_SOLID_REACTIVE_WIDE:
      rendering = rgb_matrix_solid_reactive_wide(&rgb_effect_params);       // Max ?? ms Avg ?? ms
      break;
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
    case RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE:
      rendering = rgb_matrix_solid_reactive_multiwide(&rgb_effect_params);       // Max ?? ms Avg ?? ms
      break;
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
    case RGB_MATRIX_SOLID_REACTIVE_CROSS:
      rendering = rgb_matrix_solid_reactive_cross(&rgb_effect_params);       // Max ?? ms Avg ?? ms
      break;
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
    case RGB_MATRIX_SOLID_REACTIVE_MULTICROSS:
      rendering = rgb_matrix_solid_reactive_multicross(&rgb_effect_params);       // Max ?? ms Avg ?? ms
      break;
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
    case RGB_MATRIX_SOLID_REACTIVE_NEXUS:
      rendering = rgb_matrix_solid_reactive_nexus(&rgb_effect_params);       // Max ?? ms Avg ?? ms
      break;
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
    case RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS:
      rendering = rgb_matrix_solid_reactive_multinexus(&rgb_effect_params);       // Max ?? ms Avg ?? ms
      break;
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
#ifndef DISABLE_RGB_MATRIX_SPLASH
    case RGB_MATRIX_SPLASH:
      rendering = rgb_matrix_splash(&rgb_effect_params);               // Max 5ms Avg 3ms

M quantum/rgb_matrix.h => quantum/rgb_matrix.h +18 -0
@@ 111,6 111,24 @@ enum rgb_matrix_effects {
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE
  RGB_MATRIX_SOLID_REACTIVE,
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
  RGB_MATRIX_SOLID_REACTIVE_WIDE,
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
  RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE,
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
  RGB_MATRIX_SOLID_REACTIVE_CROSS,
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
  RGB_MATRIX_SOLID_REACTIVE_MULTICROSS,
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
  RGB_MATRIX_SOLID_REACTIVE_NEXUS,
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
  RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS,
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
#ifndef DISABLE_RGB_MATRIX_SPLASH
  RGB_MATRIX_SPLASH,
#endif // DISABLE_RGB_MATRIX_SPLASH

A quantum/rgb_matrix_animations/solid_reactive_cross.h => quantum/rgb_matrix_animations/solid_reactive_cross.h +50 -0
@@ 0,0 1,50 @@
#pragma once
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#if !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS)

extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
extern last_hit_t g_last_hit_tracker;

static bool rgb_matrix_solid_reactive_multicross_range(uint8_t start, effect_params_t* params) {
  RGB_MATRIX_USE_LIMITS(led_min, led_max);

  HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, 0 };
  uint8_t count = g_last_hit_tracker.count;
  for (uint8_t i = led_min; i < led_max; i++) {
    hsv.v = 0;
    point_t point = g_rgb_leds[i].point;
    for (uint8_t j = start; j < count; j++) {
      int16_t dx = point.x - g_last_hit_tracker.x[j];
      int16_t dy = point.y - g_last_hit_tracker.y[j];
      uint8_t dist = sqrt16(dx * dx + dy * dy);
      int16_t dist2 = 16;
      uint8_t dist3;
      uint16_t effect = scale16by8(g_last_hit_tracker.tick[j], rgb_matrix_config.speed) + dist;
      dx = dx < 0 ? dx * -1 : dx;
      dy = dy < 0 ? dy * -1 : dy;
      dx = dx * dist2 > 255 ? 255 : dx * dist2;
      dy = dy * dist2 > 255 ? 255 : dy * dist2;
      dist3 = dx > dy ? dy : dx;
      effect += dist3;
      if (effect > 255)
        effect = 255;
      hsv.v = qadd8(hsv.v, 255 - effect);
    }
    hsv.v = scale8(hsv.v, rgb_matrix_config.val);
    RGB rgb = hsv_to_rgb(hsv);
    rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
  }
  return led_max < DRIVER_LED_TOTAL;
}

bool rgb_matrix_solid_reactive_multicross(effect_params_t* params) {
  return rgb_matrix_solid_reactive_multicross_range(0, params);
}

bool rgb_matrix_solid_reactive_cross(effect_params_t* params) {
  return rgb_matrix_solid_reactive_multicross_range(qsub8(g_last_hit_tracker.count, 1), params);
}

#endif // !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS)
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED

A quantum/rgb_matrix_animations/solid_reactive_nexus.h => quantum/rgb_matrix_animations/solid_reactive_nexus.h +48 -0
@@ 0,0 1,48 @@
#pragma once
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#if !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS)

extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
extern last_hit_t g_last_hit_tracker;

static bool rgb_matrix_solid_reactive_multinexus_range(uint8_t start, effect_params_t* params) {
  RGB_MATRIX_USE_LIMITS(led_min, led_max);

  HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, 0 };
  uint8_t count = g_last_hit_tracker.count;
  for (uint8_t i = led_min; i < led_max; i++) {
    hsv.v = 0;
    point_t point = g_rgb_leds[i].point;
    for (uint8_t j = start; j < count; j++) {
      int16_t dx = point.x - g_last_hit_tracker.x[j];
      int16_t dy = point.y - g_last_hit_tracker.y[j];
      uint8_t dist = sqrt16(dx * dx + dy * dy);
      int16_t dist2 = 8;
      uint16_t effect = scale16by8(g_last_hit_tracker.tick[j], rgb_matrix_config.speed) - dist;
      if (effect > 255)
        effect = 255;
      if (dist > 72)
        effect = 255;
      if ((dx > dist2 || dx < -dist2) && (dy > dist2 || dy < -dist2))
        effect = 255;
      hsv.v = qadd8(hsv.v, 255 - effect);
      hsv.h = rgb_matrix_config.hue + dy / 4;
    }
    hsv.v = scale8(hsv.v, rgb_matrix_config.val);
    RGB rgb = hsv_to_rgb(hsv);
    rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
  }
  return led_max < DRIVER_LED_TOTAL;
}

bool rgb_matrix_solid_reactive_multinexus(effect_params_t* params) {
  return rgb_matrix_solid_reactive_multinexus_range(0, params);
}

bool rgb_matrix_solid_reactive_nexus(effect_params_t* params) {
  return rgb_matrix_solid_reactive_multinexus_range(qsub8(g_last_hit_tracker.count, 1), params);
}

#endif // !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS)
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED

A quantum/rgb_matrix_animations/solid_reactive_wide.h => quantum/rgb_matrix_animations/solid_reactive_wide.h +42 -0
@@ 0,0 1,42 @@
#pragma once
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#if !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE)

extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
extern last_hit_t g_last_hit_tracker;

static bool rgb_matrix_solid_reactive_multiwide_range(uint8_t start, effect_params_t* params) {
  RGB_MATRIX_USE_LIMITS(led_min, led_max);

  HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, 0 };
  uint8_t count = g_last_hit_tracker.count;
  for (uint8_t i = led_min; i < led_max; i++) {
    hsv.v = 0;
    point_t point = g_rgb_leds[i].point;
    for (uint8_t j = start; j < count; j++) {
      int16_t dx = point.x - g_last_hit_tracker.x[j];
      int16_t dy = point.y - g_last_hit_tracker.y[j];
      uint8_t dist = sqrt16(dx * dx + dy * dy);
      uint16_t effect = scale16by8(g_last_hit_tracker.tick[j], rgb_matrix_config.speed) + dist * 5;
      if (effect > 255)
        effect = 255;
      hsv.v = qadd8(hsv.v, 255 - effect);
    }
    hsv.v = scale8(hsv.v, rgb_matrix_config.val);
    RGB rgb = hsv_to_rgb(hsv);
    rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
  }
  return led_max < DRIVER_LED_TOTAL;
}

bool rgb_matrix_solid_reactive_multiwide(effect_params_t* params) {
  return rgb_matrix_solid_reactive_multiwide_range(0, params);
}

bool rgb_matrix_solid_reactive_wide(effect_params_t* params) {
  return rgb_matrix_solid_reactive_multiwide_range(qsub8(g_last_hit_tracker.count, 1), params);
}

#endif // !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE)
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED