mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-26 06:20:48 +00:00
Merge pull request #990 from protocultor/old_sdl_gyro_switch
Gyro aiming for Switch controllers with SDL < 2.0.14
This commit is contained in:
commit
11bea2a68b
1 changed files with 118 additions and 9 deletions
|
@ -167,12 +167,25 @@ static qboolean gyro_active = false;
|
||||||
|
|
||||||
// Gyro calibration
|
// Gyro calibration
|
||||||
static float gyro_accum[3];
|
static float gyro_accum[3];
|
||||||
static unsigned int num_samples;
|
|
||||||
|
|
||||||
static cvar_t *gyro_calibration_x;
|
static cvar_t *gyro_calibration_x;
|
||||||
static cvar_t *gyro_calibration_y;
|
static cvar_t *gyro_calibration_y;
|
||||||
static cvar_t *gyro_calibration_z;
|
static cvar_t *gyro_calibration_z;
|
||||||
|
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 14) // support for controller sensors (gyro, accelerometer)
|
||||||
|
|
||||||
|
static unsigned int num_samples;
|
||||||
|
#define NATIVE_SDL_GYRO // uses SDL_CONTROLLERSENSORUPDATE to read gyro
|
||||||
|
|
||||||
|
#else // for SDL < 2.0.14, gyro can be read as a "secondary joystick" exposed by dkms-hid-nintendo
|
||||||
|
|
||||||
|
static unsigned int num_samples[3];
|
||||||
|
static SDL_Joystick *imu_joystick = NULL; // gyro "joystick"
|
||||||
|
#define IMU_JOY_AXIS_GYRO_ROLL 3
|
||||||
|
#define IMU_JOY_AXIS_GYRO_PITCH 4
|
||||||
|
#define IMU_JOY_AXIS_GYRO_YAW 5
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// To ignore SDL_JOYDEVICEADDED at game init. Allows for hot plugging of game controller afterwards.
|
// To ignore SDL_JOYDEVICEADDED at game init. Allows for hot plugging of game controller afterwards.
|
||||||
static qboolean first_init = true;
|
static qboolean first_init = true;
|
||||||
|
|
||||||
|
@ -766,7 +779,7 @@ IN_Update(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 16) // support for controller sensors (gyro, accelerometer)
|
#ifdef NATIVE_SDL_GYRO // controller sensors' reading supported (gyro, accelerometer)
|
||||||
case SDL_CONTROLLERSENSORUPDATE:
|
case SDL_CONTROLLERSENSORUPDATE:
|
||||||
if (event.csensor.sensor != SDL_SENSOR_GYRO)
|
if (event.csensor.sensor != SDL_SENSOR_GYRO)
|
||||||
{
|
{
|
||||||
|
@ -781,9 +794,39 @@ IN_Update(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else // gyro read as "secondary joystick"
|
||||||
|
case SDL_JOYAXISMOTION:
|
||||||
|
if ( !imu_joystick || event.cdevice.which != SDL_JoystickInstanceID(imu_joystick) )
|
||||||
|
{
|
||||||
|
break; // controller axes handled by SDL_CONTROLLERAXISMOTION
|
||||||
|
}
|
||||||
|
|
||||||
|
int axis_value = event.caxis.value;
|
||||||
|
if (countdown_reason == REASON_GYROCALIBRATION && updates_countdown)
|
||||||
|
{
|
||||||
|
switch (event.caxis.axis)
|
||||||
|
{
|
||||||
|
case IMU_JOY_AXIS_GYRO_PITCH:
|
||||||
|
gyro_accum[0] += axis_value;
|
||||||
|
num_samples[0]++;
|
||||||
|
break;
|
||||||
|
case IMU_JOY_AXIS_GYRO_YAW:
|
||||||
|
gyro_accum[1] += axis_value;
|
||||||
|
num_samples[1]++;
|
||||||
|
break;
|
||||||
|
case IMU_JOY_AXIS_GYRO_ROLL:
|
||||||
|
gyro_accum[2] += axis_value;
|
||||||
|
num_samples[2]++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // NATIVE_SDL_GYRO
|
||||||
|
|
||||||
if (gyro_active && gyro_mode->value &&
|
if (gyro_active && gyro_mode->value &&
|
||||||
!cl_paused->value && cls.key_dest == key_game)
|
!cl_paused->value && cls.key_dest == key_game)
|
||||||
{
|
{
|
||||||
|
#ifdef NATIVE_SDL_GYRO
|
||||||
if (!gyro_turning_axis->value)
|
if (!gyro_turning_axis->value)
|
||||||
{
|
{
|
||||||
gyro_yaw = event.csensor.data[1] - gyro_calibration_y->value; // yaw
|
gyro_yaw = event.csensor.data[1] - gyro_calibration_y->value; // yaw
|
||||||
|
@ -793,13 +836,31 @@ IN_Update(void)
|
||||||
gyro_yaw = -(event.csensor.data[2] - gyro_calibration_z->value); // roll
|
gyro_yaw = -(event.csensor.data[2] - gyro_calibration_z->value); // roll
|
||||||
}
|
}
|
||||||
gyro_pitch = event.csensor.data[0] - gyro_calibration_x->value;
|
gyro_pitch = event.csensor.data[0] - gyro_calibration_x->value;
|
||||||
|
#else // old "joystick" gyro
|
||||||
|
switch (event.caxis.axis) // inside "case SDL_JOYAXISMOTION" here
|
||||||
|
{
|
||||||
|
case IMU_JOY_AXIS_GYRO_PITCH:
|
||||||
|
gyro_pitch = -(axis_value - gyro_calibration_x->value);
|
||||||
|
break;
|
||||||
|
case IMU_JOY_AXIS_GYRO_YAW:
|
||||||
|
if (!gyro_turning_axis->value)
|
||||||
|
{
|
||||||
|
gyro_yaw = axis_value - gyro_calibration_y->value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IMU_JOY_AXIS_GYRO_ROLL:
|
||||||
|
if (gyro_turning_axis->value)
|
||||||
|
{
|
||||||
|
gyro_yaw = axis_value - gyro_calibration_z->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // NATIVE_SDL_GYRO
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gyro_yaw = gyro_pitch = 0;
|
gyro_yaw = gyro_pitch = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif // SDL_VERSION_ATLEAST(2, 0, 16)
|
|
||||||
|
|
||||||
case SDL_CONTROLLERDEVICEREMOVED:
|
case SDL_CONTROLLERDEVICEREMOVED:
|
||||||
if (!controller)
|
if (!controller)
|
||||||
|
@ -889,10 +950,23 @@ IN_Update(void)
|
||||||
|
|
||||||
case REASON_GYROCALIBRATION: // finish and save calibration
|
case REASON_GYROCALIBRATION: // finish and save calibration
|
||||||
{
|
{
|
||||||
|
#ifdef NATIVE_SDL_GYRO
|
||||||
const float inverseSamples = 1.f / num_samples;
|
const float inverseSamples = 1.f / num_samples;
|
||||||
Cvar_SetValue("gyro_calibration_x", gyro_accum[0] * inverseSamples);
|
Cvar_SetValue("gyro_calibration_x", gyro_accum[0] * inverseSamples);
|
||||||
Cvar_SetValue("gyro_calibration_y", gyro_accum[1] * inverseSamples);
|
Cvar_SetValue("gyro_calibration_y", gyro_accum[1] * inverseSamples);
|
||||||
Cvar_SetValue("gyro_calibration_z", gyro_accum[2] * inverseSamples);
|
Cvar_SetValue("gyro_calibration_z", gyro_accum[2] * inverseSamples);
|
||||||
|
#else
|
||||||
|
if (!num_samples[0] || !num_samples[1] || !num_samples[2])
|
||||||
|
{
|
||||||
|
Com_Printf("Calibration failed, please retry inside a level after having moved your controller a little.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Cvar_SetValue("gyro_calibration_x", gyro_accum[0] / num_samples[0]);
|
||||||
|
Cvar_SetValue("gyro_calibration_y", gyro_accum[1] / num_samples[1]);
|
||||||
|
Cvar_SetValue("gyro_calibration_z", gyro_accum[2] / num_samples[2]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Com_Printf("Calibration results:\n X=%f Y=%f Z=%f\n",
|
Com_Printf("Calibration results:\n X=%f Y=%f Z=%f\n",
|
||||||
gyro_calibration_x->value, gyro_calibration_y->value, gyro_calibration_z->value);
|
gyro_calibration_x->value, gyro_calibration_y->value, gyro_calibration_z->value);
|
||||||
CalibrationFinishedCallback();
|
CalibrationFinishedCallback();
|
||||||
|
@ -1269,7 +1343,11 @@ IN_Move(usercmd_t *cmd)
|
||||||
//
|
//
|
||||||
// For movement this is not needed, as those are absolute values independent of framerate
|
// For movement this is not needed, as those are absolute values independent of framerate
|
||||||
float joyViewFactor = cls.rframetime/0.01666f;
|
float joyViewFactor = cls.rframetime/0.01666f;
|
||||||
|
#ifdef NATIVE_SDL_GYRO
|
||||||
float gyroViewFactor = (1.0f / M_PI) * joyViewFactor;
|
float gyroViewFactor = (1.0f / M_PI) * joyViewFactor;
|
||||||
|
#else
|
||||||
|
float gyroViewFactor = (1.0f / 2560.0f) * joyViewFactor; // normalized for Switch gyro
|
||||||
|
#endif
|
||||||
|
|
||||||
if (joystick_yaw)
|
if (joystick_yaw)
|
||||||
{
|
{
|
||||||
|
@ -1915,10 +1993,14 @@ Controller_Rumble(const char *name, vec3_t source, qboolean from_player,
|
||||||
void
|
void
|
||||||
StartCalibration(void)
|
StartCalibration(void)
|
||||||
{
|
{
|
||||||
|
#ifdef NATIVE_SDL_GYRO
|
||||||
|
num_samples = 0;
|
||||||
|
#else
|
||||||
|
num_samples[0] = num_samples[1] = num_samples[2] = 0;
|
||||||
|
#endif
|
||||||
gyro_accum[0] = 0.0;
|
gyro_accum[0] = 0.0;
|
||||||
gyro_accum[1] = 0.0;
|
gyro_accum[1] = 0.0;
|
||||||
gyro_accum[2] = 0.0;
|
gyro_accum[2] = 0.0;
|
||||||
num_samples = 0;
|
|
||||||
updates_countdown = 300;
|
updates_countdown = 300;
|
||||||
countdown_reason = REASON_GYROCALIBRATION;
|
countdown_reason = REASON_GYROCALIBRATION;
|
||||||
}
|
}
|
||||||
|
@ -2033,9 +2115,26 @@ IN_Controller_Init(qboolean notify_user)
|
||||||
// Ugly hack to detect IMU-only devices - works for Switch controllers at least
|
// Ugly hack to detect IMU-only devices - works for Switch controllers at least
|
||||||
if (name_len > 4 && !strncmp(joystick_name + name_len - 4, " IMU", 4))
|
if (name_len > 4 && !strncmp(joystick_name + name_len - 4, " IMU", 4))
|
||||||
{
|
{
|
||||||
Com_Printf ("Skipping IMU device.\n");
|
|
||||||
SDL_JoystickClose(joystick);
|
SDL_JoystickClose(joystick);
|
||||||
joystick = NULL;
|
joystick = NULL;
|
||||||
|
#ifdef NATIVE_SDL_GYRO
|
||||||
|
Com_Printf ("Skipping IMU device.\n");
|
||||||
|
#else // if it's not a Left JoyCon, use it as Gyro
|
||||||
|
Com_Printf ("IMU device found.\n");
|
||||||
|
if ( !imu_joystick && name_len > 16 && strncmp(joystick_name + name_len - 16, "Left Joy-Con IMU", 16) != 0 )
|
||||||
|
{
|
||||||
|
imu_joystick = SDL_JoystickOpen(i);
|
||||||
|
if (imu_joystick)
|
||||||
|
{
|
||||||
|
show_gyro = true;
|
||||||
|
Com_Printf ("Using this device as Gyro sensor.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Com_Printf ("Couldn't open IMU: %s.\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2059,7 +2158,7 @@ IN_Controller_Init(qboolean notify_user)
|
||||||
SDL_JoystickClose(joystick);
|
SDL_JoystickClose(joystick);
|
||||||
joystick = NULL;
|
joystick = NULL;
|
||||||
|
|
||||||
if (is_controller)
|
if (is_controller && !controller)
|
||||||
{
|
{
|
||||||
controller = SDL_GameControllerOpen(i);
|
controller = SDL_GameControllerOpen(i);
|
||||||
if (!controller)
|
if (!controller)
|
||||||
|
@ -2071,7 +2170,7 @@ IN_Controller_Init(qboolean notify_user)
|
||||||
show_gamepad = true;
|
show_gamepad = true;
|
||||||
Com_Printf("Enabled as Game Controller, settings:\n%s\n", SDL_GameControllerMapping(controller));
|
Com_Printf("Enabled as Game Controller, settings:\n%s\n", SDL_GameControllerMapping(controller));
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 16) // support for controller sensors
|
#ifdef NATIVE_SDL_GYRO
|
||||||
|
|
||||||
if ( SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO)
|
if ( SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO)
|
||||||
&& !SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE) )
|
&& !SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE) )
|
||||||
|
@ -2090,7 +2189,7 @@ IN_Controller_Init(qboolean notify_user)
|
||||||
SDL_GameControllerSetLED(controller, 0, 80, 0); // green light
|
SDL_GameControllerSetLED(controller, 0, 80, 0); // green light
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SDL_VERSION_ATLEAST(2, 0, 16)
|
#endif // NATIVE_SDL_GYRO
|
||||||
|
|
||||||
joystick_haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(controller));
|
joystick_haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(controller));
|
||||||
|
|
||||||
|
@ -2124,7 +2223,9 @@ IN_Controller_Init(qboolean notify_user)
|
||||||
Com_Printf("Controller doesn't support rumble.\n");
|
Com_Printf("Controller doesn't support rumble.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NATIVE_SDL_GYRO // "native" exits when finding a single working controller
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2236,6 +2337,14 @@ IN_Controller_Shutdown(qboolean notify_user)
|
||||||
show_gamepad = show_gyro = show_haptic = false;
|
show_gamepad = show_gyro = show_haptic = false;
|
||||||
joystick_left_x = joystick_left_y = joystick_right_x = joystick_right_y = 0;
|
joystick_left_x = joystick_left_y = joystick_right_x = joystick_right_y = 0;
|
||||||
gyro_yaw = gyro_pitch = 0;
|
gyro_yaw = gyro_pitch = 0;
|
||||||
|
|
||||||
|
#ifndef NATIVE_SDL_GYRO
|
||||||
|
if (imu_joystick)
|
||||||
|
{
|
||||||
|
SDL_JoystickClose(imu_joystick);
|
||||||
|
imu_joystick = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue