Platform SDK: DirectX

Step 4: Set the Joystick Behavior

[Visual Basic]

The information in this topic pertains only to applications written in C++. See DirectInput Visual Basic Tutorials.

[C++]

The joystick device has been created, and its data format has been set. The next step is to set its cooperative level. In the Space Donuts sample, this is done in the callback function called when the device is enumerated. As in the previous step, pdev is a pointer to the device interface.

   if(pdev->lpVtbl->SetCooperativeLevel(pdev, hWndMain, 
      DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) != DI_OK) 
   { 
      OutputDebugString("IDirectInputDevice7::SetCooperativeLevel 
                         FAILED\n"); 
      pdev->lpVtbl->Release(pdev); 
      return DIENUM_CONTINUE; 
   } 
 

Once again, the first parameter to IDirectInputDevice7::SetCooperativeLevel is a this pointer.

The second parameter is a window handle. In this case the handle to the main program window is passed in.

The final parameter is a combination of flags describing the desired cooperative level. Space Donuts requires input from the joystick only when it is the foreground application, and does not care whether another program is using the joystick in exclusive mode, so the flags are set to DISCL_NONEXCLUSIVE | DISCL_FOREGROUND. (See Cooperative Levels for a full explanation of these flags.)

The final step carried out for each joystick enumerated in the callback function is to set the properties of the device. In the sample, the properties changed include the range and the dead zone for both the x-axis and y-axis.

By setting the range, you are telling DirectInput what maximum and minimum values you want returned for an axis. If you set a range of -1,000 to +1,000 for the x-axis, as in the example, you are asking that a value of -1,000 be returned when the stick is at the extreme left, +1,000 when it is at the extreme right, and zero when it is in the middle.

The dead zone is a region of tolerance in the middle of the axis, measured in ten-thousandths of the physical range of axis travel. If you set a dead zone of 1,000 for the x-axis, you are saying that the stick can travel one-tenth of its range to the left or right of center before a non-center value will be returned. For more information on the dead zone, see Interpreting Joystick Axis Data.

Here's the code to set the range of the x-axis:

   DIPROPRANGE diprg; 
 
   diprg.diph.dwSize       = sizeof(diprg); 
   diprg.diph.dwHeaderSize = sizeof(diprg.diph); 
   diprg.diph.dwObj        = DIJOFS_X; 
   diprg.diph.dwHow        = DIPH_BYOFFSET; 
   diprg.lMin              = -1000; 
   diprg.lMax              = +1000; 
 
   if FAILED(pdev->lpVtbl->SetProperty(pdev, 
                   DIPROP_RANGE, &diprg.diph)) 
   { 
      OutputDebugString("IDirectInputDevice7::SetProperty(DIPH_RANGE) 
                         FAILED\n"); 
      pdev->lpVtbl->Release(pdev); 
      return FALSE; 
   } 
 

The first task here is to set up the DIPROPRANGE structure diprg, whose address will be passed into the IDirectInputDevice7::SetProperty method. Actually, it's not the address of the structure itself that is passed but rather the address of its first member, which is a DIPROPHEADER structure. For more information, see Device Properties.

The property header is initialized with the following values:

The lmin and lmax members of the DIPROPRANGE structure are assigned the desired range values.

The application now calls the IDirectInputDevice7::SetProperty method. As usual, the first parameter is a this pointer. The second parameter is a flag indicating which property is being changed. The third parameter is the address of the DIPROPHEADER member of the property structure.

Setting the dead zone of the x-axis requires a similar procedure. The Space Donuts sample uses a helper function, SetDIDwordProperty, to initialize a DIPROPDWORD property structure. Unlike DIPROPRANGE, this structure contains only one data member, which in the example is set to 5,000, indicating that the stick must move half of its range from the center before the axis is reported to be off-center.

   // set X axis dead zone to 50% (to avoid accidental turning) 
   if FAILED(SetDIDwordProperty(pdev, DIPROP_DEADZONE, DIJOFS_X, 
                                DIPH_BYOFFSET, 5000)) 
   { 
      OutputDebugString("IDirectInputDevice7:: 
                           SetProperty(DIPH_DEADZONE) FAILED\n"); 
      pdev->lpVtbl->Release(pdev); 
      return FALSE; 
   } 

Next: Step 5: Gain Access to the Joystick