diff --git a/Projects/Android/AndroidManifest.xml b/Projects/Android/AndroidManifest.xml index 954a248..8b0772c 100644 --- a/Projects/Android/AndroidManifest.xml +++ b/Projects/Android/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="56" + android:versionName="1.1.4" android:installLocation="auto" > @@ -21,7 +21,7 @@ android:icon="@drawable/ic_jkxr" android:label="@string/jkxr" android:extractNativeLibs="true" - > + android:requestLegacyExternalStorage="true" > diff --git a/Projects/Android/build.gradle b/Projects/Android/build.gradle index 6eff78c..555a7ef 100644 --- a/Projects/Android/build.gradle +++ b/Projects/Android/build.gradle @@ -24,8 +24,8 @@ android { } } - minSdkVersion 26 - targetSdkVersion 26 + minSdkVersion 29 + targetSdkVersion 29 } sourceSets { @@ -46,13 +46,13 @@ android { sourceCompatibility = '1.8' targetCompatibility = '1.8' } - compileSdkVersion = 26 - buildToolsVersion = '29.0.1' + compileSdkVersion = 29 + buildToolsVersion = '29.0.3' } dependencies { - implementation "com.android.support:support-compat:26.1.0" - implementation "com.android.support:support-core-utils:26.1.0" + implementation "com.android.support:support-compat:28.0.0" + implementation "com.android.support:support-core-utils:28.0.0" implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) } diff --git a/Projects/Android/jni/JKXR/JKXR_SurfaceView.cpp b/Projects/Android/jni/JKXR/JKXR_SurfaceView.cpp index 74a0f9d..978f714 100644 --- a/Projects/Android/jni/JKXR/JKXR_SurfaceView.cpp +++ b/Projects/Android/jni/JKXR/JKXR_SurfaceView.cpp @@ -18,6 +18,8 @@ extern "C" { } #include +#include +#include //#define ENABLE_GL_DEBUG @@ -48,7 +50,8 @@ JKXR Stuff bool VR_UseScreenLayer() { - vr.using_screen_layer = (bool)((vr.cin_camera && !vr.immersive_cinematics) || + vr.using_screen_layer = _UI_IsFullscreen() || + (bool)((vr.cin_camera && !vr.immersive_cinematics) || vr.misc_camera || (CL_IsRunningInGameCinematic() || CL_InGameCinematicOnStandBy()) || (cls.state == CA_CINEMATIC) || @@ -497,8 +500,11 @@ void VR_HapticEvent(const char* event, int position, int flags, int intensity, f //Pass on to any external services VR_ExternalHapticEvent(event, position, flags, intensity, angle, yHeight); + float fIntensity = intensity / 100.0f; + //Controller Haptic Support int weaponFireChannel = vr.weapon_stabilised ? 3 : (vr_control_scheme->integer ? 2 : 1); + if (flags != 0) { weaponFireChannel = flags; @@ -515,37 +521,63 @@ void VR_HapticEvent(const char* event, int position, int flags, int intensity, f } else if (strcmp(event, "shotgun") == 0 || strcmp(event, "fireball") == 0) { - TBXR_Vibrate(400, 3, 1.0); + TBXR_Vibrate(400, 3, fIntensity); } else if (strcmp(event, "bullet") == 0) { - TBXR_Vibrate(150, 3, 1.0); + TBXR_Vibrate(150, 3, fIntensity); + } + else if (strcmp(event, "chainsaw_fire") == 0) // Saber + { + //Special handling for dual sabers + if (vr.dualsabers) + { + if (position == 4 || + position == 0) // both hands + { + weaponFireChannel = 3; + } + else if (position == 1) // left hand + { + weaponFireChannel = 2; + } + else if (position == 2) // right hand + { + weaponFireChannel = 1; + } + else + { + //no longer need to trigger haptic + return; + } + } + + TBXR_Vibrate(200, weaponFireChannel, fIntensity); } - else if (strcmp(event, "chainsaw_fire") == 0 || - strcmp(event, "RTCWQuest:fire_tesla") == 0) + else if (strcmp(event, "RTCWQuest:fire_tesla") == 0) // Weapon power build up { - TBXR_Vibrate(500, weaponFireChannel, 1.0); + TBXR_Vibrate(500, weaponFireChannel, fIntensity); } else if (strcmp(event, "machinegun_fire") == 0 || strcmp(event, "plasmagun_fire") == 0) { - TBXR_Vibrate(90, weaponFireChannel, 0.8); + TBXR_Vibrate(90, weaponFireChannel, fIntensity); } else if (strcmp(event, "shotgun_fire") == 0) { - TBXR_Vibrate(250, weaponFireChannel, 1.0); + TBXR_Vibrate(250, weaponFireChannel, fIntensity); } else if (strcmp(event, "rocket_fire") == 0 || strcmp(event, "RTCWQuest:fire_sniper") == 0 || strcmp(event, "bfg_fire") == 0 || strcmp(event, "handgrenade_fire") == 0 ) { - TBXR_Vibrate(400, weaponFireChannel, 1.0); + TBXR_Vibrate(400, weaponFireChannel, fIntensity); } else if (strcmp(event, "selector_icon") == 0 || strcmp(event, "use_button") == 0 ) { //Quick blip - TBXR_Vibrate(50, flags, 1.0); + TBXR_Vibrate(50, flags, fIntensity); } } diff --git a/Projects/Android/jni/JKXR/OpenXrInput.cpp b/Projects/Android/jni/JKXR/OpenXrInput.cpp index aca4fd2..7005f30 100644 --- a/Projects/Android/jni/JKXR/OpenXrInput.cpp +++ b/Projects/Android/jni/JKXR/OpenXrInput.cpp @@ -17,7 +17,7 @@ XrResult CheckXrResult(XrResult res, const char* originator) { #define SIDE_COUNT 2 -XrActionSet actionSet; +XrActionSet actionSet = nullptr; XrAction grabAction; XrAction poseAction; XrAction vibrateAction; @@ -64,11 +64,13 @@ XrActionStateBoolean GetActionStateBoolean(XrAction action, int hand) { XrActionStateGetInfo getInfo = {}; getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO; getInfo.action = action; + getInfo.next = NULL; if (hand >= 0) getInfo.subactionPath = handSubactionPath[hand]; XrActionStateBoolean state = {}; state.type = XR_TYPE_ACTION_STATE_BOOLEAN; + state.next = NULL; CHECK_XRCMD(xrGetActionStateBoolean(gAppState.Session, &getInfo, &state)); return state; } @@ -77,11 +79,13 @@ XrActionStateFloat GetActionStateFloat(XrAction action, int hand) { XrActionStateGetInfo getInfo = {}; getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO; getInfo.action = action; + getInfo.next = NULL; if (hand >= 0) getInfo.subactionPath = handSubactionPath[hand]; XrActionStateFloat state = {}; state.type = XR_TYPE_ACTION_STATE_FLOAT; + state.next = NULL; CHECK_XRCMD(xrGetActionStateFloat(gAppState.Session, &getInfo, &state)); return state; } @@ -90,11 +94,13 @@ XrActionStateVector2f GetActionStateVector2(XrAction action, int hand) { XrActionStateGetInfo getInfo = {}; getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO; getInfo.action = action; + getInfo.next = NULL; if (hand >= 0) getInfo.subactionPath = handSubactionPath[hand]; XrActionStateVector2f state = {}; state.type = XR_TYPE_ACTION_STATE_VECTOR2F; + state.next = NULL; CHECK_XRCMD(xrGetActionStateVector2f(gAppState.Session, &getInfo, &state)); return state; } @@ -132,6 +138,7 @@ void TBXR_InitActions( void ) strcpy(actionSetInfo.actionSetName, "gameplay"); strcpy(actionSetInfo.localizedActionSetName, "Gameplay"); actionSetInfo.priority = 0; + actionSetInfo.next = NULL; CHECK_XRCMD(xrCreateActionSet(gAppState.Instance, &actionSetInfo, &actionSet)); } @@ -325,6 +332,7 @@ void TBXR_InitActions( void ) suggestedBindings.interactionProfile = picoMixedRealityInteractionProfilePath; suggestedBindings.suggestedBindings = bindings; suggestedBindings.countSuggestedBindings = currBinding; + suggestedBindings.next = NULL; result = xrSuggestInteractionProfileBindings(gAppState.Instance, &suggestedBindings); } @@ -376,6 +384,7 @@ void TBXR_InitActions( void ) suggestedBindings.interactionProfile = touchControllerInteractionProfilePath; suggestedBindings.suggestedBindings = bindings; suggestedBindings.countSuggestedBindings = currBinding; + suggestedBindings.next = NULL; result = xrSuggestInteractionProfileBindings(gAppState.Instance, &suggestedBindings); } @@ -392,25 +401,31 @@ void TBXR_InitActions( void ) actionSpaceInfo.subactionPath = handSubactionPath[SIDE_LEFT]; CHECK_XRCMD(xrCreateActionSpace(gAppState.Session, &actionSpaceInfo, &aimSpace[SIDE_LEFT])); actionSpaceInfo.subactionPath = handSubactionPath[SIDE_RIGHT]; + actionSpaceInfo.next = NULL; CHECK_XRCMD(xrCreateActionSpace(gAppState.Session, &actionSpaceInfo, &aimSpace[SIDE_RIGHT])); XrSessionActionSetsAttachInfo attachInfo = {}; attachInfo.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO; attachInfo.countActionSets = 1; attachInfo.actionSets = &actionSet; + attachInfo.next = NULL; CHECK_XRCMD(xrAttachSessionActionSets(gAppState.Session, &attachInfo)); } void TBXR_SyncActions( void ) { - XrActiveActionSet activeActionSet = {}; - activeActionSet.actionSet = actionSet; - activeActionSet.subactionPath = XR_NULL_PATH; - XrActionsSyncInfo syncInfo; - syncInfo.type = XR_TYPE_ACTIONS_SYNC_INFO; - syncInfo.countActiveActionSets = 1; - syncInfo.activeActionSets = &activeActionSet; - CHECK_XRCMD(xrSyncActions(gAppState.Session, &syncInfo)); + if (actionSet) + { + XrActiveActionSet activeActionSet = {}; + activeActionSet.actionSet = actionSet; + activeActionSet.subactionPath = XR_NULL_PATH; + XrActionsSyncInfo syncInfo; + syncInfo.type = XR_TYPE_ACTIONS_SYNC_INFO; + syncInfo.countActiveActionSets = 1; + syncInfo.activeActionSets = &activeActionSet; + syncInfo.next = NULL; + CHECK_XRCMD(xrSyncActions(gAppState.Session, &syncInfo)); + } } void TBXR_UpdateControllers( ) diff --git a/Projects/Android/jni/JKXR/VrInputDefault.cpp b/Projects/Android/jni/JKXR/VrInputDefault.cpp index 045565e..d194091 100644 --- a/Projects/Android/jni/JKXR/VrInputDefault.cpp +++ b/Projects/Android/jni/JKXR/VrInputDefault.cpp @@ -42,8 +42,6 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, vr_control_scheme->value == 99; // Always right-handed for weapon calibration static bool dominantGripPushed = false; - static bool canUseBackpack = false; - static bool canUseQuickSave = false; //Need this for the touch screen ovrTrackedController * pWeapon = pDominantTracking; @@ -204,7 +202,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, handleTrackedControllerButton(&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, xrButton_Enter, A_ESCAPE); static float menuYaw = 0; - if (VR_UseScreenLayer() && !vr.misc_camera && !vr.cin_camera /*bit of a fiddle, but if we are in a misc camera or cin camera, we are in the game and shouldn't be in here*/) + if (VR_UseScreenLayer() && !vr.misc_camera) { bool controlsLeftHanded = vr_control_scheme->integer >= 10; if (controlsLeftHanded == vr.menu_right_handed) { @@ -346,9 +344,16 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, } } - if (vr.cin_camera) + static int cinCameraTimestamp = -1; + if (vr.cin_camera && cinCameraTimestamp == -1) { + cinCameraTimestamp = Sys_Milliseconds(); + } else if (!vr.cin_camera) { + cinCameraTimestamp = -1; + } + if (vr.cin_camera && cinCameraTimestamp + 1000 < Sys_Milliseconds()) { - //To skip cinematic use any thumb or trigger + // To skip cinematic use any thumb or trigger (but wait a while + // to prevent skipping when cinematic is started during action) if ((primaryButtonsNew & primaryThumb) != (primaryButtonsOld & primaryThumb)) { sendButtonAction("+use", (primaryButtonsNew & primaryThumb)); } @@ -822,22 +827,18 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, remote_movementForward); - if (!canUseQuickSave) { - if (((secondaryButtonsNew & secondaryButton1) != - (secondaryButtonsOld & secondaryButton1)) && - (secondaryButtonsNew & secondaryButton1)) { - //Toggle walk/run somehow?! - vr.move_speed = (++vr.move_speed) % 3; - } + if (((secondaryButtonsNew & secondaryButton1) != + (secondaryButtonsOld & secondaryButton1)) && + (secondaryButtonsNew & secondaryButton1)) { + //Toggle walk/run somehow?! + vr.move_speed = (++vr.move_speed) % 3; } //Open the datapad - if (!canUseQuickSave) { - if (((secondaryButtonsNew & secondaryButton2) != - (secondaryButtonsOld & secondaryButton2)) && - (secondaryButtonsNew & secondaryButton2)) { - Sys_QueEvent(0, SE_KEY, A_TAB, true, 0, NULL); - } + if (((secondaryButtonsNew & secondaryButton2) != + (secondaryButtonsOld & secondaryButton2)) && + (secondaryButtonsNew & secondaryButton2)) { + Sys_QueEvent(0, SE_KEY, A_TAB, true, 0, NULL); } //Use Force - off hand trigger diff --git a/Projects/Android/jni/OpenJK/code/qcommon/stv_version.h b/Projects/Android/jni/OpenJK/code/qcommon/stv_version.h index 007189b..20a2b73 100644 --- a/Projects/Android/jni/OpenJK/code/qcommon/stv_version.h +++ b/Projects/Android/jni/OpenJK/code/qcommon/stv_version.h @@ -23,7 +23,7 @@ along with this program; if not, see . // Current version of the single player game #define VERSION_STRING_DOTTED "1.0.1.1" -#define JKXR_VERSION "1.0.1" +#define JKXR_VERSION "1.1.4" #ifdef _DEBUG #define Q3_VERSION "(debug)OpenJK: v" VERSION_STRING_DOTTED " JKXR: " JKXR_VERSION diff --git a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_weapons.cpp b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_weapons.cpp index 9916fa5..79a3043 100644 --- a/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_weapons.cpp +++ b/Projects/Android/jni/OpenJK/codeJK2/cgame/cg_weapons.cpp @@ -1349,6 +1349,9 @@ void CG_AddViewWeapon( playerState_t *ps ) val = 1.0f; } + int position = vr->weapon_stabilised ? 4 : (vr->right_handed ? 2 : 1); + cgi_HapticEvent("RTCWQuest:fire_tesla", position, 0, 60 * val, 0, 0); + val += Q_flrand(0.0f, 1.0f) * 0.5f; FX_AddSprite( flash.origin, NULL, NULL, 3.0f * val * scale, 0.0f, 0.7f, 0.7f, WHITE, WHITE, Q_flrand(0.0f, 1.0f) * 360, 0.0f, 1.0f, shader, FX_USE_ALPHA | FX_DEPTH_HACK ); @@ -3292,7 +3295,16 @@ void CG_FireWeapon( centity_t *cent, qboolean alt_fire ) //Are we the player? if (cent->gent->client->ps.clientNum == 0) { - int position = vr->weapon_stabilised ? 4 : (vr->right_handed ? 1 : 2); + /* + These are specific to external haptics vest/arms/face combinations + position values: + 0 - Will play on vest and both arms if pattern files present for both + 1 - Will play on (left) vest and on left arm only if pattern files present for left + 2 - Will play on (right) vest and on right arm only if pattern files present for right + 3 - Will play on head only (if present) + 4 - Will play on all devices (that have a pattern defined for them) + */ + int position = vr->weapon_stabilised ? 4 : (vr->right_handed ? 2 : 1); //Haptics switch (ent->weapon) {