Big Update!

- bHaptics Support!!
- In CTF you now carry the flag in your off-hand when you pick it up
- Hopefully aligned the railgun scope a little better
- Toggle for weapon autoswitch in the VR menu
- Improved realign logic to delay a few frames (which hopefully means fewer misalignment issues)
- Set Ceon's new master server in the autoexec.cfg
This commit is contained in:
Simon 2022-02-22 23:48:35 +00:00
parent ee5ddcb2e9
commit ddd73940df
22 changed files with 311 additions and 136 deletions

View file

@ -36,10 +36,14 @@ android {
jniLibs.srcDirs 'src/main/jniLibs'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
}

Binary file not shown.

View file

@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.drbeef.ioq3quest"
android:installLocation="preferExternal"
android:versionCode="21"
android:versionName="0.14.0">
android:versionCode="22"
android:versionName="0.15.0">
<uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" />
<uses-feature android:glEsVersion="0x00030001" />
<!-- <uses-feature android:name="oculus.software.overlay_keyboard" android:required="false"/>-->

View file

@ -12,9 +12,4 @@ set cg_bobpitch 0
set cg_bobroll 0
set cg_weaponbob 0
set sv_pure 0
seta server1 "13.38.149.128:27960"
seta server2 "13.38.149.128:27961"
seta server3 "13.38.149.128:27962"
seta server4 "54.161.107.61:27960"
seta server5 "54.161.107.61:27961"
seta server6 "54.161.107.61:27962"
set sv_master2 "13.36.227.32:27950"

View file

@ -46,20 +46,6 @@ extern "C"
return JNI_VERSION_1_4;
}
JNIEXPORT void JNICALL Java_com_drbeef_ioq3quest_MainActivity_nativeKeyDown(JNIEnv* env, jclass cls, jobject thisObject,
jint var1 , jint var2 )
{
char buffer[10];
Com_sprintf(buffer, 10, "%c", (char)var2);
Cbuf_AddText(buffer);
}
JNIEXPORT void JNICALL Java_com_drbeef_ioq3quest_MainActivity_nativeKeyUp(JNIEnv* env, jclass cls, jobject thisObject,
jint var1 , jint var2)
{
}
}
static void ioq3_logfn(const char* msg)

View file

