1
0
Fork 0
forked from fte/fteqw

Fixed up some EXT_CSQC expectations.

Tweeked interpolation.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3313 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2009-07-18 20:46:42 +00:00
parent d119e7fadb
commit 58af42990d
19 changed files with 335 additions and 481 deletions

View file

@ -50,6 +50,8 @@ static struct predicted_player {
player_state_t *oldstate;
} predicted_players[MAX_CLIENTS];
static void CL_LerpNetFrameState(int fsanim, framestate_t *fs, lerpents_t *le);
extern int cl_playerindex, cl_h_playerindex, cl_rocketindex, cl_grenadeindex, cl_gib1index, cl_gib2index, cl_gib3index;
qboolean CL_FilterModelindex(int modelindex, int frame)
@ -379,6 +381,7 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean
// these are bits for the 'flags' field of the entity_state_t
i = MSG_ReadByte();
to->dpflags = i;
to->flags = 0;
if (i & RENDER_VIEWMODEL)
to->flags |= Q2RF_WEAPONMODEL|Q2RF_MINLIGHT|Q2RF_DEPTHHACK;
@ -1143,41 +1146,7 @@ entity_state_t *CL_FindPacketEntity(int num)
}
#endif
//return 0 to 1
//1 being entirly new frame.
float CL_LerpEntityFrac(float lerprate, float lerptime)
{
float f;
if (!lerprate)
{
return 0;
}
else
{
f = 1-(cl.time-lerptime)/lerprate;
}
if (f<0)f=0;
if (f>1)f=1;
return f;
}
float CL_EntLerpFactor(int entnum)
{
float f;
if (cl.lerpents[entnum].lerprate<=0)
return 0;
else
f = 1-(cl.time-cl.lerpents[entnum].lerptime)/cl.lerpents[entnum].lerprate;
if (f<0)
f=0;
if (f>1)
f=1;
return f;
}
void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
void CL_RotateAroundTag(entity_t *ent, int entnum, int parenttagent, int parenttagnum)
{
entity_state_t *ps;
float *org=NULL, *ang=NULL;
@ -1187,7 +1156,7 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
int model;
framestate_t fstate;
if (tagent > cl.maxlerpents)
if (parenttagent > cl.maxlerpents)
{
Con_Printf("tag entity out of range!\n");
return;
@ -1195,42 +1164,46 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
memset(&fstate, 0, sizeof(fstate));
fstate.g[FS_REG].frame[1] = cl.lerpents[tagent].frame;
//for visibility checks
ent->keynum = parenttagent;
ent->keynum = tagent;
ps = CL_FindPacketEntity(tagent);
ps = CL_FindPacketEntity(parenttagent);
if (ps)
{
if (ps->tagentity)
CL_RotateAroundTag(ent, num, ps->tagentity, ps->tagindex);
CL_RotateAroundTag(ent, entnum, ps->tagentity, ps->tagindex);
org = ps->origin;
ang = ps->angles;
model = ps->modelindex;
fstate.g[FS_REG].frame[0] = ps->frame;
CL_LerpNetFrameState(FS_REG, &fstate, &cl.lerpents[parenttagent]);
}
else
{
extern int parsecountmod;
// Con_Printf("tagent %i\n", tagent);
if (tagent <= MAX_CLIENTS && tagent > 0)
if (parenttagent <= MAX_CLIENTS && parenttagent > 0)
{
if (tagent-1 == cl.playernum[0])
if (parenttagent == cl.playernum[0]+1)
{
org = cl.simorg[0];
ang = cl.simangles[0];
}
else
{
org = cl.frames[parsecountmod].playerstate[tagent-1].origin;
ang = cl.frames[parsecountmod].playerstate[tagent-1].viewangles;
org = cl.frames[parsecountmod].playerstate[parenttagent-1].origin;
ang = cl.frames[parsecountmod].playerstate[parenttagent-1].viewangles;
}
model = cl.frames[parsecountmod].playerstate[tagent-1].modelindex;
fstate.g[FS_REG].frame[0] = cl.frames[parsecountmod].playerstate[tagent-1].frame;
model = cl.frames[parsecountmod].playerstate[parenttagent-1].modelindex;
CL_LerpNetFrameState(FS_REG, &fstate, &cl.lerpplayers[parenttagent-1]);
}
else
{
CL_LerpNetFrameState(FS_REG, &fstate, &cl.lerpents[parenttagent]);
model = 0;
}
}
if (ang)
@ -1240,10 +1213,11 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
ang[0]*=-1;
VectorInverse(axis[1]);
fstate.g[FS_REG].lerpfrac = CL_EntLerpFactor(tagent);
fstate.g[FS_REG].frametime[0] = cl.time - cl.lerpents[tagent].framechange;
fstate.g[FS_REG].frametime[1] = cl.time - cl.lerpents[tagent].oldframechange;
if (Mod_GetTag(cl.model_precache[model], tagnum, &fstate, transform))
// fstate.g[FS_REG].lerpfrac = CL_EntLerpFactor(tagent);
// fstate.g[FS_REG].frametime[0] = cl.time - cl.lerpents[tagent].framechange;
// fstate.g[FS_REG].frametime[1] = cl.time - cl.lerpents[tagent].oldframechange;
if (Mod_GetTag(cl.model_precache[model], parenttagnum, &fstate, transform))
{
old[0] = ent->axis[0][0];
old[1] = ent->axis[1][0];
@ -1400,6 +1374,39 @@ void V_AddLight (vec3_t org, float quant, float r, float g, float b)
CL_NewDlightRGB (0, org[0], org[1], org[2], quant, -0.1, r, g, b);
}
static void CL_LerpNetFrameState(int fsanim, framestate_t *fs, lerpents_t *le)
{
fs->g[fsanim].frame[0] = le->newframe;
fs->g[fsanim].frame[1] = le->oldframe;
fs->g[fsanim].frametime[0] = cl.servertime - le->newframestarttime;
fs->g[fsanim].frametime[1] = cl.servertime - le->oldframestarttime;
fs->g[fsanim].lerpfrac = 1-(fs->g[fsanim].frametime[0]) / le->framelerpdeltatime;
fs->g[fsanim].lerpfrac = bound(0, fs->g[FS_REG].lerpfrac, 1);
}
void CL_UpdateNetFrameLerpState(qboolean force, unsigned int curframe, lerpents_t *le)
{
if (force || curframe != le->newframe)
{
le->framelerpdeltatime = bound(0, cl.servertime - le->newframestarttime, 0.1); //clamp to 10 tics per second
if (!force)
{
le->oldframe = le->newframe;
le->oldframestarttime = le->newframestarttime;
}
else
{
le->oldframe = curframe;
le->oldframestarttime = cl.servertime;
}
le->newframe = curframe;
le->newframestarttime = cl.servertime;
}
}
/*
===============
CL_LinkPacketEntities
@ -1407,8 +1414,6 @@ CL_LinkPacketEntities
===============
*/
void R_FlameTrail(vec3_t start, vec3_t end, float seperation);
#define DECENTLERP
#ifdef DECENTLERP
void CL_TransitionPacketEntities(packet_entities_t *newpack, packet_entities_t *oldpack, float servertime)
{
@ -1471,32 +1476,72 @@ void CL_TransitionPacketEntities(packet_entities_t *newpack, packet_entities_t *
VectorClear(move);
}
for (i = 0; i < 3; i++)
if (sold == snew)
{
le->origin[i] = sold->origin[i] + frac*(move[i]);
//new this frame (or we noticed something changed significantly)
VectorCopy(snew->origin, le->origin);
VectorCopy(snew->angles, le->angles);
for (j = 0; j < 3; j++)
le->orglerpdeltatime = 0.1;
le->orglerpstarttime = oldpack->servertime;
}
else if (snew->dpflags & RENDER_STEP)
{
float lfrac;
//ignore the old packet entirely, except for maybe its time.
if (!VectorEquals(le->neworigin, snew->origin) || !VectorEquals(le->newangle, snew->angles))
{
a1 = sold->angles[i];
a2 = snew->angles[i];
if (a1 - a2 > 180)
a1 -= 360;
if (a1 - a2 < -180)
a1 += 360;
le->angles[i] = a1 + frac * (a2 - a1);
le->orglerpdeltatime = bound(0, oldpack->servertime - le->orglerpstarttime, 0.1); //clamp to 10 tics per second
le->orglerpstarttime = oldpack->servertime;
VectorCopy(le->neworigin, le->oldorigin);
VectorCopy(le->newangle, le->oldangle);
VectorCopy(snew->origin, le->neworigin);
VectorCopy(snew->angles, le->newangle);
}
lfrac = (servertime - le->orglerpstarttime) / le->orglerpdeltatime;
lfrac = bound(0, lfrac, 1);
for (i = 0; i < 3; i++)
{
le->origin[i] = le->oldorigin[i] + lfrac*(le->neworigin[i] - le->oldorigin[i]);
for (j = 0; j < 3; j++)
{
a1 = le->oldangle[i];
a2 = le->newangle[i];
if (a1 - a2 > 180)
a1 -= 360;
if (a1 - a2 < -180)
a1 += 360;
le->angles[i] = a1 + lfrac * (a2 - a1);
}
}
}
if (snew == sold || (sold->frame != le->frame && sold->frame != snew->frame) || snew->modelindex != sold->modelindex)
else
{
le->oldframechange = le->framechange;
le->framechange = newpack->servertime;
//lerp based purely on the packet times,
for (i = 0; i < 3; i++)
{
le->origin[i] = sold->origin[i] + frac*(move[i]);
if (le->framechange > le->oldframechange + 0.2)
le->oldframechange = le->framechange - 0.2;
le->frame = sold->frame;
for (j = 0; j < 3; j++)
{
a1 = sold->angles[i];
a2 = snew->angles[i];
if (a1 - a2 > 180)
a1 -= 360;
if (a1 - a2 < -180)
a1 += 360;
le->angles[i] = a1 + frac * (a2 - a1);
}
}
le->orglerpdeltatime = 0.1;
le->orglerpstarttime = oldpack->servertime;
}
CL_UpdateNetFrameLerpState(sold == snew, snew->frame, le);
}
}
@ -1644,21 +1689,6 @@ void CL_LinkPacketEntities (void)
memset(&ent->framestate, 0, sizeof(ent->framestate));
if (le->framechange == le->oldframechange)
ent->framestate.g[FS_REG].lerpfrac = 0;
else
{
ent->framestate.g[FS_REG].lerpfrac = 1-(servertime - le->framechange) / (le->framechange - le->oldframechange);
if (ent->framestate.g[FS_REG].lerpfrac > 1)
ent->framestate.g[FS_REG].lerpfrac = 1;
else if (ent->framestate.g[FS_REG].lerpfrac < 0)
{
ent->framestate.g[FS_REG].lerpfrac = 0;
//le->oldframechange = le->framechange;
}
}
VectorCopy(le->origin, ent->origin);
//bots or powerup glows. items always glow, powerups can be disabled
@ -1739,12 +1769,30 @@ void CL_LinkPacketEntities (void)
ent->abslight = state->abslight;
ent->drawflags = state->hexen2flags;
CL_LerpNetFrameState(FS_REG, &ent->framestate, le);
/*
// set frame
if (le->framechange == le->oldframechange)
ent->framestate.g[FS_REG].lerpfrac = 0;
else
{
ent->framestate.g[FS_REG].lerpfrac = 1-(servertime - le->framechange) / (le->framechange - le->oldframechange);
if (ent->framestate.g[FS_REG].lerpfrac > 1)
ent->framestate.g[FS_REG].lerpfrac = 1;
else if (ent->framestate.g[FS_REG].lerpfrac < 0)
{
ent->framestate.g[FS_REG].lerpfrac = 0;
//le->oldframechange = le->framechange;
}
}
ent->framestate.g[FS_REG].frame[0] = state->frame;
ent->framestate.g[FS_REG].frame[1] = le->frame;
ent->framestate.g[FS_REG].frametime[0] = cl.servertime - le->framechange;
ent->framestate.g[FS_REG].frametime[1] = cl.servertime - le->oldframechange;
*/
// f = (sin(realtime)+1)/2;
@ -1896,313 +1944,6 @@ void CL_LinkPacketEntities (void)
CSQC_DeltaEnd();
#endif
}
#else
void CL_LinkPacketEntities (void)
{
entity_t *ent;
packet_entities_t *pack;
entity_state_t *s1;
float f;
model_t *model;
vec3_t old_origin;
float autorotate;
int i;
int pnum;
//, spnum;
dlight_t *dl;
vec3_t angles;
int flicker;
pack = &cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities;
autorotate = anglemod(100*cl.time);
for (pnum=0 ; pnum<pack->num_entities ; pnum++)
{
s1 = &pack->entities[pnum];
if (cl_numvisedicts == MAX_VISEDICTS)
{
Con_Printf("Too many visible entities\n");
break;
}
ent = &cl_visedicts[cl_numvisedicts];
#ifdef Q3SHADERS
ent->forcedshader = NULL;
#endif
if (CL_MayLerp())
{
//figure out the lerp factor
if (cl.lerpents[s1->number].lerprate<=0)
f = 0;
else
f = (cl.servertime-cl.lerpents[s1->number].lerptime)/cl.lerpents[s1->number].lerprate;//(cl.gametime-cl.oldgametime);//1-(cl.time-cl.lerpents[s1->number].lerptime)/cl.lerpents[s1->number].lerprate;
if (f<0)
f=0;
if (f>1)
f=1;
}
else
f = 1;
ent->lerpfrac = 1-(cl.servertime-cl.lerpents[s1->number].lerptime)/cl.lerpents[s1->number].lerprate;
if (ent->lerpfrac<0)
ent->lerpfrac=0;
if (ent->lerpfrac>1)
ent->lerpfrac=1;
// if (s1->modelindex == 87 && !cl.paused)
// Con_Printf("%f %f\n", f, cl.lerpents[s1->number].lerptime-cl.servertime);
// calculate origin
for (i=0 ; i<3 ; i++)
ent->origin[i] = cl.lerpents[s1->number].origin[i] +
f * (s1->origin[i] - cl.lerpents[s1->number].origin[i]);
//bots or powerup glows. items always glow, powerups can be disabled
if (s1->modelindex != cl_playerindex || r_powerupglow.value)
{
flicker = r_lightflicker.value?(rand()&31):0;
// spawn light flashes, even ones coming from invisible objects
if ((s1->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED))
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + flicker, 0, 3);
else if (s1->effects & EF_BLUE)
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + flicker, 0, 1);
else if (s1->effects & EF_RED)
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + flicker, 0, 2);
else if (s1->effects & EF_BRIGHTLIGHT)
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2] + 16, 400 + flicker, 0, 0);
else if (s1->effects & EF_DIMLIGHT)
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + flicker, 0, 0);
}
if (s1->light[3])
{
CL_NewDlightRGB (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], s1->light[3], 0, s1->light[0]/1024.0f, s1->light[1]/1024.0f, s1->light[2]/1024.0f);
}
// if set to invisible, skip
if (s1->modelindex<1)
continue;
// create a new entity
if (cl_numvisedicts == MAX_VISEDICTS)
break; // object list is full
if (CL_FilterModelindex(s1->modelindex, s1->frame))
continue;
model = cl.model_precache[s1->modelindex];
if (!model)
{
Con_DPrintf("Bad modelindex (%i)\n", s1->modelindex);
continue;
}
cl_numvisedicts++;
#ifdef Q3SHADERS
ent->forcedshader = NULL;
#endif
ent->visframe = 0;
ent->keynum = s1->number;
if (cl_r2g.value && s1->modelindex == cl_rocketindex && cl_rocketindex && cl_grenadeindex)
ent->model = cl.model_precache[cl_grenadeindex];
else
ent->model = model;
ent->flags = s1->flags;
if (s1->effects & NQEF_ADDATIVE)
ent->flags |= Q2RF_ADDATIVE;
if (s1->effects & EF_NODEPTHTEST)
ent->flags |= RF_NODEPTHTEST;
// set colormap
if (s1->colormap && (s1->colormap <= MAX_CLIENTS)
&& (gl_nocolors.value == -1 || (ent->model/* && s1->modelindex == cl_playerindex*/)))
{
ent->colormap = cl.players[s1->colormap-1].translations;
ent->scoreboard = &cl.players[s1->colormap-1];
}
else
{
ent->colormap = vid.colormap;
ent->scoreboard = NULL;
}
// set skin
ent->skinnum = s1->skinnum;
ent->abslight = s1->abslight;
ent->drawflags = s1->hexen2flags;
// set frame
ent->frame = s1->frame;
ent->oldframe = cl.lerpents[s1->number].frame;
ent->frame1time = cl.servertime - cl.lerpents[s1->number].framechange;
ent->frame2time = cl.servertime - cl.lerpents[s1->number].oldframechange;
// f = (sin(realtime)+1)/2;
#ifdef PEXT_SCALE
//set scale
ent->scale = s1->scale/16.0;
#endif
#ifdef PEXT_TRANS
//set trans
ent->alpha = s1->trans/255.0;
#endif
#ifdef PEXT_FATNESS
//set trans
ent->fatness = s1->fatness/16.0;
#endif
// rotate binary objects locally
if (model && model->flags & EF_ROTATE)
{
angles[0] = 0;
angles[1] = autorotate;
angles[2] = 0;
if (cl_item_bobbing.value)
ent->origin[2] += 5+sin(cl.time*3)*5; //don't let it into the ground
}
else
{
float a1, a2;
for (i=0 ; i<3 ; i++)
{
a1 = cl.lerpents[s1->number].angles[i];
a2 = s1->angles[i];
if (a1 - a2 > 180)
a1 -= 360;
if (a1 - a2 < -180)
a1 += 360;
angles[i] = a1 + f * (a2 - a1);
}
}
VectorCopy(angles, ent->angles);
angles[0]*=-1;
AngleVectors(angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]);
if (ent->keynum <= MAX_CLIENTS
#ifdef NQPROT
&& cls.protocol == CP_QUAKEWORLD
#endif
)
ent->keynum += MAX_EDICTS;
if (s1->tagentity)
{ //ent is attached to a tag, rotate this ent accordingly.
CL_RotateAroundTag(ent, s1->number, s1->tagentity, s1->tagindex);
}
// add automatic particle trails
if (!model || (!(model->flags&~EF_ROTATE) && model->particletrail<0 && model->particleeffect<0))
continue;
if (!cls.allow_anyparticles && !(model->flags & ~EF_ROTATE))
continue;
// scan the old entity display list for a matching
for (i=0 ; i<cl_oldnumvisedicts ; i++)
{
if (cl_oldvisedicts[i].keynum == ent->keynum)
{
VectorCopy (cl_oldvisedicts[i].origin, old_origin);
break;
}
}
if (i == cl_oldnumvisedicts)
{
P_DelinkTrailstate(&(cl.lerpents[s1->number].trailstate));
P_DelinkTrailstate(&(cl.lerpents[s1->number].emitstate));
continue; // not in last message
}
for (i=0 ; i<3 ; i++)
{
if ( abs(old_origin[i] - ent->origin[i]) > 128)
{ // no trail if too far
VectorCopy (ent->origin, old_origin);
break;
}
}
if (model->particletrail >= 0)
{
if (P_ParticleTrail (old_origin, ent->origin, model->particletrail, &cl.lerpents[s1->number].trailstate))
P_ParticleTrailIndex(old_origin, ent->origin, model->traildefaultindex, 0, &cl.lerpents[s1->number].trailstate);
}
{
extern cvar_t gl_part_flame;
if (cls.allow_anyparticles && gl_part_flame.value)
{
P_EmitEffect (ent->origin, model->particleeffect, &(cl.lerpents[s1->number].emitstate));
}
}
//dlights are not so customisable.
if (r_rocketlight.value)
{
float rad = 0;
vec3_t dclr;
dclr[0] = 0.20;
dclr[1] = 0.10;
dclr[2] = 0;
if (model->flags & EF_ROCKET)
{
if (strncmp(model->name, "models/sflesh", 13))
{ //hmm. hexen spider gibs...
rad = 200;
dclr[2] = 0.05;
}
}
else if (model->flags & EF_FIREBALL)
{
rad = 120 - (rand() % 20);
}
else if (model->flags & EF_ACIDBALL)
{
rad = 120 - (rand() % 20);
}
else if (model->flags & EF_SPIT)
{
// as far as I can tell this effect inverses the light...
dclr[0] = -dclr[0];
dclr[1] = -dclr[1];
dclr[2] = -dclr[2];
rad = 120 - (rand() % 20);
}
if (rad)
{
dl = CL_AllocDlight (s1->number);
VectorCopy (ent->origin, dl->origin);
dl->die = (float)cl.time;
if (model->flags & EF_ROCKET)
dl->origin[2] += 1; // is this even necessary
dl->radius = rad * r_rocketlight.value;
VectorCopy(dclr, dl->color);
}
}
}
}
#endif
/*
=========================================================================
@ -2648,7 +2389,7 @@ guess_pm_type:
state->pm_type = PM_NORMAL;
}
if (cl.lerpplayers[num].frame != state->frame)
/* if (cl.lerpplayers[num].frame != state->frame)
{
cl.lerpplayers[num].oldframechange = cl.lerpplayers[num].framechange;
cl.lerpplayers[num].framechange = cl.time;
@ -2656,7 +2397,7 @@ guess_pm_type:
//don't care about position interpolation.
}
*/
TP_ParsePlayerInfo(oldstate, state, info);
}
@ -2885,23 +2626,8 @@ void CL_LinkPlayers (void)
ent->model = cl.model_precache[state->modelindex];
ent->skinnum = state->skinnum;
ent->framestate.g[FS_REG].frametime[0] = cl.time - cl.lerpplayers[j].framechange;
ent->framestate.g[FS_REG].frametime[1] = cl.time - cl.lerpplayers[j].oldframechange;
if (ent->framestate.g[FS_REG].frame[0] != cl.lerpplayers[j].frame)
{
ent->framestate.g[FS_REG].frame[1] = ent->framestate.g[FS_REG].frame[0];
ent->framestate.g[FS_REG].frame[0] = cl.lerpplayers[j].frame;
}
ent->framestate.g[FS_REG].lerpfrac = 1-(realtime - cl.lerpplayers[j].framechange)*10;
if (ent->framestate.g[FS_REG].lerpfrac > 1)
ent->framestate.g[FS_REG].lerpfrac = 1;
else if (ent->framestate.g[FS_REG].lerpfrac < 0)
{
ent->framestate.g[FS_REG].lerpfrac = 0;
//state->lerpstarttime = 0;
}
CL_UpdateNetFrameLerpState(false, state->frame, &cl.lerpplayers[j]);
CL_LerpNetFrameState(FS_REG, &ent->framestate, &cl.lerpplayers[j]);
if (state->modelindex == cl_playerindex)
ent->scoreboard = info; // use custom skin
@ -3649,13 +3375,6 @@ void MVD_Interpolate(void)
state->velocity[j] = oldstate->velocity[j] + f * (pplayer->oldv[j] - oldstate->velocity[j]);
}
}
if (cl.lerpplayers[i].frame != state->frame)
{
cl.lerpplayers[i].oldframechange = cl.lerpplayers[i].framechange;
cl.lerpplayers[i].framechange = demtime;
cl.lerpplayers[i].frame = state->frame;
}
}
}

