EDN Admin
Well-known member
I have the structures already from a post I found in here but have no idea how to apply them and my knowledge of C++ is not at a level where I will be able to successfully understand and port it over. I know there are analog buttons and digital and those are handled differently. My intent of this thread is a how to make Xinput work on a VB.net WPF application.
Here are the structures I found on http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/19b19285-ae5d-42dc-86d5-0f66619be33b
Private Declare Function XInputGetBatteryInformation Lib "xinput1_4.dll" (ByVal uJoyID As Integer, ByVal uJoyID2 As UInteger, ByRef pBatteryInformation As XINPUTBATTERYINFORMATION) As Int16
Private Declare Function XInputGetState Lib "xinput1_4.dll" (ByVal dwUserIndex As Integer, ByRef pState As XINPUTSTATE) As Boolean
Private Declare Function XInputSetState Lib "xinput1_4.dll" (ByVal dwUserIndex As Integer, ByRef pVibration As XINPUTVIBRATION) As Int16Private Declare Function XinputGetCapabilities Lib "xinput1_4.dll" (ByVal dwUserIndex As Integer, ByVal dwFlags As Integer, ByRef pCapabilities as XinputCapabilities) As Int16
Private Declare Function XinputGetKeystroke Lib "xinput1_4.dll" (ByVal dwUserIndex As Integer, ByVal dwReserved as Integer ByRef XinputKeystroke As pKeystroke) As Int16
Public Structure XINPUTBATTERYINFORMATION
Public BatteryType As Byte
Public BatteryLevel As Byte Public Overrides Function ToString() As String
Return String.Format("{0} {1}", DirectCast(BatteryType, BatteryTypes), DirectCast(BatteryLevel, BatteryLevel))
End Function
End Structure
Public Structure XINPUTGAMEPAD
Public wButtons As UInt16
Public bLeftTrigger As Char
Public bRightTrigger As Char
Public sThumbLX As Int16
Public sThumbLY As Int16
Public sThumbRX As Int16
Public sThumbRY As Int16Public Function IsButtonPressed(buttonFlags As Integer) As Boolean
Return (wButtons And buttonFlags) = buttonFlags
End Function
Public Function IsButtonPresent(buttonFlags As Integer) As Boolean
Return (wButtons And buttonFlags) = buttonFlags
End Function
Public Sub Copy(source As XInputGamepad)
sThumbLX = source.sThumbLX
sThumbLY = source.sThumbLY
sThumbRX = source.sThumbRX
sThumbRY = source.sThumbRY
bLeftTrigger = source.bLeftTrigger
bRightTrigger = source.bRightTrigger
wButtons = source.wButtons
End Sub
Public Overrides Function Equals(obj As Object) As Boolean
If Not (TypeOf obj Is XInputGamepad) Then
Return False
End If
Dim source As XInputGamepad = CType(obj, XInputGamepad)
Return ((sThumbLX = source.sThumbLX) AndAlso (sThumbLY = source.sThumbLY) AndAlso (sThumbRX = source.sThumbRX) AndAlso (sThumbRY = source.sThumbRY) AndAlso (bLeftTrigger = source.bLeftTrigger) AndAlso (bRightTrigger = source.bRightTrigger) AndAlso (wButtons = source.wButtons))
End Function
End Structure Public Structure XInputKeystroke
Public VirtualKey As Short
Public Unicode As Char
Public Flags As Short
Public UserIndex As Byte
Public HidCode As Byte
End Structure
Public Structure XINPUTSTATE
Public dwPacketNumber As Integer
Public Gamepad As XINPUTGAMEPADPublic Sub Copy(source As XInputState)
PacketNumber = source.PacketNumber
Gamepad.Copy(source.Gamepad)
End Sub
Public Overrides Function Equals(obj As Object) As Boolean
If (obj Is Nothing) OrElse (Not (TypeOf obj Is XInputState)) Then
Return False
End If
Dim source As XInputState = DirectCast(obj, XInputState)
Return ((PacketNumber = source.PacketNumber) AndAlso (Gamepad.Equals(source.Gamepad)))
End Function
End Structure
Public Structure XINPUTVIBRATION
Public wLeftMotorSpeed As UShort
Public wRightMotorSpeed As UShort
End StructurePublic Structure XInputCapabilities
Private Type As Byte
Public SubType As Byte
Public Flags As Short
Public Gamepad As XInputGamepad
Public Vibration As XInputVibration
End StructurePublic Class Point
Public Property X() As Integer
Get
Return m_X
End Get
Set
m_X = Value
End Set
End Property
Private m_X As Integer
Public Property Y() As Integer
Get
Return m_Y
End Get
Set
m_Y = Value
End Set
End Property
Private m_Y As Integer
End Class
Now lets say I want an if statement for pressing the "A" button so I can paste in code for what I want to happen. How do I go about that?
I know I need to enum some things tooublic Enum ButtonFlags As Integer
XINPUT_GAMEPAD_DPAD_UP = &H1
XINPUT_GAMEPAD_DPAD_DOWN = &H2
XINPUT_GAMEPAD_DPAD_LEFT = &H4
XINPUT_GAMEPAD_DPAD_RIGHT = &H8
XINPUT_GAMEPAD_START = &H10
XINPUT_GAMEPAD_BACK = &H20
XINPUT_GAMEPAD_LEFT_THUMB = &H40
XINPUT_GAMEPAD_RIGHT_THUMB = &H80
XINPUT_GAMEPAD_LEFT_SHOULDER = &H100
XINPUT_GAMEPAD_RIGHT_SHOULDER = &H200
XINPUT_GAMEPAD_A = &H1000
XINPUT_GAMEPAD_B = &H2000
XINPUT_GAMEPAD_X = &H4000
XINPUT_GAMEPAD_Y = &H8000
End Enum
Public Enum ControllerSubtypes
XINPUT_DEVSUBTYPE_UNKNOWN = &H0
XINPUT_DEVSUBTYPE_WHEEL = &H2
XINPUT_DEVSUBTYPE_ARCADE_STICK = &H3
XINPUT_DEVSUBTYPE_FLIGHT_STICK = &H4
XINPUT_DEVSUBTYPE_DANCE_PAD = &H5
XINPUT_DEVSUBTYPE_GUITAR = &H6
XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE = &H7
XINPUT_DEVSUBTYPE_DRUM_KIT = &H8
XINPUT_DEVSUBTYPE_GUITAR_BASS = &Hb
XINPUT_DEVSUBTYPE_ARCADE_PAD = &H13
End Enum
Public Enum BatteryTypes As Byte
BATTERY_TYPE_DISCONNECTED = &H0
BATTERY_TYPE_WIRED = &H1
BATTERY_TYPE_ALKALINE = &H2
BATTERY_TYPE_NIMH = &H3
BATTERY_TYPE_UNKNOWN = &Hff
End Enum
Public Enum BatteryLevel As Byte
BATTERY_LEVEL_EMPTY = &H0
BATTERY_LEVEL_LOW = &H1
BATTERY_LEVEL_MEDIUM = &H2
BATTERY_LEVEL_FULL = &H3
End Enum
Public Enum BatteryDeviceType As Byte
BATTERY_DEVTYPE_GAMEPAD = &H0
BATTERY_DEVTYPE_HEADSET = &H1
End Enum
Public Class XInputConstants
Public Const XINPUT_DEVTYPE_GAMEPAD As Integer = &H1
Public Const XINPUT_DEVSUBTYPE_GAMEPAD As Integer = &H1
Public Enum CapabilityFlags
XINPUT_CAPS_VOICE_SUPPORTED = &H4
XINPUT_CAPS_FFB_SUPPORTED = &H1
XINPUT_CAPS_WIRELESS = &H2
XINPUT_CAPS_PMD_SUPPORTED = &H8
XINPUT_CAPS_NO_NAVIGATION = &H10
End Enum
Public Const XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE As Integer = 7849
Public Const XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE As Integer = 8689
Public Const XINPUT_GAMEPAD_TRIGGER_THRESHOLD As Integer = 30
Public Const XINPUT_FLAG_GAMEPAD As Integer = &H1 Public Class XboxController
Private _playerIndex As Integer
Shared keepRunning As Boolean
Shared m_updateFrequency As Integer
Shared waitTime As Integer
Shared isRunning As Boolean
Shared [SyncLock] As Object
Shared pollingThread As Thread
Private _stopMotorTimerActive As Boolean
Private _stopMotorTime As DateTime
Private _batteryInformationGamepad As XInputBatteryInformation
Private _batteryInformationHeadset As XInputBatteryInformation
XInputCapabilities _capabilities;
Private gamepadStatePrev As New XInputState()
Private gamepadStateCurrent As New XInputState()
Public Shared Property UpdateFrequency() As Integer
Get
Return m_updateFrequency
End Get
Set
m_updateFrequency = value
waitTime = 1000 m_updateFrequency
End Set
End Property
Public Property BatteryInformationGamepad() As XInputBatteryInformation
Get
Return _batteryInformationGamepad
End Get
Friend Set
_batteryInformationGamepad = value
End Set
End Property
Public Property BatteryInformationHeadset() As XInputBatteryInformation
Get
Return _batteryInformationHeadset
End Get
Friend Set
_batteryInformationHeadset = value
End Set
End Property
Public Const MAX_CONTROLLER_COUNT As Integer = 4
Public Const FIRST_CONTROLLER_INDEX As Integer = 0
Public Const LAST_CONTROLLER_INDEX As Integer = MAX_CONTROLLER_COUNT - 1
Shared Controllers As XboxController()
Shared Sub New()
Controllers = New XboxController(MAX_CONTROLLER_COUNT - 1) {}
[SyncLock] = New Object()
For i As Integer = FIRST_CONTROLLER_INDEX To LAST_CONTROLLER_INDEX
Controllers(i) = New XboxController(i)
Next
UpdateFrequency = 25
End Sub
Public Event StateChanged As EventHandler(Of XboxControllerStateChangedEventArgs) = Nothing
Public Shared Function RetrieveController(index As Integer) As XboxController
Return Controllers(index)
End Function
Private Sub New(playerIndex As Integer)
_playerIndex = playerIndex
gamepadStatePrev.Copy(gamepadStateCurrent)
End Sub
Public Sub UpdateBatteryState()
Dim headset As New XInputBatteryInformation(), gamepad As New XInputBatteryInformation()
XInput.XInputGetBatteryInformation(_playerIndex, CByte(BatteryDeviceType.BATTERY_DEVTYPE_GAMEPAD), gamepad)
XInput.XInputGetBatteryInformation(_playerIndex, CByte(BatteryDeviceType.BATTERY_DEVTYPE_HEADSET), headset)
BatteryInformationHeadset = headset
BatteryInformationGamepad = gamepad
End Sub
Protected Sub OnStateChanged()
RaiseEvent StateChanged(Me, New XboxControllerStateChangedEventArgs() With { _
Key .CurrentInputState = gamepadStateCurrent, _
Key .PreviousInputState = gamepadStatePrev _
})
End Sub
Public Function GetCapabilities() As XInputCapabilities
Dim capabilities As New XInputCapabilities()
XInput.XInputGetCapabilities(_playerIndex, XInputConstants.XINPUT_FLAG_GAMEPAD, capabilities)
Return capabilities
End Function
#Region "Digital Button States"
Public ReadOnly Property IsDPadUpPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_DPAD_UP))
End Get
End Property
Public ReadOnly Property IsDPadDownPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_DPAD_DOWN))
End Get
End Property
Public ReadOnly Property IsDPadLeftPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_DPAD_LEFT))
End Get
End Property
Public ReadOnly Property IsDPadRightPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_DPAD_RIGHT))
End Get
End Property
Public ReadOnly Property IsAPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_A))
End Get
End Property
Public ReadOnly Property IsBPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_B))
End Get
End Property
Public ReadOnly Property IsXPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_X))
End Get
End Property
Public ReadOnly Property IsYPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_Y))
End Get
End Property
Public ReadOnly Property IsBackPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_BACK))
End Get
End Property
Public ReadOnly Property IsStartPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_START))
End Get
End Property
Public ReadOnly Property IsLeftShoulderPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_LEFT_SHOULDER))
End Get
End Property
Public ReadOnly Property IsRightShoulderPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_RIGHT_SHOULDER))
End Get
End Property
Public ReadOnly Property IsLeftStickPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_LEFT_THUMB))
End Get
End Property
Public ReadOnly Property IsRightStickPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_RIGHT_THUMB))
End Get
End Property
#End Region
#Region "Analogue Input States"
Public ReadOnly Property LeftTrigger() As Integer
Get
Return CInt(gamepadStateCurrent.Gamepad.bLeftTrigger)
End Get
End Property
Public ReadOnly Property RightTrigger() As Integer
Get
Return CInt(gamepadStateCurrent.Gamepad.bRightTrigger)
End Get
End Property
Public ReadOnly Property LeftThumbStick() As Point
Get
Dim p As New Point() With { _
Key .X = gamepadStateCurrent.Gamepad.sThumbLX, _
Key .Y = gamepadStateCurrent.Gamepad.sThumbLY _
}
Return p
End Get
End Property
Public ReadOnly Property RightThumbStick() As Point
Get
Dim p As New Point() With { _
Key .X = gamepadStateCurrent.Gamepad.sThumbRX, _
Key .Y = gamepadStateCurrent.Gamepad.sThumbRY _
}
Return p
End Get
End Property
#End Region
Private _isConnected As Boolean
Public Property IsConnected() As Boolean
Get
Return _isConnected
End Get
Friend Set
_isConnected = value
End Set
End Property
#Region "Polling"
Public Shared Sub StartPolling()
If Not isRunning Then
SyncLock [SyncLock]
If Not isRunning Then
pollingThread = New Thread(AddressOf PollerLoop)
pollingThread.Start()
End If
End SyncLock
End If
End Sub
Public Shared Sub StopPolling()
If isRunning Then
keepRunning = False
End If
End Sub
Private Shared Sub PollerLoop()
SyncLock [SyncLock]
If isRunning = True Then
Return
End If
isRunning = True
End SyncLock
keepRunning = True
While keepRunning
For i As Integer = FIRST_CONTROLLER_INDEX To LAST_CONTROLLER_INDEX
Controllers(i).UpdateState()
Next
Thread.Sleep(m_updateFrequency)
End While
SyncLock [SyncLock]
isRunning = False
End SyncLock
End Sub
Public Sub UpdateState()
Dim X As New XInputCapabilities()
Dim result As Integer = XInput.XInputGetState(_playerIndex, gamepadStateCurrent)
IsConnected = (result = 0)
UpdateBatteryState()
If gamepadStateCurrent.PacketNumber <> gamepadStatePrev.PacketNumber Then
OnStateChanged()
End If
gamepadStatePrev.Copy(gamepadStateCurrent)
If _stopMotorTimerActive AndAlso (DateTime.Now >= _stopMotorTime) Then
Dim stopStrength As New XInputVibration() With { _
Key .LeftMotorSpeed = 0, _
Key .RightMotorSpeed = 0 _
}
XInput.XInputSetState(_playerIndex, stopStrength)
End If
End Sub
#End Region
#Region "Motor Functions"
Public Sub Vibrate(leftMotor As Double, rightMotor As Double)
Vibrate(leftMotor, rightMotor, TimeSpan.MinValue)
End Sub
Public Sub Vibrate(leftMotor As Double, rightMotor As Double, length As TimeSpan)
leftMotor = Math.Max(0.0, Math.Min(1.0, leftMotor))
rightMotor = Math.Max(0.0, Math.Min(1.0, rightMotor))
Dim vibration As New XInputVibration() With { _
Key .LeftMotorSpeed = CUShort(Math.Truncate(65535.0 * leftMotor)), _
Key .RightMotorSpeed = CUShort(Math.Truncate(65535.0 * rightMotor)) _
}
Vibrate(vibration, length)
End Sub
Public Sub Vibrate(strength As XInputVibration)
_stopMotorTimerActive = False
XInput.XInputSetState(_playerIndex, strength)
End Sub
Public Sub Vibrate(strength As XInputVibration, length As TimeSpan)
XInput.XInputSetState(_playerIndex, strength)
If length <> TimeSpan.MinValue Then
_stopMotorTime = DateTime.Now.Add(length)
_stopMotorTimerActive = True
End If
End Sub
#End Region
Public Overrides Function ToString() As String
Return _playerIndex.ToString()
End Function
End ClassPublic Class XboxControllerStateChangedEventArgs
Inherits EventArgs
Public Property CurrentInputState() As XInputState
Get
Return m_CurrentInputState
End Get
Set
m_CurrentInputState = Value
End Set
End Property
Private m_CurrentInputState As XInputState
Public Property PreviousInputState() As XInputState
Get
Return m_PreviousInputState
End Get
Set
m_PreviousInputState = Value
End Set
End Property
Private m_PreviousInputState As XInputState
End Class
So, a frequency must be set to retrieve the state. The state returns whats happened(what button or buttons have been pressed) and this is how I determine what I want to do. I need to check between states to see if anything has happened. This much I understand. However, the knowledge gap coming from VB.net is hindering my ability to put all of the components together.
View the full article
Here are the structures I found on http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/19b19285-ae5d-42dc-86d5-0f66619be33b
Private Declare Function XInputGetBatteryInformation Lib "xinput1_4.dll" (ByVal uJoyID As Integer, ByVal uJoyID2 As UInteger, ByRef pBatteryInformation As XINPUTBATTERYINFORMATION) As Int16
Private Declare Function XInputGetState Lib "xinput1_4.dll" (ByVal dwUserIndex As Integer, ByRef pState As XINPUTSTATE) As Boolean
Private Declare Function XInputSetState Lib "xinput1_4.dll" (ByVal dwUserIndex As Integer, ByRef pVibration As XINPUTVIBRATION) As Int16Private Declare Function XinputGetCapabilities Lib "xinput1_4.dll" (ByVal dwUserIndex As Integer, ByVal dwFlags As Integer, ByRef pCapabilities as XinputCapabilities) As Int16
Private Declare Function XinputGetKeystroke Lib "xinput1_4.dll" (ByVal dwUserIndex As Integer, ByVal dwReserved as Integer ByRef XinputKeystroke As pKeystroke) As Int16
Public Structure XINPUTBATTERYINFORMATION
Public BatteryType As Byte
Public BatteryLevel As Byte Public Overrides Function ToString() As String
Return String.Format("{0} {1}", DirectCast(BatteryType, BatteryTypes), DirectCast(BatteryLevel, BatteryLevel))
End Function
End Structure
Public Structure XINPUTGAMEPAD
Public wButtons As UInt16
Public bLeftTrigger As Char
Public bRightTrigger As Char
Public sThumbLX As Int16
Public sThumbLY As Int16
Public sThumbRX As Int16
Public sThumbRY As Int16Public Function IsButtonPressed(buttonFlags As Integer) As Boolean
Return (wButtons And buttonFlags) = buttonFlags
End Function
Public Function IsButtonPresent(buttonFlags As Integer) As Boolean
Return (wButtons And buttonFlags) = buttonFlags
End Function
Public Sub Copy(source As XInputGamepad)
sThumbLX = source.sThumbLX
sThumbLY = source.sThumbLY
sThumbRX = source.sThumbRX
sThumbRY = source.sThumbRY
bLeftTrigger = source.bLeftTrigger
bRightTrigger = source.bRightTrigger
wButtons = source.wButtons
End Sub
Public Overrides Function Equals(obj As Object) As Boolean
If Not (TypeOf obj Is XInputGamepad) Then
Return False
End If
Dim source As XInputGamepad = CType(obj, XInputGamepad)
Return ((sThumbLX = source.sThumbLX) AndAlso (sThumbLY = source.sThumbLY) AndAlso (sThumbRX = source.sThumbRX) AndAlso (sThumbRY = source.sThumbRY) AndAlso (bLeftTrigger = source.bLeftTrigger) AndAlso (bRightTrigger = source.bRightTrigger) AndAlso (wButtons = source.wButtons))
End Function
End Structure Public Structure XInputKeystroke
Public VirtualKey As Short
Public Unicode As Char
Public Flags As Short
Public UserIndex As Byte
Public HidCode As Byte
End Structure
Public Structure XINPUTSTATE
Public dwPacketNumber As Integer
Public Gamepad As XINPUTGAMEPADPublic Sub Copy(source As XInputState)
PacketNumber = source.PacketNumber
Gamepad.Copy(source.Gamepad)
End Sub
Public Overrides Function Equals(obj As Object) As Boolean
If (obj Is Nothing) OrElse (Not (TypeOf obj Is XInputState)) Then
Return False
End If
Dim source As XInputState = DirectCast(obj, XInputState)
Return ((PacketNumber = source.PacketNumber) AndAlso (Gamepad.Equals(source.Gamepad)))
End Function
End Structure
Public Structure XINPUTVIBRATION
Public wLeftMotorSpeed As UShort
Public wRightMotorSpeed As UShort
End StructurePublic Structure XInputCapabilities
Private Type As Byte
Public SubType As Byte
Public Flags As Short
Public Gamepad As XInputGamepad
Public Vibration As XInputVibration
End StructurePublic Class Point
Public Property X() As Integer
Get
Return m_X
End Get
Set
m_X = Value
End Set
End Property
Private m_X As Integer
Public Property Y() As Integer
Get
Return m_Y
End Get
Set
m_Y = Value
End Set
End Property
Private m_Y As Integer
End Class
Now lets say I want an if statement for pressing the "A" button so I can paste in code for what I want to happen. How do I go about that?
I know I need to enum some things tooublic Enum ButtonFlags As Integer
XINPUT_GAMEPAD_DPAD_UP = &H1
XINPUT_GAMEPAD_DPAD_DOWN = &H2
XINPUT_GAMEPAD_DPAD_LEFT = &H4
XINPUT_GAMEPAD_DPAD_RIGHT = &H8
XINPUT_GAMEPAD_START = &H10
XINPUT_GAMEPAD_BACK = &H20
XINPUT_GAMEPAD_LEFT_THUMB = &H40
XINPUT_GAMEPAD_RIGHT_THUMB = &H80
XINPUT_GAMEPAD_LEFT_SHOULDER = &H100
XINPUT_GAMEPAD_RIGHT_SHOULDER = &H200
XINPUT_GAMEPAD_A = &H1000
XINPUT_GAMEPAD_B = &H2000
XINPUT_GAMEPAD_X = &H4000
XINPUT_GAMEPAD_Y = &H8000
End Enum
Public Enum ControllerSubtypes
XINPUT_DEVSUBTYPE_UNKNOWN = &H0
XINPUT_DEVSUBTYPE_WHEEL = &H2
XINPUT_DEVSUBTYPE_ARCADE_STICK = &H3
XINPUT_DEVSUBTYPE_FLIGHT_STICK = &H4
XINPUT_DEVSUBTYPE_DANCE_PAD = &H5
XINPUT_DEVSUBTYPE_GUITAR = &H6
XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE = &H7
XINPUT_DEVSUBTYPE_DRUM_KIT = &H8
XINPUT_DEVSUBTYPE_GUITAR_BASS = &Hb
XINPUT_DEVSUBTYPE_ARCADE_PAD = &H13
End Enum
Public Enum BatteryTypes As Byte
BATTERY_TYPE_DISCONNECTED = &H0
BATTERY_TYPE_WIRED = &H1
BATTERY_TYPE_ALKALINE = &H2
BATTERY_TYPE_NIMH = &H3
BATTERY_TYPE_UNKNOWN = &Hff
End Enum
Public Enum BatteryLevel As Byte
BATTERY_LEVEL_EMPTY = &H0
BATTERY_LEVEL_LOW = &H1
BATTERY_LEVEL_MEDIUM = &H2
BATTERY_LEVEL_FULL = &H3
End Enum
Public Enum BatteryDeviceType As Byte
BATTERY_DEVTYPE_GAMEPAD = &H0
BATTERY_DEVTYPE_HEADSET = &H1
End Enum
Public Class XInputConstants
Public Const XINPUT_DEVTYPE_GAMEPAD As Integer = &H1
Public Const XINPUT_DEVSUBTYPE_GAMEPAD As Integer = &H1
Public Enum CapabilityFlags
XINPUT_CAPS_VOICE_SUPPORTED = &H4
XINPUT_CAPS_FFB_SUPPORTED = &H1
XINPUT_CAPS_WIRELESS = &H2
XINPUT_CAPS_PMD_SUPPORTED = &H8
XINPUT_CAPS_NO_NAVIGATION = &H10
End Enum
Public Const XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE As Integer = 7849
Public Const XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE As Integer = 8689
Public Const XINPUT_GAMEPAD_TRIGGER_THRESHOLD As Integer = 30
Public Const XINPUT_FLAG_GAMEPAD As Integer = &H1 Public Class XboxController
Private _playerIndex As Integer
Shared keepRunning As Boolean
Shared m_updateFrequency As Integer
Shared waitTime As Integer
Shared isRunning As Boolean
Shared [SyncLock] As Object
Shared pollingThread As Thread
Private _stopMotorTimerActive As Boolean
Private _stopMotorTime As DateTime
Private _batteryInformationGamepad As XInputBatteryInformation
Private _batteryInformationHeadset As XInputBatteryInformation
XInputCapabilities _capabilities;
Private gamepadStatePrev As New XInputState()
Private gamepadStateCurrent As New XInputState()
Public Shared Property UpdateFrequency() As Integer
Get
Return m_updateFrequency
End Get
Set
m_updateFrequency = value
waitTime = 1000 m_updateFrequency
End Set
End Property
Public Property BatteryInformationGamepad() As XInputBatteryInformation
Get
Return _batteryInformationGamepad
End Get
Friend Set
_batteryInformationGamepad = value
End Set
End Property
Public Property BatteryInformationHeadset() As XInputBatteryInformation
Get
Return _batteryInformationHeadset
End Get
Friend Set
_batteryInformationHeadset = value
End Set
End Property
Public Const MAX_CONTROLLER_COUNT As Integer = 4
Public Const FIRST_CONTROLLER_INDEX As Integer = 0
Public Const LAST_CONTROLLER_INDEX As Integer = MAX_CONTROLLER_COUNT - 1
Shared Controllers As XboxController()
Shared Sub New()
Controllers = New XboxController(MAX_CONTROLLER_COUNT - 1) {}
[SyncLock] = New Object()
For i As Integer = FIRST_CONTROLLER_INDEX To LAST_CONTROLLER_INDEX
Controllers(i) = New XboxController(i)
Next
UpdateFrequency = 25
End Sub
Public Event StateChanged As EventHandler(Of XboxControllerStateChangedEventArgs) = Nothing
Public Shared Function RetrieveController(index As Integer) As XboxController
Return Controllers(index)
End Function
Private Sub New(playerIndex As Integer)
_playerIndex = playerIndex
gamepadStatePrev.Copy(gamepadStateCurrent)
End Sub
Public Sub UpdateBatteryState()
Dim headset As New XInputBatteryInformation(), gamepad As New XInputBatteryInformation()
XInput.XInputGetBatteryInformation(_playerIndex, CByte(BatteryDeviceType.BATTERY_DEVTYPE_GAMEPAD), gamepad)
XInput.XInputGetBatteryInformation(_playerIndex, CByte(BatteryDeviceType.BATTERY_DEVTYPE_HEADSET), headset)
BatteryInformationHeadset = headset
BatteryInformationGamepad = gamepad
End Sub
Protected Sub OnStateChanged()
RaiseEvent StateChanged(Me, New XboxControllerStateChangedEventArgs() With { _
Key .CurrentInputState = gamepadStateCurrent, _
Key .PreviousInputState = gamepadStatePrev _
})
End Sub
Public Function GetCapabilities() As XInputCapabilities
Dim capabilities As New XInputCapabilities()
XInput.XInputGetCapabilities(_playerIndex, XInputConstants.XINPUT_FLAG_GAMEPAD, capabilities)
Return capabilities
End Function
#Region "Digital Button States"
Public ReadOnly Property IsDPadUpPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_DPAD_UP))
End Get
End Property
Public ReadOnly Property IsDPadDownPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_DPAD_DOWN))
End Get
End Property
Public ReadOnly Property IsDPadLeftPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_DPAD_LEFT))
End Get
End Property
Public ReadOnly Property IsDPadRightPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_DPAD_RIGHT))
End Get
End Property
Public ReadOnly Property IsAPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_A))
End Get
End Property
Public ReadOnly Property IsBPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_B))
End Get
End Property
Public ReadOnly Property IsXPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_X))
End Get
End Property
Public ReadOnly Property IsYPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_Y))
End Get
End Property
Public ReadOnly Property IsBackPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_BACK))
End Get
End Property
Public ReadOnly Property IsStartPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_START))
End Get
End Property
Public ReadOnly Property IsLeftShoulderPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_LEFT_SHOULDER))
End Get
End Property
Public ReadOnly Property IsRightShoulderPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_RIGHT_SHOULDER))
End Get
End Property
Public ReadOnly Property IsLeftStickPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_LEFT_THUMB))
End Get
End Property
Public ReadOnly Property IsRightStickPressed() As Boolean
Get
Return gamepadStateCurrent.Gamepad.IsButtonPressed(CInt(ButtonFlags.XINPUT_GAMEPAD_RIGHT_THUMB))
End Get
End Property
#End Region
#Region "Analogue Input States"
Public ReadOnly Property LeftTrigger() As Integer
Get
Return CInt(gamepadStateCurrent.Gamepad.bLeftTrigger)
End Get
End Property
Public ReadOnly Property RightTrigger() As Integer
Get
Return CInt(gamepadStateCurrent.Gamepad.bRightTrigger)
End Get
End Property
Public ReadOnly Property LeftThumbStick() As Point
Get
Dim p As New Point() With { _
Key .X = gamepadStateCurrent.Gamepad.sThumbLX, _
Key .Y = gamepadStateCurrent.Gamepad.sThumbLY _
}
Return p
End Get
End Property
Public ReadOnly Property RightThumbStick() As Point
Get
Dim p As New Point() With { _
Key .X = gamepadStateCurrent.Gamepad.sThumbRX, _
Key .Y = gamepadStateCurrent.Gamepad.sThumbRY _
}
Return p
End Get
End Property
#End Region
Private _isConnected As Boolean
Public Property IsConnected() As Boolean
Get
Return _isConnected
End Get
Friend Set
_isConnected = value
End Set
End Property
#Region "Polling"
Public Shared Sub StartPolling()
If Not isRunning Then
SyncLock [SyncLock]
If Not isRunning Then
pollingThread = New Thread(AddressOf PollerLoop)
pollingThread.Start()
End If
End SyncLock
End If
End Sub
Public Shared Sub StopPolling()
If isRunning Then
keepRunning = False
End If
End Sub
Private Shared Sub PollerLoop()
SyncLock [SyncLock]
If isRunning = True Then
Return
End If
isRunning = True
End SyncLock
keepRunning = True
While keepRunning
For i As Integer = FIRST_CONTROLLER_INDEX To LAST_CONTROLLER_INDEX
Controllers(i).UpdateState()
Next
Thread.Sleep(m_updateFrequency)
End While
SyncLock [SyncLock]
isRunning = False
End SyncLock
End Sub
Public Sub UpdateState()
Dim X As New XInputCapabilities()
Dim result As Integer = XInput.XInputGetState(_playerIndex, gamepadStateCurrent)
IsConnected = (result = 0)
UpdateBatteryState()
If gamepadStateCurrent.PacketNumber <> gamepadStatePrev.PacketNumber Then
OnStateChanged()
End If
gamepadStatePrev.Copy(gamepadStateCurrent)
If _stopMotorTimerActive AndAlso (DateTime.Now >= _stopMotorTime) Then
Dim stopStrength As New XInputVibration() With { _
Key .LeftMotorSpeed = 0, _
Key .RightMotorSpeed = 0 _
}
XInput.XInputSetState(_playerIndex, stopStrength)
End If
End Sub
#End Region
#Region "Motor Functions"
Public Sub Vibrate(leftMotor As Double, rightMotor As Double)
Vibrate(leftMotor, rightMotor, TimeSpan.MinValue)
End Sub
Public Sub Vibrate(leftMotor As Double, rightMotor As Double, length As TimeSpan)
leftMotor = Math.Max(0.0, Math.Min(1.0, leftMotor))
rightMotor = Math.Max(0.0, Math.Min(1.0, rightMotor))
Dim vibration As New XInputVibration() With { _
Key .LeftMotorSpeed = CUShort(Math.Truncate(65535.0 * leftMotor)), _
Key .RightMotorSpeed = CUShort(Math.Truncate(65535.0 * rightMotor)) _
}
Vibrate(vibration, length)
End Sub
Public Sub Vibrate(strength As XInputVibration)
_stopMotorTimerActive = False
XInput.XInputSetState(_playerIndex, strength)
End Sub
Public Sub Vibrate(strength As XInputVibration, length As TimeSpan)
XInput.XInputSetState(_playerIndex, strength)
If length <> TimeSpan.MinValue Then
_stopMotorTime = DateTime.Now.Add(length)
_stopMotorTimerActive = True
End If
End Sub
#End Region
Public Overrides Function ToString() As String
Return _playerIndex.ToString()
End Function
End ClassPublic Class XboxControllerStateChangedEventArgs
Inherits EventArgs
Public Property CurrentInputState() As XInputState
Get
Return m_CurrentInputState
End Get
Set
m_CurrentInputState = Value
End Set
End Property
Private m_CurrentInputState As XInputState
Public Property PreviousInputState() As XInputState
Get
Return m_PreviousInputState
End Get
Set
m_PreviousInputState = Value
End Set
End Property
Private m_PreviousInputState As XInputState
End Class
So, a frequency must be set to retrieve the state. The state returns whats happened(what button or buttons have been pressed) and this is how I determine what I want to do. I need to check between states to see if anything has happened. This much I understand. However, the knowledge gap coming from VB.net is hindering my ability to put all of the components together.
View the full article