Implement mouse movement acceleration and deceleration.

This commit is contained in:
László Monda
2017-11-24 13:00:05 +01:00
parent 0cb3c7e0ad
commit 210ef31f27
5 changed files with 74 additions and 106 deletions

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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;

View File

@@ -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 },
}
},

View File

@@ -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.