Click here to Skip to main content
12,299,086 members (52,703 online)
Click here to Skip to main content
Add your own
alternative version

Stats

25.6K views
2.4K downloads
15 bookmarked
Posted

Joystick Driver Project

, 10 Feb 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
Need to control something with a Joystick in Windows? Here is an easy to use driver that will help you do it.

Introduction

When I wanted to create a Joystick driver so I could control my robot via a joystick plugged into my computer one of the first thing I did was look for a simple joystick driver that could set up everything for me and give me the readings I wanted without me having to code anything myself or even understand how it works.   Unfortunately, despite all the people using joysticks in their programs and projects before me, it seems I couldn’t find anyone had created anything like what I was looking for and shared it online.

So if no one else had done it I decided I would do it myself. Thus I began this project to create a portable and reusable universal joystick driver that anyone could use to easily implement joystick control in their programs. This driver uses the Joystick sample program from the DirectX SDK, as its foundation.

If you know what you’re doing it isn’t that hard to write a simple program to get some readings from a joystick. But if you don’t know what you’re doing learning all about direct input in order to create your own joystick driver isn’t easy. Given I didn’t and still don’t know what the hell I’m doing I decided to adapt the sample code from the SDK rather than writing a driver from scratch. This probably ended up being more difficult for me in the long run, however the sample code from the SDK is very comprehensive and robust program that will acquire and accept any joystick device you plug in, giving me what I believe is a better result than I could have produced otherwise.

My driver is meant to handle Joystick stuff only so all the GUI related code from the sample program has been removed making it all considerably smaller and simpler.

This driver packages all your joystick needs into a Joystick class which gets all your joystick readings. You can read 8 possible axis/sliders, four possible POV/hats and 128 possible buttons.

Here is a test GUI showing readings from a twist handle Joystick



An altered version for the test GUI of a steering wheel set

Just tell me how to use it already!

Step 1

Download the files and add the Joystick_Driver.h, Joystick_Driver.cpp and resorce.h to your project


Step 2

Make sure the linker can find all your required external dependencies: windows.h, commctrl.h, dinput.h, dinputd.h, assert.h, and wbemidl.h and additional dependencies. If your project is in Visual studio, right click on your project and go to properties. In the properties window go to...

Configuration
properties->linker->input->additional dependencies->edit

Then add

dxguid.lib, dinput8.lib, comctl32.lib

At the moment I am yet to try using this in another IDE but you should need to do for whatever IDE you may be trying to use this in.


Step 3

Now for the easy part

Declare the following

Joystick* myJoystick; //pointer to joystick object
HWND hWnd; //window handler

Where appropriate initialize

myJoystick = new Joystick();
hWnd = //define a handle to the window of your application with the appropriate syntax

Step 4

Create a timer driven function call to run the joystick.

Using a while loop is a bad idea. Especially if you have a GUI that you don’t want to have freezing up on you.

You can check that things work using a while loop but in the end you are going to need a timer driven function call regardless.

Configure your timer to go off 20-30 times a second or at intervals of 30ms-50ms.


Step 5

In your timer driven function you may have something as simple as

Void timerFunct()
{
  myJoystick->runJoystick(hWnd); 
//only update readings while a joystick is available
if(myJoystick->getmsg() == WM_TIMER)
  {
  XAxis = myJoystick->getXAxis();
  YAxis = myJoystick->getYAxis();
  ZRot = myJoystick->getZRot();
  Slider1 = myJoystick->getSlider0();

  POV1 = myJoystick->getPOV0();

  Button0 = myJoystick->getButton(0);
  Button1 = myJoystick->getButton(1);
  Button2 = myJoystick->getButton(2);
  Button3 = myJoystick->getButton(3);
  Button4 = myJoystick->getButton(4);
  }
}

This should give you the gist of how to use it. For a proper working example consider the next section.

Windows Form Application Example

Design a form application while following this example and add in the following code where needed in your form.h.

#include "Joystick_Driver.h"

public ref class Form1 : public System::Windows::Forms::Form
{
public:
    Form1(void)
    {
        InitializeComponent();
        this->JS = new Joystick();
        this->hWnd = static_cast<HWND>(this->Handle.ToPointer());
    }
    ~Form1()
    {
        if (components)
        {
            delete components;
        }
    }

//***********Here there be lots of************
//private: System::Windows::Forms::Stuff^  stuff;
//********************************************

private:
    Joystick* JS; //pointer to joystick object
private:
    HWND hWnd; //window handler

    #pragma region Windows Form Designer generated code

    void InitializeComponent(void)
    {
        //******** Here there be lots of ********
        //this->stuff->stuff = stuff;
        //***************************************
    }
    #pragma endregion

    //your own functions go here
};


In the design view add a timer to your form


Don’t forget to set the timer properties

You will now have a function in your form

private: System::Void timer1_Tick(System::Object^  sender, System::EventArgs^  e) {
}

In the design view double click the Run and Stop buttons and use these button click event functions to enable and disable the timer.

private: System::Void Run_Click(System::Object^  sender, System::EventArgs^  e)
{
    this->timer1->Enabled = true;
}

private: System::Void Stop_Click(System::Object^  sender, System::EventArgs^  e)
{
    this->timer1->Enabled = false;
}

Add the following to the timer tick function

