Basic menu hack for vr.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6138 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2021-12-20 10:06:43 +00:00
parent 4f2994ab12
commit 4a6ba7146b
18 changed files with 174 additions and 70 deletions

View File

@ -2264,6 +2264,8 @@ void CL_SendCmd (double frametime, qboolean mainloop)
CL_FinishMove(cmd, plnum);
VectorCopy(pv->aimangles, pv->simangles);
Cam_FinishMove(pv, cmd);
#ifdef CSQC_DAT

View File

@ -71,6 +71,7 @@ cvar_t cl_nolerp = CVARD("cl_nolerp", "0", "Disables interpolation. If set, miss
cvar_t cl_nolerp_netquake = CVARD("cl_nolerp_netquake", "0", "Disables interpolation when connected to an NQ server. Does affect players, even the local player. You probably don't want to set this.");
cvar_t cl_fullpitch_nq = CVARAFD("cl_fullpitch", "0", "pq_fullpitch", CVAR_SEMICHEAT, "When set, attempts to unlimit the default view pitch. Note that some servers will screw over your angles if you use this, resulting in terrible gameplay, while some may merely clamp your angle serverside. This is also considered a cheat in quakeworld, ^1so this will not function there^7. For the equivelent in quakeworld, use serverinfo minpitch+maxpitch instead, which applies to all players fairly.");
#endif
static cvar_t cl_forcevrui = CVARD("cl_forcevrui", "0", "Force the use of VR UIs, even with no VR headset active.");
cvar_t *hud_tracking_show;
cvar_t *hud_miniscores_show;
extern cvar_t net_compress;
@ -4921,6 +4922,7 @@ void CL_Init (void)
Cvar_Register (&cl_idlefps, cl_screengroup);
Cvar_Register (&cl_yieldcpu, cl_screengroup);
Cvar_Register (&cl_timeout, cl_controlgroup);
Cvar_Register (&cl_forcevrui, cl_controlgroup);
Cvar_Register (&lookspring, cl_inputgroup);
Cvar_Register (&lookstrafe, cl_inputgroup);
Cvar_Register (&sensitivity, cl_inputgroup);
@ -6471,6 +6473,7 @@ double Host_Frame (double time)
{
RSpeedMark();
vid.ime_allow = false;
vrui.enabled = cl_forcevrui.ival;
if (SCR_UpdateScreen())
fps_count++;
if (R2D_Flush)

View File

@ -7004,6 +7004,9 @@ static void CL_ParseBaseAngle(int seat)
VectorCopy (newang, cl.playerview[seat].viewangles);
}
VectorCopy (newang, cl.playerview[seat].intermissionangles);
if (fl & 8)
VRUI_SnapAngle();
}
#define SHOWNET(x) if(cl_shownet.value>=2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
@ -8491,6 +8494,7 @@ void CLNQ_ParseServerMessage (void)
VectorCopy (ang, inf->packet_entities.fixedangles[destsplit]);
}
VectorCopy (cl.playerview[destsplit].viewangles, cl.playerview[destsplit].intermissionangles);
VRUI_SnapAngle();
}
break;

View File

