Small spectator fixes

- Switch between Follow modes (1st and 3rd person) using the X button
- Switch back to the "Spectate" mode using the A button when in follow mode
- 1st Person follow mode is on a virtual screen (to avoid nausea)
- Slider for haptic intensity: affects both controller and bhaptics level
- Move 3rd person Spectator and Death Cam closer to player's viewpoint
This commit is contained in:
Simon 2022-03-05 19:26:39 +00:00
parent 9426f8605b
commit e4d49b44e6
12 changed files with 133 additions and 39 deletions

View file

@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.drbeef.ioq3quest" package="com.drbeef.ioq3quest"
android:installLocation="preferExternal" android:installLocation="preferExternal"
android:versionCode="25" android:versionCode="26"
android:versionName="0.18.0"> android:versionName="0.19.0">
<uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" /> <uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" />
<uses-feature android:glEsVersion="0x00030001" /> <uses-feature android:glEsVersion="0x00030001" />
<!-- <uses-feature android:name="oculus.software.overlay_keyboard" android:required="false"/>--> <!-- <uses-feature android:name="oculus.software.overlay_keyboard" android:required="false"/>-->

View file

@ -2725,33 +2725,43 @@ void CG_DrawActive( stereoFrame_t stereoView ) {
vec3_t baseOrg; vec3_t baseOrg;
VectorCopy( cg.refdef.vieworg, baseOrg ); VectorCopy( cg.refdef.vieworg, baseOrg );
float heightOffset = 0.0f;
float worldscale = trap_Cvar_VariableValue("vr_worldscale"); float worldscale = trap_Cvar_VariableValue("vr_worldscale");
if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW)) if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON))
{ {
worldscale *= SPECTATOR_WORLDSCALE_MULTIPLIER; worldscale *= SPECTATOR_WORLDSCALE_MULTIPLIER;
//Just move camera down about 20cm
heightOffset = -0.2f;
} }
else if (( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) && else if (( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) &&
( cg.snap->ps.pm_type != PM_INTERMISSION )) ( cg.snap->ps.pm_type != PM_INTERMISSION ))
{ {
worldscale *= DEATH_WORLDSCALE_MULTIPLIER; worldscale *= DEATH_WORLDSCALE_MULTIPLIER;
//Just move camera down about 50cm
heightOffset = -0.5f;
} }
float ipd = trap_Cvar_VariableValue("r_stereoSeparation") / 1000.0f; float ipd = trap_Cvar_VariableValue("r_stereoSeparation") / 1000.0f;
float separation = worldscale * (ipd / 2) * (stereoView == STEREO_LEFT ? -1.0f : 1.0f); float separation = worldscale * (ipd / 2) * (stereoView == STEREO_LEFT ? -1.0f : 1.0f);
if (cgs.localServer) { if (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_FIRSTPERSON)
cg.refdef.vieworg[2] -= PLAYER_HEIGHT; {
cg.refdef.vieworg[2] += vr->hmdposition[1] * worldscale; //Do nothing to view height if we are following in first person
} }
else else
{
cg.refdef.vieworg[2] -= PLAYER_HEIGHT;
cg.refdef.vieworg[2] += (vr->hmdposition[1] + heightOffset) * worldscale;
}
if (!cgs.localServer)
{ {
//If connected to external server, allow some amount of faked positional tracking //If connected to a remote server, allow some amount of faked positional tracking
cg.refdef.vieworg[2] -= PLAYER_HEIGHT;
cg.refdef.vieworg[2] += vr->hmdposition[1] * worldscale;
if (cg.snap->ps.stats[STAT_HEALTH] > 0 && if (cg.snap->ps.stats[STAT_HEALTH] > 0 &&
//Don't use fake positional if following another player - this is handled in the //Don't use fake positional if following another player - this is handled in the
//VR third person code //VR third person code
!( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW))) !( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON)))
{ {
vec3_t pos, hmdposition, vieworg; vec3_t pos, hmdposition, vieworg;
VectorClear(pos); VectorClear(pos);

View file

@ -77,7 +77,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define NUM_CROSSHAIRS 10 #define NUM_CROSSHAIRS 10
//multiplying size you go to when dead looking down on the match //multiplying size you go to when dead looking down on the match
#define DEATH_WORLDSCALE_MULTIPLIER 40 #define DEATH_WORLDSCALE_MULTIPLIER 30
#define SPECTATOR_WORLDSCALE_MULTIPLIER 10 #define SPECTATOR_WORLDSCALE_MULTIPLIER 10
#define PLAYER_HEIGHT 48 #define PLAYER_HEIGHT 48

View file

@ -2030,7 +2030,7 @@ static void CG_PlayerSprites( centity_t *cent ) {
//Put a sprite over the followed player's head //Put a sprite over the followed player's head
if ( cent->currentState.number == cg.snap->ps.clientNum && if ( cent->currentState.number == cg.snap->ps.clientNum &&
cg.renderingThirdPerson && cg.renderingThirdPerson &&
cg.snap->ps.pm_flags & PMF_FOLLOW) { (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON)) {
CG_PlayerFloatSprite( cent, cgs.media.friendShader ); CG_PlayerFloatSprite( cent, cgs.media.friendShader );
return; return;
} }

View file

@ -227,16 +227,15 @@ CG_OffsetVRThirdPersonView
static void CG_OffsetVRThirdPersonView( void ) { static void CG_OffsetVRThirdPersonView( void ) {
float scale = 1.0f; float scale = 1.0f;
if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW)) if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON))
{ {
scale *= SPECTATOR_WORLDSCALE_MULTIPLIER; scale *= SPECTATOR_WORLDSCALE_MULTIPLIER;
//Check to see if the followed player has moved far enough away to mean we should update our location //Check to see if the followed player has moved far enough away to mean we should update our location
vec3_t currentOrigin; vec3_t current;
VectorCopy(cg.refdef.vieworg, currentOrigin); VectorSubtract(cg.refdef.vieworg, cg.vr_vieworigin, current);
VectorSubtract(currentOrigin, cg.vr_vieworigin, currentOrigin); current[2] = 0;
currentOrigin[2] = 0; if (VectorLength(current) > 400)
if (VectorLength(currentOrigin) > 400)
{ {
VectorCopy(cg.refdef.vieworg, cg.vr_vieworigin); VectorCopy(cg.refdef.vieworg, cg.vr_vieworigin);
@ -665,7 +664,7 @@ static int CG_CalcViewValues( stereoFrame_t stereoView ) {
trap_Cvar_Set( "vr_noSkybox", (((ps->stats[STAT_HEALTH] <= 0) && trap_Cvar_Set( "vr_noSkybox", (((ps->stats[STAT_HEALTH] <= 0) &&
( ps->pm_type != PM_INTERMISSION )) || ( ps->pm_type != PM_INTERMISSION )) ||
cg.demoPlayback || cg.demoPlayback ||
(cg.snap->ps.pm_flags & PMF_FOLLOW) ? "1" : "0" )); (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON) ? "1" : "0" ));
// intermission view // intermission view
static float hmdYaw = 0; static float hmdYaw = 0;
@ -722,7 +721,7 @@ static int CG_CalcViewValues( stereoFrame_t stereoView ) {
if (( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) && if (( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) &&
( cg.predictedPlayerState.pm_type != PM_INTERMISSION ) || ( cg.predictedPlayerState.pm_type != PM_INTERMISSION ) ||
( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW))) ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON)))
{ {
//If dead, or spectating, view the map from above //If dead, or spectating, view the map from above
CG_OffsetVRThirdPersonView(); CG_OffsetVRThirdPersonView();
@ -797,7 +796,7 @@ static int CG_CalcViewValues( stereoFrame_t stereoView ) {
angles[ROLL] = vr->hmdorientation[ROLL]; angles[ROLL] = vr->hmdorientation[ROLL];
AnglesToAxis( angles, cg.refdef.viewaxis ); AnglesToAxis( angles, cg.refdef.viewaxis );
} }
else if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW)) else if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON))
{ {
//If we're following someone, //If we're following someone,
vec3_t angles; vec3_t angles;
@ -805,7 +804,7 @@ static int CG_CalcViewValues( stereoFrame_t stereoView ) {
angles[YAW] = vr->clientviewangles[YAW]; angles[YAW] = vr->clientviewangles[YAW];
AnglesToAxis(angles, cg.refdef.viewaxis); AnglesToAxis(angles, cg.refdef.viewaxis);
} }
else else if (!(cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_FIRSTPERSON))
{ {
//We are connected to a multiplayer server, so make the appropriate adjustment to the view //We are connected to a multiplayer server, so make the appropriate adjustment to the view
//angles as we send orientation to the server that includes the weapon angles //angles as we send orientation to the server that includes the weapon angles
@ -815,6 +814,10 @@ static int CG_CalcViewValues( stereoFrame_t stereoView ) {
angles[YAW] = deltaYaw + vr->clientviewangles[YAW]; angles[YAW] = deltaYaw + vr->clientviewangles[YAW];
AnglesToAxis(angles, cg.refdef.viewaxis); AnglesToAxis(angles, cg.refdef.viewaxis);
} }
else
{
AnglesToAxis(cg.refdefViewAngles, cg.refdef.viewaxis);
}
} else { } else {
if (vr->weapon_zoomed) { if (vr->weapon_zoomed) {
vec3_t angles; vec3_t angles;
@ -823,7 +826,7 @@ static int CG_CalcViewValues( stereoFrame_t stereoView ) {
angles[YAW] = (cg.refdefViewAngles[YAW] - vr->hmdorientation[YAW]) + vr->weaponangles[YAW]; angles[YAW] = (cg.refdefViewAngles[YAW] - vr->hmdorientation[YAW]) + vr->weaponangles[YAW];
AnglesToAxis(angles, cg.refdef.viewaxis); AnglesToAxis(angles, cg.refdef.viewaxis);
} }
else if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW)) else if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON))
{ {
//If we're following someone, //If we're following someone,
vec3_t angles; vec3_t angles;
@ -954,7 +957,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
// decide on third person view // decide on third person view
cg.renderingThirdPerson = cg.predictedPlayerState.pm_type == PM_SPECTATOR || cg.renderingThirdPerson = cg.predictedPlayerState.pm_type == PM_SPECTATOR ||
cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) || cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON) ||
cg_thirdPerson.integer; cg_thirdPerson.integer;
// build cg.refdef // build cg.refdef

