a big change with a little description...
authorlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 26 Apr 2001 05:38:37 +0000 (05:38 +0000)
committerlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 26 Apr 2001 05:38:37 +0000 (05:38 +0000)
rearranged client entity_t structure
redesigned entity update system (same protocol)
added support for split entity updates in the future for rate capping
glow trails and view relative entities should work now (untested)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@193 d7cf8633-e32d-0410-b094-e92efae38249

26 files changed:
bspfile.h
cl_effects.c
cl_input.c
cl_main.c
cl_parse.c
cl_tent.c
client.h
gl_refrag.c
gl_rmain.c
gl_rmisc.c
gl_rsurf.c
mathlib.c
mathlib.h
model_alias.c
pr_cmds.c
protocol.h
quakedef.h
r_light.c
r_part.c
r_sprites.c
render.h
sbar.c
sv_main.c
sv_move.c
transform.c
view.c

index 626c74e44569269b981a4a30a4ca4c6c5e7156c7..7c8d489aa31b2fa1621964d167d20f9a919c8baf 100644 (file)
--- a/bspfile.h
+++ b/bspfile.h
@@ -308,7 +308,7 @@ typedef struct
        epair_t         *epairs;
 } entity_t;
 
-extern int                     num_entities;
+//extern       int                     num_entities;
 extern entity_t        entities[MAX_MAP_ENTITIES];
 
 void   ParseEntities (void);
index 01bea5c92ec2d71ba4e4c14ed7fa506f37964d27..d1973b8ed1fd7add0dbe0fefa1923c8c47fc08f0 100644 (file)
@@ -118,21 +118,21 @@ void CL_DoEffects()
                        vis = CL_NewTempEntity();
                        if (!vis)
                                continue;
-                       VectorCopy(e->origin, vis->origin);
-                       vis->lerp_model = vis->model = cl.model_precache[e->modelindex];
-                       vis->frame1 = e->frame;
-                       vis->frame2 = e->frame + 1;
-                       if (vis->frame2 >= e->endframe)
-                               vis->frame2 = -1; // disappear
-                       vis->frame = vis->frame2;
-                       vis->framelerp = frame - vis->frame1;
-                       vis->frame1start = e->frame1start;
-                       vis->frame2start = e->frame2start;
-                       vis->lerp_starttime = -1;
-                       vis->colormap = -1; // no special coloring
-                       vis->scale = 1;
-                       vis->alpha = 1;
-                       vis->colormod[0] = vis->colormod[1] = vis->colormod[2] = 1;
+                       VectorCopy(e->origin, vis->render.origin);
+                       vis->render.lerp_model = vis->render.model = cl.model_precache[e->modelindex];
+                       vis->render.frame1 = e->frame;
+                       vis->render.frame2 = e->frame + 1;
+                       if (vis->render.frame2 >= e->endframe)
+                               vis->render.frame2 = -1; // disappear
+                       vis->render.frame = vis->render.frame2;
+                       vis->render.framelerp = frame - vis->render.frame1;
+                       vis->render.frame1start = e->frame1start;
+                       vis->render.frame2start = e->frame2start;
+                       vis->render.lerp_starttime = -1;
+                       vis->render.colormap = -1; // no special coloring
+                       vis->render.scale = 1;
+                       vis->render.alpha = 1;
+                       vis->render.colormod[0] = vis->render.colormod[1] = vis->render.colormod[2] = 1;
                }
        }
 }
index 21f084ff820047266da4dffe4f9ec72a314f2715..890687344bc661d368fe5d60c2c7c0decf6c440f 100644 (file)
@@ -261,7 +261,7 @@ void CL_AdjustAngles (void)
        {
                cl.viewangles[YAW] -= speed*cl_yawspeed.value*CL_KeyState (&in_right);
                cl.viewangles[YAW] += speed*cl_yawspeed.value*CL_KeyState (&in_left);
-               cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]);
+               cl.viewangles[YAW] = ANGLEMOD(cl.viewangles[YAW]);
        }
        if (in_klook.state & 1)
        {
index 40b42ebbec1fd21a6828cc516bfb8629c2fb88e2..e0db84a6e38ab4866776ef8590bfd34f5775dd29 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -82,11 +82,11 @@ void CL_ClearState (void)
        // LordHavoc: have to set up the baseline info for alpha and other stuff
        for (i = 0;i < MAX_EDICTS;i++)
        {
-               cl_entities[i].baseline.alpha = 255;
-               cl_entities[i].baseline.scale = 16;
-               cl_entities[i].baseline.glowsize = 0;
-               cl_entities[i].baseline.glowcolor = 254;
-               cl_entities[i].baseline.colormod = 255;
+               cl_entities[i].state_baseline.alpha = 255;
+               cl_entities[i].state_baseline.scale = 16;
+               cl_entities[i].state_baseline.glowsize = 0;
+               cl_entities[i].state_baseline.glowcolor = 254;
+               cl_entities[i].state_baseline.colormod = 255;
        }
 
 //
@@ -267,15 +267,15 @@ void CL_PrintEntities_f (void)
        entity_t        *ent;
        int                     i;
        
-       for (i=0,ent=cl_entities ; i<cl.num_entities ; i++,ent++)
+       for (i = 0, ent = cl_entities;i < MAX_EDICTS /*cl.num_entities*/;i++, ent++)
        {
-               Con_Printf ("%3i:",i);
-               if (!ent->model)
+               Con_Printf ("%3i:", i);
+               if (!ent->render.model)
                {
                        Con_Printf ("EMPTY\n");
                        continue;
                }
-               Con_Printf ("%s:%2i  (%5.1f,%5.1f,%5.1f) [%5.1f %5.1f %5.1f]\n", ent->model->name, ent->frame, ent->origin[0], ent->origin[1], ent->origin[2], ent->angles[0], ent->angles[1], ent->angles[2]);
+               Con_Printf ("%s:%2i  (%5.1f,%5.1f,%5.1f) [%5.1f %5.1f %5.1f]\n", ent->render.model->name, ent->render.frame, ent->render.origin[0], ent->render.origin[1], ent->render.origin[2], ent->render.angles[0], ent->render.angles[1], ent->render.angles[2]);
        }
 }
 
@@ -407,6 +407,26 @@ float      CL_LerpPoint (void)
        return frac;
 }
 
