Multiple improvements

- Single movement speed cvar
- Weapon Haptics on weapon controller
- Proper compositor layer for menu
- Weapon hand thumbstick up and down to switch weapons
- Removed weapon angle adjustment as default is fine
This commit is contained in:
Simon 2021-02-03 22:13:37 +00:00
parent 17498c172b
commit a5c1b63574
15 changed files with 1331 additions and 535 deletions

View file

@ -37,15 +37,15 @@
<sourceFolder url="file://$MODULE_DIR$/jni/QuakeQuestSrc" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/jni/QuakeQuestSrc" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/jni/darkplaces" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/jni/darkplaces" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debug/out" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debug/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debug/compileDebugRenderscript/out" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debug/compileDebugRenderscript/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debugAndroidTest/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debugAndroidTest/compileDebugAndroidTestAidl/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debugAndroidTest/compileDebugAndroidTestRenderscript/out" isTestSource="true" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debugAndroidTest/compileDebugAndroidTestRenderscript/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debugAndroidTest/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debugAndroidTest/compileDebugAndroidTestAidl/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debugUnitTest/out" isTestSource="true" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debugUnitTest/out" isTestSource="true" generated="true" />

Binary file not shown.

View file

@ -117,7 +117,8 @@ SRC_COMMON := \
SRC_QUEST := \ SRC_QUEST := \
QuakeQuestSrc/argtable3.c \ QuakeQuestSrc/argtable3.c \
QuakeQuestSrc/QuakeQuest_SurfaceView.c QuakeQuestSrc/QuakeQuest_SurfaceView.c \
QuakeQuestSrc/VrCompositor.c \
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
$(SRC_QUEST) \ $(SRC_QUEST) \

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,38 @@
#if !defined(vrcommon_h)
#define vrcommon_h
//#include <VrApi_Ext.h>
#include <VrApi_Input.h>
#include <android/log.h>
#include "../darkplaces/mathlib.h"
#define LOG_TAG "QuakeQuest"
#ifndef NDEBUG
#define DEBUG 1
#endif
#define ALOGE(...) __android_log_print( ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__ )
#if DEBUG
#define ALOGV(...) __android_log_print( ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__ )
#else
#define ALOGV(...)
#endif
float playerHeight;
float playerYaw;
float radians(float deg);
float degrees(float rad);
qboolean isMultiplayer();
double GetTimeInMilliSeconds();
float length(float x, float y);
float nonLinearFilter(float in);
bool between(float min, float val, float max);
void QuatToYawPitchRoll(ovrQuatf q, float pitchAdjust, vec3_t out);
qboolean useScreenLayer();
#endif //vrcommon_h

View file

