From 0bdea16b65430b64282c4e9bed4953f20ef2e6ff Mon Sep 17 00:00:00 2001 From: havoc Date: Tue, 23 Jan 2007 01:40:36 +0000 Subject: [PATCH] fixed bug in CSQC_AddRenderEdict (it was using the tempentity's modelindex rather than the vm entity, meaning that csqc entities never had a visible model) reduced code by merging cl.csqc_model_precache lookups into CSQC_GetModelByIndex and CSQC_GetModelFromEntity functions git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6738 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_main.c | 4 +- clvm_cmds.c | 211 +++++++++++++--------------------------------------- csprogs.c | 56 +++++++++----- 3 files changed, 87 insertions(+), 184 deletions(-) diff --git a/cl_main.c b/cl_main.c index 7d666edc..29d92e94 100644 --- a/cl_main.c +++ b/cl_main.c @@ -898,8 +898,6 @@ void CL_UpdateNetworkEntity(entity_t *e) // model setup and some modelflags if(e->state_current.modelindex < MAX_MODELS) e->render.model = cl.model_precache[e->state_current.modelindex]; - else - e->render.model = cl.csqc_model_precache[65536-e->state_current.modelindex]; if (e->render.model) { // if model is alias or this is a tenebrae-like dlight, reverse pitch direction @@ -1308,7 +1306,7 @@ static void CL_RelinkEffects(void) if(e->modelindex < MAX_MODELS) ent->render.model = cl.model_precache[e->modelindex]; else - ent->render.model = cl.csqc_model_precache[65536-e->modelindex]; + ent->render.model = cl.csqc_model_precache[-(e->modelindex+1)]; ent->render.frame = ent->render.frame2; ent->render.colormap = -1; // no special coloring ent->render.alpha = 1; diff --git a/clvm_cmds.c b/clvm_cmds.c index 51164f43..dad081c2 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -122,6 +122,9 @@ void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius); void CSQC_RelinkAllEntities (int drawmask); void CSQC_RelinkCSQCEntities (void); char *Key_GetBind (int key); +model_t *CSQC_GetModelByIndex(int modelindex); +model_t *CSQC_GetModelFromEntity(prvm_edict_t *ed); + @@ -167,25 +170,27 @@ void VM_CL_setmodel (void) e = PRVM_G_EDICT(OFS_PARM0); m = PRVM_G_STRING(OFS_PARM1); - for(i=0;iname, m)) + for (i = 0;i < MAX_MODELS && cl.csqc_model_precache[i];i++) + { + if (!strcmp(cl.csqc_model_precache[i]->name, m)) { e->fields.client->model = PRVM_SetEngineString(cl.csqc_model_precache[i]->name); e->fields.client->modelindex = -(i+1); return; } + } - for (i=0, mod = cl.model_precache[0] ; i < MAX_MODELS ; i++, mod = cl.model_precache[i]) - if(mod) - if(!strcmp(mod->name, m)) + for (i = 0;i < MAX_MODELS;i++) + { + mod = cl.model_precache[i]; + if (mod && !strcmp(mod->name, m)) { e->fields.client->model = PRVM_SetEngineString(mod->name); e->fields.client->modelindex = i; return; } + } + e->fields.client->modelindex = 0; e->fields.client->model = 0; } @@ -308,37 +313,28 @@ void VM_CL_precache_model (void) VM_SAFEPARMCOUNT(1, VM_CL_precache_model); name = PRVM_G_STRING(OFS_PARM0); - for(i=1;iname, name)) { - i = -(i+1); - break; + PRVM_G_FLOAT(OFS_RETURN) = -(i+1); + return; } - if(i) - { - PRVM_G_FLOAT(OFS_RETURN) = i; - return; } PRVM_G_FLOAT(OFS_RETURN) = 0; m = Mod_ForName(name, false, false, false); if(m && m->loaded) { - for(i=1;ifields.client->model = 0; t->fields.client->modelindex = 0; - if(!i) + if (!i) return; - if(i<0) - { - i = -(i+1); - if(i >= MAX_MODELS) - { - VM_Warning("VM_CL_setmodelindex >= MAX_MODELS\n"); - return; - } - m = cl.csqc_model_precache[i]; - } - else - if(i >= MAX_MODELS) - { - VM_Warning("VM_CL_setmodelindex >= MAX_MODELS\n"); - return; - } - else - m = cl.model_precache[i]; - if(!m) + + model = CSQC_GetModelByIndex(i); + if (!model) { VM_Warning("VM_CL_setmodelindex: null model\n"); return; } - t->fields.client->model = PRVM_SetEngineString(m->name); + t->fields.client->model = PRVM_SetEngineString(model->name); t->fields.client->modelindex = i; } //#334 string(float mdlindex) modelnameforindex (EXT_CSQC) void VM_CL_modelnameforindex (void) { - int i; + model_t *model; VM_SAFEPARMCOUNT(1, VM_CL_modelnameforindex); PRVM_G_INT(OFS_RETURN) = 0; - i = (int)PRVM_G_FLOAT(OFS_PARM0); - if(i<0) - { - i = -(i+1); - if(i >= MAX_MODELS) - { - VM_Warning("VM_CL_modelnameforindex >= MAX_MODELS\n"); - return; - } - if(cl.csqc_model_precache[i]) - PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(cl.csqc_model_precache[i]->name); - return; - } - if(i >= MAX_MODELS) - { - VM_Warning("VM_CL_modelnameforindex >= MAX_MODELS\n"); - return; - } - if(cl.model_precache[i]) - PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(cl.model_precache[i]->name); + model = CSQC_GetModelByIndex((int)PRVM_G_FLOAT(OFS_PARM0)); + PRVM_G_INT(OFS_RETURN) = model ? PRVM_SetEngineString(model->name) : 0; } //#335 float(string effectname) particleeffectnum (EXT_CSQC) @@ -1729,28 +1692,6 @@ void VM_CL_te_plasmaburn (void) //DP_QC_GETSURFACE extern void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out); -static model_t *cl_getmodel(prvm_edict_t *ed) -{ - int modelindex; - model_t *model = NULL; - if (!ed || ed->priv.server->free) - return NULL; - modelindex = (int)ed->fields.client->modelindex; - if(!modelindex) - return NULL; - if(modelindex<0) - { - modelindex = -(modelindex+1); - if(modelindex < MAX_MODELS) - model = cl.csqc_model_precache[modelindex]; - } - else - { - if(modelindex < MAX_MODELS) - model = cl.model_precache[modelindex]; - } - return model; -} static msurface_t *cl_getsurface(model_t *model, int surfacenum) { @@ -1762,7 +1703,7 @@ static msurface_t *cl_getsurface(model_t *model, int surfacenum) // #434 float(entity e, float s) getsurfacenumpoints void VM_CL_getsurfacenumpoints(void) { - model_t *model = cl_getmodel(PRVM_G_EDICT(OFS_PARM0)); + model_t *model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0)); msurface_t *surface; // return 0 if no such surface if (!model || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) @@ -1784,7 +1725,7 @@ void VM_CL_getsurfacepoint(void) int pointnum; VectorClear(PRVM_G_VECTOR(OFS_RETURN)); ed = PRVM_G_EDICT(OFS_PARM0); - if (!(model = cl_getmodel(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) + if (!(model = CSQC_GetModelFromEntity(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) return; // note: this (incorrectly) assumes it is a simple polygon pointnum = (int)PRVM_G_FLOAT(OFS_PARM2); @@ -1801,7 +1742,7 @@ void VM_CL_getsurfacenormal(void) msurface_t *surface; vec3_t normal; VectorClear(PRVM_G_VECTOR(OFS_RETURN)); - if (!(model = cl_getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) + if (!(model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) return; // FIXME: implement rotation/scaling // note: this (incorrectly) assumes it is a simple polygon @@ -1818,7 +1759,7 @@ void VM_CL_getsurfacetexture(void) model_t *model; msurface_t *surface; PRVM_G_INT(OFS_RETURN) = 0; - if (!(model = cl_getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) + if (!(model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) return; PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(surface->texture->name); } @@ -1835,7 +1776,7 @@ void VM_CL_getsurfacenearpoint(void) vec_t *point; PRVM_G_FLOAT(OFS_RETURN) = -1; ed = PRVM_G_EDICT(OFS_PARM0); - if(!(model = cl_getmodel(ed)) || !model->num_surfaces) + if(!(model = CSQC_GetModelFromEntity(ed)) || !model->num_surfaces) return; // FIXME: implement rotation/scaling @@ -1877,7 +1818,7 @@ void VM_CL_getsurfaceclippedpoint(void) vec3_t p, out; VectorClear(PRVM_G_VECTOR(OFS_RETURN)); ed = PRVM_G_EDICT(OFS_PARM0); - if (!(model = cl_getmodel(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) + if (!(model = CSQC_GetModelFromEntity(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) return; // FIXME: implement rotation/scaling VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.client->origin, p); @@ -1920,21 +1861,7 @@ void VM_CL_setattachment (void) if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0]) { modelindex = (int)tagentity->fields.client->modelindex; - model = NULL; - - if(modelindex) - { - if(modelindex<0) - { - modelindex = -(modelindex+1); - if(modelindex < MAX_MODELS) - model = cl.csqc_model_precache[modelindex]; - } - else - if(modelindex < MAX_MODELS) - model = cl.model_precache[modelindex]; - } - + model = CSQC_GetModelByIndex(modelindex); if (model) { v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.client->skin, tagname); @@ -1951,27 +1878,11 @@ void VM_CL_setattachment (void) int CL_GetTagIndex (prvm_edict_t *e, const char *tagname) { - int i; - model_t *m; - - i = (int)e->fields.client->modelindex; - - if(!i) - return -1; - if(i<0) - { - i = -(i+1); - if(i >= MAX_MODELS) - return -1; - m = cl.csqc_model_precache[i]; - } + model_t *model = CSQC_GetModelFromEntity(e); + if (model) + return Mod_Alias_GetTagIndexForName(model, (int)e->fields.client->skin, tagname); else - if(i >= MAX_MODELS) - return -1; - else - m = cl.model_precache[i]; - - return Mod_Alias_GetTagIndexForName(m, (int)e->fields.client->skin, tagname); + return -1; }; // Warnings/errors code: @@ -1987,7 +1898,7 @@ extern cvar_t cl_bobup; int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) { prvm_eval_t *val; - int modelindex, reqframe, attachloop, i; + int reqframe, attachloop; matrix4x4_t entitymatrix, tagmatrix, attachmatrix; prvm_edict_t *attachent; model_t *model; @@ -1999,22 +1910,10 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) if (ent->priv.server->free) return 2; - modelindex = (int)ent->fields.client->modelindex; + model = CSQC_GetModelFromEntity(ent); - if(!modelindex) + if(!model) return 3; - if(modelindex<0) - { - modelindex = -(modelindex+1); - if(modelindex >= MAX_MODELS) - return 3; - model = cl.csqc_model_precache[modelindex]; - } - else - if(modelindex >= MAX_MODELS) - return 3; - else - model = cl.model_precache[modelindex]; if (ent->fields.client->frame >= 0 && ent->fields.client->frame < model->numframes && model->animscenes) reqframe = model->animscenes[(int)ent->fields.client->frame].firstframe; @@ -2039,17 +1938,7 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) attachent = PRVM_EDICT_NUM(val->edict); // to this it entity our entity is attached val = PRVM_GETEDICTFIELDVALUE(ent, csqc_fieldoff_tag_index); - model = NULL; - i = (int)attachent->fields.client->modelindex; - if(i<0) - { - i = -(i+1); - if(i < MAX_MODELS) - model = cl.csqc_model_precache[i]; - } - else - if(i < MAX_MODELS) - model = cl.model_precache[i]; + model = CSQC_GetModelFromEntity(attachent); if (model && val->_float >= 1 && model->animscenes && attachent->fields.client->frame >= 0 && attachent->fields.client->frame < model->numframes) Mod_Alias_GetTagMatrix(model, model->animscenes[(int)attachent->fields.client->frame].firstframe, (int)val->_float - 1, &attachmatrix); diff --git a/csprogs.c b/csprogs.c index 8e42b6f5..7f3f4281 100644 --- a/csprogs.c +++ b/csprogs.c @@ -118,6 +118,31 @@ void CL_VM_Error (const char *format, ...) //[515]: hope it will be never execut Host_Error(va("CL_VM_Error: %s", errorstring)); } +model_t *CSQC_GetModelByIndex(int modelindex) +{ + if(!modelindex) + return NULL; + if (modelindex < 0) + { + modelindex = -(modelindex+1); + if (modelindex < MAX_MODELS) + return cl.csqc_model_precache[modelindex]; + } + else + { + if(modelindex < MAX_MODELS) + return cl.model_precache[modelindex]; + } + return NULL; +} + +model_t *CSQC_GetModelFromEntity(prvm_edict_t *ed) +{ + if (!ed || ed->priv.server->free) + return NULL; + return CSQC_GetModelByIndex((int)ed->fields.client->modelindex); +} + //[515]: set globals before calling R_UpdateView, WEIRD CRAP static void CSQC_SetGlobals (void) { @@ -171,43 +196,35 @@ extern cvar_t cl_noplayershadow; qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) { int i; + float scale; prvm_eval_t *val; entity_t *e; + model_t *model; matrix4x4_t tagmatrix, matrix2; - e = CL_NewTempEntity(); - if (!e) + model = CSQC_GetModelFromEntity(ed); + if (!model) return false; - i = (int)ed->fields.client->modelindex; - if(i >= MAX_MODELS || i <= -MAX_MODELS) //[515]: make work as error ? - { - Con_Print("CSQC_AddRenderEdict: modelindex >= MAX_MODELS\n"); - ed->fields.client->modelindex = i = 0; - } - - // model setup and some modelflags - if (i < MAX_MODELS) - e->render.model = cl.model_precache[e->state_current.modelindex]; - else - e->render.model = cl.csqc_model_precache[65536-e->state_current.modelindex]; - - if (!e->render.model) + e = CL_NewTempEntity(); + if (!e) return false; + e->render.model = model; e->render.colormap = (int)ed->fields.client->colormap; e->render.frame = (int)ed->fields.client->frame; e->render.skinnum = (int)ed->fields.client->skin; e->render.effects |= e->render.model->flags2 & (EF_FULLBRIGHT | EF_ADDITIVE); + scale = 1; if((val = PRVM_GETEDICTFIELDVALUE(ed, csqc_fieldoff_alpha)) && val->_float) e->render.alpha = val->_float; - if((val = PRVM_GETEDICTFIELDVALUE(ed, csqc_fieldoff_scale)) && val->_float) e->render.scale = val->_float; + if((val = PRVM_GETEDICTFIELDVALUE(ed, csqc_fieldoff_scale)) && val->_float) e->render.scale = scale = val->_float; if((val = PRVM_GETEDICTFIELDVALUE(ed, csqc_fieldoff_colormod)) && VectorLength2(val->vector)) VectorCopy(val->vector, e->render.colormod); if((val = PRVM_GETEDICTFIELDVALUE(ed, csqc_fieldoff_effects)) && val->_float) e->render.effects = (int)val->_float; if((val = PRVM_GETEDICTFIELDVALUE(ed, csqc_fieldoff_tag_entity)) && val->edict) { int tagentity; - int tagindex; + int tagindex = 0; tagentity = val->edict; if((val = PRVM_GETEDICTFIELDVALUE(ed, csqc_fieldoff_tag_index)) && val->_float) tagindex = (int)val->_float; @@ -232,8 +249,7 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) angles[0] = -angles[0]; // set up the render matrix - // FIXME: e->render.scale should go away - Matrix4x4_CreateFromQuakeEntity(&matrix2, ed->fields.client->origin[0], ed->fields.client->origin[1], ed->fields.client->origin[2], angles[0], angles[1], angles[2], e->render.scale); + 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); } // FIXME: csqc has frame1/frame2/frame1time/frame2time/lerpfrac but this implementation's cl_entvars_t lacks those fields -- 2.39.2