Using Game Pads and Joysticks for User Input

While the basic idea of the joystick device is quite similar to the mouse and keyboard (since they do share the same device class), there are a few other things that need to happen for these, since they are much less standardized. You can pretty much guarantee that there will be two buttons on a mouse, and the keyboard will have at least 36 keys. Joysticks and game pads, on the other hand, come in all shapes and sizes. You may have one with two axes and two buttons, and then another with 3 axes, 10 buttons, two throttles, a pedal, and who knows what else.

There's also no default SystemGuid member for creating a joystick. You will need to enumerate the joysticks first. Update the device creation function using Listing 15.4.

Listing 15.4 Initializing DirectInput for Joysticks
 public bool InitializeInput() {     // Create our joystick device     foreach(DeviceInstance di in Manager.GetDevices(DeviceClass.GameControl,         EnumDevicesFlags.AttachedOnly))     {         // Pick the first attached joystick we see         device = new Device(di.InstanceGuid);         break;     }     if (device == null) // We couldn't find a joystick         return false;     device.SetDataFormat(DeviceDataFormat.Joystick);     device.SetCooperativeLevel(this, CooperativeLevelFlags.Background |        CooperativeLevelFlags.NonExclusive);     device.Properties.AxisModeAbsolute = true;     device.Acquire();     while(running)     {         UpdateInputState();         Application.DoEvents();     }     return true; } 

Here you do the enumeration discussed at the beginning of this chapter to try to find an attached joystick or game pad. Since you didn't create the device with a system GUID, you will need to inform DirectInput about the type of device this is so that it knows how to interpret the data. You do this with the SetDataFormat method. A return value for the method has also been added so that the caller can know if the device creation has failed (because there is no device to create). With this, you will need to update the main function to handle this case:

 static void Main() {     using (Form1 frm = new Form1())     {         frm.Show();         if (!frm.InitializeInput())             MessageBox.Show("Couldn't find a joystick.");     } } 

Now, joysticks normally have a few axes that can be manipulated, and the range of these axes is unknown normally. You should treat all of the axes the same, with a "resolution" of 10,000 units. It's entirely possible that the device doesn't support this resolution, but DirectInput will fake it for you. You need to find the axes on the joystick and update the range. Add this code immediately after the device has been created:

 // Enumerate any axes foreach(DeviceObjectInstance doi in device.Objects) {     if ((doi.ObjectId & (int)DeviceObjectTypeFlags.Axis) != 0)     {         // We found an axis, set the range to a max of 10,000         device.Properties.SetRange(ParameterHow.ById,             doi.ObjectId, new InputRange(-5000, 5000));     } } 

Any device's objects can be enumerated in this fashion. Doing this on a keyboard, for example, will return an object for every key on the keyboard. Here, you only care about the axes that are found, and then you update the property of that object (doing so by ID) to ensure that the range falls within the values specified. The last thing you need to do is to update the UI. Update that method as follows:

 private void UpdateInputState() {     // Check the joystick state     JoystickState state = device.CurrentJoystickState;     string joyState = "Using JoystickState: \r\n";     joyState += string.Format("{0}x{1}",         state.X, state.Y);     textBox1.Text = joyState; } 

You could spend the time to use the preceding enumeration and detect every item in the joystick and update the UI, but the exercise doesn't really teach you anything you don't already know, so for this example, only update the x and y axes, which most all joysticks should have. The method looks remarkably like the mouse method, since the two aren't that dissimilar.

SHOP TALK: CONTROLLING THE RANGE

Game pads (and non-analog joysticks in general) will normally jump from one extreme of the range to the other. In the example earlier, when the game pad is "at rest", the value would naturally be 0. If you pressed the pad to the left, the x axis would go instantly to the minimum range value, while pressing right goes instantly to the maximum range value. There isn't any "smooth" movement of the values as you move the axis to the left; the values simply jump from one extreme to the other.

Most joysticks fall into one of two categories: a digital joystick or an analog joystick. The digital joystick is what was just described. There isn't a range of motion for pressing the axis to the left; it either happens or it does not. Analog joysticks, on the other hand, have this range built in. A good example of this is the flight controller sticks. There is a wide range of motion when moving the axes on these joysticks, and that wide range of motion can be seen when tracking the data.



Managed DirectX 9 Graphics and Game Programming, Kick Start
Managed DirectX 9 Kick Start: Graphics and Game Programming
ISBN: B003D7JUW6
EAN: N/A
Year: 2002
Pages: 180
Authors: Tom Miller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net