?/TD> |
Microsoft DirectX 9.0 |
You retrieve buffered data from action-mapped devices just as you would from unmapped devices: by calling IDirectInputDevice8::GetDeviceData. However, instead of identifying device objects by examining the dwOfs member of the DIDEVICEOBJECTDATA structure, you obtain the action associated with the object from the uAppData member. This is the same value you passed to the device in the DIACTION structure. It can be a simple identifier or a pointer to a function designed to handle the action.
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 g_lpIdiDevices array. This array contains g_nDevices elements.
for (int iDevice = 0x0; iDevice < g_nDevices; iDevice++) { DIDEVICEOBJECTDATA didod; DWORD dwObjCount = 1; // Poll the device for data. g_lpDiDevices[iDevice]->Poll(); // Retrieve the data. g_lpDiDevices[iDevice]->GetDeviceData( sizeof(didod), &didod, &dwObjCount, 0 ); // Handle the actions regardless of what device returned them. switch(didod.uAppData) { case eA_STEER: SteerCar(didod.dwData); break; case eB_UPSHIFT if (didod.dwData & 0x80) ShiftGears(UPSHIFT); break; . . . default: break; } }
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 structures are used in an action map to control direction.
{INPUT_LEFTRIGHT_ABS_AXIS, DIAXIS_SPACESIM_LATERAL, 0, _T("Turn"),}, {INPUT_LEFTRIGHT_REL_AXIS, DIMOUSE_XAXIS, 0, _T("Turn"),}, {INPUT_TURNLEFT, DIKEYBOARD_LEFT, 0, _T("Turn left"),}, {INPUT_TURNRIGHT, DIKEYBOARD_RIGHT, 0, _T("Turn right"),},
The application's input loop processes data from these actions in the following case statement.
switch (adod[j].uAppData) { case INPUT_LEFTRIGHT_ABS_AXIS: g_dwAbsLR = adod[j].dwData break; case INPUT_LEFTRIGHT_REL_AXIS: g_dwRelLR = adod[j].dwData; break; case INPUT_TURNLEFT: g_bLeft = (adod[j].dwData != 0); break; case INPUT_TURNRIGHT: g_bRight = (adod[j].dwData != 0) break; }
Note that each data source is assigned to a separate variable rather than all data sources being assigned a generic "turn" variable. If they were 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.