From 31682122145ebd3a83e9d8ed8a3cad012c19c712 Mon Sep 17 00:00:00 2001 From: Flora Aubry Date: Fri, 8 Jul 2022 23:31:07 +0000 Subject: [PATCH] Add support for Sony DualSense closes #2013 --- .../RGBController_SonyDS4.cpp | 0 .../RGBController_SonyDS4.h | 0 .../RGBController_SonyDualSense.cpp | 143 ++++++++++++++++++ .../RGBController_SonyDualSense.h | 29 ++++ .../SonyDS4Controller.cpp | 0 .../SonyDS4Controller.h | 0 .../SonyDualSenseController.cpp | 133 ++++++++++++++++ .../SonyDualSenseController.h | 47 ++++++ .../SonyGamepadControllerDetect.cpp} | 23 ++- OpenRGB.pro | 21 ++- 10 files changed, 384 insertions(+), 12 deletions(-) rename Controllers/{SonyDS4Controller => SonyGamepadController}/RGBController_SonyDS4.cpp (100%) rename Controllers/{SonyDS4Controller => SonyGamepadController}/RGBController_SonyDS4.h (100%) create mode 100644 Controllers/SonyGamepadController/RGBController_SonyDualSense.cpp create mode 100644 Controllers/SonyGamepadController/RGBController_SonyDualSense.h rename Controllers/{SonyDS4Controller => SonyGamepadController}/SonyDS4Controller.cpp (100%) rename Controllers/{SonyDS4Controller => SonyGamepadController}/SonyDS4Controller.h (100%) create mode 100644 Controllers/SonyGamepadController/SonyDualSenseController.cpp create mode 100644 Controllers/SonyGamepadController/SonyDualSenseController.h rename Controllers/{SonyDS4Controller/SonyDS4ControllerDetect.cpp => SonyGamepadController/SonyGamepadControllerDetect.cpp} (59%) diff --git a/Controllers/SonyDS4Controller/RGBController_SonyDS4.cpp b/Controllers/SonyGamepadController/RGBController_SonyDS4.cpp similarity index 100% rename from Controllers/SonyDS4Controller/RGBController_SonyDS4.cpp rename to Controllers/SonyGamepadController/RGBController_SonyDS4.cpp diff --git a/Controllers/SonyDS4Controller/RGBController_SonyDS4.h b/Controllers/SonyGamepadController/RGBController_SonyDS4.h similarity index 100% rename from Controllers/SonyDS4Controller/RGBController_SonyDS4.h rename to Controllers/SonyGamepadController/RGBController_SonyDS4.h diff --git a/Controllers/SonyGamepadController/RGBController_SonyDualSense.cpp b/Controllers/SonyGamepadController/RGBController_SonyDualSense.cpp new file mode 100644 index 00000000..49041602 --- /dev/null +++ b/Controllers/SonyGamepadController/RGBController_SonyDualSense.cpp @@ -0,0 +1,143 @@ +/*-----------------------------------------*\ +| RGBController_SonyDualSense.h | +| | +| Controller for Sony DualSense | +| | +| by flora 01/07/2022 | +\*-----------------------------------------*/ + +#include +#include "RGBController_SonyDualSense.h" + +/**------------------------------------------------------------------*\ + @name Sony Dual Sense controller + @category Gamepad + @type USB + @save :x: + @direct :white_check_mark: + @effects :x: + @detectors DetectSonyDualSenseControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_SonyDualSense::RGBController_SonyDualSense(SonyDualSenseController* controller_ptr) +{ + controller = controller_ptr; + + name = "Sony DualSense"; + + if(controller->IsBluetooth()) + { + name.append(" (BT)"); + } + + vendor = "Sony"; + type = DEVICE_TYPE_GAMEPAD; + description = "Sony DualSense Device"; + location = controller->GetLocation(); + serial = controller->GetSerialString(); + + mode Direct; + Direct.value = SONY_DUALSENSE_DIRECT_MODE_VALUE; + Direct.name = "Direct"; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Direct.color_mode = MODE_COLORS_PER_LED; + Direct.brightness_min = SONY_DUALSENSE_BRIGHTNESS_MIN; + Direct.brightness_max = SONY_DUALSENSE_BRIGHTNESS_MAX; + Direct.brightness = SONY_DUALSENSE_DEFAULT_BRIGHTNESS; + modes.push_back(Direct); + + mode Micoff; + Micoff.value = SONY_DUALSENSE_MIC_OFF_MODE_VALUE; + Micoff.name = "Mic Off (Direct)"; + Micoff.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Micoff.color_mode = MODE_COLORS_PER_LED; + Micoff.brightness_min = SONY_DUALSENSE_BRIGHTNESS_MIN; + Micoff.brightness_max = SONY_DUALSENSE_BRIGHTNESS_MAX; + Micoff.brightness = SONY_DUALSENSE_DEFAULT_BRIGHTNESS; + modes.push_back(Micoff); + + mode Micpulse; + Micpulse.value = SONY_DUALSENSE_MIC_PULSE_MODE_VALUE; + Micpulse.name = "Mic Pulse (Direct)"; + Micpulse.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Micpulse.color_mode = MODE_COLORS_PER_LED; + Micpulse.brightness_min = SONY_DUALSENSE_BRIGHTNESS_MIN; + Micpulse.brightness_max = SONY_DUALSENSE_BRIGHTNESS_MAX; + Micpulse.brightness = SONY_DUALSENSE_DEFAULT_BRIGHTNESS; + modes.push_back(Micpulse); + + SetupZones(); +} + +RGBController_SonyDualSense::~RGBController_SonyDualSense() +{ + delete controller; +} + +void RGBController_SonyDualSense::SetupZones() +{ + /*---------------------------------------------------------*\ + | This device only has one LED, so create a single zone and | + | LED for it | + \*---------------------------------------------------------*/ + zone lightbar; + lightbar.name = "Lightbar"; + lightbar.type = ZONE_TYPE_SINGLE; + lightbar.leds_min = SONY_DUALSENSE_LIGHTBAR_LED_COUNT; + lightbar.leds_max = SONY_DUALSENSE_LIGHTBAR_LED_COUNT; + lightbar.leds_count = SONY_DUALSENSE_LIGHTBAR_LED_COUNT; + lightbar.matrix_map = NULL; + zones.push_back(lightbar); + + zone playerleds; + playerleds.name = "Player LEDs"; + playerleds.type = ZONE_TYPE_LINEAR; + playerleds.leds_min = SONY_DUALSENSE_PLAYER_LED_COUNT; + playerleds.leds_max = SONY_DUALSENSE_PLAYER_LED_COUNT; + playerleds.leds_count = SONY_DUALSENSE_PLAYER_LED_COUNT; + playerleds.matrix_map = NULL; + zones.push_back(playerleds); + + leds.resize(SONY_DUALSENSE_LIGHTBAR_LED_COUNT + SONY_DUALSENSE_PLAYER_LED_COUNT); + + leds[0].name = "LED 1"; + + for(unsigned int i = 0 ; i < SONY_DUALSENSE_PLAYER_LED_COUNT; i++) + { + leds[i + 1].name = "Player " + std::to_string(i + 1); + } + + SetupColors(); +} + +void RGBController_SonyDualSense::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_SonyDualSense::DeviceUpdateLEDs() +{ + controller->SetColors(colors, modes[active_mode].brightness, modes[active_mode].value); +} + +void RGBController_SonyDualSense::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_SonyDualSense::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_SonyDualSense::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_SonyDualSense::DeviceUpdateMode() +{ +} diff --git a/Controllers/SonyGamepadController/RGBController_SonyDualSense.h b/Controllers/SonyGamepadController/RGBController_SonyDualSense.h new file mode 100644 index 00000000..5824a037 --- /dev/null +++ b/Controllers/SonyGamepadController/RGBController_SonyDualSense.h @@ -0,0 +1,29 @@ +/*-----------------------------------------*\ +| RGBController_SonyDualSense.h | +| | +| Controller for Sony DualSense | +| | +| by flora 01/07/2022 | +\*-----------------------------------------*/ + + +#include "RGBController.h" +#include "SonyDualSenseController.h" + +class RGBController_SonyDualSense : public RGBController +{ +public: + RGBController_SonyDualSense(SonyDualSenseController* controller_ptr); + ~RGBController_SonyDualSense(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + SonyDualSenseController* controller; +}; diff --git a/Controllers/SonyDS4Controller/SonyDS4Controller.cpp b/Controllers/SonyGamepadController/SonyDS4Controller.cpp similarity index 100% rename from Controllers/SonyDS4Controller/SonyDS4Controller.cpp rename to Controllers/SonyGamepadController/SonyDS4Controller.cpp diff --git a/Controllers/SonyDS4Controller/SonyDS4Controller.h b/Controllers/SonyGamepadController/SonyDS4Controller.h similarity index 100% rename from Controllers/SonyDS4Controller/SonyDS4Controller.h rename to Controllers/SonyGamepadController/SonyDS4Controller.h diff --git a/Controllers/SonyGamepadController/SonyDualSenseController.cpp b/Controllers/SonyGamepadController/SonyDualSenseController.cpp new file mode 100644 index 00000000..50141d2d --- /dev/null +++ b/Controllers/SonyGamepadController/SonyDualSenseController.cpp @@ -0,0 +1,133 @@ +/*-----------------------------------------*\ +| RGBController_SonyDualSense.h | +| | +| Controller for Sony DualSense | +| | +| by flora 01/07/2022 | +\*-----------------------------------------*/ +#include +#include +#include +#include "SonyDualSenseController.h" + +SonyDualSenseController::SonyDualSenseController(hid_device * device_handle, const char * device_path) +{ + dev = device_handle; + location = device_path; + + unsigned char usb_buf[SONY_DUALSENSE_BT_PACKET_SIZE]; + memset(usb_buf, 0x00, SONY_DUALSENSE_BT_PACKET_SIZE); + + usb_buf[0] = 0x31; + + int bytes = hid_write(dev, usb_buf, SONY_DUALSENSE_BT_PACKET_SIZE); + + is_bluetooth = bytes > 0; +} + +SonyDualSenseController::~SonyDualSenseController() +{ + hid_close(dev); +} + +std::string SonyDualSenseController::GetLocation() +{ + return("HID: " + location); +} + +std::string SonyDualSenseController::GetSerialString() +{ + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + if(ret != 0) + { + return(""); + } + + std::wstring return_wstring = serial_string; + std::string return_string(return_wstring.begin(), return_wstring.end()); + + return(return_string); +} + +void SonyDualSenseController::SetColors(std::vector colors, unsigned char brightness, unsigned char mode_value) +{ + if(is_bluetooth) + { + unsigned char buffer[SONY_DUALSENSE_BT_PACKET_SIZE + 1]; + memset(buffer, 0x00, SONY_DUALSENSE_BT_PACKET_SIZE + 1); + + buffer[0] = 0xA2; + buffer[1] = 0x31; + buffer[2] = 0x02; + buffer[3] = 0x0F; + buffer[4] = 0x55; + + buffer[11] = mode_value; + buffer[41] = 0xFF; // Must be > 0x00 to control birghtness + buffer[44] = 0x02; // bypass default blue color when connected to bluetooth + buffer[45] = 0x02 - brightness; + buffer[46] = 0x20 + + ((colors[1] > 0) ) + + ((colors[2] > 0) << 1) + + ((colors[3] > 0) << 2) + + ((colors[4] > 0) << 3) + + ((colors[5] > 0) << 4); + + buffer[47] = RGBGetRValue(colors[0]); + buffer[48] = RGBGetGValue(colors[0]); + buffer[49] = RGBGetBValue(colors[0]); + + uint32_t crc = CRCPP::CRC::Calculate(buffer, SONY_DUALSENSE_BT_PACKET_SIZE - 3, CRCPP::CRC::CRC_32()); + unsigned char outbuffer[SONY_DUALSENSE_BT_PACKET_SIZE]; + + /*-------------------------------------------------*\ + | The report has to be signed with the byte 0xa2. | + | However, hidapi already adds 0xa2 to the report, | + | so we need to remove it from the buffer. | + \*-------------------------------------------------*/ + for(unsigned int i = 1; i < SONY_DUALSENSE_BT_PACKET_SIZE + 1; i++) + { + outbuffer[i - 1] = buffer[i]; + } + + /*-------------------------------------------------*\ + | Add the crc32 to the end of the buffer | + \*-------------------------------------------------*/ + outbuffer[74] = (0x000000FF & crc); + outbuffer[75] = (0x0000FF00 & crc) >> 8; + outbuffer[76] = (0x00FF0000 & crc) >> 16; + outbuffer[77] = (0xFF000000 & crc) >> 24; + + hid_write(dev, outbuffer, SONY_DUALSENSE_BT_PACKET_SIZE); + } + else + { + unsigned char usb_buf[SONY_DUALSENSE_USB_PACKET_SIZE]; + memset(usb_buf, 0x00, SONY_DUALSENSE_USB_PACKET_SIZE); + + usb_buf[0] = 0x02; + usb_buf[1] = 0x0F; + usb_buf[2] = 0x55; + usb_buf[9] = mode_value; + usb_buf[39] = 0xFF; // Must be > 0x00 to control birghtness + usb_buf[43] = 0x02 - brightness; + usb_buf[44] = 0x20 + + ((colors[1] > 0) ) + + ((colors[2] > 0) << 1) + + ((colors[3] > 0) << 2) + + ((colors[4] > 0) << 3) + + ((colors[5] > 0) << 4); + + usb_buf[45] = RGBGetRValue(colors[0]); + usb_buf[46] = RGBGetGValue(colors[0]); + usb_buf[47] = RGBGetBValue(colors[0]); + + hid_write(dev, usb_buf, SONY_DUALSENSE_USB_PACKET_SIZE); + } +} + +bool SonyDualSenseController::IsBluetooth() +{ + return(is_bluetooth); +} diff --git a/Controllers/SonyGamepadController/SonyDualSenseController.h b/Controllers/SonyGamepadController/SonyDualSenseController.h new file mode 100644 index 00000000..d04d99fd --- /dev/null +++ b/Controllers/SonyGamepadController/SonyDualSenseController.h @@ -0,0 +1,47 @@ +/*-----------------------------------------*\ +| RGBController_SonyDualSense.h | +| | +| Controller for Sony DualSense | +| | +| by flora 01/07/2022 | +\*-----------------------------------------*/ + + +#include +#include "RGBController.h" + +#include +#include + +#define SONY_DUALSENSE_LIGHTBAR_LED_COUNT 1 +#define SONY_DUALSENSE_PLAYER_LED_COUNT 5 +#define SONY_DUALSENSE_BT_PACKET_SIZE 78 +#define SONY_DUALSENSE_USB_PACKET_SIZE 48 + +enum +{ + SONY_DUALSENSE_DIRECT_MODE_VALUE = 0x01, + SONY_DUALSENSE_MIC_OFF_MODE_VALUE = 0x00, + SONY_DUALSENSE_MIC_PULSE_MODE_VALUE = 0x02, + SONY_DUALSENSE_BRIGHTNESS_MIN = 0x00, + SONY_DUALSENSE_BRIGHTNESS_MAX = 0x02, + SONY_DUALSENSE_DEFAULT_BRIGHTNESS = 0x01 +}; + +class SonyDualSenseController +{ +public: + SonyDualSenseController(hid_device * device_handle, const char * device_path); + ~SonyDualSenseController(); + + std::string GetLocation(); + std::string GetSerialString(); + + void SetColors(std::vector colors, unsigned char brightness, unsigned char mode_value); + bool IsBluetooth(); + +private: + hid_device* dev; + std::string location; + bool is_bluetooth; +}; diff --git a/Controllers/SonyDS4Controller/SonyDS4ControllerDetect.cpp b/Controllers/SonyGamepadController/SonyGamepadControllerDetect.cpp similarity index 59% rename from Controllers/SonyDS4Controller/SonyDS4ControllerDetect.cpp rename to Controllers/SonyGamepadController/SonyGamepadControllerDetect.cpp index 1408d5d6..842a8125 100644 --- a/Controllers/SonyDS4Controller/SonyDS4ControllerDetect.cpp +++ b/Controllers/SonyGamepadController/SonyGamepadControllerDetect.cpp @@ -10,13 +10,15 @@ #include #include "RGBController_SonyDS4.h" +#include "RGBController_SonyDualSense.h" #include "Detector.h" -#define SONY_DUALSHOCK_VID 0x054C +#define SONY_VID 0x054C #define SONY_DS4_V1_PID 0x05C4 #define SONY_DS4_V2_PID 0x09CC #define SONY_DS4_RECEIVER_PID 0x0BA0 +#define SONY_DUALSENSE_PID 0x0CE6 void DetectSonyDS4Controllers(hid_device_info* info, const std::string&) { @@ -30,6 +32,19 @@ void DetectSonyDS4Controllers(hid_device_info* info, const std::string&) } } -REGISTER_HID_DETECTOR("Sony DualShock 4", DetectSonyDS4Controllers, SONY_DUALSHOCK_VID, SONY_DS4_V1_PID); -REGISTER_HID_DETECTOR("Sony DualShock 4", DetectSonyDS4Controllers, SONY_DUALSHOCK_VID, SONY_DS4_V2_PID); -REGISTER_HID_DETECTOR("Sony DualShock 4", DetectSonyDS4Controllers, SONY_DUALSHOCK_VID, SONY_DS4_RECEIVER_PID); +void DetectSonyDualSenseControllers(hid_device_info* info, const std::string&) +{ + hid_device* dev = hid_open_path(info->path); + if(dev) + { + SonyDualSenseController* controller = new SonyDualSenseController(dev, info->path); + RGBController_SonyDualSense* rgb_controller = new RGBController_SonyDualSense(controller); + // Constructor sets the name + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR("Sony DualShock 4", DetectSonyDS4Controllers, SONY_VID, SONY_DS4_V1_PID); +REGISTER_HID_DETECTOR("Sony DualShock 4", DetectSonyDS4Controllers, SONY_VID, SONY_DS4_V2_PID); +REGISTER_HID_DETECTOR("Sony DualShock 4", DetectSonyDS4Controllers, SONY_VID, SONY_DS4_RECEIVER_PID); +REGISTER_HID_DETECTOR("Sony DualSense" , DetectSonyDualSenseControllers, SONY_VID, SONY_DUALSENSE_PID); diff --git a/OpenRGB.pro b/OpenRGB.pro index 62e4729e..5eacb6de 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -153,7 +153,7 @@ INCLUDEPATH += Controllers/RoccatController/ \ Controllers/SapphireGPUController/ \ Controllers/SinowealthController/ \ - Controllers/SonyDS4Controller/ \ + Controllers/SonyGamepadController/ \ Controllers/SteelSeriesController/ \ Controllers/TecknetController/ \ Controllers/ThermaltakePoseidonZRGBController/ \ @@ -529,8 +529,11 @@ HEADERS += Controllers/SinowealthController/RGBController_Sinowealth1007.h \ Controllers/SinowealthController/RGBController_SinowealthKeyboard.h \ Controllers/SinowealthController/RGBController_SinowealthKeyboard16.h \ - Controllers/SonyDS4Controller/SonyDS4Controller.h \ - Controllers/SonyDS4Controller/RGBController_SonyDS4.h \ + Controllers/SonyGamepadController/SonyDualSenseController.h \ + Controllers/SonyGamepadController/SonyDualSenseControllerDetect.h \ + Controllers/SonyGamepadController/RGBController_SonyDualSense.h \ + Controllers/SonyGamepadController/SonyDS4Controller.h \ + Controllers/SonyGamepadController/RGBController_SonyDS4.h \ Controllers/SteelSeriesController/color32.h \ Controllers/SteelSeriesController/SteelSeriesAerox3Controller.h \ Controllers/SteelSeriesController/SteelSeriesApexBaseController.h \ @@ -1061,9 +1064,11 @@ SOURCES += Controllers/SinowealthController/RGBController_Sinowealth1007.cpp \ Controllers/SinowealthController/RGBController_SinowealthKeyboard.cpp \ Controllers/SinowealthController/RGBController_SinowealthKeyboard16.cpp \ - Controllers/SonyDS4Controller/SonyDS4Controller.cpp \ - Controllers/SonyDS4Controller/SonyDS4ControllerDetect.cpp \ - Controllers/SonyDS4Controller/RGBController_SonyDS4.cpp \ + Controllers/SonyGamepadController/SonyDualSenseController.cpp \ + Controllers/SonyGamepadController/RGBController_SonyDualSense.cpp \ + Controllers/SonyGamepadController/SonyDS4Controller.cpp \ + Controllers/SonyGamepadController/RGBController_SonyDS4.cpp \ + Controllers/SonyGamepadController/SonyGamepadControllerDetect.cpp \ Controllers/SteelSeriesController/SteelSeriesAerox3Controller.cpp \ Controllers/SteelSeriesController/SteelSeriesApexController.cpp \ Controllers/SteelSeriesController/SteelSeriesApexMController.cpp \ @@ -1304,7 +1309,7 @@ win32:SOURCES += Controllers/AsusTUFLaptopController/RGBController_AsusTUFLaptopWMI.cpp \ Controllers/ENESMBusController/XPGSpectrixS40GDetect_Windows.cpp \ Controllers/ENESMBusController/ENESMBusInterface/ENESMBusInterface_SpectrixS40G_Windows.cpp \ - Controllers/NVIDIAIlluminationController/nvapi_accessor.cpp \ + Controllers/NVIDIAIlluminationController/nvapi_accessor.cpp \ Controllers/NVIDIAIlluminationController/NVIDIAIlluminationV1Controller.cpp \ Controllers/NVIDIAIlluminationController/NVIDIAIlluminationControllerDetect.cpp \ Controllers/NVIDIAIlluminationController/RGBController_NVIDIAIllumination.cpp \ @@ -1326,7 +1331,7 @@ win32:HEADERS += AutoStart/AutoStart-Windows.h \ Controllers/AsusTUFLaptopController/RGBController_AsusTUFLaptopWMI.h \ Controllers/ENESMBusController/ENESMBusInterface/ENESMBusInterface_SpectrixS40G_Windows.h \ - Controllers/NVIDIAIlluminationController/nvapi_accessor.h \ + Controllers/NVIDIAIlluminationController/nvapi_accessor.h \ Controllers/NVIDIAIlluminationController/NVIDIAIlluminationV1Controller.h \ Controllers/NVIDIAIlluminationController/RGBController_NVIDIAIllumination.h \ Controllers/OpenRazerController/RGBController_OpenRazerWindows.h \