Compare commits

..

11 commits
1.1.26 ... main

Author SHA1 Message Date
Simon
6977676656 Prevent config being saved every frame
fixes the occasional freezing that some people experience
2024-04-08 21:04:17 +01:00
Simon
6e119d989a Improved build properties 2024-04-08 21:03:50 +01:00
Grant Bagwell
5711fe3eeb
Update README.md 2024-01-15 02:20:09 +01:00
Simon
69d6bdb842 Added missing cvars for standalone 2024-01-14 15:28:43 +00:00
Grant Bagwell
e123731955 Added Trigger Release Band Cvars + Fixed Vive Controls
Added Cvars for engaging Grip by level. Defaults Below:
vr_engage_trigger 0.7
vr_release_trigger 0.7
vr_engage_trigger_index 0.7 (Index Only)
vr_release_trigger_index 0.05 (Index Only)

Vive Controls
Left Trackpad press (whilst roughly in the middle) - Crouch
Left menu Button - Pause
Trackpad Right Press - DataPad

Right Menu Button - 1st / 3rd person
Right Trackpad Press Up = Alt Fire / Switch Off Saber
Right Trackpad Press Down = Jump
Right Trackpad Press Center = Use / Interact
2024-01-13 20:12:27 +01:00
Simon
c7f4874aba Increase Version to 1.1.27 2024-01-13 10:52:39 +00:00
Simon
6a714b3398 Couple of movement fixes
- Make 3rd person movement adhere to a compass direction so that special moves can be executed
- Reduced speed of smooth turn as it was too fast on lowest setting
2024-01-13 10:52:23 +00:00
Simon
5bf7075115 Fix jittery/bandy behaviour on VDXR and SteamLink 2024-01-13 10:51:15 +00:00
Simon Brown
a5d36a08a8
Update README.md 2024-01-09 22:24:50 +00:00
Grant Bagwell
2344e74dc1
Update README.md 2024-01-07 17:13:23 +01:00
Simon
5067a51890 Updated to installer for public release 2023-12-28 18:23:55 +00:00
27 changed files with 241 additions and 448 deletions

View file

@ -0,0 +1 @@
openjk_sp.x86_64.exe

View file

@ -0,0 +1 @@
openjo_sp.x86_64.exe

View file

