]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c
0bdc1521401670a87d820574433457cece03af25
[qmk_firmware.git] / keyboards / massdrop / ctrl / keymaps / responsive_pattern / keymap.c
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
16 extern issi3733_led_t *lede;
17 extern issi3733_led_t led_map[];
18 extern led_disp_t disp;
19
20 enum 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
57 keymap_config_t keymap_config;
58
59 const 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
97 uint8_t KEYCODE_TO_LED_ID[256];
98 uint8_t DISTANCE_MAP[KEY_LED_COUNT+1][KEY_LED_COUNT+1];
99 struct 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
108 struct {
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
122 uint8_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.
135 static 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
159 static 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 }
198 void 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
204 uint8_t led_enabled;
205 float led_animation_speed;
206 uint8_t led_animation_direction;
207 uint8_t led_animation_orientation;
208 uint8_t led_animation_breathing;
209 uint8_t led_animation_breathe_cur;
210 uint8_t breathe_step;
211 uint8_t breathe_dir;
212 uint64_t led_next_run;
213
214 uint8_t led_animation_id;
215 uint8_t led_lighting_mode;
216
217 issi3733_led_t *led_cur;
218 uint8_t led_per_run;
219 float breathe_mult;
220
221 // overrided /tmk_core/protocol/arm_atsam/led_matrix.c: line 484
222 void 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
228 void 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
426 struct {
427     bool alive;
428     uint8_t led_id;
429     uint32_t time;
430 } KEY_STROKES[KEY_STROKES_LENGTH] = {{}};
431
432
433
434
435 void 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
443 uint8_t DISTANCE_FROM_LAST_KEYSTROKE[KEY_LED_COUNT+1];
444 void 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
487 static 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 };
518 static const uint8_t COLOR_PATTERNS_COUNT = (
519         sizeof(COLOR_PATTERNS) / sizeof(COLOR_PATTERNS[0]));
520
521 void 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 }
527 void unset_user_led_rgb(uint8_t i){
528     USER_LED[i-1].state = 0;
529 }
530 void 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 }
537 void unset_indicator_led_rgb(uint8_t i, uint8_t layer){
538     USER_LED[i-1].state &= ~(1 << layer);
539 }
540
541 void 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 }
560 void 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.
579 void 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  (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT))
699 #define MODS_CTRL  (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL))
700 #define MODS_ALT  (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT))
701
702 bool 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 }