Main Site Links Resources Tutorials
News VB Gaming Code Downloads DirectX 7
Contact Webmaster VB Programming Product Reviews DirectX 8
  General Multimedia Articles DirectX 9
      Miscellaneous

DirectInput: Joysticks
By: Jack Hoxley
Written: June 2000

Download: DI_Joystick.Zip (12kb)


Without a doubt; joysticks are a games device - you wont need to use one unless you're creating a game. I've never seen one used in a multimedia application before; and I doubt I ever will.

The joystick tends to be used more in arcade style games; sports simulations in particular. You never ever get joystick options in first person shooters; RPGs or RTS games. Even then joysticks seem to play a back hand as a controller in some games - usually as the second option. This is down to the fact that most PC games players prefer to use their keyboard (I certainly do) or mouse. Joysticks tend to be a console thing mostly. Despite this, you may well still want to use the joystick in your applications

There are several different axis available to you as a programmer; but you have to check if they're present first; my cheap £2.99 joystick only has 2 buttons and 2 axis - only the newer ones have lots of axis and lots of buttons. Here is a summary of what they are, and what they do:

Axis/Button name Use/Meaning
X Movements on the left-right axis
Y Movements up or Down
Z Movements on the Z axis; often the throttle control
rX Rotation on the X axis
rY Rotation on the Y axis
rZ Rotation on the Z axis (not very common) - usually the rudder control
frX Torque on the X axis
frY Torque on the Y axis
frZ Torque on the Z axis
fX Force on the X axis
fY Force on the Y axis
fZ Force on the Z axis
vrX Angular velocity on the X axis
vrY Angular velocity on the Y axis
vrZ Angular velocity on the Z axis
Buttons(0 to 31) An array of buttons; up to 32 buttons are supported by DirectInput
POV Point Of View Hats - controllers with up to 4 directions. The value is measured in hundredths of degrees from north (away from user).


Note that all entries listed between frX and vrZ are extended capabilites - only available on the latest, most expensive devices...

Getting input from the joystick is very easy; and isn't particularly hardware intensive (as in not going to slow things down). It is advisable that you download the sample program from the top of the page to view it in it's full state, the code below is extracted from this example.

Step1: Initialising Everything.
Because joysticks aren't an essential piece of most peoples computers you'll find that lots of people (including myself) owning cheap lunps of plastic considered hi-tech 10 years ago. Although hi-tech controllers have been around for quite a while, you will still find lots of people without 32 buttons and 200 different axis. Although enumeration isn't directly covered here it is very important to check the capabilities of the user's controller. It is essential to gameplay that a user can have control of everything - despite his/her hardware; nothing is going to put them off playing it more than dying because they didn't have button 11 to press...

Set di = dx.DirectInputCreate()
'Because DirectInput Enumerations contain information on lots of different
'devices we must specify what we're looking for - in this case we want a
'Joystick. We also want to make sure it's attached to the system. Without
'this flag, DI may detect a set of joystick drivers; and report that there is
'a joystick - even when it's not actually present.

Set diDevEnum = di.GetDIEnumDevices(DIDEVTYPE_JOYSTICK, DIEDFL_ATTACHEDONLY)
'Warn the user that there is no joystick present.
If diDevEnum.GetCount = 0 Then
MsgBox "No joystick attached."
'There is no point continuing if there is
'no joystick

Unload Me
End If

'This is the enumeration; we've got this far
'so we know there is at least one. For the purpose of
'this tutorial we'll only bother using the default (first) device
'Dim i As Integer
'For i = 1 To diDevEnum.GetCount
'There may well only be 1
' Call lstJoySticks.AddItem(diDevEnum.GetItem(i).GetInstanceName)
'Next

'Get an event handle to associate with the device

EventHandle = dx.CreateEvent(Me)

Step2: Getting hold of the joystick
It is possible for more than one joystick to be attached; and for reasons just stated above, it is quite possible one will be better than the other. This example shows you how to get hold of the default (first detected) joystick:

