]> git.donarmstrong.com Git - qmk_firmware.git/blob - users/arkag/arkag.c
Remove redundant KC_TRNS and KC_NO fillers in userspace (#5140)
[qmk_firmware.git] / users / arkag / arkag.c
1 #include "arkag.h"
2
3 /*
4  Current Layout and Keeb:
5  https://github.com/arkag/qmk_firmware/blob/master/keyboards/mechmini/v2/keymaps/arkag/keymap.c
6 */
7
8 // Start: Written by konstantin: vomindoraan
9 #include <ctype.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 void send_unicode_hex_string(const char *str) {
14   if (!str) { return; } // Saftey net
15   while (*str) {
16     // Find the next code point (token) in the string
17     for (; *str == ' '; str++);
18     size_t n = strcspn(str, " "); // Length of the current token
19     char code_point[n+1];
20     strncpy(code_point, str, n);
21     code_point[n] = '\0'; // Make sure it's null-terminated
22
23     // Normalize the code point: make all hex digits lowercase
24     for (char *p = code_point; *p; p++) {
25             *p = tolower(*p);
26     }
27
28     // Send the code point as a Unicode input string
29     unicode_input_start();
30     send_string(code_point);
31     unicode_input_finish();
32     str += n; // Move to the first ' ' (or '\0') after the current token
33   }
34 }
35 // End: Written by konstantin: vomindoraan
36
37 // Start: Written by Chris Lewis
38 #ifndef MIN
39 #define MIN(a,b) (((a)<(b))?(a):(b))
40 #endif
41 #ifndef MAX
42 #define MAX(a,b) (((a)>(b))?(a):(b))
43 #endif
44
45 #define TYPING_SPEED_MAX_VALUE 200
46 uint8_t typing_speed = 0;
47
48 void velocikey_accelerate() {
49     if (typing_speed < TYPING_SPEED_MAX_VALUE) typing_speed += (TYPING_SPEED_MAX_VALUE / 50);
50 }
51
52 void velocikey_decelerate() {
53   static uint16_t decay_timer = 0;
54
55   if (timer_elapsed(decay_timer) > 500 || decay_timer == 0) {
56     if (typing_speed > 0) typing_speed -= 1;
57     //Decay a little faster at half of max speed
58     if (typing_speed > TYPING_SPEED_MAX_VALUE / 2) typing_speed -= 1;
59     //Decay even faster at 3/4 of max speed
60     if (typing_speed > TYPING_SPEED_MAX_VALUE / 4 * 3) typing_speed -= 3;
61     decay_timer = timer_read();
62   }
63 }
64
65 uint8_t velocikey_match_speed(uint8_t minValue, uint8_t maxValue) {
66   return MAX(minValue, maxValue - (maxValue - minValue) * ((float)typing_speed / TYPING_SPEED_MAX_VALUE));
67 }
68 // End: Written by Chris Lewis
69
70 uint8_t       current_os,
71               mod_primary_mask,
72               fade_interval,
73               num_extra_flashes_off = 0;
74 Color         underglow,
75               flash_color,
76               saved_color,
77               hsv_none      = {0,0,0};
78 flashState    flash_state   = no_flash;
79 fadeState     fade_state    = add_fade;
80 activityState state         = boot;
81
82 void set_color (Color new, bool update) {
83   rgblight_sethsv_eeprom_helper(new.h, new.s, new.v, update);
84 }
85
86 void save_color(Color to_save) {
87   saved_color = to_save;
88 }
89
90 void reset_color(void) {
91   underglow = saved_color;
92 }
93
94 Color mod_color(Color current_color, bool should_add, uint8_t change_amount) {
95   save_color(underglow);
96   int addlim = 359 - change_amount;
97   int sublim = change_amount;
98   int leftovers;
99   if (should_add) {
100     if (current_color.h <= addlim) {
101       current_color.h += change_amount;
102     } else {
103       leftovers = (359 + change_amount) % 359;
104       current_color.h  = 0 + leftovers;
105     }
106   } else {
107     if (current_color.h >= sublim) {
108       current_color.h -= change_amount;
109     } else {
110       leftovers = change_amount - current_color.h;
111       current_color.h  = 359 - leftovers;
112     }
113   }
114   return current_color;
115 }
116
117 void check_state (void) {
118   static uint16_t active_timer;
119   if (!active_timer) {active_timer = timer_read();}
120   static bool activated, deactivated, slept;
121   switch (state) {
122   case active:
123     if (!activated) {
124       if (slept) {rgblight_mode_noeeprom(1);}
125       activated = true;
126       deactivated = false;
127       slept = false;
128     }
129     fade_interval = velocikey_match_speed(1, 25);
130     if (timer_elapsed(active_timer) < INACTIVE_DELAY) {return;}
131     active_timer = timer_read();
132     state = inactive;
133     return;
134
135   case inactive:
136     if (!deactivated) {
137       deactivated = true;
138       activated = false;
139       slept = false;
140     }
141     velocikey_decelerate();
142     fade_interval = velocikey_match_speed(1, 25);
143     if (timer_elapsed(active_timer) < SLEEP_DELAY) {return;}
144     state = sleeping;
145     return;
146
147   case sleeping:
148     if (!slept) {
149       rgblight_mode_noeeprom(4);
150       slept = true;
151       activated = false;
152       deactivated = false;
153     }
154     return;
155
156   case boot:
157     return;
158   }
159 }
160
161 void fade_rgb (void) {
162   static uint16_t fade_timer;
163   if (state == boot) {return;}
164   if (!fade_timer) {fade_timer = timer_read();}
165   if (timer_elapsed(fade_timer) < fade_interval) {return;}
166   switch (fade_state) {
167   case add_fade:
168     if (underglow.h == 359) {
169       fade_state = sub_fade;
170       return;
171     }
172     underglow.h = underglow.h + 1;
173     break;
174
175   case sub_fade:
176     if (underglow.h == 0) {
177       fade_state = add_fade;
178       return;
179     }
180     underglow.h = underglow.h - 1;
181     break;
182   }
183   fade_timer = timer_read();
184   if (flash_state == no_flash) {
185     set_color(underglow, false);
186   }
187 }
188
189 void flash_rgb (void) {
190   static uint16_t flash_timer;
191   switch(flash_state) {
192   case no_flash:
193     return;
194
195   case flash_off:
196     if (!flash_timer) {flash_timer = timer_read();}
197     if (timer_elapsed(flash_timer) >= LED_FLASH_DELAY) {
198       set_color(hsv_none, false);
199       flash_timer = timer_read();
200       flash_state = flash_on;
201     }
202     return;
203
204   case flash_on:
205     if (timer_elapsed(flash_timer) >= LED_FLASH_DELAY) {
206       set_color(flash_color, false);
207       flash_timer = timer_read();
208       if (num_extra_flashes_off > 0) {
209         flash_state = flash_off;
210         num_extra_flashes_off--;
211       } else {
212         set_color(underglow, false);
213         flash_state = no_flash;
214       }
215     }
216     return;
217   }
218 }
219
220 void set_os (uint8_t os, bool update) {
221   current_os = os;
222   if (update) {
223     eeprom_update_byte(EECONFIG_USERSPACE, current_os);
224   }
225   switch (os) {
226   case OS_MAC:
227     set_unicode_input_mode(UC_OSX);
228     underglow = (Color){ 300, 255, 255 };
229     mod_primary_mask = MOD_GUI_MASK;
230     break;
231   case OS_WIN:
232     set_unicode_input_mode(UC_WINC);
233     underglow = (Color){ 180, 255, 255 };
234     mod_primary_mask = MOD_CTL_MASK;
235     break;
236   case OS_NIX:
237     set_unicode_input_mode(UC_LNX);
238     underglow = (Color){ 60, 255, 255 };
239     mod_primary_mask = MOD_CTL_MASK;
240     break;
241   default:
242     underglow = (Color){ 0, 0, 255 };
243     mod_primary_mask = MOD_CTL_MASK;
244   }
245   set_color(underglow, update);
246   flash_color           = underglow;
247   flash_state           = flash_off;
248   state                 = boot;
249   num_extra_flashes_off = 1;
250 }
251
252 void tap_key(uint8_t keycode) {
253   register_code(keycode);
254   unregister_code(keycode);
255 }
256
257 // register GUI if Mac or Ctrl if other
258 void pri_mod(bool press) {
259   if (press) {
260     if (current_os == OS_MAC) {
261       register_code(KC_LGUI);
262     } else {
263       register_code(KC_LCTL);
264     }
265   } else {
266     if (current_os == OS_MAC) {
267       unregister_code(KC_LGUI);
268     } else {
269       unregister_code(KC_LCTL);
270     }
271   }
272 }
273
274 // register Ctrl if Mac or GUI if other
275 void sec_mod(bool press) {
276   if (press) {
277     if (current_os == OS_MAC) {
278       register_code(KC_LCTL);
279     } else {
280       register_code(KC_LGUI);
281     }
282   } else {
283     if (current_os == OS_MAC) {
284       unregister_code(KC_LCTL);
285     } else {
286       unregister_code(KC_LGUI);
287     }
288   }
289 }
290
291 void surround_type(uint8_t num_of_chars, uint16_t keycode, bool use_shift) {
292   if (use_shift) {
293     register_code(KC_LSFT);
294   }
295   for (int i = 0; i < num_of_chars; i++) {
296     tap_key(keycode);
297   }
298   if (use_shift) {
299     unregister_code(KC_LSFT);
300   }
301   for (int i = 0; i < (num_of_chars/2); i++) {
302     tap_key(KC_LEFT);
303   }
304 }
305
306 void long_keystroke(size_t num_of_keys, uint16_t keys[]) {
307   for (int i = 0; i < num_of_keys-1; i++) {
308     register_code(keys[i]);
309   }
310   tap_key(keys[num_of_keys-1]);
311   for (int i = 0; i < num_of_keys-1; i++) {
312     unregister_code(keys[i]);
313   }
314 }
315
316 void dance_grv (qk_tap_dance_state_t *state, void *user_data) {
317   if (state->count == 1) {
318     tap_key(KC_GRV);
319   } else if (state->count == 2) {
320     surround_type(2, KC_GRAVE, false);
321   } else {
322     surround_type(6, KC_GRAVE, false);
323   }
324 }
325
326 void dance_quot (qk_tap_dance_state_t *state, void *user_data) {
327   if (state->count == 1) {
328     tap_key(KC_QUOT);
329   } else if (state->count == 2) {
330     surround_type(2, KC_QUOTE, false);
331   } else if (state->count == 3) {
332     surround_type(2, KC_QUOTE, true);
333   }
334 }
335
336 void dance_strk (qk_tap_dance_state_t *state, void *user_data) {
337   if (state->count == 1) {
338     surround_type(4, KC_TILDE, true);
339   } else if (state->count == 2) {
340     if (current_os == OS_MAC) {
341       long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_4});
342     } else if (current_os == OS_WIN) {
343       long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_S});
344     } else {
345       return;
346     }
347   }
348 }
349
350 void dance_3 (qk_tap_dance_state_t *state, void *user_data) {
351   if (state->count == 1) {
352     tap_key(KC_3);
353   } else if (state->count == 2) {
354     send_unicode_hex_string("00E8");
355   } else if (state->count == 3) {
356     send_unicode_hex_string("00E9");
357   }
358 }
359
360 void dance_c (qk_tap_dance_state_t *state, void *user_data) {
361   if (state->count == 1) {
362     tap_key(KC_C);
363   } else if (state->count == 2) {
364     send_unicode_hex_string("00E7");
365   }
366 }
367
368 void matrix_init_user(void) {
369   current_os = eeprom_read_byte(EECONFIG_USERSPACE);
370   set_os(current_os, false);
371 }
372
373 LEADER_EXTERNS();
374
375 void matrix_scan_user(void) {
376   check_state();
377   flash_rgb();
378   fade_rgb();
379   LEADER_DICTIONARY() {
380     leading = false;
381     leader_end();
382
383     // begin OS functions
384     SEQ_TWO_KEYS(KC_P, KC_B) {
385       if (current_os == OS_WIN) {
386               SEND_STRING(SS_DOWN(X_LGUI) SS_TAP(X_PAUSE) SS_UP(X_LGUI));
387       } else {
388       }
389     }
390     SEQ_THREE_KEYS(KC_C, KC_A, KC_D) {
391       if (current_os == OS_WIN) {
392               SEND_STRING(SS_DOWN(X_LCTRL) SS_DOWN(X_LALT) SS_TAP(X_DELETE) SS_UP(X_LALT) SS_UP(X_LCTRL));
393       } else {
394       }
395     }
396     SEQ_FOUR_KEYS(KC_C, KC_A, KC_L, KC_C) {
397       if (current_os == OS_WIN) {
398         SEND_STRING(SS_TAP(X_CALCULATOR));
399       } else if (current_os == OS_MAC) {
400         SEND_STRING(SS_DOWN(X_LGUI) SS_TAP(X_SPACE) SS_UP(X_LGUI) "calculator" SS_TAP(X_ENTER));
401       }
402     }
403     // end OS functions
404
405     // begin format functions
406     SEQ_ONE_KEY(KC_B) {
407       surround_type(4, KC_8, true);
408     }
409     SEQ_ONE_KEY(KC_I) {
410       surround_type(2, KC_8, true);
411     }
412     SEQ_ONE_KEY(KC_U) {
413       surround_type(4, KC_MINS, true);
414     }
415     SEQ_ONE_KEY(KC_S) {
416       surround_type(4, KC_GRAVE, true);
417     }
418     SEQ_TWO_KEYS(KC_S, KC_S) {
419       if (current_os == OS_MAC) {
420         long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_4});
421       } else if (current_os == OS_WIN) {
422         long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_S});
423       } else {
424         return;
425       }
426     }
427     SEQ_ONE_KEY(KC_C) {
428       surround_type(2, KC_GRAVE, false);
429     }
430     SEQ_TWO_KEYS(KC_C, KC_C) {
431       surround_type(6, KC_GRAVE, false);
432     }
433     // end format functions
434
435     // start fancy functions
436     SEQ_THREE_KEYS(KC_C, KC_C, KC_C) {
437       surround_type(6, KC_GRAVE, false);
438       pri_mod(true);
439       tap_key(KC_V);
440       pri_mod(false);
441       tap_key(KC_RGHT);
442       tap_key(KC_RGHT);
443       tap_key(KC_RGHT);
444       tap_key(KC_ENTER);
445     }
446     // end fancy functions
447
448     // start typing functions
449     SEQ_TWO_KEYS(KC_T, KC_M) {
450       // ™
451       send_unicode_hex_string("2122");
452     }
453     SEQ_THREE_KEYS(KC_G, KC_G, KC_T) {
454       SEND_STRING("@GrahamGoldenTech.com");
455     }
456     SEQ_THREE_KEYS(KC_L, KC_O, KC_D) {
457       // ಠ__ಠ
458       send_unicode_hex_string("0CA0 005F 005F 0CA0");
459     }
460     SEQ_FOUR_KEYS(KC_R, KC_E, KC_P, KC_O) {
461       SEND_STRING("https://github.com/qmk/qmk_firmware/tree/master/users/arkag");
462     }
463     SEQ_FOUR_KEYS(KC_F, KC_L, KC_I, KC_P) {
464       // (╯‵Д′)╯彡┻━┻
465       send_unicode_hex_string("0028 256F 2035 0414 2032 0029 256F 5F61 253B 2501 253B");
466     }
467     SEQ_FIVE_KEYS(KC_U, KC_F, KC_L, KC_I, KC_P) {
468       // ┬─┬ノ( º _ º ノ)
469       send_unicode_hex_string("252C 2500 252C 30CE 0028 0020 00BA 0020 005F 0020 00BA 0020 30CE 0029");
470     }
471     SEQ_FIVE_KEYS(KC_L, KC_E, KC_N, KC_N, KC_Y) {
472       // ( ͡° ͜ʖ ͡°)
473       send_unicode_hex_string("0028 0020 0361 00B0 0020 035C 0296 0020 0361 00B0 0029");
474     }
475     SEQ_FIVE_KEYS(KC_S, KC_H, KC_R, KC_U, KC_G) {
476       // ¯\_(ツ)_/¯
477       send_unicode_hex_string("00AF 005C 005F 0028 30C4 0029 005F 002F 00AF");
478     }
479     // end typing functions
480
481   }
482 }
483
484 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
485   switch (keycode) {
486   case M_PMOD:
487     if (record->event.pressed) {
488       pri_mod(true);
489     } else {
490       pri_mod(false);
491     }
492     return false;
493
494   case M_SMOD:
495     if (record->event.pressed) {
496       sec_mod(true);
497     } else {
498       sec_mod(false);
499     }
500     return false;
501
502   case M_OS:
503     if (record->event.pressed) {
504       set_os((current_os+1) % _OS_COUNT, true);
505     }
506     return false;
507
508   default:
509     if (record->event.pressed) {
510       state = active;
511       velocikey_accelerate();
512     }
513     return true;
514   }
515 }
516
517 //Tap Dance Definitions
518 qk_tap_dance_action_t tap_dance_actions[] = {
519   [TD_3_GRV_ACT]      = ACTION_TAP_DANCE_FN (dance_3),
520   [TD_C_CED]          = ACTION_TAP_DANCE_FN (dance_c),
521   [TD_GRV_3GRV]       = ACTION_TAP_DANCE_FN (dance_grv),
522   [TD_SING_DOUB]      = ACTION_TAP_DANCE_FN (dance_quot),
523   [TD_STRK_SHOT]      = ACTION_TAP_DANCE_FN (dance_strk),
524   [TD_HYPH_UNDR]      = ACTION_TAP_DANCE_DOUBLE (KC_MINS, LSFT(KC_MINS)),
525   [TD_BRCK_PARN_O]    = ACTION_TAP_DANCE_DOUBLE (KC_LBRC, LSFT(KC_9)),
526   [TD_BRCK_PARN_C]    = ACTION_TAP_DANCE_DOUBLE (KC_RBRC, LSFT(KC_0)),
527   [TD_LALT_RALT]      = ACTION_TAP_DANCE_DOUBLE (KC_LALT, KC_RALT),
528 };