@ -1,19 +1,17 @@
package com.drbeef.ioq3quest;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.RemoteException;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.drbeef.externalhapticsservice.HapticServiceClient;
import org.libsdl.app.SDLActivity;
import java.io.BufferedInputStream;
@ -38,8 +36,12 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback
private static final int WRITE_EXTERNAL_STORAGE_PERMISSION_ID = 2;
private static final String TAG = "ioquake3Quest";
private boolean hapticsEnabled = false;
String commandLineParams;
private HapticServiceClient externalHapticsServiceClient = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate called");
@ -167,6 +169,12 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback
} catch (Exception e) {
}
externalHapticsServiceClient = new HapticServiceClient(this, (state, desc) -> {
Log.v(TAG, "ExternalHapticsService is:" + desc);
});
externalHapticsServiceClient.bindService();
Log.d(TAG, "nativeCreate");
nativeCreate(this);
}
@ -214,43 +222,42 @@ public class MainActivity extends SDLActivity // implements KeyEvent.Callback
}
public static native void nativeCreate(MainActivity thisObject);
public static native void nativeKeyDown(MainActivity thisObject, int var1, int var2);
public static native void nativeKeyUp(MainActivity thisObject, int var1, int var2);
static {
System.loadLibrary("main");
}
public void showkeyboard() {
public void haptic_event(String event, int position, int flags, int intensity, float angle, float yHeight) {
//InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
//imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
/*
// Key events
@Override
public boolean onKeyDown(int var1, KeyEvent var2)
{
nativeKeyDown(this, var1, var2.getKeyCode());
return true;
if (externalHapticsServiceClient.hasService()) {
try {
if (!hapticsEnabled)
{
externalHapticsServiceClient.getHapticsService().hapticEnable();
hapticsEnabled = true;
return;
}
if (event.compareTo("frame_tick") == 0)
{
externalHapticsServiceClient.getHapticsService().hapticFrameTick();
}
//Use the Doom3Quest haptic patterns for now
String app = "Doom3Quest";
if (event.contains(":"))
{
String[] items = event.split(":");
app = items[0];
event = items[1];
}
externalHapticsServiceClient.getHapticsService().hapticEvent(app, event, position, flags, intensity, angle, yHeight);
}
catch (RemoteException r)
{
Log.v(TAG, r.toString());
}
}
}
@Override
public boolean onKeyLongPress(int var1, KeyEvent var2)
{
nativeKeyUp(this, var1, var2.getKeyCode());
return true;
}
@Override
public boolean onKeyUp(int var1, KeyEvent var2)
{
return true;
}
@Override
public boolean onKeyMultiple(int var1, int var2, KeyEvent var3)
{
return true;
}*/
}

View file

@ -2547,11 +2547,11 @@ static void CG_DrawWeapReticle( void )
int weap;
vec4_t color = {0, 0, 0, 1};
float indent = 0.2;
float indent = 0.16;
float X_WIDTH=640;
float Y_HEIGHT=480;
float x = (X_WIDTH * indent), y = (Y_HEIGHT * indent) + 3, w = (X_WIDTH * (1-(2*indent))) / 2.0f, h = (Y_HEIGHT * (1-(2*indent))) / 2;
float x = (X_WIDTH * indent), y = (Y_HEIGHT * indent), w = (X_WIDTH * (1-(2*indent))) / 2.0f, h = (Y_HEIGHT * (1-(2*indent))) / 2;
CG_AdjustFrom640( &x, &y, &w, &h );
@ -2572,10 +2572,10 @@ static void CG_DrawWeapReticle( void )
}
// hairs
CG_FillRect( 84, 242, 177, 2, color ); // left
CG_FillRect( 320, 245, 1, 58, color ); // center top
CG_FillRect( 319, 303, 2, 178, color ); // center bot
CG_FillRect( 380, 242, 177, 2, color ); // right
CG_FillRect( 84, 239, 177, 2, color ); // left
CG_FillRect( 320, 242, 1, 58, color ); // center top
CG_FillRect( 319, 300, 2, 178, color ); // center bot
CG_FillRect( 380, 239, 177, 2, color ); // right
}
}

View file

