Implement mouse movement acceleration and deceleration.
This commit is contained in:
@@ -82,53 +82,16 @@ static parser_error_t parsePlayMacroAction(key_action_t *keyAction, config_buffe
|
||||
|
||||
static parser_error_t parseMouseAction(key_action_t *keyAction, config_buffer_t *buffer)
|
||||
{
|
||||
uint8_t mouseAction = ReadUInt8(buffer);
|
||||
|
||||
keyAction->type = KeyActionType_Mouse;
|
||||
memset(&keyAction->mouse, 0, sizeof keyAction->mouse);
|
||||
switch (mouseAction) {
|
||||
case SerializedMouseAction_LeftClick:
|
||||
keyAction->mouse.buttonActions = MouseButton_Left;
|
||||
break;
|
||||
case SerializedMouseAction_MiddleClick:
|
||||
keyAction->mouse.buttonActions = MouseButton_Middle;
|
||||
break;
|
||||
case SerializedMouseAction_RightClick:
|
||||
keyAction->mouse.buttonActions = MouseButton_Right;
|
||||
break;
|
||||
case SerializedMouseAction_MoveUp:
|
||||
keyAction->mouse.moveActions = MouseMove_Up;
|
||||
break;
|
||||
case SerializedMouseAction_MoveDown:
|
||||
keyAction->mouse.moveActions = MouseMove_Down;
|
||||
break;
|
||||
case SerializedMouseAction_MoveLeft:
|
||||
keyAction->mouse.moveActions = MouseMove_Left;
|
||||
break;
|
||||
case SerializedMouseAction_MoveRight:
|
||||
keyAction->mouse.moveActions = MouseMove_Right;
|
||||
break;
|
||||
case SerializedMouseAction_ScrollUp:
|
||||
keyAction->mouse.scrollActions = MouseScroll_Up;
|
||||
break;
|
||||
case SerializedMouseAction_ScrollDown:
|
||||
keyAction->mouse.scrollActions = MouseScroll_Down;
|
||||
break;
|
||||
case SerializedMouseAction_ScrollLeft:
|
||||
keyAction->mouse.scrollActions = MouseScroll_Left;
|
||||
break;
|
||||
case SerializedMouseAction_ScrollRight:
|
||||
keyAction->mouse.scrollActions = MouseScroll_Right;
|
||||
break;
|
||||
case SerializedMouseAction_Accelerate:
|
||||
keyAction->mouse.speedActions = MouseSpeed_Accelerate;
|
||||
break;
|
||||
case SerializedMouseAction_Decelerate:
|
||||
keyAction->mouse.speedActions = MouseSpeed_Decelerate;
|
||||
break;
|
||||
default:
|
||||
|
||||
uint8_t mouseAction = ReadUInt8(buffer);
|
||||
if (mouseAction > SerializedMouseAction_Last) {
|
||||
return ParserError_InvalidSerializedMouseAction;
|
||||
}
|
||||
|
||||
memset(&keyAction->mouseAction, 0, sizeof keyAction->mouseAction);
|
||||
keyAction->mouseAction = mouseAction;
|
||||
|
||||
return ParserError_Success;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,10 @@
|
||||
SerializedMouseAction_ScrollRight,
|
||||
SerializedMouseAction_Accelerate,
|
||||
SerializedMouseAction_Decelerate,
|
||||
SerializedMouseAction_Last = SerializedMouseAction_Decelerate,
|
||||
SerializedMouseAction_Button_4,
|
||||
SerializedMouseAction_Button_5,
|
||||
SerializedMouseAction_Button_6,
|
||||
} serialized_mouse_action_t;
|
||||
|
||||
// Functions:
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "lufa/HIDClassCommon.h"
|
||||
#include "usb_composite_device.h"
|
||||
#include "module.h"
|
||||
#include "config_parser/parse_keymap.h"
|
||||
|
||||
// Typedefs:
|
||||
|
||||
@@ -36,25 +37,6 @@
|
||||
MouseButton_6 = 1 << 5,
|
||||
} mouse_button_t;
|
||||
|
||||
typedef enum {
|
||||
MouseMove_Up = 1 << 0,
|
||||
MouseMove_Down = 1 << 1,
|
||||
MouseMove_Left = 1 << 2,
|
||||
MouseMove_Right = 1 << 3,
|
||||
} mouse_move_action_t;
|
||||
|
||||
typedef enum {
|
||||
MouseSpeed_Accelerate = 1 << 0,
|
||||
MouseSpeed_Decelerate = 1 << 1,
|
||||
} mouse_speed_action_t;
|
||||
|
||||
typedef enum {
|
||||
MouseScroll_Up = 1 << 0,
|
||||
MouseScroll_Down = 1 << 1,
|
||||
MouseScroll_Left = 1 << 2,
|
||||
MouseScroll_Right = 1 << 3,
|
||||
} mouse_scroll_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
union {
|
||||
@@ -64,12 +46,7 @@
|
||||
uint8_t modifiers;
|
||||
uint16_t scancode;
|
||||
} ATTR_PACKED keystroke;
|
||||
struct {
|
||||
mouse_button_t buttonActions;
|
||||
mouse_scroll_t scrollActions;
|
||||
mouse_move_action_t moveActions;
|
||||
mouse_speed_action_t speedActions;
|
||||
} ATTR_PACKED mouse;
|
||||
serialized_mouse_action_t mouseAction;
|
||||
struct {
|
||||
bool isToggle;
|
||||
uint8_t layer;
|
||||
|
||||
@@ -332,23 +332,23 @@ key_action_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE] =
|
||||
{ .type = KeyActionType_None },
|
||||
|
||||
// Row 2
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_4 }},
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .moveActions = MouseMove_Up }},
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_5 }},
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_6 }},
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_Button_4 },
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_MoveUp },
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_Button_5 },
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_Button_6 },
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .scrollActions = MouseScroll_Up }},
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_ScrollUp },
|
||||
|
||||
// Row 3
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .moveActions = MouseMove_Left }},
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .moveActions = MouseMove_Down }},
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .moveActions = MouseMove_Right }},
|
||||
{ .type = KeyActionType_Mouse, .mouseAction= SerializedMouseAction_MoveLeft },
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_MoveDown },
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_MoveRight },
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .scrollActions = MouseScroll_Down }},
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_ScrollDown },
|
||||
|
||||
// Row 4
|
||||
{ .type = KeyActionType_None },
|
||||
@@ -391,9 +391,9 @@ key_action_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE] =
|
||||
// Row 3
|
||||
{ .type = KeyActionType_SwitchLayer, .switchLayer = { .layer = LayerId_Mouse }},
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_Right }},
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_Middle }},
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_Left }},
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_RightClick },
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_MiddleClick },
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_LeftClick },
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_None },
|
||||
|
||||
@@ -411,8 +411,8 @@ key_action_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE] =
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_GUI }},
|
||||
{ .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_ALT }},
|
||||
{ .type = KeyActionType_None },
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .speedActions = MouseSpeed_Decelerate }},
|
||||
{ .type = KeyActionType_Mouse, .mouse = { .speedActions = MouseSpeed_Accelerate }},
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_Decelerate },
|
||||
{ .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_Accelerate },
|
||||
{ .type = KeyActionType_None },
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "usb_report_updater.h"
|
||||
#include "timer.h"
|
||||
#include "key_debouncer.h"
|
||||
#include "config_parser/parse_keymap.h"
|
||||
|
||||
uint32_t UsbReportUpdateTime = 0;
|
||||
static uint32_t elapsedTime;
|
||||
@@ -29,7 +30,9 @@ static float mouseScrollSpeed = 0.1;
|
||||
static bool isMouseMoving;
|
||||
static bool wasMouseMoving;
|
||||
|
||||
void processMouseAction(key_action_t *action)
|
||||
static bool activeMouseStates[SerializedMouseAction_Last];
|
||||
|
||||
void processMouseActions()
|
||||
{
|
||||
static float mouseMoveCurrentSpeed;
|
||||
|
||||
@@ -37,18 +40,23 @@ void processMouseAction(key_action_t *action)
|
||||
mouseMoveCurrentSpeed = mouseMoveInitialSpeed;
|
||||
}
|
||||
|
||||
if (action->mouse.moveActions) {
|
||||
isMouseMoving = true;
|
||||
bool isMoveAction = activeMouseStates[SerializedMouseAction_MoveUp] ||
|
||||
activeMouseStates[SerializedMouseAction_MoveDown] ||
|
||||
activeMouseStates[SerializedMouseAction_MoveLeft] ||
|
||||
activeMouseStates[SerializedMouseAction_MoveRight];
|
||||
|
||||
float targetSpeed;
|
||||
if (action->mouse.speedActions & MouseSpeed_Accelerate) {
|
||||
if (activeMouseStates[SerializedMouseAction_Accelerate]) {
|
||||
targetSpeed = mouseMoveAcceleratedSpeed;
|
||||
} else if (action->mouse.speedActions & MouseSpeed_Decelerate) {
|
||||
} else if (activeMouseStates[SerializedMouseAction_Decelerate]) {
|
||||
targetSpeed = mouseMoveDeceleratedSpeed;
|
||||
} else {
|
||||
} else if (isMoveAction) {
|
||||
targetSpeed = mouseMoveBaseSpeed;
|
||||
}
|
||||
|
||||
if (isMoveAction) {
|
||||
isMouseMoving = true;
|
||||
|
||||
if (mouseMoveCurrentSpeed < targetSpeed) {
|
||||
mouseMoveCurrentSpeed += mouseMoveBaseAcceleration * elapsedTime / 1000;
|
||||
if (mouseMoveCurrentSpeed > targetSpeed) {
|
||||
@@ -63,35 +71,40 @@ void processMouseAction(key_action_t *action)
|
||||
|
||||
uint16_t distance = mouseMoveCurrentSpeed * elapsedTime / 10;
|
||||
|
||||
if (action->mouse.moveActions & MouseMove_Left) {
|
||||
if (activeMouseStates[SerializedMouseAction_MoveLeft]) {
|
||||
ActiveUsbMouseReport->x = -distance;
|
||||
} else if (action->mouse.moveActions & MouseMove_Right) {
|
||||
} else if (activeMouseStates[SerializedMouseAction_MoveRight]) {
|
||||
ActiveUsbMouseReport->x = distance;
|
||||
}
|
||||
|
||||
if (action->mouse.moveActions & MouseMove_Up) {
|
||||
if (activeMouseStates[SerializedMouseAction_MoveUp]) {
|
||||
ActiveUsbMouseReport->y = -distance;
|
||||
} else if (action->mouse.moveActions & MouseMove_Down) {
|
||||
} else if (activeMouseStates[SerializedMouseAction_MoveDown]) {
|
||||
ActiveUsbMouseReport->y = distance;
|
||||
}
|
||||
}
|
||||
|
||||
bool isScrollAction = activeMouseStates[SerializedMouseAction_ScrollUp] ||
|
||||
activeMouseStates[SerializedMouseAction_ScrollDown] ||
|
||||
activeMouseStates[SerializedMouseAction_ScrollLeft] ||
|
||||
activeMouseStates[SerializedMouseAction_ScrollRight];
|
||||
|
||||
static float mouseScrollDistanceSum = 0;
|
||||
if (action->mouse.scrollActions) {
|
||||
if (isScrollAction) {
|
||||
mouseScrollDistanceSum += mouseScrollSpeed;
|
||||
float mouseScrollDistanceIntegerSum;
|
||||
float mouseScrollDistanceFractionSum = modff(mouseScrollDistanceSum, &mouseScrollDistanceIntegerSum);
|
||||
|
||||
if (mouseScrollDistanceIntegerSum) {
|
||||
if (action->mouse.scrollActions & MouseScroll_Up) {
|
||||
if (activeMouseStates[SerializedMouseAction_ScrollUp]) {
|
||||
ActiveUsbMouseReport->wheelX = mouseScrollDistanceIntegerSum;
|
||||
} else if (action->mouse.scrollActions & MouseScroll_Down) {
|
||||
} else if (activeMouseStates[SerializedMouseAction_ScrollDown]) {
|
||||
ActiveUsbMouseReport->wheelX = -mouseScrollDistanceIntegerSum;
|
||||
}
|
||||
|
||||
if (action->mouse.scrollActions & MouseScroll_Right) {
|
||||
if (activeMouseStates[SerializedMouseAction_ScrollRight]) {
|
||||
ActiveUsbMouseReport->wheelY = mouseScrollDistanceIntegerSum;
|
||||
} else if (action->mouse.scrollActions & MouseScroll_Left) {
|
||||
} else if (activeMouseStates[SerializedMouseAction_ScrollLeft]) {
|
||||
ActiveUsbMouseReport->wheelY = -mouseScrollDistanceIntegerSum;
|
||||
}
|
||||
mouseScrollDistanceSum = mouseScrollDistanceFractionSum;
|
||||
@@ -100,7 +113,15 @@ void processMouseAction(key_action_t *action)
|
||||
mouseScrollDistanceSum = 0;
|
||||
}
|
||||
|
||||
ActiveUsbMouseReport->buttons |= action->mouse.buttonActions;
|
||||
if (activeMouseStates[SerializedMouseAction_LeftClick]) {
|
||||
ActiveUsbMouseReport->buttons |= MouseButton_Left;
|
||||
}
|
||||
if (activeMouseStates[SerializedMouseAction_MiddleClick]) {
|
||||
ActiveUsbMouseReport->buttons |= MouseButton_Middle;
|
||||
}
|
||||
if (activeMouseStates[SerializedMouseAction_RightClick]) {
|
||||
ActiveUsbMouseReport->buttons |= MouseButton_Right;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t basicScancodeIndex = 0;
|
||||
@@ -139,7 +160,7 @@ void applyKeyAction(key_state_t *keyState, key_action_t *action)
|
||||
}
|
||||
break;
|
||||
case KeyActionType_Mouse:
|
||||
processMouseAction(action);
|
||||
activeMouseStates[action->mouseAction] = true;
|
||||
break;
|
||||
case KeyActionType_SwitchKeymap:
|
||||
if (!keyState->previous && keyState->current) {
|
||||
@@ -157,6 +178,7 @@ static secondary_role_t secondaryRole;
|
||||
|
||||
void updateActiveUsbReports(void)
|
||||
{
|
||||
memset(activeMouseStates, 0, SerializedMouseAction_Last);
|
||||
wasMouseMoving = isMouseMoving;
|
||||
isMouseMoving = false;
|
||||
|
||||
@@ -243,6 +265,8 @@ void updateActiveUsbReports(void)
|
||||
}
|
||||
}
|
||||
|
||||
processMouseActions();
|
||||
|
||||
// When a layer switcher key gets pressed along with another key that produces some modifiers
|
||||
// and the accomanying key gets released then keep the related modifiers active a long as the
|
||||
// layer switcher key stays pressed. Useful for Alt+Tab keymappings and the like.
|
||||
|
||||
Reference in New Issue
Block a user