#include "SDL_config.h"
#if defined(SDL_SENSOR_VITA)
#include "SDL_error.h"
#include "SDL_sensor.h"
#include "SDL_vitasensor.h"
#include "../SDL_syssensor.h"
#include <psp2/motion.h>
#if !defined(SCE_MOTION_MAX_NUM_STATES)
#define SCE_MOTION_MAX_NUM_STATES 64
#endif
typedef struct
{
SDL_SensorType type;
SDL_SensorID instance_id;
} SDL_VitaSensor;
static SDL_VitaSensor *SDL_sensors;
static int SDL_sensors_count;
static int
SDL_VITA_SensorInit(void)
{
sceMotionReset();
sceMotionStartSampling();
sceMotionSetAngleThreshold(0);
sceMotionSetDeadband(SCE_FALSE);
sceMotionSetTiltCorrection(SCE_FALSE);
SDL_sensors_count = 2;
SDL_sensors = (SDL_VitaSensor *)SDL_calloc(SDL_sensors_count, sizeof(*SDL_sensors));
if (!SDL_sensors) {
return SDL_OutOfMemory();
}
SDL_sensors[0].type = SDL_SENSOR_ACCEL;
SDL_sensors[0].instance_id = SDL_GetNextSensorInstanceID();
SDL_sensors[1].type = SDL_SENSOR_GYRO;
SDL_sensors[1].instance_id = SDL_GetNextSensorInstanceID();
return 0;
}
static int
SDL_VITA_SensorGetCount(void)
{
return SDL_sensors_count;
}
static void
SDL_VITA_SensorDetect(void)
{
}
static const char *
SDL_VITA_SensorGetDeviceName(int device_index)
{
if (device_index < SDL_sensors_count) {
switch (SDL_sensors[device_index].type) {
case SDL_SENSOR_ACCEL:
return "Accelerometer";
case SDL_SENSOR_GYRO:
return "Gyro";
default:
return "Unknown";
}
}
return NULL;
}
static SDL_SensorType
SDL_VITA_SensorGetDeviceType(int device_index)
{
if (device_index < SDL_sensors_count) {
return SDL_sensors[device_index].type;
}
return SDL_SENSOR_INVALID;
}
static int
SDL_VITA_SensorGetDeviceNonPortableType(int device_index)
{
if (device_index < SDL_sensors_count) {
return SDL_sensors[device_index].type;
}
return -1;
}
static SDL_SensorID
SDL_VITA_SensorGetDeviceInstanceID(int device_index)
{
if (device_index < SDL_sensors_count) {
return SDL_sensors[device_index].instance_id;
}
return -1;
}
static int
SDL_VITA_SensorOpen(SDL_Sensor *sensor, int device_index)
{
struct sensor_hwdata *hwdata;
hwdata = (struct sensor_hwdata *)SDL_calloc(1, sizeof(*hwdata));
if (hwdata == NULL) {
return SDL_OutOfMemory();
}
sensor->hwdata = hwdata;
return 0;
}
static void
SDL_VITA_SensorUpdate(SDL_Sensor *sensor)
{
int err = 0;
SceMotionSensorState motionState[SCE_MOTION_MAX_NUM_STATES];
SDL_memset(motionState, 0, sizeof(motionState));
err = sceMotionGetSensorState(motionState, SCE_MOTION_MAX_NUM_STATES);
if (err != 0)
{
return;
}
for (int i = 0; i < SCE_MOTION_MAX_NUM_STATES; i++)
{
if (sensor->hwdata->counter < motionState[i].counter)
{
unsigned int timestamp = motionState[i].timestamp;
sensor->hwdata->counter = motionState[i].counter;
if (sensor->hwdata->timestamp_us) {
unsigned int delta;
if (sensor->hwdata->last_timestamp > timestamp) {
SDL_COMPILE_TIME_ASSERT(timestamp, sizeof(timestamp) == sizeof(Uint32));
delta = (SDL_MAX_UINT32 - sensor->hwdata->last_timestamp + timestamp + 1);
} else {
delta = (timestamp - sensor->hwdata->last_timestamp);
}
sensor->hwdata->timestamp_us += delta;
} else {
sensor->hwdata->timestamp_us = timestamp;
}
sensor->hwdata->last_timestamp = timestamp;
switch (sensor->type)
{
case SDL_SENSOR_ACCEL:
{
float data[3];
data[0] = motionState[i].accelerometer.x * SDL_STANDARD_GRAVITY;
data[1] = motionState[i].accelerometer.y * SDL_STANDARD_GRAVITY;
data[2] = motionState[i].accelerometer.z * SDL_STANDARD_GRAVITY;
SDL_PrivateSensorUpdate(sensor, sensor->hwdata->timestamp_us, data, SDL_arraysize(data));
}
break;
case SDL_SENSOR_GYRO:
{
float data[3];
data[0] = motionState[i].gyro.x;
data[1] = motionState[i].gyro.y;
data[2] = motionState[i].gyro.z;
SDL_PrivateSensorUpdate(sensor, sensor->hwdata->timestamp_us, data, SDL_arraysize(data));
}
break;
default:
break;
}
}
}
}
static void
SDL_VITA_SensorClose(SDL_Sensor *sensor)
{
}
static void
SDL_VITA_SensorQuit(void)
{
sceMotionStopSampling();
}
SDL_SensorDriver SDL_VITA_SensorDriver =
{
SDL_VITA_SensorInit,
SDL_VITA_SensorGetCount,
SDL_VITA_SensorDetect,
SDL_VITA_SensorGetDeviceName,
SDL_VITA_SensorGetDeviceType,
SDL_VITA_SensorGetDeviceNonPortableType,
SDL_VITA_SensorGetDeviceInstanceID,
SDL_VITA_SensorOpen,
SDL_VITA_SensorUpdate,
SDL_VITA_SensorClose,
SDL_VITA_SensorQuit,
};
#endif