gamepad_standard_mappings_win.cc 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <stddef.h>
  5. #include <algorithm>
  6. #include <iterator>
  7. #include "device/gamepad/gamepad_id_list.h"
  8. #include "device/gamepad/gamepad_standard_mappings.h"
  9. namespace device {
  10. namespace {
  11. // Older versions of the Stadia Controller firmware use an alternate mapping
  12. // function.
  13. const uint16_t kStadiaControllerOldFirmwareVersion = 0x0001;
  14. enum StadiaGamepadButtons {
  15. STADIA_GAMEPAD_BUTTON_EXTRA = BUTTON_INDEX_COUNT,
  16. STADIA_GAMEPAD_BUTTON_EXTRA2,
  17. STADIA_GAMEPAD_BUTTON_COUNT
  18. };
  19. void MapperLogitechDInput(const Gamepad& input, Gamepad* mapped) {
  20. *mapped = input;
  21. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[1];
  22. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[2];
  23. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[0];
  24. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  25. DpadFromAxis(mapped, input.axes[9]);
  26. // The Logitech button (BUTTON_INDEX_META) is not accessible through the
  27. // device's D-mode.
  28. mapped->buttons_length = BUTTON_INDEX_COUNT - 1;
  29. mapped->axes_length = AXIS_INDEX_COUNT;
  30. }
  31. void Mapper2Axes8Keys(const Gamepad& input, Gamepad* mapped) {
  32. *mapped = input;
  33. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[2];
  34. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  35. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  36. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[0];
  37. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[1]);
  38. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[1]);
  39. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[0]);
  40. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  41. AxisPositiveAsButton(input.axes[0]);
  42. // Missing buttons
  43. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = NullButton();
  44. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = NullButton();
  45. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = NullButton();
  46. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = NullButton();
  47. mapped->buttons[BUTTON_INDEX_META] = NullButton();
  48. mapped->buttons_length = BUTTON_INDEX_COUNT - 1;
  49. mapped->axes_length = 0;
  50. }
  51. void MapperDualshock4(const Gamepad& input, Gamepad* mapped) {
  52. enum Dualshock4Buttons {
  53. DUALSHOCK_BUTTON_TOUCHPAD = BUTTON_INDEX_COUNT,
  54. DUALSHOCK_BUTTON_COUNT
  55. };
  56. *mapped = input;
  57. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[1];
  58. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[2];
  59. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[0];
  60. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[3];
  61. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[4];
  62. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[5];
  63. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[3]);
  64. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  65. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[8];
  66. mapped->buttons[BUTTON_INDEX_START] = input.buttons[9];
  67. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[10];
  68. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[11];
  69. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  70. mapped->buttons[DUALSHOCK_BUTTON_TOUCHPAD] = input.buttons[13];
  71. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  72. DpadFromAxis(mapped, input.axes[9]);
  73. mapped->buttons_length = DUALSHOCK_BUTTON_COUNT;
  74. mapped->axes_length = AXIS_INDEX_COUNT;
  75. }
  76. void MapperDualSense(const Gamepad& input, Gamepad* mapped) {
  77. enum DualSenseButtons {
  78. DUAL_SENSE_BUTTON_TOUCHPAD = BUTTON_INDEX_COUNT,
  79. DUAL_SENSE_BUTTON_COUNT
  80. };
  81. *mapped = input;
  82. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[1];
  83. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[2];
  84. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[0];
  85. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[3];
  86. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[4];
  87. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[5];
  88. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[3]);
  89. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  90. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[8];
  91. mapped->buttons[BUTTON_INDEX_START] = input.buttons[9];
  92. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[10];
  93. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[11];
  94. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  95. mapped->buttons[DUAL_SENSE_BUTTON_TOUCHPAD] = input.buttons[13];
  96. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[2];
  97. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  98. DpadFromAxis(mapped, input.axes[9]);
  99. mapped->buttons_length = DUAL_SENSE_BUTTON_COUNT;
  100. mapped->axes_length = AXIS_INDEX_COUNT;
  101. }
  102. void MapperIBuffalo(const Gamepad& input, Gamepad* mapped) {
  103. *mapped = input;
  104. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[1];
  105. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[0];
  106. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  107. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[2];
  108. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[6];
  109. mapped->buttons[BUTTON_INDEX_START] = input.buttons[7];
  110. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = input.buttons[4];
  111. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = input.buttons[5];
  112. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[1]);
  113. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[1]);
  114. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[0]);
  115. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  116. AxisPositiveAsButton(input.axes[0]);
  117. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; /* no meta */
  118. mapped->axes_length = 2;
  119. }
  120. void MapperOnLiveWireless(const Gamepad& input, Gamepad* mapped) {
  121. *mapped = input;
  122. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  123. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  124. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  125. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  126. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  127. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  128. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[2]);
  129. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[5]);
  130. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[10];
  131. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  132. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  133. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  134. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  135. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  136. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
  137. DpadFromAxis(mapped, input.axes[9]);
  138. mapped->buttons_length = BUTTON_INDEX_COUNT;
  139. mapped->axes_length = AXIS_INDEX_COUNT;
  140. }
  141. void MapperADT1(const Gamepad& input, Gamepad* mapped) {
  142. *mapped = input;
  143. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  144. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  145. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  146. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  147. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  148. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  149. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[4]);
  150. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[3]);
  151. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = NullButton();
  152. mapped->buttons[BUTTON_INDEX_START] = NullButton();
  153. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  154. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  155. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  156. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  157. DpadFromAxis(mapped, input.axes[9]);
  158. mapped->buttons_length = BUTTON_INDEX_COUNT;
  159. mapped->axes_length = AXIS_INDEX_COUNT;
  160. }
  161. void MapperNvShield(const Gamepad& input, Gamepad* mapped) {
  162. enum ShieldButtons {
  163. SHIELD_BUTTON_CIRCLE = BUTTON_INDEX_COUNT,
  164. SHIELD_BUTTON_COUNT
  165. };
  166. *mapped = input;
  167. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  168. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  169. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  170. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  171. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[4]);
  172. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[3]);
  173. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[9];
  174. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  175. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  176. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  177. mapped->buttons[BUTTON_INDEX_META] = input.buttons[2];
  178. mapped->buttons[SHIELD_BUTTON_CIRCLE] = input.buttons[5];
  179. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  180. DpadFromAxis(mapped, input.axes[9]);
  181. mapped->buttons_length = SHIELD_BUTTON_COUNT;
  182. mapped->axes_length = AXIS_INDEX_COUNT;
  183. }
  184. void MapperNvShield2017(const Gamepad& input, Gamepad* mapped) {
  185. enum Shield2017Buttons {
  186. SHIELD2017_BUTTON_PLAYPAUSE = BUTTON_INDEX_COUNT,
  187. SHIELD2017_BUTTON_COUNT
  188. };
  189. *mapped = input;
  190. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  191. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  192. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  193. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  194. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  195. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  196. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[4]);
  197. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[3]);
  198. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[8];
  199. mapped->buttons[BUTTON_INDEX_START] = input.buttons[5];
  200. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  201. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  202. mapped->buttons[BUTTON_INDEX_META] = input.buttons[2];
  203. mapped->buttons[SHIELD2017_BUTTON_PLAYPAUSE] = input.buttons[11];
  204. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  205. DpadFromAxis(mapped, input.axes[9]);
  206. mapped->buttons_length = SHIELD2017_BUTTON_COUNT;
  207. mapped->axes_length = AXIS_INDEX_COUNT;
  208. }
  209. void MapperOUYA(const Gamepad& input, Gamepad* mapped) {
  210. *mapped = input;
  211. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  212. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[3];
  213. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[1];
  214. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[2];
  215. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[4];
  216. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[5];
  217. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[2]);
  218. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[5]);
  219. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = NullButton();
  220. mapped->buttons[BUTTON_INDEX_START] = NullButton();
  221. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[6];
  222. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[7];
  223. mapped->buttons[BUTTON_INDEX_DPAD_UP] = input.buttons[8];
  224. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = input.buttons[9];
  225. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = input.buttons[10];
  226. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] = input.buttons[11];
  227. mapped->buttons[BUTTON_INDEX_META] = input.buttons[15];
  228. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  229. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
  230. mapped->buttons_length = BUTTON_INDEX_COUNT;
  231. mapped->axes_length = AXIS_INDEX_COUNT;
  232. }
  233. void MapperRazerServal(const Gamepad& input, Gamepad* mapped) {
  234. *mapped = input;
  235. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  236. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  237. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  238. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  239. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  240. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  241. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[4]);
  242. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[3]);
  243. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[10];
  244. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  245. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  246. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  247. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  248. DpadFromAxis(mapped, input.axes[9]);
  249. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; /* no meta */
  250. mapped->axes_length = AXIS_INDEX_COUNT;
  251. }
  252. void MapperMogaPro(const Gamepad& input, Gamepad* mapped) {
  253. *mapped = input;
  254. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  255. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  256. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  257. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  258. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  259. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  260. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[4]);
  261. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[3]);
  262. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = NullButton();
  263. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  264. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  265. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  266. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  267. DpadFromAxis(mapped, input.axes[9]);
  268. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; /* no meta */
  269. mapped->axes_length = AXIS_INDEX_COUNT;
  270. }
  271. void MapperStadiaControllerOldFirmware(const Gamepad& input, Gamepad* mapped) {
  272. *mapped = input;
  273. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  274. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  275. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  276. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  277. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  278. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  279. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[4]);
  280. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[3]);
  281. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[10];
  282. mapped->buttons[BUTTON_INDEX_START] = input.buttons[12];
  283. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  284. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  285. mapped->buttons[BUTTON_INDEX_META] = input.buttons[11];
  286. mapped->buttons[STADIA_GAMEPAD_BUTTON_EXTRA] = input.buttons[16];
  287. mapped->buttons[STADIA_GAMEPAD_BUTTON_EXTRA2] = input.buttons[17];
  288. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  289. DpadFromAxis(mapped, input.axes[9]);
  290. mapped->buttons_length = STADIA_GAMEPAD_BUTTON_COUNT;
  291. mapped->axes_length = AXIS_INDEX_COUNT;
  292. }
  293. void MapperStadiaController(const Gamepad& input, Gamepad* mapped) {
  294. *mapped = input;
  295. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  296. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  297. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  298. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  299. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  300. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  301. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[4]);
  302. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[3]);
  303. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[10];
  304. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  305. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  306. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  307. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  308. mapped->buttons[STADIA_GAMEPAD_BUTTON_EXTRA] = input.buttons[16];
  309. mapped->buttons[STADIA_GAMEPAD_BUTTON_EXTRA2] = input.buttons[17];
  310. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  311. DpadFromAxis(mapped, input.axes[9]);
  312. mapped->buttons_length = STADIA_GAMEPAD_BUTTON_COUNT;
  313. mapped->axes_length = AXIS_INDEX_COUNT;
  314. }
  315. void MapperXSkills(const Gamepad& input, Gamepad* mapped) {
  316. enum GamecubeButtons {
  317. GAMECUBE_BUTTON_LEFT_TRIGGER_CLICK = BUTTON_INDEX_COUNT,
  318. GAMECUBE_BUTTON_RIGHT_TRIGGER_CLICK,
  319. GAMECUBE_BUTTON_COUNT
  320. };
  321. *mapped = input;
  322. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0]; // A
  323. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[2]; // X
  324. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[1]; // B
  325. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[3]; // Y
  326. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = NullButton();
  327. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[6]; // Z
  328. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[4]);
  329. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[3]);
  330. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = NullButton();
  331. mapped->buttons[BUTTON_INDEX_START] = input.buttons[7];
  332. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = NullButton();
  333. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = NullButton();
  334. mapped->buttons[BUTTON_INDEX_DPAD_UP] = input.buttons[11];
  335. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = input.buttons[10];
  336. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = input.buttons[8];
  337. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] = input.buttons[9];
  338. mapped->buttons[BUTTON_INDEX_META] = NullButton();
  339. mapped->buttons[GAMECUBE_BUTTON_LEFT_TRIGGER_CLICK] = input.buttons[4];
  340. mapped->buttons[GAMECUBE_BUTTON_RIGHT_TRIGGER_CLICK] = input.buttons[5];
  341. mapped->axes[AXIS_INDEX_LEFT_STICK_X] = input.axes[0];
  342. mapped->axes[AXIS_INDEX_LEFT_STICK_Y] = input.axes[1];
  343. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[5];
  344. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[2];
  345. mapped->buttons_length = GAMECUBE_BUTTON_COUNT;
  346. mapped->axes_length = AXIS_INDEX_COUNT;
  347. }
  348. void MapperBoomN64Psx(const Gamepad& input, Gamepad* mapped) {
  349. *mapped = input;
  350. // Mapped for a PSX device with Analog mode enabled.
  351. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[2];
  352. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  353. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  354. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[0];
  355. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  356. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  357. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = input.buttons[4];
  358. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = input.buttons[5];
  359. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[8];
  360. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  361. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[9];
  362. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[10];
  363. mapped->buttons[BUTTON_INDEX_DPAD_UP] = input.buttons[12];
  364. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = input.buttons[14];
  365. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = input.buttons[15];
  366. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] = input.buttons[13];
  367. mapped->buttons[BUTTON_INDEX_META] = NullButton();
  368. mapped->axes[AXIS_INDEX_LEFT_STICK_X] = input.axes[0];
  369. mapped->axes[AXIS_INDEX_LEFT_STICK_Y] = input.axes[1];
  370. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[2];
  371. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  372. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; // no meta
  373. mapped->axes_length = AXIS_INDEX_COUNT;
  374. }
  375. void MapperSnakebyteIDroidCon(const Gamepad& input, Gamepad* mapped) {
  376. *mapped = input;
  377. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  378. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  379. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  380. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  381. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[10];
  382. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  383. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[2];
  384. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[5];
  385. mapped->buttons[BUTTON_INDEX_META] = NullButton();
  386. DpadFromAxis(mapped, input.axes[9]);
  387. // The iDroid:con has two different modes. Distinguish them based on which
  388. // axes are used.
  389. if ((input.axes_used & 0b11000) == 0) {
  390. // "Game controller 1" mode: digital triggers.
  391. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = input.buttons[8];
  392. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = input.buttons[9];
  393. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  394. } else {
  395. // "Game controller 2" mode: analog triggers.
  396. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] =
  397. AxisPositiveAsButton(input.axes[2]);
  398. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] =
  399. AxisNegativeAsButton(input.axes[2]);
  400. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  401. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
  402. }
  403. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; // no meta
  404. mapped->axes_length = AXIS_INDEX_COUNT;
  405. }
  406. void MapperHoripadSwitch(const Gamepad& input, Gamepad* mapped) {
  407. *mapped = input;
  408. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[1];
  409. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[2];
  410. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[0];
  411. DpadFromAxis(mapped, input.axes[9]);
  412. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  413. mapped->buttons[SWITCH_PRO_BUTTON_CAPTURE] = input.buttons[13];
  414. mapped->axes[AXIS_INDEX_LEFT_STICK_X] = input.axes[0];
  415. mapped->axes[AXIS_INDEX_LEFT_STICK_Y] = input.axes[1];
  416. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[2];
  417. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  418. mapped->buttons_length = SWITCH_PRO_BUTTON_COUNT;
  419. mapped->axes_length = AXIS_INDEX_COUNT;
  420. }
  421. void MapperXboxBluetooth(const Gamepad& input, Gamepad* mapped) {
  422. *mapped = input;
  423. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  424. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  425. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  426. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  427. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  428. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  429. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[3]);
  430. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  431. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[10];
  432. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  433. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  434. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  435. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  436. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[2];
  437. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  438. DpadFromAxis(mapped, input.axes[9]);
  439. mapped->buttons_length = BUTTON_INDEX_COUNT;
  440. mapped->axes_length = AXIS_INDEX_COUNT;
  441. }
  442. constexpr struct MappingData {
  443. GamepadId gamepad_id;
  444. GamepadStandardMappingFunction function;
  445. } AvailableMappings[] = {
  446. // PowerA Wireless Controller - Nintendo GameCube style
  447. {GamepadId::kPowerALicPro, MapperSwitchPro},
  448. // Snakebyte iDroid:con
  449. {GamepadId::kBroadcomProduct8502, MapperSnakebyteIDroidCon},
  450. // 2Axes 8Keys Game Pad
  451. {GamepadId::kDragonRiseProduct0011, Mapper2Axes8Keys},
  452. // HORIPAD for Nintendo Switch
  453. {GamepadId::kHoriProduct00c1, MapperHoripadSwitch},
  454. // Xbox One S (Bluetooth)
  455. {GamepadId::kMicrosoftProduct0b20, MapperXboxBluetooth},
  456. // Xbox Elite Series 2 (Bluetooth)
  457. {GamepadId::kMicrosoftProduct0b21, MapperXboxBluetooth},
  458. // Xbox Adaptive (Bluetooth)
  459. {GamepadId::kMicrosoftProduct0b22, MapperXboxBluetooth},
  460. // Logitech F310, D-mode
  461. {GamepadId::kLogitechProductc216, MapperLogitechDInput},
  462. // Logitech F510, D-mode
  463. {GamepadId::kLogitechProductc218, MapperLogitechDInput},
  464. // Logitech F710, D-mode
  465. {GamepadId::kLogitechProductc219, MapperLogitechDInput},
  466. // Playstation Dualshock 4
  467. {GamepadId::kSonyProduct05c4, MapperDualshock4},
  468. // Dualshock 4 (PS4 Slim)
  469. {GamepadId::kSonyProduct09cc, MapperDualshock4},
  470. // Dualshock 4 USB receiver
  471. {GamepadId::kSonyProduct0ba0, MapperDualshock4},
  472. // DualSense
  473. {GamepadId::kSonyProduct0ce6, MapperDualSense},
  474. // Switch Joy-Con L
  475. {GamepadId::kNintendoProduct2006, MapperSwitchJoyCon},
  476. // Switch Joy-Con R
  477. {GamepadId::kNintendoProduct2007, MapperSwitchJoyCon},
  478. // Switch Pro Controller
  479. {GamepadId::kNintendoProduct2009, MapperSwitchPro},
  480. // Switch Charging Grip
  481. {GamepadId::kNintendoProduct200e, MapperSwitchPro},
  482. // iBuffalo Classic
  483. {GamepadId::kPadixProduct2060, MapperIBuffalo},
  484. // Nvidia Shield gamepad (2015)
  485. {GamepadId::kNvidiaProduct7210, MapperNvShield},
  486. // Nvidia Shield gamepad (2017)
  487. {GamepadId::kNvidiaProduct7214, MapperNvShield2017},
  488. // Nexus Player Controller
  489. {GamepadId::kAsusTekProduct4500, MapperADT1},
  490. // XSkills Gamecube USB adapter
  491. {GamepadId::kPlayComProduct0005, MapperXSkills},
  492. // Razer Serval Controller
  493. {GamepadId::kRazer1532Product0900, MapperRazerServal},
  494. // ADT-1 Controller
  495. {GamepadId::kGoogleProduct2c40, MapperADT1},
  496. // Stadia Controller
  497. {GamepadId::kGoogleProduct9400, MapperStadiaController},
  498. // Moga Pro Controller (HID mode)
  499. {GamepadId::kBdaProduct6271, MapperMogaPro},
  500. // OnLive Controller (Bluetooth)
  501. {GamepadId::kOnLiveProduct1008, MapperOnLiveWireless},
  502. // OnLive Controller (Wired)
  503. {GamepadId::kOnLiveProduct100a, MapperOnLiveWireless},
  504. // OUYA Controller
  505. {GamepadId::kOuyaProduct0001, MapperOUYA},
  506. // SCUF Vantage, SCUF Vantage 2
  507. {GamepadId::kScufProduct7725, MapperDualshock4},
  508. // boom PSX+N64 USB Converter
  509. {GamepadId::kPrototypeVendorProduct0667, MapperBoomN64Psx},
  510. // Stadia Controller prototype
  511. {GamepadId::kPrototypeVendorProduct9401, MapperStadiaControllerOldFirmware},
  512. };
  513. } // namespace
  514. GamepadStandardMappingFunction GetGamepadStandardMappingFunction(
  515. const base::StringPiece product_name,
  516. const uint16_t vendor_id,
  517. const uint16_t product_id,
  518. const uint16_t hid_specification_version,
  519. const uint16_t version_number,
  520. GamepadBusType bus_type) {
  521. GamepadId gamepad_id =
  522. GamepadIdList::Get().GetGamepadId(product_name, vendor_id, product_id);
  523. const MappingData* begin = std::begin(AvailableMappings);
  524. const MappingData* end = std::end(AvailableMappings);
  525. const auto* find_it = std::find_if(begin, end, [=](const MappingData& item) {
  526. return gamepad_id == item.gamepad_id;
  527. });
  528. GamepadStandardMappingFunction mapper =
  529. (find_it == end) ? nullptr : find_it->function;
  530. // The Switch Joy-Con Charging Grip allows a pair of Joy-Cons to be docked
  531. // with the grip and used over USB as a single composite gamepad. The Nintendo
  532. // data fetcher also allows a pair of Bluetooth-connected Joy-Cons to be used
  533. // as a composite device and sets the same product ID as the Charging Grip.
  534. //
  535. // In both configurations, we remap the Joy-Con buttons to align with the
  536. // Standard Gamepad mapping. Docking a Joy-Con in the Charging Grip makes the
  537. // SL and SR buttons inaccessible.
  538. //
  539. // If the Joy-Cons are not docked, the SL and SR buttons are still accessible.
  540. // Inspect the |bus_type| of the composite device to detect this case and use
  541. // an alternate mapping function that exposes the extra buttons.
  542. if (gamepad_id == GamepadId::kNintendoProduct200e &&
  543. mapper == MapperSwitchPro && bus_type != GAMEPAD_BUS_USB) {
  544. mapper = MapperSwitchComposite;
  545. }
  546. // Use an alternate mapping function if the Stadia controller is using an old
  547. // firmware version.
  548. if (gamepad_id == GamepadId::kGoogleProduct9400 &&
  549. mapper == MapperStadiaController &&
  550. version_number == kStadiaControllerOldFirmwareVersion) {
  551. mapper = MapperStadiaControllerOldFirmware;
  552. }
  553. return mapper;
  554. }
  555. } // namespace device