Microsoft DirectX 8.1 (Visual Basic) |
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.