Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2102 lines
57 KiB

  1. //========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: builds an intended movement command to send to the server
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //=======================================================================================//
  9. #include "cbase.h"
  10. #include "kbutton.h"
  11. #include "usercmd.h"
  12. #include "in_buttons.h"
  13. #include "input.h"
  14. #include "iviewrender.h"
  15. #include "iclientmode.h"
  16. #include "prediction.h"
  17. #include "bitbuf.h"
  18. #include "checksum_md5.h"
  19. #include "hltvcamera.h"
  20. #if defined( REPLAY_ENABLED )
  21. #include "replaycamera.h"
  22. #endif
  23. #include "ivieweffects.h"
  24. #include "inputsystem/iinputsystem.h"
  25. #include <ctype.h> // isalnum()
  26. #include <voice_status.h>
  27. #ifdef SIXENSE
  28. #include "sixense/in_sixense.h"
  29. #endif
  30. extern ConVar cam_idealpitch;
  31. extern ConVar cam_idealyaw;
  32. #ifdef INFESTED_DLL
  33. extern ConVar asw_cam_marine_yaw;
  34. #endif
  35. // For showing/hiding the scoreboard
  36. #include <game/client/iviewport.h>
  37. // memdbgon must be the last include file in a .cpp file!!!
  38. #include "tier0/memdbgon.h"
  39. int in_impulse[ MAX_SPLITSCREEN_PLAYERS ];
  40. static int in_cancel[ MAX_SPLITSCREEN_PLAYERS ];
  41. ConVar cl_anglespeedkey( "cl_anglespeedkey", "0.67", 0 );
  42. ConVar cl_yawspeed( "cl_yawspeed", "210", 0 );
  43. ConVar cl_pitchspeed( "cl_pitchspeed", "225", 0 );
  44. ConVar cl_pitchdown( "cl_pitchdown", "89", FCVAR_CHEAT );
  45. ConVar cl_pitchup( "cl_pitchup", "89", FCVAR_CHEAT );
  46. ConVar cl_upspeed( "cl_upspeed", "320", FCVAR_CHEAT );
  47. ConVar lookspring( "lookspring", "0", FCVAR_ARCHIVE );
  48. ConVar lookstrafe( "lookstrafe", "0", FCVAR_ARCHIVE );
  49. #ifdef PORTAL2
  50. #define MAX_LINEAR_SPEED "175"
  51. #else
  52. #define MAX_LINEAR_SPEED "450"
  53. #endif
  54. ConVar cl_sidespeed( "cl_sidespeed", MAX_LINEAR_SPEED, FCVAR_CHEAT );
  55. ConVar cl_forwardspeed( "cl_forwardspeed", MAX_LINEAR_SPEED, FCVAR_CHEAT );
  56. ConVar cl_backspeed( "cl_backspeed", MAX_LINEAR_SPEED, FCVAR_CHEAT );
  57. void IN_JoystickChangedCallback_f( IConVar *pConVar, const char *pOldString, float flOldValue );
  58. ConVar in_joystick( "joystick", "1", FCVAR_ARCHIVE, "True if the joystick is enabled, false otherwise.", true, 0.0f, true, 1.0f, IN_JoystickChangedCallback_f );
  59. ConVar thirdperson_platformer( "thirdperson_platformer", "0", 0, "Player will aim in the direction they are moving." );
  60. ConVar thirdperson_screenspace( "thirdperson_screenspace", "0", 0, "Movement will be relative to the camera, eg: left means screen-left" );
  61. ConVar sv_noclipduringpause( "sv_noclipduringpause", "0", FCVAR_REPLICATED | FCVAR_CHEAT, "If cheats are enabled, then you can noclip with the game paused (for doing screenshots, etc.)." );
  62. static ConVar cl_lagcomp_errorcheck( "cl_lagcomp_errorcheck", "0", 0, "Player index of other player to check for position errors." );
  63. static ConVar option_duck_method( "option_duck_method", "0", FCVAR_ARCHIVE | FCVAR_SS );// 0 = HOLD to duck, 1 = Duck is a toggle
  64. static ConVar option_speed_method( "option_speed_method", "0", FCVAR_ARCHIVE | FCVAR_SS );// 0 = HOLD to go slow speed, 1 = speed is a toggle
  65. static ConVar round_start_reset_duck( "round_start_reset_duck", "0", 0 );
  66. static ConVar round_start_reset_speed( "round_start_reset_speed", "0", 0 );
  67. bool UsingMouselook( int nSlot )
  68. {
  69. static SplitScreenConVarRef s_MouseLook( "cl_mouselook" );
  70. return s_MouseLook.GetBool( nSlot );
  71. }
  72. ConVar in_forceuser( "in_forceuser", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "Force user input to this split screen player." );
  73. static ConVar ss_mimic( "ss_mimic", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "Split screen users mimic base player's CUserCmds" );
  74. static void SplitScreenTeleport( int nSlot )
  75. {
  76. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer( nSlot );
  77. if ( !pPlayer )
  78. return;
  79. Vector vecOrigin = pPlayer->GetAbsOrigin();
  80. QAngle angles = pPlayer->GetAbsAngles();
  81. int nOther = ( nSlot + 1 ) % MAX_SPLITSCREEN_PLAYERS;
  82. if ( C_BasePlayer::GetLocalPlayer( nOther ) )
  83. {
  84. char cmd[ 256 ];
  85. Q_snprintf( cmd, sizeof( cmd ), "cmd%d setpos %f %f %f;setang %f %f %f\n",
  86. nOther + 1,
  87. VectorExpand( vecOrigin ),
  88. VectorExpand( angles ) );
  89. engine->ClientCmd( cmd );
  90. }
  91. }
  92. CON_COMMAND_F( ss_teleport, "Teleport other splitscreen player to my location.", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY )
  93. {
  94. SplitScreenTeleport( GET_ACTIVE_SPLITSCREEN_SLOT() );
  95. }
  96. /*
  97. ===============================================================================
  98. KEY BUTTONS
  99. Continuous button event tracking is complicated by the fact that two different
  100. input sources (say, mouse button 1 and the control key) can both press the
  101. same button, but the button should only be released when both of the
  102. pressing key have been released.
  103. When a key event issues a button command (+forward, +attack, etc), it appends
  104. its key number as a parameter to the command so it can be matched up with
  105. the release.
  106. state bit 0 is the current state of the key
  107. state bit 1 is edge triggered on the up to down transition
  108. state bit 2 is edge triggered on the down to up transition
  109. ===============================================================================
  110. */
  111. kbutton_t in_speed;
  112. kbutton_t in_walk;
  113. kbutton_t in_jlook;
  114. kbutton_t in_strafe;
  115. kbutton_t in_commandermousemove;
  116. kbutton_t in_forward;
  117. kbutton_t in_back;
  118. kbutton_t in_moveleft;
  119. kbutton_t in_moveright;
  120. // Display the netgraph
  121. kbutton_t in_graph;
  122. kbutton_t in_joyspeed; // auto-speed key from the joystick (only works for player movement, not vehicles)
  123. kbutton_t in_ducktoggle;
  124. kbutton_t in_speedtoggle;
  125. kbutton_t in_lookspin;
  126. kbutton_t in_attack;
  127. kbutton_t in_attack2;
  128. kbutton_t in_zoom;
  129. static kbutton_t in_klook;
  130. static kbutton_t in_left;
  131. static kbutton_t in_right;
  132. static kbutton_t in_lookup;
  133. static kbutton_t in_lookdown;
  134. static kbutton_t in_use;
  135. static kbutton_t in_jump;
  136. static kbutton_t in_up;
  137. static kbutton_t in_down;
  138. static kbutton_t in_duck;
  139. static kbutton_t in_reload;
  140. static kbutton_t in_alt1;
  141. static kbutton_t in_alt2;
  142. static kbutton_t in_score;
  143. static kbutton_t in_break;
  144. static kbutton_t in_grenade1;
  145. static kbutton_t in_grenade2;
  146. #ifdef INFESTED_DLL
  147. static kbutton_t in_currentability;
  148. static kbutton_t in_prevability;
  149. static kbutton_t in_nextability;
  150. static kbutton_t in_ability1;
  151. static kbutton_t in_ability2;
  152. static kbutton_t in_ability3;
  153. static kbutton_t in_ability4;
  154. static kbutton_t in_ability5;
  155. #endif
  156. bool joystick_forced_speed = false;
  157. /*
  158. ===========
  159. IN_CenterView_f
  160. ===========
  161. */
  162. void IN_CenterView_f (void)
  163. {
  164. QAngle viewangles;
  165. if ( UsingMouselook( GET_ACTIVE_SPLITSCREEN_SLOT() ) == false )
  166. {
  167. if ( !::input->CAM_InterceptingMouse() )
  168. {
  169. engine->GetViewAngles( viewangles );
  170. viewangles[PITCH] = 0;
  171. engine->SetViewAngles( viewangles );
  172. }
  173. }
  174. }
  175. /*
  176. ===========
  177. IN_Joystick_Advanced_f
  178. ===========
  179. */
  180. void IN_Joystick_Advanced_f (const CCommand& args)
  181. {
  182. ::input->Joystick_Advanced( args.ArgC() == 2 );
  183. }
  184. void IN_JoystickChangedCallback_f( IConVar *pConVar, const char *pOldString, float flOldValue )
  185. {
  186. ::input->Joystick_Advanced( true );
  187. }
  188. /*
  189. ============
  190. KB_ConvertString
  191. Removes references to +use and replaces them with the keyname in the output string. If
  192. a binding is unfound, then the original text is retained.
  193. NOTE: Only works for text with +word in it.
  194. ============
  195. */
  196. int KB_ConvertString( char *in, char **ppout )
  197. {
  198. char sz[ 4096 ];
  199. char binding[ 64 ];
  200. char *p;
  201. char *pOut;
  202. char *pEnd;
  203. const char *pBinding;
  204. if ( !ppout )
  205. return 0;
  206. *ppout = NULL;
  207. p = in;
  208. pOut = sz;
  209. while ( *p )
  210. {
  211. if ( *p == '+' )
  212. {
  213. pEnd = binding;
  214. while ( *p && ( V_isalnum( *p ) || ( pEnd == binding ) ) && ( ( pEnd - binding ) < 63 ) )
  215. {
  216. *pEnd++ = *p++;
  217. }
  218. *pEnd = '\0';
  219. pBinding = NULL;
  220. if ( strlen( binding + 1 ) > 0 )
  221. {
  222. // See if there is a binding for binding?
  223. pBinding = engine->Key_LookupBinding( binding + 1 );
  224. }
  225. if ( pBinding )
  226. {
  227. *pOut++ = '[';
  228. pEnd = (char *)pBinding;
  229. }
  230. else
  231. {
  232. pEnd = binding;
  233. }
  234. while ( *pEnd )
  235. {
  236. *pOut++ = *pEnd++;
  237. }
  238. if ( pBinding )
  239. {
  240. *pOut++ = ']';
  241. }
  242. }
  243. else
  244. {
  245. *pOut++ = *p++;
  246. }
  247. }
  248. *pOut = '\0';
  249. int maxlen = strlen( sz ) + 1;
  250. pOut = ( char * )malloc( maxlen );
  251. Q_strncpy( pOut, sz, maxlen );
  252. *ppout = pOut;
  253. return 1;
  254. }
  255. /*
  256. ==============================
  257. FindKey
  258. Allows the engine to request a kbutton handler by name, if the key exists.
  259. ==============================
  260. */
  261. kbutton_t *CInput::FindKey( const char *name )
  262. {
  263. CKeyboardKey *p;
  264. p = m_pKeys;
  265. while ( p )
  266. {
  267. if ( !Q_stricmp( name, p->name ) )
  268. {
  269. return p->pkey;
  270. }
  271. p = p->next;
  272. }
  273. return NULL;
  274. }
  275. /*
  276. ============
  277. AddKeyButton
  278. Add a kbutton_t * to the list of pointers the engine can retrieve via KB_Find
  279. ============
  280. */
  281. void CInput::AddKeyButton( const char *name, kbutton_t *pkb )
  282. {
  283. CKeyboardKey *p;
  284. kbutton_t *kb;
  285. kb = FindKey( name );
  286. if ( kb )
  287. return;
  288. p = new CKeyboardKey;
  289. Q_strncpy( p->name, name, sizeof( p->name ) );
  290. p->pkey = pkb;
  291. p->next = m_pKeys;
  292. m_pKeys = p;
  293. }
  294. //-----------------------------------------------------------------------------
  295. // Purpose:
  296. //-----------------------------------------------------------------------------
  297. CInput::CInput( void )
  298. {
  299. for ( int i = 0; i < MAX_SPLITSCREEN_PLAYERS; ++i )
  300. {
  301. m_PerUser[ i ].m_pCommands = NULL;
  302. m_PerUser[ i ].m_pCameraThirdData = NULL;
  303. m_PerUser[ i ].m_pVerifiedCommands = NULL;
  304. }
  305. m_lastAutoAimValue = 1.0f;
  306. }
  307. //-----------------------------------------------------------------------------
  308. // Purpose:
  309. //-----------------------------------------------------------------------------
  310. CInput::~CInput( void )
  311. {
  312. }
  313. /*
  314. ============
  315. Init_Keyboard
  316. Add kbutton_t definitions that the engine can query if needed
  317. ============
  318. */
  319. void CInput::Init_Keyboard( void )
  320. {
  321. m_pKeys = NULL;
  322. AddKeyButton( "in_graph", &in_graph );
  323. AddKeyButton( "in_jlook", &in_jlook );
  324. AddKeyButton( "in_reload", &in_reload );
  325. }
  326. /*
  327. ============
  328. Shutdown_Keyboard
  329. Clear kblist
  330. ============
  331. */
  332. void CInput::Shutdown_Keyboard( void )
  333. {
  334. CKeyboardKey *p, *n;
  335. p = m_pKeys;
  336. while ( p )
  337. {
  338. n = p->next;
  339. delete p;
  340. p = n;
  341. }
  342. m_pKeys = NULL;
  343. }
  344. kbutton_t::Split_t &kbutton_t::GetPerUser( int nSlot /*=-1*/ )
  345. {
  346. if ( nSlot == -1 )
  347. {
  348. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  349. nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
  350. }
  351. return m_PerUser[ nSlot ];
  352. }
  353. /*
  354. ============
  355. KeyDown
  356. ============
  357. */
  358. void KeyDown( kbutton_t *b, const char *c )
  359. {
  360. kbutton_t::Split_t &data = b->GetPerUser();
  361. int k = -1;
  362. if ( c && c[0] )
  363. {
  364. k = atoi(c);
  365. }
  366. if (k == data.down[0] || k == data.down[1])
  367. return; // repeating key
  368. if (!data.down[0])
  369. data.down[0] = k;
  370. else if (!data.down[1])
  371. data.down[1] = k;
  372. else
  373. {
  374. if ( c[0] )
  375. {
  376. DevMsg( 1,"Three keys down for a button '%c' '%c' '%c'!\n", data.down[0], data.down[1], c[0]);
  377. }
  378. return;
  379. }
  380. if (data.state & 1)
  381. return; // still down
  382. data.state |= 1 + 2; // down + impulse down
  383. }
  384. /*
  385. ============
  386. KeyUp
  387. ============
  388. */
  389. void KeyUp( kbutton_t *b, const char *c )
  390. {
  391. kbutton_t::Split_t &data = b->GetPerUser();
  392. if ( !c || !c[0] )
  393. {
  394. data.down[0] = data.down[1] = 0;
  395. data.state = 4; // impulse up
  396. return;
  397. }
  398. int k = atoi(c);
  399. if (data.down[0] == k)
  400. data.down[0] = 0;
  401. else if (data.down[1] == k)
  402. data.down[1] = 0;
  403. else
  404. return; // key up without coresponding down (menu pass through)
  405. if (data.down[0] || data.down[1])
  406. {
  407. //Msg ("Keys down for button: '%c' '%c' '%c' (%d,%d,%d)!\n", data.down[0], data.down[1], c, data.down[0], data.down[1], c);
  408. return; // some other key is still holding it down
  409. }
  410. if (!(data.state & 1))
  411. return; // still up (this should not happen)
  412. data.state &= ~1; // now up
  413. data.state |= 4; // impulse up
  414. }
  415. void IN_ClearDuckToggle()
  416. {
  417. if ( ::input->KeyState( &in_ducktoggle ) )
  418. {
  419. KeyUp( &in_ducktoggle, NULL );
  420. }
  421. }
  422. void IN_ClearSpeedToggle()
  423. {
  424. if ( ::input->KeyState( &in_speedtoggle ) )
  425. {
  426. KeyUp( &in_speedtoggle, NULL );
  427. }
  428. }
  429. void IN_ForceSpeedDown( ) {joystick_forced_speed = true;}
  430. void IN_ForceSpeedUp( ) {joystick_forced_speed = false;}
  431. void IN_CommanderMouseMoveDown( const CCommand &args ) {KeyDown(&in_commandermousemove, args[1] );}
  432. void IN_CommanderMouseMoveUp( const CCommand &args ) {KeyUp(&in_commandermousemove, args[1] );}
  433. void IN_BreakDown( const CCommand &args ) { KeyDown( &in_break , args[1] );}
  434. void IN_BreakUp( const CCommand &args )
  435. {
  436. KeyUp( &in_break, args[1] );
  437. #if defined( _DEBUG )
  438. DebuggerBreak();
  439. #endif
  440. };
  441. void IN_KLookDown ( const CCommand &args ) {KeyDown(&in_klook, args[1] );}
  442. void IN_KLookUp ( const CCommand &args ) {KeyUp(&in_klook, args[1] );}
  443. void IN_JLookDown ( const CCommand &args ) {KeyDown(&in_jlook, args[1] );}
  444. void IN_JLookUp ( const CCommand &args ) {KeyUp(&in_jlook, args[1] );}
  445. void IN_UpDown( const CCommand &args ) {KeyDown(&in_up, args[1] );}
  446. void IN_UpUp( const CCommand &args ) {KeyUp(&in_up, args[1] );}
  447. void IN_DownDown( const CCommand &args ) {KeyDown(&in_down, args[1] );}
  448. void IN_DownUp( const CCommand &args ) {KeyUp(&in_down, args[1] );}
  449. void IN_LeftDown( const CCommand &args ) {KeyDown(&in_left, args[1] );}
  450. void IN_LeftUp( const CCommand &args ) {KeyUp(&in_left, args[1] );}
  451. void IN_RightDown( const CCommand &args ) {KeyDown(&in_right, args[1] );}
  452. void IN_RightUp( const CCommand &args ) {KeyUp(&in_right, args[1] );}
  453. void IN_ForwardDown( const CCommand &args ) {KeyDown(&in_forward, args[1] );}
  454. void IN_ForwardUp( const CCommand &args ) {KeyUp(&in_forward, args[1] );}
  455. void IN_BackDown( const CCommand &args ) {KeyDown(&in_back, args[1] );}
  456. void IN_BackUp( const CCommand &args ) {KeyUp(&in_back, args[1] );}
  457. void IN_LookupDown( const CCommand &args ) {KeyDown(&in_lookup, args[1] );}
  458. void IN_LookupUp( const CCommand &args ) {KeyUp(&in_lookup, args[1] );}
  459. void IN_LookdownDown( const CCommand &args ) {KeyDown(&in_lookdown, args[1] );}
  460. void IN_LookdownUp( const CCommand &args ) {KeyUp(&in_lookdown, args[1] );}
  461. void IN_MoveleftDown( const CCommand &args ) {KeyDown(&in_moveleft, args[1] );}
  462. void IN_MoveleftUp( const CCommand &args ) {KeyUp(&in_moveleft, args[1] );}
  463. void IN_MoverightDown( const CCommand &args ) {KeyDown(&in_moveright, args[1] );}
  464. void IN_MoverightUp( const CCommand &args ) {KeyUp(&in_moveright, args[1] );}
  465. void IN_StrafeDown( const CCommand &args ) {KeyDown(&in_strafe, args[1] );}
  466. void IN_StrafeUp( const CCommand &args ) {KeyUp(&in_strafe, args[1] );}
  467. void IN_Attack2Down( const CCommand &args ) { KeyDown(&in_attack2, args[1] );}
  468. void IN_Attack2Up( const CCommand &args ) {KeyUp(&in_attack2, args[1] );}
  469. void IN_UseDown ( const CCommand &args ) {KeyDown(&in_use, args[1] );}
  470. void IN_UseUp ( const CCommand &args ) {KeyUp(&in_use, args[1] );}
  471. void IN_JumpDown ( const CCommand &args ) {KeyDown(&in_jump, args[1] );}
  472. void IN_JumpUp ( const CCommand &args )
  473. {
  474. KeyUp(&in_jump, args[1] );
  475. }
  476. void IN_DuckToggle( const CCommand &args )
  477. {
  478. if ( ::input->KeyState(&in_ducktoggle) )
  479. {
  480. IN_ClearDuckToggle();
  481. }
  482. else
  483. {
  484. KeyDown( &in_ducktoggle, args[1] );
  485. }
  486. }
  487. void IN_DuckDown( const CCommand &args )
  488. {
  489. SplitScreenConVarRef option_duck_method( "option_duck_method" );
  490. if ( option_duck_method.IsValid() && option_duck_method.GetBool( GET_ACTIVE_SPLITSCREEN_SLOT() ) )
  491. {
  492. IN_DuckToggle( args );
  493. }
  494. else
  495. {
  496. KeyDown(&in_duck, args[1] );
  497. IN_ClearDuckToggle();
  498. }
  499. }
  500. void IN_DuckUp( const CCommand &args )
  501. {
  502. SplitScreenConVarRef option_duck_method( "option_duck_method" );
  503. if ( option_duck_method.IsValid() && option_duck_method.GetBool( GET_ACTIVE_SPLITSCREEN_SLOT() ) )
  504. {
  505. // intentionally blank
  506. }
  507. else
  508. {
  509. KeyUp(&in_duck, args[1] );
  510. IN_ClearDuckToggle();
  511. }
  512. }
  513. void IN_SpeedToggle( const CCommand &args )
  514. {
  515. if ( ::input->KeyState(&in_speedtoggle) )
  516. {
  517. IN_ClearSpeedToggle();
  518. }
  519. else
  520. {
  521. KeyDown( &in_speedtoggle, args[1] );
  522. }
  523. }
  524. void IN_SpeedDown( const CCommand &args )
  525. {
  526. SplitScreenConVarRef option_speed_method( "option_speed_method" );
  527. if ( option_speed_method.IsValid() && option_speed_method.GetBool( GET_ACTIVE_SPLITSCREEN_SLOT() ) )
  528. {
  529. IN_SpeedToggle( args );
  530. }
  531. else
  532. {
  533. KeyDown(&in_speed, args[1] );
  534. IN_ClearSpeedToggle();
  535. }
  536. }
  537. void IN_SpeedUp( const CCommand &args )
  538. {
  539. SplitScreenConVarRef option_speed_method( "option_speed_method" );
  540. if ( option_speed_method.IsValid() && option_speed_method.GetBool( GET_ACTIVE_SPLITSCREEN_SLOT() ) )
  541. {
  542. // intentionally blank
  543. }
  544. else
  545. {
  546. KeyUp(&in_speed, args[1] );
  547. IN_ClearSpeedToggle();
  548. }
  549. }
  550. void IN_WalkDown( const CCommand &args ) {KeyDown(&in_walk, args[1] );}
  551. void IN_WalkUp( const CCommand &args ) {KeyUp(&in_walk, args[1] );}
  552. void IN_ReloadDown( const CCommand &args ) {KeyDown(&in_reload, args[1] );}
  553. void IN_ReloadUp( const CCommand &args ) {KeyUp(&in_reload, args[1] );}
  554. void IN_Alt1Down( const CCommand &args ) {KeyDown(&in_alt1, args[1] );}
  555. void IN_Alt1Up( const CCommand &args ) {KeyUp(&in_alt1, args[1] );}
  556. void IN_Alt2Down( const CCommand &args ) {KeyDown(&in_alt2, args[1] );}
  557. void IN_Alt2Up( const CCommand &args ) {KeyUp(&in_alt2, args[1] );}
  558. void IN_GraphDown( const CCommand &args ) {KeyDown(&in_graph, args[1] );}
  559. void IN_GraphUp( const CCommand &args ) {KeyUp(&in_graph, args[1] );}
  560. void IN_ZoomDown( const CCommand &args ) {KeyDown(&in_zoom, args[1] );}
  561. void IN_ZoomUp( const CCommand &args ) {KeyUp(&in_zoom, args[1] );}
  562. void IN_ZoomInDown( const CCommand &args ) {KeyDown(&in_grenade1, args[1] );}
  563. void IN_ZoomInUp( const CCommand &args ) {KeyUp(&in_grenade1, args[1] );}
  564. void IN_ZoomOutDown( const CCommand &args ) {KeyDown(&in_grenade2, args[1] );}
  565. void IN_ZoomOutUp( const CCommand &args ) {KeyUp(&in_grenade2, args[1] );}
  566. void IN_Grenade1Up( const CCommand &args ) { KeyUp( &in_grenade1, args[1] ); }
  567. void IN_Grenade1Down( const CCommand &args ) { KeyDown( &in_grenade1, args[1] ); }
  568. void IN_Grenade2Up( const CCommand &args ) { KeyUp( &in_grenade2, args[1] ); }
  569. void IN_Grenade2Down( const CCommand &args ) { KeyDown( &in_grenade2, args[1] ); }
  570. void IN_XboxStub( const CCommand &args ) { /*do nothing*/ }
  571. #ifdef PORTAL2
  572. #if USE_SLOWTIME
  573. // Slow-time
  574. kbutton_t in_slowtoggle;
  575. void IN_SlowTimeUp( const CCommand &args ) { KeyUp( &in_slowtoggle, args[1] ); }
  576. void IN_SlowTimeDown( const CCommand &args ) { KeyDown( &in_slowtoggle, args[1] ); }
  577. static ConCommand startslowtime( "+slowtime", IN_SlowTimeDown );
  578. static ConCommand endslowtime( "-slowtime", IN_SlowTimeUp );
  579. #endif // USE_SLOWTIME
  580. kbutton_t in_remote_view_toggle;
  581. static bool g_bRemoteViewKeyWasUp = true;
  582. void IN_RemoteViewUp( const CCommand &args )
  583. {
  584. g_bRemoteViewKeyWasUp = true;
  585. KeyUp( &in_remote_view_toggle, args[1] );
  586. }
  587. void IN_RemoteViewDown( const CCommand &args )
  588. {
  589. if ( g_bRemoteViewKeyWasUp )
  590. {
  591. g_bRemoteViewKeyWasUp = false;
  592. IGameEvent * event = gameeventmanager->CreateEvent( "remote_view_activated" );
  593. if ( event )
  594. {
  595. gameeventmanager->FireEvent( event );
  596. }
  597. }
  598. KeyDown( &in_remote_view_toggle, args[1] );
  599. }
  600. static ConCommand startremoteview( "+remote_view", IN_RemoteViewDown );
  601. static ConCommand endremoteview( "-remote_view", IN_RemoteViewUp );
  602. extern bool g_bShowGhostedPortals;
  603. void IN_ShowPortalsUp( const CCommand &args ) { g_bShowGhostedPortals = false; }
  604. void IN_ShowPortalsDown( const CCommand &args ) { g_bShowGhostedPortals = true; }
  605. static ConCommand showportals( "+showportals", IN_ShowPortalsDown );
  606. static ConCommand hideportals( "-showportals", IN_ShowPortalsUp );
  607. kbutton_t in_coop_ping;
  608. void IN_CoopPingUp( const CCommand &args) { KeyUp( &in_coop_ping, args[1] ); }
  609. void IN_CoopPingDown( const CCommand &args) { KeyDown( &in_coop_ping, args[1] ); }
  610. static ConCommand presscoopping( "+coop_ping", IN_CoopPingDown );
  611. static ConCommand unpresscoopping( "-coop_ping", IN_CoopPingUp );
  612. #endif // PORTAL2
  613. #ifdef INFESTED_DLL
  614. void IN_PrevAbilityUp( const CCommand &args ) { KeyUp( &in_prevability, args[1] ); }
  615. void IN_PrevAbilityDown( const CCommand &args ) { KeyDown( &in_prevability, args[1] ); }
  616. void IN_NextAbilityUp( const CCommand &args ) { KeyUp( &in_nextability, args[1] ); }
  617. void IN_NextAbilityDown( const CCommand &args ) { KeyDown( &in_nextability, args[1] ); }
  618. void IN_CurrentAbilityUp( const CCommand &args ) { KeyUp( &in_currentability, args[1] ); }
  619. void IN_CurrentAbilityDown( const CCommand &args ) { KeyDown( &in_currentability, args[1] ); }
  620. void IN_Ability1Up( const CCommand &args ) { KeyUp( &in_ability1, args[1] ); }
  621. void IN_Ability1Down( const CCommand &args ) { KeyDown( &in_ability1, args[1] ); }
  622. void IN_Ability2Up( const CCommand &args ) { KeyUp( &in_ability2, args[1] ); }
  623. void IN_Ability2Down( const CCommand &args ) { KeyDown( &in_ability2, args[1] ); }
  624. void IN_Ability3Up( const CCommand &args ) { KeyUp( &in_ability3, args[1] ); }
  625. void IN_Ability3Down( const CCommand &args ) { KeyDown( &in_ability3, args[1] ); }
  626. void IN_Ability4Up( const CCommand &args ) { KeyUp( &in_ability4, args[1] ); }
  627. void IN_Ability4Down( const CCommand &args ) { KeyDown( &in_ability4, args[1] ); }
  628. void IN_Ability5Up( const CCommand &args ) { KeyUp( &in_ability5, args[1] ); }
  629. void IN_Ability5Down( const CCommand &args ) { KeyDown( &in_ability5, args[1] ); }
  630. #endif
  631. void IN_AttackDown( const CCommand &args )
  632. {
  633. KeyDown( &in_attack, args[1] );
  634. }
  635. void IN_AttackUp( const CCommand &args )
  636. {
  637. KeyUp( &in_attack, args[1] );
  638. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  639. in_cancel[ GET_ACTIVE_SPLITSCREEN_SLOT() ] = 0;
  640. }
  641. // Special handling
  642. void IN_Cancel( const CCommand &args )
  643. {
  644. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  645. in_cancel[ GET_ACTIVE_SPLITSCREEN_SLOT() ] = 1;
  646. }
  647. void IN_Impulse( const CCommand &args )
  648. {
  649. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  650. in_impulse[ GET_ACTIVE_SPLITSCREEN_SLOT() ] = atoi( args[1] );
  651. }
  652. void IN_ScoreDown( const CCommand &args )
  653. {
  654. KeyDown( &in_score, args[1] );
  655. }
  656. void IN_ScoreUp( const CCommand &args )
  657. {
  658. KeyUp( &in_score, args[1] );
  659. }
  660. void IN_LookSpinDown( const CCommand &args ) {KeyDown( &in_lookspin, args[1] );}
  661. void IN_LookSpinUp( const CCommand &args ) {KeyUp( &in_lookspin, args[1] );}
  662. /*
  663. ============
  664. KeyEvent
  665. Return 1 to allow engine to process the key, otherwise, act on it as needed
  666. ============
  667. */
  668. int CInput::KeyEvent( int down, ButtonCode_t code, const char *pszCurrentBinding )
  669. {
  670. // Deal with camera intercepting the mouse
  671. if ( down &&
  672. ( ( code == MOUSE_LEFT ) || ( code == MOUSE_RIGHT ) || ( code == MOUSE_MIDDLE ) || ( code == MOUSE_WHEEL_UP ) || ( code == MOUSE_WHEEL_DOWN ) ) )
  673. {
  674. ConVarRef cl_mouseenable( "cl_mouseenable" );
  675. if ( GetPerUser().m_fCameraInterceptingMouse || !cl_mouseenable.GetBool() )
  676. return 0;
  677. }
  678. if ( GetClientMode() )
  679. return GetClientMode()->KeyInput(down, code, pszCurrentBinding);
  680. return 1;
  681. }
  682. /*
  683. ===============
  684. KeyState
  685. Returns 0.25 if a key was pressed and released during the frame,
  686. 0.5 if it was pressed and held
  687. 0 if held then released, and
  688. 1.0 if held for the entire time
  689. ===============
  690. */
  691. float CInput::KeyState ( kbutton_t *key )
  692. {
  693. kbutton_t::Split_t &data = key->GetPerUser();
  694. float val = 0.0;
  695. int impulsedown, impulseup, down;
  696. impulsedown = data.state & 2;
  697. impulseup = data.state & 4;
  698. down = data.state & 1;
  699. if ( impulsedown && !impulseup )
  700. {
  701. // pressed and held this frame?
  702. val = down ? 0.5 : 0.0;
  703. }
  704. if ( impulseup && !impulsedown )
  705. {
  706. // released this frame?
  707. val = down ? 0.0 : 0.0;
  708. }
  709. if ( !impulsedown && !impulseup )
  710. {
  711. // held the entire frame?
  712. val = down ? 1.0 : 0.0;
  713. }
  714. if ( impulsedown && impulseup )
  715. {
  716. if ( down )
  717. {
  718. // released and re-pressed this frame
  719. val = 0.75;
  720. }
  721. else
  722. {
  723. // pressed and released this frame
  724. val = 0.25;
  725. }
  726. }
  727. // clear impulses
  728. data.state &= 1;
  729. return val;
  730. }
  731. void CInput::IN_SetSampleTime( float frametime )
  732. {
  733. FOR_EACH_VALID_SPLITSCREEN_PLAYER( i )
  734. {
  735. m_PerUser[ i ].m_flKeyboardSampleTime = frametime;
  736. }
  737. }
  738. /*
  739. ==============================
  740. DetermineKeySpeed
  741. ==============================
  742. */
  743. static ConVar in_usekeyboardsampletime( "in_usekeyboardsampletime", "1", 0, "Use keyboard sample time smoothing." );
  744. float CInput::DetermineKeySpeed( int nSlot, float frametime )
  745. {
  746. if ( in_usekeyboardsampletime.GetBool() )
  747. {
  748. PerUserInput_t &user = GetPerUser( nSlot );
  749. if ( user.m_flKeyboardSampleTime <= 0 )
  750. return 0.0f;
  751. frametime = MIN( user.m_flKeyboardSampleTime, frametime );
  752. user.m_flKeyboardSampleTime -= frametime;
  753. }
  754. float speed;
  755. speed = frametime;
  756. if ( in_speed.GetPerUser( nSlot ).state & 1 )
  757. {
  758. speed *= cl_anglespeedkey.GetFloat();
  759. }
  760. return speed;
  761. }
  762. /*
  763. ==============================
  764. AdjustYaw
  765. ==============================
  766. */
  767. void CInput::AdjustYaw( int nSlot, float speed, QAngle& viewangles )
  768. {
  769. if ( !(in_strafe.GetPerUser( nSlot ).state & 1) )
  770. {
  771. viewangles[YAW] -= speed*cl_yawspeed.GetFloat() * KeyState (&in_right);
  772. viewangles[YAW] += speed*cl_yawspeed.GetFloat() * KeyState (&in_left);
  773. }
  774. const PerUserInput_t &user = GetPerUser( nSlot );
  775. // thirdperson platformer mode
  776. // use movement keys to aim the player relative to the thirdperson camera
  777. if ( CAM_IsThirdPerson() && thirdperson_platformer.GetInt() )
  778. {
  779. float side = KeyState(&in_moveleft) - KeyState(&in_moveright);
  780. float forward = KeyState(&in_forward) - KeyState(&in_back);
  781. if ( side || forward )
  782. {
  783. viewangles[YAW] = RAD2DEG(atan2(side, forward)) + user.m_vecCameraOffset[ YAW ];
  784. }
  785. if ( side || forward || KeyState (&in_right) || KeyState (&in_left) )
  786. {
  787. cam_idealyaw.SetValue( user.m_vecCameraOffset[ YAW ] - viewangles[ YAW ] );
  788. }
  789. }
  790. }
  791. /*
  792. ==============================
  793. AdjustPitch
  794. ==============================
  795. */
  796. void CInput::AdjustPitch( int nSlot, float speed, QAngle& viewangles )
  797. {
  798. // only allow keyboard looking if mouse look is disabled
  799. if ( !UsingMouselook( nSlot ) )
  800. {
  801. float up, down;
  802. if ( in_klook.GetPerUser( nSlot ).state & 1 )
  803. {
  804. view->StopPitchDrift ();
  805. viewangles[PITCH] -= speed*cl_pitchspeed.GetFloat() * KeyState (&in_forward);
  806. viewangles[PITCH] += speed*cl_pitchspeed.GetFloat() * KeyState (&in_back);
  807. }
  808. up = KeyState ( &in_lookup );
  809. down = KeyState ( &in_lookdown );
  810. viewangles[PITCH] -= speed*cl_pitchspeed.GetFloat() * up;
  811. viewangles[PITCH] += speed*cl_pitchspeed.GetFloat() * down;
  812. if ( up || down )
  813. {
  814. view->StopPitchDrift ();
  815. }
  816. }
  817. }
  818. /*
  819. ==============================
  820. ClampAngles
  821. ==============================
  822. */
  823. void CInput::ClampAngles( QAngle& viewangles )
  824. {
  825. if ( viewangles[PITCH] > cl_pitchdown.GetFloat() )
  826. {
  827. viewangles[PITCH] = cl_pitchdown.GetFloat();
  828. }
  829. if ( viewangles[PITCH] < -cl_pitchup.GetFloat() )
  830. {
  831. viewangles[PITCH] = -cl_pitchup.GetFloat();
  832. }
  833. // Don't constrain Roll in Portal because the player can be upside down! -Jeep
  834. #if !defined( PORTAL )
  835. if ( viewangles[ROLL] > 50 )
  836. {
  837. viewangles[ROLL] = 50;
  838. }
  839. if ( viewangles[ROLL] < -50 )
  840. {
  841. viewangles[ROLL] = -50;
  842. }
  843. #endif
  844. }
  845. /*
  846. ================
  847. AdjustAngles
  848. Moves the local angle positions
  849. ================
  850. */
  851. void CInput::AdjustAngles ( int nSlot, float frametime )
  852. {
  853. float speed;
  854. QAngle viewangles;
  855. // Determine control scaling factor ( multiplies time )
  856. speed = DetermineKeySpeed( nSlot, frametime );
  857. if ( speed <= 0.0f )
  858. {
  859. return;
  860. }
  861. // Retrieve latest view direction from engine
  862. engine->GetViewAngles( viewangles );
  863. // Undo tilting from previous frame
  864. viewangles -= GetPerUser().m_angPreviousViewAnglesTilt;
  865. // Apply tilting effects here (it affects aim)
  866. QAngle vecAnglesBeforeTilt = viewangles;
  867. GetViewEffects()->CalcTilt();
  868. GetViewEffects()->ApplyTilt( viewangles, 1.0f );
  869. // Remember the tilt delta so we can undo it before applying tilt next frame
  870. GetPerUser().m_angPreviousViewAnglesTilt = viewangles - vecAnglesBeforeTilt;
  871. // Adjust YAW
  872. AdjustYaw( nSlot, speed, viewangles );
  873. // Adjust PITCH if keyboard looking
  874. AdjustPitch( nSlot, speed, viewangles );
  875. // Make sure values are legitimate
  876. ClampAngles( viewangles );
  877. // Store new view angles into engine view direction
  878. engine->SetViewAngles( viewangles );
  879. }
  880. /*
  881. ==============================
  882. ComputeSideMove
  883. ==============================
  884. */
  885. void CInput::ComputeSideMove( int nSlot, CUserCmd *cmd )
  886. {
  887. // thirdperson platformer movement
  888. if ( CAM_IsThirdPerson() && thirdperson_platformer.GetInt() )
  889. {
  890. // no sideways movement in this mode
  891. return;
  892. }
  893. // thirdperson screenspace movement
  894. if ( CAM_IsThirdPerson() && thirdperson_screenspace.GetInt() )
  895. {
  896. #ifdef INFESTED_DLL
  897. float ideal_yaw = asw_cam_marine_yaw.GetFloat() - 90.0f;
  898. #else
  899. float ideal_yaw = cam_idealyaw.GetFloat();
  900. #endif
  901. float ideal_sin = sin(DEG2RAD(ideal_yaw));
  902. float ideal_cos = cos(DEG2RAD(ideal_yaw));
  903. float movement = ideal_cos*KeyState(&in_moveright)
  904. + ideal_sin*KeyState(&in_back)
  905. + -ideal_cos*KeyState(&in_moveleft)
  906. + -ideal_sin*KeyState(&in_forward);
  907. cmd->sidemove += cl_sidespeed.GetFloat() * movement;
  908. return;
  909. }
  910. // If strafing, check left and right keys and act like moveleft and moveright keys
  911. if ( in_strafe.GetPerUser( nSlot ).state & 1 )
  912. {
  913. cmd->sidemove += cl_sidespeed.GetFloat() * KeyState (&in_right);
  914. cmd->sidemove -= cl_sidespeed.GetFloat() * KeyState (&in_left);
  915. }
  916. // Otherwise, check strafe keys
  917. cmd->sidemove += cl_sidespeed.GetFloat() * KeyState (&in_moveright);
  918. cmd->sidemove -= cl_sidespeed.GetFloat() * KeyState (&in_moveleft);
  919. }
  920. /*
  921. ==============================
  922. ComputeUpwardMove
  923. ==============================
  924. */
  925. void CInput::ComputeUpwardMove( int nSlot, CUserCmd *cmd )
  926. {
  927. cmd->upmove += cl_upspeed.GetFloat() * KeyState (&in_up);
  928. cmd->upmove -= cl_upspeed.GetFloat() * KeyState (&in_down);
  929. }
  930. /*
  931. ==============================
  932. ComputeForwardMove
  933. ==============================
  934. */
  935. void CInput::ComputeForwardMove( int nSlot, CUserCmd *cmd )
  936. {
  937. // thirdperson platformer movement
  938. if ( CAM_IsThirdPerson() && thirdperson_platformer.GetInt() )
  939. {
  940. // movement is always forward in this mode
  941. float movement = KeyState(&in_forward)
  942. || KeyState(&in_moveright)
  943. || KeyState(&in_back)
  944. || KeyState(&in_moveleft);
  945. cmd->forwardmove += cl_forwardspeed.GetFloat() * movement;
  946. return;
  947. }
  948. // thirdperson screenspace movement
  949. if ( CAM_IsThirdPerson() && thirdperson_screenspace.GetInt() )
  950. {
  951. #ifdef INFESTED_DLL
  952. float ideal_yaw = asw_cam_marine_yaw.GetFloat() - 90.0f;
  953. #else
  954. float ideal_yaw = cam_idealyaw.GetFloat();
  955. #endif
  956. float ideal_sin = sin(DEG2RAD(ideal_yaw));
  957. float ideal_cos = cos(DEG2RAD(ideal_yaw));
  958. float movement = ideal_cos*KeyState(&in_forward)
  959. + ideal_sin*KeyState(&in_moveright)
  960. + -ideal_cos*KeyState(&in_back)
  961. + -ideal_sin*KeyState(&in_moveleft);
  962. cmd->forwardmove += cl_forwardspeed.GetFloat() * movement;
  963. return;
  964. }
  965. if ( !(in_klook.GetPerUser( nSlot ).state & 1 ) )
  966. {
  967. cmd->forwardmove += cl_forwardspeed.GetFloat() * KeyState (&in_forward);
  968. cmd->forwardmove -= cl_backspeed.GetFloat() * KeyState (&in_back);
  969. }
  970. }
  971. /*
  972. ==============================
  973. ScaleMovements
  974. ==============================
  975. */
  976. void CInput::ScaleMovements( CUserCmd *cmd )
  977. {
  978. // float spd;
  979. // clip to maxspeed
  980. // FIXME FIXME: This doesn't work
  981. return;
  982. /*
  983. spd = engine->GetClientMaxspeed();
  984. if ( spd == 0.0 )
  985. return;
  986. // Scale the speed so that the total velocity is not > spd
  987. float fmov = sqrt( (cmd->forwardmove*cmd->forwardmove) + (cmd->sidemove*cmd->sidemove) + (cmd->upmove*cmd->upmove) );
  988. if ( fmov > spd && fmov > 0.0 )
  989. {
  990. float fratio = spd / fmov;
  991. if ( !IsNoClipping() )
  992. {
  993. cmd->forwardmove *= fratio;
  994. cmd->sidemove *= fratio;
  995. cmd->upmove *= fratio;
  996. }
  997. }
  998. */
  999. }
  1000. /*
  1001. ===========
  1002. ControllerMove
  1003. ===========
  1004. */
  1005. void CInput::ControllerMove( int nSlot, float frametime, CUserCmd *cmd )
  1006. {
  1007. ConVarRef cl_mouseenable( "cl_mouseenable" );
  1008. if ( (IsPC() || IsPlatformPS3()) &&
  1009. cl_mouseenable.GetBool() &&
  1010. nSlot == in_forceuser.GetInt() &&
  1011. g_pInputSystem->IsDeviceReadingInput( INPUT_DEVICE_KEYBOARD_MOUSE ) )
  1012. {
  1013. if ( !GetPerUser( nSlot ).m_fCameraInterceptingMouse && m_fMouseActive )
  1014. {
  1015. MouseMove( nSlot, cmd );
  1016. }
  1017. }
  1018. JoyStickMove( frametime, cmd);
  1019. SteamControllerMove( frametime, cmd );
  1020. }
  1021. //-----------------------------------------------------------------------------
  1022. // Purpose:
  1023. // Input : *weapon -
  1024. //-----------------------------------------------------------------------------
  1025. void CInput::MakeWeaponSelection( C_BaseCombatWeapon *weapon )
  1026. {
  1027. GetPerUser().m_hSelectedWeapon = weapon;
  1028. }
  1029. CInput::PerUserInput_t &CInput::GetPerUser( int nSlot /*=-1*/ )
  1030. {
  1031. if ( nSlot == -1 )
  1032. {
  1033. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  1034. return m_PerUser[ GET_ACTIVE_SPLITSCREEN_SLOT() ];
  1035. }
  1036. return m_PerUser[ nSlot ];
  1037. }
  1038. const CInput::PerUserInput_t &CInput::GetPerUser( int nSlot /*=-1*/ ) const
  1039. {
  1040. if ( nSlot == -1 )
  1041. {
  1042. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  1043. return m_PerUser[ GET_ACTIVE_SPLITSCREEN_SLOT() ];
  1044. }
  1045. return m_PerUser[ nSlot ];
  1046. }
  1047. void CInput::ExtraMouseSample( float frametime, bool active )
  1048. {
  1049. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  1050. int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
  1051. static CUserCmd dummy[ MAX_SPLITSCREEN_PLAYERS ];
  1052. CUserCmd *cmd = &dummy[ nSlot ];
  1053. cmd->Reset();
  1054. QAngle viewangles;
  1055. if ( active )
  1056. {
  1057. // Determine view angles
  1058. AdjustAngles ( nSlot, frametime );
  1059. // Determine sideways movement
  1060. if ( g_pInputSystem->IsDeviceReadingInput( INPUT_DEVICE_KEYBOARD_MOUSE ) )
  1061. ComputeSideMove( nSlot, cmd );
  1062. // Determine vertical movement
  1063. ComputeUpwardMove( nSlot, cmd );
  1064. // Determine forward movement
  1065. if ( g_pInputSystem->IsDeviceReadingInput( INPUT_DEVICE_KEYBOARD_MOUSE ) )
  1066. ComputeForwardMove( nSlot, cmd );
  1067. // Scale based on holding speed key or having too fast of a velocity based on client maximum speed.
  1068. ScaleMovements( cmd );
  1069. // Allow mice and other controllers to add their inputs
  1070. ControllerMove( nSlot, frametime, cmd );
  1071. #ifdef SIXENSE
  1072. if ( nSlot == in_forceuser.GetInt() )
  1073. {
  1074. g_pSixenseInput->SixenseFrame( frametime, cmd );
  1075. if( g_pSixenseInput->IsEnabled() )
  1076. {
  1077. g_pSixenseInput->SetView( frametime, cmd );
  1078. }
  1079. }
  1080. #endif
  1081. }
  1082. // Retrieve view angles from engine ( could have been set in AdjustAngles above )
  1083. engine->GetViewAngles( viewangles );
  1084. if ( round_start_reset_duck.GetBool( ) == true )
  1085. {
  1086. IN_ClearDuckToggle( );
  1087. round_start_reset_duck.SetValue( false );
  1088. }
  1089. if ( round_start_reset_speed.GetBool( ) == true )
  1090. {
  1091. IN_ClearSpeedToggle( );
  1092. joystick_forced_speed = false;
  1093. round_start_reset_speed.SetValue( false );
  1094. } // Set button and flag bits, don't blow away state
  1095. #ifdef SIXENSE
  1096. if( g_pSixenseInput->IsEnabled() )
  1097. {
  1098. // Some buttons were set in SixenseUpdateKeys, so or in any real keypresses
  1099. cmd->buttons |= GetButtonBits( false );
  1100. }
  1101. else
  1102. {
  1103. cmd->buttons = GetButtonBits( false );
  1104. }
  1105. #else
  1106. cmd->buttons = GetButtonBits( false );
  1107. #endif
  1108. // Use new view angles if alive, otherwise user last angles we stored off.
  1109. VectorCopy( viewangles, cmd->viewangles );
  1110. VectorCopy( viewangles, GetPerUser().m_angPreviousViewAngles );
  1111. // Let the move manager override anything it wants to.
  1112. if ( GetClientMode()->CreateMove( frametime, cmd ) )
  1113. {
  1114. // Get current view angles after the client mode tweaks with it
  1115. engine->SetViewAngles( cmd->viewangles );
  1116. prediction->SetLocalViewAngles( cmd->viewangles );
  1117. }
  1118. CheckPaused( cmd );
  1119. CheckSplitScreenMimic( nSlot, cmd, &dummy[ 0 ] );
  1120. }
  1121. /*
  1122. ================
  1123. CreateMove
  1124. Send the intended movement message to the server
  1125. if active == 1 then we are 1) not playing back demos ( where our commands are ignored ) and
  1126. 2 ) we have finished signing on to server
  1127. ================
  1128. */
  1129. void CInput::CreateMove ( int sequence_number, float input_sample_frametime, bool active )
  1130. {
  1131. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  1132. int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
  1133. CUserCmd *cmd = &GetPerUser( nSlot ).m_pCommands[ sequence_number % MULTIPLAYER_BACKUP];
  1134. CVerifiedUserCmd *pVerified = &GetPerUser( nSlot ).m_pVerifiedCommands[ sequence_number % MULTIPLAYER_BACKUP];
  1135. cmd->Reset();
  1136. cmd->command_number = sequence_number;
  1137. cmd->tick_count = gpGlobals->tickcount;
  1138. QAngle viewangles;
  1139. if ( active || sv_noclipduringpause.GetInt() )
  1140. {
  1141. if ( nSlot == in_forceuser.GetInt() )
  1142. {
  1143. // Determine view angles
  1144. AdjustAngles ( nSlot, input_sample_frametime );
  1145. // Determine sideways movement
  1146. if ( g_pInputSystem->IsDeviceReadingInput( INPUT_DEVICE_KEYBOARD_MOUSE ) )
  1147. ComputeSideMove( nSlot, cmd );
  1148. // Determine vertical movement
  1149. ComputeUpwardMove( nSlot, cmd );
  1150. // Determine forward movement
  1151. if ( g_pInputSystem->IsDeviceReadingInput( INPUT_DEVICE_KEYBOARD_MOUSE ) )
  1152. ComputeForwardMove( nSlot, cmd );
  1153. // Scale based on holding speed key or having too fast of a velocity based on client maximum
  1154. // speed.
  1155. ScaleMovements( cmd );
  1156. }
  1157. // Allow mice and other controllers to add their inputs
  1158. ControllerMove( nSlot, input_sample_frametime, cmd );
  1159. #ifdef SIXENSE
  1160. if ( nSlot == in_forceuser.GetInt() )
  1161. {
  1162. g_pSixenseInput->SixenseFrame( input_sample_frametime, cmd );
  1163. if( g_pSixenseInput->IsEnabled() )
  1164. {
  1165. g_pSixenseInput->SetView( input_sample_frametime, cmd );
  1166. }
  1167. }
  1168. #endif
  1169. }
  1170. else
  1171. {
  1172. // need to run and reset mouse input so that there is no view pop when unpausing
  1173. if ( !GetPerUser( nSlot ).m_fCameraInterceptingMouse && m_fMouseActive )
  1174. {
  1175. float mx, my;
  1176. GetAccumulatedMouseDeltasAndResetAccumulators( nSlot, &mx, &my );
  1177. ResetMouse();
  1178. }
  1179. }
  1180. // Retreive view angles from engine ( could have been set in IN_AdjustAngles above )
  1181. engine->GetViewAngles( viewangles );
  1182. cmd->impulse = in_impulse[ nSlot ];
  1183. in_impulse[ nSlot ] = 0;
  1184. // Latch and clear weapon selection
  1185. if ( GetPerUser( nSlot ).m_hSelectedWeapon != NULL )
  1186. {
  1187. C_BaseCombatWeapon *weapon = GetPerUser( nSlot ).m_hSelectedWeapon;
  1188. cmd->weaponselect = weapon->entindex();
  1189. cmd->weaponsubtype = weapon->GetSubType();
  1190. // Always clear weapon selection
  1191. GetPerUser( nSlot ).m_hSelectedWeapon = NULL;
  1192. }
  1193. #ifdef SIXENSE
  1194. if( g_pSixenseInput->IsEnabled() )
  1195. {
  1196. // Some buttons were set in SixenseUpdateKeys, so or in any real keypresses
  1197. cmd->buttons |= GetButtonBits( true );
  1198. }
  1199. else
  1200. {
  1201. cmd->buttons = GetButtonBits( true );
  1202. }
  1203. #else
  1204. // Set button and flag bits
  1205. cmd->buttons = GetButtonBits( true );
  1206. #endif
  1207. // Using joystick?
  1208. #ifdef SIXENSE
  1209. if ( g_pInputSystem->IsDeviceReadingInput( INPUT_DEVICE_GAMEPAD ) && ( in_joystick.GetInt() || g_pSixenseInput->IsEnabled() ) )
  1210. #else
  1211. if ( ( g_pInputSystem->IsDeviceReadingInput( INPUT_DEVICE_GAMEPAD ) && in_joystick.GetInt() ) || g_pInputSystem->MotionControllerActive() || g_pInputSystem->IsSteamControllerActive() )
  1212. #endif
  1213. {
  1214. if ( cmd->forwardmove > 0 )
  1215. {
  1216. cmd->buttons |= IN_FORWARD;
  1217. }
  1218. else if ( cmd->forwardmove < 0 )
  1219. {
  1220. cmd->buttons |= IN_BACK;
  1221. }
  1222. }
  1223. // Use new view angles if alive, otherwise user last angles we stored off.
  1224. VectorCopy( viewangles, cmd->viewangles );
  1225. VectorCopy( viewangles, GetPerUser( nSlot ).m_angPreviousViewAngles );
  1226. // Let the move manager override anything it wants to.
  1227. if ( GetClientMode()->CreateMove( input_sample_frametime, cmd ) )
  1228. {
  1229. // Get current view angles after the client mode tweaks with it
  1230. #ifdef SIXENSE
  1231. // Only set the engine angles if sixense is not enabled. It is done in SixenseInput::SetView otherwise.
  1232. if( !g_pSixenseInput->IsEnabled() )
  1233. {
  1234. engine->SetViewAngles( cmd->viewangles );
  1235. }
  1236. #else
  1237. engine->SetViewAngles( cmd->viewangles );
  1238. #endif
  1239. }
  1240. CheckPaused( cmd );
  1241. CUserCmd *pPlayer0Command = &m_PerUser[ 0 ].m_pCommands[ sequence_number % MULTIPLAYER_BACKUP ];
  1242. CheckSplitScreenMimic( nSlot, cmd, pPlayer0Command );
  1243. GetPerUser( nSlot ).m_flLastForwardMove = cmd->forwardmove;
  1244. cmd->random_seed = MD5_PseudoRandom( sequence_number ) & 0x7fffffff;
  1245. HLTVCamera()->CreateMove( cmd );
  1246. #if defined( REPLAY_ENABLED )
  1247. ReplayCamera()->CreateMove( cmd );
  1248. #endif
  1249. #if defined( HL2_CLIENT_DLL )
  1250. // copy backchannel data
  1251. int i;
  1252. for (i = 0; i < GetPerUser( nSlot ).m_EntityGroundContact.Count(); i++)
  1253. {
  1254. cmd->entitygroundcontact.AddToTail( GetPerUser().m_EntityGroundContact[i] );
  1255. }
  1256. GetPerUser( nSlot ).m_EntityGroundContact.RemoveAll();
  1257. #endif
  1258. pVerified->m_cmd = *cmd;
  1259. pVerified->m_crc = cmd->GetChecksum();
  1260. }
  1261. void CInput::CheckSplitScreenMimic( int nSlot, CUserCmd *cmd, CUserCmd *pPlayer0Command )
  1262. {
  1263. // ss_mimic 2 is more of a "follow" mode
  1264. int nMimicMode = ss_mimic.GetInt();
  1265. if ( nMimicMode <= 0 || nSlot == 0 )
  1266. return;
  1267. *cmd = *pPlayer0Command;
  1268. // We can't copy these over, since we send the weapon index it'll make the server attach the weapon to the other split screen player, even
  1269. // though he doesn't own it!!!
  1270. cmd->weaponsubtype = 0;
  1271. cmd->weaponselect = 0;
  1272. // Get current view angles after the client mode tweaks with it
  1273. engine->SetViewAngles( cmd->viewangles );
  1274. int nLeader = ( nSlot + 1 ) % MAX_SPLITSCREEN_PLAYERS;
  1275. C_BasePlayer *pLeader = C_BasePlayer::GetLocalPlayer( nLeader );
  1276. C_BasePlayer *pFollower = C_BasePlayer::GetLocalPlayer( nSlot );
  1277. if ( !pLeader || !pFollower )
  1278. return;
  1279. Vector leaderPos = pLeader->GetAbsOrigin();
  1280. Vector followerPos = pFollower->GetAbsOrigin();
  1281. float flFarDist = 256.0f * 256.0f;
  1282. float flNearDist = 64.0f * 64.0f;
  1283. Vector delta = leaderPos - followerPos;
  1284. float flLength2DSqr = delta.Length2DSqr();
  1285. if ( flLength2DSqr > flFarDist )
  1286. {
  1287. SplitScreenTeleport( nLeader );
  1288. }
  1289. else if ( flLength2DSqr > flNearDist )
  1290. {
  1291. // Run toward other guy
  1292. cmd->buttons &= ~( IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT );
  1293. Vector lookDir;
  1294. Vector rightDir;
  1295. AngleVectors( cmd->viewangles, &lookDir, &rightDir, NULL );
  1296. lookDir.z = 0.0f;
  1297. lookDir.NormalizeInPlace();
  1298. Vector moveDir = delta;
  1299. moveDir.z = 0.0f;
  1300. moveDir.NormalizeInPlace();
  1301. // This is the cos of the angle between them
  1302. float fdot = lookDir.Dot( moveDir );
  1303. float rdot = rightDir.Dot( moveDir );
  1304. cmd->forwardmove = fdot * cl_forwardspeed.GetFloat();
  1305. cmd->sidemove = rdot * cl_sidespeed.GetFloat();
  1306. // We'll only be moving fwd or sideways
  1307. cmd->upmove = 0.0f;
  1308. if ( cmd->forwardmove > 0.0f )
  1309. {
  1310. cmd->buttons |= IN_FORWARD;
  1311. }
  1312. else if ( cmd->forwardmove < 0.0f )
  1313. {
  1314. cmd->buttons |= IN_BACK;
  1315. }
  1316. if ( cmd->sidemove > 0.0f )
  1317. {
  1318. cmd->buttons |= IN_MOVELEFT;
  1319. }
  1320. else if ( cmd->sidemove < 0.0f )
  1321. {
  1322. cmd->buttons |= IN_MOVERIGHT;
  1323. }
  1324. }
  1325. else
  1326. {
  1327. // Stop movement buttons
  1328. cmd->forwardmove = cmd->sidemove = cmd->upmove = 0.0f;
  1329. cmd->buttons &= ~( IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT );
  1330. }
  1331. }
  1332. void CInput::CheckPaused( CUserCmd *cmd )
  1333. {
  1334. if ( !engine->IsPaused() )
  1335. return;
  1336. cmd->buttons = 0;
  1337. cmd->forwardmove = 0;
  1338. cmd->sidemove = 0;
  1339. cmd->upmove = 0;
  1340. // Don't allow changing weapons while paused
  1341. cmd->weaponselect = 0;
  1342. }
  1343. //-----------------------------------------------------------------------------
  1344. // Purpose:
  1345. // Input : buf -
  1346. // buffersize -
  1347. // slot -
  1348. //-----------------------------------------------------------------------------
  1349. void CInput::EncodeUserCmdToBuffer( int nSlot, bf_write& buf, int sequence_number )
  1350. {
  1351. CUserCmd nullcmd;
  1352. CUserCmd *cmd = GetUserCmd( nSlot, sequence_number);
  1353. WriteUsercmd( &buf, cmd, &nullcmd );
  1354. }
  1355. //-----------------------------------------------------------------------------
  1356. // Purpose:
  1357. // Input : buf -
  1358. // buffersize -
  1359. // slot -
  1360. //-----------------------------------------------------------------------------
  1361. void CInput::DecodeUserCmdFromBuffer( int nSlot, bf_read& buf, int sequence_number )
  1362. {
  1363. CUserCmd nullcmd;
  1364. CUserCmd *cmd = &GetPerUser( nSlot ).m_pCommands[ sequence_number % MULTIPLAYER_BACKUP ];
  1365. ReadUsercmd( &buf, cmd, &nullcmd );
  1366. }
  1367. void CInput::ValidateUserCmd( CUserCmd *usercmd, int sequence_number )
  1368. {
  1369. // Validate that the usercmd hasn't been changed
  1370. CRC32_t crc = usercmd->GetChecksum();
  1371. if ( crc != GetPerUser().m_pVerifiedCommands[ sequence_number % MULTIPLAYER_BACKUP ].m_crc )
  1372. {
  1373. *usercmd = GetPerUser().m_pVerifiedCommands[ sequence_number % MULTIPLAYER_BACKUP ].m_cmd;
  1374. }
  1375. }
  1376. //-----------------------------------------------------------------------------
  1377. // Purpose:
  1378. // Input : *buf -
  1379. // from -
  1380. // to -
  1381. //-----------------------------------------------------------------------------
  1382. bool CInput::WriteUsercmdDeltaToBuffer( int nSlot, bf_write *buf, int from, int to, bool isnewcommand )
  1383. {
  1384. Assert( GetPerUser( nSlot ).m_pCommands );
  1385. CUserCmd nullcmd;
  1386. CUserCmd *f, *t;
  1387. int startbit;
  1388. startbit = buf->GetNumBitsWritten();
  1389. if ( from == -1 )
  1390. {
  1391. f = &nullcmd;
  1392. }
  1393. else
  1394. {
  1395. f = GetUserCmd( nSlot, from );
  1396. if ( !f )
  1397. {
  1398. // DevMsg( "WARNING! User command delta too old (from %i, to %i)\n", from, to );
  1399. f = &nullcmd;
  1400. }
  1401. else
  1402. {
  1403. ValidateUserCmd( f, from );
  1404. }
  1405. }
  1406. t = GetUserCmd( nSlot, to );
  1407. if ( !t )
  1408. {
  1409. // DevMsg( "WARNING! User command too old (from %i, to %i)\n", from, to );
  1410. t = &nullcmd;
  1411. }
  1412. else
  1413. {
  1414. ValidateUserCmd( t, to );
  1415. }
  1416. // Write it into the buffer
  1417. WriteUsercmd( buf, t, f );
  1418. if ( buf->IsOverflowed() )
  1419. {
  1420. int endbit;
  1421. endbit = buf->GetNumBitsWritten();
  1422. Msg( "WARNING! User command buffer overflow(%i %i), last cmd was %i bits long\n",
  1423. from, to, endbit - startbit );
  1424. return false;
  1425. }
  1426. return true;
  1427. }
  1428. //-----------------------------------------------------------------------------
  1429. // Purpose:
  1430. // Input : slot -
  1431. // Output : CUserCmd
  1432. //-----------------------------------------------------------------------------
  1433. CUserCmd *CInput::GetUserCmd( int nSlot, int sequence_number )
  1434. {
  1435. Assert( GetPerUser( nSlot ).m_pCommands );
  1436. CUserCmd *usercmd = &GetPerUser( nSlot ).m_pCommands[ sequence_number % MULTIPLAYER_BACKUP ];
  1437. if ( usercmd->command_number != sequence_number )
  1438. {
  1439. return NULL; // usercmd was overwritten by newer command
  1440. }
  1441. return usercmd;
  1442. }
  1443. //-----------------------------------------------------------------------------
  1444. // Purpose:
  1445. // Input : bits -
  1446. // in_button -
  1447. // in_ignore -
  1448. // *button -
  1449. // reset -
  1450. // Output : static void
  1451. //-----------------------------------------------------------------------------
  1452. static void CalcButtonBits( int nSlot, int& bits, int in_button, int in_ignore, kbutton_t *button, bool reset )
  1453. {
  1454. kbutton_t::Split_t *pButtonState = &button->GetPerUser( nSlot );
  1455. // Down or still down?
  1456. if ( pButtonState->state & 3 )
  1457. {
  1458. bits |= in_button;
  1459. }
  1460. int clearmask = ~2;
  1461. if ( in_ignore & in_button )
  1462. {
  1463. // This gets taken care of below in the GetButtonBits code
  1464. //bits &= ~in_button;
  1465. // Remove "still down" as well as "just down"
  1466. clearmask = ~3;
  1467. }
  1468. if ( reset )
  1469. {
  1470. pButtonState->state &= clearmask;
  1471. }
  1472. }
  1473. /*
  1474. ============
  1475. GetButtonBits
  1476. Returns appropriate button info for keyboard and mouse state
  1477. Set bResetState to 1 to clear old state info
  1478. ============
  1479. */
  1480. int CInput::GetButtonBits( bool bResetState )
  1481. {
  1482. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  1483. int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
  1484. int bits = 0;
  1485. int ignore = GetPerUser( nSlot ).m_nClearInputState;
  1486. CalcButtonBits( nSlot, bits, IN_SPEED, ignore, &in_speed, bResetState );
  1487. CalcButtonBits( nSlot, bits, IN_WALK, ignore, &in_walk, bResetState );
  1488. CalcButtonBits( nSlot, bits, IN_ATTACK, ignore, &in_attack, bResetState );
  1489. CalcButtonBits( nSlot, bits, IN_DUCK, ignore, &in_duck, bResetState );
  1490. CalcButtonBits( nSlot, bits, IN_JUMP, ignore, &in_jump, bResetState );
  1491. CalcButtonBits( nSlot, bits, IN_FORWARD, ignore, &in_forward, bResetState );
  1492. CalcButtonBits( nSlot, bits, IN_BACK, ignore, &in_back, bResetState );
  1493. CalcButtonBits( nSlot, bits, IN_USE, ignore, &in_use, bResetState );
  1494. CalcButtonBits( nSlot, bits, IN_LEFT, ignore, &in_left, bResetState );
  1495. CalcButtonBits( nSlot, bits, IN_RIGHT, ignore, &in_right, bResetState );
  1496. CalcButtonBits( nSlot, bits, IN_MOVELEFT, ignore, &in_moveleft, bResetState );
  1497. CalcButtonBits( nSlot, bits, IN_MOVERIGHT, ignore, &in_moveright, bResetState );
  1498. CalcButtonBits( nSlot, bits, IN_ATTACK2, ignore, &in_attack2, bResetState );
  1499. CalcButtonBits( nSlot, bits, IN_RELOAD, ignore, &in_reload, bResetState );
  1500. CalcButtonBits( nSlot, bits, IN_ALT1, ignore, &in_alt1, bResetState );
  1501. CalcButtonBits( nSlot, bits, IN_ALT2, ignore, &in_alt2, bResetState );
  1502. CalcButtonBits( nSlot, bits, IN_SCORE, ignore, &in_score, bResetState );
  1503. CalcButtonBits( nSlot, bits, IN_ZOOM, ignore, &in_zoom, bResetState );
  1504. CalcButtonBits( nSlot, bits, IN_GRENADE1, ignore, &in_grenade1, bResetState );
  1505. CalcButtonBits( nSlot, bits, IN_GRENADE2, ignore, &in_grenade2, bResetState );
  1506. CalcButtonBits( nSlot, bits, IN_LOOKSPIN, ignore, &in_lookspin, bResetState );
  1507. #ifdef PORTAL2
  1508. #if USE_SLOWTIME
  1509. CalcButtonBits( nSlot, bits, IN_SLOWTIME, ignore, &in_slowtoggle, bResetState );
  1510. #endif // USE_SLOWTIME
  1511. CalcButtonBits( nSlot, bits, IN_COOP_PING, ignore, &in_coop_ping, bResetState );
  1512. CalcButtonBits( nSlot, bits, IN_REMOTE_VIEW, ignore, &in_remote_view_toggle, bResetState );
  1513. #endif // PORTAL2
  1514. #ifdef INFESTED_DLL
  1515. CalcButtonBits( nSlot, bits, IN_PREV_ABILITY, ignore, &in_prevability, bResetState );
  1516. CalcButtonBits( nSlot, bits, IN_NEXT_ABILITY, ignore, &in_nextability, bResetState );
  1517. CalcButtonBits( nSlot, bits, IN_CURRENT_ABILITY, ignore, &in_currentability, bResetState );
  1518. CalcButtonBits( nSlot, bits, IN_ABILITY1, ignore, &in_ability1, bResetState );
  1519. CalcButtonBits( nSlot, bits, IN_ABILITY2, ignore, &in_ability2, bResetState );
  1520. CalcButtonBits( nSlot, bits, IN_ABILITY3, ignore, &in_ability3, bResetState );
  1521. CalcButtonBits( nSlot, bits, IN_ABILITY4, ignore, &in_ability4, bResetState );
  1522. CalcButtonBits( nSlot, bits, IN_ABILITY5, ignore, &in_ability5, bResetState );
  1523. #endif
  1524. if ( KeyState(&in_ducktoggle) )
  1525. {
  1526. bits |= IN_DUCK;
  1527. }
  1528. // dkorus: handle the toggle OR the joystick feature to force a move speed when going slow
  1529. if ( KeyState(&in_speedtoggle) || joystick_forced_speed )
  1530. {
  1531. bits |= IN_SPEED;
  1532. }
  1533. if ( in_cancel[ nSlot ] )
  1534. {
  1535. bits |= IN_CANCEL;
  1536. }
  1537. if ( GetHud( nSlot ).m_iKeyBits & IN_WEAPON1 )
  1538. {
  1539. bits |= IN_WEAPON1;
  1540. }
  1541. if ( GetHud( nSlot ).m_iKeyBits & IN_WEAPON2 )
  1542. {
  1543. bits |= IN_WEAPON2;
  1544. }
  1545. // Clear out any residual
  1546. bits &= ~ignore;
  1547. if ( bResetState )
  1548. {
  1549. GetPerUser( nSlot ).m_nClearInputState = 0;
  1550. }
  1551. return bits;
  1552. }
  1553. //-----------------------------------------------------------------------------
  1554. // Causes an input to have to be re-pressed to become active
  1555. //-----------------------------------------------------------------------------
  1556. void CInput::ClearInputButton( int bits )
  1557. {
  1558. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  1559. if ( GET_ACTIVE_SPLITSCREEN_SLOT() != in_forceuser.GetInt() )
  1560. {
  1561. return;
  1562. }
  1563. GetPerUser().m_nClearInputState |= bits;
  1564. }
  1565. /*
  1566. ==============================
  1567. GetLookSpring
  1568. ==============================
  1569. */
  1570. float CInput::GetLookSpring( void )
  1571. {
  1572. return lookspring.GetInt();
  1573. }
  1574. //-----------------------------------------------------------------------------
  1575. // Purpose:
  1576. // Output : float
  1577. //-----------------------------------------------------------------------------
  1578. float CInput::GetLastForwardMove( void )
  1579. {
  1580. return GetPerUser().m_flLastForwardMove;
  1581. }
  1582. #if defined( HL2_CLIENT_DLL )
  1583. //-----------------------------------------------------------------------------
  1584. // Purpose: back channel contact info for ground contact
  1585. // Output :
  1586. //-----------------------------------------------------------------------------
  1587. void CInput::AddIKGroundContactInfo( int entindex, float minheight, float maxheight )
  1588. {
  1589. CEntityGroundContact data;
  1590. data.entindex = entindex;
  1591. data.minheight = minheight;
  1592. data.maxheight = maxheight;
  1593. AUTO_LOCK_FM( m_IKContactPointMutex );
  1594. // These all route through the main player's slot!!!
  1595. ACTIVE_SPLITSCREEN_PLAYER_GUARD( 0 );
  1596. if ( m_PerUser[ 0 ].m_EntityGroundContact.Count() >= MAX_EDICTS )
  1597. {
  1598. // some overflow here, probably bogus anyway
  1599. AssertOnce( "CInput::AddIKGroundContactInfo: Overflow!!!" );
  1600. m_PerUser[ 0 ].m_EntityGroundContact.RemoveAll();
  1601. return;
  1602. }
  1603. m_PerUser[ 0 ].m_EntityGroundContact.AddToTail( data );
  1604. }
  1605. #endif
  1606. static ConCommand startcommandermousemove("+commandermousemove", IN_CommanderMouseMoveDown);
  1607. static ConCommand endcommandermousemove("-commandermousemove", IN_CommanderMouseMoveUp);
  1608. static ConCommand startmoveup("+moveup",IN_UpDown);
  1609. static ConCommand endmoveup("-moveup",IN_UpUp);
  1610. static ConCommand startmovedown("+movedown",IN_DownDown);
  1611. static ConCommand endmovedown("-movedown",IN_DownUp);
  1612. static ConCommand startleft("+left",IN_LeftDown);
  1613. static ConCommand endleft("-left",IN_LeftUp);
  1614. static ConCommand startright("+right",IN_RightDown);
  1615. static ConCommand endright("-right",IN_RightUp);
  1616. static ConCommand startforward("+forward",IN_ForwardDown);
  1617. static ConCommand endforward("-forward",IN_ForwardUp);
  1618. static ConCommand startback("+back",IN_BackDown);
  1619. static ConCommand endback("-back",IN_BackUp);
  1620. static ConCommand startlookup("+lookup", IN_LookupDown);
  1621. static ConCommand endlookup("-lookup", IN_LookupUp);
  1622. static ConCommand startlookdown("+lookdown", IN_LookdownDown);
  1623. static ConCommand lookdown("-lookdown", IN_LookdownUp);
  1624. static ConCommand startstrafe("+strafe", IN_StrafeDown);
  1625. static ConCommand endstrafe("-strafe", IN_StrafeUp);
  1626. static ConCommand startmoveleft("+moveleft", IN_MoveleftDown);
  1627. static ConCommand endmoveleft("-moveleft", IN_MoveleftUp);
  1628. static ConCommand startmoveright("+moveright", IN_MoverightDown);
  1629. static ConCommand endmoveright("-moveright", IN_MoverightUp);
  1630. static ConCommand startspeed("+speed", IN_SpeedDown);
  1631. static ConCommand endspeed("-speed", IN_SpeedUp);
  1632. static ConCommand startwalk("+walk", IN_WalkDown);
  1633. static ConCommand endwalk("-walk", IN_WalkUp);
  1634. static ConCommand startattack("+attack", IN_AttackDown);
  1635. static ConCommand endattack("-attack", IN_AttackUp);
  1636. static ConCommand startattack2("+attack2", IN_Attack2Down);
  1637. static ConCommand endattack2("-attack2", IN_Attack2Up);
  1638. static ConCommand startuse("+use", IN_UseDown);
  1639. static ConCommand enduse("-use", IN_UseUp);
  1640. static ConCommand startjump("+jump", IN_JumpDown);
  1641. static ConCommand endjump("-jump", IN_JumpUp);
  1642. static ConCommand impulse("impulse", IN_Impulse);
  1643. static ConCommand startklook("+klook", IN_KLookDown);
  1644. static ConCommand endklook("-klook", IN_KLookUp);
  1645. static ConCommand startjlook("+jlook", IN_JLookDown);
  1646. static ConCommand endjlook("-jlook", IN_JLookUp);
  1647. static ConCommand startduck("+duck", IN_DuckDown);
  1648. static ConCommand endduck("-duck", IN_DuckUp);
  1649. static ConCommand startreload("+reload", IN_ReloadDown);
  1650. static ConCommand endreload("-reload", IN_ReloadUp);
  1651. static ConCommand startalt1("+alt1", IN_Alt1Down);
  1652. static ConCommand endalt1("-alt1", IN_Alt1Up);
  1653. static ConCommand startalt2("+alt2", IN_Alt2Down);
  1654. static ConCommand endalt2("-alt2", IN_Alt2Up);
  1655. static ConCommand startscore("+score", IN_ScoreDown);
  1656. static ConCommand endscore("-score", IN_ScoreUp);
  1657. static ConCommand startshowscores("+showscores", IN_ScoreDown);
  1658. static ConCommand endshowscores("-showscores", IN_ScoreUp);
  1659. static ConCommand startgraph("+graph", IN_GraphDown);
  1660. static ConCommand endgraph("-graph", IN_GraphUp);
  1661. static ConCommand startbreak("+break",IN_BreakDown);
  1662. static ConCommand endbreak("-break",IN_BreakUp);
  1663. static ConCommand force_centerview("force_centerview", IN_CenterView_f);
  1664. static ConCommand joyadvancedupdate("joyadvancedupdate", IN_Joystick_Advanced_f, "", FCVAR_CLIENTCMD_CAN_EXECUTE);
  1665. static ConCommand startzoom("+zoom", IN_ZoomDown);
  1666. static ConCommand endzoom("-zoom", IN_ZoomUp);
  1667. static ConCommand startzoomin("+zoom_in", IN_ZoomInDown);
  1668. static ConCommand endzoomin("-zoom_in", IN_ZoomInUp);
  1669. static ConCommand startzoomout("+zoom_out", IN_ZoomOutDown);
  1670. static ConCommand endzoomout("-zoom_out", IN_ZoomOutUp);
  1671. static ConCommand endgrenade1( "-grenade1", IN_Grenade1Up );
  1672. static ConCommand startgrenade1( "+grenade1", IN_Grenade1Down );
  1673. static ConCommand endgrenade2( "-grenade2", IN_Grenade2Up );
  1674. static ConCommand startgrenade2( "+grenade2", IN_Grenade2Down );
  1675. static ConCommand startlookspin("+lookspin", IN_LookSpinDown);
  1676. static ConCommand endlookspin("-lookspin", IN_LookSpinUp);
  1677. static ConCommand toggle_duck( "toggle_duck", IN_DuckToggle );
  1678. #ifdef INFESTED_DLL
  1679. static ConCommand endprevability( "-prevability", IN_PrevAbilityUp );
  1680. static ConCommand startprevability( "+prevability", IN_PrevAbilityDown );
  1681. static ConCommand endnextability( "-nextability", IN_NextAbilityUp );
  1682. static ConCommand startnextability( "+nextability", IN_NextAbilityDown );
  1683. static ConCommand endcurrentability( "-currentability", IN_CurrentAbilityUp );
  1684. static ConCommand startcurrentability( "+currentability", IN_CurrentAbilityDown );
  1685. static ConCommand endability1( "-ability1", IN_Ability1Up );
  1686. static ConCommand startability1( "+ability1", IN_Ability1Down );
  1687. static ConCommand endability2( "-ability2", IN_Ability2Up );
  1688. static ConCommand startability2( "+ability2", IN_Ability2Down );
  1689. static ConCommand endability3( "-ability3", IN_Ability3Up );
  1690. static ConCommand startability3( "+ability3", IN_Ability3Down );
  1691. static ConCommand endability4( "-ability4", IN_Ability4Up );
  1692. static ConCommand startability4( "+ability4", IN_Ability4Down );
  1693. static ConCommand endability5( "-ability5", IN_Ability5Up );
  1694. static ConCommand startability5( "+ability5", IN_Ability5Down );
  1695. #endif
  1696. // Xbox 360 stub commands
  1697. static ConCommand xboxmove("xmove", IN_XboxStub);
  1698. static ConCommand xboxlook("xlook", IN_XboxStub);
  1699. /*
  1700. ============
  1701. Init_All
  1702. ============
  1703. */
  1704. void CInput::Init_All (void)
  1705. {
  1706. InitMouse( );
  1707. m_hInputContext = engine->GetInputContext( ENGINE_INPUT_CONTEXT_GAME );
  1708. for ( int i = 0; i < MAX_SPLITSCREEN_PLAYERS; ++i )
  1709. {
  1710. Assert( !m_PerUser[ i ].m_pCommands );
  1711. Assert( !m_PerUser[ i ].m_pVerifiedCommands );
  1712. m_PerUser[ i ].m_pCommands = new CUserCmd[ MULTIPLAYER_BACKUP ];
  1713. m_PerUser[ i ].m_pVerifiedCommands = new CVerifiedUserCmd[ MULTIPLAYER_BACKUP ];
  1714. }
  1715. m_fMouseInitialized = false;
  1716. m_fRestoreSPI = false;
  1717. m_fMouseActive = false;
  1718. Q_memset( m_rgOrigMouseParms, 0, sizeof( m_rgOrigMouseParms ) );
  1719. Q_memset( m_rgNewMouseParms, 0, sizeof( m_rgNewMouseParms ) );
  1720. Q_memset( m_rgCheckMouseParam, 0, sizeof( m_rgCheckMouseParam ) );
  1721. m_rgNewMouseParms[ MOUSE_ACCEL_THRESHHOLD1 ] = 0; // no 2x
  1722. m_rgNewMouseParms[ MOUSE_ACCEL_THRESHHOLD2 ] = 0; // no 4x
  1723. m_rgNewMouseParms[ MOUSE_SPEED_FACTOR ] = 1; // 0 = disabled, 1 = threshold 1 enabled, 2 = threshold 2 enabled
  1724. m_fMouseParmsValid = false;
  1725. m_fJoystickAdvancedInit = false;
  1726. m_bControllerMode = !IsPC();
  1727. m_fAccumulatedMouseMove = 0.0f;
  1728. m_lastAutoAimValue = 1.0f;
  1729. // Initialize inputs
  1730. if ( IsPC() || IsPlatformPS3() )
  1731. {
  1732. Init_Mouse ();
  1733. Init_Keyboard();
  1734. }
  1735. // Initialize third person camera controls.
  1736. Init_Camera();
  1737. }
  1738. /*
  1739. ============
  1740. Shutdown_All
  1741. ============
  1742. */
  1743. void CInput::Shutdown_All(void)
  1744. {
  1745. DeactivateMouse();
  1746. Shutdown_Keyboard();
  1747. for ( int i = 0; i < MAX_SPLITSCREEN_PLAYERS; ++i )
  1748. {
  1749. delete[] m_PerUser[ i ].m_pCommands;
  1750. m_PerUser[ i ].m_pCommands = NULL;
  1751. delete[] m_PerUser[ i ].m_pVerifiedCommands;
  1752. m_PerUser[ i ].m_pVerifiedCommands = NULL;
  1753. }
  1754. }
  1755. void CInput::LevelInit( void )
  1756. {
  1757. #if defined( HL2_CLIENT_DLL )
  1758. // Remove any IK information
  1759. for ( int i = 0; i < MAX_SPLITSCREEN_PLAYERS; ++i )
  1760. {
  1761. ACTIVE_SPLITSCREEN_PLAYER_GUARD( i );
  1762. GetPerUser().m_EntityGroundContact.RemoveAll();
  1763. }
  1764. #endif
  1765. }