Multiple fixes to improve QoL

- Prevent the highest IPD setting on Quest 2 and Quest 3s from making the view move with the controller
- Smooth Turn menu option (so user doesn't have to faff with setting a low value)
- Gesture Trigger Use is now enabled by default
- Fixed positional not working at higher refresh rates
- Improvements to the use of the pointer in the menu screen (also seems to fix scroll bars)
- Improved menu item layout
- change to sv_game.c which seems to stop the menu hanging on Start New Game sometimes
- Adjusted draw location of hands
- Don't draw offhand backwards if "Reverse Torch Direction" is enabled
This commit is contained in:
DrBeef committed 2026-01-05 11:42:10 +00:00
1 parent d6d9ee4d08
commit 3e3572d89e
13 files changed
+94 -72

No files matched your search

+2 -2
View File
@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.drbeef.lambda1vr"
android:versionCode="35"
android:versionName="1.7.0"
android:versionCode="37"
android:versionName="1.7.2"
android:installLocation="auto" >
<!-- Tell the system this app requires OpenGL ES 3.1. -->
@@ -316,7 +316,8 @@ void Android_MessageBox(const char *title, const char *text)
convar_t *vibration_enable;
convar_t *vr_snapturn_angle;
convar_t *vr_smoothturn;
convar_t *vr_turn_angle;
convar_t *vr_reloadtimeoutms;
convar_t *vr_positional_factor;
convar_t *vr_walkdirection;
@@ -366,7 +367,8 @@ void VR_Init()
srand(time(NULL));
//Create Cvars
vr_snapturn_angle = Cvar_Get( "vr_snapturn_angle", "45", CVAR_ARCHIVE, "Sets the angle for snap-turn, set to < 10.0 to enable smooth turning" );
vr_smoothturn = Cvar_Get( "vr_smoothturn", "0", CVAR_ARCHIVE, "Enables smooth turning" );
vr_turn_angle = Cvar_Get( "vr_turn_angle", "45", CVAR_ARCHIVE, "Sets the angle for snap-turn, set to < 10.0 to enable smooth turning" );
vr_reloadtimeoutms = Cvar_Get( "vr_reloadtimeoutms", "200", CVAR_ARCHIVE, "How quickly the grip trigger needs to be release to initiate a reload" );
vr_positional_factor = Cvar_Get( "vr_positional_factor", "3000", CVAR_ARCHIVE, "Number that makes positional tracking work" );
vr_walkdirection = Cvar_Get( "vr_walkdirection", "1", CVAR_ARCHIVE, "1 - Use HMD for direction, 0 - Use off-hand controller for direction" );
@@ -401,7 +403,7 @@ void VR_Init()
vr_headtorch = Cvar_Get( "vr_headtorch", "0", CVAR_ARCHIVE, "Set to 1 to enable head-torch flashlight mode" );
vr_reversetorch = Cvar_Get( "vr_reversetorch", "0", CVAR_ARCHIVE, "Set to 1 to enable reverse-direction flashlight mode" );
vr_quick_crouchjump = Cvar_Get( "vr_quick_crouchjump", "1", CVAR_ARCHIVE, "Set to 0 to disable quick crouch-jump mode (double clicking jump button triggers duck)" );
vr_gesture_triggered_use = Cvar_Get( "vr_gesture_triggered_use", "0", CVAR_ARCHIVE, "Set to 0 to disable use gesture, 1 to enable" );
vr_gesture_triggered_use = Cvar_Get( "vr_gesture_triggered_use", "1", CVAR_ARCHIVE, "Set to 0 to disable use gesture, 1 to enable" );
vr_use_gesture_boundary = Cvar_Get( "vr_use_gesture_boundary", "0.35", CVAR_ARCHIVE, "Use gesture boundary" );
//Not to be changed by users, as it will be overwritten anyway
+2 -1
View File
@@ -2,7 +2,8 @@
#include <common/cvardef.h>
#include <common/xash3d_types.h>
extern convar_t *vr_snapturn_angle;
extern convar_t *vr_smoothturn;
extern convar_t *vr_turn_angle;
extern convar_t *vr_reloadtimeoutms;
extern convar_t *vr_positional_factor;
extern convar_t *vr_walkdirection;
@@ -326,7 +326,7 @@ void HandleInput_Alt( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovr
rotation[PITCH] = 25.0f;
vec3_t inverseflashlightangles;
QuatToYawPitchRoll(pOffTracking->Pose.orientation, rotation, inverseflashlightangles);
if (vr_reversetorch->integer)
if (vr_reversetorch->integer && cl.frame.client.flags & FL_HAS_FLASHLIGHT)
{
VectorNegate(inverseflashlightangles, flashlightangles);
flashlightangles[YAW] *= -1.0f;
@@ -349,7 +349,7 @@ void HandleInput_Alt( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovr
{
//This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the
//player is facing for positional tracking
float multiplier = vr_positional_factor->value / (cl_forwardspeed->value *
float multiplier = (vr_positional_factor->value * (vr_refresh->value / 72.f)) / (cl_forwardspeed->value *
((pOffTrackedRemoteNew->Buttons & xrButton_Trigger) ? cl_movespeedkey->value : 1.0f));
//If player is ducked then multiply by 3 otherwise positional tracking feels very wrong
@@ -601,15 +601,15 @@ void HandleInput_Alt( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovr
if (!selectingWeapon) {
//engage comfort mask if using smooth rotation
player_moving |= (vr_snapturn_angle->value <= 10.0f &&
player_moving |= (vr_smoothturn->value &&
fabs(joystickX) > 0.7f);
if (joystickX > 0.7f)
{
if (increaseSnap)
{
snapTurn -= vr_snapturn_angle->value;
if (vr_snapturn_angle->value > 10.0f) {
snapTurn -= vr_turn_angle->value / (vr_smoothturn->value ? 10.f : 1.f);
if (!vr_smoothturn->value) {
increaseSnap = false;
}
@@ -629,10 +629,10 @@ void HandleInput_Alt( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovr
{
if (decreaseSnap)
{
snapTurn += vr_snapturn_angle->value;
snapTurn += vr_turn_angle->value / (vr_smoothturn->value ? 10.f : 1.f);
//If snap turn configured for less than 10 degrees
if (vr_snapturn_angle->value > 10.0f) {
if (!vr_smoothturn->value) {
decreaseSnap = false;
}
@@ -338,7 +338,7 @@ void HandleInput_Alt2( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ov
rotation[PITCH] = 25.0f;
vec3_t inverseflashlightangles;
QuatToYawPitchRoll(pOffTracking->Pose.orientation, rotation, inverseflashlightangles);
if (vr_reversetorch->integer)
if (vr_reversetorch->integer && cl.frame.client.flags & FL_HAS_FLASHLIGHT)
{
VectorNegate(inverseflashlightangles, flashlightangles);
flashlightangles[YAW] *= -1.0f;
@@ -361,7 +361,7 @@ void HandleInput_Alt2( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ov
{
//This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the
//player is facing for positional tracking
float multiplier = vr_positional_factor->value / (cl_forwardspeed->value *
float multiplier = (vr_positional_factor->value * (vr_refresh->value / 72.f)) / (cl_forwardspeed->value *
((pOffTrackedRemoteNew->Buttons & xrButton_Trigger) ? cl_movespeedkey->value : 1.0f));
//If player is ducked then multiply by 3 otherwise positional tracking feels very wrong
@@ -463,7 +463,7 @@ void HandleInput_Alt2( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ov
//Weapon Chooser
static bool weaponSwitched = false;
if (vr_snapturn_angle->value != 0) // if snap angle feature is enabled
if (vr_turn_angle->value != 0) // if snap angle feature is enabled
{
if (between(-0.25f, pOffTrackedRemoteNew->Joystick.x, 0.25f) &&
(between(0.75f, pOffTrackedRemoteNew->Joystick.y, 1.0f) ||
@@ -616,7 +616,7 @@ void HandleInput_Alt2( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ov
float joystickX = (joyx[0] + joyx[1] + joyx[2] + joyx[3]) / 4.0f;
//engage comfort mask if using smooth rotation
player_moving |= (vr_snapturn_angle->value <= 10.0f &&
player_moving |= (vr_smoothturn->value &&
fabs(joystickX) > 0.6f);
static bool increaseSnap = true;
@@ -624,8 +624,8 @@ void HandleInput_Alt2( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ov
{
if (increaseSnap)
{
snapTurn -= vr_snapturn_angle->value;
if (vr_snapturn_angle->value > 10.0f) {
snapTurn -= vr_turn_angle->value / (vr_smoothturn->value ? 10.f : 1.f);
if (!vr_smoothturn->value) {
increaseSnap = false;
}
@@ -643,10 +643,10 @@ void HandleInput_Alt2( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ov
{
if (decreaseSnap)
{
snapTurn += vr_snapturn_angle->value;
snapTurn += vr_turn_angle->value / (vr_smoothturn->value ? 10.f : 1.f);
//If snap turn configured for less than 10 degrees
if (vr_snapturn_angle->value > 10.0f) {
if (!vr_smoothturn->value) {
decreaseSnap = false;
}
@@ -138,34 +138,23 @@ void interactWithTouchScreen(ovrTrackedController *tracking, ovrInputStateTracke
float remoteAngles[3];
vec3_t rotation = {0, 0, 0};
QuatToYawPitchRoll(tracking->Pose.orientation, rotation, remoteAngles);
float yaw = remoteAngles[YAW] - playerYaw;
//Adjust for maximum yaw values
if (yaw >= 180.0f) yaw -= 180.0f;
if (yaw <= -180.0f) yaw += 180.0f;
int newRemoteTrigState = (newState->Buttons & xrButton_Trigger) != 0;
int prevRemoteTrigState = (oldState->Buttons & xrButton_Trigger) != 0;
if (yaw > -40.0f && yaw < 40.0f &&
remoteAngles[PITCH] > -22.5f && remoteAngles[PITCH] < 22.5f) {
int newRemoteTrigState = (newState->Buttons & xrButton_Trigger) != 0;
int prevRemoteTrigState = (oldState->Buttons & xrButton_Trigger) != 0;
touchEventType t = event_motion;
float touchX = (-yaw + 40.0f) / 80.0f;
float touchY = (remoteAngles[PITCH] + 22.5f) / 45.0f;
if (newRemoteTrigState != prevRemoteTrigState)
float cursorX = -sinf(DEG2RAD(remoteAngles[YAW] - playerYaw)) + 0.5f;
float cursorY = (float)(remoteAngles[PITCH] / 90.0) + 0.5f;
touchEventType t = event_motion;
if (newRemoteTrigState != prevRemoteTrigState)
{
t = newRemoteTrigState ? event_down : event_up;
if (newRemoteTrigState)
{
t = newRemoteTrigState ? event_down : event_up;
if (newRemoteTrigState)
{
initialTouchX = touchX;
initialTouchY = touchY;
}
initialTouchX = cursorX;
initialTouchY = cursorY;
}
IN_TouchEvent(t, 0, touchX, touchY, initialTouchX - touchX, initialTouchY - touchY);
}
IN_TouchEvent(t, 0, cursorX, cursorY, initialTouchX - cursorX, initialTouchY - cursorY);
}
@@ -339,7 +339,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
rotation[PITCH] = 25.0f;
vec3_t inverseflashlightangles;
QuatToYawPitchRoll(pOffTracking->Pose.orientation, rotation, inverseflashlightangles);
if (vr_reversetorch->integer)
if (vr_reversetorch->integer && cl.frame.client.flags & FL_HAS_FLASHLIGHT)
{
VectorNegate(inverseflashlightangles, flashlightangles);
flashlightangles[YAW] *= -1.0f;
@@ -361,7 +361,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
{
//This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the
//player is facing for positional tracking
float multiplier = vr_positional_factor->value / (cl_forwardspeed->value *
float multiplier = (vr_positional_factor->value * (vr_refresh->value / 72.f)) / (cl_forwardspeed->value *
((pOffTrackedRemoteNew->Buttons & xrButton_Trigger) ? cl_movespeedkey->value : 1.0f));
//If player is ducked then multiply by 3 otherwise positional tracking feels very wrong
@@ -463,7 +463,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
//Weapon Chooser
static bool weaponSwitched = false;
if (vr_snapturn_angle->value != 0) // if snap angle feature is enabled
if (vr_turn_angle->value != 0) // if snap angle feature is enabled
{
if (between(0.6f, pDominantTrackedRemoteNew->Joystick.y, 1.0f) ||
between(-1.0f, pDominantTrackedRemoteNew->Joystick.y, -0.6f))
@@ -617,7 +617,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
float joystickX = (joyx[0] + joyx[1] + joyx[2] + joyx[3]) / 4.0f;
//engage comfort mask if using smooth rotation
player_moving |= (vr_snapturn_angle->value <= 10.0f &&
player_moving |= (vr_smoothturn->value &&
fabs(joystickX) > 0.6f);
static bool increaseSnap = true;
@@ -625,8 +625,8 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
{
if (increaseSnap)
{
snapTurn -= vr_snapturn_angle->value;
if (vr_snapturn_angle->value > 10.0f) {
snapTurn -= vr_turn_angle->value / (vr_smoothturn->value ? 10.f : 1.f);
if (!vr_smoothturn->value) {
increaseSnap = false;
}
@@ -644,10 +644,10 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
{
if (decreaseSnap)
{
snapTurn += vr_snapturn_angle->value;
snapTurn += vr_turn_angle->value / (vr_smoothturn->value ? 10.f : 1.f);
//If snap turn configured for less than 10 degrees
if (vr_snapturn_angle->value > 10.0f) {
if (!vr_smoothturn->value) {
decreaseSnap = false;
}
@@ -176,7 +176,7 @@ void HandleInput_OneController( ovrInputStateTrackedRemote *pDominantTrackedRemo
rotation[PITCH] = 25.0f;
vec3_t inverseflashlightangles;
QuatToYawPitchRoll(pOffTracking->Pose.orientation, rotation, inverseflashlightangles);
if (vr_reversetorch->integer)
if (vr_reversetorch->integer && cl.frame.client.flags & FL_HAS_FLASHLIGHT)
{
VectorNegate(inverseflashlightangles, flashlightangles);
flashlightangles[YAW] *= -1.0f;
@@ -193,7 +193,7 @@ void HandleInput_OneController( ovrInputStateTrackedRemote *pDominantTrackedRemo
{
//This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the
//player is facing for positional tracking
float multiplier = vr_positional_factor->value / (cl_forwardspeed->value *
float multiplier = (vr_positional_factor->value * (vr_refresh->value / 72.f)) / (cl_forwardspeed->value *
((pOffTrackedRemoteNew->Buttons & xrButton_Trigger) ? cl_movespeedkey->value : 1.0f));
//If player is ducked then multiply by 3 otherwise positional tracking feels very wrong
@@ -155,7 +155,10 @@ void V_SetupRefDef( void )
VectorCopy(weaponangles[2], cl.refdef.weapon.angles.melee);
//Scope
if (cl.scr_fov < 90) {
// Reducing this to 85 (from 90) fixes the issue where on the highest IPD setting on Quest 2 or Quest 3s
// the player's view is moved around by the right controller, it's because that was changing the FOV to 88!
if (cl.scr_fov < 85)
{
VectorAdd(cl.refdef.simorg, cl.refdef.weapon.org, cl.refdef.simorg);
VectorSet(cl.refdef.weapon.org, 0, 0, 0);
}
@@ -3726,7 +3726,10 @@ extern convar_t *vr_mirror_weapons;
extern convar_t *vr_weapon_backface_culling;
int bScopeEngaged()
{
return (cl.scr_fov != 0 && cl.scr_fov < 90.0f);
return (cl.scr_fov != 0 &&
// Reducing this to 85 (from 90) fixes the issue where on the highest IPD setting on Quest 2 or Quest 3s
// the player's view is moved around by the right controller, it's because that was changing the FOV to 88!
cl.scr_fov < 85.0f);
}
void R_DrawViewModel( void )
@@ -3794,8 +3797,15 @@ void R_DrawViewModel( void )
extern convar_t *vr_hand_model;
extern convar_t *vr_control_scheme;
extern convar_t *vr_reversetorch;
void R_DrawHandModel( int hand )
void getHandAdjustVector(vec3_t angles, vec3_t forward) {
AngleVectors(angles, forward, NULL, NULL);
VectorNegate(forward, forward);
VectorM(5, forward, forward);
}
void R_DrawHandModel(int hand )
{
if( RI.refdef.onlyClientDraw || r_drawviewmodel->integer == 0 || vr_hand_model->integer == 0 || bScopeEngaged())
return;
@@ -3841,15 +3851,23 @@ void R_DrawHandModel( int hand )
int off_hand = (vr_control_scheme->integer >= 10) ? 1 : 0;
if (hand == off_hand)
{
//Off hand
vec3_t forward;
getHandAdjustVector(cl.refdef.flashlight.angles.adjusted, forward);
//Off hand
VectorAdd(cl.refdef.vieworg, cl.refdef.flashlight.org, clgame.handent.origin);
VectorAdd(clgame.handent.origin, forward, clgame.handent.origin);
VectorCopy(cl.refdef.flashlight.angles.adjusted, clgame.handent.curstate.angles);
clgame.handent.curstate.angles[0] *= -1.0f;
} else
{
VectorCopy(cl.refdef.weapon.angles.unadjusted, clgame.handent.curstate.angles);
clgame.handent.curstate.angles[0] *= -1.0f;
vec3_t forward;
getHandAdjustVector(clgame.handent.curstate.angles, forward);
//Dominant hand
VectorAdd(cl.refdef.vieworg, cl.refdef.weapon.org, clgame.handent.origin);
VectorCopy(cl.refdef.weapon.angles.adjusted, clgame.handent.curstate.angles);
VectorAdd(clgame.handent.origin, forward, clgame.handent.origin);
clgame.handent.curstate.angles[0] *= -1.0f;
}
//Optional culling for the viewmodel
@@ -139,7 +139,7 @@ Q_buildcommit will identify this build as release or "notset"
*/
const char *Q_buildcommit( void )
{
return "Lambda1VR-v1.7.0";
return "Lambda1VR-v1.7.2";
}
/*
@@ -3059,7 +3059,9 @@ void SV_SetStringArrayMode( qboolean dynamic )
#ifdef XASH_64BIT
#ifndef _WIN32
#define USE_MMAP
//We don't want to use this as sometimes if causes a hang on the start of the game..
//seems to work fine without it! (hopefully!!)
//#define USE_MMAP
#include <sys/mman.h>
#endif
#endif
@@ -70,6 +70,7 @@ private:
CMenuCheckBox handModels;
CMenuCheckBox quickCrouchJump;
CMenuCheckBox useGesture;
CMenuCheckBox smoothTurn;
CMenuSlider snapTurnAngle;
CMenuSlider useGestureBoundary;
@@ -109,37 +110,41 @@ void CMenuControls::_Init( void )
quickCrouchJump.LinkCvar( "vr_quick_crouchjump" );
mirrorWeapons.SetNameAndStatus( "Mirror Weapon Models", "Check to mirror weapon models (for left-handed play to avoid seeing missing sides)" );
mirrorWeapons.SetCoord( 320, 510 );
mirrorWeapons.SetCoord( 320, 500 );
mirrorWeapons.LinkCvar( "vr_mirror_weapons" );
handModels.SetNameAndStatus( "Draw Hand Models", "Check to enable controllers rendered as hand models" );
handModels.SetCoord( 720, 510 );
handModels.SetCoord( 720, 500 );
handModels.LinkCvar( "vr_hand_model" );
headTorch.SetNameAndStatus( "Head-based Torch", "Check to enable head-torch (Half-life & Blueshift only)" );
headTorch.SetCoord( 320, 570 );
headTorch.SetCoord( 320, 550 );
headTorch.LinkCvar( "vr_headtorch" );
reverseTorch.SetNameAndStatus( "Reverse Torch Direction", "Check to reverse torch direction" );
reverseTorch.SetCoord( 320, 640 );
reverseTorch.LinkCvar( "vr_reversetorch" );
useGesture.SetNameAndStatus( "Gesture Triggered Use", "Toggles triggering of use action by gesture" );
useGesture.SetCoord( 720, 570 );
useGesture.SetCoord( 720, 550 );
useGesture.LinkCvar( "vr_gesture_triggered_use" );
snapTurnAngle.SetNameAndStatus( "Snap/Smooth Turn: %.1f degrees", "Controller turn angle, < 10 is smooth turning per frame" );
reverseTorch.SetNameAndStatus( "Reverse Torch Direction", "Check to reverse torch direction" );
reverseTorch.SetCoord( 320, 600 );
reverseTorch.LinkCvar( "vr_reversetorch" );
smoothTurn.SetNameAndStatus( "Smooth Turn", "Toggles smooth turning" );
smoothTurn.SetCoord( 720, 600 );
smoothTurn.LinkCvar( "vr_smoothturn" );
snapTurnAngle.SetNameAndStatus( "Snap/Smooth Turn:", "Controller turn angle per frame" );
snapTurnAngle.Setup( 0.0, 90.0, 1.0f );
snapTurnAngle.onChanged = CMenuEditable::WriteCvarCb;
snapTurnAngle.SetCoord( 320, 750 );
snapTurnAngle.SetSize( 520, 40 );
snapTurnAngle.SetDrawValue(true);
snapTurnAngle.LinkCvar("vr_snapturn_angle");
snapTurnAngle.LinkCvar("vr_turn_angle");
useGestureBoundary.SetNameAndStatus( "Use Gesture Boundary", "Configures how far you need to reach to activate use gesture" );
useGestureBoundary.Setup( 0.2, 0.5, 0.01f );
useGestureBoundary.onChanged = CMenuEditable::WriteCvarCb;
useGestureBoundary.SetCoord( 320, 840 );
useGestureBoundary.SetCoord( 320, 850 );
useGestureBoundary.SetSize( 520, 40 );
useGestureBoundary.SetDrawValue(true);
useGestureBoundary.LinkCvar("vr_use_gesture_boundary");
@@ -152,6 +157,7 @@ void CMenuControls::_Init( void )
AddItem( reverseTorch );
AddItem( handModels );
AddItem( snapTurnAngle );
AddItem( smoothTurn );
AddItem( useGesture );
AddItem( useGestureBoundary );
@@ -185,6 +191,7 @@ void CMenuControls::SetConfig( )
reverseTorch.WriteCvar();
handModels.WriteCvar();
snapTurnAngle.WriteCvar();
smoothTurn.WriteCvar();
useGesture.WriteCvar();
useGestureBoundary.WriteCvar();