diff --git a/rpcs3/Emu/Io/LogitechG27.cpp b/rpcs3/Emu/Io/LogitechG27.cpp index b2311719d8..391e26002a 100644 --- a/rpcs3/Emu/Io/LogitechG27.cpp +++ b/rpcs3/Emu/Io/LogitechG27.cpp @@ -119,12 +119,41 @@ u16 usb_device_logitech_g27::get_num_emu_devices() void usb_device_logitech_g27::control_transfer(u8 bmRequestType, u8 bRequest, u16 wValue, u16 wIndex, u16 wLength, u32 buf_size, u8* buf, UsbTransfer* transfer) { - transfer->fake = true; - transfer->expected_count = buf_size; - transfer->expected_result = HC_CC_NOERR; - transfer->expected_time = get_timestamp() + 100; + logitech_g27_log.todo("control transfer bmRequestType %02x, bRequest %02x, wValue %04x, wIndex %04x, wLength %04x, %s", bmRequestType, bRequest, wValue, wIndex, wLength, fmt::buf_to_hexstring(buf, buf_size)); + + if (bmRequestType == 0xa1 /* LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE */ && bRequest == 0x01) + { + /* + * TODO more investigations needed if things don't work + * XXX this doesn't happen in passthrough, something went wrong before getting here + * G29 in G27 mode doesn't even support this, gives LIBUSB_ERROR_PIPE + * Not sure how games were encouraged to generate this in emulated device + */ + + logitech_g27_log.todo("failing unknown request type 0xa1 request 0x01"); + + transfer->fake = true; + transfer->expected_count = buf_size; + transfer->expected_result = EHCI_CC_XACT; + transfer->expected_time = get_timestamp() + 1000 * 1000; + return; + } + + if (bmRequestType = 0x00 /* LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE */ && bRequest == 0x09 /* LIBUSB_REQUEST_SET_CONFIGURATION */) + { + if (wValue != 1) + { + logitech_g27_log.todo("game tries to set cfg num to not 1 but %d, which the behavior is not yet known", wValue); + } + current_config = wValue; + + transfer->fake = true; + transfer->expected_count = buf_size; + transfer->expected_result = HC_CC_NOERR; + transfer->expected_time = get_timestamp() + 100; + return; + } - // Log these for now, might not need to implement anything usb_device_emulated::control_transfer(bmRequestType, bRequest, wValue, wIndex, wLength, buf_size, buf, transfer); } @@ -1516,4 +1545,11 @@ void usb_device_logitech_g27::interrupt_transfer(u32 buf_size, u8* buf, u32 endp } } +bool usb_device_logitech_g27::set_configuration(u8 cfg_num) +{ + // setting it through libusb_set_configuration on linux fails, but when passthrough does it through control transfer, it doesn't fail + logitech_g27_log.todo("emulator sets config num %u outside of control transfer, fail it for now", cfg_num); + return false; +} + #endif diff --git a/rpcs3/Emu/Io/LogitechG27.h b/rpcs3/Emu/Io/LogitechG27.h index 5a8406486a..84aebdae69 100644 --- a/rpcs3/Emu/Io/LogitechG27.h +++ b/rpcs3/Emu/Io/LogitechG27.h @@ -99,6 +99,7 @@ public: void control_transfer(u8 bmRequestType, u8 bRequest, u16 wValue, u16 wIndex, u16 wLength, u32 buf_size, u8* buf, UsbTransfer* transfer) override; void interrupt_transfer(u32 buf_size, u8* buf, u32 endpoint, UsbTransfer* transfer) override; bool open_device() override; + bool set_configuration(u8 cfg_num) override; private: void sdl_refresh();