diff options
Diffstat (limited to 'quantum/dynamic_macro.h')
| -rw-r--r-- | quantum/dynamic_macro.h | 57 |
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. */ |
| 49 | void dynamic_macro_led_blink(void) | 49 | void 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) | |||
| 62 | void dynamic_macro_record_start( | 73 | void 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( | |||
| 79 | void dynamic_macro_play( | 92 | void 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 | */ |
| 130 | void dynamic_macro_record_end(keyrecord_t *macro_pointer, keyrecord_t **macro_end) | 155 | void 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 | * ¯o_buffer macro_end | 201 | * ¯o_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, ¯o_end); | 268 | dynamic_macro_record_end(macro_buffer, macro_pointer, +1, ¯o_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 |
