Medius - Native APICatch

Catch

Stream the physical mouse, keyboard, and media input to the PC

CATCH subscribes to the user's real input. While subscribed, the box pushes a MOTION_EVENT for movement and the wheel, and a USAGE_EVENT for buttons, keys, and media, captured at the merge point before any LOCK suppression or injection, so you can lock an input and still see it to rebind it. Subscribing is fire-and-forget; the box streams until you unsubscribe.

CATCH

Subscribe to the physical-input event stream

CATCH sends a one-byte class mask. A non-zero mask subscribes; 0 unsubscribes. Opcode 0x0B.

CATCH 0x0B · payload 1 byte

Fire-and-forget

PAYLOAD
OffsetFieldTypeNotes
0masku8which classes to stream (see below); 0 = unsubscribe
MASK

Each bit turns on one class of change. The mask only chooses which reports trigger an event (every event carries the full held-usage snapshot), so a buttons-only subscription stays sparse even though the mouse reports at ~1 kHz. Combine bits with OR; 0x1F subscribes to every class.

ClassBitTriggers on
Motion0x01a non-zero X or Y delta (a MOTION_EVENT).
Wheel0x02a non-zero wheel delta (a MOTION_EVENT).
Buttons0x04a mouse-button edge (a USAGE_EVENT).
Keys0x08a keyboard key or modifier change (a USAGE_EVENT).
Media0x10a media (Consumer) usage change (a USAGE_EVENT).
PHYSICAL ONLY

The stream reports the user's physical input, never your injected overrides, and it reads the report before LOCK clamps it, so a locked axis or blocked button is still reported here. That's the intercept-and-rebind loop: lock an input to hide it from the game, catch it to act on it.

EFFECT

The box streams from the moment a non-zero mask arrives until you send 0. The subscription is PC-owned and clears on the same triggers as injection: control-PC silence (the ~1 s timeout), a RESET, a mouse detach, or inter-chip link loss, plus an explicit unsubscribe. The host library holds an open subscription alive with its keepalive (re-asserting it after a device-side blip) and across a reconnect. QUERY(CATCH) reads the active mask and a dropped-event count; the HEALTH CATCH_ON bit is set while subscribed. Library binding: catch_events.

EXAMPLE

Subscribe to every class (mask = 0x1F):

+--------+--------+--------+--------+--------+--------+
| A5     | 0B     | 00     | 01 00  | 1F     | lo hi  |
+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | mask   | CRC16  |
+--------+--------+--------+--------+--------+--------+

MOTION_EVENT

One physical relative-axis snapshot, box → PC

While a subscription with Motion or Wheel is active the box pushes a MOTION_EVENT for each physical report whose motion changed. It's unsolicited (there's no QUERY to correlate), so SEQ is a rolling per-event counter shared with USAGE_EVENT: a host detects dropped events as SEQ gaps. Opcode 0x0C.

MOTION_EVENT 0x0C · payload 6 bytes

Unsolicited

PAYLOAD
OffsetFieldTypeNotes
0dxi16physical X this report; + = right, little-endian
2dyi16physical Y this report; + = down, little-endian
4dzi16physical wheel delta this report; + = up, little-endian
BEST-EFFORT

Delivery is best-effort: under back-pressure the box drops events (counted in QUERY(CATCH)) rather than stalling the report path, so the stream never delays the game-PC-facing reports.

EXAMPLE

The user moves +10 right, no vertical or wheel motion (dx = 10):

+--------+--------+--------+--------+--------+--------+--------+--------+
| A5     | 0C     | 2A     | 06 00  | 0A 00  | 00 00  | 00 00  | lo hi  |
+--------+--------+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | dx     | dy     | dz     | CRC16  |
+--------+--------+--------+--------+--------+--------+--------+--------+

USAGE_EVENT

One physical held-usage snapshot, box → PC

While a subscription with Buttons, Keys, or Media is active the box pushes a USAGE_EVENT when that class changes: a class-tagged snapshot of the usages currently held, so a mouse-button press and a key press have the same shape. It's a full snapshot, not edge deltas, so a dropped frame self-corrects on the next one; diff successive snapshots per class for press / release edges. Opcode 0x0F.

USAGE_EVENT 0x0F · payload 1 + 3n bytes

Unsolicited

PAYLOAD
OffsetFieldTypeNotes
0nu8number of held usages that follow
+classu8per usage: 0=button 1=key 2=media (as INJECT)
+idu16the held usage's id (a button id, HID keycode with 0xE0-0xE7 modifiers, or Consumer usage), little-endian
ONE CLASS PER EVENT

Each entry is 3 bytes; the snapshot is n of them, all one class (one physical report is one class), so a Keys event lists every held key and a Buttons event every held button. Best-effort like MOTION_EVENT: dropped events are counted in QUERY(CATCH).

EXAMPLE

Left Shift held while pressing A (a keys snapshot, two usages both class = 1: Left Shift id = 0xE1, then A id = 0x04):

+--------+--------+--------+--------+--------+----------+----------+--------+
| A5     | 0F     | 2B     | 07 00  | 02     | 01 E1 00 | 01 04 00 | lo hi  |
+--------+--------+--------+--------+--------+----------+----------+--------+
| SOF    | TYPE   | SEQ    | LEN    | n      | usage[0] | usage[1] | CRC16  |
+--------+--------+--------+--------+--------+----------+----------+--------+