|
@@ -1,84 +1,161 @@
|
|
|
#include "mode_lizard.h"
|
|
#include "mode_lizard.h"
|
|
|
|
|
+#include "lizard_map.h"
|
|
|
#include "triton.h"
|
|
#include "triton.h"
|
|
|
#include "config.h"
|
|
#include "config.h"
|
|
|
|
|
+#include <string.h>
|
|
|
|
|
|
|
|
-void rfLizard(const uint8_t *r, Adafruit_USBD_HID *mdev,
|
|
|
|
|
- Adafruit_USBD_HID *kdev, uint8_t mrid, uint8_t krid)
|
|
|
|
|
|
|
+void rfLizard(Adafruit_USBD_HID *mdev, Adafruit_USBD_HID *kdev, uint8_t mrid,
|
|
|
|
|
+ uint8_t krid)
|
|
|
{
|
|
{
|
|
|
- uint32_t b = btnsOf(r);
|
|
|
|
|
- bool qamHeld = (b & TB_QAM) != 0;
|
|
|
|
|
- // --- right pad -> mouse motion with glide (mirrors mode_xinput's rfXboxMouse) ---
|
|
|
|
|
|
|
+ const PuckInput &in = g_in[0];
|
|
|
|
|
+ uint32_t buttons = in.buttons;
|
|
|
|
|
+
|
|
|
|
|
+ // Append virtual stick-deflection bits so bindings can trigger on stick direction
|
|
|
|
|
+ if (in.lx > 12000)
|
|
|
|
|
+ buttons |= LZ_BTN_LSTICK_RT;
|
|
|
|
|
+ if (in.lx < -12000)
|
|
|
|
|
+ buttons |= LZ_BTN_LSTICK_LF;
|
|
|
|
|
+ if (in.ly < -12000)
|
|
|
|
|
+ buttons |= LZ_BTN_LSTICK_DN;
|
|
|
|
|
+ if (in.ly > 12000)
|
|
|
|
|
+ buttons |= LZ_BTN_LSTICK_UP;
|
|
|
|
|
+
|
|
|
|
|
+ // ---- accumulate outputs from the binding table ----
|
|
|
|
|
+ uint8_t outMod = 0;
|
|
|
|
|
+ uint8_t outKeys[6] = { 0, 0, 0, 0, 0, 0 };
|
|
|
|
|
+ uint8_t nKeys = 0;
|
|
|
|
|
+ uint8_t outMBtn = 0;
|
|
|
|
|
+ bool doRpadMouse = false, doLpadScroll = false;
|
|
|
|
|
+ uint8_t consumerBits = 0;
|
|
|
|
|
+
|
|
|
|
|
+ // kbdConsumed: any trig bits claimed by a hold-modifier binding so that simpler
|
|
|
|
|
+ // single-button bindings sharing those bits are suppressed.
|
|
|
|
|
+ uint32_t kbdConsumed = 0;
|
|
|
|
|
+
|
|
|
|
|
+ for (uint8_t i = 0; i < g_lizardMap.count; i++) {
|
|
|
|
|
+ const LizardBinding &b = g_lizardMap.bindings[i];
|
|
|
|
|
+ if (b.outType == LZ_OUT_NONE)
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ if (b.outType == LZ_OUT_MOUSE_AXIS) {
|
|
|
|
|
+ if (b.outData[0] == LZ_MSRC_RPAD)
|
|
|
|
|
+ doRpadMouse = true;
|
|
|
|
|
+ // LZ_MSRC_LSTICK and LZ_MSRC_GYRO could be added later
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (b.outType == LZ_OUT_SCROLL) {
|
|
|
|
|
+ if (b.outData[0] == LZ_MSRC_LPAD)
|
|
|
|
|
+ doLpadScroll = true;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Check hold modifier (AND) then trigger (any-of OR)
|
|
|
|
|
+ if (b.holdMask && (buttons & b.holdMask) != b.holdMask)
|
|
|
|
|
+ continue;
|
|
|
|
|
+ if (b.trigMask && (buttons & b.trigMask) == 0)
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ switch (b.outType) {
|
|
|
|
|
+ case LZ_OUT_MOUSE_BTN:
|
|
|
|
|
+ if (!b.trigMask || (buttons & b.trigMask))
|
|
|
|
|
+ outMBtn |= b.outData[0];
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case LZ_OUT_KBD_CHORD:
|
|
|
|
|
+ // suppress if trig bits already claimed by a hold-modifier binding
|
|
|
|
|
+ if (b.holdMask == 0 && b.trigMask != 0 &&
|
|
|
|
|
+ (b.trigMask & kbdConsumed))
|
|
|
|
|
+ break;
|
|
|
|
|
+ outMod |= b.outData[0];
|
|
|
|
|
+ for (int j = 1; j < 7 && b.outData[j]; j++) {
|
|
|
|
|
+ if (nKeys < 6)
|
|
|
|
|
+ outKeys[nKeys++] = b.outData[j];
|
|
|
|
|
+ }
|
|
|
|
|
+ // claim trig bits so simpler bindings don't double-fire
|
|
|
|
|
+ if (b.holdMask != 0)
|
|
|
|
|
+ kbdConsumed |= b.trigMask;
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case LZ_OUT_CONSUMER:
|
|
|
|
|
+ if (g_usbMode == MODE_LIZARD)
|
|
|
|
|
+ consumerBits |= b.outData[0];
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ default:
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ---- right pad -> mouse motion with glide ----
|
|
|
static int prx = 0, pry = 0;
|
|
static int prx = 0, pry = 0;
|
|
|
static bool prt = false;
|
|
static bool prt = false;
|
|
|
static float vx = 0, vy = 0, rmx = 0, rmy = 0;
|
|
static float vx = 0, vy = 0, rmx = 0, rmy = 0;
|
|
|
- bool rtouch = b & TB_RPADT;
|
|
|
|
|
- int rx = s16off(r, 22), ry = s16off(r, 24);
|
|
|
|
|
- if (rtouch) {
|
|
|
|
|
- if (prt) {
|
|
|
|
|
|
|
+ int dx = 0, dy = 0;
|
|
|
|
|
+ if (doRpadMouse) {
|
|
|
|
|
+ bool rtouch = (buttons & TB_RPADT) != 0;
|
|
|
|
|
+ int rx = in.rpx, ry = in.rpy;
|
|
|
|
|
+ if (rtouch && prt) {
|
|
|
vx += (rx - prx);
|
|
vx += (rx - prx);
|
|
|
vy += (ry - pry);
|
|
vy += (ry - pry);
|
|
|
}
|
|
}
|
|
|
- prx = rx;
|
|
|
|
|
- pry = ry;
|
|
|
|
|
|
|
+ if (rtouch) {
|
|
|
|
|
+ prx = rx;
|
|
|
|
|
+ pry = ry;
|
|
|
|
|
+ }
|
|
|
|
|
+ prt = rtouch;
|
|
|
|
|
+ // Y inverted; *10 = desktop cursor sensitivity (g_mDiv 64 -> eff 640)
|
|
|
|
|
+ float mxf = vx / (float)(g_mDiv * 10) + rmx,
|
|
|
|
|
+ myf = -(vy / (float)(g_mDiv * 10)) + rmy;
|
|
|
|
|
+ dx = (int)mxf;
|
|
|
|
|
+ dy = (int)myf;
|
|
|
|
|
+ rmx = mxf - dx;
|
|
|
|
|
+ rmy = myf - dy; // sub-pixel carry
|
|
|
|
|
+ if (dx > 127)
|
|
|
|
|
+ dx = 127;
|
|
|
|
|
+ if (dx < -127)
|
|
|
|
|
+ dx = -127;
|
|
|
|
|
+ if (dy > 127)
|
|
|
|
|
+ dy = 127;
|
|
|
|
|
+ if (dy < -127)
|
|
|
|
|
+ dy = -127;
|
|
|
|
|
+ float f = g_mFric / 100.0f;
|
|
|
|
|
+ vx *= f;
|
|
|
|
|
+ vy *= f;
|
|
|
|
|
+ if (vx > -1 && vx < 1)
|
|
|
|
|
+ vx = 0;
|
|
|
|
|
+ if (vy > -1 && vy < 1)
|
|
|
|
|
+ vy = 0;
|
|
|
}
|
|
}
|
|
|
- prt = rtouch;
|
|
|
|
|
-
|
|
|
|
|
- // Y inverted; *10 = desktop-cursor sensitivity (g_mDiv 64 -> eff 640). Lower g_mDiv via WebUI slider = faster.
|
|
|
|
|
- float mxf = vx / (float)(g_mDiv * 10) + rmx,
|
|
|
|
|
- myf = -(vy / (float)(g_mDiv * 10)) + rmy;
|
|
|
|
|
- int dx = (int)mxf, dy = (int)myf;
|
|
|
|
|
- rmx = mxf - dx;
|
|
|
|
|
- rmy = myf - dy; // sub-pixel carry
|
|
|
|
|
- if (dx > 127)
|
|
|
|
|
- dx = 127;
|
|
|
|
|
- if (dx < -127)
|
|
|
|
|
- dx = -127;
|
|
|
|
|
- if (dy > 127)
|
|
|
|
|
- dy = 127;
|
|
|
|
|
- if (dy < -127)
|
|
|
|
|
- dy = -127;
|
|
|
|
|
- float f = g_mFric / 100.0f;
|
|
|
|
|
- vx *= f;
|
|
|
|
|
- vy *= f;
|
|
|
|
|
- if (vx > -1 && vx < 1)
|
|
|
|
|
- vx = 0;
|
|
|
|
|
- if (vy > -1 && vy < 1)
|
|
|
|
|
- vy = 0; // friction = glide/decay
|
|
|
|
|
- // --- left pad -> vertical scroll wheel (no momentum; only while touching, coarse) ---
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // ---- left pad -> scroll wheel ----
|
|
|
static int ply = 0;
|
|
static int ply = 0;
|
|
|
static bool plt = false;
|
|
static bool plt = false;
|
|
|
static float sacc = 0;
|
|
static float sacc = 0;
|
|
|
- bool ltouch = b & TB_LPADT;
|
|
|
|
|
- int ly = s16off(r, 18);
|
|
|
|
|
- if (ltouch) {
|
|
|
|
|
- if (plt) {
|
|
|
|
|
|
|
+ int dw = 0;
|
|
|
|
|
+ if (doLpadScroll) {
|
|
|
|
|
+ bool ltouch = (buttons & TB_LPADT) != 0;
|
|
|
|
|
+ int ly = in.lpy;
|
|
|
|
|
+ if (ltouch && plt)
|
|
|
sacc += (ly - ply) / (float)(g_mDiv * 24);
|
|
sacc += (ly - ply) / (float)(g_mDiv * 24);
|
|
|
- }
|
|
|
|
|
- ply = ly;
|
|
|
|
|
- } else
|
|
|
|
|
- sacc = 0;
|
|
|
|
|
- plt = ltouch;
|
|
|
|
|
- int dw = (int)sacc;
|
|
|
|
|
- sacc -= dw;
|
|
|
|
|
- if (dw > 15)
|
|
|
|
|
- dw = 15;
|
|
|
|
|
- if (dw < -15)
|
|
|
|
|
- dw = -15; // finger up = wheel up (positive)
|
|
|
|
|
- // --- mouse buttons: left=R-pad-click|R-trigger, right=L-trigger, middle=L-pad-click ---
|
|
|
|
|
- // trigU8 scales full-range so a full pull reaches ~0xFF; a raw >>8 tops out ~0x80, never crossing threshold.
|
|
|
|
|
- uint8_t rtrig = trigU8(u16off(r, 6)), ltrig = trigU8(u16off(r, 4));
|
|
|
|
|
- uint8_t mbtn = 0;
|
|
|
|
|
- if ((b & TB_RPADC) || rtrig > 180)
|
|
|
|
|
- mbtn |= 1; // right trigger -> left (primary) click
|
|
|
|
|
- if (ltrig > 180)
|
|
|
|
|
- mbtn |= 2; // left trigger -> right click
|
|
|
|
|
- if (b & TB_LPADC)
|
|
|
|
|
- mbtn |= 4;
|
|
|
|
|
|
|
+ if (ltouch)
|
|
|
|
|
+ ply = ly;
|
|
|
|
|
+ else
|
|
|
|
|
+ sacc = 0;
|
|
|
|
|
+ plt = ltouch;
|
|
|
|
|
+ dw = (int)sacc;
|
|
|
|
|
+ sacc -= dw;
|
|
|
|
|
+ if (dw > 15)
|
|
|
|
|
+ dw = 15;
|
|
|
|
|
+ if (dw < -15)
|
|
|
|
|
+ dw = -15;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ---- mouse report ----
|
|
|
static uint8_t pmbtn = 0;
|
|
static uint8_t pmbtn = 0;
|
|
|
- if (dx || dy || dw || mbtn != pmbtn) {
|
|
|
|
|
- pmbtn = mbtn;
|
|
|
|
|
|
|
+ if (dx || dy || dw || outMBtn != pmbtn) {
|
|
|
|
|
+ pmbtn = outMBtn;
|
|
|
hid_mouse_report_t m;
|
|
hid_mouse_report_t m;
|
|
|
- m.buttons = mbtn;
|
|
|
|
|
|
|
+ m.buttons = outMBtn;
|
|
|
m.x = (int8_t)dx;
|
|
m.x = (int8_t)dx;
|
|
|
m.y = (int8_t)dy;
|
|
m.y = (int8_t)dy;
|
|
|
m.wheel = (int8_t)dw;
|
|
m.wheel = (int8_t)dw;
|
|
@@ -86,88 +163,30 @@ void rfLizard(const uint8_t *r, Adafruit_USBD_HID *mdev,
|
|
|
if (mdev->ready())
|
|
if (mdev->ready())
|
|
|
mdev->sendReport(mrid, &m, sizeof m);
|
|
mdev->sendReport(mrid, &m, sizeof m);
|
|
|
}
|
|
}
|
|
|
- // --- keyboard: modifiers + up to 6 keycodes ---
|
|
|
|
|
- uint8_t mod = 0, kc[6] = { 0, 0, 0, 0, 0, 0 }, nk = 0;
|
|
|
|
|
- if (b & TB_LB)
|
|
|
|
|
- mod |= KEYBOARD_MODIFIER_LEFTCTRL;
|
|
|
|
|
- if (b & TB_RB)
|
|
|
|
|
- mod |= KEYBOARD_MODIFIER_LEFTALT;
|
|
|
|
|
-#define LZK(cond, code) \
|
|
|
|
|
- do { \
|
|
|
|
|
- if ((cond) && nk < 6) \
|
|
|
|
|
- kc[nk++] = (code); \
|
|
|
|
|
- } while (0)
|
|
|
|
|
- LZK(b & TB_A, HID_KEY_ENTER);
|
|
|
|
|
- LZK(b & TB_B, HID_KEY_ESCAPE);
|
|
|
|
|
- LZK(b & TB_X, HID_KEY_PAGE_UP);
|
|
|
|
|
- LZK(b & TB_Y, HID_KEY_PAGE_DOWN);
|
|
|
|
|
- LZK(b & TB_VIEW,
|
|
|
|
|
- (g_usbMode == MODE_LIZARD) ? HID_KEY_ESCAPE : HID_KEY_TAB);
|
|
|
|
|
- LZK(b & TB_MENU,
|
|
|
|
|
- (g_usbMode == MODE_LIZARD) ? HID_KEY_TAB : HID_KEY_ESCAPE);
|
|
|
|
|
-
|
|
|
|
|
- // left stick (XInput sign: +Y = up); deflect ~37% acts as a d-pad
|
|
|
|
|
- int sx = s16off(r, 8), sy = s16off(r, 10);
|
|
|
|
|
- LZK((b & TB_DUP) || sy > 12000, HID_KEY_ARROW_UP);
|
|
|
|
|
- LZK((b & TB_DDN) || sy < -12000, HID_KEY_ARROW_DOWN);
|
|
|
|
|
- LZK((b & TB_DLF) || sx < -12000, HID_KEY_ARROW_LEFT);
|
|
|
|
|
- LZK((b & TB_DRT) || sx > 12000, HID_KEY_ARROW_RIGHT);
|
|
|
|
|
-#undef LZK
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // ---- consumer control (edge-triggered) ----
|
|
|
|
|
+ static uint8_t prevCC = 0;
|
|
|
if (g_usbMode == MODE_LIZARD) {
|
|
if (g_usbMode == MODE_LIZARD) {
|
|
|
- static bool prevL5 = false, prevR5 = false;
|
|
|
|
|
- bool mh = (b & TB_STEAM) || qamHeld;
|
|
|
|
|
- bool nL5 = mh && (b & TB_L5), nR5 = mh && (b & TB_R5);
|
|
|
|
|
- if (nL5 && !prevL5) {
|
|
|
|
|
- uint8_t cc = 0x02;
|
|
|
|
|
|
|
+ if (consumerBits != prevCC) {
|
|
|
if (mdev->ready())
|
|
if (mdev->ready())
|
|
|
- mdev->sendReport(0x03, &cc, 1);
|
|
|
|
|
- }
|
|
|
|
|
- if (nR5 && !prevR5) {
|
|
|
|
|
- uint8_t cc = 0x01;
|
|
|
|
|
- if (mdev->ready())
|
|
|
|
|
- mdev->sendReport(0x03, &cc, 1);
|
|
|
|
|
- }
|
|
|
|
|
- if ((!nL5 && prevL5) || (!nR5 && prevR5)) {
|
|
|
|
|
- uint8_t cc = 0x00;
|
|
|
|
|
- if (mdev->ready())
|
|
|
|
|
- mdev->sendReport(0x03, &cc, 1);
|
|
|
|
|
- }
|
|
|
|
|
- prevL5 = nL5;
|
|
|
|
|
- prevR5 = nR5;
|
|
|
|
|
- if (mh && (b & TB_X)) {
|
|
|
|
|
- mod = KEYBOARD_MODIFIER_LEFTGUI |
|
|
|
|
|
- KEYBOARD_MODIFIER_LEFTCTRL;
|
|
|
|
|
- kc[0] = HID_KEY_O;
|
|
|
|
|
- kc[1] = 0;
|
|
|
|
|
- kc[2] = 0;
|
|
|
|
|
- kc[3] = 0;
|
|
|
|
|
- kc[4] = 0;
|
|
|
|
|
- kc[5] = 0;
|
|
|
|
|
- nk = 1;
|
|
|
|
|
- }
|
|
|
|
|
- if (mh && (b & TB_L4)) {
|
|
|
|
|
- mod = KEYBOARD_MODIFIER_LEFTCTRL |
|
|
|
|
|
- KEYBOARD_MODIFIER_LEFTALT;
|
|
|
|
|
- kc[0] = HID_KEY_DELETE;
|
|
|
|
|
- kc[1] = 0;
|
|
|
|
|
- kc[2] = 0;
|
|
|
|
|
- kc[3] = 0;
|
|
|
|
|
- kc[4] = 0;
|
|
|
|
|
- kc[5] = 0;
|
|
|
|
|
- nk = 1;
|
|
|
|
|
|
|
+ mdev->sendReport(0x03, &consumerBits, 1);
|
|
|
|
|
+ prevCC = consumerBits;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // ---- keyboard report ----
|
|
|
static uint8_t pmod = 0, pkc[6] = { 0, 0, 0, 0, 0, 0 };
|
|
static uint8_t pmod = 0, pkc[6] = { 0, 0, 0, 0, 0, 0 };
|
|
|
- bool chg = (mod != pmod);
|
|
|
|
|
|
|
+ bool chg = (outMod != pmod);
|
|
|
for (int i = 0; i < 6; i++)
|
|
for (int i = 0; i < 6; i++)
|
|
|
- if (kc[i] != pkc[i])
|
|
|
|
|
|
|
+ if (outKeys[i] != pkc[i])
|
|
|
chg = true;
|
|
chg = true;
|
|
|
if (chg) {
|
|
if (chg) {
|
|
|
- pmod = mod;
|
|
|
|
|
|
|
+ pmod = outMod;
|
|
|
for (int i = 0; i < 6; i++)
|
|
for (int i = 0; i < 6; i++)
|
|
|
- pkc[i] = kc[i];
|
|
|
|
|
- uint8_t krep[8] = { mod, 0, kc[0], kc[1],
|
|
|
|
|
- kc[2], kc[3], kc[4], kc[5] };
|
|
|
|
|
|
|
+ pkc[i] = outKeys[i];
|
|
|
|
|
+ uint8_t krep[8] = { outMod, 0, outKeys[0],
|
|
|
|
|
+ outKeys[1], outKeys[2], outKeys[3],
|
|
|
|
|
+ outKeys[4], outKeys[5] };
|
|
|
if (kdev->ready())
|
|
if (kdev->ready())
|
|
|
kdev->sendReport(krid, krep, 8);
|
|
kdev->sendReport(krid, krep, 8);
|
|
|
}
|
|
}
|