View file

@ -1714,6 +1714,7 @@ void CG_AddViewWeapon( playerState_t *ps ) {
//Scale / Move gun etc //Scale / Move gun etc
float scale = 1.0f; float scale = 1.0f;
if (!(cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_FIRSTPERSON))
{ {
char cvar_name[64]; char cvar_name[64];
Com_sprintf(cvar_name, sizeof(cvar_name), "vr_weapon_adjustment_%i", ps->weapon); Com_sprintf(cvar_name, sizeof(cvar_name), "vr_weapon_adjustment_%i", ps->weapon);

View file

@ -55,8 +55,9 @@ VR OPTIONS MENU
#define ID_SENDROLL 141 #define ID_SENDROLL 141
#define ID_LASERSIGHT 142 #define ID_LASERSIGHT 142
#define ID_GORE 143 #define ID_GORE 143
#define ID_HAPTICINTENSITY 144
#define ID_BACK 144 #define ID_BACK 145
#define NUM_HUDDEPTH 6 #define NUM_HUDDEPTH 6
#define NUM_DIRECTIONMODE 2 #define NUM_DIRECTIONMODE 2
@ -86,6 +87,7 @@ typedef struct {
menuslider_s hudyoffset; menuslider_s hudyoffset;
menuradiobutton_s sendroll; menuradiobutton_s sendroll;
menuradiobutton_s lasersight; menuradiobutton_s lasersight;
menuslider_s hapticintensity;
menulist_s gore; menulist_s gore;
menubitmap_s back; menubitmap_s back;
@ -219,6 +221,10 @@ static void VR_Event( void* ptr, int notification ) {
trap_Cvar_SetValue( "vr_lasersight", s_VR.lasersight.curvalue); trap_Cvar_SetValue( "vr_lasersight", s_VR.lasersight.curvalue);
break; break;
case ID_HAPTICINTENSITY:
trap_Cvar_SetValue( "vr_hapticIntensity", s_VR.hapticintensity.curvalue);
break;
case ID_GORE: { case ID_GORE: {
switch ((int)s_VR.gore.curvalue) { switch ((int)s_VR.gore.curvalue) {
case 0: case 0:
@ -478,6 +484,17 @@ static void VR_MenuInit( void ) {
s_VR.lasersight.generic.x = VR_X_POS; s_VR.lasersight.generic.x = VR_X_POS;
s_VR.lasersight.generic.y = y; s_VR.lasersight.generic.y = y;
y += BIGCHAR_HEIGHT;
s_VR.hapticintensity.generic.type = MTYPE_SLIDER;
s_VR.hapticintensity.generic.x = VR_X_POS;
s_VR.hapticintensity.generic.y = y;
s_VR.hapticintensity.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
s_VR.hapticintensity.generic.name = "Haptic Intensity:";
s_VR.hapticintensity.generic.id = ID_HAPTICINTENSITY;
s_VR.hapticintensity.generic.callback = VR_Event;
s_VR.hapticintensity.minvalue = 0;
s_VR.hapticintensity.maxvalue = 1.0;
y += BIGCHAR_HEIGHT + 10; y += BIGCHAR_HEIGHT + 10;
s_VR.gore.generic.type = MTYPE_SPINCONTROL; s_VR.gore.generic.type = MTYPE_SPINCONTROL;
s_VR.gore.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; s_VR.gore.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
@ -518,6 +535,7 @@ static void VR_MenuInit( void ) {
Menu_AddItem( &s_VR.menu, &s_VR.hudyoffset ); Menu_AddItem( &s_VR.menu, &s_VR.hudyoffset );
Menu_AddItem( &s_VR.menu, &s_VR.sendroll ); Menu_AddItem( &s_VR.menu, &s_VR.sendroll );
Menu_AddItem( &s_VR.menu, &s_VR.lasersight ); Menu_AddItem( &s_VR.menu, &s_VR.lasersight );
Menu_AddItem( &s_VR.menu, &s_VR.hapticintensity );
Menu_AddItem( &s_VR.menu, &s_VR.gore ); Menu_AddItem( &s_VR.menu, &s_VR.gore );
Menu_AddItem( &s_VR.menu, &s_VR.back ); Menu_AddItem( &s_VR.menu, &s_VR.back );

View file

@ -33,6 +33,7 @@ cvar_t *vr_rollWhenHit = NULL;
cvar_t *vr_hudYOffset = NULL; cvar_t *vr_hudYOffset = NULL;
cvar_t *vr_sendRollToServer = NULL; cvar_t *vr_sendRollToServer = NULL;
cvar_t *vr_lasersight = NULL; cvar_t *vr_lasersight = NULL;
cvar_t *vr_hapticIntensity = NULL;
engine_t* VR_Init( ovrJava java ) engine_t* VR_Init( ovrJava java )
{ {
@ -67,6 +68,7 @@ void VR_InitCvars( void )
vr_hudYOffset = Cvar_Get ("vr_hudYOffset", "0", CVAR_ARCHIVE); vr_hudYOffset = Cvar_Get ("vr_hudYOffset", "0", CVAR_ARCHIVE);
vr_sendRollToServer = Cvar_Get ("vr_sendRollToServer", "1", CVAR_ARCHIVE); vr_sendRollToServer = Cvar_Get ("vr_sendRollToServer", "1", CVAR_ARCHIVE);
vr_lasersight = Cvar_Get ("vr_lasersight", "0", CVAR_ARCHIVE); vr_lasersight = Cvar_Get ("vr_lasersight", "0", CVAR_ARCHIVE);
vr_hapticIntensity = Cvar_Get ("vr_hapticIntensity", "1.0", CVAR_ARCHIVE);
// Values are: scale,right,up,forward,pitch,yaw,roll // Values are: scale,right,up,forward,pitch,yaw,roll
// VALUES PROVIDED BY SkillFur - Thank-you! // VALUES PROVIDED BY SkillFur - Thank-you!

View file

@ -5,6 +5,11 @@
#define NUM_WEAPON_SAMPLES 10 #define NUM_WEAPON_SAMPLES 10
typedef enum {
VRFM_THIRDPERSON,
VRFM_FIRSTPERSON
} followMode_t;
typedef struct { typedef struct {
qboolean weapon_stabilised; qboolean weapon_stabilised;
qboolean weapon_zoomed; qboolean weapon_zoomed;
@ -13,6 +18,7 @@ typedef struct {
qboolean right_handed; qboolean right_handed;
qboolean virtual_screen; qboolean virtual_screen;
qboolean local_server; // used in bg_pmove.c qboolean local_server; // used in bg_pmove.c
followMode_t follow_mode;
int realign; // used to realign the fake 6DoF playspace in a multiplayer game int realign; // used to realign the fake 6DoF playspace in a multiplayer game

View file

@ -71,6 +71,7 @@ extern cvar_t *vr_heightAdjust;
extern cvar_t *vr_twoHandedWeapons; extern cvar_t *vr_twoHandedWeapons;
extern cvar_t *vr_refreshrate; extern cvar_t *vr_refreshrate;
extern cvar_t *vr_weaponScope; extern cvar_t *vr_weaponScope;
extern cvar_t *vr_hapticIntensity;
jclass callbackClass; jclass callbackClass;
jmethodID android_haptic_event; jmethodID android_haptic_event;
@ -206,7 +207,7 @@ void VR_Vibrate( int duration, int chan, float intensity )
return; return;
vibration_channel_duration[channel-1] = duration; vibration_channel_duration[channel-1] = duration;
vibration_channel_intensity[channel-1] = intensity; vibration_channel_intensity[channel-1] = intensity * vr_hapticIntensity->value;
} }
} }
} }
@ -268,9 +269,14 @@ static void IN_SendButtonAction(const char* action, qboolean pressed)
void VR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight ) void VR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight )
{ {
if (vr_hapticIntensity->value == 0.0f)
{
return;
}
engine_t* engine = VR_GetEngine(); engine_t* engine = VR_GetEngine();
jstring StringArg1 = (*(engine->java.Env))->NewStringUTF(engine->java.Env, event); jstring StringArg1 = (*(engine->java.Env))->NewStringUTF(engine->java.Env, event);
(*(engine->java.Env))->CallVoidMethod(engine->java.Env, engine->java.ActivityObject, android_haptic_event, StringArg1, position, flags, intensity, angle, yHeight); (*(engine->java.Env))->CallVoidMethod(engine->java.Env, engine->java.ActivityObject, android_haptic_event, StringArg1, position, flags, intensity * vr_hapticIntensity->value, angle, yHeight);
//Controller Haptic Support //Controller Haptic Support
int weaponFireChannel = vr.weapon_stabilised ? 3 : (vr_righthanded->integer ? 2 : 1); int weaponFireChannel = vr.weapon_stabilised ? 3 : (vr_righthanded->integer ? 2 : 1);
@ -714,14 +720,21 @@ static void IN_VRButtonsChanged( qboolean isRightController, uint32_t buttons )
//Jump //Jump
if ((buttons & ovrButton_A) && !(controller->buttons & ovrButton_A)) if ((buttons & ovrButton_A) && !(controller->buttons & ovrButton_A))
{ {
if (IN_GetButtonAction("A", action)) if (cl.snap.ps.pm_flags & PMF_FOLLOW)
{ {
IN_SendButtonAction(action, qtrue); Cbuf_AddText("cmd team spectator\n");
}
else
{
if (IN_GetButtonAction("A", action))
{
IN_SendButtonAction(action, qtrue);
}
} }
} }
else if (!(buttons & ovrButton_A) && (controller->buttons & ovrButton_A)) else if (!(buttons & ovrButton_A) && (controller->buttons & ovrButton_A))
{ {
if (IN_GetButtonAction("A", action)) if (IN_GetButtonAction("A", action) && !(cl.snap.ps.pm_flags & PMF_FOLLOW))
{ {
IN_SendButtonAction(action, qfalse); IN_SendButtonAction(action, qfalse);
} }
@ -741,17 +754,28 @@ static void IN_VRButtonsChanged( qboolean isRightController, uint32_t buttons )
} }
//X default is "use item" //X default is "use item"
if ((buttons & ovrButton_X) && !(controller->buttons & ovrButton_X)) { if ((buttons & ovrButton_X) && !(controller->buttons & ovrButton_X))
if (IN_GetButtonAction("X", action)) {
if (cl.snap.ps.pm_flags & PMF_FOLLOW)
{ {
IN_SendButtonAction(action, qtrue); //Switch follow mode
vr.follow_mode = 1 - vr.follow_mode;
} }
} else if (!(buttons & ovrButton_X) && (controller->buttons & ovrButton_X)) { else
if (IN_GetButtonAction("X", action)) {
if (IN_GetButtonAction("X", action))
{
IN_SendButtonAction(action, qtrue);
}
}
}
else if (!(buttons & ovrButton_X) && (controller->buttons & ovrButton_X))
{
if (IN_GetButtonAction("X", action) && !(cl.snap.ps.pm_flags & PMF_FOLLOW))
{ {
IN_SendButtonAction(action, qfalse); IN_SendButtonAction(action, qfalse);
} }
} }
//Y default is Gesture //Y default is Gesture
if ((buttons & ovrButton_Y) && !(controller->buttons & ovrButton_Y)) { if ((buttons & ovrButton_Y) && !(controller->buttons & ovrButton_Y)) {

View file

@ -268,7 +268,8 @@ void VR_DrawFrame( engine_t* engine ) {
int eyeW, eyeH; int eyeW, eyeH;
VR_GetResolution(engine, &eyeW, &eyeH); VR_GetResolution(engine, &eyeW, &eyeH);
if (VR_useScreenLayer()) if (VR_useScreenLayer() ||
(cl.snap.ps.pm_flags & PMF_FOLLOW && vr.follow_mode == VRFM_FIRSTPERSON))
{ {
static ovrLayer_Union2 cylinderLayer; static ovrLayer_Union2 cylinderLayer;
memset( &cylinderLayer, 0, sizeof( ovrLayer_Union2 ) ); memset( &cylinderLayer, 0, sizeof( ovrLayer_Union2 ) );

29
android/deploy.bat Normal file
View file

@ -0,0 +1,29 @@
@echo off
setlocal
set BUILD_TYPE=release
set VERSION=0.19.0
set adb="%ANDROID_SDK_ROOT%\platform-tools\adb.exe"
pushd android
set PACKAGE_NAME=com.drbeef.ioq3quest
set ANDROID_STORAGE_LOCATION=/sdcard/ioquake3quest/
set APK_LOCATION=.\app\build\outputs\apk\%BUILD_TYPE%\ioq3quest-%BUILD_TYPE%-%VERSION%.apk
%adb% install -r %APK_LOCATION%
if %ERRORLEVEL% NEQ 0 (
%adb% uninstall %PACKAGE_NAME%
%adb% install %APK_LOCATION%
if %ERRORLEVEL% NEQ 0 (
popd
popd
echo "Failed to install apk."
exit /b 1
)
)
:END
endlocal