View file

@ -2469,10 +2469,11 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
//pretend it came from the server, and update cheat/permissions/etc
CL_CheckServerInfo();
#ifdef PEXT_CSQC
CSQC_Shutdown();
if (cls.demoplayback)
CSQC_Init(0);
#endif
}
void CLNQ_SignonReply (void)
{
@ -2503,7 +2504,7 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
CL_SendClientCommand(true, "playermodel %s", model.string);
CL_SendClientCommand(true, "playerskin %s", skin.string);
#ifdef PEXT_CSQC
{
char *s;
s = Info_ValueForKey(cl.serverinfo, "*csprogs");
@ -2512,6 +2513,7 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
else
CSQC_Shutdown();
}
#endif
}
break;
@ -5729,9 +5731,11 @@ void CLNQ_ParseServerMessage (void)
CLNQ_ParseDarkPlaces5Entities();
break;
#ifdef PEXT_CSQC
case svcdp_csqcentities:
CSQC_ParseEntities();
break;
#endif
case svcdp_downloaddata:
CLDP_ParseDownloadData();

View file

@ -252,7 +252,6 @@ typedef struct
#define LFLAG_ALLOW_LMHACK (1<<16)
#define LFLAG_ALLOW_FLASH (1<<17)
#define LFLAG_ALLOW_PPL (1<<18)
#define LFLAG_ALLOW_PPL (1<<18)
#define LFLAG_DYNAMIC (LFLAG_ALLOW_PPL | LFLAG_ALLOW_LMHACK | LFLAG_ALLOW_FLASH | LFLAG_NORMALMODE | LFLAG_REALTIMEMODE)
@ -434,19 +433,28 @@ typedef struct downloadlist_s {
typedef struct {
float lerptime;
float framechange; //marks time of last frame change - for halflife model sequencing.
float oldframechange;
float lerprate; //inverse rate...
vec3_t origin; //current render position
vec3_t angles;
vec3_t forigin; //when the frame changed
vec3_t fangles;
vec3_t foldorigin;//
vec3_t foldangles;
//current persistant state
trailstate_t *trailstate; //when to next throw out a trail
trailstate_t *emitstate; //when to next emit
unsigned short frame, oldframe;
//current origin
vec3_t origin; //current render position
vec3_t angles;
//intermediate values for frame lerping
float framelerpdeltatime;
float newframestarttime;
int newframe;
float oldframestarttime;
int oldframe;
//intermediate values for origin lerping of stepping things
float orglerpdeltatime;
float orglerpstarttime;
vec3_t neworigin;
vec3_t oldorigin;
vec3_t newangle;
vec3_t oldangle;
} lerpents_t;
//
// the client_state_t structure is wiped completely at every

View file

@ -239,7 +239,9 @@ static void PClassic_DrawParticles(void)
int i;
float time2, time3, time1, dvel, frametime, grav;
#ifdef RGLQUAKE
#ifndef USEARRAYS
unsigned char *at, theAlpha;
#endif
vec3_t up, right;
float dist, scale, r_partscale=0;

View file

@ -187,6 +187,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#endif
//temporarily disable stuff here, so as to not break any custom configs
//#define NEWBACKEND
//fix things a little...
@ -239,7 +240,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef VM_Q1
#endif
#if defined(GLQUAKE)
#if defined(D3DQUAKE)
//not supported in anything but GL. avoid bugs.
#undef AVAIL_FREETYPE
#endif
@ -273,7 +274,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef Q3BSPS
#endif
#if !defined(Q3BSPS)
#undef Q3SHADERS
#undef Q3CLIENT //reconsider this (later)
#undef Q3SERVER //reconsider this (later)
#endif

View file

@ -1771,11 +1771,11 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, qboolean alpha)
//LH's naming scheme ("models" is likly to be ignored)
fbtexture = 0;
bumptexture = 0;
snprintf(skinname, sizeof(skinname), "%s_%i.", loadmodel->name, i);
snprintf(skinname, sizeof(skinname), "%s_%i", loadmodel->name, i);
texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true);
if (texture)
{
snprintf(skinname, sizeof(skinname), "%s_%i_luma.", loadmodel->name, i);
snprintf(skinname, sizeof(skinname), "%s_%i_luma", loadmodel->name, i);
fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, false, true);
if (gl_bump.value)
{
@ -1883,12 +1883,12 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, qboolean alpha)
//LH naming scheme
if (!texture)
{
sprintf(skinname, "%s_%i_%i.", loadmodel->name, i, t);
sprintf(skinname, "%s_%i_%i", loadmodel->name, i, t);
texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true);
}
if (!fbtexture && r_fb_models.value)
{
sprintf(skinname, "%s_%i_%i_luma.", loadmodel->name, i, t);
sprintf(skinname, "%s_%i_%i_luma", loadmodel->name, i, t);
fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, true, true);
}

