Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use unsigned integer for kinetic speed #21151

Merged
merged 1 commit into from
Jun 7, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Use unsigned integer for kinetic speed
The current kinetic mouse key function uses resource intensive
floating point to compute the quadratic curve speed. But the
result is returned as an unsigned 8-bit integer value. The code
line where fractional accuracy is important is at the division of
`speed = (uint8_t)(speed / (1000.0f / mk_interval));`

This change uses 16-bit integers for the quadratic calculation
variables, which are less resource-intensive. The output acceleration
curve is almost unchanged with the default `MOUSEKEY_INTERVAL` value.

Truncation is used to round division output to an integer. With
higher `MOUSEKEY_INTERVAL` values, rounding appears more accurate
using 16-bit integer versus floating point. Example:

`mk_interval = 30`

| speed | (uint8_t)(speed / (1000.0f / mk_interval)) | (uint8_t)(speed / (1000U / mk_interval)) |
|------|----|----|
|  292 |  8 |  9 |
|  484 | 14 | 15 |
| 1060 | 31 | 32 |
| 1660 | 49 | 50 |
  • Loading branch information
filterpaper committed Jun 7, 2023
commit 1b2b20988d335ac1580a456a9c35de72d40d57cd
18 changes: 9 additions & 9 deletions quantum/mousekey.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ uint8_t mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
uint8_t mk_wheel_delay = MOUSEKEY_WHEEL_DELAY / 10;
/* milliseconds between repeated motion events (0-255) */
# ifdef MK_KINETIC_SPEED
float mk_wheel_interval = 1000.0f / MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
uint16_t mk_wheel_interval = 1000U / MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
# else
uint8_t mk_wheel_interval = MOUSEKEY_WHEEL_INTERVAL;
# endif
Expand Down Expand Up @@ -190,37 +190,37 @@ const uint16_t mk_decelerated_speed = MOUSEKEY_DECELERATED_SPEED;
const uint16_t mk_initial_speed = MOUSEKEY_INITIAL_SPEED;

static uint8_t move_unit(void) {
float speed = mk_initial_speed;
uint16_t speed = mk_initial_speed;

if (mousekey_accel & ((1 << 0) | (1 << 2))) {
speed = mousekey_accel & (1 << 2) ? mk_accelerated_speed : mk_decelerated_speed;
} else if (mousekey_repeat && mouse_timer) {
const float time_elapsed = timer_elapsed(mouse_timer) / 50;
speed = mk_initial_speed + MOUSEKEY_MOVE_DELTA * time_elapsed + MOUSEKEY_MOVE_DELTA * 0.5 * time_elapsed * time_elapsed;
const uint16_t time_elapsed = timer_elapsed(mouse_timer) / 50;
speed = mk_initial_speed + MOUSEKEY_MOVE_DELTA * time_elapsed + MOUSEKEY_MOVE_DELTA * 0.5 * time_elapsed * time_elapsed;

speed = speed > mk_base_speed ? mk_base_speed : speed;
}

/* convert speed to USB mouse speed 1 to 127 */
speed = (uint8_t)(speed / (1000.0f / mk_interval));
speed = (uint8_t)(speed / (1000U / mk_interval));
speed = speed < 1 ? 1 : speed;

return speed > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : speed;
}

static uint8_t wheel_unit(void) {
float speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
uint16_t speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;

if (mousekey_accel & ((1 << 0) | (1 << 2))) {
speed = mousekey_accel & (1 << 2) ? MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS : MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS;
} else if (mousekey_wheel_repeat && mouse_timer) {
if (mk_wheel_interval != MOUSEKEY_WHEEL_BASE_MOVEMENTS) {
const float time_elapsed = timer_elapsed(mouse_timer) / 50;
speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS + 1 * time_elapsed + 1 * 0.5 * time_elapsed * time_elapsed;
const uint16_t time_elapsed = timer_elapsed(mouse_timer) / 50;
speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS + 1 * time_elapsed + 1 * 0.5 * time_elapsed * time_elapsed;
}
speed = speed > MOUSEKEY_WHEEL_BASE_MOVEMENTS ? MOUSEKEY_WHEEL_BASE_MOVEMENTS : speed;
}
mk_wheel_interval = 1000.0f / speed;
mk_wheel_interval = 1000U / speed;

return (uint8_t)speed > MOUSEKEY_WHEEL_INITIAL_MOVEMENTS ? 2 : 1;
}
Expand Down