Merge pull request #1170 from protocultor/wpn_preview

Sound backend selector + weapon preview for cycleweap
This commit is contained in:
Yamagi 2024-12-21 09:51:42 +01:00 committed by GitHub
commit 290c9ecabe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 176 additions and 114 deletions

View file

@ -286,6 +286,10 @@ else
SDLCFLAGS := $(shell sdl2-config --cflags)
endif
ifdef NO_SDL_GYRO
SDLCFLAGS += -DNO_SDL_GYRO
endif
# ----------
# Base include path.

View file

@ -39,18 +39,17 @@ Yamagi Quake II ships with 4 renderers:
## Choosing a Sound System
Yamagi Quake II ships with 2 sound system:
Yamagi Quake II ships with 2 sound systems:
* The **OpenAL** sound system: This is the default and highly
recommended. It provides full surround sound support and even HRTF for
recommended. It provides full surround sound support and HRTF for
headphones. But also the plain stereo playback is much better than in
the original sound system. The setup is done mostly through OpenAL,
have a look at the documentation of your OpenAL library.
* The **SDL** sound system: This is the classic sound system, providing
an experience like the original client. Set `s_openal` to `0` and
execute an `snd_restart` to activate it. The classic sound system may
be somewhat problematic on modern systems like Windows 10 or Linux
with Pulseaudio.
an experience like the original client. It's less CPU demanding than
OpenAL. Choose it in the options menu, or set `s_openal` to `0` and
execute an `snd_restart`, to activate it.
## Tuning for Precise Timings

View file

@ -511,6 +511,10 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
look a bit better (no flickering) by using the stencil buffer. Does
not work when `gl1_stereo` is `3`, `4` or `5`.
* **gl1_waterwarp**: Intensity of the "squeeze/stretch" effect on the
FOV when diving underwater. Can be any floating point number, `0`
disables it (Vanilla Quake II look). Default `1.0`.
* **gl1_lightmapcopies**: When enabled (`1`), keep 3 copies of the same
lightmap rotating, shifting to another one when drawing a new frame.
Meant for mobile/embedded devices, where changing textures just shown

View file

