Esempio n. 1
0
/*
================
CL_ParseFrame
================
*/
void CL_ParseFrame (void)
{
	int			cmd;
	int			len;
	frame_t		*old;

	memset (&cl.frame, 0, sizeof(cl.frame));
	cl.frame.serverframe = MSG_ReadLong(&net_message);
	cl.frame.deltaframe = MSG_ReadLong(&net_message);
	cl.frame.servertime = cl.frame.serverframe*100;

	// BIG HACK to let old demos continue to work
	if (cls.serverProtocol != 26)
		cl.surpressCount = MSG_ReadByte(&net_message);

	if (cl_shownet->value == 3)
		Com_Printf ("   frame:%i  delta:%i\n", cl.frame.serverframe, cl.frame.deltaframe);

	// If the frame is delta compressed from data that we
	// no longer have available, we must suck up the rest of
	// the frame, but not use it, then ask for a non-compressed
	// message 
	if (cl.frame.deltaframe <= 0)
	{
		cl.frame.valid = true;		// uncompressed frame
		old = NULL;
		cls.demowaiting = false;	// we can start recording now
	}
	else
	{
		old = &cl.frames[cl.frame.deltaframe & UPDATE_MASK];

		if (!old->valid)
		{	// should never happen
			Com_Printf ("Delta from invalid frame (not supposed to happen!).\n");
		}
		if (old->serverframe != cl.frame.deltaframe)
		{	// The frame that the server did the delta from
			// is too old, so we can't reconstruct it properly.
			Com_Printf ("Delta frame too old.\n");
		}
		else if (cl.parse_entities - old->parse_entities > MAX_PARSE_ENTITIES-128)
		{
			Com_Printf ("Delta parse_entities too old.\n");
		}
		else
		{
			cl.frame.valid = true;	// valid delta parse
		}
	}

	// clamp time 
	if (cl.time > cl.frame.servertime)
		cl.time = cl.frame.servertime;
	else if (cl.time < cl.frame.servertime - 100)
		cl.time = cl.frame.servertime - 100;

	// read areabits
	len = MSG_ReadByte(&net_message);
	MSG_ReadData(&net_message, &cl.frame.areabits, len);

	// read playerinfo
	cmd = MSG_ReadByte(&net_message);
	SHOWNET(svc_strings[cmd]);

	if (cmd != svc_playerinfo)
		Com_Error(ERR_DROP, "CL_ParseFrame: not playerinfo");

	CL_ParsePlayerstate(old, &cl.frame);

	// read packet entities
	cmd = MSG_ReadByte(&net_message);
	SHOWNET(svc_strings[cmd]);

	if (cmd != svc_packetentities)
		Com_Error(ERR_DROP, "CL_ParseFrame: not packetentities");

	CL_ParsePacketEntities(old, &cl.frame);


	// save the frame off in the backup array for later delta comparisons
	cl.frames[cl.frame.serverframe & UPDATE_MASK] = cl.frame;

	if (cl.frame.valid)
	{
		// getting a valid frame message ends the connection process
		if (cls.state != ca_active)
		{
			cls.state = ca_active;
			//cl_scores_setinuse_all(false); // jitscores - clear scoreboard
			cl.force_refdef = true;
			cl.predicted_origin[0] = cl.frame.playerstate.pmove.origin[0]*0.125;
			cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1]*0.125;
			cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2]*0.125;
			VectorCopy(cl.frame.playerstate.viewangles, cl.predicted_angles);

			if (cls.disable_servercount != cl.servercount && cl.refresh_prepped)
				SCR_EndLoadingPlaque();	// get rid of loading plaque
		}

		cl.sound_prepped = true;	// can start mixing ambient sounds

		// fire entity events
		CL_FireEntityEvents(&cl.frame);
		CL_CheckPredictionError();
	}
}
Esempio n. 2
0
/*
==================
CL_DeltaFrame

A valid frame has been parsed.
==================
*/
void CL_DeltaFrame(void)
{
    centity_t           *ent;
    entity_state_t      *state;
    int                 i, j;
    int                 framenum;

    // getting a valid frame message ends the connection process
    if (cls.state == ca_precached)
        set_active_state();

    // set server time
    framenum = cl.frame.number - cl.serverdelta;
    cl.servertime = framenum * CL_FRAMETIME;
#if USE_FPS
    cl.keyservertime = (framenum / cl.framediv) * BASE_FRAMETIME;
#endif

    // rebuild the list of solid entities for this frame
    cl.numSolidEntities = 0;

    // initialize position of the player's own entity from playerstate.
    // this is needed in situations when player entity is invisible, but
    // server sends an effect referencing it's origin (such as MZ_LOGIN, etc)
    ent = &cl_entities[cl.frame.clientNum + 1];
    Com_PlayerToEntityState(&cl.frame.ps, &ent->current);

    for (i = 0; i < cl.frame.numEntities; i++) {
        j = (cl.frame.firstEntity + i) & PARSE_ENTITIES_MASK;
        state = &cl.entityStates[j];

        // set current and prev
        entity_update(state);

        // fire events
        entity_event(state->number);
    }

    if (cls.demo.recording && !cls.demo.paused && !cls.demo.seeking && CL_FRAMESYNC) {
        CL_EmitDemoFrame();
    }

    if (cls.demo.playback) {
        // this delta has nothing to do with local viewangles,
        // clear it to avoid interfering with demo freelook hack
        VectorClear(cl.frame.ps.pmove.delta_angles);
    }

    if (cl.oldframe.ps.pmove.pm_type != cl.frame.ps.pmove.pm_type) {
        IN_Activate();
    }

    player_update(&cl.oldframe, &cl.frame, 1);

#if USE_FPS
    if (CL_FRAMESYNC)
        player_update(&cl.oldkeyframe, &cl.keyframe, cl.framediv);
#endif

    CL_CheckPredictionError();

    SCR_SetCrosshairColor();
}
Esempio n. 3
0
void
CL_ParseFrame(void)
{
    int cmd;
    int len;
    frame_t *old;

    memset(&cl.frame, 0, sizeof(cl.frame));

    cl.frame.serverframe = MSG_ReadLong(&net_message);
    cl.frame.deltaframe = MSG_ReadLong(&net_message);
    cl.frame.servertime = cl.frame.serverframe * 100;

    /* BIG HACK to let old demos continue to work */
    if (cls.serverProtocol != 26)
    {
        cl.surpressCount = MSG_ReadByte(&net_message);
    }

    if (cl_shownet->value == 3)
    {
        Com_Printf("   frame:%i  delta:%i\n", cl.frame.serverframe,
                   cl.frame.deltaframe);
    }

    /* If the frame is delta compressed from data that we
       no longer have available, we must suck up the rest of
       the frame, but not use it, then ask for a non-compressed
       message */
    if (cl.frame.deltaframe <= 0)
    {
        cl.frame.valid = true; /* uncompressed frame */
        old = NULL;
        cls.demowaiting = false; /* we can start recording now */
    }
    else
    {
        old = &cl.frames[cl.frame.deltaframe & UPDATE_MASK];

        if (!old->valid)
        {
            /* should never happen */
            Com_Printf("Delta from invalid frame (not supposed to happen!).\n");
        }

        if (old->serverframe != cl.frame.deltaframe)
        {
            /* The frame that the server did the delta from
               is too old, so we can't reconstruct it properly. */
            Com_Printf("Delta frame too old.\n");
        }
        else if (cl.parse_entities - old->parse_entities > MAX_PARSE_ENTITIES -
                 128)
        {
            Com_Printf("Delta parse_entities too old.\n");
        }
        else
        {
            cl.frame.valid = true; /* valid delta parse */
        }
    }

    /* clamp time */
    if (cl.time > cl.frame.servertime)
    {
        cl.time = cl.frame.servertime;
    }

    else if (cl.time < cl.frame.servertime - 100)
    {
        cl.time = cl.frame.servertime - 100;
    }

    /* read areabits */
    len = MSG_ReadByte(&net_message);
    MSG_ReadData(&net_message, &cl.frame.areabits, len);

    /* read playerinfo */
    cmd = MSG_ReadByte(&net_message);
    SHOWNET(svc_strings[cmd]);

    if (cmd != svc_playerinfo)
    {
        Com_Error(ERR_DROP, "CL_ParseFrame: 0x%X not playerinfo", cmd);
    }

    CL_ParsePlayerstate(old, &cl.frame);

    /* read packet entities */
    cmd = MSG_ReadByte(&net_message);
    SHOWNET(svc_strings[cmd]);

    if (cmd != svc_packetentities)
    {
        Com_Error(ERR_DROP, "CL_ParseFrame: 0x%X not packetentities", cmd);
    }

    CL_ParsePacketEntities(old, &cl.frame);

    /* save the frame off in the backup array for later delta comparisons */
    cl.frames[cl.frame.serverframe & UPDATE_MASK] = cl.frame;

    if (cl.frame.valid)
    {
        /* getting a valid frame message ends the connection process */
        if (cls.state != ca_active)
        {
            cls.state = ca_active;
            cl.force_refdef = true;
            cl.predicted_origin[0] = cl.frame.playerstate.pmove.origin[0] * 0.125f;
            cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1] * 0.125f;
            cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2] * 0.125f;
            VectorCopy(cl.frame.playerstate.viewangles, cl.predicted_angles);

            if ((cls.disable_servercount != cl.servercount) && cl.refresh_prepped)
            {
                SCR_EndLoadingPlaque();  /* get rid of loading plaque */
            }

            cl.sound_prepped = true;
        }

        /* fire entity events */
        CL_FireEntityEvents(&cl.frame);

        if (!(!cl_predict->value ||
                (cl.frame.playerstate.pmove.pm_flags &
                 PMF_NO_PREDICTION)))
        {
            CL_CheckPredictionError();
        }
    }
}