diff --git a/ControllerUSB/include/Controllers/XboxOneController.h b/ControllerUSB/include/Controllers/XboxOneController.h index 1f52a19..c5196e0 100644 --- a/ControllerUSB/include/Controllers/XboxOneController.h +++ b/ControllerUSB/include/Controllers/XboxOneController.h @@ -81,7 +81,8 @@ private: XboxOneButtonData m_buttonData; bool m_GuidePressed{false}; - uint8_t m_rumbleDataCounter = 0; + //Meant to be incremented with each out packet + uint8_t m_outPacketSerial = 0; /* int16_t kLeftThumbDeadzone = 2500; //7849; diff --git a/ControllerUSB/source/Controllers/XboxOneController.cpp b/ControllerUSB/source/Controllers/XboxOneController.cpp index 54eb06c..e5f4bd5 100644 --- a/ControllerUSB/source/Controllers/XboxOneController.cpp +++ b/ControllerUSB/source/Controllers/XboxOneController.cpp @@ -1,8 +1,54 @@ #include "Controllers/XboxOneController.h" #include +#include "../../source/log.h" static ControllerConfig _xboxoneControllerConfig{}; +//Following input packets were referenced from https://github.com/torvalds/linux/blob/master/drivers/input/joystick/xpad.c + +static const uint8_t xboxone_fw2015_init[] = { + 0x05, 0x20, 0x00, 0x01, 0x00}; + +static const uint8_t xboxone_hori_init[] = { + 0x01, 0x20, 0x00, 0x09, 0x00, 0x04, 0x20, 0x3a, + 0x00, 0x00, 0x00, 0x80, 0x00}; + +static const uint8_t xboxone_pdp_init1[] = { + 0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14}; + +static const uint8_t xboxone_pdp_init2[] = { + 0x06, 0x20, 0x00, 0x02, 0x01, 0x00}; + +static const uint8_t xboxone_rumblebegin_init[] = { + 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, + 0x1D, 0x1D, 0xFF, 0x00, 0x00}; + +static const uint8_t xboxone_rumbleend_init[] = { + 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00}; + +struct VendorProductPacket +{ + uint16_t VendorID; + uint16_t ProductID; + const uint8_t *Packet; + uint8_t Length; +}; + +static VendorProductPacket init_packets[]{ + {0x0e6f, 0x0165, xboxone_hori_init, sizeof(xboxone_hori_init)}, + {0x0f0d, 0x0067, xboxone_hori_init, sizeof(xboxone_hori_init)}, + {0x0000, 0x0000, xboxone_fw2015_init, sizeof(xboxone_fw2015_init)}, + {0x0e6f, 0x0000, xboxone_pdp_init1, sizeof(xboxone_pdp_init1)}, + {0x0e6f, 0x0000, xboxone_pdp_init2, sizeof(xboxone_pdp_init2)}, + {0x24c6, 0x541a, xboxone_rumblebegin_init, sizeof(xboxone_rumblebegin_init)}, + {0x24c6, 0x542a, xboxone_rumblebegin_init, sizeof(xboxone_rumblebegin_init)}, + {0x24c6, 0x543a, xboxone_rumblebegin_init, sizeof(xboxone_rumblebegin_init)}, + {0x24c6, 0x541a, xboxone_rumbleend_init, sizeof(xboxone_rumbleend_init)}, + {0x24c6, 0x542a, xboxone_rumbleend_init, sizeof(xboxone_rumbleend_init)}, + {0x24c6, 0x543a, xboxone_rumbleend_init, sizeof(xboxone_rumbleend_init)}, +}; + XboxOneController::XboxOneController(std::unique_ptr &&interface) : IController(std::move(interface)) { @@ -121,11 +167,30 @@ Status XboxOneController::GetInput() Status XboxOneController::SendInitBytes() { - uint8_t init_bytes[]{ - 0x05, - 0x20, 0x00, 0x01, 0x00}; + Status rc; + uint16_t vendor = m_device->GetVendor(); + uint16_t product = m_device->GetProduct(); + for (int i = 0; i != (sizeof(init_packets) / sizeof(VendorProductPacket)); ++i) + { + if (init_packets[i].VendorID != 0 && init_packets[i].VendorID != vendor) + continue; + if (init_packets[i].ProductID != 0 && init_packets[i].ProductID != product) + continue; - Status rc = m_outPipe->Write(init_bytes, sizeof(init_bytes)); + uint8_t init_packet[16]; + for (int byte = 0; byte != init_packets[i].Length; ++byte) + { + init_packet[byte] = init_packets[i].Packet[byte]; + } + + init_packet[2] = m_outPacketSerial++; + + rc = m_outPipe->Write(init_packet, init_packets[i].Length); + if (S_FAILED(rc)) + break; + else + WriteToLog("Send a specific init packet for controller v", vendor, " p", product, " with outPacket ", +init_packet[2]); + } return rc; } @@ -233,7 +298,7 @@ Status XboxOneController::SetRumble(uint8_t strong_magnitude, uint8_t weak_magni { uint8_t rumble_data[]{ 0x09, 0x00, - m_rumbleDataCounter++, + m_outPacketSerial++, 0x09, 0x00, 0x0f, 0x00, 0x00, strong_magnitude, weak_magnitude,