mirror of
https://github.com/libretro/RetroArch
synced 2024-12-25 18:25:21 +00:00
Pointer handling sanitization - wayland and libretro.h changes (#17277)
Adapt the sanitized pointer handling, discussed at #17196: Wayland driver specific changes: - make sure pointer position is always within [-0x7fff,0x7fff] by using the confined wrapper - enable lightgun to report -0x8000 if pointer is really offscreen - remove extra "inside" checks - report same pointer/lightgun coordinates for all ports - simplify pointer and lightgun handling Other changes: - unify "offscreen" condition through input_driver.c - slight tuning of pointer conversion in video_driver.c - update libretro.h with explanation and pointer offscreen value - small fixes on remote retropad test screen
This commit is contained in:
parent
a7db10508c
commit
072d949346
@ -162,13 +162,13 @@ static struct descriptor mouse = {
|
||||
};
|
||||
|
||||
static struct descriptor pointer = {
|
||||
.device = RETRO_DEVICE_POINTER/* | 0x10000*/,
|
||||
.device = RETRO_DEVICE_POINTER,
|
||||
.port_min = 0,
|
||||
.port_max = 0,
|
||||
.index_min = 0,
|
||||
.index_max = 2,
|
||||
.id_min = RETRO_DEVICE_ID_POINTER_X,
|
||||
.id_max = RETRO_DEVICE_ID_POINTER_COUNT
|
||||
.id_max = RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN
|
||||
};
|
||||
|
||||
static struct descriptor lightgun = {
|
||||
@ -710,7 +710,7 @@ static void retropad_update_input(void)
|
||||
}
|
||||
else if (id == RETRO_DEVICE_ID_MOUSE_Y || id == RETRO_DEVICE_ID_LIGHTGUN_Y)
|
||||
{
|
||||
int32_t large = pointer_y + (int16_t)state*273;
|
||||
int32_t large = pointer_y + (int16_t)state*327;
|
||||
if (large < -32768)
|
||||
pointer_y = -32768;
|
||||
else if (large > 32767)
|
||||
@ -721,6 +721,7 @@ static void retropad_update_input(void)
|
||||
}
|
||||
else if (mouse_type == NETRETROPAD_POINTER || mouse_type == NETRETROPAD_LIGHTGUN)
|
||||
{
|
||||
/* NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_DEBUG, "Pointer state: %d %d %d (%d %d)\n",i,id, (int16_t)state,pointer_x,pointer_y); */
|
||||
if (id == RETRO_DEVICE_ID_POINTER_X || id == RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X)
|
||||
pointer_x = (int16_t)state;
|
||||
else if (id == RETRO_DEVICE_ID_POINTER_Y || id == RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y)
|
||||
@ -1114,15 +1115,18 @@ void NETRETROPAD_CORE_PREFIX(retro_run)(void)
|
||||
{
|
||||
int offset;
|
||||
|
||||
offset = DESC_OFFSET(&lightgun, 0, 0, RETRO_DEVICE_ID_POINTER_PRESSED);
|
||||
offset = DESC_OFFSET(&pointer, 0, 0, RETRO_DEVICE_ID_POINTER_PRESSED);
|
||||
sensor_item_colors[104] = pointer.value[offset] ? 0xA000 : 0x0000;
|
||||
|
||||
offset = DESC_OFFSET(&lightgun, 0, 1, RETRO_DEVICE_ID_POINTER_PRESSED);
|
||||
offset = DESC_OFFSET(&pointer, 0, 1, RETRO_DEVICE_ID_POINTER_PRESSED);
|
||||
sensor_item_colors[105] = pointer.value[offset] ? 0xA000 : 0x0000;
|
||||
|
||||
offset = DESC_OFFSET(&lightgun, 0, 2, RETRO_DEVICE_ID_POINTER_PRESSED);
|
||||
offset = DESC_OFFSET(&pointer, 0, 2, RETRO_DEVICE_ID_POINTER_PRESSED);
|
||||
sensor_item_colors[106] = pointer.value[offset] ? 0xA000 : 0x0000;
|
||||
|
||||
offset = DESC_OFFSET(&pointer, 0, 0, RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN);
|
||||
sensor_item_colors[77] = pointer.value[offset] ? 0xA000 : 0x0000;
|
||||
|
||||
}
|
||||
/* Edge / offscreen indicators */
|
||||
if (mouse_type == NETRETROPAD_POINTER || mouse_type == NETRETROPAD_LIGHTGUN)
|
||||
|
@ -712,19 +712,19 @@ bool video_driver_translate_coord_viewport(
|
||||
|| (norm_full_vp_height <= 0))
|
||||
return false;
|
||||
|
||||
if (mouse_x >= 0 && mouse_x <= norm_full_vp_width)
|
||||
scaled_screen_x = ((2 * mouse_x * 0x7fff)
|
||||
if (mouse_x >= 0 && mouse_x < norm_full_vp_width)
|
||||
scaled_screen_x = ((mouse_x * 0x10000)
|
||||
/ norm_full_vp_width) - 0x7fff;
|
||||
|
||||
if (mouse_y >= 0 && mouse_y <= norm_full_vp_height)
|
||||
scaled_screen_y = ((2 * mouse_y * 0x7fff)
|
||||
if (mouse_y >= 0 && mouse_y < norm_full_vp_height)
|
||||
scaled_screen_y = ((mouse_y * 0x10000)
|
||||
/ norm_full_vp_height) - 0x7fff;
|
||||
|
||||
mouse_x -= vp->x;
|
||||
mouse_y -= vp->y;
|
||||
|
||||
if (mouse_x >= 0 && mouse_x <= norm_vp_width)
|
||||
scaled_x = ((2 * mouse_x * 0x7fff)
|
||||
if (mouse_x >= 0 && mouse_x < norm_vp_width)
|
||||
scaled_x = ((mouse_x * 0x10000)
|
||||
/ norm_vp_width) - 0x7fff;
|
||||
else if (!report_oob)
|
||||
{
|
||||
@ -734,8 +734,8 @@ bool video_driver_translate_coord_viewport(
|
||||
scaled_x = 0x7fff;
|
||||
}
|
||||
|
||||
if (mouse_y >= 0 && mouse_y <= norm_vp_height)
|
||||
scaled_y = ((2 * mouse_y * 0x7fff)
|
||||
if (mouse_y >= 0 && mouse_y < norm_vp_height)
|
||||
scaled_y = ((mouse_y * 0x10000)
|
||||
/ norm_vp_height) - 0x7fff;
|
||||
else if (!report_oob)
|
||||
{
|
||||
|
@ -122,7 +122,7 @@ static int16_t input_wl_touch_state(input_ctx_wayland_data_t *wl,
|
||||
vp.full_width = 0;
|
||||
vp.full_height = 0;
|
||||
|
||||
if (video_driver_translate_coord_viewport_wrap(&vp,
|
||||
if (video_driver_translate_coord_viewport_confined_wrap(&vp,
|
||||
wl->touches[idx].x, wl->touches[idx].y,
|
||||
&res_x, &res_y, &res_screen_x, &res_screen_y))
|
||||
{
|
||||
@ -256,7 +256,8 @@ static int16_t input_wl_state(
|
||||
return (id && id < RETROK_LAST) && BIT_GET(wl->key_state, rarch_keysym_lut[(enum retro_key)id]);
|
||||
case RETRO_DEVICE_MOUSE:
|
||||
case RARCH_DEVICE_MOUSE_SCREEN:
|
||||
if (port == 0) /* TODO/FIXME: support mouse on additional ports */
|
||||
/* The system-wide mouse is reported for all ports. *
|
||||
* Multi-mouse may be implemented using different wayland seats, see issue #16886 */
|
||||
{
|
||||
bool state = false;
|
||||
bool screen = (device == RARCH_DEVICE_MOUSE_SCREEN);
|
||||
@ -300,26 +301,18 @@ static int16_t input_wl_state(
|
||||
}
|
||||
break;
|
||||
case RETRO_DEVICE_POINTER:
|
||||
/* TODO/FIXME: support pointers on additional ports */
|
||||
/* All ports report the same pointer state. See notes at mouse case. */
|
||||
if (idx == 0)
|
||||
{
|
||||
struct video_viewport vp;
|
||||
struct video_viewport vp = {0};
|
||||
bool screen =
|
||||
(device == RARCH_DEVICE_POINTER_SCREEN);
|
||||
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(&vp,
|
||||
if (video_driver_translate_coord_viewport_confined_wrap(&vp,
|
||||
wl->mouse.x, wl->mouse.y,
|
||||
&res_x, &res_y, &res_screen_x, &res_screen_y))
|
||||
{
|
||||
@ -329,10 +322,6 @@ static int16_t input_wl_state(
|
||||
res_y = res_screen_y;
|
||||
}
|
||||
|
||||
inside = (res_x >= -0x7fff) && (res_y >= -0x7fff);
|
||||
if (!inside)
|
||||
return 0;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case RETRO_DEVICE_ID_POINTER_X:
|
||||
@ -341,13 +330,8 @@ static int16_t input_wl_state(
|
||||
return res_y;
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
||||
return wl->mouse.left;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
|
||||
if (screen)
|
||||
{
|
||||
res_x = res_screen_x;
|
||||
res_y = res_screen_y;
|
||||
}
|
||||
return (!((res_x >= -0x7fff) && (res_y >= -0x7fff)));
|
||||
case RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN:
|
||||
return input_driver_pointer_is_offscreen(res_x, res_y);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -363,68 +347,38 @@ static int16_t input_wl_state(
|
||||
}
|
||||
break;
|
||||
case RETRO_DEVICE_LIGHTGUN:
|
||||
if (port == 0) /* TODO/FIXME: support lightguns on additional ports */
|
||||
/* All ports report the same lightgun state. See notes at mouse case. */
|
||||
{
|
||||
const int edge_detect = 32700;
|
||||
struct video_viewport vp;
|
||||
bool screen =
|
||||
(device == RARCH_DEVICE_POINTER_SCREEN);
|
||||
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;
|
||||
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;
|
||||
|
||||
if (video_driver_translate_coord_viewport_wrap(&vp,
|
||||
wl->mouse.x, wl->mouse.y,
|
||||
&res_x, &res_y, &res_screen_x, &res_screen_y))
|
||||
{
|
||||
if (screen)
|
||||
{
|
||||
res_x = res_screen_x;
|
||||
res_y = res_screen_y;
|
||||
}
|
||||
|
||||
inside = (res_x >= -0x7fff) && (res_y >= -0x7fff);
|
||||
if (!inside)
|
||||
return 0;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_X: /* TODO: migrate to RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X */
|
||||
return wl->mouse.delta_x; /* deprecated relative coordinates */
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_Y: /* TODO: migrate to RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y */
|
||||
return wl->mouse.delta_y; /* deprecated relative coordinates */
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_X:
|
||||
return wl->mouse.delta_x;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_Y:
|
||||
return wl->mouse.delta_y;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X:
|
||||
return res_x;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y:
|
||||
return res_y;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
|
||||
return wl->mouse.left;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_RELOAD: /* forced/faked off-screen shot */
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_RELOAD:
|
||||
return wl->mouse.middle;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_START:
|
||||
return wl->mouse.right;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_SELECT:
|
||||
return wl->mouse.left && wl->mouse.right;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN:
|
||||
if (screen)
|
||||
{
|
||||
res_x = res_screen_x;
|
||||
res_y = res_screen_y;
|
||||
}
|
||||
inside = (res_x >= -edge_detect)
|
||||
&& (res_y >= -edge_detect)
|
||||
&& (res_x <= edge_detect)
|
||||
&& (res_y <= edge_detect);
|
||||
return (!inside);
|
||||
return input_driver_pointer_is_offscreen(res_x, res_y);
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_AUX_A: /* TODO */
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_AUX_B: /* TODO */
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_AUX_C: /* TODO */
|
||||
|
@ -644,6 +644,17 @@ static bool input_driver_button_combo_hold(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool input_driver_pointer_is_offscreen(int16_t x, int16_t y)
|
||||
{
|
||||
const int edge_detect = 32700;
|
||||
if ((x >= -edge_detect) &&
|
||||
(y >= -edge_detect) &&
|
||||
(x <= edge_detect) &&
|
||||
(y <= edge_detect))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool input_driver_button_combo(
|
||||
unsigned mode,
|
||||
retro_time_t current_time,
|
||||
|
@ -922,6 +922,8 @@ char *input_config_get_device_name_ptr(unsigned port);
|
||||
*/
|
||||
size_t input_config_get_device_name_size(unsigned port);
|
||||
|
||||
bool input_driver_pointer_is_offscreen(int16_t x, int16_t y);
|
||||
|
||||
bool input_driver_button_combo(
|
||||
unsigned mode,
|
||||
retro_time_t current_time,
|
||||
|
@ -4,12 +4,12 @@
|
||||
* @file libretro.h
|
||||
* @version 1
|
||||
* @author libretro
|
||||
* @copyright Copyright (C) 2010-2023 The RetroArch team
|
||||
* @copyright Copyright (C) 2010-2024 The RetroArch team
|
||||
*
|
||||
* @paragraph LICENSE
|
||||
* The following license statement only applies to this libretro API header (libretro.h).
|
||||
*
|
||||
* Copyright (C) 2010-2023 The RetroArch team
|
||||
* Copyright (C) 2010-2024 The RetroArch team
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
@ -272,7 +272,10 @@ extern "C" {
|
||||
* [-0x7fff, 0x7fff]: -0x7fff corresponds to the far left/top of the screen,
|
||||
* and 0x7fff corresponds to the far right/bottom of the screen.
|
||||
* The "screen" is here defined as area that is passed to the frontend and
|
||||
* later displayed on the monitor.
|
||||
* later displayed on the monitor. If the pointer is outside this screen,
|
||||
* such as in the black surrounding areas when actual display is larger,
|
||||
* edge position is reported. An explicit edge detection is also provided,
|
||||
* that will return 1 if the pointer is near the screen edge or actually outside it.
|
||||
*
|
||||
* The frontend is free to scale/resize this screen as it sees fit, however,
|
||||
* (X, Y) = (-0x7fff, -0x7fff) will correspond to the top-left pixel of the
|
||||
@ -406,7 +409,8 @@ extern "C" {
|
||||
|
||||
/* Id values for LIGHTGUN. */
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X 13 /*Absolute Position*/
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y 14 /*Absolute*/
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y 14 /*Absolute Position*/
|
||||
/** Indicates if lightgun points off the screen or near the edge */
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN 15 /*Status Check*/
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_TRIGGER 2
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_RELOAD 16 /*Forced off-screen shot*/
|
||||
@ -421,17 +425,18 @@ extern "C" {
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT 12
|
||||
/* deprecated */
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_X 0 /*Relative Position*/
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_Y 1 /*Relative*/
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_CURSOR 3 /*Use Aux:A*/
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_TURBO 4 /*Use Aux:B*/
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_PAUSE 5 /*Use Start*/
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_Y 1 /*Relative Position*/
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_CURSOR 3 /*Use Aux:A instead*/
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_TURBO 4 /*Use Aux:B instead*/
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_PAUSE 5 /*Use Start instead*/
|
||||
|
||||
/* Id values for POINTER. */
|
||||
#define RETRO_DEVICE_ID_POINTER_X 0
|
||||
#define RETRO_DEVICE_ID_POINTER_Y 1
|
||||
#define RETRO_DEVICE_ID_POINTER_PRESSED 2
|
||||
#define RETRO_DEVICE_ID_POINTER_COUNT 3
|
||||
|
||||
#define RETRO_DEVICE_ID_POINTER_X 0
|
||||
#define RETRO_DEVICE_ID_POINTER_Y 1
|
||||
#define RETRO_DEVICE_ID_POINTER_PRESSED 2
|
||||
#define RETRO_DEVICE_ID_POINTER_COUNT 3
|
||||
/** Indicates if pointer is off the screen or near the edge */
|
||||
#define RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN 15
|
||||
/** @} */
|
||||
|
||||
/* Returned from retro_get_region(). */
|
||||
|
Loading…
Reference in New Issue
Block a user