private: System::Void timer1_Tick(System::Object^  sender, System::EventArgs^  e)
{

    this->JS->runJoystick(this->hWnd);
    //only update readings on GUI while a joystick is available
    if(this->JS->getmsg() == WM_TIMER)
    {
        this->XAxis->Text = (this->JS->getXAxis()).ToString();
        this->YAxis->Text = (this->JS->getYAxis()).ToString();
        this->ZAxis->Text = (this->JS->getZAxis()).ToString();
        this->XRot->Text = (this->JS->getXRot()).ToString();
        this->YRot->Text = (this->JS->getYRot()).ToString();
        this->ZRot->Text = (this->JS->getZRot()).ToString();

        this->Slider1->Text = (this->JS->getSlider0()).ToString();
        this->Slider2->Text = (this->JS->getSlider1()).ToString();

        this->POV1->Text = (this->JS->getPOV0()).ToString();
        this->POV2->Text = (this->JS->getPOV1()).ToString();
        this->POV3->Text = (this->JS->getPOV2()).ToString();
        this->POV4->Text = (this->JS->getPOV3()).ToString();

        this->Button0->Checked = this->JS->getButton(0);
        this->Button1->Checked = this->JS->getButton(1);
        this->Button2->Checked = this->JS->getButton(2);
        this->Button3->Checked = this->JS->getButton(3);
        this->Button4->Checked = this->JS->getButton(4);
        this->Button5->Checked = this->JS->getButton(5);
        this->Button6->Checked = this->JS->getButton(6);
        this->Button7->Checked = this->JS->getButton(7);
        this->Button8->Checked = this->JS->getButton(8);
        this->Button9->Checked = this->JS->getButton(9);
        this->Button10->Checked = this->JS->getButton(10);
        this->Button11->Checked = this->JS->getButton(11);
        this->Button12->Checked = this->JS->getButton(12);
        this->Button13->Checked = this->JS->getButton(13);
        this->Button14->Checked = this->JS->getButton(14);
        this->Button15->Checked = this->JS->getButton(15);
        this->Button16->Checked = this->JS->getButton(16);
        this->Button17->Checked = this->JS->getButton(17);
        this->Button18->Checked = this->JS->getButton(18);
    }

}

Running the program

All Axis and Sliders should read within the range of -1000 to 1000. The POV will give 8 different values for all 8 directions and all buttons will simply read true or false.

Notes on functionality

You may need to delve into the driver and add your own code to it in order to do certain things. Depending on your application you are going to have to consider...

What happens when you disconnect the joystick?

At this time the diver will automatically look for another joystick and will accept any joystick it finds whether it be the same joystick once it’s plugged back in or another joystick that is already plugged in or is to be plugged in.

What happens to the readings when you disconnect the joystick?

Do you want them to freeze at the last updated value or do you want everything to go back to its default zero position?

At this time the driver freezes the readings at the last read value if the joystick disconnects.

What happens when you have two or more joysticks plugged in?

You may want to be able to choose a joystick device, or you may want to switch between joysticks while you program is running, or you may wish to have two or more joysticks working at the same time.

At this time the driver doesn’t support multiple joysticks, but it could be adapted to do so. What it will do is create a list of joystick devices and pick one of them automatically. So you can’t choose which joystick.

You can switch devices while the program is running but this means you need to physically unplug them and plug them in.

What if you want to accept inputs only from a specific type of joystick?

The driver has the capacity to recognise the Axis and Buttons that the connected joystick has available so to some degree you could implement this.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Work Damnit!
Student
Australia Australia
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionLink problems Pin
Member 118454863-Mar-16 5:04
memberMember 118454863-Mar-16 5:04 
QuestionPro! Which Project should I create? Pin
Member 1203295714-Oct-15 16:40
memberMember 1203295714-Oct-15 16:40 
QuestionThanks a lot Pin
Member 119642537-Sep-15 0:18
memberMember 119642537-Sep-15 0:18 
QuestionC++ CONSOLE APPLICATION Pin
majdi8611-May-15 21:56
membermajdi8611-May-15 21:56 
QuestionLinker problems Pin
Alan Laplace20-Mar-15 4:28
memberAlan Laplace20-Mar-15 4:28 
AnswerRe: Linker problems Pin
Member 1215015122-Nov-15 12:52
memberMember 1215015122-Nov-15 12:52 
QuestionPolling while host window is minimized Pin
Member 88477853-Mar-15 4:43
memberMember 88477853-Mar-15 4:43 
Questionhow to complete step 3 ? please help Pin
Muh Rifai Anugrah29-Jan-15 1:33
memberMuh Rifai Anugrah29-Jan-15 1:33 
Questionplease help me !!! Pin
Muh Rifai Anugrah28-Jan-15 3:11
memberMuh Rifai Anugrah28-Jan-15 3:11 
GeneralI needed this Pin
Siri Vivienne MK Ancheta1-Dec-14 0:36
memberSiri Vivienne MK Ancheta1-Dec-14 0:36 
QuestionLinker Error in Project Pin
Member 1097292119-Aug-14 3:58
memberMember 1097292119-Aug-14 3:58 
AnswerRe: Linker Error in Project Pin
dan o10-Nov-14 4:13
memberdan o10-Nov-14 4:13 
QuestionCan You Post The Source Code Pin
Member 100427455-Jan-14 9:16
memberMember 100427455-Jan-14 9:16 
QuestionMore than one joystick Pin
patoigz11-Sep-13 3:39
memberpatoigz11-Sep-13 3:39 
QuestionJoystick Initialization Problem Pin
Member 98106329-Jul-13 13:18
memberMember 98106329-Jul-13 13:18 
QuestionJoystick support Pin
Pasteko13-Feb-13 6:06
memberPasteko13-Feb-13 6:06 
AnswerRe: Joystick support Pin
Work Damnit!13-Feb-13 13:44
memberWork Damnit!13-Feb-13 13:44 
GeneralRe: Joystick support Pin
Pasteko14-Feb-13 11:09
memberPasteko14-Feb-13 11:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.160525.2 | Last Updated 10 Feb 2013
Article Copyright 2013 by Work Damnit!
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid