gamepad_standard_mappings_linux.cc 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066
  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. // The Linux kernel has been updated to improve the mapping exposed by Sony
  12. // Playstation controllers. If the high bit of the bcdHID value is set it
  13. // indicates that an improved mapping is used, otherwise the default mapping
  14. // is used.
  15. // Dualshock 4 devices are patched in 4.10:
  16. // https://github.com/torvalds/linux/commit/9131f8cc2b4eaf7c08d402243429e0bfba9aa0d6
  17. // Dualshock 3 and SIXAXIS devices are patched in 4.12:
  18. // https://github.com/torvalds/linux/commit/e19a267b9987135c00155a51e683e434b9abb56b
  19. // Dualsense devices are patched in 5.12:
  20. // https://github.com/torvalds/linux/commit/bc2e15a9a0228b10fece576d4f6a974c002ff07b
  21. const uint16_t kDualshockPatchedBcdHidMask = 0x8000;
  22. // Older versions of the Stadia Controller firmware use an alternate mapping
  23. // function.
  24. const uint16_t kStadiaControllerOldFirmwareVersion = 0x0001;
  25. enum StadiaGamepadButtons {
  26. STADIA_GAMEPAD_BUTTON_EXTRA = BUTTON_INDEX_COUNT,
  27. STADIA_GAMEPAD_BUTTON_EXTRA2,
  28. STADIA_GAMEPAD_BUTTON_COUNT
  29. };
  30. enum XboxSeriesXGamepadButtons {
  31. kSeriesXGamepadButtonShare = BUTTON_INDEX_COUNT,
  32. kSeriesXGamepadButtonCount
  33. };
  34. void MapperXInputStyleGamepad(const Gamepad& input, Gamepad* mapped) {
  35. *mapped = input;
  36. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[2]);
  37. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[5]);
  38. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[6];
  39. mapped->buttons[BUTTON_INDEX_START] = input.buttons[7];
  40. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[9];
  41. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[10];
  42. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  43. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  44. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  45. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  46. AxisPositiveAsButton(input.axes[6]);
  47. mapped->buttons[BUTTON_INDEX_META] = input.buttons[8];
  48. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  49. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
  50. mapped->buttons_length = BUTTON_INDEX_COUNT;
  51. mapped->axes_length = AXIS_INDEX_COUNT;
  52. }
  53. void MapperXboxBluetooth(const Gamepad& input, Gamepad* mapped) {
  54. *mapped = input;
  55. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  56. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  57. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[5]);
  58. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  59. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  60. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  61. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[10];
  62. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  63. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  64. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  65. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  66. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  67. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  68. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  69. AxisPositiveAsButton(input.axes[6]);
  70. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  71. mapped->buttons_length = BUTTON_INDEX_COUNT;
  72. mapped->axes_length = AXIS_INDEX_COUNT;
  73. }
  74. void MapperXboxSeriesXBluetooth(const Gamepad& input, Gamepad* mapped) {
  75. MapperXboxBluetooth(input, mapped);
  76. // Xbox Wireless Controller Model 1914 has an extra Share button not present
  77. // on other Xbox controllers. Map Share to the next button index after Meta.
  78. mapped->buttons[kSeriesXGamepadButtonShare] = input.buttons[15];
  79. mapped->buttons_length = kSeriesXGamepadButtonCount;
  80. }
  81. void MapperXboxOneS(const Gamepad& input, Gamepad* mapped) {
  82. *mapped = input;
  83. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  84. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  85. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[2];
  86. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[3];
  87. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[4];
  88. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[5];
  89. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[2]);
  90. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[5]);
  91. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[6];
  92. mapped->buttons[BUTTON_INDEX_START] = input.buttons[7];
  93. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[8];
  94. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[9];
  95. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  96. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  97. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  98. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  99. AxisPositiveAsButton(input.axes[6]);
  100. mapped->buttons[BUTTON_INDEX_META] = input.buttons[10];
  101. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  102. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
  103. mapped->buttons_length = BUTTON_INDEX_COUNT;
  104. mapped->axes_length = AXIS_INDEX_COUNT;
  105. }
  106. void MapperXboxOneS2016Firmware(const Gamepad& input, Gamepad* mapped) {
  107. *mapped = input;
  108. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  109. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  110. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  111. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  112. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  113. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  114. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[5]);
  115. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  116. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[16];
  117. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  118. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  119. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  120. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  121. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  122. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  123. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  124. AxisPositiveAsButton(input.axes[6]);
  125. // Xbox Wireless Controller (045e:02fd) received a firmware update in 2019
  126. // that changed which field is populated with the Xbox button state. Check
  127. // both fields and combine the results.
  128. auto& xbox_old = input.buttons[15];
  129. auto& xbox_new = input.buttons[12];
  130. mapped->buttons[BUTTON_INDEX_META].pressed =
  131. (xbox_old.pressed || xbox_new.pressed);
  132. mapped->buttons[BUTTON_INDEX_META].touched =
  133. (xbox_old.touched || xbox_new.touched);
  134. mapped->buttons[BUTTON_INDEX_META].value =
  135. std::max(xbox_old.value, xbox_new.value);
  136. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[3];
  137. mapped->buttons_length = BUTTON_INDEX_COUNT;
  138. mapped->axes_length = AXIS_INDEX_COUNT;
  139. }
  140. void MapperXboxElite2Bluetooth(const Gamepad& input, Gamepad* mapped) {
  141. *mapped = input;
  142. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  143. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  144. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  145. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  146. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  147. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  148. // On some systems, the View (back/select) button is interpreted as a media
  149. // key instead of a gamepad button. When it behaves as a media key, pressing
  150. // the button causes a back-navigation in the browser. The below mapping is
  151. // correct when this behavior is not present.
  152. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[16];
  153. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  154. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  155. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  156. // The modern Xbox Elite Series 2 firmware reports less axes than prior
  157. // versions. However, the only way to distinguish between the versions is
  158. // to check the length of the axes.
  159. //
  160. // In the older firmware, axes 4 and 9 are redundancies, so after axis 3
  161. // the mappings are shifted by 1
  162. int axis_shift = mapped->axes_length > 8 ? 1 : 0;
  163. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] =
  164. AxisToButton(input.axes[5 + axis_shift]);
  165. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] =
  166. AxisToButton(input.axes[4 + axis_shift]);
  167. mapped->buttons[BUTTON_INDEX_DPAD_UP] =
  168. AxisNegativeAsButton(input.axes[7 + axis_shift]);
  169. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] =
  170. AxisPositiveAsButton(input.axes[7 + axis_shift]);
  171. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] =
  172. AxisNegativeAsButton(input.axes[6 + axis_shift]);
  173. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  174. AxisPositiveAsButton(input.axes[6 + axis_shift]);
  175. // The Xbox (meta) button does not generate an input event for this device.
  176. mapped->buttons_length = BUTTON_INDEX_COUNT - 1;
  177. mapped->axes_length = AXIS_INDEX_COUNT;
  178. }
  179. void MapperLakeviewResearch(const Gamepad& input, Gamepad* mapped) {
  180. *mapped = input;
  181. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[2];
  182. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  183. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[0];
  184. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  185. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  186. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = input.buttons[4];
  187. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = input.buttons[5];
  188. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[9];
  189. mapped->buttons[BUTTON_INDEX_START] = input.buttons[8];
  190. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[5]);
  191. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[5]);
  192. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[4]);
  193. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  194. AxisPositiveAsButton(input.axes[4]);
  195. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; // no Meta on this device
  196. mapped->axes_length = AXIS_INDEX_COUNT;
  197. }
  198. void MapperDualshock3SixAxis(const Gamepad& input, Gamepad* mapped) {
  199. *mapped = input;
  200. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[14];
  201. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[13];
  202. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[15];
  203. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[12];
  204. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[10];
  205. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[11];
  206. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[12]);
  207. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[13]);
  208. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[0];
  209. mapped->buttons[BUTTON_INDEX_START] = input.buttons[3];
  210. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[1];
  211. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[2];
  212. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisToButton(input.axes[8]);
  213. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisToButton(input.axes[10]);
  214. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = input.buttons[7];
  215. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] = AxisToButton(input.axes[9]);
  216. mapped->buttons[BUTTON_INDEX_META] = input.buttons[16];
  217. mapped->buttons_length = BUTTON_INDEX_COUNT;
  218. mapped->axes_length = AXIS_INDEX_COUNT;
  219. }
  220. void MapperDualshock3SixAxisNew(const Gamepad& input, Gamepad* mapped) {
  221. *mapped = input;
  222. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  223. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  224. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  225. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[2];
  226. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[4];
  227. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[5];
  228. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[2]);
  229. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[5]);
  230. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[8];
  231. mapped->buttons[BUTTON_INDEX_START] = input.buttons[9];
  232. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[11];
  233. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[12];
  234. mapped->buttons[BUTTON_INDEX_DPAD_UP] = input.buttons[13];
  235. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = input.buttons[14];
  236. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = input.buttons[15];
  237. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] = input.buttons[16];
  238. mapped->buttons[BUTTON_INDEX_META] = input.buttons[10];
  239. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  240. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
  241. mapped->buttons_length = BUTTON_INDEX_COUNT;
  242. mapped->axes_length = AXIS_INDEX_COUNT;
  243. }
  244. void MapperDualshock4(const Gamepad& input, Gamepad* mapped) {
  245. enum Dualshock4Buttons {
  246. DUALSHOCK_BUTTON_TOUCHPAD = BUTTON_INDEX_COUNT,
  247. DUALSHOCK_BUTTON_COUNT
  248. };
  249. *mapped = input;
  250. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[1];
  251. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[2];
  252. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[0];
  253. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[3];
  254. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[4];
  255. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[5];
  256. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[3]);
  257. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  258. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[8];
  259. mapped->buttons[BUTTON_INDEX_START] = input.buttons[9];
  260. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[10];
  261. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[11];
  262. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  263. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  264. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  265. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  266. AxisPositiveAsButton(input.axes[6]);
  267. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  268. mapped->buttons[DUALSHOCK_BUTTON_TOUCHPAD] = input.buttons[13];
  269. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  270. mapped->buttons_length = DUALSHOCK_BUTTON_COUNT;
  271. mapped->axes_length = AXIS_INDEX_COUNT;
  272. }
  273. // This mapping function is intended for Playstation 4 and 5 gamepads handled
  274. // by hid-sony (kernel 4.10+) and hid-playstation (kernel 5.12+).
  275. void MapperPs4Ps5(const Gamepad& input, Gamepad* mapped) {
  276. *mapped = input;
  277. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  278. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  279. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  280. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[2];
  281. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[4];
  282. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[5];
  283. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[2]);
  284. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[5]);
  285. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[8];
  286. mapped->buttons[BUTTON_INDEX_START] = input.buttons[9];
  287. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[11];
  288. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[12];
  289. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  290. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  291. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  292. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  293. AxisPositiveAsButton(input.axes[6]);
  294. mapped->buttons[BUTTON_INDEX_META] = input.buttons[10];
  295. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  296. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
  297. mapped->buttons_length = BUTTON_INDEX_COUNT;
  298. mapped->axes_length = AXIS_INDEX_COUNT;
  299. }
  300. void MapperDualSense(const Gamepad& input, Gamepad* mapped) {
  301. enum DualSenseButtons {
  302. DUAL_SENSE_BUTTON_TOUCHPAD = BUTTON_INDEX_COUNT,
  303. DUAL_SENSE_BUTTON_COUNT
  304. };
  305. *mapped = input;
  306. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[1];
  307. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[2];
  308. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[0];
  309. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[3];
  310. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[4];
  311. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[5];
  312. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[3]);
  313. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  314. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[8];
  315. mapped->buttons[BUTTON_INDEX_START] = input.buttons[9];
  316. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[10];
  317. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[11];
  318. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  319. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  320. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  321. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  322. AxisPositiveAsButton(input.axes[6]);
  323. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  324. mapped->buttons[DUAL_SENSE_BUTTON_TOUCHPAD] = input.buttons[13];
  325. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[2];
  326. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  327. mapped->buttons_length = DUAL_SENSE_BUTTON_COUNT;
  328. mapped->axes_length = AXIS_INDEX_COUNT;
  329. }
  330. void MapperIBuffalo(const Gamepad& input, Gamepad* mapped) {
  331. *mapped = input;
  332. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[1];
  333. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[0];
  334. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  335. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[2];
  336. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[6];
  337. mapped->buttons[BUTTON_INDEX_START] = input.buttons[7];
  338. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = input.buttons[4];
  339. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = input.buttons[5];
  340. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[1]);
  341. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[1]);
  342. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[0]);
  343. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  344. AxisPositiveAsButton(input.axes[0]);
  345. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; /* no meta */
  346. mapped->axes_length = 2;
  347. }
  348. void MapperXGEAR(const Gamepad& input, Gamepad* mapped) {
  349. *mapped = input;
  350. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[2];
  351. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  352. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  353. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[0];
  354. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  355. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  356. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = input.buttons[4];
  357. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = input.buttons[5];
  358. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[5]);
  359. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[5]);
  360. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[4]);
  361. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  362. AxisPositiveAsButton(input.axes[4]);
  363. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  364. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[2];
  365. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; // no Meta on this device
  366. mapped->axes_length = AXIS_INDEX_COUNT;
  367. }
  368. void MapperDragonRiseGeneric(const Gamepad& input, Gamepad* mapped) {
  369. *mapped = input;
  370. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[6]);
  371. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[6]);
  372. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[5]);
  373. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  374. AxisPositiveAsButton(input.axes[5]);
  375. mapped->axes[AXIS_INDEX_LEFT_STICK_X] = input.axes[0];
  376. mapped->axes[AXIS_INDEX_LEFT_STICK_Y] = input.axes[1];
  377. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  378. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
  379. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; // no Meta on this device
  380. mapped->axes_length = AXIS_INDEX_COUNT;
  381. }
  382. void MapperOnLiveWireless(const Gamepad& input, Gamepad* mapped) {
  383. *mapped = input;
  384. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[2]);
  385. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[5]);
  386. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[6];
  387. mapped->buttons[BUTTON_INDEX_START] = input.buttons[7];
  388. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[9];
  389. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[10];
  390. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  391. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  392. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  393. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  394. AxisPositiveAsButton(input.axes[6]);
  395. mapped->buttons[BUTTON_INDEX_META] = input.buttons[8];
  396. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  397. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
  398. mapped->buttons_length = BUTTON_INDEX_COUNT;
  399. mapped->axes_length = AXIS_INDEX_COUNT;
  400. }
  401. void MapperADT1(const Gamepad& input, Gamepad* mapped) {
  402. *mapped = input;
  403. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[5]);
  404. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  405. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = NullButton();
  406. mapped->buttons[BUTTON_INDEX_START] = NullButton();
  407. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[7];
  408. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[8];
  409. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  410. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  411. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  412. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  413. AxisPositiveAsButton(input.axes[6]);
  414. mapped->buttons[BUTTON_INDEX_META] = input.buttons[6];
  415. mapped->buttons_length = BUTTON_INDEX_COUNT;
  416. mapped->axes_length = AXIS_INDEX_COUNT;
  417. }
  418. void MapperNvShield(const Gamepad& input, Gamepad* mapped) {
  419. *mapped = input;
  420. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[5]);
  421. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  422. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = NullButton();
  423. mapped->buttons[BUTTON_INDEX_START] = input.buttons[7];
  424. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[8];
  425. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[9];
  426. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  427. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  428. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  429. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  430. AxisPositiveAsButton(input.axes[6]);
  431. mapped->buttons[BUTTON_INDEX_META] = input.buttons[6];
  432. mapped->buttons_length = BUTTON_INDEX_COUNT;
  433. mapped->axes_length = AXIS_INDEX_COUNT;
  434. }
  435. void MapperNvShield2017(const Gamepad& input, Gamepad* mapped) {
  436. enum Shield2017Buttons {
  437. SHIELD2017_BUTTON_PLAYPAUSE = BUTTON_INDEX_COUNT,
  438. SHIELD2017_BUTTON_COUNT
  439. };
  440. *mapped = input;
  441. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[5]);
  442. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  443. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[14];
  444. mapped->buttons[BUTTON_INDEX_START] = input.buttons[13];
  445. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[7];
  446. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[8];
  447. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  448. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  449. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  450. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  451. AxisPositiveAsButton(input.axes[6]);
  452. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  453. mapped->buttons[SHIELD2017_BUTTON_PLAYPAUSE] = input.buttons[6];
  454. mapped->buttons_length = SHIELD2017_BUTTON_COUNT;
  455. mapped->axes_length = AXIS_INDEX_COUNT;
  456. }
  457. void MapperOUYA(const Gamepad& input, Gamepad* mapped) {
  458. *mapped = input;
  459. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  460. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[3];
  461. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[1];
  462. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[2];
  463. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[4];
  464. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[5];
  465. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[2]);
  466. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[5]);
  467. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = NullButton();
  468. mapped->buttons[BUTTON_INDEX_START] = NullButton();
  469. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[6];
  470. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[7];
  471. mapped->buttons[BUTTON_INDEX_DPAD_UP] = input.buttons[8];
  472. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = input.buttons[9];
  473. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = input.buttons[10];
  474. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] = input.buttons[11];
  475. mapped->buttons[BUTTON_INDEX_META] = input.buttons[15];
  476. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  477. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
  478. mapped->buttons_length = BUTTON_INDEX_COUNT;
  479. mapped->axes_length = AXIS_INDEX_COUNT;
  480. }
  481. void MapperRazerServal(const Gamepad& input, Gamepad* mapped) {
  482. *mapped = input;
  483. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[5]);
  484. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  485. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[6];
  486. mapped->buttons[BUTTON_INDEX_START] = input.buttons[7];
  487. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[9];
  488. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[10];
  489. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  490. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  491. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  492. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  493. AxisPositiveAsButton(input.axes[6]);
  494. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; /* no meta */
  495. mapped->axes_length = AXIS_INDEX_COUNT;
  496. }
  497. void MapperMoga(const Gamepad& input, Gamepad* mapped) {
  498. *mapped = input;
  499. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[5]);
  500. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  501. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = NullButton();
  502. mapped->buttons[BUTTON_INDEX_START] = input.buttons[6];
  503. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[7];
  504. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[8];
  505. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  506. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  507. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  508. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  509. AxisPositiveAsButton(input.axes[6]);
  510. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; /* no meta */
  511. mapped->axes_length = AXIS_INDEX_COUNT;
  512. }
  513. void MapperSamsung_EI_GP20(const Gamepad& input, Gamepad* mapped) {
  514. *mapped = input;
  515. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  516. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  517. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  518. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  519. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = NullButton();
  520. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = NullButton();
  521. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = input.buttons[6];
  522. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = input.buttons[7];
  523. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[10];
  524. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  525. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = NullButton();
  526. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = NullButton();
  527. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[5]);
  528. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[5]);
  529. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[4]);
  530. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  531. AxisPositiveAsButton(input.axes[4]);
  532. mapped->buttons[BUTTON_INDEX_META] = input.buttons[15];
  533. mapped->axes[AXIS_INDEX_LEFT_STICK_X] = input.axes[0];
  534. mapped->axes[AXIS_INDEX_LEFT_STICK_Y] = input.axes[1];
  535. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[2];
  536. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[3];
  537. mapped->buttons_length = BUTTON_INDEX_COUNT;
  538. mapped->axes_length = AXIS_INDEX_COUNT;
  539. }
  540. void MapperSteelSeriesZeemote(const Gamepad& input, Gamepad* mapped) {
  541. *mapped = input;
  542. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  543. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  544. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  545. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  546. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = NullButton();
  547. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = NullButton();
  548. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[12];
  549. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  550. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = NullButton();
  551. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = NullButton();
  552. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[5]);
  553. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[5]);
  554. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[4]);
  555. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  556. AxisPositiveAsButton(input.axes[4]);
  557. mapped->buttons[BUTTON_INDEX_META] = NullButton();
  558. mapped->buttons_length = BUTTON_INDEX_META;
  559. mapped->axes_length = AXIS_INDEX_COUNT;
  560. }
  561. void MapperSteelSeriesStratusXLUsb(const Gamepad& input, Gamepad* mapped) {
  562. *mapped = input;
  563. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  564. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  565. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[2];
  566. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[3];
  567. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[4];
  568. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[5];
  569. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[3]);
  570. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  571. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[18];
  572. mapped->buttons[BUTTON_INDEX_START] = input.buttons[9];
  573. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[10];
  574. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[11];
  575. mapped->buttons[BUTTON_INDEX_DPAD_UP] = input.buttons[12];
  576. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = input.buttons[13];
  577. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = input.buttons[14];
  578. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] = input.buttons[15];
  579. mapped->buttons[BUTTON_INDEX_META] = input.buttons[19];
  580. mapped->axes[AXIS_INDEX_LEFT_STICK_X] = input.axes[0];
  581. mapped->axes[AXIS_INDEX_LEFT_STICK_Y] = input.axes[1];
  582. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[2];
  583. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[5];
  584. mapped->buttons_length = BUTTON_INDEX_COUNT;
  585. mapped->axes_length = AXIS_INDEX_COUNT;
  586. }
  587. void MapperSteelSeriesStratusBt(const Gamepad& input, Gamepad* mapped) {
  588. *mapped = input;
  589. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0];
  590. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  591. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  592. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  593. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  594. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  595. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[5]);
  596. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  597. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[10];
  598. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  599. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[13];
  600. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[14];
  601. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  602. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  603. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  604. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  605. AxisPositiveAsButton(input.axes[6]);
  606. mapped->buttons[BUTTON_INDEX_META] = NullButton();
  607. // The META button currently isn't mappable since it's handled separately as
  608. // key events, causing a browser HOME action. If this is fixed, it should be
  609. // added here.
  610. mapped->axes[AXIS_INDEX_LEFT_STICK_X] = input.axes[0];
  611. mapped->axes[AXIS_INDEX_LEFT_STICK_Y] = input.axes[1];
  612. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[2];
  613. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[3];
  614. mapped->buttons_length = BUTTON_INDEX_META;
  615. mapped->axes_length = AXIS_INDEX_COUNT;
  616. }
  617. void MapperSteelSeriesStratusPlusBt(const Gamepad& input, Gamepad* mapped) {
  618. MapperSteelSeriesStratusBt(input, mapped);
  619. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  620. mapped->buttons_length = BUTTON_INDEX_COUNT;
  621. }
  622. void MapperLogitechDInput(const Gamepad& input, Gamepad* mapped) {
  623. *mapped = input;
  624. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[1];
  625. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[2];
  626. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[0];
  627. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[5]);
  628. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[5]);
  629. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[4]);
  630. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  631. AxisPositiveAsButton(input.axes[4]);
  632. // The Logitech button (BUTTON_INDEX_META) is not accessible through the
  633. // device's D-mode.
  634. mapped->buttons_length = BUTTON_INDEX_COUNT - 1;
  635. mapped->axes_length = AXIS_INDEX_COUNT;
  636. }
  637. void MapperStadiaControllerOldFirmware(const Gamepad& input, Gamepad* mapped) {
  638. *mapped = input;
  639. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[5]);
  640. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  641. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[6];
  642. mapped->buttons[BUTTON_INDEX_START] = input.buttons[8];
  643. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[9];
  644. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[10];
  645. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  646. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  647. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  648. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  649. AxisPositiveAsButton(input.axes[6]);
  650. mapped->buttons[BUTTON_INDEX_META] = input.buttons[7];
  651. mapped->buttons[STADIA_GAMEPAD_BUTTON_EXTRA] = input.buttons[11];
  652. mapped->buttons[STADIA_GAMEPAD_BUTTON_EXTRA2] = input.buttons[12];
  653. mapped->buttons_length = STADIA_GAMEPAD_BUTTON_COUNT;
  654. mapped->axes_length = AXIS_INDEX_COUNT;
  655. }
  656. void MapperStadiaController(const Gamepad& input, Gamepad* mapped) {
  657. *mapped = input;
  658. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[5]);
  659. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[4]);
  660. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[6];
  661. mapped->buttons[BUTTON_INDEX_START] = input.buttons[7];
  662. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[9];
  663. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[10];
  664. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
  665. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
  666. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
  667. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  668. AxisPositiveAsButton(input.axes[6]);
  669. mapped->buttons[BUTTON_INDEX_META] = input.buttons[8];
  670. mapped->buttons[STADIA_GAMEPAD_BUTTON_EXTRA] = input.buttons[11];
  671. mapped->buttons[STADIA_GAMEPAD_BUTTON_EXTRA2] = input.buttons[12];
  672. mapped->buttons_length = STADIA_GAMEPAD_BUTTON_COUNT;
  673. mapped->axes_length = AXIS_INDEX_COUNT;
  674. }
  675. void MapperXSkills(const Gamepad& input, Gamepad* mapped) {
  676. enum GamecubeButtons {
  677. GAMECUBE_BUTTON_LEFT_TRIGGER_CLICK = BUTTON_INDEX_COUNT,
  678. GAMECUBE_BUTTON_RIGHT_TRIGGER_CLICK,
  679. GAMECUBE_BUTTON_COUNT
  680. };
  681. *mapped = input;
  682. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[0]; // A
  683. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[2]; // X
  684. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[1]; // B
  685. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[3]; // Y
  686. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = NullButton();
  687. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[6]; // Z
  688. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[4]);
  689. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[3]);
  690. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = NullButton();
  691. mapped->buttons[BUTTON_INDEX_START] = input.buttons[7];
  692. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = NullButton();
  693. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = NullButton();
  694. mapped->buttons[BUTTON_INDEX_DPAD_UP] = input.buttons[11];
  695. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = input.buttons[10];
  696. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = input.buttons[8];
  697. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] = input.buttons[9];
  698. mapped->buttons[BUTTON_INDEX_META] = NullButton();
  699. mapped->buttons[GAMECUBE_BUTTON_LEFT_TRIGGER_CLICK] = input.buttons[4];
  700. mapped->buttons[GAMECUBE_BUTTON_RIGHT_TRIGGER_CLICK] = input.buttons[5];
  701. mapped->axes[AXIS_INDEX_LEFT_STICK_X] = input.axes[0];
  702. mapped->axes[AXIS_INDEX_LEFT_STICK_Y] = input.axes[1];
  703. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[5];
  704. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[2];
  705. mapped->buttons_length = GAMECUBE_BUTTON_COUNT;
  706. mapped->axes_length = AXIS_INDEX_COUNT;
  707. }
  708. void MapperBoomN64Psx(const Gamepad& input, Gamepad* mapped) {
  709. *mapped = input;
  710. // Mapped for a PSX device with Analog mode enabled.
  711. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[2];
  712. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[1];
  713. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  714. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[0];
  715. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  716. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  717. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = input.buttons[4];
  718. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = input.buttons[5];
  719. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[8];
  720. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  721. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[9];
  722. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[10];
  723. mapped->buttons[BUTTON_INDEX_DPAD_UP] = input.buttons[12];
  724. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = input.buttons[14];
  725. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = input.buttons[15];
  726. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] = input.buttons[13];
  727. mapped->buttons[BUTTON_INDEX_META] = NullButton();
  728. mapped->axes[AXIS_INDEX_LEFT_STICK_X] = input.axes[0];
  729. mapped->axes[AXIS_INDEX_LEFT_STICK_Y] = -input.axes[1];
  730. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[2];
  731. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = -input.axes[3];
  732. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; // no meta
  733. mapped->axes_length = AXIS_INDEX_COUNT;
  734. }
  735. void MapperSnakebyteIDroidCon(const Gamepad& input, Gamepad* mapped) {
  736. *mapped = input;
  737. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[3];
  738. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[4];
  739. mapped->buttons[BUTTON_INDEX_LEFT_SHOULDER] = input.buttons[6];
  740. mapped->buttons[BUTTON_INDEX_RIGHT_SHOULDER] = input.buttons[7];
  741. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[10];
  742. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  743. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[2];
  744. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[5];
  745. mapped->buttons[BUTTON_INDEX_META] = NullButton();
  746. if ((input.axes_used & 0b1000000) == 0) {
  747. // "Game controller 1" mode: digital triggers.
  748. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = input.buttons[8];
  749. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = input.buttons[9];
  750. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[5]);
  751. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] =
  752. AxisPositiveAsButton(input.axes[5]);
  753. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] =
  754. AxisNegativeAsButton(input.axes[4]);
  755. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  756. AxisPositiveAsButton(input.axes[4]);
  757. } else {
  758. // "Game controller 2" mode: analog triggers.
  759. mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] =
  760. AxisPositiveAsButton(input.axes[2]);
  761. mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] =
  762. AxisNegativeAsButton(input.axes[2]);
  763. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[6]);
  764. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] =
  765. AxisPositiveAsButton(input.axes[6]);
  766. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] =
  767. AxisNegativeAsButton(input.axes[5]);
  768. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  769. AxisPositiveAsButton(input.axes[5]);
  770. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  771. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
  772. }
  773. mapped->buttons_length = BUTTON_INDEX_COUNT - 1; // no meta
  774. mapped->axes_length = AXIS_INDEX_COUNT;
  775. }
  776. void MapperHoripadSwitch(const Gamepad& input, Gamepad* mapped) {
  777. *mapped = input;
  778. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[1];
  779. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[2];
  780. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[0];
  781. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[5]);
  782. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[5]);
  783. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[4]);
  784. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  785. AxisPositiveAsButton(input.axes[4]);
  786. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  787. mapped->buttons[SWITCH_PRO_BUTTON_CAPTURE] = input.buttons[13];
  788. mapped->buttons_length = SWITCH_PRO_BUTTON_COUNT;
  789. mapped->axes_length = AXIS_INDEX_COUNT;
  790. }
  791. void MapperElecomWiredDirectInput(const Gamepad& input, Gamepad* mapped) {
  792. *mapped = input;
  793. mapped->buttons[BUTTON_INDEX_PRIMARY] = input.buttons[2];
  794. mapped->buttons[BUTTON_INDEX_SECONDARY] = input.buttons[3];
  795. mapped->buttons[BUTTON_INDEX_TERTIARY] = input.buttons[0];
  796. mapped->buttons[BUTTON_INDEX_QUATERNARY] = input.buttons[1];
  797. mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[5]);
  798. mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[5]);
  799. mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[4]);
  800. mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
  801. AxisPositiveAsButton(input.axes[4]);
  802. mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[10];
  803. mapped->buttons[BUTTON_INDEX_START] = input.buttons[11];
  804. mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[8];
  805. mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[9];
  806. mapped->buttons[BUTTON_INDEX_META] = input.buttons[12];
  807. mapped->buttons_length = BUTTON_INDEX_COUNT;
  808. mapped->axes_length = AXIS_INDEX_COUNT;
  809. }
  810. void MapperElecomWirelessDirectInput(const Gamepad& input, Gamepad* mapped) {
  811. MapperElecomWiredDirectInput(input, mapped);
  812. mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
  813. mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[2];
  814. }
  815. constexpr struct MappingData {
  816. GamepadId gamepad_id;
  817. GamepadStandardMappingFunction function;
  818. } AvailableMappings[] = {
  819. // PowerA Wireless Controller - Nintendo GameCube style
  820. {GamepadId::kPowerALicPro, MapperSwitchPro},
  821. // DragonRise Generic USB
  822. {GamepadId::kDragonRiseProduct0006, MapperDragonRiseGeneric},
  823. // HORIPAD for Nintendo Switch
  824. {GamepadId::kHoriProduct00c1, MapperHoripadSwitch},
  825. // Xbox One S (Bluetooth)
  826. {GamepadId::kMicrosoftProduct02e0, MapperXboxOneS},
  827. // Xbox One S (Bluetooth)
  828. {GamepadId::kMicrosoftProduct02fd, MapperXboxOneS2016Firmware},
  829. // Xbox One Elite 2 (Bluetooth)
  830. {GamepadId::kMicrosoftProduct0b05, MapperXboxElite2Bluetooth},
  831. // Xbox Series X (Bluetooth)
  832. {GamepadId::kMicrosoftProduct0b13, MapperXboxSeriesXBluetooth},
  833. // Xbox One S (Bluetooth)
  834. {GamepadId::kMicrosoftProduct0b20, MapperXboxBluetooth},
  835. // Xbox Adaptive (Bluetooth)
  836. {GamepadId::kMicrosoftProduct0b21, MapperXboxBluetooth},
  837. // Xbox Elite Series 2 (Bluetooth)
  838. {GamepadId::kMicrosoftProduct0b22, MapperXboxBluetooth},
  839. // Logitech F310 D-mode
  840. {GamepadId::kLogitechProductc216, MapperLogitechDInput},
  841. // Logitech F510 D-mode
  842. {GamepadId::kLogitechProductc218, MapperLogitechDInput},
  843. // Logitech F710 D-mode
  844. {GamepadId::kLogitechProductc219, MapperLogitechDInput},
  845. // Samsung Gamepad EI-GP20
  846. {GamepadId::kSamsungElectronicsProducta000, MapperSamsung_EI_GP20},
  847. // Dualshock 3 / SIXAXIS
  848. {GamepadId::kSonyProduct0268, MapperDualshock3SixAxis},
  849. // Playstation Dualshock 4
  850. {GamepadId::kSonyProduct05c4, MapperDualshock4},
  851. // Dualshock 4 (PS4 Slim)
  852. {GamepadId::kSonyProduct09cc, MapperDualshock4},
  853. // Dualshock 4 USB receiver
  854. {GamepadId::kSonyProduct0ba0, MapperDualshock4},
  855. // DualSense
  856. {GamepadId::kSonyProduct0ce6, MapperDualSense},
  857. // Switch Joy-Con L
  858. {GamepadId::kNintendoProduct2006, MapperSwitchJoyCon},
  859. // Switch Joy-Con R
  860. {GamepadId::kNintendoProduct2007, MapperSwitchJoyCon},
  861. // Switch Pro Controller
  862. {GamepadId::kNintendoProduct2009, MapperSwitchPro},
  863. // Switch Charging Grip
  864. {GamepadId::kNintendoProduct200e, MapperSwitchPro},
  865. // iBuffalo Classic
  866. {GamepadId::kPadixProduct2060, MapperIBuffalo},
  867. // SmartJoy PLUS Adapter
  868. {GamepadId::kLakeviewResearchProduct0005, MapperLakeviewResearch},
  869. // WiseGroup MP-8866
  870. {GamepadId::kLakeviewResearchProduct8866, MapperLakeviewResearch},
  871. // Nvidia Shield gamepad (2015)
  872. {GamepadId::kNvidiaProduct7210, MapperNvShield},
  873. // Nvidia Shield gamepad (2017)
  874. {GamepadId::kNvidiaProduct7214, MapperNvShield2017},
  875. // Nexus Player Controller
  876. {GamepadId::kAsusTekProduct4500, MapperADT1},
  877. // XSkills Gamecube USB adapter
  878. {GamepadId::kPlayComProduct0005, MapperXSkills},
  879. // XFXforce XGEAR PS2 Controller
  880. {GamepadId::kGreenAsiaProduct0003, MapperXGEAR},
  881. // Zeemote: SteelSeries FREE
  882. {GamepadId::kSteelSeriesProduct1412, MapperSteelSeriesZeemote},
  883. // SteelSeries Stratus XL USB
  884. {GamepadId::kSteelSeriesProduct1418, MapperSteelSeriesStratusXLUsb},
  885. // SteelSeries Stratus XL Bluetooth
  886. {GamepadId::kSteelSeriesBtProduct1419, MapperSteelSeriesStratusBt},
  887. // SteelSeries Stratus Duo Bluetooth
  888. {GamepadId::kSteelSeriesBtProduct1431, MapperSteelSeriesStratusBt},
  889. // SteelSeries Stratus+ Bluetooth
  890. {GamepadId::kSteelSeriesBtProduct1434, MapperSteelSeriesStratusPlusBt},
  891. // Razer Serval Controller
  892. {GamepadId::kRazer1532Product0900, MapperRazerServal},
  893. // ADT-1 Controller
  894. {GamepadId::kGoogleProduct2c40, MapperADT1},
  895. // Stadia Controller
  896. {GamepadId::kGoogleProduct9400, MapperStadiaController},
  897. // Moga Pro Controller (HID mode)
  898. {GamepadId::kBdaProduct6271, MapperMoga},
  899. // Moga 2 HID
  900. {GamepadId::kBdaProduct89e5, MapperMoga},
  901. // OnLive Controller (Bluetooth)
  902. {GamepadId::kOnLiveProduct1008, MapperOnLiveWireless},
  903. // OnLive Controller (Wired)
  904. {GamepadId::kOnLiveProduct100a, MapperOnLiveWireless},
  905. // OUYA Controller
  906. {GamepadId::kOuyaProduct0001, MapperOUYA},
  907. // SCUF Vantage, SCUF Vantage 2
  908. {GamepadId::kScufProduct7725, MapperDualshock4},
  909. // boom PSX+N64 USB Converter
  910. {GamepadId::kPrototypeVendorProduct0667, MapperBoomN64Psx},
  911. // Stadia Controller prototype
  912. {GamepadId::kPrototypeVendorProduct9401, MapperStadiaControllerOldFirmware},
  913. // Snakebyte iDroid:con
  914. {GamepadId::kBroadcomProduct8502, MapperSnakebyteIDroidCon},
  915. // Elecom JC-U4013SBK (DirectInput mode)
  916. {GamepadId::kElecomProduct200f, MapperElecomWiredDirectInput},
  917. // Elecom JC-U4113SBK (DirectInput mode)
  918. {GamepadId::kElecomProduct2010, MapperElecomWirelessDirectInput},
  919. };
  920. } // namespace
  921. GamepadStandardMappingFunction GetGamepadStandardMappingFunction(
  922. const base::StringPiece product_name,
  923. const uint16_t vendor_id,
  924. const uint16_t product_id,
  925. const uint16_t hid_specification_version,
  926. const uint16_t version_number,
  927. GamepadBusType bus_type) {
  928. GamepadId gamepad_id =
  929. GamepadIdList::Get().GetGamepadId(product_name, vendor_id, product_id);
  930. const MappingData* begin = std::begin(AvailableMappings);
  931. const MappingData* end = std::end(AvailableMappings);
  932. const auto* find_it = std::find_if(begin, end, [=](const MappingData& item) {
  933. return gamepad_id == item.gamepad_id;
  934. });
  935. GamepadStandardMappingFunction mapper =
  936. (find_it == end) ? nullptr : find_it->function;
  937. // The Linux kernel was updated in version 4.10 to better support Dualshock 4
  938. // and Dualshock 3/SIXAXIS gamepads. The driver patches the bcdHID value when
  939. // using the new mapping to allow downstream users to distinguish them.
  940. if (mapper == MapperDualshock4 &&
  941. (hid_specification_version & kDualshockPatchedBcdHidMask)) {
  942. mapper = MapperPs4Ps5;
  943. } else if (mapper == MapperDualshock3SixAxis &&
  944. (hid_specification_version & kDualshockPatchedBcdHidMask)) {
  945. mapper = MapperDualshock3SixAxisNew;
  946. } else if (mapper == MapperDualSense &&
  947. (hid_specification_version & kDualshockPatchedBcdHidMask)) {
  948. mapper = MapperPs4Ps5;
  949. }
  950. // The Switch Joy-Con Charging Grip allows a pair of Joy-Cons to be docked
  951. // with the grip and used over USB as a single composite gamepad. The Nintendo
  952. // data fetcher also allows a pair of Bluetooth-connected Joy-Cons to be used
  953. // as a composite device and sets the same product ID as the Charging Grip.
  954. //
  955. // In both configurations, we remap the Joy-Con buttons to align with the
  956. // Standard Gamepad mapping. Docking a Joy-Con in the Charging Grip makes the
  957. // SL and SR buttons inaccessible.
  958. //
  959. // If the Joy-Cons are not docked, the SL and SR buttons are still accessible.
  960. // Inspect the |bus_type| of the composite device to detect this case and use
  961. // an alternate mapping function that exposes the extra buttons.
  962. if (gamepad_id == GamepadId::kNintendoProduct200e &&
  963. mapper == MapperSwitchPro && bus_type != GAMEPAD_BUS_USB) {
  964. mapper = MapperSwitchComposite;
  965. }
  966. // Use an alternate mapping function if the Stadia controller is using an old
  967. // firmware version.
  968. if (gamepad_id == GamepadId::kGoogleProduct9400 &&
  969. mapper == MapperStadiaController &&
  970. version_number == kStadiaControllerOldFirmwareVersion) {
  971. mapper = MapperStadiaControllerOldFirmware;
  972. }
  973. // If no mapper was found, check if the device is a known XInput gamepad.
  974. if (mapper == nullptr) {
  975. XInputType xtype =
  976. GamepadIdList::Get().GetXInputType(vendor_id, product_id);
  977. if (xtype == kXInputTypeXbox360 || xtype == kXInputTypeXboxOne)
  978. mapper = MapperXInputStyleGamepad;
  979. }
  980. return mapper;
  981. }
  982. } // namespace device