+float CL_EntityLerpPoint (entity_t *ent)
+{
+       float   f;
+
+       if (cl_nolerp.value || cls.timedemo || (sv.active && svs.maxclients == 1))
+               return 1;
+
+       f = ent->state_current.time - ent->state_previous.time;
+//     Con_Printf(" %g-%g=%g", ent->state_current.time, ent->state_previous.time, f);
+
+       if (f <= 0)
+               return 1;
+       if (f >= 0.1)
+               f = 0.1;
+
+//     Con_Printf(" %g-%g/%g=%f", cl.time, ent->state_previous.time, f, (cl.time - ent->state_previous.time) / f);
+       f = (cl.time - ent->state_previous.time) / f;
+       return bound(0, f, 1);
+}
+
 
 /*
 ===============
@@ -421,6 +441,7 @@ void CL_RelinkEntities (void)
        float           frac, f, d;
        vec3_t          delta;
        float           bobjrotate;
+//     float           bobjoffset;
        vec3_t          oldorg;
 
 // determine partial update time       
@@ -431,13 +452,13 @@ void CL_RelinkEntities (void)
 //
 // interpolate player info
 //
-       for (i=0 ; i<3 ; i++)
+       for (i = 0;i < 3;i++)
                cl.velocity[i] = cl.mvelocity[1][i] + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]);
 
        if (cls.demoplayback)
        {
        // interpolate the angles       
-               for (j=0 ; j<3 ; j++)
+               for (j = 0;j < 3;j++)
                {
                        d = cl.mviewangles[0][j] - cl.mviewangles[1][j];
                        if (d > 180)
@@ -448,152 +469,180 @@ void CL_RelinkEntities (void)
                }
        }
        
-       bobjrotate = anglemod(100*cl.time);
+       bobjrotate = ANGLEMOD(100*cl.time);
+//     bobjoffset = cos(180 * cl.time * M_PI / 180) * 4.0f + 4.0f;
        
 // start on the entity after the world
-       for (i=1,ent=cl_entities+1 ; i<cl.num_entities ; i++,ent++)
+       for (i = 1, ent = cl_entities + 1;i < MAX_EDICTS /*cl.num_entities*/;i++, ent++)
        {
-               if (!ent->model)
-               {       // empty slot
-//                     if (ent->forcelink)
-//                             R_RemoveEfrags (ent);   // just became empty
+               // if the object wasn't included in the latest packet, remove it
+               if (!ent->state_current.modelindex)
                        continue;
-               }
-
-// if the object wasn't included in the last packet, remove it
-               if (ent->msgtime != cl.mtime[0])
-               {
-                       ent->model = NULL;
-                       // LordHavoc: free on the same frame, not the next
-//                     if (ent->forcelink)
-//                             R_RemoveEfrags (ent);   // just became empty
-                       continue;
-               }
 
-               VectorCopy (ent->origin, oldorg);
+               VectorCopy (ent->render.origin, oldorg);
 
-               if (ent->forcelink)
-               {       // the entity was not updated in the last message
-                       // so move to the final spot
-                       VectorCopy (ent->msg_origins[0], ent->origin);
-                       VectorCopy (ent->msg_angles[0], ent->angles);
+               if (!ent->state_previous.modelindex)
+               {
+                       // only one state available
+                       VectorCopy (ent->state_current.origin, ent->render.origin);
+                       VectorCopy (ent->state_current.angles, ent->render.angles);
+//                     Con_Printf(" %i", i);
                }
                else
-               {       // if the delta is large, assume a teleport and don't lerp
-                       f = frac;
-                       for (j = 0;j < 3;j++)
+               {
+                       // if the delta is large, assume a teleport and don't lerp
+                       f = CL_EntityLerpPoint(ent);
+                       if (f < 1)
                        {
-                               delta[j] = ent->msg_origins[0][j] - ent->msg_origins[1][j];
-                               // LordHavoc: increased lerp tolerance from 100 to 200
-                               if (delta[j] > 200 || delta[j] < -200)
-                                       f = 1;          // assume a teleportation, not a motion
+                               for (j = 0;j < 3;j++)
+                               {
+                                       delta[j] = ent->state_current.origin[j] - ent->state_previous.origin[j];
+                                       // LordHavoc: increased lerp tolerance from 100 to 200
+                                       if (delta[j] > 200 || delta[j] < -200)
+                                               f = 1;
+                               }
                        }
-
-               // interpolate the origin and angles
-                       for (j = 0;j < 3;j++)
+                       if (f >= 1)
                        {
-                               ent->origin[j] = ent->msg_origins[1][j] + f*delta[j];
-
-                               d = ent->msg_angles[0][j] - ent->msg_angles[1][j];
-                               if (d > 180)
-                                       d -= 360;
-                               else if (d < -180)
-                                       d += 360;
-                               ent->angles[j] = ent->msg_angles[1][j] + f*d;
+                               // no interpolation
+                               VectorCopy (ent->state_current.origin, ent->render.origin);
+                               VectorCopy (ent->state_current.angles, ent->render.angles);
+                       }
+                       else
+                       {
+                               // interpolate the origin and angles
+                               for (j = 0;j < 3;j++)
+                               {
+                                       ent->render.origin[j] = ent->state_previous.origin[j] + f*delta[j];
+
+                                       d = ent->state_current.angles[j] - ent->state_previous.angles[j];
+                                       if (d > 180)
+                                               d -= 360;
+                                       else if (d < -180)
+                                               d += 360;
+                                       ent->render.angles[j] = ent->state_previous.angles[j] + f*d;
+                               }
                        }
-                       
                }
 
-               if (ent->effects & EF_BRIGHTFIELD)
-                       R_EntityParticles (ent);
-               if (ent->effects & EF_MUZZLEFLASH)
+               ent->render.flags = ent->state_current.flags;
+               ent->render.effects = ent->state_current.effects;
+               ent->render.model = cl.model_precache[ent->state_current.modelindex];
+               ent->render.frame = ent->state_current.frame;
+               if (cl.scores == NULL || !ent->state_current.colormap)
+                       ent->render.colormap = -1; // no special coloring
+               else
+                       ent->render.colormap = cl.scores[ent->state_current.colormap - 1].colors; // color it
+               ent->render.skinnum = ent->state_current.skin;
+               ent->render.alpha = ent->state_current.alpha * (1.0f / 255.0f); // FIXME: interpolate?
+               ent->render.scale = ent->state_current.scale * (1.0f / 16.0f); // FIXME: interpolate?
+               ent->render.glowsize = ent->state_current.glowsize * 4.0f; // FIXME: interpolate?
+               ent->render.glowcolor = ent->state_current.glowcolor;
+               ent->render.colormod[0] = (float) ((ent->state_current.colormod >> 5) & 7) * (1.0f / 7.0f);
+               ent->render.colormod[1] = (float) ((ent->state_current.colormod >> 2) & 7) * (1.0f / 7.0f);
+               ent->render.colormod[2] = (float) (ent->state_current.colormod & 3) * (1.0f / 3.0f);
+
+               // LordHavoc: if the entity has no effects, don't check each
+               if (ent->render.effects)
                {
-                       vec3_t v;
+                       if (ent->render.effects & EF_BRIGHTFIELD)
+                               R_EntityParticles (ent);
+                       if (ent->render.effects & EF_MUZZLEFLASH)
+                       {
+                               vec3_t v;
 
-                       AngleVectors (ent->angles, v, NULL, NULL);
+                               AngleVectors (ent->render.angles, v, NULL, NULL);
 
-                       v[0] = v[0] * 18 + ent->origin[0];
-                       v[1] = v[1] * 18 + ent->origin[1];
-                       v[2] = v[2] * 18 + ent->origin[2] + 16;
+                               v[0] = v[0] * 18 + ent->render.origin[0];
+                               v[1] = v[1] * 18 + ent->render.origin[1];
+                               v[2] = v[2] * 18 + ent->render.origin[2] + 16;
 
-                       CL_AllocDlight (ent, v, 100, 1, 1, 1, 0, 0.1);
-               }
-               if (ent->effects & EF_BRIGHTLIGHT)
-                       CL_AllocDlight (ent, ent->origin, 400, 1, 1, 1, 0, 0);
-               if (ent->effects & EF_DIMLIGHT)
-                       CL_AllocDlight (ent, ent->origin, 200, 1, 1, 1, 0, 0);
-               // LordHavoc: added EF_RED and EF_BLUE
-               if (ent->effects & EF_RED) // red
-               {                       
-                       if (ent->effects & EF_BLUE) // magenta
-                               CL_AllocDlight (ent, ent->origin, 200, 1.0f, 0.2f, 1.0f, 0, 0);
-                       else // red
-                               CL_AllocDlight (ent, ent->origin, 200, 1.0f, 0.1f, 0.1f, 0, 0);
-               }
-               else if (ent->effects & EF_BLUE) // blue
-                       CL_AllocDlight (ent, ent->origin, 200, 0.1f, 0.1f, 1.0f, 0, 0);
-               else if (ent->effects & EF_FLAME)
-               {
-                       if (ent->model)
+                               CL_AllocDlight (ent, v, 100, 1, 1, 1, 0, 0.1);
+                       }
+                       if (ent->render.effects & EF_BRIGHTLIGHT)
+                               CL_AllocDlight (ent, ent->render.origin, 400, 1, 1, 1, 0, 0);
+                       if (ent->render.effects & EF_DIMLIGHT)
+                               CL_AllocDlight (ent, ent->render.origin, 200, 1, 1, 1, 0, 0);
+                       // LordHavoc: added EF_RED and EF_BLUE
+                       if (ent->render.effects & EF_RED) // red
+                       {                       
+                               if (ent->render.effects & EF_BLUE) // magenta
+                                       CL_AllocDlight (ent, ent->render.origin, 200, 1.0f, 0.2f, 1.0f, 0, 0);
+                               else // red
+                                       CL_AllocDlight (ent, ent->render.origin, 200, 1.0f, 0.1f, 0.1f, 0, 0);
+                       }
+                       else if (ent->render.effects & EF_BLUE) // blue
+                               CL_AllocDlight (ent, ent->render.origin, 200, 0.1f, 0.1f, 1.0f, 0, 0);
+                       else if (ent->render.effects & EF_FLAME)
                        {
-                               vec3_t mins, maxs;
-                               int temp;
-                               VectorAdd(ent->origin, ent->model->mins, mins);
-                               VectorAdd(ent->origin, ent->model->maxs, maxs);
-                               // how many flames to make
-                               temp = (int) (cl.time * 300) - (int) (cl.oldtime * 300);
-                               R_FlameCube(mins, maxs, temp);
+                               if (ent->render.model)
+                               {
+                                       vec3_t mins, maxs;
+                                       int temp;
+                                       VectorAdd(ent->render.origin, ent->render.model->mins, mins);
+                                       VectorAdd(ent->render.origin, ent->render.model->maxs, maxs);
+                                       // how many flames to make
+                                       temp = (int) (cl.time * 300) - (int) (cl.oldtime * 300);
+                                       R_FlameCube(mins, maxs, temp);
+                               }
+                               CL_AllocDlight (ent, ent->render.origin, lhrandom(200, 250), 1.0f, 0.7f, 0.3f, 0, 0);
                        }
-                       CL_AllocDlight (ent, ent->origin, lhrandom(200, 250), 1.0f, 0.7f, 0.3f, 0, 0);
                }
 
-               if (ent->model->flags) // LordHavoc: if the model has no flags, don't check each
+               // LordHavoc: if the model has no flags, don't check each
+               if (ent->render.model && ent->render.model->flags)
                {
-               // rotate binary objects locally
-                       if (ent->model->flags & EF_ROTATE)
-                               ent->angles[1] = bobjrotate;
-                       if (ent->model->flags & EF_GIB)
-                               R_RocketTrail (oldorg, ent->origin, 2, ent);
-                       else if (ent->model->flags & EF_ZOMGIB)
-                               R_RocketTrail (oldorg, ent->origin, 4, ent);
-                       else if (ent->model->flags & EF_TRACER)
-                               R_RocketTrail (oldorg, ent->origin, 3, ent);
-                       else if (ent->model->flags & EF_TRACER2)
-                               R_RocketTrail (oldorg, ent->origin, 5, ent);
-                       else if (ent->model->flags & EF_ROCKET)
+                       if (ent->render.model->flags & EF_ROTATE)
                        {
-                               R_RocketTrail (oldorg, ent->origin, 0, ent);
-                               CL_AllocDlight (ent, ent->origin, 200, 1.0f, 0.8f, 0.4f, 0, 0);
+                               ent->render.angles[1] = bobjrotate;
+//                             ent->render.origin[2] += bobjoffset;
                        }
-                       else if (ent->model->flags & EF_GRENADE)
+                       // only do trails if present in the previous frame as well
+                       if (ent->state_previous.modelindex)
                        {
-                               if (ent->alpha == -1) // LordHavoc: Nehahra dem compatibility
-                                       R_RocketTrail (oldorg, ent->origin, 7, ent);
-                               else
-                                       R_RocketTrail (oldorg, ent->origin, 1, ent);
+                               if (ent->render.model->flags & EF_GIB)
+                                       R_RocketTrail (oldorg, ent->render.origin, 2, ent);
+                               else if (ent->render.model->flags & EF_ZOMGIB)
+                                       R_RocketTrail (oldorg, ent->render.origin, 4, ent);
+                               else if (ent->render.model->flags & EF_TRACER)
+                                       R_RocketTrail (oldorg, ent->render.origin, 3, ent);
+                               else if (ent->render.model->flags & EF_TRACER2)
+                                       R_RocketTrail (oldorg, ent->render.origin, 5, ent);
+                               else if (ent->render.model->flags & EF_ROCKET)
+                               {
+                                       R_RocketTrail (oldorg, ent->render.origin, 0, ent);
+                                       CL_AllocDlight (ent, ent->render.origin, 200, 1.0f, 0.8f, 0.4f, 0, 0);
+                               }
+                               else if (ent->render.model->flags & EF_GRENADE)
+                               {
+                                       if (ent->render.alpha == -1) // LordHavoc: Nehahra dem compatibility
+                                               R_RocketTrail (oldorg, ent->render.origin, 7, ent);
+                                       else
+                                               R_RocketTrail (oldorg, ent->render.origin, 1, ent);
+                               }
+                               else if (ent->render.model->flags & EF_TRACER3)
+                                       R_RocketTrail (oldorg, ent->render.origin, 6, ent);
                        }
-                       else if (ent->model->flags & EF_TRACER3)
-                               R_RocketTrail (oldorg, ent->origin, 6, ent);
                }
-               if (ent->glowsize) // LordHavoc: customizable glow
+               if (ent->render.glowsize) // LordHavoc: customizable glow
                {
-                       byte *tempcolor = (byte *)&d_8to24table[ent->glowcolor];
-                       CL_AllocDlight (ent, ent->origin, ent->glowsize, tempcolor[0]*(1.0/255.0), tempcolor[1]*(1.0/255.0), tempcolor[2]*(1.0/255.0), 0, 0);
+                       byte *tempcolor = (byte *)&d_8to24table[ent->render.glowcolor];
+                       CL_AllocDlight (ent, ent->render.origin, ent->render.glowsize, tempcolor[0]*(1.0/255.0), tempcolor[1]*(1.0/255.0), tempcolor[2]*(1.0/255.0), 0, 0);
                }
-               if (ent->glowtrail) // LordHavoc: customizable glow and trail
-                       R_RocketTrail2 (oldorg, ent->origin, ent->glowcolor, ent);
-
-               ent->forcelink = false;
+               if (ent->render.flags & RENDER_GLOWTRAIL) // LordHavoc: customizable glow and trail
+                       R_RocketTrail2 (oldorg, ent->render.origin, ent->render.glowcolor, ent);
 
                if (i == cl.viewentity && !chase_active.value)
                        continue;
 
-// LordHavoc: enabled EF_NODRAW
-               if (!ent->model || ent->effects & EF_NODRAW)
+               if (ent->render.model == NULL)
+                       continue;
+               if (ent->render.effects & EF_NODRAW)
                        continue;
                if (cl_numvisedicts < MAX_VISEDICTS)
                        cl_visedicts[cl_numvisedicts++] = ent;
        }
+//     Con_Printf("\n");
 }
 
 
index d856ce119268b9fbeb21e7262595e7b80583aea6..942e2b34753195fcd4760b840ff0f4b69696e3a1 100644 (file)
@@ -100,16 +100,21 @@ This error checks and tracks the total number of entities
 */
 entity_t       *CL_EntityNum (int num)
 {
+       /*
        if (num >= cl.num_entities)
        {
                if (num >= MAX_EDICTS)
                        Host_Error ("CL_EntityNum: %i is an invalid number",num);
-               while (cl.num_entities<=num)
-               {
-                       cl_entities[cl.num_entities].colormap = -1; // no special coloring
-                       cl.num_entities++;
-               }
+               cl.num_entities = num;
+//             while (cl.num_entities <= num)
+//             {
+//                     cl_entities[cl.num_entities].colormap = -1; // no special coloring
+//                     cl.num_entities++;
+//             }
        }
+       */
+       if (num >= MAX_EDICTS)
+               Host_Error ("CL_EntityNum: %i is an invalid number",num);
                
        return &cl_entities[num];
 }
@@ -441,7 +446,7 @@ void CL_ParseServerInfo (void)
 
 
 // local state
-       cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
+       cl_entities[0].render.model = cl.worldmodel = cl.model_precache[1];
        
        R_NewMap ();
 
@@ -450,6 +455,24 @@ void CL_ParseServerInfo (void)
        noclip_anglehack = false;               // noclip is turned off at start        
 }
 
+void CL_ValidateState(entity_state_t *s)
+{
+       model_t *model;
+
+       if (s->modelindex >= MAX_MODELS)
+               Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
+
+       // colormap is client index + 1
+       if (s->colormap > cl.maxclients)
+               Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
+
+       model = cl.model_precache[s->modelindex];
+       if (model && s->frame >= model->numframes)
+       {
+               Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
+               s->frame = 0;
+       }
+}
 
 /*
 ==================
@@ -460,13 +483,11 @@ If an entities model or origin changes from frame to frame, it must be
 relinked.  Other attributes can change without relinking.
 ==================
 */
