Merge pull request #1147 from protocultor/delta_time_fs

Flick Stick fixed duration to 0.1 seconds
This commit is contained in:
Yamagi 2024-09-08 09:49:11 +02:00 committed by GitHub
commit 5ba7695d64
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 300 additions and 239 deletions

View file

@ -570,12 +570,11 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
`1`, which enables gamepad usage; `0` disables its detection at
startup. Can only be set from command line.
* **in_sdlbackbutton**: Defines which button is used in the gamepad or
joystick as the `Esc` key, to access the main menu and 'cancel' /
'go back' on its options. Default is `0`, which corresponds to the
Back/Select/Minus button. Set to `1` to use Start/Menu/Plus, and to
`2` to use the Guide/Home/PS button. Requires a game restart
(or controller replug) when changed.
* **in_sdlbackbutton**: Defines which button is used in the gamepad as
the `Esc` key, to pull the main menu and 'cancel' / 'go back' on its
options. Valid values are `0` = Back / Select / Minus, `1` = Start /
Menu / Plus (default), or `2` = Guide / Home / PS. Requires a game
restart, or gamepad replug, when changed.
* **joy_layout**: Allows to select the stick layout of the gamepad.
- `0`: *Default*, left stick moves, right aims

View file

@ -78,7 +78,7 @@ typedef enum
// IN_Update() called at the beginning of a frame to the
// actual movement functions called at a later time.
static float mouse_x, mouse_y;
static unsigned char sdl_back_button = SDL_CONTROLLER_BUTTON_BACK;
static unsigned char sdl_back_button = SDL_CONTROLLER_BUTTON_START;
static int joystick_left_x, joystick_left_y, joystick_right_x, joystick_right_y;
static float gyro_yaw, gyro_pitch;
static qboolean mlooking;
@ -198,9 +198,10 @@ static unsigned short int updates_countdown = 30;
static updates_countdown_reasons countdown_reason = REASON_CONTROLLERINIT;
// Flick Stick
#define FLICK_TIME 6 // number of frames it takes for a flick to execute
#define FLICK_TIME 100 // time it takes for a flick to execute, in ms
static float target_angle; // angle to end up facing at the end of a flick
static unsigned short int flick_progress = FLICK_TIME;
static float flick_progress = 1.0f; // from 0.0 to 1.0
static int started_flick; // time of flick start
// Flick Stick's rotation input samples to smooth out
#define MAX_SMOOTH_SAMPLES 8
@ -867,11 +868,7 @@ IN_Update(void)
break;
case SDL_CONTROLLERDEVICEREMOVED:
if (!controller)
{
break;
}
if (event.cdevice.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller))) {
if (controller && event.cdevice.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller))) {
Cvar_SetValue("paused", 1);
IN_Controller_Shutdown(true);
IN_Controller_Init(false);
@ -1163,7 +1160,7 @@ IN_FlickStick(thumbstick_t stick, float axial_deadzone)
if (IN_StickMagnitude(stick) > Q_min(joy_flick_threshold->value, 1.0f)) // flick!
{
// Make snap-to-axis only if player wasn't already flicking
if (!is_flicking || flick_progress < FLICK_TIME)
if (!is_flicking || flick_progress < 1.0f)
{
processed = IN_SlopedAxialDeadzone(stick, axial_deadzone);
}
@ -1174,7 +1171,8 @@ IN_FlickStick(thumbstick_t stick, float axial_deadzone)
{
// Flicking begins now, with a new target
is_flicking = true;
flick_progress = 0;
flick_progress = 0.0f;
started_flick = cls.realtime;
target_angle = stick_angle;
IN_ResetSmoothSamples();
}
@ -1212,12 +1210,6 @@ IN_Move(usercmd_t *cmd)
// Factor used to transform from SDL joystick input ([-32768, 32767]) to [-1, 1] range
static const float normalize_sdl_axis = 1.0f / 32768.0f;
// Flick Stick's factors to change to the target angle with a feeling of "ease out"
static const float rotation_factor[FLICK_TIME] =
{
0.305555556f, 0.249999999f, 0.194444445f, 0.138888889f, 0.083333333f, 0.027777778f
};
static float old_mouse_x;
static float old_mouse_y;
static float joystick_yaw, joystick_pitch;
@ -1422,10 +1414,25 @@ IN_Move(usercmd_t *cmd)
}
// Flick Stick: flick in progress, changing the yaw angle to the target progressively
if (flick_progress < FLICK_TIME)
if (flick_progress < 1.0f)
{
cl.viewangles[YAW] += target_angle * rotation_factor[flick_progress];
flick_progress++;
float cur_progress = (float)(cls.realtime - started_flick) / FLICK_TIME;
if (cur_progress > 1.0f)
{
cur_progress = 1.0f;
}
else
{
// "Ease out" warp processing: f(x)=1-(1-x)^2 , 0 <= x <= 1
// http://gyrowiki.jibbsmart.com/blog:good-gyro-controls-part-2:the-flick-stick#toc0
cur_progress = 1.0f - cur_progress;
cur_progress *= cur_progress;
cur_progress = 1.0f - cur_progress;
}
cl.viewangles[YAW] += (cur_progress - flick_progress) * target_angle;
flick_progress = cur_progress;
}
}
@ -2057,19 +2064,19 @@ IN_Controller_Init(qboolean notify_user)
SDL_Joystick *joystick = NULL;
SDL_bool is_controller = SDL_FALSE;
cvar = Cvar_Get("in_sdlbackbutton", "0", CVAR_ARCHIVE);
cvar = Cvar_Get("in_sdlbackbutton", "1", CVAR_ARCHIVE);
if (cvar)
{
switch ((int)cvar->value)
{
case 1:
sdl_back_button = SDL_CONTROLLER_BUTTON_START;
case 0:
sdl_back_button = SDL_CONTROLLER_BUTTON_BACK;
break;
case 2:
sdl_back_button = SDL_CONTROLLER_BUTTON_GUIDE;
break;
default:
sdl_back_button = SDL_CONTROLLER_BUTTON_BACK;
sdl_back_button = SDL_CONTROLLER_BUTTON_START;
}
}

