Skip to content

Commit

Permalink
Pointer sanitization - winraw, dinput, sdl (partial)
Browse files Browse the repository at this point in the history
Adapt the sanitized pointer handling, discussed at libretro#17196 :

winraw and dinput driver specific changes:

    make sure pointer position is always within [-0x7fff,0x7fff] by using the confined wrapper
    remove extra "inside" checks, general simplification
    enable pointer offscreen reporting
    use common functions for edge detection and lightgun button ID conversion

sdl driver specific changes:

    pointer handling aligned with the other input drivers, as above
    added TODO for lightgun part - no suitable test env at the moment where SDL input can be used
  • Loading branch information
zoltanvb committed Dec 25, 2024
1 parent 9a5b206 commit 1863691
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 168 deletions.
98 changes: 18 additions & 80 deletions input/drivers/dinput.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,7 @@ static bool dinput_mouse_button_pressed(
static int16_t dinput_lightgun_aiming_state(
struct dinput_input *di, unsigned idx, unsigned id)
{
struct video_viewport vp;
const int edge_detect = 32700;
struct video_viewport vp = {0};
int16_t res_x = 0;
int16_t res_y = 0;
int16_t res_screen_x = 0;
Expand All @@ -446,13 +445,6 @@ static int16_t dinput_lightgun_aiming_state(
struct dinput_pointer_status
*check_pos = di->pointer_head.next;

vp.x = 0;
vp.y = 0;
vp.width = 0;
vp.height = 0;
vp.full_width = 0;
vp.full_height = 0;

while (check_pos && num < idx)
{
num++;
Expand All @@ -475,24 +467,14 @@ static int16_t dinput_lightgun_aiming_state(
&vp, x, y,
&res_x, &res_y, &res_screen_x, &res_screen_y))
{
bool inside =
(res_x >= -edge_detect)
&& (res_y >= -edge_detect)
&& (res_x <= edge_detect)
&& (res_y <= edge_detect);

switch (id)
{
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X:
if (inside)
return res_x;
break;
return res_x;
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y:
if (inside)
return res_y;
break;
return res_y;
case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
return !inside;
return input_driver_pointer_is_offscreen(res_x, res_y);
default:
break;
}
Expand All @@ -501,41 +483,6 @@ static int16_t dinput_lightgun_aiming_state(
return 0;
}

static unsigned dinput_retro_id_to_rarch(unsigned id)
{
switch (id)
{
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT:
return RARCH_LIGHTGUN_DPAD_RIGHT;
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT:
return RARCH_LIGHTGUN_DPAD_LEFT;
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP:
return RARCH_LIGHTGUN_DPAD_UP;
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN:
return RARCH_LIGHTGUN_DPAD_DOWN;
case RETRO_DEVICE_ID_LIGHTGUN_SELECT:
return RARCH_LIGHTGUN_SELECT;
case RETRO_DEVICE_ID_LIGHTGUN_PAUSE:
return RARCH_LIGHTGUN_START;
case RETRO_DEVICE_ID_LIGHTGUN_RELOAD:
return RARCH_LIGHTGUN_RELOAD;
case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
return RARCH_LIGHTGUN_TRIGGER;
case RETRO_DEVICE_ID_LIGHTGUN_AUX_A:
return RARCH_LIGHTGUN_AUX_A;
case RETRO_DEVICE_ID_LIGHTGUN_AUX_B:
return RARCH_LIGHTGUN_AUX_B;
case RETRO_DEVICE_ID_LIGHTGUN_AUX_C:
return RARCH_LIGHTGUN_AUX_C;
case RETRO_DEVICE_ID_LIGHTGUN_START:
return RARCH_LIGHTGUN_START;
default:
break;
}

return 0;
}

static int16_t dinput_input_state(
void *data,
const input_device_driver_t *joypad,
Expand Down Expand Up @@ -717,8 +664,7 @@ static int16_t dinput_input_state(
case RETRO_DEVICE_POINTER:
case RARCH_DEVICE_POINTER_SCREEN:
{
struct video_viewport vp;
bool inside = false;
struct video_viewport vp = {0};
int x = 0;
int y = 0;
int16_t res_x = 0;
Expand All @@ -729,13 +675,6 @@ static int16_t dinput_input_state(
struct dinput_pointer_status *
check_pos = di->pointer_head.next;

vp.x = 0;
vp.y = 0;
vp.width = 0;
vp.height = 0;
vp.full_width = 0;
vp.full_height = 0;

while (check_pos && num < idx)
{
num++;
Expand All @@ -753,7 +692,7 @@ static int16_t dinput_input_state(
y = check_pos->pointer_y;
}

if (video_driver_translate_coord_viewport_wrap(&vp, x, y,
if (video_driver_translate_coord_viewport_confined_wrap(&vp, x, y,
&res_x, &res_y, &res_screen_x, &res_screen_y))
{
if (device == RARCH_DEVICE_POINTER_SCREEN)
Expand All @@ -762,19 +701,18 @@ static int16_t dinput_input_state(
res_y = res_screen_y;
}

if ((inside = (res_x >= -0x7fff) && (res_y >= -0x7fff)))
switch (id)
{
switch (id)
{
case RETRO_DEVICE_ID_POINTER_X:
return res_x;
case RETRO_DEVICE_ID_POINTER_Y:
return res_y;
case RETRO_DEVICE_ID_POINTER_PRESSED:
return check_pos ? 1 : (di->flags & DINP_FLAG_MOUSE_L_BTN) > 0;
default:
break;
}
case RETRO_DEVICE_ID_POINTER_X:
return res_x;
case RETRO_DEVICE_ID_POINTER_Y:
return res_y;
case RETRO_DEVICE_ID_POINTER_PRESSED:
return check_pos ? 1 : (di->flags & DINP_FLAG_MOUSE_L_BTN) > 0;
case RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN:
return input_driver_pointer_is_offscreen(res_x, res_y);
default:
break;
}
}
}
Expand Down Expand Up @@ -802,7 +740,7 @@ static int16_t dinput_input_state(
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT:
case RETRO_DEVICE_ID_LIGHTGUN_PAUSE:
{
unsigned new_id = dinput_retro_id_to_rarch(id);
unsigned new_id = input_driver_lightgun_id_convert(id);
const uint64_t bind_joykey = input_config_binds[port][new_id].joykey;
const uint64_t bind_joyaxis = input_config_binds[port][new_id].joyaxis;
const uint64_t autobind_joykey = input_autoconf_binds[port][new_id].joykey;
Expand Down
23 changes: 5 additions & 18 deletions input/drivers/sdl_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,24 +256,15 @@ static int16_t sdl_input_state(
case RARCH_DEVICE_POINTER_SCREEN:
if (idx == 0)
{
struct video_viewport vp;
struct video_viewport vp = {0};
bool screen = device ==
RARCH_DEVICE_POINTER_SCREEN;
const int edge_detect = 32700;
bool inside = false;
int16_t res_x = 0;
int16_t res_y = 0;
int16_t res_screen_x = 0;
int16_t res_screen_y = 0;

vp.x = 0;
vp.y = 0;
vp.width = 0;
vp.height = 0;
vp.full_width = 0;
vp.full_height = 0;

if (video_driver_translate_coord_viewport_wrap(
if (video_driver_translate_coord_viewport_confined_wrap(
&vp, sdl->mouse_abs_x, sdl->mouse_abs_y,
&res_x, &res_y, &res_screen_x, &res_screen_y))
{
Expand All @@ -283,11 +274,6 @@ static int16_t sdl_input_state(
res_y = res_screen_y;
}

inside = (res_x >= -edge_detect)
&& (res_y >= -edge_detect)
&& (res_x <= edge_detect)
&& (res_y <= edge_detect);

switch (id)
{
case RETRO_DEVICE_ID_POINTER_X:
Expand All @@ -296,14 +282,15 @@ static int16_t sdl_input_state(
return res_y;
case RETRO_DEVICE_ID_POINTER_PRESSED:
return sdl->mouse_l;
case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
return !inside;
case RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN:
return input_driver_pointer_is_offscreen(res_x, res_y);
}
}
}
break;
case RETRO_DEVICE_KEYBOARD:
return (id && id < RETROK_LAST) && sdl_key_pressed(id);
/* TODO: update to match other input drivers (aiming state, button binds) */
case RETRO_DEVICE_LIGHTGUN:
switch (id)
{
Expand Down
79 changes: 9 additions & 70 deletions input/drivers/winraw_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,41 +230,24 @@ static int16_t winraw_lightgun_aiming_state(winraw_input_t *wr,
winraw_mouse_t *mouse,
unsigned port, unsigned id)
{
struct video_viewport vp;
struct video_viewport vp = {0};
int16_t res_x = 0;
int16_t res_y = 0;
int16_t res_screen_x = 0;
int16_t res_screen_y = 0;

vp.x = 0;
vp.y = 0;
vp.width = 0;
vp.height = 0;
vp.full_width = 0;
vp.full_height = 0;

if ((video_driver_translate_coord_viewport_wrap(
&vp, mouse->x, mouse->y,
&res_x, &res_y, &res_screen_x, &res_screen_y)))
{
const int edge_detect = 32700;
bool inside = (res_x >= -edge_detect)
&& (res_y >= -edge_detect)
&& (res_x <= edge_detect)
&& (res_y <= edge_detect);

switch (id)
{
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X:
if (inside)
return res_x;
break;
return res_x;
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y:
if (inside)
return res_y;
break;
return res_y;
case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
return !inside;
return input_driver_pointer_is_offscreen(res_x, res_y);
default:
break;
}
Expand Down Expand Up @@ -675,41 +658,6 @@ static void winraw_poll(void *data)
memset(wr->kb_keys, 0, SC_LAST);
}

static unsigned winraw_retro_id_to_rarch(unsigned id)
{
switch (id)
{
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT:
return RARCH_LIGHTGUN_DPAD_RIGHT;
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT:
return RARCH_LIGHTGUN_DPAD_LEFT;
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP:
return RARCH_LIGHTGUN_DPAD_UP;
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN:
return RARCH_LIGHTGUN_DPAD_DOWN;
case RETRO_DEVICE_ID_LIGHTGUN_SELECT:
return RARCH_LIGHTGUN_SELECT;
case RETRO_DEVICE_ID_LIGHTGUN_PAUSE:
return RARCH_LIGHTGUN_START;
case RETRO_DEVICE_ID_LIGHTGUN_RELOAD:
return RARCH_LIGHTGUN_RELOAD;
case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
return RARCH_LIGHTGUN_TRIGGER;
case RETRO_DEVICE_ID_LIGHTGUN_AUX_A:
return RARCH_LIGHTGUN_AUX_A;
case RETRO_DEVICE_ID_LIGHTGUN_AUX_B:
return RARCH_LIGHTGUN_AUX_B;
case RETRO_DEVICE_ID_LIGHTGUN_AUX_C:
return RARCH_LIGHTGUN_AUX_C;
case RETRO_DEVICE_ID_LIGHTGUN_START:
return RARCH_LIGHTGUN_START;
default:
break;
}

return 0;
}

static int16_t winraw_input_state(
void *data,
const input_device_driver_t *joypad,
Expand Down Expand Up @@ -876,9 +824,8 @@ static int16_t winraw_input_state(
case RETRO_DEVICE_POINTER:
case RARCH_DEVICE_POINTER_SCREEN:
{
struct video_viewport vp;
struct video_viewport vp = {0};
bool pointer_down = false;
bool inside = false;
int x = 0;
int y = 0;
int16_t res_x = 0;
Expand All @@ -889,13 +836,6 @@ static int16_t winraw_input_state(
struct winraw_pointer_status *
check_pos = wr->pointer_head.next;

vp.x = 0;
vp.y = 0;
vp.width = 0;
vp.height = 0;
vp.full_width = 0;
vp.full_height = 0;

while (check_pos && num < idx)
{
num++;
Expand All @@ -918,7 +858,7 @@ static int16_t winraw_input_state(
pointer_down = true;
}

if (!(video_driver_translate_coord_viewport_wrap(&vp, x, y,
if (!(video_driver_translate_coord_viewport_confined_wrap(&vp, x, y,
&res_x, &res_y, &res_screen_x, &res_screen_y)))
return 0;

Expand All @@ -928,9 +868,6 @@ static int16_t winraw_input_state(
res_y = res_screen_y;
}

if (!(inside = (res_x >= -0x7fff) && (res_y >= -0x7fff)))
return 0;

switch (id)
{
case RETRO_DEVICE_ID_POINTER_X:
Expand All @@ -939,6 +876,8 @@ static int16_t winraw_input_state(
return res_y;
case RETRO_DEVICE_ID_POINTER_PRESSED:
return pointer_down;
case RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN:
return input_driver_pointer_is_offscreen(res_x, res_y);
default:
break;
}
Expand Down Expand Up @@ -966,7 +905,7 @@ static int16_t winraw_input_state(
case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT:
case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: /* deprecated */
{
unsigned new_id = winraw_retro_id_to_rarch(id);
unsigned new_id = input_driver_lightgun_id_convert(id);
const uint64_t bind_joykey = input_config_binds[port][new_id].joykey;
const uint64_t bind_joyaxis = input_config_binds[port][new_id].joyaxis;
const uint64_t autobind_joykey = input_autoconf_binds[port][new_id].joykey;
Expand Down

0 comments on commit 1863691

Please sign in to comment.