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

#### Trapping the Mouse

The mouse is one of the most amazingly useful input devices ever created. Can you imagine being the guy who invented the mouse and having so many people laugh at how ridiculous they thought it was? I hope the inventor is laughing on some island over margaritas! The point is, sometimes it’s the most unusual things that work best, and the mouse is a good example of that. Anyway, let’s get serious now... let me take this bra off my head. :)

The standard PC mouse has either two or three buttons and two axes of motion: X and Y. As the mouse is moved around, it builds up packets of information describing state changes and then sends them to the PC serially (in most cases). The data is then processed by a driver and finally sent on up to Windows or DirectX. As far as we are concerned, the mouse is black magic. All we want to know is how to determine when it moves and when a button is pressed. DirectInput does this and more.

There are two ways to communicate with the mouse: absolute mode and relative mode. In absolute mode, the mouse returns its position relative to the screen coordinates based on where the mouse pointer is. Thus, in a screen resolution of 640×480, you would expect the position of the mouse to vary from 0-639, 0-479. Figure 9.6 shows this graphically.

Figure 9.6 The mouse in absolute mode.

In relative mode, the mouse driver sends the position of the mouse as relative deltas at each clock tick rather than as an absolute position. This is shown in Figure 9.7. In reality, all mice are relative; it’s the driver that keeps track of the absolute position of the mouse. Hence, I am going to work with the mouse in relative mode because it’s more flexible.

Figure 9.7 The mouse in relative mode.

Now that you know a little about the mouse, let’s see what you need to do to get it working under DirectInput:

  1. Create the mouse device with `CreateDevice()`.
  2. Set the cooperation level with `SetCooperativeLevel()`.

  > Note: If these steps look unfamiliar, please read the previous keyboard section.

  3. Set the data format with `SetDataFormat()`.
  4. Acquire the mouse with `Acquire()`.
  5. Read the mouse state with `GetDeviceState()`.
  6. Repeat step 5 until done.

Creating the Mouse Device

Looks like bedrock, baby. Let’s give it a try. First, you need an interface pointer to receive the device once you create it. Use a `IDIRECTINPUTDEVICE` pointer for this:

    // of course you need all the other stuff

    LPDIRECTINPUTDEVICE lpdimouse = NULL; // the mouse device

    // assuming that lpdi is valid

    // create the mouse device

    if (FAILED(lpdi->CreateDevice(GUID_SysMouse,

        &lpdimouse, NULL)))

       { /* error */ }

Step 1 is handled. Note that you used the device constant `GUID_SysMouse` for this type. This gives you the default mouse device.

Setting the Cooperation Level of Mouse

Now, set the cooperation level:

    if (FAILED(lpdimouse->SetCooperativeLevel(

               main_window_handle,

               DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))

       { /* error */ }

Setting the Data Format of the Mouse

Now for the data format. Remember, there are a number of standard data formats predefined by DirectInput (shown in Table 9.2); the one you want is `c_dfDIMouse`. Plug it into the function and set the data format:

    // set data format

    if (FAILED(lpdimouse->SetDataFormat(&c_dfDIMouse)))

       { /* error */ }

Okay, now you need to take a pause for a moment. With the keyboard data format `c_dfDIKeyboard`, the data structure returned was an array of 256 `UCHARS`. However, with the mouse, the data format defines something that is more mouse-like. :) Referring back to Table 9.3, the data structure that you’ll be working with is called `DIMOUSESTATE` and is shown here:

    // the mouse data structure

    typedef struct DIMOUSESTATE

        {

        LONG lX;     // X-axis

        LONG lY;     // Y-axis

        LONG lZ;     // Z-axis (wheel in most cases)

        BYTE rgbButtons[4]; // buttons, high bit means down

        } DIMOUSESTATE, *LPDIMOUSESTATE;

Thus, when you make a call to get the device state with `GetDeviceState()`, this is the structure that will be returned. No surprises here. Everything is what it would seem.

Acquiring the Mouse

The next step is to acquire the mouse with a call to `Acquire()`. Here it is:

    // acquire the mouse

    if (FAILED(lpdimouse->Acquire()))

       { /* error */ }

Cool! This is so easy. Wait until you put a wrapper around all this stuff, which will be even easier!

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.