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