From 6c3baf477c02e4c93268ef6c75a770828ba230e3 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Sat, 26 Dec 2020 03:05:46 -0600 Subject: [PATCH] Add controller for HyperX Pulsefire FPS Pro mouse (new NGenuity firmware) --- .../HyperXMouseControllerDetect.cpp | 26 +++- .../HyperXPulsefireFPSProController.cpp | 73 ++++++++++ .../HyperXPulsefireFPSProController.h | 39 +++++ .../RGBController_HyperXPulsefireFPSPro.cpp | 137 ++++++++++++++++++ .../RGBController_HyperXPulsefireFPSPro.h | 40 +++++ OpenRGB.pro | 4 + 6 files changed, 314 insertions(+), 5 deletions(-) create mode 100644 Controllers/HyperXMouseController/HyperXPulsefireFPSProController.cpp create mode 100644 Controllers/HyperXMouseController/HyperXPulsefireFPSProController.h create mode 100644 Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.cpp create mode 100644 Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.h diff --git a/Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp b/Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp index f975cb71..aa87bc81 100644 --- a/Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp +++ b/Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp @@ -1,16 +1,19 @@ #include "Detector.h" +#include "HyperXPulsefireFPSProController.h" #include "HyperXPulsefireSurgeController.h" #include "RGBController.h" +#include "RGBController_HyperXPulsefireFPSPro.h" #include "RGBController_HyperXPulsefireSurge.h" #include /*-----------------------------------------------------*\ | HyperX mouse vendor IDs | \*-----------------------------------------------------*/ -#define HYPERX_VID 0x0951 -#define HYPERX_PULSEFIRE_SURGE_PID 0x16D3 +#define HYPERX_VID 0x0951 +#define HYPERX_PULSEFIRE_SURGE_PID 0x16D3 +#define HYPERX_PULSEFIRE_FPS_PRO_PID 0x16D7 -void DetectHyperXMouseControllers(hid_device_info* info, const std::string& name) +void DetectHyperXPulsefireSurgeControllers(hid_device_info* info, const std::string& name) { hid_device* dev = hid_open_path(info->path); if( dev ) @@ -20,6 +23,19 @@ void DetectHyperXMouseControllers(hid_device_info* info, const std::string& name rgb_controller->name = name; ResourceManager::get()->RegisterRGBController(rgb_controller); } -} /* DetectHyperXMouseControllers() */ +} /* DetectHyperXPulsefireSurgeControllers() */ -REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Surge", DetectHyperXMouseControllers, HYPERX_VID, HYPERX_PULSEFIRE_SURGE_PID, 1, 0xFF01); +void DetectHyperXPulsefireFPSProControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + if( dev ) + { + HyperXPulsefireFPSProController* controller = new HyperXPulsefireFPSProController(dev, info->path); + RGBController_HyperXPulsefireFPSPro* rgb_controller = new RGBController_HyperXPulsefireFPSPro(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} /* DetectHyperXPulsefireFPSProControllers() */ + +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); diff --git a/Controllers/HyperXMouseController/HyperXPulsefireFPSProController.cpp b/Controllers/HyperXMouseController/HyperXPulsefireFPSProController.cpp new file mode 100644 index 00000000..0244596d --- /dev/null +++ b/Controllers/HyperXMouseController/HyperXPulsefireFPSProController.cpp @@ -0,0 +1,73 @@ +/*-----------------------------------------*\ +| HyperXPulsefireFPSProController.cpp | +| | +| Driver for HyperX Pulsefire FPS Pro | +| lighting controller | +| | +| Adam Honse (CalcProgrammer1) 12/26/2020 | +\*-----------------------------------------*/ + +#include "HyperXPulsefireFPSProController.h" + +#include + +HyperXPulsefireFPSProController::HyperXPulsefireFPSProController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +HyperXPulsefireFPSProController::~HyperXPulsefireFPSProController() +{ + +} + +std::string HyperXPulsefireFPSProController::GetDeviceLocation() +{ + return("HID " + location); +} + +std::string HyperXPulsefireFPSProController::GetSerialString() +{ + wchar_t serial_string[128]; + hid_get_serial_number_string(dev, serial_string, 128); + + std::wstring return_wstring = serial_string; + std::string return_string(return_wstring.begin(), return_wstring.end()); + + return(return_string); +} + +/*-------------------------------------------------------------------------------------------------*\ +| Private packet sending functions. | +\*-------------------------------------------------------------------------------------------------*/ + +void HyperXPulsefireFPSProController::SendDirect + ( + RGBColor* color_data + ) +{ + unsigned char buf[264]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(buf, 0x00, sizeof(buf)); + + /*-----------------------------------------------------*\ + | Set up Direct Mode packet | + \*-----------------------------------------------------*/ + buf[0x00] = 0x07; + buf[0x01] = HYPERX_PULSEFIRE_FPS_PRO_PACKET_ID_DIRECT; + + buf[0x02] = RGBGetRValue(color_data[0]); + buf[0x03] = RGBGetGValue(color_data[0]); + buf[0x04] = RGBGetBValue(color_data[0]); + + buf[0x08] = 0xA0; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, buf, 264); +} diff --git a/Controllers/HyperXMouseController/HyperXPulsefireFPSProController.h b/Controllers/HyperXMouseController/HyperXPulsefireFPSProController.h new file mode 100644 index 00000000..5b7ee6ca --- /dev/null +++ b/Controllers/HyperXMouseController/HyperXPulsefireFPSProController.h @@ -0,0 +1,39 @@ +/*-----------------------------------------*\ +| HyperXPulsefireFPSProController.h | +| | +| Definitions and types for HyperX | +| Pulsefire FPS Pro lighting controller | +| | +| Adam Honse (CalcProgrammer1) 12/26/2020 | +\*-----------------------------------------*/ + +#include "RGBController.h" + +#include +#include + +#pragma once + +enum +{ + HYPERX_PULSEFIRE_FPS_PRO_PACKET_ID_DIRECT = 0x0A, /* Direct control packet */ +}; + +class HyperXPulsefireFPSProController +{ +public: + HyperXPulsefireFPSProController(hid_device* dev_handle, const char* path); + ~HyperXPulsefireFPSProController(); + + std::string GetDeviceLocation(); + std::string GetSerialString(); + + void SendDirect + ( + RGBColor* color_data + ); + +private: + hid_device* dev; + std::string location; +}; diff --git a/Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.cpp b/Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.cpp new file mode 100644 index 00000000..13049d81 --- /dev/null +++ b/Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.cpp @@ -0,0 +1,137 @@ +/*-----------------------------------------*\ +| RGBController_HyperXPulsefireFPSPro.cpp | +| | +| Generic RGB Interface for HyperX | +| Pulsefire Surge | +| | +| Adam Honse (CalcProgrammer1) 2/2/2020 | +\*-----------------------------------------*/ + +#include "RGBController_HyperXPulsefireFPSPro.h" + +using namespace std::chrono_literals; + +RGBController_HyperXPulsefireFPSPro::RGBController_HyperXPulsefireFPSPro(HyperXPulsefireFPSProController* hyperx_ptr) +{ + hyperx = hyperx_ptr; + + name = "HyperX Pulsefire FPS Pro Device"; + vendor = "HyperX"; + type = DEVICE_TYPE_MOUSE; + description = "HyperX Pulsefire FPS Pro 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_HyperXPulsefireFPSPro::KeepaliveThread, this); +}; + +RGBController_HyperXPulsefireFPSPro::~RGBController_HyperXPulsefireFPSPro() +{ + keepalive_thread_run = 0; + keepalive_thread->join(); + delete keepalive_thread; +} + +void RGBController_HyperXPulsefireFPSPro::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_HyperXPulsefireFPSPro::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_HyperXPulsefireFPSPro::DeviceUpdateLEDs() +{ + last_update_time = std::chrono::steady_clock::now(); + + if(active_mode == 0) + { + hyperx->SendDirect(&colors[0]); + } + else + { + } + +} + +void RGBController_HyperXPulsefireFPSPro::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXPulsefireFPSPro::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXPulsefireFPSPro::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_HyperXPulsefireFPSPro::DeviceUpdateMode() +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXPulsefireFPSPro::KeepaliveThread() +{ + while(keepalive_thread_run.load()) + { + if(active_mode == 0) + { + if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50)) + { + DeviceUpdateLEDs(); + } + } + std::this_thread::sleep_for(10ms); + } +} diff --git a/Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.h b/Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.h new file mode 100644 index 00000000..ad4ca864 --- /dev/null +++ b/Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.h @@ -0,0 +1,40 @@ +/*-----------------------------------------*\ +| RGBController_HyperXPulsefireFPSPro.h | +| | +| Generic RGB Interface for HyperX | +| Pulsefire FPS Pro | +| | +| Adam Honse (CalcProgrammer1) 12/26/2020 | +\*-----------------------------------------*/ + +#pragma once +#include + +#include "RGBController.h" +#include "HyperXPulsefireFPSProController.h" + +class RGBController_HyperXPulsefireFPSPro : public RGBController +{ +public: + RGBController_HyperXPulsefireFPSPro(HyperXPulsefireFPSProController* hyperx_ptr); + ~RGBController_HyperXPulsefireFPSPro(); + + 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: + HyperXPulsefireFPSProController* 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 6295344a..ff2d656a 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -205,7 +205,9 @@ HEADERS += Controllers/HyperXKeyboardController/HyperXKeyboardController.h \ Controllers/HyperXKeyboardController/RGBController_HyperXAlloyOrigins.h \ Controllers/HyperXKeyboardController/RGBController_HyperXKeyboard.h \ + Controllers/HyperXMouseController/HyperXPulsefireFPSProController.h \ Controllers/HyperXMouseController/HyperXPulsefireSurgeController.h \ + Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.h \ Controllers/HyperXMouseController/RGBController_HyperXPulsefireSurge.h \ Controllers/HyperXMousematController/HyperXMousematController.h \ Controllers/HyperXMousematController/RGBController_HyperXMousemat.h \ @@ -410,7 +412,9 @@ SOURCES += Controllers/HyperXKeyboardController/RGBController_HyperXAlloyOrigins.cpp \ Controllers/HyperXKeyboardController/RGBController_HyperXKeyboard.cpp \ Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp \ + Controllers/HyperXMouseController/HyperXPulsefireFPSProController.cpp \ Controllers/HyperXMouseController/HyperXPulsefireSurgeController.cpp \ + Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.cpp \ Controllers/HyperXMouseController/RGBController_HyperXPulsefireSurge.cpp \ Controllers/HyperXMousematController/HyperXMousematController.cpp \ Controllers/HyperXMousematController/HyperXMousematControllerDetect.cpp \