doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UsercmdGen.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 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 Doom 3 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 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 Doom 3 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 #include "../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "Session_local.h"
33 
34 /*
35 ================
36 usercmd_t::ByteSwap
37 ================
38 */
39 void usercmd_t::ByteSwap( void ) {
40  angles[0] = LittleShort( angles[0] );
41  angles[1] = LittleShort( angles[1] );
42  angles[2] = LittleShort( angles[2] );
44 }
45 
46 /*
47 ================
48 usercmd_t::operator==
49 ================
50 */
51 bool usercmd_t::operator==( const usercmd_t &rhs ) const {
52  return ( buttons == rhs.buttons &&
53  forwardmove == rhs.forwardmove &&
54  rightmove == rhs.rightmove &&
55  upmove == rhs.upmove &&
56  angles[0] == rhs.angles[0] &&
57  angles[1] == rhs.angles[1] &&
58  angles[2] == rhs.angles[2] &&
59  impulse == rhs.impulse &&
60  flags == rhs.flags &&
61  mx == rhs.mx &&
62  my == rhs.my );
63 }
64 
65 
66 const int KEY_MOVESPEED = 127;
67 
68 typedef enum {
70 
82 
91 
97 
162 
165 
166 typedef struct {
167  const char *string;
170 
172  { "_moveUp", UB_UP },
173  { "_moveDown", UB_DOWN },
174  { "_left", UB_LEFT },
175  { "_right", UB_RIGHT },
176  { "_forward", UB_FORWARD },
177  { "_back", UB_BACK },
178  { "_lookUp", UB_LOOKUP },
179  { "_lookDown", UB_LOOKDOWN },
180  { "_strafe", UB_STRAFE },
181  { "_moveLeft", UB_MOVELEFT },
182  { "_moveRight", UB_MOVERIGHT },
183 
184  { "_attack", UB_ATTACK },
185  { "_speed", UB_SPEED },
186  { "_zoom", UB_ZOOM },
187  { "_showScores", UB_SHOWSCORES },
188  { "_mlook", UB_MLOOK },
189 
190  { "_button0", UB_BUTTON0 },
191  { "_button1", UB_BUTTON1 },
192  { "_button2", UB_BUTTON2 },
193  { "_button3", UB_BUTTON3 },
194  { "_button4", UB_BUTTON4 },
195  { "_button5", UB_BUTTON5 },
196  { "_button6", UB_BUTTON6 },
197  { "_button7", UB_BUTTON7 },
198 
199  { "_impulse0", UB_IMPULSE0 },
200  { "_impulse1", UB_IMPULSE1 },
201  { "_impulse2", UB_IMPULSE2 },
202  { "_impulse3", UB_IMPULSE3 },
203  { "_impulse4", UB_IMPULSE4 },
204  { "_impulse5", UB_IMPULSE5 },
205  { "_impulse6", UB_IMPULSE6 },
206  { "_impulse7", UB_IMPULSE7 },
207  { "_impulse8", UB_IMPULSE8 },
208  { "_impulse9", UB_IMPULSE9 },
209  { "_impulse10", UB_IMPULSE10 },
210  { "_impulse11", UB_IMPULSE11 },
211  { "_impulse12", UB_IMPULSE12 },
212  { "_impulse13", UB_IMPULSE13 },
213  { "_impulse14", UB_IMPULSE14 },
214  { "_impulse15", UB_IMPULSE15 },
215  { "_impulse16", UB_IMPULSE16 },
216  { "_impulse17", UB_IMPULSE17 },
217  { "_impulse18", UB_IMPULSE18 },
218  { "_impulse19", UB_IMPULSE19 },
219  { "_impulse20", UB_IMPULSE20 },
220  { "_impulse21", UB_IMPULSE21 },
221  { "_impulse22", UB_IMPULSE22 },
222  { "_impulse23", UB_IMPULSE23 },
223  { "_impulse24", UB_IMPULSE24 },
224  { "_impulse25", UB_IMPULSE25 },
225  { "_impulse26", UB_IMPULSE26 },
226  { "_impulse27", UB_IMPULSE27 },
227  { "_impulse28", UB_IMPULSE28 },
228  { "_impulse29", UB_IMPULSE29 },
229  { "_impulse30", UB_IMPULSE30 },
230  { "_impulse31", UB_IMPULSE31 },
231  { "_impulse32", UB_IMPULSE32 },
232  { "_impulse33", UB_IMPULSE33 },
233  { "_impulse34", UB_IMPULSE34 },
234  { "_impulse35", UB_IMPULSE35 },
235  { "_impulse36", UB_IMPULSE36 },
236  { "_impulse37", UB_IMPULSE37 },
237  { "_impulse38", UB_IMPULSE38 },
238  { "_impulse39", UB_IMPULSE39 },
239  { "_impulse40", UB_IMPULSE40 },
240  { "_impulse41", UB_IMPULSE41 },
241  { "_impulse42", UB_IMPULSE42 },
242  { "_impulse43", UB_IMPULSE43 },
243  { "_impulse44", UB_IMPULSE44 },
244  { "_impulse45", UB_IMPULSE45 },
245  { "_impulse46", UB_IMPULSE46 },
246  { "_impulse47", UB_IMPULSE47 },
247  { "_impulse48", UB_IMPULSE48 },
248  { "_impulse49", UB_IMPULSE49 },
249  { "_impulse50", UB_IMPULSE50 },
250  { "_impulse51", UB_IMPULSE51 },
251  { "_impulse52", UB_IMPULSE52 },
252  { "_impulse53", UB_IMPULSE53 },
253  { "_impulse54", UB_IMPULSE54 },
254  { "_impulse55", UB_IMPULSE55 },
255  { "_impulse56", UB_IMPULSE56 },
256  { "_impulse57", UB_IMPULSE57 },
257  { "_impulse58", UB_IMPULSE58 },
258  { "_impulse59", UB_IMPULSE59 },
259  { "_impulse60", UB_IMPULSE60 },
260  { "_impulse61", UB_IMPULSE61 },
261  { "_impulse62", UB_IMPULSE62 },
262  { "_impulse63", UB_IMPULSE63 },
263 
264  { NULL, UB_NONE },
265 };
266 
268  public:
269  int on;
270  bool held;
271 
273  void Clear( void );
274  void SetKeyState( int keystate, bool toggle );
275 };
276 
277 /*
278 ================
279 buttonState_t::Clear
280 ================
281 */
282 void buttonState_t::Clear( void ) {
283  held = false;
284  on = 0;
285 }
286 
287 /*
288 ================
289 buttonState_t::SetKeyState
290 ================
291 */
292 void buttonState_t::SetKeyState( int keystate, bool toggle ) {
293  if ( !toggle ) {
294  held = false;
295  on = keystate;
296  } else if ( !keystate ) {
297  held = false;
298  } else if ( !held ) {
299  held = true;
300  on ^= 1;
301  }
302 }
303 
304 
305 const int NUM_USER_COMMANDS = sizeof(userCmdStrings) / sizeof(userCmdString_t);
306 
307 const int MAX_CHAT_BUFFER = 127;
308 
310 public:
311  idUsercmdGenLocal( void );
312 
313  void Init( void );
314 
315  void InitForNewMap( void );
316 
317  void Shutdown( void );
318 
319  void Clear( void );
320 
321  void ClearAngles( void );
322 
323  usercmd_t TicCmd( int ticNumber );
324 
325  void InhibitUsercmd( inhibit_t subsystem, bool inhibit );
326 
327  void UsercmdInterrupt( void );
328 
329  int CommandStringUsercmdData( const char *cmdString );
330 
331  int GetNumUserCommands( void );
332 
333  const char * GetUserCommandName( int index );
334 
335  void MouseState( int *x, int *y, int *button, bool *down );
336 
337  int ButtonState( int key );
338  int KeyState( int key );
339 
340  usercmd_t GetDirectUsercmd( void );
341 
342 private:
343  void MakeCurrent( void );
344  void InitCurrent( void );
345 
346  bool Inhibited( void );
347  void AdjustAngles( void );
348  void KeyMove( void );
349  void JoystickMove( void );
350  void MouseMove( void );
351  void CmdButtons( void );
352 
353  void Mouse( void );
354  void Keyboard( void );
355  void Joystick( void );
356 
357  void Key( int keyNum, bool down );
358 
360  int flags;
361  int impulse;
362 
366 
369 
370  int inhibitCommands; // true when in console or menu locally
372 
374 
375  usercmd_t cmd; // the current cmd being built
377 
378  int continuousMouseX, continuousMouseY; // for gui event generatioin, never zerod
379  int mouseButton; // for gui event generatioin
380  bool mouseDown;
381 
382  int mouseDx, mouseDy; // added to by mouse events
383  int joystickAxis[MAX_JOYSTICK_AXIS]; // set by joystick events
384 
394  static idCVar m_pitch;
395  static idCVar m_yaw;
397  static idCVar m_smooth;
400 };
401 
402 idCVar idUsercmdGenLocal::in_yawSpeed( "in_yawspeed", "140", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "yaw change speed when holding down _left or _right button" );
403 idCVar idUsercmdGenLocal::in_pitchSpeed( "in_pitchspeed", "140", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "pitch change speed when holding down look _lookUp or _lookDown button" );
404 idCVar idUsercmdGenLocal::in_angleSpeedKey( "in_anglespeedkey", "1.5", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "angle change scale when holding down _speed button" );
405 idCVar idUsercmdGenLocal::in_freeLook( "in_freeLook", "1", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL, "look around with mouse (reverse _mlook button)" );
406 idCVar idUsercmdGenLocal::in_alwaysRun( "in_alwaysRun", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL, "always run (reverse _speed button) - only in MP" );
407 idCVar idUsercmdGenLocal::in_toggleRun( "in_toggleRun", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL, "pressing _speed button toggles run on/off - only in MP" );
408 idCVar idUsercmdGenLocal::in_toggleCrouch( "in_toggleCrouch", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL, "pressing _movedown button toggles player crouching/standing" );
409 idCVar idUsercmdGenLocal::in_toggleZoom( "in_toggleZoom", "0", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_BOOL, "pressing _zoom button toggles zoom on/off" );
410 idCVar idUsercmdGenLocal::sensitivity( "sensitivity", "5", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "mouse view sensitivity" );
411 idCVar idUsercmdGenLocal::m_pitch( "m_pitch", "0.022", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "mouse pitch scale" );
412 idCVar idUsercmdGenLocal::m_yaw( "m_yaw", "0.022", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "mouse yaw scale" );
413 idCVar idUsercmdGenLocal::m_strafeScale( "m_strafeScale", "6.25", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_FLOAT, "mouse strafe movement scale" );
414 idCVar idUsercmdGenLocal::m_smooth( "m_smooth", "1", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "number of samples blended for mouse viewing", 1, 8, idCmdSystem::ArgCompletion_Integer<1,8> );
415 idCVar idUsercmdGenLocal::m_strafeSmooth( "m_strafeSmooth", "4", CVAR_SYSTEM | CVAR_ARCHIVE | CVAR_INTEGER, "number of samples blended for mouse moving", 1, 8, idCmdSystem::ArgCompletion_Integer<1,8> );
416 idCVar idUsercmdGenLocal::m_showMouseRate( "m_showMouseRate", "0", CVAR_SYSTEM | CVAR_BOOL, "shows mouse movement" );
417 
418 static idUsercmdGenLocal localUsercmdGen;
419 idUsercmdGen *usercmdGen = &localUsercmdGen;
420 
421 /*
422 ================
423 idUsercmdGenLocal::idUsercmdGenLocal
424 ================
425 */
427  lastCommandTime = 0;
428  initialized = false;
429 
430  flags = 0;
431  impulse = 0;
432 
434  toggled_run.Clear();
437 
438  ClearAngles();
439  Clear();
440 }
441 
442 /*
443 ================
444 idUsercmdGenLocal::InhibitUsercmd
445 ================
446 */
447 void idUsercmdGenLocal::InhibitUsercmd( inhibit_t subsystem, bool inhibit ) {
448  if ( inhibit ) {
449  inhibitCommands |= 1 << subsystem;
450  } else {
451  inhibitCommands &= ( 0xffffffff ^ ( 1 << subsystem ) );
452  }
453 }
454 
455 /*
456 ===============
457 idUsercmdGenLocal::ButtonState
458 
459 Returns (the fraction of the frame) that the key was down
460 ===============
461 */
463  if ( key<0 || key>=UB_MAX_BUTTONS ) {
464  return -1;
465  }
466  return ( buttonState[key] > 0 ) ? 1 : 0;
467 }
468 
469 /*
470 ===============
471 idUsercmdGenLocal::KeyState
472 
473 Returns (the fraction of the frame) that the key was down
474 bk20060111
475 ===============
476 */
478  if ( key<0 || key>=K_LAST_KEY ) {
479  return -1;
480  }
481  return ( keyState[key] ) ? 1 : 0;
482 }
483 
484 
485 //=====================================================================
486 
487 
488 /*
489 ================
490 idUsercmdGenLocal::GetNumUserCommands
491 ================
492 */
494  return NUM_USER_COMMANDS;
495 }
496 
497 /*
498 ================
499 idUsercmdGenLocal::GetNumUserCommands
500 ================
501 */
503  if (index >= 0 && index < NUM_USER_COMMANDS) {
504  return userCmdStrings[index].string;
505  }
506  return "";
507 }
508 
509 /*
510 ================
511 idUsercmdGenLocal::Inhibited
512 
513 is user cmd generation inhibited
514 ================
515 */
517  return ( inhibitCommands != 0);
518 }
519 
520 /*
521 ================
522 idUsercmdGenLocal::AdjustAngles
523 
524 Moves the local angle positions
525 ================
526 */
528  float speed;
529 
532  } else {
533  speed = idMath::M_MS2SEC * USERCMD_MSEC;
534  }
535 
536  if ( !ButtonState( UB_STRAFE ) ) {
539  }
540 
543 }
544 
545 /*
546 ================
547 idUsercmdGenLocal::KeyMove
548 
549 Sets the usercmd_t based on key states
550 ================
551 */
553  int forward, side, up;
554 
555  forward = 0;
556  side = 0;
557  up = 0;
558  if ( ButtonState( UB_STRAFE ) ) {
559  side += KEY_MOVESPEED * ButtonState( UB_RIGHT );
560  side -= KEY_MOVESPEED * ButtonState( UB_LEFT );
561  }
562 
565 
567  up += KEY_MOVESPEED * ButtonState( UB_UP );
568 
569  forward += KEY_MOVESPEED * ButtonState( UB_FORWARD );
570  forward -= KEY_MOVESPEED * ButtonState( UB_BACK );
571 
572  cmd.forwardmove = idMath::ClampChar( forward );
573  cmd.rightmove = idMath::ClampChar( side );
574  cmd.upmove = idMath::ClampChar( up );
575 }
576 
577 /*
578 =================
579 idUsercmdGenLocal::MouseMove
580 =================
581 */
583  float mx, my, strafeMx, strafeMy;
584  static int history[8][2];
585  static int historyCounter;
586  int i;
587 
588  history[historyCounter&7][0] = mouseDx;
589  history[historyCounter&7][1] = mouseDy;
590 
591  // allow mouse movement to be smoothed together
592  int smooth = m_smooth.GetInteger();
593  if ( smooth < 1 ) {
594  smooth = 1;
595  }
596  if ( smooth > 8 ) {
597  smooth = 8;
598  }
599  mx = 0;
600  my = 0;
601  for ( i = 0 ; i < smooth ; i++ ) {
602  mx += history[ ( historyCounter - i + 8 ) & 7 ][0];
603  my += history[ ( historyCounter - i + 8 ) & 7 ][1];
604  }
605  mx /= smooth;
606  my /= smooth;
607 
608  // use a larger smoothing for strafing
609  smooth = m_strafeSmooth.GetInteger();
610  if ( smooth < 1 ) {
611  smooth = 1;
612  }
613  if ( smooth > 8 ) {
614  smooth = 8;
615  }
616  strafeMx = 0;
617  strafeMy = 0;
618  for ( i = 0 ; i < smooth ; i++ ) {
619  strafeMx += history[ ( historyCounter - i + 8 ) & 7 ][0];
620  strafeMy += history[ ( historyCounter - i + 8 ) & 7 ][1];
621  }
622  strafeMx /= smooth;
623  strafeMy /= smooth;
624 
625  historyCounter++;
626 
627  if ( idMath::Fabs( mx ) > 1000 || idMath::Fabs( my ) > 1000 ) {
628  Sys_DebugPrintf( "idUsercmdGenLocal::MouseMove: Ignoring ridiculous mouse delta.\n" );
629  mx = my = 0;
630  }
631 
632  mx *= sensitivity.GetFloat();
633  my *= sensitivity.GetFloat();
634 
635  if ( m_showMouseRate.GetBool() ) {
636  Sys_DebugPrintf( "[%3i %3i = %5.1f %5.1f = %5.1f %5.1f] ", mouseDx, mouseDy, mx, my, strafeMx, strafeMy );
637  }
638 
639  mouseDx = 0;
640  mouseDy = 0;
641 
642  if ( !strafeMx && !strafeMy ) {
643  return;
644  }
645 
646  if ( ButtonState( UB_STRAFE ) || !( cmd.buttons & BUTTON_MLOOK ) ) {
647  // add mouse X/Y movement to cmd
648  strafeMx *= m_strafeScale.GetFloat();
649  strafeMy *= m_strafeScale.GetFloat();
650  // clamp as a vector, instead of separate floats
651  float len = sqrt( strafeMx * strafeMx + strafeMy * strafeMy );
652  if ( len > 127 ) {
653  strafeMx = strafeMx * 127 / len;
654  strafeMy = strafeMy * 127 / len;
655  }
656  }
657 
658  if ( !ButtonState( UB_STRAFE ) ) {
659  viewangles[YAW] -= m_yaw.GetFloat() * mx;
660  } else {
661  cmd.rightmove = idMath::ClampChar( (int)(cmd.rightmove + strafeMx) );
662  }
663 
664  if ( !ButtonState( UB_STRAFE ) && ( cmd.buttons & BUTTON_MLOOK ) ) {
665  viewangles[PITCH] += m_pitch.GetFloat() * my;
666  } else {
667  cmd.forwardmove = idMath::ClampChar( (int)(cmd.forwardmove - strafeMy) );
668  }
669 }
670 
671 /*
672 =================
673 idUsercmdGenLocal::JoystickMove
674 =================
675 */
677  float anglespeed;
678 
681  } else {
682  anglespeed = idMath::M_MS2SEC * USERCMD_MSEC;
683  }
684 
685  if ( !ButtonState( UB_STRAFE ) ) {
688  } else {
691  }
692 
694 }
695 
696 /*
697 ==============
698 idUsercmdGenLocal::CmdButtons
699 ==============
700 */
702  int i;
703 
704  cmd.buttons = 0;
705 
706  // figure button bits
707  for (i = 0 ; i <= 7 ; i++) {
708  if ( ButtonState( (usercmdButton_t)( UB_BUTTON0 + i ) ) ) {
709  cmd.buttons |= 1 << i;
710  }
711  }
712 
713  // check the attack button
714  if ( ButtonState( UB_ATTACK ) ) {
716  }
717 
718  // check the run button
721  }
722 
723  // check the zoom button
724  if ( toggled_zoom.on ) {
726  }
727 
728  // check the scoreboard button
730  // the button is toggled in SP mode as well but without effect
732  }
733 
734  // check the mouse look button
737  }
738 }
739 
740 /*
741 ================
742 idUsercmdGenLocal::InitCurrent
743 
744 inits the current command for this frame
745 ================
746 */
748  memset( &cmd, 0, sizeof( cmd ) );
749  cmd.flags = flags;
750  cmd.impulse = impulse;
753 }
754 
755 /*
756 ================
757 idUsercmdGenLocal::MakeCurrent
758 
759 creates the current command for this frame
760 ================
761 */
763  idVec3 oldAngles;
764  int i;
765 
766  oldAngles = viewangles;
767 
768  if ( !Inhibited() ) {
769  // update toggled key states
773 
774  // keyboard angle adjustment
775  AdjustAngles();
776 
777  // set button bits
778  CmdButtons();
779 
780  // get basic movement from keyboard
781  KeyMove();
782 
783  // get basic movement from mouse
784  MouseMove();
785 
786  // get basic movement from joystick
787  JoystickMove();
788 
789  // check to make sure the angles haven't wrapped
790  if ( viewangles[PITCH] - oldAngles[PITCH] > 90 ) {
791  viewangles[PITCH] = oldAngles[PITCH] + 90;
792  } else if ( oldAngles[PITCH] - viewangles[PITCH] > 90 ) {
793  viewangles[PITCH] = oldAngles[PITCH] - 90;
794  }
795  } else {
796  mouseDx = 0;
797  mouseDy = 0;
798  }
799 
800  for ( i = 0; i < 3; i++ ) {
801  cmd.angles[i] = ANGLE2SHORT( viewangles[i] );
802  }
803 
806 
807  flags = cmd.flags;
808  impulse = cmd.impulse;
809 
810 }
811 
812 //=====================================================================
813 
814 
815 /*
816 ================
817 idUsercmdGenLocal::CommandStringUsercmdData
818 
819 Returns the button if the command string is used by the async usercmd generator.
820 ================
821 */
822 int idUsercmdGenLocal::CommandStringUsercmdData( const char *cmdString ) {
823  for ( userCmdString_t *ucs = userCmdStrings ; ucs->string ; ucs++ ) {
824  if ( idStr::Icmp( cmdString, ucs->string ) == 0 ) {
825  return ucs->button;
826  }
827  }
828  return UB_NONE;
829 }
830 
831 /*
832 ================
833 idUsercmdGenLocal::Init
834 ================
835 */
837  initialized = true;
838 }
839 
840 /*
841 ================
842 idUsercmdGenLocal::InitForNewMap
843 ================
844 */
846  flags = 0;
847  impulse = 0;
848 
850  toggled_run.Clear();
853 
854  Clear();
855  ClearAngles();
856 }
857 
858 /*
859 ================
860 idUsercmdGenLocal::Shutdown
861 ================
862 */
864  initialized = false;
865 }
866 
867 /*
868 ================
869 idUsercmdGenLocal::Clear
870 ================
871 */
873  // clears all key states
874  memset( buttonState, 0, sizeof( buttonState ) );
875  memset( keyState, false, sizeof( keyState ) );
876 
877  inhibitCommands = false;
878 
879  mouseDx = mouseDy = 0;
880  mouseButton = 0;
881  mouseDown = false;
882 }
883 
884 /*
885 ================
886 idUsercmdGenLocal::ClearAngles
887 ================
888 */
890  viewangles.Zero();
891 }
892 
893 /*
894 ================
895 idUsercmdGenLocal::TicCmd
896 
897 Returns a buffered usercmd
898 ================
899 */
901 
902  // the packetClient code can legally ask for com_ticNumber+1, because
903  // it is in the async code and com_ticNumber hasn't been updated yet,
904  // but all other code should never ask for anything > com_ticNumber
905  if ( ticNumber > com_ticNumber+1 ) {
906  common->Error( "idUsercmdGenLocal::TicCmd ticNumber > com_ticNumber" );
907  }
908 
909  if ( ticNumber <= com_ticNumber - MAX_BUFFERED_USERCMD ) {
910  // this can happen when something in the game code hitches badly, allowing the
911  // async code to overflow the buffers
912  //common->Printf( "warning: idUsercmdGenLocal::TicCmd ticNumber <= com_ticNumber - MAX_BUFFERED_USERCMD\n" );
913  }
914 
915  return buffered[ ticNumber & (MAX_BUFFERED_USERCMD-1) ];
916 }
917 
918 //======================================================================
919 
920 
921 /*
922 ===================
923 idUsercmdGenLocal::Key
924 
925 Handles async mouse/keyboard button actions
926 ===================
927 */
928 void idUsercmdGenLocal::Key( int keyNum, bool down ) {
929 
930  // Sanity check, sometimes we get double message :(
931  if ( keyState[ keyNum ] == down ) {
932  return;
933  }
934  keyState[ keyNum ] = down;
935 
936  int action = idKeyInput::GetUsercmdAction( keyNum );
937 
938  if ( down ) {
939 
940  buttonState[ action ]++;
941 
942  if ( !Inhibited() ) {
943  if ( action >= UB_IMPULSE0 && action <= UB_IMPULSE61 ) {
944  cmd.impulse = action - UB_IMPULSE0;
946  }
947  }
948  } else {
949  buttonState[ action ]--;
950  // we might have one held down across an app active transition
951  if ( buttonState[ action ] < 0 ) {
952  buttonState[ action ] = 0;
953  }
954  }
955 }
956 
957 /*
958 ===================
959 idUsercmdGenLocal::Mouse
960 ===================
961 */
963  int i, numEvents;
964 
965  numEvents = Sys_PollMouseInputEvents();
966 
967  if ( numEvents ) {
968  //
969  // Study each of the buffer elements and process them.
970  //
971  for( i = 0; i < numEvents; i++ ) {
972  int action, value;
973  if ( Sys_ReturnMouseInputEvent( i, action, value ) ) {
974  if ( action >= M_ACTION1 && action <= M_ACTION8 ) {
975  mouseButton = K_MOUSE1 + ( action - M_ACTION1 );
976  mouseDown = ( value != 0 );
977  Key( mouseButton, mouseDown );
978  } else {
979  switch ( action ) {
980  case M_DELTAX:
981  mouseDx += value;
983  break;
984  case M_DELTAY:
985  mouseDy += value;
987  break;
988  case M_DELTAZ:
989  int key = value < 0 ? K_MWHEELDOWN : K_MWHEELUP;
990  value = abs( value );
991  while( value-- > 0 ) {
992  Key( key, true );
993  Key( key, false );
994  mouseButton = key;
995  mouseDown = true;
996  }
997  break;
998  }
999  }
1000  }
1001  }
1002  }
1003 
1005 }
1006 
1007 /*
1008 ===============
1009 idUsercmdGenLocal::Keyboard
1010 ===============
1011 */
1013 
1014  int numEvents = Sys_PollKeyboardInputEvents();
1015 
1016  if ( numEvents ) {
1017  //
1018  // Study each of the buffer elements and process them.
1019  //
1020  int key;
1021  bool state;
1022  for( int i = 0; i < numEvents; i++ ) {
1023  if (Sys_ReturnKeyboardInputEvent( i, key, state )) {
1024  Key ( key, state );
1025  }
1026  }
1027  }
1028 
1030 }
1031 
1032 /*
1033 ===============
1034 idUsercmdGenLocal::Joystick
1035 ===============
1036 */
1038  memset( joystickAxis, 0, sizeof( joystickAxis ) );
1039 }
1040 
1041 /*
1042 ================
1043 idUsercmdGenLocal::UsercmdInterrupt
1044 
1045 Called asyncronously
1046 ================
1047 */
1049  // dedicated servers won't create usercmds
1050  if ( !initialized ) {
1051  return;
1052  }
1053 
1054  // init the usercmd for com_ticNumber+1
1055  InitCurrent();
1056 
1057  // process the system mouse events
1058  Mouse();
1059 
1060  // process the system keyboard events
1061  Keyboard();
1062 
1063  // process the system joystick events
1064  Joystick();
1065 
1066  // create the usercmd for com_ticNumber+1
1067  MakeCurrent();
1068 
1069  // save a number for debugging cmdDemos and networking
1071 
1073 }
1074 
1075 /*
1076 ================
1077 idUsercmdGenLocal::MouseState
1078 ================
1079 */
1080 void idUsercmdGenLocal::MouseState( int *x, int *y, int *button, bool *down ) {
1081  *x = continuousMouseX;
1082  *y = continuousMouseY;
1083  *button = mouseButton;
1084  *down = mouseDown;
1085 }
1086 
1087 /*
1088 ================
1089 idUsercmdGenLocal::GetDirectUsercmd
1090 ================
1091 */
1093 
1094  // initialize current usercmd
1095  InitCurrent();
1096 
1097  // process the system mouse events
1098  Mouse();
1099 
1100  // process the system keyboard events
1101  Keyboard();
1102 
1103  // process the system joystick events
1104  Joystick();
1105 
1106  // create the usercmd
1107  MakeCurrent();
1108 
1109  cmd.duplicateCount = 0;
1110 
1111  return cmd;
1112 }
static int GetUsercmdAction(int keyNum)
Definition: KeyInput.cpp:453
static idCVar m_pitch
Definition: UsercmdGen.cpp:394
static idCVar in_toggleRun
Definition: UsercmdGen.cpp:390
buttonState_t toggled_zoom
Definition: UsercmdGen.cpp:365
int ButtonState(int key)
Definition: UsercmdGen.cpp:462
GLsizei const GLfloat * value
Definition: glext.h:3614
short mx
Definition: UsercmdGen.h:99
void SetKeyState(int keystate, bool toggle)
Definition: UsercmdGen.cpp:292
int Sys_PollKeyboardInputEvents(void)
Definition: dedicated.cpp:51
void InitForNewMap(void)
Definition: UsercmdGen.cpp:845
const int MAX_CHAT_BUFFER
Definition: UsercmdGen.cpp:307
void AdjustAngles(void)
Definition: UsercmdGen.cpp:527
#define ANGLE2SHORT(x)
Definition: Math.h:62
float GetFloat(void) const
Definition: CVarSystem.h:144
usercmd_t GetDirectUsercmd(void)
usercmdButton_t button
Definition: UsercmdGen.cpp:168
int KeyState(int key)
Definition: UsercmdGen.cpp:477
static idCVar m_strafeSmooth
Definition: UsercmdGen.cpp:398
GLenum GLint GLint y
Definition: glext.h:2849
buttonState_t toggled_run
Definition: UsercmdGen.cpp:364
const int KEY_MOVESPEED
Definition: UsercmdGen.cpp:66
void Mouse(void)
Definition: UsercmdGen.cpp:962
Definition: Vector.h:316
void ByteSwap()
Definition: UsercmdGen.cpp:39
volatile int com_ticNumber
Definition: Common.cpp:96
void Sys_DebugPrintf(const char *fmt,...)
Definition: posix_main.cpp:999
static idCVar in_alwaysRun
Definition: UsercmdGen.cpp:389
int buttonState[UB_MAX_BUTTONS]
Definition: UsercmdGen.cpp:367
signed char impulse
Definition: UsercmdGen.h:101
GLenum GLsizei len
Definition: glext.h:3472
buttonState_t toggled_crouch
Definition: UsercmdGen.cpp:363
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
void Clear(void)
Definition: UsercmdGen.cpp:282
int joystickAxis[MAX_JOYSTICK_AXIS]
Definition: UsercmdGen.cpp:383
static idCVar in_angleSpeedKey
Definition: UsercmdGen.cpp:387
void CmdButtons(void)
Definition: UsercmdGen.cpp:701
int Icmp(const char *text) const
Definition: Str.h:667
usercmd_t buffered[MAX_BUFFERED_USERCMD]
Definition: UsercmdGen.cpp:376
const int BUTTON_ATTACK
Definition: UsercmdGen.h:44
void Clear(void)
Definition: UsercmdGen.cpp:872
static idCVar in_toggleCrouch
Definition: UsercmdGen.cpp:391
const char * GetUserCommandName(int index)
Definition: UsercmdGen.cpp:502
static idCVar in_toggleZoom
Definition: UsercmdGen.cpp:392
const int USERCMD_MSEC
Definition: UsercmdGen.h:41
static idCVar in_pitchSpeed
Definition: UsercmdGen.cpp:386
static bool IsActive(void)
Definition: AsyncNetwork.h:149
usercmdButton_t
Definition: UsercmdGen.cpp:68
int sequence
Definition: UsercmdGen.h:103
void Sys_EndMouseInputEvents(void)
Definition: dedicated.cpp:47
GLuint index
Definition: glext.h:3476
void KeyMove(void)
Definition: UsercmdGen.cpp:552
const int UCF_IMPULSE_SEQUENCE
Definition: UsercmdGen.h:87
static idCVar in_yawSpeed
Definition: UsercmdGen.cpp:385
void UsercmdInterrupt(void)
static float Fabs(float f)
Definition: Math.h:779
void MouseState(int *x, int *y, int *button, bool *down)
idCommon * common
Definition: Common.cpp:206
byte flags
Definition: UsercmdGen.h:102
#define NULL
Definition: Lib.h:88
int GetInteger(void) const
Definition: CVarSystem.h:143
void JoystickMove(void)
Definition: UsercmdGen.cpp:676
signed char upmove
Definition: UsercmdGen.h:97
bool keyState[K_LAST_KEY]
Definition: UsercmdGen.cpp:368
void Shutdown(void)
Definition: UsercmdGen.cpp:863
void InhibitUsercmd(inhibit_t subsystem, bool inhibit)
Definition: UsercmdGen.cpp:447
static idCVar sensitivity
Definition: UsercmdGen.cpp:393
const char * string
Definition: UsercmdGen.cpp:167
static idCVar in_freeLook
Definition: UsercmdGen.cpp:388
idUsercmdGen * usercmdGen
Definition: UsercmdGen.cpp:419
static idCVar m_showMouseRate
Definition: UsercmdGen.cpp:399
int LittleLong(int l)
Definition: Lib.cpp:281
const int BUTTON_ZOOM
Definition: UsercmdGen.h:46
#define YAW
Definition: Angles.h:42
void Key(int keyNum, bool down)
Definition: UsercmdGen.cpp:928
short LittleShort(short l)
Definition: Lib.cpp:279
int CommandStringUsercmdData(const char *cmdString)
Definition: UsercmdGen.cpp:822
int duplicateCount
Definition: UsercmdGen.h:93
bool GetBool(void) const
Definition: CVarSystem.h:142
static signed char ClampChar(int i)
Definition: Math.h:863
int Sys_ReturnKeyboardInputEvent(const int n, int &action, bool &state)
Definition: dedicated.cpp:55
inhibit_t
Definition: UsercmdGen.h:110
short angles[3]
Definition: UsercmdGen.h:98
void MouseMove(void)
Definition: UsercmdGen.cpp:582
signed char forwardmove
Definition: UsercmdGen.h:95
short my
Definition: UsercmdGen.h:100
void Sys_EndKeyboardInputEvents(void)
Definition: dedicated.cpp:53
static idCVar m_yaw
Definition: UsercmdGen.cpp:395
const int BUTTON_MLOOK
Definition: UsercmdGen.h:48
bool operator==(const usercmd_t &rhs) const
Definition: UsercmdGen.cpp:51
void Joystick(void)
void InitCurrent(void)
Definition: UsercmdGen.cpp:747
const int MAX_BUFFERED_USERCMD
Definition: UsercmdGen.h:115
void MakeCurrent(void)
Definition: UsercmdGen.cpp:762
static idCVar m_smooth
Definition: UsercmdGen.cpp:397
const int BUTTON_SCORES
Definition: UsercmdGen.h:47
int Sys_ReturnMouseInputEvent(const int n, int &action, int &value)
Definition: dedicated.cpp:49
signed char rightmove
Definition: UsercmdGen.h:96
virtual void Error(const char *fmt,...) id_attribute((format(printf
userCmdString_t userCmdStrings[]
Definition: UsercmdGen.cpp:171
const int BUTTON_RUN
Definition: UsercmdGen.h:45
void Keyboard(void)
void ClearAngles(void)
Definition: UsercmdGen.cpp:889
void Zero(void)
Definition: Vector.h:415
const int NUM_USER_COMMANDS
Definition: UsercmdGen.cpp:305
usercmd_t TicCmd(int ticNumber)
Definition: UsercmdGen.cpp:900
static const float M_MS2SEC
Definition: Math.h:217
byte buttons
Definition: UsercmdGen.h:94
#define PITCH
Definition: Angles.h:41
int GetNumUserCommands(void)
Definition: UsercmdGen.cpp:493
static idCVar m_strafeScale
Definition: UsercmdGen.cpp:396
int Sys_PollMouseInputEvents(void)
Definition: dedicated.cpp:45
bool Inhibited(void)
Definition: UsercmdGen.cpp:516