Skip to content

Commit

Permalink
Merge pull request qmk#4 from ankostis/macreview
Browse files Browse the repository at this point in the history
various code style and documentation improvements
  • Loading branch information
burkfers authored Mar 4, 2024
2 parents 33397b6 + ff9aec8 commit c863145
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 42 deletions.
78 changes: 39 additions & 39 deletions maccel/maccel.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static uint32_t maccel_timer;
# define MACCEL_LIMIT 6.0 // upper limit of accel curve (maximum acceleration factor)
#endif
#ifndef MACCEL_CPI_THROTTLE_MS
# define MACCEL_CPI_THROTTLE_MS 200 // milliseconds to wait between requesting the device's current DPI
# define MACCEL_CPI_THROTTLE_MS 200 // milliseconds to wait between requesting the device's current DPI
#endif

maccel_config_t g_maccel_config = {
Expand Down Expand Up @@ -56,7 +56,7 @@ float maccel_get_growth_rate(void) {
return g_maccel_config.growth_rate;
}
float maccel_get_offset(void) {
return g_maccel_config.limit;
return g_maccel_config.offset;
}
float maccel_get_limit(void) {
return g_maccel_config.limit;
Expand All @@ -72,7 +72,7 @@ void maccel_set_growth_rate(float val) {
}
}
void maccel_set_offset(float val) {
g_maccel_config.limit = val;
g_maccel_config.offset = val;
}
void maccel_set_limit(float val) {
if (val >= 1) { // limit less than 1 leads to nonsensical results
Expand All @@ -97,43 +97,43 @@ void maccel_toggle_enabled(void) {
#define CONSTRAIN_REPORT(val) (mouse_xy_report_t) _CONSTRAIN(val, XY_REPORT_MIN, XY_REPORT_MAX)

report_mouse_t pointing_device_task_maccel(report_mouse_t mouse_report) {
if (mouse_report.x != 0 || mouse_report.y != 0) {
if (!g_maccel_config.enabled) { // do nothing if not enabled
return mouse_report;
}
// time since last mouse report:
const uint16_t delta_time = timer_elapsed32(maccel_timer);
maccel_timer = timer_read32();
// get device cpi setting, only call when mouse hasn't moved since more than 200ms
static uint16_t device_cpi = 300;
if (delta_time > MACCEL_CPI_THROTTLE_MS) {
device_cpi = pointing_device_get_cpi();
}
// calculate dpi correction factor (for normalizing velocity range across different user dpi settings)
const float dpi_correction = (float)1000.0f / device_cpi;
// calculate euclidean distance moved (sqrt(x^2 + y^2))
const float distance = sqrtf(mouse_report.x * mouse_report.x + mouse_report.y * mouse_report.y);
// calculate delta velocity: dv = distance/dt
const float velocity_raw = distance / delta_time;
// correct raw velocity for dpi
const float velocity = dpi_correction * velocity_raw;
// calculate mouse acceleration factor: f(dv) = c - ((c-1) / ((1 + e^(x(x - b)) * a/z)))
const float maccel_factor = g_maccel_config.limit - (g_maccel_config.limit - 1) / powf(1 + expf(g_maccel_config.takeoff * (velocity - g_maccel_config.limit)), g_maccel_config.growth_rate / g_maccel_config.takeoff);
// calculate accelerated delta X and Y values and clamp:
const mouse_xy_report_t x = CONSTRAIN_REPORT(mouse_report.x * maccel_factor);
const mouse_xy_report_t y = CONSTRAIN_REPORT(mouse_report.y * maccel_factor);
if ((mouse_report.x == 0 && mouse_report.y == 0) || !g_maccel_config.enabled) {
return mouse_report;
}

// time since last mouse report:
const uint16_t delta_time = timer_elapsed32(maccel_timer);
maccel_timer = timer_read32();
// get device cpi setting, only call when mouse hasn't moved since more than 200ms
static uint16_t device_cpi = 300;
if (delta_time > MACCEL_CPI_THROTTLE_MS) {
device_cpi = pointing_device_get_cpi();
}
// calculate dpi correction factor (for normalizing velocity range across different user dpi settings)
const float dpi_correction = (float)1000.0f / device_cpi;
// calculate euclidean distance moved (sqrt(x^2 + y^2))
const float distance = sqrtf(mouse_report.x * mouse_report.x + mouse_report.y * mouse_report.y);
// calculate delta velocity: dv = distance/dt
const float velocity_raw = distance / delta_time;
// correct raw velocity for dpi
const float velocity = dpi_correction * velocity_raw;
// calculate mouse acceleration factor: f(dv) = c - ((c-1) / ((1 + e^(x(x - b)) * a/z)))
const float maccel_factor = g_maccel_config.limit - (g_maccel_config.limit - 1) / powf(1 + expf(g_maccel_config.takeoff * (velocity - g_maccel_config.limit)), g_maccel_config.growth_rate / g_maccel_config.takeoff);
// calculate accelerated delta X and Y values and clamp:
const mouse_xy_report_t x = CONSTRAIN_REPORT(mouse_report.x * maccel_factor);
const mouse_xy_report_t y = CONSTRAIN_REPORT(mouse_report.y * maccel_factor);

// console output for debugging (enable/disable in config.h)
#ifdef MACCEL_DEBUG
const float distance_out = sqrtf(x * x + y * y);
const float velocity_out = velocity * maccel_factor;
printf("MACCEL: DPI:%4i Tko: %.3f Grw: %.3f Ofs: %.3f Lmt: %.3f | Fct: %.3f v.in: %.3f v.out: %.3f d.in: %3i d.out: %3i\n", device_cpi, g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit, maccel_factor, velocity, velocity_out, CONSTRAIN_REPORT(distance), CONSTRAIN_REPORT(distance_out));
const float distance_out = sqrtf(x * x + y * y);
const float velocity_out = velocity * maccel_factor;
printf("MACCEL: DPI:%4i Tko: %.3f Grw: %.3f Ofs: %.3f Lmt: %.3f | Fct: %.3f v.in: %.3f v.out: %.3f d.in: %3i d.out: %3i\n", device_cpi, g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit, maccel_factor, velocity, velocity_out, CONSTRAIN_REPORT(distance), CONSTRAIN_REPORT(distance_out));
#endif // MACCEL_DEBUG

// report back accelerated values
mouse_report.x = x;
mouse_report.y = y;
}
// report back accelerated values
mouse_report.x = x;
mouse_report.y = y;

return mouse_report;
}

Expand All @@ -153,22 +153,22 @@ bool process_record_maccel(uint16_t keycode, keyrecord_t *record, uint16_t takeo
if (record->event.pressed) {
if (keycode == takeoff) {
maccel_set_takeoff(maccel_get_takeoff() + get_mod_step(MACCEL_TAKEOFF_STEP));
printf("MACCEL:keycode: TKO: %.3f gro: %.3f ofs: %.3f lmt: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.limit, g_maccel_config.limit);
printf("MACCEL:keycode: TKO: %.3f gro: %.3f ofs: %.3f lmt: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit);
return false;
}
if (keycode == growth_rate) {
maccel_set_growth_rate(maccel_get_growth_rate() + get_mod_step(MACCEL_GROWTH_RATE_STEP));
printf("MACCEL:keycode: tko: %.3f GRO: %.3f ofs: %.3f lmt: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.limit, g_maccel_config.limit);
printf("MACCEL:keycode: tko: %.3f GRO: %.3f ofs: %.3f lmt: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit);
return false;
}
if (keycode == offset) {
maccel_set_offset(maccel_get_offset() + get_mod_step(MACCEL_OFFSET_STEP));
printf("MACCEL:keycode: tko: %.3f gro: %.3f OFS: %.3f lmt: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.limit, g_maccel_config.limit);
printf("MACCEL:keycode: tko: %.3f gro: %.3f OFS: %.3f lmt: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit);
return false;
}
if (keycode == limit) {
maccel_set_limit(maccel_get_limit() + get_mod_step(MACCEL_LIMIT_STEP));
printf("MACCEL:keycode: tko: %.3f gro: %.3f ofs: %.3f LMT: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.limit, g_maccel_config.limit);
printf("MACCEL:keycode: tko: %.3f gro: %.3f ofs: %.3f LMT: %.3f\n", g_maccel_config.takeoff, g_maccel_config.growth_rate, g_maccel_config.offset, g_maccel_config.limit);
return false;
}
}
Expand Down
15 changes: 12 additions & 3 deletions maccel/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Continue with "Installation (common)", below.

### Installation (common)

Add to `pointing_device_task_user` in `keymap.c` or your userspace source file (paste the whole function if it did not exist):
Make sure the `pointing_device_task_user()` function in your `keymap.c` or userspace-sources exists, and contains the following code:
```c
report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
// ...
Expand All @@ -72,7 +72,7 @@ See the section on runtime adjusting by keycodes and on via support for installa
## Configuration
This accel curve works in opposite direction from what you may be used to from other acceleration tools, due to technical limitations in QMK. It scales pointer sensitivity upwards rather than downwards, which means you will have to lower your device DPI setting from what you'd normally do.
This accel curve works in opposite direction from what you may be used to from other acceleration tools, due to technical limitations in QMK. It scales pointer sensitivity upwards rather than downwards, which means you will either have to lower your device DPI setting from what you'd normally do, or lower your mouse speed in your operating system's settings, or both.
Several characteristics of the acceleration curve can be tweaked by adding relevant defines to `config.h`:
```c
Expand Down Expand Up @@ -109,6 +109,15 @@ To aid in dialing in your settings just right, a debug mode exists to print math
The debug console will print your current DPI setting and variable settings, as well as the acceleration factor, the input and output velocity, and the input and output distance.
Finally, linearity across diferrent user-CPI settings works better when pointer task throttling
is enforced, ie. add something like this in your `config.h`:
```c
// Fixed pointer-task frequency needed for consistent acceleration across different user CPIs.
#undef POINTING_DEVICE_TASK_THROTTLE_MS
#define POINTING_DEVICE_TASK_THROTTLE_MS 5
```

## Runtime adjusting of curve parameters by keycodes (optional)

### Additional required installation steps
Expand Down Expand Up @@ -207,7 +216,7 @@ Extend its `menus` configuration by placing the [menu definition](assets/via.jso
- [Dilemma v2](assets/dilemma_v2.json)
- [Dilemma Max](assets/dilemma_max.json)
Finally, after flashing the firmware to your board, load the custom via definition in the design tab in [via](https://usevia.app)
Finally, after flashing the firmware to your board, load the custom via definition in the design tab in [via](https://usevia.app) (you may have to enable the "Show Design Tab" option in the settings).
# Setup checklist
Expand Down

0 comments on commit c863145

Please sign in to comment.