mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-10 14:52:00 +00:00
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:
parent
ee5ddcb2e9
commit
ddd73940df
22 changed files with 311 additions and 136 deletions
|
@ -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'
|
||||
}
|
||||
|
|
BIN
android/app/libs/haptic_service.aar
Normal file
BIN
android/app/libs/haptic_service.aar
Normal file
Binary file not shown.
|
@ -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"/>-->
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*
|
||||
==================
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -165,6 +165,8 @@ typedef enum {
|
|||
// 1.32
|
||||
CG_FS_SEEK,
|
||||
|
||||
CG_HAPTICEVENT,
|
||||
|
||||
/*
|
||||
CG_LOADCAMERA,
|
||||
CG_STARTCAMERA,
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue