diff options
author | Max Rumpf <max.rumpf1998@gmail.com> | 2020-07-26 01:00:33 +0200 |
---|---|---|
committer | Drashna Jael're <drashna@live.com> | 2020-09-30 03:13:45 -0700 |
commit | 8190423aad0d1318c43a6ec10e459aeabe3af516 (patch) | |
tree | 545e0943c7b5da9f53f8cd7a528308faf0a3cc7d /quantum/rgblight.c | |
parent | f85b1ee83fa136e7a1795cfaf27d87d81f4b91e9 (diff) |
Tweak the Christmas animation effect to be less harsh on the eyes (#7648)
* Tweak the Christmas animation effect to be less harsh on the eyes
* Further improve the tweaked Christmas animation code
- Use constants where it makes sense
- Instead of complicated math, use a static variable to keep track if it's animating from or to red
- Don't use pow (but a simple macro instead)
- Using floating point math is necessary for the fraction in the cubic bezier function to work
* Update docs for the tweaked Christmas animation effect
* Further improve memory usage
- Don't use floats, but 32 bit ints instead (where needed)
- Replace limits.h with constant
* Fix typo
Diffstat (limited to 'quantum/rgblight.c')
-rw-r--r-- | quantum/rgblight.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 22e5f8d104..87c80582f9 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -1165,16 +1165,39 @@ void rgblight_effect_knight(animation_status_t *anim) { #endif #ifdef RGBLIGHT_EFFECT_CHRISTMAS +# define CUBED(x) ((x) * (x) * (x)) + +/** + * Christmas lights effect, with a smooth animation between red & green. + */ void rgblight_effect_christmas(animation_status_t *anim) { - uint8_t hue; + static int8_t increment = 1; + const uint8_t max_pos = 32; + const uint8_t hue_green = 85; + + uint32_t xa; + uint8_t hue, val; uint8_t i; - anim->current_offset = (anim->current_offset + 1) % 2; + // The effect works by animating anim->pos from 0 to 32 and back to 0. + // The pos is used in a cubic bezier formula to ease-in-out between red and green, leaving the interpolated colors visible as short as possible. + xa = CUBED((uint32_t) anim->pos); + hue = ((uint32_t) hue_green) * xa / (xa + CUBED((uint32_t) (max_pos - anim->pos))); + // Additionally, these interpolated colors get shown with a slightly darker value, to make them less prominent than the main colors. + val = 255 - (3 * (hue < hue_green / 2 ? hue : hue_green - hue) / 2); + for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { - hue = 0 + ((i / RGBLIGHT_EFFECT_CHRISTMAS_STEP + anim->current_offset) % 2) * 85; - sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + rgblight_ranges.effect_start_pos]); + uint8_t local_hue = (i / RGBLIGHT_EFFECT_CHRISTMAS_STEP) % 2 ? hue : hue_green - hue; + sethsv(local_hue, rgblight_config.sat, val, (LED_TYPE *)&led[i + rgblight_ranges.effect_start_pos]); } rgblight_set(); + + if (anim->pos == 0) { + increment = 1; + } else if (anim->pos == max_pos) { + increment = -1; + } + anim->pos += increment; } #endif |