cls.qw_downloadnumber++;
cls.qw_downloadpercent = 0;
+ cls.qw_downloadmemorycursize = 0;
return false;
}
while (cls.qw_downloadmemorymaxsize < cls.qw_downloadmemorycursize + size)
cls.qw_downloadmemorymaxsize *= 2;
old = cls.qw_downloadmemory;
- cls.qw_downloadmemory = Mem_Alloc(cls.permanentmempool, cls.qw_downloadmemorymaxsize);
+ cls.qw_downloadmemory = (unsigned char *)Mem_Alloc(cls.permanentmempool, cls.qw_downloadmemorymaxsize);
if (old)
{
memcpy(cls.qw_downloadmemory, old, cls.qw_downloadmemorycursize);
Con_DPrintf("Starting upload of %d bytes...\n", size);
- cls.qw_uploaddata = Mem_Alloc(cls.permanentmempool, size);
+ cls.qw_uploaddata = (unsigned char *)Mem_Alloc(cls.permanentmempool, size);
memcpy(cls.qw_uploaddata, data, size);
cls.qw_uploadsize = size;
cls.qw_uploadpos = 0;
ent->persistent.muzzleflash = 0;
VectorCopy(ent->state_current.origin, ent->persistent.trail_origin);
}
- else if (cls.timedemo || cl_nolerp.integer || DotProduct(odelta, odelta) > 1000*1000)
+ else if (cls.timedemo || cl_nolerp.integer || DotProduct(odelta, odelta) > 1000*1000 || (cl.fixangle[0] && !cl.fixangle[1]))
{
// don't interpolate the move
+ // (the fixangle[] check detects teleports, but not constant fixangles
+ // such as when spectating)
ent->persistent.lerpdeltatime = 0;
ent->persistent.lerpstarttime = cl.mtime[1];
VectorCopy(ent->state_current.origin, ent->persistent.oldorigin);
colorStart = MSG_ReadByte(); // color
colorLength = MSG_ReadByte(); // gravity (1 or 0)
velspeed = MSG_ReadCoord(cls.protocol); // randomvel
- CL_ParticleCube(pos, pos2, dir, count, colorStart, colorLength, velspeed);
+ CL_ParticleCube(pos, pos2, dir, count, colorStart, colorLength != 0, velspeed);
break;
case TE_PARTICLERAIN:
cl.mtime[1] = cl.mtime[0];
cl.mtime[0] = realtime; // qw has no clock
cl.movement_needupdate = true;
+ // if true the cl.viewangles are interpolated from cl.mviewangles[]
+ // during this frame
+ // (makes spectating players much smoother and prevents mouse movement from turning)
+ cl.fixangle[1] = cl.fixangle[0];
+ cl.fixangle[0] = false;
+ if (!cls.demoplayback)
+ VectorCopy(cl.mviewangles[0], cl.mviewangles[1]);
// slightly kill qw player entities each frame
for (i = 1;i < cl.maxclients;i++)
cl.qw_num_nails = 0;
// fade weapon view kick
- cl.qw_weaponkick = min(cl.qw_weaponkick + 10 * cl.frametime, 0);
+ cl.qw_weaponkick = min(cl.qw_weaponkick + 10 * (cl.time - cl.oldtime), 0);
while (1)
{
case qw_svc_setangle:
for (i=0 ; i<3 ; i++)
cl.viewangles[i] = MSG_ReadAngle (cls.protocol);
+ if (!cls.demoplayback)
+ {
+ cl.fixangle[0] = true;
+ VectorCopy(cl.viewangles, cl.mviewangles[0]);
+ // disable interpolation if this is new
+ if (!cl.fixangle[1])
+ VectorCopy(cl.viewangles, cl.mviewangles[1]);
+ }
break;
case qw_svc_lightstyle:
cl.mtime[1] = cl.mtime[0];
cl.mtime[0] = MSG_ReadFloat ();
cl.movement_needupdate = true;
+ // if true the cl.viewangles are interpolated from cl.mviewangles[]
+ // during this frame
+ // (makes spectating players much smoother and prevents mouse movement from turning)
+ cl.fixangle[1] = cl.fixangle[0];
+ cl.fixangle[0] = false;
+ if (!cls.demoplayback)
+ VectorCopy(cl.mviewangles[0], cl.mviewangles[1]);
break;
case svc_clientdata:
case svc_setangle:
for (i=0 ; i<3 ; i++)
cl.viewangles[i] = MSG_ReadAngle (cls.protocol);
+ if (!cls.demoplayback)
+ {
+ cl.fixangle[0] = true;
+ VectorCopy(cl.viewangles, cl.mviewangles[0]);
+ // disable interpolation if this is new
+ if (!cl.fixangle[1])
+ VectorCopy(cl.viewangles, cl.mviewangles[1]);
+ }
break;
case svc_setview: