Skip to content

Commit

Permalink
Add gyro jitter suppression
Browse files Browse the repository at this point in the history
Controlled by new cvar `gyro_noise_thresh`, defaulting to 1.5 (degrees per second).

Note: samples above this threshold are unchanged (no input delay).
  • Loading branch information
andrei-drexler committed Dec 29, 2023
1 parent d304603 commit 0a9cb6c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
25 changes: 21 additions & 4 deletions Quake/in_sdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ cvar_t gyro_calibration_x = {"gyro_calibration_x", "0", CVAR_ARCHIVE};
cvar_t gyro_calibration_y = {"gyro_calibration_y", "0", CVAR_ARCHIVE};
cvar_t gyro_calibration_z = {"gyro_calibration_z", "0", CVAR_ARCHIVE};

cvar_t gyro_noise_thresh = {"gyro_noise_thresh", "1.5", CVAR_ARCHIVE};

static SDL_JoystickID joy_active_instaceid = -1;
static SDL_GameController *joy_active_controller = NULL;

Expand Down Expand Up @@ -447,6 +449,7 @@ void IN_Init (void)
Cvar_RegisterVariable(&gyro_calibration_x);
Cvar_RegisterVariable(&gyro_calibration_y);
Cvar_RegisterVariable(&gyro_calibration_z);
Cvar_RegisterVariable(&gyro_noise_thresh);

Cmd_AddCommand ("+gyroaction", IN_GyroActionDown);
Cmd_AddCommand ("-gyroaction", IN_GyroActionUp);
Expand Down Expand Up @@ -1103,6 +1106,18 @@ qboolean IN_IsCalibratingGyro (void)
return updates_countdown != 0;
}

static float IN_FilterGyroSample (float prev, float cur)
{
float thresh = DEG2RAD (gyro_noise_thresh.value);
float d = fabs (cur - prev);
if (d < thresh)
{
d /= thresh;
cur = LERP (prev, cur, 0.01f + 0.99f * d * d);
}
return cur;
}

void IN_SendKeyEvents (void)
{
SDL_Event event;
Expand Down Expand Up @@ -1211,15 +1226,17 @@ void IN_SendKeyEvents (void)
}
if (gyro_active && gyro_mode.value)
{
float prev_yaw = gyro_yaw;
float prev_pitch = gyro_pitch;

if (!gyro_turning_axis.value)
{
gyro_yaw = event.csensor.data[1] - gyro_calibration_y.value; // yaw
}
else
{
gyro_yaw = -(event.csensor.data[2] - gyro_calibration_z.value); // roll
}
gyro_pitch = event.csensor.data[0] - gyro_calibration_x.value;

gyro_yaw = IN_FilterGyroSample (prev_yaw, gyro_yaw);
gyro_pitch = IN_FilterGyroSample (prev_pitch, gyro_pitch);
}
else
{
Expand Down
15 changes: 15 additions & 0 deletions Quake/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ extern cvar_t gyro_mode;
extern cvar_t gyro_turning_axis;
extern cvar_t gyro_pitchsensitivity;
extern cvar_t gyro_yawsensitivity;
extern cvar_t gyro_noise_thresh;

extern char crosshair_char;

Expand Down Expand Up @@ -3164,6 +3165,8 @@ void M_Calibration_Key (int key)
#define MAX_TRIGGER_DEADZONE 0.75f
#define MIN_GYRO_SENS 0.1f
#define MAX_GYRO_SENS 8.f
#define MIN_GYRO_NOISE_THRESH 0.f
#define MAX_GYRO_NOISE_THRESH 5.f

/*
================
Expand Down Expand Up @@ -3267,6 +3270,7 @@ void M_Menu_Gamepad_f (void)
def(GPAD_OPT_GYROAXIS, "Gyro Axis") \
def(GPAD_OPT_GYROSENSX, "Gyro Yaw Speed") \
def(GPAD_OPT_GYROSENSY, "Gyro Pitch Speed") \
def(GPAD_OPT_GYRONOISE, "Gyro Noise Thresh")\
def(GPAD_OPT_CALIBRATE, "Calibrate") \
////////////////////////////////////////////////////

Expand Down Expand Up @@ -3761,6 +3765,9 @@ void M_AdjustSliders (int dir)
case GPAD_OPT_GYROSENSY:
Cvar_SetValueQuick (&gyro_pitchsensitivity, CLAMP (MIN_GYRO_SENS, gyro_pitchsensitivity.value + dir * .1f, MAX_GYRO_SENS));
break;
case GPAD_OPT_GYRONOISE:
Cvar_SetValueQuick (&gyro_noise_thresh, CLAMP (MIN_GYRO_NOISE_THRESH, gyro_noise_thresh.value + dir * .5f, MAX_GYRO_NOISE_THRESH));
break;
case GPAD_OPT_CALIBRATE:
M_Menu_Calibration_f ();
break;
Expand Down Expand Up @@ -3888,6 +3895,10 @@ qboolean M_SetSliderValue (int option, float f)
f = LERP (MIN_GYRO_SENS, MAX_GYRO_SENS, f);
Cvar_SetValueQuick (&gyro_pitchsensitivity, f);
return true;
case GPAD_OPT_GYRONOISE:
f = LERP (MIN_GYRO_NOISE_THRESH, MAX_GYRO_NOISE_THRESH, f);
Cvar_SetValueQuick (&gyro_noise_thresh, f);
return true;
default:
return false;
}
Expand Down Expand Up @@ -4203,6 +4214,10 @@ static void M_Options_DrawItem (int y, int item)
r = (gyro_pitchsensitivity.value - MIN_GYRO_SENS) / (MAX_GYRO_SENS - MIN_GYRO_SENS);
M_DrawSlider (x, y, r);
break;
case GPAD_OPT_GYRONOISE:
r = (gyro_noise_thresh.value - MIN_GYRO_NOISE_THRESH) / (MAX_GYRO_NOISE_THRESH - MIN_GYRO_NOISE_THRESH);
M_DrawSlider (x, y, r);
break;

default:
break;
Expand Down

0 comments on commit 0a9cb6c

Please sign in to comment.