From 9843fdf6257e9feeb80bbc13f56f051e53316e7f Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:00:32 -0400 Subject: [PATCH 01/19] try to add usb gamepad to gameboy emulator --- MCUME_pico2/display/emuapi.cpp | 123 +++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/MCUME_pico2/display/emuapi.cpp b/MCUME_pico2/display/emuapi.cpp index b115cc2..aedad3e 100644 --- a/MCUME_pico2/display/emuapi.cpp +++ b/MCUME_pico2/display/emuapi.cpp @@ -1183,6 +1183,10 @@ char * menuSelection(void) ********************************/ #ifdef HAS_USBHOST +static bool gamepad_connected = false; +static uint8_t gamepad_addr = 0; +static uint8_t gamepad_instance = 0; + #ifdef KEYBOARD_ACTIVATED static bool kbdasjoy = false; #else @@ -1221,6 +1225,125 @@ static void signal_joy (int code, int pressed, int flags) { void kbd_signal_raw_key (int keycode, int code, int codeshifted, int flags, int pressed) { //printf("k %d\r\n", keycode); + +static void process_gamepad_report(uint8_t const* report, uint16_t len) { + // Check if we have enough data + if (len < 9) return; + + // Clear previous gamepad state while preserving keyboard input + uint16_t kbd_state = usbnavpad & (MASK_OSKB); + usbnavpad = kbd_state; + + // D-pad emulation from left analog stick (bytes 1 & 2) + // X-axis: 0x00=left, 0x7F=center, 0xFF=right + // Y-axis: 0x00=up, 0x7F=center, 0xFF=down + uint8_t x_axis = report[1]; + uint8_t y_axis = report[2]; + + // Apply some deadzone (values near center should be ignored) + // Horizontal movement + if (x_axis < 0x40) { + usbnavpad |= MASK_JOY2_LEFT; + } else if (x_axis > 0xB0) { + usbnavpad |= MASK_JOY2_RIGHT; + } + + // Vertical movement + if (y_axis < 0x40) { + usbnavpad |= MASK_JOY2_UP; + } else if (y_axis > 0xB0) { + usbnavpad |= MASK_JOY2_DOWN; + } + + // Face buttons (byte 6) + uint8_t face_buttons = report[6] & 0xF0; // Mask out the base value (0x0F) + if (face_buttons & 0x20) usbnavpad |= MASK_JOY2_BTN; // A button + if (face_buttons & 0x40) usbnavpad |= MASK_KEY_USER1; // B button + if (face_buttons & 0x10) usbnavpad |= MASK_KEY_USER2; // X button + if (face_buttons & 0x80) usbnavpad |= MASK_KEY_USER3; // Y button + + // Shoulder and menu buttons (byte 7) + if (report[7] & 0x01) usbnavpad |= MASK_JOY1_BTN; // L button + if (report[7] & 0x02) usbnavpad |= MASK_KEY_USER4; // R button + if (report[7] & 0x10) usbnavpad |= MASK_KEY_USER2; // Select (alt mapping) + if (report[7] & 0x20) usbnavpad |= MASK_KEY_USER1; // Start (alt mapping) +} + +// TinyUSB callbacks for HID devices + +// Invoked when device with hid interface is mounted +bool tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { + uint16_t vid, pid; + tuh_vid_pid_get(dev_addr, &vid, &pid); + + printf("HID device: VID = 0x%04x, PID = 0x%04x\r\n", vid, pid); + + // Check if this is our known gamepad (Totsu Engineering, 0x081F/0xE401) + if (vid == 0x081F && pid == 0xE401) { + printf("USB gamepad detected\r\n"); + gamepad_connected = true; + gamepad_addr = dev_addr; + gamepad_instance = instance; + tuh_hid_receive_report(dev_addr, instance); + return true; + } + + // Check for keyboard (existing code will handle this) + uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); + if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) { + printf("USB keyboard detected\r\n"); + return true; + } + + // Check for generic gamepad/joystick + bool is_joystick = false; + for (uint16_t i = 0; i < desc_len - 2; i++) { + // Look for Generic Desktop usage page (0x01) followed by Joystick usage (0x04) + if (desc_report[i] == 0x05 && desc_report[i+1] == 0x01 && + i+3 < desc_len && desc_report[i+2] == 0x09 && desc_report[i+3] == 0x04) { + is_joystick = true; + break; + } + } + + if (is_joystick) { + printf("Generic USB joystick/gamepad detected\r\n"); + gamepad_connected = true; + gamepad_addr = dev_addr; + gamepad_instance = instance; + tuh_hid_receive_report(dev_addr, instance); + return true; + } + + // Not a supported device + return false; +} + +// Invoked when device with hid interface is unmounted +void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { + if (dev_addr == gamepad_addr && instance == gamepad_instance) { + printf("Gamepad disconnected\r\n"); + gamepad_connected = false; + gamepad_addr = 0; + gamepad_instance = 0; + + // Clear gamepad input flags + usbnavpad &= MASK_OSKB; // Keep only the on-screen keyboard state + } +} + +// Invoked when received report from device +void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) { + if (dev_addr == gamepad_addr && instance == gamepad_instance) { + // Process gamepad report + process_gamepad_report(report, len); + } + + // Request to receive report again + tuh_hid_receive_report(dev_addr, instance); +} +#endif + #ifdef FILEBROWSER if (menuActive()) { From dfadcf2f8d289593d786cbd5d7fd96de58ce5693 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:05:10 -0400 Subject: [PATCH 02/19] move kbd_signal_raw_key --- MCUME_pico2/display/emuapi.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/MCUME_pico2/display/emuapi.cpp b/MCUME_pico2/display/emuapi.cpp index aedad3e..5156d0e 100644 --- a/MCUME_pico2/display/emuapi.cpp +++ b/MCUME_pico2/display/emuapi.cpp @@ -1223,9 +1223,6 @@ static void signal_joy (int code, int pressed, int flags) { if ( (code == ' ') && (!pressed) ) usbnavpad &= ~MASK_KEY_USER4; } -void kbd_signal_raw_key (int keycode, int code, int codeshifted, int flags, int pressed) { - //printf("k %d\r\n", keycode); - static void process_gamepad_report(uint8_t const* report, uint16_t len) { // Check if we have enough data if (len < 9) return; @@ -1342,8 +1339,9 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons // Request to receive report again tuh_hid_receive_report(dev_addr, instance); } -#endif +void kbd_signal_raw_key (int keycode, int code, int codeshifted, int flags, int pressed) { + //printf("k %d\r\n", keycode); #ifdef FILEBROWSER if (menuActive()) { From cd50ce6db772f8246a583056b44daf258324741d Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:10:15 -0400 Subject: [PATCH 03/19] change bool to void --- MCUME_pico2/display/emuapi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCUME_pico2/display/emuapi.cpp b/MCUME_pico2/display/emuapi.cpp index 5156d0e..3d21d0e 100644 --- a/MCUME_pico2/display/emuapi.cpp +++ b/MCUME_pico2/display/emuapi.cpp @@ -1269,7 +1269,7 @@ static void process_gamepad_report(uint8_t const* report, uint16_t len) { // TinyUSB callbacks for HID devices // Invoked when device with hid interface is mounted -bool tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { +void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { uint16_t vid, pid; tuh_vid_pid_get(dev_addr, &vid, &pid); From f9c0a1628d75b2233e985aa03f3599a396978997 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:12:36 -0400 Subject: [PATCH 04/19] remove returns --- MCUME_pico2/display/emuapi.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/MCUME_pico2/display/emuapi.cpp b/MCUME_pico2/display/emuapi.cpp index 3d21d0e..146bd96 100644 --- a/MCUME_pico2/display/emuapi.cpp +++ b/MCUME_pico2/display/emuapi.cpp @@ -1282,14 +1282,12 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re gamepad_addr = dev_addr; gamepad_instance = instance; tuh_hid_receive_report(dev_addr, instance); - return true; } // Check for keyboard (existing code will handle this) uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) { printf("USB keyboard detected\r\n"); - return true; } // Check for generic gamepad/joystick @@ -1309,11 +1307,9 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re gamepad_addr = dev_addr; gamepad_instance = instance; tuh_hid_receive_report(dev_addr, instance); - return true; } // Not a supported device - return false; } // Invoked when device with hid interface is unmounted From ff06fe5494a434a3d4a5ca4bedfd1e6e1b341b27 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:16:01 -0400 Subject: [PATCH 05/19] Revert "remove returns" This reverts commit f9c0a1628d75b2233e985aa03f3599a396978997. --- MCUME_pico2/display/emuapi.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MCUME_pico2/display/emuapi.cpp b/MCUME_pico2/display/emuapi.cpp index 146bd96..3d21d0e 100644 --- a/MCUME_pico2/display/emuapi.cpp +++ b/MCUME_pico2/display/emuapi.cpp @@ -1282,12 +1282,14 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re gamepad_addr = dev_addr; gamepad_instance = instance; tuh_hid_receive_report(dev_addr, instance); + return true; } // Check for keyboard (existing code will handle this) uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) { printf("USB keyboard detected\r\n"); + return true; } // Check for generic gamepad/joystick @@ -1307,9 +1309,11 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re gamepad_addr = dev_addr; gamepad_instance = instance; tuh_hid_receive_report(dev_addr, instance); + return true; } // Not a supported device + return false; } // Invoked when device with hid interface is unmounted From 6f72a4fd1fd46644ab87320d035342d5863dc119 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:16:11 -0400 Subject: [PATCH 06/19] Revert "change bool to void" This reverts commit cd50ce6db772f8246a583056b44daf258324741d. --- MCUME_pico2/display/emuapi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCUME_pico2/display/emuapi.cpp b/MCUME_pico2/display/emuapi.cpp index 3d21d0e..5156d0e 100644 --- a/MCUME_pico2/display/emuapi.cpp +++ b/MCUME_pico2/display/emuapi.cpp @@ -1269,7 +1269,7 @@ static void process_gamepad_report(uint8_t const* report, uint16_t len) { // TinyUSB callbacks for HID devices // Invoked when device with hid interface is mounted -void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { +bool tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { uint16_t vid, pid; tuh_vid_pid_get(dev_addr, &vid, &pid); From 561c082fd4ecceb9f09f665b20763ce8a622cb5f Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:16:15 -0400 Subject: [PATCH 07/19] Revert "move kbd_signal_raw_key" This reverts commit dfadcf2f8d289593d786cbd5d7fd96de58ce5693. --- MCUME_pico2/display/emuapi.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MCUME_pico2/display/emuapi.cpp b/MCUME_pico2/display/emuapi.cpp index 5156d0e..aedad3e 100644 --- a/MCUME_pico2/display/emuapi.cpp +++ b/MCUME_pico2/display/emuapi.cpp @@ -1223,6 +1223,9 @@ static void signal_joy (int code, int pressed, int flags) { if ( (code == ' ') && (!pressed) ) usbnavpad &= ~MASK_KEY_USER4; } +void kbd_signal_raw_key (int keycode, int code, int codeshifted, int flags, int pressed) { + //printf("k %d\r\n", keycode); + static void process_gamepad_report(uint8_t const* report, uint16_t len) { // Check if we have enough data if (len < 9) return; @@ -1339,9 +1342,8 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons // Request to receive report again tuh_hid_receive_report(dev_addr, instance); } +#endif -void kbd_signal_raw_key (int keycode, int code, int codeshifted, int flags, int pressed) { - //printf("k %d\r\n", keycode); #ifdef FILEBROWSER if (menuActive()) { From d9a62efb6289ee6b1f3bbf1b57b6a804b3daa7ef Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:16:20 -0400 Subject: [PATCH 08/19] Revert "try to add usb gamepad to gameboy emulator" This reverts commit 9843fdf6257e9feeb80bbc13f56f051e53316e7f. --- MCUME_pico2/display/emuapi.cpp | 123 --------------------------------- 1 file changed, 123 deletions(-) diff --git a/MCUME_pico2/display/emuapi.cpp b/MCUME_pico2/display/emuapi.cpp index aedad3e..b115cc2 100644 --- a/MCUME_pico2/display/emuapi.cpp +++ b/MCUME_pico2/display/emuapi.cpp @@ -1183,10 +1183,6 @@ char * menuSelection(void) ********************************/ #ifdef HAS_USBHOST -static bool gamepad_connected = false; -static uint8_t gamepad_addr = 0; -static uint8_t gamepad_instance = 0; - #ifdef KEYBOARD_ACTIVATED static bool kbdasjoy = false; #else @@ -1225,125 +1221,6 @@ static void signal_joy (int code, int pressed, int flags) { void kbd_signal_raw_key (int keycode, int code, int codeshifted, int flags, int pressed) { //printf("k %d\r\n", keycode); - -static void process_gamepad_report(uint8_t const* report, uint16_t len) { - // Check if we have enough data - if (len < 9) return; - - // Clear previous gamepad state while preserving keyboard input - uint16_t kbd_state = usbnavpad & (MASK_OSKB); - usbnavpad = kbd_state; - - // D-pad emulation from left analog stick (bytes 1 & 2) - // X-axis: 0x00=left, 0x7F=center, 0xFF=right - // Y-axis: 0x00=up, 0x7F=center, 0xFF=down - uint8_t x_axis = report[1]; - uint8_t y_axis = report[2]; - - // Apply some deadzone (values near center should be ignored) - // Horizontal movement - if (x_axis < 0x40) { - usbnavpad |= MASK_JOY2_LEFT; - } else if (x_axis > 0xB0) { - usbnavpad |= MASK_JOY2_RIGHT; - } - - // Vertical movement - if (y_axis < 0x40) { - usbnavpad |= MASK_JOY2_UP; - } else if (y_axis > 0xB0) { - usbnavpad |= MASK_JOY2_DOWN; - } - - // Face buttons (byte 6) - uint8_t face_buttons = report[6] & 0xF0; // Mask out the base value (0x0F) - if (face_buttons & 0x20) usbnavpad |= MASK_JOY2_BTN; // A button - if (face_buttons & 0x40) usbnavpad |= MASK_KEY_USER1; // B button - if (face_buttons & 0x10) usbnavpad |= MASK_KEY_USER2; // X button - if (face_buttons & 0x80) usbnavpad |= MASK_KEY_USER3; // Y button - - // Shoulder and menu buttons (byte 7) - if (report[7] & 0x01) usbnavpad |= MASK_JOY1_BTN; // L button - if (report[7] & 0x02) usbnavpad |= MASK_KEY_USER4; // R button - if (report[7] & 0x10) usbnavpad |= MASK_KEY_USER2; // Select (alt mapping) - if (report[7] & 0x20) usbnavpad |= MASK_KEY_USER1; // Start (alt mapping) -} - -// TinyUSB callbacks for HID devices - -// Invoked when device with hid interface is mounted -bool tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { - uint16_t vid, pid; - tuh_vid_pid_get(dev_addr, &vid, &pid); - - printf("HID device: VID = 0x%04x, PID = 0x%04x\r\n", vid, pid); - - // Check if this is our known gamepad (Totsu Engineering, 0x081F/0xE401) - if (vid == 0x081F && pid == 0xE401) { - printf("USB gamepad detected\r\n"); - gamepad_connected = true; - gamepad_addr = dev_addr; - gamepad_instance = instance; - tuh_hid_receive_report(dev_addr, instance); - return true; - } - - // Check for keyboard (existing code will handle this) - uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); - if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) { - printf("USB keyboard detected\r\n"); - return true; - } - - // Check for generic gamepad/joystick - bool is_joystick = false; - for (uint16_t i = 0; i < desc_len - 2; i++) { - // Look for Generic Desktop usage page (0x01) followed by Joystick usage (0x04) - if (desc_report[i] == 0x05 && desc_report[i+1] == 0x01 && - i+3 < desc_len && desc_report[i+2] == 0x09 && desc_report[i+3] == 0x04) { - is_joystick = true; - break; - } - } - - if (is_joystick) { - printf("Generic USB joystick/gamepad detected\r\n"); - gamepad_connected = true; - gamepad_addr = dev_addr; - gamepad_instance = instance; - tuh_hid_receive_report(dev_addr, instance); - return true; - } - - // Not a supported device - return false; -} - -// Invoked when device with hid interface is unmounted -void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { - if (dev_addr == gamepad_addr && instance == gamepad_instance) { - printf("Gamepad disconnected\r\n"); - gamepad_connected = false; - gamepad_addr = 0; - gamepad_instance = 0; - - // Clear gamepad input flags - usbnavpad &= MASK_OSKB; // Keep only the on-screen keyboard state - } -} - -// Invoked when received report from device -void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) { - if (dev_addr == gamepad_addr && instance == gamepad_instance) { - // Process gamepad report - process_gamepad_report(report, len); - } - - // Request to receive report again - tuh_hid_receive_report(dev_addr, instance); -} -#endif - #ifdef FILEBROWSER if (menuActive()) { From d8462656c8e29465b96966f1a8ffc71f4ae0cab0 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:20:26 -0400 Subject: [PATCH 09/19] try hid_app instead --- MCUME_pico2/usb_kbd/hid_app.c | 111 +++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 48 deletions(-) diff --git a/MCUME_pico2/usb_kbd/hid_app.c b/MCUME_pico2/usb_kbd/hid_app.c index c8e581e..9a31ca3 100644 --- a/MCUME_pico2/usb_kbd/hid_app.c +++ b/MCUME_pico2/usb_kbd/hid_app.c @@ -375,54 +375,69 @@ static void process_kbd_report (hid_keyboard_report_t const *report) } // this mapping is hard coded for a certain snes-style gamepad and picogb! -static void process_gamepad_report (const uint8_t *report) { - uint16_t decoded_report = 0; - - // X coordinate - if (report[0] == 0) { - decoded_report |= MASK_JOY2_RIGHT; - } else if(report[0] == 0xff) { - decoded_report |= MASK_JOY2_LEFT; - } - - // Y coordinate - if (report[1] == 0) { - decoded_report |= MASK_JOY2_UP; - } else if(report[1] == 0xff) { - decoded_report |= MASK_JOY2_DOWN; - } - - // X A B Y = top bits of byte 5 . Let's just have X/Y double A/B - if (report[5] & 0x10) { - decoded_report |= MASK_JOY2_BTN; // X - } - if (report[5] & 0x20) { - decoded_report |= MASK_KEY_USER3; // A -- this is picogb numbering - } - if (report[5] & 0x40) { - decoded_report |= MASK_JOY2_BTN; // B - } - if (report[5] & 0x80) { - decoded_report |= MASK_KEY_USER3; // Y - } - - // SELECT START = top bits of byte 6 - if (report[6] & 0x10) { - decoded_report |= MASK_KEY_USER1; // SELECT - } - if (report[6] & 0x20) { - decoded_report |= MASK_KEY_USER2; // START - } - - // Decode shoulder buttons into B/A too - if (report[6] & 0x1) { - decoded_report |= MASK_JOY2_BTN; // B - } - if (report[6] & 0x2) { - decoded_report |= MASK_KEY_USER3; // Y - } - - kbd_signal_raw_gamepad(decoded_report); +static void process_gamepad_report(const uint8_t *report) { + uint16_t decoded_report = 0; + + // Default input format from your HID explorer output: + // default input (no buttons pressed): 00 7F 7F 00 80 80 0F 00 00 + + // X-axis (byte 1): 0x00=left, 0x7F=center, 0xFF=right + if (report[1] < 0x40) { + decoded_report |= MASK_JOY2_LEFT; + } else if (report[1] > 0xB0) { + decoded_report |= MASK_JOY2_RIGHT; + } + + // Y-axis (byte 2): 0x00=up, 0x7F=center, 0xFF=down + if (report[2] < 0x40) { + decoded_report |= MASK_JOY2_UP; + } else if (report[2] > 0xB0) { + decoded_report |= MASK_JOY2_DOWN; + } + + // Face buttons (byte 6) + // A: 00 7F 7F 00 80 80 2F 00 00 (bit 0x20) + if (report[6] & 0x20) { + decoded_report |= MASK_JOY2_BTN; // A button + } + + // B: 00 7F 7F 00 80 80 4F 00 00 (bit 0x40) + if (report[6] & 0x40) { + decoded_report |= MASK_KEY_USER1; // B button + } + + // X: 00 7F 7F 00 80 80 1F 00 00 (bit 0x10) + if (report[6] & 0x10) { + decoded_report |= MASK_KEY_USER2; // X button + } + + // Y: 00 7F 7F 00 80 80 8F 00 00 (bit 0x80) + if (report[6] & 0x80) { + decoded_report |= MASK_KEY_USER3; // Y button + } + + // Start: 00 7F 7F 00 80 80 0F 20 00 (byte 7, bit 0x20) + if (report[7] & 0x20) { + decoded_report |= MASK_KEY_USER2; // Start (mapped to USER2) + } + + // Select: 00 7F 7F 00 80 80 0F 10 00 (byte 7, bit 0x10) + if (report[7] & 0x10) { + decoded_report |= MASK_KEY_USER1; // Select (mapped to USER1) + } + + // R: 00 7F 7F 00 80 80 0F 02 00 (byte 7, bit 0x02) + if (report[7] & 0x02) { + decoded_report |= MASK_KEY_USER4; // R button + } + + // L: 00 7F 7F 00 80 80 0F 01 00 (byte 7, bit 0x01) + if (report[7] & 0x01) { + decoded_report |= MASK_JOY1_BTN; // L button + } + + // Send the decoded gamepad state + kbd_signal_raw_gamepad(decoded_report); } //--------------------------------------------------------------------+ From 44fa2b265d61dfce0f039af75e4a97de988dcf6b Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:35:09 -0400 Subject: [PATCH 10/19] progress, swap up/down; map to gameboy buttons --- MCUME_pico2/usb_kbd/hid_app.c | 62 ++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/MCUME_pico2/usb_kbd/hid_app.c b/MCUME_pico2/usb_kbd/hid_app.c index 9a31ca3..f549d34 100644 --- a/MCUME_pico2/usb_kbd/hid_app.c +++ b/MCUME_pico2/usb_kbd/hid_app.c @@ -375,12 +375,21 @@ static void process_kbd_report (hid_keyboard_report_t const *report) } // this mapping is hard coded for a certain snes-style gamepad and picogb! +// Update this function in hid_app.c static void process_gamepad_report(const uint8_t *report) { uint16_t decoded_report = 0; // Default input format from your HID explorer output: // default input (no buttons pressed): 00 7F 7F 00 80 80 0F 00 00 + // Y-axis (byte 2): 0x00=up, 0x7F=center, 0xFF=down + // Note: We're swapping UP/DOWN here to fix the menu navigation + if (report[2] < 0x40) { + decoded_report |= MASK_JOY2_DOWN; // Map UP to DOWN for the menu + } else if (report[2] > 0xB0) { + decoded_report |= MASK_JOY2_UP; // Map DOWN to UP for the menu + } + // X-axis (byte 1): 0x00=left, 0x7F=center, 0xFF=right if (report[1] < 0x40) { decoded_report |= MASK_JOY2_LEFT; @@ -388,52 +397,51 @@ static void process_gamepad_report(const uint8_t *report) { decoded_report |= MASK_JOY2_RIGHT; } - // Y-axis (byte 2): 0x00=up, 0x7F=center, 0xFF=down - if (report[2] < 0x40) { - decoded_report |= MASK_JOY2_UP; - } else if (report[2] > 0xB0) { - decoded_report |= MASK_JOY2_DOWN; - } - // Face buttons (byte 6) + // Looking at emu.cpp, we need to map: + // - A button to MASK_KEY_USER3 + // - B button to MASK_JOY2_BTN + // - Select to MASK_KEY_USER1 + // - Start to MASK_KEY_USER2 + // A: 00 7F 7F 00 80 80 2F 00 00 (bit 0x20) if (report[6] & 0x20) { - decoded_report |= MASK_JOY2_BTN; // A button + decoded_report |= MASK_KEY_USER3; // A button maps to gb.direct.joypad_bits.a } // B: 00 7F 7F 00 80 80 4F 00 00 (bit 0x40) if (report[6] & 0x40) { - decoded_report |= MASK_KEY_USER1; // B button + decoded_report |= MASK_JOY2_BTN; // B button maps to gb.direct.joypad_bits.b } - // X: 00 7F 7F 00 80 80 1F 00 00 (bit 0x10) + // X: 00 7F 7F 00 80 80 1F 00 00 (bit 0x10) - Map to B as an alternative if (report[6] & 0x10) { - decoded_report |= MASK_KEY_USER2; // X button + decoded_report |= MASK_JOY2_BTN; // X button maps to B } - // Y: 00 7F 7F 00 80 80 8F 00 00 (bit 0x80) + // Y: 00 7F 7F 00 80 80 8F 00 00 (bit 0x80) - Map to A as an alternative if (report[6] & 0x80) { - decoded_report |= MASK_KEY_USER3; // Y button - } - - // Start: 00 7F 7F 00 80 80 0F 20 00 (byte 7, bit 0x20) - if (report[7] & 0x20) { - decoded_report |= MASK_KEY_USER2; // Start (mapped to USER2) + decoded_report |= MASK_KEY_USER3; // Y button maps to A } // Select: 00 7F 7F 00 80 80 0F 10 00 (byte 7, bit 0x10) if (report[7] & 0x10) { - decoded_report |= MASK_KEY_USER1; // Select (mapped to USER1) + decoded_report |= MASK_KEY_USER1; // Select button } - // R: 00 7F 7F 00 80 80 0F 02 00 (byte 7, bit 0x02) + // Start: 00 7F 7F 00 80 80 0F 20 00 (byte 7, bit 0x20) + if (report[7] & 0x20) { + decoded_report |= MASK_KEY_USER2; // Start button + } + + // R: 00 7F 7F 00 80 80 0F 02 00 (byte 7, bit 0x02) - Map to B as an alternative if (report[7] & 0x02) { - decoded_report |= MASK_KEY_USER4; // R button + decoded_report |= MASK_JOY2_BTN; // R button maps to B } - // L: 00 7F 7F 00 80 80 0F 01 00 (byte 7, bit 0x01) + // L: 00 7F 7F 00 80 80 0F 01 00 (byte 7, bit 0x01) - Map to A as an alternative if (report[7] & 0x01) { - decoded_report |= MASK_JOY1_BTN; // L button + decoded_report |= MASK_KEY_USER3; // L button maps to A } // Send the decoded gamepad state @@ -502,10 +510,10 @@ int proto = tuh_hid_interface_protocol (dev_addr, instance); process_kbd_report ((hid_keyboard_report_t const*) report); break; case HID_ITF_PROTOCOL_NONE: - if (len == 8) { - process_gamepad_report (report); - } - break; + if (len >= 8 && len <= 9) { + process_gamepad_report(report); + } + break; #if 0 // you get to implement it, hoss! case HID_ITF_PROTOCOL_MOUSE: printf("MOUSE len=%d\n", len); From 858205c3dc02ead514bbc6f88fdc800968ad6d59 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:50:20 -0400 Subject: [PATCH 11/19] invert mappings --- MCUME_pico2/usb_kbd/hid_app.c | 81 ++++++++++++++++------------------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/MCUME_pico2/usb_kbd/hid_app.c b/MCUME_pico2/usb_kbd/hid_app.c index f549d34..220f8c4 100644 --- a/MCUME_pico2/usb_kbd/hid_app.c +++ b/MCUME_pico2/usb_kbd/hid_app.c @@ -375,73 +375,66 @@ static void process_kbd_report (hid_keyboard_report_t const *report) } // this mapping is hard coded for a certain snes-style gamepad and picogb! -// Update this function in hid_app.c static void process_gamepad_report(const uint8_t *report) { uint16_t decoded_report = 0; - // Default input format from your HID explorer output: - // default input (no buttons pressed): 00 7F 7F 00 80 80 0F 00 00 - - // Y-axis (byte 2): 0x00=up, 0x7F=center, 0xFF=down - // Note: We're swapping UP/DOWN here to fix the menu navigation - if (report[2] < 0x40) { - decoded_report |= MASK_JOY2_DOWN; // Map UP to DOWN for the menu - } else if (report[2] > 0xB0) { - decoded_report |= MASK_JOY2_UP; // Map DOWN to UP for the menu - } + // Directional controls - X and Y axes + // Note: No need to swap or invert - the Game Boy code handles that // X-axis (byte 1): 0x00=left, 0x7F=center, 0xFF=right - if (report[1] < 0x40) { + if (report[1] < 0x40) { // Left decoded_report |= MASK_JOY2_LEFT; - } else if (report[1] > 0xB0) { + } else if (report[1] > 0xB0) { // Right decoded_report |= MASK_JOY2_RIGHT; } + // Y-axis (byte 2): 0x00=up, 0x7F=center, 0xFF=down + if (report[2] < 0x40) { // Up + decoded_report |= MASK_JOY2_UP; + } else if (report[2] > 0xB0) { // Down + decoded_report |= MASK_JOY2_DOWN; + } + // Face buttons (byte 6) - // Looking at emu.cpp, we need to map: - // - A button to MASK_KEY_USER3 - // - B button to MASK_JOY2_BTN - // - Select to MASK_KEY_USER1 - // - Start to MASK_KEY_USER2 - - // A: 00 7F 7F 00 80 80 2F 00 00 (bit 0x20) + // A button (maps to Game Boy A) if (report[6] & 0x20) { - decoded_report |= MASK_KEY_USER3; // A button maps to gb.direct.joypad_bits.a + decoded_report |= MASK_KEY_USER3; } - // B: 00 7F 7F 00 80 80 4F 00 00 (bit 0x40) + // B button (maps to Game Boy B) if (report[6] & 0x40) { - decoded_report |= MASK_JOY2_BTN; // B button maps to gb.direct.joypad_bits.b + decoded_report |= MASK_JOY2_BTN; } - // X: 00 7F 7F 00 80 80 1F 00 00 (bit 0x10) - Map to B as an alternative + // X button (alternate A button) if (report[6] & 0x10) { - decoded_report |= MASK_JOY2_BTN; // X button maps to B + decoded_report |= MASK_KEY_USER3; } - // Y: 00 7F 7F 00 80 80 8F 00 00 (bit 0x80) - Map to A as an alternative + // Y button (alternate B button) if (report[6] & 0x80) { - decoded_report |= MASK_KEY_USER3; // Y button maps to A + decoded_report |= MASK_JOY2_BTN; } - // Select: 00 7F 7F 00 80 80 0F 10 00 (byte 7, bit 0x10) - if (report[7] & 0x10) { - decoded_report |= MASK_KEY_USER1; // Select button - } - - // Start: 00 7F 7F 00 80 80 0F 20 00 (byte 7, bit 0x20) - if (report[7] & 0x20) { - decoded_report |= MASK_KEY_USER2; // Start button - } - - // R: 00 7F 7F 00 80 80 0F 02 00 (byte 7, bit 0x02) - Map to B as an alternative - if (report[7] & 0x02) { - decoded_report |= MASK_JOY2_BTN; // R button maps to B - } - - // L: 00 7F 7F 00 80 80 0F 01 00 (byte 7, bit 0x01) - Map to A as an alternative + // Shoulder and menu buttons (byte 7) + // L button (alternate A button) if (report[7] & 0x01) { - decoded_report |= MASK_KEY_USER3; // L button maps to A + decoded_report |= MASK_KEY_USER3; + } + + // R button (alternate B button) + if (report[7] & 0x02) { + decoded_report |= MASK_JOY2_BTN; + } + + // Select button + if (report[7] & 0x10) { + decoded_report |= MASK_KEY_USER1; + } + + // Start button + if (report[7] & 0x20) { + decoded_report |= MASK_KEY_USER2; } // Send the decoded gamepad state From 054436b8cead84c57089b6fc657184c20cca9f68 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 11:59:41 -0400 Subject: [PATCH 12/19] mapping update --- MCUME_pico2/usb_kbd/hid_app.c | 68 +++++++++++++++++------------------ 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/MCUME_pico2/usb_kbd/hid_app.c b/MCUME_pico2/usb_kbd/hid_app.c index 220f8c4..2842075 100644 --- a/MCUME_pico2/usb_kbd/hid_app.c +++ b/MCUME_pico2/usb_kbd/hid_app.c @@ -376,66 +376,62 @@ static void process_kbd_report (hid_keyboard_report_t const *report) // this mapping is hard coded for a certain snes-style gamepad and picogb! static void process_gamepad_report(const uint8_t *report) { + // Create a fresh report state uint16_t decoded_report = 0; - // Directional controls - X and Y axes - // Note: No need to swap or invert - the Game Boy code handles that + // Print the first few bytes of the report for debugging + // printf("GP: %02x %02x %02x %02x %02x %02x %02x %02x\n", + // report[0], report[1], report[2], report[3], report[4], report[5], report[6], report[7]); - // X-axis (byte 1): 0x00=left, 0x7F=center, 0xFF=right - if (report[1] < 0x40) { // Left + // Try a completely different approach to mapping the directional controls + + // LEFT button -> maps to MASK_JOY2_LEFT + if (report[2] < 0x40) { decoded_report |= MASK_JOY2_LEFT; - } else if (report[1] > 0xB0) { // Right + } + + // RIGHT button -> maps to MASK_JOY2_RIGHT + if (report[2] > 0xB0) { decoded_report |= MASK_JOY2_RIGHT; } - // Y-axis (byte 2): 0x00=up, 0x7F=center, 0xFF=down - if (report[2] < 0x40) { // Up + // UP button -> maps to MASK_JOY2_UP + if (report[1] < 0x40) { decoded_report |= MASK_JOY2_UP; - } else if (report[2] > 0xB0) { // Down + } + + // DOWN button -> maps to MASK_JOY2_DOWN + if (report[1] > 0xB0) { decoded_report |= MASK_JOY2_DOWN; } - // Face buttons (byte 6) - // A button (maps to Game Boy A) - if (report[6] & 0x20) { + // A button -> maps to MASK_KEY_USER3 (byte 6, bit 0x20) + if ((report[6] & 0x20) || (report[6] & 0x10) || (report[7] & 0x01)) { decoded_report |= MASK_KEY_USER3; } - // B button (maps to Game Boy B) - if (report[6] & 0x40) { + // B button -> maps to MASK_JOY2_BTN (byte 6, bit 0x40) + if ((report[6] & 0x40) || (report[6] & 0x80) || (report[7] & 0x02)) { decoded_report |= MASK_JOY2_BTN; } - // X button (alternate A button) - if (report[6] & 0x10) { - decoded_report |= MASK_KEY_USER3; - } - - // Y button (alternate B button) - if (report[6] & 0x80) { - decoded_report |= MASK_JOY2_BTN; - } - - // Shoulder and menu buttons (byte 7) - // L button (alternate A button) - if (report[7] & 0x01) { - decoded_report |= MASK_KEY_USER3; - } - - // R button (alternate B button) - if (report[7] & 0x02) { - decoded_report |= MASK_JOY2_BTN; - } - - // Select button + // Select button -> maps to MASK_KEY_USER1 (byte 7, bit 0x10) if (report[7] & 0x10) { decoded_report |= MASK_KEY_USER1; } - // Start button + // Start button -> maps to MASK_KEY_USER2 (byte 7, bit 0x20) if (report[7] & 0x20) { decoded_report |= MASK_KEY_USER2; } + + if ((report[6] & 0x20) || (report[6] & 0x10)) { // A or X button + decoded_report |= MASK_KEY_USER1; // SELECT for boot screen + } + + if ((report[6] & 0x40) || (report[6] & 0x80)) { // B or Y button + decoded_report |= MASK_KEY_USER2; // START for boot screen + } // Send the decoded gamepad state kbd_signal_raw_gamepad(decoded_report); From 29c62811f017c85022118a351006ffdbf6818ac5 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 12:09:23 -0400 Subject: [PATCH 13/19] left/right --- MCUME_pico2/usb_kbd/hid_app.c | 58 ++++++++++++++++------------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/MCUME_pico2/usb_kbd/hid_app.c b/MCUME_pico2/usb_kbd/hid_app.c index 2842075..7b5cd32 100644 --- a/MCUME_pico2/usb_kbd/hid_app.c +++ b/MCUME_pico2/usb_kbd/hid_app.c @@ -374,63 +374,57 @@ static void process_kbd_report (hid_keyboard_report_t const *report) prev_report = *report; } -// this mapping is hard coded for a certain snes-style gamepad and picogb! static void process_gamepad_report(const uint8_t *report) { - // Create a fresh report state uint16_t decoded_report = 0; - // Print the first few bytes of the report for debugging - // printf("GP: %02x %02x %02x %02x %02x %02x %02x %02x\n", - // report[0], report[1], report[2], report[3], report[4], report[5], report[6], report[7]); - - // Try a completely different approach to mapping the directional controls - - // LEFT button -> maps to MASK_JOY2_LEFT + // Fix the directional controls with proper mapping + // LEFT on controller maps to RIGHT on GB if (report[2] < 0x40) { - decoded_report |= MASK_JOY2_LEFT; + decoded_report |= MASK_JOY2_RIGHT; // Changed from LEFT to RIGHT } - // RIGHT button -> maps to MASK_JOY2_RIGHT + // RIGHT on controller maps to LEFT on GB if (report[2] > 0xB0) { - decoded_report |= MASK_JOY2_RIGHT; + decoded_report |= MASK_JOY2_LEFT; // Changed from RIGHT to LEFT } - // UP button -> maps to MASK_JOY2_UP + // UP and DOWN seem correctly mapped if (report[1] < 0x40) { decoded_report |= MASK_JOY2_UP; } - // DOWN button -> maps to MASK_JOY2_DOWN if (report[1] > 0xB0) { decoded_report |= MASK_JOY2_DOWN; } - // A button -> maps to MASK_KEY_USER3 (byte 6, bit 0x20) - if ((report[6] & 0x20) || (report[6] & 0x10) || (report[7] & 0x01)) { - decoded_report |= MASK_KEY_USER3; + // SNES A button (report[6] & 0x20) maps to GB A + if (report[6] & 0x20) { + decoded_report |= MASK_KEY_USER3; // GB A button } - // B button -> maps to MASK_JOY2_BTN (byte 6, bit 0x40) - if ((report[6] & 0x40) || (report[6] & 0x80) || (report[7] & 0x02)) { - decoded_report |= MASK_JOY2_BTN; + // SNES B button (report[6] & 0x40) maps to GB B + if (report[6] & 0x40) { + decoded_report |= MASK_JOY2_BTN; // GB B button } - // Select button -> maps to MASK_KEY_USER1 (byte 7, bit 0x10) + // SNES X button could map to another function if needed + // if (report[6] & 0x10) { + // decoded_report |= ...; + // } + + // SNES Y button could map to another function if needed + // if (report[6] & 0x80) { + // decoded_report |= ...; + // } + + // Select button if (report[7] & 0x10) { - decoded_report |= MASK_KEY_USER1; + decoded_report |= MASK_KEY_USER1; // GB SELECT } - // Start button -> maps to MASK_KEY_USER2 (byte 7, bit 0x20) + // Start button if (report[7] & 0x20) { - decoded_report |= MASK_KEY_USER2; - } - - if ((report[6] & 0x20) || (report[6] & 0x10)) { // A or X button - decoded_report |= MASK_KEY_USER1; // SELECT for boot screen - } - - if ((report[6] & 0x40) || (report[6] & 0x80)) { // B or Y button - decoded_report |= MASK_KEY_USER2; // START for boot screen + decoded_report |= MASK_KEY_USER2; // GB START } // Send the decoded gamepad state From a1f85ec1b8c69aa8459eb94cd3799a554d274336 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 12:24:53 -0400 Subject: [PATCH 14/19] Update hid_app.c --- MCUME_pico2/usb_kbd/hid_app.c | 76 +++++++++++++++-------------------- 1 file changed, 32 insertions(+), 44 deletions(-) diff --git a/MCUME_pico2/usb_kbd/hid_app.c b/MCUME_pico2/usb_kbd/hid_app.c index 7b5cd32..1fdcee4 100644 --- a/MCUME_pico2/usb_kbd/hid_app.c +++ b/MCUME_pico2/usb_kbd/hid_app.c @@ -373,60 +373,48 @@ static void process_kbd_report (hid_keyboard_report_t const *report) } prev_report = *report; } - + static void process_gamepad_report(const uint8_t *report) { uint16_t decoded_report = 0; - - // Fix the directional controls with proper mapping - // LEFT on controller maps to RIGHT on GB - if (report[2] < 0x40) { - decoded_report |= MASK_JOY2_RIGHT; // Changed from LEFT to RIGHT + + // Directional Controls + // Left is when byte 2 is close to 0x00 + if (report[2] < 0x40) { + decoded_report |= MASK_JOY2_RIGHT; // Note: swapped due to gameboy mapping } - - // RIGHT on controller maps to LEFT on GB - if (report[2] > 0xB0) { - decoded_report |= MASK_JOY2_LEFT; // Changed from RIGHT to LEFT + // Right is when byte 2 is close to 0xFF + if (report[2] > 0xB0) { + decoded_report |= MASK_JOY2_LEFT; // Note: swapped due to gameboy mapping } - - // UP and DOWN seem correctly mapped - if (report[1] < 0x40) { - decoded_report |= MASK_JOY2_UP; + // Up is when byte 1 is close to 0x00 + if (report[1] < 0x40) { + decoded_report |= MASK_JOY2_UP; } - - if (report[1] > 0xB0) { - decoded_report |= MASK_JOY2_DOWN; + // Down is when byte 1 is close to 0xFF + if (report[1] > 0xB0) { + decoded_report |= MASK_JOY2_DOWN; } - - // SNES A button (report[6] & 0x20) maps to GB A - if (report[6] & 0x20) { - decoded_report |= MASK_KEY_USER3; // GB A button + + // A Button (check for 0x2F or 0x1F in byte 6) + if ((report[6] & 0x20) || (report[6] & 0x10)) { + decoded_report |= MASK_KEY_USER3; } - - // SNES B button (report[6] & 0x40) maps to GB B - if (report[6] & 0x40) { - decoded_report |= MASK_JOY2_BTN; // GB B button + + // B Button (check for 0x4F or 0x8F in byte 6) + if ((report[6] & 0x40) || (report[6] & 0x80)) { + decoded_report |= MASK_JOY2_BTN; } - - // SNES X button could map to another function if needed - // if (report[6] & 0x10) { - // decoded_report |= ...; - // } - - // SNES Y button could map to another function if needed - // if (report[6] & 0x80) { - // decoded_report |= ...; - // } - - // Select button - if (report[7] & 0x10) { - decoded_report |= MASK_KEY_USER1; // GB SELECT + + // Select Button (byte 7, bit 0x10) + if (report[7] & 0x10) { + decoded_report |= MASK_KEY_USER1; } - - // Start button - if (report[7] & 0x20) { - decoded_report |= MASK_KEY_USER2; // GB START + + // Start Button (byte 7, bit 0x20) + if (report[7] & 0x20) { + decoded_report |= MASK_KEY_USER2; } - + // Send the decoded gamepad state kbd_signal_raw_gamepad(decoded_report); } From ff4dc4d916e4a02cb145419c756ade7210a693a2 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 12:37:29 -0400 Subject: [PATCH 15/19] Update hid_app.c --- MCUME_pico2/usb_kbd/hid_app.c | 59 +++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/MCUME_pico2/usb_kbd/hid_app.c b/MCUME_pico2/usb_kbd/hid_app.c index 1fdcee4..65d1454 100644 --- a/MCUME_pico2/usb_kbd/hid_app.c +++ b/MCUME_pico2/usb_kbd/hid_app.c @@ -375,45 +375,64 @@ static void process_kbd_report (hid_keyboard_report_t const *report) } static void process_gamepad_report(const uint8_t *report) { + // Print the first few bytes of the report for debugging + printf("GP: %02x %02x %02x %02x %02x %02x %02x %02x\n", + report[0], report[1], report[2], report[3], + report[4], report[5], report[6], report[7]); + uint16_t decoded_report = 0; // Directional Controls - // Left is when byte 2 is close to 0x00 - if (report[2] < 0x40) { - decoded_report |= MASK_JOY2_RIGHT; // Note: swapped due to gameboy mapping + // Check both bytes 1 and 2 for each direction + // LEFT: byte 2 is 0x00 and byte 1 is 0x7F + if (report[2] == 0x00 && report[1] == 0x7F) { + decoded_report |= MASK_JOY2_LEFT; } - // Right is when byte 2 is close to 0xFF - if (report[2] > 0xB0) { - decoded_report |= MASK_JOY2_LEFT; // Note: swapped due to gameboy mapping + // RIGHT: byte 2 is 0xFF and byte 1 is 0x7F + if (report[2] == 0xFF && report[1] == 0x7F) { + decoded_report |= MASK_JOY2_RIGHT; } - // Up is when byte 1 is close to 0x00 - if (report[1] < 0x40) { + // UP: byte 1 is 0x00 and byte 2 is 0x7F + if (report[1] == 0x00 && report[2] == 0x7F) { decoded_report |= MASK_JOY2_UP; } - // Down is when byte 1 is close to 0xFF - if (report[1] > 0xB0) { + // DOWN: byte 1 is 0xFF and byte 2 is 0x7F + if (report[1] == 0xFF && report[2] == 0x7F) { decoded_report |= MASK_JOY2_DOWN; } - // A Button (check for 0x2F or 0x1F in byte 6) - if ((report[6] & 0x20) || (report[6] & 0x10)) { + // A button -> maps to MASK_KEY_USER3 (byte 6 is 0x2F) + if (report[6] == 0x2F) { decoded_report |= MASK_KEY_USER3; } - // B Button (check for 0x4F or 0x8F in byte 6) - if ((report[6] & 0x40) || (report[6] & 0x80)) { + // B button -> maps to MASK_JOY2_BTN (byte 6 is 0x4F or 0x8F) + if ((report[6] == 0x4F) || (report[6] == 0x8F)) { decoded_report |= MASK_JOY2_BTN; } - // Select Button (byte 7, bit 0x10) - if (report[7] & 0x10) { + // X button (debugging) (byte 6 is 0x1F) + if (report[6] == 0x1F) { + printf("X button pressed\n"); + } + + // Y button (debugging) (byte 6 is 0x8F) + if (report[6] == 0x8F) { + printf("Y button pressed\n"); + } + + // Start button -> maps to MASK_KEY_USER2 (byte 7 is 0x20) + if (report[7] == 0x20) { + decoded_report |= MASK_KEY_USER2; + } + + // Select button -> maps to MASK_KEY_USER1 (byte 7 is 0x10) + if (report[7] == 0x10) { decoded_report |= MASK_KEY_USER1; } - // Start Button (byte 7, bit 0x20) - if (report[7] & 0x20) { - decoded_report |= MASK_KEY_USER2; - } + // Additional debug for button mappings + printf("Decoded report: %04x\n", decoded_report); // Send the decoded gamepad state kbd_signal_raw_gamepad(decoded_report); From 547136cf3906c4ddb32d09d3b581c76cf7844f4c Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 14:32:05 -0400 Subject: [PATCH 16/19] Revert "Update hid_app.c" This reverts commit ff4dc4d916e4a02cb145419c756ade7210a693a2. --- MCUME_pico2/usb_kbd/hid_app.c | 59 ++++++++++++----------------------- 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/MCUME_pico2/usb_kbd/hid_app.c b/MCUME_pico2/usb_kbd/hid_app.c index 65d1454..1fdcee4 100644 --- a/MCUME_pico2/usb_kbd/hid_app.c +++ b/MCUME_pico2/usb_kbd/hid_app.c @@ -375,64 +375,45 @@ static void process_kbd_report (hid_keyboard_report_t const *report) } static void process_gamepad_report(const uint8_t *report) { - // Print the first few bytes of the report for debugging - printf("GP: %02x %02x %02x %02x %02x %02x %02x %02x\n", - report[0], report[1], report[2], report[3], - report[4], report[5], report[6], report[7]); - uint16_t decoded_report = 0; // Directional Controls - // Check both bytes 1 and 2 for each direction - // LEFT: byte 2 is 0x00 and byte 1 is 0x7F - if (report[2] == 0x00 && report[1] == 0x7F) { - decoded_report |= MASK_JOY2_LEFT; + // Left is when byte 2 is close to 0x00 + if (report[2] < 0x40) { + decoded_report |= MASK_JOY2_RIGHT; // Note: swapped due to gameboy mapping } - // RIGHT: byte 2 is 0xFF and byte 1 is 0x7F - if (report[2] == 0xFF && report[1] == 0x7F) { - decoded_report |= MASK_JOY2_RIGHT; + // Right is when byte 2 is close to 0xFF + if (report[2] > 0xB0) { + decoded_report |= MASK_JOY2_LEFT; // Note: swapped due to gameboy mapping } - // UP: byte 1 is 0x00 and byte 2 is 0x7F - if (report[1] == 0x00 && report[2] == 0x7F) { + // Up is when byte 1 is close to 0x00 + if (report[1] < 0x40) { decoded_report |= MASK_JOY2_UP; } - // DOWN: byte 1 is 0xFF and byte 2 is 0x7F - if (report[1] == 0xFF && report[2] == 0x7F) { + // Down is when byte 1 is close to 0xFF + if (report[1] > 0xB0) { decoded_report |= MASK_JOY2_DOWN; } - // A button -> maps to MASK_KEY_USER3 (byte 6 is 0x2F) - if (report[6] == 0x2F) { + // A Button (check for 0x2F or 0x1F in byte 6) + if ((report[6] & 0x20) || (report[6] & 0x10)) { decoded_report |= MASK_KEY_USER3; } - // B button -> maps to MASK_JOY2_BTN (byte 6 is 0x4F or 0x8F) - if ((report[6] == 0x4F) || (report[6] == 0x8F)) { + // B Button (check for 0x4F or 0x8F in byte 6) + if ((report[6] & 0x40) || (report[6] & 0x80)) { decoded_report |= MASK_JOY2_BTN; } - // X button (debugging) (byte 6 is 0x1F) - if (report[6] == 0x1F) { - printf("X button pressed\n"); - } - - // Y button (debugging) (byte 6 is 0x8F) - if (report[6] == 0x8F) { - printf("Y button pressed\n"); - } - - // Start button -> maps to MASK_KEY_USER2 (byte 7 is 0x20) - if (report[7] == 0x20) { - decoded_report |= MASK_KEY_USER2; - } - - // Select button -> maps to MASK_KEY_USER1 (byte 7 is 0x10) - if (report[7] == 0x10) { + // Select Button (byte 7, bit 0x10) + if (report[7] & 0x10) { decoded_report |= MASK_KEY_USER1; } - // Additional debug for button mappings - printf("Decoded report: %04x\n", decoded_report); + // Start Button (byte 7, bit 0x20) + if (report[7] & 0x20) { + decoded_report |= MASK_KEY_USER2; + } // Send the decoded gamepad state kbd_signal_raw_gamepad(decoded_report); From a5a4294f9caf8f09aec88423982f3f472214cb32 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 15:40:15 -0400 Subject: [PATCH 17/19] Update hid_app.c --- MCUME_pico2/usb_kbd/hid_app.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/MCUME_pico2/usb_kbd/hid_app.c b/MCUME_pico2/usb_kbd/hid_app.c index 1fdcee4..4cddb88 100644 --- a/MCUME_pico2/usb_kbd/hid_app.c +++ b/MCUME_pico2/usb_kbd/hid_app.c @@ -379,29 +379,29 @@ static void process_gamepad_report(const uint8_t *report) { // Directional Controls // Left is when byte 2 is close to 0x00 - if (report[2] < 0x40) { + if (report[1] < 0x40) { decoded_report |= MASK_JOY2_RIGHT; // Note: swapped due to gameboy mapping } // Right is when byte 2 is close to 0xFF - if (report[2] > 0xB0) { + if (report[1] > 0xB0) { decoded_report |= MASK_JOY2_LEFT; // Note: swapped due to gameboy mapping } // Up is when byte 1 is close to 0x00 - if (report[1] < 0x40) { + if (report[2] < 0x40) { decoded_report |= MASK_JOY2_UP; } // Down is when byte 1 is close to 0xFF - if (report[1] > 0xB0) { + if (report[2] > 0xB0) { decoded_report |= MASK_JOY2_DOWN; } // A Button (check for 0x2F or 0x1F in byte 6) - if ((report[6] & 0x20) || (report[6] & 0x10)) { + if ((report[6] & 0x2F) || (report[6] & 0x1F)) { decoded_report |= MASK_KEY_USER3; } // B Button (check for 0x4F or 0x8F in byte 6) - if ((report[6] & 0x40) || (report[6] & 0x80)) { + if ((report[6] & 0x4F) || (report[6] & 0x8F)) { decoded_report |= MASK_JOY2_BTN; } @@ -481,7 +481,7 @@ int proto = tuh_hid_interface_protocol (dev_addr, instance); process_kbd_report ((hid_keyboard_report_t const*) report); break; case HID_ITF_PROTOCOL_NONE: - if (len >= 8 && len <= 9) { + if (len >= 8) { process_gamepad_report(report); } break; From 5434e35f39908ddf2dc84e5be456f19ea664ed73 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 15:51:42 -0400 Subject: [PATCH 18/19] off by 1? --- MCUME_pico2/usb_kbd/hid_app.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/MCUME_pico2/usb_kbd/hid_app.c b/MCUME_pico2/usb_kbd/hid_app.c index 4cddb88..4505777 100644 --- a/MCUME_pico2/usb_kbd/hid_app.c +++ b/MCUME_pico2/usb_kbd/hid_app.c @@ -379,29 +379,29 @@ static void process_gamepad_report(const uint8_t *report) { // Directional Controls // Left is when byte 2 is close to 0x00 - if (report[1] < 0x40) { + if (report[0] < 0x40) { decoded_report |= MASK_JOY2_RIGHT; // Note: swapped due to gameboy mapping } // Right is when byte 2 is close to 0xFF - if (report[1] > 0xB0) { + if (report[0] > 0xB0) { decoded_report |= MASK_JOY2_LEFT; // Note: swapped due to gameboy mapping } // Up is when byte 1 is close to 0x00 - if (report[2] < 0x40) { + if (report[1] < 0x40) { decoded_report |= MASK_JOY2_UP; } // Down is when byte 1 is close to 0xFF - if (report[2] > 0xB0) { + if (report[1] > 0xB0) { decoded_report |= MASK_JOY2_DOWN; } // A Button (check for 0x2F or 0x1F in byte 6) - if ((report[6] & 0x2F) || (report[6] & 0x1F)) { + if ((report[5] & 0x2F) || (report[5] & 0x1F)) { decoded_report |= MASK_KEY_USER3; } // B Button (check for 0x4F or 0x8F in byte 6) - if ((report[6] & 0x4F) || (report[6] & 0x8F)) { + if ((report[5] & 0x4F) || (report[5] & 0x8F)) { decoded_report |= MASK_JOY2_BTN; } From 8deda0cbe4a161e009999756427ab10563247fb4 Mon Sep 17 00:00:00 2001 From: Liz Date: Tue, 8 Apr 2025 16:02:12 -0400 Subject: [PATCH 19/19] up, down, left and right working, try a, b --- MCUME_pico2/usb_kbd/hid_app.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MCUME_pico2/usb_kbd/hid_app.c b/MCUME_pico2/usb_kbd/hid_app.c index 4505777..27e5550 100644 --- a/MCUME_pico2/usb_kbd/hid_app.c +++ b/MCUME_pico2/usb_kbd/hid_app.c @@ -396,22 +396,22 @@ static void process_gamepad_report(const uint8_t *report) { } // A Button (check for 0x2F or 0x1F in byte 6) - if ((report[5] & 0x2F) || (report[5] & 0x1F)) { + if ((report[5] & 0x20) || (report[5] & 0x10)) { decoded_report |= MASK_KEY_USER3; } // B Button (check for 0x4F or 0x8F in byte 6) - if ((report[5] & 0x4F) || (report[5] & 0x8F)) { + if ((report[5] & 0x40) || (report[5] & 0x80)) { decoded_report |= MASK_JOY2_BTN; } // Select Button (byte 7, bit 0x10) - if (report[7] & 0x10) { + if (report[6] & 0x10) { decoded_report |= MASK_KEY_USER1; } // Start Button (byte 7, bit 0x20) - if (report[7] & 0x20) { + if (report[6] & 0x20) { decoded_report |= MASK_KEY_USER2; }