diff --git a/Projects/Android/jni/JKVR/JKVR_SurfaceView.cpp b/Projects/Android/jni/JKVR/JKVR_SurfaceView.cpp
index 42b216e..5fda8a7 100644
--- a/Projects/Android/jni/JKVR/JKVR_SurfaceView.cpp
+++ b/Projects/Android/jni/JKVR/JKVR_SurfaceView.cpp
@@ -1268,7 +1268,7 @@ void JKVR_Init()
vr_turn_mode = Cvar_Get( "vr_turn_mode", "0", CVAR_ARCHIVE); // 0 = snap, 1 = smooth
vr_turn_angle = Cvar_Get( "vr_turn_angle", "45", CVAR_ARCHIVE);
vr_positional_factor = Cvar_Get( "vr_positional_factor", "12", CVAR_ARCHIVE);
- vr_walkdirection = Cvar_Get( "vr_walkdirection", "0", CVAR_ARCHIVE);
+ vr_walkdirection = Cvar_Get( "vr_walkdirection", "1", CVAR_ARCHIVE);
vr_movement_multiplier = Cvar_Get( "vr_movement_multiplier", "0.8", CVAR_ARCHIVE);
vr_weapon_pitchadjust = Cvar_Get( "vr_weapon_pitchadjust", "-20.0", CVAR_ARCHIVE);
vr_virtual_stock = Cvar_Get( "vr_virtual_stock", "0", CVAR_ARCHIVE);
@@ -1279,6 +1279,7 @@ void JKVR_Init()
vr_immersive_cinematics = Cvar_Get("vr_immersive_cinematics", "0", CVAR_ARCHIVE);
vr_screen_dist = Cvar_Get( "vr_screen_dist", "2.5", CVAR_ARCHIVE);
+ vr_weapon_velocity_trigger = Cvar_Get( "vr_weapon_velocity_trigger", "1.6", CVAR_ARCHIVE);
}
diff --git a/Projects/Android/jni/JKVR/VrClientInfo.h b/Projects/Android/jni/JKVR/VrClientInfo.h
index a2871dd..b76e76b 100644
--- a/Projects/Android/jni/JKVR/VrClientInfo.h
+++ b/Projects/Android/jni/JKVR/VrClientInfo.h
@@ -37,6 +37,8 @@ typedef struct {
vec3_t weaponoffset_history[NUM_WEAPON_SAMPLES];
float weaponoffset_history_timestamp[NUM_WEAPON_SAMPLES];
+ bool item_selector;
+
bool pistol; // True if the weapon is a pistol
//Lots of scope weapon stuff
@@ -49,7 +51,9 @@ typedef struct {
bool velocitytriggered;
float primaryswingvelocity;
+ bool primaryVelocityTriggeredAttack;
float secondaryswingvelocity;
+ bool secondaryVelocityTriggeredAttack;
vec3_t offhandangles;
vec3_t offhandangles_last; // Don't use this, it is just for calculating delta!
diff --git a/Projects/Android/jni/JKVR/VrCvars.h b/Projects/Android/jni/JKVR/VrCvars.h
index 79f2ae1..a1a2eaa 100644
--- a/Projects/Android/jni/JKVR/VrCvars.h
+++ b/Projects/Android/jni/JKVR/VrCvars.h
@@ -9,4 +9,5 @@ extern cvar_t *vr_virtual_stock;
extern cvar_t *vr_switch_sticks;
extern cvar_t *vr_immersive_cinematics;
extern cvar_t *vr_screen_dist;
+extern cvar_t *vr_weapon_velocity_trigger;
diff --git a/Projects/Android/jni/JKVR/VrInputCommon.cpp b/Projects/Android/jni/JKVR/VrInputCommon.cpp
index 3eb8e35..57a38fe 100644
--- a/Projects/Android/jni/JKVR/VrInputCommon.cpp
+++ b/Projects/Android/jni/JKVR/VrInputCommon.cpp
@@ -29,6 +29,7 @@ cvar_t *vr_virtual_stock;
cvar_t *vr_switch_sticks;
cvar_t *vr_immersive_cinematics;
cvar_t *vr_screen_dist;
+cvar_t *vr_weapon_velocity_trigger;
ovrInputStateTrackedRemote leftTrackedRemoteState_old;
ovrInputStateTrackedRemote leftTrackedRemoteState_new;
diff --git a/Projects/Android/jni/JKVR/VrInputDefault.cpp b/Projects/Android/jni/JKVR/VrInputDefault.cpp
index 5824466..daa32e4 100644
--- a/Projects/Android/jni/JKVR/VrInputDefault.cpp
+++ b/Projects/Android/jni/JKVR/VrInputDefault.cpp
@@ -156,308 +156,48 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
bool offhandGripPushed = (pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger);
if ( (offhandGripPushed != (pOffTrackedRemoteOld->Buttons & ovrButton_GripTrigger)) &&
offhandGripPushed && (distance < STABILISATION_DISTANCE))
-#ifndef DEBUG
+//#ifndef DEBUG
{
stabilised = qtrue;
}
-#else
+//#else
+// {
+// Cvar_Set("vr_control_scheme", "99");
+// }
+//#endif
+
+ dominantGripPushed = (pDominantTrackedRemoteNew->Buttons &
+ ovrButton_GripTrigger) != 0;
+ bool dominantButton1Pushed = (pDominantTrackedRemoteNew->Buttons &
+ domButton1) != 0;
+ bool dominantButton2Pushed = (pDominantTrackedRemoteNew->Buttons &
+ domButton2) != 0;
+
+ //Do this early so we can suppress other button actions when item selector is up
{
- Cvar_Set("vr_control_scheme", "99");
- }
-#endif
-
- vr.weapon_stabilised = stabilised;
-
- //Engage scope / virtual stock if conditions are right
- bool scopeready = vr.weapon_stabilised && (distanceToHMD < SCOPE_ENGAGE_DISTANCE);
- static bool lastScopeReady = qfalse;
- if (scopeready != lastScopeReady) {
- if (vr.scopedweapon && !vr.scopedetached) {
- if (!vr.scopeengaged && scopeready) {
- ALOGV("**WEAPON EVENT** trigger scope mode");
- sendButtonActionSimple("weapalt");
+ if (dominantGripPushed) {
+ if (dominantGripPushTime == 0) {
+ dominantGripPushTime = GetTimeInMilliSeconds();
}
- else if (vr.scopeengaged && !scopeready) {
- ALOGV("**WEAPON EVENT** disable scope mode");
- sendButtonActionSimple("weapalt");
+ vr.item_selector = true;
+ }
+ else
+ {
+ dominantGripPushTime = 0;
+ if (vr.item_selector)
+ {
+ sendButtonActionSimple("itemselectorselect");
+ vr.item_selector = false;
}
- lastScopeReady = scopeready;
}
}
- //ALOGV("**GB WEAPON ACTIVE** %i",vr.weaponid);
- if(!scopeready && vr.weaponid >= 15 && vr.weaponid <= 17)
- {
- lastScopeReady = false;
- ALOGV("**WEAPON EVENT** disable scope mode forced");
- sendButtonActionSimple("weapalt");
- }
- //Engage scope / virtual stock (iron sight lock) if conditions are right
- static bool scopeEngaged = qfalse;
- if (scopeEngaged != vr.scopeengaged)
- {
- scopeEngaged = vr.scopeengaged;
- }
-
- //dominant hand stuff first
- {
- //Record recent weapon position for trajectory based stuff
- for (int i = (NUM_WEAPON_SAMPLES-1); i != 0; --i)
- {
- VectorCopy(vr.weaponoffset_history[i-1], vr.weaponoffset_history[i]);
- vr.weaponoffset_history_timestamp[i] = vr.weaponoffset_history_timestamp[i-1];
- }
- VectorCopy(vr.weaponoffset, vr.weaponoffset_history[0]);
- vr.weaponoffset_history_timestamp[0] = vr.weaponoffset_timestamp;
-
- vr.weaponposition[0] = pWeapon->HeadPose.Pose.Position.x;
- vr.weaponposition[1] = pWeapon->HeadPose.Pose.Position.y;
- vr.weaponposition[2] = pWeapon->HeadPose.Pose.Position.z;
-
- ///Weapon location relative to view
- vr.weaponoffset[0] = pWeapon->HeadPose.Pose.Position.x - vr.hmdposition[0];
- vr.weaponoffset[1] = pWeapon->HeadPose.Pose.Position.y - vr.hmdposition[1];
- vr.weaponoffset[2] = pWeapon->HeadPose.Pose.Position.z - vr.hmdposition[2];
- vr.weaponoffset_timestamp = Sys_Milliseconds( );
-
- vr.primaryswingvelocity = sqrtf(powf(pWeapon->HeadPose.LinearVelocity.x, 2) +
- powf(pWeapon->HeadPose.LinearVelocity.y, 2) +
- powf(pWeapon->HeadPose.LinearVelocity.z, 2));
-
- vr.secondaryswingvelocity = sqrtf(powf(pOff->HeadPose.LinearVelocity.x, 2) +
- powf(pOff->HeadPose.LinearVelocity.y, 2) +
- powf(pOff->HeadPose.LinearVelocity.z, 2));
-
-
- //For melee right hand is alt attack and left hand is attack
- static bool primaryVelocityTriggeredAttack = false;
- static bool secondaryVelocityTriggeredAttack = false;
- if (vr.weaponid == WP_MELEE) {
- //Does weapon velocity trigger attack (melee) and is it fast enough
- if (vr.velocitytriggered) {
- static bool fired = qfalse;
- primaryVelocityTriggeredAttack = (vr.primaryswingvelocity > WEAPON_VELOCITY_TRIGGER);
-
- if (fired != primaryVelocityTriggeredAttack) {
- ALOGV("**WEAPON EVENT** veocity triggered %s",
- primaryVelocityTriggeredAttack ? "+altattack" : "-altattack");
- //normal attack is a punch with the left hand
- sendButtonAction("+altattack", primaryVelocityTriggeredAttack);
- fired = primaryVelocityTriggeredAttack;
- }
- } else if (primaryVelocityTriggeredAttack) {
- //send a stop attack as we have an unfinished velocity attack
- primaryVelocityTriggeredAttack = qfalse;
- ALOGV("**WEAPON EVENT** veocity triggered -altattack");
- sendButtonAction("+altattack", primaryVelocityTriggeredAttack);
- }
-
- if (vr.velocitytriggered) {
- static bool fired = qfalse;
- secondaryVelocityTriggeredAttack = (vr.secondaryswingvelocity >
- WEAPON_VELOCITY_TRIGGER);
-
- if (fired != secondaryVelocityTriggeredAttack) {
- ALOGV("**WEAPON EVENT** veocity triggered %s",
- secondaryVelocityTriggeredAttack ? "+attack" : "-attack");
- //normal attack is a punch with the left hand
- sendButtonAction("+attack", secondaryVelocityTriggeredAttack);
- fired = secondaryVelocityTriggeredAttack;
- }
- } else if (secondaryVelocityTriggeredAttack) {
- //send a stop attack as we have an unfinished velocity attack
- secondaryVelocityTriggeredAttack = qfalse;
- ALOGV("**WEAPON EVENT** veocity triggered -attack");
- sendButtonAction("+attack", secondaryVelocityTriggeredAttack);
- }
- }
- else if (vr.weaponid == WP_SABER) {
- //Does weapon velocity trigger attack
- if (vr.velocitytriggered) {
- static bool fired = qfalse;
- primaryVelocityTriggeredAttack = (vr.primaryswingvelocity > WEAPON_VELOCITY_TRIGGER);
-
- if (fired != primaryVelocityTriggeredAttack) {
- ALOGV("**WEAPON EVENT** veocity triggered %s",
- primaryVelocityTriggeredAttack ? "+attack" : "-attack");
- //normal attack is a punch with the left hand
- sendButtonAction("+attack", primaryVelocityTriggeredAttack);
- fired = primaryVelocityTriggeredAttack;
- }
- } else if (primaryVelocityTriggeredAttack) {
- //send a stop attack as we have an unfinished velocity attack
- primaryVelocityTriggeredAttack = qfalse;
- ALOGV("**WEAPON EVENT** veocity triggered -attack");
- sendButtonAction("+attack", primaryVelocityTriggeredAttack);
- }
- }
-
- if (vr.weapon_stabilised)
- {
- if (vr.scopeengaged || vr_virtual_stock->integer == 1)
- {
- //offset to the appropriate eye a little bit
- vec2_t xy;
- rotateAboutOrigin(Cvar_VariableValue("cg_stereoSeparation") / 2.0f, 0.0f, -vr.hmdorientation[YAW], xy);
- float x = pOff->HeadPose.Pose.Position.x - (vr.hmdposition[0] + xy[0]);
- float y = pOff->HeadPose.Pose.Position.y - (vr.hmdposition[1] - 0.1f); // Use a point lower
- float z = pOff->HeadPose.Pose.Position.z - (vr.hmdposition[2] + xy[1]);
- float zxDist = length(x, z);
-
- if (zxDist != 0.0f && z != 0.0f) {
- VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
- -degrees(atan2f(x, -z)), 0);
- }
- }
- else
- {
- float x = pOff->HeadPose.Pose.Position.x - pWeapon->HeadPose.Pose.Position.x;
- float y = pOff->HeadPose.Pose.Position.y - pWeapon->HeadPose.Pose.Position.y;
- float z = pOff->HeadPose.Pose.Position.z - pWeapon->HeadPose.Pose.Position.z;
- float zxDist = length(x, z);
-
- if (zxDist != 0.0f && z != 0.0f) {
- VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
- -degrees(atan2f(x, -z)), vr.weaponangles[ROLL] / 2.0f); //Dampen roll on stabilised weapon
- }
- }
- }
-
- // Calculate if player tries to reach backpack
- bool handInBackpack = false;
- bool bpDistToHMDOk = false, bpWeaponHeightOk = false, bpWeaponAngleOk = false, bpHmdToWeaponAngleOk = false;
- vec3_t hmdForwardXY = {}, weaponForwardXY = {};
- float weaponToDownAngle = 0, hmdToWeaponDotProduct = 0;
- static vec3_t downVector = {0.0, 0.0, -1.0};
-
- bool bpTrackOk = pOffTracking->Status & VRAPI_TRACKING_STATUS_POSITION_TRACKED; // 1) Position must be tracked
- if (bpTrackOk && (bpDistToHMDOk = distanceToHMD >= 0.2 && distanceToHMD <= 0.35) // 2) Weapon-to-HMD distance must be within <0.2-0.35> range
- && (bpWeaponHeightOk = vr.weaponoffset[1] >= -0.10 && vr.weaponoffset[1] <= 0.10)) // 3) Weapon height in relation to HMD must be within <-0.10, 0.10> range
- {
- AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL);
- AngleVectors(vr.weaponangles, weaponForwardXY, NULL, NULL);
-
- float weaponToDownAngle = AngleBetweenVectors(downVector, weaponForwardXY);
- // 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees
- if(bpWeaponAngleOk = weaponToDownAngle >= 80.0 && weaponToDownAngle <= 140.0)
- {
- hmdForwardXY[2] = 0;
- VectorNormalize(hmdForwardXY);
-
- weaponForwardXY[2] = 0;
- VectorNormalize(weaponForwardXY);
-
- hmdToWeaponDotProduct = DotProduct(hmdForwardXY, weaponForwardXY);
- // 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0)
- handInBackpack = bpHmdToWeaponAngleOk = hmdToWeaponDotProduct < 0;
- }
- }
-
- //off-hand stuff (done here as I reference it in the save state thing
- {
- vr.offhandposition[0] = pOff->HeadPose.Pose.Position.x;
- vr.offhandposition[1] = pOff->HeadPose.Pose.Position.y;
- vr.offhandposition[2] = pOff->HeadPose.Pose.Position.z;
-
- vr.offhandoffset[0] = pOff->HeadPose.Pose.Position.x - vr.hmdposition[0];
- vr.offhandoffset[1] = pOff->HeadPose.Pose.Position.y - vr.hmdposition[1];
- vr.offhandoffset[2] = pOff->HeadPose.Pose.Position.z - vr.hmdposition[2];
-
- vec3_t rotation = {0};
- QuatToYawPitchRoll(pOff->HeadPose.Pose.Orientation, rotation, vr.offhandangles);
-
- if (vr_walkdirection->value == 0) {
- controllerYawHeading = vr.offhandangles[YAW] - vr.hmdorientation[YAW];
- }
- else
- {
- controllerYawHeading = 0.0f;
- }
- }
-
- // Use off hand as well to trigger save condition
- canUseQuickSave = false;
- bool bpOffhandDistToHMDOk = false, bpOffhandHeightOk = false, bpOffhandAngleOk = false, bpHmdToOffhandAngleOk = false;
- vec3_t offhandForwardXY = {};
- float hmdToOffhandDotProduct = 0;
- float offhandToDownAngle = 0;
- if (bpTrackOk && (bpOffhandDistToHMDOk = distanceToHMDOff >= 0.2 && distanceToHMDOff <= 0.35) // 2) Off-to-HMD distance must be within <0.2-0.35> range
- && (bpOffhandHeightOk = vr.offhandoffset[1] >= -0.10 && vr.offhandoffset[1] <= 0.10)) // 3) Offhand height in relation to HMD must be within <-0.10, 0.10> range
- {
- //Need to do this again as might not have done it above and cant be bothered to refactor
- AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL);
- AngleVectors(vr.offhandangles, offhandForwardXY, NULL, NULL);
-
- offhandToDownAngle = AngleBetweenVectors(downVector, offhandForwardXY);
-
- // 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees
- if(bpOffhandAngleOk = offhandToDownAngle >= 80.0 && offhandToDownAngle <= 140.0)
- {
- hmdForwardXY[2] = 0;
- VectorNormalize(hmdForwardXY);
-
- offhandForwardXY[2] = 0;
- VectorNormalize(offhandForwardXY);
-
- hmdToOffhandDotProduct = DotProduct(hmdForwardXY, offhandForwardXY);
- // 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0)
- canUseQuickSave = bpHmdToOffhandAngleOk = hmdToOffhandDotProduct < 0;
- }
- }
-
- // Uncomment to debug offhand reaching
-
- ALOGV("Quick Save> Dist: %f | OffHandToDownAngle: %f | HandOffs: %f %f %f\nHmdHandDot: %f | HmdFwdXY: %f %f | WpnFwdXY: %f %f\nTrackOk: %i, DistOk: %i, HeightOk: %i, HnadAngleOk: %i, HmdHandDotOk: %i",
- distanceToHMDOff, offhandToDownAngle, vr.offhandoffset[0], vr.offhandoffset[1], vr.offhandoffset[2],
- hmdToOffhandDotProduct, hmdForwardXY[0], hmdForwardXY[1], offhandForwardXY[0], offhandForwardXY[1],
- bpTrackOk, bpOffhandDistToHMDOk, bpOffhandHeightOk, bpOffhandAngleOk, bpHmdToOffhandAngleOk);
-
-
- // Check quicksave
- if (canUseQuickSave) {
- int channel = (vr_control_scheme->integer >= 10) ? 1 : 0;
- JKVR_Vibrate(40, channel, 0.5); // vibrate to let user know they can switch
-
- if (((pOffTrackedRemoteNew->Buttons & offButton1) !=
- (pOffTrackedRemoteOld->Buttons & offButton1)) &&
- (pOffTrackedRemoteNew->Buttons & offButton1)) {
- sendButtonActionSimple("savegame quicksave");
- }
-
- if (((pOffTrackedRemoteNew->Buttons & offButton2) !=
- (pOffTrackedRemoteOld->Buttons & offButton2)) &&
- (pOffTrackedRemoteNew->Buttons & offButton2)) {
- sendButtonActionSimple("loadgame quicksave");
- }
- }
-
- dominantGripPushed = (pDominantTrackedRemoteNew->Buttons &
- ovrButton_GripTrigger) != 0;
- bool dominantButton1Pushed = (pDominantTrackedRemoteNew->Buttons &
- domButton1) != 0;
- bool dominantButton2Pushed = (pDominantTrackedRemoteNew->Buttons &
- domButton2) != 0;
-
- {
- if (dominantGripPushed) {
- if (dominantGripPushTime == 0) {
- dominantGripPushTime = GetTimeInMilliSeconds();
- }
- Cvar_Set("timescale", "0.22");
- }
- else
- {
- dominantGripPushTime = 0;
- Cvar_Set("timescale", "1.0");
- }
- }
- }
#define JOYX_SAMPLE_COUNT 4
static float joyx[JOYX_SAMPLE_COUNT] = {0};
- for (int j = JOYX_SAMPLE_COUNT-1; j > 0; --j)
- joyx[j] = joyx[j-1];
+ for (int j = JOYX_SAMPLE_COUNT - 1; j > 0; --j)
+ joyx[j] = joyx[j - 1];
joyx[0] = pPrimaryJoystick->x;
float sum = 0.0f;
for (int j = 0; j < JOYX_SAMPLE_COUNT; ++j)
@@ -465,201 +205,471 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
float primaryJoystickX = sum / 4.0f;
- //Right-hand specific stuff
- {
- //This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the
- //player is facing for positional tracking
-
- //Positional movement speed correction for when we are not hitting target framerate
- static double lastframetime = 0;
- int refresh = GetRefresh();
- double newframetime = GetTimeInMilliSeconds();
- float multiplier = (float)((1000.0 / refresh) / (newframetime - lastframetime));
- lastframetime = newframetime;
-
- vec2_t v;
- float factor = (refresh / 72.0F) * vr_positional_factor->value; // adjust positional factor based on refresh rate
- rotateAboutOrigin(-vr.hmdposition_delta[0] * factor * multiplier,
- vr.hmdposition_delta[2] * factor * multiplier, - vr.hmdorientation[YAW], v);
- positional_movementSideways = v[0];
- positional_movementForward = v[1];
-
- ALOGV(" positional_movementSideways: %f, positional_movementForward: %f",
- positional_movementSideways,
- positional_movementForward);
-
-
- //Jump (A Button)
- if ((primaryButtonsNew & primaryButton1) != (primaryButtonsOld & primaryButton1))
- {
- sendButtonAction("+moveup", (primaryButtonsNew & primaryButton1));
- }
-
- //Alt Fire (B Button)
- if ((primaryButtonsNew & primaryButton2) != (primaryButtonsOld & primaryButton2))
- {
- sendButtonAction("+altattack", (primaryButtonsNew & primaryButton2));
- }
-
-
- static bool firing = false;
-
- {
- //Fire Primary - Doesn't trigger the saber
- if (!vr.velocitytriggered && // Don't fire velocity triggered weapons
- (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) !=
- (pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger)) {
-
- ALOGV("**WEAPON EVENT** Not Grip Pushed %sattack", (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) ? "+" : "-");
- firing = (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger);
- sendButtonAction("+attack", firing);
+ //Left/right to switch between which selector we are using
+ if (vr.item_selector) {
+ static bool itemSwitched = false;
+ if (between(-0.2f, pPrimaryJoystick->y, 0.2f) &&
+ (between(0.8f, primaryJoystickX, 1.0f) ||
+ between(-1.0f, primaryJoystickX, -0.8f))) {
+ if (!itemSwitched) {
+ if (between(0.8f, primaryJoystickX, 1.0f)) {
+ sendButtonActionSimple("itemselectornext");
+ } else {
+ sendButtonActionSimple("itemselectorprev");
+ }
+ itemSwitched = true;
}
+ } else {
+ itemSwitched = false;
}
-
-
- //Duck - off hand joystick
- if ((secondaryButtonsNew & secondaryThumb) !=
- (secondaryButtonsOld & secondaryThumb)) {
-
- sendButtonAction("+movedown", (secondaryButtonsNew & secondaryThumb));
- }
-
- //Use
- if ((pDominantTrackedRemoteNew->Buttons & primaryThumb) !=
- (pDominantTrackedRemoteOld->Buttons & primaryThumb)) {
-
- sendButtonAction("+use", (pDominantTrackedRemoteNew->Buttons & primaryThumb));
- }
-
- //Weapon Chooser
- static bool itemSwitched = false;
- if (between(-0.2f, primaryJoystickX, 0.2f) &&
- (between(0.8f, pPrimaryJoystick->y, 1.0f) ||
- between(-1.0f, pPrimaryJoystick->y, -0.8f)))
- {
- if (!itemSwitched) {
- if (between(0.8f, pPrimaryJoystick->y, 1.0f))
- {
- sendButtonActionSimple("weapprev");
- }
- else
- {
- sendButtonActionSimple("weapnext");
- }
- itemSwitched = true;
- }
- } else {
- itemSwitched = false;
- }
}
+ vr.weapon_stabilised = stabilised;
+
+ //if (!vr.item_selector)
{
- //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) + pFootTrackingNew->LeftJoystick.x;
- float y = (nlf * pSecondaryJoystick->y) - pFootTrackingNew->LeftJoystick.y;
-
- vr.player_moving = (fabs(x) + fabs(y)) > 0.05f;
-
- //Adjust to be off-hand controller oriented
- vec2_t v;
- rotateAboutOrigin(x, y, controllerYawHeading, v);
-
- //Move a lot slower if scope is engaged
- remote_movementSideways = v[0] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value;
- remote_movementForward = v[1] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value;
- ALOGV(" remote_movementSideways: %f, remote_movementForward: %f",
- remote_movementSideways,
- remote_movementForward);
-
-
- //Use Force (X button)
- if (!canUseQuickSave) {
- if ((secondaryButtonsNew & secondaryButton1) !=
- (secondaryButtonsOld & secondaryButton1)) {
- sendButtonAction("+useforce", (secondaryButtonsNew & secondaryButton1));
+ //Engage scope / virtual stock if conditions are right
+ bool scopeready = vr.weapon_stabilised && (distanceToHMD < SCOPE_ENGAGE_DISTANCE);
+ static bool lastScopeReady = qfalse;
+ if (scopeready != lastScopeReady) {
+ if (vr.scopedweapon && !vr.scopedetached) {
+ if (!vr.scopeengaged && scopeready) {
+ ALOGV("**WEAPON EVENT** trigger scope mode");
+ sendButtonActionSimple("weapalt");
+ } else if (vr.scopeengaged && !scopeready) {
+ ALOGV("**WEAPON EVENT** disable scope mode");
+ sendButtonActionSimple("weapalt");
+ }
+ lastScopeReady = scopeready;
}
}
- //Open the datapad
- if (!canUseQuickSave) {
- if (((secondaryButtonsNew & secondaryButton2) !=
- (secondaryButtonsOld & secondaryButton2)) &&
- (secondaryButtonsNew & secondaryButton2)) {
- Sys_QueEvent( 0, SE_KEY, A_TAB, true, 0, NULL );
+ //ALOGV("**GB WEAPON ACTIVE** %i",vr.weaponid);
+ if (!scopeready && vr.weaponid >= 15 && vr.weaponid <= 17) {
+ lastScopeReady = false;
+ ALOGV("**WEAPON EVENT** disable scope mode forced");
+ sendButtonActionSimple("weapalt");
+ }
+
+ //Engage scope / virtual stock (iron sight lock) if conditions are right
+ static bool scopeEngaged = qfalse;
+ if (scopeEngaged != vr.scopeengaged) {
+ scopeEngaged = vr.scopeengaged;
+ }
+
+ //dominant hand stuff first
+ {
+ //Record recent weapon position for trajectory based stuff
+ for (int i = (NUM_WEAPON_SAMPLES - 1); i != 0; --i) {
+ VectorCopy(vr.weaponoffset_history[i - 1], vr.weaponoffset_history[i]);
+ vr.weaponoffset_history_timestamp[i] = vr.weaponoffset_history_timestamp[i - 1];
}
- }
+ VectorCopy(vr.weaponoffset, vr.weaponoffset_history[0]);
+ vr.weaponoffset_history_timestamp[0] = vr.weaponoffset_timestamp;
- //We need to record if we have started firing primary so that releasing trigger will stop definitely firing, if user has pushed grip
- //in meantime, then it wouldn't stop the gun firing and it would get stuck
- {
- //Run
- handleTrackedControllerButton(pOffTrackedRemoteNew,
- pOffTrackedRemoteOld,
- ovrButton_Trigger, A_SHIFT);
- }
+ VectorSet(vr.weaponposition, pWeapon->HeadPose.Pose.Position.x,
+ pWeapon->HeadPose.Pose.Position.y, pWeapon->HeadPose.Pose.Position.z);
- //Resync Yaw on mounted gun transition
- static int usingMountedGun = false;
- if (vr.mountedgun != usingMountedGun)
- {
- usingMountedGun = vr.mountedgun;
- }
+ ///Weapon location relative to view
+ VectorSet(vr.weaponoffset, pWeapon->HeadPose.Pose.Position.x,
+ pWeapon->HeadPose.Pose.Position.y, pWeapon->HeadPose.Pose.Position.z);
+ VectorSubtract(vr.weaponoffset, vr.hmdposition, vr.weaponoffset);
+ vr.weaponoffset_timestamp = Sys_Milliseconds();
- //No snap turn when using mounted gun
- static int syncCount = 0;
- static int increaseSnap = true;
- if (!vr.mountedgun && !vr.scopeengaged) {
- if (primaryJoystickX > 0.7f) {
- if (increaseSnap) {
- float turnAngle = vr_turn_mode->integer ? (vr_turn_angle->value / 9.0f) : vr_turn_angle->value;
- vr.snapTurn -= turnAngle;
+ vec3_t velocity;
+ VectorSet(velocity, pWeapon->HeadPose.LinearVelocity.x,
+ pWeapon->HeadPose.LinearVelocity.y, pWeapon->HeadPose.LinearVelocity.z);
+ vr.primaryswingvelocity = VectorLength(velocity);
- if (vr_turn_mode->integer == 0) {
- increaseSnap = false;
+ VectorSet(velocity, pOff->HeadPose.LinearVelocity.x,
+ pOff->HeadPose.LinearVelocity.y, pOff->HeadPose.LinearVelocity.z);
+ vr.secondaryswingvelocity = VectorLength(velocity);
+
+
+ //For melee right hand is alt attack and left hand is attack
+ if (vr.weaponid == WP_MELEE) {
+ //Does weapon velocity trigger attack (melee) and is it fast enough
+ if (vr.velocitytriggered) {
+ static bool fired = false;
+ vr.primaryVelocityTriggeredAttack = (vr.primaryswingvelocity >
+ vr_weapon_velocity_trigger->value);
+
+ if (fired != vr.primaryVelocityTriggeredAttack) {
+ ALOGV("**WEAPON EVENT** veocity triggered %s",
+ vr.primaryVelocityTriggeredAttack ? "+altattack" : "-altattack");
+ //normal attack is a punch with the left hand
+ sendButtonAction("+altattack", vr.primaryVelocityTriggeredAttack);
+ fired = vr.primaryVelocityTriggeredAttack;
}
+ } else if (vr.primaryVelocityTriggeredAttack) {
+ //send a stop attack as we have an unfinished velocity attack
+ vr.primaryVelocityTriggeredAttack = false;
+ ALOGV("**WEAPON EVENT** veocity triggered -altattack");
+ sendButtonAction("+altattack", vr.primaryVelocityTriggeredAttack);
+ }
- if (vr.snapTurn < -180.0f) {
- vr.snapTurn += 360.f;
+ if (vr.velocitytriggered) {
+ static bool fired = false;
+ vr.secondaryVelocityTriggeredAttack = (vr.secondaryswingvelocity >
+ vr_weapon_velocity_trigger->value);
+
+ if (fired != vr.secondaryVelocityTriggeredAttack) {
+ ALOGV("**WEAPON EVENT** veocity triggered %s",
+ vr.secondaryVelocityTriggeredAttack ? "+attack" : "-attack");
+ //normal attack is a punch with the left hand
+ sendButtonAction("+attack", vr.secondaryVelocityTriggeredAttack);
+ fired = vr.secondaryVelocityTriggeredAttack;
+ }
+ } else if (vr.secondaryVelocityTriggeredAttack) {
+ //send a stop attack as we have an unfinished velocity attack
+ vr.secondaryVelocityTriggeredAttack = qfalse;
+ ALOGV("**WEAPON EVENT** veocity triggered -attack");
+ sendButtonAction("+attack", vr.secondaryVelocityTriggeredAttack);
+ }
+ } else if (vr.weaponid == WP_SABER) {
+ //Does weapon velocity trigger attack
+ if (vr.velocitytriggered) {
+ static bool fired = false;
+ vr.primaryVelocityTriggeredAttack = (vr.primaryswingvelocity >
+ vr_weapon_velocity_trigger->value);
+
+ if (fired != vr.primaryVelocityTriggeredAttack) {
+ ALOGV("**WEAPON EVENT** veocity triggered %s",
+ vr.primaryVelocityTriggeredAttack ? "+attack" : "-attack");
+ //normal attack is a punch with the left hand
+ sendButtonAction("+attack", vr.primaryVelocityTriggeredAttack);
+ fired = vr.primaryVelocityTriggeredAttack;
+ }
+ } else if (vr.primaryVelocityTriggeredAttack) {
+ //send a stop attack as we have an unfinished velocity attack
+ vr.primaryVelocityTriggeredAttack = false;
+ ALOGV("**WEAPON EVENT** veocity triggered -attack");
+ sendButtonAction("+attack", vr.primaryVelocityTriggeredAttack);
+ }
+ }
+
+ if (vr.weapon_stabilised) {
+ if (vr.scopeengaged || vr_virtual_stock->integer == 1) {
+ //offset to the appropriate eye a little bit
+ vec2_t xy;
+ rotateAboutOrigin(Cvar_VariableValue("cg_stereoSeparation") / 2.0f, 0.0f,
+ -vr.hmdorientation[YAW], xy);
+ float x = pOff->HeadPose.Pose.Position.x - (vr.hmdposition[0] + xy[0]);
+ float y = pOff->HeadPose.Pose.Position.y -
+ (vr.hmdposition[1] - 0.1f); // Use a point lower
+ float z = pOff->HeadPose.Pose.Position.z - (vr.hmdposition[2] + xy[1]);
+ float zxDist = length(x, z);
+
+ if (zxDist != 0.0f && z != 0.0f) {
+ VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
+ -degrees(atan2f(x, -z)), 0);
+ }
+ } else {
+ float x =
+ pOff->HeadPose.Pose.Position.x - pWeapon->HeadPose.Pose.Position.x;
+ float y =
+ pOff->HeadPose.Pose.Position.y - pWeapon->HeadPose.Pose.Position.y;
+ float z =
+ pOff->HeadPose.Pose.Position.z - pWeapon->HeadPose.Pose.Position.z;
+ float zxDist = length(x, z);
+
+ if (zxDist != 0.0f && z != 0.0f) {
+ VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
+ -degrees(atan2f(x, -z)), vr.weaponangles[ROLL] /
+ 2.0f); //Dampen roll on stabilised weapon
}
}
- } else if (primaryJoystickX < 0.3f) {
- increaseSnap = true;
}
- static int decreaseSnap = true;
- if (primaryJoystickX < -0.7f) {
- if (decreaseSnap) {
+ // Calculate if player tries to reach backpack
+ bool handInBackpack = false;
+ bool bpDistToHMDOk = false, bpWeaponHeightOk = false, bpWeaponAngleOk = false, bpHmdToWeaponAngleOk = false;
+ vec3_t hmdForwardXY = {}, weaponForwardXY = {};
+ float weaponToDownAngle = 0, hmdToWeaponDotProduct = 0;
+ static vec3_t downVector = {0.0, 0.0, -1.0};
- float turnAngle = vr_turn_mode->integer ? (vr_turn_angle->value / 9.0f) : vr_turn_angle->value;
- vr.snapTurn += turnAngle;
-
- //If snap turn configured for less than 10 degrees
- if (vr_turn_mode->integer == 0) {
- decreaseSnap = false;
- }
-
- if (vr.snapTurn > 180.0f) {
- vr.snapTurn -= 360.f;
- }
- }
- } else if (primaryJoystickX > -0.3f) {
- decreaseSnap = true;
- }
- }
- else {
- if (fabs(primaryJoystickX) > 0.5f) {
- increaseSnap = false;
- }
- else
+ bool bpTrackOk = pOffTracking->Status &
+ VRAPI_TRACKING_STATUS_POSITION_TRACKED; // 1) Position must be tracked
+ if (bpTrackOk && (bpDistToHMDOk = distanceToHMD >= 0.2 && distanceToHMD <=
+ 0.35) // 2) Weapon-to-HMD distance must be within <0.2-0.35> range
+ && (bpWeaponHeightOk = vr.weaponoffset[1] >= -0.10 && vr.weaponoffset[1] <=
+ 0.10)) // 3) Weapon height in relation to HMD must be within <-0.10, 0.10> range
{
- increaseSnap = true;
+ AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL);
+ AngleVectors(vr.weaponangles, weaponForwardXY, NULL, NULL);
+
+ float weaponToDownAngle = AngleBetweenVectors(downVector, weaponForwardXY);
+ // 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees
+ if (bpWeaponAngleOk = weaponToDownAngle >= 80.0 && weaponToDownAngle <= 140.0) {
+ hmdForwardXY[2] = 0;
+ VectorNormalize(hmdForwardXY);
+
+ weaponForwardXY[2] = 0;
+ VectorNormalize(weaponForwardXY);
+
+ hmdToWeaponDotProduct = DotProduct(hmdForwardXY, weaponForwardXY);
+ // 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0)
+ handInBackpack = bpHmdToWeaponAngleOk = hmdToWeaponDotProduct < 0;
+ }
+ }
+
+ //off-hand stuff (done here as I reference it in the save state thing
+ {
+ vr.offhandposition[0] = pOff->HeadPose.Pose.Position.x;
+ vr.offhandposition[1] = pOff->HeadPose.Pose.Position.y;
+ vr.offhandposition[2] = pOff->HeadPose.Pose.Position.z;
+
+ vr.offhandoffset[0] = pOff->HeadPose.Pose.Position.x - vr.hmdposition[0];
+ vr.offhandoffset[1] = pOff->HeadPose.Pose.Position.y - vr.hmdposition[1];
+ vr.offhandoffset[2] = pOff->HeadPose.Pose.Position.z - vr.hmdposition[2];
+
+ vec3_t rotation = {0};
+ QuatToYawPitchRoll(pOff->HeadPose.Pose.Orientation, rotation, vr.offhandangles);
+
+ if (vr_walkdirection->value == 0) {
+ controllerYawHeading = vr.offhandangles[YAW] - vr.hmdorientation[YAW];
+ } else {
+ controllerYawHeading = 0.0f;
+ }
+ }
+
+ // Use off hand as well to trigger save condition
+ canUseQuickSave = false;
+ bool bpOffhandDistToHMDOk = false, bpOffhandHeightOk = false, bpOffhandAngleOk = false, bpHmdToOffhandAngleOk = false;
+ vec3_t offhandForwardXY = {};
+ float hmdToOffhandDotProduct = 0;
+ float offhandToDownAngle = 0;
+ if (bpTrackOk && (bpOffhandDistToHMDOk = distanceToHMDOff >= 0.2 &&
+ distanceToHMDOff <=
+ 0.35) // 2) Off-to-HMD distance must be within <0.2-0.35> range
+ && (bpOffhandHeightOk = vr.offhandoffset[1] >= -0.10 && vr.offhandoffset[1] <=
+ 0.10)) // 3) Offhand height in relation to HMD must be within <-0.10, 0.10> range
+ {
+ //Need to do this again as might not have done it above and cant be bothered to refactor
+ AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL);
+ AngleVectors(vr.offhandangles, offhandForwardXY, NULL, NULL);
+
+ offhandToDownAngle = AngleBetweenVectors(downVector, offhandForwardXY);
+
+ // 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees
+ if (bpOffhandAngleOk =
+ offhandToDownAngle >= 80.0 && offhandToDownAngle <= 140.0) {
+ hmdForwardXY[2] = 0;
+ VectorNormalize(hmdForwardXY);
+
+ offhandForwardXY[2] = 0;
+ VectorNormalize(offhandForwardXY);
+
+ hmdToOffhandDotProduct = DotProduct(hmdForwardXY, offhandForwardXY);
+ // 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0)
+ canUseQuickSave = bpHmdToOffhandAngleOk = hmdToOffhandDotProduct < 0;
+ }
+ }
+
+ // Uncomment to debug offhand reaching
+
+ ALOGV("Quick Save> Dist: %f | OffHandToDownAngle: %f | HandOffs: %f %f %f\nHmdHandDot: %f | HmdFwdXY: %f %f | WpnFwdXY: %f %f\nTrackOk: %i, DistOk: %i, HeightOk: %i, HnadAngleOk: %i, HmdHandDotOk: %i",
+ distanceToHMDOff, offhandToDownAngle, vr.offhandoffset[0],
+ vr.offhandoffset[1], vr.offhandoffset[2],
+ hmdToOffhandDotProduct, hmdForwardXY[0], hmdForwardXY[1], offhandForwardXY[0],
+ offhandForwardXY[1],
+ bpTrackOk, bpOffhandDistToHMDOk, bpOffhandHeightOk, bpOffhandAngleOk,
+ bpHmdToOffhandAngleOk);
+
+
+ // Check quicksave
+ if (canUseQuickSave) {
+ int channel = (vr_control_scheme->integer >= 10) ? 1 : 0;
+ JKVR_Vibrate(40, channel, 0.5); // vibrate to let user know they can switch
+
+ if (((pOffTrackedRemoteNew->Buttons & offButton1) !=
+ (pOffTrackedRemoteOld->Buttons & offButton1)) &&
+ (pOffTrackedRemoteNew->Buttons & offButton1)) {
+ sendButtonActionSimple("savegame quicksave");
+ }
+
+ if (((pOffTrackedRemoteNew->Buttons & offButton2) !=
+ (pOffTrackedRemoteOld->Buttons & offButton2)) &&
+ (pOffTrackedRemoteNew->Buttons & offButton2)) {
+ sendButtonActionSimple("loadgame quicksave");
+ }
}
}
- }
- updateScopeAngles();
+ //Right-hand specific stuff
+ {
+ //This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the
+ //player is facing for positional tracking
+
+ //Positional movement speed correction for when we are not hitting target framerate
+ static double lastframetime = 0;
+ int refresh = GetRefresh();
+ double newframetime = GetTimeInMilliSeconds();
+ float multiplier = (float) ((1000.0 / refresh) / (newframetime - lastframetime));
+ lastframetime = newframetime;
+
+ vec2_t v;
+ float factor = (refresh / 72.0F) *
+ vr_positional_factor->value; // adjust positional factor based on refresh rate
+ rotateAboutOrigin(-vr.hmdposition_delta[0] * factor * multiplier,
+ vr.hmdposition_delta[2] * factor * multiplier,
+ -vr.hmdorientation[YAW], v);
+ positional_movementSideways = v[0];
+ positional_movementForward = v[1];
+
+ ALOGV(" positional_movementSideways: %f, positional_movementForward: %f",
+ positional_movementSideways,
+ positional_movementForward);
+
+
+ //Jump (A Button)
+ if ((primaryButtonsNew & primaryButton1) != (primaryButtonsOld & primaryButton1)) {
+ sendButtonAction("+moveup", (primaryButtonsNew & primaryButton1));
+ }
+
+ //Alt Fire (B Button)
+ if ((primaryButtonsNew & primaryButton2) != (primaryButtonsOld & primaryButton2)) {
+ sendButtonAction("+altattack", (primaryButtonsNew & primaryButton2));
+ }
+
+
+ static bool firing = false;
+
+ {
+ //Fire Primary - Doesn't trigger the saber
+ if (!vr.velocitytriggered && // Don't fire velocity triggered weapons
+ (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) !=
+ (pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger)) {
+
+ ALOGV("**WEAPON EVENT** Not Grip Pushed %sattack",
+ (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) ? "+" : "-");
+ firing = (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger);
+ sendButtonAction("+attack", firing);
+ }
+ }
+
+
+ //Duck - off hand joystick
+ if ((secondaryButtonsNew & secondaryThumb) !=
+ (secondaryButtonsOld & secondaryThumb)) {
+
+ sendButtonAction("+movedown", (secondaryButtonsNew & secondaryThumb));
+ }
+
+ //Use
+ if ((pDominantTrackedRemoteNew->Buttons & primaryThumb) !=
+ (pDominantTrackedRemoteOld->Buttons & primaryThumb)) {
+
+ sendButtonAction("+use", (pDominantTrackedRemoteNew->Buttons & primaryThumb));
+ }
+ }
+
+ {
+ //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) + pFootTrackingNew->LeftJoystick.x;
+ float y = (nlf * pSecondaryJoystick->y) - pFootTrackingNew->LeftJoystick.y;
+
+ vr.player_moving = (fabs(x) + fabs(y)) > 0.05f;
+
+ //Adjust to be off-hand controller oriented
+ vec2_t v;
+ rotateAboutOrigin(x, y, controllerYawHeading, v);
+
+ //Move a lot slower if scope is engaged
+ remote_movementSideways =
+ v[0] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value;
+ remote_movementForward =
+ v[1] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value;
+ ALOGV(" remote_movementSideways: %f, remote_movementForward: %f",
+ remote_movementSideways,
+ remote_movementForward);
+
+
+ if (!canUseQuickSave) {
+ if ((secondaryButtonsNew & secondaryButton1) !=
+ (secondaryButtonsOld & secondaryButton1)) {
+ //Toggle walk/run somehow?!
+ }
+ }
+
+ //Open the datapad
+ if (!canUseQuickSave) {
+ if (((secondaryButtonsNew & secondaryButton2) !=
+ (secondaryButtonsOld & secondaryButton2)) &&
+ (secondaryButtonsNew & secondaryButton2)) {
+ Sys_QueEvent(0, SE_KEY, A_TAB, true, 0, NULL);
+ }
+ }
+
+ //Use Force - off hand trigger
+ {
+ if ((pOffTrackedRemoteNew->Buttons & ovrButton_Trigger) !=
+ (pOffTrackedRemoteOld->Buttons & ovrButton_Trigger)) {
+ sendButtonAction("+useforce", (pOffTrackedRemoteNew->Buttons & ovrButton_Trigger));
+ }
+ }
+
+ //Resync Yaw on mounted gun transition
+ static int usingMountedGun = false;
+ if (vr.mountedgun != usingMountedGun) {
+ usingMountedGun = vr.mountedgun;
+ }
+
+ //No snap turn when using mounted gun
+ static int syncCount = 0;
+ static int increaseSnap = true;
+ if (!vr.item_selector && !vr.mountedgun && !vr.scopeengaged) {
+ if (primaryJoystickX > 0.7f) {
+ if (increaseSnap) {
+ float turnAngle = vr_turn_mode->integer ? (vr_turn_angle->value / 9.0f)
+ : vr_turn_angle->value;
+ vr.snapTurn -= turnAngle;
+
+ if (vr_turn_mode->integer == 0) {
+ increaseSnap = false;
+ }
+
+ if (vr.snapTurn < -180.0f) {
+ vr.snapTurn += 360.f;
+ }
+ }
+ } else if (primaryJoystickX < 0.3f) {
+ increaseSnap = true;
+ }
+
+ static int decreaseSnap = true;
+ if (primaryJoystickX < -0.7f) {
+ if (decreaseSnap) {
+
+ float turnAngle = vr_turn_mode->integer ? (vr_turn_angle->value / 9.0f)
+ : vr_turn_angle->value;
+ vr.snapTurn += turnAngle;
+
+ //If snap turn configured for less than 10 degrees
+ if (vr_turn_mode->integer == 0) {
+ decreaseSnap = false;
+ }
+
+ if (vr.snapTurn > 180.0f) {
+ vr.snapTurn -= 360.f;
+ }
+ }
+ } else if (primaryJoystickX > -0.3f) {
+ decreaseSnap = true;
+ }
+ } else {
+ if (fabs(primaryJoystickX) > 0.5f) {
+ increaseSnap = false;
+ } else {
+ increaseSnap = true;
+ }
+ }
+ }
+
+ updateScopeAngles();
+ }
}
//Save state
diff --git a/Projects/Android/jni/OpenJK/code/client/cl_cin.cpp b/Projects/Android/jni/OpenJK/code/client/cl_cin.cpp
index 7cf2db8..cec1ac5 100644
--- a/Projects/Android/jni/OpenJK/code/client/cl_cin.cpp
+++ b/Projects/Android/jni/OpenJK/code/client/cl_cin.cpp
@@ -2015,6 +2015,76 @@ void CL_PlayInGameCinematic_f(void)
}
+// Text crawl defines
+#define TC_PLANE_WIDTH 250
+#define TC_PLANE_NEAR 90
+#define TC_PLANE_FAR 715
+#define TC_PLANE_TOP 0
+#define TC_PLANE_BOTTOM 1100
+
+#define TC_DELAY 9000
+#define TC_STOPTIME 81000
+void SCR_AddCreditTextCrawl()
+{
+ static int startTime = cls.realtime;
+ refdef_t refdef;
+ polyVert_t verts[4];
+
+ // Set up refdef
+ memset( &refdef, 0, sizeof( refdef ));
+
+ refdef.rdflags = RDF_NOWORLDMODEL;
+ AxisClear( refdef.viewaxis );
+
+ refdef.fov_x = 150;
+ refdef.fov_y = 150;
+
+ refdef.x = 0;
+ refdef.y = -50;
+ refdef.width = cls.glconfig.vidWidth;
+ refdef.height = cls.glconfig.vidHeight * 2; // deliberately extend off the bottom of the screen
+
+ // use to set shaderTime for scrolling shaders
+ refdef.time = 0;
+
+ // Set up the poly verts
+ float fadeDown = 1.0;
+ for ( int i = 0; i < 4; i++ )
+ {
+ verts[i].modulate[0] = 255*fadeDown; // gold color?
+ verts[i].modulate[1] = 235*fadeDown;
+ verts[i].modulate[2] = 127*fadeDown;
+ verts[i].modulate[3] = 255*fadeDown;
+ }
+
+ VectorScaleM( verts[2].modulate, 0.1f, verts[2].modulate ); // darken at the top??
+ VectorScaleM( verts[3].modulate, 0.1f, verts[3].modulate );
+
+ float timeoffset = (cls.realtime-startTime)*0.000015f -1;
+ VectorSet( verts[0].xyz, TC_PLANE_NEAR, -TC_PLANE_WIDTH, TC_PLANE_TOP );
+ verts[0].st[0] = 1;
+ verts[0].st[1] = 1 +timeoffset;
+
+ VectorSet( verts[1].xyz, TC_PLANE_NEAR, TC_PLANE_WIDTH, TC_PLANE_TOP );
+ verts[1].st[0] = 0;
+ verts[1].st[1] = 1 +timeoffset;
+
+ VectorSet( verts[2].xyz, TC_PLANE_FAR, TC_PLANE_WIDTH, TC_PLANE_BOTTOM );
+ verts[2].st[0] = 0;
+ verts[2].st[1] = 0 +timeoffset;
+
+ VectorSet( verts[3].xyz, TC_PLANE_FAR, -TC_PLANE_WIDTH, TC_PLANE_BOTTOM );
+ verts[3].st[0] = 1;
+ verts[3].st[1] = 0 +timeoffset;
+
+ // render it out
+ re.ClearScene();
+ re.AddPolyToScene( re.RegisterShaderNoMip( "menu/video/tc_demo" ), 4, verts );
+ re.RenderScene( &refdef );
+}
+
+
+
// Externally-called only, and only if cls.state == CA_CINEMATIC (or CL_IsRunningInGameCinematic() == true now)
//
void SCR_DrawCinematic (void)
diff --git a/Projects/Android/jni/OpenJK/code/client/cl_scrn.cpp b/Projects/Android/jni/OpenJK/code/client/cl_scrn.cpp
index dc0857d..df19f83 100644
--- a/Projects/Android/jni/OpenJK/code/client/cl_scrn.cpp
+++ b/Projects/Android/jni/OpenJK/code/client/cl_scrn.cpp
@@ -404,6 +404,7 @@ void SCR_Init( void ) {
void UI_SetActiveMenu( const char* menuname,const char *menuID );
void _UI_Refresh( int realtime );
void UI_DrawConnect( const char *servername, const char * updateInfoString );
+void SCR_AddCreditTextCrawl( void );
/*
==================
@@ -412,6 +413,7 @@ SCR_DrawScreenField
This will be called twice if rendering in stereo mode
==================
*/
+
void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {
re.BeginFrame( stereoFrame );
@@ -455,7 +457,6 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {
break;
}
}
-
re.ProcessDissolve();
// draw downloading progress bar
@@ -470,6 +471,11 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {
if ( cl_debuggraph->integer || cl_timegraph->integer ) {
SCR_DrawDebugGraph ();
}
+
+ if ( uiFullscreen )
+ {
+ SCR_AddCreditTextCrawl();
+ }
}
/*
diff --git a/Projects/Android/jni/OpenJK/code/game/bg_local.h b/Projects/Android/jni/OpenJK/code/game/bg_local.h
index 38d84b8..7e5ad28 100644
--- a/Projects/Android/jni/OpenJK/code/game/bg_local.h
+++ b/Projects/Android/jni/OpenJK/code/game/bg_local.h
@@ -83,6 +83,7 @@ void BG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles );
void BG_CalculateVRSaberPosition( vec3_t origin, vec3_t angles );
void BG_CalculateVROffHandPosition( vec3_t origin, vec3_t angles );
void BG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out);
+void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles );
#endif
diff --git a/Projects/Android/jni/OpenJK/code/game/bg_misc.cpp b/Projects/Android/jni/OpenJK/code/game/bg_misc.cpp
index 6c0e53c..81b736e 100644
--- a/Projects/Android/jni/OpenJK/code/game/bg_misc.cpp
+++ b/Projects/Android/jni/OpenJK/code/game/bg_misc.cpp
@@ -733,7 +733,7 @@ void BG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out)
}
}
-static void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles )
+void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles )
{
vec3_t offset;
VectorCopy(in_offset, offset);
diff --git a/Projects/Android/jni/OpenJK/code/game/weapons.h b/Projects/Android/jni/OpenJK/code/game/weapons.h
index 4bb063c..7845cd5 100644
--- a/Projects/Android/jni/OpenJK/code/game/weapons.h
+++ b/Projects/Android/jni/OpenJK/code/game/weapons.h
@@ -31,9 +31,6 @@ along with this program; if not, see .
#include "../qcommon/q_shared.h"
-//How fast the saber/melee needs to be physically swung in order to trigger sounds and trails etc
-#define WEAPON_VELOCITY_TRIGGER 1.6f
-
typedef enum //# weapon_e
{
WP_NONE,
diff --git a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_consolecmds.cpp b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_consolecmds.cpp
index 6a67a67..e1daca6 100644
--- a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_consolecmds.cpp
+++ b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_consolecmds.cpp
@@ -202,6 +202,10 @@ int cmdcmp( const void *a, const void *b ) {
return Q_stricmp( (const char *)a, ((consoleCommand_t*)b)->cmd );
}
+void CG_ItemSelectorSelect_f( void );
+void CG_ItemSelectorNext_f( void );
+void CG_ItemSelectorPrev_f( void );
+
/* This array MUST be sorted correctly by alphabetical name field */
static consoleCommand_t commands[] = {
{ "cam_disable", CMD_CGCam_Disable }, //gets out of camera mode for debuggin
@@ -239,6 +243,9 @@ static consoleCommand_t commands[] = {
{ "weapprev", CG_PrevWeapon_f },
{ "writecam", CG_WriteCam_f },
{ "zoom", CG_ToggleBinoculars },
+ { "itemselectorselect", CG_ItemSelectorSelect_f },
+ { "itemselectornext", CG_ItemSelectorNext_f },
+ { "itemselectorprev", CG_ItemSelectorPrev_f },
};
static const size_t numCommands = ARRAY_LEN( commands );
diff --git a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_draw.cpp b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_draw.cpp
index f657405..2bac5be 100644
--- a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_draw.cpp
+++ b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_draw.cpp
@@ -2582,7 +2582,9 @@ void CG_DrawActive( stereoFrame_t stereoView ) {
return;
}
- CG_DrawCrosshair3D();
+ if (!vr->item_selector) {
+ CG_DrawCrosshair3D();
+ }
//FIXME: these globals done once at start of frame for various funcs
AngleVectors (cg.refdefViewAngles, vfwd, vright, vup);
diff --git a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_local.h b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_local.h
index 5c6573e..5580a83 100644
--- a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_local.h
+++ b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_local.h
@@ -444,6 +444,13 @@ typedef struct {
int weaponAnimation;
int weaponAnimationTime;
+ int itemSelectorType; // 0 - weapons, 1 - force powers, 2 - gadgets
+ int itemSelectorSelection;
+ int itemSelectorTime;
+ vec3_t itemSelectorAngles;
+ vec3_t itemSelectorOrigin;
+ vec3_t itemSelectorOffset;
+
int inventorySelect; // Current inventory item chosen
int inventorySelectTime;
@@ -845,6 +852,8 @@ void CG_FireWeapon( centity_t *cent, qboolean alt_fire );
void CG_AddViewWeapon (playerState_t *ps);
void CG_DrawWeaponSelect( void );
+void CG_DrawItemSelector( void );
+
void CG_OutOfAmmoChange( void ); // should this be in pmove?
void CG_Chunks( int owner, vec3_t origin, const vec3_t normal, const vec3_t min, const vec3_t maxs,
float speed, int numChunks, material_t chunkType, int customChunk, float baseScale );
diff --git a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_main.cpp b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_main.cpp
index c8c54fe..2b9fdab 100644
--- a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_main.cpp
+++ b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_main.cpp
@@ -2535,7 +2535,7 @@ INVENTORY SELECTION
CG_InventorySelectable
===============
*/
-static qboolean CG_InventorySelectable( int index)
+qboolean CG_InventorySelectable( int index)
{
if (cg.snap->ps.inventory[index]) // Is there any in the inventory?
{
@@ -3524,7 +3524,9 @@ void CG_DrawForceSelect( void )
{
int w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 1.0f);
int x = ( SCREEN_WIDTH - w ) / 2;
- cgi_R_Font_DrawString(x, (SCREEN_HEIGHT / 2 + 50), text, colorTable[CT_ICON_BLUE], cgs.media.qhFontSmall, -1, 1.0f);
+ int y = (SCREEN_HEIGHT / 2 + 50);
+ CG_AdjustFrom640Int(&x, &y, NULL, NULL);
+ cgi_R_Font_DrawString(x, y, text, colorTable[CT_ICON_BLUE], cgs.media.qhFontSmall, -1, 1.0f);
}
}
diff --git a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_players.cpp b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_players.cpp
index b27a3bf..1e16780 100644
--- a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_players.cpp
+++ b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_players.cpp
@@ -3443,7 +3443,7 @@ void CG_AddRefEntityWithPowerups( refEntity_t *ent, int powerups, centity_t *cen
cgi_R_AddRefEntityToScene(ent);
}
- if (player1stPersonSaber && !cent->currentState.saberInFlight)
+ if (player1stPersonSaber && !cent->currentState.saberInFlight && !vr->item_selector)
{
memset( &hiltEnt, 0, sizeof(refEntity_t) );
hiltEnt.renderfx = RF_DEPTHHACK;
@@ -3459,14 +3459,11 @@ void CG_AddRefEntityWithPowerups( refEntity_t *ent, int powerups, centity_t *cen
cgi_R_AddRefEntityToScene(&hiltEnt);
static int playingSaberSwingSound = 0;
- if (vr->primaryswingvelocity > WEAPON_VELOCITY_TRIGGER && ((cg.time - playingSaberSwingSound) > 800))
+ if (vr->primaryVelocityTriggeredAttack && ((cg.time - playingSaberSwingSound) > 800))
{
cgi_S_StartSound ( hiltEnt.origin, cent->gent->s.number, CHAN_AUTO, cgi_S_RegisterSound( va( "sound/weapons/saber/saberhup%d.wav", Q_irand( 1, 9 ) ) ) );
playingSaberSwingSound = cg.time;
}
-
- //Try setting ent to be the hilt entity, then any subsequent effects below are applied to that instead
- ent = &hiltEnt;
}
// Disruptor Gun Alt-fire
@@ -4457,6 +4454,11 @@ void CG_AddSaberBlade( centity_t *cent, centity_t *scent, refEntity_t *saber, in
return;
}
+ if (vr->item_selector)
+ {
+ return;
+ }
+
/*
Ghoul2 Insert Start
*/
@@ -5549,60 +5551,70 @@ extern vmCvar_t cg_thirdPersonAlpha;
}
}
}
+ }
- //play special force effects
- if ( cent->gent->NPC && ( cent->gent->NPC->confusionTime > cg.time || cent->gent->NPC->charmedTime > cg.time || cent->gent->NPC->controlledTime > cg.time) )
- {// we are currently confused, so play an effect at the headBolt position
- theFxScheduler.PlayEffect( cgs.effects.forceConfusion, cent->gent->client->renderInfo.eyePoint );
+ //play special force effects
+ if ( cent->gent->NPC && ( cent->gent->NPC->confusionTime > cg.time || cent->gent->NPC->charmedTime > cg.time || cent->gent->NPC->controlledTime > cg.time) )
+ {// we are currently confused, so play an effect at the headBolt position
+ theFxScheduler.PlayEffect( cgs.effects.forceConfusion, cent->gent->client->renderInfo.eyePoint );
+ }
+
+ if ( cent->gent->client && cent->gent->forcePushTime > cg.time )
+ {//being pushed
+ CG_ForcePushBodyBlur( cent, ent.origin, tempAngles );
+ }
+
+ if ( cent->gent->client->ps.powerups[PW_FORCE_PUSH] > cg.time || (cent->gent->client->ps.forcePowersActive & (1<gent->client->renderInfo.handLPoint );
+ }
+
+ if ( cent->gent->client->ps.eFlags & EF_FORCE_GRIPPED )
+ {//being gripped
+ CG_ForcePushBlur( cent->gent->client->renderInfo.headPoint );
+ }
+
+ if ( cent->gent->client && cent->gent->client->ps.powerups[PW_SHOCKED] > cg.time )
+ {//being electrocuted
+ CG_ForceElectrocution( cent, ent.origin, tempAngles );
+ }
+
+ if ( cent->gent->client->ps.forcePowersActive&(1<gent->client->ps.clientNum == 0)
+ {
+ vec3_t origin, angles;
+ BG_CalculateVROffHandPosition(origin, tAng);
}
-
- if ( cent->gent->client && cent->gent->forcePushTime > cg.time )
- {//being pushed
- CG_ForcePushBodyBlur( cent, ent.origin, tempAngles );
- }
-
- if ( cent->gent->client->ps.powerups[PW_FORCE_PUSH] > cg.time || (cent->gent->client->ps.forcePowersActive & (1<gent->client->renderInfo.handLPoint );
- }
-
- if ( cent->gent->client->ps.eFlags & EF_FORCE_GRIPPED )
- {//being gripped
- CG_ForcePushBlur( cent->gent->client->renderInfo.headPoint );
- }
-
- if ( cent->gent->client && cent->gent->client->ps.powerups[PW_SHOCKED] > cg.time )
- {//being electrocuted
- CG_ForceElectrocution( cent, ent.origin, tempAngles );
- }
-
- if ( cent->gent->client->ps.forcePowersActive&(1<lerpAngles, tAng );
- /*
- if ( cent->currentState.number )
- {
- VectorSet( tAng, cent->pe.torso.pitchAngle, cent->pe.torso.yawAngle, 0 );
- }
- else
- {//FIXME: this dir looks right on players, but not on NPCs, NPCs pe angles are absolute, not relative?
- VectorSet( tAng, tempAngles[0]+cent->pe.torso.pitchAngle, tempAngles[1]+cent->pe.torso.yawAngle, 0 );
- }
- */
- if ( cent->gent->client->ps.forcePowerLevel[FP_LIGHTNING] > FORCE_LEVEL_2 )
- {//arc
- vec3_t fxAxis[3];
- AnglesToAxis( tAng, fxAxis );
- theFxScheduler.PlayEffect( cgs.effects.forceLightningWide, cent->gent->client->renderInfo.handLPoint, fxAxis );
- }
- else
- {//line
- AngleVectors( tAng, fxDir, NULL, NULL );
- theFxScheduler.PlayEffect( cgs.effects.forceLightning, cent->gent->client->renderInfo.handLPoint, fxDir );
- }
+ }
+
+ /*
+ if ( cent->currentState.number )
+ {
+ VectorSet( tAng, cent->pe.torso.pitchAngle, cent->pe.torso.yawAngle, 0 );
+ }
+ else
+ {//FIXME: this dir looks right on players, but not on NPCs, NPCs pe angles are absolute, not relative?
+ VectorSet( tAng, tempAngles[0]+cent->pe.torso.pitchAngle, tempAngles[1]+cent->pe.torso.yawAngle, 0 );
+ }
+ */
+ if ( cent->gent->client->ps.forcePowerLevel[FP_LIGHTNING] > FORCE_LEVEL_2 )
+ {//arc
+ vec3_t fxAxis[3];
+ AnglesToAxis( tAng, fxAxis );
+ theFxScheduler.PlayEffect( cgs.effects.forceLightningWide, cent->gent->client->renderInfo.handLPoint, fxAxis );
+ }
+ else
+ {//line
+ AngleVectors( tAng, fxDir, NULL, NULL );
+ theFxScheduler.PlayEffect( cgs.effects.forceLightning, cent->gent->client->renderInfo.handLPoint, fxDir );
}
}
+
//As good a place as any, I suppose, to do this keyframed sound thing
CGG2_AnimSounds( cent );
//setup old system for gun to look at
diff --git a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_view.cpp b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_view.cpp
index f3b443f..560fce5 100644
--- a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_view.cpp
+++ b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_view.cpp
@@ -30,6 +30,7 @@ along with this program; if not, see .
#include "../game/wp_saber.h"
#include "../game/anims.h"
#include "../game/g_functions.h"
+#include "bg_local.h"
#include
#define MASK_CAMERACLIP (MASK_SOLID)
@@ -1309,7 +1310,7 @@ qboolean CG_CalcFOVFromX( float fov_x )
return (inwater);
}
-float CG_ForceSpeedFOV( void )
+float CG_ForceSpeedFOV( float infov )
{
gentity_t *player = &g_entities[0];
float fov;
@@ -1318,15 +1319,15 @@ float CG_ForceSpeedFOV( void )
float amt = forceSpeedFOVMod[player->client->ps.forcePowerLevel[FP_SPEED]];
if ( timeLeft < 500 )
{//start going back
- fov = cg_fov.value + (timeLeft)/500*amt;
+ fov = infov + (timeLeft)/500*amt;
}
else if ( length - timeLeft < 1000 )
{//start zooming in
- fov = cg_fov.value + (length - timeLeft)/1000*amt;
+ fov = infov + (length - timeLeft)/1000*amt;
}
else
{//stay at this FOV
- fov = cg_fov.value+amt;
+ fov = infov+amt;
}
return fov;
}
@@ -1357,7 +1358,7 @@ static qboolean CG_CalcFov( void ) {
g_entities[cg.snap->ps.viewEntity].NPC )
{//FIXME: looks bad when take over a jedi... but never really do that, do we?
//fov_x = g_entities[cg.snap->ps.viewEntity].NPC->stats.hfov;
- fov_x = vr ? vr->fov : 90.0f;
+ fov_x = vr ? vr->fov : cg_fov.value;
//sanity-cap?
if ( fov_x > 120 )
{
@@ -1377,13 +1378,13 @@ static qboolean CG_CalcFov( void ) {
else
{
//fov_x = 120;//FIXME: read from the NPC's fov stats?
- fov_x = vr ? vr->fov : 90.0f;
+ fov_x = vr ? vr->fov : cg_fov.value;
}
}
}
else if ( (!cg.zoomMode || cg.zoomMode > 2) && (cg.snap->ps.forcePowersActive&(1<client->ps.forcePowerDuration[FP_SPEED] )//cg.renderingThirdPerson &&
{
- fov_x = CG_ForceSpeedFOV();
+ fov_x = CG_ForceSpeedFOV(vr ? vr->fov : cg_fov.value);
} else {
/*
// user selectable
@@ -1401,7 +1402,7 @@ static qboolean CG_CalcFov( void ) {
fov_x = 160;
}*/
- fov_x = vr ? vr->fov : 90.0f;
+ fov_x = vr ? vr->fov : cg_fov.value;
// Disable zooming when in third person
if ( cg.zoomMode && cg.zoomMode < 3 )//&& !cg.renderingThirdPerson ) // light amp goggles do none of the zoom silliness
@@ -1987,18 +1988,55 @@ wasForceSpeed=isForceSpeed;
cgi_CM_SnapPVS( cg.refdef.vieworg, cg.snap->areamask );
}
- // Don't draw the in-view weapon when in camera mode
- if ( !in_camera
- && !cg_pano.integer
- && cg.snap->ps.weapon != WP_SABER
- && ( cg.snap->ps.viewEntity == 0 || cg.snap->ps.viewEntity >= ENTITYNUM_WORLD ) )
+
+
+ if (vr->item_selector)
{
- CG_AddViewWeapon( &cg.predicted_player_state );
+ CG_DrawItemSelector();
}
- else if( cg.snap->ps.viewEntity != 0 && cg.snap->ps.viewEntity < ENTITYNUM_WORLD &&
- g_entities[cg.snap->ps.viewEntity].client)
- {
- CG_AddViewWeapon( &g_entities[cg.snap->ps.viewEntity ].client->ps ); // HAX - because I wanted to --eez
+ else {
+ // Don't draw the in-view weapon when in camera mode
+ if (!in_camera
+ && !cg_pano.integer
+ && cg.snap->ps.weapon != WP_SABER
+ && (cg.snap->ps.viewEntity == 0 || cg.snap->ps.viewEntity >= ENTITYNUM_WORLD)) {
+ CG_AddViewWeapon(&cg.predicted_player_state);
+ } else if (cg.snap->ps.viewEntity != 0 && cg.snap->ps.viewEntity < ENTITYNUM_WORLD &&
+ g_entities[cg.snap->ps.viewEntity].client) {
+ CG_AddViewWeapon(
+ &g_entities[cg.snap->ps.viewEntity].client->ps); // HAX - because I wanted to --eez
+ }
+
+ if (!in_camera
+ && !cg.renderingThirdPerson
+ && cg.predicted_player_state.stats[STAT_HEALTH] > 0
+ && !vr->weapon_stabilised
+ && !cg_pano.integer
+ && (cg.snap->ps.viewEntity == 0 || cg.snap->ps.viewEntity >= ENTITYNUM_WORLD))
+ {
+ vec3_t end, forward;
+ refEntity_t handEnt;
+ memset( &handEnt, 0, sizeof(refEntity_t) );
+ BG_CalculateVROffHandPosition(handEnt.origin, handEnt.angles);
+ AngleVectors(handEnt.angles, forward, NULL, NULL);
+ VectorMA( handEnt.origin, 8.0f, forward, end );
+
+ //If the current force power is directional, show the nav arrow from off-hand for now
+ if (showPowers[cg.forcepowerSelect] >= FP_PUSH) {
+ vec3_t color = {0.0f, 1.0f, 0.0f};
+ FX_AddLine(handEnt.origin, end, 0.1f, 1.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ color, color, 0.0f,
+ 60, cgi_R_RegisterShader("gfx/misc/nav_line"),
+ FX_SIZE_LINEAR | FX_ALPHA_LINEAR);
+ }
+
+ handEnt.renderfx = RF_DEPTHHACK;
+ handEnt.hModel = cgi_R_RegisterModel( "models/weapons2/thermal/thermal_hand.md3" );
+ VectorCopy(handEnt.origin, handEnt.oldorigin);
+ AnglesToAxis(handEnt.angles, handEnt.axis);
+ cgi_R_AddRefEntityToScene(&handEnt);
+ }
}
if ( !cg.hyperspace )
diff --git a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_weapons.cpp b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_weapons.cpp
index 871131e..5d7852a 100644
--- a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_weapons.cpp
+++ b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_weapons.cpp
@@ -975,7 +975,7 @@ Add the weapon, and flash for the player's view
==============
*/
extern int PM_TorsoAnimForFrame( gentity_t *ent, int torsoFrame );
-extern float CG_ForceSpeedFOV( void );
+extern float CG_ForceSpeedFOV( float infov );
void CG_AddViewWeapon( playerState_t *ps )
{
@@ -1066,7 +1066,7 @@ void CG_AddViewWeapon( playerState_t *ps )
gentity_t *player = &g_entities[0];
if ( (cg.snap->ps.forcePowersActive&(1<client->ps.forcePowerDuration[FP_SPEED] )//cg.renderingThirdPerson &&
{
- actualFOV = CG_ForceSpeedFOV();
+ actualFOV = CG_ForceSpeedFOV(cg_fov.value);
actualFOV = (cg_fovViewmodel.integer) ? actualFOV + (cg_fovViewmodel.integer - cg_fov.integer) : actualFOV;
}
else
@@ -1124,25 +1124,26 @@ void CG_AddViewWeapon( playerState_t *ps )
trace_t trace;
VectorMA(origin, 256, forward, endForward);
- static vec3_t WHITE ={1.0f,1.0f,1.0f};
+ static vec3_t RED = {1.0f,0.0f,0.0f};
FX_AddLine( origin, endForward, 0.1f, 4.0f, 0.0f,
1.0f, 0.0f, 0.0f,
- WHITE, WHITE, 0.0f,
- 120, cgi_R_RegisterShader( "gfx/effects/redLine" ),
+ RED, RED, 0.0f,
+ 120, cgi_R_RegisterShader( "gfx/effects/whiteline2" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
VectorMA(origin, 20, right, endRight);
- vec3_t color = { 0, 0, 255 };
+ vec3_t BLUE = {0.0f,0.0f,1.0f};
FX_AddLine( origin, endRight, 0.1f, 4.0f, 0.0f,
1.0f, 0.0f, 0.0f,
- color, color, 0.0f,
- 120, cgi_R_RegisterShader( "gfx/misc/nav_line" ),
+ BLUE, BLUE, 0.0f,
+ 120, cgi_R_RegisterShader( "gfx/misc/whiteline2" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
VectorMA(origin, 20, up, endUp);
+ vec3_t GREEN = {0.0f,1.0f,0.0f};
FX_AddLine( origin, endUp, 0.1f, 4.0f, 0.0f,
1.0f, 0.0f, 0.0f,
- WHITE, WHITE, 0.0f,
+ GREEN, GREEN, 0.0f,
120, cgi_R_RegisterShader( "gfx/misc/whiteline2" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
@@ -2141,7 +2142,9 @@ void CG_DrawWeaponSelect( void )
{
int w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 1.0f);
int x = ( SCREEN_WIDTH - w ) / 2;
- cgi_R_Font_DrawString(x, (SCREEN_HEIGHT - 24), text, textColor, cgs.media.qhFontSmall, -1, 1.0f);
+ int y = (SCREEN_HEIGHT - 24);
+ CG_AdjustFrom640Int(&x, &y, NULL, NULL);
+ cgi_R_Font_DrawString(x, y, text, textColor, cgs.media.qhFontSmall, -1, 1.0f);
}
}
@@ -2644,6 +2647,276 @@ void CG_Weapon_f( void )
cg.weaponSelect = num;
}
+
+void Cmd_UseInventory_f(gentity_t *ent);
+
+//Selects the currently selected thing (if one _is_ selected)
+void CG_ItemSelectorSelect_f( void )
+{
+ cg.itemSelectorTime = 0;
+ cgi_Cvar_Set("timescale", "1.0");
+
+ if (cg.itemSelectorSelection == -1)
+ {
+ cg.itemSelectorType = 0;
+ return;
+ }
+
+ if (cg.itemSelectorType == 0)
+ {
+ if (cg.weaponSelect == cg.itemSelectorSelection)
+ {
+ return;
+ }
+
+ cg.weaponSelectTime = cg.time;
+ cg.weaponSelect = cg.itemSelectorSelection;
+ }
+ else if (cg.itemSelectorType == 1)
+ {
+ if (cg.forcepowerSelect == cg.itemSelectorSelection)
+ {
+ return;
+ }
+
+ cg.forcepowerSelectTime = cg.time;
+ cg.forcepowerSelect = cg.itemSelectorSelection;
+ }
+ else if (cg.itemSelectorType == 2)
+ {
+ cg.inventorySelectTime = cg.time;
+ cg.inventorySelect = cg.itemSelectorSelection;
+
+ //Immediately use the selected inventory item
+ if (player)
+ {
+ Cmd_UseInventory_f(player);
+ }
+ }
+
+ //reset ready for next time
+ cg.itemSelectorType = 0;
+ cg.itemSelectorSelection = -1;
+}
+
+void CG_ItemSelectorNext_f( void )
+{
+ cg.itemSelectorType = (cg.itemSelectorType+1) % 3;
+ cg.itemSelectorTime = cg.time;
+}
+
+void CG_ItemSelectorPrev_f( void )
+{
+ if (--cg.itemSelectorType < 0)
+ cg.itemSelectorType = 2;
+ cg.itemSelectorTime = cg.time;
+}
+
+extern int force_icons[NUM_FORCE_POWERS];
+extern int inv_icons[INV_MAX];
+qboolean CG_InventorySelectable( int index);
+qboolean ForcePower_Valid(int index);
+
+void CG_DrawItemSelector( void )
+{
+ if (cg.itemSelectorTime == 0)
+ {
+ cg.itemSelectorTime = cg.time;
+ VectorCopy(vr->weaponangles, cg.itemSelectorAngles);
+ VectorCopy(vr->weaponposition, cg.itemSelectorOrigin);
+ VectorCopy(vr->weaponoffset, cg.itemSelectorOffset);
+ }
+
+ float dist = 10.0f;
+ float radius = 4.4f;
+ float scale = 0.05f;
+
+ float frac = (cg.time - cg.itemSelectorTime) / 20.0f;
+ if (frac > 1.0f)
+ {
+ frac = 1.0f;
+ }
+ cgi_Cvar_Set("timescale", "0.22");
+
+ vec3_t controllerOrigin, controllerAngles, controllerOffset, selectorOrigin;
+ BG_CalculateVRWeaponPosition(controllerOrigin, controllerAngles);
+ VectorSubtract(vr->weaponposition, cg.itemSelectorOrigin, controllerOffset);
+
+ vec3_t wheelAngles, wheelOrigin, beamOrigin, wheelForward, wheelRight, wheelUp;
+ BG_CalculateVRPositionInWorld(cg.itemSelectorOrigin, cg.itemSelectorOffset, cg.itemSelectorAngles, wheelOrigin, wheelAngles);
+
+ AngleVectors(wheelAngles, wheelForward, wheelRight, wheelUp);
+ VectorCopy(controllerOrigin, wheelOrigin);
+
+ VectorCopy(wheelOrigin, beamOrigin);
+ VectorMA(wheelOrigin, (dist * frac), wheelForward, wheelOrigin);
+ VectorCopy(wheelOrigin, selectorOrigin);
+
+ vec3_t pos;
+ memset(&pos, 0, sizeof pos);
+ {
+ pos[0] = (sinf(DEG2RAD(wheelAngles[YAW] - controllerAngles[YAW])) / sinf(DEG2RAD(22.5f)));
+ pos[1] = ((wheelAngles[PITCH] - controllerAngles[PITCH]) / 22.5f);
+
+ float len = VectorLength(pos);
+ if (len > 1.0f)
+ {
+ pos[0] *= (1.0f / len);
+ pos[1] *= (1.0f / len);
+ }
+ }
+
+ VectorMA(selectorOrigin, radius * pos[0], wheelRight, selectorOrigin);
+ VectorMA(selectorOrigin, radius * pos[1], wheelUp, selectorOrigin);
+
+ {
+ vec3_t color = { 0, 0, 255 };
+ FX_AddLine( beamOrigin, selectorOrigin, 0.1f, 1.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ color, color, 0.0f,
+ 60, cgi_R_RegisterShader( "gfx/misc/nav_line" ),
+ FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
+
+ }
+
+ int count;
+ switch (cg.itemSelectorType)
+ {
+ case 0: //weapons
+ count = WP_EMPLACED_GUN;
+ break;
+ case 1: // force powers
+ count = MAX_SHOWPOWERS;
+ break;
+ case 2: //gadgets
+ count = INV_GOODIE_KEY;
+ break;
+ }
+
+ qboolean selected = qfalse;
+ for (int index = 0; index < count; ++index)
+ {
+ int itemId = index;
+ if (cg.itemSelectorType == 0) {
+ itemId = index+1; // We need to ignore WP_NONE for weapons
+ if (itemId == count)
+ {
+ break;
+ }
+
+ if (itemId == WP_SABER ||
+ itemId == WP_BRYAR_PISTOL ||
+ itemId == WP_BLASTER ||
+ itemId == WP_FLECHETTE ||
+ itemId == WP_REPEATER ||
+ itemId == WP_THERMAL) {
+ CG_RegisterWeapon(itemId);
+ } else {
+ continue;
+ }
+ }
+
+ {
+ bool selectable;
+ switch (cg.itemSelectorType)
+ {
+ case 0: //weapons
+ selectable = CG_WeaponSelectable(itemId, cg.weaponSelect, qfalse) && cg.snap->ps.ammo[weaponData[itemId].ammoIndex];
+ break;
+ case 1: // force powers
+ selectable = ForcePower_Valid(itemId);
+ break;
+ case 2: //gadgets
+ selectable = CG_InventorySelectable(itemId) && inv_icons[itemId];
+ break;
+ }
+
+ if (selectable) {
+ //first calculate wheel slot position
+ vec3_t angles, iconOrigin, iconBackground, iconForeground;
+ VectorClear(angles);
+ angles[YAW] = wheelAngles[YAW];
+ angles[PITCH] = wheelAngles[PITCH];
+ angles[ROLL] =
+ (360 / count) * (itemId - 1);
+ vec3_t forward, up;
+ AngleVectors(angles, forward, NULL, up);
+
+ VectorMA(wheelOrigin, (radius * frac), up, iconOrigin);
+ VectorMA(iconOrigin, 0.2f, forward, iconBackground);
+ VectorMA(iconOrigin, -0.2f, forward, iconForeground);
+
+ {
+ vec3_t diff;
+ VectorSubtract(selectorOrigin, iconOrigin, diff);
+ float length = VectorLength(diff);
+ if (length <= 1.0f &&
+ frac == 1.0f &&
+ selectable) {
+ if (cg.itemSelectorSelection != itemId) {
+ cg.itemSelectorSelection = itemId;
+ //trap_HapticEvent("selector_icon", 0, 0, 100, 0, 0);
+ }
+
+ selected = qtrue;
+ }
+ }
+
+ if (cg.itemSelectorSelection == itemId) {
+ refEntity_t sprite;
+ memset(&sprite, 0, sizeof(sprite));
+ VectorCopy(iconOrigin, sprite.origin);
+ sprite.origin[2] += 2.5f + (0.5f * sinf(DEG2RAD(
+ AngleNormalize360(cg.time - cg.itemSelectorTime))));
+ sprite.reType = RT_SPRITE;
+ sprite.customShader = cgs.media.binocularArrow;
+ sprite.radius = 0.6f;
+ sprite.shaderRGBA[0] = 255;
+ sprite.shaderRGBA[1] = 255;
+ sprite.shaderRGBA[2] = 255;
+ sprite.shaderRGBA[3] = 255;
+ cgi_R_AddRefEntityToScene(&sprite);
+ }
+
+ {
+ refEntity_t sprite;
+ memset(&sprite, 0, sizeof(sprite));
+
+ float sRadius = 1.3f;
+
+ VectorCopy(iconOrigin, sprite.origin);
+ sprite.reType = RT_SPRITE;
+ switch (cg.itemSelectorType)
+ {
+ case 0: //weapons
+ sprite.customShader = cg_weapons[itemId].weaponIcon;
+ break;
+ case 1: // force powers
+ sprite.customShader = force_icons[showPowers[itemId]];
+ break;
+ case 2: //gadgets
+ sprite.customShader = inv_icons[itemId];
+ break;
+ }
+
+ sprite.radius =
+ sRadius * (cg.itemSelectorSelection == itemId ? 1.3f : 0.6f);
+ sprite.shaderRGBA[0] = 255;
+ sprite.shaderRGBA[1] = 255;
+ sprite.shaderRGBA[2] = 255;
+ sprite.shaderRGBA[3] = 255;
+ cgi_R_AddRefEntityToScene(&sprite);
+ }
+ }
+ }
+ }
+
+ if (!selected)
+ {
+ cg.itemSelectorSelection = -1;
+ }
+}
+
/*
===================
CG_OutOfAmmoChange
diff --git a/Projects/Android/jni/OpenJK/codeJK2/game/bg_local.h b/Projects/Android/jni/OpenJK/codeJK2/game/bg_local.h
index 38d84b8..7e5ad28 100644
--- a/Projects/Android/jni/OpenJK/codeJK2/game/bg_local.h
+++ b/Projects/Android/jni/OpenJK/codeJK2/game/bg_local.h
@@ -83,6 +83,7 @@ void BG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles );
void BG_CalculateVRSaberPosition( vec3_t origin, vec3_t angles );
void BG_CalculateVROffHandPosition( vec3_t origin, vec3_t angles );
void BG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out);
+void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles );
#endif
diff --git a/Projects/Android/jni/OpenJK/codeJK2/game/bg_misc.cpp b/Projects/Android/jni/OpenJK/codeJK2/game/bg_misc.cpp
index 6716fb0..1f5ec73 100644
--- a/Projects/Android/jni/OpenJK/codeJK2/game/bg_misc.cpp
+++ b/Projects/Android/jni/OpenJK/codeJK2/game/bg_misc.cpp
@@ -674,7 +674,7 @@ void BG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out)
}
}
-static void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles )
+void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles )
{
vec3_t offset;
VectorCopy(in_offset, offset);
diff --git a/Projects/Android/jni/OpenJK/codeJK2/game/weapons.h b/Projects/Android/jni/OpenJK/codeJK2/game/weapons.h
index c3f601a..f796fc6 100644
--- a/Projects/Android/jni/OpenJK/codeJK2/game/weapons.h
+++ b/Projects/Android/jni/OpenJK/codeJK2/game/weapons.h
@@ -31,9 +31,6 @@ along with this program; if not, see .
#include "../../code/qcommon/q_shared.h"
-//How fast the saber/melee needs to be physically swung in order to trigger sounds and trails
-#define WEAPON_VELOCITY_TRIGGER 1.6f
-
typedef enum //# weapon_e
{
WP_NONE,
diff --git a/Projects/Android/jni/OpenJK/codeJK2/game/wp_saber.cpp b/Projects/Android/jni/OpenJK/codeJK2/game/wp_saber.cpp
index bc9b6d1..74046de 100644
--- a/Projects/Android/jni/OpenJK/codeJK2/game/wp_saber.cpp
+++ b/Projects/Android/jni/OpenJK/codeJK2/game/wp_saber.cpp
@@ -5706,7 +5706,15 @@ void ForceThrow( gentity_t *self, qboolean pull )
G_Sound( self, soundIndex );
- VectorCopy( self->client->ps.viewangles, fwdangles );
+ if (self->client->ps.clientNum == 0)
+ {
+ vec3_t origin, angles;
+ BG_CalculateVROffHandPosition(origin, fwdangles);
+ }
+ else
+ {
+ VectorCopy( self->client->ps.viewangles, fwdangles );
+ }
//fwdangles[1] = self->client->ps.viewangles[1];
AngleVectors( fwdangles, forward, right, NULL );
VectorCopy( self->currentOrigin, center );
@@ -6226,7 +6234,16 @@ void ForceThrow( gentity_t *self, qboolean pull )
vec3_t pushDir;
float damage = 800;
- AngleVectors( self->client->ps.viewangles, forward, NULL, NULL );
+ if (self->client->ps.clientNum == 0)
+ {
+ vec3_t origin, angles;
+ BG_CalculateVROffHandPosition(origin, angles);
+ AngleVectors(angles, forward, right, NULL);
+ }
+ else
+ {
+ AngleVectors(self->client->ps.viewangles, forward, right, NULL);
+ }
VectorNormalize( forward );
VectorMA( self->client->renderInfo.eyePoint, radius, forward, end );
gi.trace( &tr, self->client->renderInfo.eyePoint, vec3_origin, vec3_origin, end, self->s.number, MASK_SHOT, G2_NOCOLLIDE, 0 );
@@ -6937,7 +6954,16 @@ void ForceGrip( gentity_t *self )
self->client->ps.weaponTime = floor( self->client->ps.weaponTime * g_timescale->value );
}
- AngleVectors( self->client->ps.viewangles, forward, NULL, NULL );
+ if (self->client->ps.clientNum == 0)
+ {
+ vec3_t origin, angles;
+ BG_CalculateVROffHandPosition(origin, angles);
+ AngleVectors(angles, forward, NULL, NULL);
+ }
+ else
+ {
+ AngleVectors(self->client->ps.viewangles, forward, NULL, NULL);
+ }
VectorNormalize( forward );
VectorMA( self->client->renderInfo.handLPoint, FORCE_GRIP_DIST, forward, end );
@@ -7259,7 +7285,17 @@ void ForceShootLightning( gentity_t *self )
return;
}
- AngleVectors( self->client->ps.viewangles, forward, NULL, NULL );
+ if (self->client->ps.clientNum == 0)
+ {
+ vec3_t origin, angles;
+ BG_CalculateVROffHandPosition(origin, angles);
+ AngleVectors(angles, forward, NULL, NULL);
+ }
+ else
+ {
+ AngleVectors(self->client->ps.viewangles, forward, NULL, NULL);
+ }
+
VectorNormalize( forward );
//FIXME: if lightning hits water, do water-only-flagged radius damage from that point