Quake II RTX doxygen  1.0 dev
input.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 // cl.input.c -- builds an intended movement command to send to the server
19 
20 #include "client.h"
21 #include "system/lirc.h"
22 
23 static cvar_t *cl_nodelta;
24 static cvar_t *cl_maxpackets;
25 static cvar_t *cl_packetdup;
26 static cvar_t *cl_fuzzhack;
27 #ifdef _DEBUG
28 static cvar_t *cl_showpackets;
29 #endif
30 static cvar_t *cl_instantpacket;
31 static cvar_t *cl_batchcmds;
32 
33 static cvar_t *m_filter;
34  cvar_t *m_accel;
35  cvar_t *m_autosens;
36 
37 static cvar_t *cl_upspeed;
38 static cvar_t *cl_forwardspeed;
39 static cvar_t *cl_sidespeed;
40 static cvar_t *cl_yawspeed;
41 static cvar_t *cl_pitchspeed;
42 static cvar_t *cl_run;
43 static cvar_t *cl_anglespeedkey;
44 
45 static cvar_t *freelook;
46 static cvar_t *lookspring;
47 static cvar_t *lookstrafe;
48  cvar_t *sensitivity;
49 
50  cvar_t *m_pitch;
51  cvar_t *m_invert;
52  cvar_t *m_yaw;
53 static cvar_t *m_forward;
54 static cvar_t *m_side;
55 
56 /*
57 ===============================================================================
58 
59 INPUT SUBSYSTEM
60 
61 ===============================================================================
62 */
63 
64 typedef struct {
65  qboolean modified;
66  inputAPI_t api;
67  int old_dx;
68  int old_dy;
69 } in_state_t;
70 
72 
73 static cvar_t *in_enable;
74 #if USE_DINPUT
75 static cvar_t *in_direct;
76 #endif
77 static cvar_t *in_grab;
78 
79 const inputAPI_t* IN_GetAPI()
80 {
81  return &input.api;
82 }
83 
84 static qboolean IN_GetCurrentGrab(void)
85 {
86  if (cls.active != ACT_ACTIVATED)
87  return qfalse; // main window doesn't have focus
88 
89  if (r_config.flags & QVF_FULLSCREEN)
90  return qtrue; // full screen
91 
92  if (cls.key_dest & (KEY_MENU | KEY_CONSOLE))
93  return qfalse; // menu or console is up
94 
95  if (cls.state != ca_active && cls.state != ca_cinematic)
96  return qfalse; // not connected
97 
98  if (in_grab->integer >= 2) {
99  if (cls.demo.playback && !Key_IsDown(K_SHIFT))
100  return qfalse; // playing a demo (and not using freelook)
101 
102  if (cl.frame.ps.pmove.pm_type == PM_FREEZE)
103  return qfalse; // spectator mode
104  }
105 
106  if (in_grab->integer >= 1)
107  return qtrue; // regular playing mode
108 
109  return qfalse;
110 }
111 
112 /*
113 ============
114 IN_Activate
115 ============
116 */
117 void IN_Activate(void)
118 {
119  if (input.api.Grab) {
120  input.api.Grab(IN_GetCurrentGrab());
121  }
122 }
123 
124 /*
125 ============
126 IN_Restart_f
127 ============
128 */
129 static void IN_Restart_f(void)
130 {
131  IN_Shutdown();
132  IN_Init();
133 }
134 
135 /*
136 ============
137 IN_Frame
138 ============
139 */
140 void IN_Frame(void)
141 {
142  if (input.modified) {
143  IN_Restart_f();
144  return;
145  }
146 
147  if (input.api.GetEvents) {
148  input.api.GetEvents();
149  }
150 
151 #if USE_LIRC
152  Lirc_GetEvents();
153 #endif
154 }
155 
156 /*
157 ================
158 IN_WarpMouse
159 ================
160 */
161 void IN_WarpMouse(int x, int y)
162 {
163  if (input.api.Warp) {
164  input.api.Warp(x, y);
165  }
166 }
167 
168 /*
169 ============
170 IN_Shutdown
171 ============
172 */
173 void IN_Shutdown(void)
174 {
175 #if USE_DINPUT
176  if (in_direct) {
177  in_direct->changed = NULL;
178  }
179 #endif
180  if (in_grab) {
181  in_grab->changed = NULL;
182  }
183 
184  if (input.api.Shutdown) {
185  input.api.Shutdown();
186  }
187 
188 #if USE_LIRC
189  Lirc_Shutdown();
190 #endif
191 
192  memset(&input, 0, sizeof(input));
193 }
194 
195 static void in_changed_hard(cvar_t *self)
196 {
197  input.modified = qtrue;
198 }
199 
200 static void in_changed_soft(cvar_t *self)
201 {
202  IN_Activate();
203 }
204 
205 /*
206 ============
207 IN_Init
208 ============
209 */
210 void IN_Init(void)
211 {
212  qboolean ret = qfalse;
213 
214 #if USE_LIRC
215  Lirc_Init();
216 #endif
217 
218  in_enable = Cvar_Get("in_enable", "1", 0);
219  in_enable->changed = in_changed_hard;
220  if (!in_enable->integer) {
221  Com_Printf("Mouse input disabled.\n");
222  return;
223  }
224 
225 #if USE_DINPUT
226  in_direct = Cvar_Get("in_direct", "1", 0);
227  if (in_direct->integer) {
228  DI_FillAPI(&input.api);
229  ret = input.api.Init();
230  if (!ret) {
231  Cvar_Set("in_direct", "0");
232  }
233  }
234 #endif
235 
236  if (!ret) {
238  ret = input.api.Init();
239  if (!ret) {
240  Cvar_Set("in_enable", "0");
241  return;
242  }
243  }
244 
245 #if USE_DINPUT
246  in_direct->changed = in_changed_hard;
247 #endif
248 
249  in_grab = Cvar_Get("in_grab", "1", 0);
250  in_grab->changed = in_changed_soft;
251 
252  IN_Activate();
253 }
254 
255 
256 /*
257 ===============================================================================
258 
259 KEY BUTTONS
260 
261 Continuous button event tracking is complicated by the fact that two different
262 input sources (say, mouse button 1 and the control key) can both press the
263 same button, but the button should only be released when both of the
264 pressing key have been released.
265 
266 When a key event issues a button command (+forward, +attack, etc), it appends
267 its key number as a parameter to the command so it can be matched up with
268 the release.
269 
270 state bit 0 is the current state of the key
271 state bit 1 is edge triggered on the up to down transition
272 state bit 2 is edge triggered on the down to up transition
273 
274 
275 Key_Event (int key, qboolean down, unsigned time);
276 
277  +mlook src time
278 
279 ===============================================================================
280 */
281 
282 typedef struct kbutton_s {
283  int down[2]; // key nums holding it down
284  unsigned downtime; // msec timestamp
285  unsigned msec; // msec down this frame
286  int state;
287 } kbutton_t;
288 
294 
295 static int in_impulse;
296 static qboolean in_mlooking;
297 
298 static void KeyDown(kbutton_t *b)
299 {
300  int k;
301  char *c;
302 
303  c = Cmd_Argv(1);
304  if (c[0])
305  k = atoi(c);
306  else
307  k = -1; // typed manually at the console for continuous down
308 
309  if (k == b->down[0] || k == b->down[1])
310  return; // repeating key
311 
312  if (!b->down[0])
313  b->down[0] = k;
314  else if (!b->down[1])
315  b->down[1] = k;
316  else {
317  Com_WPrintf("Three keys down for a button!\n");
318  return;
319  }
320 
321  if (b->state & 1)
322  return; // still down
323 
324  // save timestamp
325  c = Cmd_Argv(2);
326  b->downtime = atoi(c);
327  if (!b->downtime) {
328  b->downtime = com_eventTime - 100;
329  }
330 
331  b->state |= 1 + 2; // down + impulse down
332 }
333 
334 static void KeyUp(kbutton_t *b)
335 {
336  int k;
337  char *c;
338  unsigned uptime;
339 
340  c = Cmd_Argv(1);
341  if (c[0])
342  k = atoi(c);
343  else {
344  // typed manually at the console, assume for unsticking, so clear all
345  b->down[0] = b->down[1] = 0;
346  b->state = 0; // impulse up
347  return;
348  }
349 
350  if (b->down[0] == k)
351  b->down[0] = 0;
352  else if (b->down[1] == k)
353  b->down[1] = 0;
354  else
355  return; // key up without coresponding down (menu pass through)
356  if (b->down[0] || b->down[1])
357  return; // some other key is still holding it down
358 
359  if (!(b->state & 1))
360  return; // still up (this should not happen)
361 
362  // save timestamp
363  c = Cmd_Argv(2);
364  uptime = atoi(c);
365  if (!uptime) {
366  b->msec += 10;
367  } else if (uptime > b->downtime) {
368  b->msec += uptime - b->downtime;
369  }
370 
371  b->state &= ~1; // now up
372 }
373 
374 static void KeyClear(kbutton_t *b)
375 {
376  b->msec = 0;
377  b->state &= ~2; // clear impulses
378  if (b->state & 1) {
379  b->downtime = com_eventTime; // still down
380  }
381 }
382 
383 static void IN_KLookDown(void) { KeyDown(&in_klook); }
384 static void IN_KLookUp(void) { KeyUp(&in_klook); }
385 static void IN_UpDown(void) { KeyDown(&in_up); }
386 static void IN_UpUp(void) { KeyUp(&in_up); }
387 static void IN_DownDown(void) { KeyDown(&in_down); }
388 static void IN_DownUp(void) { KeyUp(&in_down); }
389 static void IN_LeftDown(void) { KeyDown(&in_left); }
390 static void IN_LeftUp(void) { KeyUp(&in_left); }
391 static void IN_RightDown(void) { KeyDown(&in_right); }
392 static void IN_RightUp(void) { KeyUp(&in_right); }
393 static void IN_ForwardDown(void) { KeyDown(&in_forward); }
394 static void IN_ForwardUp(void) { KeyUp(&in_forward); }
395 static void IN_BackDown(void) { KeyDown(&in_back); }
396 static void IN_BackUp(void) { KeyUp(&in_back); }
397 static void IN_LookupDown(void) { KeyDown(&in_lookup); }
398 static void IN_LookupUp(void) { KeyUp(&in_lookup); }
399 static void IN_LookdownDown(void) { KeyDown(&in_lookdown); }
400 static void IN_LookdownUp(void) { KeyUp(&in_lookdown); }
401 static void IN_MoveleftDown(void) { KeyDown(&in_moveleft); }
402 static void IN_MoveleftUp(void) { KeyUp(&in_moveleft); }
403 static void IN_MoverightDown(void) { KeyDown(&in_moveright); }
404 static void IN_MoverightUp(void) { KeyUp(&in_moveright); }
405 static void IN_SpeedDown(void) { KeyDown(&in_speed); }
406 static void IN_SpeedUp(void) { KeyUp(&in_speed); }
407 static void IN_StrafeDown(void) { KeyDown(&in_strafe); }
408 static void IN_StrafeUp(void) { KeyUp(&in_strafe); }
409 
410 static void IN_AttackDown(void)
411 {
412  KeyDown(&in_attack);
413 
414  if (cl_instantpacket->integer && cls.state == ca_active && cls.netchan) {
415  cl.sendPacketNow = qtrue;
416  }
417 }
418 
419 static void IN_AttackUp(void)
420 {
421  KeyUp(&in_attack);
422 }
423 
424 static void IN_UseDown(void)
425 {
426  KeyDown(&in_use);
427 
428  if (cl_instantpacket->integer && cls.state == ca_active && cls.netchan) {
429  cl.sendPacketNow = qtrue;
430  }
431 }
432 
433 static void IN_UseUp(void)
434 {
435  KeyUp(&in_use);
436 }
437 
438 static void IN_Impulse(void)
439 {
440  in_impulse = atoi(Cmd_Argv(1));
441 }
442 
443 static void IN_CenterView(void)
444 {
445  cl.viewangles[PITCH] = -SHORT2ANGLE(cl.frame.ps.pmove.delta_angles[PITCH]);
446 }
447 
448 static void IN_MLookDown(void)
449 {
450  in_mlooking = qtrue;
451 }
452 
453 static void IN_MLookUp(void)
454 {
455  in_mlooking = qfalse;
456 
457  if (!freelook->integer && lookspring->integer)
458  IN_CenterView();
459 }
460 
461 /*
462 ===============
463 CL_KeyState
464 
465 Returns the fraction of the frame that the key was down
466 ===============
467 */
468 static float CL_KeyState(kbutton_t *key)
469 {
470  unsigned msec = key->msec;
471  float val;
472 
473  if (key->state & 1) {
474  // still down
475  if (com_eventTime > key->downtime) {
476  msec += com_eventTime - key->downtime;
477  }
478  }
479 
480  // special case for instant packet
481  if (!cl.cmd.msec) {
482  return (float)(key->state & 1);
483  }
484 
485  val = (float)msec / cl.cmd.msec;
486 
487  return clamp(val, 0, 1);
488 }
489 
490 //==========================================================================
491 
494 
495 /*
496 ================
497 CL_MouseMove
498 ================
499 */
500 static void CL_MouseMove(void)
501 {
502  int dx, dy;
503  float mx, my;
504  float speed;
505 
506  if (!input.api.GetMotion) {
507  return;
508  }
509  if (cls.key_dest & (KEY_MENU | KEY_CONSOLE)) {
510  return;
511  }
512  if (!input.api.GetMotion(&dx, &dy)) {
513  return;
514  }
515 
516  if (m_filter->integer) {
517  mx = (dx + input.old_dx) * 0.5f;
518  my = (dy + input.old_dy) * 0.5f;
519  } else {
520  mx = dx;
521  my = dy;
522  }
523 
524  input.old_dx = dx;
525  input.old_dy = dy;
526 
527  if (!mx && !my) {
528  return;
529  }
530 
531  Cvar_ClampValue(m_accel, 0, 1);
532 
533  speed = sqrt(mx * mx + my * my);
534  speed = sensitivity->value + speed * m_accel->value;
535 
536  mx *= speed;
537  my *= speed;
538 
539  if (m_autosens->integer) {
540  mx *= cl.fov_x * autosens_x;
541  my *= cl.fov_y * autosens_y;
542  }
543 
544 // add mouse X/Y movement
545  if ((in_strafe.state & 1) || (lookstrafe->integer && !in_mlooking)) {
546  cl.mousemove[1] += m_side->value * mx;
547  } else {
548  cl.viewangles[YAW] -= m_yaw->value * mx;
549  }
550 
551  if ((in_mlooking || freelook->integer) && !(in_strafe.state & 1)) {
552  cl.viewangles[PITCH] += m_pitch->value * my * (m_invert->integer ? -1.f : 1.f);
553  } else {
554  cl.mousemove[0] -= m_forward->value * my;
555  }
556 }
557 
558 
559 /*
560 ================
561 CL_AdjustAngles
562 
563 Moves the local angle positions
564 ================
565 */
566 static void CL_AdjustAngles(int msec)
567 {
568  float speed;
569 
570  if (in_speed.state & 1)
571  speed = msec * cl_anglespeedkey->value * 0.001f;
572  else
573  speed = msec * 0.001f;
574 
575  if (!(in_strafe.state & 1)) {
576  cl.viewangles[YAW] -= speed * cl_yawspeed->value * CL_KeyState(&in_right);
577  cl.viewangles[YAW] += speed * cl_yawspeed->value * CL_KeyState(&in_left);
578  }
579  if (in_klook.state & 1) {
580  cl.viewangles[PITCH] -= speed * cl_pitchspeed->value * CL_KeyState(&in_forward);
581  cl.viewangles[PITCH] += speed * cl_pitchspeed->value * CL_KeyState(&in_back);
582  }
583 
584  cl.viewangles[PITCH] -= speed * cl_pitchspeed->value * CL_KeyState(&in_lookup);
585  cl.viewangles[PITCH] += speed * cl_pitchspeed->value * CL_KeyState(&in_lookdown);
586 }
587 
588 /*
589 ================
590 CL_BaseMove
591 
592 Build the intended movement vector
593 ================
594 */
595 static void CL_BaseMove(vec3_t move)
596 {
597  if (in_strafe.state & 1) {
598  move[1] += cl_sidespeed->value * CL_KeyState(&in_right);
599  move[1] -= cl_sidespeed->value * CL_KeyState(&in_left);
600  }
601 
602  move[1] += cl_sidespeed->value * CL_KeyState(&in_moveright);
603  move[1] -= cl_sidespeed->value * CL_KeyState(&in_moveleft);
604 
605  move[2] += cl_upspeed->value * CL_KeyState(&in_up);
606  move[2] -= cl_upspeed->value * CL_KeyState(&in_down);
607 
608  if (!(in_klook.state & 1)) {
609  move[0] += cl_forwardspeed->value * CL_KeyState(&in_forward);
610  move[0] -= cl_forwardspeed->value * CL_KeyState(&in_back);
611  }
612 
613 // adjust for speed key / running
614  if ((in_speed.state & 1) ^ cl_run->integer) {
615  VectorScale(move, 2, move);
616  }
617 }
618 
619 static void CL_ClampSpeed(vec3_t move)
620 {
621  float speed = cl.pmp.maxspeed;
622 
623  clamp(move[0], -speed, speed);
624  clamp(move[1], -speed, speed);
625  clamp(move[2], -speed, speed);
626 }
627 
628 static void CL_ClampPitch(void)
629 {
630  float pitch;
631 
632  pitch = SHORT2ANGLE(cl.frame.ps.pmove.delta_angles[PITCH]);
633  if (pitch > 180)
634  pitch -= 360;
635 
636  if (cl.viewangles[PITCH] + pitch < -360)
637  cl.viewangles[PITCH] += 360; // wrapped
638  if (cl.viewangles[PITCH] + pitch > 360)
639  cl.viewangles[PITCH] -= 360; // wrapped
640 
641  if (cl.viewangles[PITCH] + pitch > 89)
642  cl.viewangles[PITCH] = 89 - pitch;
643  if (cl.viewangles[PITCH] + pitch < -89)
644  cl.viewangles[PITCH] = -89 - pitch;
645 }
646 
647 /*
648 =================
649 CL_UpdateCmd
650 
651 Updates msec, angles and builds interpolated movement vector for local prediction.
652 Doesn't touch command forward/side/upmove, these are filled by CL_FinalizeCmd.
653 =================
654 */
655 void CL_UpdateCmd(int msec)
656 {
657  VectorClear(cl.localmove);
658 
659  if (sv_paused->integer) {
660  return;
661  }
662 
663  // add to milliseconds of time to apply the move
664  cl.cmd.msec += msec;
665 
666  // adjust viewangles
667  CL_AdjustAngles(msec);
668 
669  // get basic movement from keyboard
671 
672  // allow mice to add to the move
673  CL_MouseMove();
674 
675  // add accumulated mouse forward/side movement
676  cl.localmove[0] += cl.mousemove[0];
677  cl.localmove[1] += cl.mousemove[1];
678 
679  // clamp to server defined max speed
681 
682  CL_ClampPitch();
683 
684  cl.cmd.angles[0] = ANGLE2SHORT(cl.viewangles[0]);
685  cl.cmd.angles[1] = ANGLE2SHORT(cl.viewangles[1]);
686  cl.cmd.angles[2] = ANGLE2SHORT(cl.viewangles[2]);
687 }
688 
689 static void m_autosens_changed(cvar_t *self)
690 {
691  float fov;
692 
693  if (self->value > 90.0f && self->value <= 179.0f)
694  fov = self->value;
695  else
696  fov = 90.0f;
697 
698  autosens_x = 1.0f / fov;
699  autosens_y = 1.0f / V_CalcFov(fov, 4, 3);
700 }
701 
702 /*
703 ============
704 CL_RegisterInput
705 ============
706 */
708 {
709  Cmd_AddCommand("centerview", IN_CenterView);
710 
711  Cmd_AddCommand("+moveup", IN_UpDown);
712  Cmd_AddCommand("-moveup", IN_UpUp);
713  Cmd_AddCommand("+movedown", IN_DownDown);
714  Cmd_AddCommand("-movedown", IN_DownUp);
715  Cmd_AddCommand("+left", IN_LeftDown);
716  Cmd_AddCommand("-left", IN_LeftUp);
717  Cmd_AddCommand("+right", IN_RightDown);
718  Cmd_AddCommand("-right", IN_RightUp);
719  Cmd_AddCommand("+forward", IN_ForwardDown);
720  Cmd_AddCommand("-forward", IN_ForwardUp);
721  Cmd_AddCommand("+back", IN_BackDown);
722  Cmd_AddCommand("-back", IN_BackUp);
723  Cmd_AddCommand("+lookup", IN_LookupDown);
724  Cmd_AddCommand("-lookup", IN_LookupUp);
725  Cmd_AddCommand("+lookdown", IN_LookdownDown);
726  Cmd_AddCommand("-lookdown", IN_LookdownUp);
727  Cmd_AddCommand("+strafe", IN_StrafeDown);
728  Cmd_AddCommand("-strafe", IN_StrafeUp);
729  Cmd_AddCommand("+moveleft", IN_MoveleftDown);
730  Cmd_AddCommand("-moveleft", IN_MoveleftUp);
731  Cmd_AddCommand("+moveright", IN_MoverightDown);
732  Cmd_AddCommand("-moveright", IN_MoverightUp);
733  Cmd_AddCommand("+speed", IN_SpeedDown);
734  Cmd_AddCommand("-speed", IN_SpeedUp);
735  Cmd_AddCommand("+attack", IN_AttackDown);
736  Cmd_AddCommand("-attack", IN_AttackUp);
737  Cmd_AddCommand("+use", IN_UseDown);
738  Cmd_AddCommand("-use", IN_UseUp);
739  Cmd_AddCommand("impulse", IN_Impulse);
740  Cmd_AddCommand("+klook", IN_KLookDown);
741  Cmd_AddCommand("-klook", IN_KLookUp);
742  Cmd_AddCommand("+mlook", IN_MLookDown);
743  Cmd_AddCommand("-mlook", IN_MLookUp);
744 
745  Cmd_AddCommand("in_restart", IN_Restart_f);
746 
747  cl_nodelta = Cvar_Get("cl_nodelta", "0", 0);
748  cl_maxpackets = Cvar_Get("cl_maxpackets", "30", 0);
749  cl_fuzzhack = Cvar_Get("cl_fuzzhack", "0", 0);
750  cl_packetdup = Cvar_Get("cl_packetdup", "1", 0);
751 #ifdef _DEBUG
752  cl_showpackets = Cvar_Get("cl_showpackets", "0", 0);
753 #endif
754  cl_instantpacket = Cvar_Get("cl_instantpacket", "1", 0);
755  cl_batchcmds = Cvar_Get("cl_batchcmds", "1", 0);
756 
757  cl_upspeed = Cvar_Get("cl_upspeed", "200", 0);
758  cl_forwardspeed = Cvar_Get("cl_forwardspeed", "200", 0);
759  cl_sidespeed = Cvar_Get("cl_sidespeed", "200", 0);
760  cl_yawspeed = Cvar_Get("cl_yawspeed", "140", 0);
761  cl_pitchspeed = Cvar_Get("cl_pitchspeed", "150", CVAR_CHEAT);
762  cl_anglespeedkey = Cvar_Get("cl_anglespeedkey", "1.5", CVAR_CHEAT);
763  cl_run = Cvar_Get("cl_run", "1", CVAR_ARCHIVE);
764 
765  freelook = Cvar_Get("freelook", "1", CVAR_ARCHIVE);
766  lookspring = Cvar_Get("lookspring", "0", CVAR_ARCHIVE);
767  lookstrafe = Cvar_Get("lookstrafe", "0", CVAR_ARCHIVE);
768  sensitivity = Cvar_Get("sensitivity", "3", CVAR_ARCHIVE);
769 
770  m_pitch = Cvar_Get("m_pitch", "0.022", CVAR_ARCHIVE);
771  m_invert = Cvar_Get("m_invert", "0", CVAR_ARCHIVE);
772  m_yaw = Cvar_Get("m_yaw", "0.022", 0);
773  m_forward = Cvar_Get("m_forward", "1", 0);
774  m_side = Cvar_Get("m_side", "1", 0);
775  m_filter = Cvar_Get("m_filter", "0", 0);
776  m_accel = Cvar_Get("m_accel", "0", 0);
777  m_autosens = Cvar_Get("m_autosens", "0", 0);
778  m_autosens->changed = m_autosens_changed;
780 }
781 
782 /*
783 =================
784 CL_FinalizeCmd
785 
786 Builds the actual movement vector for sending to server. Assumes that msec
787 and angles are already set for this frame by CL_UpdateCmd.
788 =================
789 */
790 void CL_FinalizeCmd(void)
791 {
792  vec3_t move;
793 
794  // command buffer ticks in sync with cl_maxfps
795  if (cmd_buffer.waitCount > 0) {
796  cmd_buffer.waitCount--;
797  }
798  if (cl_cmdbuf.waitCount > 0) {
799  cl_cmdbuf.waitCount--;
800  }
801 
802  if (cls.state != ca_active) {
803  return; // not talking to a server
804  }
805 
806  if (sv_paused->integer) {
807  return;
808  }
809 
810 //
811 // figure button bits
812 //
813  if (in_attack.state & 3)
814  cl.cmd.buttons |= BUTTON_ATTACK;
815  if (in_use.state & 3)
816  cl.cmd.buttons |= BUTTON_USE;
817 
818  in_attack.state &= ~2;
819  in_use.state &= ~2;
820 
821  if (cls.key_dest == KEY_GAME && Key_AnyKeyDown()) {
822  cl.cmd.buttons |= BUTTON_ANY;
823  }
824 
825  if (cl.cmd.msec > 250) {
826  cl.cmd.msec = 100; // time was unreasonable
827  }
828 
829  // rebuild the movement vector
830  VectorClear(move);
831 
832  // get basic movement from keyboard
833  CL_BaseMove(move);
834 
835  // add mouse forward/side movement
836  move[0] += cl.mousemove[0];
837  move[1] += cl.mousemove[1];
838 
839  // clamp to server defined max speed
840  CL_ClampSpeed(move);
841 
842  // store the movement vector
843  cl.cmd.forwardmove = move[0];
844  cl.cmd.sidemove = move[1];
845  cl.cmd.upmove = move[2];
846 
847  // clear all states
848  cl.mousemove[0] = 0;
849  cl.mousemove[1] = 0;
850 
851  KeyClear(&in_right);
852  KeyClear(&in_left);
853 
856 
857  KeyClear(&in_up);
858  KeyClear(&in_down);
859 
861  KeyClear(&in_back);
862 
865 
866  cl.cmd.impulse = in_impulse;
867  in_impulse = 0;
868 
869  // save this command off for prediction
870  cl.cmdNumber++;
871  cl.cmds[cl.cmdNumber & CMD_MASK] = cl.cmd;
872 
873  // clear pending cmd
874  memset(&cl.cmd, 0, sizeof(cl.cmd));
875 }
876 
877 static inline qboolean ready_to_send(void)
878 {
879  unsigned msec;
880 
881  if (cl.sendPacketNow) {
882  return qtrue;
883  }
884  if (cls.netchan->message.cursize || cls.netchan->reliable_ack_pending) {
885  return qtrue;
886  }
887  if (!cl_maxpackets->integer) {
888  return qtrue;
889  }
890 
891  if (cl_maxpackets->integer < 10) {
892  Cvar_Set("cl_maxpackets", "10");
893  }
894 
895  msec = 1000 / cl_maxpackets->integer;
896  if (msec) {
897  msec = 100 / (100 / msec);
898  }
899  if (cls.realtime - cl.lastTransmitTime < msec) {
900  return qfalse;
901  }
902 
903  return qtrue;
904 }
905 
906 static inline qboolean ready_to_send_hacked(void)
907 {
908  if (!cl_fuzzhack->integer) {
909  return qtrue; // packet drop hack disabled
910  }
911 
913  return qtrue; // can't drop more than 2 cmds
914  }
915 
916  return ready_to_send();
917 }
918 
919 /*
920 =================
921 CL_SendDefaultCmd
922 =================
923 */
924 static void CL_SendDefaultCmd(void)
925 {
926  size_t cursize q_unused, checksumIndex;
927  usercmd_t *cmd, *oldcmd;
928  client_history_t *history;
929 
930  // archive this packet
931  history = &cl.history[cls.netchan->outgoing_sequence & CMD_MASK];
932  history->cmdNumber = cl.cmdNumber;
933  history->sent = cls.realtime; // for ping calculation
934  history->rcvd = 0;
935 
937 
938  // see if we are ready to send this packet
939  if (!ready_to_send_hacked()) {
940  cls.netchan->outgoing_sequence++; // just drop the packet
941  return;
942  }
943 
946 
947  // begin a client move command
948  MSG_WriteByte(clc_move);
949 
950  // save the position for a checksum byte
951  checksumIndex = 0;
952  if (cls.serverProtocol <= PROTOCOL_VERSION_DEFAULT) {
953  checksumIndex = msg_write.cursize;
954  SZ_GetSpace(&msg_write, 1);
955  }
956 
957  // let the server know what the last frame we
958  // got was, so the next message can be delta compressed
959  if (cl_nodelta->integer || !cl.frame.valid /*|| cls.demowaiting*/) {
960  MSG_WriteLong(-1); // no compression
961  } else {
963  }
964 
965  // send this and the previous cmds in the message, so
966  // if the last packet was dropped, it can be recovered
967  cmd = &cl.cmds[(cl.cmdNumber - 2) & CMD_MASK];
968  MSG_WriteDeltaUsercmd(NULL, cmd, cls.protocolVersion);
970  oldcmd = cmd;
971 
972  cmd = &cl.cmds[(cl.cmdNumber - 1) & CMD_MASK];
973  MSG_WriteDeltaUsercmd(oldcmd, cmd, cls.protocolVersion);
975  oldcmd = cmd;
976 
977  cmd = &cl.cmds[cl.cmdNumber & CMD_MASK];
978  MSG_WriteDeltaUsercmd(oldcmd, cmd, cls.protocolVersion);
980 
981  if (cls.serverProtocol <= PROTOCOL_VERSION_DEFAULT) {
982  // calculate a checksum over the move commands
983  msg_write.data[checksumIndex] = COM_BlockSequenceCRCByte(
984  msg_write.data + checksumIndex + 1,
985  msg_write.cursize - checksumIndex - 1,
986  cls.netchan->outgoing_sequence);
987  }
988 
989  P_FRAMES++;
990 
991  //
992  // deliver the message
993  //
994  cursize = cls.netchan->Transmit(cls.netchan, msg_write.cursize, msg_write.data, 1);
995 #ifdef _DEBUG
996  if (cl_showpackets->integer) {
997  Com_Printf("%"PRIz" ", cursize);
998  }
999 #endif
1000 
1001  SZ_Clear(&msg_write);
1002 }
1003 
1004 /*
1005 =================
1006 CL_SendBatchedCmd
1007 =================
1008 */
1009 static void CL_SendBatchedCmd(void)
1010 {
1011  int i, j, seq, bits q_unused;
1012  int numCmds, numDups;
1013  int totalCmds, totalMsec;
1014  size_t cursize q_unused;
1015  usercmd_t *cmd, *oldcmd;
1016  client_history_t *history, *oldest;
1017  byte *patch;
1018 
1019  // see if we are ready to send this packet
1020  if (!ready_to_send()) {
1021  return;
1022  }
1023 
1024  // archive this packet
1025  seq = cls.netchan->outgoing_sequence;
1026  history = &cl.history[seq & CMD_MASK];
1027  history->cmdNumber = cl.cmdNumber;
1028  history->sent = cls.realtime; // for ping calculation
1029  history->rcvd = 0;
1030 
1034 
1035  // begin a client move command
1036  patch = SZ_GetSpace(&msg_write, 1);
1037 
1038  // let the server know what the last frame we
1039  // got was, so the next message can be delta compressed
1040  if (cl_nodelta->integer || !cl.frame.valid /*|| cls.demowaiting*/) {
1041  *patch = clc_move_nodelta; // no compression
1042  } else {
1043  *patch = clc_move_batched;
1045  }
1046 
1047  Cvar_ClampInteger(cl_packetdup, 0, MAX_PACKET_FRAMES - 1);
1048  numDups = cl_packetdup->integer;
1049 
1050  *patch |= numDups << SVCMD_BITS;
1051 
1052  // send lightlevel
1054 
1055  // send this and the previous cmds in the message, so
1056  // if the last packet was dropped, it can be recovered
1057  oldcmd = NULL;
1058  totalCmds = 0;
1059  totalMsec = 0;
1060  for (i = seq - numDups; i <= seq; i++) {
1061  oldest = &cl.history[(i - 1) & CMD_MASK];
1062  history = &cl.history[i & CMD_MASK];
1063 
1064  numCmds = history->cmdNumber - oldest->cmdNumber;
1065  if (numCmds >= MAX_PACKET_USERCMDS) {
1066  Com_WPrintf("%s: MAX_PACKET_USERCMDS exceeded\n", __func__);
1067  SZ_Clear(&msg_write);
1068  break;
1069  }
1070  totalCmds += numCmds;
1071  MSG_WriteBits(numCmds, 5);
1072  for (j = oldest->cmdNumber + 1; j <= history->cmdNumber; j++) {
1073  cmd = &cl.cmds[j & CMD_MASK];
1074  totalMsec += cmd->msec;
1075  bits = MSG_WriteDeltaUsercmd_Enhanced(oldcmd, cmd, cls.protocolVersion);
1076 #ifdef _DEBUG
1077  if (cl_showpackets->integer == 3) {
1078  MSG_ShowDeltaUsercmdBits_Enhanced(bits);
1079  }
1080 #endif
1081  oldcmd = cmd;
1082  }
1083  }
1084 
1085  P_FRAMES++;
1086 
1087  //
1088  // deliver the message
1089  //
1090  cursize = cls.netchan->Transmit(cls.netchan, msg_write.cursize, msg_write.data, 1);
1091 #ifdef _DEBUG
1092  if (cl_showpackets->integer == 1) {
1093  Com_Printf("%"PRIz"(%i) ", cursize, totalCmds);
1094  } else if (cl_showpackets->integer == 2) {
1095  Com_Printf("%"PRIz"(%i) ", cursize, totalMsec);
1096  } else if (cl_showpackets->integer == 3) {
1097  Com_Printf(" | ");
1098  }
1099 #endif
1100 
1101  SZ_Clear(&msg_write);
1102 }
1103 
1104 static void CL_SendKeepAlive(void)
1105 {
1106  client_history_t *history;
1107  size_t cursize q_unused;
1108 
1109  // archive this packet
1110  history = &cl.history[cls.netchan->outgoing_sequence & CMD_MASK];
1111  history->cmdNumber = cl.cmdNumber;
1112  history->sent = cls.realtime; // for ping calculation
1113  history->rcvd = 0;
1114 
1118 
1119  cursize = cls.netchan->Transmit(cls.netchan, 0, NULL, 1);
1120 #ifdef _DEBUG
1121  if (cl_showpackets->integer) {
1122  Com_Printf("%"PRIz" ", cursize);
1123  }
1124 #endif
1125 }
1126 
1127 static void CL_SendUserinfo(void)
1128 {
1129  char userinfo[MAX_INFO_STRING];
1130  cvar_t *var;
1131  int i;
1132 
1133  if (!cls.userinfo_modified) {
1134  return;
1135  }
1136 
1137  if (cls.userinfo_modified == MAX_PACKET_USERINFOS) {
1138  size_t len = Cvar_BitInfo(userinfo, CVAR_USERINFO);
1139  Com_DDPrintf("%s: %u: full update\n", __func__, com_framenum);
1140  MSG_WriteByte(clc_userinfo);
1141  MSG_WriteData(userinfo, len + 1);
1142  MSG_FlushTo(&cls.netchan->message);
1143  } else if (cls.serverProtocol == PROTOCOL_VERSION_Q2PRO) {
1144  Com_DDPrintf("%s: %u: %d updates\n", __func__, com_framenum,
1146  for (i = 0; i < cls.userinfo_modified; i++) {
1147  var = cls.userinfo_updates[i];
1148  MSG_WriteByte(clc_userinfo_delta);
1149  MSG_WriteString(var->name);
1150  if (var->flags & CVAR_USERINFO) {
1151  MSG_WriteString(var->string);
1152  } else {
1153  // no longer in userinfo
1154  MSG_WriteString(NULL);
1155  }
1156  }
1157  MSG_FlushTo(&cls.netchan->message);
1158  } else {
1159  Com_WPrintf("%s: update count is %d, should never happen.\n",
1160  __func__, cls.userinfo_modified);
1161  }
1162 
1163  cls.userinfo_modified = 0;
1164 }
1165 
1166 void CL_SendCmd(void)
1167 {
1168  if (cls.state < ca_connected) {
1169  return; // not talking to a server
1170  }
1171 
1172  // generate usercmds while playing a demo,
1173  // but do not send them
1174  if (!cls.netchan) {
1175  return;
1176  }
1177 
1178  if (cls.state != ca_active || sv_paused->integer) {
1179  // send a userinfo update if needed
1180  CL_SendUserinfo();
1181 
1182  // just keepalive or update reliable
1183  if (cls.netchan->ShouldUpdate(cls.netchan)) {
1184  CL_SendKeepAlive();
1185  }
1186 
1187  cl.sendPacketNow = qfalse;
1188  return;
1189  }
1190 
1191  // are there any new usercmds to send after all?
1193  return; // nothing to send
1194  }
1195 
1196  // send a userinfo update if needed
1197  CL_SendUserinfo();
1198 
1199  if (cls.serverProtocol == PROTOCOL_VERSION_Q2PRO && cl_batchcmds->integer) {
1201  } else {
1203  }
1204 
1205  cl.sendPacketNow = qfalse;
1206 }
1207 
IN_BackUp
static void IN_BackUp(void)
Definition: input.c:396
client_state_s::frame
server_frame_t frame
Definition: client.h:212
in_right
static kbutton_t in_right
Definition: input.c:290
VID_FillInputAPI
void VID_FillInputAPI(inputAPI_t *api)
Definition: client.c:1388
server_frame_t::valid
qboolean valid
Definition: client.h:129
autosens_x
float autosens_x
Definition: input.c:492
client_state_s::mousemove
vec2_t mousemove
Definition: client.h:238
KeyUp
static void KeyUp(kbutton_t *b)
Definition: input.c:334
Cvar_Set
cvar_t * Cvar_Set(const char *var_name, const char *value)
Definition: cvar.c:466
CL_FinalizeCmd
void CL_FinalizeCmd(void)
Definition: input.c:790
CL_SendBatchedCmd
static void CL_SendBatchedCmd(void)
Definition: input.c:1009
m_filter
static cvar_t * m_filter
Definition: input.c:33
IN_LeftDown
static void IN_LeftDown(void)
Definition: input.c:389
IN_KLookUp
static void IN_KLookUp(void)
Definition: input.c:384
client_static_s::playback
qhandle_t playback
Definition: client.h:453
IN_LeftUp
static void IN_LeftUp(void)
Definition: input.c:390
Cvar_BitInfo
size_t Cvar_BitInfo(char *info, int bit)
Definition: cvar.c:1109
m_accel
cvar_t * m_accel
Definition: input.c:34
IN_UseDown
static void IN_UseDown(void)
Definition: input.c:424
client_state_s::cmdNumber
unsigned cmdNumber
Definition: client.h:184
cl_run
static cvar_t * cl_run
Definition: input.c:42
client_static_s::demo
struct client_static_s::@3 demo
in_moveright
static kbutton_t in_moveright
Definition: input.c:291
Cmd_AddCommand
void Cmd_AddCommand(const char *name, xcommand_t function)
Definition: cmd.c:1562
input
static in_state_t input
Definition: input.c:71
IN_BackDown
static void IN_BackDown(void)
Definition: input.c:395
IN_DownDown
static void IN_DownDown(void)
Definition: input.c:387
autosens_y
float autosens_y
Definition: input.c:493
IN_MLookDown
static void IN_MLookDown(void)
Definition: input.c:448
KeyClear
static void KeyClear(kbutton_t *b)
Definition: input.c:374
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
client_static_s::key_dest
keydest_t key_dest
Definition: client.h:376
IN_KLookDown
static void IN_KLookDown(void)
Definition: input.c:383
cl_cmdbuf
cmdbuf_t cl_cmdbuf
Definition: main.c:104
in_up
static kbutton_t in_up
Definition: input.c:293
cl_upspeed
static cvar_t * cl_upspeed
Definition: input.c:37
cl_instantpacket
static cvar_t * cl_instantpacket
Definition: input.c:30
IN_MoverightUp
static void IN_MoverightUp(void)
Definition: input.c:404
cl_packetdup
static cvar_t * cl_packetdup
Definition: input.c:25
kbutton_s
Definition: input.c:282
sensitivity
cvar_t * sensitivity
Definition: input.c:48
IN_Shutdown
void IN_Shutdown(void)
Definition: input.c:173
IN_RightUp
static void IN_RightUp(void)
Definition: input.c:392
ca_active
@ ca_active
Definition: client.h:340
IN_GetCurrentGrab
static qboolean IN_GetCurrentGrab(void)
Definition: input.c:84
CL_MouseMove
static void CL_MouseMove(void)
Definition: input.c:500
IN_Frame
void IN_Frame(void)
Definition: input.c:140
client_static_s::state
connstate_t state
Definition: client.h:375
in_lookup
static kbutton_t in_lookup
Definition: input.c:291
ca_connected
@ ca_connected
Definition: client.h:337
sv_paused
cvar_t * sv_paused
Definition: common.c:96
IN_StrafeDown
static void IN_StrafeDown(void)
Definition: input.c:407
client_static_s::active
active_t active
Definition: client.h:378
in_left
static kbutton_t in_left
Definition: input.c:290
in_speed
static kbutton_t in_speed
Definition: input.c:292
client_state_s::viewangles
vec3_t viewangles
Definition: client.h:230
kbutton_s::msec
unsigned msec
Definition: input.c:285
in_klook
static kbutton_t in_klook
Definition: input.c:289
cl_yawspeed
static cvar_t * cl_yawspeed
Definition: input.c:40
MSG_WriteByte
void MSG_WriteByte(int c)
Definition: msg.c:107
IN_MLookUp
static void IN_MLookUp(void)
Definition: input.c:453
IN_ForwardDown
static void IN_ForwardDown(void)
Definition: input.c:393
Cmd_Argv
char * Cmd_Argv(int arg)
Definition: cmd.c:899
IN_UpUp
static void IN_UpUp(void)
Definition: input.c:386
in_grab
static cvar_t * in_grab
Definition: input.c:77
in_down
static kbutton_t in_down
Definition: input.c:293
in_strafe
static kbutton_t in_strafe
Definition: input.c:292
P_FRAMES
#define P_FRAMES
Definition: client.h:400
CL_SendDefaultCmd
static void CL_SendDefaultCmd(void)
Definition: input.c:924
IN_UseUp
static void IN_UseUp(void)
Definition: input.c:433
client_static_s::userinfo_updates
cvar_t * userinfo_updates[MAX_PACKET_USERINFOS]
Definition: client.h:384
cmd_buffer
cmdbuf_t cmd_buffer
Definition: cmd.c:49
CL_AdjustAngles
static void CL_AdjustAngles(int msec)
Definition: input.c:566
client_state_s::sendPacketNow
qboolean sendPacketNow
Definition: client.h:180
in_enable
static cvar_t * in_enable
Definition: input.c:73
cl_maxpackets
static cvar_t * cl_maxpackets
Definition: input.c:24
ready_to_send
static qboolean ready_to_send(void)
Definition: input.c:877
IN_UpDown
static void IN_UpDown(void)
Definition: input.c:385
IN_RightDown
static void IN_RightDown(void)
Definition: input.c:391
SZ_GetSpace
void * SZ_GetSpace(sizebuf_t *buf, size_t len)
Definition: sizebuf.c:48
client_state_s::localmove
vec3_t localmove
Definition: client.h:234
m_forward
static cvar_t * m_forward
Definition: input.c:53
CL_ClampSpeed
static void CL_ClampSpeed(vec3_t move)
Definition: input.c:619
msg_write
sizebuf_t msg_write
Definition: msg.c:34
client_static_s::userinfo_modified
int userinfo_modified
Definition: client.h:383
Cvar_ClampValue
float Cvar_ClampValue(cvar_t *var, float min, float max)
Definition: cvar.c:571
in_moveleft
static kbutton_t in_moveleft
Definition: input.c:291
CL_BaseMove
static void CL_BaseMove(vec3_t move)
Definition: input.c:595
kbutton_s::downtime
unsigned downtime
Definition: input.c:284
IN_WarpMouse
void IN_WarpMouse(int x, int y)
Definition: input.c:161
client_static_s::serverProtocol
int serverProtocol
Definition: client.h:422
in_impulse
static int in_impulse
Definition: input.c:295
IN_StrafeUp
static void IN_StrafeUp(void)
Definition: input.c:408
Key_IsDown
int Key_IsDown(int key)
Definition: keys.c:204
IN_Init
void IN_Init(void)
Definition: input.c:210
client_state_s::cmds
usercmd_t cmds[CMD_BACKUP]
Definition: client.h:183
client_history_t::sent
unsigned sent
Definition: client.h:123
CL_ClampPitch
static void CL_ClampPitch(void)
Definition: input.c:628
IN_LookdownUp
static void IN_LookdownUp(void)
Definition: input.c:400
ready_to_send_hacked
static qboolean ready_to_send_hacked(void)
Definition: input.c:906
in_use
static kbutton_t in_use
Definition: input.c:292
IN_GetAPI
const inputAPI_t * IN_GetAPI()
Definition: input.c:79
CL_RegisterInput
void CL_RegisterInput(void)
Definition: input.c:707
client_state_s::lightlevel
int lightlevel
Definition: client.h:256
client_state_s::lastTransmitCmdNumber
unsigned lastTransmitCmdNumber
Definition: client.h:178
cl_sidespeed
static cvar_t * cl_sidespeed
Definition: input.c:39
IN_MoveleftDown
static void IN_MoveleftDown(void)
Definition: input.c:401
IN_Activate
void IN_Activate(void)
Definition: input.c:117
in_state_t::api
inputAPI_t api
Definition: input.c:66
m_invert
cvar_t * m_invert
Definition: input.c:51
m_yaw
cvar_t * m_yaw
Definition: input.c:52
in_state_t::old_dy
int old_dy
Definition: input.c:68
client_history_t::cmdNumber
unsigned cmdNumber
Definition: client.h:125
IN_LookdownDown
static void IN_LookdownDown(void)
Definition: input.c:399
cl
client_state_t cl
Definition: main.c:99
in_forward
static kbutton_t in_forward
Definition: input.c:290
CL_UpdateCmd
void CL_UpdateCmd(int msec)
Definition: input.c:655
cl_batchcmds
static cvar_t * cl_batchcmds
Definition: input.c:31
cls
client_static_t cls
Definition: main.c:98
ca_cinematic
@ ca_cinematic
Definition: client.h:341
MSG_WriteString
void MSG_WriteString(const char *string)
Definition: msg.c:160
c
statCounters_t c
Definition: main.c:30
V_CalcFov
float V_CalcFov(float fov_x, float width, float height)
Definition: view.c:379
IN_AttackDown
static void IN_AttackDown(void)
Definition: input.c:410
kbutton_t
struct kbutton_s kbutton_t
in_attack
static kbutton_t in_attack
Definition: input.c:292
MSG_WriteLong
void MSG_WriteLong(int c)
Definition: msg.c:144
client_state_s::cmd
usercmd_t cmd
Definition: client.h:182
CL_SendKeepAlive
static void CL_SendKeepAlive(void)
Definition: input.c:1104
kbutton_s::state
int state
Definition: input.c:286
cl_fuzzhack
static cvar_t * cl_fuzzhack
Definition: input.c:26
client_state_s::fov_x
float fov_x
Definition: client.h:254
Cvar_ClampInteger
int Cvar_ClampInteger(cvar_t *var, int min, int max)
Definition: cvar.c:549
client_history_t::rcvd
unsigned rcvd
Definition: client.h:124
lookspring
static cvar_t * lookspring
Definition: input.c:46
m_side
static cvar_t * m_side
Definition: input.c:54
in_mlooking
static qboolean in_mlooking
Definition: input.c:296
m_autosens
cvar_t * m_autosens
Definition: input.c:35
server_frame_t::ps
player_state_t ps
Definition: client.h:137
in_lookdown
static kbutton_t in_lookdown
Definition: input.c:291
client_history_t
Definition: client.h:122
client.h
IN_AttackUp
static void IN_AttackUp(void)
Definition: input.c:419
CL_KeyState
static float CL_KeyState(kbutton_t *key)
Definition: input.c:468
IN_Restart_f
static void IN_Restart_f(void)
Definition: input.c:129
IN_ForwardUp
static void IN_ForwardUp(void)
Definition: input.c:394
server_frame_t::number
int number
Definition: client.h:131
DI_FillAPI
void DI_FillAPI(inputAPI_t *api)
Definition: dinput.c:316
m_autosens_changed
static void m_autosens_changed(cvar_t *self)
Definition: input.c:689
in_state_t::old_dx
int old_dx
Definition: input.c:67
freelook
static cvar_t * freelook
Definition: input.c:45
client_static_s::realtime
unsigned realtime
Definition: client.h:389
CL_SendUserinfo
static void CL_SendUserinfo(void)
Definition: input.c:1127
IN_LookupUp
static void IN_LookupUp(void)
Definition: input.c:398
cl_pitchspeed
static cvar_t * cl_pitchspeed
Definition: input.c:41
in_back
static kbutton_t in_back
Definition: input.c:290
client_state_s::lastTransmitTime
unsigned lastTransmitTime
Definition: client.h:177
cl_nodelta
static cvar_t * cl_nodelta
Definition: input.c:23
cl_forwardspeed
static cvar_t * cl_forwardspeed
Definition: input.c:38
client_state_s::history
client_history_t history[CMD_BACKUP]
Definition: client.h:186
COM_BlockSequenceCRCByte
byte COM_BlockSequenceCRCByte(byte *base, size_t length, int sequence)
Definition: crc.c:148
client_state_s::fov_y
float fov_y
Definition: client.h:255
IN_MoverightDown
static void IN_MoverightDown(void)
Definition: input.c:403
IN_LookupDown
static void IN_LookupDown(void)
Definition: input.c:397
IN_DownUp
static void IN_DownUp(void)
Definition: input.c:388
IN_MoveleftUp
static void IN_MoveleftUp(void)
Definition: input.c:402
lookstrafe
static cvar_t * lookstrafe
Definition: input.c:47
client_static_s::protocolVersion
int protocolVersion
Definition: client.h:423
IN_SpeedDown
static void IN_SpeedDown(void)
Definition: input.c:405
Key_AnyKeyDown
int Key_AnyKeyDown(void)
Definition: keys.c:220
in_changed_hard
static void in_changed_hard(cvar_t *self)
Definition: input.c:195
com_framenum
unsigned com_framenum
Definition: common.c:121
client_static_s::netchan
netchan_t * netchan
Definition: client.h:421
IN_Impulse
static void IN_Impulse(void)
Definition: input.c:438
kbutton_s::down
int down[2]
Definition: input.c:283
IN_CenterView
static void IN_CenterView(void)
Definition: input.c:443
cl_anglespeedkey
static cvar_t * cl_anglespeedkey
Definition: input.c:43
in_state_t
Definition: input.c:64
in_state_t::modified
qboolean modified
Definition: input.c:65
in_changed_soft
static void in_changed_soft(cvar_t *self)
Definition: input.c:200
CL_SendCmd
void CL_SendCmd(void)
Definition: input.c:1166
KeyDown
static void KeyDown(kbutton_t *b)
Definition: input.c:298
IN_SpeedUp
static void IN_SpeedUp(void)
Definition: input.c:406
r_config
refcfg_t r_config
Definition: refresh.c:401
SZ_Clear
void SZ_Clear(sizebuf_t *buf)
Definition: sizebuf.c:40
client_state_s::lastTransmitCmdNumberReal
unsigned lastTransmitCmdNumberReal
Definition: client.h:179
com_eventTime
unsigned com_eventTime
Definition: common.c:122
m_pitch
cvar_t * m_pitch
Definition: input.c:50
client_state_s::pmp
pmoveParams_t pmp
Definition: client.h:280