Enhanced sliders for menus

"menuslider_s" types, used to create sliders in menus, now are directly
associated to a cvar. That makes possible for them to get their
currently selected value from the cvar, and express their min and max
values in terms of the real values of the cvar.
The rhythm at how they change can be overridden with s->slidestep.
The new sliders also present visually their current value to the user,
making them more useful than before.
This commit is contained in:
Jaime Moreira 2022-07-30 14:23:33 -04:00
parent f9ab797c7c
commit 6c4866995b
4 changed files with 93 additions and 201 deletions

View File

@ -108,11 +108,11 @@ typedef struct
{
menucommon_s generic;
float minvalue;
float maxvalue;
float curvalue;
float range;
char * cvar;
float minvalue;
float maxvalue;
float slidestep;
char * printformat;
} menuslider_s;
typedef struct
@ -144,11 +144,12 @@ void *Menu_ItemAtCursor(menuframework_s *m);
qboolean Menu_SelectItem(menuframework_s *s);
void Menu_SetStatusBar(menuframework_s *s, const char *string);
void Menu_SlideItem(menuframework_s *s, int dir);
int Menu_TallySlots(menuframework_s *menu);
void Menu_DrawString(int, int, const char *);
void Menu_DrawStringDark(int, int, const char *);
void Menu_DrawStringR2L(int, int, const char *);
void Menu_DrawStringR2LDark(int, int, const char *);
float ClampCvar(float min, float max, float value);
#endif

View File

