From 97ffc769f57be82e1bbf100aca6dfaf58eef1f22 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Mon, 16 Jan 2023 18:59:50 -0600 Subject: [PATCH] Initial commit for HyperX Quadcast S --- .../HyperXMicrophoneController.cpp | 98 ++++++++++++ .../HyperXMicrophoneController.h | 34 +++++ .../HyperXMicrophoneControllerDetect.cpp | 37 +++++ .../RGBController_HyperXMicrophone.cpp | 144 ++++++++++++++++++ .../RGBController_HyperXMicrophone.h | 39 +++++ OpenRGB.pro | 6 + 6 files changed, 358 insertions(+) create mode 100644 Controllers/HyperXMicrophoneController/HyperXMicrophoneController.cpp create mode 100644 Controllers/HyperXMicrophoneController/HyperXMicrophoneController.h create mode 100644 Controllers/HyperXMicrophoneController/HyperXMicrophoneControllerDetect.cpp create mode 100644 Controllers/HyperXMicrophoneController/RGBController_HyperXMicrophone.cpp create mode 100644 Controllers/HyperXMicrophoneController/RGBController_HyperXMicrophone.h diff --git a/Controllers/HyperXMicrophoneController/HyperXMicrophoneController.cpp b/Controllers/HyperXMicrophoneController/HyperXMicrophoneController.cpp new file mode 100644 index 000000000..55f0bacf5 --- /dev/null +++ b/Controllers/HyperXMicrophoneController/HyperXMicrophoneController.cpp @@ -0,0 +1,98 @@ +/*-----------------------------------------*\ +| HyperXMicrophoneController.cpp | +| | +| Driver for HyperX Microphone lighting | +| controller | +| | +| Adam Honse (CalcProgrammer1) 10/25/2020 | +\*-----------------------------------------*/ + +#include "HyperXMicrophoneController.h" + +#include + +HyperXMicrophoneController::HyperXMicrophoneController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +HyperXMicrophoneController::~HyperXMicrophoneController() +{ + hid_close(dev); +} + +std::string HyperXMicrophoneController::GetDeviceLocation() +{ + return("HID " + location); +} + +std::string HyperXMicrophoneController::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); +} + +/*-------------------------------------------------------------------------------------------------*\ +| Private packet sending functions. | +\*-------------------------------------------------------------------------------------------------*/ + +void HyperXMicrophoneController::SendDirect + ( + RGBColor* color_data + ) +{ + unsigned char buf[65]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(buf, 0x00, sizeof(buf)); + + /*-----------------------------------------------------*\ + | Set up Direct packet | + \*-----------------------------------------------------*/ + buf[0x00] = 0x00; + buf[0x01] = 0x04; + buf[0x02] = 0xF2; + + buf[0x09] = 0x01; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, buf, 65); + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(buf, 0x00, sizeof(buf)); + + /*-----------------------------------------------------*\ + | Set up Direct packet | + \*-----------------------------------------------------*/ + buf[0x00] = 0x00; + + for(int i = 0; i < 2; i++) + { + buf[(i * 4) + 1] = 0x81; + buf[(i * 4) + 2] = RGBGetRValue(color_data[i]); + buf[(i * 4) + 3] = RGBGetGValue(color_data[i]); + buf[(i * 4) + 4] = RGBGetBValue(color_data[i]); + } + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, buf, 65); +} diff --git a/Controllers/HyperXMicrophoneController/HyperXMicrophoneController.h b/Controllers/HyperXMicrophoneController/HyperXMicrophoneController.h new file mode 100644 index 000000000..6c6b58b6e --- /dev/null +++ b/Controllers/HyperXMicrophoneController/HyperXMicrophoneController.h @@ -0,0 +1,34 @@ +/*-----------------------------------------*\ +| HyperXMicrophoneController.h | +| | +| Definitions and types for HyperX | +| microphone lighting controller | +| | +| Adam Honse (CalcProgrammer1) 1/16/2023 | +\*-----------------------------------------*/ + +#include "RGBController.h" + +#include +#include + +#pragma once + +class HyperXMicrophoneController +{ +public: + HyperXMicrophoneController(hid_device* dev_handle, const char* path); + ~HyperXMicrophoneController(); + + std::string GetDeviceLocation(); + std::string GetSerialString(); + + void SendDirect + ( + RGBColor* color_data + ); + +private: + hid_device* dev; + std::string location; +}; diff --git a/Controllers/HyperXMicrophoneController/HyperXMicrophoneControllerDetect.cpp b/Controllers/HyperXMicrophoneController/HyperXMicrophoneControllerDetect.cpp new file mode 100644 index 000000000..ceb8f072a --- /dev/null +++ b/Controllers/HyperXMicrophoneController/HyperXMicrophoneControllerDetect.cpp @@ -0,0 +1,37 @@ +#include "Detector.h" +#include "HyperXMicrophoneController.h" +#include "RGBController.h" +#include "RGBController_HyperXMicrophone.h" +#include +#include + +/*-----------------------------------------------------*\ +| HyperX microphone vendor IDs | +\*-----------------------------------------------------*/ +#define HYPERX_VID_2 0x03F0 +#define HYPERX_QUADCAST_S_PID 0x0294 +#define HYPERX_QUADCAST_S_PID2 0x068C + +/******************************************************************************************\ +* * +* DetectHyperXMicrophoneControllers * +* * +* Tests the USB address to see if a HyperX Microphone controller exists there. * +* * +\******************************************************************************************/ + +void DetectHyperXMicrophoneControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + HyperXMicrophoneController* controller = new HyperXMicrophoneController(dev, info->path); + RGBController_HyperXMicrophone* rgb_controller = new RGBController_HyperXMicrophone(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} /* DetectHyperXMicrophoneControllers() */ + +REGISTER_HID_DETECTOR("HyperX Quadcast S", DetectHyperXMicrophoneControllers, HYPERX_VID_2, HYPERX_QUADCAST_S_PID); diff --git a/Controllers/HyperXMicrophoneController/RGBController_HyperXMicrophone.cpp b/Controllers/HyperXMicrophoneController/RGBController_HyperXMicrophone.cpp new file mode 100644 index 000000000..705a259b4 --- /dev/null +++ b/Controllers/HyperXMicrophoneController/RGBController_HyperXMicrophone.cpp @@ -0,0 +1,144 @@ +/*-----------------------------------------*\ +| RGBController_HyperXMicrophone.cpp | +| | +| Generic RGB Interface for HyperX | +| microphone | +| | +| Adam Honse (CalcProgrammer1) 1/16/2023 | +\*-----------------------------------------*/ + +#include "RGBController_HyperXMicrophone.h" + +using namespace std::chrono_literals; + +/**------------------------------------------------------------------*\ + @name HyperX Microphone + @category Microphone + @type USB + @save :x: + @direct :white_check_mark: + @effects :x: + @detectors DetectHyperXMicrophoneControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_HyperXMicrophone::RGBController_HyperXMicrophone(HyperXMicrophoneController* controller_ptr) +{ + controller = controller_ptr; + + name = "HyperX Microphone Device"; + vendor = "HyperX"; + type = DEVICE_TYPE_MICROPHONE; + description = "HyperX Microphone Device"; + location = controller->GetDeviceLocation(); + serial = controller->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_HyperXMicrophone::KeepaliveThread, this); +}; + +RGBController_HyperXMicrophone::~RGBController_HyperXMicrophone() +{ + keepalive_thread_run = 0; + keepalive_thread->join(); + delete keepalive_thread; + + delete controller; +} + +void RGBController_HyperXMicrophone::SetupZones() +{ + zone microphone; + microphone.name = "Microphone"; + microphone.type = ZONE_TYPE_SINGLE; + microphone.leds_min = 2; + microphone.leds_max = 2; + microphone.leds_count = 2; + microphone.matrix_map = NULL; + zones.push_back(microphone); + + 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_HyperXMicrophone::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_HyperXMicrophone::DeviceUpdateLEDs() +{ + last_update_time = std::chrono::steady_clock::now(); + + if(active_mode == 0) + { + controller->SendDirect(&colors[0]); + } + else + { + } +} + +void RGBController_HyperXMicrophone::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXMicrophone::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXMicrophone::DeviceUpdateMode() +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXMicrophone::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/HyperXMicrophoneController/RGBController_HyperXMicrophone.h b/Controllers/HyperXMicrophoneController/RGBController_HyperXMicrophone.h new file mode 100644 index 000000000..fd9d5bd5b --- /dev/null +++ b/Controllers/HyperXMicrophoneController/RGBController_HyperXMicrophone.h @@ -0,0 +1,39 @@ +/*-----------------------------------------*\ +| RGBController_HyperXMicrophone.h | +| | +| Generic RGB Interface for HyperX | +| microphone | +| | +| Adam Honse (CalcProgrammer1) 1/16/2023 | +\*-----------------------------------------*/ + +#pragma once +#include + +#include "RGBController.h" +#include "HyperXMicrophoneController.h" + +class RGBController_HyperXMicrophone : public RGBController +{ +public: + RGBController_HyperXMicrophone(HyperXMicrophoneController* controller_ptr); + ~RGBController_HyperXMicrophone(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + + void KeepaliveThread(); + +private: + HyperXMicrophoneController* controller; + 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 c16a30045..014c63081 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -129,6 +129,7 @@ INCLUDEPATH += Controllers/HPOmen30LController/ \ Controllers/HyperXDRAMController/ \ Controllers/HyperXKeyboardController/ \ + Controllers/HyperXMicrophoneController/ \ Controllers/HyperXMouseController/ \ Controllers/HyperXMousematController/ \ Controllers/IntelArcA770LEController/ \ @@ -445,6 +446,8 @@ HEADERS += Controllers/HyperXKeyboardController/RGBController_HyperXAlloyOrigins.h \ Controllers/HyperXKeyboardController/RGBController_HyperXAlloyOrigins60.h \ Controllers/HyperXKeyboardController/RGBController_HyperXAlloyOriginsCore.h \ + Controllers/HyperXMicrophoneController/HyperXMicrophoneController.h \ + Controllers/HyperXMicrophoneController/RGBController_HyperXMicrophone.h \ Controllers/HyperXMouseController/HyperXPulsefireFPSProController.h \ Controllers/HyperXMouseController/HyperXPulsefireHasteController.h \ Controllers/HyperXMouseController/HyperXPulsefireSurgeController.h \ @@ -1027,6 +1030,9 @@ SOURCES += Controllers/HyperXKeyboardController/RGBController_HyperXAlloyOrigins.cpp \ Controllers/HyperXKeyboardController/RGBController_HyperXAlloyOrigins60.cpp \ Controllers/HyperXKeyboardController/RGBController_HyperXAlloyOriginsCore.cpp \ + Controllers/HyperXMicrophoneController/HyperXMicrophoneController.cpp \ + Controllers/HyperXMicrophoneController/HyperXMicrophoneControllerDetect.cpp \ + Controllers/HyperXMicrophoneController/RGBController_HyperXMicrophone.cpp \ Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp \ Controllers/HyperXMouseController/HyperXPulsefireFPSProController.cpp \ Controllers/HyperXMouseController/HyperXPulsefireHasteController.cpp \