diff options
Diffstat (limited to 'mousetsr.c')
| -rw-r--r-- | mousetsr.c | 53 |
1 files changed, 42 insertions, 11 deletions
@@ -60,6 +60,30 @@ static void bound_position_to_window(void) if (data.pos.y > data.max.y) data.pos.y = data.max.y; } +/** Apply sensitivity to a raw mouse delta. + * @param sens value [5..100] given to set_mouse_sensitivity. + * @param x mouse delta in mickeys + * @return mouse delta scaled by sensitivity + * + * Note this is not acceleration, we are still multiplying the delta by a + * linear factor supposedly derived from the sensivitity [5..100] value. + * Every mouse driver seems to use their own formula for computing this factor. + * I am going with f(x) = x(x+32)/4096 since it looks round and fits decently, + * even with integer math (we don't divide by 4096 until after multiplying by delta). + * @see INT33_SET_MOUSE_SENSITIVITY for what the factor should look like. */ +int16_t apply_sensitivity(int16_t x, uint8_t sens) +{ + uint16_t factor = (sens * (sens + 32)); +#if 1 + // use shift by 12 rather than divide by 4096 + // unsigned math, otherwise negative values would round down when shifted + uint16_t scaled = scaleu_shift(abs(x), 12 /*4096*/, factor); + return x < 0 ? -scaled : scaled; +#else + return scalei(x, 4096, factor); +#endif +} + /** Constraints coordinate value to the desired granularity, * which must be a power of two. */ static inline int16_t snap_to_grid(int16_t val, int16_t granularity) @@ -646,6 +670,10 @@ static void handle_mouse_event(uint16_t buttons, bool absolute, int x, int y, ch } data.total_motion += ax * ax + ay * ay; + // Apply sensitivity now, since unlike acceleration/speed, it affects the raw mickey counters + x = apply_sensitivity(x, data.sensitivity_x); + y = apply_sensitivity(y, data.sensitivity_y); + // Update the raw mickey counters data.delta.x += x; data.delta.y += y; @@ -654,11 +682,11 @@ static void handle_mouse_event(uint16_t buttons, bool absolute, int x, int y, ch data.abs_pos.x = -1; data.abs_pos.y = -1; - // Convert mickeys into pixels, applying speed, sensitivity and acceleration + // Convert mickeys into pixels, applying speed and acceleration // If more than the double speed threshold has been moved in the last second, // double the speed - if (data.cur_speed > data.doubleSpeedThreshold * data.doubleSpeedThreshold) { + if (data.cur_speed > data.double_speed_threshold * data.double_speed_threshold) { x *= 2; y *= 2; } @@ -1172,7 +1200,7 @@ static void reset_mouse_settings() data.mickeysPerLine.x = 8; data.mickeysPerLine.y = 16; - data.doubleSpeedThreshold = 64; + data.double_speed_threshold = 64; data.min.x = 0; data.max.x = data.screen_max.x; data.min.y = 0; @@ -1185,6 +1213,10 @@ static void reset_mouse_settings() data.cursor_hotspot.y = 0; memcpy(data.cursor_graphic, default_cursor_graphic, sizeof(data.cursor_graphic)); + // Sensitivity is persisted through resets, but ensure we init it with 50 if 0. + if (data.sensitivity_x == 0) data.sensitivity_x = 50; + if (data.sensitivity_y == 0) data.sensitivity_y = 50; + refresh_cursor(); // This will hide the cursor and update data.cursor_visible } @@ -1414,7 +1446,7 @@ static void int33_handler(union INTPACK r) break; case INT33_SET_SPEED_DOUBLE_THRESHOLD: dprintf("Mouse set speed double threshold=%d\n", r.w.dx); - data.doubleSpeedThreshold = r.w.dx; + data.double_speed_threshold = r.w.dx; break; case INT33_EXCHANGE_EVENT_HANDLER: dputs("Mouse exchange event handler"); @@ -1446,15 +1478,14 @@ static void int33_handler(union INTPACK r) case INT33_SET_MOUSE_SENSITIVITY: dprintf("Mouse set sensitivity x=%d y=%d threshold=%d\n", r.w.bx, r.w.cx, r.w.dx); - // TODO According to cutemouse, sensitivity != mickeysPerLine - data.mickeysPerLine.x = r.w.bx; - data.mickeysPerLine.y = r.w.cx; - data.doubleSpeedThreshold = r.w.dx; + data.sensitivity_x = BOUND(r.w.bx, 1, 100); + data.sensitivity_y = BOUND(r.w.cx, 1, 100); + data.double_speed_threshold = r.w.dx; break; case INT33_GET_MOUSE_SENSITIVITY: - r.w.bx = data.mickeysPerLine.x; - r.w.cx = data.mickeysPerLine.y; - r.w.dx = data.doubleSpeedThreshold; + r.w.bx = data.sensitivity_x; + r.w.cx = data.sensitivity_y; + r.w.dx = data.double_speed_threshold; break; case INT33_RESET_SETTINGS: dputs("Mouse reset settings"); |
