summaryrefslogtreecommitdiffstats
path: root/keyboards/planck/keymaps/zach/zach_common_functions.c
blob: 2c47b228969068ab28f9d3b9b732e95eb1083b9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
#ifndef ZACH_COMMON_FUNCTIONS
#define ZACH_COMMON_FUNCTIONS
#include "eeconfig.h"
#include "action_layer.h"
#include "keymap_colemak.h"
extern keymap_config_t keymap_config;

// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
#define C(n)    RCTL(n)
#define CADKEY  RCTL(RALT(KC_DEL))

void tap(uint16_t keycode){
    register_code(keycode);
    unregister_code(keycode);
};

void persistant_default_layer_set(uint16_t default_layer){
    eeconfig_update_default_layer(default_layer);
    default_layer_set(default_layer);
};

// Automatic number generation of important keywords
enum my_keycodes{
    // Layer numbers
    _COLEMAK = 0,
    _SWCOLE,
    _RAISE,
    _LOWER,
    _ADJUST,
    _UNICODES,
    // These use process_record_user()
    COLEMAK = SAFE_RANGE,
    SWCOLE,
    LOWER,
    RAISE,
    SHFT_CAP,
    CTRLB,
    CPYPST,
    FACE,
    UNIWIN,
    UNILIN,
    DISFACE,
    TFLIP,
    TPUT,
    SHRUG,
    RANDIG,
    // Tap_Dance nums
    RAI = 0,
    LOW,
    SUP
};

#ifdef AUDIO_ENABLE
#include "audio.h"
float tone_startup[][2]         = SONG(STARTUP_SOUND);
float tone_goodbye[][2]         = SONG(GOODBYE_SOUND);
float tone_colemak[][2]         = SONG(COLEMAK_SOUND);
float tone_swcole[][2]          = SONG(QWERTY_SOUND);
float tone_capslock_on[][2]     = SONG(CAPS_LOCK_ON_SOUND);
float tone_capslock_off[][2]    = SONG(CAPS_LOCK_OFF_SOUND);
float tone_ctrl_mod[][2]        = SONG(COIN_SOUND);
float tone_copy[][2]            = SONG(SCROLL_LOCK_ON_SOUND);
float tone_paste[][2]           = SONG(SCROLL_LOCK_OFF_SOUND);
float uniwin[][2]               = SONG(UNICODE_WINDOWS);
float unilin[][2]               = SONG(UNICODE_LINUX);
#endif

#ifdef TAP_DANCE_ENABLE
#define TAPPING_TERM 200

void dance_raise_press(qk_tap_dance_state_t *state, void *user_data){// Called on each tap
  switch(state->count){      // Only turn the layer on once
    case 1:
        layer_off(_UNICODES);
        layer_on(_RAISE);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
        break;
  }
};
void dance_raise_lift(qk_tap_dance_state_t *state, void *user_data){ // Called on release
  switch(state->count){
    case 1:         // Normal action. Turn off layers
        layer_off(_RAISE);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
        layer_off(_UNICODES);
        break;
  }
};
/////////////////////////////////////////////////////////////////////
void dance_lower_press(qk_tap_dance_state_t *state, void *user_data){// Called on tap
  switch(state->count){
    case 1:         // Turn on lower
        layer_off(_UNICODES);
        layer_on(_LOWER);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
        break;
  }
};
void dance_lower_lift(qk_tap_dance_state_t *state, void *user_data){ // Called on release
  switch(state->count){
    case 1:         // Normal action. Turn off layers
        layer_off(_LOWER);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
        layer_off(_UNICODES);
        break;
    case 2:         // Turn on _UNICODES layer
        layer_off(_LOWER);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
        layer_on(_UNICODES);
        #ifdef AUDIO_ENABLE
            PLAY_NOTE_ARRAY(tone_ctrl_mod, false, 0);
        #endif
        break;
  }
};
/////////////////////////////////////////////////////////////////////
void dance_super_press(qk_tap_dance_state_t *state, void *user_data){   // Called on down
    if(state->count == 1){
        register_code(KC_LGUI);
    }
}
void dance_super_done(qk_tap_dance_state_t *state, void *user_data){    // Called on timeout
  switch(state->count){
    case 2:
        register_code(KC_LGUI);
        tap(KC_L);
        unregister_code(KC_LGUI);
        break;
  }
}
void dance_super_lift(qk_tap_dance_state_t *state, void *user_data){        // Called on up
    unregister_code(KC_LGUI);
}

qk_tap_dance_action_t tap_dance_actions[] = {
    [RAI] = ACTION_TAP_DANCE_FN_ADVANCED(dance_raise_press, NULL, dance_raise_lift),
    [LOW] = ACTION_TAP_DANCE_FN_ADVANCED(dance_lower_press, NULL, dance_lower_lift),
    [SUP] = ACTION_TAP_DANCE_FN_ADVANCED(dance_super_press, dance_super_done, dance_super_lift)
};
#endif

