]> git.donarmstrong.com Git - qmk_firmware.git/blob - users/drashna/drashna.c
Update to drashna userspace (Keymap Templating) (#2338)
[qmk_firmware.git] / users / drashna / drashna.c
1 /*
2 Copyright 2017 Christopher Courtney <drashna@live.com> @drashna
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "drashna.h"
19 #include "version.h"
20
21 #if (__has_include("secrets.h"))
22 #include "secrets.h"
23 #else
24 PROGMEM const char secret[][64] = {
25   "test1",
26   "test2",
27   "test3",
28   "test4",
29   "test5"
30 };
31 #endif
32
33 #ifdef FAUXCLICKY_ENABLE
34 float fauxclicky_pressed_note[2]  = MUSICAL_NOTE(_A6, 2);  // (_D4, 0.25);
35 float fauxclicky_released_note[2] = MUSICAL_NOTE(_A6, 2); // (_C4, 0.125);
36 #else
37 float fauxclicky_pressed[][2]             = SONG(E__NOTE(_A6)); // change to your tastes
38 float fauxclicky_released[][2]             = SONG(E__NOTE(_A6)); // change to your tastes
39 #endif 
40 bool faux_click_enabled = true;
41
42 #ifdef TAP_DANCE_ENABLE
43 //define diablo macro timer variables
44 static uint16_t diablo_timer[4];
45 static uint8_t diablo_times[] = { 0, 1, 3, 5, 10, 30 };
46 static uint8_t diablo_key_time[4];
47
48
49 bool check_dtimer(uint8_t dtimer) {
50   // has the correct number of seconds elapsed (as defined by diablo_times)
51   return (timer_elapsed(diablo_timer[dtimer]) < (diablo_key_time[dtimer] * 1000)) ? false : true;
52 };
53
54
55
56
57 // Cycle through the times for the macro, starting at 0, for disabled.
58 // Max of six values, so don't exceed
59 void diablo_tapdance_master(qk_tap_dance_state_t *state, void *user_data, uint8_t diablo_key) {
60   if (state->count >= 7) {
61     diablo_key_time[diablo_key] = diablo_times[0];
62     reset_tap_dance(state);
63   }
64   else {
65     diablo_key_time[diablo_key] = diablo_times[state->count - 1];
66   }
67 }
68
69
70 // Would rather have one function for all of this, but no idea how to do that...
71 void diablo_tapdance1(qk_tap_dance_state_t *state, void *user_data) {
72   diablo_tapdance_master(state, user_data, 0);
73 }
74
75 void diablo_tapdance2(qk_tap_dance_state_t *state, void *user_data) {
76   diablo_tapdance_master(state, user_data, 1);
77 }
78
79 void diablo_tapdance3(qk_tap_dance_state_t *state, void *user_data) {
80   diablo_tapdance_master(state, user_data, 2);
81 }
82
83 void diablo_tapdance4(qk_tap_dance_state_t *state, void *user_data) {
84   diablo_tapdance_master(state, user_data, 3);
85 }
86
87
88
89 //Tap Dance Definitions
90 qk_tap_dance_action_t tap_dance_actions[] = {
91   // tap once to disable, and more to enable timed micros
92   [TD_D3_1] = ACTION_TAP_DANCE_FN(diablo_tapdance1),
93   [TD_D3_2] = ACTION_TAP_DANCE_FN(diablo_tapdance2),
94   [TD_D3_3] = ACTION_TAP_DANCE_FN(diablo_tapdance3),
95   [TD_D3_4] = ACTION_TAP_DANCE_FN(diablo_tapdance4),
96
97 };
98 #endif
99
100 #ifdef AUDIO_ENABLE
101 float tone_qwerty[][2]       = SONG(QWERTY_SOUND);
102 float tone_dvorak[][2]       = SONG(DVORAK_SOUND);
103 float tone_colemak[][2]      = SONG(COLEMAK_SOUND);
104 float tone_workman[][2]      = SONG(PLOVER_SOUND);
105 float tone_hackstartup[][2]  = SONG(ONE_UP_SOUND);
106 #endif
107
108
109 // Add reconfigurable functions here, for keymap customization
110 // This allows for a global, userspace functions, and continued
111 // customization of the keymap.  Use _keymap instead of _user
112 // functions in the keymaps
113 __attribute__ ((weak))
114 void matrix_init_keymap(void) {}
115
116 __attribute__ ((weak))
117 void matrix_scan_keymap(void) {}
118
119 __attribute__ ((weak))
120 bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
121   return true;
122 }
123
124 __attribute__ ((weak))
125 uint32_t layer_state_set_keymap (uint32_t state) {
126   return state;
127 }
128
129 __attribute__ ((weak))
130 void led_set_keymap(uint8_t usb_led) {}
131
132 bool is_overwatch = false;
133 #ifdef RGBLIGHT_ENABLE
134 bool rgb_layer_change = true;
135 #endif
136
137
138
139
140 // Call user matrix init, set default RGB colors and then
141 // call the keymap's init function
142 void matrix_init_user(void) {
143 #ifdef RGBLIGHT_ENABLE
144   uint8_t default_layer = eeconfig_read_default_layer();
145
146   rgblight_enable();
147
148   if (true) {
149     if (default_layer & (1UL << _COLEMAK)) {
150       rgblight_set_magenta;
151     }
152     else if (default_layer & (1UL << _DVORAK)) {
153       rgblight_set_green;
154     }
155     else if (default_layer & (1UL << _WORKMAN)) {
156       rgblight_set_purple;
157     }
158     else {
159       rgblight_set_teal;
160     }
161   }
162   else
163   {
164     rgblight_set_red;
165     rgblight_mode(5);
166   }
167 #endif
168 #ifdef AUDIO_ENABLE
169 //  wait_ms(21); // gets rid of tick
170 //  stop_all_notes();
171 //  PLAY_SONG(tone_hackstartup);
172 #endif
173   matrix_init_keymap();
174 }
175 #ifdef TAP_DANCE_ENABLE
176
177 // Sends the key press to system, but only if on the Diablo layer
178 void send_diablo_keystroke(uint8_t diablo_key) {
179   if (biton32(layer_state) == _DIABLO) {
180     switch (diablo_key) {
181     case 0:
182       SEND_STRING("1");
183       break;
184     case 1:
185       SEND_STRING("2");
186       break;
187     case 2:
188       SEND_STRING("3");
189       break;
190     case 3:
191       SEND_STRING("4");
192       break;
193     }
194   }
195 }
196
197 // Checks each of the 4 timers/keys to see if enough time has elapsed
198 // Runs the "send string" command if enough time has passed, and resets the timer.
199 void run_diablo_macro_check(void) {
200   uint8_t dtime;
201
202   for (dtime = 0; dtime < 4; dtime++) {
203     if (check_dtimer(dtime) && diablo_key_time[dtime]) {
204       diablo_timer[dtime] = timer_read();
205       send_diablo_keystroke(dtime);
206     }
207   }
208
209 }
210 #endif
211 // No global matrix scan code, so just run keymap's matix
212 // scan function
213 void matrix_scan_user(void) {
214 #ifdef TAP_DANCE_ENABLE  // Run Diablo 3 macro checking code.
215   run_diablo_macro_check();
216 #endif
217   matrix_scan_keymap();
218 }
219
220 void led_set_user(uint8_t usb_led) {
221   led_set_keymap(usb_led);
222 }
223
224
225
226 void persistent_default_layer_set(uint16_t default_layer) {
227   eeconfig_update_default_layer(default_layer);
228   default_layer_set(default_layer);
229 }
230
231 // Defines actions tor my global custom keycodes. Defined in drashna.h file
232 // Then runs the _keymap's recod handier if not processed here
233 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
234
235 #ifdef CONSOLE_ENABLE
236   xprintf("KL: row: %u, column: %u, pressed: %u\n", record->event.key.col, record->event.key.row, record->event.pressed);
237 #endif
238
239 #ifdef AUDIO_ENABLE
240   if (faux_click_enabled) {
241     if (record->event.pressed) {
242       PLAY_SONG(fauxclicky_pressed);
243     } else {
244       stop_note(NOTE_A6);
245       PLAY_SONG(fauxclicky_released);
246     }
247   }
248 #endif
249
250   switch (keycode) {
251   case KC_QWERTY:
252     if (record->event.pressed) {
253 #ifdef AUDIO_ENABLE
254       PLAY_SONG(tone_qwerty);
255 #endif
256       persistent_default_layer_set(1UL << _QWERTY);
257     }
258     return false;
259     break;
260   case KC_COLEMAK:
261     if (record->event.pressed) {
262 #ifdef AUDIO_ENABLE
263       PLAY_SONG(tone_colemak);
264 #endif
265       persistent_default_layer_set(1UL << _COLEMAK);
266     }
267     return false;
268     break;
269   case KC_DVORAK:
270     if (record->event.pressed) {
271 #ifdef AUDIO_ENABLE
272       PLAY_SONG(tone_dvorak);
273 #endif
274       persistent_default_layer_set(1UL << _DVORAK);
275     }
276     return false;
277     break;
278   case KC_WORKMAN:
279     if (record->event.pressed) {
280 #ifdef AUDIO_ENABLE
281       PLAY_SONG(tone_workman);
282 #endif
283       persistent_default_layer_set(1UL << _WORKMAN);
284     }
285     return false;
286     break;
287   case LOWER:
288     if (record->event.pressed) {
289       layer_on(_LOWER);
290       update_tri_layer(_LOWER, _RAISE, _ADJUST);
291     }
292     else {
293       layer_off(_LOWER);
294       update_tri_layer(_LOWER, _RAISE, _ADJUST);
295     }
296     return false;
297     break;
298   case RAISE:
299     if (record->event.pressed) {
300       layer_on(_RAISE);
301       update_tri_layer(_LOWER, _RAISE, _ADJUST);
302     }
303     else {
304       layer_off(_RAISE);
305       update_tri_layer(_LOWER, _RAISE, _ADJUST);
306     }
307     return false;
308     break;
309   case ADJUST:
310     if (record->event.pressed) {
311       layer_on(_ADJUST);
312     }
313     else {
314       layer_off(_ADJUST);
315     }
316     return false;
317     break;
318 #if !(defined(KEYBOARD_orthodox_rev1) || defined(KEYBOARD_orthodox_rev3) || defined(KEYBOARD_ergodox_ez))
319   case KC_OVERWATCH:
320     if (record->event.pressed) {
321       is_overwatch = !is_overwatch;
322     }
323 #ifdef RGBLIGHT_ENABLE
324     is_overwatch ? rgblight_mode(17) : rgblight_mode(18);
325 #endif
326     return false;
327     break;
328   case KC_SALT:
329     if (!record->event.pressed) {
330       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
331       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
332       wait_ms(50);
333       SEND_STRING("Salt, salt, salt...");
334       register_code(KC_ENTER);
335       unregister_code(KC_ENTER);
336     }
337     return false;
338     break;
339   case KC_MORESALT:
340     if (!record->event.pressed) {
341       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
342       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
343       wait_ms(50);
344       SEND_STRING("Please sir, can I have some more salt?!");
345       register_code(KC_ENTER);
346       unregister_code(KC_ENTER);
347     }
348     return false;
349     break;
350   case KC_SALTHARD:
351     if (!record->event.pressed) {
352       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
353       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
354       wait_ms(50);
355       SEND_STRING("Your salt only makes me harder, and even more aggressive!");
356       register_code(KC_ENTER);
357       unregister_code(KC_ENTER);
358     }
359     return false;
360     break;
361   case KC_GOODGAME:
362     if (!record->event.pressed) {
363       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
364       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
365       wait_ms(50);
366       SEND_STRING("Good game, everyone!");
367       register_code(KC_ENTER);
368       unregister_code(KC_ENTER);
369     }
370     return false;
371     break;
372   case KC_GLHF:
373     if (!record->event.pressed) {
374       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
375       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
376       wait_ms(50);
377       SEND_STRING("Good luck, have fun!!!");
378       register_code(KC_ENTER);
379       unregister_code(KC_ENTER);
380     }
381     return false;
382     break;
383   case KC_SYMM:
384     if (!record->event.pressed) {
385       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
386       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
387       wait_ms(50);
388       SEND_STRING("Left click to win!");
389       register_code(KC_ENTER);
390       unregister_code(KC_ENTER);
391     }
392     return false;
393     break;
394   case KC_JUSTGAME:
395     if (!record->event.pressed) {
396       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
397       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
398       wait_ms(50);
399       SEND_STRING("It may be a game, but if you don't want to actually try, please go play AI, so that people that actually want to take the game seriously and \"get good\" have a place to do so without trolls like you throwing games.");
400       register_code(KC_ENTER);
401       unregister_code(KC_ENTER);
402     }
403     return false;
404     break;
405   case KC_TORB:
406     if (!record->event.pressed) {
407       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
408       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
409       wait_ms(50);
410       SEND_STRING("That was positively riveting!");
411       register_code(KC_ENTER);
412       unregister_code(KC_ENTER);
413     }
414     return false;
415     break;
416   case KC_AIM:
417     if (!record->event.pressed) {
418       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
419       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
420       wait_ms(50);
421       SEND_STRING("That aim is absolutely amazing. It's almost like you're a machine!" SS_TAP(X_ENTER));
422       wait_ms(3000);
423       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
424       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
425       SEND_STRING("Wait! That aim is TOO good!  You're clearly using an aim hack! CHEATER!" SS_TAP(X_ENTER));
426     }
427     return false;
428     break;
429   case KC_C9:
430     if (!record->event.pressed) {
431       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
432       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
433       wait_ms(50);
434       SEND_STRING("OMG!!!  C9!!!");
435       register_code(KC_ENTER);
436       unregister_code(KC_ENTER);
437     }
438     return false;
439     break;
440   case KC_GGEZ:
441     if (!record->event.pressed) {
442       register_code(is_overwatch ? KC_BSPC : KC_ENTER);
443       unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
444       wait_ms(50);
445       SEND_STRING("That was a fantastic game, though it was a bit easy. Try harder next time!");
446       register_code(KC_ENTER);
447       unregister_code(KC_ENTER);
448     }
449     return false;
450     break;
451 #endif
452 #ifdef TAP_DANCE_ENABLE
453   case KC_DIABLO_CLEAR:  // reset all Diable timers, disabling them
454     if (record->event.pressed) {
455       uint8_t dtime;
456
457       for (dtime = 0; dtime < 4; dtime++) {
458         diablo_key_time[dtime] = diablo_times[0];
459       }
460     }
461     return false;
462     break;
463 #endif
464   case KC_MAKE:
465     if (!record->event.pressed) {
466       SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP
467 #if  (defined(BOOTLOADER_DFU) || defined(BOOTLOADER_LUFA_DFU) || defined(BOOTLOADER_QMK_DFU))
468        ":dfu"
469 #elif defined(BOOTLOADER_HALFKAY)
470       ":teensy"
471 //#elif defined(BOOTLOADER_CATERINA)
472 //       ":avrdude"
473 #endif
474         SS_TAP(X_ENTER));
475     }
476     return false;
477     break;
478   case KC_RESET:
479     if (!record->event.pressed) {
480 #ifdef RGBLIGHT_ENABLE
481       rgblight_enable();
482       rgblight_mode(1);
483       rgblight_setrgb(0xff, 0x00, 0x00);
484 #endif
485       reset_keyboard();
486     }
487     return false;
488     break;
489   case EPRM:
490     if (record->event.pressed) {
491       eeconfig_init();
492     }
493     return false;
494     break;
495   case VRSN:
496     if (record->event.pressed) {
497       SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
498     }
499     return false;
500     break;
501   case KC_SECRET_1 ... KC_SECRET_5:
502     if (!record->event.pressed) {
503       send_string_P(secret[keycode - KC_SECRET_1]);
504     }
505     return false;
506     break;
507   case KC_FXCL:
508     if (!record->event.pressed) {
509       faux_click_enabled = !faux_click_enabled;
510     }
511     return false;
512     break;
513   case KC_RGB_T:  // Because I want the option to go back to normal RGB mode rather than always layer indication
514 #ifdef RGBLIGHT_ENABLE
515     if (record->event.pressed) {
516       rgb_layer_change = !rgb_layer_change;
517     }
518 #endif
519     return false;
520     break;
521 #ifdef RGBLIGHT_ENABLE
522   case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // quantum_keycodes.h L400 for definitions
523     if (record->event.pressed) { //This disrables layer indication, as it's assumed that if you're changing this ... you want that disabled
524       rgb_layer_change = false;
525     }
526     return true;
527     break;
528 #endif
529   }
530   return process_record_keymap(keycode, record);
531 }
532
533 // Runs state check and changes underglow color and animation
534 // on layer change, no matter where the change was initiated
535 // Then runs keymap's layer change check
536 uint32_t layer_state_set_user(uint32_t state) {
537 #ifdef RGBLIGHT_ENABLE
538   uint8_t default_layer = eeconfig_read_default_layer();
539   if (rgb_layer_change) {
540     switch (biton32(state)) {
541     case _NAV:
542       rgblight_set_blue;
543       rgblight_mode(1);
544       break;
545     case _SYMB:
546       rgblight_set_blue;
547       rgblight_mode(2);
548       break;
549     case _MOUS:
550       rgblight_set_yellow;
551       rgblight_mode(1);
552       break;
553     case _MACROS:
554       rgblight_set_orange;
555       is_overwatch ? rgblight_mode(17) : rgblight_mode(18);
556       break;
557     case _MEDIA:
558       rgblight_set_green;
559       rgblight_mode(22);
560       break;
561     case _GAMEPAD:
562       rgblight_set_orange;
563       rgblight_mode(17);
564       break;
565     case _DIABLO:
566       rgblight_set_red;
567       rgblight_mode(5);
568       break;
569     case _RAISE:
570       rgblight_set_yellow;
571       rgblight_mode(5);
572       break;
573     case _LOWER:
574       rgblight_set_orange;
575       rgblight_mode(5);
576       break;
577     case _ADJUST:
578       rgblight_set_red;
579       rgblight_mode(23);
580       break;
581     case _COVECUBE:
582       rgblight_set_green;
583       rgblight_mode(2);
584       break;
585     default:
586       if (default_layer & (1UL << _COLEMAK)) {
587         rgblight_set_magenta;
588       }
589       else if (default_layer & (1UL << _DVORAK)) {
590         rgblight_set_green;
591       }
592       else if (default_layer & (1UL << _WORKMAN)) {
593         rgblight_set_purple;
594       }
595       else {
596         rgblight_set_teal;
597       }
598       rgblight_mode(1);
599       break;
600     }
601   }
602 #endif
603   return layer_state_set_keymap (state);
604 }
605
606