aboutsummaryrefslogtreecommitdiff
path: root/quantum/dynamic_macro.h
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/dynamic_macro.h')
-rw-r--r--quantum/dynamic_macro.h57
1 files changed, 52 insertions, 5 deletions
diff --git a/quantum/dynamic_macro.h b/quantum/dynamic_macro.h
index 9e7845c99..f242405de 100644
--- a/quantum/dynamic_macro.h
+++ b/quantum/dynamic_macro.h
@@ -48,11 +48,22 @@ enum dynamic_macro_keycodes {
48/* Blink the LEDs to notify the user about some event. */ 48/* Blink the LEDs to notify the user about some event. */
49void dynamic_macro_led_blink(void) 49void dynamic_macro_led_blink(void)
50{ 50{
51#ifdef BACKLIGHT_ENABLE
51 backlight_toggle(); 52 backlight_toggle();
52 _delay_ms(100); 53 _delay_ms(100);
53 backlight_toggle(); 54 backlight_toggle();
55#endif
54} 56}
55 57
58/* Convenience macros used for retrieving the debug info. All of them
59 * need a `direction` variable accessible at the call site.
60 */
61#define DYNAMIC_MACRO_CURRENT_SLOT() (direction > 0 ? 1 : 2)
62#define DYNAMIC_MACRO_CURRENT_LENGTH(BEGIN, POINTER) \
63 ((int)(direction * ((POINTER) - (BEGIN))))
64#define DYNAMIC_MACRO_CURRENT_CAPACITY(BEGIN, END2) \
65 ((int)(direction * ((END2) - (BEGIN)) + 1))
66
56/** 67/**
57 * Start recording of the dynamic macro. 68 * Start recording of the dynamic macro.
58 * 69 *
@@ -62,6 +73,8 @@ void dynamic_macro_led_blink(void)
62void dynamic_macro_record_start( 73void dynamic_macro_record_start(
63 keyrecord_t **macro_pointer, keyrecord_t *macro_buffer) 74 keyrecord_t **macro_pointer, keyrecord_t *macro_buffer)
64{ 75{
76 dprintln("dynamic macro recording: started");
77
65 dynamic_macro_led_blink(); 78 dynamic_macro_led_blink();
66 79
67 clear_keyboard(); 80 clear_keyboard();
@@ -79,6 +92,8 @@ void dynamic_macro_record_start(
79void dynamic_macro_play( 92void dynamic_macro_play(
80 keyrecord_t *macro_buffer, keyrecord_t *macro_end, int8_t direction) 93 keyrecord_t *macro_buffer, keyrecord_t *macro_end, int8_t direction)
81{ 94{
95 dprintf("dynamic macro: slot %d playback\n", DYNAMIC_MACRO_CURRENT_SLOT());
96
82 uint32_t saved_layer_state = layer_state; 97 uint32_t saved_layer_state = layer_state;
83 98
84 clear_keyboard(); 99 clear_keyboard();
@@ -99,7 +114,7 @@ void dynamic_macro_play(
99 * 114 *
100 * @param macro_buffer[in] The start of the used macro buffer. 115 * @param macro_buffer[in] The start of the used macro buffer.
101 * @param macro_pointer[in,out] The current buffer position. 116 * @param macro_pointer[in,out] The current buffer position.
102 * @param macro2_end[in] The last buffer element it is safe to use before overwriting the other macro. 117 * @param macro2_end[in] The end of the other macro.
103 * @param direction[in] Either +1 or -1, which way to iterate the buffer. 118 * @param direction[in] Either +1 or -1, which way to iterate the buffer.
104 * @param record[in] The current keypress. 119 * @param record[in] The current keypress.
105 */ 120 */
@@ -112,25 +127,53 @@ void dynamic_macro_record_key(
112{ 127{
113 /* If we've just started recording, ignore all the key releases. */ 128 /* If we've just started recording, ignore all the key releases. */
114 if (!record->event.pressed && *macro_pointer == macro_buffer) { 129 if (!record->event.pressed && *macro_pointer == macro_buffer) {
130 dprintln("dynamic macro: ignoring a leading key-up event");
115 return; 131 return;
116 } 132 }
117 133
134 /* The other end of the other macro is the last buffer element it
135 * is safe to use before overwriting the other macro.
136 */
118 if (*macro_pointer - direction != macro2_end) { 137 if (*macro_pointer - direction != macro2_end) {
119 **macro_pointer = *record; 138 **macro_pointer = *record;
120 *macro_pointer += direction; 139 *macro_pointer += direction;
121 } else { 140 } else {
122 dynamic_macro_led_blink(); 141 dynamic_macro_led_blink();
123 } 142 }
143
144 dprintf(
145 "dynamic macro: slot %d length: %d/%d\n",
146 DYNAMIC_MACRO_CURRENT_SLOT(),
147 DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, *macro_pointer),
148 DYNAMIC_MACRO_CURRENT_CAPACITY(macro_buffer, macro2_end));
124} 149}
125 150
126/** 151/**
127 * End recording of the dynamic macro. Essentially just update the 152 * End recording of the dynamic macro. Essentially just update the
128 * pointer to the end of the macro. 153 * pointer to the end of the macro.
129 */ 154 */
130void dynamic_macro_record_end(keyrecord_t *macro_pointer, keyrecord_t **macro_end) 155void dynamic_macro_record_end(
156 keyrecord_t *macro_buffer,
157 keyrecord_t *macro_pointer,
158 int8_t direction,
159 keyrecord_t **macro_end)
131{ 160{
132 dynamic_macro_led_blink(); 161 dynamic_macro_led_blink();
133 162
163 /* Do not save the keys being held when stopping the recording,
164 * i.e. the keys used to access the layer DYN_REC_STOP is on.
165 */
166 while (macro_pointer != macro_buffer &&
167 (macro_pointer - direction)->event.pressed) {
168 dprintln("dynamic macro: trimming a trailing key-down event");
169 macro_pointer -= direction;
170 }
171
172 dprintf(
173 "dynamic macro: slot %d saved, length: %d\n",
174 DYNAMIC_MACRO_CURRENT_SLOT(),
175 DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, macro_pointer));
176
134 *macro_end = macro_pointer; 177 *macro_end = macro_pointer;
135} 178}
136 179
@@ -158,7 +201,7 @@ bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record)
158 * &macro_buffer macro_end 201 * &macro_buffer macro_end
159 * v v 202 * v v
160 * +------------------------------------------------------------+ 203 * +------------------------------------------------------------+
161 * |>>>>>> MACRO1 >>>>>>| |<<<<<<<<<<<<< MACRO2 <<<<<<<<<<<<<| 204 * |>>>>>> MACRO1 >>>>>> <<<<<<<<<<<<< MACRO2 <<<<<<<<<<<<<|
162 * +------------------------------------------------------------+ 205 * +------------------------------------------------------------+
163 * ^ ^ 206 * ^ ^
164 * r_macro_end r_macro_buffer 207 * r_macro_end r_macro_buffer
@@ -222,10 +265,10 @@ bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record)
222 * starts. */ 265 * starts. */
223 switch (macro_id) { 266 switch (macro_id) {
224 case 1: 267 case 1:
225 dynamic_macro_record_end(macro_pointer, &macro_end); 268 dynamic_macro_record_end(macro_buffer, macro_pointer, +1, &macro_end);
226 break; 269 break;
227 case 2: 270 case 2:
228 dynamic_macro_record_end(macro_pointer, &r_macro_end); 271 dynamic_macro_record_end(r_macro_buffer, macro_pointer, -1, &r_macro_end);
229 break; 272 break;
230 } 273 }
231 macro_id = 0; 274 macro_id = 0;
@@ -249,4 +292,8 @@ bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record)
249 return true; 292 return true;
250} 293}
251 294
295#undef DYNAMIC_MACRO_CURRENT_SLOT
296#undef DYNAMIC_MACRO_CURRENT_LENGTH
297#undef DYNAMIC_MACRO_CURRENT_CAPACITY
298
252#endif 299#endif