Tricks of the Windows Game Programming Gurus:Uplinking with DirectInput and Force Feedback

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

Purpose:

`DInput_Shutdown()` releases all the COM objects and any resources allocated during the call to `DInput_Init()`. Normally, you would call `DInput_Shutdown()` at the very end of your application, after you have released all the input devices themselves. We’ll get to that shortly. Anyway, here’s an example of shutting down the input system:

    DInput_Shutdown();

Function Prototype:

    DInput_Init_Keyboard(void);

Purpose:

`DInput_Init_Keyboard()` initializes and acquires the keyboard. This should always work and return True, unless another DirectX application has taken over in a really uncooperative way. Here’s an example:

    if (!DInput_Init_Keyboard())

       { /* error */ }

Function Prototype:

    int DInput_Init_Mouse(void);

Purpose:

`DInput_Init_Mouse()` initializes and acquires the mouse. The function takes no parameters and returns True if successful and False otherwise. But it should always work, unless a mouse isn’t plugged in or there’s another DirectX application that has totally taken over! If everything goes well, `lpdimouse` becomes the valid interface pointer. Here’s an example:

    if (!DInput_Init_Mouse()) { /* error */ }

Function Prototype:

    int DInput_Init_Joystick(int min_x=-256, // min x range

                    int max_x=256,  // max x range

                    int min_y=-256, // min y range

                    int max_y=256,  // max y range

                    int dead_zone=10); // dead zone in percent

Purpose:

`DInput_Init_Joystick()` initializes the joystick device for use. The function takes five parameters, which define the X-Y range of motion of the data sent back from the joystick and the dead zone as a percentage. If you want to use the defaults of -256 to 256 and a 10 percent dead zone for each axis, you need not send parameters because they have default values (it’s a C++ thing).

If the call returns back a True, a joystick was found and has been set up, initialized, and acquired. After the call, the interface pointer `lpdijoy` will be valid if you need it for anything. In addition, the string `joyname[]` will contain the “friendly” name of the joystick device, such as Microsoft Sidewinder Pro and so on.

Here’s an example of initializing the joystick and setting its X-Y ranges to -1024 to 1024, with a 5 percent dead zone:

    if (!DInput_Init_Joystick(-1024, 1024, -1024, 1024, 5))

       { /* error */ }

Function Prototype(s):

    void DInput_Release_Joystick(void);

    void DInput_Release_Mouse(void);

    void DInput_Release_Keyboard(void);

Purpose:

`DInput_Release_Joystick()`, `DInput_Release_Mouse()`, and `DInput_Release_Keyboard()` release each of those respective input devices when you’re done with them. The functions can be called even if you haven’t initialized those respective devices, so you can just call them all at the end of your application if you want. Here’s a complete example of starting up the DirectInput system, initializing all the devices, and then releasing them and shutting down:

    // initialize the DirectInput system

    DInput_Init();

    // initialize all input devices and acquire them

    DInput_Init_Joystick();

    DInput_Init_Mouse();

    DInput_Init_Keyboard();

    // input loop ....do work here

    // now done...

    // first release all devices, order is unimportant

    DInput_Release_Joystick();

    DInput_Release_Mouse();

    DInput_Release_Keyboard();

    // shutdown DirectInput

    DInput_Shutdown();

Function Prototype:

    int DInput_Read_Keyboard(void);

Purpose:

`DInput_Read_Keyboard()` scans the keyboard state and places the data in `keyboard_state[]`, which is an array of 256 bytes. This is the standard DirectInput keyboard state array, so you must use the DirectInput key constant `DIK_*` if you want to make sense of it. If a key is pressed, the array value will be 0×80. Here’s an example of testing if the right and left keys are down using the manifest constants in DirectInput (which you can look up in the SDK or the abridged Table 9.4):

    // read the keyboard

    if (!DInput_Read_Keyboard())

       { /* error */ }

    // now test the state data

    if (keyboard_state[DIK_RIGHT]

       { /* move ship right */ }

    else

    if (keyboard_state[DIK_LEFT]

       { /* move ship left */ }

Function Prototype:

    int DInput_Read_Mouse(void);

Purpose:

`DInput_Read_Mouse()` reads the relative mouse state and stores the result in `mouse_state,` which is a `DIMOUSESTATE` structure. The data is in relative delta mode. In most cases you’ll only need to look at `mouse_state.lX`, `mouse_state.lY`, and `rgbButtons[0..2]`, which are Booleans for the three mouse buttons. Here’s an example of reading the mouse and using it to move a cursor around and draw:

    // read the mouse

    if (!DInput_Read_Mouse())

       { /* error */ }

    // move cursor

    cx+=mouse_state.lX;

    cy+=mouse_state.lY;

    // test if left button is down

    if (mouse_state.rgbButtons[0])

       Draw_Pixel(cx,cy,col,buffer,pitch);

Function Prototype:

    int DInput_Read_Joystick(void);

Purpose:

`DInput_Read_Joystick()` polls the joystick and then reads the data into `joy_state`, which is a `DIJOYSTATE` structure. Of course, if there isn’t a joystick plugged in, the function returns False and `joy_state` will be invalid, but you get the idea. If it’s successful, `joy_state` contains the state information of the joystick. The data returned will be in the range you previously set for each axis, and the button values are Booleans in `rgbButtons[]`. For example, here’s how you would use the joystick to move a ship right and left, and use the first button to fire:

    // read the joystick data

    if (!DInput_Read_Joystick())

        { /* error */ }

> Note: Even though you’re using the `IDIRECTINPUTDEVICE2` interface, you don’t need to use the `DIJOYSTATE2` structure; that’s only for force feedback devices.

    // move the ship

    ship_x+=joy_state.lX;

    ship_y+=joy_state.lY;

    // test for trigger

    if (joy_state.rgbButtons[0])

       { // fire weapon // }

Of course, your joystick may have a lot of buttons and multiple axes. In that case, you can use the other fields of `joy_state` as defined in the `DIJOYSTATE` DirectInput structure.

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.