aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/feature_rgb_matrix.md4
-rw-r--r--quantum/rgb_matrix.c21
-rw-r--r--quantum/rgb_matrix.h5
-rw-r--r--quantum/rgb_matrix_animations/digital_rain_anim.h33
-rw-r--r--quantum/rgb_matrix_animations/typing_heatmap_anim.h75
5 files changed, 123 insertions, 15 deletions
diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md
index 5eb9d5536..1e4341467 100644
--- a/docs/feature_rgb_matrix.md
+++ b/docs/feature_rgb_matrix.md
@@ -201,7 +201,10 @@ enum rgb_matrix_effects {
201 RGB_MATRIX_RAINBOW_PINWHEELS, // Full dual gradients spinning two halfs of keyboard 201 RGB_MATRIX_RAINBOW_PINWHEELS, // Full dual gradients spinning two halfs of keyboard
202 RGB_MATRIX_RAINDROPS, // Randomly changes a single key's hue 202 RGB_MATRIX_RAINDROPS, // Randomly changes a single key's hue
203 RGB_MATRIX_JELLYBEAN_RAINDROPS, // Randomly changes a single key's hue and saturation 203 RGB_MATRIX_JELLYBEAN_RAINDROPS, // Randomly changes a single key's hue and saturation
204#if define(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
205 RGB_MATRIX_TYPING_HEATMAP, // How hot is your WPM!
204 RGB_MATRIX_DIGITAL_RAIN, // That famous computer simulation 206 RGB_MATRIX_DIGITAL_RAIN, // That famous computer simulation
207#endif
205#if defined(RGB_MATRIX_KEYPRESSES) || defined(RGB_MATRIX_KEYRELEASES) 208#if defined(RGB_MATRIX_KEYPRESSES) || defined(RGB_MATRIX_KEYRELEASES)
206 RGB_MATRIX_SOLID_REACTIVE_SIMPLE, // Pulses keys hit to hue & value then fades value out 209 RGB_MATRIX_SOLID_REACTIVE_SIMPLE, // Pulses keys hit to hue & value then fades value out
207 RGB_MATRIX_SOLID_REACTIVE, // Static single hue, pulses keys hit to shifted hue then fades to current hue 210 RGB_MATRIX_SOLID_REACTIVE, // Static single hue, pulses keys hit to shifted hue then fades to current hue
@@ -237,6 +240,7 @@ You can disable a single effect by defining `DISABLE_[EFFECT_NAME]` in your `con
237|`#define DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS` |Disables `RGB_MATRIX_RAINBOW_PINWHEELS` | 240|`#define DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS` |Disables `RGB_MATRIX_RAINBOW_PINWHEELS` |
238|`#define DISABLE_RGB_MATRIX_RAINDROPS` |Disables `RGB_MATRIX_RAINDROPS` | 241|`#define DISABLE_RGB_MATRIX_RAINDROPS` |Disables `RGB_MATRIX_RAINDROPS` |
239|`#define DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS` |Disables `RGB_MATRIX_JELLYBEAN_RAINDROPS` | 242|`#define DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS` |Disables `RGB_MATRIX_JELLYBEAN_RAINDROPS` |
243|`#define DISABLE_RGB_MATRIX_TYPING_HEATMAP` |Disables `RGB_MATRIX_TYPING_HEATMAP` |
240|`#define DISABLE_RGB_MATRIX_DIGITAL_RAIN` |Disables `RGB_MATRIX_DIGITAL_RAIN` | 244|`#define DISABLE_RGB_MATRIX_DIGITAL_RAIN` |Disables `RGB_MATRIX_DIGITAL_RAIN` |
241|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE` |Disables `RGB_MATRIX_SOLID_REACTIVE` | 245|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE` |Disables `RGB_MATRIX_SOLID_REACTIVE` |
242|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE` |Disables `RGB_MATRIX_SOLID_REACTIVE_SIMPLE` | 246|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE` |Disables `RGB_MATRIX_SOLID_REACTIVE_SIMPLE` |
diff --git a/quantum/rgb_matrix.c b/quantum/rgb_matrix.c
index edbcee9cd..92a94df80 100644
--- a/quantum/rgb_matrix.c
+++ b/quantum/rgb_matrix.c
@@ -38,6 +38,7 @@
38#include "rgb_matrix_animations/rainbow_pinwheels_anim.h" 38#include "rgb_matrix_animations/rainbow_pinwheels_anim.h"
39#include "rgb_matrix_animations/rainbow_moving_chevron_anim.h" 39#include "rgb_matrix_animations/rainbow_moving_chevron_anim.h"
40#include "rgb_matrix_animations/jellybean_raindrops_anim.h" 40#include "rgb_matrix_animations/jellybean_raindrops_anim.h"
41#include "rgb_matrix_animations/typing_heatmap_anim.h"
41#include "rgb_matrix_animations/digital_rain_anim.h" 42#include "rgb_matrix_animations/digital_rain_anim.h"
42#include "rgb_matrix_animations/solid_reactive_simple_anim.h" 43#include "rgb_matrix_animations/solid_reactive_simple_anim.h"
43#include "rgb_matrix_animations/solid_reactive_anim.h" 44#include "rgb_matrix_animations/solid_reactive_anim.h"
@@ -111,6 +112,10 @@ rgb_config_t rgb_matrix_config;
111rgb_counters_t g_rgb_counters; 112rgb_counters_t g_rgb_counters;
112static uint32_t rgb_counters_buffer; 113static uint32_t rgb_counters_buffer;
113 114
115#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
116uint8_t rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS] = {{0}};
117#endif
118
114#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED 119#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
115 last_hit_t g_last_hit_tracker; 120 last_hit_t g_last_hit_tracker;
116 static last_hit_t last_hit_buffer; 121 static last_hit_t last_hit_buffer;
@@ -206,6 +211,13 @@ bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
206 last_hit_buffer.count++; 211 last_hit_buffer.count++;
207 } 212 }
208#endif // RGB_MATRIX_KEYREACTIVE_ENABLED 213#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
214
215#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_TYPING_HEATMAP)
216 if (rgb_matrix_config.mode == RGB_MATRIX_TYPING_HEATMAP) {
217 process_rgb_matrix_typing_heatmap(record);
218 }
219#endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_TYPING_HEATMAP)
220
209 return true; 221 return true;
210} 222}
211 223
@@ -370,11 +382,20 @@ static void rgb_task_render(uint8_t effect) {
370 rendering = rgb_matrix_jellybean_raindrops(&rgb_effect_params); // Max 1ms Avg 0ms 382 rendering = rgb_matrix_jellybean_raindrops(&rgb_effect_params); // Max 1ms Avg 0ms
371 break; 383 break;
372#endif // DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS 384#endif // DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
385
386#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
387#ifndef DISABLE_RGB_MATRIX_TYPING_HEATMAP
388 case RGB_MATRIX_TYPING_HEATMAP:
389 rendering = rgb_matrix_typing_heatmap(&rgb_effect_params); // Max 4ms Avg 3ms
390 break;
391#endif // DISABLE_RGB_MATRIX_TYPING_HEATMAP
373#ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN 392#ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN
374 case RGB_MATRIX_DIGITAL_RAIN: 393 case RGB_MATRIX_DIGITAL_RAIN:
375 rendering = rgb_matrix_digital_rain(&rgb_effect_params); // Max 9ms Avg 8ms | this is expensive, fix it 394 rendering = rgb_matrix_digital_rain(&rgb_effect_params); // Max 9ms Avg 8ms | this is expensive, fix it
376 break; 395 break;
377#endif // DISABLE_RGB_MATRIX_DIGITAL_RAIN 396#endif // DISABLE_RGB_MATRIX_DIGITAL_RAIN
397#endif // RGB_MATRIX_FRAMEBUFFER_EFFECTS
398
378#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED 399#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
379#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE 400#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
380 case RGB_MATRIX_SOLID_REACTIVE_SIMPLE: 401 case RGB_MATRIX_SOLID_REACTIVE_SIMPLE:
diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h
index 365a92bbf..add0715d9 100644
--- a/quantum/rgb_matrix.h
+++ b/quantum/rgb_matrix.h
@@ -101,9 +101,14 @@ enum rgb_matrix_effects {
101#ifndef DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS 101#ifndef DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
102 RGB_MATRIX_JELLYBEAN_RAINDROPS, 102 RGB_MATRIX_JELLYBEAN_RAINDROPS,
103#endif // DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS 103#endif // DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
104#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
105#ifndef DISABLE_RGB_MATRIX_TYPING_HEATMAP
106 RGB_MATRIX_TYPING_HEATMAP,
107#endif // DISABLE_RGB_MATRIX_TYPING_HEATMAP
104#ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN 108#ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN
105 RGB_MATRIX_DIGITAL_RAIN, 109 RGB_MATRIX_DIGITAL_RAIN,
106#endif // DISABLE_RGB_MATRIX_DIGITAL_RAIN 110#endif // DISABLE_RGB_MATRIX_DIGITAL_RAIN
111#endif // RGB_MATRIX_FRAMEBUFFER_EFFECTS
107#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED 112#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
108#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE 113#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
109 RGB_MATRIX_SOLID_REACTIVE_SIMPLE, 114 RGB_MATRIX_SOLID_REACTIVE_SIMPLE,
diff --git a/quantum/rgb_matrix_animations/digital_rain_anim.h b/quantum/rgb_matrix_animations/digital_rain_anim.h
index 4ba3c1c87..6ccba392a 100644
--- a/quantum/rgb_matrix_animations/digital_rain_anim.h
+++ b/quantum/rgb_matrix_animations/digital_rain_anim.h
@@ -1,11 +1,13 @@
1#pragma once 1#pragma once
2#ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN 2#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_DIGITAL_RAIN)
3 3
4#ifndef RGB_DIGITAL_RAIN_DROPS 4#ifndef RGB_DIGITAL_RAIN_DROPS
5 // lower the number for denser effect/wider keyboard 5 // lower the number for denser effect/wider keyboard
6 #define RGB_DIGITAL_RAIN_DROPS 24 6 #define RGB_DIGITAL_RAIN_DROPS 24
7#endif 7#endif
8 8
9extern uint8_t rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS];
10
9bool rgb_matrix_digital_rain(effect_params_t* params) { 11bool rgb_matrix_digital_rain(effect_params_t* params) {
10 // algorithm ported from https://github.com/tremby/Kaleidoscope-LEDEffect-DigitalRain 12 // algorithm ported from https://github.com/tremby/Kaleidoscope-LEDEffect-DigitalRain
11 const uint8_t drop_ticks = 28; 13 const uint8_t drop_ticks = 28;
@@ -13,24 +15,24 @@ bool rgb_matrix_digital_rain(effect_params_t* params) {
13 const uint8_t max_brightness_boost = 0xc0; 15 const uint8_t max_brightness_boost = 0xc0;
14 const uint8_t max_intensity = 0xff; 16 const uint8_t max_intensity = 0xff;
15 17
16 static uint8_t map[MATRIX_COLS][MATRIX_ROWS] = {{0}};
17 static uint8_t drop = 0; 18 static uint8_t drop = 0;
18 19
19 if (params->init) { 20 if (params->init) {
20 rgb_matrix_set_color_all(0, 0, 0); 21 rgb_matrix_set_color_all(0, 0, 0);
21 memset(map, 0, sizeof map); 22 memset(rgb_frame_buffer, 0, sizeof rgb_frame_buffer);
22 drop = 0; 23 drop = 0;
23 } 24 }
25
24 for (uint8_t col = 0; col < MATRIX_COLS; col++) { 26 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
25 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 27 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
26 if (row == 0 && drop == 0 && rand() < RAND_MAX / RGB_DIGITAL_RAIN_DROPS) { 28 if (row == 0 && drop == 0 && rand() < RAND_MAX / RGB_DIGITAL_RAIN_DROPS) {
27 // top row, pixels have just fallen and we're 29 // top row, pixels have just fallen and we're
28 // making a new rain drop in this column 30 // making a new rain drop in this column
29 map[col][row] = max_intensity; 31 rgb_frame_buffer[col][row] = max_intensity;
30 } 32 }
31 else if (map[col][row] > 0 && map[col][row] < max_intensity) { 33 else if (rgb_frame_buffer[col][row] > 0 && rgb_frame_buffer[col][row] < max_intensity) {
32 // neither fully bright nor dark, decay it 34 // neither fully bright nor dark, decay it
33 map[col][row]--; 35 rgb_frame_buffer[col][row]--;
34 } 36 }
35 // set the pixel colour 37 // set the pixel colour
36 uint8_t led[LED_HITS_TO_REMEMBER]; 38 uint8_t led[LED_HITS_TO_REMEMBER];
@@ -38,32 +40,33 @@ bool rgb_matrix_digital_rain(effect_params_t* params) {
38 40
39 // TODO: multiple leds are supported mapped to the same row/column 41 // TODO: multiple leds are supported mapped to the same row/column
40 if (led_count > 0) { 42 if (led_count > 0) {
41 if (map[col][row] > pure_green_intensity) { 43 if (rgb_frame_buffer[col][row] > pure_green_intensity) {
42 const uint8_t boost = (uint8_t) ((uint16_t) max_brightness_boost * (map[col][row] - pure_green_intensity) / (max_intensity - pure_green_intensity)); 44 const uint8_t boost = (uint8_t) ((uint16_t) max_brightness_boost * (rgb_frame_buffer[col][row] - pure_green_intensity) / (max_intensity - pure_green_intensity));
43 rgb_matrix_set_color(led[0], boost, max_intensity, boost); 45 rgb_matrix_set_color(led[0], boost, max_intensity, boost);
44 } 46 }
45 else { 47 else {
46 const uint8_t green = (uint8_t) ((uint16_t) max_intensity * map[col][row] / pure_green_intensity); 48 const uint8_t green = (uint8_t) ((uint16_t) max_intensity * rgb_frame_buffer[col][row] / pure_green_intensity);
47 rgb_matrix_set_color(led[0], 0, green, 0); 49 rgb_matrix_set_color(led[0], 0, green, 0);
48 } 50 }
49 } 51 }
50 } 52 }
51 } 53 }
54
52 if (++drop > drop_ticks) { 55 if (++drop > drop_ticks) {
53 // reset drop timer 56 // reset drop timer
54 drop = 0; 57 drop = 0;
55 for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) { 58 for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) {
56 for (uint8_t col = 0; col < MATRIX_COLS; col++) { 59 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
57 // if ths is on the bottom row and bright allow decay 60 // if ths is on the bottom row and bright allow decay
58 if (row == MATRIX_ROWS - 1 && map[col][row] == max_intensity) { 61 if (row == MATRIX_ROWS - 1 && rgb_frame_buffer[col][row] == max_intensity) {
59 map[col][row]--; 62 rgb_frame_buffer[col][row]--;
60 } 63 }
61 // check if the pixel above is bright 64 // check if the pixel above is bright
62 if (map[col][row - 1] == max_intensity) { 65 if (rgb_frame_buffer[col][row - 1] == max_intensity) {
63 // allow old bright pixel to decay 66 // allow old bright pixel to decay
64 map[col][row - 1]--; 67 rgb_frame_buffer[col][row - 1]--;
65 // make this pixel bright 68 // make this pixel bright
66 map[col][row] = max_intensity; 69 rgb_frame_buffer[col][row] = max_intensity;
67 } 70 }
68 } 71 }
69 } 72 }
@@ -71,4 +74,4 @@ bool rgb_matrix_digital_rain(effect_params_t* params) {
71 return false; 74 return false;
72} 75}
73 76
74#endif // DISABLE_RGB_MATRIX_DIGITAL_RAIN 77#endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_DIGITAL_RAIN)
diff --git a/quantum/rgb_matrix_animations/typing_heatmap_anim.h b/quantum/rgb_matrix_animations/typing_heatmap_anim.h
new file mode 100644
index 000000000..aade53fcc
--- /dev/null
+++ b/quantum/rgb_matrix_animations/typing_heatmap_anim.h
@@ -0,0 +1,75 @@
1#pragma once
2#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_TYPING_HEATMAP)
3
4extern rgb_config_t rgb_matrix_config;
5extern uint8_t rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS];
6
7void process_rgb_matrix_typing_heatmap(keyrecord_t *record) {
8 uint8_t row = record->event.key.row;
9 uint8_t col = record->event.key.col;
10 uint8_t m_row = row - 1;
11 uint8_t p_row = row + 1;
12 uint8_t m_col = col - 1;
13 uint8_t p_col = col + 1;
14
15 if (m_col < col)
16 rgb_frame_buffer[row][m_col] = qadd8(rgb_frame_buffer[row][m_col], 16);
17 rgb_frame_buffer[row][col] = qadd8(rgb_frame_buffer[row][col], 32);
18 if (p_col < MATRIX_COLS)
19 rgb_frame_buffer[row][p_col] = qadd8(rgb_frame_buffer[row][p_col], 16);
20
21 if (p_row < MATRIX_ROWS) {
22 if (m_col < col)
23 rgb_frame_buffer[p_row][m_col] = qadd8(rgb_frame_buffer[p_row][m_col], 13);
24 rgb_frame_buffer[p_row][col] = qadd8(rgb_frame_buffer[p_row][col], 16);
25 if (p_col < MATRIX_COLS)
26 rgb_frame_buffer[p_row][p_col] = qadd8(rgb_frame_buffer[p_row][p_col], 13);
27 }
28
29 if (m_row < row) {
30 if (m_col < col)
31 rgb_frame_buffer[m_row][m_col] = qadd8(rgb_frame_buffer[m_row][m_col], 13);
32 rgb_frame_buffer[m_row][col] = qadd8(rgb_frame_buffer[m_row][col], 16);
33 if (p_col < MATRIX_COLS)
34 rgb_frame_buffer[m_row][p_col] = qadd8(rgb_frame_buffer[m_row][p_col], 13);
35 }
36}
37
38bool rgb_matrix_typing_heatmap(effect_params_t* params) {
39 // Modified version of RGB_MATRIX_USE_LIMITS to work off of matrix row / col size
40 uint8_t led_min = RGB_MATRIX_LED_PROCESS_LIMIT * params->iter;
41 uint8_t led_max = led_min + RGB_MATRIX_LED_PROCESS_LIMIT;
42 if (led_max > sizeof(rgb_frame_buffer))
43 led_max = sizeof(rgb_frame_buffer);
44
45 if (params->init) {
46 rgb_matrix_set_color_all(0, 0, 0);
47 memset(rgb_frame_buffer, 0, sizeof rgb_frame_buffer);
48 }
49
50 // Render heatmap & decrease
51 for (int i = led_min; i < led_max; i++) {
52 uint8_t row = i % MATRIX_ROWS;
53 uint8_t col = i / MATRIX_ROWS;
54 uint8_t val = rgb_frame_buffer[row][col];
55
56 // set the pixel colour
57 uint8_t led[LED_HITS_TO_REMEMBER];
58 uint8_t led_count = rgb_matrix_map_row_column_to_led(row, col, led);
59 for (uint8_t j = 0; j < led_count; ++j)
60 {
61 if (!HAS_ANY_FLAGS(g_led_config.flags[led[j]], params->flags))
62 continue;
63
64 HSV hsv = { 170 - qsub8(val, 85), rgb_matrix_config.sat, scale8((qadd8(170, val) - 170) * 3, rgb_matrix_config.val) };
65 RGB rgb = hsv_to_rgb(hsv);
66 rgb_matrix_set_color(led[j], rgb.r, rgb.g, rgb.b);
67 }
68
69 rgb_frame_buffer[row][col] = qsub8(val, 1);
70 }
71
72 return led_max < sizeof(rgb_frame_buffer);
73}
74
75#endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_TYPING_HEATMAP)