@ -576,6 +576,7 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
p->time_off = scr_centertime.value;
p->time_start = cl.time;
VRUI_SnapAngle();
}
void VARGS Stats_Message(char *msg, ...)
@ -996,6 +997,9 @@ void SCR_DrawCursor(void)
}
}
if (vrui.enabled && kcurs->handle)
kcurs->dirty = true;
if (kcurs->dirty)
{
if (kcurs->scale <= 0 || !*kcurs->name)
@ -1007,7 +1011,7 @@ void SCR_DrawCursor(void)
kcurs->dirty = false;
oldcurs = kcurs->handle;
if (rf->VID_CreateCursor && strcmp(kcurs->name, "none"))
if (rf->VID_CreateCursor && !vrui.enabled && strcmp(kcurs->name, "none"))
{
image_t dummytex;
flocation_t loc;
@ -2374,7 +2378,10 @@ void SCR_DrawConsole (qboolean noback)
if (!Key_Dest_Has(kdm_console|kdm_menu))
Con_DrawNotify (); // only draw notify in game
}
Con_DrawConsole (scr_con_current, noback);
if (vrui.enabled) //make the console all-or-nothing when its a vr ui.
Con_DrawConsole (scr_con_target?vid.height:0, noback);
else
Con_DrawConsole (scr_con_current, noback);
if (scr_con_current || Key_Dest_Has(kdm_cwindows))
clearconsole = 0;
}
@ -3291,8 +3298,6 @@ void SCR_DrawTwoDimensional(qboolean nohud)
qboolean consolefocused = !!Key_Dest_Has(kdm_console|kdm_cwindows);
RSpeedMark();
r_refdef.playerview = &cl.playerview[0];
R2D_ImageColours(1, 1, 1, 1);
//

View File

@ -637,6 +637,7 @@ void Con_ToggleConsole_Force(void)
{
con_curwindow = con;
Key_Dest_Add(kdm_cwindows);
VRUI_SnapAngle();
}
}
else
@ -644,7 +645,10 @@ void Con_ToggleConsole_Force(void)
if (Key_Dest_Has(kdm_console))
Key_Dest_Remove(kdm_console);
else
{
Key_Dest_Add(kdm_console);
VRUI_SnapAngle();
}
}
}
void Con_ToggleConsole_f (void)
@ -983,6 +987,8 @@ void Con_PrintCon (console_t *con, const char *txt, unsigned int parseflags)
con->current->flags |= CONL_CENTERED;
if (parseflags & PFS_NONOTIFY)
con->current->flags |= CONL_NONOTIFY;
else if (!Key_Dest_Has(~kdm_game) && (con->flags & CONF_NOTIFY))
VRUI_SnapAngle();
#if defined(HAVE_SPEECHTOTEXT)
if (con->current)
@ -2906,12 +2912,15 @@ static void Con_DrawMouseOver(console_t *mouseconsole)
}
else
shader = NULL;
key = Info_ValueForKey(info, "modelviewer");
if (*key)
if (!vrui.enabled)
{
model = Mod_ForName(key, MLV_WARN);
if (model->loadstate != MLS_LOADED)
model = NULL;
key = Info_ValueForKey(info, "modelviewer");
if (*key)
{
model = Mod_ForName(key, MLV_WARN);
if (model->loadstate != MLS_LOADED)
model = NULL;
}
}
key = Info_ValueForKey(info, "playaudio");

View File

