Hi Daniel,
After some research I found some libraries to try. SlimDX or SharpDX seems easy to get to work but their .dlls needs to be on the runtime machine.
I’m complete newbie on .NET so I don’t know if it’s possible to compile the used parts of the dlls as “static” as to avoid runtime dlls.
Then there’s Brandon Potters XBoxController
But since I don’t like the idea of having those extra dlls hanging around, I will evaluate also the package “Xbox Controller SDK 1.0.0” which is said to have no dependencies:
Well, this is what I found after a day’s search.
I already started trying out SharpDX, and it seems simple enough, except for the need to place the dll.s in the same .gha library (unless there’s a solution for this). SharpDX seems to cover most drivers so I will try to make something to work.
For a “jump start” with SharpDX I just got the following to work (no loop for continual reading of XInput values included). Can GH’s time component be accessed from code like in this case, somehow? As an old Delphi guy I find VB.NET convenient enough :
Imports System.Collections.Generic
Imports Grasshopper.Kernel
Imports Rhino.Geometry
Imports SharpDX.XInput
Public Class XBoxOneControlComponent
Inherits GH_Component
Public Const GC_Output_Debug = 0
Public Const GC_Output_Running = 1
Public Const GC_Output_RightThumbX = 2
Public Const GC_Output_RightThumbY = 3
Public M_DEBUG_DA As IGH_DataAccess
'// --------------------------------------------------------
Public Sub New()
'| Abbreviation (Name)
'| Description
'| Category ; Main TAB
'| SubCategory ; Group within TAB
MyBase.New("XBox One Game Control", "XBoxOne",
"Reads input from XBox One Game Controller.",
"UI", "Game")
End Sub
'// --------------------------------------------------------
''' <summary>
''' INPUT - parameters for this component.
''' </summary>
Protected Overrides Sub RegisterInputParams(ByVal pManager As GH_Component.GH_InputParamManager)
pManager.AddBooleanParameter("Scan", "S", "Scans the XBox Controller for signals", 0)
End Sub
'// --------------------------------------------------------
''' <summary>
''' OUTPUT - parameters for this component.
''' </summary>
Protected Overrides Sub RegisterOutputParams(ByVal pManager As GH_Component.GH_OutputParamManager)
pManager.AddTextParameter("Debug", "Debug", "Debug channel for development only.", GH_ParamAccess.item)
pManager.AddBooleanParameter("Running", "R", "The XBox Controller Is scanned for input", GH_ParamAccess.item)
pManager.AddNumberParameter("RightThumbX", "RTX", "Right Thumb X", GH_ParamAccess.item)
pManager.AddNumberParameter("RightThumbY", "RTY", "Right Thumb Y", GH_ParamAccess.item)
End Sub
'// --------------------------------------------------------
''' <summary>
''' USed only during development to log code progress/success in the Debug output of the component
''' </summary>
Protected Sub DebugMsg(msg As String)
M_DEBUG_DA.SetData(GC_Output_Debug, New String(msg))
End Sub
'// --------------------------------------------------------
Protected Overrides Sub SolveInstance(DA As IGH_DataAccess)
'// --------------------------------------------------------
'// Example of Dead zones sensitivity
'// --------------------------------------------------------
'Dim LStick_DeadZone As Integer = 7849
'Dim RStick_DeadZone As Integer = 8689
'Dim LTrigger_Threshold As Integer = 30
'Dim RTrigger_Threshold As Integer = 30
'// --------------------------------------------------------
'// Enable the Sub DebugMsg to use DA parameter for output
'// --------------------------------------------------------
M_DEBUG_DA = DA
'// Variable activating this GH component to read the XBox Controller (once).
'//
'// TODO: Loop to read values. What about GH's Timer component?
'//
Dim DoScan As Boolean = False
'// --------------------------------------------------------
'// Use the DA object to retrieve the data inside the first input parameter.
'// If the retieval fails (for example if there is no data) we need to abort.
'// --------------------------------------------------------
If (Not DA.GetData(0, DoScan)) Then Return
'// --------------------------------------------------------
'// Set Chained Output
'// --------------------------------------------------------
DA.SetData(GC_Output_Running, DoScan)
'// --------------------------------------------------------
'// GAME CONTROLLER
'// --------------------------------------------------------
If Not DoScan Then
DA.SetData(GC_Output_RightThumbX, 0)
DA.SetData(GC_Output_RightThumbY, 0)
DebugMsg("No DoScan")
Else
DebugMsg("OK, Scanning...")
'//------------------------------------------------------
'// Type: SharpDX.XInput.Controller
'//------------------------------------------------------
Dim controllers As New List(Of Controller)
Dim gc As Controller = Nothing
gc = New Controller(UserIndex.One)
controllers.Add(gc)
'// Disabled (for now) the other three controllers that can potentially
'// be active simultaneously
'controllers.Add(New Controller(UserIndex.Two))
'controllers.Add(New Controller(UserIndex.Three))
'controllers.Add(New Controller(UserIndex.Four))
'//------------------------------------------------------
'// Pick (first) Game Controller (gc)
'//------------------------------------------------------
For Each selectController In controllers
If selectController.IsConnected Then
gc = selectController
DebugMsg("One Controller found.")
Exit For
End If
DebugMsg("No Controller found! :( ")
Next
'//------------------------------------------------------
'// OUTPUT GamePad values, if connected
'//------------------------------------------------------
If gc IsNot Nothing AndAlso gc.IsConnected Then
Dim g_state = gc.GetState()
DA.SetData(GC_Output_RightThumbX, g_state.Gamepad.RightThumbX)
DA.SetData(GC_Output_RightThumbY, g_state.Gamepad.RightThumbY)
'// ...
'// aso
'// ...
Else
DA.SetData(GC_Output_RightThumbX, 0)
DA.SetData(GC_Output_RightThumbY, 0)
'// ...
'// aso
'// ...
End If
End If
End Sub '// SolveInstance
'// --------------------------------------------------------
Protected Overrides ReadOnly Property Icon() As System.Drawing.Bitmap
Get
Return Nothing
End Get
End Property
'// --------------------------------------------------------
Public Overrides ReadOnly Property ComponentGuid() As Guid
Get
Return New Guid(" .... your guid ... ")
End Get
End Property
End Class
// Rolf