//#ifdef UNICODE_ENABLE
// Unicode shortcuts
#define IBANG   X(0x203D)
#define RAROW   X(0x2192)
#define LAROW   X(0x2190)
#define DEGREE  X(0x00B0)
#define OMEGA   X(0x03A9)
#define WOMEGA  X(0x03C9)
#define MICRO   X(0x00B5)
#define PLUMIN  X(0x00B1)
#define SUPA2   X(0x00B2)
#define ROMAN1  X(0x2160)
#define ROMAN2  X(0x2161)
#define ROMAN3  X(0x2162)
#define ROMAN4  X(0x2163)
#define ROMAN5  X(0x2164)
#define ROMAN6  X(0x2165)
#define ROMAN7  X(0x2166)
#define roman1  X(0x2170)
#define roman2  X(0x2171)
#define roman3  X(0x2172)
#define roman4  X(0x2173)
#define roman5  X(0x2174)
#define roman6  X(0x2175)
#define roman7  X(0x2176)

#ifdef UNICODEMAP_ENABLE        // For Unicode characters larger than 0x8000. Send with X(<unicode>)
enum Ext_Unicode{
    PENGUIN = 0,
    BOAR,
    MONKEY,
    DRAGON,
    CHICK,
    TUMBLER
};
const uint32_t PROGMEM unicode_map[] = {
    [PENGUIN]   = 0x1F427,
    [BOAR]      = 0x1F417,
    [MONKEY]    = 0x1F412,
    [DRAGON]    = 0x1F409,
    [CHICK]     = 0x1F425,
    [TUMBLER]   = 0x1F943
};
#define PENGY   X(PENGUIN)
#define BOARY   X(BOAR)
#define MNKY    X(MONKEY)
#define DRGN    X(DRAGON)
#define DUCK    X(CHICK)
#define TMBL    X(TUMBLER)
#endif

//#endif