View file

@ -659,7 +659,7 @@ qboolean CM_CreateBrush ( q2cbrush_t *brush, vec3_t *verts, q2mapsurface_t *surf
normal[(k+1)%3] = v1[(k+2)%3] - v2[(k+2)%3];
normal[(k+2)%3] = -(v1[(k+1)%3] - v2[(k+1)%3]);
if (VectorCompare (normal, vec3_origin))
if (VectorEquals (normal, vec3_origin))
continue;
plane = &patchplanes[numpatchplanes++];
@ -684,7 +684,7 @@ qboolean CM_CreateBrush ( q2cbrush_t *brush, vec3_t *verts, q2mapsurface_t *surf
for (j = i + 1; j < numpatchplanes; j++)
if ( patchplanes[j].dist == patchplanes[i].dist
&& VectorCompare (patchplanes[j].normal, patchplanes[i].normal) )
&& VectorEquals (patchplanes[j].normal, patchplanes[i].normal) )
{
skip[i] = true;
break;
@ -2482,9 +2482,9 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
indexes[1] = p + size[0];
indexes[2] = p + 1;
if ( !VectorCompare(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[1]]) &&
!VectorCompare(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[2]]) &&
!VectorCompare(mesh->xyz_array[indexes[1]], mesh->xyz_array[indexes[2]]) ) {
if ( !VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[1]]) &&
!VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[2]]) &&
!VectorEquals(mesh->xyz_array[indexes[1]], mesh->xyz_array[indexes[2]]) ) {
indexes += 3;
numindexes += 3;
}
@ -2493,9 +2493,9 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
indexes[1] = p + size[0];
indexes[2] = p + size[0] + 1;
if ( !VectorCompare(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[1]]) &&
!VectorCompare(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[2]]) &&
!VectorCompare(mesh->xyz_array[indexes[1]], mesh->xyz_array[indexes[2]]) ) {
if ( !VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[1]]) &&
!VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[2]]) &&
!VectorEquals(mesh->xyz_array[indexes[1]], mesh->xyz_array[indexes[2]]) ) {
indexes += 3;
numindexes += 3;
}
@ -3042,7 +3042,7 @@ qboolean CModQ3_LoadLeafs (lump_t *l)
out->nummarksurfaces = LittleLong(in->num_leafsurfaces);
if (out->minmaxs[0] > out->minmaxs[3+0] || out->minmaxs[1] > out->minmaxs[3+1] ||
out->minmaxs[2] > out->minmaxs[3+2] || VectorCompare (out->minmaxs, out->minmaxs+3))
out->minmaxs[2] > out->minmaxs[3+2] || VectorEquals (out->minmaxs, out->minmaxs+3))
{
out->nummarksurfaces = 0;
}

