Fix support for scale with unextended protocol 999.

This commit is contained in:
Shpoike 2022-08-11 20:38:36 +01:00
parent 52d8cce64a
commit e9822ae936
10 changed files with 58 additions and 24 deletions

View File

@ -1802,7 +1802,7 @@ CL_ParseBaseline
static void CL_ParseBaseline (entity_t *ent, int version) //johnfitz -- added argument
{
int i;
int bits; //johnfitz
int bits, unknownbits;
if (version == 6)
{
@ -1831,7 +1831,17 @@ static void CL_ParseBaseline (entity_t *ent, int version) //johnfitz -- added ar
ent->baseline.angles[i] = MSG_ReadAngle (cl.protocolflags);
}
ent->baseline.alpha = (bits & B_ALPHA) ? MSG_ReadByte() : ENTALPHA_DEFAULT; //johnfitz -- PROTOCOL_FITZQUAKE
if (bits & B_ALPHA)
ent->baseline.alpha = MSG_ReadByte();
if (bits & B_SCALE) //not actually valid in 666, but reading anyway for servers that don't distinguish properly. The warning will have to suffice.
ent->baseline.scale = MSG_ReadByte();
if (cl.protocol == PROTOCOL_RMQ)
unknownbits = ~(B_LARGEMODEL|B_LARGEFRAME|B_ALPHA|B_SCALE);
else
unknownbits = ~(B_LARGEMODEL|B_LARGEFRAME|B_ALPHA);
if (bits & unknownbits)
Con_Warning("CL_ParseBaseline: Unknown bits %#x\n", bits & unknownbits);
}

View File

@ -541,9 +541,7 @@ entity_t *CL_NewTempEntity (void)
cl_visedicts[cl_numvisedicts] = ent;
cl_numvisedicts++;
ent->netstate.scale = 16;
ent->netstate.colormod[0] = ent->netstate.colormod[1] = ent->netstate.colormod[2] = 32;
ent->netstate.colormap = 0;
ent->netstate = nullentitystate;
return ent;
}

View File

