From e83cfe3bb059c717a8ebbfbf4de3aeb2bc4b87c9 Mon Sep 17 00:00:00 2001 From: Spoike Date: Thu, 19 Aug 2021 06:01:52 +0000 Subject: [PATCH] Misc q2 fixes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6022 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_ents.c | 4 ++++ engine/client/cl_main.c | 13 +++++++++++++ engine/client/client.h | 2 ++ engine/client/clq2_ents.c | 3 ++- engine/client/m_multi.c | 6 ++++-- engine/client/view.c | 4 ++++ engine/common/protocol.h | 1 + engine/gl/gl_backend.c | 40 ++++++++++++++++++++++++--------------- 8 files changed, 55 insertions(+), 18 deletions(-) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 0ca36d88d..4abf66332 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -5504,6 +5504,10 @@ void CL_LinkViewModel(void) ent.framestate.g[FS_REG].lerpweight[1] = cl.lerpfrac; ent.flags |= RF_WEAPONMODEL|RF_DEPTHHACK|RF_NOSHADOW; + if (pv->handedness == 1) + ent.flags |= RF_XFLIP; + else if (pv->handedness == 2) + return; V_AddEntity (&ent); return; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index beb76494e..e8a9fcfa8 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -159,6 +159,9 @@ cvar_t w_switch = CVARF("w_switch", "", CVAR_ARCHIVE | CVAR_USERINFO); #ifdef HEXEN2 cvar_t cl_playerclass=CVARF("cl_playerclass","", CVAR_ARCHIVE | CVAR_USERINFO); #endif +#ifdef Q2CLIENT +static cvar_t hand = CVARFD("hand", "", CVAR_ARCHIVE | CVAR_USERINFO, "For gamecode to know which hand to fire from.\n0: Right\n1: Left\n2: Chest"); +#endif cvar_t cl_nofake = CVARD("cl_nofake", "2", "value 0: permits \\r chars in chat messages\nvalue 1: blocks all \\r chars\nvalue 2: allows \\r chars, but only from teammates"); cvar_t cl_chatsound = CVAR("cl_chatsound","1"); cvar_t cl_enemychatsound = CVAR("cl_enemychatsound", "misc/talk.wav"); @@ -600,6 +603,13 @@ void CL_SendConnectPacket (netadr_t *to, int mtu, #ifdef Q2CLIENT if (connectinfo.protocol == CP_QUAKE2) { + if (!(scr_fov.flags & CVAR_USERINFO)) + { //q2 does server-controlled fov, so make sure the cvar is flagged properly. + //FIXME: this hack needs better support, for dynamically switching between protocols without spamming too many cvars for other games. + scr_fov.flags |= CVAR_USERINFO; + Cvar_Set(&scr_fov, scr_fov.string); //make sure the userinfo is set properly. + } + fteprotextsupported1 = ftepext1 & (PEXT_MODELDBL|PEXT_SOUNDDBL|PEXT_SPLITSCREEN); fteprotextsupported2 = 0; ezprotextsupported1 = 0; @@ -4977,6 +4987,9 @@ void CL_Init (void) Cvar_Register (&rate, cl_controlgroup); Cvar_Register (&drate, cl_controlgroup); Cvar_Register (&msg, cl_controlgroup); +#ifdef Q2CLIENT + Cvar_Register (&hand, cl_controlgroup); +#endif Cvar_Register (&noaim, cl_controlgroup); Cvar_Register (&b_switch, cl_controlgroup); Cvar_Register (&w_switch, cl_controlgroup); diff --git a/engine/client/client.h b/engine/client/client.h index 55939742f..931037e1b 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -711,6 +711,8 @@ struct playerview_s } prop; #ifdef Q2CLIENT + float forcefov; + int handedness; //0=right,1=left,2=center/hidden vec3_t predicted_origin; vec3_t predicted_angles; vec3_t prediction_error; diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index dc737e435..f250c1030 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -2496,7 +2496,8 @@ void CLQ2_CalcViewValues (int seat) // AngleVectors (r_refdef.viewangles, v_forward, v_right, v_up); // interpolate field of view - r_refdef.fov_x = ops->fov + lerp * (ps->fov - ops->fov); + pv->forcefov = ops->fov + lerp * (ps->fov - ops->fov); + pv->handedness = atoi(InfoBuf_ValueForKey(&cls.userinfo[seat], "hand")); //do interpolate blend alpha, but only if the rgb didn't change // don't interpolate blend color diff --git a/engine/client/m_multi.c b/engine/client/m_multi.c index b90560521..35bd21f5d 100644 --- a/engine/client/m_multi.c +++ b/engine/client/m_multi.c @@ -137,8 +137,10 @@ void MSetup_Removed(emenu_t *menu) char bot[64], top[64]; setupmenu_t *info = menu->data; - Cvar_Set(&name, info->nameedit->text); - Cvar_Set(&team, info->teamedit->text); + if (info->nameedit) + Cvar_Set(&name, info->nameedit->text); + if (info->teamedit) + Cvar_Set(&team, info->teamedit->text); if (info->skinedit) Cvar_Set(&skin, info->skinedit->text); #ifdef HEXEN2 diff --git a/engine/client/view.c b/engine/client/view.c index f7d0e42d0..4183b52ff 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1327,6 +1327,10 @@ void V_ApplyAFov(playerview_t *pv) if (!r_refdef.fov_x || !r_refdef.fov_y) { float afov = r_refdef.afov; +#ifdef Q2CLIENT + if (pv->forcefov>0) + afov = pv->forcefov; +#endif if (!afov) //make sure its sensible. { afov = scr_fov.value; diff --git a/engine/common/protocol.h b/engine/common/protocol.h index 6facd4fb1..0c38c76d4 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -1389,6 +1389,7 @@ typedef struct q1usercmd_s #define RF_FORCECOLOURMOD (1u<<22) //forces BEF_FORCECOLOURMOD #define RF_WEAPONMODELNOBOB (1u<<23) #define RF_FIRSTPERSON (1u<<24) //only draw through eyes +#define RF_XFLIP (1u<<25) //flip horizontally (for q2's left-handed weapons) // player_state_t->refdef flags #define RDF_UNDERWATER (1u<<0) // warp the screen as apropriate (fov trick) diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 113f8d5fd..448c4b718 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -178,7 +178,7 @@ struct { texid_t fogtexture; texid_t normalisationcubemap; float fogfar; - float depthrange; + int usingweaponviewmatrix; batch_t **mbatches; //model batches (ie: not world) }; @@ -417,7 +417,7 @@ void GL_ForceDepthWritable(void) void GL_SetShaderState2D(qboolean is2d) { - shaderstate.depthrange = 0; //force projection matrix info to get reset + shaderstate.usingweaponviewmatrix = -1; //force projection matrix info to get reset shaderstate.updatetime = realtime; shaderstate.force2d = is2d; if (is2d) @@ -1102,7 +1102,7 @@ qboolean GLBE_BeginShadowMap(int id, int w, int h, uploadfmt_t encoding, int *re /*set framebuffer*/ *restorefbo = GLBE_BeginRenderBuffer_DepthOnly(shaderstate.curshadowmap); - shaderstate.depthrange = 0; //make sure the projection matrix is updated. + shaderstate.usingweaponviewmatrix = -1; //make sure the projection matrix is updated. while(shaderstate.lastpasstmus>0) { @@ -1128,7 +1128,7 @@ qboolean GLBE_BeginShadowMap(int id, int w, int h, uploadfmt_t encoding, int *re void GLBE_EndShadowMap(int restorefbo) { GLBE_FBO_Pop(restorefbo); - shaderstate.depthrange = 0; //make sure the projection matrix is updated. + shaderstate.usingweaponviewmatrix = -1; //make sure the projection matrix is updated. } #endif @@ -4141,7 +4141,7 @@ void GLBE_SelectMode(backendmode_t mode) void GLBE_SelectEntity(entity_t *ent) { - float nd; + unsigned int fl; shaderstate.curentity = ent; currententity = ent; R_RotateForEntity(shaderstate.modelmatrix, shaderstate.modelviewmatrix, shaderstate.curentity, shaderstate.curentity->model); @@ -4149,18 +4149,28 @@ void GLBE_SelectEntity(entity_t *ent) if (qglLoadMatrixf) qglLoadMatrixf(shaderstate.modelviewmatrix); - if (shaderstate.curentity->flags & RF_DEPTHHACK) - nd = 0.3; - else - nd = 1; - if (shaderstate.depthrange != nd) - { - shaderstate.depthrange = nd; - if (nd < 1) + fl = shaderstate.curentity->flags&(RF_DEPTHHACK|RF_XFLIP); + if (shaderstate.usingweaponviewmatrix != fl) + { + if ((shaderstate.usingweaponviewmatrix & RF_XFLIP) && shaderstate.usingweaponviewmatrix != -1) + r_refdef.flipcull ^= SHADER_CULL_FLIP; + shaderstate.usingweaponviewmatrix = fl; + + if (fl) memcpy(shaderstate.projectionmatrix, r_refdef.m_projection_view, sizeof(shaderstate.projectionmatrix)); else memcpy(shaderstate.projectionmatrix, r_refdef.m_projection_std, sizeof(shaderstate.projectionmatrix)); + + if (fl&RF_XFLIP) + { + shaderstate.projectionmatrix[0] *= -1; + shaderstate.projectionmatrix[4] *= -1; + shaderstate.projectionmatrix[8] *= -1; + shaderstate.projectionmatrix[12] *= -1; + r_refdef.flipcull ^= SHADER_CULL_FLIP; + } + if (qglLoadMatrixf) { qglMatrixMode(GL_PROJECTION); @@ -6278,7 +6288,7 @@ void GLBE_DrawWorld (batch_t **worldbatches) RSpeedLocals(); shaderstate.mbatches = batches; - shaderstate.depthrange = 0; + shaderstate.usingweaponviewmatrix = -1; TRACE(("GLBE_DrawWorld: %p\n", worldbatches)); @@ -6470,7 +6480,7 @@ void GLBE_DrawWorld (batch_t **worldbatches) GLBE_SelectEntity(&r_worldentity); // shaderstate.curtime = shaderstate.updatetime = realtime; - shaderstate.depthrange = 0; + shaderstate.usingweaponviewmatrix = -1; shaderstate.identitylighting = 1;