Microsoft DirectX 8.1 (Visual Basic)

Retrieving Action Data

You retrieve buffered data from action-mapped devices just as you would from unmapped devices: by calling DirectInputDevice8.GetDeviceData. However, instead of identifying device objects by examining the lOfs member of the DIDEVICEOBJECTDATA type, you obtain the action associated with the object from the lUserData member. This is the same value you passed to the device in the DIACTION type.

Remember that an action can be associated with more than one device. You still have to obtain data from both devices independently, but you can use the same routine to handle the data regardless of where it comes from.

The following sample code, which might be part of the game loop in a driving simulation, retrieves data from all devices in the m_Devices array. This array contains m_nDevices elements.

Dim iDevice As Integer
For iDevice = 1 To m_nDevices
    Dim didod(BUFFERSIZE) As DIDEVICEOBJECTDATA

    'Poll the device for data.
    m_Devices(iDevice).Poll

    'Determine how many pieces of data are available.
    m_nItems = m_Devices(iDevice).GetDeviceData(didod, 0)
            
    'Handle the actions regardless of what device returned them.
    For i = 0 To m_nItems
        Select Case didod(i).lUserData
            Case eA_STEER:
                Call SteerCar (didod(i).lData)
            Case eB_UPSHIFT:
                If (didod(i).lData & &H80) Then
                    Call ShiftGears (UPSHIFT)
            .
            .
            .
        End Select
    Next
Next

Note  Axis constants for specific genres, such as DIAXIS_DRIVINGR_STEER or DIAXIS_SPACESIM_LATERAL, are used for absolute joystick data. The action mapper attempts to map this virtual control to a device object that returns absolute data. The data returned from that device should be processed accordingly in the application. Device constants such as DIMOUSE_XAXIS, however, are expected to return relative data.

When retrieving data, each potential source of data should be processed separately to keep one device object from possibly overwriting the data from another. For instance, the following DIACTION types are used in an action map to control direction.

With rgActions(0)
  .lAppData = INPUT_LEFTRIGHT_ABS_AXIS
  .lSemantic = DIAXIS_SPACESIM_LATERAL
  .lFlags = 0
  .ActionName = "Turn"
End With
With rgActions(1)
  .lAppData = INPUT_LEFTRIGHT_REL_AXIS
  .lSemantic = DIMOUSE_XAXIS
  .lFlags = 0
  .ActionName = "Turn"
End With
With rgActions(2)
  .lAppData = INPUT_TURNLEFT
  .lSemantic = DIKEYBOARD_LEFT
  .lFlags = 0
  .ActionName = "Turn left"
End With
With rgActions(3)
  .lAppData = INPUT_TURNRIGHT
  .lSemantic = DIKEYBOARD_RIGHT
  .lFlags = 0
  .ActionName = "Turn right"
End With

The application's input loop processes data from these actions in the following case statement.

Select Case adod(j).lUserData
    Case INPUT_LEFTRIGHT_ABS_AXIS:
        g_dwAbsLR = adod(j).lData
    Case INPUT_LEFTRIGHT_REL_AXIS:
        g_dwRelLR = adod(j).lData
    Case INPUT_TURNLEFT:
        g_bLeft = (adod(j).lData <> 0)
    case INPUT_TURNRIGHT:
        g_bRight = (adod(j).lData <> 0)
End Select

Note that each data source is assigned to a separate variable rather than all data sources being assigned a generic "turn" variable. If they to share a generic variable, holding down the LEFT ARROW key and then moving the joystick would cause the keyboard information to be lost. This is because the joystick data would overwrite the variable.

In addition to individual variables, there are many ways to process the data. Whatever method is used, care should be taken in the processing of data to avoid unexpectedly lost information.