Readability improved for gyro calibration & controller hotplug code

"init_delay" was renamed to "updates_countdown", since it's now a "general
purpose" countdown, having also to count the inputs left for gyro calibration,
besides controller initialization.
Reason for the countdown is now explicit, not having to depend if
"gyro_calibration" was true or not to select what was the purpose of the
countdown.
Explanation comment added for gyro initialization on Linux & Mac.
REMINDER: see if SDL2 will keep the difference of gyro readings between Windows
and Linux/Mac for the Switch controllers.
This commit is contained in:
Jaime Moreira 2022-06-14 16:16:47 -04:00
parent df399576a2
commit 35495fb6f2

View file

@ -43,6 +43,15 @@
// ---- // ----
typedef enum
{
REASON_NONE,
REASON_CONTROLLERINIT,
REASON_GYROCALIBRATION
} updates_countdown_reasons;
// ----
// These are used to communicate the events collected by // These are used to communicate the events collected by
// IN_Update() called at the beginning of a frame to the // IN_Update() called at the beginning of a frame to the
// actual movement functions called at a later time. // actual movement functions called at a later time.
@ -146,7 +155,6 @@ qboolean gyro_hardware = false;
static qboolean gyro_active = false; static qboolean gyro_active = false;
// Gyro calibration // Gyro calibration
static qboolean calibrating_gyro = false;
static float gyro_accum[3]; static float gyro_accum[3];
static unsigned int num_samples; static unsigned int num_samples;
@ -154,9 +162,14 @@ 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;
// Support for hot plugging of game controller // 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;
static int in_delay = 30;
// Countdown of calls to IN_Update(), needed for controller init and gyro calibration
static unsigned int updates_countdown = 30;
// Reason for the countdown
static updates_countdown_reasons countdown_reason = REASON_CONTROLLERINIT;
// Factors used to transform from SDL input to Q2 "view angle" change // Factors used to transform from SDL input to Q2 "view angle" change
#define NORMALIZE_SDL_AXIS (1.0f/32768.0f) #define NORMALIZE_SDL_AXIS (1.0f/32768.0f)
@ -217,7 +230,6 @@ IN_TranslateSDLtoQ2Key(unsigned int keysym)
key = K_RIGHTARROW; key = K_RIGHTARROW;
break; break;
case SDLK_RALT: case SDLK_RALT:
case SDLK_LALT: case SDLK_LALT:
key = K_ALT; key = K_ALT;
@ -295,7 +307,6 @@ IN_TranslateSDLtoQ2Key(unsigned int keysym)
key = K_F15; key = K_F15;
break; break;
case SDLK_KP_7: case SDLK_KP_7:
key = K_KP_HOME; key = K_KP_HOME;
break; break;
@ -814,7 +825,7 @@ IN_Update(void)
{ {
break; break;
} }
if (calibrating_gyro) if (countdown_reason == REASON_GYROCALIBRATION && updates_countdown)
{ {
gyro_accum[0] += event.csensor.data[0]; gyro_accum[0] += event.csensor.data[0];
gyro_accum[1] += event.csensor.data[1]; gyro_accum[1] += event.csensor.data[1];
@ -858,7 +869,8 @@ IN_Update(void)
if (!controller) if (!controller)
{ {
// This should be lower, but some controllers just don't want to get detected by the OS // This should be lower, but some controllers just don't want to get detected by the OS
in_delay = 100; updates_countdown = 100;
countdown_reason = REASON_CONTROLLERINIT;
} }
break; break;
@ -891,33 +903,43 @@ IN_Update(void)
// present themselves as two different devices, triggering SDL_JOYDEVICEADDED // present themselves as two different devices, triggering SDL_JOYDEVICEADDED
// too many times. They could trigger it even at game initialization. // too many times. They could trigger it even at game initialization.
// Also used to keep time of the 'controller gyro calibration' pause. // Also used to keep time of the 'controller gyro calibration' pause.
if (in_delay) if (updates_countdown)
{ {
in_delay--; updates_countdown--;
if (!in_delay) if (!updates_countdown) // Countdown finished, apply needed action by reason
{ {
if (calibrating_gyro) switch (countdown_reason)
{ {
const float inverseSamples = 1.f / num_samples; case REASON_CONTROLLERINIT:
Cvar_SetValue("gyro_calibration_x", gyro_accum[0] * inverseSamples); if (!first_init)
Cvar_SetValue("gyro_calibration_y", gyro_accum[1] * inverseSamples); {
Cvar_SetValue("gyro_calibration_z", gyro_accum[2] * inverseSamples); IN_Controller_Shutdown(false);
calibrating_gyro = false; IN_Controller_Init(true);
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(); else
} {
else if (!first_init) first_init = false;
{ }
IN_Controller_Shutdown(false); break;
IN_Controller_Init(true);
} case REASON_GYROCALIBRATION: // finish and save calibration
else {
{ const float inverseSamples = 1.f / num_samples;
first_init = false; 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);
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();
break;
}
default:
break; // avoiding compiler warning
} }
countdown_reason = REASON_NONE;
} }
} }
} }
/* /*
@ -1358,8 +1380,8 @@ StartCalibration(void)
gyro_accum[1] = 0.0; gyro_accum[1] = 0.0;
gyro_accum[2] = 0.0; gyro_accum[2] = 0.0;
num_samples = 0; num_samples = 0;
calibrating_gyro = true; updates_countdown = 300;
in_delay = 290; countdown_reason = REASON_GYROCALIBRATION;
} }
qboolean qboolean
@ -1514,12 +1536,14 @@ IN_Controller_Init(qboolean notify_user)
&& !SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE) ) && !SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE) )
{ {
float gyro_data_rate = SDL_GameControllerGetSensorDataRate(controller, SDL_SENSOR_GYRO); float gyro_data_rate = SDL_GameControllerGetSensorDataRate(controller, SDL_SENSOR_GYRO);
#ifndef _WIN32
#ifndef _WIN32 // Switch controllers behave differently on Linux & Mac, so sensitivity has to be readjusted
if (gyro_data_rate <= 200.0f) if (gyro_data_rate <= 200.0f)
{ {
normalize_sdl_gyro = 1.0f / 4.5f; normalize_sdl_gyro = 1.0f / 4.5f;
} }
#endif // _WIN32 #endif // _WIN32
gyro_hardware = true; gyro_hardware = true;
Com_Printf("Gyro sensor enabled at %.2f Hz\n", gyro_data_rate); Com_Printf("Gyro sensor enabled at %.2f Hz\n", gyro_data_rate);
} }