示例#1
0
文件: cl_input.c 项目: Bad-ptr/q2pro
/*
=================
CL_UpdateCmd

Updates msec, angles and builds interpolated movement vector for local prediction.
Doesn't touch command forward/side/upmove, these are filled by CL_FinalizeCmd.
=================
*/
void CL_UpdateCmd( int msec ) {
    VectorClear( cl.localmove );

    if( sv_paused->integer ) {
        return;
    }

    // add to milliseconds of time to apply the move
    cl.cmd.msec += msec;

    // adjust viewangles
    CL_AdjustAngles( msec );

    // get basic movement from keyboard
    CL_BaseMove( cl.localmove );

    // allow mice to add to the move
    CL_MouseMove();

    // add accumulated mouse forward/side movement
    cl.localmove[0] += cl.mousemove[0];
    cl.localmove[1] += cl.mousemove[1];

    // clamp to server defined max speed
    CL_ClampSpeed( cl.localmove );

    CL_ClampPitch();
    
    cl.cmd.angles[0] = ANGLE2SHORT( cl.viewangles[0] );
    cl.cmd.angles[1] = ANGLE2SHORT( cl.viewangles[1] );
    cl.cmd.angles[2] = ANGLE2SHORT( cl.viewangles[2] );
}
示例#2
0
文件: cl_main.cpp 项目: DrLabman/QMB
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);
}
示例#3
0
usercmd_t
CL_CreateCmd(void)
{
	usercmd_t cmd;

	frame_msec = sys_frame_time - old_sys_frame_time;

	if (frame_msec < 1)
	{
		frame_msec = 1;
	}

	if (frame_msec > 200)
	{
		frame_msec = 200;
	}

	/* get basic movement from keyboard */
	CL_BaseMove(&cmd);

	/* allow mice or other external controllers to add to the move */
	IN_Move(&cmd);

	CL_FinishMove(&cmd);

	old_sys_frame_time = sys_frame_time;

	return cmd;
}
示例#4
0
/*
=================
CL_RefreshCmd

jec - Adds any new input changes to usercmd
that occurred since last Init or RefreshCmd.
=================
*/
void CL_RefreshCmd (void)
{	
	int			ms;
	usercmd_t	*cmd = &cl.cmds[ cls.netchan.outgoing_sequence & (CMD_BACKUP-1) ];

	// get delta for this sample.
	frame_msec = sys_frame_time - old_sys_frame_time;	

	// bounds checking
	if (frame_msec < 1)
		return;
	if (frame_msec > 200)
		frame_msec = 200;

	//cmd->forwardmove = cmd->sidemove = cmd->upmove = 0;

	// Get basic movement from keyboard
	CL_BaseMove (cmd);

	// Allow mice or other external controllers to add to the move
	IN_Move (cmd);

	// Update cmd viewangles for CL_PredictMove
	CL_ClampPitch ();

	cmd->angles[0] = ANGLE2SHORT(cl.viewangles[0]);
	cmd->angles[1] = ANGLE2SHORT(cl.viewangles[1]);
	cmd->angles[2] = ANGLE2SHORT(cl.viewangles[2]);

	// Update cmd->msec for CL_PredictMove
	ms = (int)(cls.netFrameTime * 1000);
	if (ms > 250)
		ms = 100;

	cmd->msec = ms;

	// Update counter
	old_sys_frame_time = sys_frame_time;


	//7 = starting attack 1  2  4
	//5 = during attack   1     4 
	//4 = idle                  4

	// Send packet immediately on important events
	if (((in_attack.state & 2) || (in_attack2.state & 2) || (in_use.state & 2)))
		cls.forcePacket = true;
}
示例#5
0
void CL_RefreshCmd(void)
{
  int ms;
  usercmd_t *cmd;

  // CMD to fill
  cmd = &cl.cmds[cls.netchan.outgoing_sequence & (CMD_BACKUP - 1)];

  // Calculate delta
  frame_msec = sys_frame_time - old_sys_frame_time;

  // Check bounds
  if (frame_msec < 1) {
    return;
  } else if (frame_msec > 200) {
    frame_msec = 200;
  }

  // Add movement
  CL_BaseMove(cmd);
  input_command(cmd);

  // Clamp angels for prediction
  CL_ClampPitch();

  cmd->angles[0] = ANGLE2SHORT(cl.viewangles[0]);
  cmd->angles[1] = ANGLE2SHORT(cl.viewangles[1]);
  cmd->angles[2] = ANGLE2SHORT(cl.viewangles[2]);

  // Update time for prediction
  ms = (int) (cls.nframetime * 1000.0f);

  if (ms > 250) {
    ms = 100;
  }

  cmd->msec = ms;

  // Update frame time for the next call
  old_sys_frame_time = sys_frame_time;

  // Important events are send immediately
  if (((in_attack.state & 2)) || (in_use.state & 2)) {
    cls.forcePacket = true;
  }
}
示例#6
0
/*
=================
CL_RefreshMove

Just updates movement, such as when disconnected.
=================
*/
void CL_RefreshMove (void)
{	
	usercmd_t *cmd = &cl.cmds[ cls.netchan.outgoing_sequence & (CMD_BACKUP-1) ];

	// get delta for this sample.
	frame_msec = sys_frame_time - old_sys_frame_time;	

	// bounds checking
	if (frame_msec < 1)
		return;
	if (frame_msec > 200)
		frame_msec = 200;

	// Get basic movement from keyboard
	CL_BaseMove (cmd);

	// Allow mice or other external controllers to add to the move
	IN_Move (cmd);

	// Update counter
	old_sys_frame_time = sys_frame_time;
}
示例#7
0
void CL_RefreshMove(void)
{
  usercmd_t *cmd;

  // CMD to fill
  cmd = &cl.cmds[cls.netchan.outgoing_sequence & (CMD_BACKUP - 1)];

  // Calculate delta
  frame_msec = sys_frame_time - old_sys_frame_time;

  // Check bounds
  if (frame_msec < 1) {
    return;
  } else if (frame_msec > 200) {
    frame_msec = 200;
  }

  // Add movement
  CL_BaseMove(cmd);
  input_command(cmd);

  old_sys_frame_time = sys_frame_time;
}
示例#8
0
/*
=================
CL_CreateCmd
=================
*/
usercmd_t CL_CreateCmd (void)
{
	usercmd_t	cmd;

	frame_msec = sys_frame_time - old_sys_frame_time;
	if (frame_msec < 1)
		frame_msec = 1;
	if (frame_msec > 200)
		frame_msec = 200;
	
	// get basic movement from keyboard
	CL_BaseMove (&cmd);

	// allow mice or other external controllers to add to the move
	IN_Move (&cmd);

	CL_FinishMove (&cmd);

	old_sys_frame_time = sys_frame_time;

//cmd.impulse = cls.framecount;

	return cmd;
}
示例#9
0
void CL_SendCmd (void)
{
	sizebuf_t buf;
	byte data[128];
	usercmd_t *cmd, *oldcmd;
	int i, checksumIndex, lost;
	qbool dontdrop;
	static float pps_balance = 0;
	static int dropcount = 0;

	if (cls.demoplayback && !cls.mvdplayback)
		return; // sendcmds come from the demo

	#ifdef FTE_PEXT_CHUNKEDDOWNLOADS
	CL_SendChunkDownloadReq();
	#endif

	// save this command off for prediction
	i = cls.netchan.outgoing_sequence & UPDATE_MASK;
	cmd = &cl.frames[i].cmd;
	cl.frames[i].senttime = cls.realtime;
	cl.frames[i].receivedtime = -1;		// we haven't gotten a reply yet

	// update network stats table
	i = cls.netchan.outgoing_sequence&NETWORK_STATS_MASK;
	network_stats[i].delta = 0;     // filled-in later
	network_stats[i].sentsize = 0;  // filled-in later
	network_stats[i].senttime = cls.realtime;
	network_stats[i].receivedtime = -1;

	// get basic movement from keyboard
	CL_BaseMove (cmd);

	// allow mice or other external controllers to add to the move

	if (cl_independentPhysics.value == 0 || (physframe && cl_independentPhysics.value != 0))
	{
		IN_Move(cmd);
	}

	// if we are spectator, try autocam
	if (cl.spectator)
		Cam_Track(cmd);

	CL_FinishMove(cmd);
	cmdtime_msec += cmd->msec;

	Cam_FinishMove(cmd);

	if (cls.mvdplayback)
	{
		CL_CalcPlayerFPS(&cl.players[cl.playernum], cmd->msec);
        cls.netchan.outgoing_sequence++;
		return;
	}

	SZ_Init (&buf, data, sizeof(data));

	SZ_Write (&buf, cls.cmdmsg.data, cls.cmdmsg.cursize);
	if (cls.cmdmsg.overflowed)
		Com_DPrintf("cls.cmdmsg overflowed\n");
	SZ_Clear (&cls.cmdmsg);

	// begin a client move command
	MSG_WriteByte (&buf, clc_move);

	// save the position for a checksum byte
	checksumIndex = buf.cursize;
	MSG_WriteByte (&buf, 0);

	// write our lossage percentage
	lost = CL_CalcNet();
	MSG_WriteByte (&buf, (byte)lost);

	// send this and the previous two cmds in the message, so if the last packet was dropped, it can be recovered
	dontdrop = false;

	i = (cls.netchan.outgoing_sequence - 2) & UPDATE_MASK;
	cmd = &cl.frames[i].cmd;
	if (cl_c2sImpulseBackup.value >= 2)
		dontdrop = dontdrop || cmd->impulse;
	MSG_WriteDeltaUsercmd (&buf, &nullcmd, cmd);
	oldcmd = cmd;

	i = (cls.netchan.outgoing_sequence - 1) & UPDATE_MASK;
	cmd = &cl.frames[i].cmd;
	if (cl_c2sImpulseBackup.value >= 3)
		dontdrop = dontdrop || cmd->impulse;
	MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd);
	oldcmd = cmd;

	i = (cls.netchan.outgoing_sequence) & UPDATE_MASK;
	cmd = &cl.frames[i].cmd;
	if (cl_c2sImpulseBackup.value >= 1)
		dontdrop = dontdrop || cmd->impulse;
	MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd);

	// calculate a checksum over the move commands
	buf.data[checksumIndex] = COM_BlockSequenceCRCByte(
		buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1,
		cls.netchan.outgoing_sequence);

	// request delta compression of entities
	if (cls.netchan.outgoing_sequence - cl.validsequence >= UPDATE_BACKUP - 1)
	{
		cl.validsequence = 0;
		cl.delta_sequence = 0;
	}

	if (cl.delta_sequence && !cl_nodelta.value && cls.state == ca_active)
	{
		cl.frames[cls.netchan.outgoing_sequence & UPDATE_MASK].delta_sequence = cl.delta_sequence;
		MSG_WriteByte (&buf, clc_delta);
		MSG_WriteByte (&buf, cl.delta_sequence & 255);

		// network stats table
		network_stats[cls.netchan.outgoing_sequence&NETWORK_STATS_MASK].delta = 1;
	}
	else
	{
		cl.frames[cls.netchan.outgoing_sequence & UPDATE_MASK].delta_sequence = -1;
	}

	if (cls.demorecording)
		CL_WriteDemoCmd (cmd);

	if (cl_c2spps.value)
	{
		pps_balance += cls.frametime;
		// never drop more than 2 messages in a row -- that'll cause PL
		// and don't drop if one of the last two movemessages have an impulse
		if (pps_balance > 0 || dropcount >= 2 || dontdrop)
		{
			float	pps;
			pps = cl_c2spps.value;
			if (pps < 10) pps = 10;
			if (pps > 72) pps = 72;
			pps_balance -= 1 / pps;
			// bound pps_balance. FIXME: is there a better way?
			if (pps_balance > 0.1) pps_balance = 0.1;
			if (pps_balance < -0.1) pps_balance = -0.1;
			dropcount = 0;
		}
		else
		{
			// don't count this message when calculating PL
			cl.frames[i].receivedtime = -3;
			// drop this message
			cls.netchan.outgoing_sequence++;
			dropcount++;
			return;
		}
	}
	else
	{
		pps_balance = 0;
		dropcount = 0;
	}

