]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/quantum.c
Merge branch 'master' of https://github.com/jackhumbert/qmk_firmware
[qmk_firmware.git] / quantum / quantum.c
1 #include "quantum.h"
2 #include "timer.h"
3
4 __attribute__ ((weak))
5 void matrix_init_kb(void) {}
6
7 __attribute__ ((weak))
8 void matrix_scan_kb(void) {}
9
10 __attribute__ ((weak))
11 bool process_action_kb(keyrecord_t *record) {
12   return true;
13 }
14
15 __attribute__ ((weak))
16 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
17   return process_record_user(keycode, record);
18 }
19
20 __attribute__ ((weak))
21 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
22   return true;
23 }
24
25 __attribute__ ((weak))
26 void leader_start(void) {}
27
28 __attribute__ ((weak))
29 void leader_end(void) {}
30
31 uint8_t starting_note = 0x0C;
32 int offset = 7;
33
34
35 #ifdef AUDIO_ENABLE
36   bool music_activated = false;
37
38 // music sequencer
39 static bool music_sequence_recording = false;
40 static bool music_sequence_playing = false;
41 static float music_sequence[16] = {0};
42 static uint8_t music_sequence_count = 0;
43 static uint8_t music_sequence_position = 0;
44
45 static uint16_t music_sequence_timer = 0;
46 static uint16_t music_sequence_interval = 100;
47
48 #endif
49
50 #ifdef MIDI_ENABLE
51   bool midi_activated = false;
52 #endif
53
54 // Leader key stuff
55 bool leading = false;
56 uint16_t leader_time = 0;
57
58 uint16_t leader_sequence[3] = {0, 0, 0};
59 uint8_t leader_sequence_size = 0;
60
61 // Chording stuff
62 #define CHORDING_MAX 4
63 bool chording = false;
64
65 uint8_t chord_keys[CHORDING_MAX] = {0};
66 uint8_t chord_key_count = 0;
67 uint8_t chord_key_down = 0;
68
69 #ifdef UNICODE_ENABLE
70   static uint8_t input_mode;
71 #endif
72
73 static bool shift_interrupted[2] = {0, 0};
74
75 bool keys_chord(uint8_t keys[]) {
76   uint8_t keys_size = sizeof(keys)/sizeof(keys[0]);
77   bool pass = true;
78   uint8_t in = 0;
79   for (uint8_t i = 0; i < chord_key_count; i++) {
80     bool found = false;
81     for (uint8_t j = 0; j < keys_size; j++) {
82       if (chord_keys[i] == (keys[j] & 0xFF)) {
83         in++; // detects key in chord
84         found = true;
85         break;
86       }
87     }
88     if (found)
89       continue;
90     if (chord_keys[i] != 0)  {
91       pass = false; // makes sure rest are blank
92     }
93   }
94   return (pass && (in == keys_size));
95 }
96
97 #ifdef UNICODE_ENABLE
98
99 uint16_t hex_to_keycode(uint8_t hex)
100 {
101   if (hex == 0x0) {
102     return KC_0;
103   } else if (hex < 0xA) {
104     return KC_1 + (hex - 0x1);
105   } else {
106     return KC_A + (hex - 0xA);
107   }
108 }
109
110 void set_unicode_mode(uint8_t os_target)
111 {
112   input_mode = os_target;
113 }
114
115 #endif
116
117 bool process_record_quantum(keyrecord_t *record) {
118
119   /* This gets the keycode from the key pressed */
120   keypos_t key = record->event.key;
121   uint16_t keycode;
122
123   #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
124     uint8_t layer;
125
126     if (record->event.pressed) {
127       layer = layer_switch_get_layer(key);
128       update_source_layers_cache(key, layer);
129     } else {
130       layer = read_source_layers_cache(key);
131     }
132     keycode = keymap_key_to_keycode(layer, key);
133   #else
134     keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
135   #endif
136
137   if (!process_record_kb(keycode, record))
138     return false;
139
140     // This is how you use actions here
141     // if (keycode == KC_LEAD) {
142     //   action_t action;
143     //   action.code = ACTION_DEFAULT_LAYER_SET(0);
144     //   process_action(record, action);
145     //   return false;
146     // }
147
148   #ifdef MIDI_ENABLE
149     if (keycode == MI_ON && record->event.pressed) {
150       midi_activated = true;
151       music_scale_user();
152       return false;
153     }
154
155     if (keycode == MI_OFF && record->event.pressed) {
156       midi_activated = false;
157       midi_send_cc(&midi_device, 0, 0x7B, 0);
158       return false;
159     }
160
161     if (midi_activated) {
162       if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
163           if (record->event.pressed) {
164               starting_note++; // Change key
165               midi_send_cc(&midi_device, 0, 0x7B, 0);
166               // midi_send_cc(&midi_device, 1, 0x7B, 0);
167               // midi_send_cc(&midi_device, 2, 0x7B, 0);
168               // midi_send_cc(&midi_device, 3, 0x7B, 0);
169               // midi_send_cc(&midi_device, 4, 0x7B, 0);
170           }
171           return false;
172       }
173       if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) {
174           if (record->event.pressed) {
175               starting_note--; // Change key
176               midi_send_cc(&midi_device, 0, 0x7B, 0);
177               // midi_send_cc(&midi_device, 1, 0x7B, 0);
178               // midi_send_cc(&midi_device, 2, 0x7B, 0);
179               // midi_send_cc(&midi_device, 3, 0x7B, 0);
180               // midi_send_cc(&midi_device, 4, 0x7B, 0);
181           }
182           return false;
183       }
184       if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
185           offset++; // Change scale
186           midi_send_cc(&midi_device, 0, 0x7B, 0);
187           // midi_send_cc(&midi_device, 1, 0x7B, 0);
188           // midi_send_cc(&midi_device, 2, 0x7B, 0);
189           // midi_send_cc(&midi_device, 3, 0x7B, 0);
190           // midi_send_cc(&midi_device, 4, 0x7B, 0);
191           return false;
192       }
193       if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
194           offset--; // Change scale
195           midi_send_cc(&midi_device, 0, 0x7B, 0);
196           // midi_send_cc(&midi_device, 1, 0x7B, 0);
197           // midi_send_cc(&midi_device, 2, 0x7B, 0);
198           // midi_send_cc(&midi_device, 3, 0x7B, 0);
199           // midi_send_cc(&midi_device, 4, 0x7B, 0);
200           return false;
201       }
202       // basic
203       // uint8_t note = (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row);
204       // advanced
205       // uint8_t note = (starting_note + record->event.key.col + offset)+12*(MATRIX_ROWS - record->event.key.row);
206       // guitar
207       uint8_t note = (starting_note + record->event.key.col + offset)+5*(MATRIX_ROWS - record->event.key.row);
208       // violin
209       // uint8_t note = (starting_note + record->event.key.col + offset)+7*(MATRIX_ROWS - record->event.key.row);
210
211       if (record->event.pressed) {
212         // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
213         midi_send_noteon(&midi_device, 0, note, 127);
214       } else {
215         // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
216         midi_send_noteoff(&midi_device, 0, note, 127);
217       }
218
219       if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
220         return false;
221     }
222   #endif
223
224   #ifdef AUDIO_ENABLE
225     if (keycode == AU_ON && record->event.pressed) {
226       audio_on();
227       return false;
228     }
229
230     if (keycode == AU_OFF && record->event.pressed) {
231       audio_off();
232       return false;
233     }
234
235     if (keycode == AU_TOG && record->event.pressed) {
236         if (is_audio_on())
237         {
238             audio_off();
239         }
240         else
241         {
242             audio_on();
243         }
244       return false;
245     }
246
247     if (keycode == MU_ON && record->event.pressed) {
248         music_on();
249         return false;
250     }
251
252     if (keycode == MU_OFF && record->event.pressed) {
253         music_off();
254         return false;
255     }
256
257     if (keycode == MU_TOG && record->event.pressed) {
258         if (music_activated)
259         {
260             music_off();
261         }
262         else
263         {
264             music_on();
265         }
266         return false;
267     }
268
269     if (keycode == MUV_IN && record->event.pressed) {
270         voice_iterate();
271         music_scale_user();
272         return false;
273     }
274
275     if (keycode == MUV_DE && record->event.pressed) {
276         voice_deiterate();
277         music_scale_user();
278         return false;
279     }
280
281     if (music_activated) {
282
283       if (keycode == KC_LCTL && record->event.pressed) { // Start recording
284         stop_all_notes();
285         music_sequence_recording = true;
286         music_sequence_playing = false;
287         music_sequence_count = 0;
288         return false;
289       }
290
291       if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
292         stop_all_notes();
293         music_sequence_recording = false;
294         music_sequence_playing = false;
295         return false;
296       }
297
298       if (keycode == KC_LGUI && record->event.pressed) { // Start playing
299         stop_all_notes();
300         music_sequence_recording = false;
301         music_sequence_playing = true;
302         music_sequence_position = 0;
303         music_sequence_timer = 0;
304         return false;
305       }
306
307       if (keycode == KC_UP) {
308         if (record->event.pressed)
309             music_sequence_interval-=10;
310         return false;
311       }
312
313       if (keycode == KC_DOWN) {
314         if (record->event.pressed)
315             music_sequence_interval+=10;
316         return false;
317       }
318
319       float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row));
320       if (record->event.pressed) {
321         play_note(freq, 0xF);
322         if (music_sequence_recording) {
323           music_sequence[music_sequence_count] = freq;
324           music_sequence_count++;
325         }
326       } else {
327         stop_note(freq);
328       }
329
330       if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
331         return false;
332     }
333   #endif
334
335 #ifndef DISABLE_LEADER
336   // Leader key set-up
337   if (record->event.pressed) {
338     if (!leading && keycode == KC_LEAD) {
339       leader_start();
340       leading = true;
341       leader_time = timer_read();
342       leader_sequence_size = 0;
343       leader_sequence[0] = 0;
344       leader_sequence[1] = 0;
345       leader_sequence[2] = 0;
346       return false;
347     }
348     if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) {
349       leader_sequence[leader_sequence_size] = keycode;
350       leader_sequence_size++;
351       return false;
352     }
353   }
354 #endif
355
356 #define DISABLE_CHORDING
357 #ifndef DISABLE_CHORDING
358
359   if (keycode >= 0x5700 && keycode <= 0x57FF) {
360     if (record->event.pressed) {
361       if (!chording) {
362         chording = true;
363         for (uint8_t i = 0; i < CHORDING_MAX; i++)
364           chord_keys[i] = 0;
365         chord_key_count = 0;
366         chord_key_down = 0;
367       }
368       chord_keys[chord_key_count] = (keycode & 0xFF);
369       chord_key_count++;
370       chord_key_down++;
371       return false;
372     } else {
373       if (chording) {
374         chord_key_down--;
375         if (chord_key_down == 0) {
376           chording = false;
377           // Chord Dictionary
378           if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) {
379             register_code(KC_A);
380             unregister_code(KC_A);
381             return false;
382           }
383           for (uint8_t i = 0; i < chord_key_count; i++) {
384             register_code(chord_keys[i]);
385             unregister_code(chord_keys[i]);
386             return false;
387           }
388         }
389       }
390     }
391   }
392
393 #endif
394
395 #ifdef UNICODE_ENABLE
396
397   if (keycode > UNICODE(0) && record->event.pressed) {
398     uint16_t unicode = keycode & 0x7FFF;
399     switch(input_mode) {
400       case UC_OSX:
401         register_code(KC_LALT);
402         break;
403       case UC_LNX:
404         register_code(KC_LCTL);
405         register_code(KC_LSFT);
406         register_code(KC_U);
407         unregister_code(KC_U);
408         break;
409       case UC_WIN:
410         register_code(KC_LALT);
411         register_code(KC_PPLS);
412         unregister_code(KC_PPLS);
413         break;
414     }
415     for(int i = 3; i >= 0; i--) {
416         uint8_t digit = ((unicode >> (i*4)) & 0xF);
417         register_code(hex_to_keycode(digit));
418         unregister_code(hex_to_keycode(digit));
419     }
420     switch(input_mode) {
421       case UC_OSX:
422       case UC_WIN:
423         unregister_code(KC_LALT);
424         break;
425       case UC_LNX:
426         unregister_code(KC_LCTL);
427         unregister_code(KC_LSFT);
428         break;
429     }
430   }
431
432 #endif
433
434   switch(keycode) {
435     case KC_LSPO: {
436                     if (record->event.pressed) {
437                       shift_interrupted[0] = false;
438                       register_mods(MOD_BIT(KC_LSFT));
439                     }
440                     else {
441                       if (!shift_interrupted[0]) {
442                         register_code(KC_9);
443                         unregister_code(KC_9);
444                       }
445                       unregister_mods(MOD_BIT(KC_LSFT));
446                     }
447                     return false;
448                     break;
449                   }
450
451     case KC_RSPC: {
452                     if (record->event.pressed) {
453                       shift_interrupted[1] = false;
454                       register_mods(MOD_BIT(KC_RSFT));
455                     }
456                     else {
457                       if (!shift_interrupted[1]) {
458                         register_code(KC_0);
459                         unregister_code(KC_0);
460                       }
461                       unregister_mods(MOD_BIT(KC_RSFT));
462                     }
463                     return false;
464                     break;
465                   }
466     default: {
467                shift_interrupted[0] = true;
468                shift_interrupted[1] = true;
469                break;
470              }
471   }
472
473   return process_action_kb(record);
474 }
475
476 const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = {
477     0, 0, 0, 0, 0, 0, 0, 0,
478     0, 0, 0, 0, 0, 0, 0, 0,
479     0, 0, 0, 0, 0, 0, 0, 0,
480     0, 0, 0, 0, 0, 0, 0, 0,
481     0, 1, 1, 1, 1, 1, 1, 0,
482     1, 1, 1, 1, 0, 0, 0, 0,
483     0, 0, 0, 0, 0, 0, 0, 0,
484     0, 0, 1, 0, 1, 0, 1, 1,
485     1, 1, 1, 1, 1, 1, 1, 1,
486     1, 1, 1, 1, 1, 1, 1, 1,
487     1, 1, 1, 1, 1, 1, 1, 1,
488     1, 1, 1, 0, 0, 0, 1, 1,
489     0, 0, 0, 0, 0, 0, 0, 0,
490     0, 0, 0, 0, 0, 0, 0, 0,
491     0, 0, 0, 0, 0, 0, 0, 0,
492     0, 0, 0, 1, 1, 1, 1, 0
493 };
494
495 const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = {
496     0, 0, 0, 0, 0, 0, 0, 0,
497     KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
498     0, 0, 0, 0, 0, 0, 0, 0,
499     0, 0, 0, KC_ESC, 0, 0, 0, 0,
500     KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
501     KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
502     KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
503     KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
504     KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
505     KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
506     KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
507     KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
508     KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
509     KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
510     KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
511     KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
512 };
513
514 /* for users whose OSes are set to Colemak */
515 #if 0
516 #include "keymap_colemak.h"
517
518 const bool ascii_to_colemak_shift_lut[0x80] PROGMEM = {
519     0, 0, 0, 0, 0, 0, 0, 0,
520     0, 0, 0, 0, 0, 0, 0, 0,
521     0, 0, 0, 0, 0, 0, 0, 0,
522     0, 0, 0, 0, 0, 0, 0, 0,
523     0, 1, 1, 1, 1, 1, 1, 0,
524     1, 1, 1, 1, 0, 0, 0, 0,
525     0, 0, 0, 0, 0, 0, 0, 0,
526     0, 0, 1, 0, 1, 0, 1, 1,
527     1, 1, 1, 1, 1, 1, 1, 1,
528     1, 1, 1, 1, 1, 1, 1, 1,
529     1, 1, 1, 1, 1, 1, 1, 1,
530     1, 1, 1, 0, 0, 0, 1, 1,
531     0, 0, 0, 0, 0, 0, 0, 0,
532     0, 0, 0, 0, 0, 0, 0, 0,
533     0, 0, 0, 0, 0, 0, 0, 0,
534     0, 0, 0, 1, 1, 1, 1, 0
535 };
536
537 const uint8_t ascii_to_colemak_keycode_lut[0x80] PROGMEM = {
538     0, 0, 0, 0, 0, 0, 0, 0,
539     KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
540     0, 0, 0, 0, 0, 0, 0, 0,
541     0, 0, 0, KC_ESC, 0, 0, 0, 0,
542     KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
543     KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
544     KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
545     KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
546     KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
547     CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
548     CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
549     CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
550     KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
551     CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
552     CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
553     CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
554 };
555
556 #endif
557
558 void send_string(const char *str) {
559     while (1) {
560         uint8_t keycode;
561         uint8_t ascii_code = pgm_read_byte(str);
562         if (!ascii_code) break;
563         keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]);
564         if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) {
565             register_code(KC_LSFT);
566             register_code(keycode);
567             unregister_code(keycode);
568             unregister_code(KC_LSFT);
569         }
570         else {
571             register_code(keycode);
572             unregister_code(keycode);
573         }
574         ++str;
575     }
576 }
577
578
579 void matrix_init_quantum() {
580   matrix_init_kb();
581 }
582
583 void matrix_scan_quantum() {
584   #ifdef AUDIO_ENABLE
585   if (music_sequence_playing) {
586     if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) {
587       music_sequence_timer = timer_read();
588       stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]);
589       play_note(music_sequence[music_sequence_position], 0xF);
590       music_sequence_position = (music_sequence_position + 1) % music_sequence_count;
591     }
592   }
593
594   #endif
595
596   matrix_scan_kb();
597 }
598 #ifdef AUDIO_ENABLE
599   bool is_music_on(void) {
600       return (music_activated != 0);
601   }
602
603   void music_toggle(void) {
604       if (!music_activated) {
605           music_on();
606       } else {
607           music_off();
608       }
609   }
610
611   void music_on(void) {
612       music_activated = 1;
613       music_on_user();
614   }
615
616   void music_off(void) {
617       music_activated = 0;
618       stop_all_notes();
619   }
620
621 #endif
622
623 //------------------------------------------------------------------------------
624 // Override these functions in your keymap file to play different tunes on
625 // different events such as startup and bootloader jump
626
627 __attribute__ ((weak))
628 void startup_user() {}
629
630 __attribute__ ((weak))
631 void shutdown_user() {}
632
633 __attribute__ ((weak))
634 void music_on_user() {}
635
636 __attribute__ ((weak))
637 void audio_on_user() {}
638
639 __attribute__ ((weak))
640 void music_scale_user() {}
641
642 //------------------------------------------------------------------------------