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
|
||||
static float gyro_accum[3];
|
||||
static unsigned int num_samples;
|
||||
|
||||
static cvar_t *gyro_calibration_x;
|
||||
static cvar_t *gyro_calibration_y;
|
||||
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.
|
||||
static qboolean first_init = true;
|
||||
|
||||
|
@ -766,7 +779,7 @@ IN_Update(void)
|
|||
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:
|
||||
if (event.csensor.sensor != SDL_SENSOR_GYRO)
|
||||
{
|
||||
|
@ -781,9 +794,39 @@ IN_Update(void)
|
|||
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 &&
|
||||
!cl_paused->value && cls.key_dest == key_game)
|
||||
{
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
if (!gyro_turning_axis->value)
|
||||
{
|
||||
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_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
|
||||
{
|
||||
gyro_yaw = gyro_pitch = 0;
|
||||
}
|
||||
break;
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 16)
|
||||
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
if (!controller)
|
||||
|
@ -889,10 +950,23 @@ IN_Update(void)
|
|||
|
||||
case REASON_GYROCALIBRATION: // finish and save calibration
|
||||
{
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
const float inverseSamples = 1.f / num_samples;
|
||||
Cvar_SetValue("gyro_calibration_x", gyro_accum[0] * inverseSamples);
|
||||
Cvar_SetValue("gyro_calibration_y", gyro_accum[1] * 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",
|
||||
gyro_calibration_x->value, gyro_calibration_y->value, gyro_calibration_z->value);
|
||||
CalibrationFinishedCallback();
|
||||
|
@ -1269,7 +1343,11 @@ IN_Move(usercmd_t *cmd)
|
|||
//
|
||||
// For movement this is not needed, as those are absolute values independent of framerate
|
||||
float joyViewFactor = cls.rframetime/0.01666f;
|
||||
#ifdef NATIVE_SDL_GYRO
|
||||
float gyroViewFactor = (1.0f / M_PI) * joyViewFactor;
|
||||
#else
|
||||
float gyroViewFactor = (1.0f / 2560.0f) * joyViewFactor; // normalized for Switch gyro
|
||||
#endif
|
||||
|
||||
if (joystick_yaw)
|
||||
{
|
||||
|
@ -1915,10 +1993,14 @@ Controller_Rumble(const char *name, vec3_t source, qboolean from_player,
|
|||
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[1] = 0.0;
|
||||
gyro_accum[2] = 0.0;
|
||||
num_samples = 0;
|
||||
updates_countdown = 300;
|
||||
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
|
||||
if (name_len > 4 && !strncmp(joystick_name + name_len - 4, " IMU", 4))
|
||||
{
|
||||
Com_Printf ("Skipping IMU device.\n");
|
||||
SDL_JoystickClose(joystick);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2059,7 +2158,7 @@ IN_Controller_Init(qboolean notify_user)
|
|||
SDL_JoystickClose(joystick);
|
||||
joystick = NULL;
|
||||
|
||||
if (is_controller)
|
||||
if (is_controller && !controller)
|
||||
{
|
||||
controller = SDL_GameControllerOpen(i);
|
||||
if (!controller)
|
||||
|
@ -2071,7 +2170,7 @@ IN_Controller_Init(qboolean notify_user)
|
|||
show_gamepad = true;
|
||||
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)
|
||||
&& !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
|
||||
}
|
||||
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 16)
|
||||
#endif // NATIVE_SDL_GYRO
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
#ifdef NATIVE_SDL_GYRO // "native" exits when finding a single working controller
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2236,6 +2337,14 @@ IN_Controller_Shutdown(qboolean notify_user)
|
|||
show_gamepad = show_gyro = show_haptic = false;
|
||||
joystick_left_x = joystick_left_y = joystick_right_x = joystick_right_y = 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