| DirectInput: 
  JoysticksBy: 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 
  joystickIt 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 joystickInput 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. |