Skip to content

Commit

Permalink
Extended macro engine.
Browse files Browse the repository at this point in the history
  • Loading branch information
kareltucek committed Aug 12, 2021
1 parent 9461a23 commit 7d957f2
Show file tree
Hide file tree
Showing 35 changed files with 5,071 additions and 319 deletions.
593 changes: 593 additions & 0 deletions MACRO_DOCS.md

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,18 @@ Going forward, it's easier to flash the firmware of your choice by using the dow

5. When developing, cd to the directory you're working on (`left`/`right`). To build and flash the firmware, run `make flash`. Plain `make` just builds without flashing.


### Releasing

6. To build a full firmware tarball:
1. Run `npm install` in `scripts`.
2. Run `scripts/make-release.js`.
3. Now, the created tarball `scripts/uhk-firmware-VERSION.tar.gz` can be flashed with UHK Agent.

### Extended macro engine

To build with extended macro engine, use `make CUSTOM_CFLAGS=-DEXTENDED_MACROS` or `scripts/make-release.js --extendedMacros`. For usage, see [MACRO_DOCS.md](MACRO_DOCS.md).

## Contributing

Want to contribute? Let us show you [how](/CONTRIBUTING.md).
Expand Down
63 changes: 63 additions & 0 deletions right/src/config_parser/parse_macro.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "parse_macro.h"
#include "config_globals.h"
#include "str_utils.h"
#include "macros.h"

parser_error_t parseKeyMacroAction(config_buffer_t *buffer, macro_action_t *macroAction, serialized_macro_action_type_t macroActionType)
Expand All @@ -22,6 +23,7 @@ parser_error_t parseKeyMacroAction(config_buffer_t *buffer, macro_action_t *macr
macroAction->key.type = type;
macroAction->key.scancode = scancode;
macroAction->key.modifierMask = modifierMask;
macroAction->key.sticky = false;
return ParserError_Success;
}

Expand Down Expand Up @@ -75,6 +77,37 @@ parser_error_t parseTextMacroAction(config_buffer_t *buffer, macro_action_t *mac
macroAction->type = MacroActionType_Text;
macroAction->text.text = text;
macroAction->text.textLen = textLen;

return ParserError_Success;
}

uint8_t countCommands(macro_action_t *macroAction)
{
uint8_t count = 0;
const char* text = macroAction->cmd.text;
const char* textEnd = macroAction->cmd.text + macroAction->cmd.textLen;

while (true) {
if (text == textEnd) {
return count;
}
if (*text > 32) {
count++;
}
text = NextCmd(text, textEnd);
}
}

parser_error_t parseCommandMacroAction(config_buffer_t *buffer, macro_action_t *macroAction)
{
uint16_t textLen;
const char *text = ReadString(buffer, &textLen);

macroAction->type = MacroActionType_Command;
macroAction->cmd.text = text;
macroAction->cmd.textLen = textLen;
macroAction->cmd.cmdCount = countCommands(macroAction);

return ParserError_Success;
}

Expand All @@ -95,19 +128,48 @@ parser_error_t ParseMacroAction(config_buffer_t *buffer, macro_action_t *macroAc
return parseDelayMacroAction(buffer, macroAction);
case SerializedMacroActionType_TextMacroAction:
return parseTextMacroAction(buffer, macroAction);
case SerializedMacroActionType_CommandMacroAction:
return parseCommandMacroAction(buffer, macroAction);
}
return ParserError_InvalidSerializedMacroActionType;
}

void FindMacroName(const macro_reference_t* macro, const char** name, const char** nameEnd)
{
uint16_t nameLen;
config_buffer_t buffer = ValidatedUserConfigBuffer;
buffer.offset = macro->firstMacroActionOffset - macro->macroNameOffset;
*name = ReadString(&buffer, &nameLen);
*nameEnd = *name + nameLen;
}

uint8_t FindMacroIndexByName(const char* name, const char* nameEnd, bool reportIfFailed)
{
for (int i = 0; i < AllMacrosCount; i++) {
const char *thisName, *thisNameEnd;
FindMacroName(&AllMacros[i], &thisName, &thisNameEnd);
if(StrEqual(name, nameEnd, thisName, thisNameEnd)) {
return i;
}
}
if (reportIfFailed) {
Macros_ReportError("Macro name not found", name, nameEnd);
}
return 255;
}


