#include "cl_collision.h"
#include "snd_main.h"
#include "clvm_cmds.h"
+#include "prvm_cmds.h"
//============================================================================
// Client prog handling
static prvm_prog_t *csqc_tmpprog;
+void CL_VM_PreventInformationLeaks(void)
+{
+ prvm_eval_t *val;
+ if(!cl.csqc_loaded)
+ return;
+ CSQC_BEGIN
+ VM_ClearTraceGlobals();
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_networkentity)))
+ val->_float = 0;
+ CSQC_END
+}
+
//[515]: these are required funcs
static char *cl_required_func[] =
{
// CSQC is useless as it can't alter the view origin without
// completely replacing it
VectorCopy(cl.csqc_origin, prog->globals.client->pmove_org);
- VectorCopy(cl.velocity, prog->globals.client->pmove_vel);
+ VectorCopy(cl.movement_velocity, prog->globals.client->pmove_vel);
if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.view_angles)))
VectorCopy(cl.viewangles, val->vector);
}
extern cvar_t cl_noplayershadow;
+extern cvar_t r_equalize_entities_fullbright;
qboolean CSQC_AddRenderEdict(prvm_edict_t *ed)
{
int renderflags;
if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.alpha)) && val->_float) entrender->alpha = val->_float;
if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.scale)) && val->_float) entrender->scale = scale = val->_float;
if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.colormod)) && VectorLength2(val->vector)) VectorCopy(val->vector, entrender->colormod);
+ if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.glowmod)) && VectorLength2(val->vector)) VectorCopy(val->vector, entrender->glowmod);
if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.effects)) && val->_float) entrender->effects |= (int)val->_float;
if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.tag_entity)) && val->edict)
{
}
else
Matrix4x4_CreateIdentity(&tagmatrix);
+ if (!VectorLength2(entrender->colormod))
+ VectorSet(entrender->colormod, 1, 1, 1);
+ if (!VectorLength2(entrender->glowmod))
+ VectorSet(entrender->glowmod, 1, 1, 1);
if (renderflags & RF_USEAXIS)
{
}
// set up the animation data
- // self.frame is the interpolation target (new frame)
- // self.frame1time is the animation base time for the interpolation target
- // self.frame2 is the interpolation start (previous frame)
- // self.frame2time is the animation base time for the interpolation start
- // self.lerpfrac is the interpolation strength for self.frame
- // 3+ are for additional blends (the main use for this feature is lerping
- // pitch angle on a player model where the animator set up 5 sets of
- // animations and the csqc simply lerps between sets)
- entrender->framegroupblend[0].frame = entrender->framegroupblend[1].frame = (int) ed->fields.client->frame;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2))) entrender->framegroupblend[1].frame = (int) val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame3))) entrender->framegroupblend[2].frame = (int) val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame4))) entrender->framegroupblend[3].frame = (int) val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame1time))) entrender->framegroupblend[0].start = val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2time))) entrender->framegroupblend[1].start = val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame3time))) entrender->framegroupblend[2].start = val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame4time))) entrender->framegroupblend[3].start = val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac))) entrender->framegroupblend[0].lerp = val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac3))) entrender->framegroupblend[2].lerp = val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac4))) entrender->framegroupblend[3].lerp = val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.shadertime))) entrender->shadertime = val->_float;
- // assume that the (missing) lerpfrac2 is whatever remains after lerpfrac+lerpfrac3+lerpfrac4 are summed
- entrender->framegroupblend[1].lerp = 1 - entrender->framegroupblend[0].lerp - entrender->framegroupblend[2].lerp - entrender->framegroupblend[3].lerp;
+ CL_LoadFrameGroupBlend(ed, entrender);
// concat the matrices to make the entity relative to its tag
Matrix4x4_Concat(&entrender->matrix, &tagmatrix, &matrix2);
+ // transparent offset
+ if ((renderflags & RF_USETRANSPARENTOFFSET) && (val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.transparent_offset)))
+ entrender->transparent_offset = val->_float;
+
if(renderflags)
{
- if(renderflags & RF_VIEWMODEL) entrender->flags |= RENDER_VIEWMODEL;
+ if(renderflags & RF_VIEWMODEL) entrender->flags |= RENDER_VIEWMODEL | RENDER_NODEPTHTEST;
if(renderflags & RF_EXTERNALMODEL)entrender->flags |= RENDER_EXTERIORMODEL;
- if(renderflags & RF_DEPTHHACK) entrender->effects |= EF_NODEPTHTEST;
- if(renderflags & RF_ADDITIVE) entrender->effects |= EF_ADDITIVE;
+ if(renderflags & RF_NOCULL) entrender->flags |= RENDER_NOCULL;
+ if(renderflags & RF_DEPTHHACK) entrender->flags |= RENDER_NODEPTHTEST;
+ if(renderflags & RF_ADDITIVE) entrender->flags |= RENDER_ADDITIVE;
+
}
c = (int)ed->fields.client->colormap;
entrender->flags &= ~(RENDER_SHADOW | RENDER_LIGHT | RENDER_NOSELFSHADOW);
// either fullbright or lit
- if (!(entrender->effects & EF_FULLBRIGHT) && !r_fullbright.integer)
- entrender->flags |= RENDER_LIGHT;
+ if(!r_fullbright.integer)
+ {
+ if (!(entrender->effects & EF_FULLBRIGHT))
+ entrender->flags |= RENDER_LIGHT;
+ else if(r_equalize_entities_fullbright.integer)
+ entrender->flags |= RENDER_LIGHT | RENDER_EQUALIZE;
+ }
// hide player shadow during intermission or nehahra movie
if (!(entrender->effects & (EF_NOSHADOW | EF_ADDITIVE | EF_NODEPTHTEST))
&& (entrender->alpha >= 1)
entrender->flags |= RENDER_NOSELFSHADOW;
if (entrender->effects & EF_NOSELFSHADOW)
entrender->flags |= RENDER_NOSELFSHADOW;
+ if (entrender->effects & EF_NODEPTHTEST)
+ entrender->flags |= RENDER_NODEPTHTEST;
+ if (entrender->effects & EF_ADDITIVE)
+ entrender->flags |= RENDER_ADDITIVE;
+ if (entrender->effects & EF_DOUBLESIDED)
+ entrender->flags |= RENDER_DOUBLESIDED;
// make the other useful stuff
CL_UpdateRenderEntity(entrender);
PRVM_G_FLOAT(OFS_PARM1) = key;
PRVM_G_FLOAT(OFS_PARM2) = ascii;
PRVM_ExecuteProgram(prog->funcoffsets.CSQC_InputEvent, "QC function CSQC_InputEvent is missing");
- r = CSQC_RETURNVAL;
+ r = CSQC_RETURNVAL != 0;
}
CSQC_END
return r;
PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(cmd);
PRVM_ExecuteProgram(prog->funcoffsets.CSQC_ConsoleCommand, "QC function CSQC_ConsoleCommand is missing");
vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
- r = CSQC_RETURNVAL;
+ r = CSQC_RETURNVAL != 0;
}
CSQC_END
return r;
prog->globals.client->time = cl.time;
prog->globals.client->self = cl.csqc_server2csqcentitynumber[cl.playerentity];
PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Parse_TempEntity, "QC function CSQC_Parse_TempEntity is missing");
- r = CSQC_RETURNVAL;
+ r = CSQC_RETURNVAL != 0;
if(!r)
{
msg_readcount = t;
PRVM_G_FLOAT(OFS_PARM4) = attenuation;
VectorCopy(pos, PRVM_G_VECTOR(OFS_PARM5) );
PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Event_Sound, "QC function CSQC_Event_Sound is missing");
- r = CSQC_RETURNVAL;
+ r = CSQC_RETURNVAL != 0;
}
CSQC_END
}
{
World_UnlinkEdict(ed);
memset(ed->fields.client, 0, sizeof(*ed->fields.client));
+ World_Physics_RemoveFromEntity(&cl.world, ed);
+ World_Physics_RemoveJointFromEntity(&cl.world, ed);
}
void CL_VM_CB_CountEdicts(void)
prog->init_cmd = VM_CL_Cmd_Init;
prog->reset_cmd = VM_CL_Cmd_Reset;
prog->error_cmd = CL_VM_Error;
+ prog->ExecuteProgram = CLVM_ExecuteProgram;
PRVM_LoadProgs(csprogsfn, cl_numrequiredfunc, cl_required_func, 0, NULL, 0, NULL);
return r;
}
+
+void CL_LoadFrameGroupBlend(prvm_edict_t *ed, entity_render_t *entrender)
+{
+ prvm_eval_t *val;
+ // self.frame is the interpolation target (new frame)
+ // self.frame1time is the animation base time for the interpolation target
+ // self.frame2 is the interpolation start (previous frame)
+ // self.frame2time is the animation base time for the interpolation start
+ // self.lerpfrac is the interpolation strength for self.frame
+ // 3+ are for additional blends (the main use for this feature is lerping
+ // pitch angle on a player model where the animator set up 5 sets of
+ // animations and the csqc simply lerps between sets)
+ entrender->framegroupblend[0].frame = entrender->framegroupblend[1].frame = (int) ed->fields.client->frame;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2))) entrender->framegroupblend[1].frame = (int) val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame3))) entrender->framegroupblend[2].frame = (int) val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame4))) entrender->framegroupblend[3].frame = (int) val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame1time))) entrender->framegroupblend[0].start = val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2time))) entrender->framegroupblend[1].start = val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame3time))) entrender->framegroupblend[2].start = val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame4time))) entrender->framegroupblend[3].start = val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac))) entrender->framegroupblend[0].lerp = val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac3))) entrender->framegroupblend[2].lerp = val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac4))) entrender->framegroupblend[3].lerp = val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.shadertime))) entrender->shadertime = val->_float;
+ // assume that the (missing) lerpfrac2 is whatever remains after lerpfrac+lerpfrac3+lerpfrac4 are summed
+ entrender->framegroupblend[1].lerp = 1 - entrender->framegroupblend[0].lerp - entrender->framegroupblend[2].lerp - entrender->framegroupblend[3].lerp;
+}
+
+qboolean CL_BlendTagMatrix(entity_render_t *entrender, int tagindex, matrix4x4_t *blendmatrix)
+{
+ int j, l, k;
+ float d;
+ dp_model_t *model = entrender->model;
+ if(!model)
+ return false;
+ // blend the matrices
+ memset(&blendmatrix, 0, sizeof(blendmatrix));
+ for (j = 0;j < MAX_FRAMEBLENDS && entrender->frameblend[j].lerp > 0;j++)
+ {
+ matrix4x4_t tagmatrix;
+ if(!Mod_Alias_GetTagMatrix(model, entrender->frameblend[j].subframe, tagindex, &tagmatrix))
+ return false;
+ d = entrender->frameblend[j].lerp;
+ for (l = 0;l < 4;l++)
+ for (k = 0;k < 4;k++)
+ blendmatrix->m[l][k] += d * tagmatrix.m[l][k];
+ }
+ return true;
+}