Solved

How do I access a joystick for input?

Posted on 1997-10-13
2
1,521 Views
Last Modified: 2011-04-14
I am trying to access a joystick (game controller) as input for an application. Any suggestions on how to make it work?
I need Up/Down and Select(fire)
0
Comment
Question by:schworak
2 Comments
 
LVL 9

Accepted Solution

by:
cymbolic earned 50 total points
ID: 1437481
Use your WIN API Text viewer to bring up the declare statements.  There are a series of joy.... API's that you can use to access the Joystick.  Following is some text from an article about using the Joystick in a game environment:

Programming the Joystick
In DirectInput lingo, the term joystick also encompasses game pads, flight yokes, pedal systems, and similar devices. I'll use the term here with a similar range of meaning.
You can read the joystick either through Windows messages or by polling. In the first method, a window "captures" the joystick with joySetCapture so that the window is notified whenever the joystick is moved or a button is pressed. This makes it possible to turn the stick into a pointing device like the mouse: you can move a pointer on the screen every time the angle of the stick is altered. Moby Dick, however, is concerned with the position of the joystick on each pass through the game loop rather than with the stick's actual movements, so you want to use joyGetPosEx to do your own polling rather than monitoring the message queue.
Another reason not to use joySetCapture is that joystick messages are limited to three axes of movement (left-right, forward-back, and throttle, for example) and four buttons. This obviously won't do for a modern input device like the Microsoft Sidewinder 3D Pro, which has eight buttons, a point-of-view hat, and four axes of movement (including a throttle slider and a twisting motion on the stick itself). For the latest joysticks and game pads you definitely need the power of joyGetPosEx, which returns the state of up to 32 buttons, six axes, and the POV hat, besides transparently supporting both digital and analog devices.
The API reference advises using the old joyGetPos function for joystick devices that employ no more than three axes and four buttons. It's true that joyGetPos is a bit simpler to implement, but joyGetPosEx works with all joysticks, and I see no reason not to use it exclusively.
To include the extended joystick services in your program, you need to link to WINMM.LIB and include MMSYSTEM.H.
Detecting the Joystick
To detect the primary joystick, simply call joyGetPosEx with the JOYSTICKID1 argument:
 
JOYINFOEX joyInfoEx;
ZeroMemory(joyInfoEx, sizeof(joyInfoEx);
joyInfoEx.dwSize = sizeof(joyInfoEx);
BOOL JoyPresent = (joyGetPosEx(JOYSTICKID1, &joyInfoEx) == JOYERR_NOERROR);
 
The function returns an error (nonzero) if the joystick is not properly installed in Windows or is simply unplugged.
Note that, as with many of the other DirectX functions, you have to let joyGetPosEx know how big a structure it has to fill—annoying, but necessary for forward compatibility. On the bright side, you don't have to worry about the dwFlags field here, since you don't require any of the values returned in the structure.
Calibrating the Joystick
You don't need to. (Hey, I'm starting to like this Windows stuff!) The user is responsible for selecting and calibrating the joystick under Control Panel. If you want to give the user a chance to do this from the game menu, just call the applet:
 
WinExec("control joy.cpl", SW_NORMAL);
 
The "Dead Zone"
In Moby Dick MS-DOS, I did some arithmetic in order to create a "dead zone" around the center of the X and Y axes. Without this zone it would be almost impossible to move the ship along just one axis, as the slightest deviation of the joystick on the other axis would cause the ship to move diagonally.
At first glance it appears that joyGetPosEx is going to simplify life by setting up an automatic dead zone. To quote the API reference, the JOY_USEDEADZONE flag "expands the range for the neutral position of the joystick and calls this range the dead zone. The joystick driver returns a constant value for all positions in the dead zone."
The wording is a bit confusing, and using the dead zone is a bit more complicated than the rather terse documentation suggests. First of all, it's your responsibility to put the dead zone boundaries in the registry (under the keys defined in REGSTR.H) and then notify the system by calling joyConfigChanged. After you've done that, you still have to figure out the constant value returned for the dead zone. (One way to do it is to set the dead zone to the same size as the whole range of the joystick, read the axis positions, and then reset the dead zone to the size you actually want.) And finally, when you close your program you really should restore the original registry values, because other applications may expect the defaults.
All in all, it's simpler for us to maintain your own dead zone. You'll do the arithmetic in Moby Dick Windows just as in the MS-DOS version.
Using the Throttle
Just for fun, and to show you how easy it is to read any of the joystick controls, I've added a throttle to Ahab's ship in Moby Dick Windows. This will work with any device that has a third—or a Z axis—in addition to the X and Y axes on the stick itself. Typically the third axis is controlled by a slider or wheel on the base of the unit.
This is all you have to do to get the throttle information:
 
JOYCAPS   joyCaps;
JOYINFOEX joyInfoEx;

ZeroMemory(joyInfoEx, sizeof(joyInfoEx);

// see whether a throttle is available
joyGetDevCaps(JOYSTICKID1, &joyCaps, sizeof(joyCaps));
BOOL JoyHasThrottle = (joyCaps.wCaps & JOYCAPS_HASZ);

// if so, read its position
if (JoyHasThrottle)
{
  joyInfoEx.dwSize = sizeof(joyInfoEx);
  joyInfoEx.dwFlags = JOY_RETURNZ;
  joyGetPosEx(JOYSTICKID1, &joyInfoEx);
}
 
Now joyInfoEx.dwZpos gives you the position of the throttle. You can calculate its relative position from the wZmin and wZmax fields of joyCaps.
You can, of course, combine JOY_RETURNZ with other flags (using the "or" operator) to get information on the stick position, button states, and so on, with a single call.
Besides X, Y, and Z, three other axes can be monitored: R (for Rudder), U, and V. These will accommodate foot pedals, twisting sticks, and various other sliders, knobs, and dials, but not the POV hat, whose position is returned instead in the dwPOV field of the JOYINFOEX structure. (I'm looking forward to implementing the hat in the 3-D version of Moby Dick!)


Your declares would be in VB:

Declare Function joyGetPos Lib "winmm.dll" Alias "joyGetPos" (ByVal uJoyID As Long, pji As JOYINFO) As Long

Declare Function joyGetPosEx Lib "winmm.dll" Alias "joyGetPosEx" (ByVal uJoyID As Long, pji As JOYINFOEX) As Long


0
 
LVL 1

Expert Comment

by:lmarceau
ID: 1437482
Thanks verry much. I had never used the joystick before and wasn't sure where to start. This will work well for me.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now