Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
7.2 KiB

  1. <HEAD>
  2. <TITLE>DirectInput Input Mapper</TITLE>
  3. </HEAD>
  4. <BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#808080 ALINK=#000000>
  5. </BODY>
  6. <H2>DirectInput Input Mapper</H2>
  7. <ADDRESS>
  8. Om Sharma<br>
  9. Microsoft Corporation<br>
  10. 6 June 1999
  11. </ADDRESS>
  12. <h3>Abstract</h3>
  13. <p>
  14. The "Genre and Control definations" documents lists a number of common game genres
  15. and primary actions for each genre.
  16. An action expresses what application behavior should result from
  17. the user's operation of the control.
  18. </p>
  19. <h3>How games use Actions</h3>
  20. <p>
  21. This example illustrates how a car racing game would use the Dinput mapper
  22. to configure its controls.
  23. The enumerated array <code>eGameActions</code> supplies the codes that Dinput
  24. uses to communicate the state of controllers.
  25. An application should enumerate all the actions
  26. that it plans to expose to users.
  27. Axis and hatswitch actions should have button or key equivalents,
  28. to allow users to configure those actions on less capable devices.
  29. </p>
  30. <pre>
  31. enum eGameActions =
  32. {
  33. eA_STEER, /* Steering */
  34. eB_STEER_LEFT, /* Use button to steer to the left */
  35. eB_STEER_RIGHT, /* Use button to steer to the right */
  36. eA_ACCELERATE, /* Accelerate */
  37. eB_ACCELERATE, /* Use button to accelerate */
  38. eB_DEACCELERATE,/* Use button to deaccelerate */
  39. eA_BRAKE, /* Brake */
  40. eB_UPSHIFT, /* Shift to higher gear */
  41. eB_DOWNSHIFT, /* Shift to lower gear */
  42. eB_CYCLEVIEW, /* Cycle to next view */
  43. eB_CONFIGCAR, /* Configure vehicle */
  44. eB_COURSEVIEW, /* Toggle course view */
  45. eB_DRIVERVIEW, /* View from Drivers seat */
  46. eA_VOLUME, /* CD Volume */
  47. eB_BRAKEBIAS, /* Brake Bias */
  48. };
  49. </pre>
  50. <p>
  51. The <code>rgActions</code> array is used to bind game action codes to virtual device controls.
  52. A game should use predefined action codes, in this case <code>DICARCONTROLLER_*</code>, to refer to
  53. controls on a virtual car controller. Dinput will examine all connected
  54. devices and enumurate devices suitable for the maping.
  55. The <code>rgActions</code> should only refer to a single
  56. virtual controller genre and keyboard and mouse.
  57. </p>
  58. <pre>
  59. DIACTIONS rgActions[]=
  60. {
  61. // Genre Defined controls
  62. /************* ****************** ****************
  63. Game Action Virtual Controller User Readable
  64. Code Action Code Label For Action
  65. ************** ****************** ****************/
  66. //Genre defined axes
  67. {eA_STEER, DIDEVTYPE_CARCONTROLLER, ABAXIS_STEER, "Steer", 0x0},
  68. {eA_ACCELERATE, DIDEVTYPE_CARCONTROLLER, ABAXIS_ACCEL, "Accelerate", 0x0},
  69. {eA_BRAKE, DIDEVTYPE_CARCONTROLLER, ABAXIS_BRAKE, "Brake", 0x0},
  70. // addition axes not defined as part of the genre
  71. {eA_VOLUME, DIDEVTYPE_CARCONTROLLER, ABAXIS_ANY, "CD Volume", 0x0},
  72. // ..more game specific actions
  73. //Genre defined buttons
  74. {eB_UPSHIFT, DIDEVTYPE_CARCONTROLLER, BUTTON_UPSHIFT, "Upshift", 0x0},
  75. {eB_DOWNSHIFT, DIDEVTYPE_CARCONTROLLER, BUTTON_DWNSHIFT, "DownShift", 0x0},
  76. {eB_CYCLEVIEW, DIDEVTYPE_CARCONTROLLER, BUTTON_VIEWS, "Change View", 0x0},
  77. {eB_CONFIGCAR, DIDEVTYPE_CARCONTROLLER, BUTTON_CONFIGURECAR,"Configure", 0x0},
  78. // Additional actions not defined in the car controller genre
  79. // Listed in order of importance.
  80. {eB_DRIVERVIEW, DIDEVTYPE_KEYBOARD, DIK_1, "Driver View", 0x0},
  81. {eB_COURSEVIEW, DIDEVTYPE_KEYBOARD, DIK_C, "Course View", 0x0},
  82. {eB_BRAKEBIAS, DIDEVTYPE_KEYBOARD, DIK_B, "Brake Bias", 0x0},
  83. // ... more game specific actions.
  84. // Equivalent mappings for keyboard
  85. {eB_STEER_L, DIDEVTYPE_KEYBOARD, DIK_LEFT, "Steer Left", 0x0},
  86. {eB_STEER_R, DIDEVTYPE_KEYBOARD, DIK_RIGHT, "Steer Right", 0x0},
  87. {eB_ACCEL_MORE, DIDEVTYPE_KEYBOARD, DIK_UP, "Accelerate", 0x0},
  88. {eB_ACCEL_LESS, DIDEVTYPE_KEYBOARD, DIK_DOWN, "DeAccelerate", 0x0},
  89. // ... additional mappings for keyboard
  90. // Equivalent mappings for mouse.
  91. {eB_UPSHIFT, DIDEVTYPE_MOUSE, BUTTON_1, "UpShift", 0x0},
  92. {eB_DOWNSHIFT, DIDEVTYPE_MOUSE, BUTTON_2, "DownShift", 0x0},
  93. {eB_CYCLEVIEW, DIDEVTYPE_MOUSE, BUTTON_3, "Cycle View", 0x0},
  94. // ... additional mappings for mouse
  95. };
  96. </pre>
  97. </p> The last few elements of the <code>rgActions</code> array provide
  98. specific equivalents for controls on keyboard and mice.
  99. The controls on these devices are fairly standard, so there is no need to
  100. provide indirections. The predefined semantic <code>DI_EQUIV</code> allows the
  101. application to specify equivalent mappings for a control. This flag allows DINPUT
  102. to distuingish between a primary control and a equivalent control. Equivalent controls
  103. only avaliable on the keyboard and mice.
  104. <p>
  105. </p>
  106. Including these controls in one <code>rgSemantic</code> makes
  107. the application code simpler. The input processing code of the application
  108. can loop through active input devices and processes data from
  109. {eAch device in a similar manner.
  110. </p>
  111. <p>
  112. Now that the semantic mappings have been defined, the application can use the
  113. <code>IDirectInput8::EnumDevicesByActions</code> method in order to enumerate
  114. devices that are suitable for the virtual car controller.
  115. </p>
  116. <pre>
  117. InitializeInput()
  118. {
  119. IDirectInput* pDI;
  120. hr =pDI->EnumDevicesByActions(
  121. pDI, // IDirectInput interface
  122. &GUID_Application, // Unique GUID for {eAch application
  123. rgActions, // Action array
  124. TEXT("BillG"), // UserName, 0x0},=>CurrentUser
  125. fnDIEnumDevices, // Device Enumeration function
  126. NULL, // User variable
  127. 0x0 // Enumeration flags
  128. );
  129. if(FAILED(hr)
  130. {
  131. // No device suitable for car controller genre
  132. goto panic;
  133. }
  134. pDi->Rel{eAse();
  135. }
  136. </pre>
  137. <p>
  138. The number of complete devices determines how Dinput configures partial devices.
  139. {eAch application is required to provide a GUID that uniquely identifies it.
  140. Dinput uses this GUID to keep track of user specified configuration, or to
  141. enable enhanced configuration information provided by the hardware vendor
  142. that is specific to the application.
  143. </p>
  144. <pre>
  145. BOOL fnDIEnumDevices(
  146. IDirectInputDevice8* pDiDev,
  147. UINT nID,
  148. LPCDIDEVICEINSTANCE lpDiDI,
  149. PVOID pv
  150. )
  151. {
  152. // Display the device mapping
  153. // If a user changes the mapping,
  154. // the application will need to renogotiate the mapping.
  155. hr = pDiDev->DisplayDeviceConfiguration();
  156. if( hr = DIERR_CONFIGCHANGE )
  157. {
  158. // User has changed the device configuration, redo the mapping
  159. g_bRedoConfig = TRUE;
  160. return DIENUM_STOP;
  161. }else
  162. {
  163. // If you decide to keep the device, you need to AddRef
  164. pDiDev->AddRef();
  165. g_pDIDevice[nID] = pDiDev;
  166. // Stash away a copy of the interface pointer
  167. }
  168. return DIENUM_CONTINUE; // Look for other devices
  169. }
  170. </pre>
  171. <p>
  172. If the user changes the device configuration, this function will
  173. return an error code of DIERR_CONFIGCHANGE.
  174. This is your cue to renegotiate the mapping.
  175. </p>