diff --git a/android/app/src/main/cpp/code/cgame/cg_draw.c b/android/app/src/main/cpp/code/cgame/cg_draw.c index 72023a40..68d4f325 100644 --- a/android/app/src/main/cpp/code/cgame/cg_draw.c +++ b/android/app/src/main/cpp/code/cgame/cg_draw.c @@ -2853,9 +2853,9 @@ void CG_DrawActive( void ) { cg.refdef.vieworg[2] += (vr->hmdposition[1] + heightOffset) * worldscale; } - if (!cgs.localServer) + if (vr->use_fake_6dof) { - //If connected to a remote server, allow some amount of faked positional tracking + //If running multiplayer, allow some amount of faked positional tracking if (cg.snap->ps.stats[STAT_HEALTH] > 0 && //Don't use fake positional if following another player - this is handled in the //VR third person code diff --git a/android/app/src/main/cpp/code/cgame/cg_local.h b/android/app/src/main/cpp/code/cgame/cg_local.h index 766822b7..1922473c 100644 --- a/android/app/src/main/cpp/code/cgame/cg_local.h +++ b/android/app/src/main/cpp/code/cgame/cg_local.h @@ -1124,6 +1124,7 @@ extern vmCvar_t cg_bobroll; extern vmCvar_t cg_weaponbob; extern vmCvar_t cg_swingSpeed; extern vmCvar_t cg_shadows; +extern vmCvar_t cg_playerShadow; extern vmCvar_t cg_gibs; extern vmCvar_t cg_megagibs; extern vmCvar_t cg_drawTimer; diff --git a/android/app/src/main/cpp/code/cgame/cg_main.c b/android/app/src/main/cpp/code/cgame/cg_main.c index a52d31ef..2e64dc3f 100644 --- a/android/app/src/main/cpp/code/cgame/cg_main.c +++ b/android/app/src/main/cpp/code/cgame/cg_main.c @@ -106,6 +106,7 @@ vmCvar_t cg_bobroll; vmCvar_t cg_weaponbob; vmCvar_t cg_swingSpeed; vmCvar_t cg_shadows; +vmCvar_t cg_playerShadow; vmCvar_t cg_gibs; vmCvar_t cg_megagibs; vmCvar_t cg_drawTimer; @@ -228,6 +229,7 @@ static cvarTable_t cvarTable[] = { { &cg_fov, "cg_fov", "90", CVAR_ARCHIVE }, { &cg_viewsize, "cg_viewsize", "100", CVAR_ARCHIVE }, { &cg_shadows, "cg_shadows", "1", CVAR_ARCHIVE }, + { &cg_playerShadow, "cg_playerShadow", "1", CVAR_ARCHIVE }, { &cg_gibs, "cg_gibs", "1", CVAR_ARCHIVE }, { &cg_megagibs, "cg_megagibs", "0", CVAR_ARCHIVE }, { &cg_draw2D, "cg_draw2D", "1", CVAR_ARCHIVE }, @@ -1977,6 +1979,13 @@ void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum ) { const char *serverinfo = CG_ConfigString( CS_SERVERINFO ); vr->no_crosshair = (strcasestr(serverinfo, "nocrosshair") != NULL || strcasestr(serverinfo, "no crosshair") != NULL); + vr->local_server = cgs.localServer; +#ifdef MISSIONPACK + vr->single_player = trap_Cvar_VariableValue("ui_singlePlayerActive"); +#else + vr->single_player = trap_Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER; +#endif + vr->use_fake_6dof = !vr->single_player; } /* diff --git a/android/app/src/main/cpp/code/cgame/cg_players.c b/android/app/src/main/cpp/code/cgame/cg_players.c index 1afd526f..f6f06c64 100644 --- a/android/app/src/main/cpp/code/cgame/cg_players.c +++ b/android/app/src/main/cpp/code/cgame/cg_players.c @@ -2071,7 +2071,9 @@ static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane ) { *shadowPlane = 0; - if ( cg_shadows.integer == 0 ) { + qboolean clientPlayer = cent->currentState.number == cg.snap->ps.clientNum; + + if ( (clientPlayer && cg_playerShadow.integer == 0) || (!clientPlayer && cg_shadows.integer == 0) ) { return qfalse; } @@ -2080,6 +2082,11 @@ static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane ) { return qfalse; } + // no shadow if VR player is dead + if ( clientPlayer && ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) ) { + return qfalse; + } + // send a trace down from the player to the ground VectorCopy( cent->lerpOrigin, end ); end[2] -= SHADOW_DISTANCE; @@ -2093,7 +2100,8 @@ static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane ) { *shadowPlane = trace.endpos[2] + 1; - if ( cg_shadows.integer != 1 ) { // no mark for stencil or projection shadows + // no mark for stencil or projection shadows + if ( (clientPlayer && cg_playerShadow.integer != 1) || (!clientPlayer && cg_shadows.integer != 1) ) { return qtrue; } @@ -2101,11 +2109,11 @@ static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane ) { alpha = 1.0 - trace.fraction; // hack / FPE - bogus planes? - //assert( DotProduct( trace.plane.normal, trace.plane.normal ) != 0.0f ) + //assert( DotProduct( trace.plane.normal, trace.plane.normal ) != 0.0f ) // add the mark as a temporary, so it goes directly to the renderer // without taking a spot in the cg_marks array - CG_ImpactMark( cgs.media.shadowMarkShader, trace.endpos, trace.plane.normal, + CG_ImpactMark( cgs.media.shadowMarkShader, trace.endpos, trace.plane.normal, cent->pe.legs.yawAngle, alpha,alpha,alpha,1, qfalse, 24, qtrue ); return qtrue; @@ -2125,7 +2133,9 @@ static void CG_PlayerSplash( centity_t *cent ) { int contents; polyVert_t verts[4]; - if ( !cg_shadows.integer ) { + qboolean clientPlayer = cent->currentState.number == cg.snap->ps.clientNum; + + if ( (clientPlayer && !cg_playerShadow.integer) || (!clientPlayer && !cg_shadows.integer) ) { return; } @@ -2391,7 +2401,9 @@ void CG_Player( centity_t *cent ) { // add a water splash if partially in and out of water CG_PlayerSplash( cent ); - if ( cg_shadows.integer == 3 && shadow ) { + qboolean clientPlayer = cent->currentState.number == cg.snap->ps.clientNum; + + if ( shadow && ( (clientPlayer && cg_playerShadow.integer == 3) || (!clientPlayer && cg_shadows.integer == 3) ) ) { renderfx |= RF_SHADOW_PLANE; } renderfx |= RF_LIGHTING_ORIGIN; // use the same origin for all diff --git a/android/app/src/main/cpp/code/cgame/cg_view.c b/android/app/src/main/cpp/code/cgame/cg_view.c index f74eefd9..e7dbfbe0 100644 --- a/android/app/src/main/cpp/code/cgame/cg_view.c +++ b/android/app/src/main/cpp/code/cgame/cg_view.c @@ -745,7 +745,7 @@ static int CG_CalcViewValues( ) { VectorCopy(cg.refdef.vieworg, cg.vr_vieworigin); } - if (!cgs.localServer)// && cg.stereoView == STEREO_LEFT) + if (vr->use_fake_6dof && !vr->virtual_screen) { vec3_t weaponorigin, weaponangles; CG_CalculateVRWeaponPosition(weaponorigin, weaponangles); @@ -807,7 +807,7 @@ static int CG_CalcViewValues( ) { } // position eye relative to origin - if (!cgs.localServer) + if (vr->use_fake_6dof && !vr->virtual_screen) { if (vr->weapon_zoomed) { //If we are zoomed, then we use the refdefViewANgles (which are the weapon angles) diff --git a/android/app/src/main/cpp/code/cgame/cg_weapons.c b/android/app/src/main/cpp/code/cgame/cg_weapons.c index 68eaf649..212ff966 100644 --- a/android/app/src/main/cpp/code/cgame/cg_weapons.c +++ b/android/app/src/main/cpp/code/cgame/cg_weapons.c @@ -231,9 +231,9 @@ void CG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out) VectorSet(vrSpace, in[2], in[0], in[1] ); vec2_t r; - if (!cgs.localServer) + if (vr->use_fake_6dof) { - //We are connected to a multiplayer server, so make the appropriate adjustment to the view + //We are running multiplayer, so make the appropriate adjustment to the view //angles as we send orientation to the server that includes the weapon angles float deltaYaw = SHORT2ANGLE(cg.predictedPlayerState.delta_angles[YAW]); if (cg.snap->ps.pm_flags & PMF_FOLLOW) @@ -262,7 +262,7 @@ void CG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out) static void CG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles ) { - if (!cgs.localServer) + if (vr->use_fake_6dof) { //Use absolute position for the faked 6DoF for multiplayer vec3_t offset; @@ -274,7 +274,7 @@ static void CG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset } else { - //Local server - true 6DoF offset from HMD + //Singleplayer - true 6DoF offset from HMD vec3_t offset; VectorCopy(in_offset, offset); offset[1] = 0; // up/down is index 1 in this case @@ -284,7 +284,7 @@ static void CG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset } VectorCopy(in_orientation, angles); - if ( !cgs.localServer ) + if ( vr->use_fake_6dof ) { //Calculate the offhand angles from "first principles" float deltaYaw = SHORT2ANGLE(cg.predictedPlayerState.delta_angles[YAW]); diff --git a/android/app/src/main/cpp/code/client/cl_input.c b/android/app/src/main/cpp/code/client/cl_input.c index 019a0a0a..5103b70f 100644 --- a/android/app/src/main/cpp/code/client/cl_input.c +++ b/android/app/src/main/cpp/code/client/cl_input.c @@ -599,12 +599,10 @@ void CL_FinishMove( usercmd_t *cmd ) { vr.clientNum = cl.snap.ps.clientNum; - //If we are running with a remote non-vr server, then the best we can do is pass the angles from the weapon - //and adjust the move values accordingly, to "fake" a 3DoF weapon but keeping the movement correct - if ( !com_sv_running || !com_sv_running->integer ) + //If we are running multiplayer, pass the angles from the weapon and adjust the move values accordingly, + // to "fake" a 3DoF weapon but keeping the movement correct (necessary with a remote non-vr server) + if ( vr.use_fake_6dof ) { - vr.local_server = qfalse; - //Realign in playspace if (--vr.realign == 0) { @@ -633,10 +631,6 @@ void CL_FinishMove( usercmd_t *cmd ) { cmd->forwardmove = out[1]; } else { - //Record client number - local server uses this to know we can use absolute angles - //rather than deltas - vr.local_server = qtrue; - for (i = 0; i < 3; i++) { cmd->angles[i] = ANGLE2SHORT(cl.viewangles[i]); } diff --git a/android/app/src/main/cpp/code/game/bg_pmove.c b/android/app/src/main/cpp/code/game/bg_pmove.c index 35cded43..88f59ad3 100644 --- a/android/app/src/main/cpp/code/game/bg_pmove.c +++ b/android/app/src/main/cpp/code/game/bg_pmove.c @@ -50,7 +50,7 @@ extern vr_clientinfo_t *vr; float PM_GetFrictionCoefficient( void ) { - if (vr != NULL && vr->clientNum == pm->ps->clientNum && vr->local_server) { + if (vr != NULL && vr->clientNum == pm->ps->clientNum && !vr->use_fake_6dof) { return 10.0f; } else { return 6.0f; @@ -58,7 +58,7 @@ float PM_GetFrictionCoefficient( void ) { } float PM_GetAccelerationCoefficient( void ) { - if (vr != NULL && vr->clientNum == pm->ps->clientNum && vr->local_server) { + if (vr != NULL && vr->clientNum == pm->ps->clientNum && !vr->use_fake_6dof) { return 1000.0f; } else { return 10.0f; @@ -1828,14 +1828,14 @@ void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd ) { // circularly clamp the angles with deltas for (i=0 ; i<3 ; i++) { - if (vr != NULL && vr->clientNum == ps->clientNum && vr->local_server) + if (vr != NULL && vr->clientNum == ps->clientNum && !vr->use_fake_6dof) { - //Client is the VR player on the "local" server + //Client is the VR player in the singleplayer game temp = cmd->angles[i] + (i == YAW ? ps->delta_angles[i] : 0); } else { - //Client is either a BOT or a remote/connected player, or + //Client is either a BOT or we are running multiplayer, or //the vr player playing on a remote server (since this is shared code by game and cgame) temp = cmd->angles[i] + ps->delta_angles[i]; } diff --git a/android/app/src/main/cpp/code/game/g_main.c b/android/app/src/main/cpp/code/game/g_main.c index e350eef3..499b8580 100644 --- a/android/app/src/main/cpp/code/game/g_main.c +++ b/android/app/src/main/cpp/code/game/g_main.c @@ -519,6 +519,13 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) { char serverinfo[MAX_INFO_STRING]; trap_GetServerinfo( serverinfo, sizeof( serverinfo ) ); vr->no_crosshair = (strcasestr(serverinfo, "nocrosshair") != NULL || strcasestr(serverinfo, "no crosshair") != NULL); + vr->local_server = qtrue; +#ifdef MISSIONPACK + vr->single_player = trap_Cvar_VariableValue("ui_singlePlayerActive"); +#else + vr->single_player = trap_Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER; +#endif + vr->use_fake_6dof = !vr->single_player; } diff --git a/android/app/src/main/cpp/code/game/g_weapon.c b/android/app/src/main/cpp/code/game/g_weapon.c index 35f5ed20..a74ff579 100644 --- a/android/app/src/main/cpp/code/game/g_weapon.c +++ b/android/app/src/main/cpp/code/game/g_weapon.c @@ -109,7 +109,8 @@ qboolean CheckGauntletAttack( gentity_t *ent ) { vec3_t angles; if ( !( ent->r.svFlags & SVF_BOT ) && vr != NULL && - (ent->client->ps.clientNum == vr->clientNum)) + (ent->client->ps.clientNum == vr->clientNum) && + !vr->use_fake_6dof) { VectorCopy(vr->weaponangles, angles); angles[YAW] += ent->client->ps.viewangles[YAW] - vr->hmdorientation[YAW]; @@ -817,7 +818,8 @@ set muzzle location relative to pivoting eye void CalcMuzzlePoint ( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint ) { if ( ( ent->r.svFlags & SVF_BOT ) || //Can't use the vr_clientinfo if this isn't the vr client - vr == NULL || (ent->client->ps.clientNum != vr->clientNum)) + vr == NULL || (ent->client->ps.clientNum != vr->clientNum) || + vr->use_fake_6dof) { VectorCopy( ent->s.pos.trBase, muzzlePoint ); muzzlePoint[2] += ent->client->ps.viewheight; @@ -881,7 +883,8 @@ void FireWeapon( gentity_t *ent ) { vec3_t viewang; if ( !( ent->r.svFlags & SVF_BOT ) && vr != NULL && - (ent->client->ps.clientNum == vr->clientNum)) + (ent->client->ps.clientNum == vr->clientNum) && + !vr->use_fake_6dof) { VectorCopy(vr->weaponangles, viewang); viewang[YAW] += ent->client->ps.viewangles[YAW] - vr->hmdorientation[YAW]; diff --git a/android/app/src/main/cpp/code/q3_ui/ui_video.c b/android/app/src/main/cpp/code/q3_ui/ui_video.c index 658a51af..da61a780 100644 --- a/android/app/src/main/cpp/code/q3_ui/ui_video.c +++ b/android/app/src/main/cpp/code/q3_ui/ui_video.c @@ -252,10 +252,11 @@ GRAPHICS OPTIONS MENU #define ID_DYNAMICLIGHTS 112 #define ID_SYNCEVERYFRAME 113 #define ID_SHADOWS 114 -#define ID_GAMMA 115 +#define ID_PLAYERSHADOW 115 +#define ID_GAMMA 116 #define NUM_REFRESHRATE 4 -#define NUM_SHADOWS 2 +#define NUM_SHADOWS 3 typedef struct { menuframework_s menu; @@ -286,6 +287,7 @@ typedef struct { menuradiobutton_s dynamiclights; menuradiobutton_s synceveryframe; menulist_s shadows; + menulist_s playershadow; menuslider_s gamma; menubitmap_s apply; @@ -308,6 +310,7 @@ typedef struct qboolean dynamiclights; qboolean synceveryframe; int shadows; + int playershadow; float gamma; } InitialVideoOptions_s; @@ -501,6 +504,7 @@ static void GraphicsOptions_GetInitialVideo( void ) s_ivo.dynamiclights = s_graphicsoptions.dynamiclights.curvalue; s_ivo.synceveryframe = s_graphicsoptions.synceveryframe.curvalue; s_ivo.shadows = s_graphicsoptions.refreshrate.curvalue; + s_ivo.playershadow = s_graphicsoptions.playershadow.curvalue; s_ivo.gamma = s_graphicsoptions.gamma.curvalue; } @@ -836,8 +840,11 @@ static void GraphicsOptions_Event( void* ptr, int event ) { int shadows; switch (s_graphicsoptions.shadows.curvalue) { case 0: - shadows = 1; + shadows = 0; break; + case 1: + shadows = 1; + break; default: shadows = 3; break; @@ -846,6 +853,23 @@ static void GraphicsOptions_Event( void* ptr, int event ) { } break; + case ID_PLAYERSHADOW: { + int shadow; + switch (s_graphicsoptions.playershadow.curvalue) { + case 0: + shadow = 0; + break; + case 1: + shadow = 1; + break; + default: + shadow = 3; + break; + } + trap_Cvar_SetValue("cg_playerShadow", shadow); + } + break; + case ID_GAMMA: trap_Cvar_SetValue( "r_gamma", s_graphicsoptions.gamma.curvalue ); break; @@ -1046,12 +1070,28 @@ static void GraphicsOptions_SetMenuItems( void ) switch ( (int) trap_Cvar_VariableValue( "cg_shadows" ) ) { - case 1: + case 0: s_graphicsoptions.shadows.curvalue = 0; break; - default: + case 1: s_graphicsoptions.shadows.curvalue = 1; break; + default: + s_graphicsoptions.shadows.curvalue = 2; + break; + } + + switch ( (int) trap_Cvar_VariableValue( "cg_playerShadow" ) ) + { + case 0: + s_graphicsoptions.playershadow.curvalue = 0; + break; + case 1: + s_graphicsoptions.playershadow.curvalue = 1; + break; + default: + s_graphicsoptions.playershadow.curvalue = 2; + break; } s_graphicsoptions.dynamiclights.curvalue = trap_Cvar_VariableValue( "r_dynamiclight" ) != 0; @@ -1137,6 +1177,7 @@ void GraphicsOptions_MenuInit( void ) }; static const char *s_shadows[] = { + "None", "Low", "High", NULL @@ -1219,7 +1260,7 @@ void GraphicsOptions_MenuInit( void ) s_graphicsoptions.network.style = UI_RIGHT; s_graphicsoptions.network.color = color_red; - y = 254 - 4 * (BIGCHAR_HEIGHT + 2); + y = 254 - 5 * (BIGCHAR_HEIGHT + 2); // s_graphicsoptions.list.generic.type = MTYPE_SPINCONTROL; // s_graphicsoptions.list.generic.name = "Graphics Settings:"; // s_graphicsoptions.list.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; @@ -1342,7 +1383,7 @@ void GraphicsOptions_MenuInit( void ) // references "cg_shadows" s_graphicsoptions.shadows.generic.type = MTYPE_SPINCONTROL; - s_graphicsoptions.shadows.generic.name = "Shadow Detail:"; + s_graphicsoptions.shadows.generic.name = "Opponent Shadows:"; s_graphicsoptions.shadows.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; s_graphicsoptions.shadows.generic.x = 400; s_graphicsoptions.shadows.generic.y = y; @@ -1352,6 +1393,18 @@ void GraphicsOptions_MenuInit( void ) s_graphicsoptions.shadows.numitems = NUM_SHADOWS; y += BIGCHAR_HEIGHT+2; + // references "cg_playerShadow" + s_graphicsoptions.playershadow.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.playershadow.generic.name = "Player Shadow:"; + s_graphicsoptions.playershadow.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.playershadow.generic.x = 400; + s_graphicsoptions.playershadow.generic.y = y; + s_graphicsoptions.playershadow.itemnames = s_shadows; + s_graphicsoptions.playershadow.generic.callback = GraphicsOptions_Event; + s_graphicsoptions.playershadow.generic.id = ID_PLAYERSHADOW; + s_graphicsoptions.playershadow.numitems = NUM_SHADOWS; + y += BIGCHAR_HEIGHT+2; + // references/modifies "r_lodBias" & "subdivisions" s_graphicsoptions.geometry.generic.type = MTYPE_SPINCONTROL; s_graphicsoptions.geometry.generic.name = "Geometric Detail:"; @@ -1443,6 +1496,7 @@ void GraphicsOptions_MenuInit( void ) Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.lighting ); Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.dynamiclights ); Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.shadows ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.playershadow ); Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.geometry ); Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.tq ); // Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.texturebits ); diff --git a/android/app/src/main/cpp/code/renderergles3/tr_animation.c b/android/app/src/main/cpp/code/renderergles3/tr_animation.c index 38fffc64..95c54019 100644 --- a/android/app/src/main/cpp/code/renderergles3/tr_animation.c +++ b/android/app/src/main/cpp/code/renderergles3/tr_animation.c @@ -243,7 +243,7 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { } // set up lighting - if ( !personalModel || r_shadows->integer > 1 ) + if ( !personalModel || r_shadows->integer > 1 || r_playerShadow->integer > 1) { R_SetupEntityLighting( &tr.refdef, ent ); } @@ -292,7 +292,7 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { } // projection shadows work fine with personal models - if ( r_shadows->integer == 3 + if ( (r_shadows->integer == 3 || r_playerShadow->integer == 3) && fogNum == 0 && (ent->e.renderfx & RF_SHADOW_PLANE ) && shader->sort == SS_OPAQUE ) diff --git a/android/app/src/main/cpp/code/renderergles3/tr_init.c b/android/app/src/main/cpp/code/renderergles3/tr_init.c index eb4bb5e2..4c4795f2 100644 --- a/android/app/src/main/cpp/code/renderergles3/tr_init.c +++ b/android/app/src/main/cpp/code/renderergles3/tr_init.c @@ -181,6 +181,7 @@ cvar_t *r_lightmap; cvar_t *r_vertexLight; cvar_t *r_uiFullScreen; cvar_t *r_shadows; +cvar_t *r_playerShadow; cvar_t *r_flares; cvar_t *r_mode; cvar_t *r_nobind; @@ -1377,6 +1378,7 @@ void R_Register( void ) r_lockpvs = ri.Cvar_Get ("r_lockpvs", "0", CVAR_CHEAT); r_noportals = ri.Cvar_Get ("r_noportals", "0", CVAR_CHEAT); r_shadows = ri.Cvar_Get( "cg_shadows", "1", 0 ); + r_playerShadow = ri.Cvar_Get( "cg_playerShadow", "1", 0); r_marksOnTriangleMeshes = ri.Cvar_Get("r_marksOnTriangleMeshes", "0", CVAR_ARCHIVE); diff --git a/android/app/src/main/cpp/code/renderergles3/tr_local.h b/android/app/src/main/cpp/code/renderergles3/tr_local.h index 49b833ed..9150e636 100644 --- a/android/app/src/main/cpp/code/renderergles3/tr_local.h +++ b/android/app/src/main/cpp/code/renderergles3/tr_local.h @@ -1758,7 +1758,8 @@ extern cvar_t *r_showsky; // forces sky in front of all surfaces extern cvar_t *r_shownormals; // draws wireframe normals extern cvar_t *r_clear; // force screen clear every frame -extern cvar_t *r_shadows; // controls shadows: 0 = none, 1 = blur, 2 = stencil, 3 = black planar projection +extern cvar_t *r_shadows; // controls global shadows: 0 = none, 1 = blur, 2 = stencil, 3 = black planar projection +extern cvar_t *r_playerShadow; // controls player shadow: 0 = none, 1 = blur, 2 = stencil, 3 = black planar projection extern cvar_t *r_flares; // light flares extern cvar_t *r_intensity; diff --git a/android/app/src/main/cpp/code/renderergles3/tr_mesh.c b/android/app/src/main/cpp/code/renderergles3/tr_mesh.c index 967199d0..6f993059 100644 --- a/android/app/src/main/cpp/code/renderergles3/tr_mesh.c +++ b/android/app/src/main/cpp/code/renderergles3/tr_mesh.c @@ -350,7 +350,7 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { // // set up lighting now that we know we aren't culled // - if ( !personalModel || r_shadows->integer > 1 ) { + if ( !personalModel || r_shadows->integer > 1 || r_playerShadow->integer > 1) { R_SetupEntityLighting( &tr.refdef, ent ); } @@ -400,7 +400,7 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { // stencil shadows can't do personal models unless I polyhedron clip if ( !personalModel - && r_shadows->integer == 2 + && r_shadows->integer == 2 && fogNum == 0 && !(ent->e.renderfx & ( RF_NOSHADOW | RF_DEPTHHACK ) ) && shader->sort == SS_OPAQUE ) { @@ -408,7 +408,7 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { } // projection shadows work fine with personal models - if ( r_shadows->integer == 3 + if ( (r_shadows->integer == 3 || r_playerShadow->integer == 3) && fogNum == 0 && (ent->e.renderfx & RF_SHADOW_PLANE ) && shader->sort == SS_OPAQUE ) { diff --git a/android/app/src/main/cpp/code/renderergles3/tr_model_iqm.c b/android/app/src/main/cpp/code/renderergles3/tr_model_iqm.c index 165ac75c..a94486ee 100644 --- a/android/app/src/main/cpp/code/renderergles3/tr_model_iqm.c +++ b/android/app/src/main/cpp/code/renderergles3/tr_model_iqm.c @@ -1276,7 +1276,7 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { // // set up lighting now that we know we aren't culled // - if ( !personalModel || r_shadows->integer > 1 ) { + if ( !personalModel || r_shadows->integer > 1 || r_playerShadow->integer > 1) { R_SetupEntityLighting( &tr.refdef, ent ); } @@ -1317,7 +1317,7 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { // stencil shadows can't do personal models unless I polyhedron clip if ( !personalModel - && r_shadows->integer == 2 + && r_shadows->integer == 2 && fogNum == 0 && !(ent->e.renderfx & ( RF_NOSHADOW | RF_DEPTHHACK ) ) && shader->sort == SS_OPAQUE ) { @@ -1325,7 +1325,7 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { } // projection shadows work fine with personal models - if ( r_shadows->integer == 3 + if ( (r_shadows->integer == 3 || r_playerShadow->integer == 3) && fogNum == 0 && (ent->e.renderfx & RF_SHADOW_PLANE ) && shader->sort == SS_OPAQUE ) { diff --git a/android/app/src/main/cpp/code/renderergles3/tr_shadows.c b/android/app/src/main/cpp/code/renderergles3/tr_shadows.c index 697800c1..79915f1e 100644 --- a/android/app/src/main/cpp/code/renderergles3/tr_shadows.c +++ b/android/app/src/main/cpp/code/renderergles3/tr_shadows.c @@ -252,7 +252,7 @@ overlap and double darken. void RB_ShadowFinish( void ) { // FIXME: implement this #if 0 - if ( r_shadows->integer != 2 ) { + if ( r_shadows->integer != 2 || r_playerShadow->integer != 2) { return; } if ( glConfig.stencilBits < 4 ) { diff --git a/android/app/src/main/cpp/code/ui/ui_main.c b/android/app/src/main/cpp/code/ui/ui_main.c index 112183c1..4d3b5ca5 100644 --- a/android/app/src/main/cpp/code/ui/ui_main.c +++ b/android/app/src/main/cpp/code/ui/ui_main.c @@ -3102,6 +3102,7 @@ static void UI_Update(const char *name) { trap_Cvar_SetValue( "r_fastSky", 0 ); trap_Cvar_SetValue( "r_inGameVideo", 1 ); trap_Cvar_SetValue( "cg_shadows", 1 ); + trap_Cvar_SetValue( "cg_playerShadow", 1 ); trap_Cvar_SetValue( "cg_brassTime", 2500 ); trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" ); break; @@ -3122,6 +3123,7 @@ static void UI_Update(const char *name) { trap_Cvar_SetValue( "cg_brassTime", 2500 ); trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" ); trap_Cvar_SetValue( "cg_shadows", 0 ); + trap_Cvar_SetValue( "cg_playerShadow", 0 ); break; case 2: // fast trap_Cvar_SetValue( "r_fullScreen", 1 ); @@ -3136,6 +3138,7 @@ static void UI_Update(const char *name) { trap_Cvar_Set( "ui_videomode", "640x480" ); trap_Cvar_SetValue( "r_texturebits", 0 ); trap_Cvar_SetValue( "cg_shadows", 0 ); + trap_Cvar_SetValue( "cg_playerShadow", 0 ); trap_Cvar_SetValue( "r_fastSky", 1 ); trap_Cvar_SetValue( "r_inGameVideo", 0 ); trap_Cvar_SetValue( "cg_brassTime", 0 ); @@ -3154,6 +3157,7 @@ static void UI_Update(const char *name) { trap_Cvar_SetValue( "r_picmip", 2 ); trap_Cvar_SetValue( "r_texturebits", 16 ); trap_Cvar_SetValue( "cg_shadows", 0 ); + trap_Cvar_SetValue( "cg_playerShadow", 0 ); trap_Cvar_SetValue( "cg_brassTime", 0 ); trap_Cvar_SetValue( "r_fastSky", 1 ); trap_Cvar_SetValue( "r_inGameVideo", 0 ); diff --git a/android/app/src/main/cpp/code/vr/vr_clientinfo.h b/android/app/src/main/cpp/code/vr/vr_clientinfo.h index 7d3759f7..51a2aa4e 100644 --- a/android/app/src/main/cpp/code/vr/vr_clientinfo.h +++ b/android/app/src/main/cpp/code/vr/vr_clientinfo.h @@ -18,7 +18,9 @@ typedef struct { float weapon_zoomLevel; qboolean right_handed; qboolean virtual_screen; - qboolean local_server; // used in bg_pmove.c + qboolean local_server; + qboolean single_player; + qboolean use_fake_6dof; vrFollowMode_t follow_mode; qboolean weapon_select; qboolean weapon_select_autoclose; diff --git a/android/app/src/main/cpp/code/vr/vr_input.c b/android/app/src/main/cpp/code/vr/vr_input.c index adfeb3cc..5c342827 100644 --- a/android/app/src/main/cpp/code/vr/vr_input.c +++ b/android/app/src/main/cpp/code/vr/vr_input.c @@ -531,9 +531,9 @@ static void IN_VRJoystick( qboolean isRightController, float joystickX, float jo VectorClear(positional); vec2_t joystick; - if ( !com_sv_running || !com_sv_running->integer ) + if ( vr.use_fake_6dof ) { - //multiplayer server + //multiplayer game if (!vr_directionMode->integer) { //HMD Based rotateAboutOrigin(joystickX, joystickY, vr.hmdorientation[YAW], joystick); diff --git a/android/app/src/main/pakQ3Q/ui/ingame_system.menu b/android/app/src/main/pakQ3Q/ui/ingame_system.menu index 6c7b4205..629af318 100644 --- a/android/app/src/main/pakQ3Q/ui/ingame_system.menu +++ b/android/app/src/main/pakQ3Q/ui/ingame_system.menu @@ -295,9 +295,9 @@ itemDef { name graphics group grpSystem type ITEM_TYPE_MULTI - text "Shadow Detail:" + text "Opponent Shadows:" cvar "cg_shadows" - cvarFloatList { "Low" 1 "High" 3 } + cvarFloatList { "None" 0 "Low" 1 "High" 3 } rect 0 150 306 20 textalign ITEM_ALIGN_RIGHT textalignx 133 @@ -307,6 +307,22 @@ itemDef { visible 0 } + itemDef { + name graphics + group grpSystem + type ITEM_TYPE_MULTI + text "Player Shadow:" + cvar "cg_playerShadow" + cvarFloatList { "None" 0 "Low" 1 "High" 3 } + rect 0 170 306 20 + textalign ITEM_ALIGN_RIGHT + textalignx 133 + textaligny 17 + textscale .25 + forecolor 1 1 1 1 + visible 0 + } + itemDef { name graphics group grpSystem @@ -314,7 +330,7 @@ itemDef { text "Geometric Detail:" cvar "r_lodbias" cvarFloatList { "High" -1 "Medium" 1 "Low" 2 } - rect 0 170 256 20 + rect 0 190 256 20 textalign ITEM_ALIGN_RIGHT textalignx 133 textaligny 17 @@ -331,7 +347,7 @@ itemDef { text "Texture Detail:" cvar "r_picmip" cvarFloatList { "Low" 2 "Normal" 1 "High" 0 } - rect 0 190 256 20 + rect 0 210 256 20 textalign ITEM_ALIGN_RIGHT textalignx 133 textaligny 17 @@ -380,7 +396,7 @@ itemDef { type ITEM_TYPE_YESNO text "Compress Textures:" cvar "r_ext_compressed_textures" - rect 0 210 256 20 + rect 0 230 256 20 textalign ITEM_ALIGN_RIGHT textalignx 133 textaligny 17 diff --git a/android/app/src/main/pakQ3Q/ui/system.menu b/android/app/src/main/pakQ3Q/ui/system.menu index 23855dd4..a4ab0121 100755 --- a/android/app/src/main/pakQ3Q/ui/system.menu +++ b/android/app/src/main/pakQ3Q/ui/system.menu @@ -198,9 +198,9 @@ itemDef { name graphics group grpSystem type ITEM_TYPE_MULTI - text "Shadow Detail:" + text "Opponent Shadows:" cvar "cg_shadows" - cvarFloatList { "Low" 1 "High" 3 } + cvarFloatList { "None" 0 "Low" 1 "High" 3 } rect 99 167 256 20 textalign ITEM_ALIGN_RIGHT textalignx 128 @@ -210,6 +210,22 @@ itemDef { visible 0 } + itemDef { + name graphics + group grpSystem + type ITEM_TYPE_MULTI + text "Player Shadow:" + cvar "cg_playerShadow" + cvarFloatList { "None" 0 "Low" 1 "High" 3 } + rect 99 192 256 20 + textalign ITEM_ALIGN_RIGHT + textalignx 128 + textaligny 20 + textscale .333 + forecolor 1 1 1 1 + visible 0 + } + itemDef { name graphics group grpSystem @@ -217,7 +233,7 @@ itemDef { text "Geometric Detail:" cvar "r_lodbias" cvarFloatList { "High" -1 "Medium" 1 "Low" 2 } - rect 99 192 256 20 + rect 99 217 256 20 textalign ITEM_ALIGN_RIGHT textalignx 128 textaligny 20 @@ -234,7 +250,7 @@ itemDef { text "Texture Detail:" cvar "r_picmip" cvarFloatList { "Low" 2 "Normal" 1 "High" 0 } - rect 99 217 256 20 + rect 99 242 256 20 textalign ITEM_ALIGN_RIGHT textalignx 128 textaligny 20 @@ -283,7 +299,7 @@ itemDef { type ITEM_TYPE_YESNO text "Compress Textures:" cvar "r_ext_compressed_textures" - rect 99 242 256 20 + rect 99 267 256 20 textalign ITEM_ALIGN_RIGHT textalignx 128 textaligny 20