+byte entkill[MAX_EDICTS];
 void CL_ParseUpdate (int bits)
 {
-       int                     i, modnum, num, alpha, scale, glowsize, glowcolor, colormod, frame;
-       model_t         *model;
-       qboolean        forcelink;
-       entity_t        *ent;
-       entity_state_t *baseline;
+       int num, deltadie;
+       entity_t *ent;
 
        if (cls.signon == SIGNONS - 1)
        {       // first update is the final signon stage
@@ -476,7 +497,7 @@ void CL_ParseUpdate (int bits)
 
        if (bits & U_MOREBITS)
                bits |= (MSG_ReadByte()<<8);
-       if (bits & U_EXTEND1 && !Nehahrademcompatibility)
+       if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
        {
                bits |= MSG_ReadByte() << 16;
                if (bits & U_EXTEND2)
@@ -484,141 +505,125 @@ void CL_ParseUpdate (int bits)
        }
 
        if (bits & U_LONGENTITY)        
-               num = MSG_ReadShort ();
+               num = (unsigned) MSG_ReadShort ();
        else
-               num = MSG_ReadByte ();
+               num = (unsigned) MSG_ReadByte ();
 
-       ent = CL_EntityNum (num);
+       if (num >= MAX_EDICTS)
+               Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
+       if (num < 1)
+               Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
 
-       forcelink = ent->msgtime != cl.mtime[1]; // no previous frame to lerp from
+       // mark as visible (no kill)
+       entkill[num] = 0;
 
-       ent->msgtime = cl.mtime[0];
-       
-       // LordHavoc: new protocol stuff
-       baseline = &ent->baseline;
-       if (bits & U_DELTA)
-               baseline = &ent->deltabaseline;
+       ent = CL_EntityNum (num);
 
-       if (forcelink)
+       ent->state_previous = ent->state_current;
+       deltadie = false;
+       if (bits & U_DELTA)
        {
-               ent->deltabaseline.origin[0] = ent->deltabaseline.origin[1] = ent->deltabaseline.origin[2] = 0;
-               ent->deltabaseline.angles[0] = ent->deltabaseline.angles[1] = ent->deltabaseline.angles[2] = 0;
-               ent->deltabaseline.effects = 0;
-               ent->deltabaseline.modelindex = 0;
-               ent->deltabaseline.frame = 0;
-               ent->deltabaseline.colormap = 0;
-               ent->deltabaseline.skin = 0;
-               ent->deltabaseline.alpha = 255;
-               ent->deltabaseline.scale = 16;
-               ent->deltabaseline.glowsize = 0;
-               ent->deltabaseline.glowcolor = 254;
-               ent->deltabaseline.colormod = 255;
+               if (!ent->state_current.modelindex)
+                       deltadie = true; // was not present in previous frame, leave hidden until next full update
        }
-
-       modnum = bits & U_MODEL ? MSG_ReadByte() : baseline->modelindex;
-       if (modnum >= MAX_MODELS)
-               Host_Error ("CL_ParseModel: bad modnum");
-
-       frame = ((bits & U_FRAME) ? MSG_ReadByte() : (baseline->frame & 0xFF));
-
-       i = bits & U_COLORMAP ? MSG_ReadByte() : baseline->colormap;
-       ent->deltabaseline.colormap = i;
-       if (!i)
-               ent->colormap = -1; // no special coloring
        else
+               ent->state_current = ent->state_baseline;
+
+       ent->state_current.time = cl.mtime[0];
+
+       ent->state_current.flags = 0;
+       if (bits & U_MODEL)             ent->state_current.modelindex = (ent->state_current.modelindex & 0xFF00) | MSG_ReadByte();
+       if (bits & U_FRAME)             ent->state_current.frame = (ent->state_current.frame & 0xFF00) | MSG_ReadByte();
+       if (bits & U_COLORMAP)  ent->state_current.colormap = MSG_ReadByte();
+       if (bits & U_SKIN)              ent->state_current.skin = MSG_ReadByte();
+       if (bits & U_EFFECTS)   ent->state_current.effects = (ent->state_current.effects & 0xFF00) | MSG_ReadByte();
+       if (bits & U_ORIGIN1)   ent->state_current.origin[0] = MSG_ReadCoord();
+       if (bits & U_ANGLE1)    ent->state_current.angles[0] = MSG_ReadAngle();
+       if (bits & U_ORIGIN2)   ent->state_current.origin[1] = MSG_ReadCoord();
+       if (bits & U_ANGLE2)    ent->state_current.angles[1] = MSG_ReadAngle();
+       if (bits & U_ORIGIN3)   ent->state_current.origin[2] = MSG_ReadCoord();
+       if (bits & U_ANGLE3)    ent->state_current.angles[2] = MSG_ReadAngle();
+       if (bits & U_STEP)              ent->state_current.flags |= RENDER_STEP;
+       if (bits & U_ALPHA)             ent->state_current.alpha = MSG_ReadByte();
+       if (bits & U_SCALE)             ent->state_current.scale = MSG_ReadByte();
+       if (bits & U_EFFECTS2)  ent->state_current.effects = (ent->state_current.effects & 0x00FF) | (MSG_ReadByte() << 8);
+       if (bits & U_GLOWSIZE)  ent->state_current.glowsize = MSG_ReadByte();
+       if (bits & U_GLOWCOLOR) ent->state_current.glowcolor = MSG_ReadByte();
+       if (bits & U_GLOWTRAIL) ent->state_current.flags |= RENDER_GLOWTRAIL;
+       if (bits & U_COLORMOD)  ent->state_current.colormod = MSG_ReadByte();
+       if (bits & U_FRAME2)    ent->state_current.frame = (ent->state_current.frame & 0x00FF) | (MSG_ReadByte() << 8);
+       if (bits & U_MODEL2)    ent->state_current.modelindex = (ent->state_current.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
+       if (bits & U_VIEWMODEL) ent->state_current.flags |= RENDER_VIEWMODEL;
+
+       // LordHavoc: to allow playback of the Nehahra movie
+       if (Nehahrademcompatibility && (bits & U_EXTEND1))
        {
-               if (i > cl.maxclients)
-                       Host_Error ("i >= cl.maxclients");
-               ent->colormap = cl.scores[i-1].colors; // color it
-       }
-
-       ent->deltabaseline.skin = ent->skinnum = bits & U_SKIN ? MSG_ReadByte() : baseline->skin;
-
-       ent->effects = ((bits & U_EFFECTS) ? MSG_ReadByte() : (baseline->effects & 0xFF));
-
-// shift the known values for interpolation
-       VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
-       VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
-       VectorCopy (baseline->origin, ent->msg_origins[0]);
-       VectorCopy (baseline->angles, ent->msg_angles[0]);
-
-       if (bits & U_ORIGIN1) ent->msg_origins[0][0] = MSG_ReadCoord ();
-       if (bits & U_ANGLE1) ent->msg_angles[0][0] = MSG_ReadAngle();
-       if (bits & U_ORIGIN2) ent->msg_origins[0][1] = MSG_ReadCoord ();
-       if (bits & U_ANGLE2) ent->msg_angles[0][1] = MSG_ReadAngle();
-       if (bits & U_ORIGIN3) ent->msg_origins[0][2] = MSG_ReadCoord ();
-       if (bits & U_ANGLE3) ent->msg_angles[0][2] = MSG_ReadAngle();
-
-       VectorCopy(ent->msg_origins[0], ent->deltabaseline.origin);
-       VectorCopy(ent->msg_angles[0], ent->deltabaseline.angles);
-
-       alpha = bits & U_ALPHA ? MSG_ReadByte() : baseline->alpha;
-       scale = bits & U_SCALE ? MSG_ReadByte() : baseline->scale;
-       ent->effects |= ((bits & U_EFFECTS2) ? (MSG_ReadByte() << 8) : (baseline->effects & 0xFF00));
-       glowsize = bits & U_GLOWSIZE ? MSG_ReadByte() : baseline->glowsize;
-       glowcolor = bits & U_GLOWCOLOR ? MSG_ReadByte() : baseline->glowcolor;
-       colormod = bits & U_COLORMOD ? MSG_ReadByte() : baseline->colormod;
-       modnum |= ((bits & U_MODEL2) ? (MSG_ReadByte() << 8) : (baseline->modelindex & 0xFF00));
-       frame |= ((bits & U_FRAME2) ? (MSG_ReadByte() << 8) : (baseline->frame & 0xFF00));
-
-       if (modnum >= MAX_MODELS)
-               Host_Error("modnum (%i) >= MAX_MODELS (%i)\n", modnum, MAX_MODELS);
-
-       model = cl.model_precache[modnum];
-       if (model != ent->model)
-       {
-               ent->model = model;
-       // automatic animation (torches, etc) can be either all together
-       // or randomized
-               if (model)
-                       ent->syncbase = model->synctype == ST_RAND ? (float)(rand()&0x7fff) / 0x7fff : 0.0;
+               // LordHavoc: evil format
+               int i = MSG_ReadFloat();
+               int j = MSG_ReadFloat() * 255.0f;
+               if (i == 2)
+               {
+                       if (MSG_ReadFloat())
+                               ent->state_current.effects |= EF_FULLBRIGHT;
+               }
+               if (j < 0)
+                       ent->state_current.alpha = 0;
+               else if (j == 0 || j >= 255)
+                       ent->state_current.alpha = 255;
                else
-                       forcelink = true;       // hack to make null model players work
+                       ent->state_current.alpha = j;
        }
 
-       ent->frame = frame;
-       if (model && (unsigned) frame >= model->numframes)
-               Con_DPrintf("CL_ParseUpdate: no such frame %i in \"%s\"\n", frame, model->name);
-
-       ent->deltabaseline.alpha = alpha;
-       ent->deltabaseline.scale = scale;
-       ent->deltabaseline.effects = ent->effects;
-       ent->deltabaseline.glowsize = glowsize;
-       ent->deltabaseline.glowcolor = glowcolor;
-       ent->deltabaseline.colormod = colormod;
-       ent->deltabaseline.modelindex = modnum;
-       ent->deltabaseline.frame = frame;
-       ent->alpha = (float) alpha * (1.0 / 255.0);
-       ent->scale = (float) scale * (1.0 / 16.0);
-       ent->glowsize = glowsize * 4.0;
-       ent->glowcolor = glowcolor;
-       ent->colormod[0] = (float) ((colormod >> 5) & 7) * (1.0 / 7.0);
-       ent->colormod[1] = (float) ((colormod >> 2) & 7) * (1.0 / 7.0);
-       ent->colormod[2] = (float) (colormod & 3) * (1.0 / 3.0);
-       if (bits & U_EXTEND1 && Nehahrademcompatibility) // LordHavoc: to allow playback of the Nehahra movie
+       if (deltadie)
        {
-               i = MSG_ReadFloat();
-               ent->alpha = MSG_ReadFloat();
-               if (i == 2 && MSG_ReadFloat() != 0.0)
-                       ent->effects |= EF_FULLBRIGHT;
-               if (ent->alpha == 0)
-                       ent->alpha = 1;
+               // hide the entity
+               ent->state_current.modelindex = 0;
        }
+       else
+       {
+               CL_ValidateState(&ent->state_current);
 
-       //if ( bits & U_NOLERP )
-       //      ent->forcelink = true;
-       //if (bits & U_STEP) // FIXME: implement clientside interpolation of monsters
-
-       if ( forcelink )
-       {       // didn't have an update last message
-               VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
-               VectorCopy (ent->msg_origins[0], ent->origin);
-               VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
-               VectorCopy (ent->msg_angles[0], ent->angles);
-               ent->forcelink = true;
+               /*
+               if (!ent->state_current.modelindex)
+               {
+                       if (bits & U_DELTA)
+                       {
+                               if (bits & U_MODEL)
+                                       Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i %i\n", num, ent->state_previous.modelindex, ent->state_current.modelindex);
+                               else
+                                       Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i\n", num, ent->state_previous.modelindex);
+                       }
+                       else
+                       {
+                               if (bits & U_MODEL)
+                                       Con_Printf("CL_ParseUpdate:       NULL model on %i: %i %i\n", num, ent->state_baseline.modelindex, ent->state_current.modelindex);
+                               else
+                                       Con_Printf("CL_ParseUpdate:       NULL model on %i: %i\n", num, ent->state_baseline.modelindex);
+                       }
+               }
+               */
        }
 }
 
+int entityupdatestart;
+void CL_EntityUpdateBegin(int start)
+{
+       if (start < 0 || start >= MAX_EDICTS)
+               Host_Error("CL_EntityUpdateBegin: start (%i) < 0 or >= MAX_EDICTS (%i)\n", start, MAX_EDICTS);
+       entityupdatestart = start;
+       memset(entkill, 1, MAX_EDICTS);
+}
+
+void CL_EntityUpdateEnd(int end)
+{
+       int i;
+       if (end < 0 || end > MAX_EDICTS)
+               Host_Error("CL_EntityUpdateEnd: end (%i) < 0 or > MAX_EDICTS (%i)\n", end, MAX_EDICTS);
+       for (i = entityupdatestart;i < end;i++)
+               if (entkill[i])
+                       cl_entities[i].state_current.modelindex = 0;
+}
+
 /*
 ==================
 CL_ParseBaseline
@@ -626,28 +631,29 @@ CL_ParseBaseline
 */
 void CL_ParseBaseline (entity_t *ent, int largemodelindex)
 {
-       int                     i;
+       int i;
 
+       memset(&ent->state_baseline, 0, sizeof(entity_state_t));
        if (largemodelindex)
-               ent->baseline.modelindex = (unsigned short) MSG_ReadShort ();
+               ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
        else
-               ent->baseline.modelindex = MSG_ReadByte ();
-       ent->baseline.frame = MSG_ReadByte ();
-       ent->baseline.colormap = MSG_ReadByte();
-       ent->baseline.skin = MSG_ReadByte();
-       for (i=0 ; i<3 ; i++)
+               ent->state_baseline.modelindex = MSG_ReadByte ();
+       ent->state_baseline.frame = MSG_ReadByte ();
+       ent->state_baseline.colormap = MSG_ReadByte();
+       ent->state_baseline.skin = MSG_ReadByte();
+       for (i = 0;i < 3;i++)
        {
-               ent->baseline.origin[i] = MSG_ReadCoord ();
-               ent->baseline.angles[i] = MSG_ReadAngle ();
+               ent->state_baseline.origin[i] = MSG_ReadCoord ();
+               ent->state_baseline.angles[i] = MSG_ReadAngle ();
        }
-       ent->baseline.alpha = 255;
-       ent->baseline.scale = 16;
-       ent->baseline.glowsize = 0;
-       ent->baseline.glowcolor = 254;
-       ent->baseline.colormod = 255;
-       
-       if (ent->baseline.modelindex >= MAX_MODELS)
-               Host_Error("CL_ParseBaseline: modelindex (%i) >= MAX_MODELS (%i)\n", ent->baseline.modelindex, MAX_MODELS);
+       ent->state_baseline.alpha = 255;
+       ent->state_baseline.scale = 16;
+       ent->state_baseline.glowsize = 0;
+       ent->state_baseline.glowcolor = 254;
+       ent->state_baseline.colormod = 255;
+       ent->state_previous = ent->state_current = ent->state_baseline;
+
+       CL_ValidateState(&ent->state_baseline);
 }
 
 
@@ -660,7 +666,7 @@ Server information pertaining to this client only
 */
 void CL_ParseClientdata (int bits)
 {
-       int             i, j;
+       int i, j;
 
        bits &= 0xFFFF;
        if (bits & SU_EXTEND1)
@@ -739,34 +745,31 @@ CL_ParseStatic
 void CL_ParseStatic (int largemodelindex)
 {
        entity_t *ent;
-       int             i;
                
-       i = cl.num_statics;
-       if (i >= MAX_STATIC_ENTITIES)
+       if (cl.num_statics >= MAX_STATIC_ENTITIES)
                Host_Error ("Too many static entities");
-       ent = &cl_static_entities[i];
-       cl.num_statics++;
+       ent = &cl_static_entities[cl.num_statics++];
        CL_ParseBaseline (ent, largemodelindex);
 
 // copy it to the current state
-       ent->model = cl.model_precache[ent->baseline.modelindex];
-       ent->frame = ent->frame1 = ent->frame2 = ent->baseline.frame;
-       ent->framelerp = 0;
-       ent->lerp_starttime = -1;
+       ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
+       ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
+       ent->render.framelerp = 0;
+       ent->render.lerp_starttime = -1;
        // make torchs play out of sync
-       ent->frame1start = ent->frame2start = -(rand() & 32767);
-       ent->colormap = -1; // no special coloring
-       ent->skinnum = ent->baseline.skin;
-       ent->effects = ent->baseline.effects;
-       ent->alpha = 1;
-       ent->scale = 1;
-       ent->alpha = 1;
-       ent->glowsize = 0;
-       ent->glowcolor = 254;
-       ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
-
-       VectorCopy (ent->baseline.origin, ent->origin);
-       VectorCopy (ent->baseline.angles, ent->angles); 
+       ent->render.frame1start = ent->render.frame2start = -(rand() & 32767);
+       ent->render.colormap = -1; // no special coloring
+       ent->render.skinnum = ent->state_baseline.skin;
+       ent->render.effects = ent->state_baseline.effects;
+       ent->render.alpha = 1;
+       ent->render.scale = 1;
+       ent->render.alpha = 1;
+       ent->render.glowsize = 0;
+       ent->render.glowcolor = 254;
+       ent->render.colormod[0] = ent->render.colormod[1] = ent->render.colormod[2] = 1;
+
+       VectorCopy (ent->state_baseline.origin, ent->render.origin);
+       VectorCopy (ent->state_baseline.angles, ent->render.angles);    
        R_AddEfrags (ent);
 }
 
@@ -832,7 +835,7 @@ CL_ParseServerMessage
 void CL_ParseServerMessage (void)
 {
        int                     cmd;
-       int                     i;
+       int                     i, updateend;
        byte            cmdlog[32];
        char            *cmdlogname[32], *temp;
        int                     cmdindex, cmdcount = 0;
@@ -856,6 +859,8 @@ void CL_ParseServerMessage (void)
 // parse the message
 //
        MSG_BeginReading ();
+
+       updateend = false;
        
        while (1)
        {
@@ -867,7 +872,7 @@ void CL_ParseServerMessage (void)
                if (cmd == -1)
                {
                        SHOWNET("END OF MESSAGE");
-                       return;         // end of message
+                       break;          // end of message
                }
 
                cmdindex = cmdcount & 31;
@@ -878,7 +883,7 @@ void CL_ParseServerMessage (void)
                if (cmd & 128)
                {
                        // LordHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer)
-                       temp = "svc_entity";
+                       temp = "entity";
                        cmdlogname[cmdindex] = temp;
                        SHOWNET("fast update");
                        CL_ParseUpdate (cmd&127);
@@ -926,6 +931,9 @@ void CL_ParseServerMessage (void)
                        break;
                        
                case svc_time:
+                       // handle old protocols which do not have entity update ranges
+                       CL_EntityUpdateBegin(0);
+                       updateend = true;
                        cl.mtime[1] = cl.mtime[0];
                        cl.mtime[0] = MSG_ReadFloat ();                 
                        break;
@@ -938,10 +946,7 @@ void CL_ParseServerMessage (void)
                case svc_version:
                        i = MSG_ReadLong ();
                        if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
-                       {
                                Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
-                               return;
-                       }
                        Nehahrademcompatibility = false;
                        if (i == 250)
                                Nehahrademcompatibility = true;
@@ -986,7 +991,7 @@ void CL_ParseServerMessage (void)
                case svc_lightstyle:
                        i = MSG_ReadByte ();
                        if (i >= MAX_LIGHTSTYLES)
-                               Host_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
+                               Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
                        strncpy (cl_lightstyle[i].map,  MSG_ReadString(), MAX_STYLESTRING - 1);
                        cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
                        cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
@@ -1131,7 +1136,19 @@ void CL_ParseServerMessage (void)
                case svc_showlmp:
                        SHOWLMP_decodeshow();
                        break;
+               case svc_entitiesbegin:
+                       // the beginning of an entity update range
+                       CL_EntityUpdateBegin((unsigned) MSG_ReadShort());
+                       break;
+               case svc_entitiesend:
+                       // the end of an entity update range
+                       CL_EntityUpdateEnd((unsigned) MSG_ReadShort());
+                       updateend = false;
+                       break;
                }
        }
+
+       if (updateend)
+               CL_EntityUpdateEnd(MAX_EDICTS);
 }
 
index 363ca591d70db5bf27a9381738dd36f311da8610..22b258bcdc0dce5c148029d765d3cc5d22138330 100644 (file)
--- a/cl_tent.c
+++ b/cl_tent.c
@@ -443,10 +443,10 @@ entity_t *CL_NewTempEntity (void)
        memset (ent, 0, sizeof(*ent));
        cl_visedicts[cl_numvisedicts++] = ent;
 
-       ent->colormap = -1; // no special coloring
-       ent->scale = 1;
-       ent->alpha = 1;
-       ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
+       ent->render.colormap = -1; // no special coloring
+       ent->render.scale = 1;
+       ent->render.alpha = 1;
+       ent->render.colormod[0] = ent->render.colormod[1] = ent->render.colormod[2] = 1;
        return ent;
 }
 
@@ -474,13 +474,11 @@ void CL_UpdateTEnts (void)
                if (!b->model || b->endtime < cl.time)
                        continue;
 
-       // if coming from the player, update the start position
+               // if coming from the player, update the start position
                if (b->entity == cl.viewentity)
-               {
-                       VectorCopy (cl_entities[cl.viewentity].origin, b->start);
-               }
+                       VectorCopy (cl_entities[cl.viewentity].render.origin, b->start);
 
-       // calculate pitch and yaw
+               // calculate pitch and yaw
                VectorSubtract (b->end, b->start, dist);
 
                if (dist[1] == 0 && dist[0] == 0)
@@ -503,7 +501,7 @@ void CL_UpdateTEnts (void)
                                pitch += 360;
                }
 
-       // add new entities for the lightning
+               // add new entities for the lightning
                VectorCopy (b->start, org);
                d = VectorNormalizeLength(dist);
                while (d > 0)
@@ -511,15 +509,15 @@ void CL_UpdateTEnts (void)
                        ent = CL_NewTempEntity ();
                        if (!ent)
                                return;
-                       VectorCopy (org, ent->origin);
-                       ent->model = b->model;
-                       ent->effects = EF_FULLBRIGHT;
-                       ent->angles[0] = pitch;
-                       ent->angles[1] = yaw;
-                       ent->angles[2] = rand()%360;
+                       VectorCopy (org, ent->render.origin);
+                       ent->render.model = b->model;
+                       ent->render.effects = EF_FULLBRIGHT;
+                       ent->render.angles[0] = pitch;
+                       ent->render.angles[1] = yaw;
+                       ent->render.angles[2] = rand()%360;
 
                        if (r_glowinglightning.value > 0)
-                               CL_AllocDlight(ent, ent->origin, lhrandom(100, 120), r_glowinglightning.value * 0.25f, r_glowinglightning.value * 0.25f, r_glowinglightning.value * 0.25f, 0, 0);
+                               CL_AllocDlight(ent, ent->render.origin, lhrandom(100, 120), r_glowinglightning.value * 0.25f, r_glowinglightning.value * 0.25f, r_glowinglightning.value * 0.25f, 0, 0);
 
                        VectorMA(org, 30, dist, org);
                        d -= 30;
index f7aa2af01e3519275146367beaf504606b280fc5..42845cda32982de39b055d1fc0d8c7c7bb33cba3 100644 (file)
--- a/client.h
+++ b/client.h
@@ -144,7 +144,7 @@ typedef struct
 // information for local display
        int                     stats[MAX_CL_STATS];    // health, etc
        int                     items;                  // inventory bit flags
-       float   item_gettime[32];       // cl.time of aquiring item, for blinking
+       float           item_gettime[32];       // cl.time of acquiring item, for blinking
        float           faceanimtime;   // use anim frame if cl.time < this
 
        cshift_t        cshifts[NUM_CSHIFTS];   // color shifts for damage, powerups
@@ -208,7 +208,7 @@ typedef struct
 // refresh related state
        struct model_s  *worldmodel;    // cl_entitites[0].model
        struct efrag_s  *free_efrags;
-       int                     num_entities;   // held in cl_entities array
+//     int                     num_entities;   // held in cl_entities array
        int                     num_statics;    // held in cl_staticentities array
        entity_t        viewent;                        // the gun model
 
index 224899f84f046821315e3ffe32728f34aea035ed..ce5ba79a11daeff145978d569e3891057ca892a2 100644 (file)
@@ -52,7 +52,7 @@ void R_RemoveEfrags (entity_t *ent)
 {
        efrag_t         *ef, *old, *walk, **prev;
        
-       ef = ent->efrag;
+       ef = ent->render.efrag;
        
        while (ef)
        {
@@ -79,7 +79,7 @@ void R_RemoveEfrags (entity_t *ent)
                cl.free_efrags = old;
        }
        
-       ent->efrag = NULL; 
+       ent->render.efrag = NULL; 
 }
 
 /*
@@ -181,25 +181,25 @@ void R_AddEfrags (entity_t *ent)
        model_t         *entmodel;
        int                     i;
                
-       if (!ent->model)
+       if (!ent->render.model)
                return;
 
        r_addent = ent;
                        
-       lastlink = &ent->efrag;
+       lastlink = &ent->render.efrag;
        r_pefragtopnode = NULL;
        
-       entmodel = ent->model;
+       entmodel = ent->render.model;
 
        for (i=0 ; i<3 ; i++)
        {
-               r_emins[i] = ent->origin[i] + entmodel->mins[i];
-               r_emaxs[i] = ent->origin[i] + entmodel->maxs[i];
+               r_emins[i] = ent->render.origin[i] + entmodel->mins[i];
+               r_emaxs[i] = ent->render.origin[i] + entmodel->maxs[i];
        }
 
        R_SplitEntityOnNode (cl.worldmodel->nodes);
 
-       ent->topnode = r_pefragtopnode;
+       ent->render.topnode = r_pefragtopnode;
 }
 
 
@@ -220,7 +220,7 @@ void R_StoreEfrags (efrag_t **ppefrag)
        while ((pefrag = *ppefrag) != NULL)
        {
                pent = pefrag->entity;
-               clmodel = pent->model;
+               clmodel = pent->render.model;
 
                switch (clmodel->type)
                {
@@ -229,10 +229,10 @@ void R_StoreEfrags (efrag_t **ppefrag)
                case mod_sprite:
                        pent = pefrag->entity;
 
-                       if ((pent->visframe != r_framecount) && (cl_numvisedicts < MAX_VISEDICTS))
+                       if ((pent->render.visframe != r_framecount) && (cl_numvisedicts < MAX_VISEDICTS))
                        {
                                cl_visedicts[cl_numvisedicts++] = pent;
-                               pent->visframe = r_framecount; // render each entity only once per frame
+                               pent->render.visframe = r_framecount; // render each entity only once per frame
                        }
 
                        ppefrag = &pefrag->leafnext;
index f3806a332ca76daabd5dfedb10447c3fd6e8a335..d266859e0a131e4ca9ca7c0f2deecaad779c300e 100644 (file)
@@ -344,45 +344,70 @@ void R_DrawSpriteModel (entity_t *e, frameblend_t *blend);
 void R_LerpUpdate(entity_t *ent)
 {
        int frame;
-       frame = ent->frame;
-       if (ent->model && ent->frame >= ent->model->numframes)
+       frame = ent->render.frame;
+       if (ent->render.model && ent->render.frame >= ent->render.model->numframes)
        {
-               Con_Printf("R_LerpUpdate: no such frame%6i in \"%s\"\n", ent->frame, ent->model->name);
+               Con_Printf("R_LerpUpdate: no such frame%6i in \"%s\"\n", ent->render.frame, ent->render.model->name);
                frame = 0;
        }
 
-       if (ent->lerp_model != ent->model)
+       if (ent->render.lerp_model != ent->render.model)
        {
                // reset all interpolation information
-               ent->lerp_model = ent->model;
-               ent->frame1 = ent->frame2 = frame;
-               ent->frame1start = ent->frame2start = cl.time;
-               ent->framelerp = 1;
-               ent->lerp_starttime = 0;
+               ent->render.lerp_model = ent->render.model;
+               ent->render.frame1 = ent->render.frame2 = frame;
+               ent->render.frame1start = ent->render.frame2start = cl.time;
+               ent->render.framelerp = 1;
+               ent->render.lerp_starttime = 0;
        }
-       else if (ent->frame2 != frame)
+       else if (ent->render.frame2 != frame)
        {
                // transition to new frame
-               ent->frame1 = ent->frame2;
-               ent->frame1start = ent->frame2start;
-               ent->frame2 = frame;
-               ent->frame2start = cl.time;
-               ent->framelerp = 0;
-               ent->lerp_starttime = cl.time;
+               ent->render.frame1 = ent->render.frame2;
+               ent->render.frame1start = ent->render.frame2start;
+               ent->render.frame2 = frame;
+               ent->render.frame2start = cl.time;
+               ent->render.framelerp = 0;
+               ent->render.lerp_starttime = cl.time;
        }
        else
        {
                // lerp_starttime < 0 is used to prevent changing of framelerp
-               if (ent->lerp_starttime >= 0)
+               if (ent->render.lerp_starttime >= 0)
                {
                        // update transition
-                       ent->framelerp = (cl.time - ent->lerp_starttime) * 10;
-                       ent->framelerp = bound(0, ent->framelerp, 1);
+                       ent->render.framelerp = (cl.time - ent->render.lerp_starttime) * 10;
+                       ent->render.framelerp = bound(0, ent->render.framelerp, 1);
                }
        }
 }
 
 
+void R_PrepareEntities (void)
+{
+       int i;
+       entity_t *ent;
+       vec3_t v;
+       // this updates entities that are supposed to be view relative
+       for (i = 0;i < cl_numvisedicts;i++)
+       {
+               ent = cl_visedicts[i];
+
+               if (ent->render.flags & RENDER_VIEWMODEL)
+               {
+                       // remove flag so it will not be repeated incase RelinkEntities is not called again for a while
+                       ent->render.flags -= RENDER_VIEWMODEL;
+                       // transform origin
+                       VectorCopy(ent->render.origin, v);
+                       ent->render.origin[0] = v[0] * vpn[0] + v[1] * vright[0] + v[2] * vup[0] + r_refdef.vieworg[0];
+                       ent->render.origin[1] = v[0] * vpn[1] + v[1] * vright[1] + v[2] * vup[1] + r_refdef.vieworg[1];
+                       ent->render.origin[2] = v[0] * vpn[2] + v[1] * vright[2] + v[2] * vup[2] + r_refdef.vieworg[2];
+                       // adjust angles
+                       VectorAdd(ent->render.angles, r_refdef.viewangles, ent->render.angles);
+               }
+       }
+}
+
 /*
 =============
 R_DrawEntitiesOnList
@@ -396,12 +421,12 @@ void R_DrawEntitiesOnList1 (void)
        if (!r_drawentities.value)
                return;
 
-       for (i=0 ; i<cl_numvisedicts ; i++)
+       for (i = 0;i < cl_numvisedicts;i++)
        {
-               if (cl_visedicts[i]->model->type != mod_brush)
+               if (cl_visedicts[i]->render.model->type != mod_brush)
                        continue;
                currententity = cl_visedicts[i];
-               modelalpha = currententity->alpha;
+               modelalpha = currententity->render.alpha;
 
                R_DrawBrushModel (currententity);
        }
@@ -415,25 +440,22 @@ void R_DrawEntitiesOnList2 (void)
        if (!r_drawentities.value)
                return;
 
-       for (i=0 ; i<cl_numvisedicts ; i++)
+       for (i = 0;i < cl_numvisedicts;i++)
        {
                currententity = cl_visedicts[i];
-               modelalpha = currententity->alpha;
+               modelalpha = currententity->render.alpha;
 
-               switch (currententity->model->type)
+               switch (currententity->render.model->type)
                {
                case mod_alias:
-                       if (!strcmp(currententity->model->name, "progs/flame2.mdl"))
-                               blend[0].frame = 0;
-
                        R_LerpUpdate(currententity);
-                       R_LerpAnimation(currententity->model, currententity->frame1, currententity->frame2, currententity->frame1start, currententity->frame2start, currententity->framelerp, blend);
-                       R_DrawAliasModel (currententity, true, modelalpha, currententity->model, blend, currententity->skinnum, currententity->origin, currententity->angles, currententity->scale, currententity->effects, currententity->model->flags, currententity->colormap);
+                       R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend);
+                       R_DrawAliasModel (currententity, true, modelalpha, currententity->render.model, blend, currententity->render.skinnum, currententity->render.origin, currententity->render.angles, currententity->render.scale, currententity->render.effects, currententity->render.model->flags, currententity->render.colormap);
                        break;
 
                case mod_sprite:
                        R_LerpUpdate(currententity);
-                       R_LerpAnimation(currententity->model, currententity->frame1, currententity->frame2, currententity->frame1start, currententity->frame2start, currententity->framelerp, blend);
+                       R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend);
                        R_DrawSpriteModel (currententity, blend);
                        break;
 
@@ -452,21 +474,21 @@ void R_DrawViewModel (void)
 {
        frameblend_t blend[4];
 
-       if (!r_drawviewmodel.value || chase_active.value || envmap || !r_drawentities.value || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.model)
+       if (!r_drawviewmodel.value || chase_active.value || envmap || !r_drawentities.value || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.render.model)
                return;
 
        currententity = &cl.viewent;
-       currententity->alpha = modelalpha = cl_entities[cl.viewentity].alpha; // LordHavoc: if the player is transparent, so is his gun
-       currententity->effects = cl_entities[cl.viewentity].effects;
-       currententity->scale = 1;
-       VectorCopy(cl_entities[cl.viewentity].colormod, currententity->colormod);
+       currententity->render.alpha = modelalpha = cl_entities[cl.viewentity].render.alpha; // LordHavoc: if the player is transparent, so is the gun
+       currententity->render.effects = cl_entities[cl.viewentity].render.effects;
+       currententity->render.scale = 1;
+       VectorCopy(cl_entities[cl.viewentity].render.colormod, currententity->render.colormod);
 
        R_LerpUpdate(currententity);
-       R_LerpAnimation(currententity->model, currententity->frame1, currententity->frame2, currententity->frame1start, currententity->frame2start, currententity->framelerp, blend);
+       R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend);
 
        // hack the depth range to prevent view model from poking into walls
        glDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
-       R_DrawAliasModel (currententity, false, modelalpha, currententity->model, blend, currententity->skinnum, currententity->origin, currententity->angles, currententity->scale, currententity->effects, currententity->model->flags, currententity->colormap);
+       R_DrawAliasModel (currententity, false, modelalpha, currententity->render.model, blend, currententity->render.skinnum, currententity->render.origin, currententity->render.angles, currententity->render.scale, currententity->render.effects, currententity->render.model->flags, currententity->render.colormap);
        glDepthRange (gldepthmin, gldepthmax);
 }
 
@@ -773,8 +795,8 @@ void R_RenderView (void)
 //     if (r_norefresh.value)
 //             return;
 
-       if (!r_worldentity.model || !cl.worldmodel)
-               Sys_Error ("R_RenderView: NULL worldmodel");
+       if (!r_worldentity.render.model || !cl.worldmodel)
+               Host_Error ("R_RenderView: NULL worldmodel");
 
        lighthalf = gl_lightmode.value;
 
@@ -796,6 +818,8 @@ void R_RenderView (void)
        R_SetFrustum ();
        R_SetupGL ();
 
+       R_PrepareEntities();
+
        skypolyclear();
        wallpolyclear();
        transpolyclear();
index 72dc5e4355036dc81c21cad58a159335c31a814f..cfc884d00604395d34f86e9aea925fc804569e00 100644 (file)
@@ -170,7 +170,7 @@ void R_NewMap (void)
                d_lightstylevalue[i] = 264;             // normal light value
 
        memset (&r_worldentity, 0, sizeof(r_worldentity));
-       r_worldentity.model = cl.worldmodel;
+       r_worldentity.render.model = cl.worldmodel;
        currententity = &r_worldentity;
 
 // clear out efrags in case the level hasn't been reloaded
index 9031969f8c27bc30ccd493922145779fb7d22c32..3db223095a963a3385da8da51c854ee48377e6a8 100644 (file)
@@ -121,7 +121,7 @@ int R_AddDynamicLights (msurface_t *surf)
                if (!(surf->dlightbits[lnum >> 5] & (1 << (lnum & 31))))
                        continue;                                       // not lit by this light
 
-               VectorSubtract (cl_dlights[lnum].origin, currententity->origin, local);
+               VectorSubtract (cl_dlights[lnum].origin, currententity->render.origin, local);
                dist = DotProduct (local, surf->plane->normal) - surf->plane->dist;
 
                // for comparisons to minimum acceptable light
@@ -280,7 +280,7 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
        lightmap = surf->samples;
 
 // set to full bright if no light data
-       if ((currententity && (currententity->effects & EF_FULLBRIGHT)) || !cl.worldmodel->lightdata)
+       if ((currententity && (currententity->render.effects & EF_FULLBRIGHT)) || !cl.worldmodel->lightdata)
        {
                bl = blocklights;
                for (i=0 ; i<size ; i++)
@@ -374,7 +374,7 @@ texture_t *R_TextureAnimation (texture_t *base)
        int             relative;
        int             count;
 
-       if (currententity->frame)
+       if (currententity->render.frame)
        {
                if (base->alternate_anims)
                        base = base->alternate_anims;
@@ -819,14 +819,14 @@ void RSurf_DrawWallVertex(msurface_t *s, texture_t *t, int transform, int isbmod
        if (s->dlightframe == r_dlightframecount)
                RSurf_Light(s->dlightbits, s->polys);
        wv = wvert;
-       if (isbmodel && (currententity->colormod[0] != 1 || currententity->colormod[1] != 1 || currententity->colormod[2] != 1))
+       if (isbmodel && (currententity->render.colormod[0] != 1 || currententity->render.colormod[1] != 1 || currententity->render.colormod[2] != 1))
        {
                for (p = s->polys;p;p = p->next)
                {
                        v = p->verts[0];
-                       transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
+                       transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, currententity->render.effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
                        for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
-                               transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3] * currententity->colormod[0], wv[4] * currententity->colormod[1], wv[5] * currententity->colormod[2], alpha);
+                               transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3] * currententity->render.colormod[0], wv[4] * currententity->render.colormod[1], wv[5] * currententity->render.colormod[2], alpha);
                        transpolyend();
                }
        }
@@ -835,7 +835,7 @@ void RSurf_DrawWallVertex(msurface_t *s, texture_t *t, int transform, int isbmod
                for (p = s->polys;p;p = p->next)
                {
                        v = p->verts[0];
-                       transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
+                       transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, currententity->render.effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
                        for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
                                transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3], wv[4], wv[5], alpha);
                        transpolyend();
@@ -932,22 +932,22 @@ void R_DrawBrushModel (entity_t *e)
 
        currententity = e;
 
-       clmodel = e->model;
+       clmodel = e->render.model;
 
-       if (e->angles[0] || e->angles[1] || e->angles[2])
+       if (e->render.angles[0] || e->render.angles[1] || e->render.angles[2])
        {
                rotated = true;
                for (i=0 ; i<3 ; i++)
                {
-                       mins[i] = e->origin[i] - clmodel->radius;
-                       maxs[i] = e->origin[i] + clmodel->radius;
+                       mins[i] = e->render.origin[i] - clmodel->radius;
+                       maxs[i] = e->render.origin[i] + clmodel->radius;
                }
        }
        else
        {
                rotated = false;
-               VectorAdd (e->origin, clmodel->mins, mins);
-               VectorAdd (e->origin, clmodel->maxs, maxs);
+               VectorAdd (e->render.origin, clmodel->mins, mins);
+               VectorAdd (e->render.origin, clmodel->maxs, maxs);
        }
 
        if (R_CullBox (mins, maxs))
@@ -955,14 +955,14 @@ void R_DrawBrushModel (entity_t *e)
 
        c_bmodels++;
 
-       VectorSubtract (r_refdef.vieworg, e->origin, modelorg);
+       VectorSubtract (r_refdef.vieworg, e->render.origin, modelorg);
        if (rotated)
        {
                vec3_t  temp;
                vec3_t  forward, right, up;
 
                VectorCopy (modelorg, temp);
-               AngleVectors (e->angles, forward, right, up);
+               AngleVectors (e->render.angles, forward, right, up);
                modelorg[0] = DotProduct (temp, forward);
                modelorg[1] = -DotProduct (temp, right);
                modelorg[2] = DotProduct (temp, up);
@@ -977,14 +977,14 @@ void R_DrawBrushModel (entity_t *e)
                if (!cl_dlights[i].radius)
                        continue;
 
-               VectorSubtract(cl_dlights[i].origin, currententity->origin, org);
+               VectorSubtract(cl_dlights[i].origin, currententity->render.origin, org);
                R_NoVisMarkLights (org, &cl_dlights[i], 1<<(i&31), i >> 5, clmodel);
        }
-       vertexlit = modelalpha != 1 || clmodel->firstmodelsurface == 0 || (currententity->effects & EF_FULLBRIGHT) || currententity->colormod[0] != 1 || currententity->colormod[2] != 1 || currententity->colormod[2] != 1;
+       vertexlit = modelalpha != 1 || clmodel->firstmodelsurface == 0 || (currententity->render.effects & EF_FULLBRIGHT) || currententity->render.colormod[0] != 1 || currententity->render.colormod[2] != 1 || currententity->render.colormod[2] != 1;
 
-e->angles[0] = -e->angles[0];  // stupid quake bug
+e->render.angles[0] = -e->render.angles[0];    // stupid quake bug
        softwaretransformforentity (e);
-e->angles[0] = -e->angles[0];  // stupid quake bug
+e->render.angles[0] = -e->render.angles[0];    // stupid quake bug
 
        // draw texture
        for (i = 0;i < clmodel->nummodelsurfaces;i++, s++)
@@ -1298,10 +1298,10 @@ void R_DrawWorld (void)
        entity_t        ent;
 
        memset (&ent, 0, sizeof(ent));
-       ent.model = cl.worldmodel;
-       ent.colormod[0] = ent.colormod[1] = ent.colormod[2] = 1;
-       modelalpha = ent.alpha = 1;
-       ent.scale = 1;
+       ent.render.model = cl.worldmodel;
+       ent.render.colormod[0] = ent.render.colormod[1] = ent.render.colormod[2] = 1;
+       modelalpha = ent.render.alpha = 1;
+       ent.render.scale = 1;
 
        VectorCopy (r_refdef.vieworg, modelorg);
 
index 9d847add2d8d3bfd2a7504241c8ba4284df62c26..a1e79394937b7aa4f73dc570fb40c8412f7e3f2a 100644 (file)
--- a/mathlib.c
+++ b/mathlib.c
@@ -29,8 +29,6 @@ int nanmask = 255<<23;
 
 /*-----------------------------------------------------------------*/
 
-#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
-
 float m_bytenormals[NUMVERTEXNORMALS][3] =
 {
 {-0.525731, 0.000000, 0.850651}, {-0.442863, 0.238856, 0.864188}, 
@@ -465,18 +463,6 @@ void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point,
 /*-----------------------------------------------------------------*/
 
 
-float  anglemod(float a)
-{
-#if 0
-       if (a >= 0)
-               a -= 360*(int)(a/360);
-       else
-               a += 360*( 1 + (int)(-a/360) );
-#endif
-       a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535);
-       return a;
-}
-
 // LordHavoc note 1:
 // BoxOnPlaneSide did a switch on a 'signbits' value and had optimized
 // assembly in an attempt to accelerate it further, very inefficient
index fde3d3e55bd3f2bf60c631466768e7c8dea16c12..4b613ba9f2e7332e654591f5d1cf6fc918d97e44 100644 (file)
--- a/mathlib.h
+++ b/mathlib.h
@@ -36,6 +36,10 @@ typedef      int     fixed16_t;
 #define M_PI           3.14159265358979323846  // matches value in gcc v2 math.h
 #endif
 
+#define DEG2RAD(a) ((a) * ((float) M_PI / 180.0f))
+#define RAD2DEG(a) ((a) * (180.0f / (float) M_PI))
+#define ANGLEMOD(a) (((int) ((a) * (65536.0f / 360.0f)) & 65535) * (360.0f / 65536.0f))
+
 struct mplane_s;
 
 extern vec3_t vec3_origin;
@@ -90,7 +94,6 @@ void FloorDivMod (double numer, double denom, int *quotient, int *rem);
 int GreatestCommonDivisor (int i1, int i2);
 
 void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
-float  anglemod(float a);
 
 // LordHavoc: like AngleVectors, but taking a forward vector instead of angles, useful!
 void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up);
index f29d3a9e537f204392b061c8d65c2c318a61c632..9e1c035145c4352d4cbe1b5a411b92c4f9b3aba3 100644 (file)
@@ -36,12 +36,11 @@ int                 posenum;
 
 float          aliasbboxmin[3], aliasbboxmax[3]; // LordHavoc: proper bounding box considerations
 
-#define MAXVERTS 8192
-float vertst[MAXVERTS][2];
-int vertusage[MAXVERTS];
-int vertonseam[MAXVERTS];
-int vertremap[MAXVERTS];
-unsigned short temptris[MAXVERTS][3];
+float vertst[MAXALIASVERTS][2];
+int vertusage[MAXALIASVERTS];
+int vertonseam[MAXALIASVERTS];
+int vertremap[MAXALIASVERTS];
+unsigned short temptris[MAXALIASTRIS][3];
 
 void Mod_ConvertAliasVerts (int inverts, vec3_t scale, vec3_t translate, trivertx_t *v, trivertx_t *out)
 {
@@ -85,7 +84,7 @@ void Mod_ConvertAliasVerts (int inverts, vec3_t scale, vec3_t translate, trivert
                }
        }
        if (invalidnormals)
-               Con_Printf("Mod_ConvertAliasVerts: %i invalid normal indices found\n", invalidnormals);
+               Con_Printf("Mod_ConvertAliasVerts: \"%s\", %i invalid normal indices found\n", loadname, invalidnormals);
 }
 
 /*
@@ -532,7 +531,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer)
        numverts = LittleLong(pinmodel->numverts);
        BOUNDI(numverts,0,MAXALIASVERTS);
        numtris = LittleLong(pinmodel->numtris);
-       BOUNDI(numtris,0,65536);
+       BOUNDI(numtris,0,MAXALIASTRIS);
        numskins = LittleLong(pinmodel->numskins);
        BOUNDI(numskins,0,256);
        skinwidth = LittleLong (pinmodel->skinwidth);
@@ -722,7 +721,7 @@ void Mod_ConvertQ2AliasVerts (int numverts, vec3_t scale, vec3_t translate, triv
                }
        }
        if (invalidnormals)
-               Con_Printf("Mod_ConvertQ2AliasVerts: %i invalid normal indices found\n", invalidnormals);
+               Con_Printf("Mod_ConvertQ2AliasVerts: \"%s\", %i invalid normal indices found\n", loadname, invalidnormals);
 }
 
 /*
index e4ba51a93fcb5255775f504610455b0d36361f45..4d312c73172c7d38450c88beb89cd9ff4bfcda1a 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -1619,7 +1619,7 @@ void PF_changeyaw (void)
        float           ideal, current, move, speed;
        
        ent = PROG_TO_EDICT(pr_global_struct->self);
-       current = anglemod( ent->v.angles[1] );
+       current = ANGLEMOD(ent->v.angles[1]);
        ideal = ent->v.ideal_yaw;
        speed = ent->v.yaw_speed;
        
@@ -1647,7 +1647,7 @@ void PF_changeyaw (void)
                        move = -speed;
        }
        
-       ent->v.angles[1] = anglemod (current + move);
+       ent->v.angles[1] = ANGLEMOD (current + move);
 }
 
 /*
@@ -1662,7 +1662,7 @@ void PF_changepitch (void)
        eval_t          *val;
        
        ent = G_EDICT(OFS_PARM0);
-       current = anglemod( ent->v.angles[0] );
+       current = ANGLEMOD( ent->v.angles[0] );
        if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
                ideal = val->_float;
        else
@@ -1702,7 +1702,7 @@ void PF_changepitch (void)
                        move = -speed;
        }
        
-       ent->v.angles[0] = anglemod (current + move);
+       ent->v.angles[0] = ANGLEMOD (current + move);
 }
 
 /*
index edad508ffd36e0b9a551710a8c16869aa80dc09a..b7cf55c6fe12a63eea77dc4cd81ac0f814811073 100644 (file)
@@ -46,6 +46,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define EF_FULLBRIGHT                  512             // LordHavoc: fullbright
 #define EF_FLAME                               1024    // LordHavoc: on fire
 
+#define EF_STEP                                        0x80000000 // internal client use only - present on MOVETYPE_STEP entities, not QC accessible (too many bits)
+
 // if the high bit of the servercmd is set, the low bits are fast update flags:
 #define        U_MOREBITS      (1<<0)
 #define        U_ORIGIN1       (1<<1)
@@ -206,6 +208,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define        svc_sound2                      54              // short soundindex instead of byte
 #define        svc_spawnbaseline2      55              // short modelindex instead of byte
 #define svc_spawnstatic2       56              // short modelindex instead of byte
+#define svc_entitiesbegin      57              // [short] entitynum
+#define svc_entitiesend                58              // [short] entitynum
 
 //
 // client to server
index db706ec77183fa82cd02c7258d8103020460a1b3..7b67999a215455ea832066f5b37684c499cd6f61 100644 (file)
@@ -187,24 +187,6 @@ extern int buildnumber;
 #include "zone.h"
 #include "mathlib.h"
 
-// LordHavoc: made this more compact, and added some more fields
-typedef struct
-{
-       vec3_t  origin;
-       vec3_t  angles;
-       int             effects;
-       short   modelindex;
-       short   frame;
-       byte    colormap;
-       byte    skin;
-       byte    alpha;
-       byte    scale;
-       byte    glowsize;
-       byte    glowcolor;
-       byte    colormod;
-} entity_state_t;
-
-
 #include "r_textures.h"
 
 #include "wad.h"
index 37a2a0fd1753f6ae5a0ae6ef46f375bc027c88b1..2c4d2d0d240b4e99292587f3e2e5b644b46bc640 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -817,17 +817,17 @@ void R_LightModel(entity_t *ent, int numverts, vec3_t center, vec3_t basecolor)
        a = (byte) bound((int) 0, (int) (modelalpha * 255.0f), (int) 255);
        if (lighthalf)
        {
-               mod[0] = ent->colormod[0] * 0.5f;
-               mod[1] = ent->colormod[1] * 0.5f;
-               mod[2] = ent->colormod[2] * 0.5f;
+               mod[0] = ent->render.colormod[0] * 0.5f;
+               mod[1] = ent->render.colormod[1] * 0.5f;
+               mod[2] = ent->render.colormod[2] * 0.5f;
        }
        else
        {
-               mod[0] = ent->colormod[0];
-               mod[1] = ent->colormod[1];
-               mod[2] = ent->colormod[2];
+               mod[0] = ent->render.colormod[0];
+               mod[1] = ent->render.colormod[1];
+               mod[2] = ent->render.colormod[2];
        }
-       if (ent->effects & EF_FULLBRIGHT)
+       if (ent->render.effects & EF_FULLBRIGHT)
        {
                ((byte *)&color)[0] = (byte) (255.0f * mod[0]);
                ((byte *)&color)[1] = (byte) (255.0f * mod[1]);
index 2e3f8f361ff33c57f3584374f36115de202ac312..ed53ba2cfe8f0df1cbd8faaf1edb0d2f88d72210 100644 (file)
--- a/r_part.c
+++ b/r_part.c
@@ -65,6 +65,7 @@ rtexture_t *smokeparticletexture[8];
 rtexture_t *rainparticletexture;
 rtexture_t *bubbleparticletexture;
 rtexture_t *bulletholetexture[8];
+rtexture_t *rocketglowparticletexture;
 
 particle_t     *particles;
 int                    r_numparticles;
@@ -245,6 +246,21 @@ void R_InitParticleTexture (void)
 
                bulletholetexture[i] = R_LoadTexture (va("bulletholetexture%d", i), 32, 32, &data[0][0][0], TEXF_MIPMAP | TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE);
        }
+
+       for (y = 0;y < 32;y++)
+       {
+               dy = y - 16;
+               for (x = 0;x < 32;x++)
+               {
+                       dx = x - 16;
+                       d = (2048.0f / (dx*dx+dy*dy+1)) - 8.0f;
+                       data[y][x][0] = bound(0, d * 1.0f, 255);
+                       data[y][x][1] = bound(0, d * 0.8f, 255);
+                       data[y][x][2] = bound(0, d * 0.5f, 255);
+                       data[y][x][3] = bound(0, d * 1.0f, 255);
+               }
+       }
+       rocketglowparticletexture = R_LoadTexture ("glowparticletexture", 32, 32, &data[0][0][0], TEXF_MIPMAP | TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE);
 }
 
 void r_part_start()
@@ -444,7 +460,7 @@ void R_EntityParticles (entity_t *ent)
                forward[1] = cp*sy;
                forward[2] = -sp;
 
-               particle(pt_oneframe, 0x6f, particletexture, TPOLYTYPE_ALPHA, false, 2, 255, 9999, 0, ent->origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0);
+               particle(pt_oneframe, 0x6f, particletexture, TPOLYTYPE_ALPHA, false, 2, 255, 9999, 0, ent->render.origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->render.origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->render.origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0);
        }
 }
 
@@ -837,12 +853,10 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
        VectorSubtract(end, start, dir);
        VectorNormalize(dir);
 
-       /*
        if (type == 0) // rocket glow
-               particle(pt_glow, 254, particletexture, TPOLYTYPE_ADD, false, 10, 160, 9999, 0, start[0] - 12 * dir[0], start[1] - 12 * dir[1], start[2] - 12 * dir[2], 0, 0, 0);
-       */
+               particle(pt_oneframe, 254, rocketglowparticletexture, TPOLYTYPE_ADD, false, 24, 255, 9999, 0, end[0] - 12 * dir[0], end[1] - 12 * dir[1], end[2] - 12 * dir[2], 0, 0, 0);
 
