diff --git a/Controllers/HyperXMousematController/HyperXMousematController.cpp b/Controllers/HyperXMousematController/HyperXMousematController.cpp new file mode 100644 index 00000000..b97273b6 --- /dev/null +++ b/Controllers/HyperXMousematController/HyperXMousematController.cpp @@ -0,0 +1,102 @@ +/*-----------------------------------------*\ +| HyperXMousematController.cpp | +| | +| Driver for HyperX Mousemat lighting | +| controller | +| | +| Adam Honse (CalcProgrammer1) 10/25/2020 | +\*-----------------------------------------*/ + +#include "HyperXMousematController.h" + +#include + +HyperXMousematController::HyperXMousematController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +HyperXMousematController::~HyperXMousematController() +{ + +} + +std::string HyperXMousematController::GetDeviceLocation() +{ + return(location); +} + +/*-------------------------------------------------------------------------------------------------*\ +| Private packet sending functions. | +\*-------------------------------------------------------------------------------------------------*/ + +void HyperXMousematController::SendDirect + ( + RGBColor* color_data + ) +{ + unsigned char buf[65]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(buf, 0x00, sizeof(buf)); + + /*-----------------------------------------------------*\ + | Set up Select Profile packet | + \*-----------------------------------------------------*/ + buf[0x00] = 0x00; + buf[0x01] = 0x04; + buf[0x02] = 0xF2; + + buf[0x09] = 0x02; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, buf, 65); + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(buf, 0x00, sizeof(buf)); + + /*-----------------------------------------------------*\ + | Set up Select Profile packet | + \*-----------------------------------------------------*/ + buf[0x00] = 0x00; + + for(int i = 0; i < 16; 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); + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(buf, 0x00, sizeof(buf)); + + /*-----------------------------------------------------*\ + | Set up Select Profile packet | + \*-----------------------------------------------------*/ + buf[0x00] = 0x00; + + for(int i = 0; i < 16; i++) + { + buf[(i * 4) + 1] = 0x81; + buf[(i * 4) + 2] = RGBGetRValue(color_data[16 + i]); + buf[(i * 4) + 3] = RGBGetGValue(color_data[16 + i]); + buf[(i * 4) + 4] = RGBGetBValue(color_data[16 + i]); + } + + hid_send_feature_report(dev, buf, 65); +} diff --git a/Controllers/HyperXMousematController/HyperXMousematController.h b/Controllers/HyperXMousematController/HyperXMousematController.h new file mode 100644 index 00000000..4048a162 --- /dev/null +++ b/Controllers/HyperXMousematController/HyperXMousematController.h @@ -0,0 +1,33 @@ +/*-----------------------------------------*\ +| HyperXMousematController.h | +| | +| Definitions and types for HyperX | +| mousemat lighting controller | +| | +| Adam Honse (CalcProgrammer1) 10/25/2020 | +\*-----------------------------------------*/ + +#include "RGBController.h" + +#include +#include + +#pragma once + +class HyperXMousematController +{ +public: + HyperXMousematController(hid_device* dev_handle, const char* path); + ~HyperXMousematController(); + + std::string GetDeviceLocation(); + + void SendDirect + ( + RGBColor* color_data + ); + +private: + hid_device* dev; + std::string location; +}; diff --git a/Controllers/HyperXMousematController/HyperXMousematControllerDetect.cpp b/Controllers/HyperXMousematController/HyperXMousematControllerDetect.cpp new file mode 100644 index 00000000..371447fd --- /dev/null +++ b/Controllers/HyperXMousematController/HyperXMousematControllerDetect.cpp @@ -0,0 +1,79 @@ +#include "Detector.h" +#include "HyperXMousematController.h" +#include "RGBController.h" +#include "RGBController_HyperXMousemat.h" +#include +#include + +/*-----------------------------------------------------*\ +| HyperX mousemat vendor IDs | +\*-----------------------------------------------------*/ +#define HYPERX_VID 0x0951 +#define HYPERX_FURY_ULTRA_PID 0x1705 + +typedef struct +{ + unsigned short usb_vid; + unsigned short usb_pid; + unsigned char usb_interface; + const char * name; +} hyperx_device; + +#define HYPERX_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ])) + +static const hyperx_device device_list[] = +{ + /*-----------------------------------------------------------------------------------------------------*\ + | Mousemats | + \*-----------------------------------------------------------------------------------------------------*/ + { HYPERX_VID, HYPERX_FURY_ULTRA_PID, 0, "HyperX Fury Ultra" }, +}; + +/******************************************************************************************\ +* * +* DetectHyperXMousematControllers * +* * +* Tests the USB address to see if a HyperX Mousemat controller exists there. * +* * +\******************************************************************************************/ + +void DetectHyperXMousematControllers(std::vector& rgb_controllers) +{ + hid_device_info* info; + hid_device* dev = NULL; + + hid_init(); + + for(std::size_t device_idx = 0; device_idx < HYPERX_NUM_DEVICES; device_idx++) + { + dev = NULL; + + info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid); + + //Look for HyperX RGB Peripheral + while(info) + { + if((info->vendor_id == device_list[device_idx].usb_vid) + &&(info->product_id == device_list[device_idx].usb_pid) + &&(info->interface_number == device_list[device_idx].usb_interface)) + { + dev = hid_open_path(info->path); + + if( dev ) + { + HyperXMousematController* controller = new HyperXMousematController(dev, info->path); + + RGBController_HyperXMousemat* rgb_controller = new RGBController_HyperXMousemat(controller); + + rgb_controller->name = device_list[device_idx].name; + + rgb_controllers.push_back(rgb_controller); + } + } + + info = info->next; + } + } +} /* DetectHyperXMousematControllers() */ + +REGISTER_DETECTOR("HyperX Mousemat", DetectHyperXMousematControllers); diff --git a/Controllers/HyperXMousematController/RGBController_HyperXMousemat.cpp b/Controllers/HyperXMousematController/RGBController_HyperXMousemat.cpp new file mode 100644 index 00000000..ef8fb85c --- /dev/null +++ b/Controllers/HyperXMousematController/RGBController_HyperXMousemat.cpp @@ -0,0 +1,170 @@ +/*-----------------------------------------*\ +| RGBController_HyperXMousemat.cpp | +| | +| Generic RGB Interface for HyperX | +| mousemat | +| | +| Adam Honse (CalcProgrammer1) 10/25/2020 | +\*-----------------------------------------*/ + +#include "RGBController_HyperXMousemat.h" + +//Include thread libraries for Windows or Linux +#ifdef WIN32 +#include +#else +#include "pthread.h" +#include "unistd.h" +#endif + +//Thread functions have different types in Windows and Linux +#ifdef WIN32 +#define THREAD static void +#define THREADRETURN +#else +#define THREAD static void* +#define THREADRETURN return(NULL); +#endif + +using namespace std::chrono_literals; + +THREAD keepalive_thread(void *param) +{ + RGBController_HyperXMousemat* controller = static_cast(param); + controller->KeepaliveThread(); + THREADRETURN +} + +RGBController_HyperXMousemat::RGBController_HyperXMousemat(HyperXMousematController* hyperx_ptr) +{ + hyperx = hyperx_ptr; + + name = "HyperX Mousemat Device"; + type = DEVICE_TYPE_MOUSEMAT; + description = "HyperX Mousemat Device"; + location = hyperx->GetDeviceLocation(); + + 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 | + \*-----------------------------------------------------*/ +#ifdef WIN32 + _beginthread(keepalive_thread, 0, this); +#else + pthread_t thread; + pthread_create(&thread, NULL, &keepalive_thread, this); +#endif +}; + +RGBController_HyperXMousemat::~RGBController_HyperXMousemat() +{ + +} + +void RGBController_HyperXMousemat::SetupZones() +{ + zone led_strip; + led_strip.name = "LED Strip"; + led_strip.type = ZONE_TYPE_LINEAR; + led_strip.leds_min = 32; + led_strip.leds_max = 32; + led_strip.leds_count = 32; + led_strip.matrix_map = NULL; + zones.push_back(led_strip); + + 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_HyperXMousemat::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_HyperXMousemat::DeviceUpdateLEDs() +{ + last_update_time = std::chrono::steady_clock::now(); + + if(active_mode == 0) + { + hyperx->SendDirect(&colors[0]); + } + else + { + } + +} + +void RGBController_HyperXMousemat::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXMousemat::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXMousemat::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_HyperXMousemat::DeviceUpdateMode() +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXMousemat::KeepaliveThread() +{ + while(1) + { + 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/HyperXMousematController/RGBController_HyperXMousemat.h b/Controllers/HyperXMousematController/RGBController_HyperXMousemat.h new file mode 100644 index 00000000..b8204532 --- /dev/null +++ b/Controllers/HyperXMousematController/RGBController_HyperXMousemat.h @@ -0,0 +1,39 @@ +/*-----------------------------------------*\ +| RGBController_HyperXMousemat.h | +| | +| Generic RGB Interface for HyperX | +| mousemat | +| | +| Adam Honse (CalcProgrammer1) 10/25/2020 | +\*-----------------------------------------*/ + +#pragma once +#include + +#include "RGBController.h" +#include "HyperXMousematController.h" + +class RGBController_HyperXMousemat : public RGBController +{ +public: + RGBController_HyperXMousemat(HyperXMousematController* hyperx_ptr); + ~RGBController_HyperXMousemat(); + + 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: + HyperXMousematController* hyperx; + + std::chrono::time_point last_update_time; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 33c12c33..99e7eb89 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -75,6 +75,7 @@ INCLUDEPATH += Controllers/HyperXDRAMController/ \ Controllers/HyperXKeyboardController/ \ Controllers/HyperXMouseController/ \ + Controllers/HyperXMousematController/ \ Controllers/LEDStripController/ \ Controllers/LogitechController/ \ Controllers/MSI3ZoneController/ \ @@ -186,6 +187,8 @@ HEADERS += Controllers/HyperXKeyboardController/RGBController_HyperXKeyboard.h \ Controllers/HyperXMouseController/HyperXPulsefireSurgeController.h \ Controllers/HyperXMouseController/RGBController_HyperXPulsefireSurge.h \ + Controllers/HyperXMousematController/HyperXMousematController.h \ + Controllers/HyperXMousematController/RGBController_HyperXMousemat.h \ Controllers/LEDStripController/LEDStripController.h \ Controllers/LEDStripController/RGBController_LEDStrip.h \ Controllers/LogitechController/LogitechG203Controller.h \ @@ -368,6 +371,9 @@ SOURCES += Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp \ Controllers/HyperXMouseController/HyperXPulsefireSurgeController.cpp \ Controllers/HyperXMouseController/RGBController_HyperXPulsefireSurge.cpp \ + Controllers/HyperXMousematController/HyperXMousematController.cpp \ + Controllers/HyperXMousematController/HyperXMousematControllerDetect.cpp \ + Controllers/HyperXMousematController/RGBController_HyperXMousemat.cpp \ Controllers/LEDStripController/LEDStripController.cpp \ Controllers/LEDStripController/LEDStripControllerDetect.cpp \ Controllers/LEDStripController/RGBController_LEDStrip.cpp \