diff --git a/Quake/cl_parse.c b/Quake/cl_parse.c index 58377b53..565ac8cd 100644 --- a/Quake/cl_parse.c +++ b/Quake/cl_parse.c @@ -586,7 +586,9 @@ void CL_ParseUpdate (int bits) else ent->alpha = ent->baseline.alpha; if (bits & U_SCALE) - MSG_ReadByte(); // PROTOCOL_RMQ: currently ignored + ent->scale = MSG_ReadByte(); + else + ent->scale = ent->baseline.scale; if (bits & U_FRAME2) ent->frame = (ent->frame & 0x00FF) | (MSG_ReadByte() << 8); if (bits & U_MODEL2) @@ -681,6 +683,7 @@ void CL_ParseBaseline (entity_t *ent, int version) //johnfitz -- added argument } ent->baseline.alpha = (bits & B_ALPHA) ? MSG_ReadByte() : ENTALPHA_DEFAULT; //johnfitz -- PROTOCOL_FITZQUAKE + ent->baseline.scale = (bits & B_SCALE) ? MSG_ReadByte() : ENTSCALE_DEFAULT; } @@ -920,7 +923,7 @@ void CL_ParseStatic (int version) //johnfitz -- added a parameter ent->skinnum = ent->baseline.skin; ent->effects = ent->baseline.effects; ent->alpha = ent->baseline.alpha; //johnfitz -- alpha - + ent->scale = ent->baseline.scale; VectorCopy (ent->baseline.origin, ent->origin); VectorCopy (ent->baseline.angles, ent->angles); R_AddEfrags (ent); diff --git a/Quake/cl_tent.c b/Quake/cl_tent.c index b1c9b8cf..496b89c4 100644 --- a/Quake/cl_tent.c +++ b/Quake/cl_tent.c @@ -278,7 +278,7 @@ entity_t *CL_NewTempEntity (void) num_temp_entities++; cl_visedicts[cl_numvisedicts] = ent; cl_numvisedicts++; - + ent->scale = ENTSCALE_DEFAULT; ent->colormap = vid.colormap; return ent; } diff --git a/Quake/gl_refrag.c b/Quake/gl_refrag.c index ee2350ce..03d9b9c4 100644 --- a/Quake/gl_refrag.c +++ b/Quake/gl_refrag.c @@ -170,6 +170,8 @@ void R_AddEfrags (entity_t *ent) { qmodel_t *entmodel; int i; + vec3_t boundVec, scaledVec; + vec_t scalefactor; if (!ent->model) return; @@ -179,11 +181,21 @@ void R_AddEfrags (entity_t *ent) r_pefragtopnode = NULL; entmodel = ent->model; - - for (i=0 ; i<3 ; i++) + scalefactor = ENTSCALE_DECODE(ent->scale); + if (scalefactor != 1.0f) { - r_emins[i] = ent->origin[i] + entmodel->mins[i]; - r_emaxs[i] = ent->origin[i] + entmodel->maxs[i]; + VectorCopy (entmodel->mins, boundVec); + VectorScale (boundVec, scalefactor, scaledVec); + VectorAdd (ent->origin, scaledVec, r_emins); + + VectorCopy (entmodel->maxs, boundVec); + VectorScale (boundVec, scalefactor, scaledVec); + VectorAdd (ent->origin, scaledVec, r_emaxs); + } + else + { + VectorAdd (ent->origin, entmodel->mins, r_emins); + VectorAdd (ent->origin, entmodel->maxs, r_emaxs); } R_SplitEntityOnNode (cl.worldmodel->nodes); diff --git a/Quake/gl_rmain.c b/Quake/gl_rmain.c index 5cd38065..1fc91b11 100644 --- a/Quake/gl_rmain.c +++ b/Quake/gl_rmain.c @@ -293,22 +293,39 @@ R_CullModelForEntity -- johnfitz -- uses correct bounds based on rotation */ qboolean R_CullModelForEntity (entity_t *e) { - vec3_t mins, maxs; + vec3_t mins, maxs, minbounds, maxbounds; + vec3_t scaledVec; + vec_t scalefactor; if (e->angles[0] || e->angles[2]) //pitch or roll { - VectorAdd (e->origin, e->model->rmins, mins); - VectorAdd (e->origin, e->model->rmaxs, maxs); + VectorCopy (e->model->rmins, minbounds); + VectorCopy (e->model->rmaxs, maxbounds); + } else if (e->angles[1]) //yaw { - VectorAdd (e->origin, e->model->ymins, mins); - VectorAdd (e->origin, e->model->ymaxs, maxs); + VectorCopy (e->model->ymins, minbounds); + VectorCopy (e->model->ymaxs, maxbounds); } else //no rotation { - VectorAdd (e->origin, e->model->mins, mins); - VectorAdd (e->origin, e->model->maxs, maxs); + VectorCopy (e->model->mins, minbounds); + VectorCopy (e->model->maxs, maxbounds); + } + + scalefactor = ENTSCALE_DECODE(e->scale); + if (scalefactor != 1.0f) + { + VectorScale (minbounds, scalefactor, scaledVec); + VectorAdd (e->origin, scaledVec, mins); + VectorScale (maxbounds, scalefactor, scaledVec); + VectorAdd (e->origin, scaledVec, maxs); + } + else + { + VectorAdd (e->origin, minbounds, mins); + VectorAdd (e->origin, maxbounds, maxs); } return R_CullBox (mins, maxs); diff --git a/Quake/pr_cmds.c b/Quake/pr_cmds.c index c3950b68..cca188e6 100644 --- a/Quake/pr_cmds.c +++ b/Quake/pr_cmds.c @@ -1580,6 +1580,7 @@ static void PF_makestatic (void) edict_t *ent; int i; int bits = 0; //johnfitz -- PROTOCOL_FITZQUAKE + eval_t *val; ent = G_EDICT(OFS_PARM0); @@ -1607,6 +1608,15 @@ static void PF_makestatic (void) bits |= B_LARGEFRAME; if (ent->alpha != ENTALPHA_DEFAULT) bits |= B_ALPHA; + + val = GetEdictFieldValue(ent, "scale"); + if (val) + ent->scale = ENTSCALE_ENCODE(val->_float); + else + ent->scale = ENTSCALE_DEFAULT; + + if (ent->scale != ENTSCALE_DEFAULT) + bits |= B_SCALE; } if (bits) @@ -1641,6 +1651,9 @@ static void PF_makestatic (void) MSG_WriteByte (&sv.signon, ent->alpha); //johnfitz + if (bits & B_SCALE) + MSG_WriteByte (&sv.signon, ent->scale); + // throw the entity away now ED_Free (ent); } diff --git a/Quake/progs.h b/Quake/progs.h index 8a15416b..ea8b0a55 100644 --- a/Quake/progs.h +++ b/Quake/progs.h @@ -47,6 +47,7 @@ typedef struct edict_s entity_state_t baseline; unsigned char alpha; /* johnfitz -- hack to support alpha since it's not part of entvars_t */ + unsigned char scale; qboolean sendinterval; /* johnfitz -- send time until nextthink to client for better lerp timing */ float freetime; /* sv.time when the object was freed */ diff --git a/Quake/protocol.h b/Quake/protocol.h index 158d0a5f..06ab1b19 100644 --- a/Quake/protocol.h +++ b/Quake/protocol.h @@ -125,6 +125,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define B_LARGEMODEL (1<<0) // modelindex is short instead of byte #define B_LARGEFRAME (1<<1) // frame is short instead of byte #define B_ALPHA (1<<2) // 1 byte, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT +#define B_SCALE (1<<3) //johnfitz //johnfitz -- PROTOCOL_FITZQUAKE -- alpha encoding @@ -136,6 +137,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define ENTALPHA_TOSAVE(a) (((a)==ENTALPHA_DEFAULT)?0.0f:(((a)==ENTALPHA_ZERO)?-1.0f:((float)(a)-1)/(254))) //server convert to float for savegame //johnfitz +#define ENTSCALE_DEFAULT 16 // Equivalent to float 1.0f due to byte packing. +#define ENTSCALE_ENCODE(a) ((a) ? ((a) * ENTSCALE_DEFAULT) : ENTSCALE_DEFAULT) // Convert to byte +#define ENTSCALE_DECODE(a) ((float)(a) / ENTSCALE_DEFAULT) // Convert to float for rendering + // defaults for clientinfo messages #define DEFAULT_VIEWHEIGHT 22 @@ -257,6 +262,7 @@ typedef struct unsigned char colormap; //johnfitz -- was int unsigned char skin; //johnfitz -- was int unsigned char alpha; //johnfitz -- added + unsigned char scale; int effects; } entity_state_t; diff --git a/Quake/r_alias.c b/Quake/r_alias.c index be411847..61e6a8b4 100644 --- a/Quake/r_alias.c +++ b/Quake/r_alias.c @@ -637,6 +637,7 @@ void R_DrawAliasModel (entity_t *e) lerpdata_t lerpdata; qboolean alphatest = !!(e->model->flags & MF_HOLEY); float fovscale = 1.0f; + float scalefactor = 1.0f; // // setup pose/lerp data -- do it first so we don't miss updates due to culling @@ -659,6 +660,11 @@ void R_DrawAliasModel (entity_t *e) glPushMatrix (); R_RotateForEntity (lerpdata.origin, lerpdata.angles); + scalefactor = ENTSCALE_DECODE(e->scale); + if (scalefactor != 1.0f) + { + glScalef (scalefactor, scalefactor, scalefactor); + } glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1] * fovscale, paliashdr->scale_origin[2] * fovscale); glScalef (paliashdr->scale[0], paliashdr->scale[1] * fovscale, paliashdr->scale[2] * fovscale); @@ -980,6 +986,7 @@ void R_DrawAliasModel_ShowTris (entity_t *e) { aliashdr_t *paliashdr; lerpdata_t lerpdata; + float scalefactor; if (R_CullModelForEntity(e)) return; @@ -990,6 +997,11 @@ void R_DrawAliasModel_ShowTris (entity_t *e) glPushMatrix (); R_RotateForEntity (lerpdata.origin,lerpdata.angles); + scalefactor = ENTSCALE_DECODE(e->scale); + if (scalefactor != 1.0f) + { + glScalef (scalefactor, scalefactor, scalefactor); + } glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]); glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]); diff --git a/Quake/render.h b/Quake/render.h index bf057b0e..807707c8 100644 --- a/Quake/render.h +++ b/Quake/render.h @@ -79,6 +79,7 @@ typedef struct entity_s // not split byte alpha; //johnfitz -- alpha + byte scale; byte lerpflags; //johnfitz -- lerping float lerpstart; //johnfitz -- animation lerping float lerptime; //johnfitz -- animation lerping diff --git a/Quake/sv_main.c b/Quake/sv_main.c index 1b98eefa..6d6d25d6 100644 --- a/Quake/sv_main.c +++ b/Quake/sv_main.c @@ -603,6 +603,7 @@ void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg) vec3_t org; float miss; edict_t *ent; + eval_t *val; // find the client's PVS VectorAdd (clent->v.origin, clent->v.view_ofs, org); @@ -640,9 +641,9 @@ void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg) // johnfitz -- max size for protocol 15 is 18 bytes, not 16 as originally // assumed here. And, for protocol 85 the max size is actually 24 bytes. - // For float coords and angles the limit is 39. + // For float coords and angles the limit is 40. // FIXME: Use tighter limit according to protocol flags and send bits. - if (msg->cursize + 39 > msg->maxsize) + if (msg->cursize + 40 > msg->maxsize) { //johnfitz -- less spammy overflow message if (!dev_overflows.packetsize || dev_overflows.packetsize + CONSOLE_RESPAM_TIME < realtime ) @@ -695,7 +696,6 @@ void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg) if (pr_alpha_supported) { // TODO: find a cleaner place to put this code - eval_t *val; val = GetEdictFieldValue(ent, "alpha"); if (val) ent->alpha = ENTALPHA_ENCODE(val->_float); @@ -706,11 +706,18 @@ void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg) continue; //johnfitz + val = GetEdictFieldValue(ent, "scale"); + if (val) + ent->scale = ENTSCALE_ENCODE(val->_float); + else + ent->scale = ENTSCALE_DEFAULT; + //johnfitz -- PROTOCOL_FITZQUAKE if (sv.protocol != PROTOCOL_NETQUAKE) { if (ent->baseline.alpha != ent->alpha) bits |= U_ALPHA; + if (ent->baseline.scale != ent->scale) bits |= U_SCALE; if (bits & U_FRAME && (int)ent->v.frame & 0xFF00) bits |= U_FRAME2; if (bits & U_MODEL && (int)ent->v.modelindex & 0xFF00) bits |= U_MODEL2; if (ent->sendinterval) bits |= U_LERPFINISH; @@ -771,6 +778,8 @@ void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg) //johnfitz -- PROTOCOL_FITZQUAKE if (bits & U_ALPHA) MSG_WriteByte(msg, ent->alpha); + if (bits & U_SCALE) + MSG_WriteByte(msg, ent->scale); if (bits & U_FRAME2) MSG_WriteByte(msg, (int)ent->v.frame >> 8); if (bits & U_MODEL2) @@ -1231,12 +1240,14 @@ void SV_CreateBaseline (void) svent->baseline.colormap = entnum; svent->baseline.modelindex = SV_ModelIndex("progs/player.mdl"); svent->baseline.alpha = ENTALPHA_DEFAULT; //johnfitz -- alpha support + svent->baseline.scale = ENTSCALE_DEFAULT; } else { svent->baseline.colormap = 0; svent->baseline.modelindex = SV_ModelIndex(PR_GetString(svent->v.model)); svent->baseline.alpha = svent->alpha; //johnfitz -- alpha support + svent->baseline.scale = svent->scale; } //johnfitz -- PROTOCOL_FITZQUAKE @@ -1248,6 +1259,7 @@ void SV_CreateBaseline (void) if (svent->baseline.frame & 0xFF00) svent->baseline.frame = 0; svent->baseline.alpha = ENTALPHA_DEFAULT; + svent->baseline.scale = ENTSCALE_DEFAULT; } else //decide which extra data needs to be sent { @@ -1257,6 +1269,8 @@ void SV_CreateBaseline (void) bits |= B_LARGEFRAME; if (svent->baseline.alpha != ENTALPHA_DEFAULT) bits |= B_ALPHA; + if (svent->baseline.scale != ENTSCALE_DEFAULT) + bits |= B_SCALE; } //johnfitz @@ -1299,6 +1313,9 @@ void SV_CreateBaseline (void) if (bits & B_ALPHA) MSG_WriteByte (&sv.signon, svent->baseline.alpha); //johnfitz + + if (bits & B_SCALE) + MSG_WriteByte (&sv.signon, svent->baseline.scale); } }