parser_error_t ParseMacro(config_buffer_t *buffer, uint8_t macroIdx)
{
parser_error_t errorCode;
uint16_t nameLen;
bool isLooped = ReadBool(buffer);
bool isPrivate = ReadBool(buffer);
uint16_t nameOffset = buffer->offset;
const char *name = ReadString(buffer, &nameLen);
uint16_t macroActionsCount = ReadCompactLength(buffer);
uint16_t firstMacroActionOffset = buffer->offset;
uint16_t relativeNameOffset = firstMacroActionOffset - nameOffset;
macro_action_t dummyMacroAction;

(void)isLooped;
Expand All @@ -116,6 +178,7 @@ parser_error_t ParseMacro(config_buffer_t *buffer, uint8_t macroIdx)
if (!ParserRunDry) {
AllMacros[macroIdx].firstMacroActionOffset = firstMacroActionOffset;
AllMacros[macroIdx].macroActionsCount = macroActionsCount;
AllMacros[macroIdx].macroNameOffset = relativeNameOffset;
}
for (uint16_t i = 0; i < macroActionsCount; i++) {
errorCode = ParseMacroAction(buffer, &dummyMacroAction);
Expand Down
6 changes: 5 additions & 1 deletion right/src/config_parser/parse_macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@
SerializedMacroActionType_MoveMouseMacroAction,
SerializedMacroActionType_ScrollMouseMacroAction,
SerializedMacroActionType_DelayMacroAction,
SerializedMacroActionType_TextMacroAction
SerializedMacroActionType_TextMacroAction,
SerializedMacroActionType_CommandMacroAction
} serialized_macro_action_type_t;

// Functions:

parser_error_t ParseMacroAction(config_buffer_t *buffer, macro_action_t *macroAction);
parser_error_t ParseMacro(config_buffer_t *buffer, uint8_t macroIdx);

uint8_t FindMacroIndexByName(const char* name, const char* nameEnd, bool reportIfFailed);
void FindMacroName(const macro_reference_t* macro, const char** name, const char** nameEnd);

#endif
47 changes: 44 additions & 3 deletions right/src/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,23 @@
#include "led_display.h"
#include "timer.h"
#include "key_states.h"
#include <limits.h>

uint8_t CurrentWatch = 0;

static uint32_t lastWatch = 0;
static uint32_t watchInterval = 500;

static void ShowNumberExp(int32_t a)
static void printReport(usb_basic_keyboard_report_t *report)
{
Macros_SetStatusNum(report->modifiers);
for (int i = 0; i < 6; i++) {
Macros_SetStatusNum(report->scancodes[i]);
}
Macros_SetStatusString("\n", NULL);
}

void ShowNumberExp(int32_t a)
{
char b[3];
int mag = 0;
Expand All @@ -30,7 +40,7 @@ static void ShowNumberExp(int32_t a)
}
b[0] = '0' + num / 10;
b[1] = '0' + num % 10;
b[2] = mag == 0 ? '0' : ('A' - 1 + mag);
b[2] = mag == 0 ? '0' : ('A' - 2 + mag);
}
LedDisplay_SetText(3, b);
}
Expand Down Expand Up @@ -67,9 +77,40 @@ void WatchValue(int v, uint8_t n)
void WatchString(char const *v, uint8_t n)
{
if (CurrentTime - lastWatch > watchInterval) {
LedDisplay_SetText(3, v);
LedDisplay_SetText(strlen(v), v);
lastWatch = CurrentTime;
}
}

void WatchValueMin(int v, uint8_t n)
{
static int m = 0;

if (v < m) {
m = v;
}

if (CurrentTime - lastWatch > watchInterval) {
ShowNumberExp(m);
lastWatch = CurrentTime;
m = INT_MAX;
}
}

void WatchValueMax(int v, uint8_t n)
{
static int m = 0;

if (v > m) {
m = v;
}

if (CurrentTime - lastWatch > watchInterval) {
ShowNumberExp(m);
lastWatch = CurrentTime;
m = INT_MIN;
}
}


#endif
51 changes: 27 additions & 24 deletions right/src/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,23 @@

// Macros:

// This hook is to be placed in usb_report_updater and to be called whenever a key is activated (i.e., on key-down event).
#define WATCH_TRIGGER(STATE) TriggerWatch(STATE);

// When placed into the code, time between calls to this macro is being watched in slot N.
#define WATCH_TIME(N) \
if (CurrentWatch == N) { \
WatchTime(N); \
}

// Watches value V in slot N.
#define WATCH_VALUE(V, N) \
if (CurrentWatch == N) { \
WatchValue(V, N); \
}

// Watches string V in slot N.
#define WATCH_STRING(V, N) \
if (CurrentWatch == N) { \
WatchString(V, N); \
}
// This hook is to be placed in usb_report_updater and to be called whenever a key is activated (i.e., on key-down event).
#define WATCH_TRIGGER(STATE) TriggerWatch(STATE);

// When placed into the code, time between calls to this macro is being watched in slot N.
#define WATCH_TIME(N) if(CurrentWatch == N) { WatchTime(N); }

// Watches value V in slot N.
#define WATCH_VALUE(V, N) if(CurrentWatch == N) { WatchValue(V, N); }

// Watches value V in slot N.
#define WATCH_VALUE_MIN(V, N) if(CurrentWatch == N) { WatchValueMin(V, N); }

// Watches value V in slot N.
#define WATCH_VALUE_MAX(V, N) if(CurrentWatch == N) { WatchValueMax(V, N); }