@ -24,7 +24,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// of event processing
#include "cg_local.h"
#include "../vr/vr_clientinfo.h"
extern vr_clientinfo_t* vr;
/*
==================

View file

@ -550,6 +550,13 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
}
ci = &cgs.clientinfo[ clientNum ];
if (event >= EV_USE_ITEM0 && event <= EV_USE_ITEM15)
{
if (clientNum == cg.predictedPlayerState.clientNum) {
trap_HapticEvent("pickup_shield", 0, 0, 100, 0, 0);
}
}
switch ( event ) {
//
// movement generated events
@ -598,6 +605,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
// smooth landing z changes
cg.landChange = -8;
cg.landTime = cg.time;
trap_HapticEvent("jump_landing", 0, 0, 20, 0, 0);
}
break;
case EV_FALL_MEDIUM:
@ -608,6 +616,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
// smooth landing z changes
cg.landChange = -16;
cg.landTime = cg.time;
trap_HapticEvent("jump_landing", 0, 0, 60, 0, 0);
}
break;
case EV_FALL_FAR:
@ -618,6 +627,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
// smooth landing z changes
cg.landChange = -24;
cg.landTime = cg.time;
trap_HapticEvent("jump_landing", 0, 0, 100, 0, 0);
}
break;
@ -676,11 +686,17 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
// boing sound at origin, jump sound on player
trap_S_StartSound ( cent->lerpOrigin, -1, CHAN_VOICE, cgs.media.jumpPadSound );
trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );
if ( clientNum == cg.predictedPlayerState.clientNum ) {
trap_HapticEvent("jump_start", 0, 0, 100, 0, 0);
}
break;
case EV_JUMP:
DEBUGNAME("EV_JUMP");
trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );
if ( clientNum == cg.predictedPlayerState.clientNum ) {
trap_HapticEvent("jump_start", 0, 0, 50, 0, 0);
}
break;
case EV_TAUNT:
DEBUGNAME("EV_TAUNT");
@ -746,6 +762,9 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
// will be played at prediction time
if ( item->giType == IT_POWERUP || item->giType == IT_TEAM) {
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.n_healthSound );
if ( clientNum == cg.predictedPlayerState.clientNum ) {
trap_HapticEvent("pickup_weapon", 0, 0, 100, 0, 0);
}
} else if (item->giType == IT_PERSISTANT_POWERUP) {
#ifdef MISSIONPACK
switch (item->giTag ) {
@ -763,8 +782,14 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
break;
}
#endif
if ( clientNum == cg.predictedPlayerState.clientNum ) {
trap_HapticEvent("pickup_weapon", 0, 0, 100, 0, 0);
}
} else {
trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) );
if ( clientNum == cg.predictedPlayerState.clientNum ) {
trap_HapticEvent("pickup_shield", 0, 0, 30, 0, 0);
}
}
// show icon and name on status bar
@ -811,6 +836,11 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
case EV_CHANGE_WEAPON:
DEBUGNAME("EV_CHANGE_WEAPON");
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.selectSound );
if ( clientNum == cg.predictedPlayerState.clientNum ) {
vr->realign = 4; // auto trigger weapon re-align in 4 frames
int position = vr->weapon_stabilised ? 4 : (vr->right_handed ? 1 : 2);
trap_HapticEvent("weapon_switch", 0, 0, 100, 0, 0);
}
break;
case EV_FIRE_WEAPON:
DEBUGNAME("EV_FIRE_WEAPON");
@ -891,7 +921,10 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
DEBUGNAME("EV_PLAYER_TELEPORT_IN");
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleInSound );
CG_SpawnEffect( position);
vr->realign_playspace = qtrue; // auto trigger weapon re-align
if (clientNum == cg.predictedPlayerState.clientNum) {
vr->realign = 4; // auto trigger weapon re-align in 4 frames
trap_HapticEvent("spark", 0, 0, 80, 0, 0);
}
break;
case EV_PLAYER_TELEPORT_OUT:
@ -1203,22 +1236,31 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
cg.powerupTime = cg.time;
}
trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.quadSound );
if ( clientNum == cg.predictedPlayerState.clientNum ) {
trap_HapticEvent("decontaminate", 0, 0, 100, 0, 0);
}
break;
case EV_POWERUP_BATTLESUIT:
DEBUGNAME("EV_POWERUP_BATTLESUIT");
if ( es->number == cg.snap->ps.clientNum ) {
if ( es->number == cg.predictedPlayerState.clientNum ) {
cg.powerupActive = PW_BATTLESUIT;
cg.powerupTime = cg.time;
}
trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.protectSound );
if ( clientNum == cg.snap->ps.clientNum ) {
trap_HapticEvent("decontaminate", 0, 0, 100, 0, 0);
}
break;
case EV_POWERUP_REGEN:
DEBUGNAME("EV_POWERUP_REGEN");
if ( es->number == cg.snap->ps.clientNum ) {
if ( es->number == cg.predictedPlayerState.clientNum ) {
cg.powerupActive = PW_REGEN;
cg.powerupTime = cg.time;
}
trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.regenSound );
if ( clientNum == cg.predictedPlayerState.clientNum ) {
trap_HapticEvent("decontaminate", 0, 0, 100, 0, 0);
}
break;
case EV_GIB_PLAYER:
@ -1230,6 +1272,11 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.gibSound );
}
CG_GibPlayer( cent->lerpOrigin );
if ( clientNum == cg.snap->ps.clientNum ) {
trap_HapticEvent("shield_break", 0, 0, 100, 0, 0);
}
break;
case EV_STOPLOOPINGSOUND:

View file

@ -1529,6 +1529,9 @@ void trap_FS_Write( const void *buffer, int len, fileHandle_t f );
void trap_FS_FCloseFile( fileHandle_t f );
int trap_FS_Seek( fileHandle_t f, long offset, int origin ); // fsOrigin_t
//Haptics
int trap_HapticEvent( char *description, int position, int channel, int intensity, float yaw, float height);
// add commands to the local console as if they were typed in
// for map changing, etc. The command is not executed immediately,
// but will be executed in order the next time console commands

View file

@ -22,6 +22,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
// cg_players.c -- handle the media and animation for player entities
#include "cg_local.h"
#include "../vr/vr_clientinfo.h"
extern vr_clientinfo_t* vr;
char *cg_customSoundNames[MAX_CUSTOM_SOUNDS] = {
"*death1.wav",
@ -1619,6 +1623,37 @@ static void CG_DustTrail( centity_t *cent ) {
#endif
void CG_CalculateVROffHandPosition( vec3_t origin, vec3_t angles )
{
float worldscale = trap_Cvar_VariableValue("vr_worldscale");
if (!cgs.localServer)
{
//Use absolute position for the faked 6DoF for multiplayer
vec3_t offset, offhandposition;
VectorSubtract(vr->offhandposition, vr->hmdorigin, offhandposition);
VectorCopy(offhandposition, offset);
offset[1] = vr->offhandoffset[1]; // up/down is index 1 in this case
CG_ConvertFromVR(offset, cg.refdef.vieworg, origin);
origin[2] -= PLAYER_HEIGHT;
origin[2] += vr->hmdposition[1] * worldscale;
}
else
{
//Local server - true 6DoF offset from HMD
CG_ConvertFromVR(vr->offhandoffset, cg.refdef.vieworg, origin);
origin[2] -= PLAYER_HEIGHT;
origin[2] += vr->hmdposition[1] * worldscale;
}
VectorCopy(vr->offhandangles, angles);
// if ( cgs.localServer )
{
angles[YAW] += cg.refdefViewAngles[YAW];
}
}
/*
===============
CG_TrailItem
@ -1629,16 +1664,29 @@ static void CG_TrailItem( centity_t *cent, qhandle_t hModel ) {
vec3_t angles;
vec3_t axis[3];
VectorCopy( cent->lerpAngles, angles );
angles[PITCH] = 0;
angles[ROLL] = 0;
AnglesToAxis( angles, axis );
memset(&ent, 0, sizeof(ent));
memset( &ent, 0, sizeof( ent ) );
VectorMA( cent->lerpOrigin, -16, axis[0], ent.origin );
ent.origin[2] += 16;
angles[YAW] += 90;
AnglesToAxis( angles, ent.axis );
if (cent->currentState.clientNum == vr->clientNum)
{
CG_CalculateVROffHandPosition(ent.origin, angles);
AnglesToAxis(angles, ent.axis);
vec3_t forward;
AngleVectors( angles, forward, NULL, NULL );
VectorMA( ent.origin, -16, forward, ent.origin );
} else {
VectorCopy(cent->lerpAngles, angles);
angles[PITCH] = 0;
angles[ROLL] = 0;
AnglesToAxis(angles, axis);
memset(&ent, 0, sizeof(ent));
VectorMA(cent->lerpOrigin, -16, axis[0], ent.origin);
ent.origin[2] += 16;
angles[YAW] += 90;
AnglesToAxis(angles, ent.axis);
}
ent.hModel = hModel;
trap_R_AddRefEntityToScene( &ent );

View file

@ -172,6 +172,13 @@ void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) {
cg.damageY = -1.0;
}
if (damage > 30)
{
trap_HapticEvent("shotgun", 0, 0, 100, yaw, 0);
} else {
trap_HapticEvent("bullet", 0, 0, 100, yaw, 0);
}
// don't let the screen flashes vary as much
if ( kick > 10 ) {
kick = 10;

View file

@ -165,6 +165,8 @@ typedef enum {
// 1.32
CG_FS_SEEK,
CG_HAPTICEVENT,
/*
CG_LOADCAMERA,
CG_STARTCAMERA,

View file

@ -446,3 +446,8 @@ qboolean trap_GetEntityToken( char *buffer, int bufferSize ) {
qboolean trap_R_inPVS( const vec3_t p1, const vec3_t p2 ) {
return syscall( CG_R_INPVS, p1, p2 );
}
int trap_HapticEvent( char *description, int position, int channel, int intensity, float yaw, float height) {
return syscall( CG_HAPTICEVENT, description, position, channel, intensity, PASSFLOAT(yaw), PASSFLOAT(height));
}

View file

@ -1795,31 +1795,6 @@ void CG_AddViewWeapon( playerState_t *ps ) {
// add everything onto the hand
CG_AddPlayerWeapon( &hand, ps, &cg.predictedPlayerEntity, ps->persistant[PERS_TEAM] );
//Weapon offset debugging
if (qfalse)
{
vec3_t _origin;
vec3_t endForward, endRight, endUp;
vec3_t _angles;
clientInfo_t ci;
CG_CalculateVRWeaponPosition( _origin, _angles, qfalse );
vec3_t forward, right, up;
AngleVectors(_angles, forward, right, up);
VectorMA(_origin, 60, forward, endForward);
VectorSet(ci.color1, 1, 0, 0); // Forward is red
CG_RailTrail2(&ci, _origin, endForward);
VectorMA(_origin, 30, right, endRight);
VectorSet(ci.color1, 0, 1, 0); // right is green
CG_RailTrail2(&ci, _origin, endRight);
VectorMA(_origin, 30, up, endUp);
VectorSet(ci.color1, 0, 0, 1); // up is blue
CG_RailTrail2(&ci, _origin, endUp);
}
}
/*
@ -2114,6 +2089,69 @@ void CG_FireWeapon( centity_t *cent ) {
if ( weap->ejectBrassFunc && cg_brassTime.integer > 0 ) {
weap->ejectBrassFunc( cent );
}
//Are we the player?
if (cent->currentState.number == cg.predictedPlayerState.clientNum)
{
int position = vr->weapon_stabilised ? 4 : (vr->right_handed ? 1 : 2);
static int haptic_skip = 0;
// This is to adjust the excessive fire rate of the plasma-gun/machine-gun, everything else fires slower (or has haptics that compensate)
// so this will just fire every other time for the affected weapons
++haptic_skip;
//Haptics
switch (ent->weapon) {
case WP_GAUNTLET:
trap_HapticEvent("chainsaw_fire", position, 0, 50, 0, 0);
break;
case WP_MACHINEGUN:
if (haptic_skip & 1) {
trap_HapticEvent("machinegun_fire", position, 0, 100, 0, 0);
}
break;
case WP_SHOTGUN:
trap_HapticEvent("shotgun_fire", position, 0, 100, 0, 0);
break;
case WP_GRENADE_LAUNCHER:
trap_HapticEvent("handgrenade_fire", position, 0, 80, 0, 0);
break;
case WP_ROCKET_LAUNCHER:
trap_HapticEvent("rocket_fire", position, 0, 100, 0, 0);
break;
case WP_LIGHTNING:
trap_HapticEvent("RTCWQuest:fire_tesla", position, 0, 100, 0, 0);
break;
case WP_RAILGUN:
trap_HapticEvent("RTCWQuest:fire_sniper", position, 0, 100, 0, 0);
break;
case WP_PLASMAGUN:
if (haptic_skip & 1) {
trap_HapticEvent("plasmagun_fire", position, 0, 100, 0, 0);
}
break;
case WP_BFG:
trap_HapticEvent("bfg_fire", position, 0, 100, 0, 0);
break;
case WP_GRAPPLING_HOOK:
trap_HapticEvent("chainsaw_fire", position, 0, 100, 0, 0);
break;
#ifdef MISSIONPACK
case WP_NAILGUN:
trap_HapticEvent("shotgun_fire", position, 0, 100, 0, 0);
break;
case WP_PROX_LAUNCHER:
trap_HapticEvent("handgrenade_fire", position, 0, 100, 0, 0);
break;
case WP_CHAINGUN:
if (haptic_skip & 1) {
trap_HapticEvent("chaingun_fire", position, 0, 100, 0, 0);
}
break;
#endif
}
}
}
@ -2331,6 +2369,11 @@ CG_MissileHitPlayer
void CG_MissileHitPlayer( int weapon, vec3_t origin, vec3_t dir, int entityNum ) {
CG_Bleed( origin, entityNum );
if ( entityNum == vr->clientNum )
{
trap_HapticEvent("fireball", 0, 0, 80, 0, 0);
}
// some weapons will make an explosion with the blood, while
// others will just make the blood
switch ( weapon ) {

View file

@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "client.h"
#include "../botlib/botlib.h"
#include "../vr/vr_base.h"
#include "../vr/vr_clientinfo.h"
#ifdef USE_MUMBLE
@ -693,6 +694,10 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
return re.GetEntityToken( VMA(1), args[2] );
case CG_R_INPVS:
return re.inPVS( VMA(1), VMA(2) );
case CG_HAPTICEVENT:
VR_HapticEvent( VMA(1), args[2], args[3], args[4], VMF(5), VMF(6) );
return 0;
default:
assert(0);

View file

@ -593,21 +593,21 @@ void CL_FinishMove( usercmd_t *cmd ) {
// can be determined without allowing cheating
cmd->serverTime = cl.serverTime;
vr.clientNum = cl.snap.ps.clientNum;
//If we are running with a remote non-vr server, then the best we can do is pass the angles from the weapon
//and adjust the move values accordingly, to "fake" a 3DoF weapon but keeping the movement correct
if ( !com_sv_running || !com_sv_running->integer )
{
vr.clientNum = -1;
vr.local_server = qfalse;
vec3_t angles;
VectorCopy(vr.weaponangles, angles);
if (vr.realign_playspace)
if (--vr.realign == 0)
{
VectorCopy(vr.hmdposition, vr.hmdorigin);
vr.realign_pitch -= (cl.snap.ps.viewangles[PITCH]-vr.weaponangles[PITCH]) ;
vr.realign_playspace = qfalse;
}
angles[PITCH] += vr.realign_pitch;
@ -626,7 +626,6 @@ void CL_FinishMove( usercmd_t *cmd ) {
else {
//Record client number - local server uses this to know we can use absolute angles
//rather than deltas
vr.clientNum = cl.snap.ps.clientNum;
vr.local_server = qtrue;
for (i = 0; i < 3; i++) {

View file

@ -41,23 +41,24 @@ VR OPTIONS MENU
#define ID_HUDDEPTH 127
#define ID_RIGHTHANDED 128
#define ID_SNAPTURN 129
#define ID_DIRECTIONMODE 130
#define ID_JUMPTRIGGER 131
#define ID_REFRESHRATE 132
#define ID_WEAPONPITCH 133
#define ID_HEIGHTADJUST 134
#define ID_TWOHANDED 135
#define ID_SCOPE 136
#define ID_DRAWHUD 137
#define ID_ROLLHIT 138
#define ID_GORE 139
#define ID_AUTOSWITCH 129
#define ID_SNAPTURN 130
#define ID_DIRECTIONMODE 131
#define ID_JUMPTRIGGER 132
#define ID_REFRESHRATE 133
#define ID_WEAPONPITCH 134
#define ID_HEIGHTADJUST 135
#define ID_TWOHANDED 136
#define ID_SCOPE 137
#define ID_DRAWHUD 138
#define ID_ROLLHIT 139
#define ID_GORE 140
#define ID_BACK 140
#define ID_BACK 141
#define NUM_HUDDEPTH 6
#define NUM_DIRECTIONMODE 2
#define NUM_REFRESHRATE 5
#define NUM_REFRESHRATE 4
#define NUM_GORE 4
@ -71,6 +72,7 @@ typedef struct {
menuradiobutton_s drawhud;
menulist_s huddepth;
menuradiobutton_s righthanded;
menuradiobutton_s autoswitch;
menulist_s snapturn;
menulist_s directionmode;
menuradiobutton_s jumptrigger;
@ -92,6 +94,7 @@ static void VR_SetMenuItems( void ) {
s_VR.drawhud.curvalue = trap_Cvar_VariableValue( "cg_drawStatus" ) != 0;
s_VR.huddepth.curvalue = (int)trap_Cvar_VariableValue( "vr_hudDepth" ) % NUM_HUDDEPTH;
s_VR.righthanded.curvalue = trap_Cvar_VariableValue( "vr_righthanded" ) != 0;
s_VR.autoswitch.curvalue = trap_Cvar_VariableValue( "cg_autoswitch" ) != 0;
s_VR.snapturn.curvalue = (int)trap_Cvar_VariableValue( "vr_snapturn" ) / 45;
s_VR.directionmode.curvalue = (int)trap_Cvar_VariableValue( "vr_directionMode" ) % NUM_DIRECTIONMODE;
s_VR.jumptrigger.curvalue = trap_Cvar_VariableValue( "vr_jumpTrigger" ) != 0;
@ -110,12 +113,9 @@ static void VR_SetMenuItems( void ) {
case 90:
s_VR.refreshrate.curvalue = 3;
break;
case 120:
s_VR.refreshrate.curvalue = 4;
break;
}
s_VR.weaponpitch.curvalue = trap_Cvar_VariableValue( "vr_weaponPitch" ) + 25;
s_VR.heightadjust.curvalue = trap_Cvar_VariableValue( "vr_heightAdjust" ) != 0;
s_VR.heightadjust.curvalue = trap_Cvar_VariableValue( "vr_heightAdjust" );
s_VR.twohanded.curvalue = trap_Cvar_VariableValue( "vr_twoHandedWeapons" ) != 0;
s_VR.scope.curvalue = trap_Cvar_VariableValue( "vr_weaponScope" ) != 0;
s_VR.rollhit.curvalue = trap_Cvar_VariableValue( "vr_rollWhenHit" ) != 0;
@ -145,6 +145,10 @@ static void VR_Event( void* ptr, int notification ) {
trap_Cvar_SetValue( "vr_righthanded", s_VR.righthanded.curvalue );
break;
case ID_AUTOSWITCH:
trap_Cvar_SetValue( "cg_autoswitch", s_VR.autoswitch.curvalue );
break;
case ID_SNAPTURN:
trap_Cvar_SetValue( "vr_snapturn", s_VR.snapturn.curvalue * 45 );
break;
@ -172,9 +176,6 @@ static void VR_Event( void* ptr, int notification ) {
case 3:
refresh = 90;
break;
case 4:
refresh = 120;
break;
}
trap_Cvar_SetValue("vr_refreshrate", refresh);
}
@ -272,7 +273,6 @@ static void VR_MenuInit( void ) {
"72 (Default)",
"80",
"90",
"120",
NULL
};
@ -344,6 +344,15 @@ static void VR_MenuInit( void ) {
s_VR.righthanded.generic.x = VR_X_POS;
s_VR.righthanded.generic.y = y;
y += BIGCHAR_HEIGHT;
s_VR.autoswitch.generic.type = MTYPE_RADIOBUTTON;
s_VR.autoswitch.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
s_VR.autoswitch.generic.name = "Autoswitch Weapons:";
s_VR.autoswitch.generic.id = ID_AUTOSWITCH;
s_VR.autoswitch.generic.callback = VR_Event;
s_VR.autoswitch.generic.x = VR_X_POS;
s_VR.autoswitch.generic.y = y;
y += BIGCHAR_HEIGHT;
s_VR.snapturn.generic.type = MTYPE_SPINCONTROL;
s_VR.snapturn.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
@ -464,6 +473,7 @@ static void VR_MenuInit( void ) {
Menu_AddItem( &s_VR.menu, &s_VR.huddepth );
Menu_AddItem( &s_VR.menu, &s_VR.righthanded );
Menu_AddItem( &s_VR.menu, &s_VR.autoswitch );
Menu_AddItem( &s_VR.menu, &s_VR.snapturn );
Menu_AddItem( &s_VR.menu, &s_VR.directionmode );
Menu_AddItem( &s_VR.menu, &s_VR.jumptrigger );

View file

@ -273,7 +273,7 @@ RB_TestFlare
==================
*/
void RB_TestFlare( flare_t *f ) {
float depth;
float depth = 0;
qboolean visible;
float fade;
float screenZ;
@ -293,7 +293,7 @@ void RB_TestFlare( flare_t *f ) {
}
// read back the z buffer contents
qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
//qglReadPixels( f->windowX, f->windowY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
// if we're doing multisample rendering, switch to the old FBO
if (tr.msaaResolveFbo)

View file

@ -16,6 +16,8 @@ bool VR_useScreenLayer( void );
float radians(float deg);
void VR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight );
#endif
#endif