@ -0,0 +1,595 @@
/************************************************************************************
Filename : VrCompositor.c
*************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/prctl.h> // for prctl( PR_SET_NAME )
#include <android/log.h>
#include <android/window.h> // for AWINDOW_FLAG_KEEP_SCREEN_ON
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#include <VrApi.h>
#include <VrApi_Helpers.h>
#include "VrCompositor.h"
/*
================================================================================
renderState
================================================================================
*/
void getCurrentRenderState( renderState * state)
{
state->VertexBuffer = 0;
state->IndexBuffer = 0;
state->VertexArrayObject = 0;
state->Program = 0;
glGetIntegerv(GL_ARRAY_BUFFER, &state->VertexBuffer );
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER, &state->IndexBuffer );
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &state->VertexArrayObject );
glGetIntegerv(GL_CURRENT_PROGRAM, &state->Program );
}
void restoreRenderState( renderState * state )
{
GL( glUseProgram( state->Program ) );
GL( glBindVertexArray( state->VertexArrayObject ) );
GL( glBindBuffer( GL_ARRAY_BUFFER, state->VertexBuffer ) );
GL( glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, state->IndexBuffer ) );
}
/*
================================================================================
ovrGeometry
================================================================================
*/
enum VertexAttributeLocation
{
VERTEX_ATTRIBUTE_LOCATION_POSITION,
VERTEX_ATTRIBUTE_LOCATION_COLOR,
VERTEX_ATTRIBUTE_LOCATION_UV,
};
typedef struct
{
enum VertexAttributeLocation location;
const char * name;
} ovrVertexAttribute;
static ovrVertexAttribute ProgramVertexAttributes[] =
{
{ VERTEX_ATTRIBUTE_LOCATION_POSITION, "vertexPosition" },
{ VERTEX_ATTRIBUTE_LOCATION_COLOR, "vertexColor" },
{ VERTEX_ATTRIBUTE_LOCATION_UV, "vertexUv" },
};
static void ovrGeometry_Clear( ovrGeometry * geometry )
{
geometry->VertexBuffer = 0;
geometry->IndexBuffer = 0;
geometry->VertexArrayObject = 0;
geometry->VertexCount = 0;
geometry->IndexCount = 0;
for ( int i = 0; i < MAX_VERTEX_ATTRIB_POINTERS; i++ )
{
memset( &geometry->VertexAttribs[i], 0, sizeof( geometry->VertexAttribs[i] ) );
geometry->VertexAttribs[i].Index = -1;
}
}
static void ovrGeometry_CreateGroundPlane( ovrGeometry * geometry )
{
typedef struct
{
float positions[4][4];
unsigned char colors[4][4];
} ovrCubeVertices;
static const ovrCubeVertices cubeVertices =
{
// positions
{
{ 4.5f, -1.2f, 4.5f, 1.0f },
{ 4.5f, -1.2f, -4.5f, 1.0f },
{ -4.5f, -1.2f, -4.5f, 1.0f },
{ -4.5f, -1.2f, 4.5f, 1.0f }
},
// colors
{
{ 255, 0, 0, 255 },
{ 0, 255, 0, 255 },
{ 0, 0, 255, 255 },
{ 255, 255, 0, 255 },
},
};
static const unsigned short cubeIndices[6] =
{
0, 1, 2,
0, 2, 3,
};
geometry->VertexCount = 4;
geometry->IndexCount = 6;
geometry->VertexAttribs[0].Index = VERTEX_ATTRIBUTE_LOCATION_POSITION;
geometry->VertexAttribs[0].Size = 4;
geometry->VertexAttribs[0].Type = GL_FLOAT;
geometry->VertexAttribs[0].Normalized = false;
geometry->VertexAttribs[0].Stride = sizeof( cubeVertices.positions[0] );
geometry->VertexAttribs[0].Pointer = (const GLvoid *)offsetof( ovrCubeVertices, positions );
geometry->VertexAttribs[1].Index = VERTEX_ATTRIBUTE_LOCATION_COLOR;
geometry->VertexAttribs[1].Size = 4;
geometry->VertexAttribs[1].Type = GL_UNSIGNED_BYTE;
geometry->VertexAttribs[1].Normalized = true;
geometry->VertexAttribs[1].Stride = sizeof( cubeVertices.colors[0] );
geometry->VertexAttribs[1].Pointer = (const GLvoid *)offsetof( ovrCubeVertices, colors );
renderState state;
getCurrentRenderState(&state);
GL( glGenBuffers( 1, &geometry->VertexBuffer ) );
GL( glBindBuffer( GL_ARRAY_BUFFER, geometry->VertexBuffer ) );
GL( glBufferData( GL_ARRAY_BUFFER, sizeof( cubeVertices ), &cubeVertices, GL_STATIC_DRAW ) );
GL( glGenBuffers( 1, &geometry->IndexBuffer ) );
GL( glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, geometry->IndexBuffer ) );
GL( glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( cubeIndices ), cubeIndices, GL_STATIC_DRAW ) );
restoreRenderState(&state);
}
static void ovrGeometry_Destroy( ovrGeometry * geometry )
{
GL( glDeleteBuffers( 1, &geometry->IndexBuffer ) );
GL( glDeleteBuffers( 1, &geometry->VertexBuffer ) );
ovrGeometry_Clear( geometry );
}
static void ovrGeometry_CreateVAO( ovrGeometry * geometry )
{
renderState state;
getCurrentRenderState(&state);
GL( glGenVertexArrays( 1, &geometry->VertexArrayObject ) );
GL( glBindVertexArray( geometry->VertexArrayObject ) );
GL( glBindBuffer( GL_ARRAY_BUFFER, geometry->VertexBuffer ) );
for ( int i = 0; i < MAX_VERTEX_ATTRIB_POINTERS; i++ )
{
if ( geometry->VertexAttribs[i].Index != -1 )
{
GL( glEnableVertexAttribArray( geometry->VertexAttribs[i].Index ) );
GL( glVertexAttribPointer( geometry->VertexAttribs[i].Index, geometry->VertexAttribs[i].Size,
geometry->VertexAttribs[i].Type, geometry->VertexAttribs[i].Normalized,
geometry->VertexAttribs[i].Stride, geometry->VertexAttribs[i].Pointer ) );
}
}
GL( glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, geometry->IndexBuffer ) );
restoreRenderState(&state);
}
static void ovrGeometry_DestroyVAO( ovrGeometry * geometry )
{
GL( glDeleteVertexArrays( 1, &geometry->VertexArrayObject ) );
}
/*
================================================================================
ovrProgram
================================================================================
*/
typedef struct
{
enum
{
UNIFORM_VIEW_PROJ_MATRIX,
} index;
enum
{
UNIFORM_TYPE_VECTOR4,
UNIFORM_TYPE_MATRIX4X4,
UNIFORM_TYPE_INT,
UNIFORM_TYPE_BUFFER,
} type;
const char * name;
} ovrUniform;
static ovrUniform ProgramUniforms[] =
{
{ UNIFORM_VIEW_PROJ_MATRIX, UNIFORM_TYPE_MATRIX4X4, "viewProjectionMatrix" },
};
static void ovrProgram_Clear( ovrProgram * program )
{
program->Program = 0;
program->VertexShader = 0;
program->FragmentShader = 0;
memset( program->UniformLocation, 0, sizeof( program->UniformLocation ) );
memset( program->UniformBinding, 0, sizeof( program->UniformBinding ) );
memset( program->Textures, 0, sizeof( program->Textures ) );
}
static bool ovrProgram_Create( ovrProgram * program, const char * vertexSource, const char * fragmentSource )
{
GLint r;
GL( program->VertexShader = glCreateShader( GL_VERTEX_SHADER ) );
GL( glShaderSource( program->VertexShader, 1, &vertexSource, 0 ) );
GL( glCompileShader( program->VertexShader ) );
GL( glGetShaderiv( program->VertexShader, GL_COMPILE_STATUS, &r ) );
if ( r == GL_FALSE )
{
GLchar msg[4096];
GL( glGetShaderInfoLog( program->VertexShader, sizeof( msg ), 0, msg ) );
ALOGE( "%s\n%s\n", vertexSource, msg );
return false;
}
GL( program->FragmentShader = glCreateShader( GL_FRAGMENT_SHADER ) );
GL( glShaderSource( program->FragmentShader, 1, &fragmentSource, 0 ) );
GL( glCompileShader( program->FragmentShader ) );
GL( glGetShaderiv( program->FragmentShader, GL_COMPILE_STATUS, &r ) );
if ( r == GL_FALSE )
{
GLchar msg[4096];
GL( glGetShaderInfoLog( program->FragmentShader, sizeof( msg ), 0, msg ) );
ALOGE( "%s\n%s\n", fragmentSource, msg );
return false;
}
GL( program->Program = glCreateProgram() );
GL( glAttachShader( program->Program, program->VertexShader ) );
GL( glAttachShader( program->Program, program->FragmentShader ) );
// Bind the vertex attribute locations.
for ( int i = 0; i < sizeof( ProgramVertexAttributes ) / sizeof( ProgramVertexAttributes[0] ); i++ )
{
GL( glBindAttribLocation( program->Program, ProgramVertexAttributes[i].location, ProgramVertexAttributes[i].name ) );
}
GL( glLinkProgram( program->Program ) );
GL( glGetProgramiv( program->Program, GL_LINK_STATUS, &r ) );
if ( r == GL_FALSE )
{
GLchar msg[4096];
GL( glGetProgramInfoLog( program->Program, sizeof( msg ), 0, msg ) );
ALOGE( "Linking program failed: %s\n", msg );
return false;
}
int numBufferBindings = 0;
// Get the uniform locations.
memset( program->UniformLocation, -1, sizeof( program->UniformLocation ) );
for ( int i = 0; i < sizeof( ProgramUniforms ) / sizeof( ProgramUniforms[0] ); i++ )
{
const int uniformIndex = ProgramUniforms[i].index;
if ( ProgramUniforms[i].type == UNIFORM_TYPE_BUFFER )
{
GL( program->UniformLocation[uniformIndex] = glGetUniformBlockIndex( program->Program, ProgramUniforms[i].name ) );
program->UniformBinding[uniformIndex] = numBufferBindings++;
GL( glUniformBlockBinding( program->Program, program->UniformLocation[uniformIndex], program->UniformBinding[uniformIndex] ) );
}
else
{
GL( program->UniformLocation[uniformIndex] = glGetUniformLocation( program->Program, ProgramUniforms[i].name ) );
program->UniformBinding[uniformIndex] = program->UniformLocation[uniformIndex];
}
}
renderState state;
getCurrentRenderState(&state);
GL( glUseProgram( program->Program ) );
// Get the texture locations.
for ( int i = 0; i < MAX_PROGRAM_TEXTURES; i++ )
{
char name[32];
sprintf( name, "Texture%i", i );
program->Textures[i] = glGetUniformLocation( program->Program, name );
if ( program->Textures[i] != -1 )
{
GL( glUniform1i( program->Textures[i], i ) );
}
}
restoreRenderState(&state);
return true;
}
static void ovrProgram_Destroy( ovrProgram * program )
{
if ( program->Program != 0 )
{
GL( glDeleteProgram( program->Program ) );
program->Program = 0;
}
if ( program->VertexShader != 0 )
{
GL( glDeleteShader( program->VertexShader ) );
program->VertexShader = 0;
}
if ( program->FragmentShader != 0 )
{
GL( glDeleteShader( program->FragmentShader ) );
program->FragmentShader = 0;
}
}
static const char VERTEX_SHADER[] =
"#version 300 es\n"
"in vec3 vertexPosition;\n"
"in vec4 vertexColor;\n"
"uniform mat4 viewProjectionMatrix;\n"
"out vec4 fragmentColor;\n"
"void main()\n"
"{\n"
" gl_Position = viewProjectionMatrix * vec4( vertexPosition, 1.0 );\n"
" fragmentColor = vertexColor;\n"
"}\n";
static const char FRAGMENT_SHADER[] =
"#version 300 es\n"
"in lowp vec4 fragmentColor;\n"
"out lowp vec4 outColor;\n"
"void main()\n"
"{\n"
" outColor = fragmentColor;\n"
"}\n";
/*
================================================================================
ovrScene
================================================================================
*/
void ovrScene_Clear( ovrScene * scene )
{
scene->CreatedScene = false;
scene->CreatedVAOs = false;
ovrProgram_Clear( &scene->Program );
ovrGeometry_Clear( &scene->GroundPlane );
ovrRenderer_Clear( &scene->CylinderRenderer );
scene->CylinderWidth = 0;
scene->CylinderHeight = 0;
}
bool ovrScene_IsCreated( ovrScene * scene )
{
return scene->CreatedScene;
}
void ovrScene_CreateVAOs( ovrScene * scene )
{
if ( !scene->CreatedVAOs )
{
ovrGeometry_CreateVAO( &scene->GroundPlane );
scene->CreatedVAOs = true;
}
}
void ovrScene_DestroyVAOs( ovrScene * scene )
{
if ( scene->CreatedVAOs )
{
ovrGeometry_DestroyVAO( &scene->GroundPlane );
scene->CreatedVAOs = false;
}
}
void ovrScene_Create( int width, int height, ovrScene * scene, const ovrJava * java )
{
// Simple ground plane geometry.
{
ovrProgram_Create( &scene->Program, VERTEX_SHADER, FRAGMENT_SHADER );
ovrGeometry_CreateGroundPlane( &scene->GroundPlane );
ovrScene_CreateVAOs( scene );
}
// Create Cylinder renderer
{
scene->CylinderWidth = width;
scene->CylinderHeight = height;
//Create cylinder renderer
ovrRenderer_Create( width, height, &scene->CylinderRenderer, java );
}
scene->CreatedScene = true;
}
void ovrScene_Destroy( ovrScene * scene )
{
ovrScene_DestroyVAOs( scene );
ovrProgram_Destroy( &scene->Program );
ovrGeometry_Destroy( &scene->GroundPlane );
ovrRenderer_Destroy( &scene->CylinderRenderer );
scene->CreatedScene = false;
}
/*
================================================================================
ovrRenderer
================================================================================
*/
ovrLayerProjection2 ovrRenderer_RenderGroundPlaneToEyeBuffer( ovrRenderer * renderer, const ovrJava * java,
const ovrScene * scene, const ovrTracking2 * tracking )
{
ovrLayerProjection2 layer = vrapi_DefaultLayerProjection2();
layer.HeadPose = tracking->HeadPose;
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
{
ovrFramebuffer * frameBuffer = &renderer->FrameBuffer[eye];
layer.Textures[eye].ColorSwapChain = frameBuffer->ColorTextureSwapChain;
layer.Textures[eye].SwapChainIndex = frameBuffer->TextureSwapChainIndex;
layer.Textures[eye].TexCoordsFromTanAngles = ovrMatrix4f_TanAngleMatrixFromProjection( &tracking->Eye[eye].ProjectionMatrix );
}
layer.Header.Flags |= VRAPI_FRAME_LAYER_FLAG_CHROMATIC_ABERRATION_CORRECTION;
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
{
ovrFramebuffer * frameBuffer = &renderer->FrameBuffer[eye];
ovrFramebuffer_SetCurrent( frameBuffer );
renderState state;
getCurrentRenderState(&state);
GL( glUseProgram( scene->Program.Program ) );
ovrMatrix4f viewProjMatrix = ovrMatrix4f_Multiply( &tracking->Eye[eye].ProjectionMatrix, &tracking->Eye[eye].ViewMatrix );
glUniformMatrix4fv( scene->Program.UniformLocation[UNIFORM_VIEW_PROJ_MATRIX], 1, GL_TRUE, &viewProjMatrix.M[0][0] );
GL( glEnable( GL_SCISSOR_TEST ) );
GL( glDepthMask( GL_TRUE ) );
GL( glEnable( GL_DEPTH_TEST ) );
GL( glDepthFunc( GL_LEQUAL ) );
GL( glEnable( GL_CULL_FACE ) );
GL( glCullFace( GL_BACK ) );
GL( glViewport( 0, 0, frameBuffer->Width, frameBuffer->Height ) );
GL( glScissor( 0, 0, frameBuffer->Width, frameBuffer->Height ) );
GL( glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ) );
GL( glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) );
//bind buffers
GL( glBindBuffer( GL_ARRAY_BUFFER, scene->GroundPlane.VertexBuffer ) );
GL( glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, scene->GroundPlane.IndexBuffer ) );
GL( glBindVertexArray( scene->GroundPlane.VertexArrayObject ) );
GL( glDrawElements( GL_TRIANGLES, scene->GroundPlane.IndexCount, GL_UNSIGNED_SHORT, NULL ) );
restoreRenderState(&state);
// Explicitly clear the border texels to black when GL_CLAMP_TO_BORDER is not available.
ovrFramebuffer_ClearEdgeTexels( frameBuffer );
ovrFramebuffer_Resolve( frameBuffer );
ovrFramebuffer_Advance( frameBuffer );
}
ovrFramebuffer_SetNone();
return layer;
}
// Assumes landscape cylinder shape.
static ovrMatrix4f CylinderModelMatrix( const int texWidth, const int texHeight,
const ovrVector3f translation,
const float rotateYaw,
const float rotatePitch,
const float radius,
const float density )
{
const ovrMatrix4f scaleMatrix = ovrMatrix4f_CreateScale( radius, radius * (float)texHeight * VRAPI_PI / density, radius );
const ovrMatrix4f transMatrix = ovrMatrix4f_CreateTranslation( translation.x, translation.y, translation.z );
const ovrMatrix4f rotXMatrix = ovrMatrix4f_CreateRotation( rotateYaw, 0.0f, 0.0f );
const ovrMatrix4f rotYMatrix = ovrMatrix4f_CreateRotation( 0.0f, rotatePitch, 0.0f );
const ovrMatrix4f m0 = ovrMatrix4f_Multiply( &transMatrix, &scaleMatrix );
const ovrMatrix4f m1 = ovrMatrix4f_Multiply( &rotXMatrix, &m0 );
const ovrMatrix4f m2 = ovrMatrix4f_Multiply( &rotYMatrix, &m1 );
return m2;
}
ovrLayerCylinder2 BuildCylinderLayer( ovrRenderer * cylinderRenderer,
const int textureWidth, const int textureHeight,
const ovrTracking2 * tracking, float rotatePitch )
{
ovrLayerCylinder2 layer = vrapi_DefaultLayerCylinder2();
const float fadeLevel = 1.0f;
layer.Header.ColorScale.x =
layer.Header.ColorScale.y =
layer.Header.ColorScale.z =
layer.Header.ColorScale.w = fadeLevel;
layer.Header.SrcBlend = VRAPI_FRAME_LAYER_BLEND_SRC_ALPHA;
layer.Header.DstBlend = VRAPI_FRAME_LAYER_BLEND_ONE_MINUS_SRC_ALPHA;
//layer.Header.Flags = VRAPI_FRAME_LAYER_FLAG_CLIP_TO_TEXTURE_RECT;
layer.HeadPose = tracking->HeadPose;
const float density = 4500.0f;
const float rotateYaw = 0.0f;
const float radius = 2.0f;
const ovrVector3f translation = { 0.0f, 1.5f, -2.5f };
ovrMatrix4f cylinderTransform =
CylinderModelMatrix( textureWidth, textureHeight, translation,
rotateYaw, rotatePitch, radius, density );
const float circScale = density * 0.5f / textureWidth;
const float circBias = -circScale * ( 0.5f * ( 1.0f - 1.0f / circScale ) );
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
{
ovrFramebuffer * cylinderFrameBuffer = &cylinderRenderer->FrameBuffer[eye];
ovrMatrix4f modelViewMatrix = ovrMatrix4f_Multiply( &tracking->Eye[eye].ViewMatrix, &cylinderTransform );
layer.Textures[eye].TexCoordsFromTanAngles = ovrMatrix4f_Inverse( &modelViewMatrix );
layer.Textures[eye].ColorSwapChain = cylinderFrameBuffer->ColorTextureSwapChain;
layer.Textures[eye].SwapChainIndex = cylinderFrameBuffer->TextureSwapChainIndex;
// Texcoord scale and bias is just a representation of the aspect ratio. The positioning
// of the cylinder is handled entirely by the TexCoordsFromTanAngles matrix.
const float texScaleX = circScale;
const float texBiasX = circBias;
const float texScaleY = -0.5f;
const float texBiasY = texScaleY * ( 0.5f * ( 1.0f - ( 1.0f / texScaleY ) ) );
layer.Textures[eye].TextureMatrix.M[0][0] = texScaleX;
layer.Textures[eye].TextureMatrix.M[0][2] = texBiasX;
layer.Textures[eye].TextureMatrix.M[1][1] = texScaleY;
layer.Textures[eye].TextureMatrix.M[1][2] = -texBiasY;
layer.Textures[eye].TextureRect.width = 1.0f;
layer.Textures[eye].TextureRect.height = 1.0f;
}
return layer;
}

