📄 cl_main.c
字号:
Determines the fraction between the last two messages that the objects
should be put at.
===============
*/
float CL_LerpPoint (void)
{
float f, frac;
f = cl.mtime[0] - cl.mtime[1];
if (!f || cl_nolerp->value || cls.timedemo || sv.active)
{
cl.time = cl.mtime[0];
return 1;
}
if (f > 0.1)
{ // dropped packet, or start of demo
cl.mtime[1] = cl.mtime[0] - 0.1;
f = 0.1;
}
frac = (cl.time - cl.mtime[1]) / f;
//Con_Printf ("frac: %f\n",frac);
if (frac < 0)
{
if (frac < -0.01)
{
SetPal(1);
cl.time = cl.mtime[1];
// Con_Printf ("low frac\n");
}
frac = 0;
}
else if (frac > 1)
{
if (frac > 1.01)
{
SetPal(2);
cl.time = cl.mtime[0];
// Con_Printf ("high frac\n");
}
frac = 1;
}
else
SetPal(0);
return frac;
}
/*
===============
CL_RelinkEntities
===============
*/
void CL_RelinkEntities (void)
{
entity_t *ent;
int i, j;
float frac, f, d;
vec3_t delta;
float bobjrotate;
vec3_t oldorg;
dlight_t *dl;
// determine partial update time
frac = CL_LerpPoint ();
cl_numvisedicts = 0;
//
// interpolate player info
//
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++)
{
d = cl.mviewangles[0][j] - cl.mviewangles[1][j];
if (d > 180)
d -= 360;
else if (d < -180)
d += 360;
cl.viewangles[j] = cl.mviewangles[1][j] + frac*d;
}
}
bobjrotate = anglemod(100*cl.time);
// start on the entity after the world
for (i=1,ent=cl_entities+1 ; i<cl.num_entities ; i++,ent++)
{
if (!ent->model)
{ // empty slot
if (ent->forcelink)
R_RemoveEfrags (ent); // just became empty
continue;
}
// if the object wasn't included in the last packet, remove it
if (ent->msgtime != cl.mtime[0])
{
ent->model = NULL;
continue;
}
VectorCopy (ent->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);
}
else
{ // if the delta is large, assume a teleport and don't lerp
f = frac;
for (j=0 ; j<3 ; j++)
{
delta[j] = ent->msg_origins[0][j] - ent->msg_origins[1][j];
if (delta[j] > 100 || delta[j] < -100)
f = 1; // assume a teleportation, not a motion
}
// interpolate the origin and angles
for (j=0 ; j<3 ; j++)
{
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;
}
}
// rotate binary objects locally
if (ent->model->flags & EF_ROTATE)
ent->angles[1] = bobjrotate;
if (ent->effects & EF_BRIGHTFIELD)
R_EntityParticles (ent);
#ifdef QUAKE2
if (ent->effects & EF_DARKFIELD)
R_DarkFieldParticles (ent);
#endif
if (ent->effects & EF_MUZZLEFLASH)
{
vec3_t fv, rv, uv;
dl = CL_AllocDlight (i);
VectorCopy (ent->origin, dl->origin);
dl->origin[2] += 16;
AngleVectors (ent->angles, fv, rv, uv);
VectorMA (dl->origin, 18, fv, dl->origin);
dl->radius = 200 + (rand()&31);
dl->minlight = 32;
dl->die = cl.time + 0.1;
}
if (ent->effects & EF_BRIGHTLIGHT)
{
dl = CL_AllocDlight (i);
VectorCopy (ent->origin, dl->origin);
dl->origin[2] += 16;
dl->radius = 400 + (rand()&31);
dl->die = cl.time + 0.001;
}
if (ent->effects & EF_DIMLIGHT)
{
dl = CL_AllocDlight (i);
VectorCopy (ent->origin, dl->origin);
dl->radius = 200 + (rand()&31);
dl->die = cl.time + 0.001;
}
#ifdef QUAKE2
if (ent->effects & EF_DARKLIGHT)
{
dl = CL_AllocDlight (i);
VectorCopy (ent->origin, dl->origin);
dl->radius = 200.0 + (rand()&31);
dl->die = cl.time + 0.001;
dl->dark = true;
}
if (ent->effects & EF_LIGHT)
{
dl = CL_AllocDlight (i);
VectorCopy (ent->origin, dl->origin);
dl->radius = 200;
dl->die = cl.time + 0.001;
}
#endif
if (ent->model->flags & EF_GIB)
R_RocketTrail (oldorg, ent->origin, 2);
else if (ent->model->flags & EF_ZOMGIB)
R_RocketTrail (oldorg, ent->origin, 4);
else if (ent->model->flags & EF_TRACER)
R_RocketTrail (oldorg, ent->origin, 3);
else if (ent->model->flags & EF_TRACER2)
R_RocketTrail (oldorg, ent->origin, 5);
else if (ent->model->flags & EF_ROCKET)
{
R_RocketTrail (oldorg, ent->origin, 0);
dl = CL_AllocDlight (i);
VectorCopy (ent->origin, dl->origin);
dl->radius = 200;
dl->die = cl.time + 0.01;
}
else if (ent->model->flags & EF_GRENADE)
R_RocketTrail (oldorg, ent->origin, 1);
else if (ent->model->flags & EF_TRACER3)
R_RocketTrail (oldorg, ent->origin, 6);
ent->forcelink = false;
if (i == cl.viewentity && !chase_active->value)
continue;
#ifdef QUAKE2
if ( ent->effects & EF_NODRAW )
continue;
#endif
if (cl_numvisedicts < MAX_VISEDICTS)
{
cl_visedicts[cl_numvisedicts] = ent;
cl_numvisedicts++;
}
}
}
/*
===============
CL_ReadFromServer
Read all incoming data from the server
===============
*/
int CL_ReadFromServer (void)
{
int ret;
cl.oldtime = cl.time;
cl.time += host_frametime;
do
{
ret = CL_GetMessage ();
if (ret == -1)
Host_Error ("CL_ReadFromServer: lost server connection");
if (!ret)
break;
cl.last_received_message = realtime;
CL_ParseServerMessage ();
} while (ret && cls.state == ca_connected);
if (cl_shownet->value)
Con_Printf ("\n");
CL_RelinkEntities ();
CL_UpdateTEnts ();
//
// bring the links up to date
//
return 0;
}
/*
=================
CL_SendCmd
=================
*/
void CL_SendCmd (void)
{
usercmd_t cmd;
if (cls.state != ca_connected)
return;
if (cls.signon == SIGNONS)
{
// get basic movement from keyboard
CL_BaseMove (&cmd);
// allow mice or other external controllers to add to the move
IN_Move (&cmd);
// send the unreliable message
CL_SendMove (&cmd);
}
if (cls.demoplayback)
{
SZ_Clear (&cls.message);
return;
}
// send the reliable message
if (!cls.message.cursize)
return; // no message at all
if (!NET_CanSendMessage (cls.netcon))
{
Con_DPrintf ("CL_WriteToServer: can't send\n");
return;
}
if (NET_SendMessage (cls.netcon, &cls.message) == -1)
Host_Error ("CL_WriteToServer: lost server connection");
SZ_Clear (&cls.message);
}
// 2001-12-16 M_LOOK cvar by Heffo/Maddes start
void Callback_M_Look (cvar_t *var)
{
if ( !((in_mlook.state & 1) ^ ((int)m_look->value & 1)) && lookspring->value)
V_StartPitchDrift();
}
// 2001-12-16 M_LOOK cvar by Heffo/Maddes end
// 2001-09-18 New cvar system by Maddes (Init) start
/*
=================
CL_Init_Cvars
=================
*/
void CL_Init_Cvars (void)
{
cl_name = Cvar_Get ("_cl_name", "player", CVAR_ARCHIVE|CVAR_ORIGINAL);
cl_color = Cvar_Get ("_cl_color", "0", CVAR_ARCHIVE|CVAR_ORIGINAL);
cl_upspeed = Cvar_Get ("cl_upspeed", "200", CVAR_ORIGINAL);
cl_forwardspeed = Cvar_Get ("cl_forwardspeed", "200", CVAR_ARCHIVE|CVAR_ORIGINAL);
cl_backspeed = Cvar_Get ("cl_backspeed", "200", CVAR_ARCHIVE|CVAR_ORIGINAL);
cl_sidespeed = Cvar_Get ("cl_sidespeed", "350", CVAR_ORIGINAL);
cl_movespeedkey = Cvar_Get ("cl_movespeedkey", "2.0", CVAR_ORIGINAL);
cl_yawspeed = Cvar_Get ("cl_yawspeed", "140", CVAR_ORIGINAL);
cl_pitchspeed = Cvar_Get ("cl_pitchspeed", "150", CVAR_ORIGINAL);
cl_anglespeedkey = Cvar_Get ("cl_anglespeedkey", "1.5", CVAR_ORIGINAL);
cl_shownet = Cvar_Get ("cl_shownet", "0", CVAR_ORIGINAL);
// 2001-09-18 New cvar system by Maddes start
Cvar_SetRangecheck (cl_shownet, Cvar_RangecheckInt, 0, 2);
Cvar_Set(cl_shownet, cl_shownet->string); // do rangecheck
// 2001-09-18 New cvar system by Maddes end
cl_nolerp = Cvar_Get ("cl_nolerp", "0", CVAR_ORIGINAL);
lookspring = Cvar_Get ("lookspring", "0", CVAR_ARCHIVE|CVAR_ORIGINAL);
lookstrafe = Cvar_Get ("lookstrafe", "0", CVAR_ARCHIVE|CVAR_ORIGINAL);
sensitivity = Cvar_Get ("sensitivity", "3", CVAR_ARCHIVE|CVAR_ORIGINAL);
m_pitch = Cvar_Get ("m_pitch", "0.022", CVAR_ARCHIVE|CVAR_ORIGINAL);
m_yaw = Cvar_Get ("m_yaw", "0.022", CVAR_ARCHIVE|CVAR_ORIGINAL);
m_forward = Cvar_Get ("m_forward", "1", CVAR_ARCHIVE|CVAR_ORIGINAL);
m_side = Cvar_Get ("m_side", "0.8", CVAR_ARCHIVE|CVAR_ORIGINAL);
// 2001-12-16 M_LOOK cvar by Heffo/Maddes start
m_look = Cvar_Get ("m_look", "0", CVAR_ARCHIVE);
Cvar_SetRangecheck (m_look, Cvar_RangecheckBool, 0, 1);
Cvar_SetCallback (m_look, Callback_M_Look);
Cvar_Set(m_look, m_look->string); // do rangecheck
// 2001-12-16 M_LOOK cvar by Heffo/Maddes end
// 2001-11-31 FPS display by QuakeForge/Muff start
cl_showfps = Cvar_Get ("cl_showfps", "0", CVAR_NONE);
Cvar_SetRangecheck (cl_showfps, Cvar_RangecheckBool, 0, 1);
Cvar_Set(cl_showfps, cl_showfps->string); // do rangecheck
// 2001-11-31 FPS display by QuakeForge/Muff end
// 2001-12-24 Keeping full backwards compatibility by Maddes start
cl_compatibility = Cvar_Get ("cl_compatibility", "0", CVAR_ARCHIVE);
Cvar_SetRangecheck (cl_compatibility, Cvar_RangecheckBool, 0, 1);
Cvar_SetDescription (cl_compatibility, "When set to 1, this client will not request enhanced information from the server (server's entity limit, NVS handshake, etc.) and disables enhanced client messages (precise client aiming, etc.). This is necessary for recording demos that shall run on all Quake executables. Also see SV_COMPATIBILITY.");
Cvar_Set(cl_compatibility, cl_compatibility->string); // do rangecheck
// 2001-12-24 Keeping full backwards compatibility by Maddes end
// 2001-09-20 Configurable entity limits by Maddes start
cl_entities_min = Cvar_Get ("cl_entities_min", "0", CVAR_NONE);
Cvar_SetRangecheck (cl_entities_min, Cvar_RangecheckInt, MIN_EDICTS, MAX_EDICTS);
Cvar_Set(cl_entities_min, cl_entities_min->string); // do rangecheck
cl_entities_min_static = Cvar_Get ("cl_entities_min_static", "0", CVAR_NONE);
Cvar_SetRangecheck (cl_entities_min_static, Cvar_RangecheckInt, MIN_STATIC_ENTITIES, MAX_EDICTS);
Cvar_Set(cl_entities_min_static, cl_entities_min_static->string); // do rangecheck
cl_entities_min_temp = Cvar_Get ("cl_entities_min_temp", "0", CVAR_NONE);
Cvar_SetRangecheck (cl_entities_min_temp, Cvar_RangecheckInt, MIN_TEMP_ENTITIES, MAX_EDICTS);
Cvar_Set(cl_entities_min_temp, cl_entities_min_temp->string); // do rangecheck
// 2001-09-20 Configurable entity limits by Maddes end
}
// 2001-09-18 New cvar system by Maddes (Init) end
/*
=================
CL_Init
=================
*/
void CL_Init (void)
{
SZ_Alloc (&cls.message, 1024);
CL_InitInput ();
CL_InitTEnts ();
//
// register our commands
//
// 2001-09-18 New cvar system by Maddes (Init) start
/*
cl_name = Cvar_Get ("_cl_name", "player", CVAR_ARCHIVE|CVAR_ORIGINAL);
cl_color = Cvar_Get ("_cl_color", "0", CVAR_ARCHIVE|CVAR_ORIGINAL);
cl_upspeed = Cvar_Get ("cl_upspeed", "200", CVAR_ORIGINAL);
cl_forwardspeed = Cvar_Get ("cl_forwardspeed", "200", CVAR_ARCHIVE|CVAR_ORIGINAL);
cl_backspeed = Cvar_Get ("cl_backspeed", "200", CVAR_ARCHIVE|CVAR_ORIGINAL);
cl_sidespeed = Cvar_Get ("cl_sidespeed", "350", CVAR_ORIGINAL);
cl_movespeedkey = Cvar_Get ("cl_movespeedkey", "2.0", CVAR_ORIGINAL);
cl_yawspeed = Cvar_Get ("cl_yawspeed", "140", CVAR_ORIGINAL);
cl_pitchspeed = Cvar_Get ("cl_pitchspeed", "150", CVAR_ORIGINAL);
cl_anglespeedkey = Cvar_Get ("cl_anglespeedkey", "1.5", CVAR_ORIGINAL);
cl_shownet = Cvar_Get ("cl_shownet", "0", CVAR_ORIGINAL);
// 2001-09-18 New cvar system by Maddes start
Cvar_SetRangecheck (cl_shownet, Cvar_RangecheckInt, 0, 2);
Cvar_Set(cl_shownet, cl_shownet->string); // do rangecheck
// 2001-09-18 New cvar system by Maddes end
cl_nolerp = Cvar_Get ("cl_nolerp", "0", CVAR_ORIGINAL);
lookspring = Cvar_Get ("lookspring", "0", CVAR_ARCHIVE|CVAR_ORIGINAL);
lookstrafe = Cvar_Get ("lookstrafe", "0", CVAR_ARCHIVE|CVAR_ORIGINAL);
sensitivity = Cvar_Get ("sensitivity", "3", CVAR_ARCHIVE|CVAR_ORIGINAL);
m_pitch = Cvar_Get ("m_pitch", "0.022", CVAR_ARCHIVE|CVAR_ORIGINAL);
m_yaw = Cvar_Get ("m_yaw", "0.022", CVAR_ARCHIVE|CVAR_ORIGINAL);
m_forward = Cvar_Get ("m_forward", "1", CVAR_ARCHIVE|CVAR_ORIGINAL);
m_side = Cvar_Get ("m_side", "0.8", CVAR_ARCHIVE|CVAR_ORIGINAL);
*/
// 2001-09-18 New cvar system by Maddes (Init) end
// Cvar_RegisterVariable (&cl_autofire);
Cmd_AddCommand ("entities", CL_PrintEntities_f);
Cmd_AddCommand ("disconnect", CL_Disconnect_f);
Cmd_AddCommand ("record", CL_Record_f);
Cmd_AddCommand ("stop", CL_Stop_f);
Cmd_AddCommand ("playdemo", CL_PlayDemo_f);
Cmd_AddCommand ("timedemo", CL_TimeDemo_f);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -