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