Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 87 additions & 5 deletions input/drivers_joypad/sdl_joypad.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#include "../../tasks/tasks_internal.h"
#include "../../verbosity.h"

#define SDL_SUPPORTS_RUMBLE SDL_VERSION_ATLEAST(2, 0, 9)
#define SDL_SUPPORTS_SENSORS SDL_VERSION_ATLEAST(2, 0, 14)

typedef struct _sdl_joypad
{
SDL_Joystick *joypad;
Expand Down Expand Up @@ -216,7 +219,7 @@ static void sdl_pad_connect(unsigned id)
RARCH_WARN("[SDL] Device #%u does not support leftright haptic effect.\n", id);
}
}
#if SDL_VERSION_ATLEAST(2, 0, 9)
#if SDL_SUPPORTS_RUMBLE
if (!pad->haptic || pad->rumble_effect == -2)
{
pad->rumble_effect = -3;
Expand Down Expand Up @@ -299,7 +302,7 @@ static void *sdl_joypad_init(void *data)
else
g_has_haptic = true;

#if SDL_VERSION_ATLEAST(2, 0, 9)
#if SDL_SUPPORTS_RUMBLE
/* enable extended hid reports to support ps4/ps5 rumble over bluetooth */
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1");
#endif
Expand Down Expand Up @@ -504,7 +507,7 @@ static bool sdl_joypad_set_rumble(unsigned pad, enum retro_rumble_effect effect,
return false;
}

#if SDL_VERSION_ATLEAST(2, 0, 9)
#if SDK_SUPPORTS_RUMBLE
if (joypad->rumble_effect == -3)
{
if (SDL_JoystickRumble(joypad->joypad, efx.leftright.large_magnitude, efx.leftright.small_magnitude, efx.leftright.length) == -1)
Expand Down Expand Up @@ -548,6 +551,85 @@ static bool sdl_joypad_set_rumble(unsigned pad, enum retro_rumble_effect effect,
}
#endif

static bool sdl_joypad_set_sensor_state(unsigned pad, enum retro_sensor_action action, unsigned rate)
{
sdl_joypad_t *joypad = (sdl_joypad_t*)&sdl_pads[pad];
(void)joypad; /* maybe unused */

switch (action)
{
#if SDL_SUPPORTS_SENSORS
case RETRO_SENSOR_GYROSCOPE_DISABLE:
case RETRO_SENSOR_GYROSCOPE_ENABLE:
if (SDL_GameControllerHasSensor(joypad->controller, SDL_SENSOR_GYRO))
return !SDL_GameControllerSetSensorEnabled(joypad->controller, SDL_SENSOR_GYRO,
action == RETRO_SENSOR_GYROSCOPE_ENABLE);
else
return false;

case RETRO_SENSOR_ACCELEROMETER_DISABLE:
case RETRO_SENSOR_ACCELEROMETER_ENABLE:
if (SDL_GameControllerHasSensor(joypad->controller, SDL_SENSOR_ACCEL))
return !SDL_GameControllerSetSensorEnabled(joypad->controller, SDL_SENSOR_ACCEL,
action == RETRO_SENSOR_ACCELEROMETER_ENABLE);
else
return false;
#endif

default:
return false;
}
return false;
}

static bool sdl_joypad_get_sensor_input(unsigned pad, unsigned id, float *value)
{
#if SDL_SUPPORTS_SENSORS
sdl_joypad_t *joypad = (sdl_joypad_t*)&sdl_pads[pad];
SDL_SensorType sensor_type;
float sensor_data[3];

if (!joypad->controller)
return false;

if ((id >= RETRO_SENSOR_ACCELEROMETER_X) && (id <= RETRO_SENSOR_ACCELEROMETER_Z))
sensor_type = SDL_SENSOR_ACCEL;
else if ((id >= RETRO_SENSOR_GYROSCOPE_X) && (id <= RETRO_SENSOR_GYROSCOPE_Z))
sensor_type = SDL_SENSOR_GYRO;
else
return false;

if (SDL_GameControllerGetSensorData(joypad->controller, sensor_type, sensor_data, 3) < 0)
return false;

switch (id)
{
case RETRO_SENSOR_ACCELEROMETER_X:
*value = sensor_data[0] / SDL_STANDARD_GRAVITY;
break;
case RETRO_SENSOR_ACCELEROMETER_Y:
*value = sensor_data[2] / SDL_STANDARD_GRAVITY;
break;
case RETRO_SENSOR_ACCELEROMETER_Z:
*value = sensor_data[1] / SDL_STANDARD_GRAVITY;
break;
case RETRO_SENSOR_GYROSCOPE_X:
*value = sensor_data[0];
break;
case RETRO_SENSOR_GYROSCOPE_Y:
*value = -sensor_data[2];
break;
case RETRO_SENSOR_GYROSCOPE_Z:
*value = sensor_data[1];
break;
}

return true;
#else
return false;
#endif
}

static bool sdl_joypad_query_pad(unsigned pad)
{
return pad < MAX_USERS && sdl_pads[pad].joypad;
Expand All @@ -568,8 +650,8 @@ input_device_driver_t sdl_joypad = {
NULL, /* set_rumble */
#endif
NULL, /* set_rumble_gain */
NULL, /* set_sensor_state */
NULL, /* get_sensor_input */
sdl_joypad_set_sensor_state,
sdl_joypad_get_sensor_input,
sdl_joypad_name,
#ifdef HAVE_SDL2
"sdl2",
Expand Down
31 changes: 20 additions & 11 deletions input/input_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ bool input_driver_set_sensor(
enum retro_sensor_action action, unsigned rate)
{
const input_driver_t *current_driver;
bool enabled = false;

if (!input_driver_st.current_data)
return false;
Expand All @@ -521,36 +522,44 @@ bool input_driver_set_sensor(
|| (action == RETRO_SENSOR_GYROSCOPE_ENABLE)
|| (action == RETRO_SENSOR_ILLUMINANCE_ENABLE)))
return false;
if ( (current_driver = input_driver_st.current_driver)

if (input_driver_st.primary_joypad && input_driver_st.primary_joypad->set_sensor_state)
enabled = input_driver_st.primary_joypad->set_sensor_state(port, action, rate);

if ( !enabled
&& (current_driver = input_driver_st.current_driver)
&& current_driver->set_sensor_state)
{
void *current_data = input_driver_st.current_data;
return current_driver->set_sensor_state(current_data,
enabled |= current_driver->set_sensor_state(current_data,
port, action, rate);
}
else if (input_driver_st.primary_joypad && input_driver_st.primary_joypad->set_sensor_state)
return input_driver_st.primary_joypad->set_sensor_state(NULL,
port, action, rate);
return false;
return enabled;
}

/**************************************/

float input_driver_get_sensor(
unsigned port, bool sensors_enable, unsigned id)
{
if (!sensors_enable)
return 0.0f;

if (input_driver_st.primary_joypad && input_driver_st.primary_joypad->get_sensor_input)
{
float value;
/* if joypad driver's get_sensor_input returns false, let input driver try */
if (input_driver_st.primary_joypad->get_sensor_input(port, id, &value))
return value;
}
if (input_driver_st.current_data)
{
const input_driver_t *current_driver = input_driver_st.current_driver;
if (sensors_enable && current_driver->get_sensor_input)
if (current_driver->get_sensor_input)
{
void *current_data = input_driver_st.current_data;
return current_driver->get_sensor_input(current_data, port, id);
}
else if (sensors_enable && input_driver_st.primary_joypad &&
input_driver_st.primary_joypad->get_sensor_input)
return input_driver_st.primary_joypad->get_sensor_input(NULL,
port, id);
}

return 0.0f;
Expand Down
5 changes: 3 additions & 2 deletions input/input_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,9 +548,10 @@ struct rarch_joypad_driver
void (*poll)(void);
bool (*set_rumble)(unsigned, enum retro_rumble_effect, uint16_t);
bool (*set_rumble_gain)(unsigned, unsigned);
bool (*set_sensor_state)(void *data, unsigned port,
bool (*set_sensor_state)(unsigned port,
enum retro_sensor_action action, unsigned rate);
float (*get_sensor_input)(void *data, unsigned port, unsigned id);
/* return true if handled; false to fall back to input driver */
bool (*get_sensor_input)(unsigned port, unsigned id, float *value);
const char *(*name)(unsigned);

const char *ident;
Expand Down
Loading