@ -492,7 +492,7 @@ void IN_Commands(void)
ptr[ev->devid].delta[1] += ev->mouse.y;
//if we're emulating a cursor, make sure that's updated too.
if (touchcursor < 0 && Key_MouseShouldBeFree())
if (touchcursor < 0 && !vrui.enabled && Key_MouseShouldBeFree())
{
mousecursor_x += ev->mouse.x;
mousecursor_y += ev->mouse.y;
@ -521,6 +521,7 @@ void IN_Commands(void)
case IEV_MOUSEABS:
//Con_Printf("IEV_MOUSEABS %i: %f %f\n", ev->devid, ev->mouse.x, ev->mouse.y);
/*mouse cursors only really work with one pointer*/
if (!vrui.enabled)
if (ev->devid == touchcursor || (touchcursor < 0 && ev->devid < MAXPOINTERS && (ptr[ev->devid].oldpos[0] != ev->mouse.x || ptr[ev->devid].oldpos[1] != ev->mouse.y)))
{
float fl;
@ -657,7 +658,7 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
mousemove_x += mx;
mousemove_y += my;
if (Key_MouseShouldBeFree())
if (!vrui.enabled && Key_MouseShouldBeFree())
mx=my=0;
if (mouse->type == M_TOUCH)

View File

@ -709,7 +709,7 @@ void INS_UpdateGrabs(int fullscreen, int activeapp)
grabmouse = false;
else if (fullscreen || in_simulatemultitouch.ival || in_windowed_mouse.value)
{
if (!Key_MouseShouldBeFree())
if (vrui.enabled || !Key_MouseShouldBeFree())
grabmouse = true;
else
grabmouse = false;

View File

@ -1868,6 +1868,15 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
return true;
}
if (key == K_GP_BACK)
{
Key_Dest_Remove(kdm_console);
Key_Dest_Remove(kdm_cwindows);
if (!cls.state && !Key_Dest_Has(~kdm_game))
M_ToggleMenu_f ();
return true;
}
if ((key == K_MOUSE1 || key == K_MOUSE2))
{
int olddown[2] = {con->mousedown[0],con->mousedown[1]};

View File

@ -408,6 +408,12 @@ static qboolean M_MouseMoved(emenu_t *menu)
if (menu->mouseitem != option)
{
menu->mouseitem = option;
if (vrui.enabled)
{
menu->selecteditem = option;
if (menu->cursoritem)
menu->cursoritem->common.posy = menu->selecteditem->common.posy;
}
menu->tooltiptime = realtime + 1;
MenuTooltipChange(menu, menu->mouseitem->common.tooltip);
}
@ -1774,7 +1780,7 @@ static void M_Draw (menu_t *menu)
menu_mousedown = false;
return;
}
if ((!menu_script || scr_con_current))
if (!vrui.enabled && (!menu_script || scr_con_current))
{
if (m->nobacktint || (m->selecteditem && m->selecteditem->common.type == mt_slider && (m->selecteditem->slider.var == &v_gamma || m->selecteditem->slider.var == &v_contrast)))
/*no menu tint if we're trying to adjust gamma*/;

View File

@ -4340,7 +4340,7 @@ static void Mods_Draw(int x, int y, struct menucustom_s *c, struct emenu_s *m)
static qboolean Mods_Key(struct menucustom_s *c, struct emenu_s *m, int key, unsigned int unicode)
{
int gameidx = c->dint;
if (key == K_MOUSE1 || key == K_ENTER || key == K_GP_A)
if (key == K_MOUSE1 || key == K_ENTER || key == K_GP_A || key == K_GP_START)
{
qboolean wasgameless = !*FS_GetGamedir(false);
if (!Mods_GetMod(c->dint))

View File

@ -120,11 +120,15 @@ void Menu_Push(menu_t *menu, qboolean prompt)
}
if (menu == promptmenu)
{
if (!Key_Dest_Has(kdm_prompt))
VRUI_SnapAngle();
Key_Dest_Add(kdm_prompt);
Menu_UpdateFocus();
}
if (menu == topmenu)
{
if (!Key_Dest_Has(kdm_menu))
VRUI_SnapAngle();
Key_Dest_Add(kdm_menu);
Menu_UpdateFocus();
}

View File

@ -35,6 +35,14 @@ extern cvar_t scr_viewsize;
qboolean SCR_RSShot (void);
typedef struct
{
qboolean enabled;
vec3_t angles;
} vrui_t;
extern vrui_t vrui;
void VRUI_SnapAngle(void);
//void SCR_DrawConsole (qboolean noback);
//void SCR_SetUpToDrawConsole (void);

View File

@ -2464,18 +2464,20 @@ void V_RenderView (qboolean no2d)
Surf_LessenStains();
if (cls.state != ca_active)
return;
// if (cls.state != ca_active)
// return;
if (cl.intermissionmode != IM_NONE)
maxseats = 1;
else if (cl_forceseat.ival && cl_splitscreen.ival >= 4)
maxseats = 1;
else
maxseats = max(1, cl.splitclients);
R_PushDlights ();
r_secondaryview = 0;
for (seatnum = 0; seatnum < cl.splitclients && seatnum < maxseats; seatnum++)
for (seatnum = 0; seatnum < maxseats; seatnum++)
{
pl = (maxseats==1&&cl_forceseat.ival>=1)?(cl_forceseat.ival-1)%cl.splitclients:seatnum;
V_ClearRefdef(&cl.playerview[pl]);
@ -2512,18 +2514,21 @@ void V_RenderView (qboolean no2d)
SCR_VRectForPlayer(&r_refdef.grect, seatnum, maxseats);
V_RenderPlayerViews(r_refdef.playerview);
#ifdef PLUGINS
Plug_SBar (r_refdef.playerview);
#else
if (Sbar_ShouldDraw(r_refdef.playerview))
if (!vrui.enabled)
{
SCR_TileClear (sb_lines);
Sbar_Draw (r_refdef.playerview);
Sbar_DrawScoreboard (r_refdef.playerview);
}
else
SCR_TileClear (0);
#ifdef PLUGINS
Plug_SBar (r_refdef.playerview);
#else
if (Sbar_ShouldDraw(r_refdef.playerview))
{
SCR_TileClear (sb_lines);
Sbar_Draw (r_refdef.playerview);
Sbar_DrawScoreboard (r_refdef.playerview);
}
else
SCR_TileClear (0);
#endif
}
}
if (seatnum > 1)
{

View File

@ -2954,6 +2954,8 @@ void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemo
case mod_brush:
if (r_drawentities.ival == 2 && cls.allow_cheats) //2 is considered a cheat, because it can be used as a wallhack (whereas mdls are not normally considered as occluding).
continue;
if (emodel->lightmaps.maxstyle >= cl_max_lightstyles)
continue;
Surf_GenBrushBatches(batches, ent);
break;
case mod_alias:

View File

@ -715,6 +715,75 @@ static void R_RenderScene_Internal(void)
cl_numvisedicts = tmpvisents;
depthcleared = false; //whatever is in the depth buffer is no longer useful.
if (vrui.enabled)
{
vec3_t uifwd, uiright, uiup;
vec3_t diff;
float d;
vec3_t ctrlang, ctrlorg, aimdir;
// extern usercmd_t cl_pendingcmd[MAX_SPLITS];
AngleVectors(vrui.angles, uifwd, uiright, uiup);
VectorAngles(uiright, uifwd, r_worldentity.angles, false);
AngleVectors(r_worldentity.angles, r_worldentity.axis[0], r_worldentity.axis[1], r_worldentity.axis[2]);
VectorNegate(r_worldentity.axis[1], r_worldentity.axis[1]);
r_worldentity.scale = 1;//0.2;
VectorMA(r_refdef.vieworg, Cvar_Get("2dz", "256", 0, "")->value*r_worldentity.scale, r_worldentity.axis[2], r_worldentity.origin);
VectorMA(r_worldentity.origin, -(int)(vid.width/2)*r_worldentity.scale, r_worldentity.axis[0], r_worldentity.origin);
VectorMA(r_worldentity.origin, -(int)(vid.height/2)*r_worldentity.scale, r_worldentity.axis[1], r_worldentity.origin);
GL_SetShaderState2D(true);
VectorCopy(r_refdef.viewangles, ctrlang);
if (r_refdef.playerview->vrdev[VRDEV_RIGHT].status&VRSTATUS_ANG)
{
ctrlang[0] = SHORT2ANGLE(r_refdef.playerview->vrdev[VRDEV_RIGHT].angles[0]);
ctrlang[1] = SHORT2ANGLE(r_refdef.playerview->vrdev[VRDEV_RIGHT].angles[1]);
ctrlang[2] = SHORT2ANGLE(r_refdef.playerview->vrdev[VRDEV_RIGHT].angles[2]);
}
else
VectorCopy(r_refdef.viewangles, ctrlang);
if (r_refdef.playerview->vrdev[VRDEV_RIGHT].status&VRSTATUS_ORG)
VectorCopy(r_refdef.playerview->vrdev[VRDEV_RIGHT].origin, ctrlorg);
else
VectorCopy(r_refdef.vieworg, ctrlorg);
AngleVectors(ctrlang, aimdir, NULL, NULL);
VectorSubtract(r_worldentity.origin, ctrlorg, diff);
//d = DotProduct(diff, vpn); //figure out how far we need to move it to get an impact.
d = DotProduct(diff, r_worldentity.axis[2]);
d /= DotProduct(aimdir, r_worldentity.axis[2]); //compensate for the length.
VectorMA(ctrlorg, d, aimdir, diff); //calc the impact point...
VectorSubtract(diff, r_worldentity.origin, diff);
mousecursor_x = DotProduct(diff, r_worldentity.axis[0]);
mousecursor_y = DotProduct(diff, r_worldentity.axis[1]);
mousecursor_x = bound(0, mousecursor_x, vid.width-1);
mousecursor_y = bound(0, mousecursor_y, vid.height-1);
#ifdef PLUGINS
Plug_SBar (r_refdef.playerview);
#else
if (Sbar_ShouldDraw(r_refdef.playerview))
{
SCR_TileClear (sb_lines);
Sbar_Draw (r_refdef.playerview);
Sbar_DrawScoreboard (r_refdef.playerview);
}
else
SCR_TileClear (0);
#endif
SCR_DrawTwoDimensional(true);
VectorClear(r_worldentity.origin);
VectorClear(r_worldentity.angles);
VectorSet(r_worldentity.axis[0], 1,0,0);
VectorSet(r_worldentity.axis[1], 0,1,0);
VectorSet(r_worldentity.axis[2], 0,0,1);
r_worldentity.scale = 1;
GL_SetShaderState2D(false);
}
}
static void R_RenderEyeScene (texid_t rendertarget, vec4_t fovoverride, vec3_t eyeangorg[2])
{
@ -729,6 +798,7 @@ static void R_RenderEyeScene (texid_t rendertarget, vec4_t fovoverride, vec3_t e
if ((size_t)(refdef.playerview-cl.playerview) < MAX_SPLITS)
CL_ClampPitch (refdef.playerview-cl.playerview, 0);
vrui.enabled = true;
if (rendertarget)
{
r = GLBE_FBO_Update(&fbo_vr, FBO_RB_DEPTH, &rendertarget, 1, r_nulltex, rendertarget->width, rendertarget->height, 0);
@ -742,44 +812,6 @@ static void R_RenderEyeScene (texid_t rendertarget, vec4_t fovoverride, vec3_t e
R_SetupGL (eyeangorg, fovoverride, NULL, rendertarget);
R_RenderScene_Internal();
/*//if (eyematrix)
{
vec3_t newa, newo;
matrix3x4 headmatrix; //position of the head in local space
//eyematrix //position of the eye in head space...
matrix3x4 headeyematrix;
matrix3x4 correctionmatrix; //to nudge the 2d stuff into view
matrix3x4 viewmatrix; //final transform
extern usercmd_t cl_pendingcmd[MAX_SPLITS];
newa[0] = SHORT2ANGLE(cl_pendingcmd[0].vr[VRDEV_HEAD].angles[0]);
newa[1] = SHORT2ANGLE(cl_pendingcmd[0].vr[VRDEV_HEAD].angles[1]);
newa[2] = SHORT2ANGLE(cl_pendingcmd[0].vr[VRDEV_HEAD].angles[2]);
Matrix3x4_RM_FromAngles(newa, cl_pendingcmd[0].vr[VRDEV_HEAD].origin, headmatrix[0]);
newa[0] = Cvar_Get("2dpitch", "-90", 0, "")->value;
newa[1] = Cvar_Get("2dyaw", "0", 0, "")->value;
newa[2] = Cvar_Get("2droll", "90", 0, "")->value;
//why /4, not /2? wtf?
newo[0] = vid.width/4 + Cvar_Get("2dfwd", "0", 0, "")->value;
newo[1] = vid.height/4 + Cvar_Get("2dleft", "0", 0, "")->value;
newo[2] = Cvar_Get("2dup", "-256", 0, "")->value;
Matrix3x4_RM_FromAngles(newa, newo, correctionmatrix[0]);
Matrix3x4_Multiply(headmatrix[0], eyematrix[0], headeyematrix[0]);
Matrix3x4_Multiply(headeyematrix[0], correctionmatrix[0], viewmatrix[0]);
Matrix3x4_RM_ToVectors(viewmatrix[0], vpn, vright, vup, r_origin);
VectorNegate(vright, vright);
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_origin);
GL_SetShaderState2D(true);
Menu_Draw();
SCR_DrawConsole(false);
if (R2D_Flush)
R2D_Flush();
GL_SetShaderState2D(false);
}*/
if (rendertarget)
{
GLBE_FBO_Pop(r);
@ -1982,7 +2014,9 @@ void GLR_RenderView (void)
if (!(r_refdef.flags & RDF_NOWORLDMODEL))
{
//FIXME: fbo stuff
if (!r_worldentity.model || r_worldentity.model->loadstate != MLS_LOADED || !cl.worldmodel)
if (!r_worldentity.model || !cl.worldmodel)
r_refdef.flags |= RDF_NOWORLDMODEL;
else if (r_worldentity.model->loadstate != MLS_LOADED || !cl.worldmodel)
{
GL_Set2D (false);
R2D_ImageColours(0, 0, 0, 1);

View File

@ -45,6 +45,16 @@ extern cvar_t vid_conautoscale;
extern qboolean scr_con_forcedraw;
extern qboolean depthcleared;
vrui_t vrui;
void VRUI_SnapAngle(void)
{
// VectorCopy(cl.playerview[0].viewangles, vrui.angles);
vrui.angles[0] = 0;
vrui.angles[1] = cl.playerview[0].aimangles[1];
vrui.angles[2] = 0;
}
/*
==================
SCR_UpdateScreen
@ -184,7 +194,7 @@ qboolean GLSCR_UpdateScreen (void)
#endif
else
{
if (r_worldentity.model && cls.state == ca_active)
if ((r_worldentity.model && cls.state == ca_active) || vid.vr || vrui.enabled)
V_RenderView (nohud);
else
noworld = true;
@ -218,7 +228,9 @@ qboolean GLSCR_UpdateScreen (void)
nohud = true;
}
SCR_DrawTwoDimensional(nohud);
r_refdef.playerview = &cl.playerview[0];
if (!vrui.enabled)
SCR_DrawTwoDimensional(nohud);
V_UpdatePalette (false);
R2D_BrightenScreen();

View File

@ -2764,7 +2764,7 @@ static void UpdateGrabs(void)
if (!vid.activeapp)
wantmgrabs = false;
allownullcursor = wantmgrabs; //this says whether we can possibly want it. if false then we disallow the null cursor. Yes, this might break mods that do their own sw cursors. such mods are flawed in other ways too.
if (Key_MouseShouldBeFree())
if (!vrui.enabled && Key_MouseShouldBeFree())
wantmgrabs = false;
// if (modeswitchpending)
// wantmgrabs = false;

View File

@ -1464,7 +1464,7 @@ static void WL_SwapBuffers(void)
}
//if the game wants absolute mouse positions...
wantabs = !vid.activeapp || Key_MouseShouldBeFree() || !in_windowed_mouse.value;
wantabs = !vid.activeapp || (!vrui.enabled && Key_MouseShouldBeFree()) || !in_windowed_mouse.value;
//and force it on if we're lacking one of the plethora of extensions that were needed to get the damn thing actually usable.
wantabs |= !w.relative_pointer || !w.pointer_constraints;
if (!wantabs && w.cursorfocus && !w.locked_pointer && w.pointer_constraints)