Added left and right sensors for Nintendo Joy-Con and Wii controllers

This commit is contained in:
Sam Lantinga 2022-09-07 00:00:27 -07:00
parent 30f55a5d59
commit 4018f35ef2
4 changed files with 87 additions and 29 deletions

View File

@ -71,7 +71,11 @@ typedef enum
SDL_SENSOR_INVALID = -1, /**< Returned for an invalid sensor */
SDL_SENSOR_UNKNOWN, /**< Unknown sensor type */
SDL_SENSOR_ACCEL, /**< Accelerometer */
SDL_SENSOR_GYRO /**< Gyroscope */
SDL_SENSOR_GYRO, /**< Gyroscope */
SDL_SENSOR_ACCEL_L, /**< Accelerometer for left Joy-Con controller and Wii nunchuk */
SDL_SENSOR_GYRO_L, /**< Gyroscope for left Joy-Con controller */
SDL_SENSOR_ACCEL_R, /**< Accelerometer for right Joy-Con controller */
SDL_SENSOR_GYRO_R /**< Gyroscope for right Joy-Con controller */
} SDL_SensorType;
/**

View File

@ -254,7 +254,6 @@ typedef struct {
SDL_bool m_bRumblePending;
SDL_bool m_bRumbleZeroPending;
Uint32 m_unRumblePending;
SDL_bool m_bHasSensors;
SDL_bool m_bReportSensors;
SDL_bool m_bHasSensorData;
Uint32 m_unLastInput;
@ -1351,7 +1350,16 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 200.0f);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 200.0f);
ctx->m_bHasSensors = SDL_TRUE;
}
if (device->parent &&
ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) {
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO_L, 200.0f);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_L, 200.0f);
}
if (device->parent &&
ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO_R, 200.0f);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_R, 200.0f);
}
}
@ -1610,10 +1618,6 @@ HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joy
{
SDL_DriverSwitch_Context* ctx = (SDL_DriverSwitch_Context*)device->context;
if (!ctx->m_bHasSensors) {
return SDL_Unsupported();
}
SetIMUEnabled(ctx, enabled);
ctx->m_bReportSensors = enabled;
@ -1816,7 +1820,7 @@ static void SendSensorUpdate(SDL_Joystick *joystick, SDL_DriverSwitch_Context *c
* since that's our de facto standard from already supporting those controllers, and
* users will want consistent axis mappings across devices.
*/
if (type == SDL_SENSOR_GYRO) {
if (type == SDL_SENSOR_GYRO || type == SDL_SENSOR_GYRO_L || type == SDL_SENSOR_GYRO_R ) {
data[0] = -(ctx->m_IMUScaleData.fGyroScaleY * (float)values[1]);
data[1] = ctx->m_IMUScaleData.fGyroScaleZ * (float)values[2];
data[2] = -(ctx->m_IMUScaleData.fGyroScaleX * (float)values[0]);
@ -2068,13 +2072,37 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
if (bHasSensorData) {
ctx->m_bHasSensorData = SDL_TRUE;
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[2].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[1].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[0].sGyroX);
if (!ctx->device->parent ||
ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[2].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[1].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[0].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[2].sAccelX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[1].sAccelX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[0].sAccelX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[2].sAccelX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[1].sAccelX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[0].sAccelX);
}
if (ctx->device->parent &&
ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) {
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_L, &packet->imuState[2].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_L, &packet->imuState[1].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_L, &packet->imuState[0].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_L, &packet->imuState[2].sAccelX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_L, &packet->imuState[1].sAccelX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_L, &packet->imuState[0].sAccelX);
}
if (ctx->device->parent &&
ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_R, &packet->imuState[2].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_R, &packet->imuState[1].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_R, &packet->imuState[0].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_R, &packet->imuState[2].sAccelX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_R, &packet->imuState[1].sAccelX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_R, &packet->imuState[0].sAccelX);
}
} else if (ctx->m_bHasSensorData) {
/* Uh oh, someone turned off the IMU? */

View File

@ -809,6 +809,9 @@ HIDAPI_DriverWii_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
if (ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_None ||
ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_Nunchuk) {
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 100.0f);
if (ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_Nunchuk) {
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_L, 100.0f);
}
if (ctx->m_bMotionPlusPresent) {
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 100.0f);
@ -1162,7 +1165,6 @@ static void HandleNunchuckButtonData(SDL_DriverWii_Context *ctx, SDL_Joystick *j
PostStickCalibrated(joystick, &ctx->m_StickCalibrationData[0], SDL_CONTROLLER_AXIS_LEFTX, data->rgucExtension[0]);
PostStickCalibrated(joystick, &ctx->m_StickCalibrationData[1], SDL_CONTROLLER_AXIS_LEFTY, data->rgucExtension[1]);
#if 0 /* We'll report this when we have the concept of right/left sensors */
if (ctx->m_bReportSensors) {
const float ACCEL_RES_PER_G = 200.0f;
Sint16 x, y, z;
@ -1190,9 +1192,8 @@ static void HandleNunchuckButtonData(SDL_DriverWii_Context *ctx, SDL_Joystick *j
values[0] = -((float)x / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY;
values[1] = ((float)z / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY;
values[2] = ((float)y / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY;
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, values, 3);
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL_L, values, 3);
}
#endif
}
static void HandleMotionPlusData(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick, const WiiButtonData *data)

View File

@ -127,6 +127,26 @@ static void UpdateWindowTitle()
}
}
static const char *GetSensorName(SDL_SensorType sensor)
{
switch (sensor) {
case SDL_SENSOR_ACCEL:
return "accelerometer";
case SDL_SENSOR_GYRO:
return "gyro";
case SDL_SENSOR_ACCEL_L:
return "accelerometer (L)";
case SDL_SENSOR_GYRO_L:
return "gyro (L)";
case SDL_SENSOR_ACCEL_R:
return "accelerometer (R)";
case SDL_SENSOR_GYRO_R:
return "gyro (R)";
default:
return "UNKNOWN";
}
}
static int FindController(SDL_JoystickID controller_id)
{
int i;
@ -145,6 +165,15 @@ static void AddController(int device_index, SDL_bool verbose)
SDL_GameController *controller;
SDL_GameController **controllers;
Uint16 firmware_version;
SDL_SensorType sensors[] = {
SDL_SENSOR_ACCEL,
SDL_SENSOR_GYRO,
SDL_SENSOR_ACCEL_L,
SDL_SENSOR_GYRO_L,
SDL_SENSOR_ACCEL_R,
SDL_SENSOR_GYRO_R
};
unsigned int i;
controller_id = SDL_JoystickGetDeviceInstanceID(device_index);
if (controller_id < 0) {
@ -187,18 +216,15 @@ static void AddController(int device_index, SDL_bool verbose)
}
}
if (SDL_GameControllerHasSensor(gamecontroller, SDL_SENSOR_ACCEL)) {
if (verbose) {
SDL_Log("Enabling accelerometer at %.2f Hz\n", SDL_GameControllerGetSensorDataRate(gamecontroller, SDL_SENSOR_ACCEL));
}
SDL_GameControllerSetSensorEnabled(gamecontroller, SDL_SENSOR_ACCEL, SDL_TRUE);
}
for (i = 0; i < SDL_arraysize(sensors); ++i) {
SDL_SensorType sensor = sensors[i];
if (SDL_GameControllerHasSensor(gamecontroller, SDL_SENSOR_GYRO)) {
if (verbose) {
SDL_Log("Enabling gyro at %.2f Hz\n", SDL_GameControllerGetSensorDataRate(gamecontroller, SDL_SENSOR_GYRO));
if (SDL_GameControllerHasSensor(gamecontroller, sensor)) {
if (verbose) {
SDL_Log("Enabling %s at %.2f Hz\n", GetSensorName(sensor), SDL_GameControllerGetSensorDataRate(gamecontroller, sensor));
}
SDL_GameControllerSetSensorEnabled(gamecontroller, sensor, SDL_TRUE);
}
SDL_GameControllerSetSensorEnabled(gamecontroller, SDL_SENSOR_GYRO, SDL_TRUE);
}
if (SDL_GameControllerHasRumble(gamecontroller)) {
@ -565,8 +591,7 @@ loop(void *arg)
case SDL_CONTROLLERSENSORUPDATE:
SDL_Log("Controller %d sensor %s: %.2f, %.2f, %.2f\n",
event.csensor.which,
event.csensor.sensor == SDL_SENSOR_ACCEL ? "accelerometer" :
event.csensor.sensor == SDL_SENSOR_GYRO ? "gyro" : "unknown",
GetSensorName((SDL_SensorType)event.csensor.sensor),
event.csensor.data[0],
event.csensor.data[1],
event.csensor.data[2]);