X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=csprogs.c;h=58290c5b88f001ab9e7af72d061f7a503a34a633;hp=fc7f3d5a12555316381dfa76f5e7946e8cfb6406;hb=8c6898ab1f01b8efd78fea454b3f8654c4265ebb;hpb=48ce3f26e6f1ea3efe455160dc1bca48a51d2a84 diff --git a/csprogs.c b/csprogs.c index fc7f3d5a..58290c5b 100644 --- a/csprogs.c +++ b/csprogs.c @@ -19,18 +19,16 @@ 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; + PRVM_clientglobalfloat(trace_networkentity) = 0; CSQC_END } //[515]: these are required funcs -static char *cl_required_func[] = +static const char *cl_required_func[] = { "CSQC_Init", "CSQC_InputEvent", @@ -40,6 +38,164 @@ static char *cl_required_func[] = static int cl_numrequiredfunc = sizeof(cl_required_func) / sizeof(char*); +#define CL_REQFIELDS (sizeof(cl_reqfields) / sizeof(prvm_required_field_t)) + +prvm_required_field_t cl_reqfields[] = +{ +#define PRVM_DECLARE_serverglobalfloat(x) +#define PRVM_DECLARE_serverglobalvector(x) +#define PRVM_DECLARE_serverglobalstring(x) +#define PRVM_DECLARE_serverglobaledict(x) +#define PRVM_DECLARE_serverglobalfunction(x) +#define PRVM_DECLARE_clientglobalfloat(x) +#define PRVM_DECLARE_clientglobalvector(x) +#define PRVM_DECLARE_clientglobalstring(x) +#define PRVM_DECLARE_clientglobaledict(x) +#define PRVM_DECLARE_clientglobalfunction(x) +#define PRVM_DECLARE_menuglobalfloat(x) +#define PRVM_DECLARE_menuglobalvector(x) +#define PRVM_DECLARE_menuglobalstring(x) +#define PRVM_DECLARE_menuglobaledict(x) +#define PRVM_DECLARE_menuglobalfunction(x) +#define PRVM_DECLARE_serverfieldfloat(x) +#define PRVM_DECLARE_serverfieldvector(x) +#define PRVM_DECLARE_serverfieldstring(x) +#define PRVM_DECLARE_serverfieldedict(x) +#define PRVM_DECLARE_serverfieldfunction(x) +#define PRVM_DECLARE_clientfieldfloat(x) {ev_float, #x }, +#define PRVM_DECLARE_clientfieldvector(x) {ev_vector, #x }, +#define PRVM_DECLARE_clientfieldstring(x) {ev_string, #x }, +#define PRVM_DECLARE_clientfieldedict(x) {ev_entity, #x }, +#define PRVM_DECLARE_clientfieldfunction(x) {ev_function, #x }, +#define PRVM_DECLARE_menufieldfloat(x) +#define PRVM_DECLARE_menufieldvector(x) +#define PRVM_DECLARE_menufieldstring(x) +#define PRVM_DECLARE_menufieldedict(x) +#define PRVM_DECLARE_menufieldfunction(x) +#define PRVM_DECLARE_serverfunction(x) +#define PRVM_DECLARE_clientfunction(x) +#define PRVM_DECLARE_menufunction(x) +#define PRVM_DECLARE_field(x) +#define PRVM_DECLARE_global(x) +#define PRVM_DECLARE_function(x) +#include "prvm_offsets.h" +#undef PRVM_DECLARE_serverglobalfloat +#undef PRVM_DECLARE_serverglobalvector +#undef PRVM_DECLARE_serverglobalstring +#undef PRVM_DECLARE_serverglobaledict +#undef PRVM_DECLARE_serverglobalfunction +#undef PRVM_DECLARE_clientglobalfloat +#undef PRVM_DECLARE_clientglobalvector +#undef PRVM_DECLARE_clientglobalstring +#undef PRVM_DECLARE_clientglobaledict +#undef PRVM_DECLARE_clientglobalfunction +#undef PRVM_DECLARE_menuglobalfloat +#undef PRVM_DECLARE_menuglobalvector +#undef PRVM_DECLARE_menuglobalstring +#undef PRVM_DECLARE_menuglobaledict +#undef PRVM_DECLARE_menuglobalfunction +#undef PRVM_DECLARE_serverfieldfloat +#undef PRVM_DECLARE_serverfieldvector +#undef PRVM_DECLARE_serverfieldstring +#undef PRVM_DECLARE_serverfieldedict +#undef PRVM_DECLARE_serverfieldfunction +#undef PRVM_DECLARE_clientfieldfloat +#undef PRVM_DECLARE_clientfieldvector +#undef PRVM_DECLARE_clientfieldstring +#undef PRVM_DECLARE_clientfieldedict +#undef PRVM_DECLARE_clientfieldfunction +#undef PRVM_DECLARE_menufieldfloat +#undef PRVM_DECLARE_menufieldvector +#undef PRVM_DECLARE_menufieldstring +#undef PRVM_DECLARE_menufieldedict +#undef PRVM_DECLARE_menufieldfunction +#undef PRVM_DECLARE_serverfunction +#undef PRVM_DECLARE_clientfunction +#undef PRVM_DECLARE_menufunction +#undef PRVM_DECLARE_field +#undef PRVM_DECLARE_global +#undef PRVM_DECLARE_function +}; + +#define CL_REQGLOBALS (sizeof(cl_reqglobals) / sizeof(prvm_required_field_t)) + +prvm_required_field_t cl_reqglobals[] = +{ +#define PRVM_DECLARE_serverglobalfloat(x) +#define PRVM_DECLARE_serverglobalvector(x) +#define PRVM_DECLARE_serverglobalstring(x) +#define PRVM_DECLARE_serverglobaledict(x) +#define PRVM_DECLARE_serverglobalfunction(x) +#define PRVM_DECLARE_clientglobalfloat(x) {ev_float, #x}, +#define PRVM_DECLARE_clientglobalvector(x) {ev_vector, #x}, +#define PRVM_DECLARE_clientglobalstring(x) {ev_string, #x}, +#define PRVM_DECLARE_clientglobaledict(x) {ev_entity, #x}, +#define PRVM_DECLARE_clientglobalfunction(x) {ev_function, #x}, +#define PRVM_DECLARE_menuglobalfloat(x) +#define PRVM_DECLARE_menuglobalvector(x) +#define PRVM_DECLARE_menuglobalstring(x) +#define PRVM_DECLARE_menuglobaledict(x) +#define PRVM_DECLARE_menuglobalfunction(x) +#define PRVM_DECLARE_serverfieldfloat(x) +#define PRVM_DECLARE_serverfieldvector(x) +#define PRVM_DECLARE_serverfieldstring(x) +#define PRVM_DECLARE_serverfieldedict(x) +#define PRVM_DECLARE_serverfieldfunction(x) +#define PRVM_DECLARE_clientfieldfloat(x) +#define PRVM_DECLARE_clientfieldvector(x) +#define PRVM_DECLARE_clientfieldstring(x) +#define PRVM_DECLARE_clientfieldedict(x) +#define PRVM_DECLARE_clientfieldfunction(x) +#define PRVM_DECLARE_menufieldfloat(x) +#define PRVM_DECLARE_menufieldvector(x) +#define PRVM_DECLARE_menufieldstring(x) +#define PRVM_DECLARE_menufieldedict(x) +#define PRVM_DECLARE_menufieldfunction(x) +#define PRVM_DECLARE_serverfunction(x) +#define PRVM_DECLARE_clientfunction(x) +#define PRVM_DECLARE_menufunction(x) +#define PRVM_DECLARE_field(x) +#define PRVM_DECLARE_global(x) +#define PRVM_DECLARE_function(x) +#include "prvm_offsets.h" +#undef PRVM_DECLARE_serverglobalfloat +#undef PRVM_DECLARE_serverglobalvector +#undef PRVM_DECLARE_serverglobalstring +#undef PRVM_DECLARE_serverglobaledict +#undef PRVM_DECLARE_serverglobalfunction +#undef PRVM_DECLARE_clientglobalfloat +#undef PRVM_DECLARE_clientglobalvector +#undef PRVM_DECLARE_clientglobalstring +#undef PRVM_DECLARE_clientglobaledict +#undef PRVM_DECLARE_clientglobalfunction +#undef PRVM_DECLARE_menuglobalfloat +#undef PRVM_DECLARE_menuglobalvector +#undef PRVM_DECLARE_menuglobalstring +#undef PRVM_DECLARE_menuglobaledict +#undef PRVM_DECLARE_menuglobalfunction +#undef PRVM_DECLARE_serverfieldfloat +#undef PRVM_DECLARE_serverfieldvector +#undef PRVM_DECLARE_serverfieldstring +#undef PRVM_DECLARE_serverfieldedict +#undef PRVM_DECLARE_serverfieldfunction +#undef PRVM_DECLARE_clientfieldfloat +#undef PRVM_DECLARE_clientfieldvector +#undef PRVM_DECLARE_clientfieldstring +#undef PRVM_DECLARE_clientfieldedict +#undef PRVM_DECLARE_clientfieldfunction +#undef PRVM_DECLARE_menufieldfloat +#undef PRVM_DECLARE_menufieldvector +#undef PRVM_DECLARE_menufieldstring +#undef PRVM_DECLARE_menufieldedict +#undef PRVM_DECLARE_menufieldfunction +#undef PRVM_DECLARE_serverfunction +#undef PRVM_DECLARE_clientfunction +#undef PRVM_DECLARE_menufunction +#undef PRVM_DECLARE_field +#undef PRVM_DECLARE_global +#undef PRVM_DECLARE_function +}; + void CL_VM_Error (const char *format, ...) DP_FUNC_PRINTF(1); void CL_VM_Error (const char *format, ...) //[515]: hope it will be never executed =) { @@ -62,67 +218,53 @@ void CL_VM_Error (const char *format, ...) //[515]: hope it will be never execut } void CL_VM_UpdateDmgGlobals (int dmg_take, int dmg_save, vec3_t dmg_origin) { - prvm_eval_t *val; if(cl.csqc_loaded) { CSQC_BEGIN - val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.dmg_take); - if(val) - val->_float = dmg_take; - val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.dmg_save); - if(val) - val->_float = dmg_save; - val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.dmg_origin); - if(val) - { - val->vector[0] = dmg_origin[0]; - val->vector[1] = dmg_origin[1]; - val->vector[2] = dmg_origin[2]; - } + PRVM_clientglobalfloat(dmg_take) = dmg_take; + PRVM_clientglobalfloat(dmg_save) = dmg_save; + VectorCopy(dmg_origin, PRVM_clientglobalvector(dmg_origin)); CSQC_END } } void CSQC_UpdateNetworkTimes(double newtime, double oldtime) { - prvm_eval_t *val; if(!cl.csqc_loaded) return; CSQC_BEGIN - if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.servertime))) - val->_float = newtime; - if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.serverprevtime))) - val->_float = oldtime; - if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.serverdeltatime))) - val->_float = newtime - oldtime; + PRVM_clientglobalfloat(servertime) = newtime; + PRVM_clientglobalfloat(serverprevtime) = oldtime; + PRVM_clientglobalfloat(serverdeltatime) = newtime - oldtime; CSQC_END } //[515]: set globals before calling R_UpdateView, WEIRD CRAP static void CSQC_SetGlobals (void) { - prvm_eval_t *val; CSQC_BEGIN prog->globals.client->time = cl.time; prog->globals.client->frametime = max(0, cl.time - cl.oldtime); prog->globals.client->servercommandframe = cls.servermovesequence; prog->globals.client->clientcommandframe = cl.movecmd[0].sequence; VectorCopy(cl.viewangles, prog->globals.client->input_angles); - VectorCopy(cl.viewangles, cl.csqc_angles); // // FIXME: this actually belongs into getinputstate().. [12/17/2007 Black] prog->globals.client->input_buttons = cl.movecmd[0].buttons; VectorSet(prog->globals.client->input_movevalues, cl.movecmd[0].forwardmove, cl.movecmd[0].sidemove, cl.movecmd[0].upmove); - //VectorCopy(cl.movement_origin, cl.csqc_origin); - Matrix4x4_OriginFromMatrix(&cl.entities[cl.viewentity].render.matrix, cl.csqc_origin); + VectorCopy(cl.csqc_vieworiginfromengine, cl.csqc_vieworigin); + VectorCopy(cl.csqc_viewanglesfromengine, cl.csqc_viewangles); // LordHavoc: Spike says not to do this, but without pmove_org the // CSQC is useless as it can't alter the view origin without // completely replacing it - VectorCopy(cl.csqc_origin, prog->globals.client->pmove_org); + Matrix4x4_OriginFromMatrix(&cl.entities[cl.viewentity].render.matrix, prog->globals.client->pmove_org); VectorCopy(cl.movement_velocity, prog->globals.client->pmove_vel); + PRVM_clientglobalfloat(pmove_onground) = cl.onground; + PRVM_clientglobalfloat(pmove_inwater) = cl.inwater; - if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.view_angles))) - VectorCopy(cl.viewangles, val->vector); + VectorCopy(cl.viewangles, PRVM_clientglobalvector(view_angles)); + VectorCopy(cl.punchangle, PRVM_clientglobalvector(view_punchangle)); + VectorCopy(cl.punchvector, PRVM_clientglobalvector(view_punchvector)); prog->globals.client->maxclients = cl.maxclients; CSQC_END } @@ -159,10 +301,8 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum) int renderflags; int c; float scale; - prvm_eval_t *val; entity_render_t *entrender; dp_model_t *model; - matrix4x4_t tagmatrix, matrix2; model = CL_GetModelFromEdict(ed); if (!model) @@ -174,8 +314,9 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum) return false; entrender = cl.csqcrenderentities + edictnum; r_refdef.scene.entities[r_refdef.scene.numentities++] = entrender; - entrender->entitynumber = edictnum; + entrender->entitynumber = edictnum + MAX_EDICTS; //entrender->shadertime = 0; // shadertime was set by spawn() + entrender->flags = 0; entrender->alpha = 1; entrender->scale = 1; VectorSet(entrender->colormod, 1, 1, 1); @@ -189,61 +330,41 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum) return false; } + entrender->userwavefunc_param[0] = PRVM_clientedictfloat(ed, userwavefunc_param0); + entrender->userwavefunc_param[1] = PRVM_clientedictfloat(ed, userwavefunc_param1); + entrender->userwavefunc_param[2] = PRVM_clientedictfloat(ed, userwavefunc_param2); + entrender->userwavefunc_param[3] = PRVM_clientedictfloat(ed, userwavefunc_param3); + entrender->model = model; entrender->skinnum = (int)ed->fields.client->skin; entrender->effects |= entrender->model->effects; - scale = 1; - renderflags = 0; - if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.renderflags)) && val->_float) renderflags = (int)val->_float; - 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) - { - int tagentity; - int tagindex = 0; - tagentity = val->edict; - if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.tag_index)) && val->_float) - tagindex = (int)val->_float; - CL_GetTagMatrix (&tagmatrix, PRVM_PROG_TO_EDICT(tagentity), tagindex); - } - else - Matrix4x4_CreateIdentity(&tagmatrix); + renderflags = (int)PRVM_clientedictfloat(ed, renderflags); + entrender->alpha = PRVM_clientedictfloat(ed, alpha); + entrender->scale = scale = PRVM_clientedictfloat(ed, scale); + VectorCopy(PRVM_clientedictvector(ed, colormod), entrender->colormod); + VectorCopy(PRVM_clientedictvector(ed, glowmod), entrender->glowmod); + if(ed->fields.client->effects) entrender->effects |= (int)ed->fields.client->effects; + if (!entrender->alpha) + entrender->alpha = 1.0f; + if (!entrender->scale) + entrender->scale = scale = 1.0f; if (!VectorLength2(entrender->colormod)) VectorSet(entrender->colormod, 1, 1, 1); if (!VectorLength2(entrender->glowmod)) VectorSet(entrender->glowmod, 1, 1, 1); - if (renderflags & RF_USEAXIS) - { - vec3_t left; - VectorNegate(prog->globals.client->v_right, left); - Matrix4x4_FromVectors(&matrix2, prog->globals.client->v_forward, left, prog->globals.client->v_up, ed->fields.client->origin); - Matrix4x4_Scale(&matrix2, scale, 1); - } - else - { - vec3_t angles; - VectorCopy(ed->fields.client->angles, angles); - // if model is alias, reverse pitch direction - if (entrender->model->type == mod_alias) - angles[0] = -angles[0]; - - // set up the render matrix - Matrix4x4_CreateFromQuakeEntity(&matrix2, ed->fields.client->origin[0], ed->fields.client->origin[1], ed->fields.client->origin[2], angles[0], angles[1], angles[2], scale); - } + // LordHavoc: use the CL_GetTagMatrix function on self to ensure consistent behavior (duplicate code would be bad) + CL_GetTagMatrix(&entrender->matrix, ed, 0); // set up the animation data - CL_LoadFrameGroupBlend(ed, entrender); - - // concat the matrices to make the entity relative to its tag - Matrix4x4_Concat(&entrender->matrix, &tagmatrix, &matrix2); + VM_GenerateFrameGroupBlend(ed->priv.server->framegroupblend, ed); + VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model); + VM_UpdateEdictSkeleton(ed, model, ed->priv.server->frameblend); + entrender->shadertime = PRVM_clientedictfloat(ed, shadertime); // transparent offset - if ((renderflags & RF_USETRANSPARENTOFFSET) && (val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.transparent_offset))) - entrender->transparent_offset = val->_float; + if (renderflags & RF_USETRANSPARENTOFFSET) + entrender->transparent_offset = PRVM_clientglobalfloat(transparent_offset); if(renderflags) { @@ -252,7 +373,6 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum) 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; @@ -267,7 +387,7 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum) // either fullbright or lit if(!r_fullbright.integer) { - if (!(entrender->effects & EF_FULLBRIGHT)) + if (!(entrender->effects & EF_FULLBRIGHT) && !(renderflags & RF_FULLBRIGHT)) entrender->flags |= RENDER_LIGHT; else if(r_equalize_entities_fullbright.integer) entrender->flags |= RENDER_LIGHT | RENDER_EQUALIZE; @@ -275,6 +395,7 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum) // hide player shadow during intermission or nehahra movie if (!(entrender->effects & (EF_NOSHADOW | EF_ADDITIVE | EF_NODEPTHTEST)) && (entrender->alpha >= 1) + && !(renderflags & RF_NOSHADOW) && !(entrender->flags & RENDER_VIEWMODEL) && (!(entrender->flags & RENDER_EXTERIORMODEL) || (!cl.intermission && cls.protocol != PROTOCOL_NEHAHRAMOVIE && !cl_noplayershadow.integer))) entrender->flags |= RENDER_SHADOW; @@ -290,7 +411,14 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum) entrender->flags |= RENDER_DOUBLESIDED; // make the other useful stuff + memcpy(entrender->framegroupblend, ed->priv.server->framegroupblend, sizeof(ed->priv.server->framegroupblend)); CL_UpdateRenderEntity(entrender); + // override animation data with full control + memcpy(entrender->frameblend, ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend)); + if (ed->priv.server->skeleton.relativetransforms) + entrender->skeleton = &ed->priv.server->skeleton; + else + entrender->skeleton = NULL; return true; } @@ -303,7 +431,7 @@ qboolean CL_VM_InputEvent (qboolean down, int key, int ascii) return false; CSQC_BEGIN - if (!prog->funcoffsets.CSQC_InputEvent) + if (!PRVM_clientfunction(CSQC_InputEvent)) r = false; else { @@ -312,7 +440,7 @@ qboolean CL_VM_InputEvent (qboolean down, int key, int ascii) PRVM_G_FLOAT(OFS_PARM0) = !down; // 0 is down, 1 is up PRVM_G_FLOAT(OFS_PARM1) = key; PRVM_G_FLOAT(OFS_PARM2) = ascii; - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_InputEvent, "QC function CSQC_InputEvent is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_InputEvent), "QC function CSQC_InputEvent is missing"); r = CSQC_RETURNVAL != 0; } CSQC_END @@ -328,6 +456,7 @@ qboolean CL_VM_UpdateView (void) // vec3_t oldangles; if(!cl.csqc_loaded) return false; + R_TimeReport("pre-UpdateView"); CSQC_BEGIN //VectorCopy(cl.viewangles, oldangles); prog->globals.client->time = cl.time; @@ -340,11 +469,12 @@ qboolean CL_VM_UpdateView (void) // pass in width and height as parameters (EXT_CSQC_1) PRVM_G_FLOAT(OFS_PARM0) = vid.width; PRVM_G_FLOAT(OFS_PARM1) = vid.height; - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_UpdateView, "QC function CSQC_UpdateView is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_UpdateView), "QC function CSQC_UpdateView is missing"); //VectorCopy(oldangles, cl.viewangles); // Dresk : Reset Dmg Globals Here CL_VM_UpdateDmgGlobals(0, 0, emptyvector); CSQC_END + R_TimeReport("UpdateView"); return true; } @@ -356,13 +486,13 @@ qboolean CL_VM_ConsoleCommand (const char *cmd) if(!cl.csqc_loaded) return false; CSQC_BEGIN - if (prog->funcoffsets.CSQC_ConsoleCommand) + if (PRVM_clientfunction(CSQC_ConsoleCommand)) { prog->globals.client->time = cl.time; prog->globals.client->self = cl.csqc_server2csqcentitynumber[cl.playerentity]; restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize; PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(cmd); - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_ConsoleCommand, "QC function CSQC_ConsoleCommand is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_ConsoleCommand), "QC function CSQC_ConsoleCommand is missing"); vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; r = CSQC_RETURNVAL != 0; } @@ -377,12 +507,12 @@ qboolean CL_VM_Parse_TempEntity (void) if(!cl.csqc_loaded) return false; CSQC_BEGIN - if(prog->funcoffsets.CSQC_Parse_TempEntity) + if(PRVM_clientfunction(CSQC_Parse_TempEntity)) { t = msg_readcount; 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"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Parse_TempEntity), "QC function CSQC_Parse_TempEntity is missing"); r = CSQC_RETURNVAL != 0; if(!r) { @@ -460,13 +590,13 @@ void CL_VM_Parse_StuffCmd (const char *msg) return; } CSQC_BEGIN - if(prog->funcoffsets.CSQC_Parse_StuffCmd) + if(PRVM_clientfunction(CSQC_Parse_StuffCmd)) { prog->globals.client->time = cl.time; prog->globals.client->self = cl.csqc_server2csqcentitynumber[cl.playerentity]; restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize; PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(msg); - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Parse_StuffCmd, "QC function CSQC_Parse_StuffCmd is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Parse_StuffCmd), "QC function CSQC_Parse_StuffCmd is missing"); vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; } else @@ -481,7 +611,7 @@ static void CL_VM_Parse_Print (const char *msg) prog->globals.client->self = cl.csqc_server2csqcentitynumber[cl.playerentity]; restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize; PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(msg); - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Parse_Print, "QC function CSQC_Parse_Print is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Parse_Print), "QC function CSQC_Parse_Print is missing"); vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; } @@ -494,7 +624,7 @@ void CSQC_AddPrintText (const char *msg) return; } CSQC_BEGIN - if(prog->funcoffsets.CSQC_Parse_Print) + if(PRVM_clientfunction(CSQC_Parse_Print)) { // FIXME: is this bugged? i = strlen(msg)-1; @@ -527,13 +657,13 @@ void CL_VM_Parse_CenterPrint (const char *msg) return; } CSQC_BEGIN - if(prog->funcoffsets.CSQC_Parse_CenterPrint) + if(PRVM_clientfunction(CSQC_Parse_CenterPrint)) { prog->globals.client->time = cl.time; prog->globals.client->self = cl.csqc_server2csqcentitynumber[cl.playerentity]; restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize; PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(msg); - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Parse_CenterPrint, "QC function CSQC_Parse_CenterPrint is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Parse_CenterPrint), "QC function CSQC_Parse_CenterPrint is missing"); vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; } else @@ -543,25 +673,19 @@ void CL_VM_Parse_CenterPrint (const char *msg) void CL_VM_UpdateIntermissionState (int intermission) { - prvm_eval_t *val; if(cl.csqc_loaded) { CSQC_BEGIN - val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.intermission); - if(val) - val->_float = intermission; + PRVM_clientglobalfloat(intermission) = intermission; CSQC_END } } void CL_VM_UpdateShowingScoresState (int showingscores) { - prvm_eval_t *val; if(cl.csqc_loaded) { CSQC_BEGIN - val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.sb_showscores); - if(val) - val->_float = showingscores; + PRVM_clientglobalfloat(sb_showscores) = showingscores; CSQC_END } } @@ -571,7 +695,7 @@ qboolean CL_VM_Event_Sound(int sound_num, float volume, int channel, float atten if(cl.csqc_loaded) { CSQC_BEGIN - if(prog->funcoffsets.CSQC_Event_Sound) + if(PRVM_clientfunction(CSQC_Event_Sound)) { prog->globals.client->time = cl.time; prog->globals.client->self = cl.csqc_server2csqcentitynumber[cl.playerentity]; @@ -581,7 +705,7 @@ qboolean CL_VM_Event_Sound(int sound_num, float volume, int channel, float atten PRVM_G_FLOAT(OFS_PARM3) = volume; 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"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Event_Sound), "QC function CSQC_Event_Sound is missing"); r = CSQC_RETURNVAL != 0; } CSQC_END @@ -595,7 +719,6 @@ void CL_VM_UpdateCoopDeathmatchGlobals (int gametype) int localcoop; int localdeathmatch; - prvm_eval_t *val; if(cl.csqc_loaded) { if(gametype == GAME_COOP) @@ -617,12 +740,8 @@ void CL_VM_UpdateCoopDeathmatchGlobals (int gametype) localdeathmatch = 0; } CSQC_BEGIN - val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.coop); - if(val) - val->_float = localcoop; - val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.deathmatch); - if(val) - val->_float = localdeathmatch; + PRVM_clientglobalfloat(coop) = localcoop; + PRVM_clientglobalfloat(deathmatch) = localdeathmatch; CSQC_END } } @@ -632,12 +751,12 @@ float CL_VM_Event (float event) //[515]: needed ? I'd say "YES", but don't know if(!cl.csqc_loaded) return 0; CSQC_BEGIN - if(prog->funcoffsets.CSQC_Event) + if(PRVM_clientfunction(CSQC_Event)) { prog->globals.client->time = cl.time; prog->globals.client->self = cl.csqc_server2csqcentitynumber[cl.playerentity]; PRVM_G_FLOAT(OFS_PARM0) = event; - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Event, "QC function CSQC_Event is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Event), "QC function CSQC_Event is missing"); r = CSQC_RETURNVAL; } CSQC_END @@ -660,14 +779,14 @@ void CSQC_ReadEntities (void) { entnum = MSG_ReadShort(); if(!entnum || msg_badread) - return; + break; realentnum = entnum & 0x7FFF; prog->globals.client->self = cl.csqc_server2csqcentitynumber[realentnum]; if(entnum & 0x8000) { if(prog->globals.client->self) { - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Ent_Remove, "QC function CSQC_Ent_Remove is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Ent_Remove), "QC function CSQC_Ent_Remove is missing"); cl.csqc_server2csqcentitynumber[realentnum] = 0; } else @@ -683,7 +802,7 @@ void CSQC_ReadEntities (void) { if(!prog->globals.client->self) { - if(!prog->funcoffsets.CSQC_Ent_Spawn) + if(!PRVM_clientfunction(CSQC_Ent_Spawn)) { prvm_edict_t *ed; ed = PRVM_ED_Alloc(); @@ -697,15 +816,15 @@ void CSQC_ReadEntities (void) PRVM_G_FLOAT(OFS_PARM0) = (float) realentnum; // make sure no one gets wrong ideas prog->globals.client->self = 0; - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Ent_Spawn, "QC function CSQC_Ent_Spawn is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Ent_Spawn), "QC function CSQC_Ent_Spawn is missing"); prog->globals.client->self = cl.csqc_server2csqcentitynumber[realentnum] = PRVM_EDICT( PRVM_G_INT( OFS_RETURN ) ); } PRVM_G_FLOAT(OFS_PARM0) = 1; - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Ent_Update, "QC function CSQC_Ent_Update is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Ent_Update), "QC function CSQC_Ent_Update is missing"); } else { PRVM_G_FLOAT(OFS_PARM0) = 0; - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Ent_Update, "QC function CSQC_Ent_Update is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Ent_Update), "QC function CSQC_Ent_Update is missing"); } } } @@ -725,7 +844,7 @@ void CL_VM_CB_EndIncreaseEdicts(void) prvm_edict_t *ent; // link every entity except world - for (i = 1, ent = prog->edicts;i < prog->max_edicts;i++, ent++) + for (i = 1, ent = prog->edicts;i < prog->num_edicts;i++, ent++) if (!ent->priv.server->free) CL_LinkEdict(ent); } @@ -750,6 +869,7 @@ void CL_VM_CB_FreeEdict(prvm_edict_t *ed) memset(entrender, 0, sizeof(*entrender)); World_UnlinkEdict(ed); memset(ed->fields.client, 0, sizeof(*ed->fields.client)); + VM_RemoveEdictSkeleton(ed); World_Physics_RemoveFromEntity(&cl.world, ed); World_Physics_RemoveJointFromEntity(&cl.world, ed); } @@ -787,7 +907,7 @@ void Cmd_ClearCsqcFuncs (void); // returns true if the packet is valid, false if end of file is reached // used for dumping the CSQC download into demo files -qboolean MakeDownloadPacket(const char *filename, unsigned char *data, unsigned long len, int crc, int cnt, sizebuf_t *buf, int protocol) +qboolean MakeDownloadPacket(const char *filename, unsigned char *data, size_t len, int crc, int cnt, sizebuf_t *buf, int protocol) { int packetsize = buf->maxsize - 7; // byte short long int npackets = (len + packetsize - 1) / (packetsize); @@ -799,7 +919,7 @@ qboolean MakeDownloadPacket(const char *filename, unsigned char *data, unsigned if(cnt == 0) { MSG_WriteByte(buf, svc_stufftext); - MSG_WriteString(buf, va("\ncl_downloadbegin %lu %s\n", len, filename)); + MSG_WriteString(buf, va("\ncl_downloadbegin %lu %s\n", (unsigned long)len, filename)); return true; } else if(cnt >= 1 && cnt <= npackets) @@ -819,7 +939,7 @@ qboolean MakeDownloadPacket(const char *filename, unsigned char *data, unsigned else if(cnt == npackets + 1) { MSG_WriteByte(buf, svc_stufftext); - MSG_WriteString(buf, va("\ncl_downloadfinished %lu %d\n", len, crc)); + MSG_WriteString(buf, va("\ncl_downloadfinished %lu %d\n", (unsigned long)len, crc)); return true; } return false; @@ -832,7 +952,6 @@ void CL_VM_Init (void) fs_offset_t csprogsdatasize; int csprogsdatacrc, requiredcrc; int requiredsize; - prvm_eval_t *val; // reset csqc_progcrc after reading it, so that changing servers doesn't // expect csqc on the next server @@ -856,7 +975,7 @@ void CL_VM_Init (void) } if (csprogsdata) { - csprogsdatacrc = CRC_Block(csprogsdata, csprogsdatasize); + csprogsdatacrc = CRC_Block(csprogsdata, (size_t)csprogsdatasize); if (csprogsdatacrc != requiredcrc || csprogsdatasize != requiredsize) { if (cls.demoplayback) @@ -917,7 +1036,7 @@ void CL_VM_Init (void) prog->error_cmd = CL_VM_Error; prog->ExecuteProgram = CLVM_ExecuteProgram; - PRVM_LoadProgs(csprogsfn, cl_numrequiredfunc, cl_required_func, 0, NULL, 0, NULL); + PRVM_LoadProgs(csprogsfn, cl_numrequiredfunc, cl_required_func, CL_REQFIELDS, cl_reqfields, CL_REQGLOBALS, cl_reqglobals); if (!prog->loaded) { @@ -928,14 +1047,14 @@ void CL_VM_Init (void) return; } - Con_Printf("CSQC %s ^5loaded (crc=%i, size=%i)\n", csprogsfn, csprogsdatacrc, (int)csprogsdatasize); + Con_DPrintf("CSQC %s ^5loaded (crc=%i, size=%i)\n", csprogsfn, csprogsdatacrc, (int)csprogsdatasize); if(cls.demorecording) { if(cls.demo_lastcsprogssize != csprogsdatasize || cls.demo_lastcsprogscrc != csprogsdatacrc) { int i; - char buf[NET_MAXMESSAGE]; + static char buf[NET_MAXMESSAGE]; sizebuf_t sb; unsigned char *demobuf; fs_offset_t demofilesize; @@ -944,7 +1063,7 @@ void CL_VM_Init (void) i = 0; CL_CutDemo(&demobuf, &demofilesize); - while(MakeDownloadPacket(csqc_progname.string, csprogsdata, csprogsdatasize, csprogsdatacrc, i++, &sb, cls.protocol)) + while(MakeDownloadPacket(csqc_progname.string, csprogsdata, (size_t)csprogsdatasize, csprogsdatacrc, i++, &sb, cls.protocol)) CL_WriteDemoMessage(&sb); CL_PasteDemo(&demobuf, &demofilesize); @@ -962,18 +1081,16 @@ void CL_VM_Init (void) prog->globals.client->time = cl.time; prog->globals.client->self = 0; - prog->globals.client->mapname = cl.worldmodel ? PRVM_SetEngineString(cl.worldmodel->name) : PRVM_SetEngineString(""); + prog->globals.client->mapname = PRVM_SetEngineString(cl.worldname); prog->globals.client->player_localentnum = cl.playerentity; // set map description (use world entity 0) - val = PRVM_EDICTFIELDVALUE(prog->edicts, prog->fieldoffsets.message); - if(val) - val->string = PRVM_SetEngineString(cl.levelname); + PRVM_clientedictstring(prog->edicts, message) = PRVM_SetEngineString(cl.worldmessage); VectorCopy(cl.world.mins, prog->edicts->fields.client->mins); VectorCopy(cl.world.maxs, prog->edicts->fields.client->maxs); // call the prog init - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Init, "QC function CSQC_Init is missing"); + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Init), "QC function CSQC_Init is missing"); PRVM_End; cl.csqc_loaded = true; @@ -995,11 +1112,11 @@ void CL_VM_ShutDown (void) CSQC_BEGIN prog->globals.client->time = cl.time; prog->globals.client->self = 0; - if (prog->funcoffsets.CSQC_Shutdown) - PRVM_ExecuteProgram(prog->funcoffsets.CSQC_Shutdown, "QC function CSQC_Shutdown is missing"); + if (PRVM_clientfunction(CSQC_Shutdown)) + PRVM_ExecuteProgram(PRVM_clientfunction(CSQC_Shutdown), "QC function CSQC_Shutdown is missing"); PRVM_ResetProg(); CSQC_END - Con_Print("CSQC ^1unloaded\n"); + Con_DPrint("CSQC ^1unloaded\n"); cl.csqc_loaded = false; } @@ -1032,52 +1149,45 @@ qboolean CL_VM_GetEntitySoundOrigin(int entnum, vec3_t out) return r; } -void CL_LoadFrameGroupBlend(prvm_edict_t *ed, entity_render_t *entrender) +qboolean CL_VM_TransformView(int entnum, matrix4x4_t *viewmatrix, mplane_t *clipplane, vec3_t visorigin) { - 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.frame2 - // self.lerpfrac3 is the interpolation strength for self.frame3 - // self.lerpfrac4 is the interpolation strength for self.frame4 - // 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[1].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) lerpfrac1 is whatever remains after lerpfrac2+lerpfrac3+lerpfrac4 are summed - entrender->framegroupblend[0].lerp = 1 - entrender->framegroupblend[1].lerp - entrender->framegroupblend[2].lerp - entrender->framegroupblend[3].lerp; -} + qboolean ret = false; + prvm_edict_t *ed; + vec3_t forward, left, up, origin, ang; + matrix4x4_t mat, matq; -int CL_BlendTagMatrix(entity_render_t *entrender, int tagindex, matrix4x4_t *blendmatrix) -{ - int j, l, k; - int ret; - float d; - dp_model_t *model = entrender->model; - // blend the matrices - memset(blendmatrix, 0, sizeof(*blendmatrix)); - for (j = 0;j < MAX_FRAMEBLENDS && entrender->frameblend[j].lerp > 0;j++) - { - matrix4x4_t tagmatrix; - ret = Mod_Alias_GetTagMatrix(model, entrender->frameblend[j].subframe, tagindex, &tagmatrix); - if(ret) - return ret; - 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 0; + CSQC_BEGIN + ed = PRVM_EDICT_NUM(entnum); + // camera: + // camera_transform + if(PRVM_clientedictfunction(ed, camera_transform)) + { + ret = true; + if(viewmatrix || clipplane || visorigin) + { + Matrix4x4_ToVectors(viewmatrix, forward, left, up, origin); + AnglesFromVectors(ang, forward, up, false); + prog->globals.client->time = cl.time; + prog->globals.client->self = entnum; + VectorCopy(origin, PRVM_G_VECTOR(OFS_PARM0)); + VectorCopy(ang, PRVM_G_VECTOR(OFS_PARM1)); + VectorCopy(forward, PRVM_clientglobalvector(v_forward)); + VectorScale(left, -1, PRVM_clientglobalvector(v_right)); + VectorCopy(up, PRVM_clientglobalvector(v_up)); + VectorCopy(origin, PRVM_clientglobalvector(trace_endpos)); + PRVM_ExecuteProgram(PRVM_clientedictfunction(ed, camera_transform), "QC function e.camera_transform is missing"); + VectorCopy(PRVM_G_VECTOR(OFS_RETURN), origin); + VectorCopy(PRVM_clientglobalvector(v_forward), forward); + VectorScale(PRVM_clientglobalvector(v_right), -1, left); + VectorCopy(PRVM_clientglobalvector(v_up), up); + VectorCopy(PRVM_clientglobalvector(trace_endpos), visorigin); + Matrix4x4_Invert_Full(&mat, viewmatrix); + Matrix4x4_FromVectors(viewmatrix, forward, left, up, origin); + Matrix4x4_Concat(&matq, viewmatrix, &mat); + Matrix4x4_TransformPositivePlane(&matq, clipplane->normal[0], clipplane->normal[1], clipplane->normal[2], clipplane->dist, &clipplane->normal[0]); + } + } + CSQC_END + + return ret; }