gamepad_util.h 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // gamepad_util.h -- shared helpers for building host USB gamepad reports from g_in.
  2. //
  3. // These are reused across the DualSense / DS4 / Switch personalities: analog-stick rescaling, Steam-trackpad
  4. // -> absolute-touch mapping, and the PlayStation-layout button/hat/face/shoulder packers. Per-target button
  5. // code maps (codeToXB / codeToSwitch / codeToJc) live with their own controllers; only the cross-mode pieces
  6. // are here.
  7. #pragma once
  8. #include <stdint.h>
  9. #include "triton.h"
  10. // int16 stick (center 0) -> uint8 (center 0x80), optional axis invert (HID Y is down-positive).
  11. uint8_t swStick(int16_t v, bool invert);
  12. // Write a signed 16-bit value little-endian.
  13. static inline void le16(uint8_t *p, int16_t v)
  14. {
  15. p[0] = (uint8_t)(v & 0xFF);
  16. p[1] = (uint8_t)((v >> 8) & 0xFF);
  17. }
  18. // Fill a DS4/DualSense motion-calibration feature report PAYLOAD. The TinyUSB GET_REPORT path already wrote the
  19. // report id and hands us the buffer PAST it, so our offsets = the kernel's buf[] index minus one (bias at 0..5,
  20. // stays zero from the caller's memset). Zero bias + symmetric non-zero ranges so hid-playstation's/hid-sony's
  21. // divisor (|plus-bias|+|minus-bias|, and gyro speed_plus+speed_minus) is never zero. Shared by report 0x02 (DS4)
  22. // and 0x05 (DualSense) -- identical layout; the caller returns size-1 and leaves trailing bytes zero.
  23. void psNeutralCalib(uint8_t *buf);
  24. // Steam trackpad s16 coords -> absolute touch surface. TOUCH_PAD_W is split into left/right halves so both
  25. // pads can co-exist as two contacts on a single DualSense/DS4 touchpad.
  26. #define TOUCH_PAD_W 1920u
  27. uint16_t padNormU16(int16_t v, uint16_t maxv);
  28. uint16_t touchHalfX(int16_t v, bool rightHalf);
  29. uint16_t touchYInv(int16_t v, uint16_t height);
  30. void touchPackPoint(uint8_t *base, int finger, bool touch, uint16_t x,
  31. uint16_t y);
  32. // DualSense / DS4: many hosts only honor contact slot 0 -- put a lone pad in slot 0, both pads in 0+1.
  33. void touchPackPads(uint8_t *pts, bool lTouch, bool rTouch, uint16_t lx,
  34. uint16_t ly, uint16_t rx, uint16_t ry);
  35. void steamPadsToTouch(uint32_t b, uint16_t touchH, int16_t lpx, int16_t lpy,
  36. int16_t rpx, int16_t rpy, uint16_t *lx, uint16_t *ly,
  37. uint16_t *rx, uint16_t *ry);
  38. // Convert configurable button code -> TB_* flag (shared across modes).
  39. static inline uint32_t tritonFromCode(uint8_t c)
  40. {
  41. switch (c) {
  42. case 1:
  43. return TB_A;
  44. case 2:
  45. return TB_B;
  46. case 3:
  47. return TB_X;
  48. case 4:
  49. return TB_Y;
  50. case 5:
  51. return TB_LB;
  52. case 6:
  53. return TB_RB;
  54. case 7:
  55. return TB_L3;
  56. case 8:
  57. return TB_R3;
  58. case 9:
  59. return TB_VIEW;
  60. case 10:
  61. return TB_QAM;
  62. case 11:
  63. return TB_STEAM;
  64. case 12:
  65. return TB_DUP;
  66. case 13:
  67. return TB_DDN;
  68. case 14:
  69. return TB_DLF;
  70. case 15:
  71. return TB_DRT;
  72. case 16:
  73. return TB_TOUCH;
  74. case 17:
  75. return TB_MUTE;
  76. case 19:
  77. return TB_L2; // left trigger (LT / L2 / ZL)
  78. case 20:
  79. return TB_R2; // right trigger (RT / R2 / ZR)
  80. default:
  81. return 0;
  82. }
  83. }
  84. // PlayStation-layout button packing (shared by mode_ps5 + mode_hidgyro).
  85. uint32_t psButtonsFromSteam(
  86. uint32_t raw); // apply back-paddle + chord-guard + QAM remapping
  87. // L1..R3 + Create/Options byte. lt/rt are the per-slot analog trigger values so the digital ZL/ZR trip
  88. // doesn't leak across slots when several slots are active.
  89. uint8_t psShouldersByte(uint32_t b, uint8_t lt, uint8_t rt);
  90. uint8_t psHatNibble(uint32_t b); // d-pad -> 8-way hat (8 = neutral)
  91. uint8_t psFaceNibble(uint32_t b); // face buttons (with A/B + X/Y swap)