aboutsummaryrefslogtreecommitdiff
path: root/users
diff options
context:
space:
mode:
Diffstat (limited to 'users')
-rw-r--r--users/drashna/config.h131
-rw-r--r--users/drashna/drashna.c138
-rw-r--r--users/drashna/drashna.h69
-rw-r--r--users/drashna/process_records.c257
-rw-r--r--users/drashna/process_records.h66
-rw-r--r--users/drashna/readme.md192
-rw-r--r--users/drashna/readme_handlers.md97
-rw-r--r--users/drashna/readme_keycodes.md10
-rw-r--r--users/drashna/readme_rgb.md43
-rw-r--r--users/drashna/readme_secrets.md123
-rw-r--r--users/drashna/readme_tap_dance.md119
-rw-r--r--users/drashna/readme_wrappers.md11
-rw-r--r--users/drashna/rgb_stuff.c302
-rw-r--r--users/drashna/rgb_stuff.h22
-rw-r--r--users/drashna/rules.mk1
-rw-r--r--users/drashna/send_unicode.h71
-rw-r--r--users/drashna/tap_dances.c77
-rw-r--r--users/drashna/tap_dances.h16
-rw-r--r--users/drashna/wrappers.h14
19 files changed, 996 insertions, 763 deletions
diff --git a/users/drashna/config.h b/users/drashna/config.h
index a6d8e7526..8f6e700d2 100644
--- a/users/drashna/config.h
+++ b/users/drashna/config.h
@@ -1,47 +1,95 @@
1#pragma once 1#pragma once
2 2
3
4#ifdef AUDIO_ENABLE 3#ifdef AUDIO_ENABLE
5# define AUDIO_CLICKY 4# if __GNUC__ > 7
6# define STARTUP_SONG SONG(RICK_ROLL) 5# if __has_include("drashna_song_list.h")
7# define GOODBYE_SONG SONG(SONIC_RING) 6# include "drashna_song_list.h"
8# define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \ 7# endif // if file exists
9 SONG(COLEMAK_SOUND), \ 8# endif // __GNUC__
10 SONG(DVORAK_SOUND), \ 9
11 SONG(OVERWATCH_THEME) \ 10# define AUDIO_CLICKY
12 } 11# define STARTUP_SONG SONG(RICK_ROLL)
13 12# define GOODBYE_SONG SONG(SONIC_RING)
14# define AUDIO_CLICKY_FREQ_RANDOMNESS 1.5f 13# define DEFAULT_LAYER_SONGS \
15 14 { SONG(QWERTY_SOUND), SONG(COLEMAK_SOUND), SONG(DVORAK_SOUND), SONG(OVERWATCH_THEME) }
16# define UNICODE_SONG_OSX SONG(RICK_ROLL) 15
17# define UNICODE_SONG_LNX SONG(RICK_ROLL) 16# define AUDIO_CLICKY_FREQ_RANDOMNESS 1.5f
18# define UNICODE_SONG_WIN SONG(RICK_ROLL) 17
19# define UNICODE_SONG_BSD SONG(RICK_ROLL) 18# define UNICODE_SONG_OSX SONG(RICK_ROLL)
20# define UNICODE_SONG_WINC SONG(RICK_ROLL) 19# define UNICODE_SONG_LNX SONG(RICK_ROLL)
21 20# define UNICODE_SONG_WIN SONG(RICK_ROLL)
22#endif // !AUDIO_ENABLE 21# define UNICODE_SONG_BSD SONG(RICK_ROLL)
22# define UNICODE_SONG_WINC SONG(RICK_ROLL)
23#endif // !AUDIO_ENABLE
23 24
24#ifdef RGBLIGHT_ENABLE 25#ifdef RGBLIGHT_ENABLE
25# define RGBLIGHT_SLEEP 26# define RGBLIGHT_SLEEP
26# undef RGBLIGHT_ANIMATIONS 27# undef RGBLIGHT_ANIMATIONS
27# define RGBLIGHT_EFFECT_BREATHING 28# define RGBLIGHT_EFFECT_BREATHING
28# define RGBLIGHT_EFFECT_SNAKE 29# define RGBLIGHT_EFFECT_SNAKE
29# define RGBLIGHT_EFFECT_KNIGHT 30# define RGBLIGHT_EFFECT_KNIGHT
30#endif // RGBLIGHT_ENABLE 31#endif // RGBLIGHT_ENABLE
32
33#ifdef RGB_MATRIX_ENABLE
34# define RGB_MATRIX_KEYPRESSES // reacts to keypresses (will slow down matrix scan by a lot)
35// # define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (not recommened)
36# define RGB_MATRIX_FRAMEBUFFER_EFFECTS
37// # define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
38# define RGB_DISABLE_WHEN_USB_SUSPENDED true // turn off effects when suspended
39// # define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255
40// # define EECONFIG_RGB_MATRIX (uint32_t *)16
41
42# if defined(__AVR__) && !defined(__AVR_AT90USB1286__)
43# define DISABLE_RGB_MATRIX_ALPHAS_MODS
44# define DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
45# define DISABLE_RGB_MATRIX_BREATHING
46# define DISABLE_RGB_MATRIX_BAND_SAT
47# define DISABLE_RGB_MATRIX_BAND_VAL
48# define DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
49# define DISABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
50# define DISABLE_RGB_MATRIX_BAND_SPIRAL_SAT
51# define DISABLE_RGB_MATRIX_BAND_SPIRAL_VAL
52# define DISABLE_RGB_MATRIX_CYCLE_ALL
53# define DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
54# define DISABLE_RGB_MATRIX_CYCLE_UP_DOWN
55# define DISABLE_RGB_MATRIX_CYCLE_OUT_IN
56// # define DISABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
57# define DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
58# define DISABLE_RGB_MATRIX_DUAL_BEACON
59# define DISABLE_RGB_MATRIX_CYCLE_PINWHEEL
60# define DISABLE_RGB_MATRIX_CYCLE_SPIRAL
61# define DISABLE_RGB_MATRIX_RAINBOW_BEACON
62# define DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
63# define DISABLE_RGB_MATRIX_RAINDROPS
64# define DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
65// # define DISABLE_RGB_MATRIX_TYPING_HEATMAP
66# define DISABLE_RGB_MATRIX_DIGITAL_RAIN
67# define DISABLE_RGB_MATRIX_SOLID_REACTIVE
68# define DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
69# define DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
70# define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
71# define DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
72# define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
73# define DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
74# define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
75# define DISABLE_RGB_MATRIX_SPLASH
76# define DISABLE_RGB_MATRIX_MULTISPLASH
77# define DISABLE_RGB_MATRIX_SOLID_SPLASH
78# define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
79# endif // AVR
80#endif // RGB_MATRIX_ENABLE
31 81
32#ifndef ONESHOT_TAP_TOGGLE 82#ifndef ONESHOT_TAP_TOGGLE
33# define ONESHOT_TAP_TOGGLE 2 83# define ONESHOT_TAP_TOGGLE 2
34#endif // !ONESHOT_TAP_TOGGLE 84#endif // !ONESHOT_TAP_TOGGLE
35 85
36#ifndef ONESHOT_TIMEOUT 86#ifndef ONESHOT_TIMEOUT
37# define ONESHOT_TIMEOUT 3000 87# define ONESHOT_TIMEOUT 3000
38#endif// !ONESHOT_TIMEOUT 88#endif // !ONESHOT_TIMEOUT
39 89
40#ifndef QMK_KEYS_PER_SCAN 90#ifndef QMK_KEYS_PER_SCAN
41# define QMK_KEYS_PER_SCAN 4 91# define QMK_KEYS_PER_SCAN 4
42#endif // !QMK_KEYS_PER_SCAN 92#endif // !QMK_KEYS_PER_SCAN
43
44
45 93
46// this makes it possible to do rolling combos (zx) with keys that 94// this makes it possible to do rolling combos (zx) with keys that
47// convert to other keys on hold (z becomes ctrl when you hold it, 95// convert to other keys on hold (z becomes ctrl when you hold it,
@@ -55,27 +103,26 @@
55#define FORCE_NKRO 103#define FORCE_NKRO
56 104
57#ifndef TAPPING_TOGGLE 105#ifndef TAPPING_TOGGLE
58# define TAPPING_TOGGLE 1 106# define TAPPING_TOGGLE 1
59#endif 107#endif
60 108
61#ifdef TAPPING_TERM 109#ifdef TAPPING_TERM
62# undef TAPPING_TERM 110# undef TAPPING_TERM
63#endif // TAPPING_TERM 111#endif // TAPPING_TERM
64#if defined(KEYBOARD_ergodox_ez) 112#if defined(KEYBOARD_ergodox_ez)
65# define TAPPING_TERM 185 113# define TAPPING_TERM 185
66#elif defined(KEYBOARD_crkbd) 114#elif defined(KEYBOARD_crkbd)
67# define TAPPING_TERM 200 115# define TAPPING_TERM 200
68#else 116#else
69# define TAPPING_TERM 175 117# define TAPPING_TERM 175
70#endif 118#endif
71 119
72
73#define TAP_CODE_DELAY 5 120#define TAP_CODE_DELAY 5
74 121
75/* Disable unused and unneeded features to reduce on firmware size */ 122/* Disable unused and unneeded features to reduce on firmware size */
76#ifdef LOCKING_SUPPORT_ENABLE 123#ifdef LOCKING_SUPPORT_ENABLE
77# undef LOCKING_SUPPORT_ENABLE 124# undef LOCKING_SUPPORT_ENABLE
78#endif 125#endif
79#ifdef LOCKING_RESYNC_ENABLE 126#ifdef LOCKING_RESYNC_ENABLE
80# undef LOCKING_RESYNC_ENABLE 127# undef LOCKING_RESYNC_ENABLE
81#endif 128#endif
diff --git a/users/drashna/drashna.c b/users/drashna/drashna.c
index acc6b9f9e..c1809dad0 100644
--- a/users/drashna/drashna.c
+++ b/users/drashna/drashna.c
@@ -19,22 +19,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20userspace_config_t userspace_config; 20userspace_config_t userspace_config;
21#if (defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)) 21#if (defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE))
22 #define DRASHNA_UNICODE_MODE UC_WIN 22# define DRASHNA_UNICODE_MODE UC_WIN
23#else 23#else
24 // set to 2 for UC_WIN, set to 4 for UC_WINC 24// set to 2 for UC_WIN, set to 4 for UC_WINC
25 #define DRASHNA_UNICODE_MODE 2 25# define DRASHNA_UNICODE_MODE 2
26#endif 26#endif
27 27
28
29// This block is for all of the gaming macros, as they were all doing 28// This block is for all of the gaming macros, as they were all doing
30// the same thing, but with differring text sent. 29// the same thing, but with differring text sent.
31bool send_game_macro(const char *str, keyrecord_t *record, bool override) { 30bool send_game_macro(const char *str, keyrecord_t *record, bool override) {
32 if (!record->event.pressed || override) { 31 if (!record->event.pressed || override) {
33 uint16_t keycode; 32 uint16_t keycode;
34 if (userspace_config.is_overwatch) { 33 if (userspace_config.is_overwatch) {
35 keycode = KC_BSPC; 34 keycode = KC_BSPC;
36 } else { 35 } else {
37 keycode = KC_ENTER; 36 keycode = KC_ENTER;
38 } 37 }
39 clear_keyboard(); 38 clear_keyboard();
40 tap_code(keycode); 39 tap_code(keycode);
@@ -47,12 +46,12 @@ bool send_game_macro(const char *str, keyrecord_t *record, bool override) {
47 return false; 46 return false;
48} 47}
49 48
50bool mod_key_press_timer (uint16_t code, uint16_t mod_code, bool pressed) { 49bool mod_key_press_timer(uint16_t code, uint16_t mod_code, bool pressed) {
51 static uint16_t this_timer; 50 static uint16_t this_timer;
52 if(pressed) { 51 if (pressed) {
53 this_timer= timer_read(); 52 this_timer = timer_read();
54 } else { 53 } else {
55 if (timer_elapsed(this_timer) < TAPPING_TERM){ 54 if (timer_elapsed(this_timer) < TAPPING_TERM) {
56 tap_code(code); 55 tap_code(code);
57 } else { 56 } else {
58 register_code(mod_code); 57 register_code(mod_code);
@@ -63,11 +62,11 @@ bool mod_key_press_timer (uint16_t code, uint16_t mod_code, bool pressed) {
63 return false; 62 return false;
64} 63}
65 64
66bool mod_key_press (uint16_t code, uint16_t mod_code, bool pressed, uint16_t this_timer) { 65bool mod_key_press(uint16_t code, uint16_t mod_code, bool pressed, uint16_t this_timer) {
67 if(pressed) { 66 if (pressed) {
68 this_timer= timer_read(); 67 this_timer = timer_read();
69 } else { 68 } else {
70 if (timer_elapsed(this_timer) < TAPPING_TERM){ 69 if (timer_elapsed(this_timer) < TAPPING_TERM) {
71 tap_code(code); 70 tap_code(code);
72 } else { 71 } else {
73 register_code(mod_code); 72 register_code(mod_code);
@@ -80,13 +79,13 @@ bool mod_key_press (uint16_t code, uint16_t mod_code, bool pressed, uint16_t thi
80 79
81void bootmagic_lite(void) { 80void bootmagic_lite(void) {
82 matrix_scan(); 81 matrix_scan();
83 #if defined(DEBOUNCING_DELAY) && DEBOUNCING_DELAY > 0 82#if defined(DEBOUNCING_DELAY) && DEBOUNCING_DELAY > 0
84 wait_ms(DEBOUNCING_DELAY * 2); 83 wait_ms(DEBOUNCING_DELAY * 2);
85 #elif defined(DEBOUNCE) && DEBOUNCE > 0 84#elif defined(DEBOUNCE) && DEBOUNCE > 0
86 wait_ms(DEBOUNCE * 2); 85 wait_ms(DEBOUNCE * 2);
87 #else 86#else
88 wait_ms(30); 87 wait_ms(30);
89 #endif 88#endif
90 matrix_scan(); 89 matrix_scan();
91 if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) { 90 if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
92 bootloader_jump(); 91 bootloader_jump();
@@ -97,7 +96,7 @@ void bootmagic_lite(void) {
97// This allows for a global, userspace functions, and continued 96// This allows for a global, userspace functions, and continued
98// customization of the keymap. Use _keymap instead of _user 97// customization of the keymap. Use _keymap instead of _user
99// functions in the keymaps 98// functions in the keymaps
100__attribute__ ((weak)) 99__attribute__((weak))
101void matrix_init_keymap(void) {} 100void matrix_init_keymap(void) {}
102 101
103// Call user matrix init, set default RGB colors and then 102// Call user matrix init, set default RGB colors and then
@@ -105,64 +104,63 @@ void matrix_init_keymap(void) {}
105void matrix_init_user(void) { 104void matrix_init_user(void) {
106 userspace_config.raw = eeconfig_read_user(); 105 userspace_config.raw = eeconfig_read_user();
107 106
108 #ifdef BOOTLOADER_CATERINA 107#ifdef BOOTLOADER_CATERINA
109 DDRD &= ~(1<<5); 108 DDRD &= ~(1 << 5);
110 PORTD &= ~(1<<5); 109 PORTD &= ~(1 << 5);
111 110
112 DDRB &= ~(1<<0); 111 DDRB &= ~(1 << 0);
113 PORTB &= ~(1<<0); 112 PORTB &= ~(1 << 0);
114 #endif 113#endif
115 114
116 #if (defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)) 115#if (defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE))
117 set_unicode_input_mode(DRASHNA_UNICODE_MODE); 116 set_unicode_input_mode(DRASHNA_UNICODE_MODE);
118 get_unicode_input_mode(); 117 get_unicode_input_mode();
119 #endif //UNICODE_ENABLE 118#endif // UNICODE_ENABLE
120 matrix_init_keymap(); 119 matrix_init_keymap();
121} 120}
122 121
123__attribute__((weak)) 122__attribute__((weak))
124void keyboard_post_init_keymap(void){ } 123void keyboard_post_init_keymap(void) {}
125 124
126void keyboard_post_init_user(void){ 125void keyboard_post_init_user(void) {
127#ifdef RGBLIGHT_ENABLE 126#ifdef RGBLIGHT_ENABLE
128 keyboard_post_init_rgb(); 127 keyboard_post_init_rgb();
129#endif 128#endif
130 keyboard_post_init_keymap(); 129 keyboard_post_init_keymap();
131} 130}
132 131
133__attribute__ ((weak)) 132__attribute__((weak))
134void shutdown_keymap(void) {} 133void shutdown_keymap(void) {}
135 134
136void shutdown_user (void) { 135void shutdown_user(void) {
137 #ifdef RGBLIGHT_ENABLE 136#ifdef RGBLIGHT_ENABLE
138 rgblight_enable_noeeprom(); 137 rgblight_enable_noeeprom();
139 rgblight_mode_noeeprom(1); 138 rgblight_mode_noeeprom(1);
140 rgblight_setrgb_red(); 139 rgblight_setrgb_red();
141 #endif // RGBLIGHT_ENABLE 140#endif // RGBLIGHT_ENABLE
142 #ifdef RGB_MATRIX_ENABLE 141#ifdef RGB_MATRIX_ENABLE
143 // uint16_t timer_start = timer_read(); 142 // uint16_t timer_start = timer_read();
144 // rgb_matrix_set_color_all( 0xFF, 0x00, 0x00 ); 143 // rgb_matrix_set_color_all( 0xFF, 0x00, 0x00 );
145 // while(timer_elapsed(timer_start) < 250) { wait_ms(1); } 144 // while(timer_elapsed(timer_start) < 250) { wait_ms(1); }
146 #endif //RGB_MATRIX_ENABLE 145#endif // RGB_MATRIX_ENABLE
147 shutdown_keymap(); 146 shutdown_keymap();
148} 147}
149 148
150__attribute__ ((weak)) 149__attribute__((weak))
151void suspend_power_down_keymap(void) {} 150void suspend_power_down_keymap(void) {}
152 151
153void suspend_power_down_user(void) { 152void suspend_power_down_user(void) {
154 suspend_power_down_keymap(); 153 suspend_power_down_keymap();
155} 154}
156 155
157__attribute__ ((weak)) 156__attribute__((weak))
158void suspend_wakeup_init_keymap(void) {} 157void suspend_wakeup_init_keymap(void) {}
159 158
160void suspend_wakeup_init_user(void) { 159void suspend_wakeup_init_user(void) {
161 suspend_wakeup_init_keymap(); 160 suspend_wakeup_init_keymap();
162} 161}
163 162
164 163__attribute__((weak))
165__attribute__ ((weak))
166void matrix_scan_keymap(void) {} 164void matrix_scan_keymap(void) {}
167 165
168// No global matrix scan code, so just run keymap's matrix 166// No global matrix scan code, so just run keymap's matrix
@@ -176,20 +174,17 @@ void matrix_scan_user(void) {
176 174
177#ifdef TAP_DANCE_ENABLE // Run Diablo 3 macro checking code. 175#ifdef TAP_DANCE_ENABLE // Run Diablo 3 macro checking code.
178 run_diablo_macro_check(); 176 run_diablo_macro_check();
179#endif // TAP_DANCE_ENABLE 177#endif // TAP_DANCE_ENABLE
180 178
181#ifdef RGBLIGHT_ENABLE 179#ifdef RGBLIGHT_ENABLE
182 matrix_scan_rgb(); 180 matrix_scan_rgb();
183#endif // RGBLIGHT_ENABLE 181#endif // RGBLIGHT_ENABLE
184 182
185 matrix_scan_keymap(); 183 matrix_scan_keymap();
186} 184}
187 185
188 186__attribute__((weak))
189__attribute__ ((weak)) 187layer_state_t layer_state_set_keymap(layer_state_t state) { return state; }
190layer_state_t layer_state_set_keymap (layer_state_t state) {
191 return state;
192}
193 188
194// on layer change, no matter where the change was initiated 189// on layer change, no matter where the change was initiated
195// Then runs keymap's layer change check 190// Then runs keymap's layer change check
@@ -197,28 +192,25 @@ layer_state_t layer_state_set_user(layer_state_t state) {
197 state = update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST); 192 state = update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST);
198#ifdef RGBLIGHT_ENABLE 193#ifdef RGBLIGHT_ENABLE
199 state = layer_state_set_rgb(state); 194 state = layer_state_set_rgb(state);
200#endif // RGBLIGHT_ENABLE 195#endif // RGBLIGHT_ENABLE
201 return layer_state_set_keymap (state); 196 return layer_state_set_keymap(state);
202} 197}
203 198
204 199__attribute__((weak))
205__attribute__ ((weak)) 200layer_state_t default_layer_state_set_keymap(layer_state_t state) { return state; }
206layer_state_t default_layer_state_set_keymap (layer_state_t state) {
207 return state;
208}
209 201
210// Runs state check and changes underglow color and animation 202// Runs state check and changes underglow color and animation
211layer_state_t default_layer_state_set_user(layer_state_t state) { 203layer_state_t default_layer_state_set_user(layer_state_t state) {
212 state = default_layer_state_set_keymap(state); 204 state = default_layer_state_set_keymap(state);
213#if 0 205#if 0
214#ifdef RGBLIGHT_ENABLE 206# ifdef RGBLIGHT_ENABLE
215 state = default_layer_state_set_rgb(state); 207 state = default_layer_state_set_rgb(state);
216#endif // RGBLIGHT_ENABLE 208# endif // RGBLIGHT_ENABLE
217#endif 209#endif
218 return state; 210 return state;
219} 211}
220 212
221__attribute__ ((weak)) 213__attribute__((weak))
222void led_set_keymap(uint8_t usb_led) {} 214void led_set_keymap(uint8_t usb_led) {}
223 215
224// Any custom LED code goes here. 216// Any custom LED code goes here.
@@ -228,17 +220,19 @@ void led_set_user(uint8_t usb_led) {
228 led_set_keymap(usb_led); 220 led_set_keymap(usb_led);
229} 221}
230 222
231__attribute__ ((weak)) 223__attribute__((weak))
232void eeconfig_init_keymap(void) {} 224void eeconfig_init_keymap(void) {}
233 225
234void eeconfig_init_user(void) { 226void eeconfig_init_user(void) {
235 userspace_config.raw = 0; 227 userspace_config.raw = 0;
236 userspace_config.rgb_layer_change = true; 228 userspace_config.rgb_layer_change = true;
237 eeconfig_update_user(userspace_config.raw); 229 eeconfig_update_user(userspace_config.raw);
238 #if (defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)) 230#if (defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE))
239 set_unicode_input_mode(DRASHNA_UNICODE_MODE); 231 set_unicode_input_mode(DRASHNA_UNICODE_MODE);
240 get_unicode_input_mode(); 232 get_unicode_input_mode();
241 #else 233#else
242 eeprom_update_byte(EECONFIG_UNICODEMODE, DRASHNA_UNICODE_MODE); 234 eeprom_update_byte(EECONFIG_UNICODEMODE, DRASHNA_UNICODE_MODE);
243 #endif 235#endif
236 eeconfig_init_keymap();
237 keyboard_init();
244} 238}
diff --git a/users/drashna/drashna.h b/users/drashna/drashna.h
index 507504f04..0d6dac380 100644
--- a/users/drashna/drashna.h
+++ b/users/drashna/drashna.h
@@ -22,20 +22,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
22#include "wrappers.h" 22#include "wrappers.h"
23#include "process_records.h" 23#include "process_records.h"
24#ifdef TAP_DANCE_ENABLE 24#ifdef TAP_DANCE_ENABLE
25# include "tap_dances.h" 25# include "tap_dances.h"
26#endif // TAP_DANCE_ENABLE 26#endif // TAP_DANCE_ENABLE
27#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) 27#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
28# include "rgb_stuff.h" 28# include "rgb_stuff.h"
29#endif
30#if defined(AUDIO_ENABLE) && __GNUC__ > 7
31# if __has_include("drashna_song_list.h")
32# include "drashna_song_list.h"
33# endif
34#endif 29#endif
35 30
36/* Define layer names */ 31/* Define layer names */
37enum userspace_layers { 32enum userspace_layers {
38 _QWERTY = 0, 33 _QWERTY = 0,
39 _NUMLOCK = 0, 34 _NUMLOCK = 0,
40 _COLEMAK, 35 _COLEMAK,
41 _DVORAK, 36 _DVORAK,
@@ -58,47 +53,45 @@ enum userspace_layers {
58define modifiers here, since MOD_* doesn't seem to work for these 53define modifiers here, since MOD_* doesn't seem to work for these
59 */ 54 */
60 55
61 56bool mod_key_press_timer(uint16_t code, uint16_t mod_code, bool pressed);
62bool mod_key_press_timer (uint16_t code, uint16_t mod_code, bool pressed); 57bool mod_key_press(uint16_t code, uint16_t mod_code, bool pressed, uint16_t this_timer);
63bool mod_key_press (uint16_t code, uint16_t mod_code, bool pressed, uint16_t this_timer); 58bool send_game_macro(const char *str, keyrecord_t *record, bool override);
64bool send_game_macro(const char *str, keyrecord_t *record, bool override); 59void matrix_init_keymap(void);
65void matrix_init_keymap(void); 60void shutdown_keymap(void);
66void shutdown_keymap(void); 61void suspend_power_down_keymap(void);
67void suspend_power_down_keymap(void); 62void suspend_wakeup_init_keymap(void);
68void suspend_wakeup_init_keymap(void); 63void matrix_scan_keymap(void);
69void matrix_scan_keymap(void); 64layer_state_t layer_state_set_keymap(layer_state_t state);
70layer_state_t layer_state_set_keymap (layer_state_t state); 65layer_state_t default_layer_state_set_keymap(layer_state_t state);
71layer_state_t default_layer_state_set_keymap (layer_state_t state); 66void led_set_keymap(uint8_t usb_led);
72void led_set_keymap(uint8_t usb_led); 67void eeconfig_init_keymap(void);
73void eeconfig_init_keymap(void);
74 68
75typedef union { 69typedef union {
76 uint32_t raw; 70 uint32_t raw;
77 struct { 71 struct {
78 bool rgb_layer_change :1; 72 bool rgb_layer_change :1;
79 bool is_overwatch :1; 73 bool is_overwatch :1;
80 bool nuke_switch :1; 74 bool nuke_switch :1;
81 uint8_t unicode_mod :4; 75 uint8_t unicode_mod :4;
82 bool swapped_numbers :1; 76 bool swapped_numbers :1;
83 }; 77 };
84} userspace_config_t; 78} userspace_config_t;
85 79
86extern userspace_config_t userspace_config; 80extern userspace_config_t userspace_config;
87 81
88
89/* 82/*
90Custom Keycodes for Diablo 3 layer 83Custom Keycodes for Diablo 3 layer
91But since TD() doesn't work when tap dance is disabled 84But since TD() doesn't work when tap dance is disabled
92We use custom codes here, so we can substitute the right stuff 85We use custom codes here, so we can substitute the right stuff
93*/ 86*/
94#ifdef TAP_DANCE_ENABLE 87#ifdef TAP_DANCE_ENABLE
95# define KC_D3_1 TD(TD_D3_1) 88# define KC_D3_1 TD(TD_D3_1)
96# define KC_D3_2 TD(TD_D3_2) 89# define KC_D3_2 TD(TD_D3_2)
97# define KC_D3_3 TD(TD_D3_3) 90# define KC_D3_3 TD(TD_D3_3)
98# define KC_D3_4 TD(TD_D3_4) 91# define KC_D3_4 TD(TD_D3_4)
99#else // TAP_DANCE_ENABLE 92#else // TAP_DANCE_ENABLE
100# define KC_D3_1 KC_1 93# define KC_D3_1 KC_1
101# define KC_D3_2 KC_2 94# define KC_D3_2 KC_2
102# define KC_D3_3 KC_3 95# define KC_D3_3 KC_3
103# define KC_D3_4 KC_4 96# define KC_D3_4 KC_4
104#endif // TAP_DANCE_ENABLE 97#endif // TAP_DANCE_ENABLE
diff --git a/users/drashna/process_records.c b/users/drashna/process_records.c
index 770219917..5666d052d 100644
--- a/users/drashna/process_records.c
+++ b/users/drashna/process_records.c
@@ -2,160 +2,161 @@
2 2
3uint16_t copy_paste_timer; 3uint16_t copy_paste_timer;
4 4
5__attribute__ ((weak)) 5__attribute__((weak))
6bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { 6bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; }
7 return true;
8}
9 7
10__attribute__ ((weak)) 8__attribute__((weak))
11bool process_record_secrets(uint16_t keycode, keyrecord_t *record) { 9bool process_record_secrets(uint16_t keycode, keyrecord_t *record) { return true; }
12 return true;
13}
14 10
15// Defines actions tor my global custom keycodes. Defined in drashna.h file 11// Defines actions tor my global custom keycodes. Defined in drashna.h file
16// Then runs the _keymap's record handier if not processed here 12// Then runs the _keymap's record handier if not processed here
17bool process_record_user(uint16_t keycode, keyrecord_t *record) { 13bool process_record_user(uint16_t keycode, keyrecord_t *record) {
18 14 // If console is enabled, it will print the matrix position and status of each key pressed
19 // If console is enabled, it will print the matrix position and status of each key pressed
20#ifdef KEYLOGGER_ENABLE 15#ifdef KEYLOGGER_ENABLE
21# if defined(KEYBOARD_ergodox_ez) || defined(KEYBOARD_keebio_iris_rev2) 16# if defined(KEYBOARD_ergodox_ez) || defined(KEYBOARD_keebio_iris_rev2)
22 xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.row, record->event.key.col, record->event.pressed); 17 xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.row, record->event.key.col, record->event.pressed);
23# else 18# else
24 xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); 19 xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed);
25# endif 20# endif
26#endif //KEYLOGGER_ENABLE 21#endif // KEYLOGGER_ENABLE
27 22
28 switch (keycode) { 23 switch (keycode) {
29 case KC_QWERTY ... KC_CARPLAX: 24 case KC_QWERTY ... KC_CARPLAX:
30 if (record->event.pressed) { 25 if (record->event.pressed) {
31 set_single_persistent_default_layer(keycode - KC_QWERTY); 26 set_single_persistent_default_layer(keycode - KC_QWERTY);
32 } 27 }
33 break; 28 break;
34 29
35 case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader 30 case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader
36 if (!record->event.pressed) { 31 if (!record->event.pressed) {
37 uint8_t temp_mod = get_mods(); 32 uint8_t temp_mod = get_mods();
38 uint8_t temp_osm = get_oneshot_mods(); 33 uint8_t temp_osm = get_oneshot_mods();
39 clear_mods(); clear_oneshot_mods(); 34 clear_mods();
40 send_string_with_delay_P(PSTR("make " QMK_KEYBOARD ":" QMK_KEYMAP), TAP_CODE_DELAY); 35 clear_oneshot_mods();
36 send_string_with_delay_P(PSTR("make " QMK_KEYBOARD ":" QMK_KEYMAP), TAP_CODE_DELAY);
41#ifndef MAKE_BOOTLOADER 37#ifndef MAKE_BOOTLOADER
42 if ( ( temp_mod | temp_osm ) & MOD_MASK_SHIFT ) 38 if ((temp_mod | temp_osm) & MOD_MASK_SHIFT)
43#endif 39#endif
44 { 40 {
45 #if defined(__arm__) 41#if defined(__arm__)
46 send_string_with_delay_P(PSTR(":dfu-util"), TAP_CODE_DELAY); 42 send_string_with_delay_P(PSTR(":dfu-util"), TAP_CODE_DELAY);
47 #elif defined(BOOTLOADER_DFU) 43#elif defined(BOOTLOADER_DFU)
48 send_string_with_delay_P(PSTR(":dfu"), TAP_CODE_DELAY); 44 send_string_with_delay_P(PSTR(":dfu"), TAP_CODE_DELAY);
49 #elif defined(BOOTLOADER_HALFKAY) 45#elif defined(BOOTLOADER_HALFKAY)
50 send_string_with_delay_P(PSTR(":teensy"), TAP_CODE_DELAY); 46 send_string_with_delay_P(PSTR(":teensy"), TAP_CODE_DELAY);
51 #elif defined(BOOTLOADER_CATERINA) 47#elif defined(BOOTLOADER_CATERINA)
52 send_string_with_delay_P(PSTR(":avrdude"), TAP_CODE_DELAY); 48 send_string_with_delay_P(PSTR(":avrdude"), TAP_CODE_DELAY);
53 #endif // bootloader options 49#endif // bootloader options
54 } 50 }
55 if ( ( temp_mod | temp_osm ) & MOD_MASK_CTRL) { send_string_with_delay_P(PSTR(" -j8 --output-sync"), TAP_CODE_DELAY); } 51 if ((temp_mod | temp_osm) & MOD_MASK_CTRL) {
52 send_string_with_delay_P(PSTR(" -j8 --output-sync"), TAP_CODE_DELAY);
53 }
56#ifdef RGB_MATRIX_SPLIT_RIGHT 54#ifdef RGB_MATRIX_SPLIT_RIGHT
57 send_string_with_delay_P(PSTR(" RGB_MATRIX_SPLIT_RIGHT=yes OLED_DRIVER_ENABLE=no"), TAP_CODE_DELAY); 55 send_string_with_delay_P(PSTR(" RGB_MATRIX_SPLIT_RIGHT=yes"), TAP_CODE_DELAY);
56# ifndef OLED_DRIVER_ENABLE
57 send_string_with_delay_P(PSTR(" OLED_DRIVER_ENABLE=no"), TAP_CODE_DELAY);
58# endif
58#endif 59#endif
59 send_string_with_delay_P(PSTR(SS_TAP(X_ENTER)), TAP_CODE_DELAY); 60 send_string_with_delay_P(PSTR(SS_TAP(X_ENTER)), TAP_CODE_DELAY);
60 } 61 }
61 62
62 break; 63 break;
63 64
64 case VRSN: // Prints firmware version 65 case VRSN: // Prints firmware version
65 if (record->event.pressed) { 66 if (record->event.pressed) {
66 send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY); 67 send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY);
67 } 68 }
68 break; 69 break;
69 70
70 // These are a serious of gaming macros. 71 // These are a serious of gaming macros.
71 // Only enables for the viterbi, basically, 72 // Only enables for the viterbi, basically,
72 // to save on firmware space, since it's limited. 73 // to save on firmware space, since it's limited.
73#ifdef MACROS_ENABLED 74#ifdef MACROS_ENABLED
74 case KC_OVERWATCH: // Toggle's if we hit "ENTER" or "BACKSPACE" to input macros 75 case KC_OVERWATCH: // Toggle's if we hit "ENTER" or "BACKSPACE" to input macros
75 if (record->event.pressed) { userspace_config.is_overwatch ^= 1; eeconfig_update_user(userspace_config.raw); } 76 if (record->event.pressed) {
76#ifdef RGBLIGHT_ENABLE 77 userspace_config.is_overwatch ^= 1;
77 userspace_config.is_overwatch ? rgblight_mode_noeeprom(17) : rgblight_mode_noeeprom(18); 78 eeconfig_update_user(userspace_config.raw);
78#endif //RGBLIGHT_ENABLE 79 }
79 break; 80# ifdef RGBLIGHT_ENABLE
80 case KC_SALT: 81 userspace_config.is_overwatch ? rgblight_mode_noeeprom(17) : rgblight_mode_noeeprom(18);
81 return send_game_macro("Salt, salt, salt...", record, false); 82# endif // RGBLIGHT_ENABLE
82 case KC_MORESALT: 83 break;
83 return send_game_macro("Please sir, can I have some more salt?!", record, false); 84 case KC_SALT:
84 case KC_SALTHARD: 85 return send_game_macro("Salt, salt, salt...", record, false);
85 return send_game_macro("Your salt only makes me harder, and even more aggressive!", record, false); 86 case KC_MORESALT:
86 case KC_GOODGAME: 87 return send_game_macro("Please sir, can I have some more salt?!", record, false);
87 return send_game_macro("Good game, everyone!", record, false); 88 case KC_SALTHARD:
88 case KC_GLHF: 89 return send_game_macro("Your salt only makes me harder, and even more aggressive!", record, false);
89 return send_game_macro("Good luck, have fun!!!", record, false); 90 case KC_GOODGAME:
90 case KC_SYMM: 91 return send_game_macro("Good game, everyone!", record, false);
91 return send_game_macro("Left click to win!", record, false); 92 case KC_GLHF:
92 case KC_JUSTGAME: 93 return send_game_macro("Good luck, have fun!!!", record, false);
93 return send_game_macro("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.", record, false); 94 case KC_SYMM:
94 case KC_TORB: 95 return send_game_macro("Left click to win!", record, false);
95 return send_game_macro("That was positively riveting!", record, false); 96 case KC_JUSTGAME:
96 case KC_AIM: 97 return send_game_macro("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.", record, false);
97 send_game_macro("That aim is absolutely amazing. It's almost like you're a machine!", record, true); 98 case KC_TORB:
98 return send_game_macro("Wait! That aim is TOO good! You're clearly using an aim hack! CHEATER!", record, false); 99 return send_game_macro("That was positively riveting!", record, false);
99 case KC_C9: 100 case KC_AIM:
100 return send_game_macro("OMG!!! C9!!!", record, false); 101 send_game_macro("That aim is absolutely amazing. It's almost like you're a machine!", record, true);
101 case KC_GGEZ: 102 return send_game_macro("Wait! That aim is TOO good! You're clearly using an aim hack! CHEATER!", record, false);
102 return send_game_macro("That was a fantastic game, though it was a bit easy. Try harder next time!", record, false); 103 case KC_C9:
103#endif // MACROS_ENABLED 104 return send_game_macro("OMG!!! C9!!!", record, false);
104 105 case KC_GGEZ:
106 return send_game_macro("That was a fantastic game, though it was a bit easy. Try harder next time!", record, false);
107#endif // MACROS_ENABLED
105 108
106 case KC_DIABLO_CLEAR: // reset all Diablo timers, disabling them 109 case KC_DIABLO_CLEAR: // reset all Diablo timers, disabling them
107#ifdef TAP_DANCE_ENABLE 110#ifdef TAP_DANCE_ENABLE
108 if (record->event.pressed) { 111 if (record->event.pressed) {
109 uint8_t dtime; 112 for (uint8_t index = 0; index < 4; index++) {
110 for (dtime = 0; dtime < 4; dtime++) { 113 diablo_timer[index].key_interval = 0;
111 diablo_timer[dtime].key_time = diablo_times[0]; 114 }
112 } 115 }
113 } 116#endif // TAP_DANCE_ENABLE
114#endif // TAP_DANCE_ENABLE 117 break;
115 break;
116 118
117 119 case KC_CCCV: // One key copy/paste
118 case KC_CCCV: // One key copy/paste 120 if (record->event.pressed) {
119 if(record->event.pressed){ 121 copy_paste_timer = timer_read();
120 copy_paste_timer = timer_read();
121 } else { 122 } else {
122 if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) { // Hold, copy 123 if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) { // Hold, copy
123 register_code(KC_LCTL); 124 register_code(KC_LCTL);
124 tap_code(KC_C); 125 tap_code(KC_C);
125 unregister_code(KC_LCTL); 126 unregister_code(KC_LCTL);
126 } else { // Tap, paste 127 } else { // Tap, paste
127 register_code(KC_LCTL); 128 register_code(KC_LCTL);
128 tap_code(KC_V); 129 tap_code(KC_V);
129 unregister_code(KC_LCTL); 130 unregister_code(KC_LCTL);
131 }
130 } 132 }
131 } 133 break;
132 break;
133#ifdef UNICODE_ENABLE 134#ifdef UNICODE_ENABLE
134 case UC_FLIP: // (ノಠ痊ಠ)ノ彡┻━┻ 135 case UC_FLIP: // (ノಠ痊ಠ)ノ彡┻━┻
135 if (record->event.pressed) { 136 if (record->event.pressed) {
136 send_unicode_hex_string("0028 30CE 0CA0 75CA 0CA0 0029 30CE 5F61 253B 2501 253B"); 137 send_unicode_hex_string("0028 30CE 0CA0 75CA 0CA0 0029 30CE 5F61 253B 2501 253B");
137 } 138 }
138 break; 139 break;
139 case UC_TABL: // ┬─┬ノ( º _ ºノ) 140 case UC_TABL: // ┬─┬ノ( º _ ºノ)
140 if (record->event.pressed) { 141 if (record->event.pressed) {
141 send_unicode_hex_string("252C 2500 252C 30CE 0028 0020 00BA 0020 005F 0020 00BA 30CE 0029"); 142 send_unicode_hex_string("252C 2500 252C 30CE 0028 0020 00BA 0020 005F 0020 00BA 30CE 0029");
142 } 143 }
143 break; 144 break;
144 case UC_SHRG: // ¯\_(ツ)_/¯ 145 case UC_SHRG: // ¯\_(ツ)_/¯
145 if (record->event.pressed) { 146 if (record->event.pressed) {
146 send_unicode_hex_string("00AF 005C 005F 0028 30C4 0029 005F 002F 00AF"); 147 send_unicode_hex_string("00AF 005C 005F 0028 30C4 0029 005F 002F 00AF");
147 } 148 }
148 break; 149 break;
149 case UC_DISA: // ಠ_ಠ 150 case UC_DISA: // ಠ_ಠ
150 if (record->event.pressed) { 151 if (record->event.pressed) {
151 send_unicode_hex_string("0CA0 005F 0CA0"); 152 send_unicode_hex_string("0CA0 005F 0CA0");
152 } 153 }
153 break; 154 break;
154#endif 155#endif
155 } 156 }
156 return process_record_keymap(keycode, record) && 157 return process_record_keymap(keycode, record) &&
157#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) 158#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
158 process_record_user_rgb(keycode, record) && 159 process_record_user_rgb(keycode, record) &&
159#endif // RGBLIGHT_ENABLE 160#endif // RGBLIGHT_ENABLE
160 process_record_secrets(keycode, record); 161 process_record_secrets(keycode, record);
161} 162}
diff --git a/users/drashna/process_records.h b/users/drashna/process_records.h
index 35adec84c..8901a6f91 100644
--- a/users/drashna/process_records.h
+++ b/users/drashna/process_records.h
@@ -2,24 +2,24 @@
2#include "drashna.h" 2#include "drashna.h"
3 3
4#if defined(KEYMAP_SAFE_RANGE) 4#if defined(KEYMAP_SAFE_RANGE)
5# define PLACEHOLDER_SAFE_RANGE KEYMAP_SAFE_RANGE 5# define PLACEHOLDER_SAFE_RANGE KEYMAP_SAFE_RANGE
6#else 6#else
7# define PLACEHOLDER_SAFE_RANGE SAFE_RANGE 7# define PLACEHOLDER_SAFE_RANGE SAFE_RANGE
8#endif 8#endif
9 9
10enum userspace_custom_keycodes { 10enum userspace_custom_keycodes {
11 VRSN = PLACEHOLDER_SAFE_RANGE, // Prints QMK Firmware and board info 11 VRSN = PLACEHOLDER_SAFE_RANGE, // Prints QMK Firmware and board info
12 KC_QWERTY, // Sets default layer to QWERTY 12 KC_QWERTY, // Sets default layer to QWERTY
13 KC_COLEMAK, // Sets default layer to COLEMAK 13 KC_COLEMAK, // Sets default layer to COLEMAK
14 KC_DVORAK, // Sets default layer to DVORAK 14 KC_DVORAK, // Sets default layer to DVORAK
15 KC_WORKMAN, // Sets default layer to WORKMAN 15 KC_WORKMAN, // Sets default layer to WORKMAN
16 KC_NORMAN, // Sets default layer to NORMAN 16 KC_NORMAN, // Sets default layer to NORMAN
17 KC_MALTRON, // Sets default layer to MALTRON 17 KC_MALTRON, // Sets default layer to MALTRON
18 KC_EUCALYN, // Sets default layer to EUCALYN 18 KC_EUCALYN, // Sets default layer to EUCALYN
19 KC_CARPLAX, // Sets default layer to CARPLAX 19 KC_CARPLAX, // Sets default layer to CARPLAX
20 KC_DIABLO_CLEAR, // Clears all Diablo Timers 20 KC_DIABLO_CLEAR, // Clears all Diablo Timers
21 KC_OVERWATCH, // Toggles game macro input mode (so in OW, it defaults to game chat) 21 KC_OVERWATCH, // Toggles game macro input mode (so in OW, it defaults to game chat)
22 KC_SALT, // See drashna.c for details 22 KC_SALT, // See drashna.c for details
23 KC_MORESALT, 23 KC_MORESALT,
24 KC_SALTHARD, 24 KC_SALTHARD,
25 KC_GOODGAME, 25 KC_GOODGAME,
@@ -30,27 +30,25 @@ enum userspace_custom_keycodes {
30 KC_AIM, 30 KC_AIM,
31 KC_C9, 31 KC_C9,
32 KC_GGEZ, 32 KC_GGEZ,
33 KC_MAKE, // Run keyboard's customized make command 33 KC_MAKE, // Run keyboard's customized make command
34 KC_RGB_T, // Toggles RGB Layer Indication mode 34 KC_RGB_T, // Toggles RGB Layer Indication mode
35 KC_SECRET_1, // test1 35 KC_SECRET_1, // test1
36 KC_SECRET_2, // test2 36 KC_SECRET_2, // test2
37 KC_SECRET_3, // test3 37 KC_SECRET_3, // test3
38 KC_SECRET_4, // test4 38 KC_SECRET_4, // test4
39 KC_SECRET_5, // test5 39 KC_SECRET_5, // test5
40 KC_CCCV, // Hold to copy, tap to paste 40 KC_CCCV, // Hold to copy, tap to paste
41 KC_NUKE, // NUCLEAR LAUNCH DETECTED!!! 41 KC_NUKE, // NUCLEAR LAUNCH DETECTED!!!
42 UC_FLIP, // (ಠ痊ಠ)┻━┻ 42 UC_FLIP, // (ಠ痊ಠ)┻━┻
43 UC_TABL, // ┬─┬ノ( º _ ºノ) 43 UC_TABL, // ┬─┬ノ( º _ ºノ)
44 UC_SHRG, // ¯\_(ツ)_/¯ 44 UC_SHRG, // ¯\_(ツ)_/¯
45 UC_DISA, // ಠ_ಠ 45 UC_DISA, // ಠ_ಠ
46 NEW_SAFE_RANGE //use "NEWPLACEHOLDER for keymap specific codes 46 NEW_SAFE_RANGE // use "NEWPLACEHOLDER for keymap specific codes
47}; 47};
48 48
49bool process_record_secrets(uint16_t keycode, keyrecord_t *record); 49bool process_record_secrets(uint16_t keycode, keyrecord_t *record);
50bool process_record_keymap(uint16_t keycode, keyrecord_t *record); 50bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
51 51
52
53
54#define LOWER MO(_LOWER) 52#define LOWER MO(_LOWER)
55#define RAISE MO(_RAISE) 53#define RAISE MO(_RAISE)
56#define ADJUST MO(_ADJUST) 54#define ADJUST MO(_ADJUST)
@@ -74,10 +72,10 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
74#define KC_RST KC_RESET 72#define KC_RST KC_RESET
75 73
76#ifdef SWAP_HANDS_ENABLE 74#ifdef SWAP_HANDS_ENABLE
77#define KC_C1R3 SH_TT 75# define KC_C1R3 SH_TT
78#else // SWAP_HANDS_ENABLE 76#else // SWAP_HANDS_ENABLE
79#define KC_C1R3 KC_BSPC 77# define KC_C1R3 KC_BSPC
80#endif // SWAP_HANDS_ENABLE 78#endif // SWAP_HANDS_ENABLE
81 79
82#define BK_LWER LT(_LOWER, KC_BSPC) 80#define BK_LWER LT(_LOWER, KC_BSPC)
83#define SP_LWER LT(_LOWER, KC_SPC) 81#define SP_LWER LT(_LOWER, KC_SPC)
diff --git a/users/drashna/readme.md b/users/drashna/readme.md
index ffc60060f..d98d1d0a6 100644
--- a/users/drashna/readme.md
+++ b/users/drashna/readme.md
@@ -2,192 +2,14 @@
2 2
3This is my personal userspace file. Most of my code exists here, as it's heavily shared. 3This is my personal userspace file. Most of my code exists here, as it's heavily shared.
4 4
5## Custom userspace handlers 5* [RGB Customization](readme_rgb.md)
6* [Diablo Tap Dancing](readme_tap_dance.md)
7* [Keymap Wrappers](readme_wrappers.md)
8* [Custom Function Handlers](readme_handlers.md)
9* [Secret Macros](readme_secrets.md)
10* [Custom Keycodes](readme_keycodes.md)
6 11
7Specifically QMK works by using customized handlers for everything. This allows for multiple levels of customization.
8
9`matrix_scan` calls `matrix_scan_quantum`, which alls `matrix_scan_kb`, which calls `matrix_scan_user`.
10`process_record` calls a bunch of stuff, but eventually calls `process_record_kb` which calls `process_record_user`
11The same goes for `matrix_init`, `layer_state_set`, `led_set`, and a few other functions.
12
13All (most) `_user` functions are handled here instead. To allow keyboard specific configuration, I've created `_keymap` functions that can be called by the keymap.c files instead.
14
15This allows for keyboard specific configuration while maintaining the ability to customize the board.
16
17My [Ergodox EZ Keymap](https://github.com/qmk/qmk_firmware/blob/master/layouts/community/ergodox/drashna/keymap.c#L297) is a good example of this, as it uses the LEDs as modifier indicators.
18
19## Keyboard Layout Templates
20
21This borrows from @jola5's "Not quite neo" code. This allows me to maintain blocks of keymaps in the userspace, so that I can modify the userspace, and this is reflected in all of the keyboards that use it, at once.
22
23This makes adding tap/hold mods, or other special keycodes or functions to all keyboards super easy, as it's done to all of them at once.
24
25The caveat here is that the keymap needs a processor/wrapper, as it doesn't like the substitutions. However, this is as simple as just pushing it through a define. For instance:
26
27`#define LAYOUT_ergodox_wrapper(...) LAYOUT_ergodox(__VA_ARGS__)`
28
29Once that's been done and you've switched the keymaps to use the "wrapper", it will read the substitution blocks just fine.
30
31Credit goes to @jola5 for first implementing this awesome idea.
32
33
34## Custom Keycodes
35
36Keycodes are defined in the drashna.h file and need to be included in the keymap.c files, so that they can be used there.
37
38A bunch of macros are present and are only included on boards that are not the Ergodox EZ or Orthodox, as they are not needed for those boards.
39
40Included is a custom macro for compiling my keyboards. This includes the bootloader target (`:teensy`, `:avrdude`, or `:dfu`), and keeps RGBLIGHT, AUDIO and/or FAUXCLICKY enabled, if it previously was (regardless of the rules file).
41
42This also includes a modified RESET keycode as well, that sets the underglow to red.
43
44## Layer Indication
45
46This uses the `layer_state_set_*` command to change the layer color, to indicate which layer it is on. This includes the default keymap, as well.
47
48Since this is done via userspace, it is the same between all systems.
49
50Additionally, there is a custom keycode to toggle layer indication. And all RGB keycodes disable layer indication by default, as well. This way, I can leave special effects doing when I want.
51
52Also. I use `rgblight_sethsv` since it works with animation modes (that support it).
53
54## Diablo Layer
55
56This layer has some special handling.
57
58When Tap Dances are enabled, this layer has the ability to "spam" keypresses.
59
60For instance, tapping the TD "1" twice causes the layer to hit "1" ever 1 second (appoximately). This is useful for auto-hotkeying skills (such as bone armor or devour).
61
62Tappind once disables this, and switching layers temporarily disables this, until you switch back to the layer.
63
64For critics that think this is cheating, search "diablo 3 num lock auto cast". This is just a simpler method, since I no longer own a normal (non QMK) numpad.
65
66## Secret Macros
67
68With help from gitter and Colinta, this adds the ability to add hidden macros from other users.
69
70First, I have several files that are hidden/excluded from Git/GitHub. These contain everything needed for the macros. To hide these files, open `.git/info/exclude` and add `secrets.c` and `secrets.h` to that file, below the comments.
71
72And this requires `KC_SECRET_1` through `KC_SECRET_5` to be defined in your `<name>.h` file to define the keycodes for the new macros.
73
74
75### .git/info/exclude
76
77```
78# git ls-files --others --exclude-from=.git/info/exclude
79# Lines that start with '#' are comments.
80# For a project mostly in C, the following would be a good set of
81# exclude patterns (uncomment them if you want to use them):
82# *.[oa]
83# *~
84/users/drashna/secrets.c
85/users/drashna/secrets.h
86```
87
88Then you can create these files:
89
90### secrets.c
91
92```c
93#include "drashna.h" // replace with your keymap's "h" file, or whatever file stores the keycodes
94
95#if (__has_include("secrets.h") && !defined(NO_SECRETS))
96#include "secrets.h"
97#else
98// `PROGMEM const char secret[][x]` may work better, but it takes up more space in the firmware
99// And I'm not familiar enough to know which is better or why...
100static const char * const secret[] = {
101 "test1",
102 "test2",
103 "test3",
104 "test4",
105 "test5"
106};
107#endif
108
109bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
110 switch (keycode) {
111 case KC_SECRET_1 ... KC_SECRET_5: // Secrets! Externally defined strings, not stored in repo
112 if (!record->event.pressed) {
113 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
114 send_string_with_delay(secret[keycode - KC_SECRET_1], MACRO_TIMER);
115 }
116 return false;
117 break;
118 }
119 return true;
120}
121```
122
123### secrets.h
124
125```c
126static const char * const secrets[] = {
127 "secret1",
128 "secret2",
129 "secret3",
130 "secret4",
131 "secret5"
132};
133```
134
135Replacing the strings with the codes that you need.
136
137### name.c
138
139In the `<name>.c` file, you will want to add this to the top:
140
141```c
142__attribute__ ((weak))
143bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
144 return true;
145}
146```
147
148This is so that the function can be called here, and replaced in the `secrets.c` file, and so it won't error out if it doesn't exist.
149
150And then, in the `process_record_user` function, assuming you have `return process_record_keymap(keycode, record)` here, you'll want to replace the "final" return with the following. Otherwise, you want to replace the `return true;` with `return process_record_secrets(keycode, record);`
151
152```c
153 return process_record_keymap(keycode, record) && process_record_secrets(keycode, record);
154}
155```
156
157### rules.mk
158
159Here, you want your `/users/<name>/rules.mk` file to "detect" the existence of the `secrets.c` file, and only add it if the file exists. To do so, add this block:
160
161```make
162ifneq ("$(wildcard $(USER_PATH)/secrets.c)","")
163 SRC += secrets.c
164endif
165```
166
167Additionally, if you want to make sure that you can disable the function without messing with the file, you need to add this to your `/users/<name>/rules.mk`, so that it catches the flag:
168
169```make
170ifeq ($(strip $(NO_SECRETS)), yes)
171 OPT_DEFS += -DNO_SECRETS
172endif
173```
174
175Then, if you run `make keyboard:name NO_SECRETS=yes`, it will default to the test strings in your `<name>.c` file, rather than reading from your file.
176 12
177## Pro Micro Hacking 13## Pro Micro Hacking
178 14
179Well, you can get the QMK DFU bootloader working on the ProMicro. But you need to change fuses. 15See [this thread](https://www.reddit.com/r/olkb/comments/8sxgzb/replace_pro_micro_bootloader_with_qmk_dfu/) for details on how to flash QMK DFU to Pro Micros.
180
181What worked to get into the firmware properly was:
182
183```
184Low: 0x5E High: 0xD9 Extended: 0xC3 Lock: 0x3F
185```
186
187The reason that there was some issues before, is that JTAG was still enabled, and using some of the pins that the keyboard uses. Disabling JTAG (either by fuse, or modifying the matrix code for splits fixes the issue).
188
189And for reference, if you want to go back to caterina, the default fuse settings I believe were:
190
191```
192Low: 0xFF High: 0xD8 Extended: 0xC3 Lock: 0x3F
193```
diff --git a/users/drashna/readme_handlers.md b/users/drashna/readme_handlers.md
new file mode 100644
index 000000000..4abaf5147
--- /dev/null
+++ b/users/drashna/readme_handlers.md
@@ -0,0 +1,97 @@
1# Custom Userspace Function handlers
2
3Specifically QMK works by using customized handlers for everything. This allows for multiple levels of customization.
4
5`matrix_scan` calls `matrix_scan_quantum`, which calls `matrix_scan_kb`, which calls `matrix_scan_user`.
6`process_record` calls a bunch of stuff, but eventually calls `process_record_kb` which calls `process_record_user`
7The same goes for `matrix_init`, `layer_state_set`, `led_set`, and a few other functions.
8
9All (most) `_user` functions are handled here, in the userspace instead. To allow keyboard specific configuration, I've created `_keymap` functions that can be called by the keymap.c files instead.
10
11This allows for keyboard specific configuration while maintaining the ability to customize the board.
12
13My [Ergodox EZ Keymap](https://github.com/qmk/qmk_firmware/blob/master/layouts/community/ergodox/drashna/keymap.c) is a good example of this, as it uses the LEDs as modifier indicators.
14
15But for a list:
16
17```c
18__attribute__ ((weak))
19void matrix_init_keymap(void) {}
20
21void matrix_init_user(void) {
22 matrix_init_keymap();
23}
24
25__attribute__((weak))
26void keyboard_post_init_keymap(void){ }
27
28void keyboard_post_init_user(void){
29 keyboard_post_init_keymap();
30}
31
32__attribute__ ((weak))
33void matrix_scan_keymap(void) {}
34
35void matrix_scan_user(void) {
36 matrix_scan_keymap();
37}
38
39
40__attribute__ ((weak))
41bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
42 return true;
43}
44
45bool process_record_user(uint16_t keycode, keyrecord_t *record) {
46 return process_record_keymap(keycode, record);
47}
48
49
50__attribute__ ((weak))
51layer_state_t layer_state_set_keymap (layer_state_t state) {
52 return state;
53}
54
55layer_state_t layer_state_set_user (layer_state_t state) {
56 return layer_state_set_keymap (state);
57}
58
59
60__attribute__ ((weak))
61void led_set_keymap(uint8_t usb_led) {}
62
63void led_set_user(uint8_t usb_led) {
64 led_set_keymap(usb_led);
65}
66
67
68__attribute__ ((weak))
69void suspend_power_down_keymap(void) {}
70
71void suspend_power_down_user(void) {
72 suspend_power_down_keymap();
73}
74
75
76__attribute__ ((weak))
77void suspend_wakeup_init_keymap(void) {}
78
79void suspend_wakeup_init_user(void) {
80 suspend_wakeup_init_keymap();
81}
82
83
84__attribute__ ((weak))
85void shutdown_keymap(void) {}
86
87void shutdown_user (void) {
88 shutdown_keymap();
89}
90
91__attribute__ ((weak))
92void eeconfig_init_keymap(void) {}
93
94void eeconfig_init_user(void) {
95 eeconfig_init_keymap();
96}
97```
diff --git a/users/drashna/readme_keycodes.md b/users/drashna/readme_keycodes.md
new file mode 100644
index 000000000..f5e6fb271
--- /dev/null
+++ b/users/drashna/readme_keycodes.md
@@ -0,0 +1,10 @@
1
2# Custom Keycodes
3
4Keycodes are defined in the drashna.h file and need to be included in the keymap.c files, so that they can be used there.
5
6A bunch of macros are present and are only included on boards that are not the Ergodox EZ or Orthodox, as they are not needed for those boards.
7
8Included is a custom macro for compiling my keyboards. This includes the bootloader target (`:teensy`, `:avrdude`, or `:dfu`), and keeps RGBLIGHT, AUDIO and/or FAUXCLICKY enabled, if it previously was (regardless of the rules file).
9
10This also includes a modified RESET keycode as well, that sets the underglow to red.
diff --git a/users/drashna/readme_rgb.md b/users/drashna/readme_rgb.md
new file mode 100644
index 000000000..acf01b051
--- /dev/null
+++ b/users/drashna/readme_rgb.md
@@ -0,0 +1,43 @@
1# Layer Indication Code
2
3At least for RGB Light, the `layer_state_set` function is used to detect the current highest layer, and change the underglow based on that layer.
4
5This works for both the regular layers, and for the default layers, too.
6
7I use the sethsv variants of the commands, so that different modes can be used, as well.
8
9RGB Matrix uses a custom, per board implementation, at the moment.
10
11# RGB Light Startup Animation
12
13On startup, if enabled, the board will cycle through the entire hue wheel, starting and ending on the default layer color.
14
15```c
16void keyboard_post_init_rgb(void) {
17#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_STARTUP_ANIMATION)
18 if (userspace_config.rgb_layer_change) { rgblight_enable_noeeprom(); }
19 if (rgblight_config.enable) {
20 layer_state_set_user(layer_state);
21 uint16_t old_hue = rgblight_config.hue;
22 rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
23 for (uint16_t i = 255; i > 0; i--) {
24 rgblight_sethsv_noeeprom( ( i + old_hue) % 255, 255, 255);
25 matrix_scan();
26 wait_ms(10);
27 }
28 }
29#endif
30 layer_state_set_user(layer_state);
31}
32```
33
34This could probably benefit from some cleanup and better handling.
35
36
37# RGB Light Twinkling
38
39This enables random twinkling of the LEDs when typing.
40
41# RGB Light Mod Indicators
42
43Allows feedback of which mods (oneshot or otherwise) are enabled.
diff --git a/users/drashna/readme_secrets.md b/users/drashna/readme_secrets.md
new file mode 100644
index 000000000..a9408dc2e
--- /dev/null
+++ b/users/drashna/readme_secrets.md
@@ -0,0 +1,123 @@
1# Secret Macros
2
3With help from gitter and Colinta, this adds the ability to add hidden macros from other users.
4
5First, I have several files that are hidden/excluded from Git/GitHub. These contain everything needed for the macros. To hide these files, open `.git/info/exclude` and add `secrets.c` and `secrets.h` to that file, below the comments.
6
7And this requires `KC_SECRET_1` through `KC_SECRET_5` to be added in your keycode enum (usually in your `<name>.h` file) the keycodes for the new macros.
8
9## Git Exclusion
10
11To prevent `git` from seeing, or committing the secret files, you can exclude them. What's the point of having secrets if they're posted on GitHub for everyone to see!?!
12
13You can do this with the `.git/info/exclude` file, so that it's only ignored locally. Unfortunately, that means it's not consistently handled on each system.
14
15However, if you create a `.gitignore` file in the same folder, you keep things consistent between every system that the code is checked out on.
16
17```c
18secrets.c
19secrets.h
20```
21
22## secrets.c
23
24Here is the magic. This handles including the "secrets", and adding the custom macros to send them.
25
26```c
27#include "drashna.h" // replace with your keymap's "h" file, or whatever file stores the keycodes
28
29#if (__has_include("secrets.h") && !defined(NO_SECRETS))
30#include "secrets.h"
31#else
32// `PROGMEM const char secret[][x]` may work better, but it takes up more space in the firmware
33// And I'm not familiar enough to know which is better or why...
34static const char * const secret[] = {
35 "test1",
36 "test2",
37 "test3",
38 "test4",
39 "test5"
40};
41#endif
42
43bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
44 switch (keycode) {
45 case KC_SECRET_1 ... KC_SECRET_5: // Secrets! Externally defined strings, not stored in repo
46 if (!record->event.pressed) {
47 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
48 send_string_with_delay(secret[keycode - KC_SECRET_1], MACRO_TIMER);
49 }
50 return false;
51 break;
52 }
53 return true;
54}
55```
56
57## secrets.h
58
59Now, for the actual secrets! The file needs to look like
60
61```c
62static const char * secrets[] = {
63 "secret1",
64 "secret2",
65 "secret3",
66 "secret4",
67 "secret5"
68};
69```
70
71Replacing the strings with the codes that you need.
72
73## Process Record
74
75In whichever file you have your `process_record_*` function in, you will want to add this to the top:
76
77```c
78__attribute__ ((weak))
79bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
80 return true;
81}
82```
83
84This is so that the function can be called here, and replaced in the `secrets.c` file, and so it won't error out if it doesn't exist.
85
86And then, in the `process_record_user` function, assuming you have `return process_record_keymap(keycode, record)` here, you'll want to replace the "final" return with the following. Otherwise, you want to replace the `return true;` with `return process_record_secrets(keycode, record);`
87
88```c
89bool process_record_user(uint16_t keycode, keyrecord_t *record) {
90 // your existing macro code here.
91 return process_record_keymap(keycode, record) && process_record_secrets(keycode, record);
92}
93```
94
95## rules.mk
96
97Here, you want your `/users/<name>/rules.mk` file to "detect" the existence of the `secrets.c` file, and only add it if the file exists.
98
99Additionally, to ensure that it's not added or processed in any way, it checks to see if `NO_SECRETS` is set. This way, if you run `make keyboard:name NO_SECRETS=yes`, it will remove the feature altogether.
100
101```make
102ifneq ($(strip $(NO_SECRETS)), yes)
103 ifneq ("$(wildcard $(USER_PATH)/secrets.c)","")
104 SRC += secrets.c
105 endif
106endif
107```
108
109Alternately, if you want to make sure that you can disable the function without messing with the file, you need to add this to your `/users/<name>/rules.mk`, so that it catches the flag:
110
111```make
112ifneq ("$(wildcard $(USER_PATH)/secrets.c)","")
113 SRC += secrets.c
114endif
115
116ifeq ($(strip $(NO_SECRETS)), yes)
117 OPT_DEFS += -DNO_SECRETS
118endif
119```
120
121## Extras
122
123Additionally, because this file isn't present in the repo at all, you could add additional functionality that nobody else will see.
diff --git a/users/drashna/readme_tap_dance.md b/users/drashna/readme_tap_dance.md
new file mode 100644
index 000000000..a61dd1f2b
--- /dev/null
+++ b/users/drashna/readme_tap_dance.md
@@ -0,0 +1,119 @@
1# Diablo Tap Dances
2
3My [Tap Dance](https://github.com/qmk/qmk_firmware/blob/master/users/drashna/tap_dances.c) file includes the tap dance declarations, and everything needed for them.
4
5This is used for making Diablo 3 much easier to plan, especially at high rift levels.
6
7This works by using Tap Dances. The taps don't actually "do anything". Instead, it sets up the interval for how often to send specific keypresses. As you can tell, this makes automating things very easy.
8
9For critics that think this is cheating, just search "[diablo 3 num lock auto cast](http://lmgtfy.com/?q=diablo+3+numlock+autocast)". This is just a simpler method, that doesn't require a numpad.
10
11
12## Custom Tap Dance Type
13The real fun here is that the tap dances use a custom defined Tap Dance type:
14
15```c
16#define ACTION_TAP_DANCE_DIABLO(index, keycode) { \
17 .fn = { NULL, (void *)diablo_tapdance_master, NULL }, \
18 .user_data = (void *)&((diable_keys_t) { index, keycode }), \
19 }
20```
21This lets me set an index and keycode for the tap dance. This isn't the cool part yet, but this allows for the really cool stuff.
22
23The Index is needed because I don't know how to handle it otherwise.
24
25## The Actual Dances
26
27These are the custom defined dances that I'm using. It sets up everything for later, using the above custom dance type.
28
29```c
30//Tap Dance Definitions, sets the index and the keycode.
31qk_tap_dance_action_t tap_dance_actions[] = {
32 // tap once to disable, and more to enable timed micros
33 [TD_D3_1] = ACTION_TAP_DANCE_DIABLO(0, KC_1),
34 [TD_D3_2] = ACTION_TAP_DANCE_DIABLO(1, KC_2),
35 [TD_D3_3] = ACTION_TAP_DANCE_DIABLO(2, KC_3),
36 [TD_D3_4] = ACTION_TAP_DANCE_DIABLO(3, KC_4),
37};
38```
39
40## Custom Data Structures
41
42First, to get this all working, there are a couple of things that need to be set up. In a header file (or you could put it into the keymap), you need to create a couple of custom structures:
43
44```c
45typedef struct {
46 uint16_t timer;
47 uint8_t key_interval;
48 uint8_t keycode;
49} diablo_timer_t;
50
51typedef struct {
52 uint8_t index;
53 uint8_t keycode;
54} diable_keys_t;
55```
56
57The first structure is for tracking each key that is being used. The second is to pass data from the Tap Dance action array to the actual function that we will need.
58
59
60## Custom Arrays
61
62To facilitate things, you will need a couple of arrays in your `c` file.
63
64```c
65//define diablo macro timer variables
66diablo_timer_t diablo_timer[4];
67
68// Set the default intervals. Always start with 0 so that it will disable on first hit.
69// Otherwise, you will need to hit a bunch of times, or hit the "clear" command
70uint8_t diablo_times[] = { 0, 1, 3, 5, 10, 30 };
71```
72
73The first one (`diablo_timer`) is what keeps track of the timer used for the keys, the interval that it uses, and the actual keycode. This makes managing it a lot easier.
74
75The second array is a list of predefined intervals, in seconds. You can add more here, or remove entries. It doesn't matter how long the array is, as this is computed automatically.
76
77## The Magic - Part 1: Master function
78
79The first part of the magic here is the `diablo_tapdance_master` function. The Tap Dance feature calls this function, directly, and passes some data to the function. Namely, it passes the array of the index and the keycode (`diablo_keys_t` from above). This sets the keycode and the interval for the specific index of `diabolo_timer` based on the number of taps. If you hit it more than the number of items in the array, then it zeroes out the interval, disabling it.
80
81```c
82// Cycle through the times for the macro, starting at 0, for disabled.
83void diablo_tapdance_master(qk_tap_dance_state_t *state, void *user_data) {
84 diable_keys_t *diablo_keys = (diable_keys_t *)user_data;
85 // Sets the keycode based on the index
86 diablo_timer[diablo_keys->index].keycode = diablo_keys->keycode;
87
88 // if the tapdance is hit more than the number of elemints in the array, reset
89 if (state->count >= (sizeof(diablo_times) / sizeof(uint8_t) ) ) {
90 diablo_timer[diablo_keys->index].key_interval = 0;
91 reset_tap_dance(state);
92 } else { // else set the interval (tapdance count starts at 1, array starts at 0, so offset by one)
93 diablo_timer[diablo_keys->index].key_interval = diablo_times[state->count - 1];
94 }
95}
96```
97
98## The Magic - Part 2: The Coup de Grace
99
100The real core here is the `run_diablo_macro_check()` function. You need to call this from `matrix_scan_user`, as this handles the timer check.
101
102Specifically, it runs a check for each index of the timer. It checks to see if it's enabled, and if enough time has passed. If enough time has passed, it resets the timer, and will tap the keycode that you set for that index, but only if the Diablo layer is enabled.
103
104```c
105// Checks each of the 4 timers/keys to see if enough time has elapsed
106void run_diablo_macro_check(void) {
107 for (uint8_t index = 0; index < NUM_OF_DIABLO_KEYS; index++) {
108 // if key_interval is 0, it's disabled, so only run if it's set. If it's set, check the timer.
109 if ( diablo_timer[index].key_interval && timer_elapsed( diablo_timer[index].timer ) > ( diablo_timer[index].key_interval * 1000 ) ) {
110 // reset the timer, since enough time has passed
111 diablo_timer[index].timer = timer_read();
112 // send keycode ONLY if we're on the diablo layer.
113 if (IS_LAYER_ON(_DIABLO)) {
114 tap_code(diablo_timer[index].keycode);
115 }
116 }
117 }
118}
119```
diff --git a/users/drashna/readme_wrappers.md b/users/drashna/readme_wrappers.md
new file mode 100644
index 000000000..fd62ff160
--- /dev/null
+++ b/users/drashna/readme_wrappers.md
@@ -0,0 +1,11 @@
1## Keyboard Layout Templates
2
3This borrows from @jola5's "Not quite neo" code. This allows me to maintain blocks of keymaps in the userspace, so that I can modify the userspace, and this is reflected in all of the keyboards that use it, at once.
4
5This makes adding tap/hold mods, or other special keycodes or functions to all keyboards super easy, as it's done to all of them at once.
6
7The caveat here is that the keymap needs a processor/wrapper, as it doesn't like the substitutions. However, this is as simple as just pushing it through a define. For instance:
8
9`#define LAYOUT_ergodox_wrapper(...) LAYOUT_ergodox(__VA_ARGS__)`
10
11Once that's been done and you've switched the keymaps to use the "wrapper", it will read the substitution blocks just fine.
diff --git a/users/drashna/rgb_stuff.c b/users/drashna/rgb_stuff.c
index 7d364fa68..12851e261 100644
--- a/users/drashna/rgb_stuff.c
+++ b/users/drashna/rgb_stuff.c
@@ -4,77 +4,75 @@
4 4
5#if defined(RGBLIGHT_ENABLE) 5#if defined(RGBLIGHT_ENABLE)
6extern rgblight_config_t rgblight_config; 6extern rgblight_config_t rgblight_config;
7bool has_initialized; 7bool has_initialized;
8#endif 8#endif
9 9
10#ifdef RGBLIGHT_ENABLE 10#ifdef RGBLIGHT_ENABLE
11void rgblight_sethsv_default_helper(uint8_t index) { 11void rgblight_sethsv_default_helper(uint8_t index) { rgblight_sethsv_at(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, index); }
12 rgblight_sethsv_at(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, index); 12#endif // RGBLIGHT_ENABLE
13}
14#endif // RGBLIGHT_ENABLE
15 13
16#ifdef INDICATOR_LIGHTS 14#ifdef INDICATOR_LIGHTS
17void set_rgb_indicators(uint8_t this_mod, uint8_t this_led, uint8_t this_osm) { 15void set_rgb_indicators(uint8_t this_mod, uint8_t this_led, uint8_t this_osm) {
18 if (userspace_config.rgb_layer_change && biton32(layer_state) == 0) { 16 if (userspace_config.rgb_layer_change && biton32(layer_state) == 0) {
19 if ( (this_mod | this_osm) & MOD_MASK_SHIFT || this_led & (1<<USB_LED_CAPS_LOCK) ) { 17 if ((this_mod | this_osm) & MOD_MASK_SHIFT || this_led & (1 << USB_LED_CAPS_LOCK)) {
20 #ifdef SHFT_LED1 18# ifdef SHFT_LED1
21 rgblight_sethsv_at(120, 255, 255, SHFT_LED1); 19 rgblight_sethsv_at(120, 255, 255, SHFT_LED1);
22 #endif // SHFT_LED1 20# endif // SHFT_LED1
23 #ifdef SHFT_LED2 21# ifdef SHFT_LED2
24 rgblight_sethsv_at(120, 255, 255, SHFT_LED2); 22 rgblight_sethsv_at(120, 255, 255, SHFT_LED2);
25 #endif // SHFT_LED2 23# endif // SHFT_LED2
26 } else { 24 } else {
27 #ifdef SHFT_LED1 25# ifdef SHFT_LED1
28 rgblight_sethsv_default_helper(SHFT_LED1); 26 rgblight_sethsv_default_helper(SHFT_LED1);
29 #endif // SHFT_LED1 27# endif // SHFT_LED1
30 #ifdef SHFT_LED2 28# ifdef SHFT_LED2
31 rgblight_sethsv_default_helper(SHFT_LED2); 29 rgblight_sethsv_default_helper(SHFT_LED2);
32 #endif // SHFT_LED2 30# endif // SHFT_LED2
33 } 31 }
34 if ( (this_mod | this_osm) & MOD_MASK_CTRL) { 32 if ((this_mod | this_osm) & MOD_MASK_CTRL) {
35 #ifdef CTRL_LED1 33# ifdef CTRL_LED1
36 rgblight_sethsv_at(0, 255, 255, CTRL_LED1); 34 rgblight_sethsv_at(0, 255, 255, CTRL_LED1);
37 #endif // CTRL_LED1 35# endif // CTRL_LED1
38 #ifdef CTRL_LED2 36# ifdef CTRL_LED2
39 rgblight_sethsv_at(0, 255, 255, CTRL_LED2); 37 rgblight_sethsv_at(0, 255, 255, CTRL_LED2);
40 #endif // CTRL_LED2 38# endif // CTRL_LED2
41 } else { 39 } else {
42 #ifdef CTRL_LED1 40# ifdef CTRL_LED1
43 rgblight_sethsv_default_helper(CTRL_LED1); 41 rgblight_sethsv_default_helper(CTRL_LED1);
44 #endif // CTRL_LED1 42# endif // CTRL_LED1
45 #ifdef CTRL_LED2 43# ifdef CTRL_LED2
46 rgblight_sethsv_default_helper(CTRL_LED2); 44 rgblight_sethsv_default_helper(CTRL_LED2);
47 #endif // CTRL_LED2 45# endif // CTRL_LED2
48 } 46 }
49 if ( (this_mod | this_osm) & MOD_MASK_GUI) { 47 if ((this_mod | this_osm) & MOD_MASK_GUI) {
50 #ifdef GUI_LED1 48# ifdef GUI_LED1
51 rgblight_sethsv_at(51, 255, 255, GUI_LED1); 49 rgblight_sethsv_at(51, 255, 255, GUI_LED1);
52 #endif // GUI_LED1 50# endif // GUI_LED1
53 #ifdef GUI_LED2 51# ifdef GUI_LED2
54 rgblight_sethsv_at(51, 255, 255, GUI_LED2); 52 rgblight_sethsv_at(51, 255, 255, GUI_LED2);
55 #endif // GUI_LED2 53# endif // GUI_LED2
56 } else { 54 } else {
57 #ifdef GUI_LED1 55# ifdef GUI_LED1
58 rgblight_sethsv_default_helper(GUI_LED1); 56 rgblight_sethsv_default_helper(GUI_LED1);
59 #endif // GUI_LED1 57# endif // GUI_LED1
60 #ifdef GUI_LED2 58# ifdef GUI_LED2
61 rgblight_sethsv_default_helper(GUI_LED2); 59 rgblight_sethsv_default_helper(GUI_LED2);
62 #endif // GUI_LED2 60# endif // GUI_LED2
63 } 61 }
64 if ( (this_mod | this_osm) & MOD_MASK_ALT) { 62 if ((this_mod | this_osm) & MOD_MASK_ALT) {
65 #ifdef ALT_LED1 63# ifdef ALT_LED1
66 rgblight_sethsv_at(240, 255, 255, ALT_LED1); 64 rgblight_sethsv_at(240, 255, 255, ALT_LED1);
67 #endif // ALT_LED1 65# endif // ALT_LED1
68 #ifdef GUI_LED2 66# ifdef GUI_LED2
69 rgblight_sethsv_at(240, 255, 255, ALT_LED2); 67 rgblight_sethsv_at(240, 255, 255, ALT_LED2);
70 #endif // GUI_LED2 68# endif // GUI_LED2
71 } else { 69 } else {
72 #ifdef GUI_LED1 70# ifdef GUI_LED1
73 rgblight_sethsv_default_helper(ALT_LED1); 71 rgblight_sethsv_default_helper(ALT_LED1);
74 #endif // GUI_LED1 72# endif // GUI_LED1
75 #ifdef GUI_LED2 73# ifdef GUI_LED2
76 rgblight_sethsv_default_helper(ALT_LED2); 74 rgblight_sethsv_default_helper(ALT_LED2);
77 #endif // GUI_LED2 75# endif // GUI_LED2
78 } 76 }
79 } 77 }
80} 78}
@@ -84,75 +82,73 @@ void matrix_scan_indicator(void) {
84 set_rgb_indicators(get_mods(), host_keyboard_leds(), get_oneshot_mods()); 82 set_rgb_indicators(get_mods(), host_keyboard_leds(), get_oneshot_mods());
85 } 83 }
86} 84}
87#endif //INDICATOR_LIGHTS 85#endif // INDICATOR_LIGHTS
88 86
89#ifdef RGBLIGHT_TWINKLE 87#ifdef RGBLIGHT_TWINKLE
90static rgblight_fadeout lights[RGBLED_NUM]; 88static rgblight_fadeout lights[RGBLED_NUM];
91 89
92__attribute__ ((weak)) 90__attribute__((weak)) bool rgblight_twinkle_is_led_used_keymap(uint8_t index) { return false; }
93bool rgblight_twinkle_is_led_used_keymap(uint8_t index) { return false; }
94 91
95bool rgblight_twinkle_is_led_used(uint8_t index) { 92bool rgblight_twinkle_is_led_used(uint8_t index) {
96 switch (index) { 93 switch (index) {
97#ifdef INDICATOR_LIGHTS 94# ifdef INDICATOR_LIGHTS
98#ifdef SHFT_LED1 95# ifdef SHFT_LED1
99 case SHFT_LED1: 96 case SHFT_LED1:
100 return true; 97 return true;
101#endif //SHFT_LED1 98# endif // SHFT_LED1
102#ifdef SHFT_LED2 99# ifdef SHFT_LED2
103 case SHFT_LED2: 100 case SHFT_LED2:
104 return true; 101 return true;
105#endif //SHFT_LED2 102# endif // SHFT_LED2
106#ifdef CTRL_LED1 103# ifdef CTRL_LED1
107 case CTRL_LED1: 104 case CTRL_LED1:
108 return true; 105 return true;
109#endif //CTRL_LED1 106# endif // CTRL_LED1
110#ifdef CTRL_LED2 107# ifdef CTRL_LED2
111 case CTRL_LED2: 108 case CTRL_LED2:
112 return true; 109 return true;
113#endif //CTRL_LED2 110# endif // CTRL_LED2
114#ifdef GUI_LED1 111# ifdef GUI_LED1
115 case GUI_LED1: 112 case GUI_LED1:
116 return true; 113 return true;
117#endif //GUI_LED1 114# endif // GUI_LED1
118#ifdef GUI_LED2 115# ifdef GUI_LED2
119 case GUI_LED2: 116 case GUI_LED2:
120 return true; 117 return true;
121#endif //GUI_LED2 118# endif // GUI_LED2
122#ifdef ALT_LED1 119# ifdef ALT_LED1
123 case ALT_LED1: 120 case ALT_LED1:
124 return true; 121 return true;
125#endif //ALT_LED1 122# endif // ALT_LED1
126#ifdef ALT_LED2 123# ifdef ALT_LED2
127 case ALT_LED2: 124 case ALT_LED2:
128 return true; 125 return true;
129#endif //ALT_LED2 126# endif // ALT_LED2
130#endif //INDICATOR_LIGHTS 127# endif // INDICATOR_LIGHTS
131 default: 128 default:
132 return rgblight_twinkle_is_led_used_keymap(index); 129 return rgblight_twinkle_is_led_used_keymap(index);
133 } 130 }
134} 131}
135 132
136void scan_rgblight_fadeout(void) { // Don't effing change this function .... rgblight_sethsv is supppppper intensive 133void scan_rgblight_fadeout(void) { // Don't effing change this function .... rgblight_sethsv is supppppper intensive
137 bool litup = false; 134 bool litup = false;
138 for (uint8_t light_index = 0 ; light_index < RGBLED_NUM ; ++light_index ) { 135 for (uint8_t light_index = 0; light_index < RGBLED_NUM; ++light_index) {
139 if (lights[light_index].enabled && timer_elapsed(lights[light_index].timer) > 10) { 136 if (lights[light_index].enabled && timer_elapsed(lights[light_index].timer) > 10) {
140 rgblight_fadeout *light = &lights[light_index]; 137 rgblight_fadeout *light = &lights[light_index];
141 litup = true; 138 litup = true;
142 139
143 if (light->life) { 140 if (light->life) {
144 light->life -= 1; 141 light->life -= 1;
145 if (biton32(layer_state) == 0) { 142 if (biton32(layer_state) == 0) {
146 sethsv(light->hue + rand() % 0xF, 255, light->life, (LED_TYPE *)&led[light_index]); 143 sethsv(light->hue + rand() % 0xF, 255, light->life, (LED_TYPE *)&led[light_index]);
147 } 144 }
148 light->timer = timer_read(); 145 light->timer = timer_read();
149 } 146 } else {
150 else { 147 if (light->enabled && biton32(layer_state) == 0) {
151 if (light->enabled && biton32(layer_state) == 0) { 148 rgblight_sethsv_default_helper(light_index);
152 rgblight_sethsv_default_helper(light_index); 149 }
150 litup = light->enabled = false;
153 } 151 }
154 litup = light->enabled = false;
155 }
156 } 152 }
157 } 153 }
158 if (litup && biton32(layer_state) == 0) { 154 if (litup && biton32(layer_state) == 0) {
@@ -161,39 +157,37 @@ void scan_rgblight_fadeout(void) { // Don't effing change this function .... rgb
161} 157}
162 158
163void start_rgb_light(void) { 159void start_rgb_light(void) {
164
165 uint8_t indices[RGBLED_NUM]; 160 uint8_t indices[RGBLED_NUM];
166 uint8_t indices_count = 0; 161 uint8_t indices_count = 0;
167 uint8_t min_life = 0xFF; 162 uint8_t min_life = 0xFF;
168 uint8_t min_life_index = -1; 163 uint8_t min_life_index = -1;
169 for (uint8_t index = 0 ; index < RGBLED_NUM ; ++index ) { 164 for (uint8_t index = 0; index < RGBLED_NUM; ++index) {
170 if (rgblight_twinkle_is_led_used(index)) { continue; } 165 if (rgblight_twinkle_is_led_used(index)) {
171 if (lights[index].enabled) { 166 continue;
172 if (min_life_index == -1 || 167 }
173 lights[index].life < min_life) 168 if (lights[index].enabled) {
174 { 169 if (min_life_index == -1 || lights[index].life < min_life) {
175 min_life = lights[index].life; 170 min_life = lights[index].life;
176 min_life_index = index; 171 min_life_index = index;
172 }
173 continue;
177 } 174 }
178 continue;
179 }
180 175
181 indices[indices_count] = index; 176 indices[indices_count] = index;
182 ++indices_count; 177 ++indices_count;
183 } 178 }
184 179
185 uint8_t light_index; 180 uint8_t light_index;
186 if (!indices_count) { 181 if (!indices_count) {
187 light_index = min_life_index; 182 light_index = min_life_index;
188 } 183 } else {
189 else { 184 light_index = indices[rand() % indices_count];
190 light_index = indices[rand() % indices_count];
191 } 185 }
192 186
193 rgblight_fadeout *light = &lights[light_index]; 187 rgblight_fadeout *light = &lights[light_index];
194 light->enabled = true; 188 light->enabled = true;
195 light->timer = timer_read(); 189 light->timer = timer_read();
196 light->life = 0xC0 + rand() % 0x40; 190 light->life = 0xC0 + rand() % 0x40;
197 191
198 light->hue = rgblight_config.hue + (rand() % 0xB4) - 0x54; 192 light->hue = rgblight_config.hue + (rand() % 0xB4) - 0x54;
199 193
@@ -201,7 +195,6 @@ void start_rgb_light(void) {
201} 195}
202#endif 196#endif
203 197
204
205bool process_record_user_rgb(uint16_t keycode, keyrecord_t *record) { 198bool process_record_user_rgb(uint16_t keycode, keyrecord_t *record) {
206 if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) { 199 if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
207 keycode = keycode & 0xFF; 200 keycode = keycode & 0xFF;
@@ -214,9 +207,12 @@ bool process_record_user_rgb(uint16_t keycode, keyrecord_t *record) {
214 case KC_KP_SLASH ... KC_KP_DOT: 207 case KC_KP_SLASH ... KC_KP_DOT:
215 case KC_F13 ... KC_F24: 208 case KC_F13 ... KC_F24:
216 case KC_AUDIO_MUTE ... KC_MEDIA_REWIND: 209 case KC_AUDIO_MUTE ... KC_MEDIA_REWIND:
217 if (record->event.pressed) { start_rgb_light(); } 210 if (record->event.pressed) {
218 return true; break; 211 start_rgb_light();
219#endif // RGBLIGHT_TWINKLE 212 }
213 return true;
214 break;
215#endif // RGBLIGHT_TWINKLE
220 case KC_RGB_T: // This allows me to use underglow as layer indication, or as normal 216 case KC_RGB_T: // This allows me to use underglow as layer indication, or as normal
221#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) 217#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
222 if (record->event.pressed) { 218 if (record->event.pressed) {
@@ -224,41 +220,48 @@ bool process_record_user_rgb(uint16_t keycode, keyrecord_t *record) {
224 xprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change); 220 xprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change);
225 eeconfig_update_user(userspace_config.raw); 221 eeconfig_update_user(userspace_config.raw);
226 if (userspace_config.rgb_layer_change) { 222 if (userspace_config.rgb_layer_change) {
227 layer_state_set(layer_state); // This is needed to immediately set the layer color (looks better) 223 layer_state_set(layer_state); // This is needed to immediately set the layer color (looks better)
228 } 224 }
229 } 225 }
230#endif // RGBLIGHT_ENABLE 226#endif // RGBLIGHT_ENABLE
231 return false; break; 227 return false;
228 break;
232#ifdef RGBLIGHT_ENABLE 229#ifdef RGBLIGHT_ENABLE
233 case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // quantum_keycodes.h L400 for definitions 230 case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // quantum_keycodes.h L400 for definitions
234 if (record->event.pressed) { //This disables layer indication, as it's assumed that if you're changing this ... you want that disabled 231 if (record->event.pressed) { // This disables layer indication, as it's assumed that if you're changing this ... you want that disabled
235 if (userspace_config.rgb_layer_change) { 232 if (userspace_config.rgb_layer_change) {
236 userspace_config.rgb_layer_change = false; 233 userspace_config.rgb_layer_change = false;
237 xprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change); 234 xprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change);
238 eeconfig_update_user(userspace_config.raw); 235 eeconfig_update_user(userspace_config.raw);
239 } 236 }
240 } 237 }
241 return true; break; 238 return true;
242#endif // RGBLIGHT_ENABLE 239 break;
243 } 240#endif // RGBLIGHT_ENABLE
241 }
244 return true; 242 return true;
245} 243}
246 244
247
248
249void keyboard_post_init_rgb(void) { 245void keyboard_post_init_rgb(void) {
250#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_STARTUP_ANIMATION) 246#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_STARTUP_ANIMATION)
251 if (userspace_config.rgb_layer_change) { rgblight_enable_noeeprom(); } 247 bool is_enabled = rgblight_config.enable;
248 if (userspace_config.rgb_layer_change) {
249 rgblight_enable_noeeprom();
250 }
252 if (rgblight_config.enable) { 251 if (rgblight_config.enable) {
253 layer_state_set_user(layer_state); 252 layer_state_set_user(layer_state);
254 uint16_t old_hue = rgblight_config.hue; 253 uint16_t old_hue = rgblight_config.hue;
255 rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT); 254 rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
256 for (uint16_t i = 255; i > 0; i--) { 255 for (uint16_t i = 255; i > 0; i--) {
257 rgblight_sethsv_noeeprom( ( i + old_hue) % 255, 255, 255); 256 rgblight_sethsv_noeeprom((i + old_hue) % 255, 255, 255);
258 matrix_scan(); 257 matrix_scan();
259 wait_ms(10); 258 wait_ms(10);
260 } 259 }
261 } 260 }
261 if (!is_enabled) {
262 rgblight_disable_noeeprom();
263 }
264
262#endif 265#endif
263 layer_state_set_user(layer_state); 266 layer_state_set_user(layer_state);
264} 267}
@@ -266,15 +269,13 @@ void keyboard_post_init_rgb(void) {
266void matrix_scan_rgb(void) { 269void matrix_scan_rgb(void) {
267#ifdef RGBLIGHT_TWINKLE 270#ifdef RGBLIGHT_TWINKLE
268 scan_rgblight_fadeout(); 271 scan_rgblight_fadeout();
269#endif // RGBLIGHT_ENABLE 272#endif // RGBLIGHT_ENABLE
270 273
271#ifdef INDICATOR_LIGHTS 274#ifdef INDICATOR_LIGHTS
272 matrix_scan_indicator(); 275 matrix_scan_indicator();
273#endif 276#endif
274
275} 277}
276 278
277
278layer_state_t layer_state_set_rgb(layer_state_t state) { 279layer_state_t layer_state_set_rgb(layer_state_t state) {
279#ifdef RGBLIGHT_ENABLE 280#ifdef RGBLIGHT_ENABLE
280 if (userspace_config.rgb_layer_change) { 281 if (userspace_config.rgb_layer_change) {
@@ -307,40 +308,73 @@ layer_state_t layer_state_set_rgb(layer_state_t state) {
307 rgblight_sethsv_noeeprom_red(); 308 rgblight_sethsv_noeeprom_red();
308 rgblight_mode_noeeprom(RGBLIGHT_MODE_KNIGHT + 2); 309 rgblight_mode_noeeprom(RGBLIGHT_MODE_KNIGHT + 2);
309 break; 310 break;
310 default: // for any other layers, or the default layer 311 default: // for any other layers, or the default layer
311 switch (biton32(default_layer_state)) { 312 switch (biton32(default_layer_state)) {
312 case _COLEMAK: 313 case _COLEMAK:
313 rgblight_sethsv_noeeprom_magenta(); break; 314 rgblight_sethsv_noeeprom_magenta();
315 break;
314 case _DVORAK: 316 case _DVORAK:
315 rgblight_sethsv_noeeprom_springgreen(); break; 317 rgblight_sethsv_noeeprom_springgreen();
318 break;
316 case _WORKMAN: 319 case _WORKMAN:
317 rgblight_sethsv_noeeprom_goldenrod(); break; 320 rgblight_sethsv_noeeprom_goldenrod();
321 break;
318 case _NORMAN: 322 case _NORMAN:
319 rgblight_sethsv_noeeprom_coral(); break; 323 rgblight_sethsv_noeeprom_coral();
324 break;
320 case _MALTRON: 325 case _MALTRON:
321 rgblight_sethsv_noeeprom_yellow(); break; 326 rgblight_sethsv_noeeprom_yellow();
327 break;
322 case _EUCALYN: 328 case _EUCALYN:
323 rgblight_sethsv_noeeprom_pink(); break; 329 rgblight_sethsv_noeeprom_pink();
330 break;
324 case _CARPLAX: 331 case _CARPLAX:
325 rgblight_sethsv_noeeprom_blue(); break; 332 rgblight_sethsv_noeeprom_blue();
333 break;
326 default: 334 default:
327 rgblight_sethsv_noeeprom_cyan(); break; 335 rgblight_sethsv_noeeprom_cyan();
336 break;
328 } 337 }
329 biton32(state) == _MODS ? rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING) : rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT); // if _MODS layer is on, then breath to denote it 338 biton32(state) == _MODS ? rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING) : rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT); // if _MODS layer is on, then breath to denote it
330 break; 339 break;
331 } 340 }
332 } 341 }
333#endif // RGBLIGHT_ENABLE 342#endif // RGBLIGHT_ENABLE
334 343
335 return state; 344 return state;
336} 345}
337 346
338#ifdef RGB_MATRIX_ENABLE 347#ifdef RGB_MATRIX_ENABLE
348# include "lib/lib8tion/lib8tion.h"
339extern led_config_t g_led_config; 349extern led_config_t g_led_config;
340void rgb_matrix_layer_helper (uint8_t red, uint8_t green, uint8_t blue, uint8_t led_type) { 350void rgb_matrix_layer_helper(uint8_t hue, uint8_t sat, uint8_t val, uint8_t mode, uint8_t speed, uint8_t led_type) {
341 for (int i = 0; i < DRIVER_LED_TOTAL; i++) { 351 HSV hsv = {hue, sat, val};
342 if (HAS_FLAGS(g_led_config.flags[i], led_type)) { 352 if (hsv.v > rgb_matrix_config.hsv.v) {
343 rgb_matrix_set_color( i, red, green, blue ); 353 hsv.v = rgb_matrix_config.hsv.v;
354 }
355
356 switch (mode) {
357 case 1: // breathing
358 {
359 uint16_t time = scale16by8(g_rgb_counters.tick, speed / 8);
360 hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
361 RGB rgb = hsv_to_rgb(hsv);
362 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
363 if (HAS_FLAGS(g_led_config.flags[i], led_type)) {
364 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
365 }
366 }
367 break;
368 }
369 default: // Solid Color
370 {
371 RGB rgb = hsv_to_rgb(hsv);
372 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
373 if (HAS_FLAGS(g_led_config.flags[i], led_type)) {
374 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
375 }
376 }
377 break;
344 } 378 }
345 } 379 }
346} 380}
diff --git a/users/drashna/rgb_stuff.h b/users/drashna/rgb_stuff.h
index f5bbd0f3b..ce45d6a00 100644
--- a/users/drashna/rgb_stuff.h
+++ b/users/drashna/rgb_stuff.h
@@ -1,23 +1,23 @@
1#pragma once 1#pragma once
2#include "quantum.h" 2#include "quantum.h"
3#ifdef RGB_MATRIX_ENABLE 3#ifdef RGB_MATRIX_ENABLE
4 #include "rgb_matrix.h" 4# include "rgb_matrix.h"
5#endif 5#endif
6 6
7typedef struct { 7typedef struct {
8 bool enabled; 8 bool enabled;
9 uint8_t hue; 9 uint8_t hue;
10 uint16_t timer; 10 uint16_t timer;
11 uint8_t life; 11 uint8_t life;
12} rgblight_fadeout; 12} rgblight_fadeout;
13 13
14bool process_record_user_rgb(uint16_t keycode, keyrecord_t *record); 14bool process_record_user_rgb(uint16_t keycode, keyrecord_t *record);
15void scan_rgblight_fadeout(void); 15void scan_rgblight_fadeout(void);
16void keyboard_post_init_rgb(void); 16void keyboard_post_init_rgb(void);
17void matrix_scan_rgb(void); 17void matrix_scan_rgb(void);
18layer_state_t layer_state_set_rgb(layer_state_t state); 18layer_state_t layer_state_set_rgb(layer_state_t state);
19layer_state_t default_layer_state_set_rgb(layer_state_t state); 19layer_state_t default_layer_state_set_rgb(layer_state_t state);
20void rgblight_sethsv_default_helper(uint8_t index); 20void rgblight_sethsv_default_helper(uint8_t index);
21void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); 21void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
22 22
23void rgb_matrix_layer_helper (uint8_t red, uint8_t green, uint8_t blue, uint8_t led_type); 23void rgb_matrix_layer_helper(uint8_t hue, uint8_t sat, uint8_t val, uint8_t mode, uint8_t speed, uint8_t led_type);
diff --git a/users/drashna/rules.mk b/users/drashna/rules.mk
index cdb9e5436..b414036a4 100644
--- a/users/drashna/rules.mk
+++ b/users/drashna/rules.mk
@@ -2,6 +2,7 @@ SRC += drashna.c \
2 process_records.c 2 process_records.c
3 3
4LINK_TIME_OPTIMIZATION_ENABLE = yes 4LINK_TIME_OPTIMIZATION_ENABLE = yes
5SPACE_CADET_ENABLE = no
5 6
6ifneq ("$(wildcard $(USER_PATH)/secrets.c)","") 7ifneq ("$(wildcard $(USER_PATH)/secrets.c)","")
7 SRC += secrets.c 8 SRC += secrets.c
diff --git a/users/drashna/send_unicode.h b/users/drashna/send_unicode.h
deleted file mode 100644
index 743abc58b..000000000
--- a/users/drashna/send_unicode.h
+++ /dev/null
@@ -1,71 +0,0 @@
1#pragma once
2
3#include "quantum.h"
4
5void send_unicode_hex_string(const char* str);
6
7/* use X(n) to call the */
8#ifdef UNICODEMAP_ENABLE
9enum unicode_name {
10 THINK, // thinking face 🤔
11 GRIN, // grinning face 😊
12 SMRK, // smirk 😏
13 WEARY, // good shit 😩
14 UNAMU, // unamused 😒
15
16 SNEK, // snke 🐍
17 PENGUIN, // 🐧
18 DRAGON, // 🐉
19 MONKEY, // 🐒
20 CHICK, // 🐥
21 BOAR, // 🐗
22
23 OKOK, // 👌
24 EFFU, // 🖕
25 INUP, // 👆
26 THUP, // 👍
27 THDN, // 👎
28
29 BBB, // dat B 🅱
30 POO, // poop 💩
31 HUNDR, // 100 💯
32 EGGPL, // EGGPLANT 🍆
33 WATER, // wet 💦
34 TUMBLER, // 🥃
35
36 LIT, // fire 🔥
37 BANG, // ‽
38 IRONY, // ⸮
39 DEGREE // °
40};
41
42
43const uint32_t PROGMEM unicode_map[] = {
44 [THINK] = 0x1F914,
45 [GRIN] = 0x1F600,
46 [BBB] = 0x1F171,
47 [POO] = 0x1F4A9,
48 [HUNDR] = 0x1F4AF,
49 [SMRK] = 0x1F60F,
50 [WEARY] = 0x1F629,
51 [EGGPL] = 0x1F346,
52 [WATER] = 0x1F4A6,
53 [LIT] = 0x1F525,
54 [UNAMU] = 0x1F612,
55 [SNEK] = 0x1F40D,
56 [PENGUIN] = 0x1F427,
57 [BOAR] = 0x1F417,
58 [MONKEY] = 0x1F412,
59 [CHICK] = 0x1F425,
60 [DRAGON] = 0x1F409,
61 [OKOK] = 0x1F44C,
62 [EFFU] = 0x1F595,
63 [INUP] = 0x1F446,
64 [THDN] = 0x1F44E,
65 [THUP] = 0x1F44D,
66 [TUMBLER] = 0x1F943,
67 [BANG] = 0x0203D,
68 [IRONY] = 0x02E2E,
69 [DEGREE] = 0x000B0
70 };
71#endif // UNICODEMAP_ENABLE
diff --git a/users/drashna/tap_dances.c b/users/drashna/tap_dances.c
index 18ca96e18..65019ab75 100644
--- a/users/drashna/tap_dances.c
+++ b/users/drashna/tap_dances.c
@@ -1,65 +1,56 @@
1#include "tap_dances.h" 1#include "tap_dances.h"
2 2
3#define NUM_OF_DIABLO_KEYS 4
4// define diablo macro timer variables
5diablo_timer_t diablo_timer[NUM_OF_DIABLO_KEYS];
3 6
4//define diablo macro timer variables 7// Set the default intervals. Always start with 0 so that it will disable on first hit.
5diablo_timer_t diablo_timer[4]; 8// Otherwise, you will need to hit a bunch of times, or hit the "clear" command
6 9uint8_t diablo_times[] = {0, 1, 3, 5, 10, 30};
7uint8_t diablo_times[] = { 0, 0, 1, 3, 5, 10, 30 };
8
9// has the correct number of seconds elapsed (as defined by diablo_times)
10bool check_dtimer(uint8_t dtimer) { return (timer_elapsed(diablo_timer[dtimer].key_time) < (diablo_timer[dtimer].timer * 1000)) ? false : true; };
11 10
12// Cycle through the times for the macro, starting at 0, for disabled. 11// Cycle through the times for the macro, starting at 0, for disabled.
13// Max of six values, so don't exceed
14void diablo_tapdance_master(qk_tap_dance_state_t *state, void *user_data) { 12void diablo_tapdance_master(qk_tap_dance_state_t *state, void *user_data) {
15 int index = (int)user_data; 13 diable_keys_t *diablo_keys = (diable_keys_t *)user_data;
16 if (state->count >= 7) { 14 // Sets the keycode based on the index
17 diablo_timer[index].key_time = diablo_times[0]; 15 diablo_timer[diablo_keys->index].keycode = diablo_keys->keycode;
16
17 // if the tapdance is hit more than the number of elemints in the array, reset
18 if (state->count >= (sizeof(diablo_times) / sizeof(uint8_t))) {
19 diablo_timer[diablo_keys->index].key_interval = 0;
18 reset_tap_dance(state); 20 reset_tap_dance(state);
19 } else { 21 } else { // else set the interval (tapdance count starts at 1, array starts at 0, so offset by one)
20 diablo_timer[index].key_time = diablo_times[state->count]; 22 diablo_timer[diablo_keys->index].key_interval = diablo_times[state->count - 1];
21 } 23 }
22} 24}
23 25
24// One funtion to rule them all!! 26// clang-format off
25#define ACTION_TAP_DANCE_DIABLO(arg) { \ 27// One function to rule them all!! Where the Magic Sauce lies
28#define ACTION_TAP_DANCE_DIABLO(index, keycode) { \
26 .fn = { NULL, (void *)diablo_tapdance_master, NULL }, \ 29 .fn = { NULL, (void *)diablo_tapdance_master, NULL }, \
27 .user_data = (void *)arg, \ 30 .user_data = (void *)&((diable_keys_t) { index, keycode }), \
28 } 31 }
32// clang-format on
29 33
30//Tap Dance Definitions 34// Tap Dance Definitions, sets the index and the keycode.
31qk_tap_dance_action_t tap_dance_actions[] = { 35qk_tap_dance_action_t tap_dance_actions[] = {
32 // tap once to disable, and more to enable timed micros 36 // tap once to disable, and more to enable timed micros
33 [TD_D3_1] = ACTION_TAP_DANCE_DIABLO(0), 37 [TD_D3_1] = ACTION_TAP_DANCE_DIABLO(0, KC_1),
34 [TD_D3_2] = ACTION_TAP_DANCE_DIABLO(1), 38 [TD_D3_2] = ACTION_TAP_DANCE_DIABLO(1, KC_2),
35 [TD_D3_3] = ACTION_TAP_DANCE_DIABLO(2), 39 [TD_D3_3] = ACTION_TAP_DANCE_DIABLO(2, KC_3),
36 [TD_D3_4] = ACTION_TAP_DANCE_DIABLO(3), 40 [TD_D3_4] = ACTION_TAP_DANCE_DIABLO(3, KC_4),
37}; 41};
38 42
39// Sends the key press to system, but only if on the Diablo layer
40void send_diablo_keystroke(uint8_t diablo_key) {
41 if (IS_LAYER_ON(_DIABLO)) {
42 switch (diablo_key) {
43 case 0:
44 tap_code(KC_1); break;
45 case 1:
46 tap_code(KC_2); break;
47 case 2:
48 tap_code(KC_3); break;
49 case 3:
50 tap_code(KC_4); break;
51 }
52 }
53}
54
55// Checks each of the 4 timers/keys to see if enough time has elapsed 43// Checks each of the 4 timers/keys to see if enough time has elapsed
56// Runs the "send string" command if enough time has passed, and resets the timer.
57void run_diablo_macro_check(void) { 44void run_diablo_macro_check(void) {
58 uint8_t dtime; 45 for (uint8_t index = 0; index < NUM_OF_DIABLO_KEYS; index++) {
59 for (dtime = 0; dtime < 4; dtime++) { 46 // if key_interval is 0, it's disabled, so only run if it's set. If it's set, check the timer.
60 if (check_dtimer(dtime) && diablo_timer[dtime].key_time) { 47 if (diablo_timer[index].key_interval && timer_elapsed(diablo_timer[index].timer) > (diablo_timer[index].key_interval * 1000)) {
61 diablo_timer[dtime].timer = timer_read(); 48 // reset the timer, since enough time has passed
62 send_diablo_keystroke(dtime); 49 diablo_timer[index].timer = timer_read();
50 // send keycode ONLY if we're on the diablo layer.
51 if (IS_LAYER_ON(_DIABLO)) {
52 tap_code(diablo_timer[index].keycode);
53 }
63 } 54 }
64 } 55 }
65} 56}
diff --git a/users/drashna/tap_dances.h b/users/drashna/tap_dances.h
index 4a293b258..44fa0b934 100644
--- a/users/drashna/tap_dances.h
+++ b/users/drashna/tap_dances.h
@@ -1,22 +1,30 @@
1#pragma once 1#pragma once
2#include "drashna.h" 2#include "drashna.h"
3 3
4//define diablo macro timer variables 4// define diablo macro timer variables
5extern uint8_t diablo_times[]; 5extern uint8_t diablo_times[];
6typedef struct { 6typedef struct {
7 uint16_t timer; 7 uint16_t timer;
8 uint8_t key_time; 8 uint8_t key_interval;
9 uint8_t keycode;
9} diablo_timer_t; 10} diablo_timer_t;
10 11
11extern diablo_timer_t diablo_timer[4]; 12typedef struct {
13 uint8_t index;
14 uint8_t keycode;
15} diable_keys_t;
16
17extern diablo_timer_t diablo_timer[];
12 18
13void run_diablo_macro_check(void); 19void run_diablo_macro_check(void);
14 20
15#ifdef TAP_DANCE_ENABLE 21#ifdef TAP_DANCE_ENABLE
22// clang-format off
16enum { 23enum {
17 TD_D3_1 = 0, 24 TD_D3_1 = 0,
18 TD_D3_2, 25 TD_D3_2,
19 TD_D3_3, 26 TD_D3_3,
20 TD_D3_4 27 TD_D3_4
21}; 28};
22#endif // TAP_DANCE_ENABLE 29// clang-format on
30#endif // TAP_DANCE_ENABLE
diff --git a/users/drashna/wrappers.h b/users/drashna/wrappers.h
index 93f842f4b..a87247071 100644
--- a/users/drashna/wrappers.h
+++ b/users/drashna/wrappers.h
@@ -6,9 +6,10 @@ arguments, we need a wrapper in order for these definitions to be
6expanded before being used as arguments to the LAYOUT_xxx macro. 6expanded before being used as arguments to the LAYOUT_xxx macro.
7*/ 7*/
8#if (!defined(LAYOUT) && defined(KEYMAP)) 8#if (!defined(LAYOUT) && defined(KEYMAP))
9# define LAYOUT KEYMAP 9# define LAYOUT KEYMAP
10#endif 10#endif
11 11
12// clang-format off
12#define LAYOUT_ergodox_wrapper(...) LAYOUT_ergodox(__VA_ARGS__) 13#define LAYOUT_ergodox_wrapper(...) LAYOUT_ergodox(__VA_ARGS__)
13#define LAYOUT_ergodox_pretty_wrapper(...) LAYOUT_ergodox_pretty(__VA_ARGS__) 14#define LAYOUT_ergodox_pretty_wrapper(...) LAYOUT_ergodox_pretty(__VA_ARGS__)
14#define KEYMAP_wrapper(...) LAYOUT(__VA_ARGS__) 15#define KEYMAP_wrapper(...) LAYOUT(__VA_ARGS__)
@@ -135,6 +136,15 @@ NOTE: These are all the same length. If you do a search/replace
135#define _____________CARPLAX_QGMLWY_R3_____________ KC_K, KC_P, KC_COMM, KC_DOT, KC_SLSH 136#define _____________CARPLAX_QGMLWY_R3_____________ KC_K, KC_P, KC_COMM, KC_DOT, KC_SLSH
136 137
137 138
139#define _________________WHITE_R1__________________ KC_V, KC_Y, KC_D, KC_COMM, KC_QUOT
140#define _________________WHITE_R2__________________ KC_A, KC_T, KC_H, KC_E, KC_B
141#define _________________WHITE_R3__________________ KC_P, KC_K, KC_G, KC_W, KC_Q
142
143#define _________________WHITE_L1__________________ KC_INT1, KC_J, KC_M, KC_L, KC_U
144#define _________________WHITE_L2__________________ KC_MINS, KC_C, KC_S, KC_N, KC_O // KC_I
145#define _________________WHITE_L3__________________ KC_X, KC_R, KC_F, KC_DOT, KC_Z
146
147
138#define ________________NUMBER_LEFT________________ KC_1, KC_2, KC_3, KC_4, KC_5 148#define ________________NUMBER_LEFT________________ KC_1, KC_2, KC_3, KC_4, KC_5
139#define ________________NUMBER_RIGHT_______________ KC_6, KC_7, KC_8, KC_9, KC_0 149#define ________________NUMBER_RIGHT_______________ KC_6, KC_7, KC_8, KC_9, KC_0
140#define _________________FUNC_LEFT_________________ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5 150#define _________________FUNC_LEFT_________________ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5
@@ -170,3 +180,5 @@ NOTE: These are all the same length. If you do a search/replace
170#define _________________ADJUST_R1_________________ KC_SEC1, KC_SEC2, KC_SEC3, KC_SEC4, KC_SEC5 180#define _________________ADJUST_R1_________________ KC_SEC1, KC_SEC2, KC_SEC3, KC_SEC4, KC_SEC5
171#define _________________ADJUST_R2_________________ AG_SWAP, QWERTY, COLEMAK, DVORAK, WORKMAN 181#define _________________ADJUST_R2_________________ AG_SWAP, QWERTY, COLEMAK, DVORAK, WORKMAN
172#define _________________ADJUST_R3_________________ MG_NKRO, KC_MUTE, KC_VOLD, KC_VOLU, KC_MNXT 182#define _________________ADJUST_R3_________________ MG_NKRO, KC_MUTE, KC_VOLD, KC_VOLU, KC_MNXT
183
184// clang-format on