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

At this point, you have the structures `keystate[]`, `mousestate`, and `joystate` ready to go. Here’s a function that would do the job:

    void Merge_Input(INPUT_EVENT_PTR event_data, // the result

                     UCHAR *keydata, // keyboard data

                     LPDIMOUSESTATE mousedata, // mouse data

                     LPDIJOYSTATE  joydata) // joystick data

    {

    // merge all the data together

    // clear the record to be safe

    memset(event_data,0,sizeof(INPUT_EVENT));

    // first the fire button

    if (mousedata->rgbButtons[0] || joydata->rgbButtons[0] ||

        keydata[DIK_LCONTROL])

    event_data->fire = 1;

    // now the special button

    if (mousedata->rgbButtons[1] || joydata->rgbButtons[1] ||

        keydata[DIK_ESCAPE])

    event_data->special = 1;

    // now the x-axis

    if (mousedata->lX > 0 || joydata->lX > 32 ||

        keydata[DIK_RIGHT])

    event_data->dx = 1;

    // now the -x-axis

    if (mousedata->lX < 0 || joydata->lX < -32 ||

        keydata[DIK_LEFT])

    event_data->dx = -1;

    // and the y-axis

    if (mousedata->lY > 0 || joydata->lY > 32 ||

        keydata[DIK_DOWN])

    event_data->dy = 1;

    // now the -y-axis

    if (mousedata->lY < 0 || joydata->lY < -32 ||

        keydata[DIK_UP])

    event_data->dy = -1;

    } // end Merge_Data

Killer, huh? Of course, you can make this much more sophisticated by checking if the device is actually online, scaling the data, and so on, but you get the idea.

### Going Deeper with Force Feedback

Force feedback is really a massive topic. I had no idea how complex it was until I tried playing with it. Alas, I’m not going to go into it in any depth. A whole book could be written just about force feedback (and DirectMusic for that matter, but that’s another story). However, I am going to give you an idea of what it is, and you’ll set up a teeny-weeny force demo.

Force feedback describes the next generation of input devices, which have actuators, motors, and so forth that can exert forces on your hand, or your whole body for that matter. (“Cybersex” is going to take on a whole new meaning in a couple of years.) You’ve probably seen or may even own a force feedback device, such as the Microsoft Force Feedback joystick or some other similar device.

Programming these devices is very complex. Not only is a good understanding of force, spring, and motion needed, but the devices and the forces events, or effects, have a very close relationship to musical notes. That is, they can have an envelope that modulates the forces as they are applied to the various motors and actuators on the joystick. Thus, values like rate, frequency, timing, and so on all play a role in using and programming force feedback. In fact, creating effects to play or command the force feedback device is so complex that there are third-party tools you can use to create them, such as Microsoft’s Force Factory. Luckily, you aren’t going to need to use anything that fancy for this demo.

#### The Physics of Force Feedback

Force feedback devices let you set up two types of effects: motive forces and conditions. Motive forces are like active forces that are always in flux, whereas conditions are in response to an event. In either case, you control the amount of force N (in Newtons) and the properties of the force, such as its direction, duration, and so forth.

#### Setting Up Force Feedback

The first step in creating a force feedback device is to find one and get its `GUID`. If you recall how you scanned for standard joystick `GUID`s, you’re going to do the same thing for force feedback devices. However, when you do the device enumeration, you’re going to call it like this:

    GUID fjoystickGUID; // used to hold GUID for force joystick

    // enumerate attached joystick devices only with

    // DInput_Enum_Joysticks() as the callback function

    if (FAILED(lpdi->EnumDevices(

               DIDEVTYPE_JOYSTICK,  // joysticks only

               DInput_Enum_Joysticks, // enumeration function

               &fjoystickGUID,  // send guid back in this var

               DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK)))

       { /* error */ }

Once you have the `GUID`, you create the device as usual. However, you must make sure that the cooperation level is set for `DISCL_EXCLUSIVE` mode (no one else can use force feedback while you’re using it), and you must use the version 2.0 data format. Here’s all the code:

    LPDIRECTINPUTDEVICE lpdijoy_temp; // joystick device interface

    // version 2 interface pointer

    LPDIRECTINPUTDEVICE2 lpdijoy;

    // create the joystick with GUID

    if (FAILED(lpdi->CreateDevice(joystickGUID, &lpdijoy_temp,

                              NULL)))

       { /* error */ }

    // query for the new interface from the old one

    lpdijoy_temp->QueryInterface(IID_IDirectInputDevice2,

                                (void **) &lpdijoy);

    // release the old interface

    lpdijoy_temp->Release();

    if (FAILED(lpdijoy->SetCooperativeLevel(

               main_window_handle,

               DISCL_BACKGROUND | DISCL_EXCLUSIVE)))

       { /* error */ }

    // set data format

    if (FAILED(lpdijoy->SetDataFormat(&c_dfDIJoystick2)))

       { /* error */ }

Okay, now you have a force feedback device set up and ready to go. So what should you do with it?

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.