View file

@ -81,7 +81,7 @@ typedef enum
// IN_Update() called at the beginning of a frame to the
// actual movement functions called at a later time.
static float mouse_x, mouse_y;
static unsigned char sdl_back_button = SDL_GAMEPAD_BUTTON_BACK;
static unsigned char sdl_back_button = SDL_GAMEPAD_BUTTON_START;
static int joystick_left_x, joystick_left_y, joystick_right_x, joystick_right_y;
static float gyro_yaw, gyro_pitch;
static qboolean mlooking;
@ -176,9 +176,9 @@ static cvar_t *gyro_calibration_x;
static cvar_t *gyro_calibration_y;
static cvar_t *gyro_calibration_z;
static unsigned int num_samples;
#define NATIVE_SDL_GYRO // uses SDL_CONTROLLERSENSORUPDATE to read gyro
#define NATIVE_SDL_GYRO // uses SDL_EVENT_GAMEPAD_SENSOR_UPDATE to read gyro
// To ignore SDL_JOYDEVICEADDED at game init. Allows for hot plugging of game controller afterwards.
// To ignore SDL_EVENT_JOYSTICK_ADDED at game init. Allows for hot plugging of gamepad afterwards.
static qboolean first_init = true;
// Countdown of calls to IN_Update(), needed for controller init and gyro calibration
@ -188,9 +188,10 @@ static unsigned short int updates_countdown = 30;
static updates_countdown_reasons countdown_reason = REASON_CONTROLLERINIT;
// Flick Stick
#define FLICK_TIME 6 // number of frames it takes for a flick to execute
#define FLICK_TIME 100 // time it takes for a flick to execute, in ms
static float target_angle; // angle to end up facing at the end of a flick
static unsigned short int flick_progress = FLICK_TIME;
static float flick_progress = 1.0f; // from 0.0 to 1.0
static int started_flick; // time of flick start
// Flick Stick's rotation input samples to smooth out
#define MAX_SMOOTH_SAMPLES 8
@ -858,11 +859,7 @@ IN_Update(void)
break;
case SDL_EVENT_GAMEPAD_REMOVED :
if (!controller)
{
break;
}
if (event.gdevice.which == SDL_GetJoystickInstanceID(SDL_GetGamepadJoystick(controller))) {
if (controller && event.gdevice.which == SDL_GetJoystickInstanceID(SDL_GetGamepadJoystick(controller))) {
Cvar_SetValue("paused", 1);
IN_Controller_Shutdown(true);
IN_Controller_Init(false);
@ -919,7 +916,7 @@ IN_Update(void)
sys_frame_time = Sys_Milliseconds();
// Hot plugging delay handling, to not be "overwhelmed" because some controllers
// present themselves as two different devices, triggering SDL_JOYDEVICEADDED
// present themselves as two different devices, triggering SDL_EVENT_JOYSTICK_ADDED
// too many times. They could trigger it even at game initialization.
// Also used to keep time of the 'controller gyro calibration' pause.
if (updates_countdown)
@ -951,7 +948,7 @@ IN_Update(void)
#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");
Com_Printf("Calibration failed, please retry inside a level after having moved your gamepad a little.\n");
}
else
{
@ -1148,7 +1145,7 @@ IN_FlickStick(thumbstick_t stick, float axial_deadzone)
if (IN_StickMagnitude(stick) > Q_min(joy_flick_threshold->value, 1.0f)) // flick!
{
// Make snap-to-axis only if player wasn't already flicking
if (!is_flicking || flick_progress < FLICK_TIME)
if (!is_flicking || flick_progress < 1.0f)
{
processed = IN_SlopedAxialDeadzone(stick, axial_deadzone);
}
@ -1159,7 +1156,8 @@ IN_FlickStick(thumbstick_t stick, float axial_deadzone)
{
// Flicking begins now, with a new target
is_flicking = true;
flick_progress = 0;
flick_progress = 0.0f;
started_flick = cls.realtime;
target_angle = stick_angle;
IN_ResetSmoothSamples();
}
@ -1197,12 +1195,6 @@ IN_Move(usercmd_t *cmd)
// Factor used to transform from SDL joystick input ([-32768, 32767]) to [-1, 1] range
static const float normalize_sdl_axis = 1.0f / 32768.0f;
// Flick Stick's factors to change to the target angle with a feeling of "ease out"
static const float rotation_factor[FLICK_TIME] =
{
0.305555556f, 0.249999999f, 0.194444445f, 0.138888889f, 0.083333333f, 0.027777778f
};
static float old_mouse_x;
static float old_mouse_y;
static float joystick_yaw, joystick_pitch;
@ -1407,10 +1399,25 @@ IN_Move(usercmd_t *cmd)
}
// Flick Stick: flick in progress, changing the yaw angle to the target progressively
if (flick_progress < FLICK_TIME)
if (flick_progress < 1.0f)
{
cl.viewangles[YAW] += target_angle * rotation_factor[flick_progress];
flick_progress++;
float cur_progress = (float)(cls.realtime - started_flick) / FLICK_TIME;
if (cur_progress > 1.0f)
{
cur_progress = 1.0f;
}
else
{
// "Ease out" warp processing: f(x)=1-(1-x)^2 , 0 <= x <= 1
// http://gyrowiki.jibbsmart.com/blog:good-gyro-controls-part-2:the-flick-stick#toc0
cur_progress = 1.0f - cur_progress;
cur_progress *= cur_progress;
cur_progress = 1.0f - cur_progress;
}
cl.viewangles[YAW] += (cur_progress - flick_progress) * target_angle;
flick_progress = cur_progress;
}
}
@ -2043,19 +2050,19 @@ IN_Controller_Init(qboolean notify_user)
SDL_Joystick *joystick = NULL;
SDL_bool is_controller = SDL_FALSE;
cvar = Cvar_Get("in_sdlbackbutton", "0", CVAR_ARCHIVE);
cvar = Cvar_Get("in_sdlbackbutton", "1", CVAR_ARCHIVE);
if (cvar)
{
switch ((int)cvar->value)
{
case 1:
sdl_back_button = SDL_GAMEPAD_BUTTON_START;
case 0:
sdl_back_button = SDL_GAMEPAD_BUTTON_BACK;
break;
case 2:
sdl_back_button = SDL_GAMEPAD_BUTTON_GUIDE;
break;
default:
sdl_back_button = SDL_GAMEPAD_BUTTON_BACK;
sdl_back_button = SDL_GAMEPAD_BUTTON_START;
}
}
@ -2067,7 +2074,7 @@ IN_Controller_Init(qboolean notify_user)
if (notify_user)
{
Com_Printf("- Game Controller init attempt -\n");
Com_Printf("- Gamepad init attempt -\n");
}
if (!SDL_WasInit(SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC))
@ -2082,7 +2089,7 @@ IN_Controller_Init(qboolean notify_user)
if (SDL_Init(SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC) == -1)
{
Com_Printf ("Couldn't init SDL Game Controller: %s.\n", SDL_GetError());
Com_Printf ("Couldn't init SDL Gamepad: %s.\n", SDL_GetError());
return;
}
}
@ -2176,7 +2183,7 @@ IN_Controller_Init(qboolean notify_user)
SDL_GetJoystickGUIDString(guid, joystick_guid, 64);
Com_Printf ("To use joystick as game controller, provide its config by either:\n"
Com_Printf ("To identify joystick as Gamepad, provide its config by either:\n"
" * Putting 'gamecontrollerdb.txt' file in your game directory.\n"
" * Or setting SDL_GAMECONTROLLERCONFIG environment variable. E.g.:\n");
Com_Printf ("SDL_GAMECONTROLLERCONFIG='%s,%s,leftx:a0,lefty:a1,rightx:a2,righty:a3,back:b1,...'\n", joystick_guid, joystick_name);
@ -2190,12 +2197,12 @@ IN_Controller_Init(qboolean notify_user)
controller = SDL_OpenGamepad(joysticks[i]);
if (!controller)
{
Com_Printf("SDL Controller error: %s.\n", SDL_GetError());
Com_Printf("SDL Gamepad error: %s.\n", SDL_GetError());
continue; // try next joystick
}
show_gamepad = true;
Com_Printf("Enabled as Game Controller, settings:\n%s\n",
Com_Printf("Enabled as Gamepad, settings:\n%s\n",
SDL_GetGamepadMapping(controller));
#ifdef NATIVE_SDL_GYRO
@ -2244,7 +2251,7 @@ IN_Controller_Init(qboolean notify_user)
}
else
{
Com_Printf("Controller doesn't support rumble.\n");
Com_Printf("Gamepad doesn't support rumble.\n");
}
#ifdef NATIVE_SDL_GYRO // "native" exits when finding a single working controller
@ -2360,7 +2367,7 @@ IN_Controller_Shutdown(qboolean notify_user)
{
if (notify_user)
{
Com_Printf("- Game Controller disconnected -\n");
Com_Printf("- Gamepad disconnected -\n");
}
IN_Haptic_Shutdown();

View file

@ -1955,7 +1955,7 @@ Gyro_MenuInit(void)
s_calibrating_text[0].generic.type = MTYPE_SEPARATOR;
s_calibrating_text[0].generic.x = 48 * scale + 32;
s_calibrating_text[0].generic.y = (y += 20);
s_calibrating_text[0].generic.name = "place the controller on a flat,";
s_calibrating_text[0].generic.name = "place the gamepad on a flat,";
s_calibrating_text[1].generic.type = MTYPE_SEPARATOR;
s_calibrating_text[1].generic.x = 48 * scale + 32;

View file

@ -79,6 +79,16 @@ static menuaction_s s_apply_action;
// gl1, gl3, gles1, gles3, gl4, vk, soft
#define MAXRENDERERS 7
typedef enum
{
ref_custom,
ref_gl1, // encompasses gl1 and gles1
ref_gl3, // encompasses gl3 and gles3
ref_gl4,
ref_vk,
ref_soft
} renderer_type;
typedef struct
{
const char *boxstr;
@ -195,12 +205,39 @@ ResetDefaults(void *unused)
#define CUSTOM_MODE_NAME "[Custom ]"
#define AUTO_MODE_NAME "[Auto ]"
static renderer_type
CurrentRendererByCvar(void)
{
if (Q_stricmp(vid_renderer->string, "gl3") == 0 || Q_stricmp(vid_renderer->string, "gles3") == 0)
{
return ref_gl3;
}
if (Q_stricmp(vid_renderer->string, "gl1") == 0 || Q_stricmp(vid_renderer->string, "gles1") == 0)
{
return ref_gl1;
}
if (Q_stricmp(vid_renderer->string, "soft") == 0)
{
return ref_soft;
}
if (Q_stricmp(vid_renderer->string, "gl4") == 0)
{
return ref_gl4;
}
if (Q_stricmp(vid_renderer->string, "vk") == 0)
{
return ref_vk;
}
return ref_custom;
}
static void
ApplyFilter(void* unused)
{
if (Q_stricmp(vid_renderer->string, "gl3") == 0 || Q_stricmp(vid_renderer->string, "gles3") == 0 ||
Q_stricmp(vid_renderer->string, "gl1") == 0 || Q_stricmp(vid_renderer->string, "gles1") == 0)
switch (CurrentRendererByCvar())
{
case ref_gl3:
case ref_gl1:
if (s_filter_list.curvalue == 0)
{
Cvar_Set("gl_texturemode", "GL_NEAREST");
@ -213,10 +250,8 @@ ApplyFilter(void* unused)
{
Cvar_Set("gl_texturemode", "GL_LINEAR_MIPMAP_LINEAR");
}
}
if (Q_stricmp(vid_renderer->string, "soft") == 0)
{
break;
case ref_soft:
if (s_filter_list.curvalue == 0)
{
Cvar_Set("sw_texture_filtering", "0");
@ -225,6 +260,9 @@ ApplyFilter(void* unused)
{
Cvar_Set("sw_texture_filtering", "1");
}
break;
default:
break; // avoid compiler warning
}
}
@ -412,6 +450,8 @@ VID_MenuInit(void)
0
};
const renderer_type current_renderer = CurrentRendererByCvar();
static const char *uiscale_names[] = {
"auto",
"1x",
@ -569,8 +609,9 @@ VID_MenuInit(void)
s_fov_slider.slidestep = 1;
s_fov_slider.printformat = "%.0f";
if (strcmp(vid_renderer->string, "gl3") == 0 || strcmp(vid_renderer->string, "gles3") == 0)
switch (current_renderer)
{
case ref_gl3:
s_gl3_intensity_slider.generic.type = MTYPE_SLIDER;
s_gl3_intensity_slider.generic.name = "color intensity";
s_gl3_intensity_slider.generic.x = 0;
@ -594,9 +635,9 @@ VID_MenuInit(void)
s_gl3_colorlight_list.generic.y = (y += 10);
s_gl3_colorlight_list.itemnames = yesno_names;
s_gl3_colorlight_list.curvalue = (gl3_colorlight->value != 0);
}
if (strcmp(vid_renderer->string, "gl4") == 0)
{
break;
case ref_gl4:
s_gl4_intensity_slider.generic.type = MTYPE_SLIDER;
s_gl4_intensity_slider.generic.name = "color intensity";
s_gl4_intensity_slider.generic.x = 0;
@ -620,9 +661,9 @@ VID_MenuInit(void)
s_gl4_colorlight_list.generic.y = (y += 10);
s_gl4_colorlight_list.itemnames = yesno_names;
s_gl4_colorlight_list.curvalue = (gl4_colorlight->value != 0);
}
else if (strcmp(vid_renderer->string, "vk") == 0)
{
break;
case ref_vk:
s_vk_intensity_slider.generic.type = MTYPE_SLIDER;
s_vk_intensity_slider.generic.name = "color intensity";
s_vk_intensity_slider.generic.x = 0;
@ -648,9 +689,9 @@ VID_MenuInit(void)
s_vk_dynamic_list.generic.y = (y += 10);
s_vk_dynamic_list.itemnames = yesno_names;
s_vk_dynamic_list.curvalue = (vk_dynamic->value != 0);
}
else
{
break;
case ref_gl1:
gl3_colorlight = NULL;
s_gl1_intensity_slider.generic.type = MTYPE_SLIDER;
s_gl1_intensity_slider.generic.name = "color intensity";
@ -669,6 +710,10 @@ VID_MenuInit(void)
s_gl1_overbrightbits_slider.maxvalue = 2;
s_gl1_overbrightbits_slider.slidestep = 1;
s_gl1_overbrightbits_slider.printformat = "%.0f";
break;
default:
break;
}
s_uiscale_list.generic.type = MTYPE_SPINCONTROL;
@ -747,14 +792,15 @@ VID_MenuInit(void)
s_filter_list.generic.name = "texture filter";
s_filter_list.curvalue = 0;
s_filter_list.generic.callback = ApplyFilter;
s_filter_list.generic.x = 0;
const char* filter = NULL;
int mode = 0;
if (Q_stricmp(vid_renderer->string, "gl3") == 0 || Q_stricmp(vid_renderer->string, "gles3") == 0 ||
Q_stricmp(vid_renderer->string, "gl1") == 0 || Q_stricmp(vid_renderer->string, "gles1") == 0)
switch (current_renderer)
{
s_filter_list.generic.x = 0;
case ref_gl3:
case ref_gl1:
s_filter_list.generic.y = (y += 10);
s_filter_list.itemnames = filter_names;
@ -773,10 +819,9 @@ VID_MenuInit(void)
{
mode = 2;
}
}
else if (Q_stricmp(vid_renderer->string, "soft") == 0)
{
s_filter_list.generic.x = 0;
break;
case ref_soft:
s_filter_list.generic.y = (y += 10);
s_filter_list.itemnames = onoff_names;
@ -787,6 +832,10 @@ VID_MenuInit(void)
{
mode = 1;
}
break;
default:
break;
}
s_filter_list.curvalue = mode;
@ -814,37 +863,36 @@ VID_MenuInit(void)
Menu_AddItem(&s_opengl_menu, (void *)&s_brightness_slider);
Menu_AddItem(&s_opengl_menu, (void *)&s_fov_slider);
if (strcmp(vid_renderer->string, "gl3") == 0 || strcmp(vid_renderer->string, "gles3") == 0)
switch (current_renderer)
{
case ref_gl3:
Menu_AddItem(&s_opengl_menu, (void *)&s_gl3_intensity_slider);
Menu_AddItem(&s_opengl_menu, (void *)&s_gl3_overbrightbits_slider);
Menu_AddItem(&s_opengl_menu, (void *)&s_gl3_colorlight_list);
}
else if (strcmp(vid_renderer->string, "gl4") == 0)
{
break;
case ref_gl4:
Menu_AddItem(&s_opengl_menu, (void *)&s_gl4_intensity_slider);
Menu_AddItem(&s_opengl_menu, (void *)&s_gl4_overbrightbits_slider);
Menu_AddItem(&s_opengl_menu, (void *)&s_gl4_colorlight_list);
}
else if (strcmp(vid_renderer->string, "vk") == 0)
{
break;
case ref_vk:
Menu_AddItem(&s_opengl_menu, (void *)&s_vk_intensity_slider);
Menu_AddItem(&s_opengl_menu, (void *)&s_vk_overbrightbits_slider);
Menu_AddItem(&s_opengl_menu, (void *)&s_vk_dynamic_list);
}
else if (strcmp(vid_renderer->string, "gl1") == 0 || strcmp(vid_renderer->string, "gles1") == 0)
{
break;
case ref_gl1:
Menu_AddItem(&s_opengl_menu, (void *)&s_gl1_intensity_slider);
Menu_AddItem(&s_opengl_menu, (void *)&s_gl1_overbrightbits_slider);
break;
default:
break;
}
Menu_AddItem(&s_opengl_menu, (void *)&s_uiscale_list);
Menu_AddItem(&s_opengl_menu, (void *)&s_fs_box);
Menu_AddItem(&s_opengl_menu, (void *)&s_vsync_list);
Menu_AddItem(&s_opengl_menu, (void *)&s_af_list);
Menu_AddItem(&s_opengl_menu, (void *)&s_msaa_list);
if (Q_stricmp(vid_renderer->string, "gl3") == 0 || Q_stricmp(vid_renderer->string, "gles3") == 0 ||
Q_stricmp(vid_renderer->string, "gl1") == 0 || Q_stricmp(vid_renderer->string, "gles1") == 0 ||
Q_stricmp(vid_renderer->string, "soft") == 0)
if (current_renderer == ref_gl3 || current_renderer == ref_gl1 || current_renderer == ref_soft)
{
Menu_AddItem(&s_opengl_menu, (void *)&s_filter_list);
}