vial/combo: implement dynamic combos
This commit is contained in:
parent
8ccef55b3e
commit
26a9cb5749
@ -86,6 +86,7 @@ static pin_t encoders_pad_a[] = ENCODERS_PAD_A;
|
|||||||
#define VIAL_QMK_SETTINGS_SIZE 0
|
#define VIAL_QMK_SETTINGS_SIZE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Tap-dance
|
||||||
#define VIAL_TAP_DANCE_EEPROM_ADDR (VIAL_QMK_SETTINGS_EEPROM_ADDR + VIAL_QMK_SETTINGS_SIZE)
|
#define VIAL_TAP_DANCE_EEPROM_ADDR (VIAL_QMK_SETTINGS_EEPROM_ADDR + VIAL_QMK_SETTINGS_SIZE)
|
||||||
|
|
||||||
#ifdef VIAL_TAP_DANCE_ENABLE
|
#ifdef VIAL_TAP_DANCE_ENABLE
|
||||||
@ -94,9 +95,18 @@ static pin_t encoders_pad_a[] = ENCODERS_PAD_A;
|
|||||||
#define VIAL_TAP_DANCE_SIZE 0
|
#define VIAL_TAP_DANCE_SIZE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Dynamic macro starts after tap-dance
|
// Combos
|
||||||
|
#define VIAL_COMBO_EEPROM_ADDR (VIAL_TAP_DANCE_EEPROM_ADDR + VIAL_TAP_DANCE_SIZE)
|
||||||
|
|
||||||
|
#ifdef VIAL_COMBO_ENABLE
|
||||||
|
#define VIAL_COMBO_SIZE (sizeof(vial_combo_entry_t) * VIAL_COMBO_ENTRIES)
|
||||||
|
#else
|
||||||
|
#define VIAL_COMBO_SIZE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Dynamic macro
|
||||||
#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
|
#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
|
||||||
# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (VIAL_TAP_DANCE_EEPROM_ADDR + VIAL_TAP_DANCE_SIZE)
|
# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (VIAL_COMBO_EEPROM_ADDR + VIAL_COMBO_SIZE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Sanity check that dynamic keymaps fit in available EEPROM
|
// Sanity check that dynamic keymaps fit in available EEPROM
|
||||||
@ -104,7 +114,7 @@ static pin_t encoders_pad_a[] = ENCODERS_PAD_A;
|
|||||||
// The keyboard should override DYNAMIC_KEYMAP_LAYER_COUNT to reduce it,
|
// The keyboard should override DYNAMIC_KEYMAP_LAYER_COUNT to reduce it,
|
||||||
// or DYNAMIC_KEYMAP_EEPROM_MAX_ADDR to increase it, *only if* the microcontroller has
|
// or DYNAMIC_KEYMAP_EEPROM_MAX_ADDR to increase it, *only if* the microcontroller has
|
||||||
// more than the default.
|
// more than the default.
|
||||||
_Static_assert(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR - DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR >= 100, "Dynamic keymaps are configured to use more EEPROM than is available.");
|
_Static_assert(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR >= DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + 100, "Dynamic keymaps are configured to use more EEPROM than is available.");
|
||||||
|
|
||||||
// Dynamic macros are stored after the keymaps and use what is available
|
// Dynamic macros are stored after the keymaps and use what is available
|
||||||
// up to and including DYNAMIC_KEYMAP_EEPROM_MAX_ADDR.
|
// up to and including DYNAMIC_KEYMAP_EEPROM_MAX_ADDR.
|
||||||
@ -215,6 +225,28 @@ int dynamic_keymap_set_tap_dance(uint8_t index, const vial_tap_dance_entry_t *en
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef VIAL_COMBO_ENABLE
|
||||||
|
int dynamic_keymap_get_combo(uint8_t index, vial_combo_entry_t *entry) {
|
||||||
|
if (index >= VIAL_COMBO_ENTRIES)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
void *address = (void*)(VIAL_COMBO_EEPROM_ADDR + index * sizeof(vial_combo_entry_t));
|
||||||
|
eeprom_read_block(entry, address, sizeof(vial_combo_entry_t));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dynamic_keymap_set_combo(uint8_t index, const vial_combo_entry_t *entry) {
|
||||||
|
if (index >= VIAL_COMBO_ENTRIES)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
void *address = (void*)(VIAL_COMBO_EEPROM_ADDR + index * sizeof(vial_combo_entry_t));
|
||||||
|
eeprom_write_block(entry, address, sizeof(vial_combo_entry_t));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(VIAL_ENCODERS_ENABLE) && defined(VIAL_ENCODER_DEFAULT)
|
#if defined(VIAL_ENCODERS_ENABLE) && defined(VIAL_ENCODER_DEFAULT)
|
||||||
static const uint16_t PROGMEM vial_encoder_default[] = VIAL_ENCODER_DEFAULT;
|
static const uint16_t PROGMEM vial_encoder_default[] = VIAL_ENCODER_DEFAULT;
|
||||||
_Static_assert(sizeof(vial_encoder_default)/sizeof(*vial_encoder_default) == 2 * DYNAMIC_KEYMAP_LAYER_COUNT * NUMBER_OF_ENCODERS,
|
_Static_assert(sizeof(vial_encoder_default)/sizeof(*vial_encoder_default) == 2 * DYNAMIC_KEYMAP_LAYER_COUNT * NUMBER_OF_ENCODERS,
|
||||||
@ -262,6 +294,12 @@ void dynamic_keymap_reset(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef VIAL_COMBO_ENABLE
|
||||||
|
vial_combo_entry_t combo = { 0 };
|
||||||
|
for (size_t i = 0; i < VIAL_COMBO_ENTRIES; ++i)
|
||||||
|
dynamic_keymap_set_combo(i, &combo);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef VIAL_ENABLE
|
#ifdef VIAL_ENABLE
|
||||||
/* re-lock the keyboard */
|
/* re-lock the keyboard */
|
||||||
vial_unlocked = vial_unlocked_prev;
|
vial_unlocked = vial_unlocked_prev;
|
||||||
|
@ -38,6 +38,10 @@ void dynamic_keymap_set_qmk_settings(uint16_t offset, uint8_t value);
|
|||||||
int dynamic_keymap_get_tap_dance(uint8_t index, vial_tap_dance_entry_t *entry);
|
int dynamic_keymap_get_tap_dance(uint8_t index, vial_tap_dance_entry_t *entry);
|
||||||
int dynamic_keymap_set_tap_dance(uint8_t index, const vial_tap_dance_entry_t *entry);
|
int dynamic_keymap_set_tap_dance(uint8_t index, const vial_tap_dance_entry_t *entry);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef VIAL_COMBO_ENABLE
|
||||||
|
int dynamic_keymap_get_combo(uint8_t index, vial_combo_entry_t *entry);
|
||||||
|
int dynamic_keymap_set_combo(uint8_t index, const vial_combo_entry_t *entry);
|
||||||
|
#endif
|
||||||
void dynamic_keymap_reset(void);
|
void dynamic_keymap_reset(void);
|
||||||
// These get/set the keycodes as stored in the EEPROM buffer
|
// These get/set the keycodes as stored in the EEPROM buffer
|
||||||
// Data is big-endian 16-bit values (the keycodes)
|
// Data is big-endian 16-bit values (the keycodes)
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "process_combo.h"
|
#include "process_combo.h"
|
||||||
|
|
||||||
|
#ifdef VIAL_COMBO_ENABLE
|
||||||
|
#include "dynamic_keymap.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef COMBO_VARIABLE_LEN
|
#ifndef COMBO_VARIABLE_LEN
|
||||||
__attribute__((weak)) combo_t key_combos[COMBO_COUNT] = {};
|
__attribute__((weak)) combo_t key_combos[COMBO_COUNT] = {};
|
||||||
#else
|
#else
|
||||||
@ -84,12 +88,27 @@ static inline void dump_key_buffer(bool emit) {
|
|||||||
static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record) {
|
static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record) {
|
||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
uint16_t index = -1;
|
uint16_t index = -1;
|
||||||
|
#ifdef VIAL_COMBO_ENABLE
|
||||||
|
uint8_t combo_idx = (uintptr_t)combo->keys;
|
||||||
|
vial_combo_entry_t entry;
|
||||||
|
if (dynamic_keymap_get_combo(combo_idx, &entry) != 0)
|
||||||
|
return false;
|
||||||
|
for (count = 0; count < sizeof(entry.input)/sizeof(*entry.input); ++count) {
|
||||||
|
uint16_t key = entry.input[count];
|
||||||
|
if (key == KC_NO) break;
|
||||||
|
if (key == keycode) index = count;
|
||||||
|
}
|
||||||
|
/* must have at least 2 keys in the combo */
|
||||||
|
if (count < 2)
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
/* Find index of keycode and number of combo keys */
|
/* Find index of keycode and number of combo keys */
|
||||||
for (const uint16_t *keys = combo->keys;; ++count) {
|
for (const uint16_t *keys = combo->keys;; ++count) {
|
||||||
uint16_t key = pgm_read_word(&keys[count]);
|
uint16_t key = pgm_read_word(&keys[count]);
|
||||||
if (keycode == key) index = count;
|
if (keycode == key) index = count;
|
||||||
if (COMBO_END == key) break;
|
if (COMBO_END == key) break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Continue processing if not a combo key */
|
/* Continue processing if not a combo key */
|
||||||
if (-1 == (int8_t)index) return false;
|
if (-1 == (int8_t)index) return false;
|
||||||
|
@ -58,10 +58,17 @@ _Static_assert(sizeof(vial_unlock_combo_rows) == sizeof(vial_unlock_combo_cols),
|
|||||||
static void reload_tap_dance(void);
|
static void reload_tap_dance(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef VIAL_COMBO_ENABLE
|
||||||
|
static void init_combo(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
void vial_init(void) {
|
void vial_init(void) {
|
||||||
#ifdef VIAL_TAP_DANCE_ENABLE
|
#ifdef VIAL_TAP_DANCE_ENABLE
|
||||||
reload_tap_dance();
|
reload_tap_dance();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef VIAL_COMBO_ENABLE
|
||||||
|
init_combo();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void vial_handle_cmd(uint8_t *msg, uint8_t length) {
|
void vial_handle_cmd(uint8_t *msg, uint8_t length) {
|
||||||
@ -218,6 +225,20 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) {
|
|||||||
reload_tap_dance();
|
reload_tap_dance();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case dynamic_vial_combo_get: {
|
||||||
|
uint8_t idx = msg[3];
|
||||||
|
vial_combo_entry_t entry = { 0 };
|
||||||
|
msg[0] = dynamic_keymap_get_combo(idx, &entry);
|
||||||
|
memcpy(&msg[1], &entry, sizeof(entry));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case dynamic_vial_combo_set: {
|
||||||
|
uint8_t idx = msg[3];
|
||||||
|
vial_combo_entry_t entry;
|
||||||
|
memcpy(&entry, &msg[4], sizeof(entry));
|
||||||
|
msg[0] = dynamic_keymap_set_combo(idx, &entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -462,15 +483,23 @@ static void reload_tap_dance(void) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VIAL_COMBO_ENABLE
|
#ifdef VIAL_COMBO_ENABLE
|
||||||
const uint16_t PROGMEM test_combo[] = {KC_X, KC_Z, COMBO_END};
|
combo_t key_combos[VIAL_COMBO_ENTRIES];
|
||||||
combo_t key_combos[COMBO_COUNT] = {COMBO_ACTION(test_combo)};
|
|
||||||
|
static void init_combo(void) {
|
||||||
|
for (size_t i = 0; i < VIAL_COMBO_ENTRIES; ++i) {
|
||||||
|
key_combos[i].keys = (void*)(uintptr_t)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void process_combo_event(uint16_t combo_index, bool pressed) {
|
void process_combo_event(uint16_t combo_index, bool pressed) {
|
||||||
uprintf("combo event %d\n", combo_index);
|
vial_combo_entry_t entry;
|
||||||
|
if (dynamic_keymap_get_combo(combo_index, &entry) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (pressed)
|
if (pressed)
|
||||||
vial_keycode_down(0x5F12);
|
vial_keycode_down(entry.output);
|
||||||
else
|
else
|
||||||
vial_keycode_up(0x5F12);
|
vial_keycode_up(entry.output);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,6 +52,8 @@ enum {
|
|||||||
dynamic_vial_get_number_of_entries = 0x00,
|
dynamic_vial_get_number_of_entries = 0x00,
|
||||||
dynamic_vial_tap_dance_get = 0x01,
|
dynamic_vial_tap_dance_get = 0x01,
|
||||||
dynamic_vial_tap_dance_set = 0x02,
|
dynamic_vial_tap_dance_set = 0x02,
|
||||||
|
dynamic_vial_combo_get = 0x03,
|
||||||
|
dynamic_vial_combo_set = 0x04,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Fake position in keyboard matrix, can't use 255 as that is immediately rejected by IS_NOEVENT
|
/* Fake position in keyboard matrix, can't use 255 as that is immediately rejected by IS_NOEVENT
|
||||||
@ -87,6 +89,12 @@ _Static_assert(sizeof(vial_tap_dance_entry_t) == 10, "Unexpected size of the via
|
|||||||
#define VIAL_COMBO_ENTRIES 16
|
#define VIAL_COMBO_ENTRIES 16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t input[4];
|
||||||
|
uint16_t output;
|
||||||
|
} vial_combo_entry_t;
|
||||||
|
_Static_assert(sizeof(vial_combo_entry_t) == 10, "Unexpected size of the vial_combo_entry_t structure");
|
||||||
|
|
||||||
/* also to catch wrong include order in e.g. process_combo.h */
|
/* also to catch wrong include order in e.g. process_combo.h */
|
||||||
#ifdef COMBO_COUNT
|
#ifdef COMBO_COUNT
|
||||||
#error COMBO_COUNT redefined - define VIAL_COMBO_ENTRIES instead
|
#error COMBO_COUNT redefined - define VIAL_COMBO_ENTRIES instead
|
||||||
|
Loading…
x
Reference in New Issue
Block a user