'Create the joystick device
Set diDev = Nothing

'Get the 1st Joystick. You'll want to enumerate available
'devices first...

Set diDev = di.CreateDevice(diDevEnum.GetItem(1).GetGuidInstance)
'Tell DirectInput we're interacting with a Joystick
diDev.SetCommonDataFormat DIFORMAT_JOYSTICK
'With the cooperativelevel set to NONEXCLUSIVE we're likely to lose the
'joystick easier - setting this to Exclusive will make it more difficult
'for windows or other applications to steal it from us.

diDev.SetCooperativeLevel Me.hWnd, DISCL_BACKGROUND Or DISCL_NONEXCLUSIVE

'Find out what device objects it has

diDev.GetCapabilities joyCaps
'Call IdentifyAxes(diDev)

'Ask for notification of events

Call diDev.SetEventNotification(EventHandle)
'Set deadzone for X and Y axis to 10 percent of the range of travel
With DiProp_Dead .lData = 1000
.lObj = DIJOFS_X
.lSize = Len(DiProp_Dead)
.lHow = DIPH_BYOFFSET
.lObj = DIJOFS_X
diDev.SetProperty "DIPROP_DEADZONE", DiProp_Dead
.lObj = DIJOFS_Y
diDev.SetProperty "DIPROP_DEADZONE", DiProp_Dead
End With

' Set saturation zones for X and Y axis to 5 percent of the range
With DiProp_Saturation
.lData = 9500
.lHow = DIPH_BYOFFSET
.lSize = Len(DiProp_Saturation)
.lObj = DIJOFS_X
diDev.SetProperty "DIPROP_SATURATION", DiProp_Saturation
.lObj = DIJOFS_Y
diDev.SetProperty "DIPROP_SATURATION", DiProp_Saturation
End With

SetProp 'See the full example for what this does; it just sets up the range of the axis

'Get the joystick
diDev.Acquire
'Me.Caption = "Joystick Sample: Querying Properties"
'Get the list of current properties
' USB joysticks wont call this callback until you play with the joystick
' so we call the callback ourselves the first time

DirectXEvent_DXCallback 0
'Poll the device so that events are sure to be signaled.
'Usually this would be done in Sub Main or in the game rendering loop.

While running = True
DoEvents
diDev.Poll
Wend

Step3: Getting input from the joystick
Input from the joystick is done through the use of DirectXEvent. This procedure is called by DirectInput everytime the user presses a button; the code that we place in this procedure is what is executed each time - so we place code that checks/updates the program based on what the user has just done:

'If we haven't initialised yet; go no further
If diDev Is Nothing Then Exit Sub

'Get the device info
On Local Error Resume Next
diDev.GetDeviceStateJoystick js
'Js should now contain all the up-to-date information
'on the joystick. Unless there was an error:

'If we lost the joystick then we want to get it back again.

If Err.Number = DIERR_NOTACQUIRED Or Err.Number = DIERR_INPUTLOST Then
diDev.Acquire
Exit Sub
End If

'A simple example of moving a dummy sprite
'around based on input from the joystick

Select Case js.x
Case 0 'Full Left
Shape1.Left = 0
Case 5000 'Middle
Shape1.Left = 1
Case 10000 'Full Right
Shape1.Left = 2
End Select

Select Case js.y
Case 0 'Full up
Shape1.Top = 0
Case 5000 'Middle
Shape1.Top = 1
Case 10000 'Full down
Shape1.Top = 2
End Select

'There is more on getting information on the axis in the complete example.

You should now be able to get information based on the X/Y coordinates of the joystick. This example doesn't pay any attention to the buttons, hats or extra axis on a joystick; but the code is available in the downloadable example (it's just commented out). You can get the full program from the top of the page; or from the downloads page.

DirectX 4 VB 2000 Jack Hoxley. All rights reserved.
Reproduction of this site and it's contents, in whole or in part, is prohibited,
except where explicitly stated otherwise.
Design by Mateo
Contact Webmaster