Merge pull request #12 from DrBeef/bhaptics

Bhaptics / Cybershoes
This commit is contained in:
Simon 2021-07-20 19:51:25 +01:00 committed by GitHub
commit a805cefed8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 748 additions and 86 deletions

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.drbeef.rtcwquest"
android:versionCode="47"
android:versionName="1.1.9" android:installLocation="auto" >
android:versionCode="48"
android:versionName="1.2.0" android:installLocation="auto" >
<!-- Tell the system this app requires OpenGL ES 3.1. -->
<uses-feature android:glEsVersion="0x00030001" android:required="true"/>
@ -10,12 +10,13 @@
<uses-feature android:name="android.hardware.vr.headtracking" android:version="1"
android:required="true" />
<!-- Network access needed for OVRMonitor -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Volume Control -->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application android:allowBackup="false" android:icon="@drawable/ic_rtcwquest" android:label="@string/rtcwquest">
<meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
<meta-data android:name="com.oculus.supportedDevices" android:value="quest|quest2"/>

View file

@ -23,7 +23,7 @@ android {
abiFilters 'armeabi-v7a'
}
}
minSdkVersion 24
minSdkVersion 26
targetSdkVersion 26
}
@ -40,13 +40,14 @@ android {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
compileSdkVersion = 24
compileSdkVersion = 26
buildToolsVersion = '29.0.1'
}
dependencies {
implementation "com.android.support:support-compat:24.2.0"
implementation "com.android.support:support-core-utils:24.2.0"
implementation "com.android.support:support-compat:26.1.0"
implementation "com.android.support:support-core-utils:26.1.0"
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}
repositories {

View file

@ -908,6 +908,155 @@ void RTCWVR_Vibrate( int duration, int channel, float intensity )
vibration_channel_intensity[channel] = intensity;
}
void RTCWVR_Haptic( int duration, int channel, float intensity, char *description, float yaw, float height )
{
if(strstr(description,"camera_shake") == NULL && strstr(description,"ignore") == NULL && strstr(description,"dead_") == NULL)
Com_Printf("GBRTCW: Vibrate Description: %s (Yaw: %f Pitch: %f)", description, yaw, height);
if(strcmp(description,"player_dead") == 0) {
RTCWVR_HapticEvent("player_dead", 0, 0, 100.0f * intensity, yaw, height);
}
else if(strcmp(description,"door_kick") == 0) {
RTCWVR_HapticEvent("kick_door", 0, 0, 100.0f * intensity, yaw, height);
}
else if(strcmp(description,"door_open") == 0) {
RTCWVR_HapticEvent("open_door", 0, 0, 100.0f * intensity, yaw, height);
}
else if(strcmp(description,"alarm_on") == 0) {
RTCWVR_HapticEvent("heartbeat", 0, 0, 100.0f * intensity, yaw, height);
}
else if(strcmp(description,"end_alarm") == 0) {
RTCWVR_HapticStopEvent("heartbeat");
}
else if(strcmp(description,"switch_weapon") == 0 || strcmp(description,"pickup_item") == 0) {
RTCWVR_HapticEvent(description, channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"give_armor") == 0 || strcmp(description,"give_food") == 0 ||
strcmp(description,"give_drink") == 0 || strcmp(description,"give_health") == 0 || strcmp(description,"pickup_treasure") == 0) {
RTCWVR_HapticEvent(description, 0, 0, 100.0f * intensity, yaw, height);
}
else if(strstr(description,"damage_") != NULL) {
RTCWVR_HapticEvent(description, 0, 0, 100.0f * intensity, yaw, height);
}
else if(strstr(description,"stop_firing_") != NULL) {
/*
if(strcmp(description,"stop_firing_9") == 0 || strcmp(description,"stop_firing_flames") == 0) {
RTCWVR_HapticStopEvent("fire_flamethrower");
}*/
}
else if(strstr(description,"fire_") != NULL) {
if(strcmp(description,"fire_11") == 0 || strcmp(description,"fire_2") == 0) {
RTCWVR_HapticEvent("fire_pistol", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_3") == 0) {
RTCWVR_HapticEvent("fire_mp40", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_4") == 0) {
RTCWVR_HapticEvent("fire_mauser", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_5") == 0 || strcmp(description,"fire_17") == 0) {
RTCWVR_HapticEvent("fire_fg42", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_6") == 0) {
RTCWVR_HapticEvent("fire_grenadelauncher", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_7") == 0 || strcmp(description,"fire_rocket") == 0) {
RTCWVR_HapticEvent("fire_panzerfaust", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_8") == 0) {
RTCWVR_HapticEvent("fire_venom", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_9") == 0 || strcmp(description,"fire_flames") == 0) {
RTCWVR_HapticEvent("fire_flamethrower", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_10") == 0 || strcmp(description,"fire_tesla") == 0) {
RTCWVR_HapticEvent("fire_tesla", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_12") == 0) {
RTCWVR_HapticEvent("fire_thompson", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_13") == 0) {
RTCWVR_HapticEvent("fire_garand", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_14") == 0) {
RTCWVR_HapticEvent("fire_grenade", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_15") == 0) {
RTCWVR_HapticEvent("fire_sniper", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_16") == 0) {
RTCWVR_HapticEvent("fire_snooperscope", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_18") == 0) {
RTCWVR_HapticEvent("fire_sten", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_19") == 0) {
RTCWVR_HapticEvent("fire_silencer", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"fire_20") == 0) {
//Plays on 0 position (Vest) (not left or right)
RTCWVR_HapticEvent("fire_akimbo", 0, 0, 100.0f * intensity, 0, 0);
}
}
else if(strcmp(description,"knife_hit") == 0) {
RTCWVR_HapticEvent("knife_hit", channel == 1 ? 2 : 1, 0, 100.0f * intensity, 0, 0);
}
else if(strcmp(description,"camera_shake_left") == 0) {
RTCWVR_HapticEvent("rumble_front", 0, 0, 100.0f * intensity, yaw, height);
}
else if(strcmp(description,"camera_shake_right") == 0) {
RTCWVR_HapticEvent("rumble_back", 0, 0, 100.0f * intensity, yaw, height);
}
else {
if(strstr(description,"ignore") == NULL &&
strstr(description,"dead") == NULL)
Com_Printf("Missing Haptic: %s", description);
}
}
void jni_haptic_event(const char* event, int position, int flags, int intensity, float angle, float yHeight);
void jni_haptic_updateevent(const char* event, int intensity, float angle);
void jni_haptic_stopevent(const char* event);
void jni_haptic_endframe();
void jni_haptic_enable();
void jni_haptic_disable();
void RTCWVR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight )
{
//Com_Printf( "GBRTCW: Vibrate Event Fired: %s", event );
jni_haptic_event(event, position, flags, intensity, angle, yHeight);
}
void RTCWVR_HapticUpdateEvent(const char* event, int intensity, float angle )
{
jni_haptic_updateevent(event, intensity, angle);
}
void RTCWVR_HapticEndFrame()
{
jni_haptic_endframe();
}
void RTCWVR_HapticStopEvent(const char* event)
{
jni_haptic_stopevent(event);
}
void RTCWVR_HapticEnable()
{
static bool firstTime = true;
if (firstTime) {
jni_haptic_enable();
firstTime = false;
jni_haptic_event("fire_pistol", 0, 0, 100, 0, 0);
}
}
void RTCWVR_HapticDisable()
{
jni_haptic_disable();
}
void RTCWVR_GetMove(float *forward, float *side, float *pos_forward, float *pos_side, float *up,
float *yaw, float *pitch, float *roll)
{
@ -1503,7 +1652,7 @@ void * AppThreadFunction(void * parm ) {
// This app will handle android gamepad events itself.
vrapi_SetPropertyInt(&gAppState.Java, VRAPI_EAT_NATIVE_GAMEPAD_EVENTS, 0);
//Set device defaults
//Set device defaults
if (vrapi_GetSystemPropertyInt(&java, VRAPI_SYS_PROP_DEVICE_TYPE) == VRAPI_DEVICE_TYPE_OCULUSQUEST)
{
if (SS_MULTIPLIER == 0.0f)
@ -1515,12 +1664,12 @@ void * AppThreadFunction(void * parm ) {
{
if (SS_MULTIPLIER == 0.0f)
{
//Lower to allow 90hz to work nicely
SS_MULTIPLIER = 1.0f;
//GB Override as refresh is now 72 by default as we decided a higher res is better as 90hz has stutters
SS_MULTIPLIER = 1.35f;
}
else if (SS_MULTIPLIER > 1.2F)
else if (SS_MULTIPLIER > 1.5f)
{
SS_MULTIPLIER = 1.2f;
SS_MULTIPLIER = 1.5f;
}
} else {
//Don't know what headset this is!? abort
@ -1572,7 +1721,7 @@ void * AppThreadFunction(void * parm ) {
vrapi_GetSystemPropertyFloatArray(&java, VRAPI_SYS_PROP_SUPPORTED_DISPLAY_REFRESH_RATES,
&refreshRatesArray[0], numberOfRefreshRates);
for (int i = 0; i < numberOfRefreshRates; i++) {
ALOGV("Supported refresh rate : %s Hz", refreshRatesArray[i]);
ALOGV("Supported refresh rate : %d Hz", refreshRatesArray[i]);
if (maximumSupportRefresh < refreshRatesArray[i]) {
maximumSupportRefresh = refreshRatesArray[i];
}
@ -1585,7 +1734,7 @@ void * AppThreadFunction(void * parm ) {
if (REFRESH == 0 || REFRESH > maximumSupportRefresh)
{
REFRESH = maximumSupportRefresh;
REFRESH = 72.0;
}
//-----------------------------------------------------------------------------------------------------------
@ -1716,12 +1865,14 @@ void RTCWVR_getTrackedRemotesOrientation() {//Get info for tracked remotes
switch (vr_control_scheme->integer)
{
case RIGHT_HANDED_DEFAULT:
HandleInput_Default(&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, &rightRemoteTracking_new,
HandleInput_Default(&footTrackedRemoteState_new, &footTrackedRemoteState_old,
&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, &rightRemoteTracking_new,
&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, &leftRemoteTracking_new,
ovrButton_A, ovrButton_B, ovrButton_X, ovrButton_Y);
break;
case LEFT_HANDED_DEFAULT:
HandleInput_Default(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, &leftRemoteTracking_new,
HandleInput_Default(&footTrackedRemoteState_new, &footTrackedRemoteState_old,
&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, &leftRemoteTracking_new,
&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, &rightRemoteTracking_new,
ovrButton_X, ovrButton_Y, ovrButton_A, ovrButton_B);
break;
@ -1809,6 +1960,7 @@ void RTCWVR_submitFrame()
RTCWVR_incrementFrameIndex();
RTCWVR_HapticEndFrame();
}
static void ovrAppThread_Create( ovrAppThread * appThread, JNIEnv * env, jobject activityObject, jclass activityClass )
@ -1845,8 +1997,14 @@ Activity lifecycle
jmethodID android_shutdown;
jmethodID android_haptic_event;
jmethodID android_haptic_updateevent;
jmethodID android_haptic_stopevent;
jmethodID android_haptic_endframe;
jmethodID android_haptic_enable;
jmethodID android_haptic_disable;
static JavaVM *jVM;
static jobject shutdownCallbackObj=0;
static jobject jniCallbackObj=0;
void jni_shutdown()
{
@ -1857,7 +2015,88 @@ void jni_shutdown()
{
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
}
return (*env)->CallVoidMethod(env, shutdownCallbackObj, android_shutdown);
return (*env)->CallVoidMethod(env, jniCallbackObj, android_shutdown);
}
void jni_haptic_event(const char* event, int position, int flags, int intensity, float angle, float yHeight)
{
JNIEnv *env;
jobject tmp;
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
{
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
}
jstring StringArg1 = (*env)->NewStringUTF(env, event);
return (*env)->CallVoidMethod(env, jniCallbackObj, android_haptic_event, StringArg1, position, flags, intensity, angle, yHeight);
}
void jni_haptic_updateevent(const char* event, int intensity, float angle)
{
JNIEnv *env;
jobject tmp;
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
{
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
}
jstring StringArg1 = (*env)->NewStringUTF(env, event);
return (*env)->CallVoidMethod(env, jniCallbackObj, android_haptic_updateevent, StringArg1, intensity, angle);
}
void jni_haptic_stopevent(const char* event)
{
ALOGV("Calling: jni_haptic_stopevent");
JNIEnv *env;
jobject tmp;
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
{
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
}
jstring StringArg1 = (*env)->NewStringUTF(env, event);
return (*env)->CallVoidMethod(env, jniCallbackObj, android_haptic_stopevent, StringArg1);
}
void jni_haptic_endframe()
{
JNIEnv *env;
jobject tmp;
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
{
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
}
return (*env)->CallVoidMethod(env, jniCallbackObj, android_haptic_endframe);
}
void jni_haptic_enable()
{
ALOGV("Calling: jni_haptic_enable");
JNIEnv *env;
jobject tmp;
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
{
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
}
return (*env)->CallVoidMethod(env, jniCallbackObj, android_haptic_enable);
}
void jni_haptic_disable()
{
ALOGV("Calling: jni_haptic_disable");
JNIEnv *env;
jobject tmp;
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
{
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
}
return (*env)->CallVoidMethod(env, jniCallbackObj, android_haptic_disable);
}
int JNI_OnLoad(JavaVM* vm, void* reserved)
@ -1953,10 +2192,16 @@ JNIEXPORT void JNICALL Java_com_drbeef_rtcwquest_GLES3JNILib_onStart( JNIEnv * e
ALOGV( " GLES3JNILib::onStart()" );
shutdownCallbackObj = (jobject)(*env)->NewGlobalRef(env, obj1);
jclass callbackClass = (*env)->GetObjectClass(env, shutdownCallbackObj);
jniCallbackObj = (jobject)(*env)->NewGlobalRef(env, obj1);
jclass callbackClass = (*env)->GetObjectClass(env, jniCallbackObj);
android_shutdown = (*env)->GetMethodID(env,callbackClass,"shutdown","()V");
android_haptic_event = (*env)->GetMethodID(env, callbackClass, "haptic_event", "(Ljava/lang/String;IIIFF)V");
android_haptic_updateevent = (*env)->GetMethodID(env, callbackClass, "haptic_updateevent", "(Ljava/lang/String;IF)V");
android_haptic_stopevent = (*env)->GetMethodID(env, callbackClass, "haptic_stopevent", "(Ljava/lang/String;)V");
android_haptic_endframe = (*env)->GetMethodID(env, callbackClass, "haptic_endframe", "()V");
android_haptic_enable = (*env)->GetMethodID(env, callbackClass, "haptic_enable", "()V");
android_haptic_disable = (*env)->GetMethodID(env, callbackClass, "haptic_disable", "()V");
ovrAppThread * appThread = (ovrAppThread *)((size_t)handle);
ovrMessage message;

View file

@ -60,6 +60,13 @@ int GetRefresh();
qboolean RTCWVR_useScreenLayer();
void RTCWVR_GetScreenRes(int *width, int *height);
void RTCWVR_Vibrate(int duration, int channel, float intensity );
void RTCWVR_Haptic(int duration, int channel, float intensity, char *description, float yaw, float height);
void RTCWVR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight );
void RTCWVR_HapticUpdateEvent(const char* event, int intensity, float angle );
void RTCWVR_HapticEndFrame();
void RTCWVR_HapticStopEvent(const char* event);
void RTCWVR_HapticEnable();
void RTCWVR_HapticDisable();
qboolean RTCWVR_processMessageQueue();
void RTCWVR_FrameSetup();
void RTCWVR_setUseScreenLayer(qboolean use);

View file

@ -154,7 +154,13 @@ ovrLayerCylinder2 BuildCylinderLayer( ovrRenderer * cylinderRenderer,
const float density = 4500.0f;
const float rotateYaw = 0.0f;
const float radius = 4.0f;
const float distance = vr_screen_dist ? -vr_screen_dist->value : -3.5f;
//GB Hacky Override
float screen_offset = 0;
if(textureWidth > 1900)
{
screen_offset = -2.625f;
}
const float distance = vr_screen_dist ? -vr_screen_dist->value + screen_offset : -3.5f + screen_offset;
const ovrVector3f translation = { 0.0f, playerHeight/2, distance };

View file

@ -21,6 +21,9 @@ ovrInputStateTrackedRemote rightTrackedRemoteState_old;
ovrInputStateTrackedRemote rightTrackedRemoteState_new;
ovrTracking rightRemoteTracking_new;
ovrInputStateGamepad footTrackedRemoteState_old;
ovrInputStateGamepad footTrackedRemoteState_new;
ovrDeviceID controllerIDs[2];
float remote_movementSideways;
@ -35,7 +38,8 @@ void sendButtonActionSimple(const char* action);
void acquireTrackedRemotesData(const ovrMobile *Ovr, double displayTime);
void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking,
void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateGamepad *pFootTrackingOld,
ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking,
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTracking* pOffTracking,
int domButton1, int domButton2, int offButton1, int offButton2 );

View file

@ -94,7 +94,22 @@ void acquireTrackedRemotesData(const ovrMobile *Ovr, double displayTime) {//The
break;
}
if (cap.Type == ovrControllerType_TrackedRemote) {
if (cap.Type == ovrControllerType_Gamepad) {
ovrInputGamepadCapabilities remoteCaps;
remoteCaps.Header = cap;
if (vrapi_GetInputDeviceCapabilities(Ovr, &remoteCaps.Header) >= 0) {
// remote is connected
ovrInputStateGamepad remoteState;
remoteState.Header.ControllerType = ovrControllerType_Gamepad;
if ( vrapi_GetCurrentInputState( Ovr, cap.DeviceID, &remoteState.Header ) >= 0 )
{
// act on device state returned in remoteState
footTrackedRemoteState_new = remoteState;
}
}
}
else if (cap.Type == ovrControllerType_TrackedRemote) {
ovrTracking remoteTracking;
ovrInputStateTrackedRemote trackedRemoteState;
trackedRemoteState.Header.ControllerType = ovrControllerType_TrackedRemote;

View file

@ -25,7 +25,10 @@ Authors : Simon Brown
void SV_Trace( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask, int capsule );
void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking,
void RTCWVR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight );
void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateGamepad *pFootTrackingOld,
ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking,
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTracking* pOffTracking,
int domButton1, int domButton2, int offButton1, int offButton2 )
@ -442,6 +445,8 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
}
//We need to record if we have started firing primary so that releasing trigger will stop firing, if user has pushed grip
//in meantime, then it wouldn't stop the gun firing and it would get stuck
static qboolean firing = false;
@ -547,8 +552,8 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
//Apply a filter and quadratic scaler so small movements are easier to make
float dist = length(pSecondaryJoystick->x, pSecondaryJoystick->y);
float nlf = nonLinearFilter(dist);
float x = nlf * pSecondaryJoystick->x;
float y = nlf * pSecondaryJoystick->y;
float x = (nlf * pSecondaryJoystick->x) + pFootTrackingNew->LeftJoystick.x;
float y = (nlf * pSecondaryJoystick->y) - pFootTrackingNew->LeftJoystick.y;
vr.player_moving = (fabs(x) + fabs(y)) > 0.05f;
@ -614,6 +619,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
handleTrackedControllerButton(pOffTrackedRemoteNew,
pOffTrackedRemoteOld,
ovrButton_Trigger, K_SHIFT);
} else {
if (pOffTrackedRemoteNew->Buttons & ovrButton_Trigger)
{

View file

@ -3575,8 +3575,12 @@ void CG_ApplyShakeCamera() {
if (VectorLength(cg.cameraShakeAngles) > 0.1f)
{
trap_Vibrate(10, 0, Com_Clamp(0.0f, 1.0f, fabs(cg.cameraShakeAngles[0])));
trap_Vibrate(10, 1, Com_Clamp(0.0f, 1.0f, fabs(cg.cameraShakeAngles[1])));
// up/down = cg.cameraShakeAngles[0]
// left/right = cg.cameraShakeAngles[1];
// roll cg.cameraShakeAngles[2]
trap_Vibrate(10, 0, Com_Clamp(0.0f, 1.0f, fabs(cg.cameraShakeAngles[0])),"camera_shake_left",270,fabs(cg.cameraShakeAngles[0]));
trap_Vibrate(10, 0, Com_Clamp(0.0f, 1.0f, fabs(cg.cameraShakeAngles[1])),"camera_shake_right",90,fabs(cg.cameraShakeAngles[0]));
}
}

View file

@ -1706,6 +1706,8 @@ void CG_RumbleEfx( float pitch, float yaw ) {
VectorCopy( recoil, cg.kickAVel );
// set the recoil
cg.recoilPitch -= pitchRecoilAdd;
}

View file

@ -32,9 +32,10 @@ If you have questions concerning this license or the applicable additional terms
#include "cg_local.h"
#include "../ui/ui_shared.h" // for Menus_CloseAll()
#include "../../../RTCWVR/VrClientInfo.h"
extern int hWeaponSnd;
extern vr_client_info_t *cgVR;
extern void CG_Tracer( vec3_t source, vec3_t dest, int sparks );
//==========================================================================
@ -1979,17 +1980,17 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
// client will get this message if reloading while using an alternate weapon
// client should voluntarily switch back to primary at that point
switch ( es->weapon ) {
case WP_SNOOPERSCOPE:
newweap = WP_GARAND;
break;
case WP_SNIPERRIFLE:
newweap = WP_MAUSER;
break;
case WP_FG42SCOPE:
newweap = WP_FG42;
break;
default:
break;
case WP_SNOOPERSCOPE:
newweap = WP_GARAND;
break;
case WP_SNIPERRIFLE:
newweap = WP_MAUSER;
break;
case WP_FG42SCOPE:
newweap = WP_FG42;
break;
default:
break;
}
// TTimo
@ -2239,12 +2240,14 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
ByteToDir( es->eventParm, dir );
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, qtrue, es->otherEntityNum2 );
trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.fkickwall );
trap_Vibrate(1, 1, 0.8, "door_kick", 0.0, -0.5);
break;
case EV_WOLFKICK_HIT_FLESH:
DEBUGNAME( "EV_WOLFKICK_HIT_FLESH" );
CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm, qtrue, es->otherEntityNum2 );
trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.fkickflesh );
trap_Vibrate(1, 1, 0.7, "door_kick", 0.0, -0.5);
break;
case EV_WOLFKICK_MISS:

View file

@ -2458,7 +2458,9 @@ int trap_Key_GetCatcher( void );
void trap_Key_SetCatcher( int catcher );
int trap_Key_GetKey( const char *binding );
int trap_Vibrate(int duration, int channel, float intensity );
int trap_Haptic( int duration, int channel, float intensity, char *description, float yaw, float height);
int trap_Vibrate( int duration, int channel, float intensity, char *description, float yaw, float height);
int trap_EnableHaptics();
// RF
void trap_SendMoveSpeedsToGame( int entnum, char *movespeeds );

View file

@ -2454,6 +2454,9 @@ void CG_Init( int serverMessageNum, int serverCommandSequence ) {
}
// jpw
// -NERVE - SMF
//GB - Turn on haptics here - because reasons
trap_EnableHaptics();
}
/*

View file

@ -221,6 +221,13 @@ void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) {
vd->damageDuration = kick * 50 * ( 1 + 2 * ( !vd->damageX && !vd->damageY ) );
cg.damageTime = cg.snap->serverTime;
cg.damageIndex = slot;
//GB - Add a haptic event
//Ensure a decent level of haptic feedback for any damage
//float hapticLevel = 80 + min(damage * 4, 120.0);
//Indicate head damage if appropriate
//RTCWVR_HapticEvent("damage", 0, 0, hapticLevel, yaw, pitch);
}

View file

@ -219,7 +219,9 @@ typedef enum {
CG_GETMODELINFO,
CG_HAPTIC
CG_HAPTIC,
CG_HAPTICENABLE,
CG_HAPTICTRIGGER
} cgameImport_t;

View file

@ -549,6 +549,14 @@ qboolean trap_GetModelInfo( int clientNum, char *modelName, animModelInfo_t **mo
return syscall( CG_GETMODELINFO, clientNum, modelName, modelInfo );
}
int trap_Vibrate( int duration, int channel, float intensity ) {
return syscall( CG_HAPTIC, duration, channel, PASSFLOAT(intensity) );
int trap_Vibrate( int duration, int channel, float intensity, char *description, float yaw, float height) {
return syscall( CG_HAPTIC, duration, channel, PASSFLOAT(intensity), description, PASSFLOAT(yaw), PASSFLOAT(height));
}
int trap_Haptic( int duration, int channel, float intensity, char *description, float yaw, float height) {
return syscall( CG_HAPTICTRIGGER, duration, channel, PASSFLOAT(intensity), description, PASSFLOAT(yaw), PASSFLOAT(height));
}
int trap_EnableHaptics() {
return syscall( CG_HAPTICENABLE );
}

View file

@ -1666,8 +1666,8 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
//Don't allow long running haptics to continue once dead
if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) {
trap_Vibrate(0, 0, 0.0);
trap_Vibrate(0, 1, 0.0);
trap_Vibrate(0, 0, 0.0, "dead_left", 0.0, 0.0);
trap_Vibrate(0, 1, 0.0, "dead_right", 0.0, 0.0);
}
DEBUGTIME

View file

@ -2229,10 +2229,10 @@ static void CG_FlamethrowerFlame( centity_t *cent, vec3_t origin ) {
CG_FireFlameChunks(cent, origin, angles, 1.0, qtrue, 1);
trap_Vibrate(-1, cgVR->right_handed ? 1 : 0, 0.6);
trap_Vibrate(-1, cgVR->right_handed ? 1 : 0, 0.6, "fire_flames", 0.0, 0.0);
if (cgVR->weapon_stabilised)
{
trap_Vibrate(-1, cgVR->right_handed ? 0 : 1, 0.5);
trap_Vibrate(-1, cgVR->right_handed ? 0 : 1, 0.5, "fire_flames", 0.0, 0.0);
}
}
@ -2776,10 +2776,10 @@ void CG_PlayerTeslaCoilFire( centity_t *cent, vec3_t flashorigin ) {
trap_R_AddLightToScene( tr.endpos, 256 + 600 * tr.fraction, 0.2, 0.6, 1, 0 );
}
trap_Vibrate(-1, cgVR->right_handed ? 1 : 0, 0.8);
trap_Vibrate(-1, cgVR->right_handed ? 1 : 0, 0.8, "fire_tesla", 0.0, 0.0);
if (cgVR->weapon_stabilised)
{
trap_Vibrate(-1, cgVR->right_handed ? 0 : 1, 0.8);
trap_Vibrate(-1, cgVR->right_handed ? 0 : 1, 0.8, "fire_tesla", 0.0, 0.0);
}
// shake the camera a bit
@ -3378,8 +3378,11 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
if (wasfiring) {
//Stop haptics
trap_Vibrate(0, 0, 0.0);
trap_Vibrate(0, 1, 0.0);
char *fire_command = (char*)malloc(8 * sizeof(char));
//sprintf(fire_command, "stop_firing_%i", weaponNum);
//trap_Vibrate(0, 0, 0.0, fire_command, 0.0, 0.0);
trap_Vibrate(0, 0, 0.0, "ignore", 0.0, 0.0);
trap_Vibrate(0, 1, 0.0, "ignore", 0.0, 0.0);
wasfiring = qfalse;
}
}
@ -4356,6 +4359,7 @@ void CG_SetSniperZoom( int lastweap, int newweap ) {
default:
Com_Printf("**WEAPON EVENT** cgVR->scopeengaged = qfalse");
cgVR->scopeengaged = qfalse;
trap_Haptic(1, cgVR->right_handed ? 1 : 0, 0.7f, "switch_weapon", 0.0f, 0.0f);
break;
}
@ -4369,6 +4373,7 @@ void CG_SetSniperZoom( int lastweap, int newweap ) {
switch ( newweap ) {
default:
return; // no sniper zoom, get out.
case WP_SNIPERRIFLE:

View file

@ -45,7 +45,13 @@ extern qboolean getCameraInfo( int camNum, int time, vec3_t *origin, vec3_t *ang
extern void SV_SendMoveSpeedsToGame( int entnum, char *text );
extern qboolean SV_GetModelInfo( int clientNum, char *modelName, animModelInfo_t **modelInfo );
void RTCWVR_Vibrate(int duration, int channel, float intensity );
void RTCWVR_Haptic(int duration, int channel, float intensity, char *description, float yaw, float height);
void RTCWVR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight );
void RTCWVR_HapticUpdateEvent(const char* event, int intensity, float angle );
void RTCWVR_HapticEndFrame();
void RTCWVR_HapticStopEvent(const char* event);
void RTCWVR_HapticEnable();
void RTCWVR_HapticDisable();
/*
====================
@ -857,7 +863,26 @@ int CL_CgameSystemCalls( int *args ) {
return SV_GetModelInfo( args[1], VMA( 2 ), VMA( 3 ) );
case CG_HAPTIC:
//args[2] = Right or left channel (1 = Right / 0 = left)
//VMF(3) = Intensity
//VMA(4) = Description
//VMF(5) = Yaw
//VMF(6) = Height
RTCWVR_Vibrate( args[1], args[2], VMF( 3 ) );
RTCWVR_Haptic( args[1], args[2], VMF( 3 ), VMA(4), VMF(5), VMF(6) );
return 0;
case CG_HAPTICTRIGGER:
//VMF(1) = Intensity
//VMA(2) = Description
//VMF(3) = Yaw
//VMF(4) = Height
RTCWVR_Haptic( args[1], args[2], VMF( 3 ), VMA(4), VMF(5), VMF(6) );
return 0;
case CG_HAPTICENABLE:
RTCWVR_HapticEnable();
return 0;
default:

View file

@ -557,6 +557,7 @@ void SCR_UpdateScreen( void ) {
recursive = 1;
RTCWVR_FrameSetup();
RTCWVR_processMessageQueue();
//Get controller state here

View file

@ -543,16 +543,16 @@ typedef enum {
WP_VENOM, // 8
WP_FLAMETHROWER, // 9
WP_TESLA, // 10
// WP_SPEARGUN, // 11
// WP_SPEARGUN, // __
// weapon keys only go 1-0, so put the alternates above that (since selection will be a double click on the german weapon key)
// American equivalents
// WP_KNIFE2, // 12
// WP_KNIFE2, // __
WP_COLT, // 11 equivalent american weapon to german luger
WP_THOMPSON, // 12 equivalent american weapon to german mp40
WP_GARAND, // 13 equivalent american weapon to german mauser
// WP_BAR, // 16 equivalent american weapon to german fg42
// WP_BAR, // __ equivalent american weapon to german fg42
WP_GRENADE_PINEAPPLE, // 14
// WP_ROCKET_LAUNCHER, // 18 equivalent american weapon to german panzerfaust

View file

@ -60,7 +60,7 @@ void P_DamageFeedback( gentity_t *player ) {
// total points of damage shot at the player this frame
count = client->damage_blood + client->damage_armor;
if ( count == 0 ) {
if ( count == 0 ) {
return; // didn't take any damage
}
@ -95,8 +95,137 @@ void P_DamageFeedback( gentity_t *player ) {
client->ps.damageCount = count;
if (!client->ps.aiChar) {
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f);
trap_Vibrate(1000, 0, (count / 255.0) + 0.5f);
vec3_t viewangle;
float_t pitch, yaw;
//pitch = (abs(angles[PITCH]) / 360.0) - 0.5;
pitch = angles[PITCH];
Com_Printf( "GBRTCW: damage location pitch = %f", pitch );
if(pitch > -90)
pitch = pitch / 180.0;
else if(pitch <= -270 && pitch > -360)
pitch = (pitch + 360) / 180;
VectorCopy( client->ps.viewangles, viewangle );
//If this doesn't work try (+ 360) instead of abs
//Com_Printf( "GBRTCW: viewangle yaw = %f", viewangle[YAW] );
//Com_Printf( "GBRTCW: damage location yaw = %f", angles[YAW] );
yaw = angles[YAW] - (viewangle[YAW] + 180.0f);
if(yaw < 0.0f)
yaw += 360.0f;
if(yaw > 360.0f)
yaw -= 360.0f;
//AnglesToAxis( viewangle, wolfkick.axis );
switch(client->lasthurt_mod)
{
case MOD_SHOTGUN:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_shotgun", yaw, pitch);
break;
case MOD_GRENADE:
case MOD_GRENADE_SPLASH:
case MOD_GRENADE_LAUNCHER:
case MOD_GRENADE_PINEAPPLE:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_frag", yaw, pitch);
break;
case MOD_ROCKET:
case MOD_ROCKET_SPLASH:
case MOD_ROCKET_LAUNCHER:
case MOD_PANZERFAUST:
case MOD_BFG:
case MOD_BFG_SPLASH:
case MOD_MORTAR:
case MOD_MORTAR_SPLASH:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_rocket", yaw, pitch);
break;
case MOD_KNIFE:
case MOD_KNIFE2:
case MOD_KNIFE_STEALTH:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_knife", yaw, pitch);
break;
case MOD_LUGER:
case MOD_COLT:
case MOD_SILENCER:
case MOD_AKIMBO:
case MOD_SPEARGUN_CO2:
case MOD_TARGET_LASER:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_low_bullet", yaw, pitch);
break;
case MOD_THOMPSON:
case MOD_STEN:
case MOD_MAUSER:
case MOD_MP40:
case MOD_GARAND:
case MOD_SPEARGUN:
case MOD_CROSS:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_mid_bullet", yaw, pitch);
break;
case MOD_RAILGUN:
case MOD_SNIPERRIFLE:
case MOD_SNOOPERSCOPE:
case MOD_FG42:
case MOD_FG42SCOPE:
case MOD_BAR: //----(SA)
case MOD_MACHINEGUN:
case MOD_VENOM:
case MOD_VENOM_FULL:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_high_bullet", yaw, pitch);
break;
case MOD_FLAMETHROWER:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_flamethrower", yaw, pitch);
break;
case MOD_LIGHTNING:
case MOD_TESLA:
case MOD_TELEFRAG:
case MOD_LOPER_HIT:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_electric", yaw, pitch);
break;
case MOD_EXPLOSIVE:
case MOD_DYNAMITE:
case MOD_DYNAMITE_SPLASH:
case MOD_AIRSTRIKE:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_explosion", yaw, pitch);
break;
case MOD_GAUNTLET:
case MOD_GRAPPLE:
case MOD_KICKED:
case MOD_GRABBER:
case MOD_LOPER_LEAP:
case MOD_LOPER_GROUND:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_melee", yaw, pitch);
break;
case MOD_FALLING:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_fall", yaw, pitch);
break;
case MOD_SUICIDE:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_death", yaw, pitch);
break;
case MOD_POISONGAS:
case MOD_WATER:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_gas", yaw, pitch);
break;
case MOD_ZOMBIESPIRIT:
case MOD_ZOMBIESPIRIT_SPLASH:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_zombiespirit", yaw, pitch);
break;
case MOD_SLIME:
case MOD_ZOMBIESPIT:
case MOD_ZOMBIESPIT_SPLASH:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_slime", yaw, pitch);
break;
case MOD_LAVA:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_fire", yaw, pitch);
break;
case MOD_CRUSH:
case MOD_TRIGGER_HURT:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_crush", yaw, pitch);
break;
default:
trap_Vibrate(1000, 1, (count / 255.0) + 0.5f, "damage_mid_bullet", yaw, pitch);
break;
}
trap_Vibrate(1000, 0, (count / 255.0) + 0.5f, "ignore", 0.0, 0.0);
}

View file

@ -163,6 +163,8 @@ void alarmbox_use( gentity_t *ent, gentity_t *other, gentity_t *foo ) {
alarmbox_updateparts( ent, qtrue );
if ( other->client ) {
G_AddEvent( ent, EV_GENERAL_SOUND, ent->soundPos3 );
//TODO GB Add heartbeat
trap_Haptic(1, 0, 1.0f, "alarm_on", 0.0f, 0.0f);
}
// G_Printf("touched alarmbox\n");
@ -183,6 +185,8 @@ void alarmbox_die( gentity_t *ent, gentity_t *inflictor, gentity_t *attacker, in
ent->takedamage = qfalse;
alarmbox_updateparts( ent, qtrue );
trap_Haptic(1, 0, 1.0f, "end_alarm", 0.0f, 0.0f);
// fire 'death' targets
if ( ent->targetdeath ) {
t = NULL;

View file

@ -1407,7 +1407,8 @@ void Cmd_Activate_f( gentity_t *ent ) {
if ( ( ( Q_stricmp( traceEnt->classname, "func_door" ) == 0 ) || ( Q_stricmp( traceEnt->classname, "func_door_rotating" ) == 0 ) ) ) {
//----(SA) modified
if ( walking ) {
//GB Force this on as they don't hve a key which seems unfair in VR
if ( walking || 1 == 1) {
traceEnt->flags |= FL_SOFTACTIVATE; // no noise
}
G_TryDoor( traceEnt, ent, ent ); // (door,other,activator)
@ -1419,7 +1420,7 @@ void Cmd_Activate_f( gentity_t *ent ) {
// Use_BinaryMover (traceEnt, ent, ent);
// traceEnt->active = qtrue;
} else if ( !Q_stricmp( traceEnt->classname, "func_invisible_user" ) ) {
if ( walking ) {
if ( walking || 1 == 1) {
traceEnt->flags |= FL_SOFTACTIVATE; // no noise
}
traceEnt->use( traceEnt, ent, ent );

View file

@ -359,8 +359,10 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
// if (self->client && self->client->hook)
// Weapon_HookFree(self->client->hook);
trap_Haptic(1,0,1.0f,"player_dead",0,0);
self->client->ps.pm_type = PM_DEAD;
if ( attacker ) {
killer = attacker->s.number;
if ( attacker->client ) {

View file

@ -39,7 +39,7 @@ If you have questions concerning this license or the applicable additional terms
*/
#include "g_local.h"
#include "../../../RTCWVR/VrClientInfo.h"
#define RESPAWN_SP -1
@ -54,7 +54,7 @@ If you have questions concerning this license or the applicable additional terms
#define RESPAWN_PARTIAL 998 // for multi-stage ammo/health
#define RESPAWN_PARTIAL_DONE 999 // for multi-stage ammo/health
extern vr_client_info_t* gVR;
//======================================================================
int Pickup_Powerup( gentity_t *ent, gentity_t *other ) {
@ -87,6 +87,7 @@ int Pickup_Powerup( gentity_t *ent, gentity_t *other ) {
// brandy also gives a little health (10)
if ( ent->item->giTag == PW_NOFATIGUE ) {
if ( Q_stricmp( ent->item->classname, "item_stamina_brandy" ) == 0 ) {
trap_Haptic(1, 0, 0.6, "give_drink", 0.0f, 0.0f);
other->health += 10;
if ( other->health > other->client->ps.stats[STAT_MAX_HEALTH] ) {
other->health = other->client->ps.stats[STAT_MAX_HEALTH];
@ -169,6 +170,7 @@ int Pickup_Powerup( gentity_t *ent, gentity_t *other ) {
//======================================================================
int Pickup_Key( gentity_t *ent, gentity_t *other ) {
other->client->ps.stats[STAT_KEYS] |= ( 1 << ent->item->giTag );
trap_Haptic(1, gVR->right_handed ? 1 : 0, 1.0f, "pickup_item", 0.0f, 0.0f);
if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
if ( !( ent->spawnflags & 8 ) ) {
return RESPAWN_SP;
@ -187,6 +189,7 @@ Pickup_Clipboard
*/
int Pickup_Clipboard( gentity_t *ent, gentity_t *other ) {
trap_Haptic(1, gVR->right_handed ? 1 : 0, 1.0f, "pickup_item", 0.0f, 0.0f);
if ( ent->spawnflags & 4 ) {
return 0; // leave in world
@ -203,6 +206,7 @@ Pickup_Treasure
int Pickup_Treasure( gentity_t *ent, gentity_t *other ) {
gentity_t *player = AICast_FindEntityForName( "player" );
player->numTreasureFound++;
trap_Haptic(1, 0, 1.0, "pickup_treasure", 0.0f, 0.0f);
G_SendMissionStats();
return RESPAWN_SP; // no respawn
}
@ -218,6 +222,7 @@ void UseHoldableItem( gentity_t *ent, int item ) {
switch ( item ) {
case HI_WINE: // 1921 Chateu Lafite - gives 25 pts health up to max health
ent->health += 25;
trap_Haptic(1, 0, 1.0, "give_drink", 0.0f, 0.0f);
if ( ent->health > ent->client->ps.stats[STAT_MAX_HEALTH] ) {
ent->health = ent->client->ps.stats[STAT_MAX_HEALTH];
}
@ -256,6 +261,7 @@ int Pickup_Holdable( gentity_t *ent, gentity_t *other ) {
other->client->ps.holding = item->giTag;
other->client->ps.stats[STAT_HOLDABLE_ITEM] |= ( 1 << ent->item->giTag ); //----(SA) added
trap_Haptic(1, gVR->right_handed ? 1 : 0, 1.0f, "pickup_item", 0.0f, 0.0f);
if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
if ( !( ent->spawnflags & 8 ) ) {
@ -386,6 +392,7 @@ int Pickup_Ammo( gentity_t *ent, gentity_t *other ) {
}
Add_Ammo( other, ent->item->giTag, quantity, qfalse ); //----(SA) modified
trap_Haptic(1, gVR->right_handed ? 1 : 0, 1.0f, "pickup_item", 0.0f, 0.0f);
// single player has no respawns (SA)
if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
@ -468,6 +475,7 @@ int Pickup_Weapon( gentity_t *ent, gentity_t *other ) {
//----(SA) end
Add_Ammo( other, weapon, quantity, !alreadyHave );
trap_Haptic(1, gVR->right_handed ? 1 : 0, 1.0f, "pickup_item", 0.0f, 0.0f);
//----(SA) no hook
// if (weapon == WP_GRAPPLING_HOOK)
@ -498,6 +506,28 @@ int Pickup_Weapon( gentity_t *ent, gentity_t *other ) {
int Pickup_Health( gentity_t *ent, gentity_t *other ) {
int max;
int quantity = 0;
float intensity = 1.0f;
//Trigger a haptic for armor pickup
intensity = ent->count / 100;
if(intensity < 0.4)
intensity = 0.4f;
//Need to find food and see if different (cheese and other stuff)
//item_health / icons/iconh_med (25)
//item_health_wall / icons/iconh_wall (25)
//item_health_turkey / icons/iconh_turkey (15)
//item_health_breadandmeat / "icons/iconh_breadandmeat (10)
if(strstr(ent->item->classname,"turkey") ||
strstr(ent->item->classname,"bread") ||
strstr(ent->item->classname,"meat") ||
strstr(ent->item->classname,"wine") ||
strstr(ent->item->classname,"latour")) {
//quantity (25)
trap_Haptic(1, 0, intensity, "give_food", 0.0f, 0.0f);
} else {
trap_Haptic(1, 0, intensity, "give_health", 0.0f, 0.0f);
}
// small and mega healths will go over the max
if ( ent->item->quantity != 5 && ent->item->quantity != 100 ) {
@ -548,6 +578,12 @@ int Pickup_Health( gentity_t *ent, gentity_t *other ) {
//======================================================================
int Pickup_Armor( gentity_t *ent, gentity_t *other ) {
//Trigger a haptic for armor pickup
if ( other->client->ps.stats[STAT_ARMOR] < 100 ) {
trap_Haptic(1,0,1.0f,"give_armor",0.0f, 0.0f);
}
other->client->ps.stats[STAT_ARMOR] += ent->item->quantity;
// if ( other->client->ps.stats[STAT_ARMOR] > other->client->ps.stats[STAT_MAX_HEALTH] * 2 ) {
// other->client->ps.stats[STAT_ARMOR] = other->client->ps.stats[STAT_MAX_HEALTH] * 2;

View file

@ -1214,7 +1214,10 @@ void trap_GetUsercmd( int clientNum, usercmd_t *cmd );
qboolean trap_GetEntityToken( char *buffer, int bufferSize );
qboolean trap_GetTag( int clientNum, char *tagName, orientation_t * or );
int trap_Vibrate(int duration, int channel, float intensity );
//int trap_Vibrate(int duration, int channel, float intensity );
int trap_Haptic( int duration, int channel, float intensity, char *description, float yaw, float height);
int trap_Vibrate( int duration, int channel, float intensity, char *description, float yaw, float height);
int trap_EnableHaptics();
int trap_DebugPolygonCreate( int color, int numPoints, vec3_t *points );
void trap_DebugPolygonDelete( int id );

View file

@ -29,6 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#include <stdbool.h>
#include "g_local.h"
#include "../../../RTCWVR/VrClientInfo.h"
@ -2413,7 +2414,7 @@ void G_RunFrame( int levelTime ) {
int msec;
//int start, end;
// if we are waiting for the level to restart, do nothing
// if we are waiting for the level to restart, do nothing
if ( level.restarted ) {
return;
}

View file

@ -35,6 +35,9 @@ If you have questions concerning this license or the applicable additional terms
*/
#include "g_local.h"
#include "../../../RTCWVR/VrClientInfo.h"
extern vr_client_info_t* gVR;
char *hintStrings[] = {
"", // HINT_NONE
@ -769,13 +772,16 @@ void SetMoverState( gentity_t *ent, moverState_t moverState, int time ) {
if ( kicked ) {
f = 2000.0 / ent->gDuration; // double speed when kicked open
ent->s.apos.trDuration = ent->gDuration / 2.0;
} else if ( soft ) {
f = 500.0 / ent->gDuration; // 1/2 speed when soft opened
ent->s.apos.trDuration = ent->gDuration * 2;
//trap_Vibrate(1, gVR->right_handed ? 0 : 1, 0.5f, "door_open", 0, 0); //I've reversed the hands as I presume you will open it with the hand your gun isn't in.
} else {
f = 1000.0 / ent->gDuration;
// ent->s.apos.trDuration = ent->gDurationBack; // (SA) durationback?
ent->s.apos.trDuration = ent->gDuration;
//trap_Vibrate(1, gVR->right_handed ? 0 : 1, 0.75f, "door_open", 0, 0); //not sure what this is
}
VectorScale( ent->rotate, f * ent->angle, ent->s.apos.trDelta );
ent->s.apos.trType = TR_LINEAR_STOP;
@ -1387,7 +1393,7 @@ void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
if ( kicked ) {
ent->teammaster->flags |= FL_KICKACTIVATE;
}
if ( soft ) {
else if ( soft || 1 == 1) {
ent->teammaster->flags |= FL_SOFTACTIVATE;
}
@ -2200,17 +2206,21 @@ void G_TryDoor( gentity_t *ent, gentity_t *other, gentity_t *activator ) {
Use_BinaryMover( ent->teammaster, activator, activator );
G_UseTargets( ent->teammaster, activator );
} else
}
else
{
ent->active = qtrue;
if ( walking ) {
if ( walking || 1 == 1) {
ent->flags |= FL_SOFTACTIVATE; // no noise
if(gVR)
trap_Vibrate(1, gVR->right_handed ? 0 : 1, 0.3f, "door_open", 0, 0); //I've reversed the hands as I presume you will open it with the hand your gun isn't in.
} else {
if(gVR)
trap_Vibrate(1, gVR->right_handed ? 0 : 1, 0.5f, "door_open", 0, 0); //I've reversed the hands as I presume you will open it with the hand your gun isn't in.
if ( activator ) {
soundrange = HEAR_RANGE_DOOR_OPEN;
}
}
Use_BinaryMover( ent, activator, activator );
G_UseTargets( ent, activator );
}

View file

@ -250,6 +250,8 @@ typedef enum {
G_GETTAG,
G_HAPTIC,
G_HAPTICTRIGGER,
G_FULL_HAPTIC,
BOTLIB_SETUP = 200, // ( void );
BOTLIB_SHUTDOWN, // ( void );

View file

@ -255,8 +255,12 @@ qboolean trap_GetTag( int clientNum, char *tagName, orientation_t *or ) {
return syscall( G_GETTAG, clientNum, tagName, or );
}
int trap_Vibrate(int duration, int channel, float intensity ) {
return syscall( G_HAPTIC, duration, channel, PASSFLOAT(intensity) );
int trap_Vibrate( int duration, int channel, float intensity, char *description, float yaw, float height) {
return syscall( G_HAPTIC, duration, channel, PASSFLOAT(intensity), description, PASSFLOAT(yaw), PASSFLOAT(height));
}
int trap_Haptic( int duration, int channel, float intensity, char *description, float yaw, float height) {
return syscall( G_HAPTICTRIGGER, duration, channel, PASSFLOAT(intensity), description, PASSFLOAT(yaw), PASSFLOAT(height));
}
// BotLib traps start here

View file

@ -141,7 +141,7 @@ void Weapon_Knife( gentity_t *ent ) {
tent->s.weapon = ent->s.weapon;
//we hit something
trap_Vibrate(100, gVR->right_handed ? 1 : 0, 0.9);
trap_Vibrate(100, gVR->right_handed ? 1 : 0, 0.9, "knife_hit", 0.0, 0.0);
if ( tr.entityNum == ENTITYNUM_WORLD ) { // don't worry about doing any damage
return;
@ -963,15 +963,17 @@ void Bullet_Fire( gentity_t *ent, float spread, int damage ) {
if (!ent->aiCharacter) {
qboolean right = gVR->right_handed;
// Allocates storage
char *fire_command = (char*)malloc(8 * sizeof(char));
sprintf(fire_command, "fire_%i", ent->s.weapon);
if (ent->s.weapon == WP_AKIMBO)
{
right = BG_AkimboFireSequence(ent->s.weapon, ent->client->ps.ammoclip[WP_AKIMBO], ent->client->ps.ammoclip[WP_COLT] );
trap_Vibrate(100, right ? 1 : 0, 1.0);
trap_Vibrate(100, right ? 1 : 0, 1.0, fire_command, 0.0, 0.0);
} else{
trap_Vibrate(100, right ? 1 : 0, 1.0);
trap_Vibrate(100, right ? 1 : 0, 1.0, fire_command, 0.0, 0.0);
if (gVR->weapon_stabilised) {
trap_Vibrate(100, right ? 0 : 1, 0.7);
trap_Vibrate(100, right ? 0 : 1, 0.7, fire_command, 0.0, 0.0);
}
}
}
@ -2033,9 +2035,9 @@ void FireWeapon( gentity_t *ent ) {
ent->client->ps.classWeaponTime = level.time; // JPW NERVE
Weapon_RocketLauncher_Fire( ent, aimSpreadScale );
if (!ent->aiCharacter) {
trap_Vibrate(200, gVR->right_handed ? 1 : 0, 1.0);
trap_Vibrate(200, gVR->right_handed ? 1 : 0, 1.0, "fire_rocket", 0.0, 0.0);
if (gVR->weapon_stabilised) {
trap_Vibrate(200, gVR->right_handed ? 0 : 1, 0.7);
trap_Vibrate(200, gVR->right_handed ? 0 : 1, 0.7, "fire_rocket", 0.0, 0.0);
}
}
break;

View file

@ -304,6 +304,13 @@ static int FloatAsInt( float f ) {
}
void RTCWVR_Vibrate(int duration, int channel, float intensity );
void RTCWVR_Haptic(int duration, int channel, float intensity, char *description, float yaw, float height);
void RTCWVR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight );
void RTCWVR_HapticUpdateEvent(const char* event, int intensity, float angle );
void RTCWVR_HapticEndFrame();
void RTCWVR_HapticStopEvent(const char* event);
void RTCWVR_HapticEnable();
void RTCWVR_HapticDisable();
/*
====================
@ -473,8 +480,12 @@ int SV_GameSystemCalls( int *args ) {
return SV_GetTag( args[1], VMA( 2 ), VMA( 3 ) );
case G_HAPTIC:
RTCWVR_Vibrate( args[1], args[2], VMF( 3 ) );
return 0;
RTCWVR_Haptic( args[1], args[2], VMF( 3 ), VMA(4), VMF(5), VMF(6) );
return 0;
case G_HAPTICTRIGGER:
RTCWVR_Haptic( args[1], args[2], VMF( 3 ), VMA(4), VMF(5), VMF(6) );
return 0;
//====================================
case BOTLIB_SETUP:

Binary file not shown.

View file

@ -14,17 +14,24 @@ import java.io.OutputStream;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import com.drbeef.externalhapticsservice.HapticServiceClient;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
@ -38,7 +45,10 @@ import static android.system.Os.setenv;
System.loadLibrary( "rtcw_client" );
}
private HapticServiceClient externalHapticsServiceClient = null;
private static final String TAG = "RTCWQuest";
private static final String APPLICATION = "RTCWQuest";
private int permissionCount = 0;
private static final int READ_EXTERNAL_STORAGE_PERMISSION_ID = 1;
@ -69,6 +79,84 @@ import static android.system.Os.setenv;
System.exit(0);
}
public void haptic_event(String event, int position, int flags, int intensity, float angle, float yHeight) {
if (externalHapticsServiceClient.hasService()) {
try {
externalHapticsServiceClient.getHapticsService().hapticEvent(APPLICATION, event, position, flags, intensity, angle, yHeight);
}
catch (RemoteException r)
{
Log.v(APPLICATION, r.toString());
}
}
}
public void haptic_updateevent(String event, int intensity, float angle) {
if (externalHapticsServiceClient.hasService()) {
try {
externalHapticsServiceClient.getHapticsService().hapticUpdateEvent(APPLICATION, event, intensity, angle);
}
catch (RemoteException r)
{
Log.v(APPLICATION, r.toString());
}
}
}
public void haptic_stopevent(String event) {
if (externalHapticsServiceClient.hasService()) {
try {
externalHapticsServiceClient.getHapticsService().hapticStopEvent(APPLICATION, event);
}
catch (RemoteException r)
{
Log.v(APPLICATION, r.toString());
}
}
}
public void haptic_endframe() {
if (externalHapticsServiceClient.hasService()) {
try {
externalHapticsServiceClient.getHapticsService().hapticFrameTick();
}
catch (RemoteException r)
{
Log.v(APPLICATION, r.toString());
}
}
}
public void haptic_enable() {
if (externalHapticsServiceClient.hasService()) {
try {
externalHapticsServiceClient.getHapticsService().hapticEnable();
}
catch (RemoteException r)
{
Log.v(APPLICATION, r.toString());
}
}
}
public void haptic_disable() {
if (externalHapticsServiceClient.hasService()) {
try {
externalHapticsServiceClient.getHapticsService().hapticDisable();
}
catch (RemoteException r)
{
Log.v(APPLICATION, r.toString());
}
}
}
@Override protected void onCreate( Bundle icicle )
{
Log.v( TAG, "----------------------------------------------------------------" );
@ -212,6 +300,12 @@ import static android.system.Os.setenv;
}
externalHapticsServiceClient = new HapticServiceClient(this, (state, desc) -> {
Log.v(APPLICATION, "ExternalHapticsService is:" + desc);
});
externalHapticsServiceClient.bindService();
mNativeHandle = GLES3JNILib.onCreate( this, commandLineParams );
}
@ -262,7 +356,10 @@ import static android.system.Os.setenv;
Log.v( TAG, "GLES3JNIActivity::onStart()" );
super.onStart();
GLES3JNILib.onStart( mNativeHandle, this );
if ( mNativeHandle != 0 )
{
GLES3JNILib.onStart(mNativeHandle, this);
}
}
@Override protected void onResume()
@ -270,20 +367,29 @@ import static android.system.Os.setenv;
Log.v( TAG, "GLES3JNIActivity::onResume()" );
super.onResume();
GLES3JNILib.onResume( mNativeHandle );
if ( mNativeHandle != 0 )
{
GLES3JNILib.onResume(mNativeHandle);
}
}
@Override protected void onPause()
{
Log.v( TAG, "GLES3JNIActivity::onPause()" );
GLES3JNILib.onPause( mNativeHandle );
if ( mNativeHandle != 0 )
{
GLES3JNILib.onPause(mNativeHandle);
}
super.onPause();
}
@Override protected void onStop()
{
Log.v( TAG, "GLES3JNIActivity::onStop()" );
GLES3JNILib.onStop( mNativeHandle );
if ( mNativeHandle != 0 )
{
GLES3JNILib.onStop(mNativeHandle);
}
super.onStop();
}
@ -296,7 +402,12 @@ import static android.system.Os.setenv;
GLES3JNILib.onSurfaceDestroyed( mNativeHandle );
}
GLES3JNILib.onDestroy( mNativeHandle );
if ( mNativeHandle != 0 )
{
GLES3JNILib.onDestroy(mNativeHandle);
}
externalHapticsServiceClient.stopBinding();
super.onDestroy();
// Reset everything in case the user re opens the app
@ -333,5 +444,4 @@ import static android.system.Os.setenv;
mSurfaceHolder = null;
}
}
}