-       t = ent->trail_time;
+       t = ent->render.trail_time;
        if (t >= cl.time)
                return; // no particles to spawn this frame (sparse trail)
 
@@ -854,7 +868,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
        if (len <= 0.01f)
        {
                // advance the trail time
-               ent->trail_time = cl.time;
+               ent->render.trail_time = cl.time;
                return;
        }
        speed = len / (cl.time - cl.oldtime);
@@ -869,14 +883,14 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
        if (contents == CONTENTS_SKY || contents == CONTENTS_LAVA)
        {
                // advance the trail time
-               ent->trail_time = cl.time;
+               ent->render.trail_time = cl.time;
                return;
        }
 
        bubbles = (contents == CONTENTS_WATER || contents == CONTENTS_SLIME);
 
        polytype = TPOLYTYPE_ALPHA;
-       if (ent->effects & EF_ADDITIVE)
+       if (ent->render.effects & EF_ADDITIVE)
                polytype = TPOLYTYPE_ADD;
 
        while (t < cl.time)
@@ -974,7 +988,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
                dec *= speed;
                VectorMA (start, dec, vec, start);
        }
-       ent->trail_time = t;
+       ent->render.trail_time = t;
 }
 
 void R_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent)
index db8e90e934c588cec1ac93d852b5a2d72c9c1330..95facc3cf94c10c7be87ab5f30d0028228254d39 100644 (file)
@@ -4,7 +4,7 @@ void GL_DrawSpriteImage (mspriteframe_t *frame, vec3_t origin, vec3_t up, vec3_t
 {
        byte alphaub;
        alphaub = bound(0, alpha, 255);
-       transpolybegin(R_GetTexture(frame->texture), 0, R_GetTexture(frame->fogtexture), currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
+       transpolybegin(R_GetTexture(frame->texture), 0, R_GetTexture(frame->fogtexture), currententity->render.effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
        transpolyvertub(origin[0] + frame->down * up[0] + frame->left * right[0], origin[1] + frame->down * up[1] + frame->left * right[1], origin[2] + frame->down * up[2] + frame->left * right[2], 0, 1, red, green, blue, alphaub);
        transpolyvertub(origin[0] + frame->up * up[0] + frame->left * right[0], origin[1] + frame->up * up[1] + frame->left * right[1], origin[2] + frame->up * up[2] + frame->left * right[2], 0, 0, red, green, blue, alphaub);
        transpolyvertub(origin[0] + frame->up * up[0] + frame->right * right[0], origin[1] + frame->up * up[1] + frame->right * right[1], origin[2] + frame->up * up[2] + frame->right * right[2], 1, 0, red, green, blue, alphaub);
@@ -29,34 +29,34 @@ void R_DrawSpriteModel (entity_t *e, frameblend_t *blend)
 
        c_sprites++;
 
-       psprite = Mod_Extradata(e->model);
+       psprite = Mod_Extradata(e->render.model);
        //psprite = e->model->cache.data;
 
        if (psprite->type == SPR_ORIENTED)
        {       // bullet marks on walls
-               AngleVectors (e->angles, NULL, right, up);
-               VectorSubtract(e->origin, vpn, org);
+               AngleVectors (e->render.angles, NULL, right, up);
+               VectorSubtract(e->render.origin, vpn, org);
        }
        else
        {       // normal sprite
                VectorCopy(vup, up);
                VectorCopy(vright, right);
-               VectorCopy(e->origin, org);
+               VectorCopy(e->render.origin, org);
        }
-       if (e->scale != 1)
+       if (e->render.scale != 1)
        {
-               VectorScale(up, e->scale, up);
-               VectorScale(right, e->scale, right);
+               VectorScale(up, e->render.scale, up);
+               VectorScale(right, e->render.scale, right);
        }
 
-       if (e->model->flags & EF_FULLBRIGHT || e->effects & EF_FULLBRIGHT)
+       if (e->render.model->flags & EF_FULLBRIGHT || e->render.effects & EF_FULLBRIGHT)
        {
-               color[0] = e->colormod[0] * 255;
-               color[1] = e->colormod[1] * 255;
-               color[2] = e->colormod[2] * 255;
+               color[0] = e->render.colormod[0] * 255;
+               color[1] = e->render.colormod[1] * 255;
+               color[2] = e->render.colormod[2] * 255;
        }
        else
-               R_CompleteLightPoint(color, e->origin, true);
+               R_CompleteLightPoint(color, e->render.origin, true);
 
        colorub[0] = bound(0, color[0], 255);
        colorub[1] = bound(0, color[1], 255);
@@ -64,12 +64,12 @@ void R_DrawSpriteModel (entity_t *e, frameblend_t *blend)
 
        // LordHavoc: interpolated sprite rendering
        if (blend[0].lerp)
-               GL_DrawSpriteImage(((mspriteframe_t *)(psprite->ofs_frames + (int) psprite)) + blend[0].frame, org, up, right, colorub[0],colorub[1],colorub[2], e->alpha*255*blend[0].lerp);
+               GL_DrawSpriteImage(((mspriteframe_t *)(psprite->ofs_frames + (int) psprite)) + blend[0].frame, org, up, right, colorub[0],colorub[1],colorub[2], e->render.alpha*255*blend[0].lerp);
        if (blend[1].lerp)
-               GL_DrawSpriteImage(((mspriteframe_t *)(psprite->ofs_frames + (int) psprite)) + blend[1].frame, org, up, right, colorub[0],colorub[1],colorub[2], e->alpha*255*blend[1].lerp);
+               GL_DrawSpriteImage(((mspriteframe_t *)(psprite->ofs_frames + (int) psprite)) + blend[1].frame, org, up, right, colorub[0],colorub[1],colorub[2], e->render.alpha*255*blend[1].lerp);
        if (blend[2].lerp)
-               GL_DrawSpriteImage(((mspriteframe_t *)(psprite->ofs_frames + (int) psprite)) + blend[2].frame, org, up, right, colorub[0],colorub[1],colorub[2], e->alpha*255*blend[2].lerp);
+               GL_DrawSpriteImage(((mspriteframe_t *)(psprite->ofs_frames + (int) psprite)) + blend[2].frame, org, up, right, colorub[0],colorub[1],colorub[2], e->render.alpha*255*blend[2].lerp);
        if (blend[3].lerp)
-               GL_DrawSpriteImage(((mspriteframe_t *)(psprite->ofs_frames + (int) psprite)) + blend[3].frame, org, up, right, colorub[0],colorub[1],colorub[2], e->alpha*255*blend[3].lerp);
+               GL_DrawSpriteImage(((mspriteframe_t *)(psprite->ofs_frames + (int) psprite)) + blend[3].frame, org, up, right, colorub[0],colorub[1],colorub[2], e->render.alpha*255*blend[3].lerp);
 }
 
index e69a5bddd018333184df7afa8516fa458c466ba5..d67134d34e272611b047a33165436bb980b7591c 100644 (file)
--- a/render.h
+++ b/render.h
@@ -35,57 +35,77 @@ typedef struct efrag_s
        struct efrag_s          *entnext;
 } efrag_t;
 
+#define RENDER_STEP 1
+#define RENDER_GLOWTRAIL 2
+#define RENDER_VIEWMODEL 4
+
+// LordHavoc: made this more compact, and added some more fields
+typedef struct
+{
+       double  time; // time this state was updated
+       vec3_t  origin;
+       vec3_t  angles;
+       int             effects;
+       unsigned short modelindex;
+       unsigned short frame;
+       byte    colormap;
+       byte    skin;
+       byte    alpha;
+       byte    scale;
+       byte    glowsize;
+       byte    glowcolor;
+       byte    colormod;
+       byte    flags;
+} entity_state_t;
 
 typedef struct entity_s
 {
-       qboolean                                forcelink;              // model changed
-
-       int                                             update_type;
-
-       entity_state_t                  baseline;               // to fill in defaults in updates
-       entity_state_t                  deltabaseline;  // LordHavoc: previous frame
-
-       double                                  msgtime;                // time of last update
-       vec3_t                                  msg_origins[2]; // last two updates (0 is newest)       
-       vec3_t                                  origin;
-       vec3_t                                  msg_angles[2];  // last two updates (0 is newest)
-       vec3_t                                  angles; 
-
-       // LordHavoc: added support for alpha transprency and other effects
-       float                                   alpha;                  // opacity (alpha) of the model
-       float                                   colormod[3];    // color tint for model
-       float                                   scale;                  // size the model is shown
-       float                                   trail_time;
-       float                                   glowsize;               // how big the glow is
-       byte                                    glowcolor;              // color of glow and particle trail (paletted)
-       byte                                    glowtrail;              // leaves a trail of particles
-       byte                                    isviewmodel;    // attached to view
-
-       struct model_s                  *model;                 // NULL = no model
-       struct efrag_s                  *efrag;                 // linked list of efrags
-       int                                             frame;                  // current desired frame (usually identical to frame2, but frame2 is not always used)
-       struct model_s                  *lerp_model;    // lerp resets when model changes
-       float                                   lerp_starttime; // start of this transition
-       int                                             frame1;                 // frame that the model is interpolating from
-       int                                             frame2;                 // frame that the model is interpolating to
-       double                                  framelerp;              // interpolation factor, usually computed from lerp_starttime
-       double                                  frame1start;    // time frame1 began playing (for framegroup animations)
-       double                                  frame2start;    // time frame2 began playing (for framegroup animations)
-       float                                   syncbase;               // for client-side animations
-       int                                             colormap;
-       int                                             effects;                // light, particles, etc
-       int                                             skinnum;                // for Alias models
-       int                                             visframe;               // last frame this entity was
-                                                                                       //  found in an active leaf
-                                                                                       
-       int                                             dlightframe;    // dynamic lighting
-       int                                             dlightbits[8];
-       
-// FIXME: could turn these into a union
-       int                                             trivial_accept;
-       struct mnode_s                  *topnode;               // for bmodels, first world node
-                                                                                       //  that splits bmodel, or NULL if
-                                                                                       //  not split
+       entity_state_t                  state_baseline; // baseline for entity
+       entity_state_t                  state_previous; // previous state (interpolating from this)
+       entity_state_t                  state_current;  // current state (interpolating to this)
+
+       struct
+       {
+               vec3_t                                  origin;
+               vec3_t                                  angles; 
+
+               // LordHavoc: added support for alpha transprency and other effects
+               float                                   alpha;                  // opacity (alpha) of the model
+               float                                   colormod[3];    // color tint for model
+               float                                   scale;                  // size the model is shown
+               float                                   glowsize;               // how big the glow is
+               byte                                    glowcolor;              // color of glow and particle trail (paletted)
+               byte                                    flags;                  // render flags
+
+               struct model_s                  *model;                 // NULL = no model
+               int                                             frame;                  // current desired frame (usually identical to frame2, but frame2 is not always used)
+               struct efrag_s                  *efrag;                 // linked list of efrags
+               int                                             colormap;
+               int                                             effects;                // light, particles, etc
+               int                                             skinnum;                // for Alias models
+
+               int                                             visframe;               // last frame this entity was found in an active leaf
+
+               struct model_s                  *lerp_model;    // lerp resets when model changes
+               float                                   lerp_starttime; // start of this transition
+               int                                             frame1;                 // frame that the model is interpolating from
+               int                                             frame2;                 // frame that the model is interpolating to
+               double                                  framelerp;              // interpolation factor, usually computed from lerp_starttime
+               double                                  frame1start;    // time frame1 began playing (for framegroup animations)
+               double                                  frame2start;    // time frame2 began playing (for framegroup animations)
+//             float                                   syncbase;               // for client-side animations
+
+               int                                             dlightframe;    // dynamic lighting
+               int                                             dlightbits[8];
+               
+               float                                   trail_time;
+       // FIXME: could turn these into a union
+//             int                                             trivial_accept;
+               struct mnode_s                  *topnode;               // for bmodels, first world node
+                                                                                               //  that splits bmodel, or NULL if
+                                                                                               //  not split
+       }
+       render;
 } entity_t;
 
 // !!! if this is changed, it must be changed in asm_draw.h too !!!
diff --git a/sbar.c b/sbar.c
index fd63c1339165db8af43702d93845d50120f73591..32e1db6d5d934c0cecc7ddcc489c358fb1d6915f 100644 (file)
--- a/sbar.c
+++ b/sbar.c
@@ -783,6 +783,9 @@ void Sbar_DrawFace (void)
                f = 4;
        else
                f = cl.stats[STAT_HEALTH] / 20;
+       // LordHavoc: I don't even know how the game didn't crash without this
+       if (f < 0)
+               f = 0;
 
        if (cl.time <= cl.faceanimtime)
        {
index 330a9ba712fdf731635c0060d49a65bd1c2ca164..59da2be28ad1fa1485a1892741c9b30e1c965919 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -483,6 +483,8 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                MSG_WriteFloat(msg, org[2]);
        }
        */
+       MSG_WriteByte(msg, svc_entitiesbegin);
+       MSG_WriteShort(msg, 1);
 
        clentnum = EDICT_TO_PROG(clent); // LordHavoc: for comparison purposes
 // send over all entities (except the client) that touch the pvs
@@ -744,6 +746,9 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                if (bits & U_FRAME2)    MSG_WriteByte(msg, (int)ent->v.frame >> 8);
                if (bits & U_MODEL2)    MSG_WriteByte(msg, (int)ent->v.modelindex >> 8);
        }
+
+       MSG_WriteByte(msg, svc_entitiesend);
+       MSG_WriteShort(msg, MAX_EDICTS);
 }
 
 /*
index 87f3ed434a38ab1cd53b99de326a0701472b501c..8bf64f62ae02e304d3bfe924d767a8dfd88527ce 100644 (file)
--- a/sv_move.c
+++ b/sv_move.c
@@ -287,8 +287,8 @@ void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist)
        float                   d[3];
        float           tdir, olddir, turnaround;
 
-       olddir = anglemod( (int)(actor->v.ideal_yaw/45)*45 );
-       turnaround = anglemod(olddir - 180);
+       olddir = ANGLEMOD((int)(actor->v.ideal_yaw/45)*45);
+       turnaround = ANGLEMOD(olddir - 180);
 
        deltax = enemy->v.origin[0] - actor->v.origin[0];
        deltay = enemy->v.origin[1] - actor->v.origin[1];
index e025c7f3ea5f1ef5ceadfd124f78a6af69af3ad0..52107efc6791916373be0d877b6e9c21b79e3f42 100644 (file)
@@ -151,8 +151,8 @@ void softwaretransformset (vec3_t origin, vec3_t angles, vec_t scale)
 void softwaretransformforentity (entity_t *e)
 {
        vec3_t angles;
-       angles[0] = -e->angles[0];
-       angles[1] = e->angles[1];
-       angles[2] = e->angles[2];
-       softwaretransformset(e->origin, angles, e->scale);
+       angles[0] = -e->render.angles[0];
+       angles[1] = e->render.angles[1];
+       angles[2] = e->render.angles[2];
+       softwaretransformset(e->render.origin, angles, e->render.scale);
 }
diff --git a/view.c b/view.c
index 5eddbe637856bd74ee2eca45eafca7e5d7a6a8d5..793fec6351983e1ea8a8bfb0ad7f3185a104cbbe 100644 (file)
--- a/view.c
+++ b/view.c
@@ -312,10 +312,10 @@ void V_ParseDamage (void)
 //
        ent = &cl_entities[cl.viewentity];
        
-       VectorSubtract (from, ent->origin, from);
+       VectorSubtract (from, ent->render.origin, from);
        VectorNormalize (from);
        
-       AngleVectors (ent->angles, forward, right, NULL);
+       AngleVectors (ent->render.angles, forward, right, NULL);
 
        side = DotProduct (from, right);
        v_dmg_roll = count*side*v_kickroll.value;
@@ -555,7 +555,7 @@ void V_UpdateBlends (void)
 
 float angledelta (float a)
 {
-       a = anglemod(a);
+       a = ANGLEMOD(a);
        if (a > 180)
                a -= 360;
        return a;
@@ -615,12 +615,12 @@ void CalcGunAngle (void)
        cl.viewent.angles[YAW] = r_refdef.viewangles[YAW] + yaw;
        cl.viewent.angles[PITCH] = - (r_refdef.viewangles[PITCH] + pitch);
        */