View file

@ -0,0 +1,216 @@
/************************************************************************************
Filename : VrCompositor.h
*************************************************************************************/
#define CHECK_GL_ERRORS
#ifdef CHECK_GL_ERRORS
#include "VrCommon.h"
static const char * GlErrorString( GLenum error )
{
switch ( error )
{
case GL_NO_ERROR: return "GL_NO_ERROR";
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
default: return "unknown";
}
}
static void GLCheckErrors( int line )
{
for ( int i = 0; i < 10; i++ )
{
const GLenum error = glGetError();
if ( error == GL_NO_ERROR )
{
break;
}
ALOGE( "GL error on line %d: %s", line, GlErrorString( error ) );
}
}
#define GL( func ) func; GLCheckErrors( __LINE__ );
#else // CHECK_GL_ERRORS
#define GL( func ) func;
#endif // CHECK_GL_ERRORS
/*
================================================================================
ovrFramebuffer
================================================================================
*/
typedef struct
{
int Width;
int Height;
int Multisamples;
int TextureSwapChainLength;
int TextureSwapChainIndex;
ovrTextureSwapChain * ColorTextureSwapChain;
GLuint * DepthBuffers;
GLuint * FrameBuffers;
} ovrFramebuffer;
void ovrFramebuffer_SetCurrent( ovrFramebuffer * frameBuffer );
void ovrFramebuffer_Destroy( ovrFramebuffer * frameBuffer );
void ovrFramebuffer_SetNone();
void ovrFramebuffer_Resolve( ovrFramebuffer * frameBuffer );
void ovrFramebuffer_Advance( ovrFramebuffer * frameBuffer );
void ovrFramebuffer_ClearEdgeTexels( ovrFramebuffer * frameBuffer );
/*
================================================================================
ovrRenderer
================================================================================
*/
typedef struct
{
ovrFramebuffer FrameBuffer[VRAPI_FRAME_LAYER_EYE_MAX];
int NumBuffers;
} ovrRenderer;
void ovrRenderer_Clear( ovrRenderer * renderer );
void ovrRenderer_Create( int width, int height, ovrRenderer * renderer, const ovrJava * java );
void ovrRenderer_Destroy( ovrRenderer * renderer );
/*
================================================================================
renderState
================================================================================
*/
typedef struct
{
GLuint VertexBuffer;
GLuint IndexBuffer;
GLuint VertexArrayObject;
GLuint Program;
GLuint VertexShader;
GLuint FragmentShader;
} renderState;
void getCurrentRenderState( renderState * state);
void restoreRenderState( renderState * state );
/*
================================================================================
ovrGeometry
================================================================================
*/
typedef struct
{
GLuint Index;
GLint Size;
GLenum Type;
GLboolean Normalized;
GLsizei Stride;
const GLvoid * Pointer;
} ovrVertexAttribPointer;
#define MAX_VERTEX_ATTRIB_POINTERS 3
typedef struct
{
GLuint VertexBuffer;
GLuint IndexBuffer;
GLuint VertexArrayObject;
int VertexCount;
int IndexCount;
ovrVertexAttribPointer VertexAttribs[MAX_VERTEX_ATTRIB_POINTERS];
} ovrGeometry;
/*
================================================================================
ovrProgram
================================================================================
*/
#define MAX_PROGRAM_UNIFORMS 8
#define MAX_PROGRAM_TEXTURES 8
typedef struct
{
GLuint Program;
GLuint VertexShader;
GLuint FragmentShader;
// These will be -1 if not used by the program.
GLint UniformLocation[MAX_PROGRAM_UNIFORMS]; // ProgramUniforms[].name
GLint UniformBinding[MAX_PROGRAM_UNIFORMS]; // ProgramUniforms[].name
GLint Textures[MAX_PROGRAM_TEXTURES]; // Texture%i
} ovrProgram;
/*
================================================================================
ovrScene
================================================================================
*/
typedef struct
{
bool CreatedScene;
bool CreatedVAOs;
ovrProgram Program;
ovrGeometry GroundPlane;
//Proper renderer for stereo rendering to the cylinder layer
ovrRenderer CylinderRenderer;
int CylinderWidth;
int CylinderHeight;
} ovrScene;
bool ovrScene_IsCreated( ovrScene * scene );
void ovrScene_Clear( ovrScene * scene );
void ovrScene_Create( int width, int height, ovrScene * scene, const ovrJava * java );
void ovrScene_CreateVAOs( ovrScene * scene );
void ovrScene_DestroyVAOs( ovrScene * scene );
void ovrScene_Destroy( ovrScene * scene );
/*
================================================================================
ovrRenderer
================================================================================
*/
ovrLayerProjection2 ovrRenderer_RenderGroundPlaneToEyeBuffer( ovrRenderer * renderer, const ovrJava * java,
const ovrScene * scene, const ovrTracking2 * tracking );
ovrLayerProjection2 ovrRenderer_RenderToEyeBuffer( ovrRenderer * renderer, const ovrJava * java,
const ovrTracking2 * tracking );
ovrLayerCylinder2 BuildCylinderLayer( ovrRenderer * cylinderRenderer,
const int textureWidth, const int textureHeight,
const ovrTracking2 * tracking, float rotateYaw );
;

