Major Mulltiplayer Support changes

- Multiplayer support
- Updated weapon offsets with SkillFur's latest values
- APK contains and copies the glsl shader files now (no need to copy them separately)
This commit is contained in:
Simon 2022-02-08 23:22:43 +00:00
parent 3678133c67
commit 2926e73185
23 changed files with 172 additions and 118 deletions

View file

@ -16,7 +16,7 @@ BUILD_GAME_QVM=0
BUILD_GAME_SO=1
BUILD_MISSIONPACK=0
BUILD_SERVER=0
BUILD_STANDALONE=1
BUILD_STANDALONE=0
GENERATE_DEPENDENCIES=0
USE_CODEC_VORBIS=0
USE_CURL=0

View file

@ -2,14 +2,14 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.drbeef.ioq3quest"
android:installLocation="preferExternal"
android:versionCode="11"
android:versionName="0.7.1">
android:versionCode="12"
android:versionName="0.8.0">
<uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" />
<uses-feature android:glEsVersion="0x00030001" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

View file

@ -65,7 +65,7 @@ int main(int argc, char* argv[]) {
engine_t* engine = nullptr;
engine = VR_Init(java);
//sleep(30);
//sleep(40);
//First set up resolution cached values
int width, height;
@ -76,6 +76,7 @@ int main(int argc, char* argv[]) {
char *args = (char*)getenv("commandline");
Com_Init(args);
NET_Init( );
VR_InitRenderer(engine);

View file

@ -12,14 +12,18 @@ import androidx.core.content.ContextCompat;
import org.libsdl.app.SDLActivity;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static android.system.Os.setenv;
@ -35,12 +39,14 @@ public class MainActivity extends SDLActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG,"onCreate called");
try {
checkPermissionsAndInitialize();
} catch (Exception e) {}
super.onCreate(savedInstanceState);
}
/** Initializes the Activity only if the permission has been granted. */
private void checkPermissionsAndInitialize() {
private void checkPermissionsAndInitialize() throws IOException {
// Boilerplate for checking runtime permissions in Android.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
@ -65,19 +71,49 @@ public class MainActivity extends SDLActivity
}
}
public void create() {
Log.d(TAG, "making dirs");
//Make the directories
new File("/sdcard/ioquake3Quest/").mkdirs();
public static void unzip(File zipFile, File targetDirectory) throws IOException {
ZipInputStream zis = new ZipInputStream(
new BufferedInputStream(new FileInputStream(zipFile)));
try {
ZipEntry ze;
int count;
byte[] buffer = new byte[8192];
while ((ze = zis.getNextEntry()) != null) {
File file = new File(targetDirectory, ze.getName());
File dir = ze.isDirectory() ? file : file.getParentFile();
if (!dir.isDirectory() && !dir.mkdirs())
throw new FileNotFoundException("Failed to ensure directory: " +
dir.getAbsolutePath());
if (ze.isDirectory())
continue;
FileOutputStream fout = new FileOutputStream(file);
try {
while ((count = zis.read(buffer)) != -1)
fout.write(buffer, 0, count);
} finally {
fout.close();
}
}
} finally {
zis.close();
}
}
public void create() throws IOException {
//Make the directories
new File("/sdcard/ioquake3Quest/baseq3").mkdirs();
Log.d(TAG, "copying commandline.txt");
//Copy the command line params file
copy_asset("/sdcard/ioquake3Quest", "commandline.txt", false);
//glsl
copy_asset("/sdcard/ioquake3Quest", "glsl.zip", true);
new File("/sdcard/ioquake3Quest/baseq3/glsl").mkdirs();
unzip(new File("/sdcard/ioquake3Quest/glsl.zip"), new File("/sdcard/ioquake3Quest/baseq3/glsl"));
//Read these from a file and pass through
commandLineParams = new String();
Log.d(TAG, "reading commandline.txt");
//See if user is trying to use command line params
if (new File("/sdcard/ioquake3Quest/commandline.txt").exists())
{

View file

@ -2674,9 +2674,11 @@ void CG_DrawActive( stereoFrame_t stereoView ) {
VectorCopy( cg.refdef.vieworg, baseOrg );
float worldscale = trap_Cvar_VariableValue("vr_worldscale") *
(( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) ? DEATH_WORLDSCALE_MULTIPLIER : 1.0f);
(( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) &&
( cg.snap->ps.pm_type != PM_INTERMISSION ) ? DEATH_WORLDSCALE_MULTIPLIER : 1.0f);
float ipd = 0.065f;
float ipd = trap_Cvar_VariableValue("r_stereoSeparation") / 1000.0f;
float separation = stereoView == STEREO_LEFT ?
worldscale * (-ipd / 2) : //left
worldscale * (ipd / 2); // right

View file

@ -50,8 +50,11 @@ This must be the very first function compiled into the .q3vm file
Q_EXPORT intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) {
switch ( command ) {
case CG_INIT:
CG_Init( arg0, arg1, arg2 );
case CG_INIT: {
int ptr[2] = {arg3, arg4};
cgVR = (vr_clientinfo_t *) (*(long *) (ptr));
CG_Init(arg0, arg1, arg2);
}
return 0;
case CG_SHUTDOWN:
CG_Shutdown();
@ -78,11 +81,6 @@ Q_EXPORT intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, i
case CG_EVENT_HANDLING:
CG_EventHandling(arg0);
return 0;
case CG_SET_VR_CLIENT_INFO: {
int ptr[2] = {arg0, arg1};
cgVR = (vr_clientinfo_t *) (*(long*)(ptr));
return 0;
}
default:
CG_Error( "vmMain: unknown command %i", command );
break;

View file

@ -231,11 +231,9 @@ typedef enum {
CG_MOUSE_EVENT,
// void (*CG_MouseEvent)( int dx, int dy );
CG_EVENT_HANDLING,
CG_EVENT_HANDLING
// void (*CG_EventHandling)(int type);
CG_SET_VR_CLIENT_INFO
} cgameExport_t;
//----------------------------------------------

View file

@ -633,20 +633,12 @@ static int CG_CalcViewValues( void ) {
CG_CalcVrect();
ps = &cg.predictedPlayerState;
/*
if (cg.cameraMode) {
vec3_t origin, angles;
if (trap_getCameraInfo(cg.time, &origin, &angles)) {
VectorCopy(origin, cg.refdef.vieworg);
angles[ROLL] = 0;
VectorCopy(angles, cg.refdefViewAngles);
AnglesToAxis( cg.refdefViewAngles, cg.refdef.viewaxis );
return CG_CalcFov();
} else {
cg.cameraMode = qfalse;
}
}
*/
//HACK!! - should change this to a renderer function call
//Indicate to renderer whether we are in deathcam mode, We don't want sky in death cam mode
trap_Cvar_Set( "r_deathCam", ((ps->stats[STAT_HEALTH] <= 0) &&
( ps->pm_type != PM_INTERMISSION )) ? "1" : "0" );
// intermission view
static float hmdYaw = 0;
if ( ps->pm_type == PM_INTERMISSION ) {
@ -665,6 +657,7 @@ static int CG_CalcViewValues( void ) {
VectorCopy(cgVR->hmdorientation, cg.refdefViewAngles);
cg.refdefViewAngles[YAW] += (ps->viewangles[YAW] - hmdYaw);
AnglesToAxis( cg.refdefViewAngles, cg.refdef.viewaxis );
return CG_CalcFov();
}
@ -710,12 +703,19 @@ static int CG_CalcViewValues( void ) {
CG_OffsetFirstPersonView();
}
//HACK!! - should change this to a renderer function call
//Indicate to renderer whether we are in deathcam mode, We don't want sky in death cam mode
trap_Cvar_Set( "r_deathCam", (cg.snap->ps.stats[STAT_HEALTH] <= 0) ? "1" : "0" );
// position eye relative to origin
float sv_running = trap_Cvar_VariableValue("sv_running");
if (sv_running == 0.0f )
{
//We are connected to a multiplayer server, so make the appropriate adjustment to the view
//angles as we send orientation to the server that includes the weapon angles
vec3_t angles;
VectorCopy(cgVR->hmdorientation, angles);
angles[YAW] = (cg.refdefViewAngles[YAW] + cgVR->hmdorientation[YAW]) - cgVR->weaponangles[YAW];
AnglesToAxis( angles, cg.refdef.viewaxis );
} else {
AnglesToAxis( cg.refdefViewAngles, cg.refdef.viewaxis );
}
if ( cg.hyperspace ) {
cg.refdef.rdflags |= RDF_NOWORLDMODEL | RDF_HYPERSPACE;

View file

@ -230,7 +230,16 @@ void CG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out)
VectorSet(vrSpace, in[2], in[0], in[1] );
vec2_t r;
float sv_running = trap_Cvar_VariableValue("sv_running");
if (sv_running == 0.0f )
{
//We are connected to a multiplayer server, so make the appropriate adjustment to the view
//angles as we send orientation to the server that includes the weapon angles
rotateAboutOrigin(vrSpace[0], vrSpace[1], cg.refdefViewAngles[YAW] - cgVR->weaponangles[YAW], r);
} else {
rotateAboutOrigin(vrSpace[0], vrSpace[1], cg.refdefViewAngles[YAW] - cgVR->hmdorientation[YAW], r);
}
vrSpace[0] = -r[0];
vrSpace[1] = -r[1];
@ -255,7 +264,16 @@ void CG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles )
VectorCopy(cgVR->weaponangles, angles);
float sv_running = trap_Cvar_VariableValue("sv_running");
if (sv_running == 0.0f )
{
//take player state angles provided by server
angles[YAW] = cg.snap->ps.viewangles[YAW];
angles[PITCH] = cg.snap->ps.viewangles[PITCH];
} else
{
angles[YAW] += (cg.refdefViewAngles[YAW] - cgVR->hmdorientation[YAW]);
}
}
/*

View file

@ -55,17 +55,6 @@ void CL_GetGlconfig( glconfig_t *glconfig ) {
*glconfig = cls.glconfig;
}
/*
=====================
CL_CGameRendering
=====================
*/
void CL_CGameSetVRClientInfo() {
long val = (long)(&vr);
int *ptr = (int*)(&val); //HACK!!
VM_Call( cgvm, CG_SET_VR_CLIENT_INFO, ptr[0], ptr[1] );
}
/*
====================
CL_GetUserCmd
@ -751,10 +740,14 @@ void CL_InitCGame( void ) {
}
clc.state = CA_LOADING;
//Pass the vr client info in on the init
long val = (long)(&vr);
int *ptr = (int*)(&val); //HACK!!
// init for this gamestate
// use the lastExecutedServerCommand instead of the serverCommandSequence
// otherwise server commands sent just before a gamestate are dropped
VM_Call( cgvm, CG_INIT, clc.serverMessageSequence, clc.lastExecutedServerCommand, clc.clientNum );
VM_Call( cgvm, CG_INIT, clc.serverMessageSequence, clc.lastExecutedServerCommand, clc.clientNum, ptr[0], ptr[1] );
// reset any CVAR_CHEAT cvars registered by cgame
if ( !clc.demoplaying && !cl_connectedToCheatServer )

View file

@ -598,13 +598,13 @@ void CL_FinishMove( usercmd_t *cmd ) {
{
vec3_t angles;
VectorCopy(vr.weaponangles, angles);
angles[YAW] += cl.viewangles[YAW];
angles[YAW] += (cl.viewangles[YAW] - vr.hmdorientation[YAW]);
for (i = 0; i < 3; i++) {
cmd->angles[i] = ANGLE2SHORT(angles[i]);
}
vec3_t out;
rotateAboutOrigin(cmd->rightmove, cmd->forwardmove, cl.viewangles[YAW], out);
rotateAboutOrigin(cmd->rightmove, cmd->forwardmove, -vr.weaponangles[YAW], out);
cmd->rightmove = out[0];
cmd->forwardmove = out[1];
}

View file

@ -538,7 +538,6 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {
break;
case CA_LOADING:
case CA_PRIMED:
CL_CGameSetVRClientInfo();
// draw the game information screen and loading progress
CL_CGameRendering(stereoFrame);
@ -549,7 +548,6 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {
VM_Call( uivm, UI_DRAW_CONNECT_SCREEN, qtrue );
break;
case CA_ACTIVE:
CL_CGameSetVRClientInfo();
// always supply STEREO_CENTER as vieworg offset is now done by the engine.
CL_CGameRendering(stereoFrame);
SCR_DrawDemoRecording();

View file

@ -1123,12 +1123,15 @@ void CL_InitUI( void ) {
Com_Error( ERR_FATAL, "VM_Create on UI failed" );
}
long val = (long)(&vr);
int *ptr = (int*)(&val); //HACK!!
// sanity check
v = VM_Call( uivm, UI_GETAPIVERSION );
if (v == UI_OLD_API_VERSION) {
// Com_Printf(S_COLOR_YELLOW "WARNING: loading old Quake III Arena User Interface version %d\n", v );
// init for this gamestate
VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE));
VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE), ptr[0], ptr[1]);
}
else if (v != UI_API_VERSION) {
// Free uivm now, so UI_SHUTDOWN doesn't get called later.
@ -1140,13 +1143,7 @@ void CL_InitUI( void ) {
}
else {
// init for this gamestate
VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE) );
}
{
long val = (long)(&vr);
int *ptr = (int*)(&val); //HACK!!
VM_Call( uivm, UI_SET_VR_CLIENT_INFO, ptr[0], ptr[1] );
VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE), ptr[0], ptr[1] );
}
}

View file

@ -507,8 +507,6 @@ void CL_ReadPackets (void);
void CL_WritePacket( void );
void IN_CenterView (void);
void CL_CGameSetVRClientInfo( void );
void CL_VerifyCode( void );
float CL_KeyState (kbutton_t *key);

View file

@ -204,8 +204,11 @@ This must be the very first function compiled into the .q3vm file
*/
Q_EXPORT intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) {
switch ( command ) {
case GAME_INIT:
G_InitGame( arg0, arg1, arg2 );
case GAME_INIT: {
int ptr[2] = {arg3, arg4};
gVR = (vr_clientinfo_t *) (*(long *) (ptr));
G_InitGame(arg0, arg1, arg2);
}
return 0;
case GAME_SHUTDOWN:
G_ShutdownGame( arg0 );
@ -234,11 +237,6 @@ Q_EXPORT intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, i
return ConsoleCommand();
case BOTAI_START_FRAME:
return BotAIStartFrame( arg0 );
case GAME_SET_VR_CLIENT_INFO: {
int ptr[2] = {arg0, arg1};
gVR = (vr_clientinfo_t *) (*(long*)(ptr));
return 0;
}
}
return -1;

View file

@ -425,8 +425,6 @@ typedef enum {
// The game can issue trap_argc() / trap_argv() commands to get the command
// and parameters. Return qfalse if the game doesn't recognize it as a command.
BOTAI_START_FRAME, // ( int time );
GAME_SET_VR_CLIENT_INFO
BOTAI_START_FRAME // ( int time );
} gameExport_t;

View file

@ -47,8 +47,12 @@ Q_EXPORT intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, i
case UI_GETAPIVERSION:
return UI_API_VERSION;
case UI_INIT:
case UI_INIT: {
int ptr[2] = {arg1, arg2};
uiVR = (vr_clientinfo_t *) (*(long *) (ptr));
UI_Init();
}
return 0;
case UI_SHUTDOWN:
@ -82,13 +86,6 @@ Q_EXPORT intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, i
return 0;
case UI_HASUNIQUECDKEY: // mod authors need to observe this
return qtrue; // change this to qfalse for mods!
case UI_SET_VR_CLIENT_INFO:{
int ptr[2] = {arg0, arg1};
uiVR = (vr_clientinfo_t *) (*(long*)(ptr));
return 0;
}
}
return -1;

View file

@ -248,6 +248,8 @@ static char fs_gamedir[MAX_OSPATH]; // this will be a single file name with no
static cvar_t *fs_debug;
static cvar_t *fs_homepath;
static cvar_t *fs_forceNativeVM;
#ifdef __APPLE__
// Also search the .app bundle for .pk3 files
static cvar_t *fs_apppath;
@ -1332,6 +1334,7 @@ long FS_FOpenFileReadDir(const char *filename, searchpath_t *search, fileHandle_
!FS_IsExt(filename, ".menu", len) && // menu files
!FS_IsExt(filename, ".game", len) && // menu files
!FS_IsExt(filename, ".dat", len) && // for journal files
!FS_IsExt(filename, ".glsl", len) && // external glsl files
!FS_IsDemoExt(filename, len)) // demos
{
*file = 0;
@ -1467,7 +1470,7 @@ int FS_FindVM(void **startSearch, char *found, int foundlen, const char *name, i
while(search)
{
if(search->dir && !fs_numServerPaks)
if(search->dir && (!fs_numServerPaks || fs_forceNativeVM->integer != 0))
{
dir = search->dir;
@ -1495,7 +1498,8 @@ int FS_FindVM(void **startSearch, char *found, int foundlen, const char *name, i
return VMI_COMPILED;
}
}
else if(search->pack)
else if(search->pack &&
fs_forceNativeVM->integer == 0)
{
pack = search->pack;
@ -3986,6 +3990,9 @@ void FS_InitFilesystem( void ) {
Com_StartupVariable("fs_homepath");
Com_StartupVariable("fs_game");
fs_forceNativeVM = Cvar_Get( "fs_forceNativeVM", "1", CVAR_ARCHIVE );
if(!FS_FilenameCompare(Cvar_VariableString("fs_game"), com_basegame->string))
Cvar_Set("fs_game", "");

View file

@ -24,8 +24,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "server.h"
#include "../botlib/botlib.h"
#include "../vr/vr_clientinfo.h"
botlib_export_t *botlib_export;
extern vr_clientinfo_t vr;
// these functions must be used instead of pointer arithmetic, because
// the game allocates gentities with private information after the server shared part
@ -886,9 +888,13 @@ static void SV_InitGameVM( qboolean restart ) {
svs.clients[i].gentity = NULL;
}
//Ensure the game library has our VR client info
long val = (long)(&vr);
int *ptr = (int*)(&val); //HACK!!
// use the current msec count for a random seed
// init for this gamestate
VM_Call (gvm, GAME_INIT, sv.time, Com_Milliseconds(), restart);
VM_Call (gvm, GAME_INIT, sv.time, Com_Milliseconds(), restart, ptr[0], ptr[1]);
}

View file

@ -21,7 +21,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "server.h"
#include "../vr/vr_clientinfo.h"
#ifdef USE_VOIP
cvar_t *sv_voip;
@ -31,7 +30,6 @@ cvar_t *sv_voipProtocol;
serverStatic_t svs; // persistant server info
server_t sv; // local server
vm_t *gvm = NULL; // game virtual machine
extern vr_clientinfo_t vr;
cvar_t *sv_fps = NULL; // time rate for running non-clients
cvar_t *sv_timeout; // seconds without any message
@ -1130,10 +1128,6 @@ void SV_Frame( int msec ) {
startTime = 0; // quite a compiler warning
}
//Ensure the game library has our VR client info
long val = (long)(&vr);
int *ptr = (int*)(&val); //HACK!!
VM_Call( gvm, GAME_SET_VR_CLIENT_INFO, ptr[0], ptr[1] );
// update ping based on the all received frames
SV_CalcPings();

View file

@ -182,12 +182,10 @@ typedef enum {
UI_DRAW_CONNECT_SCREEN,
// void UI_DrawConnectScreen( qboolean overlay );
UI_HASUNIQUECDKEY,
UI_HASUNIQUECDKEY
// if !overlay, the background will be drawn, otherwise it will be
// overlayed over whatever the cgame has drawn.
// a GetClientState syscall will be made to get the current strings
UI_SET_VR_CLIENT_INFO
} uiExport_t;
#endif

View file

@ -46,12 +46,12 @@ void VR_InitCvars( void )
// VALUES PROVIDED BY SkillFur - Thank-you!
Cvar_Get ("vr_weapon_adjustment_1", "1,-4.0,7,-10,-20,-15,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_2", "0.8,-3.0,5.5,0,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_3", "0.7,-2.5,5.5,0,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_4", "0.75,-4.0,6.5,-4,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_5", "0.8,-3.8,6,7.5,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_3", "0.7,-3.0,5.5,0,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_4", "0.75,-5.4,6.5,-4,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_5", "0.8,-5.2,6,7.5,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_6", "0.8,-3.3,6,7,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_7", "0.8,-3.0,6,0,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_8", "0.8,-3.5,6,1.5,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_7", "0.8,-5.5,6,0,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_8", "0.8,-4.5,6,1.5,0,0,0", CVAR_ARCHIVE);
Cvar_Get ("vr_weapon_adjustment_9", "0.8,-5.5,6,0,0,0,0", CVAR_ARCHIVE);
}

View file

@ -192,7 +192,7 @@ static float length(float x, float y)
void IN_VRInit( void )
{
vr_righthanded = Cvar_Get ("vr_righthanded", "1", CVAR_ARCHIVE);
vr_snapturn = Cvar_Get ("vr_snapturn", "1", CVAR_ARCHIVE);
vr_snapturn = Cvar_Get ("vr_snapturn", "45", CVAR_ARCHIVE);
vr_extralatencymode = Cvar_Get ("vr_extralatencymode", "1", CVAR_ARCHIVE);
}
@ -273,20 +273,37 @@ static void IN_VRJoystick( qboolean isRightController, float joystickX, float jo
rotateAboutOrigin(-vr.hmdposition_delta[0] * factor * multiplier,
vr.hmdposition_delta[2] * factor * multiplier, - vr.hmdorientation[YAW], positional);
vec2_t joystick;
if ( !com_sv_running || !com_sv_running->integer )
{
//multiplayer server
rotateAboutOrigin(joystickX, joystickY, vr.hmdorientation[YAW], joystick);
} else
{
joystick[0] = joystickX;
joystick[1] = joystickY;
}
//sideways
Com_QueueEvent(in_vrEventTime, SE_JOYSTICK_AXIS, 0, joystickX * 127.0f + positional[0] * 127.0f, 0, NULL);
Com_QueueEvent(in_vrEventTime, SE_JOYSTICK_AXIS, 0, joystick[0] * 127.0f + positional[0] * 127.0f, 0, NULL);
//forward/back
Com_QueueEvent(in_vrEventTime, SE_JOYSTICK_AXIS, 1, joystickY * 127.0f + positional[1] * 127.0f, 0, NULL);
Com_QueueEvent(in_vrEventTime, SE_JOYSTICK_AXIS, 1, joystick[1] * 127.0f + positional[1] * 127.0f, 0, NULL);
}
else //right controller
{
//yaw
if (vr_snapturn->integer)
if (vr_snapturn->integer > 0)
{
int snap = 45;
if (vr_snapturn->integer > 1)
{
snap = vr_snapturn->integer;
}
if (!(controller->axisButtons & VR_TOUCH_AXIS_RIGHT) && joystickX > pressedThreshold) {
controller->axisButtons |= VR_TOUCH_AXIS_RIGHT;
CL_SnapTurn(45);
CL_SnapTurn(snap);
} else if ((controller->axisButtons & VR_TOUCH_AXIS_RIGHT) &&
joystickX < releasedThreshold) {
controller->axisButtons &= ~VR_TOUCH_AXIS_RIGHT;
@ -294,7 +311,7 @@ static void IN_VRJoystick( qboolean isRightController, float joystickX, float jo
if (!(controller->axisButtons & VR_TOUCH_AXIS_LEFT) && joystickX < -pressedThreshold) {
controller->axisButtons |= VR_TOUCH_AXIS_LEFT;
CL_SnapTurn(-45);
CL_SnapTurn(-snap);
} else if ((controller->axisButtons & VR_TOUCH_AXIS_LEFT) &&
joystickX > -releasedThreshold) {
controller->axisButtons &= ~VR_TOUCH_AXIS_LEFT;
@ -374,7 +391,7 @@ static void IN_VRButtonsChanged( qboolean isRightController, uint32_t buttons )
}
if ((buttons & ovrButton_X) && !(controller->buttons & ovrButton_X)) {
sendButtonActionSimple("fraglimit 1");
//sendButtonActionSimple("fraglimit 1");
Com_QueueEvent(in_vrEventTime, SE_KEY, K_PAD0_X, qtrue, 0, NULL);
} else if (!(buttons & ovrButton_X) && (controller->buttons & ovrButton_X)) {
Com_QueueEvent(in_vrEventTime, SE_KEY, K_PAD0_X, qfalse, 0, NULL);