Merge branch 'main' into contributions

This commit is contained in:
Petr Bartos 2024-11-10 20:06:07 +01:00
commit 2ef52a8e6a
51 changed files with 333 additions and 495 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.0.22"
#define MyAppVersion "1.1.27"
#define MyAppPublisher "Team Beef VR"
#define MyAppURL "https://www.patreon.com/teambeef"
#define MyAppExeName "openjk_sp.x86_64.exe"
@ -24,7 +24,7 @@ DisableProgramGroupPage=yes
;PrivilegesRequired=lowest
OutputDir=C:\Dev\Quest\JKXR\JKXR-PCVR-Installer
OutputBaseFilename=JKXR_JKA_Setup
Compression=lzma
Compression=zip
SolidCompression=yes
WizardStyle=modern
AlwaysShowDirOnReadyPage=yes
@ -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.0.22"
#define MyAppVersion "1.1.27"
#define MyAppPublisher "Team Beef VR"
#define MyAppURL "https://www.patreon.com/teambeef"
#define MyAppExeName "openjo_sp.x86_64.exe"
@ -10,7 +10,7 @@
[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{3B2C9382-66B4-48E6-B625-F567F350283D}
AppId={{962B9188-98B6-4216-BEB8-C8BCF901C6D0}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
@ -24,7 +24,7 @@ DisableProgramGroupPage=yes
;PrivilegesRequired=lowest
OutputDir=C:\Dev\Quest\JKXR\JKXR-PCVR-Installer
OutputBaseFilename=JKXR_JKO_Setup
Compression=lzma
Compression=zip
SolidCompression=yes
WizardStyle=modern
AlwaysShowDirOnReadyPage=yes
@ -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="67"
android:versionName="1.1.25" 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,8 +17,9 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application android:allowBackup="false"
android:icon="@drawable/ic_jkxr"
android:icon="@mipmap/teambeef"
android:label="@string/jkxr"
android:extractNativeLibs="true"
android:requestLegacyExternalStorage="true" >

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)
@ -890,9 +926,16 @@ void TBXR_UpdateControllers( )
if (GetActionStateBoolean(BAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= 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;
@ -905,12 +948,23 @@ void TBXR_UpdateControllers( )
{
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
@ -347,7 +349,7 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
VectorNormalize(weaponForward);
if (cl.frame.ps.weapon > WP_SABER &&
DotProduct(weaponForward, dir) > 0.8f)
DotProduct(weaponForward, dir) > 0.6f)
{
vr.weapon_stabilised = true;
}
@ -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;
@ -1972,7 +1971,11 @@ void TBXR_submitFrame()
if (usingScreenLayer) {
usingScreenLayer = qfalse;
VR_ResetRenderer();
float configuredSuperSampling = Cvar_VariableValue("vr_super_sampling");
if (configuredSuperSampling != 0.0f && configuredSuperSampling != superSampling)
{
VR_ResetRenderer();
}
}
memset(&projection_layer, 0, sizeof(XrCompositionLayerProjection));

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

@ -1634,26 +1634,20 @@ static void CG_DrawWeapReticle( void )
vec4_t light_color = {0.7, 0.7, 0.7, 1};
vec4_t black = {0.0, 0.0, 0.0, 1};
float indent = 0.1;
float indent = 0.12;
float X_WIDTH=640;
float Y_HEIGHT=480;
float STRETCH = 6;
float x = (X_WIDTH * indent), y = (Y_HEIGHT * indent), w = (X_WIDTH * (1-(2*indent))) / 2.0f, h = (Y_HEIGHT * (1-(2*indent))) / 2;
// sides
CG_FillRect( 0, 0, (X_WIDTH * indent)+1, Y_HEIGHT, black );
CG_FillRect( X_WIDTH * (1 - indent) - 1, 0, (X_WIDTH * indent) + 2, Y_HEIGHT, black );
// top/bottom
CG_FillRect( X_WIDTH * indent, 0, X_WIDTH * (1-indent), Y_HEIGHT * indent + 1, black );
CG_FillRect( X_WIDTH * indent, Y_HEIGHT * (1-indent) - 1, X_WIDTH * (1-indent), Y_HEIGHT * indent + 2, black );
{
// center
if ( cgs.media.reticleShader ) {
cgi_R_DrawStretchPic( x, y, w, h, 0, 0, 1, 1, cgs.media.reticleShader ); // tl
cgi_R_DrawStretchPic( x + w, y, w, h, 1, 0, 0, 1, cgs.media.reticleShader ); // tr
cgi_R_DrawStretchPic( x, y + h, w, h, 0, 1, 1, 0, cgs.media.reticleShader ); // bl
cgi_R_DrawStretchPic( x + w, y + h, w, h, 1, 1, 0, 0, cgs.media.reticleShader ); // br
cgi_R_DrawStretchPic( x - STRETCH, y - STRETCH, w + STRETCH, h+STRETCH, 0, 0, 1, 1, cgs.media.reticleShader ); // tl
cgi_R_DrawStretchPic( x + w, y - STRETCH, w + STRETCH, h + STRETCH, 1, 0, 0, 1, cgs.media.reticleShader ); // tr
cgi_R_DrawStretchPic( x - STRETCH, y + h, w + STRETCH, h + STRETCH, 0, 1, 1, 0, cgs.media.reticleShader ); // bl
cgi_R_DrawStretchPic( x + w, y + h, w + STRETCH, h + STRETCH, 1, 1, 0, 0, cgs.media.reticleShader ); // br
}
// hairs
@ -1662,6 +1656,13 @@ static void CG_DrawWeapReticle( void )
CG_FillRect( 319, 300, 2, 178, black ); // center bot
CG_FillRect( 380, 239, 177, 2, black ); // right
}
// sides
CG_FillRect( 0, 0, (X_WIDTH * indent)+1, Y_HEIGHT, black );
CG_FillRect( X_WIDTH * (1 - indent) - 1, 0, (X_WIDTH * indent) + 2, Y_HEIGHT, black );
// top/bottom
CG_FillRect( X_WIDTH * indent, 0, X_WIDTH * (1-indent), Y_HEIGHT * indent + 1, black );
CG_FillRect( X_WIDTH * indent, Y_HEIGHT * (1-indent) - 1, X_WIDTH * (1-indent), Y_HEIGHT * indent + 2, black );
}
//--------------------------------------

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.25"
#define JKXR_VERSION "1.1.28"
#ifdef _DEBUG
#define Q3_VERSION "(debug)OpenJK: v" VERSION_STRING_DOTTED " JKXR: " JKXR_VERSION

View file

@ -725,37 +725,38 @@ CG_DrawWeapReticle
*/
static void CG_DrawWeapReticle( void )
{
vec4_t light_color = {0.7, 0.7, 0.7, 1};
vec4_t black = {0.0, 0.0, 0.0, 1};
vec4_t light_color = {0.7, 0.7, 0.7, 1};
vec4_t black = {0.0, 0.0, 0.0, 1};
float indent = 0.1;
float X_WIDTH=640;
float Y_HEIGHT=480;
float indent = 0.12;
float X_WIDTH=640;
float Y_HEIGHT=480;
float STRETCH = 6;
float x = (X_WIDTH * indent), y = (Y_HEIGHT * indent), w = (X_WIDTH * (1-(2*indent))) / 2.0f, h = (Y_HEIGHT * (1-(2*indent))) / 2;
float x = (X_WIDTH * indent), y = (Y_HEIGHT * indent), w = (X_WIDTH * (1-(2*indent))) / 2.0f, h = (Y_HEIGHT * (1-(2*indent))) / 2;
{
// center
if ( cgs.media.reticleShader ) {
cgi_R_DrawStretchPic( x - STRETCH, y - STRETCH, w + STRETCH, h+STRETCH, 0, 0, 1, 1, cgs.media.reticleShader ); // tl
cgi_R_DrawStretchPic( x + w, y - STRETCH, w + STRETCH, h + STRETCH, 1, 0, 0, 1, cgs.media.reticleShader ); // tr
cgi_R_DrawStretchPic( x - STRETCH, y + h, w + STRETCH, h + STRETCH, 0, 1, 1, 0, cgs.media.reticleShader ); // bl
cgi_R_DrawStretchPic( x + w, y + h, w + STRETCH, h + STRETCH, 1, 1, 0, 0, cgs.media.reticleShader ); // br
}
// hairs
CG_FillRect( 84, 239, 177, 2, black ); // left
CG_FillRect( 320, 242, 1, 58, black ); // center top
CG_FillRect( 319, 300, 2, 178, black ); // center bot
CG_FillRect( 380, 239, 177, 2, black ); // right
}
// sides
CG_FillRect(0, 0, (X_WIDTH * indent) + 1, Y_HEIGHT, black);
CG_FillRect(X_WIDTH * (1 - indent) - 1, 0, (X_WIDTH * indent) + 2, Y_HEIGHT, black);
CG_FillRect( 0, 0, (X_WIDTH * indent)+1, Y_HEIGHT, black );
CG_FillRect( X_WIDTH * (1 - indent) - 1, 0, (X_WIDTH * indent) + 2, Y_HEIGHT, black );
// top/bottom
CG_FillRect(X_WIDTH * indent, 0, X_WIDTH * (1 - indent), Y_HEIGHT * indent + 1, black);
CG_FillRect(X_WIDTH * indent, Y_HEIGHT * (1 - indent) - 1, X_WIDTH * (1 - indent), Y_HEIGHT * indent + 2, black);
{
// center
if ( cgs.media.reticleShader ) {
cgi_R_DrawStretchPic( x, y, w, h, 0, 0, 1, 1, cgs.media.reticleShader ); // tl
cgi_R_DrawStretchPic( x + w, y, w, h, 1, 0, 0, 1, cgs.media.reticleShader ); // tr
cgi_R_DrawStretchPic( x, y + h, w, h, 0, 1, 1, 0, cgs.media.reticleShader ); // bl
cgi_R_DrawStretchPic( x + w, y + h, w, h, 1, 1, 0, 0, cgs.media.reticleShader ); // br
}
// hairs
CG_FillRect( 84, 239, 177, 2, black ); // left
CG_FillRect( 320, 242, 1, 58, black ); // center top
CG_FillRect( 319, 300, 2, 178, black ); // center bot
CG_FillRect( 380, 239, 177, 2, black ); // right
}
CG_FillRect( X_WIDTH * indent, 0, X_WIDTH * (1-indent), Y_HEIGHT * indent + 1, black );
CG_FillRect( X_WIDTH * indent, Y_HEIGHT * (1-indent) - 1, X_WIDTH * (1-indent), Y_HEIGHT * indent + 2, black );
}
//--------------------------------------

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,25 +7,24 @@
[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
This is currently built for standalone VR HMDs (see the Building section below) and will currently **not** run on any other device, the list of supported devices is: Meta Quest (1, 2, Pro) and Pico (3 & 4).
Support for PCVR based devices will hopefully come in the future.
The easiest way to install this on your device is using SideQuest. Download SideQuest here:
https://sidequestvr.com/setup-howto
### Jedi Knight: Jedi Outcast
### Jedi Knight: Jedi Outcast / Jedi Academy
The public release of JK XR currently supports the game Jedi Outcast; access to the Jedi Academy early-access build can be found on the Team Beef patreon (link below). However there are lots of mods and access to the free demo level available through the accomapnying JK XR Companion App, which is also installed alongside JK XR on SideQuest.
The public release of JK XR now supports the games Jedi Outcast and Jedi Academy.
## Team Beef Patreon
[![Team Beef Patreon](https://github.com/DrBeef/JKXR/blob/main/assets/PatreonBanner.jpg)](https://www.patreon.com/teambeef)
The Team Beef Patreon where you can find all the in-development early-access builds for JK XR with Jedi Academy support, as well as other active projects can be found.
The Team Beef Patreon where you can find all the in-development early-access builds other active Team Beef projects.
## Gameplay and VR Features
@ -68,22 +67,51 @@ The companion app will be installed at the same time when using the SideQuest of
You can find the latest version, which also includes the Companion App hosted on Sidequest. Use the links at the top of the page (separated by headset). Before installing via SideQuest you must have enabled "Developer Mode" on your headset. You can find the details on how to do that below:
Pico 3/4 Instructions
---------------------
https://trello.com/c/Idb627uv/47-pico-4-installation-instructions
Meta Quest Install Instructions
-------------------------------
https://trello.com/c/C0YTFpvX/48-quest-quest-2-installation-instructions
## Copying the Full Game files to your Oculus Quest
PCVR
----
Download the PCVR installers from the release page and use them to install to the game location.
### OpenXR runtimes information for PCVR Headsets
We recommend the following combinations to get the optimal experience while playing JKXR on PCVR:
**Valve Index** -> Via SteamVR (SteamVR OpenXR Runtime)
**HTC Vive** -> Via SteamVR (SteamVR 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** - Virtual Desktop (VDXR or SteamVR) / Streaming Assistant (Currently Untested)
## Copying the Full Game files to your Meta Quest / Pico
Before you are able to run the full game of Jedi Knight: Jedi Outcast in VR you will need to:
- Install JK XR thought SideQuest (this will also install the companion app)
- Start JK XR for the first time, it will ask for appropriate permissions (which you must allow), create the necessary folders and then close down
- You can now run the Companion App. This will check that it has the files for the full game.
- (optional) Copy only the assets files (assets0.pk3, assets1.pk3, assets2.pk3, assets5.pk3) from your PC install of JKO (Jedi Outcast\GameData\base) into the following folder on your device:
- Copy only the assets files (assets0.pk3, assets1.pk3, assets2.pk3, assets5.pk3) from your PC install of JKO (Jedi Outcast\GameData\base) into the following folder on your device:
\JKXR\JK2\base
or
\JKXR\JK3\base
- You must then use the Companion App to download any mods and start the game. It is possible to play the JK Demo without having copied across the full game assets. All other mods require the full game.
@ -108,6 +136,9 @@ This control scheme on how to play can also be found in the Controls -> JKXR HEL
![Control Scheme](https://github.com/DrBeef/JKXR/blob/main/z_vr_assets_base/gfx/menus/control_scheme.jpg)
## Building from Source
If you wish to build JK XR from source, then you need the following:
@ -121,6 +152,9 @@ There is no dependency on any specific headset native libraries, as this port us
JKXR\Projects\Android\libs\arm64-v8a
PCVR instructions will follow in the future (when I get round to adding them),
## Credits
* Team Beef are DrBeef, Baggyg, Bummser
@ -128,7 +162,9 @@ JKXR\Projects\Android\libs\arm64-v8a
* JKXR Companion App: BaggyG
* Additional Development Contributions: MuadDib, BaggyG
* VR Compatible Weapon Models: Vince Crusty and Elin
* With Special Thanks to: Team Beef patrons, all Team Beef discord members,
* VR Compatible Hand Models: LennyGuy20
With Special Thanks to: Team Beef patrons, all Team Beef discord members,
the OpenJK Development Team and Raven Software for
creating and open-sourcing these wonderful games

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 167 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/teambeef_adaptive_back"/>
<foreground android:drawable="@mipmap/teambeef_adaptive_fore"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB