1 /*
2 ===========================================================================
3 
4 Return to Castle Wolfenstein multiplayer GPL Source Code
5 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Return to Castle Wolfenstein multiplayer GPL Source Code (“RTCW MP Source Code”).
8 
9 RTCW MP Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 RTCW MP Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with RTCW MP Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the RTCW MP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW MP Source Code.  If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 // cl.input.c  -- builds an intended movement command to send to the server
30 
31 #include "client.h"
32 
33 unsigned frame_msec;
34 int old_com_frameTime;
35 
36 /*
37 ===============================================================================
38 
39 KEY BUTTONS
40 
41 Continuous button event tracking is complicated by the fact that two different
42 input sources (say, mouse button 1 and the control key) can both press the
43 same button, but the button should only be released when both of the
44 pressing key have been released.
45 
46 When a key event issues a button command (+forward, +attack, etc), it appends
47 its key number as argv(1) so it can be matched up with the release.
48 
49 argv(2) will be set to the time the event happened, which allows exact
50 control even at low framerates when the down and up events may both get qued
51 at the same time.
52 
53 ===============================================================================
54 */
55 
56 static kbutton_t kb[NUM_BUTTONS];
57 
58 #ifdef USE_VOIP
59 kbutton_t	in_voiprecord;
60 #endif
61 
IN_MLookDown(void)62 void IN_MLookDown( void ) {
63 	kb[KB_MLOOK].active = qtrue;
64 }
65 
IN_MLookUp(void)66 void IN_MLookUp( void ) {
67 	kb[KB_MLOOK].active = qfalse;
68 	if ( !cl_freelook->integer ) {
69 		IN_CenterView();
70 	}
71 }
72 
IN_KeyDown(kbutton_t * b)73 void IN_KeyDown( kbutton_t *b ) {
74 	int k;
75 	char    *c;
76 
77 	c = Cmd_Argv( 1 );
78 	if ( c[0] ) {
79 		k = atoi( c );
80 	} else {
81 		k = -1;     // typed manually at the console for continuous down
82 	}
83 
84 	if ( k == b->down[0] || k == b->down[1] ) {
85 		return;     // repeating key
86 	}
87 
88 	if ( !b->down[0] ) {
89 		b->down[0] = k;
90 	} else if ( !b->down[1] ) {
91 		b->down[1] = k;
92 	} else {
93 		Com_Printf( "Three keys down for a button!\n" );
94 		return;
95 	}
96 
97 	if ( b->active ) {
98 		return;     // still down
99 	}
100 
101 	// save timestamp for partial frame summing
102 	c = Cmd_Argv( 2 );
103 	b->downtime = atoi( c );
104 
105 	b->active = qtrue;
106 	b->wasPressed = qtrue;
107 }
108 
IN_KeyUp(kbutton_t * b)109 void IN_KeyUp( kbutton_t *b ) {
110 	int k;
111 	char    *c;
112 	unsigned uptime;
113 
114 	c = Cmd_Argv( 1 );
115 	if ( c[0] ) {
116 		k = atoi( c );
117 	} else {
118 		// typed manually at the console, assume for unsticking, so clear all
119 		b->down[0] = b->down[1] = 0;
120 		b->active = qfalse;
121 		return;
122 	}
123 
124 	if ( b->down[0] == k ) {
125 		b->down[0] = 0;
126 	} else if ( b->down[1] == k ) {
127 		b->down[1] = 0;
128 	} else {
129 		return;     // key up without coresponding down (menu pass through)
130 	}
131 	if ( b->down[0] || b->down[1] ) {
132 		return;     // some other key is still holding it down
133 	}
134 
135 	b->active = qfalse;
136 
137 	// save timestamp for partial frame summing
138 	c = Cmd_Argv( 2 );
139 	uptime = atoi( c );
140 	if ( uptime ) {
141 		b->msec += uptime - b->downtime;
142 	} else {
143 		b->msec += frame_msec / 2;
144 	}
145 
146 	b->active = qfalse;
147 }
148 
149 
150 
151 /*
152 ===============
153 CL_KeyState
154 
155 Returns the fraction of the frame that the key was down
156 ===============
157 */
CL_KeyState(kbutton_t * key)158 float CL_KeyState( kbutton_t *key ) {
159 	float val;
160 	int msec;
161 
162 	msec = key->msec;
163 	key->msec = 0;
164 
165 	if ( key->active ) {
166 		// still down
167 		if ( !key->downtime ) {
168 			msec = com_frameTime;
169 		} else {
170 			msec += com_frameTime - key->downtime;
171 		}
172 		key->downtime = com_frameTime;
173 	}
174 
175 #if 0
176 	if ( msec ) {
177 		Com_Printf( "%i ", msec );
178 	}
179 #endif
180 
181 	val = (float)msec / frame_msec;
182 	if ( val < 0 ) {
183 		val = 0;
184 	}
185 	if ( val > 1 ) {
186 		val = 1;
187 	}
188 
189 	return val;
190 }
191 
192 
193 
IN_UpDown(void)194 void IN_UpDown( void ) {IN_KeyDown( &kb[KB_UP] );}
IN_UpUp(void)195 void IN_UpUp( void ) {IN_KeyUp( &kb[KB_UP] );}
IN_DownDown(void)196 void IN_DownDown( void ) {IN_KeyDown( &kb[KB_DOWN] );}
IN_DownUp(void)197 void IN_DownUp( void ) {IN_KeyUp( &kb[KB_DOWN] );}
IN_LeftDown(void)198 void IN_LeftDown( void ) {IN_KeyDown( &kb[KB_LEFT] );}
IN_LeftUp(void)199 void IN_LeftUp( void ) {IN_KeyUp( &kb[KB_LEFT] );}
IN_RightDown(void)200 void IN_RightDown( void ) {IN_KeyDown( &kb[KB_RIGHT] );}
IN_RightUp(void)201 void IN_RightUp( void ) {IN_KeyUp( &kb[KB_RIGHT] );}
IN_ForwardDown(void)202 void IN_ForwardDown( void ) {IN_KeyDown( &kb[KB_FORWARD] );}
IN_ForwardUp(void)203 void IN_ForwardUp( void ) {IN_KeyUp( &kb[KB_FORWARD] );}
IN_BackDown(void)204 void IN_BackDown( void ) {IN_KeyDown( &kb[KB_BACK] );}
IN_BackUp(void)205 void IN_BackUp( void ) {IN_KeyUp( &kb[KB_BACK] );}
IN_LookupDown(void)206 void IN_LookupDown( void ) {IN_KeyDown( &kb[KB_LOOKUP] );}
IN_LookupUp(void)207 void IN_LookupUp( void ) {IN_KeyUp( &kb[KB_LOOKUP] );}
IN_LookdownDown(void)208 void IN_LookdownDown( void ) {IN_KeyDown( &kb[KB_LOOKDOWN] );}
IN_LookdownUp(void)209 void IN_LookdownUp( void ) {IN_KeyUp( &kb[KB_LOOKDOWN] );}
IN_MoveleftDown(void)210 void IN_MoveleftDown( void ) {IN_KeyDown( &kb[KB_MOVELEFT] );}
IN_MoveleftUp(void)211 void IN_MoveleftUp( void ) {IN_KeyUp( &kb[KB_MOVELEFT] );}
IN_MoverightDown(void)212 void IN_MoverightDown( void ) {IN_KeyDown( &kb[KB_MOVERIGHT] );}
IN_MoverightUp(void)213 void IN_MoverightUp( void ) {IN_KeyUp( &kb[KB_MOVERIGHT] );}
214 
IN_SpeedDown(void)215 void IN_SpeedDown( void ) {IN_KeyDown( &kb[KB_SPEED] );}
IN_SpeedUp(void)216 void IN_SpeedUp( void ) {IN_KeyUp( &kb[KB_SPEED] );}
IN_StrafeDown(void)217 void IN_StrafeDown( void ) {IN_KeyDown( &kb[KB_STRAFE] );}
IN_StrafeUp(void)218 void IN_StrafeUp( void ) {IN_KeyUp( &kb[KB_STRAFE] );}
219 
220 #ifdef USE_VOIP
IN_VoipRecordDown(void)221 void IN_VoipRecordDown(void)
222 {
223 	IN_KeyDown(&in_voiprecord);
224 	Cvar_Set("cl_voipSend", "1");
225 }
226 
IN_VoipRecordUp(void)227 void IN_VoipRecordUp(void)
228 {
229 	IN_KeyUp(&in_voiprecord);
230 	Cvar_Set("cl_voipSend", "0");
231 }
232 #endif
233 
IN_Button0Down(void)234 void IN_Button0Down( void ) {IN_KeyDown( &kb[KB_BUTTONS0] );}
IN_Button0Up(void)235 void IN_Button0Up( void ) {IN_KeyUp( &kb[KB_BUTTONS0] );}
IN_Button1Down(void)236 void IN_Button1Down( void ) {IN_KeyDown( &kb[KB_BUTTONS1] );}
IN_Button1Up(void)237 void IN_Button1Up( void ) {IN_KeyUp( &kb[KB_BUTTONS1] );}
IN_UseItemDown(void)238 void IN_UseItemDown( void ) {IN_KeyDown( &kb[KB_BUTTONS2] );}
IN_UseItemUp(void)239 void IN_UseItemUp( void ) {IN_KeyUp( &kb[KB_BUTTONS2] );}
IN_Button3Down(void)240 void IN_Button3Down( void ) {IN_KeyDown( &kb[KB_BUTTONS3] );}
IN_Button3Up(void)241 void IN_Button3Up( void ) {IN_KeyUp( &kb[KB_BUTTONS3] );}
IN_Button4Down(void)242 void IN_Button4Down( void ) {IN_KeyDown( &kb[KB_BUTTONS4] );}
IN_Button4Up(void)243 void IN_Button4Up( void ) {IN_KeyUp( &kb[KB_BUTTONS4] );}
244 // void IN_Button5Down(void) {IN_KeyDown(&kb[KB_BUTTONS5]);}
245 // void IN_Button5Up(void) {IN_KeyUp(&kb[KB_BUTTONS5]);}
246 
247 // void IN_Button6Down(void) {IN_KeyDown(&kb[KB_BUTTONS6]);}
248 // void IN_Button6Up(void) {IN_KeyUp(&kb[KB_BUTTONS6]);}
249 
250 // Rafael activate
IN_ActivateDown(void)251 void IN_ActivateDown( void ) {IN_KeyDown( &kb[KB_BUTTONS6] );}
IN_ActivateUp(void)252 void IN_ActivateUp( void ) {IN_KeyUp( &kb[KB_BUTTONS6] );}
253 // done.
254 
255 // Rafael Kick
IN_KickDown(void)256 void IN_KickDown( void ) {IN_KeyDown( &kb[KB_KICK] );}
IN_KickUp(void)257 void IN_KickUp( void ) {IN_KeyUp( &kb[KB_KICK] );}
258 // done.
259 
IN_SprintDown(void)260 void IN_SprintDown( void ) {IN_KeyDown( &kb[KB_BUTTONS5] );}
IN_SprintUp(void)261 void IN_SprintUp( void ) {IN_KeyUp( &kb[KB_BUTTONS5] );}
262 
263 
264 // wbuttons (wolf buttons)
IN_Wbutton0Down(void)265 void IN_Wbutton0Down( void )  { IN_KeyDown( &kb[KB_WBUTTONS0] );    }   //----(SA) secondary fire button
IN_Wbutton0Up(void)266 void IN_Wbutton0Up( void )    { IN_KeyUp( &kb[KB_WBUTTONS0] );  }
IN_ZoomDown(void)267 void IN_ZoomDown( void )      { IN_KeyDown( &kb[KB_WBUTTONS1] );    }   //----(SA)	zoom key
IN_ZoomUp(void)268 void IN_ZoomUp( void )        { IN_KeyUp( &kb[KB_WBUTTONS1] );  }
IN_QuickGrenDown(void)269 void IN_QuickGrenDown( void ) { IN_KeyDown( &kb[KB_WBUTTONS2] );    }   //----(SA)	"Quickgrenade"
IN_QuickGrenUp(void)270 void IN_QuickGrenUp( void )   { IN_KeyUp( &kb[KB_WBUTTONS2] );  }
IN_ReloadDown(void)271 void IN_ReloadDown( void )    { IN_KeyDown( &kb[KB_WBUTTONS3] );    }   //----(SA)	manual weapon re-load
IN_ReloadUp(void)272 void IN_ReloadUp( void )      { IN_KeyUp( &kb[KB_WBUTTONS3] );  }
IN_LeanLeftDown(void)273 void IN_LeanLeftDown( void )  { IN_KeyDown( &kb[KB_WBUTTONS4] );    }   //----(SA)	lean left
IN_LeanLeftUp(void)274 void IN_LeanLeftUp( void )    { IN_KeyUp( &kb[KB_WBUTTONS4] );  }
IN_LeanRightDown(void)275 void IN_LeanRightDown( void ) { IN_KeyDown( &kb[KB_WBUTTONS5] );    }   //----(SA)	lean right
IN_LeanRightUp(void)276 void IN_LeanRightUp( void )   { IN_KeyUp( &kb[KB_WBUTTONS5] );  }
277 
278 // JPW NERVE
IN_MP_DropWeaponDown(void)279 void IN_MP_DropWeaponDown( void ) {IN_KeyDown( &kb[KB_WBUTTONS6] );}
IN_MP_DropWeaponUp(void)280 void IN_MP_DropWeaponUp( void ) {IN_KeyUp( &kb[KB_WBUTTONS6] );}
281 // jpw
282 
283 // unused
IN_Wbutton7Down(void)284 void IN_Wbutton7Down( void )  { IN_KeyDown( &kb[KB_WBUTTONS7] );    }
IN_Wbutton7Up(void)285 void IN_Wbutton7Up( void )    { IN_KeyUp( &kb[KB_WBUTTONS7] );  }
286 
IN_CenterView(void)287 void IN_CenterView( void ) {
288 	qboolean ok = qtrue;
289 	if ( cgvm ) {
290 		ok = VM_Call( cgvm, CG_CHECKCENTERVIEW );
291 	}
292 	if ( ok ) {
293 		cl.viewangles[PITCH] = -SHORT2ANGLE( cl.snap.ps.delta_angles[PITCH] );
294 	}
295 }
296 
IN_Notebook(void)297 void IN_Notebook( void ) {
298 	//if ( cls.state == CA_ACTIVE && !clc.demoplaying ) {
299 	//VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_NOTEBOOK);	// startup notebook
300 	//}
301 }
302 
IN_Help(void)303 void IN_Help( void ) {
304 	if ( clc.state == CA_ACTIVE && !clc.demoplaying ) {
305 		VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_HELP );        // startup help system
306 	}
307 }
308 
309 
310 //==========================================================================
311 
312 cvar_t  *cl_yawspeed;
313 cvar_t  *cl_pitchspeed;
314 
315 cvar_t  *cl_run;
316 
317 cvar_t  *cl_anglespeedkey;
318 
319 cvar_t  *cl_recoilPitch;
320 
321 cvar_t  *cl_bypassMouseInput;       // NERVE - SMF
322 
323 /*
324 ================
325 CL_AdjustAngles
326 
327 Moves the local angle positions
328 ================
329 */
CL_AdjustAngles(void)330 void CL_AdjustAngles( void ) {
331 	float speed;
332 
333 	if ( kb[KB_SPEED].active ) {
334 		speed = 0.001 * cls.frametime * cl_anglespeedkey->value;
335 	} else {
336 		speed = 0.001 * cls.frametime;
337 	}
338 
339 	if ( !kb[KB_STRAFE].active ) {
340 		cl.viewangles[YAW] -= speed * cl_yawspeed->value * CL_KeyState( &kb[KB_RIGHT] );
341 		cl.viewangles[YAW] += speed * cl_yawspeed->value * CL_KeyState( &kb[KB_LEFT] );
342 	}
343 
344 	cl.viewangles[PITCH] -= speed * cl_pitchspeed->value * CL_KeyState( &kb[KB_LOOKUP] );
345 	cl.viewangles[PITCH] += speed * cl_pitchspeed->value * CL_KeyState( &kb[KB_LOOKDOWN] );
346 }
347 
348 /*
349 ================
350 CL_KeyMove
351 
352 Sets the usercmd_t based on key states
353 ================
354 */
CL_KeyMove(usercmd_t * cmd)355 void CL_KeyMove( usercmd_t *cmd ) {
356 	int movespeed;
357 	int forward, side, up;
358 	// Rafael Kick
359 	int kick;
360 	// done
361 
362 	//
363 	// adjust for speed key / running
364 	// the walking flag is to keep animations consistant
365 	// even during acceleration and develeration
366 	//
367 	if ( kb[KB_SPEED].active ^ cl_run->integer ) {
368 		movespeed = 127;
369 		cmd->buttons &= ~BUTTON_WALKING;
370 	} else {
371 		cmd->buttons |= BUTTON_WALKING;
372 		movespeed = 64;
373 	}
374 
375 	forward = 0;
376 	side = 0;
377 	up = 0;
378 	if ( kb[KB_STRAFE].active ) {
379 		side += movespeed * CL_KeyState( &kb[KB_RIGHT] );
380 		side -= movespeed * CL_KeyState( &kb[KB_LEFT] );
381 	}
382 
383 	side += movespeed * CL_KeyState( &kb[KB_MOVERIGHT] );
384 	side -= movespeed * CL_KeyState( &kb[KB_MOVELEFT] );
385 
386 //----(SA)	added
387 	if ( cmd->buttons & BUTTON_ACTIVATE ) {
388 		if ( side > 0 ) {
389 			cmd->wbuttons |= WBUTTON_LEANRIGHT;
390 		} else if ( side < 0 ) {
391 			cmd->wbuttons |= WBUTTON_LEANLEFT;
392 		}
393 
394 		side = 0;   // disallow the strafe when holding 'activate'
395 	}
396 //----(SA)	end
397 
398 	up += movespeed * CL_KeyState( &kb[KB_UP] );
399 	up -= movespeed * CL_KeyState( &kb[KB_DOWN] );
400 
401 	forward += movespeed * CL_KeyState( &kb[KB_FORWARD] );
402 	forward -= movespeed * CL_KeyState( &kb[KB_BACK] );
403 
404 	// Rafael Kick
405 	kick = CL_KeyState( &kb[KB_KICK] );
406 	// done
407 
408 	if ( !( cl.snap.ps.persistant[PERS_HWEAPON_USE] ) ) {
409 		cmd->forwardmove = ClampChar( forward );
410 		cmd->rightmove = ClampChar( side );
411 		cmd->upmove = ClampChar( up );
412 
413 		// Rafael - Kick
414 		cmd->wolfkick = ClampChar( kick );
415 		// done
416 
417 	}
418 }
419 
420 /*
421 =================
422 CL_MouseEvent
423 =================
424 */
CL_MouseEvent(int dx,int dy,int time)425 void CL_MouseEvent( int dx, int dy, int time ) {
426 	if ( Key_GetCatcher( ) & KEYCATCH_UI ) {
427 		// NERVE - SMF - if we just want to pass it along to game
428 		if ( cl_bypassMouseInput->integer == 1 ) {
429 			cl.mouseDx[cl.mouseIndex] += dx;
430 			cl.mouseDy[cl.mouseIndex] += dy;
431 		} else {
432 			VM_Call( uivm, UI_MOUSE_EVENT, dx, dy );
433 		}
434 
435 	} else if (Key_GetCatcher( ) & KEYCATCH_CGAME) {
436 		VM_Call( cgvm, CG_MOUSE_EVENT, dx, dy );
437 	} else {
438 		cl.mouseDx[cl.mouseIndex] += dx;
439 		cl.mouseDy[cl.mouseIndex] += dy;
440 	}
441 }
442 
443 /*
444 =================
445 CL_JoystickEvent
446 
447 Joystick values stay set until changed
448 =================
449 */
CL_JoystickEvent(int axis,int value,int time)450 void CL_JoystickEvent( int axis, int value, int time ) {
451 	if ( axis < 0 || axis >= MAX_JOYSTICK_AXIS ) {
452 		Com_Error( ERR_DROP, "CL_JoystickEvent: bad axis %i", axis );
453 	}
454 	cl.joystickAxis[axis] = value;
455 }
456 
457 /*
458 =================
459 CL_JoystickMove
460 =================
461 */
CL_JoystickMove(usercmd_t * cmd)462 void CL_JoystickMove( usercmd_t *cmd ) {
463 	float anglespeed;
464 
465 	float yaw     = j_yaw->value     * cl.joystickAxis[j_yaw_axis->integer];
466 	float right   = j_side->value    * cl.joystickAxis[j_side_axis->integer];
467 	float forward = j_forward->value * cl.joystickAxis[j_forward_axis->integer];
468 	float pitch   = j_pitch->value   * cl.joystickAxis[j_pitch_axis->integer];
469 	float up      = j_up->value      * cl.joystickAxis[j_up_axis->integer];
470 
471 	if ( !( kb[KB_SPEED].active ^ cl_run->integer ) ) {
472 		cmd->buttons |= BUTTON_WALKING;
473 	}
474 
475 	if ( kb[KB_SPEED].active ) {
476 		anglespeed = 0.001 * cls.frametime * cl_anglespeedkey->value;
477 	} else {
478 		anglespeed = 0.001 * cls.frametime;
479 	}
480 
481 	if ( !kb[KB_STRAFE].active ) {
482 		cl.viewangles[YAW] += anglespeed * yaw;
483 		cmd->rightmove = ClampChar( cmd->rightmove + (int)right );
484 	} else {
485 		cl.viewangles[YAW] += anglespeed * right;
486 		cmd->rightmove = ClampChar( cmd->rightmove + (int)yaw );
487 	}
488 	if ( kb[KB_MLOOK].active ) {
489 		cl.viewangles[PITCH] += anglespeed * forward;
490 		cmd->forwardmove = ClampChar( cmd->forwardmove + (int)pitch );
491 	} else {
492 		cl.viewangles[PITCH] += anglespeed * pitch;
493 		cmd->forwardmove = ClampChar( cmd->forwardmove + (int)forward );
494 	}
495 
496 	cmd->upmove = ClampChar( cmd->upmove + (int)up );
497 }
498 
499 /*
500 =================
501 CL_MouseMove
502 =================
503 */
CL_MouseMove(usercmd_t * cmd)504 void CL_MouseMove(usercmd_t *cmd) {
505 	float mx, my;
506 
507 	// allow mouse smoothing
508 	if ( m_filter->integer ) {
509 		mx = ( cl.mouseDx[0] + cl.mouseDx[1] ) * 0.5f;
510 		my = ( cl.mouseDy[0] + cl.mouseDy[1] ) * 0.5f;
511 	} else {
512 		mx = cl.mouseDx[cl.mouseIndex];
513 		my = cl.mouseDy[cl.mouseIndex];
514 	}
515 	cl.mouseIndex ^= 1;
516 	cl.mouseDx[cl.mouseIndex] = 0;
517 	cl.mouseDy[cl.mouseIndex] = 0;
518 
519 	if (mx == 0.0f && my == 0.0f)
520 		return;
521 
522 	if (cl_mouseAccel->value != 0.0f)
523 	{
524 		if(cl_mouseAccelStyle->integer == 0)
525 		{
526 			float accelSensitivity;
527 			float rate;
528 
529 			rate = sqrt(mx * mx + my * my) / (float) frame_msec;
530 
531 			accelSensitivity = cl_sensitivity->value + rate * cl_mouseAccel->value;
532 			mx *= accelSensitivity;
533 			my *= accelSensitivity;
534 
535 			if(cl_showMouseRate->integer)
536 				Com_Printf("rate: %f, accelSensitivity: %f\n", rate, accelSensitivity);
537 		}
538 		else
539 		{
540 			float rate[2];
541 			float power[2];
542 
543 			// sensitivity remains pretty much unchanged at low speeds
544 			// cl_mouseAccel is a power value to how the acceleration is shaped
545 			// cl_mouseAccelOffset is the rate for which the acceleration will have doubled the non accelerated amplification
546 			// NOTE: decouple the config cvars for independent acceleration setup along X and Y?
547 
548 			rate[0] = fabs(mx) / (float) frame_msec;
549 			rate[1] = fabs(my) / (float) frame_msec;
550 			power[0] = powf(rate[0] / cl_mouseAccelOffset->value, cl_mouseAccel->value);
551 			power[1] = powf(rate[1] / cl_mouseAccelOffset->value, cl_mouseAccel->value);
552 
553 			mx = cl_sensitivity->value * (mx + ((mx < 0) ? -power[0] : power[0]) * cl_mouseAccelOffset->value);
554 			my = cl_sensitivity->value * (my + ((my < 0) ? -power[1] : power[1]) * cl_mouseAccelOffset->value);
555 
556 			if(cl_showMouseRate->integer)
557 				Com_Printf("ratex: %f, ratey: %f, powx: %f, powy: %f\n", rate[0], rate[1], power[0], power[1]);
558 		}
559 	}
560 	else
561 	{
562 		// Rafael - mg42
563 		if ( cl.snap.ps.persistant[PERS_HWEAPON_USE] ) {
564 			mx *= 2.5; //(accelSensitivity * 0.1);
565 			my *= 2; //(accelSensitivity * 0.075);
566 		} else
567 		{
568 			mx *= cl_sensitivity->value;
569 			my *= cl_sensitivity->value;
570 		}
571 	}
572 
573 	// ingame FOV
574 	mx *= cl.cgameSensitivity;
575 	my *= cl.cgameSensitivity;
576 
577 	// add mouse X/Y movement to cmd
578 	if ( kb[KB_STRAFE].active ) {
579 		cmd->rightmove = ClampChar( cmd->rightmove + m_side->value * mx );
580 	} else {
581 		cl.viewangles[YAW] -= m_yaw->value * mx;
582 	}
583 
584 	if ( ( kb[KB_MLOOK].active || cl_freelook->integer ) && !kb[KB_STRAFE].active ) {
585 		cl.viewangles[PITCH] += m_pitch->value * my;
586 	} else {
587 		cmd->forwardmove = ClampChar( cmd->forwardmove - m_forward->value * my );
588 	}
589 }
590 
591 
592 /*
593 ==============
594 CL_CmdButtons
595 ==============
596 */
CL_CmdButtons(usercmd_t * cmd)597 void CL_CmdButtons( usercmd_t *cmd ) {
598 	int i;
599 
600 	//
601 	// figure button bits
602 	// send a button bit even if the key was pressed and released in
603 	// less than a frame
604 	//
605 	for ( i = 0 ; i < 7 ; i++ ) {
606 		if ( kb[KB_BUTTONS0 + i].active || kb[KB_BUTTONS0 + i].wasPressed ) {
607 			cmd->buttons |= 1 << i;
608 		}
609 		kb[KB_BUTTONS0 + i].wasPressed = qfalse;
610 	}
611 
612 	for ( i = 0 ; i < 7 ; i++ ) {
613 		if ( kb[KB_WBUTTONS0 + i].active || kb[KB_WBUTTONS0 + i].wasPressed ) {
614 			cmd->wbuttons |= 1 << i;
615 		}
616 		kb[KB_WBUTTONS0 + i].wasPressed = qfalse;
617 	}
618 
619 	if ( Key_GetCatcher( ) && !cl_bypassMouseInput->integer ) {
620 		cmd->buttons |= BUTTON_TALK;
621 	}
622 
623 	// allow the game to know if any key at all is
624 	// currently pressed, even if it isn't bound to anything
625 	if ( anykeydown && ( Key_GetCatcher( ) == 0 || cl_bypassMouseInput->integer ) ) {
626 		cmd->buttons |= BUTTON_ANY;
627 	}
628 }
629 
630 
631 /*
632 ==============
633 CL_FinishMove
634 ==============
635 */
CL_FinishMove(usercmd_t * cmd)636 void CL_FinishMove( usercmd_t *cmd ) {
637 	int i;
638 
639 	// copy the state that the cgame is currently sending
640 	cmd->weapon = cl.cgameUserCmdValue;
641 
642 	cmd->holdable = cl.cgameUserHoldableValue;  //----(SA)	modified
643 
644 	cmd->mpSetup = cl.cgameMpSetup;             // NERVE - SMF
645 	cmd->identClient = cl.cgameMpIdentClient;   // NERVE - SMF
646 
647 	// send the current server time so the amount of movement
648 	// can be determined without allowing cheating
649 	cmd->serverTime = cl.serverTime;
650 
651 	for ( i = 0 ; i < 3 ; i++ ) {
652 		cmd->angles[i] = ANGLE2SHORT( cl.viewangles[i] );
653 	}
654 }
655 
656 
657 /*
658 =================
659 CL_CreateCmd
660 =================
661 */
CL_CreateCmd(void)662 usercmd_t CL_CreateCmd( void ) {
663 	usercmd_t cmd;
664 	vec3_t oldAngles;
665 	float recoilAdd;
666 
667 	VectorCopy( cl.viewangles, oldAngles );
668 
669 	// keyboard angle adjustment
670 	CL_AdjustAngles();
671 
672 	memset( &cmd, 0, sizeof( cmd ) );
673 
674 	CL_CmdButtons( &cmd );
675 
676 	// get basic movement from keyboard
677 	CL_KeyMove( &cmd );
678 
679 	// get basic movement from mouse
680 	CL_MouseMove( &cmd );
681 
682 	// get basic movement from joystick
683 	CL_JoystickMove( &cmd );
684 
685 	// check to make sure the angles haven't wrapped
686 	if ( cl.viewangles[PITCH] - oldAngles[PITCH] > 90 ) {
687 		cl.viewangles[PITCH] = oldAngles[PITCH] + 90;
688 	} else if ( oldAngles[PITCH] - cl.viewangles[PITCH] > 90 ) {
689 		cl.viewangles[PITCH] = oldAngles[PITCH] - 90;
690 	}
691 
692 	// RF, set the kickAngles so aiming is effected
693 	recoilAdd = cl_recoilPitch->value;
694 	if ( fabs( cl.viewangles[PITCH] + recoilAdd ) < 40 ) {
695 		cl.viewangles[PITCH] += recoilAdd;
696 	}
697 	// the recoilPitch has been used, so clear it out
698 	cl_recoilPitch->value = 0;
699 
700 	// store out the final values
701 	CL_FinishMove( &cmd );
702 
703 	// draw debug graphs of turning for mouse testing
704 	if ( cl_debugMove->integer ) {
705 		if ( cl_debugMove->integer == 1 ) {
706 			SCR_DebugGraph( fabs(cl.viewangles[YAW] - oldAngles[YAW]) );
707 		}
708 		if ( cl_debugMove->integer == 2 ) {
709 			SCR_DebugGraph( fabs(cl.viewangles[PITCH] - oldAngles[PITCH]) );
710 		}
711 	}
712 
713 	return cmd;
714 }
715 
716 
717 /*
718 =================
719 CL_CreateNewCommands
720 
721 Create a new usercmd_t structure for this frame
722 =================
723 */
CL_CreateNewCommands(void)724 void CL_CreateNewCommands( void ) {
725 	int cmdNum;
726 
727 	// no need to create usercmds until we have a gamestate
728 	if ( clc.state < CA_PRIMED ) {
729 		return;
730 	}
731 
732 	frame_msec = com_frameTime - old_com_frameTime;
733 
734 	// if running over 1000fps, act as if each frame is 1ms
735 	// prevents divisions by zero
736 	if ( frame_msec < 1 ) {
737 		frame_msec = 1;
738 	}
739 
740 	// if running less than 5fps, truncate the extra time to prevent
741 	// unexpected moves after a hitch
742 	if ( frame_msec > 200 ) {
743 		frame_msec = 200;
744 	}
745 	old_com_frameTime = com_frameTime;
746 
747 
748 	// generate a command for this frame
749 	cl.cmdNumber++;
750 	cmdNum = cl.cmdNumber & CMD_MASK;
751 	cl.cmds[cmdNum] = CL_CreateCmd();
752 }
753 
754 /*
755 =================
756 CL_ReadyToSendPacket
757 
758 Returns qfalse if we are over the maxpackets limit
759 and should choke back the bandwidth a bit by not sending
760 a packet this frame.  All the commands will still get
761 delivered in the next packet, but saving a header and
762 getting more delta compression will reduce total bandwidth.
763 =================
764 */
CL_ReadyToSendPacket(void)765 qboolean CL_ReadyToSendPacket( void ) {
766 	int oldPacketNum;
767 	int delta;
768 
769 	// don't send anything if playing back a demo
770 	if ( clc.demoplaying || clc.state == CA_CINEMATIC ) {
771 		return qfalse;
772 	}
773 
774 	// If we are downloading, we send no less than 50ms between packets
775 	if ( *clc.downloadTempName &&
776 		 cls.realtime - clc.lastPacketSentTime < 50 ) {
777 		return qfalse;
778 	}
779 
780 	// if we don't have a valid gamestate yet, only send
781 	// one packet a second
782 	if ( clc.state != CA_ACTIVE &&
783 		 clc.state != CA_PRIMED &&
784 		 !*clc.downloadTempName &&
785 		 cls.realtime - clc.lastPacketSentTime < 1000 ) {
786 		return qfalse;
787 	}
788 
789 	// send every frame for loopbacks
790 	if ( clc.netchan.remoteAddress.type == NA_LOOPBACK ) {
791 		return qtrue;
792 	}
793 
794 	// send every frame for LAN
795 	if ( cl_lanForcePackets->integer && Sys_IsLANAddress( clc.netchan.remoteAddress ) ) {
796 		return qtrue;
797 	}
798 
799 	// check for exceeding cl_maxpackets
800 	if ( cl_maxpackets->integer < 25 ) {
801 		Cvar_Set( "cl_maxpackets", "25" );
802 	} else if ( cl_maxpackets->integer > 125 ) {
803 		Cvar_Set( "cl_maxpackets", "125" );
804 	}
805 	oldPacketNum = ( clc.netchan.outgoingSequence - 1 ) & PACKET_MASK;
806 	delta = cls.realtime -  cl.outPackets[ oldPacketNum ].p_realtime;
807 	if ( delta < 1000 / cl_maxpackets->integer ) {
808 		// the accumulated commands will go out in the next packet
809 		return qfalse;
810 	}
811 
812 	return qtrue;
813 }
814 
815 /*
816 ===================
817 CL_WritePacket
818 
819 Create and send the command packet to the server
820 Including both the reliable commands and the usercmds
821 
822 During normal gameplay, a client packet will contain something like:
823 
824 4	sequence number
825 2	qport
826 4	serverid
827 4	acknowledged sequence number
828 4	clc.serverCommandSequence
829 <optional reliable commands>
830 1	clc_move or clc_moveNoDelta
831 1	command count
832 <count * usercmds>
833 
834 ===================
835 */
CL_WritePacket(void)836 void CL_WritePacket( void ) {
837 	msg_t buf;
838 	byte data[MAX_MSGLEN];
839 	int i, j;
840 	usercmd_t   *cmd, *oldcmd;
841 	usercmd_t nullcmd;
842 	int packetNum;
843 	int oldPacketNum;
844 	int count, key;
845 
846 	// don't send anything if playing back a demo
847 	if ( clc.demoplaying || clc.state == CA_CINEMATIC ) {
848 		return;
849 	}
850 
851 	memset( &nullcmd, 0, sizeof( nullcmd ) );
852 	oldcmd = &nullcmd;
853 
854 	MSG_Init( &buf, data, sizeof( data ) );
855 
856 	MSG_Bitstream( &buf );
857 	// write the current serverId so the server
858 	// can tell if this is from the current gameState
859 	MSG_WriteLong( &buf, cl.serverId );
860 
861 	// write the last message we received, which can
862 	// be used for delta compression, and is also used
863 	// to tell if we dropped a gamestate
864 	MSG_WriteLong( &buf, clc.serverMessageSequence );
865 
866 	// write the last reliable message we received
867 	MSG_WriteLong( &buf, clc.serverCommandSequence );
868 
869 	// write any unacknowledged clientCommands
870 	for ( i = clc.reliableAcknowledge + 1 ; i <= clc.reliableSequence ; i++ ) {
871 		MSG_WriteByte( &buf, clc_clientCommand );
872 		MSG_WriteLong( &buf, i );
873 		MSG_WriteString( &buf, clc.reliableCommands[ i & ( MAX_RELIABLE_COMMANDS - 1 ) ] );
874 	}
875 
876 	// we want to send all the usercmds that were generated in the last
877 	// few packet, so even if a couple packets are dropped in a row,
878 	// all the cmds will make it to the server
879 	if ( cl_packetdup->integer < 0 ) {
880 		Cvar_Set( "cl_packetdup", "0" );
881 	} else if ( cl_packetdup->integer > 5 ) {
882 		Cvar_Set( "cl_packetdup", "5" );
883 	}
884 	oldPacketNum = ( clc.netchan.outgoingSequence - 1 - cl_packetdup->integer ) & PACKET_MASK;
885 	count = cl.cmdNumber - cl.outPackets[ oldPacketNum ].p_cmdNumber;
886 	if ( count > MAX_PACKET_USERCMDS ) {
887 		count = MAX_PACKET_USERCMDS;
888 		Com_Printf( "MAX_PACKET_USERCMDS\n" );
889 	}
890 
891 #ifdef USE_VOIP
892 	if (clc.voipOutgoingDataSize > 0)
893 	{
894 		if((clc.voipFlags & VOIP_SPATIAL) || Com_IsVoipTarget(clc.voipTargets, sizeof(clc.voipTargets), -1))
895 		{
896 			MSG_WriteByte (&buf, clc_voipOpus);
897 			MSG_WriteByte (&buf, clc.voipOutgoingGeneration);
898 			MSG_WriteLong (&buf, clc.voipOutgoingSequence);
899 			MSG_WriteByte (&buf, clc.voipOutgoingDataFrames);
900 			MSG_WriteData (&buf, clc.voipTargets, sizeof(clc.voipTargets));
901 			MSG_WriteByte(&buf, clc.voipFlags);
902 			MSG_WriteShort (&buf, clc.voipOutgoingDataSize);
903 			MSG_WriteData (&buf, clc.voipOutgoingData, clc.voipOutgoingDataSize);
904 
905 			// If we're recording a demo, we have to fake a server packet with
906 			//  this VoIP data so it gets to disk; the server doesn't send it
907 			//  back to us, and we might as well eliminate concerns about dropped
908 			//  and misordered packets here.
909 			if(clc.demorecording && !clc.demowaiting)
910 			{
911 				const int voipSize = clc.voipOutgoingDataSize;
912 				msg_t fakemsg;
913 				byte fakedata[MAX_MSGLEN];
914 				MSG_Init (&fakemsg, fakedata, sizeof (fakedata));
915 				MSG_Bitstream (&fakemsg);
916 				MSG_WriteLong (&fakemsg, clc.reliableAcknowledge);
917 				MSG_WriteByte (&fakemsg, svc_voipOpus);
918 				MSG_WriteShort (&fakemsg, clc.clientNum);
919 				MSG_WriteByte (&fakemsg, clc.voipOutgoingGeneration);
920 				MSG_WriteLong (&fakemsg, clc.voipOutgoingSequence);
921 				MSG_WriteByte (&fakemsg, clc.voipOutgoingDataFrames);
922 				MSG_WriteShort (&fakemsg, clc.voipOutgoingDataSize );
923 				MSG_WriteBits (&fakemsg, clc.voipFlags, VOIP_FLAGCNT);
924 				MSG_WriteData (&fakemsg, clc.voipOutgoingData, voipSize);
925 				MSG_WriteByte (&fakemsg, svc_EOF);
926 				CL_WriteDemoMessage (&fakemsg, 0);
927 			}
928 
929 			clc.voipOutgoingSequence += clc.voipOutgoingDataFrames;
930 			clc.voipOutgoingDataSize = 0;
931 			clc.voipOutgoingDataFrames = 0;
932 		}
933 		else
934 		{
935 			// We have data, but no targets. Silently discard all data
936 			clc.voipOutgoingDataSize = 0;
937 			clc.voipOutgoingDataFrames = 0;
938 		}
939 	}
940 #endif
941 
942 	if ( count >= 1 ) {
943 		if ( cl_showSend->integer ) {
944 			Com_Printf( "(%i)", count );
945 		}
946 
947 		// begin a client move command
948 		if ( cl_nodelta->integer || !cl.snap.valid || clc.demowaiting
949 			 || clc.serverMessageSequence != cl.snap.messageNum ) {
950 			MSG_WriteByte( &buf, clc_moveNoDelta );
951 		} else {
952 			MSG_WriteByte( &buf, clc_move );
953 		}
954 
955 		// write the command count
956 		MSG_WriteByte( &buf, count );
957 
958 		// use the checksum feed in the key
959 		key = clc.checksumFeed;
960 		// also use the message acknowledge
961 		key ^= clc.serverMessageSequence;
962 		// also use the last acknowledged server command in the key
963 		key ^= MSG_HashKey(clc.serverCommands[ clc.serverCommandSequence & (MAX_RELIABLE_COMMANDS-1) ], 32);
964 
965 		// write all the commands, including the predicted command
966 		for ( i = 0 ; i < count ; i++ ) {
967 			j = ( cl.cmdNumber - count + i + 1 ) & CMD_MASK;
968 			cmd = &cl.cmds[j];
969 			MSG_WriteDeltaUsercmdKey( &buf, key, oldcmd, cmd );
970 			oldcmd = cmd;
971 		}
972 	}
973 
974 	//
975 	// deliver the message
976 	//
977 	packetNum = clc.netchan.outgoingSequence & PACKET_MASK;
978 	cl.outPackets[ packetNum ].p_realtime = cls.realtime;
979 	cl.outPackets[ packetNum ].p_serverTime = oldcmd->serverTime;
980 	cl.outPackets[ packetNum ].p_cmdNumber = cl.cmdNumber;
981 	clc.lastPacketSentTime = cls.realtime;
982 
983 	if ( cl_showSend->integer ) {
984 		Com_Printf( "%i ", buf.cursize );
985 	}
986 
987 	CL_Netchan_Transmit( &clc.netchan, &buf );
988 }
989 
990 /*
991 =================
992 CL_SendCmd
993 
994 Called every frame to builds and sends a command packet to the server.
995 =================
996 */
CL_SendCmd(void)997 void CL_SendCmd( void ) {
998 	// don't send any message if not connected
999 	if ( clc.state < CA_CONNECTED ) {
1000 		return;
1001 	}
1002 
1003 	// don't send commands if paused
1004 	if ( com_sv_running->integer && sv_paused->integer && cl_paused->integer ) {
1005 		return;
1006 	}
1007 
1008 	// we create commands even if a demo is playing,
1009 	CL_CreateNewCommands();
1010 
1011 	// don't send a packet if the last packet was sent too recently
1012 	if ( !CL_ReadyToSendPacket() ) {
1013 		if ( cl_showSend->integer ) {
1014 			Com_Printf( ". " );
1015 		}
1016 		return;
1017 	}
1018 
1019 	CL_WritePacket();
1020 }
1021 
1022 /*
1023 ============
1024 CL_InitInput
1025 ============
1026 */
CL_InitInput(void)1027 void CL_InitInput( void ) {
1028 	Cmd_AddCommand( "centerview",IN_CenterView );
1029 
1030 	Cmd_AddCommand( "+moveup",IN_UpDown );
1031 	Cmd_AddCommand( "-moveup",IN_UpUp );
1032 	Cmd_AddCommand( "+movedown",IN_DownDown );
1033 	Cmd_AddCommand( "-movedown",IN_DownUp );
1034 	Cmd_AddCommand( "+left",IN_LeftDown );
1035 	Cmd_AddCommand( "-left",IN_LeftUp );
1036 	Cmd_AddCommand( "+right",IN_RightDown );
1037 	Cmd_AddCommand( "-right",IN_RightUp );
1038 	Cmd_AddCommand( "+forward",IN_ForwardDown );
1039 	Cmd_AddCommand( "-forward",IN_ForwardUp );
1040 	Cmd_AddCommand( "+back",IN_BackDown );
1041 	Cmd_AddCommand( "-back",IN_BackUp );
1042 	Cmd_AddCommand( "+lookup", IN_LookupDown );
1043 	Cmd_AddCommand( "-lookup", IN_LookupUp );
1044 	Cmd_AddCommand( "+lookdown", IN_LookdownDown );
1045 	Cmd_AddCommand( "-lookdown", IN_LookdownUp );
1046 	Cmd_AddCommand( "+strafe", IN_StrafeDown );
1047 	Cmd_AddCommand( "-strafe", IN_StrafeUp );
1048 	Cmd_AddCommand( "+moveleft", IN_MoveleftDown );
1049 	Cmd_AddCommand( "-moveleft", IN_MoveleftUp );
1050 	Cmd_AddCommand( "+moveright", IN_MoverightDown );
1051 	Cmd_AddCommand( "-moveright", IN_MoverightUp );
1052 	Cmd_AddCommand( "+speed", IN_SpeedDown );
1053 	Cmd_AddCommand( "-speed", IN_SpeedUp );
1054 
1055 	Cmd_AddCommand( "+attack", IN_Button0Down );   // ---- id   (primary firing)
1056 	Cmd_AddCommand( "-attack", IN_Button0Up );
1057 
1058 	Cmd_AddCommand( "+button1", IN_Button1Down );
1059 	Cmd_AddCommand( "-button1", IN_Button1Up );
1060 
1061 	Cmd_AddCommand( "+useitem", IN_UseItemDown );
1062 	Cmd_AddCommand( "-useitem", IN_UseItemUp );
1063 
1064 	Cmd_AddCommand( "+salute",   IN_Button3Down ); //----(SA) salute
1065 	Cmd_AddCommand( "-salute",   IN_Button3Up );
1066 
1067 	Cmd_AddCommand( "+button4", IN_Button4Down );
1068 	Cmd_AddCommand( "-button4", IN_Button4Up );
1069 
1070 	// Rafael Activate
1071 	Cmd_AddCommand( "+activate", IN_ActivateDown );
1072 	Cmd_AddCommand( "-activate", IN_ActivateUp );
1073 	// done.
1074 
1075 	// Rafael Kick
1076 	Cmd_AddCommand( "+kick", IN_KickDown );
1077 	Cmd_AddCommand( "-kick", IN_KickUp );
1078 	// done
1079 
1080 	Cmd_AddCommand( "+sprint", IN_SprintDown );
1081 	Cmd_AddCommand( "-sprint", IN_SprintUp );
1082 
1083 
1084 	// wolf buttons
1085 	Cmd_AddCommand( "+attack2",      IN_Wbutton0Down );   //----(SA) secondary firing
1086 	Cmd_AddCommand( "-attack2",      IN_Wbutton0Up );
1087 	Cmd_AddCommand( "+zoom",     IN_ZoomDown );       //
1088 	Cmd_AddCommand( "-zoom",     IN_ZoomUp );
1089 	Cmd_AddCommand( "+quickgren",    IN_QuickGrenDown );  //
1090 	Cmd_AddCommand( "-quickgren",    IN_QuickGrenUp );
1091 	Cmd_AddCommand( "+reload",       IN_ReloadDown );     //
1092 	Cmd_AddCommand( "-reload",       IN_ReloadUp );
1093 	Cmd_AddCommand( "+leanleft", IN_LeanLeftDown );
1094 	Cmd_AddCommand( "-leanleft", IN_LeanLeftUp );
1095 	Cmd_AddCommand( "+leanright",    IN_LeanRightDown );
1096 	Cmd_AddCommand( "-leanright",    IN_LeanRightUp );
1097 // JPW NERVE multiplayer buttons
1098 	Cmd_AddCommand( "+dropweapon",   IN_MP_DropWeaponDown );  // JPW NERVE drop two-handed weapon
1099 	Cmd_AddCommand( "-dropweapon",   IN_MP_DropWeaponUp );
1100 // jpw
1101 	Cmd_AddCommand( "+wbutton7", IN_Wbutton7Down );   //
1102 	Cmd_AddCommand( "-wbutton7", IN_Wbutton7Up );
1103 //----(SA) end
1104 
1105 	Cmd_AddCommand( "+mlook", IN_MLookDown );
1106 	Cmd_AddCommand( "-mlook", IN_MLookUp );
1107 
1108 #ifdef USE_VOIP
1109 	Cmd_AddCommand( "+voiprecord", IN_VoipRecordDown );
1110 	Cmd_AddCommand( "-voiprecord", IN_VoipRecordUp );
1111 #endif
1112 
1113 //	Cmd_AddCommand( "notebook", IN_Notebook );
1114 	Cmd_AddCommand( "help",IN_Help );
1115 
1116 	cl_nodelta = Cvar_Get( "cl_nodelta", "0", 0 );
1117 	cl_debugMove = Cvar_Get( "cl_debugMove", "0", 0 );
1118 }
1119 
1120 /*
1121 ============
1122 CL_ShutdownInput
1123 ============
1124 */
CL_ShutdownInput(void)1125 void CL_ShutdownInput(void)
1126 {
1127 	Cmd_RemoveCommand("centerview");
1128 
1129 	Cmd_RemoveCommand("+moveup");
1130 	Cmd_RemoveCommand("-moveup");
1131 	Cmd_RemoveCommand("+movedown");
1132 	Cmd_RemoveCommand("-movedown");
1133 	Cmd_RemoveCommand("+left");
1134 	Cmd_RemoveCommand("-left");
1135 	Cmd_RemoveCommand("+right");
1136 	Cmd_RemoveCommand("-right");
1137 	Cmd_RemoveCommand("+forward");
1138 	Cmd_RemoveCommand("-forward");
1139 	Cmd_RemoveCommand("+back");
1140 	Cmd_RemoveCommand("-back");
1141 	Cmd_RemoveCommand("+lookup");
1142 	Cmd_RemoveCommand("-lookup");
1143 	Cmd_RemoveCommand("+lookdown");
1144 	Cmd_RemoveCommand("-lookdown");
1145 	Cmd_RemoveCommand("+strafe");
1146 	Cmd_RemoveCommand("-strafe");
1147 	Cmd_RemoveCommand("+moveleft");
1148 	Cmd_RemoveCommand("-moveleft");
1149 	Cmd_RemoveCommand("+moveright");
1150 	Cmd_RemoveCommand("-moveright");
1151 	Cmd_RemoveCommand("+speed");
1152 	Cmd_RemoveCommand("-speed");
1153 
1154 	Cmd_RemoveCommand("+attack");
1155 	Cmd_RemoveCommand("-attack");
1156 
1157 	Cmd_RemoveCommand("+button1");
1158 	Cmd_RemoveCommand("-button1");
1159 
1160 	Cmd_RemoveCommand("+useitem");
1161 	Cmd_RemoveCommand("-useitem");
1162 
1163 	Cmd_RemoveCommand("+salute");
1164 	Cmd_RemoveCommand("-salute");
1165 
1166 	Cmd_RemoveCommand("+button4");
1167 	Cmd_RemoveCommand("-button4");
1168 
1169 	Cmd_RemoveCommand("+activate");
1170 	Cmd_RemoveCommand("-activate");
1171 
1172 	Cmd_RemoveCommand("+kick");
1173 	Cmd_RemoveCommand("-kick");
1174 
1175 	Cmd_RemoveCommand("+sprint");
1176 	Cmd_RemoveCommand("-sprint");
1177 
1178 	Cmd_RemoveCommand("+attack2");
1179 	Cmd_RemoveCommand("-attack2");
1180 	Cmd_RemoveCommand("+zoom");
1181 	Cmd_RemoveCommand("-zoom");
1182 	Cmd_RemoveCommand("+quickgren");
1183 	Cmd_RemoveCommand("-quickgren");
1184 	Cmd_RemoveCommand("+reload");
1185 	Cmd_RemoveCommand("-reload");
1186 	Cmd_RemoveCommand("+leanleft");
1187 	Cmd_RemoveCommand("-leanleft");
1188 	Cmd_RemoveCommand("+leanright");
1189 	Cmd_RemoveCommand("-leanright");
1190 	Cmd_RemoveCommand("+dropweapon");
1191 	Cmd_RemoveCommand("-dropweapon");
1192 	Cmd_RemoveCommand("+wbutton7");
1193 	Cmd_RemoveCommand("-wbutton7");
1194 
1195 	Cmd_RemoveCommand("+mlook");
1196 	Cmd_RemoveCommand("-mlook");
1197 
1198 #ifdef USE_VOIP
1199 	Cmd_RemoveCommand("+voiprecord");
1200 	Cmd_RemoveCommand("-voiprecord");
1201 #endif
1202 
1203 	Cmd_RemoveCommand("help");
1204 }
1205 
1206 /*
1207 ============
1208 CL_ClearKeys
1209 ============
1210 */
CL_ClearKeys(void)1211 void CL_ClearKeys( void ) {
1212 	memset( kb, 0, sizeof( kb ) );
1213 }
1214