+void CL_LerpPlayer(float frac)
+{
+ int i;
+ float d;
+
+ if (cl.entitydatabase.numframes)
+ {
+ cl.viewentorigin[0] = cl.viewentoriginold[0] + frac * (cl.viewentoriginnew[0] - cl.viewentoriginold[0]);
+ cl.viewentorigin[1] = cl.viewentoriginold[1] + frac * (cl.viewentoriginnew[1] - cl.viewentoriginold[1]);
+ cl.viewentorigin[2] = cl.viewentoriginold[2] + frac * (cl.viewentoriginnew[2] - cl.viewentoriginold[2]);
+ }
+ else
+ VectorCopy (cl_entities[cl.viewentity].render.origin, cl.viewentorigin);
+
+ cl.viewzoom = cl.viewzoomold + frac * (cl.viewzoomnew - cl.viewzoomold);
+
+ 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 (i = 0;i < 3;i++)
+ {
+ d = cl.mviewangles[0][i] - cl.mviewangles[1][i];
+ if (d > 180)
+ d -= 360;
+ else if (d < -180)
+ d += 360;
+ cl.viewangles[i] = cl.mviewangles[1][i] + frac*d;
+ }
+ }
+}
+
+void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate)
+{
+ int i;
+ cl_effect_t *e;
+ if (!modelindex) // sanity check
+ return;
+ for (i = 0, e = cl_effect;i < MAX_EFFECTS;i++, e++)
+ {
+ if (e->active)
+ continue;
+ e->active = true;
+ VectorCopy(org, e->origin);
+ e->modelindex = modelindex;
+ e->starttime = cl.time;
+ e->startframe = startframe;
+ e->endframe = startframe + framecount;
+ e->framerate = framerate;
+
+ e->frame = 0;
+ e->frame1time = cl.time;
+ e->frame2time = cl.time;
+ break;
+ }
+}
+
+static void CL_RelinkEffects()
+{
+ int i, intframe;
+ cl_effect_t *e;
+ entity_t *vis;
+ float frame;
+
+ for (i = 0, e = cl_effect;i < MAX_EFFECTS;i++, e++)
+ {
+ if (e->active)
+ {
+ frame = (cl.time - e->starttime) * e->framerate + e->startframe;
+ intframe = frame;
+ if (intframe < 0 || intframe >= e->endframe)
+ {
+ e->active = false;
+ memset(e, 0, sizeof(*e));
+ continue;
+ }
+
+ if (intframe != e->frame)
+ {
+ e->frame = intframe;
+ e->frame1time = e->frame2time;
+ e->frame2time = cl.time;
+ }
+
+ if ((vis = CL_NewTempEntity()))
+ {
+ // interpolation stuff
+ vis->render.frame1 = intframe;
+ vis->render.frame2 = intframe + 1;
+ if (vis->render.frame2 >= e->endframe)
+ vis->render.frame2 = -1; // disappear
+ vis->render.framelerp = frame - intframe;
+ vis->render.frame1time = e->frame1time;
+ vis->render.frame2time = e->frame2time;
+
+ // normal stuff
+ VectorCopy(e->origin, vis->render.origin);
+ vis->render.model = cl.model_precache[e->modelindex];
+ vis->render.frame = vis->render.frame2;
+ vis->render.colormap = -1; // no special coloring
+ vis->render.scale = 1;
+ vis->render.alpha = 1;
+ }
+ }
+ }
+}
+
+void CL_RelinkEntities (void)
+{
+ float frac;
+
+ // fraction from previous network update to current
+ frac = CL_LerpPoint ();
+
+ CL_DecayLights ();
+ CL_RelinkStaticEntities();
+ CL_RelinkNetworkEntities();
+ TraceLine_ScanForBModels();
+ CL_RelinkEffects();
+ CL_MoveParticles();
+ CL_UpdateTEnts();
+
+ CL_LerpPlayer(frac);
+}