Diff
1diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md
2index df124ea0f50a4da11dd7ee5eda0ca469df19ad4c..18636776cddad76eb6bddf1bae7e477e813e8b1d 100644
3--- a/docs/feature_rgb_matrix.md
4+++ b/docs/feature_rgb_matrix.md
5@@ -196,12 +196,18 @@ enum rgb_matrix_effects {
6 RGB_MATRIX_BREATHING, // Single hue brightness cycling animation
7 RGB_MATRIX_BAND_SAT, // Single hue band fading saturation scrolling left to right
8 RGB_MATRIX_BAND_VAL, // Single hue band fading brightness scrolling left to right
9+ RGB_MATRIX_BAND_PINWHEEL_SAT, // Single hue 3 blade spinning pinwheel fades saturation
10+ RGB_MATRIX_BAND_PINWHEEL_VAL, // Single hue 3 blade spinning pinwheel fades brightness
11+ RGB_MATRIX_BAND_SPIRAL_SAT, // Single hue spinning spiral fades saturation
12+ RGB_MATRIX_BAND_SPIRAL_VAL, // Single hue spinning spiral fades brightness
13 RGB_MATRIX_CYCLE_ALL, // Full keyboard solid hue cycling through full gradient
14 RGB_MATRIX_CYCLE_LEFT_RIGHT, // Full gradient scrolling left to right
15 RGB_MATRIX_CYCLE_UP_DOWN, // Full gradient scrolling top to bottom
16 RGB_MATRIX_CYCLE_OUT_IN, // Full gradient scrolling out to in
17 RGB_MATRIX_CYCLE_OUT_IN_DUAL, // Full dual gradients scrolling out to in
18 RGB_MATRIX_RAINBOW_MOVING_CHEVRON, // Full gradent Chevron shapped scrolling left to right
19+ RGB_MATRIX_CYCLE_PINWHEEL, // Full gradient spinning pinwheel around center of keyboard
20+ RGB_MATRIX_CYCLE_SPIRAL, // Full gradient spinning spiral around center of keyboard
21 RGB_MATRIX_DUAL_BEACON, // Full gradient spinning around center of keyboard
22 RGB_MATRIX_RAINBOW_BEACON, // Full tighter gradient spinning around center of keyboard
23 RGB_MATRIX_RAINBOW_PINWHEELS, // Full dual gradients spinning two halfs of keyboard
24@@ -239,6 +245,10 @@ You can disable a single effect by defining `DISABLE_[EFFECT_NAME]` in your `con
25 |`#define DISABLE_RGB_MATRIX_BREATHING` |Disables `RGB_MATRIX_BREATHING` |
26 |`#define DISABLE_RGB_MATRIX_BAND_SAT` |Disables `RGB_MATRIX_BAND_SAT` |
27 |`#define DISABLE_RGB_MATRIX_BAND_VAL` |Disables `RGB_MATRIX_BAND_VAL` |
28+|`#define DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT` |Disables `RGB_MATRIX_BAND_PINWHEEL_SAT` |
29+|`#define DISABLE_RGB_MATRIX_BAND_PINWHEEL_VAL` |Disables `RGB_MATRIX_BAND_PINWHEEL_VAL` |
30+|`#define DISABLE_RGB_MATRIX_BAND_SPIRAL_SAT` |Disables `RGB_MATRIX_BAND_SPIRAL_SAT` |
31+|`#define DISABLE_RGB_MATRIX_BAND_SPIRAL_VAL` |Disables `RGB_MATRIX_BAND_SPIRAL_VAL` |
32 |`#define DISABLE_RGB_MATRIX_CYCLE_ALL` |Disables `RGB_MATRIX_CYCLE_ALL` |
33 |`#define DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT` |Disables `RGB_MATRIX_CYCLE_LEFT_RIGHT` |
34 |`#define DISABLE_RGB_MATRIX_CYCLE_UP_DOWN` |Disables `RGB_MATRIX_CYCLE_UP_DOWN` |
35@@ -246,6 +256,8 @@ You can disable a single effect by defining `DISABLE_[EFFECT_NAME]` in your `con
36 |`#define DISABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL` |Disables `RGB_MATRIX_CYCLE_OUT_IN_DUAL` |
37 |`#define DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON` |Disables `RGB_MATRIX_RAINBOW_MOVING_CHEVRON` |
38 |`#define DISABLE_RGB_MATRIX_DUAL_BEACON` |Disables `RGB_MATRIX_DUAL_BEACON` |
39+|`#define DISABLE_RGB_MATRIX_CYCLE_PINWHEEL` |Disables `RGB_MATRIX_CYCLE_PINWHEEL` |
40+|`#define DISABLE_RGB_MATRIX_CYCLE_SPIRAL` |Disables `RGB_MATRIX_CYCLE_SPIRAL` |
41 |`#define DISABLE_RGB_MATRIX_RAINBOW_BEACON` |Disables `RGB_MATRIX_RAINBOW_BEACON` |
42 |`#define DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS` |Disables `RGB_MATRIX_RAINBOW_PINWHEELS` |
43 |`#define DISABLE_RGB_MATRIX_RAINDROPS` |Disables `RGB_MATRIX_RAINDROPS` |
44diff --git a/lib/lib8tion/trig8.h b/lib/lib8tion/trig8.h
45index 6ef3ce625f40a72bd6c64027d7ddd44d78151e09..cfba6373fb94748743a16188c55b1c8df25d4529 100644
46--- a/lib/lib8tion/trig8.h
47+++ b/lib/lib8tion/trig8.h
48@@ -255,5 +255,30 @@ LIB8STATIC uint8_t cos8( uint8_t theta)
49 return sin8( theta + 64);
50 }
51
52+/// Fast 16-bit approximation of atan2(x).
53+/// @returns atan2, value between 0 and 255
54+LIB8STATIC uint8_t atan2_8(int16_t dy, int16_t dx)
55+{
56+ if (dy == 0)
57+ {
58+ if (dx >= 0)
59+ return 0;
60+ else
61+ return 128;
62+ }
63+
64+ int16_t abs_y = dy > 0 ? dy : -dy;
65+ int8_t a;
66+
67+ if (dx >= 0)
68+ a = 32 - (32 * (dx - abs_y) / (dx + abs_y));
69+ else
70+ a = 96 - (32 * (dx + abs_y) / (abs_y - dx));
71+
72+ if (dy < 0)
73+ return -a; // negate if in quad III or IV
74+ return a;
75+}
76+
77 ///@}
78 #endif
79diff --git a/quantum/rgb_matrix_animations/colorband_pinwheel_sat_anim.h b/quantum/rgb_matrix_animations/colorband_pinwheel_sat_anim.h
80new file mode 100644
81index 0000000000000000000000000000000000000000..3e6df1fbeb8ebda370604f74973f5499ea17a488
82--- /dev/null
83+++ b/quantum/rgb_matrix_animations/colorband_pinwheel_sat_anim.h
84@@ -0,0 +1,22 @@
85+#ifndef DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
86+RGB_MATRIX_EFFECT(BAND_PINWHEEL_SAT)
87+#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
88+
89+bool BAND_PINWHEEL_SAT(effect_params_t* params) {
90+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
91+
92+ HSV hsv = { rgb_matrix_config.hue, 0, rgb_matrix_config.val };
93+ uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 2);
94+ for (uint8_t i = led_min; i < led_max; i++) {
95+ RGB_MATRIX_TEST_LED_FLAGS();
96+ int16_t dx = g_led_config.point[i].x - 112;
97+ int16_t dy = g_led_config.point[i].y - 32;
98+ hsv.s = rgb_matrix_config.sat - time - atan2_8(dy, dx) * 3;
99+ RGB rgb = hsv_to_rgb(hsv);
100+ rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
101+ }
102+ return led_max < DRIVER_LED_TOTAL;
103+}
104+
105+#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
106+#endif // DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
107diff --git a/quantum/rgb_matrix_animations/colorband_pinwheel_val_anim.h b/quantum/rgb_matrix_animations/colorband_pinwheel_val_anim.h
108new file mode 100644
109index 0000000000000000000000000000000000000000..88cc7d1f23d870966d5a0633cf32850def8efb25
110--- /dev/null
111+++ b/quantum/rgb_matrix_animations/colorband_pinwheel_val_anim.h
112@@ -0,0 +1,22 @@
113+#ifndef DISABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
114+RGB_MATRIX_EFFECT(BAND_PINWHEEL_VAL)
115+#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
116+
117+bool BAND_PINWHEEL_VAL(effect_params_t* params) {
118+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
119+
120+ HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, 0 };
121+ uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 2);
122+ for (uint8_t i = led_min; i < led_max; i++) {
123+ RGB_MATRIX_TEST_LED_FLAGS();
124+ int16_t dx = g_led_config.point[i].x - 112;
125+ int16_t dy = g_led_config.point[i].y - 32;
126+ hsv.v = rgb_matrix_config.val - time - atan2_8(dy, dx) * 3;
127+ RGB rgb = hsv_to_rgb(hsv);
128+ rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
129+ }
130+ return led_max < DRIVER_LED_TOTAL;
131+}
132+
133+#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
134+#endif // DISABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
135diff --git a/quantum/rgb_matrix_animations/colorband_spiral_sat_anim.h b/quantum/rgb_matrix_animations/colorband_spiral_sat_anim.h
136new file mode 100644
137index 0000000000000000000000000000000000000000..44955900a5daef442cf057c18fdcd1c55dc14669
138--- /dev/null
139+++ b/quantum/rgb_matrix_animations/colorband_spiral_sat_anim.h
140@@ -0,0 +1,23 @@
141+#ifndef DISABLE_RGB_MATRIX_BAND_SPIRAL_SAT
142+RGB_MATRIX_EFFECT(BAND_SPIRAL_SAT)
143+#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
144+
145+bool BAND_SPIRAL_SAT(effect_params_t* params) {
146+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
147+
148+ HSV hsv = { rgb_matrix_config.hue, 0, rgb_matrix_config.val };
149+ uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 2);
150+ for (uint8_t i = led_min; i < led_max; i++) {
151+ RGB_MATRIX_TEST_LED_FLAGS();
152+ int16_t dx = g_led_config.point[i].x - 112;
153+ int16_t dy = g_led_config.point[i].y - 32;
154+ uint8_t dist = sqrt16(dx * dx + dy * dy);
155+ hsv.s = rgb_matrix_config.sat + dist - time - atan2_8(dy, dx);
156+ RGB rgb = hsv_to_rgb(hsv);
157+ rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
158+ }
159+ return led_max < DRIVER_LED_TOTAL;
160+}
161+
162+#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
163+#endif // DISABLE_RGB_MATRIX_BAND_SPIRAL_SAT
164diff --git a/quantum/rgb_matrix_animations/colorband_spiral_val_anim.h b/quantum/rgb_matrix_animations/colorband_spiral_val_anim.h
165new file mode 100644
166index 0000000000000000000000000000000000000000..5aea0c8da11f59572080e8e6cd28252cf925c3f6
167--- /dev/null
168+++ b/quantum/rgb_matrix_animations/colorband_spiral_val_anim.h
169@@ -0,0 +1,23 @@
170+#ifndef DISABLE_RGB_MATRIX_BAND_SPIRAL_VAL
171+RGB_MATRIX_EFFECT(BAND_SPIRAL_VAL)
172+#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
173+
174+bool BAND_SPIRAL_VAL(effect_params_t* params) {
175+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
176+
177+ HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, 0 };
178+ uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 2);
179+ for (uint8_t i = led_min; i < led_max; i++) {
180+ RGB_MATRIX_TEST_LED_FLAGS();
181+ int16_t dx = g_led_config.point[i].x - 112;
182+ int16_t dy = g_led_config.point[i].y - 32;
183+ uint8_t dist = sqrt16(dx * dx + dy * dy);
184+ hsv.v = rgb_matrix_config.val + dist - time - atan2_8(dy, dx);
185+ RGB rgb = hsv_to_rgb(hsv);
186+ rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
187+ }
188+ return led_max < DRIVER_LED_TOTAL;
189+}
190+
191+#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
192+#endif // DISABLE_RGB_MATRIX_BAND_SPIRAL_VAL
193diff --git a/quantum/rgb_matrix_animations/cycle_pinwheel_anim.h b/quantum/rgb_matrix_animations/cycle_pinwheel_anim.h
194new file mode 100644
195index 0000000000000000000000000000000000000000..59d60ac07728c16284ad9d3c8ed40e03d6d66037
196--- /dev/null
197+++ b/quantum/rgb_matrix_animations/cycle_pinwheel_anim.h
198@@ -0,0 +1,22 @@
199+#ifndef DISABLE_RGB_MATRIX_CYCLE_PINWHEEL
200+RGB_MATRIX_EFFECT(CYCLE_PINWHEEL)
201+#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
202+
203+bool CYCLE_PINWHEEL(effect_params_t* params) {
204+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
205+
206+ HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
207+ uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
208+ for (uint8_t i = led_min; i < led_max; i++) {
209+ RGB_MATRIX_TEST_LED_FLAGS();
210+ int16_t dx = g_led_config.point[i].x - 112;
211+ int16_t dy = g_led_config.point[i].y - 32;
212+ hsv.h = atan2_8(dy, dx) + time;
213+ RGB rgb = hsv_to_rgb(hsv);
214+ rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
215+ }
216+ return led_max < DRIVER_LED_TOTAL;
217+}
218+
219+#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
220+#endif // DISABLE_RGB_MATRIX_CYCLE_PINWHEEL
221diff --git a/quantum/rgb_matrix_animations/cycle_spiral_anim.h b/quantum/rgb_matrix_animations/cycle_spiral_anim.h
222new file mode 100644
223index 0000000000000000000000000000000000000000..865309c252b786e9adf9a94c33d0bb27a9f0c435
224--- /dev/null
225+++ b/quantum/rgb_matrix_animations/cycle_spiral_anim.h
226@@ -0,0 +1,23 @@
227+#ifndef DISABLE_RGB_MATRIX_CYCLE_SPIRAL
228+RGB_MATRIX_EFFECT(CYCLE_SPIRAL)
229+#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
230+
231+bool CYCLE_SPIRAL(effect_params_t* params) {
232+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
233+
234+ HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
235+ uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 2);
236+ for (uint8_t i = led_min; i < led_max; i++) {
237+ RGB_MATRIX_TEST_LED_FLAGS();
238+ int16_t dx = g_led_config.point[i].x - 112;
239+ int16_t dy = g_led_config.point[i].y - 32;
240+ uint8_t dist = sqrt16(dx * dx + dy * dy);
241+ hsv.h = dist - time - atan2_8(dy, dx);
242+ RGB rgb = hsv_to_rgb(hsv);
243+ rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
244+ }
245+ return led_max < DRIVER_LED_TOTAL;
246+}
247+
248+#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
249+#endif // DISABLE_RGB_MATRIX_CYCLE_SPIRAL
250diff --git a/quantum/rgb_matrix_animations/rgb_matrix_effects.inc b/quantum/rgb_matrix_animations/rgb_matrix_effects.inc
251index 4b01afaa352261e68e2848e10f6b7c0c2a1affbb..01332ed0dda6bbc4c01310ac27abce306607c8aa 100644
252--- a/quantum/rgb_matrix_animations/rgb_matrix_effects.inc
253+++ b/quantum/rgb_matrix_animations/rgb_matrix_effects.inc
254@@ -5,12 +5,18 @@
255 #include "rgb_matrix_animations/breathing_anim.h"
256 #include "rgb_matrix_animations/colorband_sat_anim.h"
257 #include "rgb_matrix_animations/colorband_val_anim.h"
258+#include "rgb_matrix_animations/colorband_pinwheel_sat_anim.h"
259+#include "rgb_matrix_animations/colorband_pinwheel_val_anim.h"
260+#include "rgb_matrix_animations/colorband_spiral_sat_anim.h"
261+#include "rgb_matrix_animations/colorband_spiral_val_anim.h"
262 #include "rgb_matrix_animations/cycle_all_anim.h"
263 #include "rgb_matrix_animations/cycle_left_right_anim.h"
264 #include "rgb_matrix_animations/cycle_up_down_anim.h"
265 #include "rgb_matrix_animations/rainbow_moving_chevron_anim.h"
266 #include "rgb_matrix_animations/cycle_out_in_anim.h"
267 #include "rgb_matrix_animations/cycle_out_in_dual_anim.h"
268+#include "rgb_matrix_animations/cycle_pinwheel_anim.h"
269+#include "rgb_matrix_animations/cycle_spiral_anim.h"
270 #include "rgb_matrix_animations/dual_beacon_anim.h"
271 #include "rgb_matrix_animations/rainbow_beacon_anim.h"
272 #include "rgb_matrix_animations/rainbow_pinwheels_anim.h"