2011-02-18 14:31:32 +00:00
|
|
|
/*
|
|
|
|
===========================================================================
|
|
|
|
Copyright (C) 1999-2005 Id Software, Inc.
|
|
|
|
|
|
|
|
This file is part of Quake III Arena source code.
|
|
|
|
|
|
|
|
Quake III Arena source code is free software; you can redistribute it
|
|
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
|
|
or (at your option) any later version.
|
|
|
|
|
|
|
|
Quake III Arena source code is distributed in the hope that it will be
|
|
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with Quake III Arena source code; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
===========================================================================
|
|
|
|
*/
|
|
|
|
// cl.input.c -- builds an intended movement command to send to the server
|
|
|
|
|
|
|
|
#include "client.h"
|
|
|
|
|
|
|
|
unsigned frame_msec;
|
|
|
|
int old_com_frameTime;
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============================================================================
|
|
|
|
|
|
|
|
KEY BUTTONS
|
|
|
|
|
|
|
|
Continuous button event tracking is complicated by the fact that two different
|
|
|
|
input sources (say, mouse button 1 and the control key) can both press the
|
|
|
|
same button, but the button should only be released when both of the
|
|
|
|
pressing key have been released.
|
|
|
|
|
|
|
|
When a key event issues a button command (+forward, +attack, etc), it appends
|
|
|
|
its key number as argv(1) so it can be matched up with the release.
|
|
|
|
|
|
|
|
argv(2) will be set to the time the event happened, which allows exact
|
|
|
|
control even at low framerates when the down and up events may both get qued
|
|
|
|
at the same time.
|
|
|
|
|
|
|
|
===============================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
kbutton_t in_left, in_right, in_forward, in_back;
|
|
|
|
kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright;
|
|
|
|
kbutton_t in_strafe, in_speed;
|
|
|
|
kbutton_t in_up, in_down;
|
|
|
|
|
|
|
|
#ifdef USE_VOIP
|
|
|
|
kbutton_t in_voiprecord;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
kbutton_t in_buttons[16];
|
|
|
|
|
|
|
|
|
|
|
|
qboolean in_mlooking;
|
|
|
|
|
|
|
|
|
|
|
|
void IN_MLookDown( void ) {
|
|
|
|
in_mlooking = qtrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IN_MLookUp( void ) {
|
|
|
|
in_mlooking = qfalse;
|
|
|
|
if ( !cl_freelook->integer ) {
|
|
|
|
IN_CenterView ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IN_KeyDown( kbutton_t *b ) {
|
|
|
|
int k;
|
|
|
|
char *c;
|
|
|
|
|
|
|
|
c = Cmd_Argv(1);
|
|
|
|
if ( c[0] ) {
|
|
|
|
k = atoi(c);
|
|
|
|
} else {
|
|
|
|
k = -1; // typed manually at the console for continuous down
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( k == b->down[0] || k == b->down[1] ) {
|
|
|
|
return; // repeating key
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !b->down[0] ) {
|
|
|
|
b->down[0] = k;
|
|
|
|
} else if ( !b->down[1] ) {
|
|
|
|
b->down[1] = k;
|
|
|
|
} else {
|
|
|
|
Com_Printf ("Three keys down for a button!\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( b->active ) {
|
|
|
|
return; // still down
|
|
|
|
}
|
|
|
|
|
|
|
|
// save timestamp for partial frame summing
|
|
|
|
c = Cmd_Argv(2);
|
|
|
|
b->downtime = atoi(c);
|
|
|
|
|
|
|
|
b->active = qtrue;
|
|
|
|
b->wasPressed = qtrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IN_KeyUp( kbutton_t *b ) {
|
|
|
|
int k;
|
|
|
|
char *c;
|
|
|
|
unsigned uptime;
|
|
|
|
|
|
|
|
c = Cmd_Argv(1);
|
|
|
|
if ( c[0] ) {
|
|
|
|
k = atoi(c);
|
|
|
|
} else {
|
|
|
|
// typed manually at the console, assume for unsticking, so clear all
|
|
|
|
b->down[0] = b->down[1] = 0;
|
|
|
|
b->active = qfalse;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( b->down[0] == k ) {
|
|
|
|
b->down[0] = 0;
|
|
|
|
} else if ( b->down[1] == k ) {
|
|
|
|
b->down[1] = 0;
|
|
|
|
} else {
|
|
|
|
return; // key up without coresponding down (menu pass through)
|
|
|
|
}
|
|
|
|
if ( b->down[0] || b->down[1] ) {
|
|
|
|
return; // some other key is still holding it down
|
|
|
|
}
|
|
|
|
|
|
|
|
b->active = qfalse;
|
|
|
|
|
|
|
|
// save timestamp for partial frame summing
|
|
|
|
c = Cmd_Argv(2);
|
|
|
|
uptime = atoi(c);
|
|
|
|
if ( uptime ) {
|
|
|
|
b->msec += uptime - b->downtime;
|
|
|
|
} else {
|
|
|
|
b->msec += frame_msec / 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
b->active = qfalse;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
CL_KeyState
|
|
|
|
|
|
|
|
Returns the fraction of the frame that the key was down
|
|
|
|
===============
|
|
|
|
*/
|
|
|
|
float CL_KeyState( kbutton_t *key ) {
|
|
|
|
float val;
|
|
|
|
int msec;
|
|
|
|
|
|
|
|
msec = key->msec;
|
|
|
|
key->msec = 0;
|
|
|
|
|
|
|
|
if ( key->active ) {
|
|
|
|
// still down
|
|
|
|
if ( !key->downtime ) {
|
|
|
|
msec = com_frameTime;
|
|
|
|
} else {
|
|
|
|
msec += com_frameTime - key->downtime;
|
|
|
|
}
|
|
|
|
key->downtime = com_frameTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (msec) {
|
|
|
|
Com_Printf ("%i ", msec);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
val = (float)msec / frame_msec;
|
|
|
|
if ( val < 0 ) {
|
|
|
|
val = 0;
|
|
|
|
}
|
|
|
|
if ( val > 1 ) {
|
|
|
|
val = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void IN_UpDown(void) {IN_KeyDown(&in_up);}
|
|
|
|
void IN_UpUp(void) {IN_KeyUp(&in_up);}
|
|
|
|
void IN_DownDown(void) {IN_KeyDown(&in_down);}
|
|
|
|
void IN_DownUp(void) {IN_KeyUp(&in_down);}
|
|
|
|
void IN_LeftDown(void) {IN_KeyDown(&in_left);}
|
|
|
|
void IN_LeftUp(void) {IN_KeyUp(&in_left);}
|
|
|
|
void IN_RightDown(void) {IN_KeyDown(&in_right);}
|
|
|
|
void IN_RightUp(void) {IN_KeyUp(&in_right);}
|
|
|
|
void IN_ForwardDown(void) {IN_KeyDown(&in_forward);}
|
|
|
|
void IN_ForwardUp(void) {IN_KeyUp(&in_forward);}
|
|
|
|
void IN_BackDown(void) {IN_KeyDown(&in_back);}
|
|
|
|
void IN_BackUp(void) {IN_KeyUp(&in_back);}
|
|
|
|
void IN_LookupDown(void) {IN_KeyDown(&in_lookup);}
|
|
|
|
void IN_LookupUp(void) {IN_KeyUp(&in_lookup);}
|
|
|
|
void IN_LookdownDown(void) {IN_KeyDown(&in_lookdown);}
|
|
|
|
void IN_LookdownUp(void) {IN_KeyUp(&in_lookdown);}
|
|
|
|
void IN_MoveleftDown(void) {IN_KeyDown(&in_moveleft);}
|
|
|
|
void IN_MoveleftUp(void) {IN_KeyUp(&in_moveleft);}
|
|
|
|
void IN_MoverightDown(void) {IN_KeyDown(&in_moveright);}
|
|
|
|
void IN_MoverightUp(void) {IN_KeyUp(&in_moveright);}
|
|
|
|
|
|
|
|
void IN_SpeedDown(void) {IN_KeyDown(&in_speed);}
|
|
|
|
void IN_SpeedUp(void) {IN_KeyUp(&in_speed);}
|
|
|
|
void IN_StrafeDown(void) {IN_KeyDown(&in_strafe);}
|
|
|
|
void IN_StrafeUp(void) {IN_KeyUp(&in_strafe);}
|
|
|
|
|
|
|
|
#ifdef USE_VOIP
|
|
|
|
void IN_VoipRecordDown(void)
|
|
|
|
{
|
|
|
|
IN_KeyDown(&in_voiprecord);
|
|
|
|
Cvar_Set("cl_voipSend", "1");
|
|
|
|
}
|
|
|
|
|
|
|
|
void IN_VoipRecordUp(void)
|
|
|
|
{
|
|
|
|
IN_KeyUp(&in_voiprecord);
|
|
|
|
Cvar_Set("cl_voipSend", "0");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void IN_Button0Down(void) {IN_KeyDown(&in_buttons[0]);}
|
|
|
|
void IN_Button0Up(void) {IN_KeyUp(&in_buttons[0]);}
|
|
|
|
void IN_Button1Down(void) {IN_KeyDown(&in_buttons[1]);}
|
|
|
|
void IN_Button1Up(void) {IN_KeyUp(&in_buttons[1]);}
|
|
|
|
void IN_Button2Down(void) {IN_KeyDown(&in_buttons[2]);}
|
|
|
|
void IN_Button2Up(void) {IN_KeyUp(&in_buttons[2]);}
|
|
|
|
void IN_Button3Down(void) {IN_KeyDown(&in_buttons[3]);}
|
|
|
|
void IN_Button3Up(void) {IN_KeyUp(&in_buttons[3]);}
|
|
|
|
void IN_Button4Down(void) {IN_KeyDown(&in_buttons[4]);}
|
|
|
|
void IN_Button4Up(void) {IN_KeyUp(&in_buttons[4]);}
|
|
|
|
void IN_Button5Down(void) {IN_KeyDown(&in_buttons[5]);}
|
|
|
|
void IN_Button5Up(void) {IN_KeyUp(&in_buttons[5]);}
|
|
|
|
void IN_Button6Down(void) {IN_KeyDown(&in_buttons[6]);}
|
|
|
|
void IN_Button6Up(void) {IN_KeyUp(&in_buttons[6]);}
|
|
|
|
void IN_Button7Down(void) {IN_KeyDown(&in_buttons[7]);}
|
|
|
|
void IN_Button7Up(void) {IN_KeyUp(&in_buttons[7]);}
|
|
|
|
void IN_Button8Down(void) {IN_KeyDown(&in_buttons[8]);}
|
|
|
|
void IN_Button8Up(void) {IN_KeyUp(&in_buttons[8]);}
|
|
|
|
void IN_Button9Down(void) {IN_KeyDown(&in_buttons[9]);}
|
|
|
|
void IN_Button9Up(void) {IN_KeyUp(&in_buttons[9]);}
|
|
|
|
void IN_Button10Down(void) {IN_KeyDown(&in_buttons[10]);}
|
|
|
|
void IN_Button10Up(void) {IN_KeyUp(&in_buttons[10]);}
|
|
|
|
void IN_Button11Down(void) {IN_KeyDown(&in_buttons[11]);}
|
|
|
|
void IN_Button11Up(void) {IN_KeyUp(&in_buttons[11]);}
|
|
|
|
void IN_Button12Down(void) {IN_KeyDown(&in_buttons[12]);}
|
|
|
|
void IN_Button12Up(void) {IN_KeyUp(&in_buttons[12]);}
|
|
|
|
void IN_Button13Down(void) {IN_KeyDown(&in_buttons[13]);}
|
|
|
|
void IN_Button13Up(void) {IN_KeyUp(&in_buttons[13]);}
|
|
|
|
void IN_Button14Down(void) {IN_KeyDown(&in_buttons[14]);}
|
|
|
|
void IN_Button14Up(void) {IN_KeyUp(&in_buttons[14]);}
|
|
|
|
void IN_Button15Down(void) {IN_KeyDown(&in_buttons[15]);}
|
|
|
|
void IN_Button15Up(void) {IN_KeyUp(&in_buttons[15]);}
|
|
|
|
|
|
|
|
void IN_CenterView (void) {
|
|
|
|
cl.viewangles[PITCH] = -SHORT2ANGLE(cl.snap.ps.delta_angles[PITCH]);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
cvar_t *cl_yawspeed;
|
|
|
|
cvar_t *cl_pitchspeed;
|
|
|
|
|
|
|
|
cvar_t *cl_run;
|
|
|
|
|
|
|
|
cvar_t *cl_anglespeedkey;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
CL_AdjustAngles
|
|
|
|
|
|
|
|
Moves the local angle positions
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
void CL_AdjustAngles( void ) {
|
|
|
|
float speed;
|
|
|
|
|
|
|
|
if ( in_speed.active ) {
|
|
|
|
speed = 0.001 * cls.frametime * cl_anglespeedkey->value;
|
|
|
|
} else {
|
|
|
|
speed = 0.001 * cls.frametime;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !in_strafe.active ) {
|
|
|
|
cl.viewangles[YAW] -= speed*cl_yawspeed->value*CL_KeyState (&in_right);
|
|
|
|
cl.viewangles[YAW] += speed*cl_yawspeed->value*CL_KeyState (&in_left);
|
|
|
|
}
|
|
|
|
|
|
|
|
cl.viewangles[PITCH] -= speed*cl_pitchspeed->value * CL_KeyState (&in_lookup);
|
|
|
|
cl.viewangles[PITCH] += speed*cl_pitchspeed->value * CL_KeyState (&in_lookdown);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
CL_KeyMove
|
|
|
|
|
|
|
|
Sets the usercmd_t based on key states
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
void CL_KeyMove( usercmd_t *cmd ) {
|
|
|
|
int movespeed;
|
|
|
|
int forward, side, up;
|
|
|
|
|
|
|
|
//
|
|
|
|
// adjust for speed key / running
|
|
|
|
// the walking flag is to keep animations consistant
|
|
|
|
// even during acceleration and develeration
|
|
|
|
//
|
|
|
|
if ( in_speed.active ^ cl_run->integer ) {
|
|
|
|
movespeed = 127;
|
|
|
|
cmd->buttons &= ~BUTTON_TURBO;
|
|
|
|
} else {
|
|
|
|
cmd->buttons |= BUTTON_TURBO;
|
|
|
|
movespeed = 64;
|
|
|
|
}
|
|
|
|
|
|
|
|
forward = 0;
|
|
|
|
side = 0;
|
|
|
|
up = 0;
|
|
|
|
if ( in_strafe.active ) {
|
|
|
|
side += movespeed * CL_KeyState (&in_right);
|
|
|
|
side -= movespeed * CL_KeyState (&in_left);
|
|
|
|
}
|
|
|
|
|
|
|
|
side += movespeed * CL_KeyState (&in_moveright);
|
|
|
|
side -= movespeed * CL_KeyState (&in_moveleft);
|
|
|
|
|
|
|
|
|
|
|
|
up += movespeed * CL_KeyState (&in_up);
|
|
|
|
up -= movespeed * CL_KeyState (&in_down);
|
|
|
|
|
|
|
|
forward += movespeed * CL_KeyState (&in_forward);
|
|
|
|
forward -= movespeed * CL_KeyState (&in_back);
|
|
|
|
|
|
|
|
cmd->forwardmove = ClampChar( forward );
|
|
|
|
cmd->rightmove = ClampChar( side );
|
|
|
|
cmd->upmove = ClampChar( up );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=================
|
|
|
|
CL_MouseEvent
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
void CL_MouseEvent( int dx, int dy, int time ) {
|
|
|
|
if ( Key_GetCatcher( ) & KEYCATCH_UI ) {
|
|
|
|
VM_Call( uivm, UI_MOUSE_EVENT, dx, dy );
|
|
|
|
} else if (Key_GetCatcher( ) & KEYCATCH_CGAME) {
|
|
|
|
VM_Call (cgvm, CG_MOUSE_EVENT, dx, dy);
|
|
|
|
} else {
|
|
|
|
cl.mouseDx[cl.mouseIndex] += dx;
|
|
|
|
cl.mouseDy[cl.mouseIndex] += dy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=================
|
|
|
|
CL_JoystickEvent
|
|
|
|
|
|
|
|
Joystick values stay set until changed
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
void CL_JoystickEvent( int axis, int value, int time ) {
|
|
|
|
if ( axis < 0 || axis >= MAX_JOYSTICK_AXIS ) {
|
|
|
|
Com_Error( ERR_DROP, "CL_JoystickEvent: bad axis %i", axis );
|
|
|
|
}
|
|
|
|
cl.joystickAxis[axis] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=================
|
|
|
|
CL_JoystickMove
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
void CL_JoystickMove( usercmd_t *cmd ) {
|
|
|
|
float anglespeed;
|
|
|
|
|
2011-07-29 17:52:36 +00:00
|
|
|
if ( !(in_speed.active ^ cl_run->integer) ) {
|
2011-02-18 14:31:32 +00:00
|
|
|
cmd->buttons |= BUTTON_TURBO;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( in_speed.active ) {
|
|
|
|
anglespeed = 0.001 * cls.frametime * cl_anglespeedkey->value;
|
|
|
|
} else {
|
|
|
|
anglespeed = 0.001 * cls.frametime;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !in_strafe.active ) {
|
2011-07-26 08:52:24 +00:00
|
|
|
cl.viewangles[YAW] += anglespeed * j_yaw->value * cl.joystickAxis[j_yaw_axis->integer];
|
|
|
|
cmd->rightmove = ClampChar( cmd->rightmove + (int) (j_side->value * cl.joystickAxis[j_side_axis->integer]) );
|
2011-02-18 14:31:32 +00:00
|
|
|
} else {
|
2011-07-26 08:52:24 +00:00
|
|
|
cl.viewangles[YAW] += anglespeed * j_side->value * cl.joystickAxis[j_side_axis->integer];
|
|
|
|
cmd->rightmove = ClampChar( cmd->rightmove + (int) (j_yaw->value * cl.joystickAxis[j_yaw_axis->integer]) );
|
2011-02-18 14:31:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( in_mlooking ) {
|
2011-07-26 08:52:24 +00:00
|
|
|
cl.viewangles[PITCH] += anglespeed * j_forward->value * cl.joystickAxis[j_forward_axis->integer];
|
|
|
|
cmd->forwardmove = ClampChar( cmd->forwardmove + (int) (j_pitch->value * cl.joystickAxis[j_pitch_axis->integer]) );
|
2011-02-18 14:31:32 +00:00
|
|
|
} else {
|
2011-07-26 08:52:24 +00:00
|
|
|
cl.viewangles[PITCH] += anglespeed * j_pitch->value * cl.joystickAxis[j_pitch_axis->integer];
|
|
|
|
cmd->forwardmove = ClampChar( cmd->forwardmove + (int) (j_forward->value * cl.joystickAxis[j_forward_axis->integer]) );
|
2011-02-18 14:31:32 +00:00
|
|
|
}
|
|
|
|
|
2012-09-15 03:03:44 +00:00
|
|
|
cmd->upmove = ClampChar( cmd->upmove + (int) (j_up->value * cl.joystickAxis[j_up_axis->integer]) );
|
2011-02-18 14:31:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=================
|
|
|
|
CL_MouseMove
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
|
|
|
|
void CL_MouseMove(usercmd_t *cmd)
|
|
|
|
{
|
|
|
|
float mx, my;
|
|
|
|
|
|
|
|
// allow mouse smoothing
|
|
|
|
if (m_filter->integer)
|
|
|
|
{
|
|
|
|
mx = (cl.mouseDx[0] + cl.mouseDx[1]) * 0.5f;
|
|
|
|
my = (cl.mouseDy[0] + cl.mouseDy[1]) * 0.5f;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mx = cl.mouseDx[cl.mouseIndex];
|
|
|
|
my = cl.mouseDy[cl.mouseIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
cl.mouseIndex ^= 1;
|
|
|
|
cl.mouseDx[cl.mouseIndex] = 0;
|
|
|
|
cl.mouseDy[cl.mouseIndex] = 0;
|
|
|
|
|
|
|
|
if (mx == 0.0f && my == 0.0f)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (cl_mouseAccel->value != 0.0f)
|
|
|
|
{
|
|
|
|
if(cl_mouseAccelStyle->integer == 0)
|
|
|
|
{
|
|
|
|
float accelSensitivity;
|
|
|
|
float rate;
|
|
|
|
|
|
|
|
rate = sqrt(mx * mx + my * my) / (float) frame_msec;
|
|
|
|
|
|
|
|
accelSensitivity = cl_sensitivity->value + rate * cl_mouseAccel->value;
|
|
|
|
mx *= accelSensitivity;
|
|
|
|
my *= accelSensitivity;
|
|
|
|
|
|
|
|
if(cl_showMouseRate->integer)
|
|
|
|
Com_Printf("rate: %f, accelSensitivity: %f\n", rate, accelSensitivity);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
float rate[2];
|
|
|
|
float power[2];
|
|
|
|
|
|
|
|
// sensitivity remains pretty much unchanged at low speeds
|
|
|
|
// cl_mouseAccel is a power value to how the acceleration is shaped
|
|
|
|
// cl_mouseAccelOffset is the rate for which the acceleration will have doubled the non accelerated amplification
|
|
|
|
// NOTE: decouple the config cvars for independent acceleration setup along X and Y?
|
|
|
|
|
|
|
|
rate[0] = fabs(mx) / (float) frame_msec;
|
|
|
|
rate[1] = fabs(my) / (float) frame_msec;
|
|
|
|
power[0] = powf(rate[0] / cl_mouseAccelOffset->value, cl_mouseAccel->value);
|
|
|
|
power[1] = powf(rate[1] / cl_mouseAccelOffset->value, cl_mouseAccel->value);
|
|
|
|
|
|
|
|
mx = cl_sensitivity->value * (mx + ((mx < 0) ? -power[0] : power[0]) * cl_mouseAccelOffset->value);
|
|
|
|
my = cl_sensitivity->value * (my + ((my < 0) ? -power[1] : power[1]) * cl_mouseAccelOffset->value);
|
|
|
|
|
|
|
|
if(cl_showMouseRate->integer)
|
|
|
|
Com_Printf("ratex: %f, ratey: %f, powx: %f, powy: %f\n", rate[0], rate[1], power[0], power[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mx *= cl_sensitivity->value;
|
|
|
|
my *= cl_sensitivity->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ingame FOV
|
|
|
|
mx *= cl.cgameSensitivity;
|
|
|
|
my *= cl.cgameSensitivity;
|
|
|
|
|
|
|
|
// add mouse X/Y movement to cmd
|
|
|
|
if(in_strafe.active)
|
|
|
|
cmd->rightmove = ClampChar(cmd->rightmove + m_side->value * mx);
|
|
|
|
else
|
|
|
|
cl.viewangles[YAW] -= m_yaw->value * mx;
|
|
|
|
|
|
|
|
if ((in_mlooking || cl_freelook->integer) && !in_strafe.active)
|
|
|
|
cl.viewangles[PITCH] += m_pitch->value * my;
|
|
|
|
else
|
|
|
|
cmd->forwardmove = ClampChar(cmd->forwardmove - m_forward->value * my);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
==============
|
|
|
|
CL_CmdButtons
|
|
|
|
==============
|
|
|
|
*/
|
|
|
|
void CL_CmdButtons( usercmd_t *cmd ) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
//
|
|
|
|
// figure button bits
|
|
|
|
// send a button bit even if the key was pressed and released in
|
|
|
|
// less than a frame
|
|
|
|
//
|
|
|
|
for (i = 0 ; i < 15 ; i++) {
|
|
|
|
if ( in_buttons[i].active || in_buttons[i].wasPressed ) {
|
|
|
|
cmd->buttons |= 1 << i;
|
|
|
|
}
|
|
|
|
in_buttons[i].wasPressed = qfalse;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( Key_GetCatcher( ) ) {
|
|
|
|
cmd->buttons |= BUTTON_TALK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// allow the game to know if any key at all is
|
|
|
|
// currently pressed, even if it isn't bound to anything
|
|
|
|
if ( anykeydown && Key_GetCatcher( ) == 0 ) {
|
|
|
|
cmd->buttons |= BUTTON_ANY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
==============
|
|
|
|
CL_FinishMove
|
|
|
|
==============
|
|
|
|
*/
|
|
|
|
void CL_FinishMove( usercmd_t *cmd ) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
// copy the state that the cgame is currently sending
|
|
|
|
cmd->weapon = cl.cgameUserCmdValue;
|
|
|
|
|
|
|
|
// send the current server time so the amount of movement
|
|
|
|
// can be determined without allowing cheating
|
|
|
|
cmd->serverTime = cl.serverTime;
|
|
|
|
|
|
|
|
for (i=0 ; i<3 ; i++) {
|
|
|
|
cmd->angles[i] = ANGLE2SHORT(cl.viewangles[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
=================
|
|
|
|
CL_CreateCmd
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
usercmd_t CL_CreateCmd( void ) {
|
|
|
|
usercmd_t cmd;
|
|
|
|
vec3_t oldAngles;
|
|
|
|
|
|
|
|
VectorCopy( cl.viewangles, oldAngles );
|
|
|
|
|
|
|
|
// keyboard angle adjustment
|
|
|
|
CL_AdjustAngles ();
|
|
|
|
|
|
|
|
Com_Memset( &cmd, 0, sizeof( cmd ) );
|
|
|
|
|
|
|
|
CL_CmdButtons( &cmd );
|
|
|
|
|
|
|
|
// get basic movement from keyboard
|
|
|
|
CL_KeyMove( &cmd );
|
|
|
|
|
|
|
|
// get basic movement from mouse
|
|
|
|
CL_MouseMove( &cmd );
|
|
|
|
|
|
|
|
// get basic movement from joystick
|
|
|
|
CL_JoystickMove( &cmd );
|
|
|
|
|
|
|
|
// check to make sure the angles haven't wrapped
|
|
|
|
if ( cl.viewangles[PITCH] - oldAngles[PITCH] > 90 ) {
|
|
|
|
cl.viewangles[PITCH] = oldAngles[PITCH] + 90;
|
|
|
|
} else if ( oldAngles[PITCH] - cl.viewangles[PITCH] > 90 ) {
|
|
|
|
cl.viewangles[PITCH] = oldAngles[PITCH] - 90;
|
|
|
|
}
|
|
|
|
|
|
|
|
// store out the final values
|
|
|
|
CL_FinishMove( &cmd );
|
|
|
|
|
|
|
|
// draw debug graphs of turning for mouse testing
|
|
|
|
if ( cl_debugMove->integer ) {
|
|
|
|
if ( cl_debugMove->integer == 1 ) {
|
2011-07-29 17:52:36 +00:00
|
|
|
SCR_DebugGraph( abs(cl.viewangles[YAW] - oldAngles[YAW]) );
|
2011-02-18 14:31:32 +00:00
|
|
|
}
|
|
|
|
if ( cl_debugMove->integer == 2 ) {
|
2011-07-29 17:52:36 +00:00
|
|
|
SCR_DebugGraph( abs(cl.viewangles[PITCH] - oldAngles[PITCH]) );
|
2011-02-18 14:31:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return cmd;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
=================
|
|
|
|
CL_CreateNewCommands
|
|
|
|
|
|
|
|
Create a new usercmd_t structure for this frame
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
void CL_CreateNewCommands( void ) {
|
|
|
|
int cmdNum;
|
|
|
|
|
|
|
|
// no need to create usercmds until we have a gamestate
|
2011-07-26 08:52:24 +00:00
|
|
|
if ( clc.state < CA_PRIMED ) {
|
2011-02-18 14:31:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
frame_msec = com_frameTime - old_com_frameTime;
|
|
|
|
|
|
|
|
// if running less than 5fps, truncate the extra time to prevent
|
|
|
|
// unexpected moves after a hitch
|
|
|
|
if ( frame_msec > 200 ) {
|
|
|
|
frame_msec = 200;
|
|
|
|
}
|
|
|
|
old_com_frameTime = com_frameTime;
|
|
|
|
|
|
|
|
|
|
|
|
// generate a command for this frame
|
|
|
|
cl.cmdNumber++;
|
|
|
|
cmdNum = cl.cmdNumber & CMD_MASK;
|
|
|
|
cl.cmds[cmdNum] = CL_CreateCmd ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=================
|
|
|
|
CL_ReadyToSendPacket
|
|
|
|
|
|
|
|
Returns qfalse if we are over the maxpackets limit
|
|
|
|
and should choke back the bandwidth a bit by not sending
|
|
|
|
a packet this frame. All the commands will still get
|
|
|
|
delivered in the next packet, but saving a header and
|
|
|
|
getting more delta compression will reduce total bandwidth.
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
qboolean CL_ReadyToSendPacket( void ) {
|
|
|
|
int oldPacketNum;
|
|
|
|
int delta;
|
|
|
|
|
|
|
|
// don't send anything if playing back a demo
|
2011-07-26 08:52:24 +00:00
|
|
|
if ( clc.demoplaying || clc.state == CA_CINEMATIC ) {
|
2011-02-18 14:31:32 +00:00
|
|
|
return qfalse;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we are downloading, we send no less than 50ms between packets
|
|
|
|
if ( *clc.downloadTempName &&
|
|
|
|
cls.realtime - clc.lastPacketSentTime < 50 ) {
|
|
|
|
return qfalse;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if we don't have a valid gamestate yet, only send
|
|
|
|
// one packet a second
|
2011-07-26 08:52:24 +00:00
|
|
|
if ( clc.state != CA_ACTIVE &&
|
|
|
|
clc.state != CA_PRIMED &&
|
2011-02-18 14:31:32 +00:00
|
|
|
!*clc.downloadTempName &&
|
|
|
|
cls.realtime - clc.lastPacketSentTime < 1000 ) {
|
|
|
|
return qfalse;
|
|
|
|
}
|
|
|
|
|
|
|
|
// send every frame for loopbacks
|
|
|
|
if ( clc.netchan.remoteAddress.type == NA_LOOPBACK ) {
|
|
|
|
return qtrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// send every frame for LAN
|
|
|
|
if ( cl_lanForcePackets->integer && Sys_IsLANAddress( clc.netchan.remoteAddress ) ) {
|
|
|
|
return qtrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check for exceeding cl_maxpackets
|
|
|
|
if ( cl_maxpackets->integer < 15 ) {
|
|
|
|
Cvar_Set( "cl_maxpackets", "15" );
|
|
|
|
} else if ( cl_maxpackets->integer > 125 ) {
|
|
|
|
Cvar_Set( "cl_maxpackets", "125" );
|
|
|
|
}
|
|
|
|
oldPacketNum = (clc.netchan.outgoingSequence - 1) & PACKET_MASK;
|
|
|
|
delta = cls.realtime - cl.outPackets[ oldPacketNum ].p_realtime;
|
|
|
|
if ( delta < 1000 / cl_maxpackets->integer ) {
|
|
|
|
// the accumulated commands will go out in the next packet
|
|
|
|
return qfalse;
|
|
|
|
}
|
|
|
|
|
|
|
|
return qtrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===================
|
|
|
|
CL_WritePacket
|
|
|
|
|
|
|
|
Create and send the command packet to the server
|
|
|
|
Including both the reliable commands and the usercmds
|
|
|
|
|
|
|
|
During normal gameplay, a client packet will contain something like:
|
|
|
|
|
|
|
|
4 sequence number
|
|
|
|
2 qport
|
|
|
|
4 serverid
|
|
|
|
4 acknowledged sequence number
|
|
|
|
4 clc.serverCommandSequence
|
|
|
|
<optional reliable commands>
|
|
|
|
1 clc_move or clc_moveNoDelta
|
|
|
|
1 command count
|
|
|
|
<count * usercmds>
|
|
|
|
|
|
|
|
===================
|
|
|
|
*/
|
|
|
|
void CL_WritePacket( void ) {
|
|
|
|
msg_t buf;
|
|
|
|
byte data[MAX_MSGLEN];
|
|
|
|
int i, j;
|
|
|
|
usercmd_t *cmd, *oldcmd;
|
|
|
|
usercmd_t nullcmd;
|
|
|
|
int packetNum;
|
|
|
|
int oldPacketNum;
|
|
|
|
int count, key;
|
|
|
|
|
|
|
|
// don't send anything if playing back a demo
|
2011-07-26 08:52:24 +00:00
|
|
|
if ( clc.demoplaying || clc.state == CA_CINEMATIC ) {
|
2011-02-18 14:31:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Com_Memset( &nullcmd, 0, sizeof(nullcmd) );
|
|
|
|
oldcmd = &nullcmd;
|
|
|
|
|
|
|
|
MSG_Init( &buf, data, sizeof(data) );
|
|
|
|
|
|
|
|
MSG_Bitstream( &buf );
|
|
|
|
// write the current serverId so the server
|
|
|
|
// can tell if this is from the current gameState
|
|
|
|
MSG_WriteLong( &buf, cl.serverId );
|
|
|
|
|
|
|
|
// write the last message we received, which can
|
|
|
|
// be used for delta compression, and is also used
|
|
|
|
// to tell if we dropped a gamestate
|
|
|
|
MSG_WriteLong( &buf, clc.serverMessageSequence );
|
|
|
|
|
|
|
|
// write the last reliable message we received
|
|
|
|
MSG_WriteLong( &buf, clc.serverCommandSequence );
|
|
|
|
|
|
|
|
// write any unacknowledged clientCommands
|
|
|
|
for ( i = clc.reliableAcknowledge + 1 ; i <= clc.reliableSequence ; i++ ) {
|
|
|
|
MSG_WriteByte( &buf, clc_clientCommand );
|
|
|
|
MSG_WriteLong( &buf, i );
|
|
|
|
MSG_WriteString( &buf, clc.reliableCommands[ i & (MAX_RELIABLE_COMMANDS-1) ] );
|
|
|
|
}
|
|
|
|
|
|
|
|
// we want to send all the usercmds that were generated in the last
|
|
|
|
// few packet, so even if a couple packets are dropped in a row,
|
|
|
|
// all the cmds will make it to the server
|
|
|
|
if ( cl_packetdup->integer < 0 ) {
|
|
|
|
Cvar_Set( "cl_packetdup", "0" );
|
|
|
|
} else if ( cl_packetdup->integer > 5 ) {
|
|
|
|
Cvar_Set( "cl_packetdup", "5" );
|
|
|
|
}
|
|
|
|
oldPacketNum = (clc.netchan.outgoingSequence - 1 - cl_packetdup->integer) & PACKET_MASK;
|
|
|
|
count = cl.cmdNumber - cl.outPackets[ oldPacketNum ].p_cmdNumber;
|
|
|
|
if ( count > MAX_PACKET_USERCMDS ) {
|
|
|
|
count = MAX_PACKET_USERCMDS;
|
|
|
|
Com_Printf("MAX_PACKET_USERCMDS\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef USE_VOIP
|
2011-07-29 17:52:36 +00:00
|
|
|
if (clc.voipOutgoingDataSize > 0)
|
|
|
|
{
|
|
|
|
if((clc.voipFlags & VOIP_SPATIAL) || Com_IsVoipTarget(clc.voipTargets, sizeof(clc.voipTargets), -1))
|
|
|
|
{
|
|
|
|
MSG_WriteByte (&buf, clc_voip);
|
|
|
|
MSG_WriteByte (&buf, clc.voipOutgoingGeneration);
|
|
|
|
MSG_WriteLong (&buf, clc.voipOutgoingSequence);
|
|
|
|
MSG_WriteByte (&buf, clc.voipOutgoingDataFrames);
|
|
|
|
MSG_WriteData (&buf, clc.voipTargets, sizeof(clc.voipTargets));
|
|
|
|
MSG_WriteByte(&buf, clc.voipFlags);
|
|
|
|
MSG_WriteShort (&buf, clc.voipOutgoingDataSize);
|
|
|
|
MSG_WriteData (&buf, clc.voipOutgoingData, clc.voipOutgoingDataSize);
|
|
|
|
|
|
|
|
// If we're recording a demo, we have to fake a server packet with
|
|
|
|
// this VoIP data so it gets to disk; the server doesn't send it
|
|
|
|
// back to us, and we might as well eliminate concerns about dropped
|
|
|
|
// and misordered packets here.
|
|
|
|
if(clc.demorecording && !clc.demowaiting)
|
|
|
|
{
|
|
|
|
const int voipSize = clc.voipOutgoingDataSize;
|
|
|
|
msg_t fakemsg;
|
|
|
|
byte fakedata[MAX_MSGLEN];
|
|
|
|
MSG_Init (&fakemsg, fakedata, sizeof (fakedata));
|
|
|
|
MSG_Bitstream (&fakemsg);
|
|
|
|
MSG_WriteLong (&fakemsg, clc.reliableAcknowledge);
|
|
|
|
MSG_WriteByte (&fakemsg, svc_voip);
|
|
|
|
MSG_WriteShort (&fakemsg, clc.clientNum);
|
|
|
|
MSG_WriteByte (&fakemsg, clc.voipOutgoingGeneration);
|
|
|
|
MSG_WriteLong (&fakemsg, clc.voipOutgoingSequence);
|
|
|
|
MSG_WriteByte (&fakemsg, clc.voipOutgoingDataFrames);
|
|
|
|
MSG_WriteShort (&fakemsg, clc.voipOutgoingDataSize );
|
ioquake3 resync to revision 2398 from 2369.
This is the last ioquake3 revision before ioquake3 changed from subversion to git at the beginning of 2013.
#5808 - Include and use .glsl in source (rend2)
#5812 - Use refdef's coordinates when drawing to screen shadow fbo, and separate depth texture and screen texture coordinates in glsl shaders.
Include Rend2 renderer in MacOSX bundle
Include OpenGL1 and Rend2 renderers in MacOSX UB
Include Rend2 renderer in NSIS installer.
Include OpenGL1 and Rend2 renderers in Loki Setup Installer.
Have NSIS uninstaller delete rend2.
Split light sample into direct and ambient parts when using deluxemaps or per-vertex light vectors. Fixes #5813.
Fix writting voip data in demos (broke in r2102).
Fix server ignoring client move commands if voip data is included.
Allow changing cl_voip without restarting.
Fix assert failing in CL_ParseVoip() while flipping cl_voip off and on.
Only declare var_SampleToView in lightall shader when it is actually used.
Fix a couple files not ending with a newline.
Fix clients being able to reset their player state and respawn using donedl.
Fix passing arg9 (qvm only), arg10, and arg11 to vmMain for native libs and non-i386 compiled or interpated qvms. (Currently they aren't use in vmMain in game, cgame, or ui.)
Fix passing args[11] to args[15] from vm to engine on ppc64 and sparc64. Some of the args are used by game bot prediction syscalls. May have been causing bugs. Note: This was fixed for x86_64 in r2163.
Fix reconnect command to work after leaving server. (#5794)
Fix dedicated server crashing when using MSG_ReadDelta*, though it only happens if someone modifies the engine. (#5449)
Makefile fixes for OpenBSD by Jonathan Gray. (#5728)
Save all arguments from connect for reconnect command.
Remove unnecessary localhost check from reconnect command.
Support r_srgb even without hardware support. Also tweak default autoexposure/tonemap settings to look good on both r_srgb 0 and 1.
Changed the MacOS-X build system to make UB's containing i386 and x86_64 arches and made make-macosx.sh not build UB's but only standard binaries
Fix spectator client being switched from follow to free after map_restart if following a client with a higher client number.
Fix client unlinking issue caused by ent->s.number being set to followed client's ps->clientNum after map_restart. Reported by Ensiform.
Changes from Ensiform:
- In G_AddBot, try to allocate clientNum before doing anything else.
- In G_AddBot, don't set SVF_BOT and inuse. It's done in ClientConnect, plus inuse causes ClientDisconnect to be run for no reason.
- In G_AddBot, only set skill in bot useinfo once.
- Avoid using cl->ps.clientNum to check if cl is a bot.
Fix bot skill format so it doesn't always have a space at the beginning of it.
More fixes to the macosx buildsystem. This removes the SDL Framework and makes use of a SDL library that is position independant. This also brings back PPC builds into the UB and also as a standa alone build choice.
Have make-macosx.sh require the user to specify which architecture she/he wants to build for and suggest building UB's if the user is unaware of what architectures are
Lets list all the valid options.
2017-07-09 21:21:12 +00:00
|
|
|
MSG_WriteBits (&fakemsg, clc.voipFlags, VOIP_FLAGCNT);
|
2011-07-29 17:52:36 +00:00
|
|
|
MSG_WriteData (&fakemsg, clc.voipOutgoingData, voipSize);
|
|
|
|
MSG_WriteByte (&fakemsg, svc_EOF);
|
|
|
|
CL_WriteDemoMessage (&fakemsg, 0);
|
2011-02-18 14:31:32 +00:00
|
|
|
}
|
|
|
|
|
2011-07-29 17:52:36 +00:00
|
|
|
clc.voipOutgoingSequence += clc.voipOutgoingDataFrames;
|
|
|
|
clc.voipOutgoingDataSize = 0;
|
|
|
|
clc.voipOutgoingDataFrames = 0;
|
2011-02-18 14:31:32 +00:00
|
|
|
}
|
2011-07-29 17:52:36 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// We have data, but no targets. Silently discard all data
|
|
|
|
clc.voipOutgoingDataSize = 0;
|
|
|
|
clc.voipOutgoingDataFrames = 0;
|
2011-02-18 14:31:32 +00:00
|
|
|
}
|
2011-07-29 17:52:36 +00:00
|
|
|
}
|
2011-02-18 14:31:32 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if ( count >= 1 ) {
|
|
|
|
if ( cl_showSend->integer ) {
|
|
|
|
Com_Printf( "(%i)", count );
|
|
|
|
}
|
|
|
|
|
|
|
|
// begin a client move command
|
|
|
|
if ( cl_nodelta->integer || !cl.snap.valid || clc.demowaiting
|
|
|
|
|| clc.serverMessageSequence != cl.snap.messageNum ) {
|
|
|
|
MSG_WriteByte (&buf, clc_moveNoDelta);
|
|
|
|
} else {
|
|
|
|
MSG_WriteByte (&buf, clc_move);
|
|
|
|
}
|
|
|
|
|
|
|
|
// write the command count
|
|
|
|
MSG_WriteByte( &buf, count );
|
|
|
|
|
|
|
|
// use the checksum feed in the key
|
|
|
|
key = clc.checksumFeed;
|
|
|
|
// also use the message acknowledge
|
|
|
|
key ^= clc.serverMessageSequence;
|
|
|
|
// also use the last acknowledged server command in the key
|
|
|
|
key ^= MSG_HashKey(clc.serverCommands[ clc.serverCommandSequence & (MAX_RELIABLE_COMMANDS-1) ], 32);
|
|
|
|
|
|
|
|
// write all the commands, including the predicted command
|
|
|
|
for ( i = 0 ; i < count ; i++ ) {
|
|
|
|
j = (cl.cmdNumber - count + i + 1) & CMD_MASK;
|
|
|
|
cmd = &cl.cmds[j];
|
|
|
|
MSG_WriteDeltaUsercmdKey (&buf, key, oldcmd, cmd);
|
|
|
|
oldcmd = cmd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// deliver the message
|
|
|
|
//
|
|
|
|
packetNum = clc.netchan.outgoingSequence & PACKET_MASK;
|
|
|
|
cl.outPackets[ packetNum ].p_realtime = cls.realtime;
|
|
|
|
cl.outPackets[ packetNum ].p_serverTime = oldcmd->serverTime;
|
|
|
|
cl.outPackets[ packetNum ].p_cmdNumber = cl.cmdNumber;
|
|
|
|
clc.lastPacketSentTime = cls.realtime;
|
|
|
|
|
|
|
|
if ( cl_showSend->integer ) {
|
|
|
|
Com_Printf( "%i ", buf.cursize );
|
|
|
|
}
|
|
|
|
|
|
|
|
CL_Netchan_Transmit (&clc.netchan, &buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=================
|
|
|
|
CL_SendCmd
|
|
|
|
|
|
|
|
Called every frame to builds and sends a command packet to the server.
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
void CL_SendCmd( void ) {
|
|
|
|
// don't send any message if not connected
|
2011-07-26 08:52:24 +00:00
|
|
|
if ( clc.state < CA_CONNECTED ) {
|
2011-02-18 14:31:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// don't send commands if paused
|
|
|
|
if ( com_sv_running->integer && sv_paused->integer && cl_paused->integer ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// we create commands even if a demo is playing,
|
|
|
|
CL_CreateNewCommands();
|
|
|
|
|
|
|
|
// don't send a packet if the last packet was sent too recently
|
|
|
|
if ( !CL_ReadyToSendPacket() ) {
|
|
|
|
if ( cl_showSend->integer ) {
|
|
|
|
Com_Printf( ". " );
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CL_WritePacket();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
CL_InitInput
|
|
|
|
============
|
|
|
|
*/
|
|
|
|
void CL_InitInput( void ) {
|
|
|
|
Cmd_AddCommand ("centerview",IN_CenterView);
|
|
|
|
|
|
|
|
Cmd_AddCommand ("+moveup",IN_UpDown);
|
|
|
|
Cmd_AddCommand ("-moveup",IN_UpUp);
|
|
|
|
Cmd_AddCommand ("+movedown",IN_DownDown);
|
|
|
|
Cmd_AddCommand ("-movedown",IN_DownUp);
|
|
|
|
Cmd_AddCommand ("+left",IN_LeftDown);
|
|
|
|
Cmd_AddCommand ("-left",IN_LeftUp);
|
|
|
|
Cmd_AddCommand ("+right",IN_RightDown);
|
|
|
|
Cmd_AddCommand ("-right",IN_RightUp);
|
|
|
|
Cmd_AddCommand ("+forward",IN_ForwardDown);
|
|
|
|
Cmd_AddCommand ("-forward",IN_ForwardUp);
|
|
|
|
Cmd_AddCommand ("+back",IN_BackDown);
|
|
|
|
Cmd_AddCommand ("-back",IN_BackUp);
|
|
|
|
Cmd_AddCommand ("+lookup", IN_LookupDown);
|
|
|
|
Cmd_AddCommand ("-lookup", IN_LookupUp);
|
|
|
|
Cmd_AddCommand ("+lookdown", IN_LookdownDown);
|
|
|
|
Cmd_AddCommand ("-lookdown", IN_LookdownUp);
|
|
|
|
Cmd_AddCommand ("+strafe", IN_StrafeDown);
|
|
|
|
Cmd_AddCommand ("-strafe", IN_StrafeUp);
|
|
|
|
Cmd_AddCommand ("+moveleft", IN_MoveleftDown);
|
|
|
|
Cmd_AddCommand ("-moveleft", IN_MoveleftUp);
|
|
|
|
Cmd_AddCommand ("+moveright", IN_MoverightDown);
|
|
|
|
Cmd_AddCommand ("-moveright", IN_MoverightUp);
|
|
|
|
Cmd_AddCommand ("+speed", IN_SpeedDown);
|
|
|
|
Cmd_AddCommand ("-speed", IN_SpeedUp);
|
|
|
|
Cmd_AddCommand ("+attack", IN_Button0Down);
|
|
|
|
Cmd_AddCommand ("-attack", IN_Button0Up);
|
|
|
|
Cmd_AddCommand ("+button0", IN_Button0Down);
|
|
|
|
Cmd_AddCommand ("-button0", IN_Button0Up);
|
|
|
|
Cmd_AddCommand ("+button1", IN_Button1Down);
|
|
|
|
Cmd_AddCommand ("-button1", IN_Button1Up);
|
|
|
|
Cmd_AddCommand ("+button2", IN_Button2Down);
|
|
|
|
Cmd_AddCommand ("-button2", IN_Button2Up);
|
|
|
|
Cmd_AddCommand ("+button3", IN_Button3Down);
|
|
|
|
Cmd_AddCommand ("-button3", IN_Button3Up);
|
|
|
|
Cmd_AddCommand ("+button4", IN_Button4Down);
|
|
|
|
Cmd_AddCommand ("-button4", IN_Button4Up);
|
|
|
|
Cmd_AddCommand ("+button5", IN_Button5Down);
|
|
|
|
Cmd_AddCommand ("-button5", IN_Button5Up);
|
|
|
|
Cmd_AddCommand ("+button6", IN_Button6Down);
|
|
|
|
Cmd_AddCommand ("-button6", IN_Button6Up);
|
|
|
|
Cmd_AddCommand ("+button7", IN_Button7Down);
|
|
|
|
Cmd_AddCommand ("-button7", IN_Button7Up);
|
|
|
|
Cmd_AddCommand ("+button8", IN_Button8Down);
|
|
|
|
Cmd_AddCommand ("-button8", IN_Button8Up);
|
|
|
|
Cmd_AddCommand ("+button9", IN_Button9Down);
|
|
|
|
Cmd_AddCommand ("-button9", IN_Button9Up);
|
|
|
|
Cmd_AddCommand ("+button10", IN_Button10Down);
|
|
|
|
Cmd_AddCommand ("-button10", IN_Button10Up);
|
|
|
|
Cmd_AddCommand ("+button11", IN_Button11Down);
|
|
|
|
Cmd_AddCommand ("-button11", IN_Button11Up);
|
|
|
|
Cmd_AddCommand ("+button12", IN_Button12Down);
|
|
|
|
Cmd_AddCommand ("-button12", IN_Button12Up);
|
|
|
|
Cmd_AddCommand ("+button13", IN_Button13Down);
|
|
|
|
Cmd_AddCommand ("-button13", IN_Button13Up);
|
|
|
|
Cmd_AddCommand ("+button14", IN_Button14Down);
|
|
|
|
Cmd_AddCommand ("-button14", IN_Button14Up);
|
|
|
|
Cmd_AddCommand ("+mlook", IN_MLookDown);
|
|
|
|
Cmd_AddCommand ("-mlook", IN_MLookUp);
|
|
|
|
|
|
|
|
#ifdef USE_VOIP
|
|
|
|
Cmd_AddCommand ("+voiprecord", IN_VoipRecordDown);
|
|
|
|
Cmd_AddCommand ("-voiprecord", IN_VoipRecordUp);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0);
|
|
|
|
cl_debugMove = Cvar_Get ("cl_debugMove", "0", 0);
|
|
|
|
}
|
2011-07-26 08:52:24 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
CL_ShutdownInput
|
|
|
|
============
|
|
|
|
*/
|
|
|
|
void CL_ShutdownInput(void)
|
|
|
|
{
|
|
|
|
Cmd_RemoveCommand("centerview");
|
|
|
|
|
|
|
|
Cmd_RemoveCommand("+moveup");
|
|
|
|
Cmd_RemoveCommand("-moveup");
|
|
|
|
Cmd_RemoveCommand("+movedown");
|
|
|
|
Cmd_RemoveCommand("-movedown");
|
|
|
|
Cmd_RemoveCommand("+left");
|
|
|
|
Cmd_RemoveCommand("-left");
|
|
|
|
Cmd_RemoveCommand("+right");
|
|
|
|
Cmd_RemoveCommand("-right");
|
|
|
|
Cmd_RemoveCommand("+forward");
|
|
|
|
Cmd_RemoveCommand("-forward");
|
|
|
|
Cmd_RemoveCommand("+back");
|
|
|
|
Cmd_RemoveCommand("-back");
|
|
|
|
Cmd_RemoveCommand("+lookup");
|
|
|
|
Cmd_RemoveCommand("-lookup");
|
|
|
|
Cmd_RemoveCommand("+lookdown");
|
|
|
|
Cmd_RemoveCommand("-lookdown");
|
|
|
|
Cmd_RemoveCommand("+strafe");
|
|
|
|
Cmd_RemoveCommand("-strafe");
|
|
|
|
Cmd_RemoveCommand("+moveleft");
|
|
|
|
Cmd_RemoveCommand("-moveleft");
|
|
|
|
Cmd_RemoveCommand("+moveright");
|
|
|
|
Cmd_RemoveCommand("-moveright");
|
|
|
|
Cmd_RemoveCommand("+speed");
|
|
|
|
Cmd_RemoveCommand("-speed");
|
|
|
|
Cmd_RemoveCommand("+attack");
|
|
|
|
Cmd_RemoveCommand("-attack");
|
|
|
|
Cmd_RemoveCommand("+button0");
|
|
|
|
Cmd_RemoveCommand("-button0");
|
|
|
|
Cmd_RemoveCommand("+button1");
|
|
|
|
Cmd_RemoveCommand("-button1");
|
|
|
|
Cmd_RemoveCommand("+button2");
|
|
|
|
Cmd_RemoveCommand("-button2");
|
|
|
|
Cmd_RemoveCommand("+button3");
|
|
|
|
Cmd_RemoveCommand("-button3");
|
|
|
|
Cmd_RemoveCommand("+button4");
|
|
|
|
Cmd_RemoveCommand("-button4");
|
|
|
|
Cmd_RemoveCommand("+button5");
|
|
|
|
Cmd_RemoveCommand("-button5");
|
|
|
|
Cmd_RemoveCommand("+button6");
|
|
|
|
Cmd_RemoveCommand("-button6");
|
|
|
|
Cmd_RemoveCommand("+button7");
|
|
|
|
Cmd_RemoveCommand("-button7");
|
|
|
|
Cmd_RemoveCommand("+button8");
|
|
|
|
Cmd_RemoveCommand("-button8");
|
|
|
|
Cmd_RemoveCommand("+button9");
|
|
|
|
Cmd_RemoveCommand("-button9");
|
|
|
|
Cmd_RemoveCommand("+button10");
|
|
|
|
Cmd_RemoveCommand("-button10");
|
|
|
|
Cmd_RemoveCommand("+button11");
|
|
|
|
Cmd_RemoveCommand("-button11");
|
|
|
|
Cmd_RemoveCommand("+button12");
|
|
|
|
Cmd_RemoveCommand("-button12");
|
|
|
|
Cmd_RemoveCommand("+button13");
|
|
|
|
Cmd_RemoveCommand("-button13");
|
|
|
|
Cmd_RemoveCommand("+button14");
|
|
|
|
Cmd_RemoveCommand("-button14");
|
|
|
|
Cmd_RemoveCommand("+mlook");
|
|
|
|
Cmd_RemoveCommand("-mlook");
|
|
|
|
|
|
|
|
#ifdef USE_VOIP
|
|
|
|
Cmd_RemoveCommand("+voiprecord");
|
|
|
|
Cmd_RemoveCommand("-voiprecord");
|
|
|
|
#endif
|
|
|
|
}
|