mirror of
https://github.com/DrBeef/JKXR.git
synced 2025-04-24 10:38:56 +00:00
Compare commits
11 commits
Author | SHA1 | Date | |
---|---|---|---|
|
6977676656 | ||
|
6e119d989a | ||
|
5711fe3eeb | ||
|
69d6bdb842 | ||
|
e123731955 | ||
|
c7f4874aba | ||
|
6a714b3398 | ||
|
5bf7075115 | ||
|
a5d36a08a8 | ||
|
2344e74dc1 | ||
|
5067a51890 |
27 changed files with 241 additions and 448 deletions
1
JKXR-PCVR-Installer/JKA/TeamBeefVR.bat
Normal file
1
JKXR-PCVR-Installer/JKA/TeamBeefVR.bat
Normal file
|
@ -0,0 +1 @@
|
|||
openjk_sp.x86_64.exe
|
1
JKXR-PCVR-Installer/JKO/TeamBeefVR.bat
Normal file
1
JKXR-PCVR-Installer/JKO/TeamBeefVR.bat
Normal file
|
@ -0,0 +1 @@
|
|||
openjo_sp.x86_64.exe
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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/")
|
||||
|
|
8
Projects/Android/gradle.properties
Normal file
8
Projects/Android/gradle.properties
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
rootProject.projectDir = new File(settingsDir, '../..')
|
||||
//rootProject.projectDir = settingsDir
|
||||
rootProject.name = "JKXR"
|
||||
|
||||
include ':', 'Projects:Android'
|
||||
|
|
Binary file not shown.
14
README.md
14
README.md
|
@ -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
|
||||
|
|
238
XrApp.gradle
238
XrApp.gradle
|
@ -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
|
22
build.gradle
22
build.gradle
|
@ -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
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
org.gradle.jvmargs=-Xmx1536M
|
||||
org.gradle.caching=true
|
||||
org.gradle.configureondemand=true
|
|
@ -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
|
Loading…
Reference in a new issue