Pointer sanitization - winraw, dinput, sdl (partial) (#17283)

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
This commit is contained in:
zoltanvb 2024-12-25 17:18:17 +01:00 committed by GitHub
parent b124fe6e65
commit e5fde4dd09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 168 deletions

View File

@ -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;
@ -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++;
@ -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;
}
@ -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,
@ -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;
@ -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++;
@ -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)
@ -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;
}
}
}
@ -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;

View File

@ -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))
{
@ -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:
@ -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)
{

View File

@ -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;
}
@ -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,
@ -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;
@ -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++;
@ -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;
@ -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:
@ -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;
}
@ -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;