summary refs log tree commit diff
path: root/quantum
diff options
context:
space:
mode:
authorMax Rumpf <max.rumpf1998@gmail.com>2020-07-26 01:00:33 +0200
committerJames Young <18669334+noroadsleft@users.noreply.github.com>2020-08-29 14:30:02 -0700
commit4b74f985ec7b14f5517df4e591f0c36b24f85f5c (patch)
tree241f9f678df1485314e15f9e2aa9e59727131ff4 /quantum
parentd4be07dad368c57669c88ead6c093c9e23086855 (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')
-rw-r--r--quantum/rgblight.c31
-rw-r--r--quantum/rgblight.h2
2 files changed, 28 insertions, 5 deletions
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index f9e9da1679..52d8da1813 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -1163,16 +1163,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
 
diff --git a/quantum/rgblight.h b/quantum/rgblight.h
index 7b26962947..c3a9e94b7c 100644
--- a/quantum/rgblight.h
+++ b/quantum/rgblight.h
@@ -142,7 +142,7 @@ enum RGBLIGHT_EFFECT_MODE {
 #    endif
 
 #    ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL
-#        define RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 1000
+#        define RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 40
 #    endif
 
 #    ifndef RGBLIGHT_EFFECT_CHRISTMAS_STEP