Team Fortress 2 Source Code as on 22/4/2020
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.

469 lines
15 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #ifndef INPUTSYSTEM_H
  9. #define INPUTSYSTEM_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #ifdef WIN32
  14. #if !defined( _X360 )
  15. #define _WIN32_WINNT 0x502
  16. #include <windows.h>
  17. #include <zmouse.h>
  18. #include "xbox/xboxstubs.h"
  19. #include "../../dx9sdk/include/XInput.h"
  20. #endif
  21. #endif
  22. #ifdef POSIX
  23. #include "posix_stubs.h"
  24. #endif // POSIX
  25. #include "appframework/ilaunchermgr.h"
  26. #include "inputsystem/iinputsystem.h"
  27. #include "tier2/tier2.h"
  28. #include "inputsystem/ButtonCode.h"
  29. #include "inputsystem/AnalogCode.h"
  30. #include "bitvec.h"
  31. #include "tier1/utlvector.h"
  32. #include "tier1/utlflags.h"
  33. #if defined( _X360 )
  34. #include "xbox/xbox_win32stubs.h"
  35. #include "xbox/xbox_console.h"
  36. #endif
  37. #include "steam/steam_api.h"
  38. //-----------------------------------------------------------------------------
  39. // Implementation of the input system
  40. //-----------------------------------------------------------------------------
  41. class CInputSystem : public CTier2AppSystem< IInputSystem >
  42. {
  43. typedef CTier2AppSystem< IInputSystem > BaseClass;
  44. public:
  45. // Constructor, destructor
  46. CInputSystem();
  47. virtual ~CInputSystem();
  48. // Inherited from IAppSystem
  49. virtual InitReturnVal_t Init();
  50. virtual bool Connect( CreateInterfaceFn factory );
  51. virtual void Shutdown();
  52. // Inherited from IInputSystem
  53. virtual void AttachToWindow( void* hWnd );
  54. virtual void DetachFromWindow();
  55. virtual void EnableInput( bool bEnable );
  56. virtual void EnableMessagePump( bool bEnable );
  57. virtual int GetPollTick() const;
  58. virtual void PollInputState();
  59. virtual bool IsButtonDown( ButtonCode_t code ) const;
  60. virtual int GetButtonPressedTick( ButtonCode_t code ) const;
  61. virtual int GetButtonReleasedTick( ButtonCode_t code ) const;
  62. virtual int GetAnalogValue( AnalogCode_t code ) const;
  63. virtual int GetAnalogDelta( AnalogCode_t code ) const;
  64. virtual int GetEventCount() const;
  65. virtual const InputEvent_t* GetEventData() const;
  66. virtual void PostUserEvent( const InputEvent_t &event );
  67. virtual int GetJoystickCount() const;
  68. virtual void EnableJoystickInput( int nJoystick, bool bEnable );
  69. virtual void EnableJoystickDiagonalPOV( int nJoystick, bool bEnable );
  70. virtual void SampleDevices( void );
  71. virtual void SetRumble( float fLeftMotor, float fRightMotor, int userId );
  72. virtual void StopRumble( void );
  73. virtual void ResetInputState( void );
  74. virtual void SetPrimaryUserId( int userId );
  75. virtual const char *ButtonCodeToString( ButtonCode_t code ) const;
  76. virtual const char *AnalogCodeToString( AnalogCode_t code ) const;
  77. virtual ButtonCode_t StringToButtonCode( const char *pString ) const;
  78. virtual AnalogCode_t StringToAnalogCode( const char *pString ) const;
  79. virtual ButtonCode_t VirtualKeyToButtonCode( int nVirtualKey ) const;
  80. virtual int ButtonCodeToVirtualKey( ButtonCode_t code ) const;
  81. virtual ButtonCode_t ScanCodeToButtonCode( int lParam ) const;
  82. virtual void SleepUntilInput( int nMaxSleepTimeMS );
  83. virtual int GetPollCount() const;
  84. virtual void SetCursorPosition( int x, int y );
  85. #if defined( WIN32 ) && !defined ( _X360 )
  86. virtual void *GetHapticsInterfaceAddress() const;
  87. #else
  88. virtual void *GetHapticsInterfaceAddress() const { return NULL;}
  89. #endif
  90. bool GetRawMouseAccumulators( int& accumX, int& accumY );
  91. virtual void SetConsoleTextMode( bool bConsoleTextMode );
  92. // Windows proc
  93. LRESULT WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  94. private:
  95. enum
  96. {
  97. STICK1_AXIS_LEFT,
  98. STICK1_AXIS_RIGHT,
  99. STICK1_AXIS_DOWN,
  100. STICK1_AXIS_UP,
  101. STICK2_AXIS_LEFT,
  102. STICK2_AXIS_RIGHT,
  103. STICK2_AXIS_DOWN,
  104. STICK2_AXIS_UP,
  105. MAX_STICKAXIS
  106. };
  107. // track Xbox stick keys from previous frame
  108. enum
  109. {
  110. LASTKEY_STICK1_X,
  111. LASTKEY_STICK1_Y,
  112. LASTKEY_STICK2_X,
  113. LASTKEY_STICK2_Y,
  114. MAX_LASTKEY,
  115. };
  116. enum
  117. {
  118. INPUT_STATE_QUEUED = 0,
  119. INPUT_STATE_CURRENT,
  120. INPUT_STATE_COUNT,
  121. };
  122. public:
  123. struct JoystickInfo_t
  124. {
  125. void *m_pDevice; // Really an SDL_GameController*, NULL if not present.
  126. void *m_pHaptic; // Really an SDL_Haptic*
  127. float m_fCurrentRumble;
  128. bool m_bRumbleEnabled;
  129. int m_nButtonCount;
  130. int m_nAxisFlags;
  131. int m_nDeviceId;
  132. bool m_bHasPOVControl;
  133. bool m_bDiagonalPOVControlEnabled;
  134. unsigned int m_nFlags;
  135. unsigned int m_nLastPolledButtons;
  136. unsigned int m_nLastPolledAxisButtons;
  137. unsigned int m_nLastPolledPOVState;
  138. unsigned long m_pLastPolledAxes[MAX_JOYSTICK_AXES];
  139. };
  140. struct xdevice_t
  141. {
  142. int userId;
  143. byte type;
  144. byte subtype;
  145. word flags;
  146. bool active;
  147. XINPUT_STATE states[2];
  148. int newState;
  149. xKey_t lastStickKeys[MAX_LASTKEY];
  150. int stickThreshold[MAX_STICKAXIS];
  151. float stickScale[MAX_STICKAXIS];
  152. int quitTimeout;
  153. int dpadLock;
  154. // rumble
  155. XINPUT_VIBRATION vibration;
  156. bool pendingRumbleUpdate;
  157. };
  158. struct appKey_t
  159. {
  160. int repeats;
  161. int sample;
  162. };
  163. struct InputState_t
  164. {
  165. // Analog states
  166. CBitVec<BUTTON_CODE_LAST> m_ButtonState;
  167. int m_ButtonPressedTick[BUTTON_CODE_LAST];
  168. int m_ButtonReleasedTick[BUTTON_CODE_LAST];
  169. int m_pAnalogDelta[ANALOG_CODE_LAST];
  170. int m_pAnalogValue[ANALOG_CODE_LAST];
  171. CUtlVector< InputEvent_t > m_Events;
  172. bool m_bDirty;
  173. };
  174. // Initializes all Xbox controllers
  175. void InitializeXDevices( void );
  176. // Opens an Xbox controller
  177. void OpenXDevice( xdevice_t* pXDevice, int userId );
  178. // Closes an Xbox controller
  179. void CloseXDevice( xdevice_t* pXDevice );
  180. // Samples the Xbox controllers
  181. void PollXDevices( void );
  182. // Samples an Xbox controller and queues input events
  183. void ReadXDevice( xdevice_t* pXDevice );
  184. // Submits force feedback data to an Xbox controller
  185. void WriteToXDevice( xdevice_t* pXDevice );
  186. // Sets rumble values for an Xbox controller
  187. void SetXDeviceRumble( float fLeftMotor, float fRightMotor, int userId );
  188. // Posts an Xbox key event, ignoring key repeats
  189. void PostXKeyEvent( int nUserId, xKey_t xKey, int nSample );
  190. // Dispatches all joystick button events through the game's window procs
  191. void ProcessEvent( UINT uMsg, WPARAM wParam, LPARAM lParam );
  192. // Initializes joysticks
  193. void InitializeJoysticks( void );
  194. // Shut down joysticks
  195. void ShutdownJoysticks( void );
  196. // Samples the joystick
  197. void PollJoystick( void );
  198. // Update the joystick button state
  199. void UpdateJoystickButtonState( int nJoystick );
  200. // Update the joystick POV control
  201. void UpdateJoystickPOVControl( int nJoystick );
  202. // Record button state and post the event
  203. void JoystickButtonEvent( ButtonCode_t button, int sample );
  204. #if defined( WIN32 ) && !defined ( _X360 )
  205. // NVNT attaches window to novint devices
  206. void AttachWindowToNovintDevices( void * hWnd );
  207. // NVNT detaches window from novint input
  208. void DetachWindowFromNovintDevices( void );
  209. // NVNT Initializes novint devices
  210. void InitializeNovintDevices( void );
  211. // NVNT Samples a novint device
  212. void PollNovintDevices( void );
  213. // NVNT Update the novint device button state
  214. void UpdateNovintDeviceButtonState( int nDevice );
  215. // NVNT Record button state and post the event
  216. void NovintDeviceButtonEvent( ButtonCode_t button, int sample );
  217. //Added called and set to true when binding input and set to false once bound
  218. void SetNovintPure( bool bPure );
  219. #else
  220. void SetNovintPure( bool bPure ) {} // to satify the IInput virtual interface
  221. #endif
  222. // Chains the window message to the previous wndproc
  223. LRESULT ChainWindowMessage( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  224. // Post an event to the queue
  225. void PostEvent( int nType, int nTick, int nData = 0, int nData2 = 0, int nData3 = 0 );
  226. // Deals with app deactivation (sends a bunch of button released messages)
  227. void ActivateInputSystem( bool bActivated );
  228. // Determines all mouse button presses
  229. int ButtonMaskFromMouseWParam( WPARAM wParam, ButtonCode_t code = BUTTON_CODE_INVALID, bool bDown = false ) const;
  230. // Updates the state of all mouse buttons
  231. void UpdateMouseButtonState( int nButtonMask, ButtonCode_t dblClickCode = BUTTON_CODE_INVALID );
  232. // Copies the input state record over
  233. void CopyInputState( InputState_t *pDest, const InputState_t &src, bool bCopyEvents );
  234. // Post an button press/release event to the queue
  235. void PostButtonPressedEvent( InputEventType_t nType, int nTick, ButtonCode_t scanCode, ButtonCode_t virtualCode );
  236. void PostButtonReleasedEvent( InputEventType_t nType, int nTick, ButtonCode_t scanCode, ButtonCode_t virtualCode );
  237. // Release all buttons
  238. void ReleaseAllButtons( int nFirstButton = 0, int nLastButton = BUTTON_CODE_LAST - 1 );
  239. // Zero analog state
  240. void ZeroAnalogState( int nFirstState, int nLastState );
  241. // Converts xbox keys to button codes
  242. ButtonCode_t XKeyToButtonCode( int nUserId, int nXKey ) const;
  243. // Computes the sample tick
  244. int ComputeSampleTick();
  245. // Clears the input state, doesn't generate key-up messages
  246. void ClearInputState();
  247. // Called for mouse move events. Sets the current x and y and posts events for the mouse moving.
  248. void UpdateMousePositionState( InputState_t &state, short x, short y );
  249. // Initializes SteamControllers - Returns true if steam is running and finds controllers, otherwise false
  250. bool InitializeSteamControllers( void );
  251. // Returns number of connected Steam Controllers
  252. uint32 GetNumSteamControllersConnected();
  253. // Update and sample steam controllers
  254. void PollSteamControllers( void );
  255. #if defined( PLATFORM_WINDOWS_PC )
  256. void PollInputState_Windows();
  257. #endif
  258. void JoystickHotplugAdded( int joystickIndex );
  259. void JoystickHotplugRemoved( int joystickId );
  260. void JoystickButtonPress( int joystickId, int button ); // button is a SDL_CONTROLLER_BUTTON;
  261. void JoystickButtonRelease( int joystickId, int button ); // same as above.
  262. void JoystickAxisMotion( int joystickId, int axis, int value );
  263. // Steam Controller
  264. void ReadSteamController( int iIndex );
  265. void PostKeyEvent( int iIndex, sKey_t sKey, int nSample );
  266. const int GetSteamPadDeadZone( ESteamPadAxis axis );
  267. bool IsSteamControllerConnected( void ) { return m_bSteamController; }
  268. bool IsSteamControllerActive( void );
  269. void ActivateSteamControllerActionSetForSlot( uint64 nSlot, GameActionSet_t eActionSet );
  270. ControllerActionSetHandle_t GetActionSetHandle( GameActionSet_t eActionSet );
  271. ControllerActionSetHandle_t GetActionSetHandle( const char* szActionSet );
  272. bool GetControllerStateForSlot( int nSlot );
  273. int GetSteamControllerIndexForSlot( int nSlot );
  274. bool GetRadialMenuStickValues( int nSlot, float &fX, float &fY );
  275. virtual ISteamController* SteamControllerInterface();
  276. bool InitializeSteamControllerActionSets();
  277. // Gets the action origin (i.e. which physical input) maps to the given action name
  278. virtual EControllerActionOrigin GetSteamControllerActionOrigin( const char* action, GameActionSet_t action_set );
  279. virtual EControllerActionOrigin GetSteamControllerActionOrigin( const char* action, ControllerActionSetHandle_t action_set_handle );
  280. // Maps a Steam Controller action origin to a string (consisting of a single character) in our SC icon font
  281. virtual const wchar_t* GetSteamControllerFontCharacterForActionOrigin( EControllerActionOrigin origin );
  282. // Maps a Steam Controller action origin to a short text string (e.g. "X", "LB", "LDOWN") describing the control.
  283. // Prefer to actually use the icon font wherever possible.
  284. virtual const wchar_t* GetSteamControllerDescriptionForActionOrigin( EControllerActionOrigin origin );
  285. // Converts SteamController keys to button codes
  286. ButtonCode_t SKeyToButtonCode( int nUserId, int nXKey ) const;
  287. // This is called with "true" by dedicated server initialization (before calling Init) in order to
  288. // force us to skip initialization of Steam (which messes up dedicated servers).
  289. virtual void SetSkipControllerInitialization( bool bSkip )
  290. {
  291. m_bSkipControllerInitialization = bSkip;
  292. }
  293. #if defined( USE_SDL )
  294. void PollInputState_Platform();
  295. ILauncherMgr *m_pLauncherMgr;
  296. #endif
  297. WNDPROC m_ChainedWndProc;
  298. HWND m_hAttachedHWnd;
  299. bool m_bEnabled;
  300. bool m_bPumpEnabled;
  301. bool m_bIsPolling;
  302. // Current button state
  303. InputState_t m_InputState[INPUT_STATE_COUNT];
  304. // Current action set
  305. GameActionSet_t m_currentActionSet[STEAM_CONTROLLER_MAX_COUNT];
  306. DWORD m_StartupTimeTick;
  307. int m_nLastPollTick;
  308. int m_nLastSampleTick;
  309. int m_nPollCount;
  310. // Mouse wheel hack
  311. UINT m_uiMouseWheel;
  312. // Joystick info
  313. CUtlFlags<unsigned short> m_JoysticksEnabled;
  314. int m_nJoystickCount;
  315. bool m_bJoystickInitialized;
  316. bool m_bXController;
  317. JoystickInfo_t m_pJoystickInfo[ MAX_JOYSTICKS ];
  318. // Steam Controller
  319. struct steampad_t
  320. {
  321. steampad_t()
  322. {
  323. m_nHardwareIndex = 0;
  324. m_nJoystickIndex = INVALID_USER_ID;
  325. m_nLastPacketIndex = 0;
  326. active = false;
  327. memset( lastAnalogKeys, 0, sizeof( lastAnalogKeys ) );
  328. }
  329. bool active;
  330. sKey_t lastAnalogKeys[MAX_STEAMPADAXIS];
  331. appKey_t m_appSKeys[SK_MAX_KEYS];
  332. // Hardware index and joystick index don't necessarily match
  333. // Joystick index will depend on the order of multiple initialized devices
  334. // Which could include other controller types
  335. // Hardware index should line up 1:1 with the order they're polled
  336. // and could change based on removing devices, unlike Joystick Index
  337. uint32 m_nHardwareIndex;
  338. int m_nJoystickIndex;
  339. uint32 m_nLastPacketIndex;
  340. };
  341. float m_pRadialMenuStickVal[STEAM_CONTROLLER_MAX_COUNT][2];
  342. steampad_t m_Device[STEAM_CONTROLLER_MAX_COUNT];
  343. uint32 m_unNumConnected;
  344. float m_flLastSteamControllerInput;
  345. int m_nJoystickBaseline;
  346. int m_nControllerType[MAX_JOYSTICKS+STEAM_CONTROLLER_MAX_COUNT];
  347. bool m_bSteamController; // true if the Steam Controller system has been initialized successfully (this doesn't mean one is actually connected necessarily)
  348. bool m_bSteamControllerActionsInitialized; // true if our action sets and handles were successfully initialized (this doesn't mean a controller is necessarily connected, or that in-game client actions were initialized)
  349. bool m_bSteamControllerActive; // true if our action sets and handles were successfully initialized *and* that at least one controller is actually connected and switched on.
  350. #if defined( WIN32 ) && !defined ( _X360 )
  351. // NVNT Novint device info
  352. int m_nNovintDeviceCount;
  353. bool m_bNovintDevices;
  354. #endif
  355. // Xbox controller info
  356. appKey_t m_appXKeys[ XUSER_MAX_COUNT ][ XK_MAX_KEYS ];
  357. xdevice_t m_XDevices[ XUSER_MAX_COUNT ];
  358. int m_PrimaryUserId;
  359. // raw mouse input
  360. bool m_bRawInputSupported;
  361. int m_mouseRawAccumX, m_mouseRawAccumY;
  362. // For the 'SleepUntilInput' feature
  363. HANDLE m_hEvent;
  364. CSysModule *m_pXInputDLL;
  365. CSysModule *m_pRawInputDLL;
  366. #if defined( WIN32 ) && !defined ( _X360 )
  367. // NVNT falcon module
  368. CSysModule *m_pNovintDLL;
  369. #endif
  370. bool m_bConsoleTextMode;
  371. public:
  372. // Steam API context for use by input system for access to steam controllers.
  373. CSteamAPIContext& SteamAPIContext() { return m_SteamAPIContext; }
  374. private:
  375. CSteamAPIContext m_SteamAPIContext;
  376. bool m_bSkipControllerInitialization;
  377. };
  378. #endif // INPUTSYSTEM_H