@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "JKXR - Jedi Academy"
#define MyAppVersion "1.1.26"
#define MyAppVersion "1.1.27"
#define MyAppPublisher "Team Beef VR"
#define MyAppURL "https://www.patreon.com/teambeef"
#define MyAppExeName "openjk_sp.x86_64.exe"
@ -40,6 +40,7 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{
[Files]
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\JKA\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\JKA\jagamex86_64.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\JKA\TeamBeefVR.bat"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\JKA\OpenAL32.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\JKA\rdsp-vanilla_x86_64.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\packaged_mods_credits.txt"; DestDir: "{app}"; Flags: ignoreversion

View file

@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "JKXR - Jedi Outcast"
#define MyAppVersion "1.1.26"
#define MyAppVersion "1.1.27"
#define MyAppPublisher "Team Beef VR"
#define MyAppURL "https://www.patreon.com/teambeef"
#define MyAppExeName "openjo_sp.x86_64.exe"
@ -40,6 +40,7 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{
[Files]
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\JKO\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\JKO\jospgamex86_64.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\JKO\TeamBeefVR.bat"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\JKO\OpenAL32.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\JKO\rdjosp-vanilla_x86_64.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Dev\Quest\JKXR\JKXR-PCVR-Installer\JKO\SDL2.dll"; DestDir: "{app}"; Flags: ignoreversion

View file

@ -1,116 +0,0 @@
####################################################
# INSTALL AND RUN INSTRUCTIONS FOR JKXR FOR PCVR #
####################################################
NOTES ON OPENXR
===============
This build of JKXR has so far only been tested on Meta and Pico devices. We recommend if you are using a Meta device that you set Oculus as the default OpenXR runtime. For all other devices you can set SteamVR as the OpenXR runtime. We're looking for feedback on what works and what doesn't (with Vive Wands expected not to work as yet - but still need info). If your headset manufacturer includes an OpenXR runtime better to use that.... use SteamVR as a fallback.
STEAM INSTALLS
==============
Please note, any instructions below that are for Jedi Outcast, the exact same instructions are applicable to Jedi Academy, though the folder/file names need to be change as appropriate.
To Install
----------
Simply double click on the file: Steam__Install.bat
This should copy all the necessary bits to the right places.
If it fails, then you will have to find your steam install folder and follow the non-steam instructions below.
NOTE: If you've played JKO/JKA using OpenJK in the past, then there will probably be an old config file lying around that may mess stuff up.. browse to the install folder and delete openjo_sp.cfg or openjk_sp.cfg
To Run
------
Simply double click on the file: Steam__Run_JKXR.bat
To Uninstall
------------
Simply double click on the file: Steam__Uninstall.bat
FOR OTHER (NON-STEAM)
=====================
Please note, the instructions below are for Jedi Outcast, the exact same instructions are applicable to Jedi Academy, though the folder names need to be change as appropriate.
To Install
----------
You'll need to locate the folder in which your copy of Jedi Knight: Jedi Outcast/Academy is installed.
For Jedi Outcast copy the following files into the same folder as the jk2sp.exe:
openjk_sp.x86_64.exe
jagamex86_64.dll
rdsp-vanilla_x86_64.dll
SDL2.dll
For Jedi Academy copy the following files into the same folder as the jasp.exe:
openjo_sp.x86_64.exe
jospgamex86_64.dll
rdjosp-vanilla_x86_64.dll
SDL2.dll
And copy all the pk3 files from the base folder into the base folder of your install.
NOTE: If you've played JKO/JKA using OpenJK in the past, then there will probably be an old config file lying around that may mess stuff up.. browse to the install folder and delete openjo_sp.cfg or openjk_sp.cfg
ANOTHER NOTE: Alternatively you can actually play JKXR from the extracted folder location.. all you need to do in that case is copy the pk3 files from your installation of Jedi Outcast/Academy into the base folder in the location you extracted the 7zip archive to. In this case if you are playing the single player campaign on flatscreen, none of the VR modifications will interfere with your game.
To Start
--------
Simply double click the executable you copied in to your JKO install folder: openjo_sp.x86_64.exe
To Uninstall
------------
Delete all the files you copied over originally
THINGS TO NOTE
==============
1. There are bugs - feedback appreciated
2. You will probably have to map your controllers if you aren't using a Quest or a Pico as we've not touched any controller mappings and configuration yet
3. If you have no sound, ensure the JKXR window has focus and that you have selected your headset as the primary sound output
MODS
====
This package contains some mods, please see the packaged_mods_credits.txt file for credits
We highly recommend the Expanded Menu for Jedi Outcast mod, this has a lot of excellent functionality:
https://www.moddb.com/mods/jedi-outcast-expanded-menu
We also recommend The Ladder for Jedi Outcast:
https://mrwonko.de/jk3files/Jedi%20Outcast/Maps/Single%20Player/2198/
Other mods will work with this build, however YMMV

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.jkxr"
android:versionCode="68"
android:versionName="1.1.26" android:installLocation="auto" >
android:versionCode="70"
android:versionName="1.1.28" android:installLocation="auto" >
<!-- Tell the system this app requires OpenGL ES 3.1. -->
<uses-feature android:glEsVersion="0x00030002" android:required="true"/>
@ -17,6 +17,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application android:allowBackup="false"
android:icon="@mipmap/teambeef"
android:label="@string/jkxr"

View file

@ -1,5 +1,15 @@
buildscript {
repositories {
google() // For Gradle 4.0+
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.3'
}
}
apply plugin: 'com.android.application'
apply from: "${rootProject.projectDir}/XrApp.gradle"
android {
// This is the name of the generated apk file, which will have
@ -14,12 +24,13 @@ android {
// will replace an older one.
applicationId "com.drbeef." + project.archivesBaseName
// override app plugin abiFilters for both 32 and 64-bit support
externalNativeBuild {
ndk {
abiFilters 'arm64-v8a'
}
ndkBuild {
def numProcs = Runtime.runtime.availableProcessors()
arguments "V=0", "-j$numProcs", "-C$project.buildDir.parent", "APP_PLATFORM=android-29", "NDK_TOOLCHAIN_VERSION=clang", "APP_STL=c++_static"
abiFilters 'arm64-v8a'
}
}
@ -28,26 +39,95 @@ android {
targetSdkVersion 29
}
sourceSets {
main {
externalNativeBuild {
ndkBuild {
path file('jni/Android.mk')
}
}
signingConfigs {
def keystorePath = (project.hasProperty('key.store')) ?
new File(project.getProperty('key.store')) :
project.file('android.debug.keystore')
def keystorePassword = (project.hasProperty('key.store.password')) ?
project.getProperty('key.store.password') : 'android'
def keystoreKeyAlias = (project.hasProperty('key.alias')) ?
project.getProperty('key.alias') : 'androiddebugkey'
def keystoreKeyPassword = (project.hasProperty('key.alias.password')) ?
project.getProperty('key.alias.password') : 'android'
debug {
storeFile keystorePath
storePassword keystorePassword
keyAlias keystoreKeyAlias
keyPassword keystoreKeyPassword
v2SigningEnabled true
}
release {
storeFile keystorePath
storePassword keystorePassword
keyAlias keystoreKeyAlias
keyPassword keystoreKeyPassword
v2SigningEnabled true
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
debuggable true
jniDebuggable true
externalNativeBuild {
ndkBuild {
arguments "NDK_DEBUG=1","USE_ASAN=1"
}
}
}
release {
signingConfig signingConfigs.release
debuggable false
jniDebuggable false
externalNativeBuild {
ndkBuild {
arguments "NDK_DEBUG=0","USE_ASAN=0"
}
}
}
}
sourceSets.main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['../../java']
jniLibs.srcDir 'libs'
res.srcDirs = ['../../res']
assets.srcDirs = ['../../assets']
}
jni.srcDirs = ['jni']
}
packagingOptions {
exclude 'lib/arm64-v8a/libopenxr_loader.so'
lintOptions {
checkReleaseBuilds false
disable 'ExpiredTargetSdkVersion'
}
//packagingOptions {
// exclude 'lib/arm64-v8a/libopenxr_loader.so'
//}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
compileSdkVersion = 29
buildToolsVersion = '29.0.3'
ndkVersion '21.1.6352462'
}
dependencies {
@ -59,12 +139,15 @@ dependencies {
repositories {
google()
}
buildscript {
repositories {
google()
}
// Workaround to fix issue in Android Studio Chipmunk 2021.2.1 and later
// where opening a project would result in a 'prepareKotlinBuildScriptModel'
// not found error
if (!tasks.findByName("prepareKotlinBuildScriptModel")) {
tasks.register("prepareKotlinBuildScriptModel") {}
}
task packBaseResources(type: Zip) {
from "../../z_vr_assets_base/"
destinationDir file("../../assets/")

View file

@ -0,0 +1,8 @@
org.gradle.jvmargs=-Xmx1536M \
--add-exports=java.base/sun.nio.ch=ALL-UNNAMED \
--add-opens=java.base/java.lang=ALL-UNNAMED \
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens=java.base/java.io=ALL-UNNAMED \
--add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED
org.gradle.caching=true
org.gradle.configureondemand=true

View file

@ -1,6 +1,5 @@
#Sun Sep 04 16:36:21 BST 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View file

@ -802,15 +802,24 @@ void TBXR_UpdateControllers( )
trackpadPosition = GetActionStateVector2(trackPadAction, SIDE_LEFT).currentState;
if (GetActionStateBoolean(trackPadClickAction, SIDE_LEFT).currentState)
{
if (trackpadPosition.x >= -0.2 && trackpadPosition.x <= 0.2)
if (trackpadPosition.x >= -0.3 && trackpadPosition.x <= 0.3)
{
if (trackpadPosition.y >= 0.2)
//Always the in center for crouch
//Crouch
leftTrackedRemoteState_new.Buttons |= xrButton_LThumb;
leftTrackedRemoteState_new.Buttons |= xrButton_Joystick;
}
else
{
if (trackpadPosition.x <= -0.3) //Left
{
leftTrackedRemoteState_new.Buttons |= xrButton_Y;
//Ingame Menu - dont need this on Vive
//leftTrackedRemoteState_new.Buttons |= xrButton_X;
}
else if (trackpadPosition.y <= -0.2)
else if(trackpadPosition.x >= 0.3) //Right
{
leftTrackedRemoteState_new.Buttons |= xrButton_X;
//DataPad
leftTrackedRemoteState_new.Buttons |= xrButton_Y;
}
}
}
@ -821,31 +830,48 @@ void TBXR_UpdateControllers( )
if (GetActionStateBoolean(XTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_X;
if (GetActionStateBoolean(YAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_Y;
if (GetActionStateBoolean(YTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_Y;
if (GetActionStateBoolean(thumbstickClickAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_LThumb;
if (GetActionStateBoolean(thumbstickClickAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_Joystick;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_LThumb;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_Joystick;
}
//Defaults engage/disable at the same level
float enableLevel = vr_engage_trigger->value;
float disableLevel = vr_release_trigger->value;
//INDEX we'll need to add force check so its not boolean
if (gAppState.controllersPresent == VIVE_CONTROLLERS)
{
leftTrackedRemoteState_new.GripTrigger = GetActionStateBoolean(squeezeClickAction, SIDE_LEFT).currentState;
enableLevel = 1.0f;
disableLevel = 1.0f;
}
else if (gAppState.controllersPresent == INDEX_CONTROLLERS)
{
leftTrackedRemoteState_new.GripTrigger = GetActionStateFloat(squeezeForceAction, SIDE_LEFT).currentState;
// Use different release level for the Index Knuckles
enableLevel = vr_engage_trigger_index->value;
disableLevel = vr_release_trigger_index->value;
}
else
{
leftTrackedRemoteState_new.GripTrigger = GetActionStateFloat(squeezeAction, SIDE_LEFT).currentState;
}
if (leftTrackedRemoteState_new.GripTrigger > 0.7f)
static int leftGripEngaged = false;
if (leftTrackedRemoteState_new.GripTrigger >= enableLevel && !leftGripEngaged)
{
leftGripEngaged = true;
}
else if (leftTrackedRemoteState_new.GripTrigger < disableLevel && leftGripEngaged)
{
leftGripEngaged = false;
}
if (leftGripEngaged)
{
leftTrackedRemoteState_new.Buttons |= xrButton_GripTrigger;
}
if (GetActionStateBoolean(thumbstickClickAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_LThumb;
if (GetActionStateBoolean(thumbstickClickAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_Joystick;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_LThumb;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_Joystick;
leftTrackedRemoteState_new.IndexTrigger = GetActionStateFloat(triggerAction, SIDE_LEFT).currentState;
if (leftTrackedRemoteState_new.IndexTrigger > 0.5f) leftTrackedRemoteState_new.Buttons |= xrButton_Trigger;
if (GetActionStateBoolean(triggerTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_Trigger;
@ -867,15 +893,25 @@ void TBXR_UpdateControllers( )
{
if (trackpadPosition.x >= -0.2 && trackpadPosition.x <= 0.2)
{
if (trackpadPosition.y >= 0.2)
if (trackpadPosition.y >= 0.3)
{
//Menu button on Vive instead
rightTrackedRemoteState_new.Buttons |= xrButton_B;
}
else if (trackpadPosition.y <= -0.2)
else if (trackpadPosition.y <= -0.3)
{
rightTrackedRemoteState_new.Buttons |= xrButton_A;
}
else
{
rightTrackedRemoteState_new.Buttons |= xrButton_Joystick;
rightTrackedRemoteState_new.Buttons |= xrButton_RThumb;
}
}
else
{
rightTrackedRemoteState_new.Buttons |= xrButton_Joystick;
rightTrackedRemoteState_new.Buttons |= xrButton_RThumb;
}
}
if (GetActionStateBoolean(backAction, SIDE_RIGHT).currentState)
@ -888,29 +924,47 @@ void TBXR_UpdateControllers( )
if (GetActionStateBoolean(AAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_A;
if (GetActionStateBoolean(ATouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_A;
if (GetActionStateBoolean(BAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_B;
if (GetActionStateBoolean(BTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_B;
if (GetActionStateBoolean(BTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_B;
if (GetActionStateBoolean(backAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_Enter;
if (GetActionStateBoolean(thumbstickClickAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_RThumb;
if (GetActionStateBoolean(thumbstickClickAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_Joystick;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_RThumb;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_Joystick;
}
//INDEX we'll need to add force check so its not boolean
//Defaults engage/disable at the same level
if (gAppState.controllersPresent == VIVE_CONTROLLERS)
{
rightTrackedRemoteState_new.GripTrigger = GetActionStateBoolean(squeezeClickAction, SIDE_RIGHT).currentState;
rightTrackedRemoteState_new.GripTrigger = GetActionStateBoolean(squeezeClickAction, SIDE_RIGHT).currentState;
}
else if (gAppState.controllersPresent == INDEX_CONTROLLERS)
{
rightTrackedRemoteState_new.GripTrigger = GetActionStateFloat(squeezeForceAction, SIDE_RIGHT).currentState;
rightTrackedRemoteState_new.GripTrigger = GetActionStateFloat(squeezeForceAction, SIDE_RIGHT).currentState;
}
else
{
rightTrackedRemoteState_new.GripTrigger = GetActionStateFloat(squeezeAction, SIDE_RIGHT).currentState;
}
if (rightTrackedRemoteState_new.GripTrigger > 0.7f) rightTrackedRemoteState_new.Buttons |= xrButton_GripTrigger;
if (GetActionStateBoolean(thumbstickClickAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_RThumb;
if (GetActionStateBoolean(thumbstickClickAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_Joystick;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_RThumb;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_Joystick;
static int rightGripEngaged = false;
if (rightTrackedRemoteState_new.GripTrigger >= enableLevel && !rightGripEngaged)
{
rightGripEngaged = true;
}
else if (rightTrackedRemoteState_new.GripTrigger < disableLevel && rightGripEngaged)
{
rightGripEngaged = false;
}
if (rightGripEngaged)
{
rightTrackedRemoteState_new.Buttons |= xrButton_GripTrigger;
}
rightTrackedRemoteState_new.IndexTrigger = GetActionStateFloat(triggerAction, SIDE_RIGHT).currentState;
if (rightTrackedRemoteState_new.IndexTrigger > 0.5f) rightTrackedRemoteState_new.Buttons |= xrButton_Trigger;
if (GetActionStateBoolean(triggerTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_Trigger;

View file

@ -2,6 +2,7 @@ extern cvar_t *vr_turn_mode;
extern cvar_t *vr_turn_angle;
extern cvar_t *vr_positional_factor;
extern cvar_t *vr_walkdirection;
extern cvar_t *vr_3rdperson_digital_direction;
extern cvar_t *vr_weapon_pitchadjust;
extern cvar_t *vr_saber_pitchadjust;
extern cvar_t *vr_control_scheme;
@ -34,3 +35,7 @@ extern cvar_t *vr_use_gesture_boundary;
extern cvar_t *vr_align_weapons; // Only used for development
extern cvar_t *vr_refresh;
extern cvar_t *vr_super_sampling;
extern cvar_t *vr_engage_trigger;
extern cvar_t *vr_release_trigger;
extern cvar_t *vr_engage_trigger_index;
extern cvar_t *vr_release_trigger_index;

View file

@ -15,6 +15,7 @@ cvar_t *vr_turn_mode;
cvar_t *vr_turn_angle;
cvar_t *vr_positional_factor;
cvar_t *vr_walkdirection;
cvar_t *vr_3rdperson_digital_direction;
cvar_t *vr_weapon_pitchadjust;
cvar_t *vr_saber_pitchadjust;
cvar_t *vr_control_scheme;
@ -47,6 +48,10 @@ cvar_t *vr_use_gesture_boundary;
cvar_t *vr_align_weapons;
cvar_t *vr_refresh;
cvar_t *vr_super_sampling;
cvar_t *vr_engage_trigger;
cvar_t *vr_release_trigger;
cvar_t *vr_engage_trigger_index;
cvar_t *vr_release_trigger_index;
ovrInputStateTrackedRemote leftTrackedRemoteState_old;
ovrInputStateTrackedRemote leftTrackedRemoteState_new;

View file

@ -39,6 +39,8 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
vr.right_handed = vr_control_scheme->value < 10 ||
vr_control_scheme->value == 99; // Always right-handed for weapon calibration
bool thirdPersonActive = !!((int) Cvar_VariableValue("cg_thirdPerson"));
static bool dominantGripPushed = false;
//Need this for the touch screen
@ -808,7 +810,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
vr.offhandoffset[1] = pOff->Pose.position.y - vr.hmdposition[1];
vr.offhandoffset[2] = pOff->Pose.position.z - vr.hmdposition[2];
if (vr_walkdirection->value == 0) {
if (vr_walkdirection->value == 0 && !thirdPersonActive) {
controllerYawHeading = vr.offhandangles[ANGLES_ADJUSTED][YAW] - vr.hmdorientation[YAW];
} else {
controllerYawHeading = 0.0f;
@ -954,6 +956,17 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
vec2_t v;
rotateAboutOrigin(x, y, controllerYawHeading, v);
// If in third person, use digital input (North, North-East, East, South-East etc)
// for movement as it allows execution of player special moves correctly in JKA
if (thirdPersonActive && vr_3rdperson_digital_direction->integer)
{
float angle = RAD2DEG(atan2f(v[1], v[0])) + 22.5;
int segment = angle / 45.0f;
angle = segment * 45.0f;
v[0] = nlf * cosf(DEG2RAD(angle));
v[1] = nlf * sinf(DEG2RAD(angle));
}
float move_speed_multiplier = 1.0f;
switch (vr.move_speed)
{
@ -968,7 +981,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
break;
}
if (vr_always_run->integer)
if (vr_always_run->integer || vr_3rdperson_digital_direction->integer)
{
move_speed_multiplier = 1.0f;
}
@ -1072,7 +1085,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
if (!usingSnapTurn && fabs(primaryJoystickX) > 0.1f) //smooth turn
{
vr.snapTurn -= ((vr_turn_angle->value / 10.0f) *
vr.snapTurn -= ((vr_turn_angle->value / 25.0f) *
primaryJoystickX);
if (vr.snapTurn > 180.0f) {
vr.snapTurn -= 360.f;
@ -1158,7 +1171,6 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
// Process "use" gesture
if (vr_gesture_triggered_use->integer) {
bool thirdPersonActive = !!((int) Cvar_VariableValue("cg_thirdPerson"));
bool gestureUseAllowed = !vr.weapon_stabilised && !vr.cin_camera && !vr.misc_camera && !vr.remote_turret && !vr.emplaced_gun && !vr.in_vehicle && !thirdPersonActive;
// Off-hand gesture
float distanceToBody = sqrt(vr.offhandoffset[0]*vr.offhandoffset[0] + vr.offhandoffset[2]*vr.offhandoffset[2]);

View file

@ -328,6 +328,7 @@ void VR_Init()
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", "1", CVAR_ARCHIVE);
vr_3rdperson_digital_direction = Cvar_Get( "vr_3rdperson_digital_direction", "1", CVAR_ARCHIVE);
vr_weapon_pitchadjust = Cvar_Get( "vr_weapon_pitchadjust", "-20.0", CVAR_ARCHIVE);
vr_saber_pitchadjust = Cvar_Get( "vr_saber_pitchadjust", "-13.36", CVAR_ARCHIVE);
vr_virtual_stock = Cvar_Get( "vr_virtual_stock", "0", CVAR_ARCHIVE);
@ -363,6 +364,10 @@ void VR_Init()
vr_align_weapons = Cvar_Get ("vr_align_weapons", "0", CVAR_ARCHIVE);
vr_refresh = Cvar_Get ("vr_refresh", "72", CVAR_ARCHIVE);
vr_super_sampling = Cvar_Get ("vr_super_sampling", "1.0", CVAR_ARCHIVE);
vr_engage_trigger = Cvar_Get("vr_engage_trigger", "0.7", CVAR_ARCHIVE);
vr_release_trigger = Cvar_Get("vr_release_trigger", "0.7", CVAR_ARCHIVE);
vr_engage_trigger_index = Cvar_Get("vr_engage_trigger_index", "0.7", CVAR_ARCHIVE);
vr_release_trigger_index = Cvar_Get("vr_release_trigger_index", "0.05", CVAR_ARCHIVE);
cvar_t *expanded_menu_enabled = Cvar_Get ("expanded_menu_enabled", "0", CVAR_ARCHIVE);
if (FS_FileExists("expanded_menu.pk3") || FS_BaseFileExists("expanded_menu.pk3")) {

View file

@ -1848,6 +1848,7 @@ void TBXR_FrameSetup()
VR_FrameSetup();
//Get controller state here
TBXR_updateProjections();
TBXR_GetHMDOrientation();
VR_HandleControllerInput();
@ -1947,8 +1948,6 @@ void TBXR_submitFrame()
return;
}
TBXR_updateProjections();
//Calculate the maximum extent fov for use in culling in the engine (we won't want to cull inside this fov)
vr.fov_x = (fabs(gAppState.Views[0].fov.angleLeft) + fabs(gAppState.Views[1].fov.angleRight)) * 180.0f / M_PI;
vr.fov_y = (fabs(gAppState.Views[0].fov.angleUp) + fabs(gAppState.Views[0].fov.angleDown)) * 180.0f / M_PI;

View file

@ -246,6 +246,7 @@ void VR_Init()
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", "1", CVAR_ARCHIVE);
vr_3rdperson_digital_direction = Cvar_Get( "vr_3rdperson_digital_direction", "1", CVAR_ARCHIVE);
vr_weapon_pitchadjust = Cvar_Get( "vr_weapon_pitchadjust", "-20.0", CVAR_ARCHIVE);
vr_saber_pitchadjust = Cvar_Get( "vr_saber_pitchadjust", "-13.36", CVAR_ARCHIVE);
vr_virtual_stock = Cvar_Get( "vr_virtual_stock", "0", CVAR_ARCHIVE);
@ -280,6 +281,10 @@ void VR_Init()
vr_use_gesture_boundary = Cvar_Get ("vr_use_gesture_boundary", "0.35", CVAR_ARCHIVE);
vr_align_weapons = Cvar_Get ("vr_align_weapons", "0", CVAR_ARCHIVE);
vr_refresh = Cvar_Get ("vr_refresh", "72", CVAR_ARCHIVE);
vr_engage_trigger = Cvar_Get("vr_engage_trigger", "0.7", CVAR_ARCHIVE);
vr_release_trigger = Cvar_Get("vr_release_trigger", "0.7", CVAR_ARCHIVE);
vr_engage_trigger_index = Cvar_Get("vr_engage_trigger_index", "0.7", CVAR_ARCHIVE);
vr_release_trigger_index = Cvar_Get("vr_release_trigger_index", "0.05", CVAR_ARCHIVE);
cvar_t *expanded_menu_enabled = Cvar_Get ("expanded_menu_enabled", "0", CVAR_ARCHIVE);
if (FS_FileExists("expanded_menu.pk3") || FS_BaseFileExists("expanded_menu.pk3")) {

View file

@ -1040,7 +1040,7 @@ void TBXR_FrameSetup()
//Game specific frame setup stuff called here
VR_FrameSetup();
//Get controller state here
TBXR_updateProjections();
TBXR_GetHMDOrientation();
VR_HandleControllerInput();
@ -1148,8 +1148,6 @@ void TBXR_submitFrame()
return;
}
TBXR_updateProjections();
//Calculate the maximum extent fov for use in culling in the engine (we won't want to cull inside this fov)
vr.fov_x = (fabs(gAppState.Views[0].fov.angleLeft) + fabs(gAppState.Views[1].fov.angleRight)) * 180.0f / M_PI;
vr.fov_y = (fabs(gAppState.Views[0].fov.angleUp) + fabs(gAppState.Views[0].fov.angleDown)) * 180.0f / M_PI;

View file

@ -1371,7 +1371,7 @@ void Com_Frame( void ) {
TBXR_FrameSetup();
// write config file if anything changed
Com_WriteConfiguration();
//Com_WriteConfiguration();
//
// main event loop
@ -1571,6 +1571,10 @@ Com_Shutdown
=================
*/
void Com_Shutdown (void) {
// write config file if anything changed
Com_WriteConfiguration();
CM_ClearMap();
if (logfile) {

View file

@ -23,7 +23,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
// Current version of the single player game
#include "../win32/AutoVersion.h"
#define JKXR_VERSION "1.1.26"
#define JKXR_VERSION "1.1.28"
#ifdef _DEBUG
#define Q3_VERSION "(debug)OpenJK: v" VERSION_STRING_DOTTED " JKXR: " JKXR_VERSION

View file

@ -5,5 +5,4 @@
# For customization when using a Version Control System, please read the
# header note.
#Thu Dec 12 20:21:11 GMT 2019
ndk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk\\ndk\\21.1.6352462
sdk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk

View file

@ -1,4 +1,2 @@
rootProject.projectDir = new File(settingsDir, '../..')
//rootProject.projectDir = settingsDir
rootProject.name = "JKXR"
include ':', 'Projects:Android'

View file

@ -7,6 +7,8 @@
[SideQuest Latest Version (Pico Headsets)](https://sidequestvr.com/app/15541)
[PCVR Installers (found on the latest release here)](https://github.com/DrBeef/JKXR/releases)
JK XR is a VR port of the Jedi Knight games using OpenXR (the open standard for virtual and augmented reality devices) and is based on the excellent OpenJK port, originally forked from: https://github.com/JACoders/OpenJK
@ -80,18 +82,18 @@ Download the PCVR installers from the release page and use them to install to th
We recommend the following combinations to get the optimal experience while playing JKXR on PCVR:
**Valve Index** -> Via SteamVR (SteamVR OpenXR Runtime) -> This will be standard for Valve Index Users
**Valve Index** -> Via SteamVR (SteamVR OpenXR Runtime)
**HTC Vive** -> Via SteamVR (SteamVR OpenXR Runtime) -> This will be standard for Valve Index Users
**HTC Vive** -> Via SteamVR (SteamVR OpenXR Runtime)
**Meta Headsets** -> Link / Airlink (Oculus OpenXR Runtime) -> Make sure this is set via the Oculus desktop app Settings->General->OpenXR Runtime
**Meta Headsets** -> Link / Airlink (Oculus OpenXR Runtime) / SteamLink / Virtual Desktop (VDXR or SteamVR)
**Windows Mixed Reality (WMR) Devices** (I.e. HP G2) -> Make sure you set the SteamVR to be the default OpenXR runtime.
**Pimax** -> Currently unplayable. We have been in discussions with Pimax and there is a new PimaxPlay that fixes the issues (upside down screens).
When released the game must be played via unofficial PimaxXR OpenXR runtime (https://github.com/mbucchia/Pimax-OpenXR). Do not play via SteamVR OpenXR runtime
**Pico** - Our honest option is the best version on Pico is the standalone version on Sidequest. If you are determined to use PCVR, the only working option is via Virtual Desktop. Ensure you have set SteamVR as the OpenXR Runtime in the Virtual Desktop Streamer app (see picture)
Do not play via Streaming Assistant / VDXR
**Pico** - Virtual Desktop (VDXR or SteamVR) / Streaming Assistant (Currently Untested)
## Copying the Full Game files to your Meta Quest / Pico

View file

@ -1,238 +0,0 @@
import org.gradle.internal.os.OperatingSystem;
import com.android.ddmlib.AndroidDebugBridge
import com.android.ddmlib.IDevice
import com.android.ddmlib.CollectingOutputReceiver
import org.apache.tools.ant.taskdefs.condition.Os
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
}
tasks.register("wrapper")
}
class XrAppPlugin implements Plugin<Project> {
Project project = null
void installApk( IDevice device, File apkFile, String applicationId ) {
project.logger.quiet "Installing ${applicationId} on device ${device.serialNumber}"
String toinstall = "/data/local/tmp/toinstall.apk"
try {
device.pushFile( apkFile.path, toinstall )
} catch ( Exception e ) {
throw new RuntimeException( "Failed to push ${apkFile.path} to ${toinstall}. ${e}", e )
}
while ( true ) {
try {
device.installRemotePackage( toinstall, true )
break
} catch ( Exception e ) {
project.logger.quiet "Failed to install ${applicationId} on device ${device.serialNumber} (${e}). Trying to uninstall first."
}
try {
device.uninstallPackage( applicationId )
} catch ( Exception e ) {
throw new RuntimeException( "Failed to uninstall ${applicationId}. ${e}", e )
}
}
}
void stopApk( IDevice device, String packageName ) {
CollectingOutputReceiver receiver = new CollectingOutputReceiver()
device.executeShellCommand( "am force-stop ${packageName}", receiver )
}
void runApk( IDevice device, manifestFile ) {
CollectingOutputReceiver receiver = new CollectingOutputReceiver()
def activityClass = new XmlSlurper().parse( manifestFile ).application.activity.find{ it.'intent-filter'.find{ filter ->
return filter.action .find{it.'@android:name'.text() == 'android.intent.action.MAIN' } \
&& ( filter.category.find{it.'@android:name'.text() == 'android.intent.category.LAUNCHER'} \
|| filter.category.find{it.'@android:name'.text() == 'android.intent.category.INFO'} )
}}.'@android:name'
def startActivity = "${project.android.defaultConfig.applicationId}/${activityClass}"
project.logger.quiet "Starting \'$startActivity\' on ${project.deviceMap.size()} devices:"
project.logger.quiet "- ${device.serialNumber}"
device.executeShellCommand( "am start $startActivity", receiver )
}
void apply( Project project ) {
this.project = project
// FIXME: The Task.leftShift(Closure) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
project.task( "cleanWorkAround" ) {
description "Workaround for .externalNativeBuild not being deleted on clean"
}.doLast {
project.delete project.file( ".externalNativeBuild" )
}
project.android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 24
targetSdkVersion 25
externalNativeBuild {
ndk {
}
ndkBuild {
def numProcs = Runtime.runtime.availableProcessors()
arguments "V=0", "-j$numProcs", "-C$project.buildDir.parent", "APP_PLATFORM=android-24", "NDK_TOOLCHAIN_VERSION=clang", "APP_STL=c++_static"
}
}
}
externalNativeBuild {
ndkBuild {
path 'jni/Android.mk'
}
}
signingConfigs {
def keystorePath = (project.hasProperty('key.store')) ?
new File(project.getProperty('key.store')) :
project.file('android.debug.keystore')
def keystorePassword = (project.hasProperty('key.store.password')) ?
project.getProperty('key.store.password') : 'android'
def keystoreKeyAlias = (project.hasProperty('key.alias')) ?
project.getProperty('key.alias') : 'androiddebugkey'
def keystoreKeyPassword = (project.hasProperty('key.alias.password')) ?
project.getProperty('key.alias.password') : 'android'
debug {
storeFile keystorePath
storePassword keystorePassword
keyAlias keystoreKeyAlias
keyPassword keystoreKeyPassword
v2SigningEnabled true
}
release {
storeFile keystorePath
storePassword keystorePassword
keyAlias keystoreKeyAlias
keyPassword keystoreKeyPassword
v2SigningEnabled true
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
debuggable true
jniDebuggable true
externalNativeBuild {
ndkBuild {
arguments "NDK_DEBUG=1","USE_ASAN=1"
}
}
}
release {
signingConfig signingConfigs.release
debuggable false
jniDebuggable false
externalNativeBuild {
ndkBuild {
arguments "NDK_DEBUG=0","USE_ASAN=0"
}
}
}
}
}
// WORKAROUND: On Mac OS X, running ndk-build clean with a high num of parallel executions
// set may result in the following build error: rm: fts_read: No such file or directory.
// Currently, there isn't a good way to specify numProcs=1 only on clean. So, in order
// to work around the issue, delete the auto-generated .externalNativeBuild artifacts
// (where $numProcs specified) before executing the clean task.
project.clean.dependsOn project.cleanWorkAround
project.clean {
// remove the auto-generated debug keystore (currently generated by python build script)
// delete "android.debug.keystore"
}
project.afterEvaluate {
Task initDeviceList = project.task( "initDeviceList()" ).doLast {
project.ext.deviceMap = [ : ]
if (project.hasProperty( "should_install" ) == true) {
AndroidDebugBridge.initIfNeeded( false )
AndroidDebugBridge bridge = AndroidDebugBridge.createBridge( project.android.getAdbExe().absolutePath, false )
long timeOut = 30000 // 30 sec
int sleepTime = 1000
while ( !bridge.hasInitialDeviceList() && timeOut > 0 ) {
sleep( sleepTime )
timeOut -= sleepTime
}
if ( timeOut <= 0 && !bridge.hasInitialDeviceList() ) {
throw new RuntimeException( "Timeout getting device list.", null )
}
// if a device is connected both physically and over the network, only include the physical ID
if ( project.hasProperty( "should_install" ) == true ) {
bridge.devices.split { it.getProperty( "ro.serialno" ) != it.serialNumber }.each {
it.collectEntries( project.deviceMap, { [ ( it.getProperty( "ro.serialno" )) : it ] } )
}
}
}
}
project.task( "stopApk", dependsOn: initDeviceList ) {
description "Stops app if currently running on device"
}.doLast {
project.deviceMap.each { deviceSerial, device ->
stopApk( device, android.defaultConfig.applicationId )
}
}
project.android.applicationVariants.all { variant ->
Task installAndRun = project.task( "installAndRun${variant.name.capitalize()}" ) {
dependsOn variant.assembleProvider.get()
dependsOn initDeviceList
onlyIf { project.hasProperty( "should_install" ) }
description "Installs and runs the APK file"
}.doLast { variant.outputs.each { output ->
if ( output.outputFile.exists() ) {
if ( project.deviceMap.size() == 0 ) {
project.logger.quiet "Install requested, but no devices found."
} else {
project.deviceMap.each { deviceSerial, device ->
installApk( device, output.outputFile, project.android.defaultConfig.applicationId )
runApk( device, new File(output.processManifest.manifestOutputDirectory.get().asFile, "AndroidManifest.xml"))
}
}
}
}
}
variant.assembleProvider.get().finalizedBy installAndRun
}
}
}
}
// Workaround to fix issue in Android Studio Chipmunk 2021.2.1 and later
// where opening a project would result in a 'prepareKotlinBuildScriptModel'
// not found error
if (!tasks.findByName("prepareKotlinBuildScriptModel")) {
tasks.register("prepareKotlinBuildScriptModel") {}
}
apply plugin: XrAppPlugin

View file

@ -1,22 +0,0 @@
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View file

@ -1,3 +0,0 @@
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.gradle.configureondemand=true

View file

@ -1,9 +0,0 @@
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Thu Dec 12 20:21:11 GMT 2019
ndk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk\\ndk\\21.1.6352462
sdk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk