From 5a01ce5297c4f0928e7b75e400ec944a601e68be Mon Sep 17 00:00:00 2001 From: ergo720 <45463469+ergo720@users.noreply.github.com> Date: Thu, 4 Nov 2021 20:52:23 +0100 Subject: [PATCH] Fixed wrong SBC subtype + fixed off by two bytes rumble struct + removed rumble hack + switched to interrupt transfers --- src/common/input/InputManager.cpp | 6 ++--- src/common/input/InputManager.h | 2 ++ src/common/input/LibusbDevice.cpp | 22 ++++++------------- src/core/hle/XAPI/Xapi.cpp | 4 ++-- src/core/hle/XAPI/Xapi.h | 15 +++++++------ .../controllers/DlgLibusbControllerConfig.cpp | 6 ++--- 6 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/common/input/InputManager.cpp b/src/common/input/InputManager.cpp index a787d3a0f..23f7ba75d 100644 --- a/src/common/input/InputManager.cpp +++ b/src/common/input/InputManager.cpp @@ -420,7 +420,7 @@ bool InputDeviceManager::UpdateInputXpad(std::shared_ptr& Device, v return false; } - XpadInput* in_buf = reinterpret_cast(static_cast(Buffer) + 2); + XpadInput* in_buf = reinterpret_cast(static_cast(Buffer) + XID_PACKET_HEADER); for (int i = 0; i < 8; i++) { ControlState state = (bindings[i] != nullptr) ? dynamic_cast(bindings[i])->GetState() : 0.0; if (state) { @@ -463,7 +463,7 @@ bool InputDeviceManager::UpdateInputXpad(std::shared_ptr& Device, v } else { if (bindings[24] != nullptr) { - XpadOutput* out_buf = reinterpret_cast(static_cast(Buffer) + 2); + XpadOutput* out_buf = reinterpret_cast(static_cast(Buffer) + XID_PACKET_HEADER); dynamic_cast(bindings[24])->SetState(out_buf->left_actuator_strength / static_cast(0xFFFF), out_buf->right_actuator_strength / static_cast(0xFFFF)); } @@ -496,7 +496,7 @@ bool InputDeviceManager::UpdateInputSBC(std::shared_ptr& Device, vo // 9 -> GearLever Up // 10 -> GearLever Down static uint16_t last_in_state[XBOX_NUM_PORTS] = { 0, 0, 0, 0 }; - SBCInput *in_buf = reinterpret_cast(static_cast(Buffer) + 2); + SBCInput *in_buf = reinterpret_cast(static_cast(Buffer) + XID_PACKET_HEADER); for (int i = 0; i < 4; i++) { ControlState state = (bindings[i] != nullptr) ? dynamic_cast(bindings[i])->GetState() : 0.0; if (state) { diff --git a/src/common/input/InputManager.h b/src/common/input/InputManager.h index b511ef7d4..b9d3df104 100644 --- a/src/common/input/InputManager.h +++ b/src/common/input/InputManager.h @@ -52,6 +52,8 @@ #define MU_OFFSET 4 #define MAX_DEVS (XBOX_NUM_PORTS + XBOX_CTRL_NUM_SLOTS * XBOX_NUM_PORTS) +#define XID_PACKET_HEADER 2 + extern int dev_num_buttons[to_underlying(XBOX_INPUT_DEVICE::DEVICE_MAX)]; inline XBOX_INPUT_DEVICE input_support_list[] = { diff --git a/src/common/input/LibusbDevice.cpp b/src/common/input/LibusbDevice.cpp index 76f06c1c3..eeddac1de 100644 --- a/src/common/input/LibusbDevice.cpp +++ b/src/common/input/LibusbDevice.cpp @@ -32,8 +32,8 @@ #include "core\kernel\support\Emu.h" #include "core\hle\XAPI\Xapi.h" -// Sanitiy check: ensure out libusb version is high enough for libusb_get_device_descriptor to succeed -static_assert(LIBUSB_API_VERSION >= 0x01000102); +// Sanitiy check: ensure out libusb version is high enough for libusb_get_device_descriptor to succeed and to pass nullptr to libusb_interrupt_transfer +static_assert(LIBUSB_API_VERSION >= 0x01000105); namespace Libusb @@ -162,7 +162,7 @@ namespace Libusb if ((Desc->idVendor == 0x0a7b) && (Desc->idProduct == 0xd000)) { m_Type = XBOX_INPUT_DEVICE::HW_STEEL_BATTALION_CONTROLLER; m_UcType = XINPUT_DEVTYPE_STEELBATTALION; - m_UcSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD_ALT; + m_UcSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD; m_Name = "Steel battalion controller"; m_BufferInSize = sizeof(XidSBCInput); m_BufferOutSize = sizeof(XidSBCOutput); @@ -283,30 +283,22 @@ namespace Libusb bool LibusbDevice::ExecuteIo(void *Buffer, int Direction) { + // NOTE: a SET_REPORT control transfer to the SBC doesn't seem to work, the parameters might not be appropriate for it... So, we use + // the interrupt pipes for everything instead *static_cast(Buffer) = 0; // write bReportId if (Direction == DIRECTION_IN) { *(static_cast(Buffer) + 1) = m_BufferInSize; // write bLength - // submit a GET_REPORT request - if (libusb_control_transfer(m_hDev, 0xA1, 1, 0x0100, m_IfaceNum, static_cast(Buffer), m_BufferInSize, m_IntervalIn) == m_BufferInSize) { + if (libusb_interrupt_transfer(m_hDev, m_EndpointIn, static_cast(Buffer), m_BufferInSize, nullptr, m_IntervalIn) != 0) { return false; } } else { if (m_HasEndpointOut) { *(static_cast(Buffer) + 1) = m_BufferOutSize; // write bLength - // https://github.com/libusb/libusb/blob/f33c9562a1dd7a0cb333fcd9a670ba14fbbfbc0e/examples/xusb.c#L300 - // For some reason libusb seems to require to constraint the actuator strenght to 0-255 - if (m_Type == XBOX_INPUT_DEVICE::HW_XBOX_CONTROLLER) { - XidGamepadOutput *OutBuffer = static_cast(Buffer); - OutBuffer->OutBuffer.left_actuator_strength = (OutBuffer->OutBuffer.left_actuator_strength >> 8); - OutBuffer->OutBuffer.right_actuator_strength = (OutBuffer->OutBuffer.right_actuator_strength >> 8); - } - // submit a SET_REPORT request - if (libusb_control_transfer(m_hDev, 0x21, 9, 0x0200, m_IfaceNum, static_cast(Buffer), m_BufferOutSize, m_IntervalOut) == m_BufferOutSize) { + if (libusb_interrupt_transfer(m_hDev, m_EndpointOut, static_cast(Buffer), m_BufferOutSize, nullptr, m_IntervalOut) != 0) { return false; } } - } return true; diff --git a/src/core/hle/XAPI/Xapi.cpp b/src/core/hle/XAPI/Xapi.cpp index fac7d7335..10df2b86d 100644 --- a/src/core/hle/XAPI/Xapi.cpp +++ b/src/core/hle/XAPI/Xapi.cpp @@ -264,7 +264,7 @@ void ConstructHleInputDevice(DeviceState *dev, DeviceState *upstream, int type, dev->info.buff.sbc.InBuffer.sAimingY = static_cast(0x7F); dev->info.bAutoPollDefault = true; dev->info.ucType = XINPUT_DEVTYPE_STEELBATTALION; - dev->info.ucSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD_ALT; + dev->info.ucSubType = XINPUT_DEVSUBTYPE_GC_GAMEPAD; dev->info.ucInputStateSize = sizeof(SBCInput); dev->info.ucFeedbackSize = sizeof(SBCOutput); if (type == to_underlying(XBOX_INPUT_DEVICE::HW_STEEL_BATTALION_CONTROLLER)) { @@ -773,7 +773,7 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XInputSetState) int port = dev->port_idx; if (g_devs[port].info.hHandle == hDevice && !g_devs[port].bPendingRemoval) { pFeedback->Header.dwStatus = ERROR_IO_PENDING; - g_InputDeviceManager.UpdateXboxPortInput(port, (void*)&pFeedback->Rumble, DIRECTION_OUT, to_underlying(g_devs[port].type)); + g_InputDeviceManager.UpdateXboxPortInput(port, (void*)&pFeedback->Header.bReportId, DIRECTION_OUT, to_underlying(g_devs[port].type)); pFeedback->Header.dwStatus = ERROR_SUCCESS; if (pFeedback->Header.hEvent != NULL && ObReferenceObjectByHandle(pFeedback->Header.hEvent, &xbox::ExEventObjectType, (PVOID*)&pFeedback->Header.IoCompletedEvent) == ERROR_SUCCESS) { diff --git a/src/core/hle/XAPI/Xapi.h b/src/core/hle/XAPI/Xapi.h index 1b5d2949f..e28f12465 100644 --- a/src/core/hle/XAPI/Xapi.h +++ b/src/core/hle/XAPI/Xapi.h @@ -214,7 +214,6 @@ XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES; // ****************************************************************** //general GAMEPAD uses subtype 0x01. #define XINPUT_DEVSUBTYPE_GC_GAMEPAD 0x01 -//SteelBatallion controller uses subtype 0x02 #define XINPUT_DEVSUBTYPE_GC_GAMEPAD_ALT 0x02 #define XINPUT_DEVSUBTYPE_GC_WHEEL 0x10 #define XINPUT_DEVSUBTYPE_GC_ARCADE_STICK 0x20 @@ -243,16 +242,18 @@ XINPUT_STATE, *PXINPUT_STATE; // ****************************************************************** // * XINPUT_FEEDBACK_HEADER // ****************************************************************** -#include "AlignPrefix1.h" +#pragma pack(1) typedef struct _XINPUT_FEEDBACK_HEADER { - xbox::dword_xt dwStatus; + xbox::dword_xt dwStatus; HANDLE OPTIONAL hEvent; - xbox::byte_xt Unknown1[4]; + xbox::byte_xt Unknown1[4]; PVOID IoCompletedEvent; // PKEVENT really - xbox::byte_xt Unknown2[50]; + xbox::byte_xt Unknown2[48]; + xbox::byte_xt bReportId; + xbox::byte_xt bLength; } -#include "AlignPosfix1.h" + XINPUT_FEEDBACK_HEADER, *PXINPUT_FEEDBACK_HEADER; // ****************************************************************** @@ -268,7 +269,7 @@ typedef struct _XINPUT_FEEDBACK }; } XINPUT_FEEDBACK, *PXINPUT_FEEDBACK; - +#pragma pack() // ****************************************************************** // * RTL_HEAP_PARAMETERS // ****************************************************************** diff --git a/src/gui/controllers/DlgLibusbControllerConfig.cpp b/src/gui/controllers/DlgLibusbControllerConfig.cpp index 2daa4bed3..60655cd47 100644 --- a/src/gui/controllers/DlgLibusbControllerConfig.cpp +++ b/src/gui/controllers/DlgLibusbControllerConfig.cpp @@ -137,9 +137,9 @@ void LibusbInputWindow::TestInput() bool detect = false; while (now <= timeout) { LibusbDev->ExecuteIo(buffer, DIRECTION_IN); - if (std::memcmp(reinterpret_cast(buffer) + 2, - reinterpret_cast(&buffer[1]) + 2, - sizeof(InputBuff) - 2)) { + if (std::memcmp(reinterpret_cast(buffer) + XID_PACKET_HEADER, + reinterpret_cast(&buffer[1]) + XID_PACKET_HEADER, + sizeof(InputBuff) - XID_PACKET_HEADER)) { detect = true; break; }