@ -1787,9 +1787,9 @@ static void COM_SetupNullState(void)
// nullentitystate.glowmod[0] = 32;
// nullentitystate.glowmod[1] = 32;
// nullentitystate.glowmod[2] = 32;
nullentitystate.alpha = 0; //fte has 255 by default, with 0 for invisible. fitz uses 1 for invisible, 0 default, and 255=full alpha
nullentitystate.scale = 16;
// nullentitystate.solidsize = 0;//ES_SOLID_BSP;
nullentitystate.alpha = ENTALPHA_DEFAULT; //fte has 255 by default, with 0 for invisible. fitz uses 1 for invisible, 0 default, and 255=full alpha
nullentitystate.scale = ENTSCALE_DEFAULT;
nullentitystate.solidsize = ES_SOLID_NOT;
}
/*

View File

@ -300,7 +300,7 @@ R_CullModelForEntity -- johnfitz -- uses correct bounds based on rotation
qboolean R_CullModelForEntity (entity_t *e)
{
vec3_t mins, maxs;
float scale = e->netstate.scale/16.0;
float scale = ENTSCALE_DECODE(e->netstate.scale);
if (e->angles[0] || e->angles[2]) //pitch or roll
{
@ -333,8 +333,8 @@ void R_RotateForEntity (vec3_t origin, vec3_t angles, unsigned char scale)
glRotatef (-angles[0], 0, 1, 0);
glRotatef (angles[2], 1, 0, 0);
if (scale != 16)
glScalef (scale/16.0, scale/16.0, scale/16.0);
if (scale != ENTSCALE_DEFAULT)
glScalef (ENTSCALE_DECODE(scale), ENTSCALE_DECODE(scale), ENTSCALE_DECODE(scale));
}
/*

View File

@ -748,6 +748,7 @@ qmodel_t *CL_ModelForIndex(int index)
static void CL_LoadCSProgs(void)
{
qboolean fullcsqc = false;
int i;
PR_ClearProgs(&cl.qcvm);
if (pr_checkextension.value && !cl_nocsqc.value)
{ //only try to use csqc if qc extensions are enabled.
@ -774,6 +775,8 @@ static void CL_LoadCSProgs(void)
qcvm->edicts = (edict_t *) malloc (qcvm->max_edicts*qcvm->edict_size);
qcvm->num_edicts = qcvm->reserved_edicts = 1;
memset(qcvm->edicts, 0, qcvm->num_edicts*qcvm->edict_size);
for (i = 0; i < qcvm->num_edicts; i++)
EDICT_NUM(i)->baseline = nullentitystate;
//in terms of exploit protection this is kinda pointless as someone can just strip out this check and compile themselves. oh well.
if ((*versionedname && qcvm->progshash == csqchash && qcvm->progssize == csqcsize) || cls.demoplayback)

View File

@ -95,7 +95,7 @@ edict_t *ED_Alloc (void)
qcvm->num_edicts++;
e = EDICT_NUM(i);
memset(e, 0, qcvm->edict_size); // ericw -- switched sv.edicts to malloc(), so we are accessing uninitialized memory and must fully zero it, not just ED_ClearEdict
e->baseline = nullentitystate;
return e;
}

View File

@ -6084,8 +6084,8 @@ static void PR_addentity_internal(edict_t *ed) //adds a csqc entity into the sce
e->netstate.colormod[2] *= colormod->vector[2];
}
e->alpha = alpha?ENTALPHA_ENCODE(alpha->_float):ENTALPHA_DEFAULT;
if (scale && scale->_float)
e->netstate.scale *= scale->_float;
if (scale)
e->netstate.scale = ENTSCALE_ENCODE(scale->_float);
//can't exactly use currentpose/previous pose, as we don't know them.
e->lerpflags = LERP_EXPLICIT|LERP_RESETANIM|LERP_RESETMOVE;
@ -6937,7 +6937,7 @@ static void PF_cl_getrenderentity(void)
AngleVectors(tmp, tmp, tmp, G_VECTOR(OFS_RETURN));
break;
case GE_SCALE:
G_FLOAT(OFS_RETURN+0) = cl.entities[entnum].netstate.scale/16.0;
G_FLOAT(OFS_RETURN+0) = ENTSCALE_DECODE(cl.entities[entnum].netstate.scale);
break;
case GE_ALPHA:
G_FLOAT(OFS_RETURN+0) = ENTALPHA_DECODE(cl.entities[entnum].alpha);

View File

@ -241,6 +241,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) // added as part of rmq 999 (NOT valid for 666)
//johnfitz
//johnfitz -- PROTOCOL_FITZQUAKE -- alpha encoding
@ -252,6 +253,11 @@ 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
#define ENTSCALE_ENCODE(f) ((f)?CLAMP(1,(int)(ENTSCALE_DEFAULT*(f)),255):ENTSCALE_DEFAULT)
#define ENTSCALE_DECODE(es) ((es)/(float)ENTSCALE_DEFAULT)
#define ENTSCALE_QS_IS_BROKEN //FIXME: remove this once QS fixes its support for B_SCALE, allowing for scaled makestatic and baselines. Until then we are no worse than DP, just with more bloated ent deltas (replacementdeltas avoids spawnstatic feature loss).
// defaults for clientinfo messages
#define DEFAULT_VIEWHEIGHT 22

View File

@ -143,10 +143,7 @@ void R_DrawSpriteModel (entity_t *e)
if (psprite->type == SPR_ORIENTED)
GL_PolygonOffset (OFFSET_DECAL);
if (e->netstate.scale != 16)
scale = e->netstate.scale/16.0;
else
scale = 1;
scale = ENTSCALE_DECODE(e->netstate.scale);
glColor3f (e->netstate.colormod[0]/32.0,e->netstate.colormod[0]/32.0,e->netstate.colormod[0]/32.0);

View File

@ -1110,10 +1110,10 @@ void SV_BuildEntityState(edict_t *ent, entity_state_t *state)
state->frame = ent->v.frame;
state->colormap = ent->v.colormap;
state->skin = ent->v.skin;
if ((val = GetEdictFieldValue(ent, qcvm->extfields.scale)) && val->_float)
state->scale = val->_float*16;
if ((val = GetEdictFieldValue(ent, qcvm->extfields.scale)))
state->scale = ENTSCALE_ENCODE(val->_float);
else
state->scale = 16;
state->scale = ENTSCALE_DEFAULT;
if ((val = GetEdictFieldValue(ent, qcvm->extfields.alpha)))
state->alpha = ENTALPHA_ENCODE(val->_float);
else
@ -1325,6 +1325,10 @@ void MSG_WriteStaticOrBaseLine(sizebuf_t *buf, int idx, entity_state_t *state, u
bits |= B_LARGEFRAME;
if (state->alpha != ENTALPHA_DEFAULT)
bits |= B_ALPHA;
#ifndef ENTSCALE_QS_IS_BROKEN
if (state->scale != ENTSCALE_DEFAULT && protocol == PROTOCOL_RMQ)
bits |= B_SCALE;
#endif
}
if (idx>=0)
{
@ -1357,6 +1361,8 @@ void MSG_WriteStaticOrBaseLine(sizebuf_t *buf, int idx, entity_state_t *state, u
}
if (bits & B_ALPHA)
MSG_WriteByte (buf, state->alpha);
if (bits & B_SCALE)
MSG_WriteByte (buf, state->scale);
}
}
@ -2399,6 +2405,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
eval_t *val;
int maxsize = msg->maxsize;
int effects;
int scale = ENTSCALE_DEFAULT;
//try to avoid sounds getting lost. flickering entities are weird, but missing sounds+particles are just eerie.
maxsize -= client->datagram.cursize;
@ -2514,6 +2521,10 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
continue;
//johnfitz
val = GetEdictFieldValue(ent, qcvm->extfields.scale);
if (val)
scale = ENTSCALE_ENCODE(val->_float);
//spike -- PROTOCOL_VERSION_BJP3
if (sv.protocol == PROTOCOL_VERSION_BJP3)
{
@ -2524,11 +2535,11 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
//johnfitz -- PROTOCOL_FITZQUAKE
if (sv.protocol != PROTOCOL_NETQUAKE)
{
if (ent->baseline.alpha != ent->alpha) bits |= U_ALPHA;
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;
if (ent->baseline.scale != scale && sv.protocol == PROTOCOL_RMQ) bits |= U_SCALE;
if (bits >= 65536) bits |= U_EXTEND1;
if (bits >= 16777216) bits |= U_EXTEND2;
}
@ -2615,6 +2626,8 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
//johnfitz -- PROTOCOL_FITZQUAKE
if (bits & U_ALPHA)
MSG_WriteByte(msg, ent->alpha);
if (bits & U_SCALE)
MSG_WriteByte(msg, scale);
if (bits & U_FRAME2)
MSG_WriteByte(msg, (int)ent->v.frame >> 8);
if (bits & U_MODEL2)
@ -3386,6 +3399,7 @@ void SV_CreateBaseline (void)
//
// create entity baseline
//
svent->baseline = nullentitystate;
VectorCopy (svent->v.origin, svent->baseline.origin);
VectorCopy (svent->v.angles, svent->baseline.angles);
svent->baseline.frame = svent->v.frame;
@ -3407,7 +3421,13 @@ void SV_CreateBaseline (void)
svent->baseline.alpha = svent->alpha; //johnfitz -- alpha support
}
//Spike -- baselines are now generated on a per-client basis.
#ifndef ENTSCALE_QS_IS_BROKEN //Older versions of QS do NOT support B_SCALE. If we use default baseline values here then we will simply fall back to spamming U_SCALE every time instead.
val = GetEdictFieldValue(svent, qcvm->extfields.scale);
if (val)
svent->baseline.scale = ENTALPHA_ENCODE(val->_float);
#endif
//Spike -- baselines are now transmitted on a per-client basis.
//FIXME: should merge the above with other edict->entity_state copies (updates, baselines, spawnstatics)
//1) this allows per-client extensions.
//2) this avoids pre-generating a single signon buffer, splitting it over multiple packets.