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.
487 lines
15 KiB
487 lines
15 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//===========================================================================// |
|
#ifndef INPUTSYSTEM_H |
|
#define INPUTSYSTEM_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
|
|
#ifdef WIN32 |
|
#if !defined( _X360 ) |
|
#define _WIN32_WINNT 0x502 |
|
#include <windows.h> |
|
#include <zmouse.h> |
|
#include "xbox/xboxstubs.h" |
|
#include "../../dx9sdk/include/XInput.h" |
|
#endif |
|
#endif |
|
|
|
#ifdef POSIX |
|
#include "posix_stubs.h" |
|
#endif // POSIX |
|
|
|
#include "appframework/ilaunchermgr.h" |
|
|
|
#include "inputsystem/iinputsystem.h" |
|
#include "tier2/tier2.h" |
|
|
|
#include "inputsystem/ButtonCode.h" |
|
#include "inputsystem/AnalogCode.h" |
|
#include "bitvec.h" |
|
#include "tier1/utlvector.h" |
|
#include "tier1/utlflags.h" |
|
|
|
#if defined( _X360 ) |
|
#include "xbox/xbox_win32stubs.h" |
|
#include "xbox/xbox_console.h" |
|
#endif |
|
|
|
#include "steam/steam_api.h" |
|
|
|
#define TOUCH_FINGER_MAX_COUNT 10 |
|
|
|
//----------------------------------------------------------------------------- |
|
// Implementation of the input system |
|
//----------------------------------------------------------------------------- |
|
class CInputSystem : public CTier2AppSystem< IInputSystem > |
|
{ |
|
typedef CTier2AppSystem< IInputSystem > BaseClass; |
|
|
|
public: |
|
// Constructor, destructor |
|
CInputSystem(); |
|
virtual ~CInputSystem(); |
|
|
|
// Inherited from IAppSystem |
|
virtual InitReturnVal_t Init(); |
|
virtual bool Connect( CreateInterfaceFn factory ); |
|
|
|
virtual void Shutdown(); |
|
|
|
// Inherited from IInputSystem |
|
virtual void AttachToWindow( void* hWnd ); |
|
virtual void DetachFromWindow(); |
|
virtual void EnableInput( bool bEnable ); |
|
virtual void EnableMessagePump( bool bEnable ); |
|
virtual int GetPollTick() const; |
|
virtual void PollInputState(); |
|
virtual bool IsButtonDown( ButtonCode_t code ) const; |
|
virtual int GetButtonPressedTick( ButtonCode_t code ) const; |
|
virtual int GetButtonReleasedTick( ButtonCode_t code ) const; |
|
virtual int GetAnalogValue( AnalogCode_t code ) const; |
|
virtual int GetAnalogDelta( AnalogCode_t code ) const; |
|
virtual int GetEventCount() const; |
|
virtual const InputEvent_t* GetEventData() const; |
|
virtual void PostUserEvent( const InputEvent_t &event ); |
|
virtual int GetJoystickCount() const; |
|
virtual void EnableJoystickInput( int nJoystick, bool bEnable ); |
|
virtual void EnableJoystickDiagonalPOV( int nJoystick, bool bEnable ); |
|
virtual void SampleDevices( void ); |
|
virtual void SetRumble( float fLeftMotor, float fRightMotor, int userId ); |
|
virtual void StopRumble( void ); |
|
virtual void ResetInputState( void ); |
|
virtual void SetPrimaryUserId( int userId ); |
|
virtual const char *ButtonCodeToString( ButtonCode_t code ) const; |
|
virtual const char *AnalogCodeToString( AnalogCode_t code ) const; |
|
virtual ButtonCode_t StringToButtonCode( const char *pString ) const; |
|
virtual AnalogCode_t StringToAnalogCode( const char *pString ) const; |
|
virtual ButtonCode_t VirtualKeyToButtonCode( int nVirtualKey ) const; |
|
virtual int ButtonCodeToVirtualKey( ButtonCode_t code ) const; |
|
virtual ButtonCode_t ScanCodeToButtonCode( int lParam ) const; |
|
virtual void SleepUntilInput( int nMaxSleepTimeMS ); |
|
virtual int GetPollCount() const; |
|
virtual void SetCursorPosition( int x, int y ); |
|
#if defined( WIN32 ) && !defined ( _X360 ) |
|
virtual void *GetHapticsInterfaceAddress() const; |
|
#else |
|
virtual void *GetHapticsInterfaceAddress() const { return NULL;} |
|
#endif |
|
bool GetRawMouseAccumulators( int& accumX, int& accumY ); |
|
virtual bool GetTouchAccumulators( int fingerId, float &dx, float &dy ); |
|
|
|
virtual void SetConsoleTextMode( bool bConsoleTextMode ); |
|
|
|
// Windows proc |
|
LRESULT WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); |
|
|
|
|
|
private: |
|
enum |
|
{ |
|
STICK1_AXIS_LEFT, |
|
STICK1_AXIS_RIGHT, |
|
STICK1_AXIS_DOWN, |
|
STICK1_AXIS_UP, |
|
STICK2_AXIS_LEFT, |
|
STICK2_AXIS_RIGHT, |
|
STICK2_AXIS_DOWN, |
|
STICK2_AXIS_UP, |
|
MAX_STICKAXIS |
|
}; |
|
|
|
// track Xbox stick keys from previous frame |
|
enum |
|
{ |
|
LASTKEY_STICK1_X, |
|
LASTKEY_STICK1_Y, |
|
LASTKEY_STICK2_X, |
|
LASTKEY_STICK2_Y, |
|
MAX_LASTKEY, |
|
}; |
|
|
|
enum |
|
{ |
|
INPUT_STATE_QUEUED = 0, |
|
INPUT_STATE_CURRENT, |
|
|
|
INPUT_STATE_COUNT, |
|
}; |
|
|
|
public: |
|
|
|
struct JoystickInfo_t |
|
{ |
|
void *m_pDevice; // Really an SDL_GameController*, NULL if not present. |
|
void *m_pHaptic; // Really an SDL_Haptic* |
|
float m_fCurrentRumble; |
|
bool m_bRumbleEnabled; |
|
int m_nButtonCount; |
|
int m_nAxisFlags; |
|
int m_nDeviceId; |
|
bool m_bHasPOVControl; |
|
bool m_bDiagonalPOVControlEnabled; |
|
unsigned int m_nFlags; |
|
unsigned int m_nLastPolledButtons; |
|
unsigned int m_nLastPolledAxisButtons; |
|
unsigned int m_nLastPolledPOVState; |
|
unsigned long m_pLastPolledAxes[MAX_JOYSTICK_AXES]; |
|
}; |
|
|
|
struct xdevice_t |
|
{ |
|
int userId; |
|
byte type; |
|
byte subtype; |
|
word flags; |
|
bool active; |
|
XINPUT_STATE states[2]; |
|
int newState; |
|
xKey_t lastStickKeys[MAX_LASTKEY]; |
|
int stickThreshold[MAX_STICKAXIS]; |
|
float stickScale[MAX_STICKAXIS]; |
|
int quitTimeout; |
|
int dpadLock; |
|
// rumble |
|
XINPUT_VIBRATION vibration; |
|
bool pendingRumbleUpdate; |
|
}; |
|
|
|
struct appKey_t |
|
{ |
|
int repeats; |
|
int sample; |
|
}; |
|
|
|
struct InputState_t |
|
{ |
|
// Analog states |
|
CBitVec<BUTTON_CODE_LAST> m_ButtonState; |
|
int m_ButtonPressedTick[BUTTON_CODE_LAST]; |
|
int m_ButtonReleasedTick[BUTTON_CODE_LAST]; |
|
int m_pAnalogDelta[ANALOG_CODE_LAST]; |
|
int m_pAnalogValue[ANALOG_CODE_LAST]; |
|
CUtlVector< InputEvent_t > m_Events; |
|
bool m_bDirty; |
|
}; |
|
|
|
// Initializes all Xbox controllers |
|
void InitializeXDevices( void ); |
|
|
|
// Opens an Xbox controller |
|
void OpenXDevice( xdevice_t* pXDevice, int userId ); |
|
|
|
// Closes an Xbox controller |
|
void CloseXDevice( xdevice_t* pXDevice ); |
|
|
|
// Samples the Xbox controllers |
|
void PollXDevices( void ); |
|
|
|
// Samples an Xbox controller and queues input events |
|
void ReadXDevice( xdevice_t* pXDevice ); |
|
|
|
// Submits force feedback data to an Xbox controller |
|
void WriteToXDevice( xdevice_t* pXDevice ); |
|
|
|
// Sets rumble values for an Xbox controller |
|
void SetXDeviceRumble( float fLeftMotor, float fRightMotor, int userId ); |
|
|
|
// Posts an Xbox key event, ignoring key repeats |
|
void PostXKeyEvent( int nUserId, xKey_t xKey, int nSample ); |
|
|
|
// Dispatches all joystick button events through the game's window procs |
|
void ProcessEvent( UINT uMsg, WPARAM wParam, LPARAM lParam ); |
|
|
|
// Initializes joysticks |
|
void InitializeJoysticks( void ); |
|
|
|
// Shut down joysticks |
|
void ShutdownJoysticks( void ); |
|
|
|
// Samples the joystick |
|
void PollJoystick( void ); |
|
|
|
// Update the joystick button state |
|
void UpdateJoystickButtonState( int nJoystick ); |
|
|
|
// Update the joystick POV control |
|
void UpdateJoystickPOVControl( int nJoystick ); |
|
|
|
// Record button state and post the event |
|
void JoystickButtonEvent( ButtonCode_t button, int sample ); |
|
|
|
// Init touch |
|
void InitializeTouch( void ); |
|
|
|
// Shut down touch |
|
void ShutdownTouch( void ); |
|
|
|
|
|
#if defined( WIN32 ) && !defined ( _X360 ) |
|
// NVNT attaches window to novint devices |
|
void AttachWindowToNovintDevices( void * hWnd ); |
|
|
|
// NVNT detaches window from novint input |
|
void DetachWindowFromNovintDevices( void ); |
|
|
|
// NVNT Initializes novint devices |
|
void InitializeNovintDevices( void ); |
|
|
|
// NVNT Samples a novint device |
|
void PollNovintDevices( void ); |
|
|
|
// NVNT Update the novint device button state |
|
void UpdateNovintDeviceButtonState( int nDevice ); |
|
|
|
// NVNT Record button state and post the event |
|
void NovintDeviceButtonEvent( ButtonCode_t button, int sample ); |
|
|
|
//Added called and set to true when binding input and set to false once bound |
|
void SetNovintPure( bool bPure ); |
|
#else |
|
void SetNovintPure( bool bPure ) {} // to satify the IInput virtual interface |
|
#endif |
|
// Chains the window message to the previous wndproc |
|
LRESULT ChainWindowMessage( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); |
|
|
|
// Post an event to the queue |
|
void PostEvent( int nType, int nTick, int nData = 0, int nData2 = 0, int nData3 = 0 ); |
|
|
|
// Deals with app deactivation (sends a bunch of button released messages) |
|
void ActivateInputSystem( bool bActivated ); |
|
|
|
// Determines all mouse button presses |
|
int ButtonMaskFromMouseWParam( WPARAM wParam, ButtonCode_t code = BUTTON_CODE_INVALID, bool bDown = false ) const; |
|
|
|
// Updates the state of all mouse buttons |
|
void UpdateMouseButtonState( int nButtonMask, ButtonCode_t dblClickCode = BUTTON_CODE_INVALID ); |
|
|
|
// Copies the input state record over |
|
void CopyInputState( InputState_t *pDest, const InputState_t &src, bool bCopyEvents ); |
|
|
|
// Post an button press/release event to the queue |
|
void PostButtonPressedEvent( InputEventType_t nType, int nTick, ButtonCode_t scanCode, ButtonCode_t virtualCode ); |
|
void PostButtonReleasedEvent( InputEventType_t nType, int nTick, ButtonCode_t scanCode, ButtonCode_t virtualCode ); |
|
|
|
// Release all buttons |
|
void ReleaseAllButtons( int nFirstButton = 0, int nLastButton = BUTTON_CODE_LAST - 1 ); |
|
|
|
// Zero analog state |
|
void ZeroAnalogState( int nFirstState, int nLastState ); |
|
|
|
// Converts xbox keys to button codes |
|
ButtonCode_t XKeyToButtonCode( int nUserId, int nXKey ) const; |
|
|
|
// Computes the sample tick |
|
int ComputeSampleTick(); |
|
|
|
// Clears the input state, doesn't generate key-up messages |
|
void ClearInputState(); |
|
|
|
// Called for mouse move events. Sets the current x and y and posts events for the mouse moving. |
|
void UpdateMousePositionState( InputState_t &state, short x, short y ); |
|
|
|
// Initializes SteamControllers - Returns true if steam is running and finds controllers, otherwise false |
|
bool InitializeSteamControllers( void ); |
|
|
|
// Returns number of connected Steam Controllers |
|
uint32 GetNumSteamControllersConnected(); |
|
|
|
// Update and sample steam controllers |
|
void PollSteamControllers( void ); |
|
|
|
#if defined( PLATFORM_WINDOWS_PC ) |
|
void PollInputState_Windows(); |
|
#endif |
|
|
|
void JoystickHotplugAdded( int joystickIndex ); |
|
void JoystickHotplugRemoved( int joystickId ); |
|
void JoystickButtonPress( int joystickId, int button ); // button is a SDL_CONTROLLER_BUTTON; |
|
void JoystickButtonRelease( int joystickId, int button ); // same as above. |
|
void JoystickAxisMotion( int joystickId, int axis, int value ); |
|
|
|
void FingerEvent( int eventType, int fingerId, float x, float y, float dx, float dy ); |
|
|
|
// Steam Controller |
|
void ReadSteamController( int iIndex ); |
|
void PostKeyEvent( int iIndex, sKey_t sKey, int nSample ); |
|
const int GetSteamPadDeadZone( ESteamPadAxis axis ); |
|
bool IsSteamControllerConnected( void ) { return m_bSteamController; } |
|
bool IsSteamControllerActive( void ); |
|
void ActivateSteamControllerActionSetForSlot( uint64 nSlot, GameActionSet_t eActionSet ); |
|
ControllerActionSetHandle_t GetActionSetHandle( GameActionSet_t eActionSet ); |
|
ControllerActionSetHandle_t GetActionSetHandle( const char* szActionSet ); |
|
bool GetControllerStateForSlot( int nSlot ); |
|
int GetSteamControllerIndexForSlot( int nSlot ); |
|
bool GetRadialMenuStickValues( int nSlot, float &fX, float &fY ); |
|
virtual ISteamController* SteamControllerInterface(); |
|
bool InitializeSteamControllerActionSets(); |
|
|
|
// Gets the action origin (i.e. which physical input) maps to the given action name |
|
virtual EControllerActionOrigin GetSteamControllerActionOrigin( const char* action, GameActionSet_t action_set ); |
|
virtual EControllerActionOrigin GetSteamControllerActionOrigin( const char* action, ControllerActionSetHandle_t action_set_handle ); |
|
|
|
// Maps a Steam Controller action origin to a string (consisting of a single character) in our SC icon font |
|
virtual const wchar_t* GetSteamControllerFontCharacterForActionOrigin( EControllerActionOrigin origin ); |
|
|
|
// Maps a Steam Controller action origin to a short text string (e.g. "X", "LB", "LDOWN") describing the control. |
|
// Prefer to actually use the icon font wherever possible. |
|
virtual const wchar_t* GetSteamControllerDescriptionForActionOrigin( EControllerActionOrigin origin ); |
|
|
|
// Converts SteamController keys to button codes |
|
ButtonCode_t SKeyToButtonCode( int nUserId, int nXKey ) const; |
|
|
|
// This is called with "true" by dedicated server initialization (before calling Init) in order to |
|
// force us to skip initialization of Steam (which messes up dedicated servers). |
|
virtual void SetSkipControllerInitialization( bool bSkip ) |
|
{ |
|
m_bSkipControllerInitialization = bSkip; |
|
} |
|
|
|
virtual void StartTextInput(); |
|
|
|
#if defined( USE_SDL ) |
|
void PollInputState_Platform(); |
|
|
|
ILauncherMgr *m_pLauncherMgr; |
|
#endif |
|
|
|
WNDPROC m_ChainedWndProc; |
|
HWND m_hAttachedHWnd; |
|
bool m_bEnabled; |
|
bool m_bPumpEnabled; |
|
bool m_bIsPolling; |
|
|
|
// Current button state |
|
InputState_t m_InputState[INPUT_STATE_COUNT]; |
|
|
|
// Current action set |
|
GameActionSet_t m_currentActionSet[STEAM_CONTROLLER_MAX_COUNT]; |
|
|
|
DWORD m_StartupTimeTick; |
|
int m_nLastPollTick; |
|
int m_nLastSampleTick; |
|
int m_nPollCount; |
|
|
|
// Mouse wheel hack |
|
UINT m_uiMouseWheel; |
|
|
|
// Joystick info |
|
CUtlFlags<unsigned short> m_JoysticksEnabled; |
|
int m_nJoystickCount; |
|
bool m_bJoystickInitialized; |
|
bool m_bTouchInitialized; |
|
bool m_bXController; |
|
JoystickInfo_t m_pJoystickInfo[ MAX_JOYSTICKS ]; |
|
|
|
// Steam Controller |
|
struct steampad_t |
|
{ |
|
steampad_t() |
|
{ |
|
m_nHardwareIndex = 0; |
|
m_nJoystickIndex = INVALID_USER_ID; |
|
m_nLastPacketIndex = 0; |
|
active = false; |
|
memset( lastAnalogKeys, 0, sizeof( lastAnalogKeys ) ); |
|
} |
|
bool active; |
|
|
|
sKey_t lastAnalogKeys[MAX_STEAMPADAXIS]; |
|
appKey_t m_appSKeys[SK_MAX_KEYS]; |
|
// Hardware index and joystick index don't necessarily match |
|
// Joystick index will depend on the order of multiple initialized devices |
|
// Which could include other controller types |
|
// Hardware index should line up 1:1 with the order they're polled |
|
// and could change based on removing devices, unlike Joystick Index |
|
uint32 m_nHardwareIndex; |
|
int m_nJoystickIndex; |
|
uint32 m_nLastPacketIndex; |
|
}; |
|
|
|
float m_pRadialMenuStickVal[STEAM_CONTROLLER_MAX_COUNT][2]; |
|
steampad_t m_Device[STEAM_CONTROLLER_MAX_COUNT]; |
|
uint32 m_unNumConnected; |
|
float m_flLastSteamControllerInput; |
|
int m_nJoystickBaseline; |
|
int m_nControllerType[MAX_JOYSTICKS+STEAM_CONTROLLER_MAX_COUNT]; |
|
|
|
bool m_bSteamController; // true if the Steam Controller system has been initialized successfully (this doesn't mean one is actually connected necessarily) |
|
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) |
|
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. |
|
|
|
#if defined( WIN32 ) && !defined ( _X360 ) |
|
// NVNT Novint device info |
|
int m_nNovintDeviceCount; |
|
bool m_bNovintDevices; |
|
#endif |
|
|
|
// Xbox controller info |
|
appKey_t m_appXKeys[ XUSER_MAX_COUNT ][ XK_MAX_KEYS ]; |
|
xdevice_t m_XDevices[ XUSER_MAX_COUNT ]; |
|
int m_PrimaryUserId; |
|
|
|
// raw mouse input |
|
bool m_bRawInputSupported; |
|
int m_mouseRawAccumX, m_mouseRawAccumY; |
|
|
|
float m_touchAccumX[TOUCH_FINGER_MAX_COUNT], m_touchAccumY[TOUCH_FINGER_MAX_COUNT]; |
|
|
|
// For the 'SleepUntilInput' feature |
|
HANDLE m_hEvent; |
|
|
|
CSysModule *m_pXInputDLL; |
|
CSysModule *m_pRawInputDLL; |
|
|
|
#if defined( WIN32 ) && !defined ( _X360 ) |
|
// NVNT falcon module |
|
CSysModule *m_pNovintDLL; |
|
#endif |
|
|
|
bool m_bConsoleTextMode; |
|
|
|
public: |
|
// Steam API context for use by input system for access to steam controllers. |
|
CSteamAPIContext& SteamAPIContext() { return m_SteamAPIContext; } |
|
|
|
private: |
|
CSteamAPIContext m_SteamAPIContext; |
|
bool m_bSkipControllerInitialization; |
|
}; |
|
|
|
#endif // INPUTSYSTEM_H
|
|
|