#ifdef FTE_PEXT2_VOICECHAT
	S_Voip_Transmit(clc_voicechat, &buf);
#endif

	cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].sentsize = buf.cursize + 8;    // 8 = PACKET_HEADER
	// network stats table
	network_stats[cls.netchan.outgoing_sequence&NETWORK_STATS_MASK].sentsize = buf.cursize + 8;

	// deliver the message
	Netchan_Transmit (&cls.netchan, buf.cursize, buf.data);
}
示例#10
0
/*
=================
CL_SendCmd
=================
*/
void CL_SendCmd (void)
{
	sizebuf_t	buf;
	byte		data[128];
	int			i;
	usercmd_t	*cmd;

	if (cls.demoplayback)
		return; // sendcmds come from the demo

	// save this command off for prediction
	i = cls.netchan.outgoing_sequence & UPDATE_MASK;
	cmd = &cl.frames[i].cmd;
	cl.frames[i].senttime = realtime;
	cl.frames[i].receivedtime = -1;		// we haven't gotten a reply yet

	// get basic movement from keyboard
	CL_BaseMove (cmd);

	// allow mice or other external controllers to add to the move
	IN_Move (cmd);

	// if we are spectator, try autocam
	if (cl.spectator)
		Cam_Track(cmd);

	CL_FinishMove(cmd);

	Cam_FinishMove(cmd);

// send this and the previous cmds in the message, so
// if the last packet was dropped, it can be recovered
	buf.maxsize = 128;
	buf.cursize = 0;
	buf.data = data;

	MSG_WriteByte (&buf, clc_move);
	i = (cls.netchan.outgoing_sequence-2) & UPDATE_MASK;
	MSG_WriteUsercmd (&buf, &cl.frames[i].cmd, false);
	i = (cls.netchan.outgoing_sequence-1) & UPDATE_MASK;
	MSG_WriteUsercmd (&buf, &cl.frames[i].cmd, false);
	i = (cls.netchan.outgoing_sequence) & UPDATE_MASK;
	MSG_WriteUsercmd (&buf, &cl.frames[i].cmd, true);

//	Con_Printf("I  %hd %hd %hd\n",cmd->forwardmove, cmd->sidemove, cmd->upmove);

	// request delta compression of entities
	if (cls.netchan.outgoing_sequence - cl.validsequence >= UPDATE_BACKUP-1)
		cl.validsequence = 0;

	if (cl.validsequence && !cl_nodelta.value && cls.state == ca_active &&
		!cls.demorecording)
	{
		cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = cl.validsequence;
		MSG_WriteByte (&buf, clc_delta);
		MSG_WriteByte (&buf, cl.validsequence&255);
	}
	else
		cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = -1;

	if (cls.demorecording)
		CL_WriteDemoCmd(cmd);

//
// deliver the message
//
	Netchan_Transmit (&cls.netchan, buf.cursize, buf.data);	
}
示例#11
0
文件: cl_input.c 项目: Bad-ptr/q2pro
/*
=================
CL_FinalizeCmd

Builds the actual movement vector for sending to server. Assumes that msec
and angles are already set for this frame by CL_UpdateCmd.
=================
*/
void CL_FinalizeCmd( void ) {
    vec3_t move;

    // command buffer ticks in sync with cl_maxfps
    if( cmd_buffer.waitCount > 0 ) {
        cmd_buffer.waitCount--;
    }
    if( cl_cmdbuf.waitCount > 0 ) {
        cl_cmdbuf.waitCount--;
    }

    if( cls.state < ca_active ) {
        return; // not talking to a server
    }

    if( sv_paused->integer ) {
        return;
    }

//
// figure button bits
//    
    if( in_attack.state & 3 )
        cl.cmd.buttons |= BUTTON_ATTACK;
    if( in_use.state & 3 )
        cl.cmd.buttons |= BUTTON_USE;

    in_attack.state &= ~2;
    in_use.state &= ~2;

    if( cls.key_dest == KEY_GAME && Key_AnyKeyDown() ) {
        cl.cmd.buttons |= BUTTON_ANY;
    }

    if( cl.cmd.msec > 250 ) {
        cl.cmd.msec = 100;        // time was unreasonable
    }

    // rebuild the movement vector
    VectorClear( move );

    // get basic movement from keyboard
    CL_BaseMove( move );

    // add mouse forward/side movement
    move[0] += cl.mousemove[0];
    move[1] += cl.mousemove[1];

    // clamp to server defined max speed
    CL_ClampSpeed( move );

    // store the movement vector
    cl.cmd.forwardmove = move[0];
    cl.cmd.sidemove = move[1];
    cl.cmd.upmove = move[2];

    // clear all states
    cl.mousemove[0] = 0;
    cl.mousemove[1] = 0;

    KeyClear( &in_right );
    KeyClear( &in_left );

    KeyClear( &in_moveright );
    KeyClear( &in_moveleft );

    KeyClear( &in_up );
    KeyClear( &in_down );

    KeyClear( &in_forward );
    KeyClear( &in_back );

    KeyClear( &in_lookup );
    KeyClear( &in_lookdown );

    cl.cmd.impulse = in_impulse;
    in_impulse = 0;

    // save this command off for prediction
    cl.cmdNumber++;
    cl.cmds[cl.cmdNumber & CMD_MASK] = cl.cmd;

    // clear pending cmd
    memset( &cl.cmd, 0, sizeof( cl.cmd ) );
}
示例#12
0
/*
=================
CL_SendCmd
=================
*/
void CL_SendCmd (void)
{
	sizebuf_t	buf;
	byte		data[128];
	int			i;
	usercmd_t	*cmd, *oldcmd;
	int			checksumIndex;
	int			lost;
	int			seq_hash;

	if (cls.demoplayback)
		return; // sendcmds come from the demo

	// save this command off for prediction
	i = cls.netchan.outgoing_sequence & UPDATE_MASK;
	cmd = &cl.frames[i].cmd;
	cl.frames[i].senttime = realtime;
	cl.frames[i].receivedtime = -1;		// we haven't gotten a reply yet

//	seq_hash = (cls.netchan.outgoing_sequence & 0xffff) ; // ^ QW_CHECK_HASH;
	seq_hash = cls.netchan.outgoing_sequence;

	// get basic movement from keyboard
	CL_BaseMove (cmd);

	// allow mice or other external controllers to add to the move
	IN_Move (cmd);

	// if we are spectator, try autocam
	if (cl.spectator)
		Cam_Track(cmd);

	CL_FinishMove(cmd);

	Cam_FinishMove(cmd);

// send this and the previous cmds in the message, so
// if the last packet was dropped, it can be recovered
	buf.maxsize = 128;
	buf.cursize = 0;
	buf.data = data;

	MSG_WriteByte (&buf, clc_move);

	// save the position for a checksum byte
	checksumIndex = buf.cursize;
	MSG_WriteByte (&buf, 0);

	// write our lossage percentage
	lost = CL_CalcNet();
	MSG_WriteByte (&buf, (byte)lost);

	i = (cls.netchan.outgoing_sequence-2) & UPDATE_MASK;
	cmd = &cl.frames[i].cmd;
	MSG_WriteDeltaUsercmd (&buf, &nullcmd, cmd);
	oldcmd = cmd;

	i = (cls.netchan.outgoing_sequence-1) & UPDATE_MASK;
	cmd = &cl.frames[i].cmd;
	MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd);
	oldcmd = cmd;

	i = (cls.netchan.outgoing_sequence) & UPDATE_MASK;
	cmd = &cl.frames[i].cmd;
	MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd);

	// calculate a checksum over the move commands
	buf.data[checksumIndex] = COM_BlockSequenceCRCByte(
		buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1,
		seq_hash);

	// request delta compression of entities
	if (cls.netchan.outgoing_sequence - cl.validsequence >= UPDATE_BACKUP-1)
		cl.validsequence = 0;

	if (cl.validsequence && !cl_nodelta.value && cls.state == ca_active &&
		!cls.demorecording)
	{
		cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = cl.validsequence;
		MSG_WriteByte (&buf, clc_delta);
		MSG_WriteByte (&buf, cl.validsequence&255);
	}
	else
		cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = -1;

	if (cls.demorecording)
		CL_WriteDemoCmd(cmd);

//
// deliver the message
//
	Netchan_Transmit (&cls.netchan, buf.cursize, buf.data);	
}