static uint16_t key_timer;
static uint8_t  caps_status = 0;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {
    case COLEMAK:
        if(record->event.pressed){
            persistant_default_layer_set(1UL<<_COLEMAK);
            #ifdef AUDIO_ENABLE
              PLAY_NOTE_ARRAY(tone_colemak, false, 0);
            #endif
        }
        return false;
        break;
    case SWCOLE:
        if(record->event.pressed){
            persistant_default_layer_set(1UL<<_SWCOLE);
            #ifdef AUDIO_ENABLE
              PLAY_NOTE_ARRAY(tone_swcole, false, 0);
            #endif
        }
        return false;
        break;
    case RAISE:
        if(record->event.pressed){
            layer_on(_RAISE);
            update_tri_layer(_LOWER, _RAISE, _ADJUST);
        } else {
            layer_off(_RAISE);
            update_tri_layer(_LOWER, _RAISE, _ADJUST);
        }
        return false;
        break;
    case LOWER:
        if(record->event.pressed){
            layer_on(_LOWER);
            update_tri_layer(_LOWER, _RAISE, _ADJUST);
        } else {
            layer_off(_LOWER);
            update_tri_layer(_LOWER, _RAISE, _ADJUST);
        }
        return false;
        break;
    case SHFT_CAP: 
        if(record->event.pressed){
            key_timer = timer_read();               // if the key is being pressed, we start the timer.
            register_code(KC_LSHIFT);
        } else {                                    // this means the key was just released (tap or "held down")
            if(timer_elapsed(key_timer) < 152){     // Time in ms, the threshold we pick for counting something as a tap.
                tap(KC_CAPS);
                if(caps_status == 0){
                    caps_status = 1;
                    #ifdef AUDIO_ENABLE
                        PLAY_NOTE_ARRAY(tone_capslock_on, false, 0);
                    #endif
                } else {
                    caps_status = 0;
                    #ifdef AUDIO_ENABLE
                        PLAY_NOTE_ARRAY(tone_capslock_off, false, 0);
                    #endif
                }
            }
            unregister_code(KC_LSHIFT);
        }
        return false;
        break;
    case CTRLB:                                     // Control-B on tap (bold)
        if(record->event.pressed){
            key_timer = timer_read();               // if the key is being pressed, we start the timer.
            register_code(KC_LCTL);
        } else {                                    // this means the key was just released (tap or "held down")
            if (timer_elapsed(key_timer) < 152) {   // Time in ms, the threshold we pick for counting something as a tap.
                tap(KC_B);
                #ifdef AUDIO_ENABLE
                    PLAY_NOTE_ARRAY(tone_ctrl_mod, false, 0);
                #endif
                #ifdef BACKLIGHT_BREATHING
                    breathing_speed_set(2);
                    breathing_pulse();
                #endif
            }
            unregister_code(KC_LCTL);
        }
        return false;
        break;
    case CPYPST:                                    // One key copy/paste
        if(record->event.pressed){
            key_timer = timer_read();
        } else {
            if (timer_elapsed(key_timer) > 152) {   // Hold, copy
                register_code(KC_LCTL);
                tap(KC_C);
                unregister_code(KC_LCTL);
                #ifdef AUDIO_ENABLE
                    PLAY_NOTE_ARRAY(tone_copy, false, 0);
                #endif
            } else {                                // Tap, paste
                register_code(KC_LCTL);
                tap(KC_V);
                unregister_code(KC_LCTL);
                #ifdef AUDIO_ENABLE
                    PLAY_NOTE_ARRAY(tone_paste, false, 0);
                #endif
            }
        }
        return false;
        break;
    #ifdef UNICODE_ENABLE
    case UNIWIN:
        if(record->event.pressed){
            set_unicode_input_mode(UC_WIN);
            #ifdef AUDIO_ENABLE
              PLAY_NOTE_ARRAY(uniwin, false, 0);
            #endif
        }
        return false;
        break;
    case UNILIN:
        if(record->event.pressed){
            set_unicode_input_mode(UC_LNX);
            #ifdef AUDIO_ENABLE
              PLAY_NOTE_ARRAY(unilin, false, 0);
            #endif
        }
        return false;
        break;
    case DISFACE:       // ಠ_ಠ
        if(record->event.pressed){
            process_unicode((0x0CA0|QK_UNICODE), record);   // Eye
            register_code(KC_RSFT);
            tap(KC_MINS);
            unregister_code(KC_RSFT);
            process_unicode((0x0CA0|QK_UNICODE), record);   // Eye
        }
        return false;
        break;
    case TFLIP:         // (╯°□°)╯ ︵ ┻━┻
        if(record->event.pressed){
            register_code(KC_RSFT);
            tap(KC_9);
            unregister_code(KC_RSFT);
            process_unicode((0x256F|QK_UNICODE), record);   // Arm
            process_unicode((0x00B0|QK_UNICODE), record);   // Eye
            process_unicode((0x25A1|QK_UNICODE), record);   // Mouth
            process_unicode((0x00B0|QK_UNICODE), record);   // Eye
            register_code(KC_RSFT);
            tap(KC_0);
            unregister_code(KC_RSFT);
            process_unicode((0x256F|QK_UNICODE), record);   // Arm
            tap(KC_SPC);
            process_unicode((0x0361|QK_UNICODE), record);   // Flippy
            tap(KC_SPC);
            process_unicode((0x253B|QK_UNICODE), record);   // Table
            process_unicode((0x2501|QK_UNICODE), record);   // Table
            process_unicode((0x253B|QK_UNICODE), record);   // Table
        }
        return false;
        break;
    case TPUT:          // ┬──┬ ノ( ゜-゜ノ)
        if(record->event.pressed){
            process_unicode((0x252C|QK_UNICODE), record);   // Table
            process_unicode((0x2500|QK_UNICODE), record);   // Table
            process_unicode((0x2500|QK_UNICODE), record);   // Table
            process_unicode((0x252C|QK_UNICODE), record);   // Table
            tap(KC_SPC);
            process_unicode((0x30CE|QK_UNICODE), record);   // Arm
            register_code(KC_RSFT);
            tap(KC_9);
            unregister_code(KC_RSFT);
            tap(KC_SPC);
            process_unicode((0x309C|QK_UNICODE), record);   // Eye
            tap(KC_MINS);
            process_unicode((0x309C|QK_UNICODE), record);   // Eye
            process_unicode((0x30CE|QK_UNICODE), record);   // Arm
            register_code(KC_RSFT);
            tap(KC_0);
            unregister_code(KC_RSFT);
        }
        return false;
        break;
    case SHRUG:         // ¯\_(ツ)_/¯
        if(record->event.pressed){
            process_unicode((0x00AF|QK_UNICODE), record);   // Hand
            tap(KC_BSLS);                                   // Arm
            register_code(KC_RSFT);
            tap(KC_UNDS);                                   // Arm
            tap(KC_LPRN);                                   // Head
            unregister_code(KC_RSFT);
            process_unicode((0x30C4|QK_UNICODE), record);   // Face
            register_code(KC_RSFT);
            tap(KC_RPRN);                                   // Head
            tap(KC_UNDS);                                   // Arm
            unregister_code(KC_RSFT);
            tap(KC_SLSH);                                   // Arm
            process_unicode((0x00AF|QK_UNICODE), record);   // Hand
        }
        return false;
        break;
    #endif
    case FACE:          // (o_O)
        if(record->event.pressed){
            register_code(KC_RSFT);
            tap(KC_LPRN);
            unregister_code(KC_RSFT);
            tap(KC_O);
            register_code(KC_RSFT);
            tap(KC_UNDS);
            tap(KC_O);
            tap(KC_RPRN);
            unregister_code(KC_RSFT);
        }
        return false;
        break;
    case RANDIG:
        if (record->event.pressed) {
            tap_random_base64();
        }
        return false;
        break;
  }
  return true;
};

void matrix_init_user(void){        // Run once at startup
    #ifdef AUDIO_ENABLE
        _delay_ms(50); // gets rid of tick
        PLAY_NOTE_ARRAY(tone_startup, false, 0);
    #endif
}

#ifdef AUDIO_ENABLE
void play_goodbye_tone(void){
  PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
  _delay_ms(150);
}

void shutdown_user(){
    PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
    _delay_ms(150);
    stop_all_notes();
}

void music_on_user(void){           // Run when the music layer is turned on
    PLAY_NOTE_ARRAY(tone_startup, false, 0);
}

void music_off_user(void){          // Run when music is turned off
	PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
}
#endif

#endif