// Watches string V in slot N.
#define WATCH_STRING(V, N) if(CurrentWatch == N) { WatchString(V, N); }

// Variables:

Expand All @@ -47,15 +44,21 @@
void TriggerWatch(key_state_t *keyState);
void WatchTime(uint8_t n);
void WatchValue(int v, uint8_t n);
void WatchString(char const *v, uint8_t n);
void WatchValueMin(int v, uint8_t n);
void WatchValueMax(int v, uint8_t n);
void WatchString(char const * v, uint8_t n);
void ShowNumberExp(int32_t a);

#endif /* SRC_UTILS_DBG_H_ */
#else

// Macros:

#define WATCH_TRIGGER(N)
#define WATCH_TIME(N)
#define WATCH_VALUE(V, N)
#define WATCH_TRIGGER(N)
#define WATCH_TIME(N)
#define WATCH_VALUE(V, N)
#define WATCH_VALUE_MIN(V, N)
#define WATCH_VALUE_MAX(V, N)
#define WATCH_STRING(V, N)

#endif
21 changes: 16 additions & 5 deletions right/src/keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "config_parser/parse_keymap.h"
#include "config_parser/config_globals.h"
#include "macros.h"
#include "macro_events.h"

keymap_reference_t AllKeymaps[MAX_KEYMAP_NUM] = {
{
Expand All @@ -26,18 +27,28 @@ void SwitchKeymapById(uint8_t index)
ParseKeymap(&ValidatedUserConfigBuffer, index, AllKeymapsCount, AllMacrosCount);
LedDisplay_UpdateText();
UpdateLayerLeds();
MacroEvent_OnKeymapChange(index);
}

bool SwitchKeymapByAbbreviation(uint8_t length, char *abbrev)
{
uint8_t FindKeymapByAbbreviation(uint8_t length, const char *abbrev) {
for (uint8_t i=0; i<AllKeymapsCount; i++) {
keymap_reference_t *keymap = AllKeymaps + i;
if (keymap->abbreviationLen == length && memcmp(keymap->abbreviation, abbrev, length) == 0) {
SwitchKeymapById(i);
return true;
return i;
}
}
return false;
return 0xFF;
}

bool SwitchKeymapByAbbreviation(uint8_t length, const char *abbrev)
{
uint8_t keymapId = FindKeymapByAbbreviation(length, abbrev);

if (keymapId != 0xFF) {
return true;
} else {
return false;
}
}

// The factory keymap is initialized before it gets overwritten by the default keymap of the EEPROM.
Expand Down
3 changes: 2 additions & 1 deletion right/src/keymap.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
// Functions:

void SwitchKeymapById(uint8_t index);
bool SwitchKeymapByAbbreviation(uint8_t length, char *abbrev);
bool SwitchKeymapByAbbreviation(uint8_t length, const char *abbrev);
uint8_t FindKeymapByAbbreviation(uint8_t length, const char *abbrev);

#endif
17 changes: 16 additions & 1 deletion right/src/layer_switcher.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "layer_switcher.h"
#include "ledmap.h"
#include "timer.h"
#include "macros.h"

static uint16_t DoubleTapSwitchLayerTimeout = 300;
static uint16_t DoubleTapSwitchLayerReleaseTimeout = 200;
Expand Down Expand Up @@ -42,15 +43,22 @@ static layer_id_t heldLayer = LayerId_Base;
// Recompute active layer whenever state of the layer locks changes.
void updateActiveLayer() {
layer_id_t activeLayer = LayerId_Base;
layer_id_t activeLayerHeld = LayerId_Base;
if(activeLayer == LayerId_Base) {
activeLayer = toggledLayer;
}
if(activeLayer == LayerId_Base) {
activeLayer = heldLayer;
}
activeLayerHeld = heldLayer == ActiveLayer && ActiveLayer != LayerId_Base;

if(activeLayer == LayerId_Base) {
activeLayer = Macros_ActiveLayer;
activeLayerHeld = Macros_ActiveLayer;
}
//(write actual ActiveLayer atomically, so that random observer is not confused)
ActiveLayer = activeLayer;
ActiveLayerHeld = heldLayer == ActiveLayer && ActiveLayer != LayerId_Base;
ActiveLayerHeld = activeLayerHeld;
UpdateLayerLeds();
}

Expand Down Expand Up @@ -163,3 +171,10 @@ void LayerSwitcher_UpdateActiveLayer() {
updateActiveLayer();
}
}

/**
* Fork extensions:
*/
void LayerSwitcher_RecalculateLayerComposition() {
updateActiveLayer();
}
2 changes: 2 additions & 0 deletions right/src/layer_switcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@

void LayerSwitcher_UpdateActiveLayer();

void LayerSwitcher_RecalculateLayerComposition();

#endif /* SRC_LAYER_SWITCHER_H_ */
Loading

0 comments on commit 7d957f2

Please sign in to comment.