mode_lizard.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include "mode_lizard.h"
  2. #include "lizard_map.h"
  3. #include "triton.h"
  4. #include "config.h"
  5. #include <string.h>
  6. void rfLizard(Adafruit_USBD_HID *mdev, Adafruit_USBD_HID *kdev, uint8_t mrid,
  7. uint8_t krid)
  8. {
  9. const PuckInput &in = g_in[0];
  10. uint32_t buttons = in.buttons;
  11. // Append virtual stick-deflection bits so bindings can trigger on stick direction
  12. if (in.lx > 12000)
  13. buttons |= LZ_BTN_LSTICK_RT;
  14. if (in.lx < -12000)
  15. buttons |= LZ_BTN_LSTICK_LF;
  16. if (in.ly < -12000)
  17. buttons |= LZ_BTN_LSTICK_DN;
  18. if (in.ly > 12000)
  19. buttons |= LZ_BTN_LSTICK_UP;
  20. // ---- accumulate outputs from the binding table ----
  21. uint8_t outMod = 0;
  22. uint8_t outKeys[6] = { 0, 0, 0, 0, 0, 0 };
  23. uint8_t nKeys = 0;
  24. uint8_t outMBtn = 0;
  25. bool doRpadMouse = false, doLpadScroll = false;
  26. uint8_t consumerBits = 0;
  27. // kbdConsumed: any trig bits claimed by a hold-modifier binding so that simpler
  28. // single-button bindings sharing those bits are suppressed.
  29. uint32_t kbdConsumed = 0;
  30. for (uint8_t i = 0; i < g_lizardMap.count; i++) {
  31. const LizardBinding &b = g_lizardMap.bindings[i];
  32. if (b.outType == LZ_OUT_NONE)
  33. continue;
  34. if (b.outType == LZ_OUT_MOUSE_AXIS) {
  35. if (b.outData[0] == LZ_MSRC_RPAD)
  36. doRpadMouse = true;
  37. // LZ_MSRC_LSTICK and LZ_MSRC_GYRO could be added later
  38. continue;
  39. }
  40. if (b.outType == LZ_OUT_SCROLL) {
  41. if (b.outData[0] == LZ_MSRC_LPAD)
  42. doLpadScroll = true;
  43. continue;
  44. }
  45. // Check hold modifier (AND) then trigger (any-of OR)
  46. if (b.holdMask && (buttons & b.holdMask) != b.holdMask)
  47. continue;
  48. if (b.trigMask && (buttons & b.trigMask) == 0)
  49. continue;
  50. switch (b.outType) {
  51. case LZ_OUT_MOUSE_BTN:
  52. if (!b.trigMask || (buttons & b.trigMask))
  53. outMBtn |= b.outData[0];
  54. break;
  55. case LZ_OUT_KBD_CHORD:
  56. // suppress if trig bits already claimed by a hold-modifier binding
  57. if (b.holdMask == 0 && b.trigMask != 0 &&
  58. (b.trigMask & kbdConsumed))
  59. break;
  60. outMod |= b.outData[0];
  61. for (int j = 1; j < 7 && b.outData[j]; j++) {
  62. if (nKeys < 6)
  63. outKeys[nKeys++] = b.outData[j];
  64. }
  65. // claim trig bits so simpler bindings don't double-fire
  66. if (b.holdMask != 0)
  67. kbdConsumed |= b.trigMask;
  68. break;
  69. case LZ_OUT_CONSUMER:
  70. if (g_usbMode == MODE_LIZARD)
  71. consumerBits |= b.outData[0];
  72. break;
  73. default:
  74. break;
  75. }
  76. }
  77. // ---- right pad -> mouse motion with glide ----
  78. static int prx = 0, pry = 0;
  79. static bool prt = false;
  80. static float vx = 0, vy = 0, rmx = 0, rmy = 0;
  81. int dx = 0, dy = 0;
  82. if (doRpadMouse) {
  83. bool rtouch = (buttons & TB_RPADT) != 0;
  84. int rx = in.rpx, ry = in.rpy;
  85. if (rtouch && prt) {
  86. vx += (rx - prx);
  87. vy += (ry - pry);
  88. }
  89. if (rtouch) {
  90. prx = rx;
  91. pry = ry;
  92. }
  93. prt = rtouch;
  94. // Y inverted; *10 = desktop cursor sensitivity (g_mDiv 64 -> eff 640)
  95. float mxf = vx / (float)(g_mDiv * 10) + rmx,
  96. myf = -(vy / (float)(g_mDiv * 10)) + rmy;
  97. dx = (int)mxf;
  98. dy = (int)myf;
  99. rmx = mxf - dx;
  100. rmy = myf - dy; // sub-pixel carry
  101. if (dx > 127)
  102. dx = 127;
  103. if (dx < -127)
  104. dx = -127;
  105. if (dy > 127)
  106. dy = 127;
  107. if (dy < -127)
  108. dy = -127;
  109. float f = g_mFric / 100.0f;
  110. vx *= f;
  111. vy *= f;
  112. if (vx > -1 && vx < 1)
  113. vx = 0;
  114. if (vy > -1 && vy < 1)
  115. vy = 0;
  116. }
  117. // ---- left pad -> scroll wheel ----
  118. static int ply = 0;
  119. static bool plt = false;
  120. static float sacc = 0;
  121. int dw = 0;
  122. if (doLpadScroll) {
  123. bool ltouch = (buttons & TB_LPADT) != 0;
  124. int ly = in.lpy;
  125. if (ltouch && plt)
  126. sacc += (ly - ply) / (float)(g_mDiv * 24);
  127. if (ltouch)
  128. ply = ly;
  129. else
  130. sacc = 0;
  131. plt = ltouch;
  132. dw = (int)sacc;
  133. sacc -= dw;
  134. if (dw > 15)
  135. dw = 15;
  136. if (dw < -15)
  137. dw = -15;
  138. }
  139. // ---- mouse report ----
  140. static uint8_t pmbtn = 0;
  141. if (dx || dy || dw || outMBtn != pmbtn) {
  142. pmbtn = outMBtn;
  143. hid_mouse_report_t m;
  144. m.buttons = outMBtn;
  145. m.x = (int8_t)dx;
  146. m.y = (int8_t)dy;
  147. m.wheel = (int8_t)dw;
  148. m.pan = 0;
  149. if (mdev->ready())
  150. mdev->sendReport(mrid, &m, sizeof m);
  151. }
  152. // ---- consumer control (edge-triggered) ----
  153. static uint8_t prevCC = 0;
  154. if (g_usbMode == MODE_LIZARD) {
  155. if (consumerBits != prevCC) {
  156. if (mdev->ready())
  157. mdev->sendReport(0x03, &consumerBits, 1);
  158. prevCC = consumerBits;
  159. }
  160. }
  161. // ---- keyboard report ----
  162. static uint8_t pmod = 0, pkc[6] = { 0, 0, 0, 0, 0, 0 };
  163. bool chg = (outMod != pmod);
  164. for (int i = 0; i < 6; i++)
  165. if (outKeys[i] != pkc[i])
  166. chg = true;
  167. if (chg) {
  168. pmod = outMod;
  169. for (int i = 0; i < 6; i++)
  170. pkc[i] = outKeys[i];
  171. uint8_t krep[8] = { outMod, 0, outKeys[0],
  172. outKeys[1], outKeys[2], outKeys[3],
  173. outKeys[4], outKeys[5] };
  174. if (kdev->ready())
  175. kdev->sendReport(krid, krep, 8);
  176. }
  177. }