Example #1
0
/*
===============
V_SetupRefDef

update refdef values each frame
===============
*/
void V_SetupRefDef( void )
{
	cl_entity_t	*clent;

	clent = CL_GetLocalPlayer ();

	clgame.entities->curstate.scale = clgame.movevars.waveHeight;
	VectorCopy( cl.frame.local.client.punchangle, cl.refdef.punchangle );
	clgame.viewent.curstate.modelindex = cl.frame.local.client.viewmodel;
	clgame.viewent.model = Mod_Handle( clgame.viewent.curstate.modelindex );
	clgame.viewent.curstate.entityType = ET_NORMAL;
	clgame.viewent.index = cl.playernum + 1;

	cl.refdef.movevars = &clgame.movevars;
	cl.refdef.onground = ( cl.frame.local.client.flags & FL_ONGROUND ) ? 1 : 0;
	cl.refdef.health = cl.frame.local.client.health;
	cl.refdef.playernum = cl.playernum;
	cl.refdef.max_entities = clgame.maxEntities;
	cl.refdef.maxclients = cl.maxclients;
	cl.refdef.time = cl.time;
	cl.refdef.frametime = cl.time - cl.oldtime;
	cl.refdef.demoplayback = cls.demoplayback;
	cl.refdef.smoothing = cl_smooth->integer;
	cl.refdef.waterlevel = cl.frame.local.client.waterlevel;		
	cl.refdef.onlyClientDraw = 0;	// reset clientdraw
	cl.refdef.viewsize = scr_viewsize->integer;
	cl.refdef.hardware = true;	// always true
	cl.refdef.spectator = cl.spectator;
	cl.refdef.nextView = 0;

	// setup default viewport
	cl.refdef.viewport[0] = cl.refdef.viewport[1] = 0;
	cl.refdef.viewport[2] = scr_width->integer;
	cl.refdef.viewport[3] = scr_height->integer;

	// calc FOV
	cl.refdef.fov_x = cl.data.fov; // this is a final fov value
	cl.refdef.fov_y = V_CalcFov( &cl.refdef.fov_x, cl.refdef.viewport[2], cl.refdef.viewport[3] );

	if( CL_IsPredicted( ) && !cl.refdef.demoplayback )
	{	
		VectorCopy( cl.predicted_origin, cl.refdef.simorg );
		VectorCopy( cl.predicted_velocity, cl.refdef.simvel );
		VectorCopy( cl.predicted_viewofs, cl.refdef.viewheight );
	}
	else
	{
		VectorCopy( cl.frame.local.client.origin, cl.refdef.simorg );
		VectorCopy( cl.frame.local.client.view_ofs, cl.refdef.viewheight );
		VectorCopy( cl.frame.local.client.velocity, cl.refdef.simvel );
	}
}
Example #2
0
/*
===============
V_SetupRefDef

update refdef values each frame
===============
*/
void V_SetupRefDef( void )
{
	cl_entity_t	*clent;
	int		size;
	int		sb_lines;

	clent = CL_GetLocalPlayer ();

	clgame.entities->curstate.scale = clgame.movevars.waveHeight;
	VectorCopy( cl.frame.local.client.punchangle, cl.refdef.punchangle );
	clgame.viewent.curstate.modelindex = cl.frame.local.client.viewmodel;
	clgame.viewent.model = Mod_Handle( clgame.viewent.curstate.modelindex );
	clgame.viewent.curstate.number = cl.playernum + 1;
	clgame.viewent.curstate.entityType = ET_NORMAL;
	clgame.viewent.index = cl.playernum + 1;

	cl.refdef.movevars = &clgame.movevars;
	cl.refdef.onground = ( cl.frame.local.client.flags & FL_ONGROUND ) ? 1 : 0;
	cl.refdef.health = cl.frame.local.client.health;
	cl.refdef.playernum = cl.playernum;
	cl.refdef.max_entities = clgame.maxEntities;
	cl.refdef.maxclients = cl.maxclients;
	cl.refdef.time = cl.time;
	cl.refdef.frametime = cl.time - cl.oldtime;
	cl.refdef.demoplayback = cls.demoplayback;
	cl.refdef.smoothing = cl_smooth->integer;
	cl.refdef.viewsize = scr_viewsize->integer;
	cl.refdef.waterlevel = cl.frame.local.client.waterlevel;		
	cl.refdef.onlyClientDraw = 0;	// reset clientdraw
	cl.refdef.hardware = true;	// always true
	cl.refdef.spectator = (clent->curstate.spectator != 0);
	cl.refdef.nextView = 0;

	SCR_AddDirtyPoint( 0, 0 );
	SCR_AddDirtyPoint( scr_width->integer - 1, scr_height->integer - 1 );

	if( cl.refdef.viewsize >= 120 )
		sb_lines = 0;		// no status bar at all
	else if( cl.refdef.viewsize >= 110 )
		sb_lines = 24;		// no inventory
	else sb_lines = 48;

	size = min( scr_viewsize->integer, 100 );

	cl.refdef.viewport[2] = scr_width->integer * size / 100;
	cl.refdef.viewport[3] = scr_height->integer * size / 100;

	if( cl.refdef.viewport[3] > scr_height->integer - sb_lines )
		cl.refdef.viewport[3] = scr_height->integer - sb_lines;
	if( cl.refdef.viewport[3] > scr_height->integer )
		cl.refdef.viewport[3] = scr_height->integer;

	cl.refdef.viewport[0] = (scr_width->integer - cl.refdef.viewport[2]) / 2;
	cl.refdef.viewport[1] = (scr_height->integer - sb_lines - cl.refdef.viewport[3]) / 2;

	// calc FOV
	cl.refdef.fov_x = cl.data.fov; // this is a final fov value
	cl.refdef.fov_y = V_CalcFov( &cl.refdef.fov_x, cl.refdef.viewport[2], cl.refdef.viewport[3] );

	// adjust FOV for widescreen
	if( glState.wideScreen && r_adjust_fov->integer )
		V_AdjustFov( &cl.refdef.fov_x, &cl.refdef.fov_y, cl.refdef.viewport[2], cl.refdef.viewport[3], false );

	if( CL_IsPredicted( ) && !cl.refdef.demoplayback )
	{	
		VectorCopy( cl.predicted_origin, cl.refdef.simorg );
		VectorCopy( cl.predicted_velocity, cl.refdef.simvel );
		VectorCopy( cl.predicted_viewofs, cl.refdef.viewheight );
	}
	else
	{
		VectorCopy( cl.frame.local.client.origin, cl.refdef.simorg );
		VectorCopy( cl.frame.local.client.view_ofs, cl.refdef.viewheight );
		VectorCopy( cl.frame.local.client.velocity, cl.refdef.simvel );
	}
}
Example #3
0
/*
=============
CL_ParseEvent

=============
*/
void CL_ParseEvent( sizebuf_t *msg )
{
	int		event_index;
	int		i, num_events;
	int		packet_ent;
	event_args_t	nullargs, args;
	qboolean		has_update;
	entity_state_t	*state;
	cl_entity_t	*pEnt;
	float		delay;

	Q_memset( &nullargs, 0, sizeof( nullargs ));

	num_events = BF_ReadUBitLong( msg, 5 );

	// parse events queue
	for( i = 0 ; i < num_events; i++ )
	{
		event_index = BF_ReadUBitLong( msg, MAX_EVENT_BITS );
		Q_memset( &args, 0, sizeof( args ));
		has_update = false;

		if( BF_ReadOneBit( msg ))
		{
			packet_ent = BF_ReadUBitLong( msg, MAX_ENTITY_BITS );

			if( BF_ReadOneBit( msg ))
			{
				MSG_ReadDeltaEvent( msg, &nullargs, &args );
				has_update = true;
			}
		}
		else packet_ent = -1;

		if( packet_ent != -1 )
			state = &cls.packet_entities[(cl.frame.first_entity+packet_ent)%cls.num_client_entities];
		else state = NULL;

		// it's a client. Override some params
		if( args.entindex >= 1 && args.entindex <= cl.maxclients )
		{
			if(( args.entindex - 1 ) == cl.playernum )
			{
				if( state && !CL_IsPredicted( ))
				{
					// restore viewangles from angles
					args.angles[PITCH] = -state->angles[PITCH] * 3;
					args.angles[YAW] = state->angles[YAW];
					args.angles[ROLL] = 0; // no roll
				}
				else
				{
					// get the predicted angles
					VectorCopy( cl.refdef.cl_viewangles, args.angles );
				}

				VectorCopy( cl.frame.local.client.origin, args.origin );
				VectorCopy( cl.frame.local.client.velocity, args.velocity );
			}
			else if( state )
			{
				// restore viewangles from angles
				args.angles[PITCH] = -state->angles[PITCH] * 3;
				args.angles[YAW] = state->angles[YAW];
				args.angles[ROLL] = 0; // no roll

				// if we restore origin and velocity everytime, why don't do it here also?
				if( VectorIsNull( args.origin ))
					VectorCopy( state->origin, args.origin );
				if( VectorIsNull( args.velocity ))
					VectorCopy( state->velocity, args.velocity );
			}
		}
		else if( state )
		{
			if( VectorIsNull( args.origin ))
				VectorCopy( state->origin, args.origin );
			if( VectorIsNull( args.angles ))
				VectorCopy( state->angles, args.angles );
			if( VectorIsNull( args.velocity ))
				VectorCopy( state->velocity, args.velocity );
		}
		else if(( pEnt = CL_GetEntityByIndex( args.entindex )) != NULL )
		{
			if( VectorIsNull( args.origin ))
				VectorCopy( pEnt->curstate.origin, args.origin );
			if( VectorIsNull( args.angles ))
				VectorCopy( pEnt->curstate.angles, args.angles );
			if( VectorIsNull( args.velocity ))
				VectorCopy( pEnt->curstate.velocity, args.velocity );
		}

		if( BF_ReadOneBit( msg ))
			delay = (float)BF_ReadWord( msg ) * (1.0f / 100.0f);
		else delay = 0.0f;

		// g-cont. should we need find the event with same index?
		CL_QueueEvent( 0, event_index, delay, &args );
	}
}
Example #4
0
/*
=================
CL_PredictMovement

Sets cl.predicted_origin and cl.predicted_angles
=================
*/
void CL_PredictMovement( void )
{
	int		frame = 1;
	int		ack, outgoing_command;
	int		current_command;
	int		current_command_mod;
	cl_entity_t	*player, *viewent;
	clientdata_t	*cd;

	if( cls.state != ca_active ) return;

	if( cls.demoplayback && cl.refdef.cmd != NULL )
	{
		// restore viewangles from cmd.angles
		VectorCopy( cl.refdef.cmd->viewangles, cl.refdef.cl_viewangles );
	}

	if( cl.refdef.paused || cls.key_dest == key_menu ) return;

	player = CL_GetLocalPlayer ();
	viewent = CL_GetEntityByIndex( cl.refdef.viewentity );
	cd = &cl.frame.local.client;

	// unpredicted pure angled values converted into axis
	AngleVectors( cl.refdef.cl_viewangles, cl.refdef.forward, cl.refdef.right, cl.refdef.up );

	if( !CL_IsPredicted( ))
	{	
		// run commands even if client predicting is disabled - client expected it
		clgame.pmove->runfuncs = true;
		CL_PostRunCmd( cl.refdef.cmd, cls.lastoutgoingcommand );
		return;
	}

	ack = cls.netchan.incoming_acknowledged;
	outgoing_command = cls.netchan.outgoing_sequence;

	ASSERT( cl.refdef.cmd != NULL );

	// setup initial pmove state
	CL_SetupPMove( clgame.pmove, cd, &player->curstate, cl.refdef.cmd );
	clgame.pmove->runfuncs = false;

	while( 1 )
	{
		// we've run too far forward
		if( frame >= CL_UPDATE_BACKUP - 1 )
			break;

		// Incoming_acknowledged is the last usercmd the server acknowledged having acted upon
		current_command = ack + frame;
		current_command_mod = current_command & CL_UPDATE_MASK;

		// we've caught up to the current command.
		if( current_command >= outgoing_command )
			break;

		clgame.pmove->cmd = cl.cmds[current_command_mod];

		// motor!
		clgame.dllFuncs.pfnPlayerMove( clgame.pmove, false ); // run frames
		clgame.pmove->runfuncs = ( current_command > outgoing_command - 1 ) ? true : false;

		frame++;
	}

	CL_PostRunCmd( cl.refdef.cmd, frame );
		
	// copy results out for rendering
	VectorCopy( clgame.pmove->view_ofs, cl.predicted_viewofs );
	VectorCopy( clgame.pmove->origin, cl.predicted_origin );
	VectorCopy( clgame.pmove->velocity, cl.predicted_velocity );
}
Example #5
0
/*
=================
CL_PredictMovement

Sets cl.predicted_origin and cl.predicted_angles
=================
*/
void CL_PredictMovement( void )
{
    double	time;
    int		frame = 1;
    int		ack, outgoing_command;
    int		current_command;
    int		current_command_mod;
    local_state_t *from = 0, *to = 0;

    if( cls.state != ca_active ) return;

    if( cls.demoplayback && cl.refdef.cmd != NULL )
    {
        // restore viewangles from cmd.angles
        VectorCopy( cl.refdef.cmd->viewangles, cl.refdef.cl_viewangles );
    }

    if( cl.refdef.paused || cls.key_dest == key_menu ) return;

    pfnSetUpPlayerPrediction( false, false );

    // unpredicted pure angled values converted into axis
    AngleVectors( cl.refdef.cl_viewangles, cl.refdef.forward, cl.refdef.right, cl.refdef.up );

    ASSERT( cl.refdef.cmd != NULL );
    if( !cl_predict->integer || Host_IsLocalClient() )
    {
        // fake prediction code
        // we need to perform cl_lw prediction while cl_predict is disabled
        // because cl_lw is enabled by default in Half-Life
        if( !cl_lw->integer )
            return;

        ack = cls.netchan.incoming_acknowledged;
        outgoing_command = cls.netchan.outgoing_sequence;

        from = &cl.predict[cl.parsecountmod];
        from->playerstate = cl.frame.playerstate[cl.playernum];
        from->client = cl.frame.local.client;
        Q_memcpy( from->weapondata, cl.frame.local.weapondata, sizeof( from->weapondata ));

        time = cl.frame.time;

        while( 1 )
        {
            // we've run too far forward
            if( frame >= CL_UPDATE_BACKUP - 1 )
                break;

            // Incoming_acknowledged is the last usercmd the server acknowledged having acted upon
            current_command = ack + frame;
            current_command_mod = current_command & CL_UPDATE_MASK;

            // we've caught up to the current command.
            if( current_command >= outgoing_command )
                break;

            to = &cl.predict[( cl.parsecountmod + frame ) & CL_UPDATE_MASK];

            CL_FakeUsercmd( from, to, &cl.cmds[current_command_mod],
                            cl.runfuncs[current_command_mod],
                            &time, cls.netchan.incoming_acknowledged + frame );

            cl.runfuncs[current_command_mod] = false;

            from = to;
            frame++;
        }

        if( to )
        {
            cl.predicted_viewmodel = to->client.viewmodel;
            cl.scr_fov = to->client.fov;
            if( cl.scr_fov < 1.0f || cl.scr_fov> 170.0f )
                cl.scr_fov = 90.0f;
        }
        return;
    }

    if( !CL_IsPredicted( ))
    {
        local_state_t t1, t2;
        Q_memset( &t1, 0, sizeof( local_state_t ));
        Q_memset( &t2, 0, sizeof( local_state_t ));
        clgame.dllFuncs.pfnPostRunCmd( &t1, &t2, cl.refdef.cmd, false, cl.time, cls.lastoutgoingcommand );

        cl.scr_fov = t2.client.fov;
        if( cl.scr_fov < 1.0f || cl.scr_fov> 170.0f )
            cl.scr_fov = 90.0f;
        return;
    }

    ack = cls.netchan.incoming_acknowledged;
    outgoing_command = cls.netchan.outgoing_sequence;

    from = &cl.predict[cl.parsecountmod];
    from->playerstate = cl.frame.playerstate[cl.playernum];
    from->client = cl.frame.local.client;
    Q_memcpy( from->weapondata, cl.frame.local.weapondata, sizeof( from->weapondata ));

    time = cl.frame.time;

    CL_SetSolidEntities ();
    CL_SetSolidPlayers ( cl.playernum );

    while( 1 )
    {
        // we've run too far forward
        if( frame >= CL_UPDATE_BACKUP - 1 )
            break;

        // Incoming_acknowledged is the last usercmd the server acknowledged having acted upon
        current_command = ack + frame;
        current_command_mod = current_command & CL_UPDATE_MASK;

        // we've caught up to the current command.
        if( current_command >= outgoing_command )
            break;

        to = &cl.predict[( cl.parsecountmod + frame ) & CL_UPDATE_MASK];

        CL_RunUsercmd( from, to, &cl.cmds[current_command_mod],
                       cl.runfuncs[current_command_mod],
                       &time, cls.netchan.incoming_acknowledged + frame );

        cl.runfuncs[current_command_mod] = false;

        from = to;
        frame++;
    }

    if( to )
    {
        cl.predicted_viewmodel = to->client.viewmodel;
        cl.scr_fov = to->client.fov;
        if( cl.scr_fov < 1.0f || cl.scr_fov> 170.0f )
            cl.scr_fov = 90.0f;
        VectorCopy( to->playerstate.origin, cl.predicted_origin );
        VectorCopy( to->client.velocity, cl.predicted_velocity );
        VectorCopy( to->client.view_ofs, cl.predicted_viewofs );
        VectorCopy( to->client.punchangle, cl.predicted_punchangle );
    }
}
/*
=================
CL_PredictMovement

Sets cl.predicted_origin and cl.predicted_angles
=================
*/
void CL_PredictMovement()
{
	int	frame;
	int	ack, outgoing_command;
	int	current_command;
	int	current_command_mod;
	cl_entity_t	*player, *viewent;
	clientdata_t	*cd;

	if( cls.state != ca_active )
		return;

	if( cls.demoplayback && cl.refdef.cmd != NULL )
		VectorCopy( cl.refdef.cmd->viewangles, cl.refdef.cl_viewangles ); // restore viewangles from cmd.angles

	if(cl.refdef.paused /*|| cls.key_dest == key_menu*/)
		//return;

	player = CL_GetLocalPlayer ();
	viewent = CL_GetEntityByIndex( cl.refdef.viewentity );
	cd = &cl.frame.local.client;

	// unpredicted pure angled values converted into axis
	AngleVectors( cl.refdef.cl_viewangles, cl.refdef.forward, cl.refdef.right, cl.refdef.up );

	if( !CL_IsPredicted( ))
	{	
		// run commands even if client predicting is disabled - client expect it
		clgame.pmove->runfuncs = true;
		CL_PostRunCmd( cl.refdef.cmd, cls.lastoutgoingcommand );
		return;
	};

	ack = cls.netchan.incoming_acknowledged;
	outgoing_command = cls.netchan.outgoing_sequence;
	
	// if we are too far out of date, just freeze
	if(outgoing_command - ack >= CL_UPDATE_BACKUP)
	{
		//if(cl_showmiss->value)
			//Com_Printf ("exceeded CL_UPDATE_BACKUP\n");
		return;	
	};

	ASSERT( cl.refdef.cmd != NULL );

	// setup initial pmove state
	CL_SetupPMove( clgame.pmove, cd, &player->curstate, cl.refdef.cmd );
	clgame.pmove->runfuncs = false;
	
	frame = 0;

	while(++ack < outgoing_command)
	{
		// we've run too far forward
		//if( frame >= CL_UPDATE_BACKUP - 1 )
		//	break;
		
		frame = ack & (CL_UPDATE_BACKUP - 1);

		// Incoming_acknowledged is the last usercmd the server acknowledged having acted upon
		current_command = ack + frame;
		current_command_mod = current_command & CL_UPDATE_MASK;

		// we've caught up to the current command
		// this was the most up to date command
		if(current_command >= outgoing_command)
			break;

		clgame.pmove->cmd = cl.cmds[current_command_mod];

		// Call the client dll player movement function (and it will call the PM_Move())
		clgame.dllFuncs.pfnPlayerMove(clgame.pmove, false); // run frames
		clgame.pmove->runfuncs = ( current_command > outgoing_command - 1 ) ? true : false; // Prevent to play sounds/etc more that once
		
		frame++;
	};

	CL_PostRunCmd( cl.refdef.cmd, cls.lastoutgoingcommand );

	// copy results out for rendering
	VectorCopy( clgame.pmove->view_ofs, cl.predicted_viewofs );
	VectorCopy( clgame.pmove->origin, cl.predicted_origin );
	VectorCopy( clgame.pmove->velocity, cl.predicted_velocity );
};