Skip to content

Commit

Permalink
add transform function customization, remove hints
Browse files Browse the repository at this point in the history
  • Loading branch information
expikr committed Nov 26, 2024
1 parent 5c8bed3 commit 342f92b
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 73 deletions.
29 changes: 0 additions & 29 deletions include/SDL3/SDL_hints.h
Original file line number Diff line number Diff line change
Expand Up @@ -2505,35 +2505,6 @@ extern "C" {
*/
#define SDL_HINT_MOUSE_RELATIVE_MODE_WARP "SDL_MOUSE_RELATIVE_MODE_WARP"

/**
* A variable setting the scale for mouse motion, in floating point, when the
* mouse is in relative mode.
*
* This hint can be set anytime.
*
* \since This hint is available since SDL 3.1.3.
*/
#define SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE "SDL_MOUSE_RELATIVE_SPEED_SCALE"

/**
* A variable controlling whether the system mouse acceleration curve is used
* for relative mouse motion.
*
* The variable can be set to the following values:
*
* - "0": Relative mouse motion will be unscaled. (default)
* - "1": Relative mouse motion will be scaled using the system mouse
* acceleration curve.
*
* If SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE is set, that will override the
* system speed scale.
*
* This hint can be set anytime.
*
* \since This hint is available since SDL 3.1.3.
*/
#define SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE "SDL_MOUSE_RELATIVE_SYSTEM_SCALE"

/**
* A variable controlling whether a motion event should be generated for mouse
* warping in relative mode.
Expand Down
31 changes: 31 additions & 0 deletions include/SDL3/SDL_mouse.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,37 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetMouseNameForID(SDL_MouseID insta
*/
extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void);

/**
* Retieve an implementation of the function by which the platform
* transforms raw mouse inputs into cursor motion.
*
* This returns a function pointer to the implmentation if one exists,
* or NULL if not. This pointer can be passed to SDL_SetInputTransform
* if one wishes to scale relative mouse motion using the implementation,
* in which case the userdata argument is ignored and platform-specific
* data will be used instead.
*
* \returns a pointer to an input transform function.
*
* \since This function is available since SDL 3.1.3.
*
* \sa SDL_SetInputTransform
*/
extern SDL_DECLSPEC const void * SDLCALL SDL_GetSystemInputTransform(void);

/**
* Set a user-defined function by which to transform relative mouse inputs,
* and its associated internal data which will be passed to the function.
*
* \param transform a pointer to an input transform function, or NULL to disable.
* \param userdata an optional pointer to the associated internal data.
*
* \since This function is available since SDL 3.1.3.
*
* \sa SDL_GetSystemInputTransform
*/
extern SDL_DECLSPEC void SDLCALL SDL_SetInputTransform(const void *transform, void *userdata);

/**
* Query SDL's cache for the synchronous mouse button state and the
* window-relative SDL-cursor position.
Expand Down
54 changes: 16 additions & 38 deletions src/events/SDL_mouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,26 +100,6 @@ static void SDLCALL SDL_MouseNormalSpeedScaleChanged(void *userdata, const char
}
}

static void SDLCALL SDL_MouseRelativeSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;

if (hint && *hint) {
mouse->enable_relative_speed_scale = true;
mouse->relative_speed_scale = (float)SDL_atof(hint);
} else {
mouse->enable_relative_speed_scale = false;
mouse->relative_speed_scale = 1.0f;
}
}

static void SDLCALL SDL_MouseRelativeSystemScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;

mouse->enable_relative_system_scale = SDL_GetStringBoolean(hint, false);
}

static void SDLCALL SDL_MouseWarpEmulationChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
Expand Down Expand Up @@ -220,12 +200,6 @@ bool SDL_PreInitMouse(void)
SDL_AddHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
SDL_MouseNormalSpeedScaleChanged, mouse);

SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE,
SDL_MouseRelativeSpeedScaleChanged, mouse);

SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE,
SDL_MouseRelativeSystemScaleChanged, mouse);

SDL_AddHintCallback(SDL_HINT_MOUSE_EMULATE_WARP_WITH_RELATIVE,
SDL_MouseWarpEmulationChanged, mouse);

Expand Down Expand Up @@ -696,13 +670,12 @@ static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL

if (relative) {
if (mouse->relative_mode) {
if (mouse->enable_relative_speed_scale) {
x *= mouse->relative_speed_scale;
y *= mouse->relative_speed_scale;
} else if (mouse->enable_relative_system_scale) {
if (mouse->ApplySystemScale) {
mouse->ApplySystemScale(mouse->system_scale_data, timestamp, window, mouseID, &x, &y);
if (mouse->InputTransform) {
void *data = mouse->input_transform_data;
if (mouse->InputTransform == mouse->ApplySystemScale) {
data = mouse->system_scale_data;
}
mouse->InputTransform(data, timestamp, window, mouseID, &x, &y);
}
} else {
if (mouse->enable_normal_speed_scale) {
Expand Down Expand Up @@ -1049,12 +1022,6 @@ void SDL_QuitMouse(void)
SDL_RemoveHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
SDL_MouseNormalSpeedScaleChanged, mouse);

SDL_RemoveHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE,
SDL_MouseRelativeSpeedScaleChanged, mouse);

SDL_RemoveHintCallback(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE,
SDL_MouseRelativeSystemScaleChanged, mouse);

SDL_RemoveHintCallback(SDL_HINT_MOUSE_EMULATE_WARP_WITH_RELATIVE,
SDL_MouseWarpEmulationChanged, mouse);

Expand Down Expand Up @@ -1083,6 +1050,17 @@ void SDL_QuitMouse(void)
SDL_mice = NULL;
}

const void *SDL_GetSystemInputTransform(void) {
SDL_Mouse *mouse = SDL_GetMouse();
return (const void*)mouse->ApplySystemScale;
}

void SDL_SetInputTransform(const void *transform, void *userdata) {
SDL_Mouse *mouse = SDL_GetMouse();
mouse->InputTransform = transform;
mouse->input_transform_data = userdata;
}

SDL_MouseButtonFlags SDL_GetMouseState(float *x, float *y)
{
SDL_Mouse *mouse = SDL_GetMouse();
Expand Down
7 changes: 4 additions & 3 deletions src/events/SDL_mouse_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ typedef struct
void (*ApplySystemScale)(void *internal, Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float *x, float *y);
void *system_scale_data;

// User-defined mouse input transform
const void (*InputTransform)(void *userdata, Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float *x, float *y);
void *input_transform_data;

// Data common to all mice
SDL_Window *focus;
float x;
Expand All @@ -105,9 +109,6 @@ typedef struct
int relative_mode_clip_interval;
bool enable_normal_speed_scale;
float normal_speed_scale;
bool enable_relative_speed_scale;
float relative_speed_scale;
bool enable_relative_system_scale;
Uint32 double_click_time;
int double_click_radius;
bool touch_mouse_events;
Expand Down
6 changes: 3 additions & 3 deletions src/video/windows/SDL_windowsmouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,9 +694,9 @@ void WIN_UpdateMouseSystemScale(void)
{
SDL_Mouse *mouse = SDL_GetMouse();

if (mouse->ApplySystemScale == WIN_ApplySystemScale) {
mouse->system_scale_data = &WIN_system_scale_data;
}
// always set to platform impl to be safe, even though it's not exposed to user.
mouse->ApplySystemScale == WIN_ApplySystemScale
mouse->system_scale_data = &WIN_system_scale_data;

// always reinitialize to valid defaults, whether fetch was successful or not.
WIN_MouseData *data = &WIN_system_scale_data;
Expand Down

0 comments on commit 342f92b

Please sign in to comment.