View file

@ -1268,6 +1268,8 @@ void R_DrawGAliasModel (entity_t *e)
#if defined(Q3SHADERS) && defined(Q2BSPS)
fog = CM_FogForOrigin(currententity->origin);
#elif defined(Q3SHADERS)
fog = NULL;
#endif
qglColor4f(shadelight[0]/255, shadelight[1]/255, shadelight[2]/255, e->shaderRGBAf[3]);

View file

@ -977,9 +977,9 @@ void R_DeformVertices ( meshbuffer_t *mb )
for ( j = 2; j >= 0; j-- )
{
quad[3] = (float *)(vertexArray + indexesArray[k+3+j]);
if ( !VectorCompare (quad[3], quad[0]) &&
!VectorCompare (quad[3], quad[1]) &&
!VectorCompare (quad[3], quad[2]) ) {
if ( !VectorEquals (quad[3], quad[0]) &&
!VectorEquals (quad[3], quad[1]) &&
!VectorEquals (quad[3], quad[2]) ) {
break;
}
}
@ -1026,9 +1026,9 @@ void R_DeformVertices ( meshbuffer_t *mb )
for ( j = 2; j >= 0; j-- )
{
quad[3] = (float *)(vertexArray + indexesArray[k+3+j]);
if ( !VectorCompare (quad[3], quad[0]) &&
!VectorCompare (quad[3], quad[1]) &&
!VectorCompare (quad[3], quad[2]) )
if ( !VectorEquals (quad[3], quad[0]) &&
!VectorEquals (quad[3], quad[1]) &&
!VectorEquals (quad[3], quad[2]) )
{
break;
}
@ -2429,7 +2429,7 @@ void R_AddDynamicLights ( meshbuffer_t *mb )
VectorMA ( dlorigin, -dist, normal, point );
scale = 1 / (light->radius - dist);
if ( !VectorCompare (normal, oldnormal) ) {
if ( !VectorEquals (normal, oldnormal) ) {
MakeNormalVectors ( normal, right, up );
VectorCopy ( normal, oldnormal );
}

View file

@ -4893,7 +4893,7 @@ qboolean PPL_ScissorForBox(vec3_t mins, vec3_t maxs)
v[1] = (i & 2) ? mins[1] : maxs[1];
v[2] = (i & 4) ? mins[2] : maxs[2];
v[3] = 1.0f;
Matrix4_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, (float)vid.width/vid.height, r_refdef.fov_y);
Matrix4_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y);
v2[0]*=r_view_width;
v2[1]*=r_view_height;
// GL_TransformToScreen(v, v2);

View file

@ -994,6 +994,7 @@ void R_ImportRTLights(char *entlump)
dl->flags |= LFLAG_REALTIMEMODE;
dl->flags |= (pflags & PFLAGS_CORONA)?LFLAG_ALLOW_FLASH:0;
dl->flags |= (pflags & PFLAGS_NOSHADOW)?LFLAG_NOSHADOWS:0;
dl->flags |= LFLAG_ALLOW_PPL;
dl->style = style+1;
//FIXME: cubemaps if skin >= 16
@ -1092,7 +1093,7 @@ void R_LoadRTLights(void)
dl->radius = radius;
VectorCopy(rgb, dl->color);
dl->die = 0;
dl->flags = flags;
dl->flags = flags|LFLAG_ALLOW_PPL;
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
dl->style = style+1;

View file

@ -2165,7 +2165,7 @@ void R_MarkLeafSurfaces_Q1 (void)
int shift;
r_visframecount++;
if (1)//r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2)
if (r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2)
{
}
else
@ -2190,7 +2190,7 @@ void R_MarkLeafSurfaces_Q1 (void)
vis = fatvis;
}
else
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL);
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, fatvis);
}
@ -2679,6 +2679,7 @@ int GLAllocBlock (int w, int h, int *x, int *y)
if (!lightmap[texnum])
{
lightmap[texnum] = Z_Malloc(sizeof(*lightmap[texnum]));
lightmap[texnum]->meshchain = NULL;
lightmap[texnum]->modified = true;
// reset stainmap since it now starts at 255
memset(lightmap[texnum]->stainmaps, 255, sizeof(lightmap[texnum]->stainmaps));
@ -2749,6 +2750,7 @@ int GLFillBlock (int texnum, int w, int h, int x, int y)
if (!lightmap[i])
{
lightmap[i] = BZ_Malloc(sizeof(*lightmap[i]));
lightmap[i]->meshchain = NULL;
lightmap[i]->modified = true;
for (l=0 ; l<LMBLOCK_HEIGHT ; l++)
{
@ -2846,7 +2848,6 @@ void GL_BuildSurfaceDisplayList (msurface_t *fa)
t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
VectorCopy (vec, mesh->xyz_array[i]);
mesh->xyz_array[i][3] = 1;
mesh->st_array[i][0] = s/fa->texinfo->texture->width;
mesh->st_array[i][1] = t/fa->texinfo->texture->height;
@ -3124,16 +3125,24 @@ static void GL_GenBrushModelVBO(model_t *mod)
vbo->lmcoord[vcount+v][0] = m->lmst_array[v][0];
vbo->lmcoord[vcount+v][1] = m->lmst_array[v][1];
}
vbo->normals[vcount+v][0] = m->normals_array[v][0];
vbo->normals[vcount+v][1] = m->normals_array[v][1];
vbo->normals[vcount+v][2] = m->normals_array[v][2];
vbo->svector[vcount+v][0] = m->snormals_array[v][0];
vbo->svector[vcount+v][1] = m->snormals_array[v][1];
vbo->svector[vcount+v][2] = m->snormals_array[v][2];
vbo->tvector[vcount+v][0] = m->tnormals_array[v][0];
vbo->tvector[vcount+v][1] = m->tnormals_array[v][1];
vbo->tvector[vcount+v][2] = m->tnormals_array[v][2];
if (m->normals_array)
{
vbo->normals[vcount+v][0] = m->normals_array[v][0];
vbo->normals[vcount+v][1] = m->normals_array[v][1];
vbo->normals[vcount+v][2] = m->normals_array[v][2];
}
if (m->snormals_array)
{
vbo->svector[vcount+v][0] = m->snormals_array[v][0];
vbo->svector[vcount+v][1] = m->snormals_array[v][1];
vbo->svector[vcount+v][2] = m->snormals_array[v][2];
}
if (m->tnormals_array)
{
vbo->tvector[vcount+v][0] = m->tnormals_array[v][0];
vbo->tvector[vcount+v][1] = m->tnormals_array[v][1];
vbo->tvector[vcount+v][2] = m->tnormals_array[v][2];
}
}
vcount += v;
}

