mode_lizard.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "mode_lizard.h"
  2. #include "triton.h"
  3. #include "config.h"
  4. void rfLizard(const uint8_t *r, Adafruit_USBD_HID *mdev,
  5. Adafruit_USBD_HID *kdev, uint8_t mrid, uint8_t krid)
  6. {
  7. uint32_t b = btnsOf(r);
  8. bool qamHeld = (b & TB_QAM) != 0;
  9. // --- right pad -> mouse motion with glide (mirrors mode_xinput's rfXboxMouse) ---
  10. static int prx = 0, pry = 0;
  11. static bool prt = false;
  12. static float vx = 0, vy = 0, rmx = 0, rmy = 0;
  13. bool rtouch = b & TB_RPADT;
  14. int rx = s16off(r, 22), ry = s16off(r, 24);
  15. if (rtouch) {
  16. if (prt) {
  17. vx += (rx - prx);
  18. vy += (ry - pry);
  19. }
  20. prx = rx;
  21. pry = ry;
  22. }
  23. prt = rtouch;
  24. // Y inverted; *10 = desktop-cursor sensitivity (g_mDiv 64 -> eff 640). Lower g_mDiv via WebUI slider = faster.
  25. float mxf = vx / (float)(g_mDiv * 10) + rmx,
  26. myf = -(vy / (float)(g_mDiv * 10)) + rmy;
  27. int dx = (int)mxf, dy = (int)myf;
  28. rmx = mxf - dx;
  29. rmy = myf - dy; // sub-pixel carry
  30. if (dx > 127)
  31. dx = 127;
  32. if (dx < -127)
  33. dx = -127;
  34. if (dy > 127)
  35. dy = 127;
  36. if (dy < -127)
  37. dy = -127;
  38. float f = g_mFric / 100.0f;
  39. vx *= f;
  40. vy *= f;
  41. if (vx > -1 && vx < 1)
  42. vx = 0;
  43. if (vy > -1 && vy < 1)
  44. vy = 0; // friction = glide/decay
  45. // --- left pad -> vertical scroll wheel (no momentum; only while touching, coarse) ---
  46. static int ply = 0;
  47. static bool plt = false;
  48. static float sacc = 0;
  49. bool ltouch = b & TB_LPADT;
  50. int ly = s16off(r, 18);
  51. if (ltouch) {
  52. if (plt) {
  53. sacc += (ly - ply) / (float)(g_mDiv * 24);
  54. }
  55. ply = ly;
  56. } else
  57. sacc = 0;
  58. plt = ltouch;
  59. int dw = (int)sacc;
  60. sacc -= dw;
  61. if (dw > 15)
  62. dw = 15;
  63. if (dw < -15)
  64. dw = -15; // finger up = wheel up (positive)
  65. // --- mouse buttons: left=R-pad-click|R-trigger, right=L-trigger, middle=L-pad-click ---
  66. // trigU8 scales full-range so a full pull reaches ~0xFF; a raw >>8 tops out ~0x80, never crossing threshold.
  67. uint8_t rtrig = trigU8(u16off(r, 6)), ltrig = trigU8(u16off(r, 4));
  68. uint8_t mbtn = 0;
  69. if ((b & TB_RPADC) || rtrig > 180)
  70. mbtn |= 1; // right trigger -> left (primary) click
  71. if (ltrig > 180)
  72. mbtn |= 2; // left trigger -> right click
  73. if (b & TB_LPADC)
  74. mbtn |= 4;
  75. static uint8_t pmbtn = 0;
  76. if (dx || dy || dw || mbtn != pmbtn) {
  77. pmbtn = mbtn;
  78. hid_mouse_report_t m;
  79. m.buttons = mbtn;
  80. m.x = (int8_t)dx;
  81. m.y = (int8_t)dy;
  82. m.wheel = (int8_t)dw;
  83. m.pan = 0;
  84. if (mdev->ready())
  85. mdev->sendReport(mrid, &m, sizeof m);
  86. }
  87. // --- keyboard: modifiers + up to 6 keycodes ---
  88. uint8_t mod = 0, kc[6] = { 0, 0, 0, 0, 0, 0 }, nk = 0;
  89. if (b & TB_LB)
  90. mod |= KEYBOARD_MODIFIER_LEFTCTRL;
  91. if (b & TB_RB)
  92. mod |= KEYBOARD_MODIFIER_LEFTALT;
  93. #define LZK(cond, code) \
  94. do { \
  95. if ((cond) && nk < 6) \
  96. kc[nk++] = (code); \
  97. } while (0)
  98. LZK(b & TB_A, HID_KEY_ENTER);
  99. LZK(b & TB_B, HID_KEY_ESCAPE);
  100. LZK(b & TB_X, HID_KEY_PAGE_UP);
  101. LZK(b & TB_Y, HID_KEY_PAGE_DOWN);
  102. LZK(b & TB_VIEW,
  103. (g_usbMode == MODE_LIZARD) ? HID_KEY_ESCAPE : HID_KEY_TAB);
  104. LZK(b & TB_MENU,
  105. (g_usbMode == MODE_LIZARD) ? HID_KEY_TAB : HID_KEY_ESCAPE);
  106. // left stick (XInput sign: +Y = up); deflect ~37% acts as a d-pad
  107. int sx = s16off(r, 8), sy = s16off(r, 10);
  108. LZK((b & TB_DUP) || sy > 12000, HID_KEY_ARROW_UP);
  109. LZK((b & TB_DDN) || sy < -12000, HID_KEY_ARROW_DOWN);
  110. LZK((b & TB_DLF) || sx < -12000, HID_KEY_ARROW_LEFT);
  111. LZK((b & TB_DRT) || sx > 12000, HID_KEY_ARROW_RIGHT);
  112. #undef LZK
  113. if (g_usbMode == MODE_LIZARD) {
  114. static bool prevL5 = false, prevR5 = false;
  115. bool mh = (b & TB_STEAM) || qamHeld;
  116. bool nL5 = mh && (b & TB_L5), nR5 = mh && (b & TB_R5);
  117. if (nL5 && !prevL5) {
  118. uint8_t cc = 0x02;
  119. if (mdev->ready())
  120. mdev->sendReport(0x03, &cc, 1);
  121. }
  122. if (nR5 && !prevR5) {
  123. uint8_t cc = 0x01;
  124. if (mdev->ready())
  125. mdev->sendReport(0x03, &cc, 1);
  126. }
  127. if ((!nL5 && prevL5) || (!nR5 && prevR5)) {
  128. uint8_t cc = 0x00;
  129. if (mdev->ready())
  130. mdev->sendReport(0x03, &cc, 1);
  131. }
  132. prevL5 = nL5;
  133. prevR5 = nR5;
  134. if (mh && (b & TB_X)) {
  135. mod = KEYBOARD_MODIFIER_LEFTGUI |
  136. KEYBOARD_MODIFIER_LEFTCTRL;
  137. kc[0] = HID_KEY_O;
  138. kc[1] = 0;
  139. kc[2] = 0;
  140. kc[3] = 0;
  141. kc[4] = 0;
  142. kc[5] = 0;
  143. nk = 1;
  144. }
  145. if (mh && (b & TB_L4)) {
  146. mod = KEYBOARD_MODIFIER_LEFTCTRL |
  147. KEYBOARD_MODIFIER_LEFTALT;
  148. kc[0] = HID_KEY_DELETE;
  149. kc[1] = 0;
  150. kc[2] = 0;
  151. kc[3] = 0;
  152. kc[4] = 0;
  153. kc[5] = 0;
  154. nk = 1;
  155. }
  156. }
  157. static uint8_t pmod = 0, pkc[6] = { 0, 0, 0, 0, 0, 0 };
  158. bool chg = (mod != pmod);
  159. for (int i = 0; i < 6; i++)
  160. if (kc[i] != pkc[i])
  161. chg = true;
  162. if (chg) {
  163. pmod = mod;
  164. for (int i = 0; i < 6; i++)
  165. pkc[i] = kc[i];
  166. uint8_t krep[8] = { mod, 0, kc[0], kc[1],
  167. kc[2], kc[3], kc[4], kc[5] };
  168. if (kdev->ready())
  169. kdev->sendReport(krid, krep, 8);
  170. }
  171. }