mirror of https://github.com/encounter/SDL.git
Added API for sensors on game controllers
Added support for the PS4 controller gyro and accelerometer on iOS and HIDAPI drivers Also fixed an issue with the accelerometer on iOS having inverted axes
This commit is contained in:
parent
b79e1baa36
commit
fcb21aa883
|
@ -128,6 +128,7 @@ typedef enum
|
|||
SDL_CONTROLLERTOUCHPADDOWN, /**< Game controller touchpad was touched */
|
||||
SDL_CONTROLLERTOUCHPADMOTION, /**< Game controller touchpad finger was moved */
|
||||
SDL_CONTROLLERTOUCHPADUP, /**< Game controller touchpad finger was lifted */
|
||||
SDL_CONTROLLERSENSORUPDATE, /**< Game controller sensor was updated */
|
||||
|
||||
/* Touch events */
|
||||
SDL_FINGERDOWN = 0x700,
|
||||
|
@ -426,13 +427,24 @@ typedef struct SDL_ControllerTouchpadEvent
|
|||
Uint32 type; /**< ::SDL_CONTROLLERTOUCHPADDOWN or ::SDL_CONTROLLERTOUCHPADMOTION or ::SDL_CONTROLLERTOUCHPADUP */
|
||||
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
|
||||
SDL_JoystickID which; /**< The joystick instance id */
|
||||
int touchpad; /**< The index of the touchpad */
|
||||
int finger; /**< The index of the finger on the touchpad */
|
||||
Sint32 touchpad; /**< The index of the touchpad */
|
||||
Sint32 finger; /**< The index of the finger on the touchpad */
|
||||
float x; /**< Normalized in the range 0...1 with 0 being on the left */
|
||||
float y; /**< Normalized in the range 0...1 with 0 being at the top */
|
||||
float pressure; /**< Normalized in the range 0...1 */
|
||||
} SDL_ControllerTouchpadEvent;
|
||||
|
||||
/**
|
||||
* \brief Game controller sensor event structure (event.csensor.*)
|
||||
*/
|
||||
typedef struct SDL_ControllerSensorEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_CONTROLLERSENSORUPDATE */
|
||||
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */
|
||||
SDL_JoystickID which; /**< The joystick instance id */
|
||||
Sint32 sensor; /**< The type of the sensor, one of the values of ::SDL_SensorType */
|
||||
float data[3]; /**< Up to 3 values from the sensor, as defined in SDL_sensor.h */
|
||||
} SDL_ControllerSensorEvent;
|
||||
|
||||
/**
|
||||
* \brief Audio device event structure (event.adevice.*)
|
||||
|
@ -597,6 +609,7 @@ typedef union SDL_Event
|
|||
SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */
|
||||
SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */
|
||||
SDL_ControllerTouchpadEvent ctouchpad; /**< Game Controller touchpad event data */
|
||||
SDL_ControllerSensorEvent csensor; /**< Game Controller sensor event data */
|
||||
SDL_AudioDeviceEvent adevice; /**< Audio device event data */
|
||||
SDL_SensorEvent sensor; /**< Sensor event data */
|
||||
SDL_QuitEvent quit; /**< Quit request event data */
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "SDL_stdinc.h"
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_rwops.h"
|
||||
#include "SDL_sensor.h"
|
||||
#include "SDL_joystick.h"
|
||||
|
||||
#include "begin_code.h"
|
||||
|
@ -430,6 +431,52 @@ extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpadFingers(SDL_GameCont
|
|||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touchpad, int finger, Uint8 *state, float *x, float *y, float *pressure);
|
||||
|
||||
/**
|
||||
* Return whether a game controller has a particular sensor.
|
||||
*
|
||||
* \param gamecontroller The controller to query
|
||||
* \param type The type of sensor to query
|
||||
*
|
||||
* \return SDL_TRUE if the sensor exists, SDL_FALSE otherwise.
|
||||
*/
|
||||
extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasSensor(SDL_GameController *gamecontroller, SDL_SensorType type);
|
||||
|
||||
/**
|
||||
* Set whether data reporting for a game controller sensor is enabled
|
||||
*
|
||||
* \param gamecontroller The controller to update
|
||||
* \param type The type of sensor to enable/disable
|
||||
* \param enabled Whether data reporting should be enabled
|
||||
*
|
||||
* \return 0 or -1 if an error occurred.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GameControllerSetSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type, SDL_bool enabled);
|
||||
|
||||
/**
|
||||
* Query whether sensor data reporting is enabled for a game controller
|
||||
*
|
||||
* \param gamecontroller The controller to query
|
||||
* \param type The type of sensor to query
|
||||
*
|
||||
* \return SDL_TRUE if the sensor is enabled, SDL_FALSE otherwise.
|
||||
*/
|
||||
extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerIsSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type);
|
||||
|
||||
/**
|
||||
* Get the current state of a game controller sensor.
|
||||
*
|
||||
* The number of values and interpretation of the data is sensor dependent.
|
||||
* See SDL_sensor.h for the details for each type of sensor.
|
||||
*
|
||||
* \param gamecontroller The controller to query
|
||||
* \param type The type of sensor to query
|
||||
* \param data A pointer filled with the current sensor state
|
||||
* \param num_values The number of values to write to data
|
||||
*
|
||||
* \return 0 or -1 if an error occurred.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GameControllerGetSensorData(SDL_GameController *gamecontroller, SDL_SensorType type, float *data, int num_values);
|
||||
|
||||
/**
|
||||
* Start a rumble effect
|
||||
* Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.
|
||||
|
|
|
@ -78,14 +78,16 @@ typedef enum
|
|||
* Accelerometer sensor
|
||||
*
|
||||
* The accelerometer returns the current acceleration in SI meters per
|
||||
* second squared. This includes gravity, so a device at rest will have
|
||||
* an acceleration of SDL_STANDARD_GRAVITY straight down.
|
||||
* second squared. This measurement includes the force of gravity, so
|
||||
* a device at rest will have an value of SDL_STANDARD_GRAVITY away
|
||||
* from the center of the earth.
|
||||
*
|
||||
* values[0]: Acceleration on the x axis
|
||||
* values[1]: Acceleration on the y axis
|
||||
* values[2]: Acceleration on the z axis
|
||||
*
|
||||
* For phones held in portrait mode, the axes are defined as follows:
|
||||
* For phones held in portrait mode and game controllers held in front of you,
|
||||
* the axes are defined as follows:
|
||||
* -X ... +X : left ... right
|
||||
* -Y ... +Y : bottom ... top
|
||||
* -Z ... +Z : farther ... closer
|
||||
|
@ -105,16 +107,17 @@ typedef enum
|
|||
* see positive rotation on that axis when it appeared to be rotating
|
||||
* counter-clockwise.
|
||||
*
|
||||
* values[0]: Angular speed around the x axis
|
||||
* values[1]: Angular speed around the y axis
|
||||
* values[2]: Angular speed around the z axis
|
||||
* values[0]: Angular speed around the x axis (pitch)
|
||||
* values[1]: Angular speed around the y axis (yaw)
|
||||
* values[2]: Angular speed around the z axis (roll)
|
||||
*
|
||||
* For phones held in portrait mode, the axes are defined as follows:
|
||||
* For phones held in portrait mode and game controllers held in front of you,
|
||||
* the axes are defined as follows:
|
||||
* -X ... +X : left ... right
|
||||
* -Y ... +Y : bottom ... top
|
||||
* -Z ... +Z : farther ... closer
|
||||
*
|
||||
* The axis data is not changed when the phone is rotated.
|
||||
* The axis data is not changed when the phone or controller is rotated.
|
||||
*
|
||||
* \sa SDL_GetDisplayOrientation()
|
||||
*/
|
||||
|
|
|
@ -782,3 +782,7 @@
|
|||
#define SDL_crc32 SDL_crc32_REAL
|
||||
#define SDL_GameControllerGetSerial SDL_GameControllerGetSerial_REAL
|
||||
#define SDL_JoystickGetSerial SDL_JoystickGetSerial_REAL
|
||||
#define SDL_GameControllerHasSensor SDL_GameControllerHasSensor_REAL
|
||||
#define SDL_GameControllerSetSensorEnabled SDL_GameControllerSetSensorEnabled_REAL
|
||||
#define SDL_GameControllerIsSensorEnabled SDL_GameControllerIsSensorEnabled_REAL
|
||||
#define SDL_GameControllerGetSensorData SDL_GameControllerGetSensorData_REAL
|
||||
|
|
|
@ -843,3 +843,7 @@ SDL_DYNAPI_PROC(int,SDL_GameControllerGetTouchpadFinger,(SDL_GameController *a,
|
|||
SDL_DYNAPI_PROC(Uint32,SDL_crc32,(Uint32 a, const void *b, size_t c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_GameControllerGetSerial,(SDL_GameController *a),(a),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_JoystickGetSerial,(SDL_Joystick *a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasSensor,(SDL_GameController *a, SDL_SensorType b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GameControllerSetSensorEnabled,(SDL_GameController *a, SDL_SensorType b, SDL_bool c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerIsSensorEnabled,(SDL_GameController *a, SDL_SensorType b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GameControllerGetSensorData,(SDL_GameController *a, SDL_SensorType b, float *c, int d),(a,b,c,d),return)
|
||||
|
|
|
@ -2059,6 +2059,111 @@ SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touc
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a game controller has a particular sensor.
|
||||
*/
|
||||
SDL_bool
|
||||
SDL_GameControllerHasSensor(SDL_GameController *gamecontroller, SDL_SensorType type)
|
||||
{
|
||||
SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller);
|
||||
int i;
|
||||
|
||||
if (joystick) {
|
||||
for (i = 0; i < joystick->nsensors; ++i) {
|
||||
if (joystick->sensors[i].type == type) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set whether data reporting for a game controller sensor is enabled
|
||||
*/
|
||||
int SDL_GameControllerSetSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type, SDL_bool enabled)
|
||||
{
|
||||
SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller);
|
||||
int i;
|
||||
|
||||
if (!joystick) {
|
||||
return SDL_InvalidParamError("gamecontroller");
|
||||
}
|
||||
|
||||
for (i = 0; i < joystick->nsensors; ++i) {
|
||||
SDL_JoystickSensorInfo *sensor = &joystick->sensors[i];
|
||||
|
||||
if (sensor->type == type) {
|
||||
if (sensor->enabled == enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
if (joystick->nsensors_enabled == 0) {
|
||||
if (joystick->driver->SetSensorsEnabled(joystick, SDL_TRUE) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
++joystick->nsensors_enabled;
|
||||
} else {
|
||||
if (joystick->nsensors_enabled == 1) {
|
||||
if (joystick->driver->SetSensorsEnabled(joystick, SDL_FALSE) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
--joystick->nsensors_enabled;
|
||||
}
|
||||
|
||||
sensor->enabled = enabled;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
/*
|
||||
* Query whether sensor data reporting is enabled for a game controller
|
||||
*/
|
||||
SDL_bool SDL_GameControllerIsSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type)
|
||||
{
|
||||
SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller);
|
||||
int i;
|
||||
|
||||
if (joystick) {
|
||||
for (i = 0; i < joystick->nsensors; ++i) {
|
||||
if (joystick->sensors[i].type == type) {
|
||||
return joystick->sensors[i].enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current state of a game controller sensor.
|
||||
*/
|
||||
int
|
||||
SDL_GameControllerGetSensorData(SDL_GameController *gamecontroller, SDL_SensorType type, float *data, int num_values)
|
||||
{
|
||||
SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller);
|
||||
int i;
|
||||
|
||||
if (!joystick) {
|
||||
return SDL_InvalidParamError("gamecontroller");
|
||||
}
|
||||
|
||||
for (i = 0; i < joystick->nsensors; ++i) {
|
||||
SDL_JoystickSensorInfo *sensor = &joystick->sensors[i];
|
||||
|
||||
if (sensor->type == type) {
|
||||
num_values = SDL_min(num_values, SDL_arraysize(sensor->data));
|
||||
SDL_memcpy(data, sensor->data, num_values*sizeof(*data));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
const char *
|
||||
SDL_GameControllerName(SDL_GameController *gamecontroller)
|
||||
{
|
||||
|
|
|
@ -1109,7 +1109,7 @@ SDL_PrivateJoystickShouldIgnoreEvent()
|
|||
void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers)
|
||||
{
|
||||
int ntouchpads = joystick->ntouchpads + 1;
|
||||
SDL_JoystickTouchpadInfo *touchpads = (SDL_JoystickTouchpadInfo *)SDL_realloc(joystick->touchpads, sizeof(SDL_JoystickTouchpadInfo));
|
||||
SDL_JoystickTouchpadInfo *touchpads = (SDL_JoystickTouchpadInfo *)SDL_realloc(joystick->touchpads, (ntouchpads * sizeof(SDL_JoystickTouchpadInfo)));
|
||||
if (touchpads) {
|
||||
SDL_JoystickTouchpadInfo *touchpad = &touchpads[ntouchpads - 1];
|
||||
SDL_JoystickTouchpadFingerInfo *fingers = (SDL_JoystickTouchpadFingerInfo *)SDL_calloc(nfingers, sizeof(SDL_JoystickTouchpadFingerInfo));
|
||||
|
@ -1128,6 +1128,21 @@ void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers)
|
|||
}
|
||||
}
|
||||
|
||||
void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type)
|
||||
{
|
||||
int nsensors = joystick->nsensors + 1;
|
||||
SDL_JoystickSensorInfo *sensors = (SDL_JoystickSensorInfo *)SDL_realloc(joystick->sensors, (nsensors * sizeof(SDL_JoystickSensorInfo)));
|
||||
if (sensors) {
|
||||
SDL_JoystickSensorInfo *sensor = &sensors[nsensors - 1];
|
||||
|
||||
SDL_zerop(sensor);
|
||||
sensor->type = type;
|
||||
|
||||
joystick->nsensors = nsensors;
|
||||
joystick->sensors = sensors;
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
|
||||
{
|
||||
SDL_JoystickDriver *driver;
|
||||
|
@ -2463,8 +2478,8 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
|
|||
{
|
||||
SDL_JoystickTouchpadInfo *touchpad_info;
|
||||
SDL_JoystickTouchpadFingerInfo *finger_info;
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
int posted;
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
Uint32 event_type;
|
||||
#endif
|
||||
|
||||
|
@ -2544,4 +2559,41 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
|
|||
return posted;
|
||||
}
|
||||
|
||||
int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, SDL_SensorType type, const float *data, int num_values)
|
||||
{
|
||||
int i;
|
||||
int posted = 0;
|
||||
|
||||
for (i = 0; i < joystick->nsensors; ++i) {
|
||||
SDL_JoystickSensorInfo *sensor = &joystick->sensors[i];
|
||||
|
||||
if (sensor->type == type) {
|
||||
if (sensor->enabled) {
|
||||
/* Allow duplicate events, for things like gyro updates */
|
||||
|
||||
/* Update internal sensor state */
|
||||
num_values = SDL_min(num_values, SDL_arraysize(sensor->data));
|
||||
SDL_memcpy(sensor->data, data, num_values*sizeof(*data));
|
||||
|
||||
/* Post the event, if desired */
|
||||
posted = 0;
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
if (SDL_GetEventState(SDL_CONTROLLERSENSORUPDATE) == SDL_ENABLE) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_CONTROLLERSENSORUPDATE;
|
||||
event.csensor.which = joystick->instance_id;
|
||||
event.csensor.sensor = type;
|
||||
num_values = SDL_min(num_values, SDL_arraysize(event.csensor.data));
|
||||
SDL_memset(event.csensor.data, 0, sizeof(event.csensor.data));
|
||||
SDL_memcpy(event.csensor.data, data, num_values*sizeof(*data));
|
||||
posted = SDL_PushEvent(&event) == 1;
|
||||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return posted;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -109,6 +109,7 @@ extern void SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick);
|
|||
|
||||
/* Internal event queueing functions */
|
||||
extern void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers);
|
||||
extern void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type);
|
||||
extern void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance);
|
||||
extern void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance);
|
||||
extern int SDL_PrivateJoystickAxis(SDL_Joystick *joystick,
|
||||
|
@ -121,6 +122,8 @@ extern int SDL_PrivateJoystickButton(SDL_Joystick *joystick,
|
|||
Uint8 button, Uint8 state);
|
||||
extern int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick,
|
||||
int touchpad, int finger, Uint8 state, float x, float y, float pressure);
|
||||
extern int SDL_PrivateJoystickSensor(SDL_Joystick *joystick,
|
||||
SDL_SensorType type, const float *data, int num_values);
|
||||
extern void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick,
|
||||
SDL_JoystickPowerLevel ePowerLevel);
|
||||
|
||||
|
|
|
@ -53,6 +53,13 @@ typedef struct _SDL_JoystickTouchpadInfo
|
|||
SDL_JoystickTouchpadFingerInfo *fingers;
|
||||
} SDL_JoystickTouchpadInfo;
|
||||
|
||||
typedef struct _SDL_JoystickSensorInfo
|
||||
{
|
||||
SDL_SensorType type;
|
||||
SDL_bool enabled;
|
||||
float data[3]; /* If this needs to expand, update SDL_ControllerSensorEvent */
|
||||
} SDL_JoystickSensorInfo;
|
||||
|
||||
struct _SDL_Joystick
|
||||
{
|
||||
SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */
|
||||
|
@ -78,6 +85,10 @@ struct _SDL_Joystick
|
|||
int ntouchpads; /* Number of touchpads on the joystick */
|
||||
SDL_JoystickTouchpadInfo *touchpads; /* Current touchpad states */
|
||||
|
||||
int nsensors; /* Number of sensors on the joystick */
|
||||
int nsensors_enabled;
|
||||
SDL_JoystickSensorInfo *sensors;
|
||||
|
||||
Uint16 low_frequency_rumble;
|
||||
Uint16 high_frequency_rumble;
|
||||
Uint32 rumble_expiration;
|
||||
|
@ -94,6 +105,7 @@ struct _SDL_Joystick
|
|||
SDL_bool is_game_controller;
|
||||
SDL_bool delayed_guide_button; /* SDL_TRUE if this device has the guide button event delayed */
|
||||
SDL_JoystickPowerLevel epowerlevel; /* power level of this joystick, SDL_JOYSTICK_POWER_UNKNOWN if not supported */
|
||||
|
||||
struct _SDL_JoystickDriver *driver;
|
||||
|
||||
struct joystick_hwdata *hwdata; /* Driver dependent information */
|
||||
|
@ -154,6 +166,9 @@ typedef struct _SDL_JoystickDriver
|
|||
SDL_bool (*HasLED)(SDL_Joystick *joystick);
|
||||
int (*SetLED)(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue);
|
||||
|
||||
/* Sensor functionality */
|
||||
int (*SetSensorsEnabled)(SDL_Joystick *joystick, SDL_bool enabled);
|
||||
|
||||
/* Function to update the state of a joystick - called as a device poll.
|
||||
* This function shouldn't update the joystick structure directly,
|
||||
* but instead should call SDL_PrivateJoystick*() to deliver events
|
||||
|
|
|
@ -630,6 +630,12 @@ ANDROID_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 bl
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
ANDROID_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void
|
||||
ANDROID_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
|
@ -711,6 +717,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
|
|||
ANDROID_JoystickRumbleTriggers,
|
||||
ANDROID_JoystickHasLED,
|
||||
ANDROID_JoystickSetLED,
|
||||
ANDROID_JoystickSetSensorsEnabled,
|
||||
ANDROID_JoystickUpdate,
|
||||
ANDROID_JoystickClose,
|
||||
ANDROID_JoystickQuit,
|
||||
|
|
|
@ -786,6 +786,12 @@ BSD_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
BSD_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
SDL_JoystickDriver SDL_BSD_JoystickDriver =
|
||||
{
|
||||
BSD_JoystickInit,
|
||||
|
@ -801,6 +807,7 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver =
|
|||
BSD_JoystickRumbleTriggers,
|
||||
BSD_JoystickHasLED,
|
||||
BSD_JoystickSetLED,
|
||||
BSD_JoystickSetSensorsEnabled,
|
||||
BSD_JoystickUpdate,
|
||||
BSD_JoystickClose,
|
||||
BSD_JoystickQuit,
|
||||
|
|
|
@ -940,6 +940,12 @@ DARWIN_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blu
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
DARWIN_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void
|
||||
DARWIN_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
|
@ -1090,6 +1096,7 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver =
|
|||
DARWIN_JoystickRumbleTriggers,
|
||||
DARWIN_JoystickHasLED,
|
||||
DARWIN_JoystickSetLED,
|
||||
DARWIN_JoystickSetSensorsEnabled,
|
||||
DARWIN_JoystickUpdate,
|
||||
DARWIN_JoystickClose,
|
||||
DARWIN_JoystickQuit,
|
||||
|
|
|
@ -107,6 +107,12 @@ DUMMY_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
DUMMY_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void
|
||||
DUMMY_JoystickUpdate(SDL_Joystick *joystick)
|
||||
{
|
||||
|
@ -143,6 +149,7 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver =
|
|||
DUMMY_JoystickRumbleTriggers,
|
||||
DUMMY_JoystickHasLED,
|
||||
DUMMY_JoystickSetLED,
|
||||
DUMMY_JoystickSetSensorsEnabled,
|
||||
DUMMY_JoystickUpdate,
|
||||
DUMMY_JoystickClose,
|
||||
DUMMY_JoystickQuit,
|
||||
|
|
|
@ -427,6 +427,12 @@ EMSCRIPTEN_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
EMSCRIPTEN_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver =
|
||||
{
|
||||
EMSCRIPTEN_JoystickInit,
|
||||
|
@ -442,6 +448,7 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver =
|
|||
EMSCRIPTEN_JoystickRumbleTriggers,
|
||||
EMSCRIPTEN_JoystickHasLED,
|
||||
EMSCRIPTEN_JoystickSetLED,
|
||||
EMSCRIPTEN_JoystickSetSensorsEnabled,
|
||||
EMSCRIPTEN_JoystickUpdate,
|
||||
EMSCRIPTEN_JoystickClose,
|
||||
EMSCRIPTEN_JoystickQuit,
|
||||
|
|
|
@ -281,6 +281,11 @@ extern "C"
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int HAIKU_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
SDL_JoystickDriver SDL_HAIKU_JoystickDriver =
|
||||
{
|
||||
HAIKU_JoystickInit,
|
||||
|
@ -296,6 +301,7 @@ extern "C"
|
|||
HAIKU_JoystickRumbleTriggers,
|
||||
HAIKU_JoystickHasLED,
|
||||
HAIKU_JoystickSetLED,
|
||||
HAIKU_JoystickSetSensorsEnabled,
|
||||
HAIKU_JoystickUpdate,
|
||||
HAIKU_JoystickClose,
|
||||
HAIKU_JoystickQuit,
|
||||
|
|
|
@ -381,6 +381,12 @@ HIDAPI_DriverGameCube_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *jo
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_DriverGameCube_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverGameCube_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
|
@ -423,6 +429,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
|
|||
HIDAPI_DriverGameCube_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverGameCube_HasJoystickLED,
|
||||
HIDAPI_DriverGameCube_SetJoystickLED,
|
||||
HIDAPI_DriverGameCube_SetJoystickSensorsEnabled,
|
||||
HIDAPI_DriverGameCube_CloseJoystick,
|
||||
HIDAPI_DriverGameCube_FreeDevice,
|
||||
NULL,
|
||||
|
|
|
@ -37,6 +37,17 @@
|
|||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_PS4
|
||||
|
||||
/* Define this if you want to log all packets from the controller */
|
||||
/*#define DEBUG_PS4_PROTOCOL*/
|
||||
|
||||
/* Define this if you want to log calibration data */
|
||||
/*#define DEBUG_PS4_CALIBRATION*/
|
||||
|
||||
#define GYRO_RES_PER_DEGREE 1024.0f
|
||||
#define ACCEL_RES_PER_G 8192.0f
|
||||
|
||||
#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
k_EPS4ReportIdUsbState = 1,
|
||||
|
@ -71,12 +82,12 @@ typedef struct
|
|||
Uint8 ucTriggerLeft;
|
||||
Uint8 ucTriggerRight;
|
||||
Uint8 _rgucPad0[ 3 ];
|
||||
Sint16 sGyroX;
|
||||
Sint16 sGyroY;
|
||||
Sint16 sGyroZ;
|
||||
Sint16 sAccelX;
|
||||
Sint16 sAccelY;
|
||||
Sint16 sAccelZ;
|
||||
Uint8 rgucGyroX[2];
|
||||
Uint8 rgucGyroY[2];
|
||||
Uint8 rgucGyroZ[2];
|
||||
Uint8 rgucAccelX[2];
|
||||
Uint8 rgucAccelY[2];
|
||||
Uint8 rgucAccelZ[2];
|
||||
Uint8 _rgucPad1[ 5 ];
|
||||
Uint8 ucBatteryLevel;
|
||||
Uint8 _rgucPad2[ 4 ];
|
||||
|
@ -102,11 +113,20 @@ typedef struct
|
|||
Uint8 ucVolumeSpeaker;
|
||||
} DS4EffectsState_t;
|
||||
|
||||
typedef struct {
|
||||
Sint16 bias;
|
||||
float sensitivity;
|
||||
} IMUCalibrationData;
|
||||
|
||||
typedef struct {
|
||||
SDL_bool is_dongle;
|
||||
SDL_bool is_bluetooth;
|
||||
SDL_bool official_controller;
|
||||
SDL_bool audio_supported;
|
||||
SDL_bool effects_supported;
|
||||
SDL_bool report_sensors;
|
||||
SDL_bool hardware_calibration;
|
||||
IMUCalibrationData calibration[6];
|
||||
int player_index;
|
||||
Uint8 rumble_left;
|
||||
Uint8 rumble_right;
|
||||
|
@ -191,6 +211,168 @@ HIDAPI_DriverPS4_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverPS4_LoadCalibrationData(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
|
||||
int i, tries, size;
|
||||
SDL_bool have_data = SDL_FALSE;
|
||||
Uint8 data[USB_PACKET_LENGTH];
|
||||
|
||||
if (!ctx->official_controller) {
|
||||
#ifdef DEBUG_PS4_CALIBRATION
|
||||
SDL_Log("Not an official controller, ignoring calibration\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
for( tries = 0; tries < 5; ++tries ) {
|
||||
/* For Bluetooth controllers, this report switches them into advanced report mode */
|
||||
size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdGyroCalibration_USB, data, sizeof(data));
|
||||
if (size < 35) {
|
||||
#ifdef DEBUG_PS4_CALIBRATION
|
||||
SDL_Log("Short read of calibration data: %d, ignoring calibration\n", size);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->is_bluetooth) {
|
||||
size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdGyroCalibration_BT, data, sizeof(data));
|
||||
if (size < 35) {
|
||||
#ifdef DEBUG_PS4_CALIBRATION
|
||||
SDL_Log("Short read of calibration data: %d, ignoring calibration\n", size);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* In some cases this report returns all zeros. Usually immediately after connection with the PS4 Dongle */
|
||||
for (i = 0; i < size; ++i) {
|
||||
if (data[i]) {
|
||||
have_data = SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (have_data) {
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_Delay(2);
|
||||
}
|
||||
|
||||
if (have_data) {
|
||||
Sint16 sGyroPitchBias, sGyroYawBias, sGyroRollBias;
|
||||
Sint16 sGyroPitchPlus, sGyroPitchMinus;
|
||||
Sint16 sGyroYawPlus, sGyroYawMinus;
|
||||
Sint16 sGyroRollPlus, sGyroRollMinus;
|
||||
Sint16 sGyroSpeedPlus, sGyroSpeedMinus;
|
||||
|
||||
Sint16 sAccXPlus, sAccXMinus;
|
||||
Sint16 sAccYPlus, sAccYMinus;
|
||||
Sint16 sAccZPlus, sAccZMinus;
|
||||
|
||||
float flNumerator;
|
||||
Sint16 sRange2g;
|
||||
|
||||
#ifdef DEBUG_PS4_CALIBRATION
|
||||
HIDAPI_DumpPacket("PS4 calibration packet: size = %d", data, size);
|
||||
#endif
|
||||
|
||||
sGyroPitchBias = LOAD16(data[1], data[2]);
|
||||
sGyroYawBias = LOAD16(data[3], data[4]);
|
||||
sGyroRollBias = LOAD16(data[5], data[6]);
|
||||
|
||||
if (ctx->is_bluetooth || ctx->is_dongle) {
|
||||
sGyroPitchPlus = LOAD16(data[7], data[8]);
|
||||
sGyroYawPlus = LOAD16(data[9], data[10]);
|
||||
sGyroRollPlus = LOAD16(data[11], data[12]);
|
||||
sGyroPitchMinus = LOAD16(data[13], data[14]);
|
||||
sGyroYawMinus = LOAD16(data[15], data[16]);
|
||||
sGyroRollMinus = LOAD16(data[17], data[18]);
|
||||
} else {
|
||||
sGyroPitchPlus = LOAD16(data[7], data[8]);
|
||||
sGyroPitchMinus = LOAD16(data[9], data[10]);
|
||||
sGyroYawPlus = LOAD16(data[11], data[12]);
|
||||
sGyroYawMinus = LOAD16(data[13], data[14]);
|
||||
sGyroRollPlus = LOAD16(data[15], data[16]);
|
||||
sGyroRollMinus = LOAD16(data[17], data[18]);
|
||||
}
|
||||
|
||||
sGyroSpeedPlus = LOAD16(data[19], data[20]);
|
||||
sGyroSpeedMinus = LOAD16(data[21], data[22]);
|
||||
|
||||
sAccXPlus = LOAD16(data[23], data[24]);
|
||||
sAccXMinus = LOAD16(data[25], data[26]);
|
||||
sAccYPlus = LOAD16(data[27], data[28]);
|
||||
sAccYMinus = LOAD16(data[29], data[30]);
|
||||
sAccZPlus = LOAD16(data[31], data[32]);
|
||||
sAccZMinus = LOAD16(data[33], data[34]);
|
||||
|
||||
flNumerator = (sGyroSpeedPlus + sGyroSpeedMinus) * GYRO_RES_PER_DEGREE;
|
||||
ctx->calibration[0].bias = sGyroPitchBias;
|
||||
ctx->calibration[0].sensitivity = flNumerator / (sGyroPitchPlus - sGyroPitchMinus);
|
||||
|
||||
ctx->calibration[1].bias = sGyroYawBias;
|
||||
ctx->calibration[1].sensitivity = flNumerator / (sGyroYawPlus - sGyroYawMinus);
|
||||
|
||||
ctx->calibration[2].bias = sGyroRollBias;
|
||||
ctx->calibration[2].sensitivity = flNumerator / (sGyroRollPlus - sGyroRollMinus);
|
||||
|
||||
sRange2g = sAccXPlus - sAccXMinus;
|
||||
ctx->calibration[3].bias = sAccXPlus - sRange2g / 2;
|
||||
ctx->calibration[3].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g;
|
||||
|
||||
sRange2g = sAccYPlus - sAccYMinus;
|
||||
ctx->calibration[4].bias = sAccYPlus - sRange2g / 2;
|
||||
ctx->calibration[4].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g;
|
||||
|
||||
sRange2g = sAccZPlus - sAccZMinus;
|
||||
ctx->calibration[5].bias = sAccZPlus - sRange2g / 2;
|
||||
ctx->calibration[5].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g;
|
||||
|
||||
ctx->hardware_calibration = SDL_TRUE;
|
||||
for (i = 0; i < 6; ++i) {
|
||||
float divisor = (i < 3 ? 64.0f : 1.0f);
|
||||
#ifdef DEBUG_PS4_CALIBRATION
|
||||
SDL_Log("calibration[%d] bias = %d, sensitivity = %f\n", i, ctx->calibration[i].bias, ctx->calibration[i].sensitivity);
|
||||
#endif
|
||||
/* Some controllers have a bad calibration */
|
||||
if ((SDL_abs(ctx->calibration[i].bias) > 1024) || (SDL_fabs(1.0f - ctx->calibration[i].sensitivity / divisor) > 0.5f)) {
|
||||
#ifdef DEBUG_PS4_CALIBRATION
|
||||
SDL_Log("invalid calibration, ignoring\n");
|
||||
#endif
|
||||
ctx->hardware_calibration = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG_PS4_CALIBRATION
|
||||
SDL_Log("Calibration data not available\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static float
|
||||
HIDAPI_DriverPS4_ApplyCalibrationData(SDL_DriverPS4_Context *ctx, int index, Sint16 value)
|
||||
{
|
||||
float result;
|
||||
|
||||
if (ctx->hardware_calibration) {
|
||||
IMUCalibrationData *calibration = &ctx->calibration[index];
|
||||
|
||||
result = (value - calibration->bias) * calibration->sensitivity;
|
||||
} else {
|
||||
result = value;
|
||||
}
|
||||
|
||||
/* Convert the raw data to the units expected by SDL */
|
||||
if (index < 3) {
|
||||
result = (result / GYRO_RES_PER_DEGREE) * M_PI / 180.0f;
|
||||
} else {
|
||||
result = (result / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_DriverPS4_UpdateEffects(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
|
@ -286,37 +468,24 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
|||
ctx->is_dongle = (device->vendor_id == USB_VENDOR_SONY && device->product_id == USB_PRODUCT_SONY_DS4_DONGLE);
|
||||
if (ctx->is_dongle) {
|
||||
ctx->is_bluetooth = SDL_FALSE;
|
||||
ctx->official_controller = SDL_TRUE;
|
||||
} else if (device->vendor_id == USB_VENDOR_SONY) {
|
||||
int i;
|
||||
Uint8 data[USB_PACKET_LENGTH];
|
||||
int length;
|
||||
int size;
|
||||
|
||||
/* This will fail if we're on Bluetooth */
|
||||
length = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdSerialNumber, data, sizeof(data));
|
||||
if (length >= 7) {
|
||||
SDL_bool had_data = SDL_FALSE;
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
if (data[i] != 0x00) {
|
||||
had_data = SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (had_data) {
|
||||
size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdSerialNumber, data, sizeof(data));
|
||||
if (size >= 7) {
|
||||
char serial[18];
|
||||
|
||||
SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
|
||||
data[6], data[5], data[4], data[3], data[2], data[1]);
|
||||
joystick->serial = SDL_strdup(serial);
|
||||
} else {
|
||||
/* Maybe the dongle without a connected controller? */
|
||||
}
|
||||
|
||||
ctx->is_bluetooth = SDL_FALSE;
|
||||
} else {
|
||||
ctx->is_bluetooth = SDL_TRUE;
|
||||
}
|
||||
ctx->official_controller = SDL_TRUE;
|
||||
} else {
|
||||
/* Third party controllers appear to all be wired */
|
||||
ctx->is_bluetooth = SDL_FALSE;
|
||||
|
@ -351,6 +520,8 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
|||
joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
|
||||
|
||||
SDL_PrivateJoystickAddTouchpad(joystick, 2);
|
||||
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO);
|
||||
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL);
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
@ -391,6 +562,19 @@ HIDAPI_DriverPS4_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
|
|||
return HIDAPI_DriverPS4_UpdateEffects(device);
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
|
||||
|
||||
if (enabled) {
|
||||
HIDAPI_DriverPS4_LoadCalibrationData(device);
|
||||
}
|
||||
ctx->report_sensors = enabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet)
|
||||
{
|
||||
|
@ -521,6 +705,20 @@ HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_
|
|||
touchpad_y = (packet->rgucTouchpadData2[1] >> 4) | ((int)packet->rgucTouchpadData2[2] << 4);
|
||||
SDL_PrivateJoystickTouchpad(joystick, 0, 1, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f);
|
||||
|
||||
if (ctx->report_sensors) {
|
||||
float data[3];
|
||||
|
||||
data[0] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 0, LOAD16(packet->rgucGyroX[0], packet->rgucGyroX[1]));
|
||||
data[1] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 1, LOAD16(packet->rgucGyroY[0], packet->rgucGyroY[1]));
|
||||
data[2] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 2, LOAD16(packet->rgucGyroZ[0], packet->rgucGyroZ[1]));
|
||||
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, data, 3);
|
||||
|
||||
data[0] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 3, LOAD16(packet->rgucAccelX[0], packet->rgucAccelX[1]));
|
||||
data[1] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 4, LOAD16(packet->rgucAccelY[0], packet->rgucAccelY[1]));
|
||||
data[2] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 5, LOAD16(packet->rgucAccelZ[0], packet->rgucAccelZ[1]));
|
||||
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, data, 3);
|
||||
}
|
||||
|
||||
SDL_memcpy(&ctx->last_state, packet, sizeof(ctx->last_state));
|
||||
}
|
||||
|
||||
|
@ -540,6 +738,9 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_PS4_PROTOCOL
|
||||
HIDAPI_DumpPacket("PS4 packet: size = %d", data, size);
|
||||
#endif
|
||||
switch (data[0]) {
|
||||
case k_EPS4ReportIdUsbState:
|
||||
HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t *)&data[1]);
|
||||
|
@ -603,6 +804,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
|
|||
HIDAPI_DriverPS4_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverPS4_HasJoystickLED,
|
||||
HIDAPI_DriverPS4_SetJoystickLED,
|
||||
HIDAPI_DriverPS4_SetJoystickSensorsEnabled,
|
||||
HIDAPI_DriverPS4_CloseJoystick,
|
||||
HIDAPI_DriverPS4_FreeDevice,
|
||||
NULL
|
||||
|
|
|
@ -72,8 +72,12 @@ typedef struct
|
|||
Uint8 rgucButtonsAndHat[3]; /* 7 */
|
||||
Uint8 ucZero; /* 10 */
|
||||
Uint8 rgucPacketSequence[4]; /* 11 - 32 bit little endian */
|
||||
Uint8 rgucAccel[6]; /* 15 */
|
||||
Uint8 rgucGyro[6]; /* 21 */
|
||||
Uint8 rgucGyroX[2]; /* 15 */
|
||||
Uint8 rgucGyroY[2]; /* 17 */
|
||||
Uint8 rgucGyroZ[2]; /* 19 */
|
||||
Uint8 rgucAccelX[2]; /* 21 */
|
||||
Uint8 rgucAccelY[2]; /* 23 */
|
||||
Uint8 rgucAccelZ[2]; /* 25 */
|
||||
Uint8 rgucTimer1[4]; /* 27 - 32 bit little endian */
|
||||
Uint8 ucBatteryTemp; /* 31 */
|
||||
Uint8 ucTouchpadCounter1; /* 32 - high bit clear + counter */
|
||||
|
@ -351,6 +355,12 @@ HIDAPI_DriverPS5_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
|
|||
return HIDAPI_DriverPS5_UpdateEffects(device);
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_DriverPS5_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverPS5_Context *ctx, PS5SimpleStatePacket_t *packet)
|
||||
{
|
||||
|
@ -649,6 +659,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 =
|
|||
HIDAPI_DriverPS5_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverPS5_HasJoystickLED,
|
||||
HIDAPI_DriverPS5_SetJoystickLED,
|
||||
HIDAPI_DriverPS5_SetJoystickSensorsEnabled,
|
||||
HIDAPI_DriverPS5_CloseJoystick,
|
||||
HIDAPI_DriverPS5_FreeDevice,
|
||||
NULL
|
||||
|
|
|
@ -1054,6 +1054,13 @@ HIDAPI_DriverSteam_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_DriverSteam_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
/* You should use the full Steam Input API for sensor support */
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
|
@ -1191,6 +1198,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam =
|
|||
HIDAPI_DriverSteam_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverSteam_HasJoystickLED,
|
||||
HIDAPI_DriverSteam_SetJoystickLED,
|
||||
HIDAPI_DriverSteam_SetSensorsEnabled,
|
||||
HIDAPI_DriverSteam_CloseJoystick,
|
||||
HIDAPI_DriverSteam_FreeDevice,
|
||||
NULL
|
||||
|
|
|
@ -942,6 +942,12 @@ HIDAPI_DriverSwitch_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joys
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void HandleInputOnlyControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchInputOnlyControllerStatePacket_t *packet)
|
||||
{
|
||||
Sint16 axis;
|
||||
|
@ -1298,6 +1304,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
|
|||
HIDAPI_DriverSwitch_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverSwitch_HasJoystickLED,
|
||||
HIDAPI_DriverSwitch_SetJoystickLED,
|
||||
HIDAPI_DriverSwitch_SetJoystickSensorsEnabled,
|
||||
HIDAPI_DriverSwitch_CloseJoystick,
|
||||
HIDAPI_DriverSwitch_FreeDevice,
|
||||
NULL
|
||||
|
|
|
@ -815,6 +815,12 @@ HIDAPI_DriverXbox360_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_DriverXbox360_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
#ifdef __WIN32__
|
||||
/* This is the packet format for Xbox 360 and Xbox One controllers on Windows,
|
||||
however with this interface there is no rumble support, no guide button,
|
||||
|
@ -1326,6 +1332,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 =
|
|||
HIDAPI_DriverXbox360_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverXbox360_HasJoystickLED,
|
||||
HIDAPI_DriverXbox360_SetJoystickLED,
|
||||
HIDAPI_DriverXbox360_SetJoystickSensorsEnabled,
|
||||
HIDAPI_DriverXbox360_CloseJoystick,
|
||||
HIDAPI_DriverXbox360_FreeDevice,
|
||||
HIDAPI_DriverXbox360_PostUpdate,
|
||||
|
|
|
@ -176,6 +176,12 @@ HIDAPI_DriverXbox360W_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *jo
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXbox360W_Context *ctx, Uint8 *data, int size)
|
||||
{
|
||||
|
@ -316,6 +322,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W =
|
|||
HIDAPI_DriverXbox360W_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverXbox360W_HasJoystickLED,
|
||||
HIDAPI_DriverXbox360W_SetJoystickLED,
|
||||
HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled,
|
||||
HIDAPI_DriverXbox360W_CloseJoystick,
|
||||
HIDAPI_DriverXbox360W_FreeDevice,
|
||||
NULL
|
||||
|
|
|
@ -406,6 +406,12 @@ HIDAPI_DriverXboxOne_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
|
||||
{
|
||||
|
@ -934,6 +940,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
|
|||
HIDAPI_DriverXboxOne_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverXboxOne_HasJoystickLED,
|
||||
HIDAPI_DriverXboxOne_SetJoystickLED,
|
||||
HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled,
|
||||
HIDAPI_DriverXboxOne_CloseJoystick,
|
||||
HIDAPI_DriverXboxOne_FreeDevice,
|
||||
NULL
|
||||
|
|
|
@ -1130,6 +1130,23 @@ HIDAPI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blu
|
|||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick * joystick, SDL_bool enabled)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (joystick->hwdata) {
|
||||
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
||||
|
||||
result = device->driver->SetJoystickSensorsEnabled(device, joystick, enabled);
|
||||
} else {
|
||||
SDL_SetError("SetSensorsEnabled failed, device disconnected");
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
|
@ -1206,6 +1223,7 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
|
|||
HIDAPI_JoystickRumbleTriggers,
|
||||
HIDAPI_JoystickHasLED,
|
||||
HIDAPI_JoystickSetLED,
|
||||
HIDAPI_JoystickSetSensorsEnabled,
|
||||
HIDAPI_JoystickUpdate,
|
||||
HIDAPI_JoystickClose,
|
||||
HIDAPI_JoystickQuit,
|
||||
|
|
|
@ -99,6 +99,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
|
|||
int (*RumbleJoystickTriggers)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble);
|
||||
SDL_bool (*HasJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
|
||||
int (*SetJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue);
|
||||
int (*SetJoystickSensorsEnabled)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled);
|
||||
void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
|
||||
void (*FreeDevice)(SDL_HIDAPI_Device *device);
|
||||
void (*PostUpdate)(void);
|
||||
|
|
|
@ -79,6 +79,7 @@ static id disconnectObserver = nil;
|
|||
#define ENABLE_MFI_BATTERY
|
||||
#define ENABLE_MFI_RUMBLE
|
||||
#define ENABLE_MFI_LIGHT
|
||||
#define ENABLE_MFI_SENSORS
|
||||
#define ENABLE_PHYSICAL_INPUT_PROFILE
|
||||
#endif
|
||||
|
||||
|
@ -611,6 +612,20 @@ IOS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MFI_SENSORS
|
||||
if (@available(iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = joystick->hwdata->controller;
|
||||
GCMotion *motion = controller.motion;
|
||||
if (motion && motion.hasRotationRate) {
|
||||
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO);
|
||||
}
|
||||
if (motion && motion.hasGravityAndUserAcceleration) {
|
||||
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL);
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_MFI_SENSORS */
|
||||
|
||||
#endif /* SDL_JOYSTICK_MFI */
|
||||
}
|
||||
}
|
||||
|
@ -806,6 +821,31 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
|
|||
for (i = 0; i < button_count; i++) {
|
||||
SDL_PrivateJoystickButton(joystick, i, buttons[i]);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MFI_SENSORS
|
||||
if (@available(iOS 14.0, tvOS 14.0, *)) {
|
||||
GCMotion *motion = controller.motion;
|
||||
if (motion && motion.sensorsActive) {
|
||||
float data[3];
|
||||
|
||||
if (motion.hasRotationRate) {
|
||||
GCRotationRate rate = motion.rotationRate;
|
||||
data[0] = rate.x;
|
||||
data[1] = rate.z;
|
||||
data[2] = -rate.y;
|
||||
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, data, 3);
|
||||
}
|
||||
if (motion.hasGravityAndUserAcceleration) {
|
||||
GCAcceleration accel = motion.acceleration;
|
||||
data[0] = -accel.x * SDL_STANDARD_GRAVITY;
|
||||
data[1] = -accel.y * SDL_STANDARD_GRAVITY;
|
||||
data[2] = -accel.z * SDL_STANDARD_GRAVITY;
|
||||
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, data, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_MFI_SENSORS */
|
||||
|
||||
} else if (controller.gamepad) {
|
||||
GCGamepad *gamepad = controller.gamepad;
|
||||
|
||||
|
@ -1193,6 +1233,25 @@ IOS_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
IOS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
#ifdef ENABLE_MFI_SENSORS
|
||||
@autoreleasepool {
|
||||
if (@available(iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = joystick->hwdata->controller;
|
||||
GCMotion *motion = controller.motion;
|
||||
if (motion) {
|
||||
motion.sensorsActive = enabled ? YES : NO;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_MFI_SENSORS */
|
||||
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void
|
||||
IOS_JoystickUpdate(SDL_Joystick *joystick)
|
||||
{
|
||||
|
@ -1304,6 +1363,7 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver =
|
|||
IOS_JoystickRumbleTriggers,
|
||||
IOS_JoystickHasLED,
|
||||
IOS_JoystickSetLED,
|
||||
IOS_JoystickSetSensorsEnabled,
|
||||
IOS_JoystickUpdate,
|
||||
IOS_JoystickClose,
|
||||
IOS_JoystickQuit,
|
||||
|
|
|
@ -1044,6 +1044,12 @@ LINUX_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_INLINE void
|
||||
HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
|
||||
{
|
||||
|
@ -1527,6 +1533,7 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver =
|
|||
LINUX_JoystickRumbleTriggers,
|
||||
LINUX_JoystickHasLED,
|
||||
LINUX_JoystickSetLED,
|
||||
LINUX_JoystickSetSensorsEnabled,
|
||||
LINUX_JoystickUpdate,
|
||||
LINUX_JoystickClose,
|
||||
LINUX_JoystickQuit,
|
||||
|
|
|
@ -358,6 +358,12 @@ VIRTUAL_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 bl
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
VIRTUAL_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
VIRTUAL_JoystickUpdate(SDL_Joystick * joystick)
|
||||
|
@ -432,6 +438,7 @@ SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver =
|
|||
VIRTUAL_JoystickRumbleTriggers,
|
||||
VIRTUAL_JoystickHasLED,
|
||||
VIRTUAL_JoystickSetLED,
|
||||
VIRTUAL_JoystickSetSensorsEnabled,
|
||||
VIRTUAL_JoystickUpdate,
|
||||
VIRTUAL_JoystickClose,
|
||||
VIRTUAL_JoystickQuit,
|
||||
|
|
|
@ -635,6 +635,12 @@ RAWINPUT_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 b
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
RAWINPUT_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
RAWINPUT_JoystickUpdate(SDL_Joystick * joystick)
|
||||
|
@ -768,6 +774,7 @@ SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver =
|
|||
RAWINPUT_JoystickRumbleTriggers,
|
||||
RAWINPUT_JoystickHasLED,
|
||||
RAWINPUT_JoystickSetLED,
|
||||
RAWINPUT_JoystickSetSensorsEnabled,
|
||||
RAWINPUT_JoystickUpdate,
|
||||
RAWINPUT_JoystickClose,
|
||||
RAWINPUT_JoystickQuit,
|
||||
|
|
|
@ -607,6 +607,12 @@ WGI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
WGI_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static Uint8
|
||||
ConvertHatValue(__x_ABI_CWindows_CGaming_CInput_CGameControllerSwitchPosition value)
|
||||
{
|
||||
|
@ -752,6 +758,7 @@ SDL_JoystickDriver SDL_WGI_JoystickDriver =
|
|||
WGI_JoystickRumbleTriggers,
|
||||
WGI_JoystickHasLED,
|
||||
WGI_JoystickSetLED,
|
||||
WGI_JoystickSetSensorsEnabled,
|
||||
WGI_JoystickUpdate,
|
||||
WGI_JoystickClose,
|
||||
WGI_JoystickQuit,
|
||||
|
|
|
@ -518,6 +518,12 @@ WINDOWS_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 bl
|
|||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
WINDOWS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void
|
||||
WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
|
@ -604,6 +610,7 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
|
|||
WINDOWS_JoystickRumbleTriggers,
|
||||
WINDOWS_JoystickHasLED,
|
||||
WINDOWS_JoystickSetLED,
|
||||
WINDOWS_JoystickSetSensorsEnabled,
|
||||
WINDOWS_JoystickUpdate,
|
||||
WINDOWS_JoystickClose,
|
||||
WINDOWS_JoystickQuit,
|
||||
|
|
|
@ -158,9 +158,9 @@ SDL_COREMOTION_SensorUpdate(SDL_Sensor *sensor)
|
|||
if (accelerometerData) {
|
||||
CMAcceleration acceleration = accelerometerData.acceleration;
|
||||
float data[3];
|
||||
data[0] = acceleration.x * SDL_STANDARD_GRAVITY;
|
||||
data[1] = acceleration.y * SDL_STANDARD_GRAVITY;
|
||||
data[2] = acceleration.z * SDL_STANDARD_GRAVITY;
|
||||
data[0] = -acceleration.x * SDL_STANDARD_GRAVITY;
|
||||
data[1] = -acceleration.y * SDL_STANDARD_GRAVITY;
|
||||
data[2] = -acceleration.z * SDL_STANDARD_GRAVITY;
|
||||
if (SDL_memcmp(data, sensor->hwdata->data, sizeof(data)) != 0) {
|
||||
SDL_PrivateSensorUpdate(sensor, data, SDL_arraysize(data));
|
||||
SDL_memcpy(sensor->hwdata->data, data, sizeof(data));
|
||||
|
|
|
@ -97,9 +97,28 @@ LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
|
|||
return texture;
|
||||
}
|
||||
|
||||
static void
|
||||
InitGameController()
|
||||
{
|
||||
const char *name = SDL_GameControllerName(gamecontroller);
|
||||
|
||||
SDL_Log("Opened game controller %s\n", name);
|
||||
|
||||
if (SDL_GameControllerHasSensor(gamecontroller, SDL_SENSOR_ACCEL)) {
|
||||
SDL_Log("Enabling accelerometer\n");
|
||||
SDL_GameControllerSetSensorEnabled(gamecontroller, SDL_SENSOR_ACCEL, SDL_TRUE);
|
||||
}
|
||||
|
||||
if (SDL_GameControllerHasSensor(gamecontroller, SDL_SENSOR_GYRO)) {
|
||||
SDL_Log("Enabling gyro\n");
|
||||
SDL_GameControllerSetSensorEnabled(gamecontroller, SDL_SENSOR_GYRO, SDL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
UpdateWindowTitle()
|
||||
{
|
||||
if (gamecontroller) {
|
||||
const char *name = SDL_GameControllerName(gamecontroller);
|
||||
const char *serial = SDL_GameControllerGetSerial(gamecontroller);
|
||||
const char *basetitle = "Game Controller Test: ";
|
||||
|
@ -119,6 +138,9 @@ UpdateWindowTitle()
|
|||
SDL_SetWindowTitle(window, title);
|
||||
SDL_free(title);
|
||||
}
|
||||
} else {
|
||||
SDL_SetWindowTitle(window, "Waiting for controller...");
|
||||
}
|
||||
}
|
||||
|
||||
static Uint16 ConvertAxisToRumble(Sint16 axis)
|
||||
|
@ -146,10 +168,11 @@ loop(void *arg)
|
|||
if (!gamecontroller) {
|
||||
gamecontroller = SDL_GameControllerOpen(event.cdevice.which);
|
||||
if (gamecontroller) {
|
||||
UpdateWindowTitle();
|
||||
InitGameController();
|
||||
} else {
|
||||
SDL_Log("Couldn't open controller: %s\n", SDL_GetError());
|
||||
}
|
||||
UpdateWindowTitle();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -159,8 +182,9 @@ loop(void *arg)
|
|||
SDL_GameControllerClose(gamecontroller);
|
||||
gamecontroller = SDL_GameControllerOpen(0);
|
||||
if (gamecontroller) {
|
||||
UpdateWindowTitle();
|
||||
InitGameController();
|
||||
}
|
||||
UpdateWindowTitle();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -178,6 +202,15 @@ loop(void *arg)
|
|||
event.ctouchpad.pressure);
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERSENSORUPDATE:
|
||||
SDL_Log("Controller sensor %s: %.2f, %.2f, %.2f\n",
|
||||
event.csensor.sensor == SDL_SENSOR_ACCEL ? "accelerometer" :
|
||||
event.csensor.sensor == SDL_SENSOR_GYRO ? "gyro" : "unknown",
|
||||
event.csensor.data[0],
|
||||
event.csensor.data[1],
|
||||
event.csensor.data[2]);
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
SDL_Log("Controller axis %s changed to %d\n", SDL_GameControllerGetStringForAxis((SDL_GameControllerAxis)event.caxis.axis), event.caxis.value);
|
||||
break;
|
||||
|
@ -414,6 +447,8 @@ main(int argc, char *argv[])
|
|||
/* !!! FIXME: */
|
||||
/*SDL_RenderSetLogicalSize(screen, background->w, background->h);*/
|
||||
|
||||
UpdateWindowTitle();
|
||||
|
||||
/* Loop, getting controller events! */
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_main_loop_arg(loop, NULL, 0, 1);
|
||||
|
|
Loading…
Reference in New Issue