View file

@ -430,9 +430,7 @@ float CL_KeyState (kbutton_t *key)
//========================================================================== //==========================================================================
cvar_t cl_upspeed = {CVAR_SAVE, "cl_upspeed","400","vertical movement speed (while swimming or flying)"}; cvar_t cl_upspeed = {CVAR_SAVE, "cl_upspeed","400","vertical movement speed (while swimming or flying)"};
cvar_t cl_forwardspeed = {CVAR_SAVE, "cl_forwardspeed","150","forward movement speed"}; cvar_t cl_movementspeed = {CVAR_SAVE, "cl_movementspeed","150","forward movement speed"};
cvar_t cl_backspeed = {CVAR_SAVE, "cl_backspeed","150","backward movement speed"};
cvar_t cl_sidespeed = {CVAR_SAVE, "cl_sidespeed","150","strafe movement speed"};
cvar_t cl_movespeedkey = {CVAR_SAVE, "cl_movespeedkey","2.0","how much +speed multiplies keyboard movement speed"}; cvar_t cl_movespeedkey = {CVAR_SAVE, "cl_movespeedkey","2.0","how much +speed multiplies keyboard movement speed"};
cvar_t cl_movecliptokeyboard = {0, "cl_movecliptokeyboard", "0", "if set to 1, any move is clipped to the nine keyboard states; if set to 2, only the direction is clipped, not the amount"}; cvar_t cl_movecliptokeyboard = {0, "cl_movecliptokeyboard", "0", "if set to 1, any move is clipped to the nine keyboard states; if set to 2, only the direction is clipped, not the amount"};
@ -446,7 +444,7 @@ cvar_t cl_yawmult = {CVAR_SAVE, "cl_yawmult","1.0","Multiplier for yaw (leave at
cvar_t cl_pitchmult = {CVAR_SAVE, "cl_pitchmult","1.0","Multiplier for yaw (leave at 1.0)"}; cvar_t cl_pitchmult = {CVAR_SAVE, "cl_pitchmult","1.0","Multiplier for yaw (leave at 1.0)"};
cvar_t cl_controllerdeadzone = {0, "cl_controllerdeadzone","0.05","Amount of deadzone to prevent movement drift due to badly calibrated controller (0.0 to 1.0)"}; cvar_t cl_controllerdeadzone = {0, "cl_controllerdeadzone","0.05","Amount of deadzone to prevent movement drift due to badly calibrated controller (0.0 to 1.0)"};
cvar_t cl_righthanded = {CVAR_SAVE, "cl_righthanded","1","right-handed?"}; cvar_t cl_righthanded = {CVAR_SAVE, "cl_righthanded","1","right-handed?"};
cvar_t vr_weaponpitchadjust = {CVAR_SAVE, "vr_weaponpitchadjust","-30.0","Weapon pitch adjustment"}; cvar_t vr_weaponpitchadjust = {CVAR_SAVE, "vr_weaponpitchadjust","-20.0","Weapon pitch adjustment"};
cvar_t cl_trackingmode = {CVAR_SAVE, "cl_trackingmode","1","Tracking Mode:- 1 - 6DoF or 0 - 3DoF"}; cvar_t cl_trackingmode = {CVAR_SAVE, "cl_trackingmode","1","Tracking Mode:- 1 - 6DoF or 0 - 3DoF"};
@ -578,20 +576,20 @@ void CL_Input (void)
// get basic movement from keyboard // get basic movement from keyboard
if (in_strafe.state & 1) if (in_strafe.state & 1)
{ {
cl.cmd.sidemove += cl_sidespeed.value * CL_KeyState (&in_right); cl.cmd.sidemove += cl_movementspeed.value * CL_KeyState (&in_right);
cl.cmd.sidemove -= cl_sidespeed.value * CL_KeyState (&in_left); cl.cmd.sidemove -= cl_movementspeed.value * CL_KeyState (&in_left);
} }
cl.cmd.sidemove += cl_sidespeed.value * CL_KeyState (&in_moveright); cl.cmd.sidemove += cl_movementspeed.value * CL_KeyState (&in_moveright);
cl.cmd.sidemove -= cl_sidespeed.value * CL_KeyState (&in_moveleft); cl.cmd.sidemove -= cl_movementspeed.value * CL_KeyState (&in_moveleft);
cl.cmd.upmove += cl_upspeed.value * CL_KeyState (&in_up); cl.cmd.upmove += cl_upspeed.value * CL_KeyState (&in_up);
cl.cmd.upmove -= cl_upspeed.value * CL_KeyState (&in_down); cl.cmd.upmove -= cl_upspeed.value * CL_KeyState (&in_down);
if (! (in_klook.state & 1) ) if (! (in_klook.state & 1) )
{ {
cl.cmd.forwardmove += cl_forwardspeed.value * CL_KeyState (&in_forward); cl.cmd.forwardmove += cl_movementspeed.value * CL_KeyState (&in_forward);
cl.cmd.forwardmove -= cl_backspeed.value * CL_KeyState (&in_back); cl.cmd.forwardmove -= cl_movementspeed.value * CL_KeyState (&in_back);
} }
// adjust for speed key // adjust for speed key
@ -777,16 +775,16 @@ void CL_Input (void)
else if(cl_movecliptokeyboard.integer) else if(cl_movecliptokeyboard.integer)
{ {
// digital direction, digital amount // digital direction, digital amount
if(cl.cmd.sidemove >= cl_sidespeed.value * f * 0.5) if(cl.cmd.sidemove >= cl_movementspeed.value * f * 0.5)
cl.cmd.sidemove = cl_sidespeed.value * f; cl.cmd.sidemove = cl_movementspeed.value * f;
else if(cl.cmd.sidemove <= -cl_sidespeed.value * f * 0.5) else if(cl.cmd.sidemove <= -cl_movementspeed.value * f * 0.5)
cl.cmd.sidemove = -cl_sidespeed.value * f; cl.cmd.sidemove = -cl_movementspeed.value * f;
else else
cl.cmd.sidemove = 0; cl.cmd.sidemove = 0;
if(cl.cmd.forwardmove >= cl_forwardspeed.value * f * 0.5) if(cl.cmd.forwardmove >= cl_movementspeed.value * f * 0.5)
cl.cmd.forwardmove = cl_forwardspeed.value * f; cl.cmd.forwardmove = cl_movementspeed.value * f;
else if(cl.cmd.forwardmove <= -cl_backspeed.value * f * 0.5) else if(cl.cmd.forwardmove <= -cl_movementspeed.value * f * 0.5)
cl.cmd.forwardmove = -cl_backspeed.value * f; cl.cmd.forwardmove = -cl_movementspeed.value * f;
else else
cl.cmd.forwardmove = 0; cl.cmd.forwardmove = 0;
} }

View file

@ -2469,9 +2469,7 @@ void CL_Init (void)
// register our commands // register our commands
// //
Cvar_RegisterVariable (&cl_upspeed); Cvar_RegisterVariable (&cl_upspeed);
Cvar_RegisterVariable (&cl_forwardspeed); Cvar_RegisterVariable (&cl_movementspeed);
Cvar_RegisterVariable (&cl_backspeed);
Cvar_RegisterVariable (&cl_sidespeed);
Cvar_RegisterVariable (&cl_movespeedkey); Cvar_RegisterVariable (&cl_movespeedkey);
Cvar_RegisterVariable (&cl_yawspeed); Cvar_RegisterVariable (&cl_yawspeed);
Cvar_RegisterVariable (&cl_pitchspeed); Cvar_RegisterVariable (&cl_pitchspeed);

View file

@ -1483,9 +1483,7 @@ extern cvar_t rcon_password;
extern cvar_t rcon_address; extern cvar_t rcon_address;
extern cvar_t cl_upspeed; extern cvar_t cl_upspeed;
extern cvar_t cl_forwardspeed; extern cvar_t cl_movementspeed;
extern cvar_t cl_backspeed;
extern cvar_t cl_sidespeed;
extern cvar_t cl_movespeedkey; extern cvar_t cl_movespeedkey;

View file

@ -51,9 +51,11 @@ static qboolean r_gpuskeletal;
// 1.0 pixel unit / 1.5 inch == 0.666666 pixel units per inch // 1.0 pixel unit / 1.5 inch == 0.666666 pixel units per inch
cvar_t vr_worldscale = {CVAR_SAVE, "vr_worldscale", "26.2467", "VR World scale multiplier"}; cvar_t vr_worldscale = {CVAR_SAVE, "vr_worldscale", "26.2467", "VR World scale multiplier"};
qboolean useScreenLayer();
float GetStereoSeparation() float GetStereoSeparation()
{ {
return vr_worldscale.value * 0.065f; return useScreenLayer() ? 0.0f : vr_worldscale.value * 0.065f;
} }

View file

@ -1756,27 +1756,13 @@ static void M_Menu_Options_AdjustSliders (int dir)
else if (options_cursor == optnum++) ; else if (options_cursor == optnum++) ;
else if (options_cursor == optnum++) else if (options_cursor == optnum++)
{ {
cl_forwardspeed.value += dir * 10; cl_movementspeed.value += dir * 10;
if (cl_forwardspeed.value > 500) if (cl_movementspeed.value > 500)
cl_forwardspeed.value = 500; cl_movementspeed.value = 500;
if (cl_forwardspeed.value < 10) if (cl_movementspeed.value < 10)
cl_forwardspeed.value = 10; cl_movementspeed.value = 10;
cl_backspeed.value += dir * 10; Cvar_SetValueQuick (&cl_movementspeed, cl_movementspeed.value);
if (cl_backspeed.value > 500)
cl_backspeed.value = 500;
if (cl_backspeed.value < 10)
cl_backspeed.value = 10;
cl_sidespeed.value += dir * 10;
if (cl_sidespeed.value > 500)
cl_sidespeed.value = 500;
if (cl_sidespeed.value < 10)
cl_sidespeed.value = 10;
Cvar_SetValueQuick (&cl_forwardspeed, cl_forwardspeed.value);
Cvar_SetValueQuick (&cl_backspeed, cl_backspeed.value);
Cvar_SetValueQuick (&cl_sidespeed, cl_sidespeed.value);
} }
else if (options_cursor == optnum++) Cvar_SetValueQuick(&showfps, !showfps.integer); else if (options_cursor == optnum++) Cvar_SetValueQuick(&showfps, !showfps.integer);
else if (options_cursor == optnum++) ; else if (options_cursor == optnum++) ;
@ -1888,7 +1874,7 @@ static void M_Options_Draw (void)
M_Options_PrintCommand( " Positional Tracking: Enabled", false); M_Options_PrintCommand( " Positional Tracking: Enabled", false);
M_Options_PrintSlider( " Player Movement Speed", true, cl_forwardspeed.value, 10, 500); M_Options_PrintSlider( " Player Movement Speed", true, cl_movementspeed.value, 10, 500);
M_Options_PrintCheckbox(" Show Framerate", true, showfps.integer); M_Options_PrintCheckbox(" Show Framerate", true, showfps.integer);
M_Options_PrintCommand( " Custom Brightness", true); M_Options_PrintCommand( " Custom Brightness", true);
M_Options_PrintSlider( " Game Brightness", true, r_hdr_scenebrightness.value, 1, 4); M_Options_PrintSlider( " Game Brightness", true, r_hdr_scenebrightness.value, 1, 4);

View file

@ -134,9 +134,11 @@ int Sbar_GetYOffset()
return offset; return offset;
} }
qboolean useScreenLayer();
int Sbar_GetXOffset() int Sbar_GetXOffset()
{ {
if (!vrMode) if (useScreenLayer())
return 0; return 0;
//This will give the status bar depth in the 3D space //This will give the status bar depth in the 3D space

View file

@ -1382,8 +1382,8 @@ void VID_ApplyJoyState(vid_joystate_t *joystate)
VID_KeyEventForButton(vid_joystate.button[j] != 0, joystate->button[j] != 0, joybuttonkey360[j][c], &vid_joybuttontimer[j]); VID_KeyEventForButton(vid_joystate.button[j] != 0, joystate->button[j] != 0, joybuttonkey360[j][c], &vid_joybuttontimer[j]);
// axes // axes
cl.cmd.forwardmove += VID_JoyState_GetAxis(joystate, joy_x360_axisforward.integer, joy_x360_sensitivityforward.value, joy_x360_deadzoneforward.value) * cl_forwardspeed.value; cl.cmd.forwardmove += VID_JoyState_GetAxis(joystate, joy_x360_axisforward.integer, joy_x360_sensitivityforward.value, joy_x360_deadzoneforward.value) * cl_movementspeed.value;
cl.cmd.sidemove += VID_JoyState_GetAxis(joystate, joy_x360_axisside.integer, joy_x360_sensitivityside.value, joy_x360_deadzoneside.value) * cl_sidespeed.value; cl.cmd.sidemove += VID_JoyState_GetAxis(joystate, joy_x360_axisside.integer, joy_x360_sensitivityside.value, joy_x360_deadzoneside.value) * cl_movementspeed.value;
cl.cmd.upmove += VID_JoyState_GetAxis(joystate, joy_x360_axisup.integer, joy_x360_sensitivityup.value, joy_x360_deadzoneup.value) * cl_upspeed.value; cl.cmd.upmove += VID_JoyState_GetAxis(joystate, joy_x360_axisup.integer, joy_x360_sensitivityup.value, joy_x360_deadzoneup.value) * cl_upspeed.value;
cl.viewangles[0] += VID_JoyState_GetAxis(joystate, joy_x360_axispitch.integer, joy_x360_sensitivitypitch.value, joy_x360_deadzonepitch.value) * cl.realframetime * cl_pitchspeed.value; cl.viewangles[0] += VID_JoyState_GetAxis(joystate, joy_x360_axispitch.integer, joy_x360_sensitivitypitch.value, joy_x360_deadzonepitch.value) * cl.realframetime * cl_pitchspeed.value;
cl.viewangles[1] += VID_JoyState_GetAxis(joystate, joy_x360_axisyaw.integer, joy_x360_sensitivityyaw.value, joy_x360_deadzoneyaw.value) * cl.realframetime * cl_yawspeed.value; cl.viewangles[1] += VID_JoyState_GetAxis(joystate, joy_x360_axisyaw.integer, joy_x360_sensitivityyaw.value, joy_x360_deadzoneyaw.value) * cl.realframetime * cl_yawspeed.value;
@ -1396,8 +1396,8 @@ void VID_ApplyJoyState(vid_joystate_t *joystate)
VID_KeyEventForButton(vid_joystate.button[j] != 0, joystate->button[j] != 0, joybuttonkey[j][c], &vid_joybuttontimer[j]); VID_KeyEventForButton(vid_joystate.button[j] != 0, joystate->button[j] != 0, joybuttonkey[j][c], &vid_joybuttontimer[j]);
// axes // axes
cl.cmd.forwardmove += VID_JoyState_GetAxis(joystate, joy_axisforward.integer, joy_sensitivityforward.value, joy_deadzoneforward.value) * cl_forwardspeed.value; cl.cmd.forwardmove += VID_JoyState_GetAxis(joystate, joy_axisforward.integer, joy_sensitivityforward.value, joy_deadzoneforward.value) * cl_movementspeed.value;
cl.cmd.sidemove += VID_JoyState_GetAxis(joystate, joy_axisside.integer, joy_sensitivityside.value, joy_deadzoneside.value) * cl_sidespeed.value; cl.cmd.sidemove += VID_JoyState_GetAxis(joystate, joy_axisside.integer, joy_sensitivityside.value, joy_deadzoneside.value) * cl_movementspeed.value;
cl.cmd.upmove += VID_JoyState_GetAxis(joystate, joy_axisup.integer, joy_sensitivityup.value, joy_deadzoneup.value) * cl_upspeed.value; cl.cmd.upmove += VID_JoyState_GetAxis(joystate, joy_axisup.integer, joy_sensitivityup.value, joy_deadzoneup.value) * cl_upspeed.value;
cl.viewangles[0] += VID_JoyState_GetAxis(joystate, joy_axispitch.integer, joy_sensitivitypitch.value, joy_deadzonepitch.value) * cl.realframetime * cl_pitchspeed.value; cl.viewangles[0] += VID_JoyState_GetAxis(joystate, joy_axispitch.integer, joy_sensitivitypitch.value, joy_deadzonepitch.value) * cl.realframetime * cl_pitchspeed.value;
cl.viewangles[1] += VID_JoyState_GetAxis(joystate, joy_axisyaw.integer, joy_sensitivityyaw.value, joy_deadzoneyaw.value) * cl.realframetime * cl_yawspeed.value; cl.viewangles[1] += VID_JoyState_GetAxis(joystate, joy_axisyaw.integer, joy_sensitivityyaw.value, joy_deadzoneyaw.value) * cl.realframetime * cl_yawspeed.value;

View file

@ -203,7 +203,7 @@ void V_DriftPitch (void)
// don't count small mouse motion // don't count small mouse motion
if (cl.nodrift) if (cl.nodrift)
{ {
if ( fabs(cl.cmd.forwardmove) < cl_forwardspeed.value) if ( fabs(cl.cmd.forwardmove) < cl_movementspeed.value)
cl.driftmove = 0; cl.driftmove = 0;
else else
cl.driftmove += cl.realframetime; cl.driftmove += cl.realframetime;