aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c939
1 files changed, 939 insertions, 0 deletions
diff --git a/keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c b/keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c
new file mode 100644
index 000000000..eabd8d23a
--- /dev/null
+++ b/keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c
@@ -0,0 +1,939 @@
1#include QMK_KEYBOARD_H
2
3// uint8_t keyboard_leds(void)
4#include <tmk_core/protocol/arm_atsam/main_arm_atsam.h>
5
6
7#if ISSI3733_LED_COUNT == 119
8# define KEY_LED_COUNT 87
9#elif ISSI3733_LED_COUNT == 105
10# define KEY_LED_COUNT 67
11#endif
12
13#define min(x, y) (x < y ? x : y)
14
15
16extern issi3733_led_t *lede;
17extern issi3733_led_t led_map[];
18extern led_disp_t disp;
19
20enum ctrl_keycodes {
21 L_BRI = SAFE_RANGE, //LED Brightness Increase
22 L_BRD, //LED Brightness Decrease
23 L_PTN, //LED Pattern Select Next
24 L_PTP, //LED Pattern Select Previous
25 L_PSI, //LED Pattern Speed Increase
26 L_PSD, //LED Pattern Speed Decrease
27 L_T_MD, //LED Toggle Mode
28 L_T_ONF, //LED Toggle On / Off
29 L_ON, //LED On
30 L_OFF, //LED Off
31 L_T_BR, //LED Toggle Breath Effect
32 L_T_PTD, //LED Toggle Scrolling Pattern Direction
33 U_T_AUTO, //USB Extra Port Toggle Auto Detect / Always Active
34 U_T_AGCR, //USB Toggle Automatic GCR control
35 DBG_TOG, //DEBUG Toggle On / Off
36 DBG_MTRX, //DEBUG Toggle Matrix Prints
37 DBG_KBD, //DEBUG Toggle Keyboard Prints
38 DBG_MOU, //DEBUG Toggle Mouse Prints
39 MD_BOOT, //Restart into bootloader after hold timeout
40
41 L_SP_PR, //LED Splash Pattern Select Previous
42 L_SP_NE, //LED Splash Pattern Select Next
43
44 L_SP_WD, //LED Splash Widen Wavefront width
45 L_SP_NW, //LED Splash Narrow Wavefront width
46
47 L_SP_FA, //LED Splash wave travel speed faster (shorter period)
48 L_SP_SL, //LED Splash wave travel speed slower (longer period)
49
50 L_CP_PR, //LED Color Pattern Select Previous
51 L_CP_NX, //LEB Color Pattern Select Next
52};
53
54#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode
55#define ______ KC_TRNS
56
57keymap_config_t keymap_config;
58
59const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
60 [0] = LAYOUT(
61 KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS, \
62 KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, \
63 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, \
64 KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
65 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \
66 KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \
67 ),
68 [1] = LAYOUT(
69 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, _______, _______, \
70 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, \
71 L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, U_T_AUTO,U_T_AGCR,_______, MO(2), _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \
72 L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
73 _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, \
74 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
75 ),
76 [2] = LAYOUT(
77 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
78 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
79 L_CP_NX, L_SP_SL, L_SP_WD, L_SP_FA, _______, _______, L_CP_NX, L_SP_SL, L_SP_WD, L_SP_FA, _______, _______, _______, _______, _______, _______, _______, \
80 L_CP_PR, L_SP_PR, L_SP_NW, L_SP_NE, _______, _______, L_CP_PR, L_SP_PR, L_SP_NW, L_SP_NE, _______, _______, _______, \
81 _______, _______, _______, _______, _______, _______, TG_NKRO, _______, _______, _______, _______, _______, _______, \
82 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
83 ),
84 /*
85 [X] = LAYOUT(
86 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
87 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
88 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
89 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
90 _______, _______, _______, _______, _______, _______, TG_NKRO, _______, _______, _______, _______, _______, _______, \
91 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
92 ),
93 */
94};
95
96// see: /tmk_core/common/keycode.h
97uint8_t KEYCODE_TO_LED_ID[256];
98uint8_t DISTANCE_MAP[KEY_LED_COUNT+1][KEY_LED_COUNT+1];
99struct user_led_t {
100 uint8_t state;
101 uint8_t r;
102 uint8_t g;
103 uint8_t b;
104} USER_LED[KEY_LED_COUNT] = {
105
106};
107
108struct {
109 uint8_t PATTERN_INDEX;
110 uint8_t WAVE_FRONT_WIDTH;
111 uint16_t WAVE_PERIOD;
112 uint8_t COLOR_PATTERN_INDEX;
113 uint8_t TRAVEL_DISTANCE;
114} USER_CONFIG = {
115 .PATTERN_INDEX = 1,
116 .WAVE_FRONT_WIDTH = 3,
117 .WAVE_PERIOD = 50,
118 .COLOR_PATTERN_INDEX = 0,
119 .TRAVEL_DISTANCE = 25,
120};
121
122uint8_t ktli(uint16_t keycode){
123 if(keycode < 256){
124 // the array is initialized in `matrix_init_user()`
125 return KEYCODE_TO_LED_ID[keycode];
126 }
127 switch(keycode){
128 // definition of MO(layer): quantum/quantum_keycodes.h: line 614
129 case MO(1): return 82;
130 }
131 return 0;
132};
133
134// Runs just one time when the keyboard initializes.
135static void init_keycode_to_led_map(void){
136 uint16_t LED_MAP[MATRIX_ROWS][MATRIX_COLS] = LAYOUT(
137 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
138 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,
139 36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
140 52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,
141#if KEY_LED_COUNT >= 87
142 68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87
143#endif
144 );
145
146 uint16_t key = 0;
147 for(uint8_t y = 0; y < MATRIX_ROWS; ++y){
148 for(uint8_t x = 0; x < MATRIX_COLS; ++x){
149 key = keymaps[0][y][x];
150 if(key < 256){
151 KEYCODE_TO_LED_ID[key] = LED_MAP[y][x];
152 }
153 }
154 }
155}
156// https://docs.qmk.fm/#/feature_terminal
157#define KEY_POSITION_MAP_ROWS 6
158#define KEY_POSITION_MAP_COLUMNS 20
159static void init_distance_map(void){
160 uint16_t KEY_POSITION_MAP[KEY_POSITION_MAP_ROWS][KEY_POSITION_MAP_COLUMNS] = {
161 { KC_NO, KC_ESC, KC_NO, KC_F1, KC_F2, KC_F3, KC_F4, KC_NO, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NO, KC_PSCR, KC_SLCK, KC_PAUS, },
162 // { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, },
163 { KC_NO, KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_BSPC, KC_NO, KC_INS, KC_HOME, KC_PGUP, },
164 { KC_NO, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_BSLS, KC_NO, KC_DEL, KC_END, KC_PGDN, },
165 { KC_NO, KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_ENT, KC_ENT, KC_NO, KC_NO, KC_NO, KC_NO, },
166 { KC_NO, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_RSFT, KC_RSFT, KC_RSFT, KC_NO, KC_NO, KC_UP, KC_NO, },
167 { KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_RALT, KC_NO, MO(1), KC_APP, KC_RCTL, KC_RCTL, KC_RCTL, KC_NO, KC_LEFT, KC_DOWN, KC_RIGHT, },
168 };
169 uint8_t columns = KEY_POSITION_MAP_COLUMNS;
170 uint8_t rows = KEY_POSITION_MAP_ROWS;
171
172 for(uint8_t y = 0; y < rows; ++y){
173 for(uint8_t x = 0; x < columns; ++x){
174 uint8_t id1 = ktli(KEY_POSITION_MAP[y][x]);
175
176 for(uint8_t j = y; j < rows; ++j){
177 for(uint8_t i = 0; i < columns; ++i){
178 uint8_t id2 = ktli(KEY_POSITION_MAP[j][i]);
179
180 if(id1 == id2) continue;
181
182 uint8_t dx = abs(i - x);
183 uint8_t dy = abs(j - y);
184 uint8_t dis = dx + dy;
185 if(i < x && j > y){
186 dis -= min(dx, dy);
187 }
188
189 uint8_t _dis = DISTANCE_MAP[id1][id2];
190 if(_dis && _dis <= dis) continue;
191 DISTANCE_MAP[id1][id2] = dis;
192 DISTANCE_MAP[id2][id1] = dis;
193 }
194 }
195 }
196 }
197}
198void matrix_init_user(void) {
199 init_keycode_to_led_map();
200 init_distance_map();
201};
202
203// /tmk_core/protocol/arm_atsam/led_matrix.c: line 244
204uint8_t led_enabled;
205float led_animation_speed;
206uint8_t led_animation_direction;
207uint8_t led_animation_orientation;
208uint8_t led_animation_breathing;
209uint8_t led_animation_breathe_cur;
210uint8_t breathe_step;
211uint8_t breathe_dir;
212uint64_t led_next_run;
213
214uint8_t led_animation_id;
215uint8_t led_lighting_mode;
216
217issi3733_led_t *led_cur;
218uint8_t led_per_run;
219float breathe_mult;
220
221// overrided /tmk_core/protocol/arm_atsam/led_matrix.c: line 484
222void rgb_matrix_init_user(void){
223 led_animation_speed = ANIMATION_SPEED_STEP * 15;
224 led_per_run = 15;
225}
226
227// overrided /tmk_core/protocol/arm_atsam/led_matrix.c: line 262
228void led_matrix_run(void)
229{
230 float ro;
231 float go;
232 float bo;
233 float po;
234 uint8_t led_this_run = 0;
235 led_setup_t *f = (led_setup_t*)led_setups[led_animation_id];
236
237 if (led_cur == 0) //Denotes start of new processing cycle in the case of chunked processing
238 {
239 led_cur = led_map;
240
241 disp.frame += 1;
242
243 breathe_mult = 1;
244
245 if (led_animation_breathing)
246 {
247 led_animation_breathe_cur += breathe_step * breathe_dir;
248
249 if (led_animation_breathe_cur >= BREATHE_MAX_STEP)
250 breathe_dir = -1;
251 else if (led_animation_breathe_cur <= BREATHE_MIN_STEP)
252 breathe_dir = 1;
253
254 //Brightness curve created for 256 steps, 0 - ~98%
255 breathe_mult = 0.000015 * led_animation_breathe_cur * led_animation_breathe_cur;
256 if (breathe_mult > 1) breathe_mult = 1;
257 else if (breathe_mult < 0) breathe_mult = 0;
258 }
259 }
260
261 uint8_t fcur = 0;
262 uint8_t fmax = 0;
263
264 //Frames setup
265 while (f[fcur].end != 1)
266 {
267 fcur++; //Count frames
268 }
269
270 fmax = fcur; //Store total frames count
271
272 struct user_led_t user_led_cur;
273 while (led_cur < lede && led_this_run < led_per_run)
274 {
275 ro = 0;
276 go = 0;
277 bo = 0;
278
279 uint8_t led_index = led_cur - led_map; // only this part differs from the original function.
280 if(led_index < KEY_LED_COUNT){ //
281 user_led_cur = USER_LED[led_index]; // `struct user_led_t USER_LED[]` is stored globally.
282 } //
283 //
284 if(led_index < KEY_LED_COUNT && user_led_cur.state){ // `user_led_cur` is just for convenience
285 ro = user_led_cur.r; //
286 go = user_led_cur.g; //
287 bo = user_led_cur.b; //
288 } //
289 else if (led_lighting_mode == LED_MODE_KEYS_ONLY && led_cur->scan == 255)
290 {
291 //Do not act on this LED
292 }
293 else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && led_cur->scan != 255)
294 {
295 //Do not act on this LED
296 }
297 else if (led_lighting_mode == LED_MODE_INDICATORS_ONLY)
298 {
299 //Do not act on this LED (Only show indicators)
300 }
301 else
302 {
303 //Act on LED
304 for (fcur = 0; fcur < fmax; fcur++)
305 {
306
307 if (led_animation_orientation)
308 {
309 po = led_cur->py;
310 }
311 else
312 {
313 po = led_cur->px;
314 }
315
316 float pomod;
317 pomod = (float)(disp.frame % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed;
318
319 //Add in any moving effects
320 if ((!led_animation_direction && f[fcur].ef & EF_SCR_R) || (led_animation_direction && (f[fcur].ef & EF_SCR_L)))
321 {
322 pomod *= 100.0f;
323 pomod = (uint32_t)pomod % 10000;
324 pomod /= 100.0f;
325
326 po -= pomod;
327
328 if (po > 100) po -= 100;
329 else if (po < 0) po += 100;
330 }
331 else if ((!led_animation_direction && f[fcur].ef & EF_SCR_L) || (led_animation_direction && (f[fcur].ef & EF_SCR_R)))
332 {
333 pomod *= 100.0f;
334 pomod = (uint32_t)pomod % 10000;
335 pomod /= 100.0f;
336 po += pomod;
337
338 if (po > 100) po -= 100;
339 else if (po < 0) po += 100;
340 }
341
342 //Check if LED's po is in current frame
343 if (po < f[fcur].hs) continue;
344 if (po > f[fcur].he) continue;
345 //note: < 0 or > 100 continue
346
347 //Calculate the po within the start-stop percentage for color blending
348 po = (po - f[fcur].hs) / (f[fcur].he - f[fcur].hs);
349
350 //Add in any color effects
351 if (f[fcur].ef & EF_OVER)
352 {
353 ro = (po * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
354 go = (po * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
355 bo = (po * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
356 }
357 else if (f[fcur].ef & EF_SUBTRACT)
358 {
359 ro -= (po * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
360 go -= (po * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
361 bo -= (po * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
362 }
363 else
364 {
365 ro += (po * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
366 go += (po * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
367 bo += (po * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
368 }
369 }
370 }
371
372 //Clamp values 0-255
373 if (ro > 255) ro = 255; else if (ro < 0) ro = 0;
374 if (go > 255) go = 255; else if (go < 0) go = 0;
375 if (bo > 255) bo = 255; else if (bo < 0) bo = 0;
376
377 if (led_animation_breathing)
378 {
379 ro *= breathe_mult;
380 go *= breathe_mult;
381 bo *= breathe_mult;
382 }
383
384 *led_cur->rgb.r = (uint8_t)ro;
385 *led_cur->rgb.g = (uint8_t)go;
386 *led_cur->rgb.b = (uint8_t)bo;
387
388#ifdef USB_LED_INDICATOR_ENABLE
389 if (keyboard_leds())
390 {
391 uint8_t kbled = keyboard_leds();
392 if (
393 #if USB_LED_NUM_LOCK_SCANCODE != 255
394 (led_cur->scan == USB_LED_NUM_LOCK_SCANCODE && kbled & (1<<USB_LED_NUM_LOCK)) ||
395 #endif //NUM LOCK
396 #if USB_LED_CAPS_LOCK_SCANCODE != 255
397 (led_cur->scan == USB_LED_CAPS_LOCK_SCANCODE && kbled & (1<<USB_LED_CAPS_LOCK)) ||
398 #endif //CAPS LOCK
399 #if USB_LED_SCROLL_LOCK_SCANCODE != 255
400 (led_cur->scan == USB_LED_SCROLL_LOCK_SCANCODE && kbled & (1<<USB_LED_SCROLL_LOCK)) ||
401 #endif //SCROLL LOCK
402 #if USB_LED_COMPOSE_SCANCODE != 255
403 (led_cur->scan == USB_LED_COMPOSE_SCANCODE && kbled & (1<<USB_LED_COMPOSE)) ||
404 #endif //COMPOSE
405 #if USB_LED_KANA_SCANCODE != 255
406 (led_cur->scan == USB_LED_KANA_SCANCODE && kbled & (1<<USB_LED_KANA)) ||
407 #endif //KANA
408 (0))
409 {
410 if (*led_cur->rgb.r > 127) *led_cur->rgb.r = 0;
411 else *led_cur->rgb.r = 255;
412 if (*led_cur->rgb.g > 127) *led_cur->rgb.g = 0;
413 else *led_cur->rgb.g = 255;
414 if (*led_cur->rgb.b > 127) *led_cur->rgb.b = 0;
415 else *led_cur->rgb.b = 255;
416 }
417 }
418#endif //USB_LED_INDICATOR_ENABLE
419
420 led_cur++;
421 led_this_run++;
422 }
423}
424
425#define KEY_STROKES_LENGTH 20
426struct {
427 bool alive;
428 uint8_t led_id;
429 uint32_t time;
430} KEY_STROKES[KEY_STROKES_LENGTH] = {{}};
431
432
433
434
435void set_led_rgb(uint8_t led_id, uint8_t r, uint8_t g, uint8_t b){
436 issi3733_led_t *target_led = (led_map + led_id);
437 *target_led->rgb.r = r;
438 *target_led->rgb.g = g;
439 *target_led->rgb.b = b;
440}
441
442
443uint8_t DISTANCE_FROM_LAST_KEYSTROKE[KEY_LED_COUNT+1];
444void calculate_keystroke_distance(void){
445 bool alive;
446 uint8_t led_id, period_passed;
447 uint32_t t;
448
449
450 for(uint8_t i = 0; i <= KEY_LED_COUNT; ++i){
451 DISTANCE_FROM_LAST_KEYSTROKE[i] = 0;
452 }
453
454 for(uint8_t i = 0; i < KEY_STROKES_LENGTH; ++i){
455 if(KEY_STROKES[i].alive){
456 t = timer_elapsed32(KEY_STROKES[i].time);
457 alive = 0;
458 led_id = KEY_STROKES[i].led_id;
459 period_passed = t / USER_CONFIG.WAVE_PERIOD;
460
461 uint8_t delta_period;
462 for(uint8_t j = 1; j <= KEY_LED_COUNT; ++j){
463 delta_period = period_passed - DISTANCE_MAP[led_id][j];
464 if(( delta_period < USER_CONFIG.WAVE_FRONT_WIDTH) && (
465 DISTANCE_MAP[led_id][j] <= USER_CONFIG.TRAVEL_DISTANCE
466 )){
467 switch(USER_CONFIG.PATTERN_INDEX){
468 case 3:
469 case 4:
470 case 5:
471 case 6:
472 DISTANCE_FROM_LAST_KEYSTROKE[j] += delta_period;
473 break;
474 default:
475 DISTANCE_FROM_LAST_KEYSTROKE[j] = 1;
476 break;
477 }
478 alive = 1;
479 }
480 }
481 KEY_STROKES[i].alive = alive;
482 }
483 }
484}
485
486#define COLOR_PATTERN_RGB_COUNT 18
487static uint8_t COLOR_PATTERNS[][COLOR_PATTERN_RGB_COUNT][3] = {
488 { // default rainbow color
489 {255, 0, 0}, {255, 0, 0}, {255, 127, 0},
490 {255, 127, 0}, {255, 255, 0}, {255, 255, 0},
491 {120, 255, 0}, {120, 255, 0}, { 0, 255, 0},
492 { 0, 255, 0}, { 0, 255, 120}, { 0, 255, 120},
493 { 0, 0, 255}, { 0, 0, 255}, { 75, 0, 130},
494 { 75, 0, 130}, { 43, 0, 130}, { 43, 0, 130},
495 }, { // light rainbow color
496 {248, 12, 18}, {238, 17, 0}, {255, 51, 17},
497 {255, 68, 32}, {255, 102, 68}, {255, 153, 51},
498 {254, 174, 45}, {204, 187, 51}, {208, 195, 16},
499 {170, 204, 34}, {105, 208, 37}, { 34, 204, 170},
500 { 18, 189, 185}, { 17, 170, 187}, { 68, 68, 221},
501 { 51, 17, 187}, { 59, 12, 189}, { 68, 34, 153},
502 }, { // white flat
503 {255, 255, 255}, {255, 255, 255}, {255, 255, 255},
504 {255, 255, 255}, {255, 255, 255}, {255, 255, 255},
505 {255, 255, 255}, {255, 255, 255}, {255, 255, 255},
506 {255, 255, 255}, {255, 255, 255}, {255, 255, 255},
507 {255, 255, 255}, {255, 255, 255}, {255, 255, 255},
508 {255, 255, 255}, {255, 255, 255}, {255, 255, 255},
509 }, { // white fade, cos curve
510 {255, 255, 255}, {255, 255, 255}, {252, 252, 252},
511 {247, 247, 247}, {240, 240, 240}, {232, 232, 232},
512 {221, 221, 221}, {209, 209, 209}, {196, 196, 196},
513 {181, 181, 181}, {164, 164, 164}, {147, 147, 147},
514 {128, 128, 128}, {108, 108, 108}, { 88, 88, 88},
515 { 66, 66, 66}, { 45, 45, 45}, { 23, 23, 23},
516 },
517};
518static const uint8_t COLOR_PATTERNS_COUNT = (
519 sizeof(COLOR_PATTERNS) / sizeof(COLOR_PATTERNS[0]));
520
521void set_user_led_rgb(uint8_t i, uint8_t r, uint8_t g, uint8_t b){
522 USER_LED[i-1].state = 1;
523 USER_LED[i-1].r = r;
524 USER_LED[i-1].g = g;
525 USER_LED[i-1].b = b;
526}
527void unset_user_led_rgb(uint8_t i){
528 USER_LED[i-1].state = 0;
529}
530void set_indicator_led_rgb(uint8_t i,
531 uint8_t layer, uint8_t r, uint8_t g, uint8_t b){
532 USER_LED[i-1].state |= 1 << layer;
533 USER_LED[i-1].r = r;
534 USER_LED[i-1].g = g;
535 USER_LED[i-1].b = b;
536}
537void unset_indicator_led_rgb(uint8_t i, uint8_t layer){
538 USER_LED[i-1].state &= ~(1 << layer);
539}
540
541void refresh_pattern_indicators(void){
542 static uint8_t GRV_123456[] = {
543 KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6,
544 };
545
546 if(layer_state >= 0x04){
547 for(uint8_t i = 0; i < 7; ++i){
548 if(i == USER_CONFIG.PATTERN_INDEX){
549 set_indicator_led_rgb(ktli(GRV_123456[i]), 2, 0, 0, 255);
550 } else{
551 set_indicator_led_rgb(ktli(GRV_123456[i]), 2, 0, 255, 0);
552 }
553 }
554 } else{
555 for(uint8_t i = 0; i < 7; ++i){
556 unset_indicator_led_rgb(ktli(GRV_123456[i]), 2);
557 }
558 }
559}
560void refresh_color_pattern_indicators(void){
561 static uint8_t ZXCVBNM_COMM_DOT[] = {
562 KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT,
563 };
564
565 if(layer_state >= 0x04){
566 uint8_t (*c)[3] = &COLOR_PATTERNS[USER_CONFIG.COLOR_PATTERN_INDEX][0];
567 for(uint8_t i = 0; i < 9; ++i){
568 set_indicator_led_rgb(ktli(ZXCVBNM_COMM_DOT[i]),
569 2, c[i][0], c[i][1], c[i][2]);
570 }
571 } else{
572 for(uint8_t i = 0; i < 9; ++i){
573 unset_indicator_led_rgb(ktli(ZXCVBNM_COMM_DOT[i]), 2);
574 }
575 }
576}
577
578// Runs constantly in the background, in a loop.
579void matrix_scan_user(void) {
580 static uint32_t scan_timer = 0;
581 static uint8_t last_layer = 0;
582
583 uint8_t layer = 0;
584 if(layer_state >= 0x04){
585 layer = 2;
586 } else if(layer_state >= 0x02){
587 layer = 1;
588 }
589
590 calculate_keystroke_distance();
591
592
593 #define USE_PATTERN 0
594 #define BLACK_RGB 1
595 #define COLOR_RGB 2
596 uint8_t ci; // color index
597 uint8_t *rgb;
598 uint8_t handle_type;
599 uint8_t distance;
600 for(uint8_t i = 1; i <= KEY_LED_COUNT; ++i){
601 if(USER_LED[i-1].state >= 2) continue;
602
603 handle_type = USE_PATTERN;
604 distance = DISTANCE_FROM_LAST_KEYSTROKE[i];
605
606 switch(USER_CONFIG.PATTERN_INDEX){
607 case 0: handle_type = USE_PATTERN; break;
608 case 1: handle_type = distance ? USE_PATTERN : BLACK_RGB; break;
609 case 2: handle_type = distance ? BLACK_RGB : USE_PATTERN; break;
610 case 3: handle_type = distance ? COLOR_RGB : BLACK_RGB; break;
611 case 4: handle_type = distance ? COLOR_RGB : USE_PATTERN; break;
612 case 5:
613 case 6: handle_type = distance ? COLOR_RGB : USE_PATTERN; break;
614 }
615 switch(handle_type){
616 case USE_PATTERN: unset_user_led_rgb(i); break;
617 case BLACK_RGB: set_user_led_rgb(i, 0, 0, 0); break;
618 case COLOR_RGB:
619 ci = (DISTANCE_FROM_LAST_KEYSTROKE[i] * COLOR_PATTERN_RGB_COUNT /
620 USER_CONFIG.WAVE_FRONT_WIDTH) % COLOR_PATTERN_RGB_COUNT;
621 rgb = &COLOR_PATTERNS[USER_CONFIG.COLOR_PATTERN_INDEX][ci][0];
622
623 set_user_led_rgb(i, rgb[0], rgb[1], rgb[2]);
624 break;
625 }
626 }
627
628
629 // could be moved to process_record_user()
630 if(layer != last_layer){
631
632 static uint8_t QWEASDP[] = {
633 KC_Q, KC_W, KC_E, KC_A, KC_S, KC_D, KC_P,
634 };
635 static uint8_t YUIOHJKL[] = {
636 KC_Y, KC_U, KC_I, KC_O, KC_H, KC_J, KC_K, KC_L,
637 };
638
639 switch(last_layer){
640 case 1:
641 for(uint8_t i = 0; i < 7; ++i){
642 unset_indicator_led_rgb(ktli(QWEASDP[i]), 1);
643 }
644 break;
645 case 2:
646 for(uint8_t i = 0; i < 6; ++i){
647 unset_indicator_led_rgb(ktli(QWEASDP[i]), 2);
648 }
649 for(uint8_t i = 0; i < 8; ++i){
650 unset_indicator_led_rgb(ktli(YUIOHJKL[i]), 2);
651 }
652 unset_indicator_led_rgb(ktli(KC_TAB), 2);
653 unset_indicator_led_rgb(ktli(KC_CAPS), 2);
654 break;
655 }
656
657
658 switch(layer){
659 case 1:
660 for(uint8_t i = 0; i < 7; ++i){
661 set_indicator_led_rgb(ktli(QWEASDP[i]), 1, 255, 0, 0);
662 }
663 break;
664 case 2:
665 for(uint8_t i = 0; i < 6; ++i){
666 set_indicator_led_rgb(ktli(QWEASDP[i]), 2, 0, 255, 0);
667 }
668 for(uint8_t i = 0; i < 8; ++i){
669 set_indicator_led_rgb(ktli(YUIOHJKL[i]), 2, 0, 255, 0);
670 }
671 set_indicator_led_rgb(ktli(KC_TAB), 2, 0, 255, 0);
672 set_indicator_led_rgb(ktli(KC_CAPS), 2, 0, 255, 0);
673 break;
674 }
675
676 refresh_pattern_indicators();
677 refresh_color_pattern_indicators();
678 last_layer = layer;
679 }
680
681
682 switch(layer){
683 case 0:
684 if(timer_elapsed32(scan_timer) > 2000){
685 scan_timer = timer_read32();
686 } else if(timer_elapsed32(scan_timer) > 1000){
687 // set_user_led_rgb(ktli(KC_F5), 255, 255, 255);
688 }
689 break;
690 case 1:
691 break;
692 case 2:
693 break;
694 }
695
696};
697
698#define MODS_SHIFT (keyboard_report->mods & MOD_BIT(KC_LSHIFT) || keyboard_report->mods & MOD_BIT(KC_RSHIFT))
699#define MODS_CTRL (keyboard_report->mods & MOD_BIT(KC_LCTL) || keyboard_report->mods & MOD_BIT(KC_RCTRL))
700#define MODS_ALT (keyboard_report->mods & MOD_BIT(KC_LALT) || keyboard_report->mods & MOD_BIT(KC_RALT))
701
702bool process_record_user(uint16_t keycode, keyrecord_t *record) {
703 static uint32_t key_timer;
704
705
706 switch (keycode) {
707 case L_BRI:
708 if (record->event.pressed) {
709 if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX;
710 else gcr_desired += LED_GCR_STEP;
711 if (led_animation_breathing) gcr_breathe = gcr_desired;
712 }
713 return false;
714 case L_BRD:
715 if (record->event.pressed) {
716 if (LED_GCR_STEP > gcr_desired) gcr_desired = 0;
717 else gcr_desired -= LED_GCR_STEP;
718 if (led_animation_breathing) gcr_breathe = gcr_desired;
719 }
720 return false;
721 case L_PTN:
722 if (record->event.pressed) {
723 if (led_animation_id == led_setups_count - 1) led_animation_id = 0;
724 else led_animation_id++;
725 }
726 return false;
727 case L_PTP:
728 if (record->event.pressed) {
729 if (led_animation_id == 0) led_animation_id = led_setups_count - 1;
730 else led_animation_id--;
731 }
732 return false;
733 case L_PSI:
734 if (record->event.pressed) {
735 led_animation_speed += ANIMATION_SPEED_STEP;
736 }
737 return false;
738 case L_PSD:
739 if (record->event.pressed) {
740 led_animation_speed -= ANIMATION_SPEED_STEP;
741 if (led_animation_speed < 0) led_animation_speed = 0;
742 }
743 return false;
744 case L_T_MD:
745 if (record->event.pressed) {
746 led_lighting_mode++;
747 if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL;
748 }
749 return false;
750 case L_T_ONF:
751 if (record->event.pressed) {
752 led_enabled = !led_enabled;
753 I2C3733_Control_Set(led_enabled);
754 }
755 return false;
756 case L_ON:
757 if (record->event.pressed) {
758 led_enabled = 1;
759 I2C3733_Control_Set(led_enabled);
760 }
761 return false;
762 case L_OFF:
763 if (record->event.pressed) {
764 led_enabled = 0;
765 I2C3733_Control_Set(led_enabled);
766 }
767 return false;
768 case L_T_BR:
769 if (record->event.pressed) {
770 led_animation_breathing = !led_animation_breathing;
771 if (led_animation_breathing) {
772 gcr_breathe = gcr_desired;
773 led_animation_breathe_cur = BREATHE_MIN_STEP;
774 breathe_dir = 1;
775 }
776 }
777 return false;
778 case L_T_PTD:
779 if (record->event.pressed) {
780 led_animation_direction = !led_animation_direction;
781 }
782 return false;
783 case U_T_AUTO:
784 if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
785 TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode");
786 }
787 return false;
788 case U_T_AGCR:
789 if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
790 TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode");
791 }
792 return false;
793 case DBG_TOG:
794 if (record->event.pressed) {
795 TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode");
796 }
797 return false;
798 case DBG_MTRX:
799 if (record->event.pressed) {
800 TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix");
801 }
802 return false;
803 case DBG_KBD:
804 if (record->event.pressed) {
805 TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard");
806 }
807 return false;
808 case DBG_MOU:
809 if (record->event.pressed) {
810 TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse");
811 }
812 return false;
813 case MD_BOOT:
814 if (record->event.pressed) {
815 key_timer = timer_read32();
816 } else {
817 if (timer_elapsed32(key_timer) >= 500) {
818 reset_keyboard();
819 }
820 }
821 return false;
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839 case L_SP_PR: // previous dripple pattern
840 case L_SP_NE: // next dripple pattern
841 if (record->event.pressed) {
842#define PATTERN_COUNT 7
843 uint8_t incre = keycode == L_SP_PR ? PATTERN_COUNT-1 : 1;
844 USER_CONFIG.PATTERN_INDEX += incre;
845 USER_CONFIG.PATTERN_INDEX %= PATTERN_COUNT;
846
847 if(USER_CONFIG.PATTERN_INDEX <= 4){
848 USER_CONFIG.TRAVEL_DISTANCE = 25;
849 USER_CONFIG.COLOR_PATTERN_INDEX = 0;
850 USER_CONFIG.WAVE_PERIOD = 50;
851 }
852
853 switch(USER_CONFIG.PATTERN_INDEX){
854 case 0: // None
855 break;
856 case 1: // background off, wave on
857 USER_CONFIG.WAVE_FRONT_WIDTH = 2;
858 break;
859 case 2: // background on, wave off
860 USER_CONFIG.WAVE_FRONT_WIDTH = 5;
861 break;
862 case 3: // background off, rainbow wave
863 USER_CONFIG.WAVE_FRONT_WIDTH = 10;
864 break;
865 case 4: // background on, rainbow wave
866 USER_CONFIG.WAVE_FRONT_WIDTH = 10;
867 break;
868 case 5:
869 USER_CONFIG.WAVE_FRONT_WIDTH = 10;
870
871 USER_CONFIG.COLOR_PATTERN_INDEX = 2;
872 USER_CONFIG.TRAVEL_DISTANCE = 0;
873 USER_CONFIG.WAVE_PERIOD = 100;
874 break;
875 case 6:
876 USER_CONFIG.WAVE_FRONT_WIDTH = 25;
877
878 USER_CONFIG.COLOR_PATTERN_INDEX = 3;
879 USER_CONFIG.TRAVEL_DISTANCE = 2;
880 USER_CONFIG.WAVE_PERIOD = 10;
881 break;
882 }
883
884 // remove effect after changing pattern
885 for(int i = 0; i < KEY_STROKES_LENGTH; ++i){
886 KEY_STROKES[i].alive = 0;
887 }
888 refresh_pattern_indicators();
889 refresh_color_pattern_indicators();
890 }
891 return false;
892 case L_SP_WD:
893 case L_SP_NW:
894 if(record->event.pressed){
895 short incre = keycode == L_SP_WD ? 1 : -1;
896 USER_CONFIG.WAVE_FRONT_WIDTH += incre;
897 if(USER_CONFIG.WAVE_FRONT_WIDTH < 1){
898 USER_CONFIG.WAVE_FRONT_WIDTH = 1;
899 }
900 }
901 return false;
902 case L_SP_FA:
903 case L_SP_SL:
904 if(record->event.pressed){
905 short incre = keycode == L_SP_FA ? -1 : 1;
906
907 USER_CONFIG.WAVE_PERIOD += 10 * incre;
908 if(USER_CONFIG.WAVE_PERIOD < 10){
909 USER_CONFIG.WAVE_PERIOD = 10;
910 }
911 }
912 return false;
913 // these are the keys not in range 0x04 - 0x52
914 case L_CP_PR:
915 case L_CP_NX:
916 if(record->event.pressed){
917 uint8_t incre = keycode == L_CP_PR ? COLOR_PATTERNS_COUNT - 1 : 1;
918 USER_CONFIG.COLOR_PATTERN_INDEX += incre;
919 USER_CONFIG.COLOR_PATTERN_INDEX %= COLOR_PATTERNS_COUNT;
920 refresh_color_pattern_indicators();
921 }
922 return false;
923 default:
924 if (record->event.pressed){
925 uint8_t led_id = ktli(keycode);
926 if(led_id){
927 for(int i = 0; i < KEY_STROKES_LENGTH; ++i){
928 if(!KEY_STROKES[i].alive){
929 KEY_STROKES[i].alive = 1;
930 KEY_STROKES[i].led_id = led_id;
931 KEY_STROKES[i].time = timer_read32();
932 break;
933 }
934 }
935 }
936 }
937 return true; //Process all other keycodes normally
938 }
939}