gamepad_util.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #include "gamepad_util.h"
  2. #include "triton.h"
  3. #include "config.h"
  4. void psNeutralCalib(uint8_t *buf)
  5. {
  6. // Payload offsets = kernel buf[] index minus 1. buf[0..5] gyro bias stays zero (caller memset). Symmetric
  7. // ranges -> non-zero divisors on the host.
  8. le16(buf + 6, 2844);
  9. le16(buf + 8, -2844); // gyro pitch +/-
  10. le16(buf + 10, 2844);
  11. le16(buf + 12, -2844); // gyro yaw +/-
  12. le16(buf + 14, 2844);
  13. le16(buf + 16, -2844); // gyro roll +/-
  14. le16(buf + 18, 2844);
  15. le16(buf + 20, 2844); // gyro speed +/- (sum != 0)
  16. le16(buf + 22, 8192);
  17. le16(buf + 24, -8192); // accel X +/-
  18. le16(buf + 26, 8192);
  19. le16(buf + 28, -8192); // accel Y +/-
  20. le16(buf + 30, 8192);
  21. le16(buf + 32, -8192); // accel Z +/-
  22. }
  23. uint8_t swStick(int16_t v, bool invert)
  24. {
  25. int32_t a = 0x80 + (invert ? -((int32_t)v >> 8) : ((int32_t)v >> 8));
  26. if (a < 0)
  27. a = 0;
  28. if (a > 255)
  29. a = 255;
  30. return (uint8_t)a;
  31. }
  32. // Map Steam trackpad s16 coords into a 0..max axis (centered touch -> mid-range).
  33. uint16_t padNormU16(int16_t v, uint16_t maxv)
  34. {
  35. int32_t t = ((int32_t)v + 32768);
  36. if (t < 0)
  37. t = 0;
  38. if (t > 65535)
  39. t = 65535;
  40. return (uint16_t)((t * (int32_t)maxv) / 65535);
  41. }
  42. uint16_t touchHalfX(int16_t v, bool rightHalf)
  43. {
  44. uint16_t halfMax = TOUCH_PAD_W / 2 - 1;
  45. uint16_t x = padNormU16(v, halfMax);
  46. return rightHalf ? (uint16_t)(TOUCH_PAD_W / 2 + x) : x;
  47. }
  48. uint16_t touchYInv(int16_t v, uint16_t height)
  49. {
  50. uint16_t maxy = height - 1;
  51. return (uint16_t)(maxy - padNormU16(v, maxy));
  52. }
  53. void touchPackPoint(uint8_t *base, int finger, bool touch, uint16_t x,
  54. uint16_t y)
  55. {
  56. uint8_t *f = base + finger * 4;
  57. if (!touch) {
  58. f[0] = 0x80;
  59. f[1] = 0;
  60. f[2] = 0;
  61. f[3] = 0;
  62. return;
  63. }
  64. f[0] = (uint8_t)(finger & 0x7F);
  65. f[1] = (uint8_t)(x & 0xFF);
  66. f[2] = (uint8_t)(((x >> 8) & 0x0F) | ((y & 0x0F) << 4));
  67. f[3] = (uint8_t)((y >> 4) & 0xFF);
  68. }
  69. void touchPackPads(uint8_t *pts, bool lTouch, bool rTouch, uint16_t lx,
  70. uint16_t ly, uint16_t rx, uint16_t ry)
  71. {
  72. touchPackPoint(pts, 0, false, 0, 0);
  73. touchPackPoint(pts, 1, false, 0, 0);
  74. if (lTouch && rTouch) {
  75. touchPackPoint(pts, 0, true, lx, ly);
  76. touchPackPoint(pts, 1, true, rx, ry);
  77. } else if (lTouch) {
  78. touchPackPoint(pts, 0, true, lx, ly);
  79. } else if (rTouch) {
  80. touchPackPoint(pts, 0, true, rx, ry);
  81. }
  82. }
  83. void steamPadsToTouch(uint32_t b, uint16_t touchH, int16_t lpx, int16_t lpy,
  84. int16_t rpx, int16_t rpy, uint16_t *lx, uint16_t *ly,
  85. uint16_t *rx, uint16_t *ry)
  86. {
  87. bool lt = (b & TB_LPADT) || (b & TB_LPADC),
  88. rt = (b & TB_RPADT) || (b & TB_RPADC);
  89. *lx = touchHalfX(lpx, false);
  90. *ly = touchYInv(lpy, touchH);
  91. *rx = touchHalfX(rpx, true);
  92. *ry = touchYInv(rpy, touchH);
  93. if (lt && !(b & TB_LPADT)) {
  94. *lx = TOUCH_PAD_W / 4;
  95. *ly = touchH / 2;
  96. }
  97. if (rt && !(b & TB_RPADT)) {
  98. *rx = TOUCH_PAD_W / 4 * 3;
  99. *ry = touchH / 2;
  100. }
  101. }
  102. // Map g_back[] paddle code -> Steam button flags (same codes as codeToXB / codeToSwitch).
  103. static void psOrBackCode(uint32_t *b, uint8_t c)
  104. {
  105. switch (c) {
  106. case 1:
  107. *b |= TB_A;
  108. break;
  109. case 2:
  110. *b |= TB_B;
  111. break;
  112. case 3:
  113. *b |= TB_X;
  114. break;
  115. case 4:
  116. *b |= TB_Y;
  117. break;
  118. case 5:
  119. *b |= TB_LB;
  120. break;
  121. case 6:
  122. *b |= TB_RB;
  123. break;
  124. case 7:
  125. *b |= TB_L3;
  126. break;
  127. case 8:
  128. *b |= TB_R3;
  129. break;
  130. case 9:
  131. *b |= TB_VIEW;
  132. break;
  133. case 10:
  134. *b |= TB_QAM;
  135. break;
  136. case 11:
  137. *b |= TB_STEAM;
  138. break;
  139. case 12:
  140. *b |= TB_DUP;
  141. break;
  142. case 13:
  143. *b |= TB_DDN;
  144. break;
  145. case 14:
  146. *b |= TB_DLF;
  147. break;
  148. case 15:
  149. *b |= TB_DRT;
  150. break;
  151. case 16:
  152. *b |= TB_TOUCH;
  153. break;
  154. case 17:
  155. *b |= TB_MUTE;
  156. break;
  157. default:
  158. break;
  159. }
  160. }
  161. uint32_t psButtonsFromSteam(uint32_t raw)
  162. {
  163. uint32_t b = raw;
  164. if (g_qamMap && (b & TB_QAM)) {
  165. b &= ~(uint32_t)TB_QAM;
  166. b |= tritonFromCode(g_qamMap);
  167. }
  168. if ((b & CHORD_BACK4) == CHORD_BACK4)
  169. b &= ~(uint32_t)(TB_A | TB_B | TB_X | TB_Y);
  170. if (b & TB_L4)
  171. psOrBackCode(&b, g_back[0]);
  172. if (b & TB_R4)
  173. psOrBackCode(&b, g_back[1]);
  174. if (b & TB_L5)
  175. psOrBackCode(&b, g_back[2]);
  176. if (b & TB_R5)
  177. psOrBackCode(&b, g_back[3]);
  178. return b;
  179. }
  180. // DualSense / DS4 buttons[1]: L1..R3, Create(Share), Options(Start)
  181. uint8_t psShouldersByte(uint32_t b)
  182. {
  183. return ((b & TB_LB) ? 0x01 : 0) | ((b & TB_RB) ? 0x02 : 0) |
  184. ((g_in.lt > SW_TRIG_ON || (b & 0x8000000u)) ? 0x04 : 0) |
  185. ((g_in.rt > SW_TRIG_ON || (b & 0x800000u)) ? 0x08 : 0) |
  186. ((b & TB_MENU) ? 0x10 : 0) |
  187. ((b & TB_VIEW) ? 0x20 : 0) // Menu=Options, View=Create/Share
  188. | ((b & TB_L3) ? 0x40 : 0) | ((b & TB_R3) ? 0x80 : 0);
  189. }
  190. uint8_t psHatNibble(uint32_t b)
  191. {
  192. bool u = b & TB_DUP, d = b & TB_DDN, l = b & TB_DLF, r = b & TB_DRT;
  193. if (u && r)
  194. return 1;
  195. if (r && d)
  196. return 3;
  197. if (d && l)
  198. return 5;
  199. if (l && u)
  200. return 7;
  201. if (u)
  202. return 0;
  203. if (r)
  204. return 2;
  205. if (d)
  206. return 4;
  207. if (l)
  208. return 6;
  209. return 8;
  210. }
  211. uint8_t psFaceNibble(uint32_t b)
  212. {
  213. uint8_t f = 0;
  214. if (g_abSwap) {
  215. if (b & TB_A)
  216. f |= 0x40;
  217. if (b & TB_B)
  218. f |= 0x20;
  219. if (b & TB_X)
  220. f |= 0x80;
  221. if (b & TB_Y)
  222. f |= 0x10;
  223. } else {
  224. if (b & TB_A)
  225. f |= 0x20;
  226. if (b & TB_B)
  227. f |= 0x40;
  228. if (b & TB_X)
  229. f |= 0x10;
  230. if (b & TB_Y)
  231. f |= 0x80;
  232. }
  233. return f;
  234. }