View file

@ -13,7 +13,7 @@ typedef struct {
qboolean virtual_screen;
qboolean local_server; // used in bg_pmove.c
qboolean realign_playspace; // used to realign the weapon in a multiplayer game
int realign; // used to realign the weapon/playspace in a multiplayer game
int realign_pitch; // used to realign the weapon pitch in a multiplayer game
int clientNum;

View file

@ -73,6 +73,9 @@ extern cvar_t *vr_refreshrate;
extern cvar_t *vr_weaponScope;
extern cvar_t *vr_jumpTrigger;
jclass callbackClass;
jmethodID android_haptic_event;
void rotateAboutOrigin(float x, float y, float rotation, vec2_t out)
{
@ -199,6 +202,10 @@ static float length(float x, float y)
void IN_VRInit( void )
{
memset(&vr, 0, sizeof(vr));
engine_t *engine = VR_GetEngine();
callbackClass = (*engine->java.Env)->GetObjectClass(engine->java.Env, engine->java.ActivityObject);
android_haptic_event = (*engine->java.Env)->GetMethodID(engine->java.Env, callbackClass, "haptic_event","(Ljava/lang/String;IIIFF)V");
}
static void IN_VRController( qboolean isRightController, ovrTracking remoteTracking )
@ -408,11 +415,11 @@ static void IN_VRTriggers( qboolean isRightController, float index ) {
}
}
void jni_showkeyboard( void )
void VR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight )
{
jclass callbackClass = (*VR_GetEngine()->java.Env)->GetObjectClass(VR_GetEngine()->java.Env, VR_GetEngine()->java.ActivityObject);
jmethodID android_showkeyboard = (*VR_GetEngine()->java.Env)->GetMethodID(VR_GetEngine()->java.Env, callbackClass, "showkeyboard","()V");
return (*(VR_GetEngine()->java.Env))->CallVoidMethod(VR_GetEngine()->java.Env, VR_GetEngine()->java.ActivityObject, android_showkeyboard);
engine_t* engine = VR_GetEngine();
jstring StringArg1 = (*(engine->java.Env))->NewStringUTF(engine->java.Env, event);
(*(engine->java.Env))->CallVoidMethod(engine->java.Env, engine->java.ActivityObject, android_haptic_event, StringArg1, position, flags, intensity, angle, yHeight);
}
@ -496,7 +503,7 @@ static void IN_VRButtonsChanged( qboolean isRightController, uint32_t buttons )
if ((buttons & ovrButton_Y) && !(controller->buttons & ovrButton_Y)) {
//Actually want this to reset the player location
//jni_showkeyboard();
vr.realign_playspace = qtrue;
vr.realign = 4;
} else if (!(buttons & ovrButton_Y) && (controller->buttons & ovrButton_Y)) {
}
@ -533,7 +540,10 @@ void IN_VRInputFrame( void )
vr.virtual_screen = VR_useScreenLayer();
{
//trigger frame tick for haptics
VR_HapticEvent("frame_tick", 0, 0, 0, 0, 0);
{
// We extract Yaw, Pitch, Roll instead of directly using the orientation
// to allow "additional" yaw manipulation with mouse/controller.
const ovrQuatf quatHmd = VR_GetEngine()->tracking.HeadPose.Pose.Orientation;