@ -86,22 +86,6 @@ typedef struct
menulayer_t m_layers[MAX_MENU_DEPTH];
int m_menudepth;
static float
ClampCvar(float min, float max, float value)
{
if (value < min)
{
return min;
}
if (value > max)
{
return max;
}
return value;
}
static qboolean
M_IsGame(const char *gamename)
{
@ -1667,18 +1651,6 @@ TurningAxisFunc(void *unused)
Cvar_SetValue("gyro_turning_axis", (int)s_turning_axis_box.curvalue);
}
static void
GyroYawSensitivityFunc(void *unused)
{
Cvar_SetValue("gyro_yawsensitivity", s_gyro_yawsensitivity_slider.curvalue / 10.0F);
}
static void
GyroPitchSensitivityFunc(void *unused)
{
Cvar_SetValue("gyro_pitchsensitivity", s_gyro_pitchsensitivity_slider.curvalue / 10.0F);
}
static void
Gyro_MenuInit(void)
{
@ -1724,19 +1696,17 @@ Gyro_MenuInit(void)
s_gyro_yawsensitivity_slider.generic.x = 0;
s_gyro_yawsensitivity_slider.generic.y = (y += 20);
s_gyro_yawsensitivity_slider.generic.name = "yaw sensitivity";
s_gyro_yawsensitivity_slider.generic.callback = GyroYawSensitivityFunc;
s_gyro_yawsensitivity_slider.minvalue = 1;
s_gyro_yawsensitivity_slider.maxvalue = 80;
s_gyro_yawsensitivity_slider.curvalue = gyro_yawsensitivity->value * 10;
s_gyro_yawsensitivity_slider.cvar = "gyro_yawsensitivity";
s_gyro_yawsensitivity_slider.minvalue = 0.1f;
s_gyro_yawsensitivity_slider.maxvalue = 8.0f;
s_gyro_pitchsensitivity_slider.generic.type = MTYPE_SLIDER;
s_gyro_pitchsensitivity_slider.generic.x = 0;
s_gyro_pitchsensitivity_slider.generic.y = (y += 10);
s_gyro_pitchsensitivity_slider.generic.name = "pitch sensitivity";
s_gyro_pitchsensitivity_slider.generic.callback = GyroPitchSensitivityFunc;
s_gyro_pitchsensitivity_slider.minvalue = 1;
s_gyro_pitchsensitivity_slider.maxvalue = 80;
s_gyro_pitchsensitivity_slider.curvalue = gyro_pitchsensitivity->value * 10;
s_gyro_pitchsensitivity_slider.cvar = "gyro_pitchsensitivity";
s_gyro_pitchsensitivity_slider.minvalue = 0.1f;
s_gyro_pitchsensitivity_slider.maxvalue = 8.0f;
s_calibrating_text[0].generic.type = MTYPE_SEPARATOR;
s_calibrating_text[0].generic.x = 48 * scale + 30;
@ -1823,48 +1793,6 @@ ConfigGyroFunc(void *unused)
M_Menu_Gyro_f();
}
static void
HapticMagnitudeFunc(void *unused)
{
Cvar_SetValue("joy_haptic_magnitude", s_joy_haptic_slider.curvalue / 10.0F);
}
static void
JoyExpoFunc(void *unused)
{
Cvar_SetValue("joy_expo", s_joy_expo_slider.curvalue / 10.0F);
}
static void
JoyYawSensitivityFunc(void *unused)
{
Cvar_SetValue("joy_yawsensitivity", s_joy_yawsensitivity_slider.curvalue / 10.0F);
}
static void
JoyPitchSensitivityFunc(void *unused)
{
Cvar_SetValue("joy_pitchsensitivity", s_joy_pitchsensitivity_slider.curvalue / 10.0F);
}
static void
JoyForwardSensitivityFunc(void *unused)
{
Cvar_SetValue("joy_forwardsensitivity", s_joy_forwardsensitivity_slider.curvalue / 10.0F);
}
static void
JoySideSensitivityFunc(void *unused)
{
Cvar_SetValue("joy_sidesensitivity", s_joy_sidesensitivity_slider.curvalue / 10.0F);
}
static void
JoyUpSensitivityFunc(void *unused)
{
Cvar_SetValue("joy_upsensitivity", s_joy_upsensitivity_slider.curvalue / 10.0F);
}
static void
Joy_MenuInit(void)
{
@ -1874,90 +1802,83 @@ Joy_MenuInit(void)
s_joy_menu.x = (int)(viddef.width * 0.50f);
s_joy_menu.nitems = 0;
s_joy_yawsensitivity_slider.curvalue = joy_yawsensitivity->value * 10;
s_joy_yawsensitivity_slider.generic.type = MTYPE_SLIDER;
s_joy_yawsensitivity_slider.generic.x = 0;
s_joy_yawsensitivity_slider.generic.y = y;
y += 10;
s_joy_yawsensitivity_slider.generic.name = "yaw sensitivity";
s_joy_yawsensitivity_slider.generic.callback = JoyYawSensitivityFunc;
s_joy_yawsensitivity_slider.minvalue = 0;
s_joy_yawsensitivity_slider.maxvalue = 70;
s_joy_yawsensitivity_slider.cvar = "joy_yawsensitivity";
s_joy_yawsensitivity_slider.minvalue = 0.0f;
s_joy_yawsensitivity_slider.maxvalue = 7.0f;
Menu_AddItem(&s_joy_menu, (void *)&s_joy_yawsensitivity_slider);
s_joy_pitchsensitivity_slider.curvalue = joy_pitchsensitivity->value * 10;
s_joy_pitchsensitivity_slider.generic.type = MTYPE_SLIDER;
s_joy_pitchsensitivity_slider.generic.x = 0;
s_joy_pitchsensitivity_slider.generic.y = y;
y += 10;
s_joy_pitchsensitivity_slider.generic.name = "pitch sensitivity";
s_joy_pitchsensitivity_slider.generic.callback = JoyPitchSensitivityFunc;
s_joy_pitchsensitivity_slider.minvalue = 0;
s_joy_pitchsensitivity_slider.maxvalue = 70;
s_joy_pitchsensitivity_slider.cvar = "joy_pitchsensitivity";
s_joy_pitchsensitivity_slider.minvalue = 0.0f;
s_joy_pitchsensitivity_slider.maxvalue = 7.0f;
Menu_AddItem(&s_joy_menu, (void *)&s_joy_pitchsensitivity_slider);
y += 10;
s_joy_forwardsensitivity_slider.curvalue = joy_forwardsensitivity->value * 10;
s_joy_forwardsensitivity_slider.generic.type = MTYPE_SLIDER;
s_joy_forwardsensitivity_slider.generic.x = 0;
s_joy_forwardsensitivity_slider.generic.y = y;
y += 10;
s_joy_forwardsensitivity_slider.generic.name = "forward sensitivity";
s_joy_forwardsensitivity_slider.generic.callback = JoyForwardSensitivityFunc;
s_joy_forwardsensitivity_slider.minvalue = 0;
s_joy_forwardsensitivity_slider.maxvalue = 20;
s_joy_forwardsensitivity_slider.cvar = "joy_forwardsensitivity";
s_joy_forwardsensitivity_slider.minvalue = 0.0f;
s_joy_forwardsensitivity_slider.maxvalue = 2.0f;
Menu_AddItem(&s_joy_menu, (void *)&s_joy_forwardsensitivity_slider);
s_joy_sidesensitivity_slider.curvalue = joy_sidesensitivity->value * 10;
s_joy_sidesensitivity_slider.generic.type = MTYPE_SLIDER;
s_joy_sidesensitivity_slider.generic.x = 0;
s_joy_sidesensitivity_slider.generic.y = y;
y += 10;
s_joy_sidesensitivity_slider.generic.name = "side sensitivity";
s_joy_sidesensitivity_slider.generic.callback = JoySideSensitivityFunc;
s_joy_sidesensitivity_slider.minvalue = 0;
s_joy_sidesensitivity_slider.maxvalue = 20;
s_joy_sidesensitivity_slider.cvar = "joy_sidesensitivity";
s_joy_sidesensitivity_slider.minvalue = 0.0f;
s_joy_sidesensitivity_slider.maxvalue = 2.0f;
Menu_AddItem(&s_joy_menu, (void *)&s_joy_sidesensitivity_slider);
y += 10;
s_joy_upsensitivity_slider.curvalue = joy_upsensitivity->value * 10;
s_joy_upsensitivity_slider.generic.type = MTYPE_SLIDER;
s_joy_upsensitivity_slider.generic.x = 0;
s_joy_upsensitivity_slider.generic.y = y;
y += 10;
s_joy_upsensitivity_slider.generic.name = "up sensitivity";
s_joy_upsensitivity_slider.generic.callback = JoyUpSensitivityFunc;
s_joy_upsensitivity_slider.minvalue = 0;
s_joy_upsensitivity_slider.maxvalue = 20;
s_joy_upsensitivity_slider.cvar = "joy_upsensitivity";
s_joy_upsensitivity_slider.minvalue = 0.0f;
s_joy_upsensitivity_slider.maxvalue = 2.0f;
Menu_AddItem(&s_joy_menu, (void *)&s_joy_upsensitivity_slider);
y += 10;
s_joy_expo_slider.curvalue = joy_expo->value * 10;
s_joy_expo_slider.generic.type = MTYPE_SLIDER;
s_joy_expo_slider.generic.x = 0;
s_joy_expo_slider.generic.y = y;
y += 10;
s_joy_expo_slider.generic.name = "expo";
s_joy_expo_slider.generic.callback = JoyExpoFunc;
s_joy_expo_slider.minvalue = 10;
s_joy_expo_slider.maxvalue = 50;
s_joy_expo_slider.cvar = "joy_expo";
s_joy_expo_slider.minvalue = 1;
s_joy_expo_slider.maxvalue = 5;
Menu_AddItem(&s_joy_menu, (void *)&s_joy_expo_slider);
if (show_haptic) {
y += 10;
s_joy_haptic_slider.curvalue = Cvar_VariableValue("joy_haptic_magnitude") * 10.0F;
s_joy_haptic_slider.generic.type = MTYPE_SLIDER;
s_joy_haptic_slider.generic.x = 0;
s_joy_haptic_slider.generic.y = y;
y += 10;
s_joy_haptic_slider.generic.name = "haptic magnitude";
s_joy_haptic_slider.generic.callback = HapticMagnitudeFunc;
s_joy_haptic_slider.minvalue = 0;
s_joy_haptic_slider.maxvalue = 22;
s_joy_haptic_slider.cvar = "joy_haptic_magnitude";
s_joy_haptic_slider.minvalue = 0.0f;
s_joy_haptic_slider.maxvalue = 2.2f;
Menu_AddItem(&s_joy_menu, (void *)&s_joy_haptic_slider);
}
@ -2066,21 +1987,12 @@ FreeLookFunc(void *unused)
Cvar_SetValue("freelook", (float)s_options_freelook_box.curvalue);
}
static void
MouseSpeedFunc(void *unused)
{
Cvar_SetValue("sensitivity", s_options_sensitivity_slider.curvalue / 2.0F);
}
static void
ControlsSetMenuItemValues(void)
{
s_options_sfxvolume_slider.curvalue = Cvar_VariableValue("s_volume") * 10;
s_options_oggshuffle_box.curvalue = (Cvar_VariableValue("ogg_shuffle") != 0);
s_options_oggvolume_slider.curvalue = Cvar_VariableValue("ogg_volume") * 10;
s_options_oggenable_box.curvalue = (Cvar_VariableValue("ogg_enable") != 0);
s_options_quality_list.curvalue = (Cvar_VariableValue("s_loadas8bit") == 0);
s_options_sensitivity_slider.curvalue = sensitivity->value * 2;
s_options_alwaysrun_box.curvalue = (cl_run->value != 0);
s_options_invertmouse_box.curvalue = (m_pitch->value < 0);
s_options_lookstrafe_box.curvalue = (lookstrafe->value != 0);
@ -2110,12 +2022,6 @@ LookstrafeFunc(void *unused)
Cvar_SetValue("lookstrafe", (float)!lookstrafe->value);
}
static void
UpdateVolumeFunc(void *unused)
{
Cvar_SetValue("s_volume", s_options_sfxvolume_slider.curvalue / 10);
}
static void
OGGShuffleFunc(void *unused)
{
@ -2139,12 +2045,6 @@ OGGShuffleFunc(void *unused)
}
}
static void
UpdateOggVolumeFunc(void *unused)
{
Cvar_SetValue("ogg_volume", s_options_oggvolume_slider.curvalue / 10);
}
static void
EnableOGGMusic(void *unused)
{
@ -2266,17 +2166,17 @@ Options_MenuInit(void)
s_options_sfxvolume_slider.generic.x = 0;
s_options_sfxvolume_slider.generic.y = 0;
s_options_sfxvolume_slider.generic.name = "effects volume";
s_options_sfxvolume_slider.generic.callback = UpdateVolumeFunc;
s_options_sfxvolume_slider.minvalue = 0;
s_options_sfxvolume_slider.maxvalue = 10;
s_options_sfxvolume_slider.cvar = "s_volume";
s_options_sfxvolume_slider.minvalue = 0.0f;
s_options_sfxvolume_slider.maxvalue = 1.0f;
s_options_oggvolume_slider.generic.type = MTYPE_SLIDER;
s_options_oggvolume_slider.generic.x = 0;
s_options_oggvolume_slider.generic.y = 10;
s_options_oggvolume_slider.generic.name = "OGG volume";
s_options_oggvolume_slider.generic.callback = UpdateOggVolumeFunc;
s_options_oggvolume_slider.minvalue = 0;
s_options_oggvolume_slider.maxvalue = 10;
s_options_oggvolume_slider.cvar = "ogg_volume";
s_options_oggvolume_slider.minvalue = 0.0f;
s_options_oggvolume_slider.maxvalue = 1.0f;
s_options_oggenable_box.generic.type = MTYPE_SPINCONTROL;
s_options_oggenable_box.generic.x = 0;
@ -2303,9 +2203,10 @@ Options_MenuInit(void)
s_options_sensitivity_slider.generic.x = 0;
s_options_sensitivity_slider.generic.y = 60;
s_options_sensitivity_slider.generic.name = "mouse speed";
s_options_sensitivity_slider.generic.callback = MouseSpeedFunc;
s_options_sensitivity_slider.cvar = "sensitivity";
s_options_sensitivity_slider.minvalue = 0;
s_options_sensitivity_slider.maxvalue = 22;
s_options_sensitivity_slider.maxvalue = 11;
s_options_sensitivity_slider.slidestep = 0.5f;
s_options_alwaysrun_box.generic.type = MTYPE_SPINCONTROL;
s_options_alwaysrun_box.generic.x = 0;

View File

@ -43,6 +43,22 @@ extern viddef_t viddef;
#define VID_WIDTH viddef.width
#define VID_HEIGHT viddef.height
float
ClampCvar(float min, float max, float value)
{
if (value < min)
{
return min;
}
if (value > max)
{
return max;
}
return value;
}
/*
=================
Bitmap_Draw
@ -643,16 +659,15 @@ Separator_Draw(menuseparator_s *s)
void
Slider_DoSlide(menuslider_s *s, int dir)
{
s->curvalue += dir;
float value = Cvar_VariableValue(s->cvar);
float step = 0.1f;
if (s->curvalue > s->maxvalue)
if (s->slidestep)
{
s->curvalue = s->maxvalue;
}
else if (s->curvalue < s->minvalue)
{
s->curvalue = s->minvalue;
step = s->slidestep;
}
value += dir * step;
Cvar_SetValue(s->cvar, ClampCvar(s->minvalue, s->maxvalue, value));
if (s->generic.callback)
{
@ -666,29 +681,19 @@ void
Slider_Draw(menuslider_s *s)
{
int i;
char buffer[5];
const char * format;
float scale = SCR_GetMenuScale();
int x = 0;
int y = 0;
int x = s->generic.parent->x + s->generic.x;
int y = s->generic.parent->y + s->generic.y;
x = s->generic.parent->x + s->generic.x;
y = s->generic.parent->y + s->generic.y;
float value = Cvar_VariableValue(s->cvar);
float range = (ClampCvar(s->minvalue, s->maxvalue, value) - s->minvalue) /
(s->maxvalue - s->minvalue);
Menu_DrawStringR2LDark(x + (LCOLUMN_OFFSET * scale),
y, s->generic.name);
s->range = (s->curvalue - s->minvalue) /
(float)(s->maxvalue - s->minvalue);
if (s->range < 0)
{
s->range = 0;
}
if (s->range > 1)
{
s->range = 1;
}
Draw_CharScaled(x + (RCOLUMN_OFFSET * scale),
y * scale, 128, scale);
@ -698,10 +703,22 @@ Slider_Draw(menuslider_s *s)
y * scale, 129, scale);
}
Draw_CharScaled(x + (RCOLUMN_OFFSET * scale) + (i * 8) + + 8,
Draw_CharScaled(x + (RCOLUMN_OFFSET * scale) + (i * 8) + 8,
y * scale, 130, scale);
Draw_CharScaled(x + ((int)((RCOLUMN_OFFSET * scale) + (SLIDER_RANGE * scale - 1) * 8 * s->range)) + 8,
Draw_CharScaled(x + ((int)((RCOLUMN_OFFSET * scale) + (SLIDER_RANGE * scale - 1) * 8 * range)) + 8,
y * scale, 131, scale);
if (!s->printformat)
{
format = "%.1f";
}
else
{
format = s->printformat;
}
snprintf(buffer, 5, format, value);
Menu_DrawString(x + (RCOLUMN_OFFSET * scale) + ((SLIDER_RANGE + 2) * scale * 8),
y, buffer);
}
void

View File

@ -37,9 +37,7 @@ static cvar_t *r_hudscale;
static cvar_t *r_consolescale;
static cvar_t *r_menuscale;
static cvar_t *crosshair_scale;
static cvar_t *fov;
extern cvar_t *scr_viewsize;
extern cvar_t *vid_gamma;
extern cvar_t *vid_fullscreen;
extern cvar_t *vid_renderer;
static cvar_t *r_vsync;
@ -159,21 +157,6 @@ GetCustomValue(menulist_s *list)
return i;
}
static void
BrightnessCallback(void *s)
{
menuslider_s *slider = (menuslider_s *)s;
float gamma = slider->curvalue / 10.0;
Cvar_SetValue("vid_gamma", gamma);
}
static void
FOVCallback(void *s) {
menuslider_s *slider = (menuslider_s *)s;
Cvar_SetValue("fov", slider->curvalue);
}
static void
ResetDefaults(void *unused)
{
@ -426,16 +409,6 @@ VID_MenuInit(void)
crosshair_scale = Cvar_Get("crosshair_scale", "-1", CVAR_ARCHIVE);
}
if (!fov)
{
fov = Cvar_Get("fov", "90", CVAR_USERINFO | CVAR_ARCHIVE);
}
if (!vid_gamma)
{
vid_gamma = Cvar_Get("vid_gamma", "1.2", CVAR_ARCHIVE);
}
if (!vid_renderer)
{
vid_renderer = Cvar_Get("vid_renderer", "gl1", CVAR_ARCHIVE);
@ -501,19 +474,19 @@ VID_MenuInit(void)
s_brightness_slider.generic.name = "brightness";
s_brightness_slider.generic.x = 0;
s_brightness_slider.generic.y = (y += 20);
s_brightness_slider.generic.callback = BrightnessCallback;
s_brightness_slider.minvalue = 1;
s_brightness_slider.maxvalue = 20;
s_brightness_slider.curvalue = vid_gamma->value * 10;
s_brightness_slider.cvar = "vid_gamma";
s_brightness_slider.minvalue = 0.1f;
s_brightness_slider.maxvalue = 2.0f;
s_fov_slider.generic.type = MTYPE_SLIDER;
s_fov_slider.generic.name = "field of view";
s_fov_slider.generic.x = 0;
s_fov_slider.generic.y = (y += 10);
s_fov_slider.generic.name = "field of view";
s_fov_slider.generic.callback = FOVCallback;
s_fov_slider.cvar = "fov";
s_fov_slider.minvalue = 60;
s_fov_slider.maxvalue = 120;
s_fov_slider.curvalue = fov->value;
s_fov_slider.slidestep = 1;
s_fov_slider.printformat = "%.0f";
s_uiscale_list.generic.type = MTYPE_SPINCONTROL;
s_uiscale_list.generic.name = "ui scale";