@ -173,19 +173,20 @@ 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)
// If the used SDL version doesn't support gamepad sensors...
#if !SDL_VERSION_ATLEAST(2, 0, 14)
// ...disable support for reading them.
#define NO_SDL_GYRO
#endif
#ifndef NO_SDL_GYRO // use SDL_CONTROLLERSENSORUPDATE to read gyro
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
#else // 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.
@ -789,7 +790,7 @@ IN_Update(void)
break;
}
#ifdef NATIVE_SDL_GYRO // controller sensors' reading supported (gyro, accelerometer)
#ifndef NO_SDL_GYRO // gamepad sensors' reading is supported (gyro, accelerometer)
case SDL_CONTROLLERSENSORUPDATE:
if (event.csensor.sensor != SDL_SENSOR_GYRO)
{
@ -804,7 +805,7 @@ IN_Update(void)
break;
}
#else // gyro read as "secondary joystick"
#else // gyro read from a "secondary joystick" (usually with name ending in "IMU")
case SDL_JOYAXISMOTION:
if ( !imu_joystick || event.cdevice.which != SDL_JoystickInstanceID(imu_joystick) )
{
@ -831,12 +832,12 @@ IN_Update(void)
break;
}
#endif // NATIVE_SDL_GYRO
#endif // !NO_SDL_GYRO
if (gyro_active && gyro_mode->value &&
!cl_paused->value && cls.key_dest == key_game)
{
#ifdef NATIVE_SDL_GYRO
#ifndef NO_SDL_GYRO
if (!gyro_turning_axis->value)
{
gyro_yaw = event.csensor.data[1] - gyro_calibration_y->value; // yaw
@ -864,7 +865,7 @@ IN_Update(void)
gyro_yaw = axis_value - gyro_calibration_z->value;
}
}
#endif // NATIVE_SDL_GYRO
#endif // !NO_SDL_GYRO
}
else
{
@ -956,7 +957,7 @@ IN_Update(void)
case REASON_GYROCALIBRATION: // finish and save calibration
{
#ifdef NATIVE_SDL_GYRO
#ifndef NO_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);
@ -1081,7 +1082,7 @@ IN_TightenInput(float yaw, float pitch)
{
thumbstick_t input = { yaw, pitch };
const float magnitude = IN_StickMagnitude(input);
#ifdef NATIVE_SDL_GYRO
#ifndef NO_SDL_GYRO
const float threshold = (M_PI / 180.0f) * gyro_tightening->value;
#else
const float threshold = (2560.0f / 180.0f) * gyro_tightening->value;
@ -1369,7 +1370,7 @@ 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
#ifndef NO_SDL_GYRO
float gyroViewFactor = (1.0f / M_PI) * joyViewFactor;
#else
float gyroViewFactor = (1.0f / 2560.0f) * joyViewFactor; // normalized for Switch gyro
@ -2039,7 +2040,7 @@ Controller_Rumble(const char *name, vec3_t source, qboolean from_player,
void
StartCalibration(void)
{
#ifdef NATIVE_SDL_GYRO
#ifndef NO_SDL_GYRO
num_samples = 0;
#else
num_samples[0] = num_samples[1] = num_samples[2] = 0;
@ -2159,27 +2160,36 @@ IN_Controller_Init(qboolean notify_user)
Com_Printf ("Trying joystick %d, '%s'\n", i+1, joystick_name);
// 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))
if ( name_len > 6 && strstr(joystick_name + name_len - 6, "IMU") )
{
#ifndef NO_SDL_GYRO
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 )
qboolean using_imu = !imu_joystick && !( strstr(joystick_name, "Joy-Con") && strstr(joystick_name, "L") );
Com_Printf ("IMU device found... ");
SDL_JoystickClose(joystick);
joystick = NULL;
if (using_imu)
{
imu_joystick = SDL_JoystickOpen(i);
if (imu_joystick)
{
show_gyro = true;
Com_Printf ("Using this device as Gyro sensor.\n");
Com_Printf ("using it as Gyro sensor.\n");
}
else
{
Com_Printf ("Couldn't open IMU: %s.\n", SDL_GetError());
Com_Printf ("\nCouldn't open IMU: %s.\n", SDL_GetError());
}
}
else
{
Com_Printf ("skipping.\n");
}
#endif
continue;
}
@ -2216,7 +2226,7 @@ IN_Controller_Init(qboolean notify_user)
show_gamepad = true;
Com_Printf("Enabled as Game Controller, settings:\n%s\n", SDL_GameControllerMapping(controller));
#ifdef NATIVE_SDL_GYRO
#ifndef NO_SDL_GYRO
if ( SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO)
&& !SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE) )
@ -2239,7 +2249,7 @@ IN_Controller_Init(qboolean notify_user)
SDL_GameControllerSetLED(controller, 0, 80, 0); // green light
}
#endif // NATIVE_SDL_GYRO
#endif // !NO_SDL_GYRO
joystick_haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(controller));
@ -2273,7 +2283,7 @@ 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
#ifndef NO_SDL_GYRO // "native SDL gyro" exits when finding a single working gamepad
break;
#endif
}
@ -2390,7 +2400,7 @@ IN_Controller_Shutdown(qboolean notify_user)
joystick_left_x = joystick_left_y = joystick_right_x = joystick_right_y = 0;
gyro_yaw = gyro_pitch = 0;
#ifndef NATIVE_SDL_GYRO
#ifdef NO_SDL_GYRO
if (imu_joystick)
{
SDL_JoystickClose(imu_joystick);

View file

@ -175,8 +175,17 @@ static float gyro_accum[3];
static cvar_t *gyro_calibration_x;
static cvar_t *gyro_calibration_y;
static cvar_t *gyro_calibration_z;
// If "SDL gyro" is not explicitly disabled, use SDL_EVENT_GAMEPAD_SENSOR_UPDATE to read gyro
#ifndef NO_SDL_GYRO
static unsigned int num_samples;
#define NATIVE_SDL_GYRO // uses SDL_EVENT_GAMEPAD_SENSOR_UPDATE to read gyro
#else // otherwise, 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_EVENT_JOYSTICK_ADDED at game init. Allows for hot plugging of gamepad afterwards.
static qboolean first_init = true;
@ -780,7 +789,7 @@ IN_Update(void)
break;
}
#ifdef NATIVE_SDL_GYRO // controller sensors' reading supported (gyro, accelerometer)
#ifndef NO_SDL_GYRO // gamepad sensors' reading is supported (gyro, accelerometer)
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE :
if (event.gsensor.sensor != SDL_SENSOR_GYRO)
{
@ -795,11 +804,11 @@ IN_Update(void)
break;
}
#else // gyro read as "secondary joystick"
#else // gyro read from a "secondary joystick" (usually with name ending in "IMU")
case SDL_EVENT_JOYSTICK_AXIS_MOTION :
if ( !imu_joystick || event.gdevice.which != SDL_GetJoystickID(imu_joystick) )
{
break; // controller axes handled by SDL_CONTROLLERAXISMOTION
break; // gamepad axes handled by SDL_EVENT_GAMEPAD_AXIS_MOTION
}
int axis_value = event.gaxis.value;
@ -822,12 +831,12 @@ IN_Update(void)
break;
}
#endif // NATIVE_SDL_GYRO
#endif // !NO_SDL_GYRO
if (gyro_active && gyro_mode->value &&
!cl_paused->value && cls.key_dest == key_game)
{
#ifdef NATIVE_SDL_GYRO
#ifndef NO_SDL_GYRO
if (!gyro_turning_axis->value)
{
gyro_yaw = event.gsensor.data[1] - gyro_calibration_y->value; // yaw
@ -838,7 +847,7 @@ IN_Update(void)
}
gyro_pitch = event.gsensor.data[0] - gyro_calibration_x->value;
#else // old "joystick" gyro
switch (event.gaxis.axis) // inside "case SDL_JOYAXISMOTION" here
switch (event.gaxis.axis) // inside "case SDL_EVENT_JOYSTICK_AXIS_MOTION" here
{
case IMU_JOY_AXIS_GYRO_PITCH:
gyro_pitch = -(axis_value - gyro_calibration_x->value);
@ -855,7 +864,7 @@ IN_Update(void)
gyro_yaw = axis_value - gyro_calibration_z->value;
}
}
#endif // NATIVE_SDL_GYRO
#endif // !NO_SDL_GYRO
}
else
{
@ -945,7 +954,7 @@ IN_Update(void)
case REASON_GYROCALIBRATION: // finish and save calibration
{
#ifdef NATIVE_SDL_GYRO
#ifndef NO_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);
@ -1070,7 +1079,11 @@ IN_TightenInput(float yaw, float pitch)
{
thumbstick_t input = { yaw, pitch };
const float magnitude = IN_StickMagnitude(input);
#ifndef NO_SDL_GYRO
const float threshold = (M_PI / 180.0f) * gyro_tightening->value;
#else
const float threshold = (2560.0f / 180.0f) * gyro_tightening->value;
#endif
if (magnitude < threshold)
{
@ -1354,7 +1367,7 @@ 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
#ifndef NO_SDL_GYRO
float gyroViewFactor = (1.0f / M_PI) * joyViewFactor;
#else
float gyroViewFactor = (1.0f / 2560.0f) * joyViewFactor; // normalized for Switch gyro
@ -2025,7 +2038,7 @@ Controller_Rumble(const char *name, vec3_t source, qboolean from_player,
void
StartCalibration(void)
{
#ifdef NATIVE_SDL_GYRO
#ifndef NO_SDL_GYRO
num_samples = 0;
#else
num_samples[0] = num_samples[1] = num_samples[2] = 0;
@ -2152,27 +2165,36 @@ IN_Controller_Init(qboolean notify_user)
Com_Printf ("Trying joystick %d, '%s'\n", i+1, joystick_name);
// 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))
if ( name_len > 6 && strstr(joystick_name + name_len - 6, "IMU") )
{
#ifndef NO_SDL_GYRO
SDL_CloseJoystick(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 )
qboolean using_imu = !imu_joystick && !( strstr(joystick_name, "Joy-Con") && strstr(joystick_name, "L") );
Com_Printf ("IMU device found... ");
SDL_CloseJoystick(joystick);
joystick = NULL;
if (using_imu)
{
imu_joystick = SDL_OpenJoystick(joysticks[i]);
if (imu_joystick)
{
show_gyro = true;
Com_Printf ("Using this device as Gyro sensor.\n");
Com_Printf ("using it as Gyro sensor.\n");
}
else
{
Com_Printf ("Couldn't open IMU: %s.\n", SDL_GetError());
Com_Printf ("\nCouldn't open IMU: %s.\n", SDL_GetError());
}
}
else
{
Com_Printf ("skipping.\n");
}
#endif
continue;
}
@ -2210,10 +2232,10 @@ IN_Controller_Init(qboolean notify_user)
Com_Printf("Enabled as Gamepad, settings:\n%s\n",
SDL_GetGamepadMapping(controller));
#ifdef NATIVE_SDL_GYRO
#ifndef NO_SDL_GYRO
if (SDL_GamepadHasSensor(controller, SDL_SENSOR_GYRO)
&& !SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, true) )
&& SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, true) )
{
show_gyro = true;
Com_Printf( "Gyro sensor enabled at %.2f Hz\n",
@ -2230,7 +2252,7 @@ IN_Controller_Init(qboolean notify_user)
SDL_SetGamepadLED(controller, 0, 80, 0); // green light
}
#endif // NATIVE_SDL_GYRO
#endif // !NO_SDL_GYRO
joystick_haptic = SDL_OpenHapticFromJoystick(SDL_GetGamepadJoystick(controller));
@ -2259,7 +2281,7 @@ IN_Controller_Init(qboolean notify_user)
Com_Printf("Gamepad doesn't support rumble.\n");
}
#ifdef NATIVE_SDL_GYRO // "native" exits when finding a single working controller
#ifndef NO_SDL_GYRO // "native SDL gyro" exits when finding a single working gamepad
break;
#endif
}
@ -2384,7 +2406,7 @@ IN_Controller_Shutdown(qboolean notify_user)
joystick_left_x = joystick_left_y = joystick_right_x = joystick_right_y = 0;
gyro_yaw = gyro_pitch = 0;
#ifndef NATIVE_SDL_GYRO
#ifdef NO_SDL_GYRO
if (imu_joystick)
{
SDL_CloseJoystick(imu_joystick);

View file

@ -1326,12 +1326,20 @@ char *controller_bindnames[][2] =
{"+movedown", "down / crouch"},
{"weapnext", "next weapon"},
{"weapprev", "previous weapon"},
{"cycleweap weapon_chaingun weapon_machinegun weapon_blaster", "long range: quickswitch 1"},
{"cycleweap weapon_supershotgun weapon_shotgun", "close range: quickswitch 2"},
{"cycleweap weapon_rocketlauncher weapon_grenadelauncher ammo_grenades", "explosives: quickswitch 3"},
{"cycleweap weapon_bfg weapon_railgun weapon_hyperblaster", "special: quickswitch 4"},
{"prefweap weapon_railgun weapon_hyperblaster weapon_chaingun weapon_supershotgun weapon_machinegun weapon_shotgun weapon_blaster", "best safe weapon"},
{"prefweap weapon_bfg weapon_railgun weapon_rocketlauncher weapon_hyperblaster weapon_grenadelauncher weapon_chaingun ammo_grenades weapon_supershotgun", "best unsafe weapon"},
{"cycleweap weapon_plasmabeam weapon_boomer weapon_chaingun weapon_etf_rifle"
" weapon_machinegun weapon_blaster", "long range: quickswitch 1"},
{"cycleweap weapon_supershotgun weapon_shotgun weapon_chainfist",
"close range: quickswitch 2"},
{"cycleweap weapon_phalanx weapon_rocketlauncher weapon_proxlauncher"
" weapon_grenadelauncher ammo_grenades", "explosives: quickswitch 3"},
{"cycleweap weapon_bfg weapon_disintegrator weapon_railgun weapon_hyperblaster"
" ammo_tesla ammo_trap", "special: quickswitch 4"},
{"prefweap weapon_railgun weapon_plasmabeam weapon_boomer weapon_hyperblaster weapon_chaingun"
" weapon_supershotgun weapon_etf_rifle weapon_machinegun weapon_shotgun weapon_blaster",
"best safe weapon"},
{"prefweap weapon_bfg weapon_disintegrator weapon_phalanx weapon_railgun weapon_rocketlauncher"
" weapon_plasmabeam weapon_boomer weapon_hyperblaster weapon_grenadelauncher weapon_chaingun"
" weapon_proxlauncher ammo_grenades weapon_supershotgun", "best unsafe weapon"},
{"centerview", "center view"},
{"inven", "inventory"},
{"invuse", "use item"},
@ -1489,12 +1497,20 @@ char *controller_alt_bindnames[][2] =
{
{"weapnext", "next weapon"},
{"weapprev", "previous weapon"},
{"cycleweap weapon_chaingun weapon_machinegun weapon_blaster", "long range: quickswitch 1"},
{"cycleweap weapon_supershotgun weapon_shotgun", "close range: quickswitch 2"},
{"cycleweap weapon_rocketlauncher weapon_grenadelauncher ammo_grenades", "explosives: quickswitch 3"},
{"cycleweap weapon_bfg weapon_railgun weapon_hyperblaster", "special: quickswitch 4"},
{"prefweap weapon_railgun weapon_hyperblaster weapon_chaingun weapon_supershotgun weapon_machinegun weapon_shotgun weapon_blaster", "best safe weapon"},
{"prefweap weapon_bfg weapon_railgun weapon_rocketlauncher weapon_hyperblaster weapon_grenadelauncher weapon_chaingun ammo_grenades weapon_supershotgun", "best unsafe weapon"},
{"cycleweap weapon_plasmabeam weapon_boomer weapon_chaingun weapon_etf_rifle"
" weapon_machinegun weapon_blaster", "long range: quickswitch 1"},
{"cycleweap weapon_supershotgun weapon_shotgun weapon_chainfist",
"close range: quickswitch 2"},
{"cycleweap weapon_phalanx weapon_rocketlauncher weapon_proxlauncher"
" weapon_grenadelauncher ammo_grenades", "explosives: quickswitch 3"},
{"cycleweap weapon_bfg weapon_disintegrator weapon_railgun weapon_hyperblaster"
" ammo_tesla ammo_trap", "special: quickswitch 4"},
{"prefweap weapon_railgun weapon_plasmabeam weapon_boomer weapon_hyperblaster weapon_chaingun"
" weapon_supershotgun weapon_etf_rifle weapon_machinegun weapon_shotgun weapon_blaster",
"best safe weapon"},
{"prefweap weapon_bfg weapon_disintegrator weapon_phalanx weapon_railgun weapon_rocketlauncher"
" weapon_plasmabeam weapon_boomer weapon_hyperblaster weapon_grenadelauncher weapon_chaingun"
" weapon_proxlauncher ammo_grenades weapon_supershotgun", "best unsafe weapon"},
{"centerview", "center view"},
{"inven", "inventory"},
{"invuse", "use item"},
@ -2254,7 +2270,7 @@ ControlsSetMenuItemValues(void)
{
s_options_oggshuffle_box.curvalue = Cvar_VariableValue("ogg_shuffle");
s_options_oggenable_box.curvalue = (Cvar_VariableValue("ogg_enable") != 0);
s_options_quality_list.curvalue = (Cvar_VariableValue("s_loadas8bit") == 0);
s_options_quality_list.curvalue = (Cvar_VariableValue("s_openal") == 0);
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);
@ -2341,18 +2357,9 @@ ConsoleFunc(void *unused)
}
static void
UpdateSoundQualityFunc(void *unused)
UpdateSoundBackendFunc(void *unused)
{
if (s_options_quality_list.curvalue == 0)
{
Cvar_SetValue("s_khz", 22);
Cvar_SetValue("s_loadas8bit", false);
}
else
{
Cvar_SetValue("s_khz", 44);
Cvar_SetValue("s_loadas8bit", false);
}
Cvar_Set("s_openal", (s_options_quality_list.curvalue == 0)? "1":"0" );
m_popup_string = "Restarting the sound system. This\n"
"could take up to a minute, so\n"
@ -2388,9 +2395,9 @@ Options_MenuInit(void)
0
};
static const char *quality_items[] =
static const char *sound_items[] =
{
"normal", "high", 0
"openal", "sdl", 0
};
static const char *yesno_names[] =
@ -2458,9 +2465,9 @@ Options_MenuInit(void)
s_options_quality_list.generic.type = MTYPE_SPINCONTROL;
s_options_quality_list.generic.x = 0;
s_options_quality_list.generic.y = (y += 10);
s_options_quality_list.generic.name = "sound quality";
s_options_quality_list.generic.callback = UpdateSoundQualityFunc;
s_options_quality_list.itemnames = quality_items;
s_options_quality_list.generic.name = "sound backend";
s_options_quality_list.generic.callback = UpdateSoundBackendFunc;
s_options_quality_list.itemnames = sound_items;
s_options_sensitivity_slider.generic.type = MTYPE_SLIDER;
s_options_sensitivity_slider.generic.x = 0;
@ -6366,6 +6373,7 @@ M_Init(void)
Cmd_AddCommand("menu_gyro", M_Menu_Gyro_f);
Cmd_AddCommand("menu_buttons", M_Menu_ControllerButtons_f);
Cmd_AddCommand("menu_altbuttons", M_Menu_ControllerAltButtons_f);
Cmd_AddCommand("menu_sticks", M_Menu_Stick_f);
Cmd_AddCommand("menu_quit", M_Menu_Quit_f);
/* initialize the server address book cvars (adr0, adr1, ...)

View file

@ -36,7 +36,7 @@ int cur_lm_copy; // which lightmap copy to use (when lightmapcopies=on)
static GLushort vtx_ptr, idx_ptr; // pointers for array positions in gl_buf
extern void R_MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
extern void R_SetPerspective(GLdouble fovy);
void
R_ResetGLBuffer(void)
@ -50,7 +50,6 @@ R_ApplyGLBuffer(void)
// Properties of batched draws here
GLint vtx_size;
qboolean texture, mtex, alpha, color, alias, texenv_set;
float fovy, dist;
if (vtx_ptr == 0 || idx_ptr == 0)
{
@ -107,9 +106,7 @@ R_ApplyGLBuffer(void)
glScalef(-1, 1, 1);
}
fovy = (r_gunfov->value < 0) ? r_newrefdef.fov_y : r_gunfov->value;
dist = (r_farsee->value == 0) ? 4096.0f : 8192.0f;
R_MYgluPerspective(fovy, (float)r_newrefdef.width / r_newrefdef.height, 4, dist);
R_SetPerspective( (r_gunfov->value < 0) ? r_newrefdef.fov_y : r_gunfov->value );
glMatrixMode(GL_MODELVIEW);

View file

@ -143,6 +143,7 @@ cvar_t *gl1_stereo_separation;
cvar_t *gl1_stereo_anaglyph_colors;
cvar_t *gl1_stereo_convergence;
static cvar_t *gl1_waterwarp;
refimport_t ri;
@ -727,19 +728,35 @@ R_SetupFrame(void)
}
void
R_MYgluPerspective(GLdouble fovy, GLdouble aspect,
GLdouble zNear, GLdouble zFar)
R_SetPerspective(GLdouble fovy)
{
// gluPerspective style parameters
static const GLdouble zNear = 4;
const GLdouble zFar = (r_farsee->value) ? 8192.0f : 4096.0f;
const GLdouble aspectratio = (GLdouble)r_newrefdef.width / r_newrefdef.height;
GLdouble xmin, xmax, ymin, ymax;
// traditional gluPerspective calculations - https://youtu.be/YqSNGcF5nvM?t=644
ymax = zNear * tan(fovy * M_PI / 360.0);
xmax = ymax * aspectratio;
if ((r_newrefdef.rdflags & RDF_UNDERWATER) && gl1_waterwarp->value)
{
const GLdouble warp = sin(r_newrefdef.time * 1.5) * 0.03 * gl1_waterwarp->value;
ymax *= 1.0 - warp;
xmax *= 1.0 + warp;
}
ymin = -ymax;
xmin = -xmax;
xmin = ymin * aspect;
xmax = ymax * aspect;
xmin += - gl1_stereo_convergence->value * (2 * gl_state.camera_separation) / zNear;
xmax += - gl1_stereo_convergence->value * (2 * gl_state.camera_separation) / zNear;
if (gl_state.camera_separation)
{
const GLdouble separation = - gl1_stereo_convergence->value * (2 * gl_state.camera_separation) / zNear;
xmin += separation;
xmax += separation;
}
glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
}
@ -747,7 +764,6 @@ R_MYgluPerspective(GLdouble fovy, GLdouble aspect,
void
R_SetupGL(void)
{
float screenaspect;
int x, x2, y2, y, w, h;
/* set up viewport */
@ -777,18 +793,10 @@ R_SetupGL(void)
glViewport(x, y2, w, h);
/* set up projection matrix */
screenaspect = (float)r_newrefdef.width / r_newrefdef.height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (r_farsee->value == 0)
{
R_MYgluPerspective(r_newrefdef.fov_y, screenaspect, 4, 4096);
}
else
{
R_MYgluPerspective(r_newrefdef.fov_y, screenaspect, 4, 8192);
}
R_SetPerspective(r_newrefdef.fov_y);
glCullFace(GL_FRONT);
@ -1302,6 +1310,8 @@ R_Register(void)
gl1_stereo_anaglyph_colors = ri.Cvar_Get( "gl1_stereo_anaglyph_colors", "rc", CVAR_ARCHIVE );
gl1_stereo_convergence = ri.Cvar_Get( "gl1_stereo_convergence", "1", CVAR_ARCHIVE );
gl1_waterwarp = ri.Cvar_Get( "gl1_waterwarp", "1.0", CVAR_ARCHIVE );
ri.Cmd_AddCommand("imagelist", R_ImageList_f);
ri.Cmd_AddCommand("screenshot", R_ScreenShot);
ri.Cmd_AddCommand("modellist", Mod_Modellist_f);

View file

@ -1708,29 +1708,37 @@ static void
Cmd_CycleWeap_f(edict_t *ent)
{
gitem_t *weap;
gclient_t *cl;
int num_weaps;
if (!ent)
{
return;
}
if (gi.argc() <= 1)
num_weaps = gi.argc();
if (num_weaps <= 1)
{
gi.cprintf(ent, PRINT_HIGH, "Usage: cycleweap classname1 classname2 .. classnameN\n");
return;
}
weap = cycle_weapon(ent);
if (weap)
if (!weap) return;
cl = ent->client;
if (cl->pers.inventory[ITEM_INDEX(weap)] <= 0)
{
if (ent->client->pers.inventory[ITEM_INDEX(weap)] <= 0)
{
gi.cprintf(ent, PRINT_HIGH, "Out of item: %s\n", weap->pickup_name);
}
else
{
weap->use(ent, weap);
}
gi.cprintf(ent, PRINT_HIGH, "Out of item: %s\n", weap->pickup_name);
return;
}
weap->use(ent, weap);
if (num_weaps > 3 && cl->newweapon == weap)
{
cl->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(weap->icon);
cl->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS + ITEM_INDEX(weap);
cl->pickup_msg_time = level.time + 0.7f;
}
}