mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-07 08:36:02 -10:00
input: a controller's sub-device sensors, from SDL's left-hand sensors
The frontend passes a core's sensor calls for a sub-device (RETRO_SENSOR_SUBDEVICE) on to the drivers with the index kept. It remembers which sub-device sensors the core enabled, as it does the controller's own, so one not enabled, or whose enable no driver took, reads 0 without asking a driver. The controller's own sensors are handled as before, and sensitivity and orientation apply to both; the profile's axis remap stays the controller's. The SDL2 (2.26 and up) and SDL3 joypad drivers answer sub-device 1 from SDL's _L sensors: a Wii Remote's Nunchuk accelerometer, the left Joy-Con of a pair. SDL3 restores it on a reconnect as it does the others. Every other driver already refuses an index it does not know. samples/input/sensor_subdevice runs the wrappers as they ship.
This commit is contained in:
1 parent
04f8e90a9a
commit
80b3aefa35
9 files changed
+315
-12
No files matched your search
@@ -1124,6 +1124,19 @@ jobs:
|
||||
timeout 120 ./udev_rumble_test
|
||||
make clean
|
||||
echo "[pass] udev_rumble_test"
|
||||
- name: Build and run sensor_subdevice_test (ASan + UBSan)
|
||||
shell: bash
|
||||
working-directory: samples/input/sensor_subdevice
|
||||
run: |
|
||||
set -eu
|
||||
# A core's sensor calls for a controller's sub-device (the
|
||||
# Nunchuk, a left Joy-Con) through the frontend's wrappers as
|
||||
# they ship: passed on with the index once enabled, refused
|
||||
# when no driver has it, the controller's own unchanged.
|
||||
make clean && make SANITIZER=address,undefined
|
||||
UBSAN_OPTIONS=halt_on_error=1 timeout 60 ./sensor_subdevice_test
|
||||
make clean
|
||||
echo "[pass] sensor_subdevice_test"
|
||||
- name: Build and run dingux_rumble_test (ASan + UBSan, then TSan)
|
||||
shell: bash
|
||||
working-directory: samples/input/dingux_rumble
|
||||
|
||||
@@ -393,3 +393,4 @@ samples/gfx/d3d12_upscaler/Zdir_xess/
|
||||
samples/gfx/d3d12_upscaler/Zdir_none/
|
||||
samples/record/ffmpeg_pipeline/record_finalize_fragment.c
|
||||
samples/record/ffmpeg_pipeline/record_start_fragment.c
|
||||
samples/input/sensor_subdevice/core_sensor_fragment.c
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#define SDL_SUPPORTS_RUMBLE SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
#define SDL_SUPPORTS_SENSORS SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
/* the _L sensors: a Wii Remote's Nunchuk, the left Joy-Con of a pair */
|
||||
#define SDL_SUPPORTS_SENSORS_L SDL_VERSION_ATLEAST(2, 26, 0)
|
||||
#define SDL_SUPPORTS_TOUCHPAD SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
#define SDL_SUPPORTS_HIDAPI_WII SDL_VERSION_ATLEAST(2, 26, 0)
|
||||
#define SDL_SUPPORTS_HIDAPI_PS3 SDL_VERSION_ATLEAST(2, 26, 0)
|
||||
@@ -583,6 +585,31 @@ static bool sdl2_joypad_set_sensor_state(unsigned pad, enum retro_sensor_action
|
||||
sdl2_joypad_t *joypad = (sdl2_joypad_t*)&sdl2_pads[pad];
|
||||
(void)joypad; /* maybe unused */
|
||||
|
||||
/* sensor sub-device 1 (RETRO_SENSOR_SUBDEVICE): the part in the
|
||||
* left hand */
|
||||
if (RETRO_SENSOR_INDEX(action))
|
||||
{
|
||||
#if SDL_SUPPORTS_SENSORS_L
|
||||
unsigned base = RETRO_SENSOR_BASE(action);
|
||||
SDL_SensorType type;
|
||||
if (RETRO_SENSOR_INDEX(action) != 1)
|
||||
return false;
|
||||
if ( base == RETRO_SENSOR_GYROSCOPE_ENABLE
|
||||
|| base == RETRO_SENSOR_GYROSCOPE_DISABLE)
|
||||
type = SDL_SENSOR_GYRO_L;
|
||||
else if (base == RETRO_SENSOR_ACCELEROMETER_ENABLE
|
||||
|| base == RETRO_SENSOR_ACCELEROMETER_DISABLE)
|
||||
type = SDL_SENSOR_ACCEL_L;
|
||||
else
|
||||
return false;
|
||||
if (SDL_GameControllerHasSensor(joypad->controller, type))
|
||||
return !SDL_GameControllerSetSensorEnabled(joypad->controller, type,
|
||||
(SDL_bool)( base == RETRO_SENSOR_GYROSCOPE_ENABLE
|
||||
|| base == RETRO_SENSOR_ACCELEROMETER_ENABLE));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (action)
|
||||
{
|
||||
#if SDL_SUPPORTS_SENSORS
|
||||
@@ -615,9 +642,18 @@ static bool sdl2_joypad_get_sensor_input(unsigned pad, unsigned id, float *value
|
||||
sdl2_joypad_t *joypad = (sdl2_joypad_t*)&sdl2_pads[pad];
|
||||
SDL_SensorType sensor_type;
|
||||
float sensor_data[3];
|
||||
unsigned idx = RETRO_SENSOR_INDEX(id);
|
||||
|
||||
if (!joypad->controller)
|
||||
return false;
|
||||
#if SDL_SUPPORTS_SENSORS_L
|
||||
if (idx > 1)
|
||||
return false;
|
||||
#else
|
||||
if (idx)
|
||||
return false;
|
||||
#endif
|
||||
id = RETRO_SENSOR_BASE(id);
|
||||
|
||||
if ((id >= RETRO_SENSOR_ACCELEROMETER_X) && (id <= RETRO_SENSOR_ACCELEROMETER_Z))
|
||||
sensor_type = SDL_SENSOR_ACCEL;
|
||||
@@ -625,6 +661,11 @@ static bool sdl2_joypad_get_sensor_input(unsigned pad, unsigned id, float *value
|
||||
sensor_type = SDL_SENSOR_GYRO;
|
||||
else
|
||||
return false;
|
||||
#if SDL_SUPPORTS_SENSORS_L
|
||||
if (idx)
|
||||
sensor_type = sensor_type == SDL_SENSOR_ACCEL
|
||||
? SDL_SENSOR_ACCEL_L : SDL_SENSOR_GYRO_L;
|
||||
#endif
|
||||
|
||||
if (SDL_GameControllerGetSensorData(joypad->controller, sensor_type, sensor_data, 3) < 0)
|
||||
return false;
|
||||
|
||||
@@ -44,6 +44,11 @@ typedef struct _sdl3_joypad
|
||||
uint16_t rumble[2]; /* raw magnitude per retro_rumble_effect (strong/weak) */
|
||||
bool sensor_accel; /* Whether or not the sensor has been connected. */
|
||||
bool sensor_gyro;
|
||||
/* sensor sub-device 1 (RETRO_SENSOR_SUBDEVICE): the part in the left
|
||||
* hand, a Wii Remote's Nunchuk or the left Joy-Con of a pair, which
|
||||
* SDL reports as its _L sensors */
|
||||
bool sensor_accel_l;
|
||||
bool sensor_gyro_l;
|
||||
uint8_t touch_fingers; /* the first touchpad's, at most two */
|
||||
} sdl3_joypad_t;
|
||||
|
||||
@@ -359,6 +364,10 @@ static void sdl3_joypad_connect(SDL_JoystickID jid)
|
||||
SDL_SetGamepadSensorEnabled(gamepad, SDL_SENSOR_ACCEL, true);
|
||||
if (has_gyro && pad->sensor_gyro)
|
||||
SDL_SetGamepadSensorEnabled(gamepad, SDL_SENSOR_GYRO, true);
|
||||
if (pad->sensor_accel_l && SDL_GamepadHasSensor(gamepad, SDL_SENSOR_ACCEL_L))
|
||||
SDL_SetGamepadSensorEnabled(gamepad, SDL_SENSOR_ACCEL_L, true);
|
||||
if (pad->sensor_gyro_l && SDL_GamepadHasSensor(gamepad, SDL_SENSOR_GYRO_L))
|
||||
SDL_SetGamepadSensorEnabled(gamepad, SDL_SENSOR_GYRO_L, true);
|
||||
|
||||
if (SDL_GetNumGamepadTouchpads(gamepad) > 0)
|
||||
{
|
||||
@@ -389,11 +398,15 @@ static void sdl3_joypad_disconnect(SDL_JoystickID jid)
|
||||
|
||||
/* Keep the requested sensor state so it can be restored on reconnect. */
|
||||
{
|
||||
bool sensor_accel = sdl3_joypads[i].sensor_accel;
|
||||
bool sensor_gyro = sdl3_joypads[i].sensor_gyro;
|
||||
bool sensor_accel = sdl3_joypads[i].sensor_accel;
|
||||
bool sensor_gyro = sdl3_joypads[i].sensor_gyro;
|
||||
bool sensor_accel_l = sdl3_joypads[i].sensor_accel_l;
|
||||
bool sensor_gyro_l = sdl3_joypads[i].sensor_gyro_l;
|
||||
memset(&sdl3_joypads[i], 0, sizeof(sdl3_joypads[i]));
|
||||
sdl3_joypads[i].sensor_accel = sensor_accel;
|
||||
sdl3_joypads[i].sensor_gyro = sensor_gyro;
|
||||
sdl3_joypads[i].sensor_accel = sensor_accel;
|
||||
sdl3_joypads[i].sensor_gyro = sensor_gyro;
|
||||
sdl3_joypads[i].sensor_accel_l = sensor_accel_l;
|
||||
sdl3_joypads[i].sensor_gyro_l = sensor_gyro_l;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -717,6 +730,28 @@ static bool sdl3_joypad_set_sensor_state(unsigned pad,
|
||||
|
||||
gamepad = sdl3_joypads[pad].gamepad;
|
||||
|
||||
if (RETRO_SENSOR_INDEX(action) == 1)
|
||||
{
|
||||
unsigned base = RETRO_SENSOR_BASE(action);
|
||||
bool gyro = base == RETRO_SENSOR_GYROSCOPE_ENABLE
|
||||
|| base == RETRO_SENSOR_GYROSCOPE_DISABLE;
|
||||
bool enable = base == RETRO_SENSOR_GYROSCOPE_ENABLE
|
||||
|| base == RETRO_SENSOR_ACCELEROMETER_ENABLE;
|
||||
SDL_SensorType type = gyro ? SDL_SENSOR_GYRO_L : SDL_SENSOR_ACCEL_L;
|
||||
|
||||
if ( !gyro
|
||||
&& base != RETRO_SENSOR_ACCELEROMETER_ENABLE
|
||||
&& base != RETRO_SENSOR_ACCELEROMETER_DISABLE)
|
||||
return false;
|
||||
if (gyro)
|
||||
sdl3_joypads[pad].sensor_gyro_l = enable;
|
||||
else
|
||||
sdl3_joypads[pad].sensor_accel_l = enable;
|
||||
if (gamepad && SDL_GamepadHasSensor(gamepad, type))
|
||||
return SDL_SetGamepadSensorEnabled(gamepad, type, enable);
|
||||
return !enable;
|
||||
}
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case RETRO_SENSOR_GYROSCOPE_ENABLE:
|
||||
@@ -759,6 +794,7 @@ static bool sdl3_joypad_get_sensor_input(unsigned pad, unsigned id, float *value
|
||||
{
|
||||
SDL_SensorType sensor_type;
|
||||
float sensor_data[3];
|
||||
bool left;
|
||||
|
||||
if (pad >= MAX_USERS)
|
||||
return false;
|
||||
@@ -766,10 +802,15 @@ static bool sdl3_joypad_get_sensor_input(unsigned pad, unsigned id, float *value
|
||||
if (!sdl3_joypads[pad].gamepad)
|
||||
return false;
|
||||
|
||||
if (RETRO_SENSOR_INDEX(id) > 1)
|
||||
return false;
|
||||
left = RETRO_SENSOR_INDEX(id) == 1;
|
||||
id = RETRO_SENSOR_BASE(id);
|
||||
|
||||
if ((id >= RETRO_SENSOR_ACCELEROMETER_X) && (id <= RETRO_SENSOR_ACCELEROMETER_Z))
|
||||
sensor_type = SDL_SENSOR_ACCEL;
|
||||
sensor_type = left ? SDL_SENSOR_ACCEL_L : SDL_SENSOR_ACCEL;
|
||||
else if ((id >= RETRO_SENSOR_GYROSCOPE_X) && (id <= RETRO_SENSOR_GYROSCOPE_Z))
|
||||
sensor_type = SDL_SENSOR_GYRO;
|
||||
sensor_type = left ? SDL_SENSOR_GYRO_L : SDL_SENSOR_GYRO;
|
||||
else
|
||||
return false;
|
||||
|
||||
|
||||
+67
-6
@@ -1912,10 +1912,11 @@ bool input_driver_set_sensor(
|
||||
{
|
||||
const input_driver_t *current_driver;
|
||||
bool enabled = false;
|
||||
unsigned base = RETRO_SENSOR_BASE(action);
|
||||
bool is_disable =
|
||||
(action == RETRO_SENSOR_ACCELEROMETER_DISABLE)
|
||||
|| (action == RETRO_SENSOR_GYROSCOPE_DISABLE)
|
||||
|| (action == RETRO_SENSOR_ILLUMINANCE_DISABLE);
|
||||
(base == RETRO_SENSOR_ACCELEROMETER_DISABLE)
|
||||
|| (base == RETRO_SENSOR_GYROSCOPE_DISABLE)
|
||||
|| (base == RETRO_SENSOR_ILLUMINANCE_DISABLE);
|
||||
|
||||
if (!input_driver_st.current_data)
|
||||
return false;
|
||||
@@ -8680,6 +8681,7 @@ bool input_set_sensor_state(unsigned port,
|
||||
joy_idx, input_sensors_enable, action, rate);
|
||||
}
|
||||
|
||||
/* ===== BEGIN input core sensor wrappers ===== */
|
||||
/* Core-facing wrappers that track which sensors the core has enabled.
|
||||
* Used as the retro_sensor_interface callbacks so the frontend knows
|
||||
* what the core requested independently of shader/platform enables. */
|
||||
@@ -8687,6 +8689,39 @@ bool input_core_set_sensor_state(unsigned port,
|
||||
enum retro_sensor_action action, unsigned rate)
|
||||
{
|
||||
input_driver_state_t *input_st = &input_driver_st;
|
||||
unsigned idx = RETRO_SENSOR_INDEX(action);
|
||||
|
||||
/* A sub-device's sensor (RETRO_SENSOR_SUBDEVICE): passed on as it
|
||||
* came, for a joypad driver that knows the controller's parts */
|
||||
if (idx)
|
||||
{
|
||||
uint8_t bit;
|
||||
if (idx > INPUT_SENSOR_SUBDEVICES)
|
||||
return false;
|
||||
switch (RETRO_SENSOR_BASE(action))
|
||||
{
|
||||
case RETRO_SENSOR_ACCELEROMETER_ENABLE:
|
||||
case RETRO_SENSOR_ACCELEROMETER_DISABLE:
|
||||
bit = (uint8_t)(1u << (2 * (idx - 1)));
|
||||
break;
|
||||
case RETRO_SENSOR_GYROSCOPE_ENABLE:
|
||||
case RETRO_SENSOR_GYROSCOPE_DISABLE:
|
||||
bit = (uint8_t)(2u << (2 * (idx - 1)));
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if ( RETRO_SENSOR_BASE(action) == RETRO_SENSOR_ACCELEROMETER_ENABLE
|
||||
|| RETRO_SENSOR_BASE(action) == RETRO_SENSOR_GYROSCOPE_ENABLE)
|
||||
{
|
||||
if (!input_set_sensor_state(port, action, rate))
|
||||
return false;
|
||||
input_st->core_sub_sensors |= bit;
|
||||
return true;
|
||||
}
|
||||
input_st->core_sub_sensors &= (uint8_t)~bit;
|
||||
return input_set_sensor_state(port, action, rate);
|
||||
}
|
||||
|
||||
switch (action)
|
||||
{
|
||||
@@ -8713,6 +8748,24 @@ bool input_core_set_sensor_state(unsigned port,
|
||||
float input_core_get_sensor_state(unsigned port, unsigned id)
|
||||
{
|
||||
input_driver_state_t *input_st = &input_driver_st;
|
||||
unsigned idx = RETRO_SENSOR_INDEX(id);
|
||||
|
||||
if (idx)
|
||||
{
|
||||
unsigned base = RETRO_SENSOR_BASE(id);
|
||||
unsigned bit;
|
||||
if (idx > INPUT_SENSOR_SUBDEVICES)
|
||||
return 0.0f;
|
||||
if (base <= RETRO_SENSOR_ACCELEROMETER_Z)
|
||||
bit = 1u << (2 * (idx - 1));
|
||||
else if (base <= RETRO_SENSOR_GYROSCOPE_Z)
|
||||
bit = 2u << (2 * (idx - 1));
|
||||
else
|
||||
return 0.0f;
|
||||
if (!(input_st->core_sub_sensors & bit))
|
||||
return 0.0f;
|
||||
return input_get_sensor_state(port, id);
|
||||
}
|
||||
|
||||
/* Only return data for sensor types the core has enabled */
|
||||
if (id <= RETRO_SENSOR_ACCELEROMETER_Z && !input_st->core_accel_rate)
|
||||
@@ -8724,6 +8777,7 @@ float input_core_get_sensor_state(unsigned port, unsigned id)
|
||||
|
||||
return input_get_sensor_state(port, id);
|
||||
}
|
||||
/* ===== END input core sensor wrappers ===== */
|
||||
|
||||
const char *joypad_driver_name(unsigned i)
|
||||
{
|
||||
@@ -8845,9 +8899,15 @@ static float input_get_sensor_state_internal(
|
||||
unsigned joy_idx;
|
||||
bool input_sensors_enable = false;
|
||||
float sensitivity = 1.0f;
|
||||
unsigned fetch_id = id;
|
||||
/* a sub-device's sensor is turned and scaled as the controller's;
|
||||
* the profile's axis remap is the controller's own */
|
||||
unsigned idx = RETRO_SENSOR_INDEX(id);
|
||||
unsigned fetch_id;
|
||||
float sign = 1.0f;
|
||||
|
||||
id = RETRO_SENSOR_BASE(id);
|
||||
fetch_id = id;
|
||||
|
||||
/* Return 0 if settings unavailable (e.g., during driver transitions) */
|
||||
if (!settings)
|
||||
return 0.0f;
|
||||
@@ -8863,7 +8923,7 @@ static float input_get_sensor_state_internal(
|
||||
return 0.0f;
|
||||
|
||||
/* Apply sensor axis remap from autoconfig profile */
|
||||
if (id <= RETRO_SENSOR_GYROSCOPE_Z)
|
||||
if (!idx && id <= RETRO_SENSOR_GYROSCOPE_Z)
|
||||
{
|
||||
const input_sensor_map_t *map = input_config_get_sensor_map(joy_idx);
|
||||
if (map && map->axes[id].source >= 0)
|
||||
@@ -8942,7 +9002,8 @@ static float input_get_sensor_state_internal(
|
||||
#endif /* HAVE_COCOATOUCH */
|
||||
|
||||
/* Get raw sensor value (use fetch_id for rotated axes) */
|
||||
raw_value = input_driver_get_sensor(joy_idx, true, fetch_id);
|
||||
raw_value = input_driver_get_sensor(joy_idx, true,
|
||||
RETRO_SENSOR_SUBDEVICE(idx, fetch_id));
|
||||
|
||||
/* Apply sensitivity and rotation sign */
|
||||
return raw_value * sensitivity * sign;
|
||||
|
||||
@@ -618,6 +618,9 @@ struct input_driver
|
||||
* changes only in its own poll: lent to the readers between two polls
|
||||
* in place of a copy (input_driver.c, the snapshot bridge). What each
|
||||
* field holds is what button(), axis() and get_buttons() answer. */
|
||||
/* sensor sub-devices a core may address (RETRO_SENSOR_SUBDEVICE),
|
||||
* after the controller itself */
|
||||
#define INPUT_SENSOR_SUBDEVICES 4
|
||||
#define INPUT_PAD_VIEW_AXES 16
|
||||
#define INPUT_PAD_VIEW_HATS 4
|
||||
#define INPUT_PAD_VIEW_TOUCHES 2
|
||||
@@ -1021,6 +1024,9 @@ typedef struct
|
||||
bool platform_menu_button;
|
||||
unsigned core_accel_rate; /* >0 means core wants accel at this rate */
|
||||
unsigned core_gyro_rate; /* >0 means core wants gyro at this rate */
|
||||
/* the sub-devices' sensors the core has enabled: bit 2(i-1) the
|
||||
* accelerometer of sub-device i, bit 2(i-1)+1 its gyroscope */
|
||||
uint8_t core_sub_sensors;
|
||||
/* First-press port assignment, see input_first_press_apply():
|
||||
* buttons seen released on a user with no core port, the users to
|
||||
* map at the next frame boundary, and whether any of it is live. */
|
||||
|
||||
@@ -5724,6 +5724,7 @@ void runloop_event_deinit_core(void)
|
||||
input_driver_state_t *input_st = input_state_get_ptr();
|
||||
input_st->core_accel_rate = 0;
|
||||
input_st->core_gyro_rate = 0;
|
||||
input_st->core_sub_sensors = 0;
|
||||
}
|
||||
|
||||
video_driver_cached_frame_retire();
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
ROOT := ../../..
|
||||
TARGET := sensor_subdevice_test
|
||||
CC ?= cc
|
||||
# The frontend's core sensor wrappers, extracted from input_driver.c
|
||||
# between their markers, so the test runs the shipping code.
|
||||
CFLAGS += -std=gnu99 -O1 -g1 -Wall -DRARCH_INTERNAL \
|
||||
-I. -I$(ROOT) -I$(ROOT)/libretro-common/include -I$(ROOT)/deps
|
||||
ifneq ($(SANITIZER),)
|
||||
CFLAGS += -fsanitize=$(SANITIZER) -fno-omit-frame-pointer
|
||||
LDFLAGS += -fsanitize=$(SANITIZER)
|
||||
endif
|
||||
all: $(TARGET)
|
||||
core_sensor_fragment.c: $(ROOT)/input/input_driver.c
|
||||
sed -n '/===== BEGIN input core sensor wrappers =====/,/===== END input core sensor wrappers =====/p' $< > $@
|
||||
$(TARGET): sensor_subdevice_test.c core_sensor_fragment.c
|
||||
$(CC) $(CFLAGS) -o $@ sensor_subdevice_test.c $(LDFLAGS)
|
||||
check: all
|
||||
./$(TARGET)
|
||||
clean:
|
||||
rm -f $(TARGET) $(TARGET).exe core_sensor_fragment.c
|
||||
.PHONY: all check clean
|
||||
@@ -0,0 +1,118 @@
|
||||
/* A core's sensor calls with a sub-device index (RETRO_SENSOR_SUBDEVICE),
|
||||
* through the frontend's wrappers as they ship (extracted from
|
||||
* input_driver.c between their markers). The controller's own sensors
|
||||
* behave as before; a sub-device's are passed on to the drivers with
|
||||
* the index kept, read only once enabled, and refused past the
|
||||
* sub-devices the frontend tracks. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "input/input_driver.h"
|
||||
|
||||
static input_driver_state_t input_driver_st;
|
||||
|
||||
/* the driver side, stood in for: what it was asked, and its answer */
|
||||
static unsigned last_action, last_id, set_calls, get_calls;
|
||||
static bool driver_has = true;
|
||||
|
||||
bool input_set_sensor_state(unsigned port,
|
||||
enum retro_sensor_action action, unsigned rate)
|
||||
{
|
||||
(void)port; (void)rate;
|
||||
last_action = (unsigned)action;
|
||||
set_calls++;
|
||||
return driver_has;
|
||||
}
|
||||
|
||||
float input_get_sensor_state(unsigned port, unsigned id)
|
||||
{
|
||||
(void)port;
|
||||
last_id = id;
|
||||
get_calls++;
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
#include "core_sensor_fragment.c"
|
||||
|
||||
static unsigned failures;
|
||||
#define CHECK(cond, msg) do { if (!(cond)) { \
|
||||
printf(" FAIL %s\n", msg); failures++; } } while (0)
|
||||
|
||||
#define SUB(i, x) ((enum retro_sensor_action)RETRO_SENSOR_SUBDEVICE((i), (x)))
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* the controller's own: as before */
|
||||
CHECK(RETRO_SENSOR_SUBDEVICE(0, RETRO_SENSOR_GYROSCOPE_Y) == RETRO_SENSOR_GYROSCOPE_Y,
|
||||
"index 0 is not the value in use");
|
||||
CHECK(input_core_get_sensor_state(0, RETRO_SENSOR_ACCELEROMETER_X) == 0.0f,
|
||||
"the accelerometer read before it was enabled");
|
||||
CHECK(input_core_set_sensor_state(0, RETRO_SENSOR_ACCELEROMETER_ENABLE, 60)
|
||||
&& input_driver_st.core_accel_rate == 60, "the accelerometer enable");
|
||||
CHECK(input_core_get_sensor_state(0, RETRO_SENSOR_ACCELEROMETER_X) == 0.5f
|
||||
&& last_id == RETRO_SENSOR_ACCELEROMETER_X, "the accelerometer read");
|
||||
printf(" ok the controller's own sensors behave as before\n");
|
||||
|
||||
/* the Nunchuk's accelerometer: refused while not enabled, passed
|
||||
* on with its index once it is */
|
||||
get_calls = 0;
|
||||
CHECK(input_core_get_sensor_state(0,
|
||||
RETRO_SENSOR_SUBDEVICE(1, RETRO_SENSOR_ACCELEROMETER_X)) == 0.0f
|
||||
&& get_calls == 0, "sub-device 1 read before it was enabled");
|
||||
CHECK(input_core_set_sensor_state(0, SUB(1, RETRO_SENSOR_ACCELEROMETER_ENABLE), 100)
|
||||
&& last_action == RETRO_SENSOR_SUBDEVICE(1, RETRO_SENSOR_ACCELEROMETER_ENABLE),
|
||||
"sub-device 1's enable was not passed on with its index");
|
||||
CHECK(input_driver_st.core_accel_rate == 60,
|
||||
"sub-device 1's enable changed the controller's rate");
|
||||
CHECK(input_core_get_sensor_state(0,
|
||||
RETRO_SENSOR_SUBDEVICE(1, RETRO_SENSOR_ACCELEROMETER_Z)) == 0.5f
|
||||
&& last_id == RETRO_SENSOR_SUBDEVICE(1, RETRO_SENSOR_ACCELEROMETER_Z),
|
||||
"sub-device 1's read was not passed on with its index");
|
||||
get_calls = 0;
|
||||
CHECK(input_core_get_sensor_state(0,
|
||||
RETRO_SENSOR_SUBDEVICE(1, RETRO_SENSOR_GYROSCOPE_X)) == 0.0f
|
||||
&& get_calls == 0, "sub-device 1's gyroscope read without being enabled");
|
||||
printf(" ok a sub-device's sensor is passed on with its index, once enabled\n");
|
||||
|
||||
/* disabled: no more reads */
|
||||
CHECK(input_core_set_sensor_state(0, SUB(1, RETRO_SENSOR_ACCELEROMETER_DISABLE), 0),
|
||||
"sub-device 1's disable");
|
||||
get_calls = 0;
|
||||
CHECK(input_core_get_sensor_state(0,
|
||||
RETRO_SENSOR_SUBDEVICE(1, RETRO_SENSOR_ACCELEROMETER_X)) == 0.0f
|
||||
&& get_calls == 0, "sub-device 1 read after it was disabled");
|
||||
|
||||
/* a frontend driver without it: the enable says so, and nothing reads */
|
||||
driver_has = false;
|
||||
CHECK(!input_core_set_sensor_state(0, SUB(1, RETRO_SENSOR_GYROSCOPE_ENABLE), 100),
|
||||
"a sub-device the drivers do not have was enabled");
|
||||
get_calls = 0;
|
||||
CHECK(input_core_get_sensor_state(0,
|
||||
RETRO_SENSOR_SUBDEVICE(1, RETRO_SENSOR_GYROSCOPE_X)) == 0.0f
|
||||
&& get_calls == 0, "a sub-device that failed to enable was read");
|
||||
driver_has = true;
|
||||
|
||||
/* past what is tracked, and actions with no sensor behind them */
|
||||
set_calls = 0;
|
||||
CHECK(!input_core_set_sensor_state(0,
|
||||
SUB(INPUT_SENSOR_SUBDEVICES + 1, RETRO_SENSOR_ACCELEROMETER_ENABLE), 100)
|
||||
&& set_calls == 0, "a sub-device past the tracked ones was passed on");
|
||||
CHECK(!input_core_set_sensor_state(0, SUB(1, RETRO_SENSOR_ILLUMINANCE_ENABLE), 100)
|
||||
&& set_calls == 0, "a sub-device's light sensor was passed on");
|
||||
CHECK(input_core_get_sensor_state(0,
|
||||
RETRO_SENSOR_SUBDEVICE(INPUT_SENSOR_SUBDEVICES + 1,
|
||||
RETRO_SENSOR_ACCELEROMETER_X)) == 0.0f,
|
||||
"a sub-device past the tracked ones read");
|
||||
printf(" ok disabled, missing and untracked sub-devices read 0\n");
|
||||
|
||||
if (failures)
|
||||
{
|
||||
printf("FAIL sensor_subdevice_test: %u\n", failures);
|
||||
return 1;
|
||||
}
|
||||
printf("PASS sensor_subdevice_test\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user