From ab9a7674bd850b592ea185520667313828f6e210 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Thu, 19 Aug 2021 18:17:10 -0500 Subject: [PATCH] Initial HyperX Pulsefire Haste support --- .../HyperXMouseControllerDetect.cpp | 29 +++- .../HyperXPulsefireHasteController.cpp | 111 ++++++++++++++ .../HyperXPulsefireHasteController.h | 46 ++++++ .../RGBController_HyperXPulsefireHaste.cpp | 139 ++++++++++++++++++ .../RGBController_HyperXPulsefireHaste.h | 40 +++++ OpenRGB.pro | 4 + 6 files changed, 365 insertions(+), 4 deletions(-) create mode 100644 Controllers/HyperXMouseController/HyperXPulsefireHasteController.cpp create mode 100644 Controllers/HyperXMouseController/HyperXPulsefireHasteController.h create mode 100644 Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.cpp create mode 100644 Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.h diff --git a/Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp b/Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp index 020f3858..d4fc1503 100644 --- a/Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp +++ b/Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp @@ -4,6 +4,7 @@ #include "HyperXPulsefireDartController.h" #include "RGBController.h" #include "RGBController_HyperXPulsefireFPSPro.h" +#include "RGBController_HyperXPulsefireHaste.h" #include "RGBController_HyperXPulsefireSurge.h" #include "RGBController_HyperXPulsefireDart.h" #include @@ -16,6 +17,7 @@ #define HYPERX_PULSEFIRE_FPS_PRO_PID 0x16D7 #define HYPERX_PULSEFIRE_DART_WIRELESS_PID 0x16E1 #define HYPERX_PULSEFIRE_DART_WIRED_PID 0x16E2 +#define HYPERX_PULSEFIRE_HASTE_PID 0x1727 void DetectHyperXPulsefireSurgeControllers(hid_device_info* info, const std::string& name) { @@ -41,6 +43,19 @@ void DetectHyperXPulsefireFPSProControllers(hid_device_info* info, const std::st } } /* DetectHyperXPulsefireFPSProControllers() */ +void DetectHyperXPulsefireHasteControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + if( dev ) + { + printf( "pulsefire haste usage %X, usage page %X\r\n", info->usage, info->usage_page); + HyperXPulsefireHasteController* controller = new HyperXPulsefireHasteController(dev, info->path); + RGBController_HyperXPulsefireHaste* rgb_controller = new RGBController_HyperXPulsefireHaste(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} /* DetectHyperXPulsefireFPSProControllers() */ + void DetectHyperXPulsefireDartControllers(hid_device_info* info, const std::string& name) { hid_device* dev = hid_open_path(info->path); @@ -53,7 +68,13 @@ void DetectHyperXPulsefireDartControllers(hid_device_info* info, const std::stri } } /* DetectHyperXPulsefireDartControllers() */ -REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Surge", DetectHyperXPulsefireSurgeControllers, HYPERX_VID, HYPERX_PULSEFIRE_SURGE_PID, 1, 0xFF01); -REGISTER_HID_DETECTOR_IP("HyperX Pulsefire FPS Pro", DetectHyperXPulsefireFPSProControllers, HYPERX_VID, HYPERX_PULSEFIRE_FPS_PRO_PID, 1, 0xFF01); -REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Dart (Wireless)", DetectHyperXPulsefireDartControllers, HYPERX_VID, HYPERX_PULSEFIRE_DART_WIRELESS_PID, 2, 0xFF00); -REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Dart (Wired)", DetectHyperXPulsefireDartControllers, HYPERX_VID, HYPERX_PULSEFIRE_DART_WIRED_PID, 1, 0xFF13); +REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Surge", DetectHyperXPulsefireSurgeControllers, HYPERX_VID, HYPERX_PULSEFIRE_SURGE_PID, 1, 0xFF01); +REGISTER_HID_DETECTOR_IP("HyperX Pulsefire FPS Pro", DetectHyperXPulsefireFPSProControllers, HYPERX_VID, HYPERX_PULSEFIRE_FPS_PRO_PID, 1, 0xFF01); +REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Dart (Wireless)", DetectHyperXPulsefireDartControllers, HYPERX_VID, HYPERX_PULSEFIRE_DART_WIRELESS_PID, 2, 0xFF00); +REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Dart (Wired)", DetectHyperXPulsefireDartControllers, HYPERX_VID, HYPERX_PULSEFIRE_DART_WIRED_PID, 1, 0xFF13); + +#ifdef _WIN32 +REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Haste", DetectHyperXPulsefireHasteControllers, HYPERX_VID, HYPERX_PULSEFIRE_HASTE_PID, 3, 0xFF90); +#else +REGISTER_HID_DETECTOR_PU("HyperX Pulsefire Haste", DetectHyperXPulsefireHasteControllers, HYPERX_VID, HYPERX_PULSEFIRE_HASTE_PID, 1, 2); +#endif \ No newline at end of file diff --git a/Controllers/HyperXMouseController/HyperXPulsefireHasteController.cpp b/Controllers/HyperXMouseController/HyperXPulsefireHasteController.cpp new file mode 100644 index 00000000..1539f968 --- /dev/null +++ b/Controllers/HyperXMouseController/HyperXPulsefireHasteController.cpp @@ -0,0 +1,111 @@ +/*-----------------------------------------*\ +| HyperXPulsefireHasteController.cpp | +| | +| Driver for HyperX Pulsefire Haste | +| lighting controller | +| | +| Adam Honse (CalcProgrammer1) 8/19/2021 | +\*-----------------------------------------*/ + +#include "HyperXPulsefireHasteController.h" + +#include + +HyperXPulsefireHasteController::HyperXPulsefireHasteController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +HyperXPulsefireHasteController::~HyperXPulsefireHasteController() +{ + hid_close(dev); +} + +std::string HyperXPulsefireHasteController::GetDeviceLocation() +{ + return("HID " + location); +} + +std::string HyperXPulsefireHasteController::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 HyperXPulsefireHasteController::SendDirect + ( + RGBColor* color_data + ) +{ + SendDirectSetup(); + SendDirectColor(color_data); +} + +/*-------------------------------------------------------------------------------------------------*\ +| Private packet sending functions. | +\*-------------------------------------------------------------------------------------------------*/ + +void HyperXPulsefireHasteController::SendDirectSetup() +{ + unsigned char buf[65]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(buf, 0x00, sizeof(buf)); + + /*-----------------------------------------------------*\ + | Set up Direct Mode Setup packet | + \*-----------------------------------------------------*/ + buf[0x00] = 0x00; + buf[0x01] = HYPERX_PULSEFIRE_HASTE_PACKET_ID_SETUP; + buf[0x02] = 0xF2; + + buf[0x08] = 0x02; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, buf, 65); +} + +void HyperXPulsefireHasteController::SendDirectColor + ( + RGBColor* color_data + ) +{ + unsigned char buf[65]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(buf, 0x00, sizeof(buf)); + + /*-----------------------------------------------------*\ + | Set up Direct Mode packet | + \*-----------------------------------------------------*/ + buf[0x00] = 0x00; + buf[0x01] = HYPERX_PULSEFIRE_HASTE_PACKET_ID_COLOR; + + buf[0x02] = RGBGetRValue(color_data[0]); + buf[0x03] = RGBGetGValue(color_data[0]); + buf[0x04] = RGBGetBValue(color_data[0]); + + buf[0x08] = 0x02; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, buf, 65); +} diff --git a/Controllers/HyperXMouseController/HyperXPulsefireHasteController.h b/Controllers/HyperXMouseController/HyperXPulsefireHasteController.h new file mode 100644 index 00000000..5c6992af --- /dev/null +++ b/Controllers/HyperXMouseController/HyperXPulsefireHasteController.h @@ -0,0 +1,46 @@ +/*-----------------------------------------*\ +| HyperXPulsefireHasteController.h | +| | +| Definitions and types for HyperX | +| Pulsefire FPS Pro lighting controller | +| | +| Adam Honse (CalcProgrammer1) 8/19/2021 | +\*-----------------------------------------*/ + +#include "RGBController.h" + +#include +#include + +#pragma once + +enum +{ + HYPERX_PULSEFIRE_HASTE_PACKET_ID_SETUP = 0x04, /* Direct setup packet */ + HYPERX_PULSEFIRE_HASTE_PACKET_ID_COLOR = 0x81, /* Direct color packet */ +}; + +class HyperXPulsefireHasteController +{ +public: + HyperXPulsefireHasteController(hid_device* dev_handle, const char* path); + ~HyperXPulsefireHasteController(); + + std::string GetDeviceLocation(); + std::string GetSerialString(); + + void SendDirect + ( + RGBColor* color_data + ); + +private: + hid_device* dev; + std::string location; + + void SendDirectSetup(); + void SendDirectColor + ( + RGBColor* color_data + ); +}; diff --git a/Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.cpp b/Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.cpp new file mode 100644 index 00000000..fbeab64e --- /dev/null +++ b/Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.cpp @@ -0,0 +1,139 @@ +/*-----------------------------------------*\ +| RGBController_HyperXPulsefireHaste.cpp | +| | +| Generic RGB Interface for HyperX | +| Pulsefire Haste | +| | +| Adam Honse (CalcProgrammer1) 8/19/2021 | +\*-----------------------------------------*/ + +#include "RGBController_HyperXPulsefireHaste.h" + +using namespace std::chrono_literals; + +RGBController_HyperXPulsefireHaste::RGBController_HyperXPulsefireHaste(HyperXPulsefireHasteController* hyperx_ptr) +{ + hyperx = hyperx_ptr; + + name = "HyperX Pulsefire Haste Device"; + vendor = "HyperX"; + type = DEVICE_TYPE_MOUSE; + description = "HyperX Pulsefire Haste Device"; + location = hyperx->GetDeviceLocation(); + serial = hyperx->GetSerialString(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = 0xFFFF; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + SetupZones(); + + /*-----------------------------------------------------*\ + | The Corsair Lighting Node Pro requires a packet within| + | 20 seconds of sending the lighting change in order | + | to not revert back into rainbow mode. Start a thread | + | to continuously send a keepalive packet every 5s | + \*-----------------------------------------------------*/ + keepalive_thread_run = 1; + keepalive_thread = new std::thread(&RGBController_HyperXPulsefireHaste::KeepaliveThread, this); +}; + +RGBController_HyperXPulsefireHaste::~RGBController_HyperXPulsefireHaste() +{ + keepalive_thread_run = 0; + keepalive_thread->join(); + delete keepalive_thread; + + delete hyperx; +} + +void RGBController_HyperXPulsefireHaste::SetupZones() +{ + zone logo; + logo.name = "Logo"; + logo.type = ZONE_TYPE_SINGLE; + logo.leds_min = 1; + logo.leds_max = 1; + logo.leds_count = 1; + logo.matrix_map = NULL; + zones.push_back(logo); + + for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + for(unsigned int led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++) + { + led new_led; + + new_led.name = zones[zone_idx].name; + + if(zones[zone_idx].leds_count > 1) + { + new_led.name.append(" LED "); + new_led.name.append(std::to_string(led_idx + 1)); + } + + leds.push_back(new_led); + } + } + + SetupColors(); +} + +void RGBController_HyperXPulsefireHaste::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_HyperXPulsefireHaste::DeviceUpdateLEDs() +{ + last_update_time = std::chrono::steady_clock::now(); + + if(active_mode == 0) + { + hyperx->SendDirect(&colors[0]); + } + else + { + } + +} + +void RGBController_HyperXPulsefireHaste::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXPulsefireHaste::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXPulsefireHaste::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_HyperXPulsefireHaste::DeviceUpdateMode() +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXPulsefireHaste::KeepaliveThread() +{ + while(keepalive_thread_run.load()) + { + if(active_mode == 0) + { + if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50)) + { + UpdateLEDs(); + } + } + std::this_thread::sleep_for(10ms); + } +} diff --git a/Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.h b/Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.h new file mode 100644 index 00000000..2c6fe0ee --- /dev/null +++ b/Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.h @@ -0,0 +1,40 @@ +/*-----------------------------------------*\ +| RGBController_HyperXPulsefireHaste.h | +| | +| Generic RGB Interface for HyperX | +| Pulsefire Haste | +| | +| Adam Honse (CalcProgrammer1) 8/19/2021 | +\*-----------------------------------------*/ + +#pragma once +#include + +#include "RGBController.h" +#include "HyperXPulsefireHasteController.h" + +class RGBController_HyperXPulsefireHaste : public RGBController +{ +public: + RGBController_HyperXPulsefireHaste(HyperXPulsefireHasteController* hyperx_ptr); + ~RGBController_HyperXPulsefireHaste(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + + void KeepaliveThread(); + +private: + HyperXPulsefireHasteController* hyperx; + std::thread* keepalive_thread; + std::atomic keepalive_thread_run; + std::chrono::time_point last_update_time; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 7b967491..d7e101f1 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -304,9 +304,11 @@ HEADERS += Controllers/HyperXKeyboardController/RGBController_HyperXAlloyOriginsCore.h \ Controllers/HyperXKeyboardController/RGBController_HyperXKeyboard.h \ Controllers/HyperXMouseController/HyperXPulsefireFPSProController.h \ + Controllers/HyperXMouseController/HyperXPulsefireHasteController.h \ Controllers/HyperXMouseController/HyperXPulsefireSurgeController.h \ Controllers/HyperXMouseController/HyperXPulsefireDartController.h \ Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.h \ + Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.h \ Controllers/HyperXMouseController/RGBController_HyperXPulsefireSurge.h \ Controllers/HyperXMouseController/RGBController_HyperXPulsefireDart.h \ Controllers/HyperXMousematController/HyperXMousematController.h \ @@ -660,9 +662,11 @@ SOURCES += Controllers/HyperXKeyboardController/RGBController_HyperXKeyboard.cpp \ Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp \ Controllers/HyperXMouseController/HyperXPulsefireFPSProController.cpp \ + Controllers/HyperXMouseController/HyperXPulsefireHasteController.cpp \ Controllers/HyperXMouseController/HyperXPulsefireSurgeController.cpp \ Controllers/HyperXMouseController/HyperXPulsefireDartController.cpp \ Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.cpp \ + Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.cpp \ Controllers/HyperXMouseController/RGBController_HyperXPulsefireSurge.cpp \ Controllers/HyperXMouseController/RGBController_HyperXPulsefireDart.cpp \ Controllers/HyperXMousematController/HyperXMousematController.cpp \