diff options
| author | DennyTom <denemark.tomas@gmail.com> | 2020-04-07 04:13:17 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-07 21:13:17 +1000 |
| commit | e409fb47f27f9cf56479928ed86eb2eb346eec54 (patch) | |
| tree | f7b27bec198b7bb6250fbcf73111c189bc22d107 /keyboards/georgi | |
| parent | ae74922d1485e3c8e120dbc141d003ed7696b1f9 (diff) | |
| download | qmk_firmware-e409fb47f27f9cf56479928ed86eb2eb346eec54.tar.gz qmk_firmware-e409fb47f27f9cf56479928ed86eb2eb346eec54.zip | |
DennyTom's buttery_engine (#8138)
* Selectively adding pieces
* Adding georgi keymap
* Adding more files, fixing make
* Smaller makefiles
* Fixing make rules
* README more inline with QMK's guidelines
* Turning off buggy assert
* Improving documentation based on a user feedback.
* Slightly better schema
* Resurrected state machine diagram
Diffstat (limited to 'keyboards/georgi')
| -rw-r--r-- | keyboards/georgi/keymaps/dennytom/README.md | 11 | ||||
| -rw-r--r-- | keyboards/georgi/keymaps/dennytom/keymap.c | 1208 | ||||
| -rw-r--r-- | keyboards/georgi/keymaps/dennytom/keymap_def.json | 153 | ||||
| -rw-r--r-- | keyboards/georgi/keymaps/dennytom/rules.mk | 8 |
4 files changed, 1380 insertions, 0 deletions
diff --git a/keyboards/georgi/keymaps/dennytom/README.md b/keyboards/georgi/keymaps/dennytom/README.md new file mode 100644 index 000000000..14bc1d204 --- /dev/null +++ b/keyboards/georgi/keymaps/dennytom/README.md | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | # # Dennytom's Georgi Layout | ||
| 2 | |||
| 3 | This keymap is using a custom chording engine. Head out to my (DennyTom) user space to find the source files and details. | ||
| 4 | |||
| 5 | To make a real keymap from the JSON file, run | ||
| 6 | |||
| 7 | ```sh | ||
| 8 | python3 parser.py keymap_def.json keymap.c | ||
| 9 | ``` | ||
| 10 | |||
| 11 | Likely will change with use. I enjoy the modifiers on the "home row". \ No newline at end of file | ||
diff --git a/keyboards/georgi/keymaps/dennytom/keymap.c b/keyboards/georgi/keymaps/dennytom/keymap.c new file mode 100644 index 000000000..2e0191774 --- /dev/null +++ b/keyboards/georgi/keymaps/dennytom/keymap.c | |||
| @@ -0,0 +1,1208 @@ | |||
| 1 | #include QMK_KEYBOARD_H | ||
| 2 | |||
| 3 | #define H_TOP1 ((HASH_TYPE) 1 << 0) | ||
| 4 | #define H_TOP2 ((HASH_TYPE) 1 << 1) | ||
| 5 | #define H_TOP3 ((HASH_TYPE) 1 << 2) | ||
| 6 | #define H_TOP4 ((HASH_TYPE) 1 << 3) | ||
| 7 | #define H_TOP5 ((HASH_TYPE) 1 << 4) | ||
| 8 | #define H_TOP6 ((HASH_TYPE) 1 << 5) | ||
| 9 | #define H_TOP7 ((HASH_TYPE) 1 << 6) | ||
| 10 | #define H_TOP8 ((HASH_TYPE) 1 << 7) | ||
| 11 | #define H_TOP9 ((HASH_TYPE) 1 << 8) | ||
| 12 | #define H_TOP10 ((HASH_TYPE) 1 << 9) | ||
| 13 | #define H_TOP11 ((HASH_TYPE) 1 << 10) | ||
| 14 | #define H_TOP12 ((HASH_TYPE) 1 << 11) | ||
| 15 | #define H_BOT1 ((HASH_TYPE) 1 << 12) | ||
| 16 | #define H_BOT2 ((HASH_TYPE) 1 << 13) | ||
| 17 | #define H_BOT3 ((HASH_TYPE) 1 << 14) | ||
| 18 | #define H_BOT4 ((HASH_TYPE) 1 << 15) | ||
| 19 | #define H_BOT5 ((HASH_TYPE) 1 << 16) | ||
| 20 | #define H_BOT6 ((HASH_TYPE) 1 << 17) | ||
| 21 | #define H_BOT7 ((HASH_TYPE) 1 << 18) | ||
| 22 | #define H_BOT8 ((HASH_TYPE) 1 << 19) | ||
| 23 | #define H_BOT9 ((HASH_TYPE) 1 << 20) | ||
| 24 | #define H_BOT10 ((HASH_TYPE) 1 << 21) | ||
| 25 | #define H_BOT11 ((HASH_TYPE) 1 << 22) | ||
| 26 | #define H_BOT12 ((HASH_TYPE) 1 << 23) | ||
| 27 | #define H_THU1 ((HASH_TYPE) 1 << 24) | ||
| 28 | #define H_THU2 ((HASH_TYPE) 1 << 25) | ||
| 29 | #define H_THU3 ((HASH_TYPE) 1 << 26) | ||
| 30 | #define H_THU4 ((HASH_TYPE) 1 << 27) | ||
| 31 | #define H_THU5 ((HASH_TYPE) 1 << 28) | ||
| 32 | #define H_THU6 ((HASH_TYPE) 1 << 29) | ||
| 33 | |||
| 34 | enum internal_keycodes { | ||
| 35 | TOP1 = SAFE_RANGE, | ||
| 36 | TOP2, TOP3, TOP4, TOP5, TOP6, TOP7, TOP8, TOP9, TOP10, TOP11, TOP12, BOT1, BOT2, BOT3, BOT4, BOT5, BOT6, BOT7, BOT8, BOT9, BOT10, BOT11, BOT12, THU1, THU2, THU3, THU4, THU5, THU6, | ||
| 37 | FIRST_INTERNAL_KEYCODE = TOP1, | ||
| 38 | LAST_INTERNAL_KEYCODE = THU6 | ||
| 39 | }; | ||
| 40 | |||
| 41 | enum pseudolayers { | ||
| 42 | ALWAYS_ON, QWERTY, NUM, FNC, NAV, MOUSE | ||
| 43 | }; | ||
| 44 | |||
| 45 | #define CHORD_TIMEOUT 100 | ||
| 46 | #define DANCE_TIMEOUT 200 | ||
| 47 | #define LEADER_TIMEOUT 750 | ||
| 48 | #define TAP_TIMEOUT 50 | ||
| 49 | #define LONG_PRESS_MULTIPLIER 3 | ||
| 50 | #define DYNAMIC_MACRO_MAX_LENGTH 20 | ||
| 51 | #define COMMAND_MAX_LENGTH 5 | ||
| 52 | #define STRING_MAX_LENGTH 16 | ||
| 53 | #define LEADER_MAX_LENGTH 5 | ||
| 54 | #define HASH_TYPE uint32_t | ||
| 55 | #define NUMBER_OF_KEYS 30 | ||
| 56 | #define DEFAULT_PSEUDOLAYER QWERTY | ||
| 57 | |||
| 58 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
| 59 | [0] = LAYOUT_georgi(TOP1, TOP2, TOP3, TOP4, TOP5, TOP6, TOP7, TOP8, TOP9, TOP10, TOP11, TOP12, BOT1, BOT2, BOT3, BOT4, BOT5, BOT6, BOT7, BOT8, BOT9, BOT10, BOT11, BOT12, THU1, THU2, THU3, THU4, THU5, THU6), | ||
| 60 | }; | ||
| 61 | size_t keymapsCount = 1; | ||
| 62 | |||
| 63 | uint8_t keycodes_buffer_array[] = { | ||
| 64 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
| 65 | }; | ||
| 66 | |||
| 67 | uint8_t command_buffer[] = { | ||
| 68 | 0, 0, 0, 0, 0 | ||
| 69 | }; | ||
| 70 | |||
| 71 | uint16_t leader_buffer[] = { | ||
| 72 | 0, 0, 0, 0, 0 | ||
| 73 | }; | ||
| 74 | |||
| 75 | uint8_t dynamic_macro_buffer[] = { | ||
| 76 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
| 77 | }; | ||
| 78 | |||
| 79 | enum chord_states { | ||
| 80 | IDLE, | ||
| 81 | READY, | ||
| 82 | ACTIVATED, | ||
| 83 | DEACTIVATED, | ||
| 84 | PRESS_FROM_ACTIVE, | ||
| 85 | FINISHED_FROM_ACTIVE, | ||
| 86 | IDLE_IN_DANCE, | ||
| 87 | READY_IN_DANCE, | ||
| 88 | FINISHED, | ||
| 89 | LOCKED, | ||
| 90 | READY_LOCKED, | ||
| 91 | RESTART, | ||
| 92 | IN_ONE_SHOT | ||
| 93 | }; | ||
| 94 | |||
| 95 | struct Chord { | ||
| 96 | uint32_t keycodes_hash; | ||
| 97 | uint8_t pseudolayer; | ||
| 98 | uint8_t* state; | ||
| 99 | uint8_t* counter; | ||
| 100 | uint16_t value1; | ||
| 101 | uint8_t value2; | ||
| 102 | void (*function) (const struct Chord*); | ||
| 103 | }; | ||
| 104 | |||
| 105 | uint8_t current_pseudolayer = DEFAULT_PSEUDOLAYER; | ||
| 106 | bool lock_next = false; | ||
| 107 | uint16_t chord_timer = 0; | ||
| 108 | uint16_t dance_timer = 0; | ||
| 109 | bool autoshift_mode = true; | ||
| 110 | uint8_t keycode_index = 0; | ||
| 111 | uint8_t command_mode = 0; | ||
| 112 | uint8_t command_ind = 0; | ||
| 113 | bool in_leader_mode = false; | ||
| 114 | uint8_t leader_ind = 0; | ||
| 115 | uint16_t leader_timer = 0; | ||
| 116 | uint8_t dynamic_macro_mode = false; | ||
| 117 | uint8_t dynamic_macro_ind = 0; | ||
| 118 | bool a_key_went_through = false; | ||
| 119 | struct Chord* last_chord = NULL; | ||
| 120 | |||
| 121 | bool handle_US_ANSI_shifted_keys(int16_t keycode, bool in) { | ||
| 122 | bool is_US_ANSI_shifted = true; | ||
| 123 | |||
| 124 | int16_t regular_keycode = KC_NO; | ||
| 125 | switch (keycode) { | ||
| 126 | case KC_TILDE: | ||
| 127 | regular_keycode = KC_GRAVE; | ||
| 128 | break; | ||
| 129 | case KC_EXCLAIM: | ||
| 130 | regular_keycode = KC_1; | ||
| 131 | break; | ||
| 132 | case KC_AT: | ||
| 133 | regular_keycode = KC_2; | ||
| 134 | break; | ||
| 135 | case KC_HASH: | ||
| 136 | regular_keycode = KC_3; | ||
| 137 | break; | ||
| 138 | case KC_DOLLAR: | ||
| 139 | regular_keycode = KC_4; | ||
| 140 | break; | ||
| 141 | case KC_PERCENT: | ||
| 142 | regular_keycode = KC_5; | ||
| 143 | break; | ||
| 144 | case KC_CIRCUMFLEX: | ||
| 145 | regular_keycode = KC_6; | ||
| 146 | break; | ||
| 147 | case KC_AMPERSAND: | ||
| 148 | regular_keycode = KC_7; | ||
| 149 | break; | ||
| 150 | case KC_ASTERISK: | ||
| 151 | regular_keycode = KC_8; | ||
| 152 | break; | ||
| 153 | case KC_LEFT_PAREN: | ||
| 154 | regular_keycode = KC_9; | ||
| 155 | break; | ||
| 156 | case KC_RIGHT_PAREN: | ||
| 157 | regular_keycode = KC_0; | ||
| 158 | break; | ||
| 159 | case KC_UNDERSCORE: | ||
| 160 | regular_keycode = KC_MINUS; | ||
| 161 | break; | ||
| 162 | case KC_PLUS: | ||
| 163 | regular_keycode = KC_EQUAL; | ||
| 164 | break; | ||
| 165 | case KC_LEFT_CURLY_BRACE: | ||
| 166 | regular_keycode = KC_LBRACKET; | ||
| 167 | break; | ||
| 168 | case KC_RIGHT_CURLY_BRACE: | ||
| 169 | regular_keycode = KC_RBRACKET; | ||
| 170 | break; | ||
| 171 | case KC_PIPE: | ||
| 172 | regular_keycode = KC_BSLASH; | ||
| 173 | break; | ||
| 174 | case KC_COLON: | ||
| 175 | regular_keycode = KC_SCOLON; | ||
| 176 | break; | ||
| 177 | case KC_DOUBLE_QUOTE: | ||
| 178 | regular_keycode = KC_QUOTE; | ||
| 179 | break; | ||
| 180 | case KC_LEFT_ANGLE_BRACKET: | ||
| 181 | regular_keycode = KC_COMMA; | ||
| 182 | break; | ||
| 183 | case KC_RIGHT_ANGLE_BRACKET: | ||
| 184 | regular_keycode = KC_DOT; | ||
| 185 | break; | ||
| 186 | case KC_QUESTION: | ||
| 187 | regular_keycode = KC_SLASH; | ||
| 188 | break; | ||
| 189 | default: | ||
| 190 | is_US_ANSI_shifted = false; | ||
| 191 | } | ||
| 192 | if (is_US_ANSI_shifted) { | ||
| 193 | if (in) { | ||
| 194 | register_code(KC_LSFT); | ||
| 195 | register_code(regular_keycode); | ||
| 196 | } else { | ||
| 197 | unregister_code(regular_keycode); | ||
| 198 | unregister_code(KC_LSFT); | ||
| 199 | } | ||
| 200 | } | ||
| 201 | return is_US_ANSI_shifted; | ||
| 202 | } | ||
| 203 | |||
| 204 | void key_in(int16_t keycode) { | ||
| 205 | if (command_mode == 1 && command_ind < COMMAND_MAX_LENGTH) { | ||
| 206 | command_buffer[command_ind] = keycode; | ||
| 207 | command_ind++; | ||
| 208 | a_key_went_through = true; | ||
| 209 | } else if (in_leader_mode && leader_ind < LEADER_MAX_LENGTH) { | ||
| 210 | leader_buffer[leader_ind] = keycode; | ||
| 211 | leader_ind++; | ||
| 212 | a_key_went_through = true; | ||
| 213 | } else if (dynamic_macro_mode && dynamic_macro_ind < DYNAMIC_MACRO_MAX_LENGTH) { | ||
| 214 | dynamic_macro_buffer[dynamic_macro_ind] = keycode; | ||
| 215 | dynamic_macro_ind++; | ||
| 216 | a_key_went_through = true; | ||
| 217 | } else { | ||
| 218 | if (!handle_US_ANSI_shifted_keys(keycode, true)) { | ||
| 219 | register_code(keycode); | ||
| 220 | } | ||
| 221 | send_keyboard_report(); | ||
| 222 | a_key_went_through = true; | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 226 | void key_out(int16_t keycode) { | ||
| 227 | if (command_mode == 0) { | ||
| 228 | if (!handle_US_ANSI_shifted_keys(keycode, false)) { | ||
| 229 | if (command_mode == 0 && in_leader_mode == false && dynamic_macro_mode == false) { | ||
| 230 | unregister_code(keycode); | ||
| 231 | } | ||
| 232 | } | ||
| 233 | send_keyboard_report(); | ||
| 234 | } | ||
| 235 | } | ||
| 236 | |||
| 237 | void tap_key(int16_t keycode) { | ||
| 238 | key_in(keycode); | ||
| 239 | wait_ms(TAP_TIMEOUT); | ||
| 240 | key_out(keycode); | ||
| 241 | } | ||
| 242 | const char * const strings[] PROGMEM = { | ||
| 243 | |||
| 244 | }; | ||
| 245 | void single_dance(const struct Chord* self) { | ||
| 246 | switch (*self->state) { | ||
| 247 | case ACTIVATED: | ||
| 248 | key_in(self->value1); | ||
| 249 | break; | ||
| 250 | case DEACTIVATED: | ||
| 251 | key_out(self->value1); | ||
| 252 | *self->state = IDLE; | ||
| 253 | break; | ||
| 254 | case RESTART: | ||
| 255 | key_out(self->value1); | ||
| 256 | break; | ||
| 257 | default: | ||
| 258 | break; | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | void key_layer_dance(const struct Chord* self) { | ||
| 263 | switch (*self->state) { | ||
| 264 | case ACTIVATED: | ||
| 265 | current_pseudolayer = self->value2; | ||
| 266 | a_key_went_through = false; | ||
| 267 | break; | ||
| 268 | case DEACTIVATED: | ||
| 269 | case RESTART: | ||
| 270 | if (!a_key_went_through) { | ||
| 271 | tap_key(self->value1); | ||
| 272 | } | ||
| 273 | current_pseudolayer = self->pseudolayer; | ||
| 274 | *self->state = IDLE; // does not have effect if the state was RESTART | ||
| 275 | break; | ||
| 276 | default: | ||
| 277 | break; | ||
| 278 | } | ||
| 279 | } | ||
| 280 | |||
| 281 | void key_mod_dance(const struct Chord* self) { | ||
| 282 | switch (*self->state) { | ||
| 283 | case ACTIVATED: | ||
| 284 | key_in(self->value2); | ||
| 285 | a_key_went_through = false; | ||
| 286 | break; | ||
| 287 | case DEACTIVATED: | ||
| 288 | case RESTART: | ||
| 289 | key_out(self->value2); | ||
| 290 | if (!a_key_went_through) { | ||
| 291 | tap_key(self->value1); | ||
| 292 | } | ||
| 293 | *self->state = IDLE; // does not have effect if the state was RESTART | ||
| 294 | break; | ||
| 295 | default: | ||
| 296 | break; | ||
| 297 | } | ||
| 298 | } | ||
| 299 | |||
| 300 | void key_key_dance(const struct Chord* self) { | ||
| 301 | switch (*self->state) { | ||
| 302 | case ACTIVATED: | ||
| 303 | break; | ||
| 304 | case DEACTIVATED: | ||
| 305 | tap_key(self->value1); | ||
| 306 | *self->state = IDLE; | ||
| 307 | break; | ||
| 308 | case FINISHED: | ||
| 309 | case PRESS_FROM_ACTIVE: | ||
| 310 | key_in(self->value2); | ||
| 311 | break; | ||
| 312 | case RESTART: | ||
| 313 | key_out(self->value2); | ||
| 314 | break; | ||
| 315 | default: | ||
| 316 | break; | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | void autoshift_dance_impl(const struct Chord* self) { | ||
| 321 | switch (*self->state) { | ||
| 322 | case ACTIVATED: | ||
| 323 | *self->counter = 0; | ||
| 324 | break; | ||
| 325 | case DEACTIVATED: | ||
| 326 | case RESTART: | ||
| 327 | tap_key(self->value1); | ||
| 328 | *self->state = IDLE; | ||
| 329 | break; | ||
| 330 | case FINISHED_FROM_ACTIVE: | ||
| 331 | if (*self->counter == (LONG_PRESS_MULTIPLIER - 2)) { | ||
| 332 | key_in(KC_LSFT); | ||
| 333 | tap_key(self->value1); | ||
| 334 | key_out(KC_LSFT); | ||
| 335 | *self->state = IDLE; | ||
| 336 | // the skip to IDLE is usually just a lag optimization, | ||
| 337 | // in this case it has a logic function, on a short | ||
| 338 | // press (still longer than a tap) the key does not get shifted | ||
| 339 | } else { | ||
| 340 | *self->counter += 1; | ||
| 341 | *self->state = PRESS_FROM_ACTIVE; | ||
| 342 | dance_timer = timer_read(); | ||
| 343 | } | ||
| 344 | break; | ||
| 345 | default: | ||
| 346 | break; | ||
| 347 | } | ||
| 348 | } | ||
| 349 | |||
| 350 | void autoshift_dance(const struct Chord* self) { | ||
| 351 | if (autoshift_mode) { | ||
| 352 | autoshift_dance_impl(self); | ||
| 353 | } else { | ||
| 354 | single_dance(self); | ||
| 355 | } | ||
| 356 | } | ||
| 357 | |||
| 358 | void autoshift_toggle(const struct Chord* self){ | ||
| 359 | if (*self->state == ACTIVATED) { | ||
| 360 | autoshift_mode = !autoshift_mode; | ||
| 361 | *self->state = IDLE; | ||
| 362 | } | ||
| 363 | } | ||
| 364 | |||
| 365 | void temp_pseudolayer(const struct Chord* self) { | ||
| 366 | switch (*self->state) { | ||
| 367 | case ACTIVATED: | ||
| 368 | current_pseudolayer = self->value1; | ||
| 369 | break; | ||
| 370 | case DEACTIVATED: | ||
| 371 | current_pseudolayer = self->pseudolayer; | ||
| 372 | *self->state = IDLE; | ||
| 373 | break; | ||
| 374 | case RESTART: | ||
| 375 | current_pseudolayer = self->pseudolayer; | ||
| 376 | break; | ||
| 377 | default: | ||
| 378 | break; | ||
| 379 | } | ||
| 380 | } | ||
| 381 | |||
| 382 | void temp_pseudolayer_alt(const struct Chord* self) { | ||
| 383 | switch (*self->state) { | ||
| 384 | case ACTIVATED: | ||
| 385 | current_pseudolayer = self->value1; | ||
| 386 | break; | ||
| 387 | case DEACTIVATED: | ||
| 388 | current_pseudolayer = self->value2; | ||
| 389 | *self->state = IDLE; | ||
| 390 | break; | ||
| 391 | case RESTART: | ||
| 392 | current_pseudolayer = self->value2; | ||
| 393 | break; | ||
| 394 | default: | ||
| 395 | break; | ||
| 396 | } | ||
| 397 | } | ||
| 398 | |||
| 399 | void perm_pseudolayer(const struct Chord* self) { | ||
| 400 | if (*self->state == ACTIVATED) { | ||
| 401 | current_pseudolayer = self->value1; | ||
| 402 | *self->state = IDLE; | ||
| 403 | } | ||
| 404 | } | ||
| 405 | |||
| 406 | void switch_layer(const struct Chord* self) { | ||
| 407 | if (*self->state == ACTIVATED) { | ||
| 408 | layer_move(self->value1); | ||
| 409 | *self->state = IDLE; | ||
| 410 | } | ||
| 411 | } | ||
| 412 | |||
| 413 | void lock(const struct Chord* self) { | ||
| 414 | if (*self->state == ACTIVATED) { | ||
| 415 | lock_next = true; | ||
| 416 | *self->state = IDLE; | ||
| 417 | } | ||
| 418 | } | ||
| 419 | |||
| 420 | void one_shot_key(const struct Chord* self) { | ||
| 421 | switch (*self->state) { | ||
| 422 | case ACTIVATED: | ||
| 423 | break; | ||
| 424 | case DEACTIVATED: | ||
| 425 | key_in(self->value1); | ||
| 426 | *self->state = IN_ONE_SHOT; | ||
| 427 | break; | ||
| 428 | case FINISHED: | ||
| 429 | case PRESS_FROM_ACTIVE: | ||
| 430 | key_in(self->value1); | ||
| 431 | a_key_went_through = false; | ||
| 432 | break; | ||
| 433 | case RESTART: | ||
| 434 | if (a_key_went_through) { | ||
| 435 | key_out(self->value1); | ||
| 436 | } else { | ||
| 437 | *self->state = IN_ONE_SHOT; | ||
| 438 | } | ||
| 439 | default: | ||
| 440 | break; | ||
| 441 | } | ||
| 442 | } | ||
| 443 | |||
| 444 | void one_shot_layer(const struct Chord* self) { | ||
| 445 | switch (*self->state) { | ||
| 446 | case ACTIVATED: | ||
| 447 | break; | ||
| 448 | case DEACTIVATED: | ||
| 449 | current_pseudolayer = self->value1; | ||
| 450 | *self->state = IN_ONE_SHOT; | ||
| 451 | break; | ||
| 452 | case FINISHED: | ||
| 453 | case PRESS_FROM_ACTIVE: | ||
| 454 | current_pseudolayer = self->value1; | ||
| 455 | a_key_went_through = false; | ||
| 456 | break; | ||
| 457 | case RESTART: | ||
| 458 | if (a_key_went_through) { | ||
| 459 | current_pseudolayer = self->pseudolayer; | ||
| 460 | } else { | ||
| 461 | *self->state = IN_ONE_SHOT; | ||
| 462 | } | ||
| 463 | default: | ||
| 464 | break; | ||
| 465 | } | ||
| 466 | } | ||
| 467 | |||
| 468 | void command(const struct Chord* self) { | ||
| 469 | if (*self->state == ACTIVATED) { | ||
| 470 | command_mode++; | ||
| 471 | *self->state = IDLE; | ||
| 472 | } | ||
| 473 | } | ||
| 474 | |||
| 475 | bool identical(uint16_t* buffer1, uint16_t* buffer2) { | ||
| 476 | bool same = true; | ||
| 477 | for (int i = 0; i < LEADER_MAX_LENGTH; i++) { | ||
| 478 | same = same && (buffer1[i] == buffer2[i]); | ||
| 479 | } | ||
| 480 | return same; | ||
| 481 | } | ||
| 482 | |||
| 483 | void leader(const struct Chord* self) { | ||
| 484 | if (*self->state == ACTIVATED) { | ||
| 485 | in_leader_mode = true; | ||
| 486 | *self->state = IDLE; | ||
| 487 | } | ||
| 488 | } | ||
| 489 | |||
| 490 | void dynamic_macro_record(const struct Chord* self) { | ||
| 491 | if (*self->state == ACTIVATED) { | ||
| 492 | for (int i = 0; i < DYNAMIC_MACRO_MAX_LENGTH; i++) { | ||
| 493 | dynamic_macro_buffer[i] = 0; | ||
| 494 | } | ||
| 495 | dynamic_macro_mode = true; | ||
| 496 | *self->state = IDLE; | ||
| 497 | } | ||
| 498 | } | ||
| 499 | |||
| 500 | void dynamic_macro_next(const struct Chord* self) { | ||
| 501 | if (*self->state == ACTIVATED) { | ||
| 502 | if (dynamic_macro_mode && dynamic_macro_ind < DYNAMIC_MACRO_MAX_LENGTH) { | ||
| 503 | dynamic_macro_buffer[dynamic_macro_ind] = 0; | ||
| 504 | dynamic_macro_ind++; | ||
| 505 | } | ||
| 506 | *self->state = IDLE; | ||
| 507 | } | ||
| 508 | } | ||
| 509 | |||
| 510 | void dynamic_macro_end(const struct Chord* self) { | ||
| 511 | if (*self->state == ACTIVATED) { | ||
| 512 | if (dynamic_macro_mode) { | ||
| 513 | dynamic_macro_mode = false; | ||
| 514 | } | ||
| 515 | *self->state = IDLE; | ||
| 516 | } | ||
| 517 | } | ||
| 518 | |||
| 519 | void dynamic_macro_play(const struct Chord* self) { | ||
| 520 | if (*self->state == ACTIVATED) { | ||
| 521 | int ind_start = 0; | ||
| 522 | while (ind_start < DYNAMIC_MACRO_MAX_LENGTH) { | ||
| 523 | for (int i = ind_start; i < DYNAMIC_MACRO_MAX_LENGTH; i++) { | ||
| 524 | if (dynamic_macro_buffer[i] == 0) { | ||
| 525 | break; | ||
| 526 | } | ||
| 527 | register_code(dynamic_macro_buffer[i]); | ||
| 528 | } | ||
| 529 | send_keyboard_report(); | ||
| 530 | wait_ms(TAP_TIMEOUT); | ||
| 531 | for (int i = ind_start; i < DYNAMIC_MACRO_MAX_LENGTH; i++) { | ||
| 532 | if (dynamic_macro_buffer[i] == 0) { | ||
| 533 | ind_start = i + 1; | ||
| 534 | break; | ||
| 535 | } | ||
| 536 | unregister_code(dynamic_macro_buffer[i]); | ||
| 537 | } | ||
| 538 | send_keyboard_report(); | ||
| 539 | } | ||
| 540 | *self->state = IDLE; | ||
| 541 | } | ||
| 542 | } | ||
| 543 | |||
| 544 | void string_in(const struct Chord* self) { | ||
| 545 | if (*self->state == ACTIVATED) { | ||
| 546 | char buffer[STRING_MAX_LENGTH]; | ||
| 547 | strcpy_P(buffer, (char*)pgm_read_word(&(strings[self->value1]))); | ||
| 548 | send_string(buffer); | ||
| 549 | } | ||
| 550 | } | ||
| 551 | |||
| 552 | void clear(const struct Chord* self); | ||
| 553 | |||
| 554 | void reset_keyboard_kb(void){ | ||
| 555 | #ifdef WATCHDOG_ENABLE | ||
| 556 | MCUSR = 0; | ||
| 557 | wdt_disable(); | ||
| 558 | wdt_reset(); | ||
| 559 | #endif | ||
| 560 | reset_keyboard(); | ||
| 561 | } | ||
| 562 | |||
| 563 | void reset(const struct Chord* self) { | ||
| 564 | if (*self->state == ACTIVATED) { | ||
| 565 | reset_keyboard_kb(); | ||
| 566 | } | ||
| 567 | } | ||
| 568 | |||
| 569 | uint8_t state_0 = IDLE; | ||
| 570 | const struct Chord chord_0 PROGMEM = {H_TOP1 + H_TOP12 + H_BOT1 + H_BOT12, ALWAYS_ON, &state_0, NULL, 0, 0, clear}; | ||
| 571 | uint8_t state_1 = IDLE; | ||
| 572 | const struct Chord chord_1 PROGMEM = {H_TOP6 + H_TOP7 + H_BOT6 + H_BOT7, ALWAYS_ON, &state_1, NULL, 0, 0, command}; | ||
| 573 | uint8_t state_2 = IDLE; | ||
| 574 | const struct Chord chord_2 PROGMEM = {H_TOP1, QWERTY, &state_2, NULL, KC_ESC, 0, single_dance}; | ||
| 575 | uint8_t state_3 = IDLE; | ||
| 576 | const struct Chord chord_3 PROGMEM = {H_TOP2, QWERTY, &state_3, NULL, KC_Q, 0, single_dance}; | ||
| 577 | uint8_t state_4 = IDLE; | ||
| 578 | const struct Chord chord_4 PROGMEM = {H_TOP3, QWERTY, &state_4, NULL, KC_W, 0, single_dance}; | ||
| 579 | uint8_t state_5 = IDLE; | ||
| 580 | const struct Chord chord_5 PROGMEM = {H_TOP4, QWERTY, &state_5, NULL, KC_E, 0, single_dance}; | ||
| 581 | uint8_t state_6 = IDLE; | ||
| 582 | const struct Chord chord_6 PROGMEM = {H_TOP5, QWERTY, &state_6, NULL, KC_R, 0, single_dance}; | ||
| 583 | uint8_t state_7 = IDLE; | ||
| 584 | const struct Chord chord_7 PROGMEM = {H_TOP6, QWERTY, &state_7, NULL, KC_T, 0, single_dance}; | ||
| 585 | uint8_t state_8 = IDLE; | ||
| 586 | const struct Chord chord_8 PROGMEM = {H_TOP7, QWERTY, &state_8, NULL, KC_Y, 0, single_dance}; | ||
| 587 | uint8_t state_9 = IDLE; | ||
| 588 | const struct Chord chord_9 PROGMEM = {H_TOP8, QWERTY, &state_9, NULL, KC_U, 0, single_dance}; | ||
| 589 | uint8_t state_10 = IDLE; | ||
| 590 | const struct Chord chord_10 PROGMEM = {H_TOP9, QWERTY, &state_10, NULL, KC_I, 0, single_dance}; | ||
| 591 | uint8_t state_11 = IDLE; | ||
| 592 | const struct Chord chord_11 PROGMEM = {H_TOP10, QWERTY, &state_11, NULL, KC_O, 0, single_dance}; | ||
| 593 | uint8_t state_12 = IDLE; | ||
| 594 | const struct Chord chord_12 PROGMEM = {H_TOP11, QWERTY, &state_12, NULL, KC_P, 0, single_dance}; | ||
| 595 | uint8_t state_13 = IDLE; | ||
| 596 | const struct Chord chord_13 PROGMEM = {H_TOP12, QWERTY, &state_13, NULL, KC_BSLASH, 0, single_dance}; | ||
| 597 | uint8_t state_14 = IDLE; | ||
| 598 | const struct Chord chord_14 PROGMEM = {H_TOP1 + H_BOT1, QWERTY, &state_14, NULL, KC_INS, 0, single_dance}; | ||
| 599 | uint8_t state_15 = IDLE; | ||
| 600 | const struct Chord chord_15 PROGMEM = {H_TOP2 + H_BOT2, QWERTY, &state_15, NULL, KC_A, 0, single_dance}; | ||
| 601 | uint8_t state_16 = IDLE; | ||
| 602 | uint8_t counter_16 = 0; | ||
| 603 | const struct Chord chord_16 PROGMEM = {H_TOP3 + H_BOT3, QWERTY, &state_16, &counter_16, KC_S, KC_LALT, key_key_dance}; | ||
| 604 | uint8_t state_17 = IDLE; | ||
| 605 | const struct Chord chord_17 PROGMEM = {H_TOP4 + H_BOT4, QWERTY, &state_17, NULL, KC_D, KC_LCTL, key_mod_dance}; | ||
| 606 | uint8_t state_18 = IDLE; | ||
| 607 | const struct Chord chord_18 PROGMEM = {H_TOP5 + H_BOT5, QWERTY, &state_18, NULL, KC_F, KC_LSFT, key_mod_dance}; | ||
| 608 | uint8_t state_19 = IDLE; | ||
| 609 | uint8_t counter_19 = 0; | ||
| 610 | const struct Chord chord_19 PROGMEM = {H_TOP6 + H_BOT6, QWERTY, &state_19, &counter_19, KC_G, KC_LGUI, key_key_dance}; | ||
| 611 | uint8_t state_20 = IDLE; | ||
| 612 | uint8_t counter_20 = 0; | ||
| 613 | const struct Chord chord_20 PROGMEM = {H_TOP7 + H_BOT7, QWERTY, &state_20, &counter_20, KC_H, KC_RGUI, key_key_dance}; | ||
| 614 | uint8_t state_21 = IDLE; | ||
| 615 | const struct Chord chord_21 PROGMEM = {H_TOP8 + H_BOT8, QWERTY, &state_21, NULL, KC_J, KC_RSFT, key_mod_dance}; | ||
| 616 | uint8_t state_22 = IDLE; | ||
| 617 | const struct Chord chord_22 PROGMEM = {H_TOP9 + H_BOT9, QWERTY, &state_22, NULL, KC_K, KC_RCTL, key_mod_dance}; | ||
| 618 | uint8_t state_23 = IDLE; | ||
| 619 | uint8_t counter_23 = 0; | ||
| 620 | const struct Chord chord_23 PROGMEM = {H_TOP10 + H_BOT10, QWERTY, &state_23, &counter_23, KC_L, KC_RALT, key_key_dance}; | ||
| 621 | uint8_t state_24 = IDLE; | ||
| 622 | const struct Chord chord_24 PROGMEM = {H_TOP11 + H_BOT11, QWERTY, &state_24, NULL, KC_SCOLON, 0, single_dance}; | ||
| 623 | uint8_t state_25 = IDLE; | ||
| 624 | const struct Chord chord_25 PROGMEM = {H_BOT1, QWERTY, &state_25, NULL, KC_TAB, 0, single_dance}; | ||
| 625 | uint8_t state_26 = IDLE; | ||
| 626 | const struct Chord chord_26 PROGMEM = {H_BOT2, QWERTY, &state_26, NULL, KC_Z, 0, single_dance}; | ||
| 627 | uint8_t state_27 = IDLE; | ||
| 628 | const struct Chord chord_27 PROGMEM = {H_BOT3, QWERTY, &state_27, NULL, KC_X, 0, single_dance}; | ||
| 629 | uint8_t state_28 = IDLE; | ||
| 630 | const struct Chord chord_28 PROGMEM = {H_BOT4, QWERTY, &state_28, NULL, KC_C, 0, single_dance}; | ||
| 631 | uint8_t state_29 = IDLE; | ||
| 632 | const struct Chord chord_29 PROGMEM = {H_BOT5, QWERTY, &state_29, NULL, KC_V, 0, single_dance}; | ||
| 633 | uint8_t state_30 = IDLE; | ||
| 634 | const struct Chord chord_30 PROGMEM = {H_BOT6, QWERTY, &state_30, NULL, KC_B, 0, single_dance}; | ||
| 635 | uint8_t state_31 = IDLE; | ||
| 636 | const struct Chord chord_31 PROGMEM = {H_BOT7, QWERTY, &state_31, NULL, KC_N, 0, single_dance}; | ||
| 637 | uint8_t state_32 = IDLE; | ||
| 638 | const struct Chord chord_32 PROGMEM = {H_BOT8, QWERTY, &state_32, NULL, KC_M, 0, single_dance}; | ||
| 639 | uint8_t state_33 = IDLE; | ||
| 640 | const struct Chord chord_33 PROGMEM = {H_BOT9, QWERTY, &state_33, NULL, KC_COMMA, 0, single_dance}; | ||
| 641 | uint8_t state_34 = IDLE; | ||
| 642 | const struct Chord chord_34 PROGMEM = {H_BOT10, QWERTY, &state_34, NULL, KC_DOT, 0, single_dance}; | ||
| 643 | uint8_t state_35 = IDLE; | ||
| 644 | const struct Chord chord_35 PROGMEM = {H_BOT11, QWERTY, &state_35, NULL, KC_SLASH, 0, single_dance}; | ||
| 645 | uint8_t state_36 = IDLE; | ||
| 646 | const struct Chord chord_36 PROGMEM = {H_BOT12, QWERTY, &state_36, NULL, KC_QUOTE, 0, single_dance}; | ||
| 647 | uint8_t state_37 = IDLE; | ||
| 648 | const struct Chord chord_37 PROGMEM = {H_THU1, QWERTY, &state_37, NULL, KC_ENTER, 0, single_dance}; | ||
| 649 | uint8_t state_38 = IDLE; | ||
| 650 | uint8_t counter_38 = 0; | ||
| 651 | const struct Chord chord_38 PROGMEM = {H_THU2, QWERTY, &state_38, &counter_38, KC_SPC, NUM, key_layer_dance}; | ||
| 652 | uint8_t state_39 = IDLE; | ||
| 653 | uint8_t counter_39 = 0; | ||
| 654 | const struct Chord chord_39 PROGMEM = {H_THU3, QWERTY, &state_39, &counter_39, KC_BSPC, NAV, key_layer_dance}; | ||
| 655 | uint8_t state_40 = IDLE; | ||
| 656 | const struct Chord chord_40 PROGMEM = {H_THU4, QWERTY, &state_40, NULL, KC_DEL, 0, single_dance}; | ||
| 657 | uint8_t state_41 = IDLE; | ||
| 658 | uint8_t counter_41 = 0; | ||
| 659 | const struct Chord chord_41 PROGMEM = {H_THU5, QWERTY, &state_41, &counter_41, KC_SPC, FNC, key_layer_dance}; | ||
| 660 | uint8_t state_42 = IDLE; | ||
| 661 | const struct Chord chord_42 PROGMEM = {H_THU6, QWERTY, &state_42, NULL, KC_ENTER, 0, single_dance}; | ||
| 662 | uint8_t state_43 = IDLE; | ||
| 663 | const struct Chord chord_43 PROGMEM = {H_THU2 + H_THU3, QWERTY, &state_43, NULL, MOUSE, 0, temp_pseudolayer}; | ||
| 664 | uint8_t state_44 = IDLE; | ||
| 665 | const struct Chord chord_44 PROGMEM = {H_TOP1, NUM, &state_44, NULL, KC_GRAVE, 0, single_dance}; | ||
| 666 | uint8_t state_45 = IDLE; | ||
| 667 | const struct Chord chord_45 PROGMEM = {H_TOP2, NUM, &state_45, NULL, KC_1, 0, single_dance}; | ||
| 668 | uint8_t state_46 = IDLE; | ||
| 669 | const struct Chord chord_46 PROGMEM = {H_TOP3, NUM, &state_46, NULL, KC_2, 0, single_dance}; | ||
| 670 | uint8_t state_47 = IDLE; | ||
| 671 | const struct Chord chord_47 PROGMEM = {H_TOP4, NUM, &state_47, NULL, KC_3, 0, single_dance}; | ||
| 672 | uint8_t state_48 = IDLE; | ||
| 673 | const struct Chord chord_48 PROGMEM = {H_TOP5, NUM, &state_48, NULL, KC_4, 0, single_dance}; | ||
| 674 | uint8_t state_49 = IDLE; | ||
| 675 | const struct Chord chord_49 PROGMEM = {H_TOP6, NUM, &state_49, NULL, KC_5, 0, single_dance}; | ||
| 676 | uint8_t state_50 = IDLE; | ||
| 677 | const struct Chord chord_50 PROGMEM = {H_TOP7, NUM, &state_50, NULL, KC_6, 0, single_dance}; | ||
| 678 | uint8_t state_51 = IDLE; | ||
| 679 | const struct Chord chord_51 PROGMEM = {H_TOP8, NUM, &state_51, NULL, KC_7, 0, single_dance}; | ||
| 680 | uint8_t state_52 = IDLE; | ||
| 681 | const struct Chord chord_52 PROGMEM = {H_TOP9, NUM, &state_52, NULL, KC_8, 0, single_dance}; | ||
| 682 | uint8_t state_53 = IDLE; | ||
| 683 | const struct Chord chord_53 PROGMEM = {H_TOP10, NUM, &state_53, NULL, KC_9, 0, single_dance}; | ||
| 684 | uint8_t state_54 = IDLE; | ||
| 685 | const struct Chord chord_54 PROGMEM = {H_TOP11, NUM, &state_54, NULL, KC_0, 0, single_dance}; | ||
| 686 | uint8_t state_55 = IDLE; | ||
| 687 | const struct Chord chord_55 PROGMEM = {H_TOP12, NUM, &state_55, NULL, KC_MINUS, 0, single_dance}; | ||
| 688 | uint8_t state_56 = IDLE; | ||
| 689 | const struct Chord chord_56 PROGMEM = {H_TOP3 + H_BOT3, NUM, &state_56, NULL, KC_LALT, 0, single_dance}; | ||
| 690 | uint8_t state_57 = IDLE; | ||
| 691 | const struct Chord chord_57 PROGMEM = {H_TOP4 + H_BOT4, NUM, &state_57, NULL, KC_LCTL, 0, single_dance}; | ||
| 692 | uint8_t state_58 = IDLE; | ||
| 693 | const struct Chord chord_58 PROGMEM = {H_TOP5 + H_BOT5, NUM, &state_58, NULL, KC_LSFT, 0, single_dance}; | ||
| 694 | uint8_t state_59 = IDLE; | ||
| 695 | const struct Chord chord_59 PROGMEM = {H_TOP6 + H_BOT6, NUM, &state_59, NULL, KC_LGUI, 0, single_dance}; | ||
| 696 | uint8_t state_60 = IDLE; | ||
| 697 | const struct Chord chord_60 PROGMEM = {H_TOP7 + H_BOT7, NUM, &state_60, NULL, KC_RGUI, 0, single_dance}; | ||
| 698 | uint8_t state_61 = IDLE; | ||
| 699 | const struct Chord chord_61 PROGMEM = {H_TOP8 + H_BOT8, NUM, &state_61, NULL, KC_RSFT, 0, single_dance}; | ||
| 700 | uint8_t state_62 = IDLE; | ||
| 701 | const struct Chord chord_62 PROGMEM = {H_TOP9 + H_BOT9, NUM, &state_62, NULL, KC_RCTL, 0, single_dance}; | ||
| 702 | uint8_t state_63 = IDLE; | ||
| 703 | const struct Chord chord_63 PROGMEM = {H_TOP10 + H_BOT10, NUM, &state_63, NULL, KC_RALT, 0, single_dance}; | ||
| 704 | uint8_t state_64 = IDLE; | ||
| 705 | const struct Chord chord_64 PROGMEM = {H_BOT12, NUM, &state_64, NULL, KC_EQUAL, 0, single_dance}; | ||
| 706 | uint8_t state_65 = IDLE; | ||
| 707 | const struct Chord chord_65 PROGMEM = {H_TOP2, FNC, &state_65, NULL, KC_F1, 0, single_dance}; | ||
| 708 | uint8_t state_66 = IDLE; | ||
| 709 | const struct Chord chord_66 PROGMEM = {H_TOP3, FNC, &state_66, NULL, KC_F2, 0, single_dance}; | ||
| 710 | uint8_t state_67 = IDLE; | ||
| 711 | const struct Chord chord_67 PROGMEM = {H_TOP4, FNC, &state_67, NULL, KC_F3, 0, single_dance}; | ||
| 712 | uint8_t state_68 = IDLE; | ||
| 713 | const struct Chord chord_68 PROGMEM = {H_TOP5, FNC, &state_68, NULL, KC_F4, 0, single_dance}; | ||
| 714 | uint8_t state_69 = IDLE; | ||
| 715 | const struct Chord chord_69 PROGMEM = {H_TOP6, FNC, &state_69, NULL, KC_F5, 0, single_dance}; | ||
| 716 | uint8_t state_70 = IDLE; | ||
| 717 | const struct Chord chord_70 PROGMEM = {H_TOP7, FNC, &state_70, NULL, KC_F6, 0, single_dance}; | ||
| 718 | uint8_t state_71 = IDLE; | ||
| 719 | const struct Chord chord_71 PROGMEM = {H_TOP8, FNC, &state_71, NULL, KC_F7, 0, single_dance}; | ||
| 720 | uint8_t state_72 = IDLE; | ||
| 721 | const struct Chord chord_72 PROGMEM = {H_TOP9, FNC, &state_72, NULL, KC_F8, 0, single_dance}; | ||
| 722 | uint8_t state_73 = IDLE; | ||
| 723 | const struct Chord chord_73 PROGMEM = {H_TOP10, FNC, &state_73, NULL, KC_F9, 0, single_dance}; | ||
| 724 | uint8_t state_74 = IDLE; | ||
| 725 | const struct Chord chord_74 PROGMEM = {H_TOP11, FNC, &state_74, NULL, KC_F10, 0, single_dance}; | ||
| 726 | uint8_t state_75 = IDLE; | ||
| 727 | const struct Chord chord_75 PROGMEM = {H_TOP12, FNC, &state_75, NULL, KC_F11, 0, single_dance}; | ||
| 728 | uint8_t state_76 = IDLE; | ||
| 729 | const struct Chord chord_76 PROGMEM = {H_TOP3 + H_BOT3, FNC, &state_76, NULL, KC_LALT, 0, single_dance}; | ||
| 730 | uint8_t state_77 = IDLE; | ||
| 731 | const struct Chord chord_77 PROGMEM = {H_TOP4 + H_BOT4, FNC, &state_77, NULL, KC_LCTL, 0, single_dance}; | ||
| 732 | uint8_t state_78 = IDLE; | ||
| 733 | const struct Chord chord_78 PROGMEM = {H_TOP5 + H_BOT5, FNC, &state_78, NULL, KC_LSFT, 0, single_dance}; | ||
| 734 | uint8_t state_79 = IDLE; | ||
| 735 | const struct Chord chord_79 PROGMEM = {H_TOP6 + H_BOT6, FNC, &state_79, NULL, KC_LGUI, 0, single_dance}; | ||
| 736 | uint8_t state_80 = IDLE; | ||
| 737 | const struct Chord chord_80 PROGMEM = {H_TOP7 + H_BOT7, FNC, &state_80, NULL, KC_RGUI, 0, single_dance}; | ||
| 738 | uint8_t state_81 = IDLE; | ||
| 739 | const struct Chord chord_81 PROGMEM = {H_TOP8 + H_BOT8, FNC, &state_81, NULL, KC_RSFT, 0, single_dance}; | ||
| 740 | uint8_t state_82 = IDLE; | ||
| 741 | const struct Chord chord_82 PROGMEM = {H_TOP9 + H_BOT9, FNC, &state_82, NULL, KC_RCTL, 0, single_dance}; | ||
| 742 | uint8_t state_83 = IDLE; | ||
| 743 | const struct Chord chord_83 PROGMEM = {H_TOP10 + H_BOT10, FNC, &state_83, NULL, KC_RALT, 0, single_dance}; | ||
| 744 | uint8_t state_84 = IDLE; | ||
| 745 | const struct Chord chord_84 PROGMEM = {H_BOT12, FNC, &state_84, NULL, KC_F12, 0, single_dance}; | ||
| 746 | uint8_t state_85 = IDLE; | ||
| 747 | const struct Chord chord_85 PROGMEM = {H_TOP8, NAV, &state_85, NULL, KC_HOME, 0, single_dance}; | ||
| 748 | uint8_t state_86 = IDLE; | ||
| 749 | const struct Chord chord_86 PROGMEM = {H_TOP9, NAV, &state_86, NULL, KC_UP, 0, single_dance}; | ||
| 750 | uint8_t state_87 = IDLE; | ||
| 751 | const struct Chord chord_87 PROGMEM = {H_TOP10, NAV, &state_87, NULL, KC_END, 0, single_dance}; | ||
| 752 | uint8_t state_88 = IDLE; | ||
| 753 | const struct Chord chord_88 PROGMEM = {H_TOP11, NAV, &state_88, NULL, KC_PGUP, 0, single_dance}; | ||
| 754 | uint8_t state_89 = IDLE; | ||
| 755 | const struct Chord chord_89 PROGMEM = {H_TOP3 + H_BOT3, NAV, &state_89, NULL, KC_LALT, 0, single_dance}; | ||
| 756 | uint8_t state_90 = IDLE; | ||
| 757 | const struct Chord chord_90 PROGMEM = {H_TOP4 + H_BOT4, NAV, &state_90, NULL, KC_LCTL, 0, single_dance}; | ||
| 758 | uint8_t state_91 = IDLE; | ||
| 759 | const struct Chord chord_91 PROGMEM = {H_TOP5 + H_BOT5, NAV, &state_91, NULL, KC_LSFT, 0, single_dance}; | ||
| 760 | uint8_t state_92 = IDLE; | ||
| 761 | const struct Chord chord_92 PROGMEM = {H_TOP6 + H_BOT6, NAV, &state_92, NULL, KC_LGUI, 0, single_dance}; | ||
| 762 | uint8_t state_93 = IDLE; | ||
| 763 | const struct Chord chord_93 PROGMEM = {H_BOT8, NAV, &state_93, NULL, KC_LEFT, 0, single_dance}; | ||
| 764 | uint8_t state_94 = IDLE; | ||
| 765 | const struct Chord chord_94 PROGMEM = {H_BOT9, NAV, &state_94, NULL, KC_DOWN, 0, single_dance}; | ||
| 766 | uint8_t state_95 = IDLE; | ||
| 767 | const struct Chord chord_95 PROGMEM = {H_BOT10, NAV, &state_95, NULL, KC_RIGHT, 0, single_dance}; | ||
| 768 | uint8_t state_96 = IDLE; | ||
| 769 | const struct Chord chord_96 PROGMEM = {H_BOT11, NAV, &state_96, NULL, KC_PGDN, 0, single_dance}; | ||
| 770 | uint8_t state_97 = IDLE; | ||
| 771 | const struct Chord chord_97 PROGMEM = {H_TOP8, MOUSE, &state_97, NULL, KC_BTN1, 0, single_dance}; | ||
| 772 | uint8_t state_98 = IDLE; | ||
| 773 | const struct Chord chord_98 PROGMEM = {H_TOP9, MOUSE, &state_98, NULL, KC_MS_U, 0, single_dance}; | ||
| 774 | uint8_t state_99 = IDLE; | ||
| 775 | const struct Chord chord_99 PROGMEM = {H_TOP10, MOUSE, &state_99, NULL, KC_BTN2, 0, single_dance}; | ||
| 776 | uint8_t state_100 = IDLE; | ||
| 777 | const struct Chord chord_100 PROGMEM = {H_TOP11, MOUSE, &state_100, NULL, KC_WH_U, 0, single_dance}; | ||
| 778 | uint8_t state_101 = IDLE; | ||
| 779 | const struct Chord chord_101 PROGMEM = {H_TOP3 + H_BOT3, MOUSE, &state_101, NULL, KC_LALT, 0, single_dance}; | ||
| 780 | uint8_t state_102 = IDLE; | ||
| 781 | const struct Chord chord_102 PROGMEM = {H_TOP4 + H_BOT4, MOUSE, &state_102, NULL, KC_LCTL, 0, single_dance}; | ||
| 782 | uint8_t state_103 = IDLE; | ||
| 783 | const struct Chord chord_103 PROGMEM = {H_TOP5 + H_BOT5, MOUSE, &state_103, NULL, KC_LSFT, 0, single_dance}; | ||
| 784 | uint8_t state_104 = IDLE; | ||
| 785 | const struct Chord chord_104 PROGMEM = {H_TOP6 + H_BOT6, MOUSE, &state_104, NULL, KC_LGUI, 0, single_dance}; | ||
| 786 | uint8_t state_105 = IDLE; | ||
| 787 | const struct Chord chord_105 PROGMEM = {H_BOT8, MOUSE, &state_105, NULL, KC_MS_L, 0, single_dance}; | ||
| 788 | uint8_t state_106 = IDLE; | ||
| 789 | const struct Chord chord_106 PROGMEM = {H_BOT9, MOUSE, &state_106, NULL, KC_MS_D, 0, single_dance}; | ||
| 790 | uint8_t state_107 = IDLE; | ||
| 791 | const struct Chord chord_107 PROGMEM = {H_BOT10, MOUSE, &state_107, NULL, KC_MS_R, 0, single_dance}; | ||
| 792 | uint8_t state_108 = IDLE; | ||
| 793 | const struct Chord chord_108 PROGMEM = {H_BOT11, MOUSE, &state_108, NULL, KC_WH_D, 0, single_dance}; | ||
| 794 | |||
| 795 | const struct Chord* const list_of_chords[] PROGMEM = { | ||
| 796 | &chord_0, &chord_1, &chord_2, &chord_3, &chord_4, &chord_5, &chord_6, &chord_7, &chord_8, &chord_9, &chord_10, &chord_11, &chord_12, &chord_13, &chord_14, &chord_15, &chord_16, &chord_17, &chord_18, &chord_19, &chord_20, &chord_21, &chord_22, &chord_23, &chord_24, &chord_25, &chord_26, &chord_27, &chord_28, &chord_29, &chord_30, &chord_31, &chord_32, &chord_33, &chord_34, &chord_35, &chord_36, &chord_37, &chord_38, &chord_39, &chord_40, &chord_41, &chord_42, &chord_43, &chord_44, &chord_45, &chord_46, &chord_47, &chord_48, &chord_49, &chord_50, &chord_51, &chord_52, &chord_53, &chord_54, &chord_55, &chord_56, &chord_57, &chord_58, &chord_59, &chord_60, &chord_61, &chord_62, &chord_63, &chord_64, &chord_65, &chord_66, &chord_67, &chord_68, &chord_69, &chord_70, &chord_71, &chord_72, &chord_73, &chord_74, &chord_75, &chord_76, &chord_77, &chord_78, &chord_79, &chord_80, &chord_81, &chord_82, &chord_83, &chord_84, &chord_85, &chord_86, &chord_87, &chord_88, &chord_89, &chord_90, &chord_91, &chord_92, &chord_93, &chord_94, &chord_95, &chord_96, &chord_97, &chord_98, &chord_99, &chord_100, &chord_101, &chord_102, &chord_103, &chord_104, &chord_105, &chord_106, &chord_107, &chord_108 | ||
| 797 | }; | ||
| 798 | |||
| 799 | const uint16_t** const leader_triggers PROGMEM = NULL; | ||
| 800 | void (*leader_functions[]) (void) = {}; | ||
| 801 | |||
| 802 | #define NUMBER_OF_CHORDS 109 | ||
| 803 | #define NUMBER_OF_LEADER_COMBOS 0 | ||
| 804 | |||
| 805 | bool are_hashed_keycodes_in_sound(HASH_TYPE keycodes_hash, HASH_TYPE sound) { | ||
| 806 | return (keycodes_hash & sound) == keycodes_hash; | ||
| 807 | } | ||
| 808 | |||
| 809 | uint8_t keycode_to_index(uint16_t keycode) { | ||
| 810 | return keycode - FIRST_INTERNAL_KEYCODE; | ||
| 811 | } | ||
| 812 | |||
| 813 | void sound_keycode_array(uint16_t keycode) { | ||
| 814 | uint8_t index = keycode_to_index(keycode); | ||
| 815 | keycode_index++; | ||
| 816 | keycodes_buffer_array[index] = keycode_index; | ||
| 817 | } | ||
| 818 | |||
| 819 | void silence_keycode_hash_array(HASH_TYPE keycode_hash) { | ||
| 820 | for (int i = 0; i < NUMBER_OF_KEYS; i++) { | ||
| 821 | bool index_in_hash = ((HASH_TYPE) 1 << i) & keycode_hash; | ||
| 822 | if (index_in_hash) { | ||
| 823 | uint8_t current_val = keycodes_buffer_array[i]; | ||
| 824 | keycodes_buffer_array[i] = 0; | ||
| 825 | for (int j = 0; j < NUMBER_OF_KEYS; j++) { | ||
| 826 | if (keycodes_buffer_array[j] > current_val) { | ||
| 827 | keycodes_buffer_array[j]--; | ||
| 828 | } | ||
| 829 | } | ||
| 830 | keycode_index--; | ||
| 831 | } | ||
| 832 | } | ||
| 833 | } | ||
| 834 | |||
| 835 | bool are_hashed_keycodes_in_array(HASH_TYPE keycode_hash) { | ||
| 836 | for (int i = 0; i < NUMBER_OF_KEYS; i++) { | ||
| 837 | bool index_in_hash = ((HASH_TYPE) 1 << i) & keycode_hash; | ||
| 838 | bool index_in_array = (bool) keycodes_buffer_array[i]; | ||
| 839 | if (index_in_hash && !index_in_array) { | ||
| 840 | return false; | ||
| 841 | } | ||
| 842 | } | ||
| 843 | return true; | ||
| 844 | } | ||
| 845 | |||
| 846 | void kill_one_shots(void) { | ||
| 847 | struct Chord chord_storage; | ||
| 848 | struct Chord* chord_ptr; | ||
| 849 | struct Chord* chord; | ||
| 850 | |||
| 851 | for (int i = 0; i < NUMBER_OF_CHORDS; i++) { | ||
| 852 | chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]); | ||
| 853 | memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord)); | ||
| 854 | chord = &chord_storage; | ||
| 855 | |||
| 856 | if (*chord->state == IN_ONE_SHOT) { | ||
| 857 | *chord->state = RESTART; | ||
| 858 | chord->function(chord); | ||
| 859 | if (*chord->state == RESTART) { | ||
| 860 | *chord->state = IDLE; | ||
| 861 | } | ||
| 862 | } | ||
| 863 | } | ||
| 864 | } | ||
| 865 | |||
| 866 | void process_finished_dances(void) { | ||
| 867 | struct Chord chord_storage; | ||
| 868 | struct Chord* chord_ptr; | ||
| 869 | struct Chord* chord; | ||
| 870 | |||
| 871 | for (int i = 0; i < NUMBER_OF_CHORDS; i++) { | ||
| 872 | chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]); | ||
| 873 | memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord)); | ||
| 874 | chord = &chord_storage; | ||
| 875 | |||
| 876 | if (*chord->state == ACTIVATED) { | ||
| 877 | *chord->state = PRESS_FROM_ACTIVE; | ||
| 878 | chord->function(chord); | ||
| 879 | if (a_key_went_through) { | ||
| 880 | kill_one_shots(); | ||
| 881 | } | ||
| 882 | dance_timer = timer_read(); | ||
| 883 | } else if (*chord->state == IDLE_IN_DANCE) { | ||
| 884 | *chord->state = FINISHED; | ||
| 885 | chord->function(chord); | ||
| 886 | if (*chord->state == FINISHED) { | ||
| 887 | *chord->state = RESTART; | ||
| 888 | if (*chord->state == RESTART) { | ||
| 889 | *chord->state = IDLE; | ||
| 890 | } | ||
| 891 | } | ||
| 892 | } else if (*chord->state == PRESS_FROM_ACTIVE) { | ||
| 893 | *chord->state = FINISHED_FROM_ACTIVE; | ||
| 894 | chord->function(chord); | ||
| 895 | if (a_key_went_through) { | ||
| 896 | kill_one_shots(); | ||
| 897 | } | ||
| 898 | dance_timer = timer_read(); | ||
| 899 | } | ||
| 900 | } | ||
| 901 | } | ||
| 902 | |||
| 903 | uint8_t keycodes_buffer_array_min(uint8_t* first_keycode_index) { | ||
| 904 | for (int i = 0; i < NUMBER_OF_KEYS; i++) { | ||
| 905 | if (keycodes_buffer_array[i] == 1) { | ||
| 906 | if (first_keycode_index != NULL) { | ||
| 907 | *first_keycode_index = (uint8_t) i; | ||
| 908 | } | ||
| 909 | return 1; | ||
| 910 | } | ||
| 911 | } | ||
| 912 | return 0; | ||
| 913 | } | ||
| 914 | |||
| 915 | void remove_subchords(void) { | ||
| 916 | struct Chord chord_storage; | ||
| 917 | struct Chord* chord_ptr; | ||
| 918 | struct Chord* chord; | ||
| 919 | |||
| 920 | for (int i = 0; i < NUMBER_OF_CHORDS; i++) { | ||
| 921 | chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]); | ||
| 922 | memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord)); | ||
| 923 | chord = &chord_storage; | ||
| 924 | |||
| 925 | if (!(*chord->state == READY || *chord->state == READY_IN_DANCE || *chord->state == READY_LOCKED)) { | ||
| 926 | continue; | ||
| 927 | } | ||
| 928 | |||
| 929 | struct Chord chord_storage_2; | ||
| 930 | struct Chord* chord_ptr_2; | ||
| 931 | struct Chord* chord_2; | ||
| 932 | for (int j = 0; j < NUMBER_OF_CHORDS; j++) { | ||
| 933 | if (i == j) {continue;} | ||
| 934 | |||
| 935 | chord_ptr_2 = (struct Chord*) pgm_read_word (&list_of_chords[j]); | ||
| 936 | memcpy_P(&chord_storage_2, chord_ptr_2, sizeof(struct Chord)); | ||
| 937 | chord_2 = &chord_storage_2; | ||
| 938 | |||
| 939 | if (are_hashed_keycodes_in_sound(chord_2->keycodes_hash, chord->keycodes_hash)) { | ||
| 940 | if (*chord_2->state == READY) { | ||
| 941 | *chord_2->state = IDLE; | ||
| 942 | } | ||
| 943 | if (*chord_2->state == READY_IN_DANCE) { | ||
| 944 | *chord_2->state = IDLE_IN_DANCE; | ||
| 945 | } | ||
| 946 | if (*chord_2->state == READY_LOCKED) { | ||
| 947 | *chord_2->state = LOCKED; | ||
| 948 | } | ||
| 949 | } | ||
| 950 | } | ||
| 951 | } | ||
| 952 | } | ||
| 953 | |||
| 954 | void process_ready_chords(void) { | ||
| 955 | uint8_t first_keycode_index = 0; | ||
| 956 | while (keycodes_buffer_array_min(&first_keycode_index)) { | ||
| 957 | // find ready chords | ||
| 958 | struct Chord chord_storage; | ||
| 959 | struct Chord* chord_ptr; | ||
| 960 | struct Chord* chord; | ||
| 961 | |||
| 962 | for (int i = 0; i < NUMBER_OF_CHORDS; i++) { | ||
| 963 | chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]); | ||
| 964 | memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord)); | ||
| 965 | chord = &chord_storage; | ||
| 966 | |||
| 967 | // if the chord does not contain the first keycode | ||
| 968 | bool contains_first_keycode = ((uint32_t) 1 << first_keycode_index) & chord->keycodes_hash; | ||
| 969 | if (!contains_first_keycode) { | ||
| 970 | continue; | ||
| 971 | } | ||
| 972 | |||
| 973 | if (!are_hashed_keycodes_in_array(chord->keycodes_hash)){ | ||
| 974 | continue; | ||
| 975 | } | ||
| 976 | |||
| 977 | if (*chord->state == LOCKED) { | ||
| 978 | *chord->state = READY_LOCKED; | ||
| 979 | continue; | ||
| 980 | } | ||
| 981 | |||
| 982 | if (!(chord->pseudolayer == current_pseudolayer || chord->pseudolayer == ALWAYS_ON)) { | ||
| 983 | continue; | ||
| 984 | } | ||
| 985 | |||
| 986 | if (*chord->state == IDLE) { | ||
| 987 | *chord->state = READY; | ||
| 988 | continue; | ||
| 989 | } | ||
| 990 | |||
| 991 | if (*chord->state == IDLE_IN_DANCE) { | ||
| 992 | *chord->state = READY_IN_DANCE; | ||
| 993 | } | ||
| 994 | } | ||
| 995 | |||
| 996 | // remove subchords | ||
| 997 | remove_subchords(); | ||
| 998 | |||
| 999 | // execute logic | ||
| 1000 | // this should be only one chord | ||
| 1001 | for (int i = 0; i < NUMBER_OF_CHORDS; i++) { | ||
| 1002 | chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]); | ||
| 1003 | memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord)); | ||
| 1004 | chord = &chord_storage; | ||
| 1005 | |||
| 1006 | if (*chord->state == READY_LOCKED) { | ||
| 1007 | *chord->state = RESTART; | ||
| 1008 | chord->function(chord); | ||
| 1009 | if (*chord->state == RESTART) { | ||
| 1010 | *chord->state = IDLE; | ||
| 1011 | } | ||
| 1012 | break; | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | if (*chord->state == READY || *chord->state == READY_IN_DANCE) { | ||
| 1016 | if (last_chord && last_chord != chord) { | ||
| 1017 | process_finished_dances(); | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | bool lock_next_prev_state = lock_next; | ||
| 1021 | |||
| 1022 | *chord->state = ACTIVATED; | ||
| 1023 | chord->function(chord); | ||
| 1024 | dance_timer = timer_read(); | ||
| 1025 | |||
| 1026 | if (lock_next && lock_next == lock_next_prev_state) { | ||
| 1027 | lock_next = false; | ||
| 1028 | *chord->state = PRESS_FROM_ACTIVE; | ||
| 1029 | chord->function(chord); | ||
| 1030 | if (*chord->state == PRESS_FROM_ACTIVE) { | ||
| 1031 | *chord->state = LOCKED; | ||
| 1032 | } | ||
| 1033 | if (a_key_went_through) { | ||
| 1034 | kill_one_shots(); | ||
| 1035 | } | ||
| 1036 | } | ||
| 1037 | break; | ||
| 1038 | } | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | // silence notes | ||
| 1042 | silence_keycode_hash_array(chord->keycodes_hash); | ||
| 1043 | } | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | void deactivate_active_chords(uint16_t keycode) { | ||
| 1047 | HASH_TYPE hash = (HASH_TYPE)1 << (keycode - SAFE_RANGE); | ||
| 1048 | bool broken; | ||
| 1049 | struct Chord chord_storage; | ||
| 1050 | struct Chord* chord_ptr; | ||
| 1051 | struct Chord* chord; | ||
| 1052 | |||
| 1053 | for (int i = 0; i < NUMBER_OF_CHORDS; i++) { | ||
| 1054 | chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]); | ||
| 1055 | memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord)); | ||
| 1056 | chord = &chord_storage; | ||
| 1057 | |||
| 1058 | broken = are_hashed_keycodes_in_sound(hash, chord->keycodes_hash); | ||
| 1059 | if (!broken) { | ||
| 1060 | continue; | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | switch (*chord->state) { | ||
| 1064 | case ACTIVATED: | ||
| 1065 | *chord->state = DEACTIVATED; | ||
| 1066 | chord->function(chord); | ||
| 1067 | |||
| 1068 | if (*chord->state == DEACTIVATED) { | ||
| 1069 | dance_timer = timer_read(); | ||
| 1070 | *chord->state = IDLE_IN_DANCE; | ||
| 1071 | } | ||
| 1072 | if (*chord->state != IN_ONE_SHOT) { | ||
| 1073 | kill_one_shots(); | ||
| 1074 | } | ||
| 1075 | break; | ||
| 1076 | case PRESS_FROM_ACTIVE: | ||
| 1077 | case FINISHED_FROM_ACTIVE: | ||
| 1078 | *chord->state = RESTART; | ||
| 1079 | chord->function(chord); | ||
| 1080 | if (*chord->state == RESTART) { | ||
| 1081 | *chord->state = IDLE; | ||
| 1082 | } | ||
| 1083 | kill_one_shots(); | ||
| 1084 | break; | ||
| 1085 | default: | ||
| 1086 | break; | ||
| 1087 | } | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | } | ||
| 1091 | |||
| 1092 | void process_command(void) { | ||
| 1093 | command_mode = 0; | ||
| 1094 | for (int i = 0; i < COMMAND_MAX_LENGTH; i++) { | ||
| 1095 | if (command_buffer[i]) { | ||
| 1096 | register_code(command_buffer[i]); | ||
| 1097 | } | ||
| 1098 | send_keyboard_report(); | ||
| 1099 | } | ||
| 1100 | wait_ms(TAP_TIMEOUT); | ||
| 1101 | for (int i = 0; i < COMMAND_MAX_LENGTH; i++) { | ||
| 1102 | if (command_buffer[i]) { | ||
| 1103 | unregister_code(command_buffer[i]); | ||
| 1104 | } | ||
| 1105 | send_keyboard_report(); | ||
| 1106 | } | ||
| 1107 | for (int i = 0; i < COMMAND_MAX_LENGTH; i++) { | ||
| 1108 | command_buffer[i] = 0; | ||
| 1109 | } | ||
| 1110 | command_ind = 0; | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | void process_leader(void) { | ||
| 1114 | in_leader_mode = false; | ||
| 1115 | for (int i = 0; i < NUMBER_OF_LEADER_COMBOS; i++) { | ||
| 1116 | uint16_t trigger[LEADER_MAX_LENGTH]; | ||
| 1117 | memcpy_P(trigger, leader_triggers[i], LEADER_MAX_LENGTH * sizeof(uint16_t)); | ||
| 1118 | |||
| 1119 | if (identical(leader_buffer, trigger)) { | ||
| 1120 | (*leader_functions[i])(); | ||
| 1121 | break; | ||
| 1122 | } | ||
| 1123 | } | ||
| 1124 | for (int i = 0; i < LEADER_MAX_LENGTH; i++) { | ||
| 1125 | leader_buffer[i] = 0; | ||
| 1126 | } | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | bool process_record_user(uint16_t keycode, keyrecord_t *record) { | ||
| 1130 | if (keycode < FIRST_INTERNAL_KEYCODE || keycode > LAST_INTERNAL_KEYCODE) { | ||
| 1131 | return true; | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | if (record->event.pressed) { | ||
| 1135 | sound_keycode_array(keycode); | ||
| 1136 | } else { | ||
| 1137 | process_ready_chords(); | ||
| 1138 | deactivate_active_chords(keycode); | ||
| 1139 | } | ||
| 1140 | chord_timer = timer_read(); | ||
| 1141 | leader_timer = timer_read(); | ||
| 1142 | |||
| 1143 | return false; | ||
| 1144 | } | ||
| 1145 | |||
| 1146 | void matrix_scan_user(void) { | ||
| 1147 | bool chord_timer_expired = timer_elapsed(chord_timer) > CHORD_TIMEOUT; | ||
| 1148 | if (chord_timer_expired && keycodes_buffer_array_min(NULL)) { | ||
| 1149 | process_ready_chords(); | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | bool dance_timer_expired = timer_elapsed(dance_timer) > DANCE_TIMEOUT; | ||
| 1153 | if (dance_timer_expired) { // would love to have && in_dance but not sure how | ||
| 1154 | process_finished_dances(); | ||
| 1155 | } | ||
| 1156 | |||
| 1157 | bool in_command_mode = command_mode == 2; | ||
| 1158 | if (in_command_mode) { | ||
| 1159 | process_command(); | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | bool leader_timer_expired = timer_elapsed(leader_timer) > LEADER_TIMEOUT; | ||
| 1163 | if (leader_timer_expired && in_leader_mode) { | ||
| 1164 | process_leader(); | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | } | ||
| 1168 | |||
| 1169 | void clear(const struct Chord* self) { | ||
| 1170 | if (*self->state == ACTIVATED) { | ||
| 1171 | // kill all chords | ||
| 1172 | struct Chord chord_storage; | ||
| 1173 | struct Chord* chord_ptr; | ||
| 1174 | struct Chord* chord; | ||
| 1175 | |||
| 1176 | for (int i = 0; i < NUMBER_OF_CHORDS; i++) { | ||
| 1177 | chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]); | ||
| 1178 | memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord)); | ||
| 1179 | chord = &chord_storage; | ||
| 1180 | |||
| 1181 | *chord->state = IDLE; | ||
| 1182 | |||
| 1183 | if (chord->counter) { | ||
| 1184 | *chord->counter = 0; | ||
| 1185 | } | ||
| 1186 | } | ||
| 1187 | |||
| 1188 | // clear keyboard | ||
| 1189 | clear_keyboard(); | ||
| 1190 | send_keyboard_report(); | ||
| 1191 | |||
| 1192 | // switch to default pseudolayer | ||
| 1193 | current_pseudolayer = DEFAULT_PSEUDOLAYER; | ||
| 1194 | |||
| 1195 | // clear all keyboard states | ||
| 1196 | lock_next = false; | ||
| 1197 | autoshift_mode = true; | ||
| 1198 | command_mode = 0; | ||
| 1199 | in_leader_mode = false; | ||
| 1200 | leader_ind = 0; | ||
| 1201 | dynamic_macro_mode = false; | ||
| 1202 | a_key_went_through = false; | ||
| 1203 | |||
| 1204 | for (int i = 0; i < DYNAMIC_MACRO_MAX_LENGTH; i++) { | ||
| 1205 | dynamic_macro_buffer[i] = 0; | ||
| 1206 | } | ||
| 1207 | } | ||
| 1208 | } \ No newline at end of file | ||
diff --git a/keyboards/georgi/keymaps/dennytom/keymap_def.json b/keyboards/georgi/keymaps/dennytom/keymap_def.json new file mode 100644 index 000000000..232ccafad --- /dev/null +++ b/keyboards/georgi/keymaps/dennytom/keymap_def.json | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | { | ||
| 2 | "keys": [ | ||
| 3 | "TOP1", "TOP2", "TOP3", "TOP4", "TOP5", "TOP6", "TOP7", "TOP8", "TOP9", "TOP10", "TOP11", "TOP12", | ||
| 4 | "BOT1", "BOT2", "BOT3", "BOT4", "BOT5", "BOT6", "BOT7", "BOT8", "BOT9", "BOT10", "BOT11", "BOT12", | ||
| 5 | "THU1", "THU2", "THU3", "THU4", "THU5", "THU6" | ||
| 6 | ], | ||
| 7 | "parameters": { | ||
| 8 | "layout_function_name": "LAYOUT_georgi", | ||
| 9 | "chord_timeout": 100, | ||
| 10 | "dance_timeout": 200, | ||
| 11 | "leader_timeout": 750, | ||
| 12 | "tap_timeout": 50, | ||
| 13 | "command_max_length": 5, | ||
| 14 | "leader_max_length": 5, | ||
| 15 | "dynamic_macro_max_length": 20, | ||
| 16 | "string_max_length": 16, | ||
| 17 | "long_press_multiplier": 3, | ||
| 18 | "default_pseudolayer": "QWERTY" | ||
| 19 | }, | ||
| 20 | "layers": [ | ||
| 21 | { | ||
| 22 | "type": "auto" | ||
| 23 | } | ||
| 24 | ], | ||
| 25 | "chord_sets": [ | ||
| 26 | { | ||
| 27 | "name": "rows", | ||
| 28 | "chords": | ||
| 29 | [ | ||
| 30 | ["TOP1"], ["TOP2"], ["TOP3"], ["TOP4"], ["TOP5"], ["TOP6"], ["TOP7"], ["TOP8"], ["TOP9"], ["TOP10"], ["TOP11"], ["TOP12"], | ||
| 31 | ["TOP1", "BOT1"], ["TOP2", "BOT2"], ["TOP3", "BOT3"], ["TOP4", "BOT4"], ["TOP5", "BOT5"], ["TOP6", "BOT6"], ["TOP7", "BOT7"], ["TOP8", "BOT8"], ["TOP9", "BOT9"], ["TOP10", "BOT10"], ["TOP11", "BOT11"], ["TOP12", "BOT12"], | ||
| 32 | ["BOT1"], ["BOT2"], ["BOT3"], ["BOT4"], ["BOT5"], ["BOT6"], ["BOT7"], ["BOT8"], ["BOT9"], ["BOT10"], ["BOT11"], ["BOT12"], | ||
| 33 | ["THU1"], ["THU2"], ["THU3"], ["THU4"], ["THU5"], ["THU6"] | ||
| 34 | ] | ||
| 35 | } | ||
| 36 | ], | ||
| 37 | "pseudolayers": [ | ||
| 38 | { | ||
| 39 | "name": "ALWAYS_ON", | ||
| 40 | "chords": [ | ||
| 41 | { | ||
| 42 | "type": "visual", | ||
| 43 | "chord": [ | ||
| 44 | "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", | ||
| 45 | "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", | ||
| 46 | " ", " ", " ", " ", " ", " " | ||
| 47 | ], | ||
| 48 | "keycode": "CLEAR_KB" | ||
| 49 | }, | ||
| 50 | { | ||
| 51 | "type": "visual", | ||
| 52 | "chord": [ | ||
| 53 | " ", " ", " ", " ", " ", "X", "X", " ", " ", " ", " ", " ", | ||
| 54 | " ", " ", " ", " ", " ", "X", "X", " ", " ", " ", " ", " ", | ||
| 55 | " ", " ", " ", " ", " ", " " | ||
| 56 | ], | ||
| 57 | "keycode": "CMD" | ||
| 58 | } | ||
| 59 | ] | ||
| 60 | }, | ||
| 61 | { | ||
| 62 | "name": "QWERTY", | ||
| 63 | "chords": [ | ||
| 64 | { | ||
| 65 | "type": "chord_set", | ||
| 66 | "set": "rows", | ||
| 67 | "keycodes": [ | ||
| 68 | "ESC", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "\\", | ||
| 69 | "INS", "A", "KK(S, LALT)", "KM(D, LCTL)", "KM(F, LSFT)", "KK(G, LGUI)", "KK(H, RGUI)", "KM(J, RSFT)", "KM(K, RCTL)", "KK(L, RALT)", ";", " ", | ||
| 70 | "TAB", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "'", | ||
| 71 | "","","","","","" | ||
| 72 | ] | ||
| 73 | }, | ||
| 74 | { | ||
| 75 | "type": "visual_array", | ||
| 76 | "keys": ["THU1", "THU2", "THU3", "THU4", "THU5", "THU6"], | ||
| 77 | "dictionary": [ | ||
| 78 | ["X", " ", " ", " ", " ", " ", "ENTER"], | ||
| 79 | [" ", "X", " ", " ", " ", " ", "KL(SPC, NUM)"], | ||
| 80 | [" ", " ", "X", " ", " ", " ", "KL(BSPC, NAV)"], | ||
| 81 | [" ", " ", " ", "X", " ", " ", "DEL"], | ||
| 82 | [" ", " ", " ", " ", "X", " ", "KL(SPC, FNC)"], | ||
| 83 | [" ", " ", " ", " ", " ", "X", "ENTER"], | ||
| 84 | [" ", "X", "X", " ", " ", " ", "MO(MOUSE)"] | ||
| 85 | ] | ||
| 86 | } | ||
| 87 | ] | ||
| 88 | }, | ||
| 89 | { | ||
| 90 | "name": "NUM", | ||
| 91 | "chords": [ | ||
| 92 | { | ||
| 93 | "type": "chord_set", | ||
| 94 | "set": "rows", | ||
| 95 | "keycodes": [ | ||
| 96 | "`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", | ||
| 97 | " ", " ", "LALT", "LCTL", "LSFT", "LGUI", "RGUI", "RSFT", "RCTL", "RALT", " ", " ", | ||
| 98 | " ", " ", " ", " ", " ", " ", " ", " ", " ", "[", "]", "=", | ||
| 99 | " ", " ", " ", " ", " ", " " | ||
| 100 | ] | ||
| 101 | } | ||
| 102 | ] | ||
| 103 | }, | ||
| 104 | { | ||
| 105 | "name": "FNC", | ||
| 106 | "chords": [ | ||
| 107 | { | ||
| 108 | "type": "chord_set", | ||
| 109 | "set": "rows", | ||
| 110 | "keycodes": [ | ||
| 111 | " ", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", | ||
| 112 | " ", " ", "LALT", "LCTL", "LSFT", "LGUI", "RGUI", "RSFT", "RCTL", "RALT", " ", " ", | ||
| 113 | " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "F12", | ||
| 114 | " ", " ", " ", " ", " ", " " | ||
| 115 | ] | ||
| 116 | } | ||
| 117 | ] | ||
| 118 | }, | ||
| 119 | { | ||
| 120 | "name": "NAV", | ||
| 121 | "chords": [ | ||
| 122 | { | ||
| 123 | "type": "chord_set", | ||
| 124 | "set": "rows", | ||
| 125 | "keycodes": [ | ||
| 126 | " ", " ", " ", " ", " ", " ", " ", "HOME", "UP", "END", "PGUP", " ", | ||
| 127 | " ", " ", "LALT", "LCTL", "LSFT", "LGUI", " ", " ", " ", " ", " ", " ", | ||
| 128 | " ", " ", " ", " ", " ", " ", " ", "LEFT", "DOWN", "RIGHT", "PGDN", " ", | ||
| 129 | " ", " ", " ", " ", " ", " " | ||
| 130 | ] | ||
| 131 | } | ||
| 132 | ] | ||
| 133 | }, | ||
| 134 | { | ||
| 135 | "name": "MOUSE", | ||
| 136 | "chords": [ | ||
| 137 | { | ||
| 138 | "type": "chord_set", | ||
| 139 | "set": "rows", | ||
| 140 | "keycodes": [ | ||
| 141 | " ", " ", " ", " ", " ", " ", " ", "BTN1", "MS_U", "BTN2", "WH_U", " ", | ||
| 142 | " ", " ", "LALT", "LCTL", "LSFT", "LGUI", " ", " ", " ", " ", " ", " ", | ||
| 143 | " ", " ", " ", " ", " ", " ", " ", "MS_L", "MS_D", "MS_R", "WH_D", " ", | ||
| 144 | " ", " ", " ", " ", " ", " " | ||
| 145 | ] | ||
| 146 | } | ||
| 147 | ] | ||
| 148 | } | ||
| 149 | ], | ||
| 150 | "leader_sequences": [], | ||
| 151 | "extra_code": "", | ||
| 152 | "extra_dependencies": [] | ||
| 153 | } \ No newline at end of file | ||
diff --git a/keyboards/georgi/keymaps/dennytom/rules.mk b/keyboards/georgi/keymaps/dennytom/rules.mk new file mode 100644 index 000000000..1155f72c0 --- /dev/null +++ b/keyboards/georgi/keymaps/dennytom/rules.mk | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | MOUSEKEY_ENABLE = yes | ||
| 2 | EXTRAKEY_ENABLE = yes | ||
| 3 | CONSOLE_ENABLE = no | ||
| 4 | # COMMAND_ENABLE = no | ||
| 5 | NKRO_ENABLE = yes | ||
| 6 | |||
| 7 | TMPVAR := $(SRC) | ||
| 8 | SRC = $(filter-out sten.c, $(TMPVAR)) \ No newline at end of file | ||