View file

@ -48,6 +48,7 @@ void GLVID_Console_Resize(void)
{
#ifdef AVAIL_FREETYPE
extern struct font_s *conchar_font;
extern cvar_t gl_font;
#endif
extern cvar_t vid_conwidth, vid_conheight;
int cwidth, cheight;
@ -199,6 +200,9 @@ void GLSCR_UpdateScreen (void)
return; // not initialized yet
}
qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
#ifdef VM_UI
uimenu = UI_MenuState();
#else

View file

@ -653,13 +653,17 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
parmtype = SP_ENTCOLOURS;
}
else if (!Q_stricmp(token, "upper"))
{
parmtype = SP_TOPCOLOURS;
}
else if (!Q_stricmp(token, "lower"))
{
parmtype = SP_BOTTOMCOLOURS;
}
else if (!Q_stricmp(token, "lightradius"))
parmtype = SP_LIGHTRADIUS;
else if (!Q_stricmp(token, "lightcolour"))
parmtype = SP_LIGHTCOLOUR;
else if (!Q_stricmp(token, "lightpos"))
parmtype = SP_LIGHTPOSITION;
else
Con_Printf("shader %s: parameter type \"%s\" not known\n", shader->name, token);
if (!shader->programhandle)
{
@ -681,6 +685,8 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
{
switch(parmtype)
{
case SP_BAD:
break;
case SP_TEXTURE:
case SP_CVARI:
GLSlang_SetUniform1i(uniformloc, specialint);
@ -2077,11 +2083,98 @@ void Shader_RunCinematic (void)
void Shader_DefaultBSP(char *shortname, shader_t *s, void *args)
{
texnums_t *tn = args;
shaderpass_t *pass;
int bumptex;
extern cvar_t gl_bump;
if (*shortname == '*' && tn)
{
extern int waterprogram;
extern int waterprogram_time;
if (waterprogram)
{
//quake1 water
pass = &s->passes[s->numpasses++];
pass->flags = SHADER_PASS_DEPTHWRITE|SHADER_PASS_NOCOLORARRAY;
pass->tcgen = TC_GEN_BASE;
pass->anim_frames[0] = tn->base;
pass->depthfunc = GL_LEQUAL;
pass->blendmode = GL_MODULATE;
pass->alphagen = ALPHA_GEN_IDENTITY;
pass->rgbgen = RGB_GEN_IDENTITY;
pass->numMergedPasses = 1;
pass->flush = R_RenderMeshProgram;
s->programhandle = waterprogram;
s->numprogparams = 0;
s->progparm[s->numprogparams].handle = waterprogram_time;
s->progparm[s->numprogparams].type = SP_TIME;
s->numprogparams++;
s->numdeforms = 0;
s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT; //q1 surfaces are one sided - there are actually two of them
s->features = MF_STCOORDS;
s->sort = SHADER_SORT_OPAQUE;
s->registration_sequence = 1;//fizme: registration_sequence;
return;
}
}
if (!strncmp(shortname, "sky", 3) && tn)
{
extern int skyprogram;
extern int skyprogram_time;
extern int skyprogram_eyepos;
if (skyprogram)
{
//quake1 sky
pass = &s->passes[s->numpasses++];
pass->flags = SHADER_PASS_DEPTHWRITE|SHADER_PASS_NOCOLORARRAY;
pass->tcgen = TC_GEN_BASE;
pass->anim_frames[0] = tn->base;
pass->depthfunc = GL_LEQUAL;
pass->blendmode = GL_MODULATE;
pass->alphagen = ALPHA_GEN_IDENTITY;
pass->rgbgen = RGB_GEN_IDENTITY;
pass->numMergedPasses = 2;
pass->flush = R_RenderMeshProgram;
pass = &s->passes[s->numpasses++];
pass->flags = SHADER_PASS_NOCOLORARRAY;
pass->tcgen = TC_GEN_BASE;
pass->anim_frames[0] = tn->fullbright;
pass->depthfunc = GL_LEQUAL;
pass->blendmode = GL_MODULATE;
pass->alphagen = ALPHA_GEN_IDENTITY;
pass->rgbgen = RGB_GEN_IDENTITY;
s->programhandle = skyprogram;
s->numprogparams = 0;
s->progparm[s->numprogparams].handle = skyprogram_time;
s->progparm[s->numprogparams].type = SP_TIME;
s->numprogparams++;
s->progparm[s->numprogparams].handle = skyprogram_eyepos;
s->progparm[s->numprogparams].type = SP_EYEPOS;
s->numprogparams++;
s->numdeforms = 0;
s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT; //q1 surfaces are one sided - there are actually two of them
s->features = MF_STCOORDS;
s->sort = SHADER_SORT_OPAQUE;
s->registration_sequence = 1;//fizme: registration_sequence;
return;
}
}
if (gl_config.arb_texture_env_dot3)
{
if (gl_bump.value)

View file

@ -61,12 +61,12 @@ extern cvar_t r_fastsky;
extern cvar_t r_fastskycolour;
static char defaultskybox[MAX_QPATH];
static int skyprogram;
static int skyprogram_time;
static int skyprogram_eyepos;
/*static*/ int skyprogram;
/*static*/ int skyprogram_time;
/*static*/ int skyprogram_eyepos;
static int waterprogram;
static int waterprogram_time;
/*static*/ int waterprogram;
/*static*/ int waterprogram_time;
int skyboxtex[6];
static vec3_t glskycolor;

View file

@ -433,6 +433,7 @@ typedef struct glRect_s {
} glRect_t;
typedef unsigned char stmap;
typedef struct {
mesh_t *meshchain;
qboolean modified;
qboolean deluxmodified;
glRect_t rectchange;

View file

@ -204,6 +204,10 @@ typedef struct {
SP_TIME,
SP_EYEPOS,
SP_LIGHTRADIUS,
SP_LIGHTCOLOUR,
SP_LIGHTPOSITION,
//things that are set immediatly
SP_FIRSTIMMEDIATE, //never set
SP_CVARI,

View file

@ -7121,6 +7121,7 @@ void PF_sv_particleeffectnum(progfuncs_t *prinst, struct globalvars_s *pr_global
//void(float effectnum, entity ent, vector start, vector end) trailparticles (EXT_CSQC),
void PF_sv_trailparticles(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
#ifdef PEXT_CSQC
#pragma message("PF_sv_trailparticles: first two parameters differ from dp, but comply with spec")
int efnum = G_FLOAT(OFS_PARM0);
int ednum = G_EDICTNUM(prinst, OFS_PARM1);
@ -7148,10 +7149,12 @@ void PF_sv_trailparticles(progfuncs_t *prinst, struct globalvars_s *pr_globals)
MSG_WriteCoord(&sv.nqmulticast, end[2]);
SV_MulticastProtExt(start, MULTICAST_PHS, ~0, PEXT_CSQC, 0);
#endif
}
//void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
void PF_sv_pointparticles(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
#ifdef PEXT_CSQC
int efnum = G_FLOAT(OFS_PARM0);
float *org = G_VECTOR(OFS_PARM1);
float *vel = G_VECTOR(OFS_PARM2);
@ -7197,6 +7200,7 @@ void PF_sv_pointparticles(progfuncs_t *prinst, struct globalvars_s *pr_globals)
MSG_WriteShort(&sv.nqmulticast, count);
}
SV_MulticastProtExt(org, MULTICAST_PHS, ~0, PEXT_CSQC, 0);
#endif
}

View file

@ -1517,6 +1517,7 @@ void SV_UpdateClientStats (client_t *client, int pnum)
}
else
{
#ifdef PEXT_CSQC
if ((client->fteprotocolextensions & PEXT_CSQC) && (sv.csqcchecksum || progstype == PROG_H2))
{
if (statsf[i] && statsf[i] - (float)(int)statsf[i] == 0)
@ -1564,7 +1565,9 @@ void SV_UpdateClientStats (client_t *client, int pnum)
}
}
}
else if (!statsi[i])
else
#endif
if (!statsi[i])
statsi[i] = statsf[i];
if (statsi[i] != client->statsi[i])
{