Skip to content

Commit 25f3649

Browse files
committed
Luxurious mouse support
1 parent c393b80 commit 25f3649

File tree

1 file changed

+84
-17
lines changed

1 file changed

+84
-17
lines changed

main/main.c

Lines changed: 84 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,22 @@ typedef struct {
9494
uint8_t rt; // Right trigger
9595
} gamepad_report_t;
9696

97+
typedef struct {
98+
union {
99+
struct {
100+
uint8_t button1 : 1;
101+
uint8_t button2 : 1;
102+
uint8_t button3 : 1;
103+
uint8_t reserved : 5;
104+
};
105+
uint8_t val;
106+
} buttons;
107+
int16_t x_displacement;
108+
int16_t y_displacement;
109+
int8_t scroll;
110+
int8_t tilt;
111+
} mouse_report_t;
112+
97113
/**
98114
* @brief APP event group
99115
*
@@ -360,39 +376,90 @@ static void hid_host_keyboard_report_callback(const uint8_t* const data, const i
360376
memcpy(prev_keys, &kb_report->key, HID_KEYBOARD_KEY_MAX);
361377
}
362378

379+
int16_t sign_extend_12bit(uint16_t value) {
380+
if (value & 0x800) {
381+
// If the 12th bit is set (negative number in 12-bit signed)
382+
return (int16_t)(value | 0xF000); // Fill top 4 bits with 1s
383+
} else {
384+
return (int16_t)(value & 0x0FFF); // Mask to 12 bits
385+
}
386+
}
387+
363388
/**
364389
* @brief USB HID Host Mouse Interface report callback handler
365390
*
366391
* @param[in] data Pointer to input report data buffer
367392
* @param[in] length Length of input report data buffer
368393
*/
369394
static void hid_host_mouse_report_callback(const uint8_t* const data, const int length) {
370-
hid_mouse_input_report_boot_t* mouse_report = (hid_mouse_input_report_boot_t*)data;
371-
372395
if (length < sizeof(hid_mouse_input_report_boot_t)) {
373396
return;
374397
}
375398

376-
static int x_pos = 0;
377-
static int y_pos = 0;
399+
static char hex_string[3 * 64] = {0}; // Safe for up to 64 bytes
400+
char* p = hex_string;
401+
402+
for (int i = 0; i < length; i++) {
403+
p += sprintf(p, "%02X ", data[i]);
404+
}
405+
if (p > hex_string) *(p - 1) = '\0';
406+
407+
cls();
408+
pax_draw_text(&fb, BLACK, pax_font_sky_mono, 16, 10, 180, hex_string);
409+
410+
mouse_report_t mouse_report = {0};
411+
412+
if (length <= 4) {
413+
hid_mouse_input_report_boot_t* boot_mouse_report = (hid_mouse_input_report_boot_t*)data;
414+
mouse_report.x_displacement = boot_mouse_report->x_displacement;
415+
mouse_report.y_displacement = boot_mouse_report->y_displacement;
416+
mouse_report.buttons.val = boot_mouse_report->buttons.val;
417+
if (length == 3) {
418+
mouse_report.scroll = data[4];
419+
}
420+
} else if (length == 5) {
421+
mouse_report.buttons.val = data[0];
422+
mouse_report.x_displacement = (int8_t)data[1];
423+
mouse_report.y_displacement = (int8_t)data[2];
424+
mouse_report.scroll = (int8_t)data[3];
425+
mouse_report.tilt = (int8_t)data[4];
426+
} else if (length < 9) {
427+
mouse_report.buttons.val = data[1];
428+
mouse_report.x_displacement = sign_extend_12bit((data[4] & 0x0F) << 8) | data[3];
429+
mouse_report.y_displacement = sign_extend_12bit(data[5] << 4) | (data[4] >> 4);
430+
mouse_report.scroll = (int8_t)data[6];
431+
if (length == 8) {
432+
mouse_report.tilt = (int8_t)data[7];
433+
}
434+
} else {
435+
mouse_report.buttons.val = data[1];
436+
mouse_report.x_displacement = (int16_t)((data[4] << 8) | data[3]);
437+
mouse_report.y_displacement = (int16_t)((data[6] << 8) | data[5]);
438+
mouse_report.scroll = (int8_t)data[7];
439+
mouse_report.tilt = (int8_t)data[8];
440+
}
441+
442+
static int x_pos = 0;
443+
static int y_pos = 0;
444+
static int x_scroll = 0;
445+
static int y_scroll = 0;
378446

379447
// Calculate absolute position from displacement
380-
x_pos += mouse_report->x_displacement;
381-
y_pos += mouse_report->y_displacement;
448+
x_pos += mouse_report.x_displacement;
449+
y_pos += mouse_report.y_displacement;
450+
x_scroll += mouse_report.scroll;
451+
y_scroll += mouse_report.tilt;
382452

383453
hid_print_new_device_report_header(HID_PROTOCOL_MOUSE);
384454

385-
printf("X: %06d\tY: %06d\t|%c|%c|%c|\r", x_pos, y_pos, (mouse_report->buttons.button1 ? 'o' : ' '),
386-
(mouse_report->buttons.button3 ? 'o' : ' '), (mouse_report->buttons.button2 ? 'o' : ' '));
387-
fflush(stdout);
388-
389455
char text[64];
390-
cls();
391-
snprintf(text, sizeof(text), "Mouse X: %06d\tY: %06d\t|%c|%c|%c|", x_pos, y_pos,
392-
(mouse_report->buttons.button1 ? 'o' : ' '), (mouse_report->buttons.button3 ? 'o' : ' '),
393-
(mouse_report->buttons.button2 ? 'o' : ' '));
456+
snprintf(text, sizeof(text), "Mouse X: %06d\tY: %06d\t|%c|%c|%c| Scroll: %03d Tilt: %03d", x_pos, y_pos,
457+
(mouse_report.buttons.button1 ? 'o' : ' '), (mouse_report.buttons.button3 ? 'o' : ' '),
458+
(mouse_report.buttons.button2 ? 'o' : ' '), x_scroll, y_scroll);
394459
pax_draw_text(&fb, BLACK, pax_font_sky_mono, 16, 0, 18, text);
395460
blit();
461+
printf("%s\n", text);
462+
fflush(stdout);
396463
}
397464

398465
static void parse_gamepad_report(gamepad_report_t* rpt, const uint8_t* data, int length) {
@@ -616,9 +683,6 @@ void hid_host_device_event(hid_host_device_handle_t hid_device_handle, const hid
616683
char text[64];
617684
snprintf(text, sizeof(text), "HID Device, protocol '%s' CONNECTED", hid_proto_name_str[dev_params.proto]);
618685
pax_draw_text(&fb, BLACK, pax_font_sky_mono, 16, 0, 18, text);
619-
620-
// TODO detection magic
621-
622686
blit();
623687

624688
const hid_host_device_config_t dev_config = {.callback = hid_host_interface_callback, .callback_arg = NULL};
@@ -629,6 +693,9 @@ void hid_host_device_event(hid_host_device_handle_t hid_device_handle, const hid
629693
if (HID_PROTOCOL_KEYBOARD == dev_params.proto) {
630694
ESP_ERROR_CHECK(hid_class_request_set_idle(hid_device_handle, 0, 0));
631695
}
696+
if (HID_PROTOCOL_MOUSE == dev_params.proto) {
697+
hid_class_request_set_protocol(hid_device_handle, HID_REPORT_PROTOCOL_REPORT);
698+
}
632699
}
633700
ESP_ERROR_CHECK(hid_host_device_start(hid_device_handle));
634701
break;

0 commit comments

Comments
 (0)