diff --git a/ControllerUSB/include/ControllerTypes.h b/ControllerUSB/include/ControllerTypes.h index c3b4342..db2442d 100644 --- a/ControllerUSB/include/ControllerTypes.h +++ b/ControllerUSB/include/ControllerTypes.h @@ -26,4 +26,13 @@ enum ProductIDs PRODUCT_DUALSHOCK3 = 0x268, PRODUCT_DUALSHOCK4 = 0x5c4, -}; \ No newline at end of file +}; + +enum ControllerSupport +{ + SUPPORTS_RUMBLE, + SUPPORTS_BLUETOOTH, + SUPPORTS_SIXAXIS, + SUPPORTS_SEVENAXIS, + SUPPORTS_PRESSUREBUTTONS, +}; diff --git a/ControllerUSB/include/Controllers.h b/ControllerUSB/include/Controllers.h index cb50e8e..d0210ea 100644 --- a/ControllerUSB/include/Controllers.h +++ b/ControllerUSB/include/Controllers.h @@ -79,4 +79,42 @@ ControllerType GetControllerTypeFromIds(uint16_t vendor_id, uint16_t product_id) break; } return CONTROLLER_UNDEFINED; +} + +bool DoesControllerSupport(ControllerType type, ControllerSupport supportType) +{ + switch (type) + { + case CONTROLLER_XBOX360: + if (supportType == SUPPORTS_RUMBLE) + return true; + return false; + case CONTROLLER_XBOXONE: + switch (supportType) + { + case SUPPORTS_RUMBLE: + return true; + case SUPPORTS_BLUETOOTH: + return true; + default: + return false; + } + case CONTROLLER_DUALSHOCK3: + switch (supportType) + { + case SUPPORTS_RUMBLE: + return true; + case SUPPORTS_BLUETOOTH: + return true; + case SUPPORTS_PRESSUREBUTTONS: + return true; + case SUPPORTS_SIXAXIS: + return true; + default: + return false; + } + default: + return false; + } + return false; } \ No newline at end of file diff --git a/ControllerUSB/include/Controllers/Dualshock3Controller.h b/ControllerUSB/include/Controllers/Dualshock3Controller.h index c657538..8d1bb37 100644 --- a/ControllerUSB/include/Controllers/Dualshock3Controller.h +++ b/ControllerUSB/include/Controllers/Dualshock3Controller.h @@ -5,43 +5,97 @@ //References used: //https://cs.chromium.org/chromium/src/device/gamepad/dualshock4_controller.cc +enum Dualshock3FeatureValue +{ + Ds3FeatureUnknown1 = 0x0201, + Ds3FeatureUnknown2 = 0x0301, + Ds3FeatureDeviceAddress = 0x03F2, + Ds3FeatureStartDevice = 0x03F4, + Ds3FeatureHostAddress = 0x03F5, + Ds3FeatureUnknown3 = 0x03F7, + Ds3FeatureUnknown4 = 0x03EF, + Ds3FeatureUnknown5 = 0x03F8, +}; + +enum Dualshock3InputPacketType +{ + Ds3InputPacket_Button = 0x01, +}; + struct Dualshock3ButtonData { + //byte0 uint8_t type; - uint8_t length; + //byte1 + uint8_t pad0; - bool dpad_up : 1; - bool dpad_down : 1; - bool dpad_left : 1; - bool dpad_right : 1; - - bool start : 1; + //byte2 bool back : 1; bool stick_left_click : 1; bool stick_right_click : 1; + bool start : 1; + bool dpad_up : 1; + bool dpad_right : 1; + bool dpad_down : 1; + bool dpad_left : 1; + + //byte3 + bool trigger_left : 1; + bool trigger_right : 1; bool bumper_left : 1; bool bumper_right : 1; + + bool triangle : 1; + bool circle : 1; + bool cross : 1; + bool square : 1; + + //byte4 bool guide : 1; - bool dummy1 : 1; // Always 0. + uint8_t pad1 : 7; + //byte5 + uint8_t pad2; - bool a : 1; - bool b : 1; - bool x : 1; - bool y : 1; + //byte6-7 + uint8_t stick_left_x; + uint8_t stick_left_y; - uint8_t trigger_left; - uint8_t trigger_right; + //byte8-9 + uint8_t stick_right_x; + uint8_t stick_right_y; - int16_t stick_left_x; - int16_t stick_left_y; - int16_t stick_right_x; - int16_t stick_right_y; + //byte10-13 + uint8_t pad3[4]; - // Always 0. - uint32_t dummy2; - uint16_t dummy3; -}; + //byte14-17 These respond for how hard the corresponding button has been pressed. 0xFF completely, 0x00 not at all + uint8_t dpad_up_pressure; + uint8_t dpad_right_pressure; + uint8_t dpad_down_pressure; + uint8_t dpad_left_pressure; + + //byte18-19 + uint8_t trigger_left_pressure; + uint8_t trigger_right_pressure; + + //byte20-21 + uint8_t bumper_left_pressure; + uint8_t bumper_right_pressure; + + //byte22-25 + uint8_t triangle_pressure; + uint8_t circle_pressure; + uint8_t cross_pressure; + uint8_t square_pressure; + + uint8_t pad4[15]; + + //byte41-48 + uint16_t accelerometer_x; + uint16_t accelerometer_y; + uint16_t accelerometer_z; + uint16_t gyroscope; +} __attribute__((packed)); /* @@ -91,20 +145,6 @@ const uint8_t LEDS[] = { 0x0E, // LED9 0x0F // LED10 }; - -//Button data -for( int i=0 ; i<3 ; i++ ) HID_PS3_Data.button[i] = data[i+0x2]; -for( int i=0 ; i<4 ; i++ ) HID_PS3_Data.analog_stick[i] = data[i+0x6]; -for( int i=0 ; i<12 ; i++ ) HID_PS3_Data.button_analog[i] = data[i+0x0e]; - -printf("Button state 0x%02x 0x%02x 0x%02x \n", data->button[0], data->button[1], data->button[2] ); -printf("Analog state 0x%02x 0x%02x 0x%02x 0x%02x \n", data->analog_stick[0], data->analog_stick[1], data->analog_stick[2], data->analog_stick[3] ); - -printf("Analog state "); - for( int i=0 ; i<12 ; i++ ) printf("%02x ", data->button_analog[i]); - - - */ class Dualshock3Controller : public IController @@ -115,10 +155,10 @@ private: Dualshock3ButtonData m_buttonData; - int16_t kLeftThumbDeadzone = 0; //7849; - int16_t kRightThumbDeadzone = 0; //8689; - uint16_t kTriggerMax = 0; //1023; - uint16_t kTriggerDeadzone = 0; //120; + int8_t kLeftThumbDeadzone = 0; + int8_t kRightThumbDeadzone = 0; + int8_t kTriggerMax = 0; + int8_t kTriggerDeadzone = 0; public: Dualshock3Controller(std::unique_ptr &&interface); @@ -134,12 +174,12 @@ public: virtual NormalizedButtonData GetNormalizedButtonData(); - virtual ControllerType GetType() { return CONTROLLER_XBOX360; } + virtual ControllerType GetType() { return CONTROLLER_DUALSHOCK3; } inline const Dualshock3ButtonData &GetButtonData() { return m_buttonData; }; - float NormalizeTrigger(uint16_t value); - void NormalizeAxis(int16_t x, int16_t y, int16_t deadzone, float *x_out, float *y_out); + float NormalizeTrigger(uint8_t value); + void NormalizeAxis(uint8_t x, uint8_t y, uint8_t deadzone, float *x_out, float *y_out); Status SendInitBytes(); Status SetRumble(uint8_t strong_magnitude, uint8_t weak_magnitude); diff --git a/ControllerUSB/include/Controllers/Dualshock4Controller.h b/ControllerUSB/include/Controllers/Dualshock4Controller.h index 9d43b84..e8b5516 100644 --- a/ControllerUSB/include/Controllers/Dualshock4Controller.h +++ b/ControllerUSB/include/Controllers/Dualshock4Controller.h @@ -70,7 +70,7 @@ public: virtual NormalizedButtonData GetNormalizedButtonData(); - virtual ControllerType GetType() { return CONTROLLER_XBOX360; } + virtual ControllerType GetType() { return CONTROLLER_DUALSHOCK4; } inline const Dualshock4ButtonData &GetButtonData() { return m_buttonData; }; diff --git a/ControllerUSB/include/IController.h b/ControllerUSB/include/IController.h index 708e505..4419216 100644 --- a/ControllerUSB/include/IController.h +++ b/ControllerUSB/include/IController.h @@ -68,5 +68,5 @@ public: inline IUSBDevice *GetDevice() { return m_device.get(); } virtual ControllerType GetType() = 0; - virtual Status SetRumble(uint8_t strong_magnitude,uint8_t weak_magnitude) = 0; + virtual Status SetRumble(uint8_t strong_magnitude, uint8_t weak_magnitude) = 0; }; \ No newline at end of file diff --git a/ControllerUSB/source/Controllers/Dualshock3Controller.cpp b/ControllerUSB/source/Controllers/Dualshock3Controller.cpp index 6bea656..35a198d 100644 --- a/ControllerUSB/source/Controllers/Dualshock3Controller.cpp +++ b/ControllerUSB/source/Controllers/Dualshock3Controller.cpp @@ -42,8 +42,9 @@ Status Dualshock3Controller::OpenInterfaces() return rc; if (interface->GetDescriptor()->bNumEndpoints >= 2) { + //Send an initial control packet uint8_t initBytes[] = {0x42, 0x0C, 0x00, 0x00}; - rc = interface->ControlTransfer(0x21, 0x09, 0x03F4, 0, 0x04, initBytes); + rc = interface->ControlTransfer(0x21, 0x09, Ds3FeatureStartDevice, 0, sizeof(initBytes), initBytes); if (S_FAILED(rc)) return 60; @@ -81,21 +82,21 @@ void Dualshock3Controller::CloseInterfaces() Status Dualshock3Controller::GetInput() { - /* + uint8_t input_bytes[64]; Status rc = m_inPipe->Read(input_bytes, sizeof(input_bytes)); if (S_FAILED(rc)) return rc; - m_buttonData = *reinterpret_cast(input_bytes); - + if (input_bytes[0] == Ds3InputPacket_Button) + { + m_buttonData = *reinterpret_cast(input_bytes); + } return rc; - */ - return 9; } -float Dualshock3Controller::NormalizeTrigger(uint16_t value) +float Dualshock3Controller::NormalizeTrigger(uint8_t value) { //If the given value is below the trigger zone, save the calc and return 0, otherwise adjust the value to the deadzone return value < kTriggerDeadzone @@ -104,14 +105,14 @@ float Dualshock3Controller::NormalizeTrigger(uint16_t value) (kTriggerMax - kTriggerDeadzone); } -void Dualshock3Controller::NormalizeAxis(int16_t x, - int16_t y, - int16_t deadzone, +void Dualshock3Controller::NormalizeAxis(uint8_t x, + uint8_t y, + uint8_t deadzone, float *x_out, float *y_out) { - float x_val = x; - float y_val = y; + float x_val = x - 127.0f; + float y_val = 127.0f - y; // Determine how far the stick is pushed. //This will never exceed 32767 because if the stick is //horizontally maxed in one direction, vertically it must be neutral(0) and vice versa @@ -120,15 +121,13 @@ void Dualshock3Controller::NormalizeAxis(int16_t x, if (real_magnitude > deadzone) { // Clip the magnitude at its expected maximum value. - float magnitude = std::min(32767.0f, real_magnitude); + float magnitude = std::min(127.0f, real_magnitude); // Adjust magnitude relative to the end of the dead zone. magnitude -= deadzone; // Normalize the magnitude with respect to its expected range giving a // magnitude value of 0.0 to 1.0 //ratio = (currentValue / maxValue) / realValue - float ratio = (magnitude / (32767 - deadzone)) / real_magnitude; - // Y is negated because xbox controllers have an opposite sign from - // the 'standard controller' recommendations. + float ratio = (magnitude / (127 - deadzone)) / real_magnitude; *x_out = x_val * ratio; *y_out = y_val * ratio; } @@ -144,10 +143,10 @@ NormalizedButtonData Dualshock3Controller::GetNormalizedButtonData() { NormalizedButtonData normalData; - normalData.bottom_action = m_buttonData.a; - normalData.right_action = m_buttonData.b; - normalData.left_action = m_buttonData.x; - normalData.top_action = m_buttonData.y; + normalData.bottom_action = m_buttonData.cross; + normalData.right_action = m_buttonData.circle; + normalData.left_action = m_buttonData.square; + normalData.top_action = m_buttonData.triangle; normalData.dpad_up = m_buttonData.dpad_up; normalData.dpad_down = m_buttonData.dpad_down; @@ -166,10 +165,10 @@ NormalizedButtonData Dualshock3Controller::GetNormalizedButtonData() normalData.capture = false; normalData.home = false; - //normalData.guide = m_buttonData.sync; + normalData.guide = m_buttonData.guide; - normalData.left_trigger = NormalizeTrigger(m_buttonData.trigger_left); - normalData.right_trigger = NormalizeTrigger(m_buttonData.trigger_right); + normalData.left_trigger = m_buttonData.trigger_left; + normalData.right_trigger = m_buttonData.trigger_right; NormalizeAxis(m_buttonData.stick_left_x, m_buttonData.stick_left_y, kLeftThumbDeadzone, &normalData.left_stick_x, &normalData.left_stick_y); @@ -181,15 +180,6 @@ NormalizedButtonData Dualshock3Controller::GetNormalizedButtonData() Status Dualshock3Controller::SetRumble(uint8_t strong_magnitude, uint8_t weak_magnitude) { + //Not implemented yet return 9; - /* - uint8_t rumble_data[]{ - 0x09, 0x00, - m_rumbleDataCounter++, - 0x09, 0x00, 0x0f, 0x00, 0x00, - strong_magnitude, - weak_magnitude, - 0xff, 0x00, 0x00}; - return m_outPipe->Write(rumble_data, sizeof(rumble_data)); - */ } \ No newline at end of file diff --git a/source/mainLoop.cpp b/source/mainLoop.cpp index 904040c..c1e60aa 100644 --- a/source/mainLoop.cpp +++ b/source/mainLoop.cpp @@ -34,6 +34,11 @@ Result mainLoop() UsbHsInterfaceFilter filter; filter.Flags = UsbHsInterfaceFilterFlags_idVendor; filter.idVendor = vendor; + if (vendor == VENDOR_SONY) + { + filter.Flags |= UsbHsInterfaceFilterFlags_idProduct; + filter.idProduct = PRODUCT_DUALSHOCK3; + } auto &&event = events[i] = {vendor, Event()}; rc = usbHsCreateInterfaceAvailableEvent(&event.event, true, i, &filter);