Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Added SDL_HINT_MOUSE_NORMAL_SPEED_SCALE and SDL_HINT_MOUSE_RELATIVE_S…
…PEED_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.
  • Loading branch information
slouken committed Dec 3, 2016
1 parent 26f05ec commit 4eda58b
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 0 deletions.
10 changes: 10 additions & 0 deletions include/SDL_hints.h
Expand Up @@ -232,6 +232,16 @@ extern "C" {
*/
#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD"

/**
* \brief A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode
*/
#define SDL_HINT_MOUSE_NORMAL_SPEED_SCALE "SDL_MOUSE_NORMAL_SPEED_SCALE"

/**
* \brief A variable setting the scale for mouse motion, in floating point, when the mouse is in relative mode
*/
#define SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE "SDL_MOUSE_RELATIVE_SPEED_SCALE"

/**
* \brief A variable controlling whether relative mouse mode is implemented using mouse warping
*
Expand Down
52 changes: 52 additions & 0 deletions src/events/SDL_mouse.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
{
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions src/events/SDL_mouse_c.h
Expand Up @@ -83,6 +83,10 @@ typedef struct
Uint32 buttonstate;
SDL_bool relative_mode;
SDL_bool relative_mode_warp;
float normal_speed_scale;
float relative_speed_scale;
float scale_accum_x;
float scale_accum_y;

/* Data for double-click tracking */
int num_clickstates;
Expand Down

0 comments on commit 4eda58b

Please sign in to comment.