-       cl.viewent.angles[YAW] = r_refdef.viewangles[YAW];
-       cl.viewent.angles[PITCH] = -r_refdef.viewangles[PITCH];
+       cl.viewent.render.angles[YAW] = r_refdef.viewangles[YAW];
+       cl.viewent.render.angles[PITCH] = -r_refdef.viewangles[PITCH];
 
-       cl.viewent.angles[ROLL] -= v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value;
-       cl.viewent.angles[PITCH] -= v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value;
-       cl.viewent.angles[YAW] -= v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value;
+       cl.viewent.render.angles[ROLL] -= v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value;
+       cl.viewent.render.angles[PITCH] -= v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value;
+       cl.viewent.render.angles[YAW] -= v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value;
 }
 
 /*
@@ -634,21 +634,21 @@ void V_BoundOffsets (void)
        
        ent = &cl_entities[cl.viewentity];
 
-// absolutely bound refresh reletive to entity clipping hull
+// absolutely bound refresh relative to entity clipping hull
 // so the view can never be inside a solid wall
 
-       if (r_refdef.vieworg[0] < ent->origin[0] - 14)
-               r_refdef.vieworg[0] = ent->origin[0] - 14;
-       else if (r_refdef.vieworg[0] > ent->origin[0] + 14)
-               r_refdef.vieworg[0] = ent->origin[0] + 14;
-       if (r_refdef.vieworg[1] < ent->origin[1] - 14)
-               r_refdef.vieworg[1] = ent->origin[1] - 14;
-       else if (r_refdef.vieworg[1] > ent->origin[1] + 14)
-               r_refdef.vieworg[1] = ent->origin[1] + 14;
-       if (r_refdef.vieworg[2] < ent->origin[2] - 22)
-               r_refdef.vieworg[2] = ent->origin[2] - 22;
-       else if (r_refdef.vieworg[2] > ent->origin[2] + 30)
-               r_refdef.vieworg[2] = ent->origin[2] + 30;
+       if (r_refdef.vieworg[0] < ent->render.origin[0] - 14)
+               r_refdef.vieworg[0] = ent->render.origin[0] - 14;
+       else if (r_refdef.vieworg[0] > ent->render.origin[0] + 14)
+               r_refdef.vieworg[0] = ent->render.origin[0] + 14;
+       if (r_refdef.vieworg[1] < ent->render.origin[1] - 14)
+               r_refdef.vieworg[1] = ent->render.origin[1] - 14;
+       else if (r_refdef.vieworg[1] > ent->render.origin[1] + 14)
+               r_refdef.vieworg[1] = ent->render.origin[1] + 14;
+       if (r_refdef.vieworg[2] < ent->render.origin[2] - 22)
+               r_refdef.vieworg[2] = ent->render.origin[2] - 22;
+       else if (r_refdef.vieworg[2] > ent->render.origin[2] + 30)
+               r_refdef.vieworg[2] = ent->render.origin[2] + 30;
 }
 
 /*
@@ -677,7 +677,7 @@ void V_CalcViewRoll (void)
 {
        float           side;
                
-       side = V_CalcRoll (cl_entities[cl.viewentity].angles, cl.velocity);
+       side = V_CalcRoll (cl_entities[cl.viewentity].render.angles, cl.velocity);
        r_refdef.viewangles[ROLL] += side;
 
        if (v_dmg_time > 0)
@@ -712,9 +712,9 @@ void V_CalcIntermissionRefdef (void)
 // view is the weapon model (only visible from inside body)
        view = &cl.viewent;
 
-       VectorCopy (ent->origin, r_refdef.vieworg);
-       VectorCopy (ent->angles, r_refdef.viewangles);
-       view->model = NULL;
+       VectorCopy (ent->render.origin, r_refdef.vieworg);
+       VectorCopy (ent->render.angles, r_refdef.viewangles);
+       view->render.model = NULL;
 
 // always idle in intermission
        old = v_idlescale.value;
@@ -747,67 +747,64 @@ void V_CalcRefdef (void)
        view = &cl.viewent;
        
 
-// transform the view offset by the model's matrix to get the offset from
-// model origin for the view
+// transform the view offset by the model's matrix to get the offset from model origin for the view
        if (!chase_active.value) // LordHavoc: get rid of angle problems in chase_active mode
        {
-               ent->angles[YAW] = cl.viewangles[YAW];  // the model should face the view dir
-               ent->angles[PITCH] = -cl.viewangles[PITCH];     // the model should face the view dir
+               ent->render.angles[YAW] = cl.viewangles[YAW];   // the model should face the view dir
+               ent->render.angles[PITCH] = -cl.viewangles[PITCH];      // the model should face the view dir
        }
                                                                                
        
        bob = V_CalcBob ();
        
 // refresh position
-       VectorCopy (ent->origin, r_refdef.vieworg);
+       VectorCopy (ent->render.origin, r_refdef.vieworg);
        r_refdef.vieworg[2] += cl.viewheight + bob;
 
+       // LordHavoc: the protocol has changed...  so this is an obsolete approach
 // never let it sit exactly on a node line, because a water plane can
 // dissapear when viewed with the eye exactly on it.
 // the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis
-       r_refdef.vieworg[0] += 1.0/32;
-       r_refdef.vieworg[1] += 1.0/32;
-       r_refdef.vieworg[2] += 1.0/32;
+//     r_refdef.vieworg[0] += 1.0/32;
+//     r_refdef.vieworg[1] += 1.0/32;
+//     r_refdef.vieworg[2] += 1.0/32;
 
        if (!intimerefresh)
-       {
                VectorCopy (cl.viewangles, r_refdef.viewangles);
-       }
        V_CalcViewRoll ();
        V_AddIdle ();
 
 // offsets
-       angles[PITCH] = -ent->angles[PITCH];    // because entity pitches are
-                                                                                       //  actually backward
-       angles[YAW] = ent->angles[YAW];
-       angles[ROLL] = ent->angles[ROLL];
+       angles[PITCH] = -ent->render.angles[PITCH];     // because entity pitches are actually backward
+       angles[YAW] = ent->render.angles[YAW];
+       angles[ROLL] = ent->render.angles[ROLL];
 
        AngleVectors (angles, forward, NULL, NULL);
 
        V_BoundOffsets ();
                
 // set up gun position
-       VectorCopy (cl.viewangles, view->angles);
+       VectorCopy (cl.viewangles, view->render.angles);
        
        CalcGunAngle ();
 
-       VectorCopy (ent->origin, view->origin);
-       view->origin[2] += cl.viewheight;
+       VectorCopy (ent->render.origin, view->render.origin);
+       view->render.origin[2] += cl.viewheight;
 
        for (i=0 ; i<3 ; i++)
        {
-               view->origin[i] += forward[i]*bob*0.4;
+               view->render.origin[i] += forward[i]*bob*0.4;
 //             view->origin[i] += right[i]*bob*0.4;
 //             view->origin[i] += up[i]*bob*0.8;
        }
-       view->origin[2] += bob;
+       view->render.origin[2] += bob;
 
 // fudge position around to keep amount of weapon visible
 // roughly equal with different FOV
 
-       view->model = cl.model_precache[cl.stats[STAT_WEAPON]];
-       view->frame = cl.stats[STAT_WEAPONFRAME];
-       view->colormap = -1; // no special coloring
+       view->render.model = cl.model_precache[cl.stats[STAT_WEAPON]];
+       view->render.frame = cl.stats[STAT_WEAPONFRAME];
+       view->render.colormap = -1; // no special coloring
 
 // set up the refresh position
        if (!intimerefresh)
@@ -817,7 +814,7 @@ void V_CalcRefdef (void)
        }
 
 // smooth out stair step ups
-if (cl.onground && ent->origin[2] - oldz > 0)
+if (cl.onground && ent->render.origin[2] - oldz > 0)
 {
        float steptime;
        
@@ -827,15 +824,15 @@ if (cl.onground && ent->origin[2] - oldz > 0)
                steptime = 0;
 
        oldz += steptime * 80;
-       if (oldz > ent->origin[2])
-               oldz = ent->origin[2];
-       if (ent->origin[2] - oldz > 12)
-               oldz = ent->origin[2] - 12;
-       r_refdef.vieworg[2] += oldz - ent->origin[2];
-       view->origin[2] += oldz - ent->origin[2];
+       if (oldz > ent->render.origin[2])
+               oldz = ent->render.origin[2];
+       if (ent->render.origin[2] - oldz > 12)
+               oldz = ent->render.origin[2] - 12;
+       r_refdef.vieworg[2] += oldz - ent->render.origin[2];
+       view->render.origin[2] += oldz - ent->render.origin[2];
 }
 else
-       oldz = ent->origin[2];
+       oldz = ent->render.origin[2];
 
 // LordHavoc: origin view kick
        VectorAdd(r_refdef.vieworg, cl.punchvector, r_refdef.vieworg);