Added SDL_HINT_MOUSE_NORMAL_SPEED_SCALE and SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE to scale the speed of the mouse.

This currently doesn't affect absolute motion, which would need to be implemented on each windowing system so the cursor matches the reported mouse coordinates.
This commit is contained in:
Sam Lantinga
2016-12-02 21:01:13 -08:00
parent 26f05ecb4d
commit 4eda58ba6a
3 changed files with 66 additions and 0 deletions

View File

@@ -40,12 +40,34 @@ static int SDL_double_click_radius = 1;
static int
SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
static void
SDL_MouseNormalSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
mouse->normal_speed_scale = SDL_atof(hint);
}
static void
SDL_MouseRelativeSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
mouse->relative_speed_scale = SDL_atof(hint);
}
/* Public functions */
int
SDL_MouseInit(void)
{
SDL_Mouse *mouse = SDL_GetMouse();
SDL_AddHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
SDL_MouseNormalSpeedScaleChanged, mouse);
SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE,
SDL_MouseRelativeSpeedScaleChanged, mouse);
mouse->cursor_shown = SDL_TRUE;
return (0);
@@ -199,6 +221,21 @@ SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int
return SDL_PrivateSendMouseMotion(window, mouseID, relative, x, y);
}
static int
GetScaledMouseDelta(float scale, int value, float *accum)
{
if (scale != 1.0f) {
*accum += scale * value;
if (*accum >= 0.0f) {
value = (int)SDL_floor(*accum);
} else {
value = (int)SDL_ceil(*accum);
}
*accum -= value;
}
return value;
}
static int
SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y)
{
@@ -221,6 +258,13 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
}
if (relative) {
if (mouse->relative_mode) {
x = GetScaledMouseDelta(mouse->relative_speed_scale, x, &mouse->scale_accum_x);
y = GetScaledMouseDelta(mouse->relative_speed_scale, y, &mouse->scale_accum_y);
} else {
x = GetScaledMouseDelta(mouse->normal_speed_scale, x, &mouse->scale_accum_x);
y = GetScaledMouseDelta(mouse->normal_speed_scale, y, &mouse->scale_accum_y);
}
xrel = x;
yrel = y;
x = (mouse->last_x + xrel);
@@ -475,6 +519,12 @@ SDL_MouseQuit(void)
}
SDL_zerop(mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
SDL_MouseNormalSpeedScaleChanged, mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE,
SDL_MouseRelativeSpeedScaleChanged, mouse);
}
Uint32
@@ -603,6 +653,8 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
}
}
mouse->relative_mode = enabled;
mouse->scale_accum_x = 0.0f;
mouse->scale_accum_y = 0.0f;
if (mouse->focus) {
SDL_UpdateWindowGrab(mouse->focus);