November 28, 2014
Hot Topics:

Direct Input 7 Joystick Class

  • August 31, 2000
  • By Jason Brooks
  • Send Email »
  • More Articles »


Environment: Win9x, Windows NT/2000, DirectX Installed

Introduction

DirectX isn't the most friendly of API's available, so here's a simple class that you can use to utilise DirectX7 for multiple Joystick Control.

Unfortunately it doesn't include ForceFeedback support as I don't have a compatible device, however if you want to add that support, the code is well commented.

To use the class, define a global variable


CDIJoystick myJoystick1;

The class will automatically enumerate all attached joysticks on the target PC upon creation.
If there are more than one attached device, you could give the games player a choice of device to use.
Alternatively, you can use multiple instances of this class so that two player games can use different joysticks for instance!

The class has the following public methods.

  • void CDIJoystick.SetHWND(HWND hwnd)
    Set the windows handle to which Direct Input Will be attached to.  Must be the Parent Window.
  • LPCDIDEVICEINSTANCE CDIJoystick.GetFirstJoystickID(void)
    Get the first Device Instance of Enumerated Devices.  Returns NULL if none attached. Must be called before proceeding Method.
  • LPCDIDEVICEINSTANCE CDIJoystick.GetNextJoystickID(void)
    Get the Next Device Instance of Enumerated Devices.  Returns NULL if no more attached.
  • void CDIJoystick.SetPreferredDevice(&myguid);
    Sets the current Joystick Device Based on it GUID
  • int CDIJoystick.HowManyButtons(void);
    Returns the number of buttons attached to the prefferred device.  0 = None or a problem with the device.  I.e. unplugged or removed from system.
  • TCHAR* CDIJoystick.GetFirstButtonName(void)
    Returns the friendly button name for the attached device. Must be called before proceeding Method.
  • TCHAR* CDIJoystick.GetNextButtonName(void)
    Returns the next friendly button name for the attached device.
  • bool CDIJoystick.PollDevice(void)
    Must be called to update joystick state information.  Returns true if data obtained.  false if there is a problem polling the device.
  • bool CDIJoystick.IsJoystickLeft(void)
    true if the joystick is being pushed left, false if not
  • bool CDIJoystick.IsJoystickRight(void)
    true if the joystick is being pushed right, false if not
  • bool CDIJoystick.IsJoystickUp(void)
    true if the joystick is being pushed up, false if not
  • bool CDIJoystick.IsJoystickDown(void)
    true if the joystick is being pushed down, false if not
  • bool CDIJoystick.IsJoystickFire(void)
    true if any of the joystick buttons are pressed, false if not
  • int CDIJoystick.IsJoystickFire(int button)
    returns true if button has been pressed, false otherwise.  Button = 0 to Number of Buttons Available -1
  • LPDIJOYSTATE2 CDIJoystick.GetJoystickStateInfo void);
    Returns a LPDIJOYSTATE2 pointer, This enables you to probe more of the functionality of the joystick if more advance features are required.
  • void CDIJoystick.RunControlPanel(void)
Start the windows control panel.

Before using or obtaining information about the device you must supply a HWND to the Parent window from which you will receive input.

If you are using MFC you can either set the HWND from the Application from using:

myJoystick1.SetHWND(m_pMainWnd->m_hWnd);

if you're inside a Dialog Based Application:


CWnd *jb=this;

myJoystick1.SetHWND(jb->m_hWnd);

if your not using MFC you will have to Initiailise COM and set HWND according to your global window

HRESULT hr=CoInitialize(NULL);

myJoystick1.SetHWND(g_hwnd);

<span class="codeComment">// Remember to CoUninitialize when exiting your application!</span>

For the purpose of demonstration, the following code snippet shows how to populate a list control with the names of each attached device to your system.

CWnd *jb=this;

myJoystick1.SetHWND(jb->m_hWnd);



<span class="codeComment">// Reset Combo Control</span>

m_ctlJoystickName.ResetContent();



LPCDIDEVICEINSTANCE lpddi=NULL;



<span class="codeComment">// Ensure you have First Joystick ID to start </span>

<span class="codeComment">// search for additional Devices!</span>

lpddi=myJoystick1.GetFirstJoystickID();



if(!lpddi)

{

 <span class="codeComment">// No joysticks have been found!</span>

 MessageBox("I have not been able to find a joystick on 

            "your system.","No Joystick Detected",

            MB_ICONHAND|MB_OK);

 OnCancel();

}

else

{



 while(lpddi)

 {

  int x=m_ctlJoystickName.AddString(lpddi->tszInstanceName);

  m_ctlJoystickName.SetItemDataPtr(x,(void*)lpddi);

  lpddi=myJoystick1.GetNextJoystickID();

 }



 m_ctlJoystickName.SetCurSel(0);

 OnSelchangeButtonNames();



 SetTimer(1,50,NULL);



 <span class="codeComment">// return TRUE unless you set the focus to a control</span>

 return TRUE; 

}

return TRUE; 

Now that the list control has been populated, You may wish to find out how many fire buttons are attached to the device.  Using a snippet from the demo project we have:

CWnd*jb=this;

myJoystick1.SetHWND(jb->m_hWnd);



LPCDIDEVICEINSTANCE lpddi=NULL;



m_ctlButtonNames.ResetContent();



int x=m_ctlJoystickName.GetCurSel();



lpddi=(LPCDIDEVICEINSTANCE)m_ctlJoystickName.GetItemDataPtr(x);



GUID myguid;



if(lpddi && ((int)lpddi!=-1))

{

 memcpy(&myguid,&(lpddi->guidInstance),sizeof(GUID));



 myJoystick1.SetPreferredDevice(&myguid);



 m_Buttons=myJoystick1.HowManyButtons();

	

 TCHAR* name=NULL;

 name=myJoystick1.GetFirstButtonName();



 while(name)

 {

  m_ctlButtonNames.AddString(name);

  name=myJoystick1.GetNextButtonName();

 }

}



m_ctlButtonNames.SetCurSel(0); 

Now that a Joystick Device has been selected, all that remains is to read the device.
You must allways all the PollDevice Method to obtain the latest joystick data.  
If you are only interested in Up, Down, Left, Right and Fire movements the following code snippet will work:

myJoystick1.PollDevice();



if(myJoystick1.IsJoystickLeft()) m_Left=true; 

else m_Left=false;



if(myJoystick1.IsJoystickRight()) m_Right=true; 

else m_Right=false;



if(myJoystick1.IsJoystickUp()) m_Up=true; 

else m_Up=false;



if(myJoystick1.IsJoystickDown()) m_Down=true; 

else m_Down=false;



if(myJoystick1.IsJoystickFire()) m_Fire=true; 

else m_Fire=false;

If on the other hand your interested in precision data, i.e. your device is analogue you can use:

myJoystick1.PollDevice();

LPDIJOYSTATE2 joy=myJoystick1.GetJoystickStateInfo();



m_XAxis.Format("%d",joy->lX);

m_YAxis.Format("%d",joy->lY);

m_ZAxis.Format("%d",joy->lZ);



m_RXAxis.Format("%d",joy->lRx);

m_RYAxis.Format("%d",joy->lRy);

m_RZAxis.Format("%d",joy->lRz);





m_FireText.Empty();



for(int i=0;i<m_Buttons;i++)

{

 if(myJoystick1.IsJoystickFire(i))

 {

  CString temp;

  temp.Format("Fire Button : %d\r\n",i);

  m_FireText+=temp;

 }

}

Downloads

Download demo project - 33 Kb
Download source - 10 Kb






Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel