diff --git a/Controllers/HyperXKeyboardController/HyperXEve1800Controller/HyperXEve1800Controller.cpp b/Controllers/HyperXKeyboardController/HyperXEve1800Controller/HyperXEve1800Controller.cpp new file mode 100644 index 000000000..657136306 --- /dev/null +++ b/Controllers/HyperXKeyboardController/HyperXEve1800Controller/HyperXEve1800Controller.cpp @@ -0,0 +1,121 @@ +/*---------------------------------------------------------*\ +| HyperXEve1800Controller.cpp | +| | +| Driver for HyperX Eve 1800 keyboard | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#include +#include "HyperXEve1800Controller.h" +#include "StringUtils.h" + +HyperXEve1800Controller::HyperXEve1800Controller(hid_device* dev_handle, const char* path, std::string dev_name) +{ + dev = dev_handle; + location = path; + name = dev_name; +} + +HyperXEve1800Controller::~HyperXEve1800Controller() +{ + hid_close(dev); +} + +std::string HyperXEve1800Controller::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string HyperXEve1800Controller::GetNameString() +{ + return(name); +} + +std::string HyperXEve1800Controller::GetSerialString() +{ + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + return(""); + } + + return(StringUtils::wstring_to_string(serial_string)); +} + +void HyperXEve1800Controller::SetBrightness(unsigned int brightness) +{ + unsigned char buf[65]; + + memset(buf, 0x00, sizeof(buf)); + + buf[0x00] = 0x40; + buf[0x01] = 0x01; + buf[0x02] = 0x00; + buf[0x03] = 0x00; + buf[0x04] = brightness & 0xFF; + + hid_write(dev, buf, 65); +} + +void HyperXEve1800Controller::SetLEDsDirect(std::vector colors) +{ + SendDirectInitialization(); + + if(colors.empty()) + { + RGBColor temp = 0x00000000; + SendDirectColorPacket(&temp, 1); + } + else + { + SendDirectColorPacket(&colors[0], (unsigned int)colors.size()); + } +} + +void HyperXEve1800Controller::SendDirectInitialization() +{ + unsigned char buf[65]; + + memset(buf, 0x00, sizeof(buf)); + + buf[0x00] = 0x44; + buf[0x01] = 0x01; + buf[0x02] = 0x04; + buf[0x03] = 0x00; + + hid_write(dev, buf, 65); +} + +void HyperXEve1800Controller::SendDirectColorPacket(RGBColor* color_data, unsigned int color_count) +{ + unsigned char buf[65]; + + memset(buf, 0x00, sizeof(buf)); + + buf[0x00] = 0x44; + buf[0x01] = 0x02; + buf[0x02] = 0x00; + buf[0x03] = 0x00; + + /*-----------------------------------------------------*\ + | The Eve 1800 exposes 10 lighting zones, but this | + | report format can carry up to 20 RGB triplets. | + \*-----------------------------------------------------*/ + if(color_count > 20) + { + color_count = 20; + } + + for(unsigned int color_idx = 0; color_idx < color_count; color_idx++) + { + buf[4 + (color_idx * 3)] = RGBGetRValue(color_data[color_idx]); + buf[4 + (color_idx * 3) + 1] = RGBGetGValue(color_data[color_idx]); + buf[4 + (color_idx * 3) + 2] = RGBGetBValue(color_data[color_idx]); + } + + hid_write(dev, buf, 65); +} diff --git a/Controllers/HyperXKeyboardController/HyperXEve1800Controller/HyperXEve1800Controller.h b/Controllers/HyperXKeyboardController/HyperXEve1800Controller/HyperXEve1800Controller.h new file mode 100644 index 000000000..4e88ffede --- /dev/null +++ b/Controllers/HyperXKeyboardController/HyperXEve1800Controller/HyperXEve1800Controller.h @@ -0,0 +1,36 @@ +/*---------------------------------------------------------*\ +| HyperXEve1800Controller.h | +| | +| Driver for HyperX Eve 1800 keyboard | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include +#include "RGBController.h" + +class HyperXEve1800Controller +{ +public: + HyperXEve1800Controller(hid_device* dev_handle, const char* path, std::string dev_name); + ~HyperXEve1800Controller(); + + std::string GetDeviceLocation(); + std::string GetNameString(); + std::string GetSerialString(); + + void SetBrightness(unsigned int brightness); + void SetLEDsDirect(std::vector colors); + +private: + hid_device* dev; + std::string location; + std::string name; + + void SendDirectInitialization(); + void SendDirectColorPacket(RGBColor* color_data, unsigned int color_count); +}; diff --git a/Controllers/HyperXKeyboardController/HyperXEve1800Controller/RGBController_HyperXEve1800.cpp b/Controllers/HyperXKeyboardController/HyperXEve1800Controller/RGBController_HyperXEve1800.cpp new file mode 100644 index 000000000..fae8c988d --- /dev/null +++ b/Controllers/HyperXKeyboardController/HyperXEve1800Controller/RGBController_HyperXEve1800.cpp @@ -0,0 +1,127 @@ +/*---------------------------------------------------------*\ +| RGBController_HyperXEve1800.cpp | +| | +| RGBController for HyperX Eve 1800 keyboard | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#include "RGBController_HyperXEve1800.h" + +using namespace std::chrono_literals; + +#define HYPERX_EVE_1800_BRIGHTNESS_MIN 0x00 +#define HYPERX_EVE_1800_BRIGHTNESS_MAX 0xFF +#define HYPERX_EVE_1800_ZONE_COUNT 10 + +/**------------------------------------------------------------------*\ + @name HyperX Eve 1800 + @category Keyboard + @type USB + @save :x: + @direct :white_check_mark: + @effects :x: + @detectors DetectHyperXEve1800 + @comment +\*-------------------------------------------------------------------*/ + +RGBController_HyperXEve1800::RGBController_HyperXEve1800(HyperXEve1800Controller* controller_ptr) +{ + controller = controller_ptr; + + name = controller->GetNameString(); + vendor = "HyperX"; + type = DEVICE_TYPE_KEYBOARD; + description = "HyperX Eve 1800 Keyboard Device"; + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = 0xFFFF; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Direct.brightness_min = HYPERX_EVE_1800_BRIGHTNESS_MIN; + Direct.brightness_max = HYPERX_EVE_1800_BRIGHTNESS_MAX; + Direct.brightness = HYPERX_EVE_1800_BRIGHTNESS_MAX; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + SetupZones(); + + keepalive_thread_run = 1; + keepalive_thread = new std::thread(&RGBController_HyperXEve1800::KeepaliveThread, this); +} + +RGBController_HyperXEve1800::~RGBController_HyperXEve1800() +{ + keepalive_thread_run = 0; + keepalive_thread->join(); + delete keepalive_thread; + + delete controller; +} + +void RGBController_HyperXEve1800::SetupZones() +{ + zone new_zone; + new_zone.name = "Keyboard"; + new_zone.type = ZONE_TYPE_LINEAR; + new_zone.leds_min = HYPERX_EVE_1800_ZONE_COUNT; + new_zone.leds_max = HYPERX_EVE_1800_ZONE_COUNT; + new_zone.leds_count = HYPERX_EVE_1800_ZONE_COUNT; + new_zone.matrix_map = NULL; + zones.push_back(new_zone); + + for(unsigned int led_idx = 0; led_idx < zones[0].leds_count; led_idx++) + { + led new_led; + new_led.name = "Zone "; + new_led.name.append(std::to_string(led_idx + 1)); + leds.push_back(new_led); + } + + SetupColors(); +} + +void RGBController_HyperXEve1800::ResizeZone(int /*zone*/, int /*new_size*/) +{ + +} + +void RGBController_HyperXEve1800::DeviceUpdateLEDs() +{ + controller->SetLEDsDirect(colors); + last_update_time = std::chrono::steady_clock::now(); +} + +void RGBController_HyperXEve1800::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXEve1800::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HyperXEve1800::DeviceUpdateMode() +{ + controller->SetBrightness(modes[active_mode].brightness); + DeviceUpdateLEDs(); +} + +void RGBController_HyperXEve1800::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/HyperXKeyboardController/HyperXEve1800Controller/RGBController_HyperXEve1800.h b/Controllers/HyperXKeyboardController/HyperXEve1800Controller/RGBController_HyperXEve1800.h new file mode 100644 index 000000000..897a9dd9a --- /dev/null +++ b/Controllers/HyperXKeyboardController/HyperXEve1800Controller/RGBController_HyperXEve1800.h @@ -0,0 +1,39 @@ +/*---------------------------------------------------------*\ +| RGBController_HyperXEve1800.h | +| | +| RGBController for HyperX Eve 1800 keyboard | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include "RGBController.h" +#include "HyperXEve1800Controller.h" + +class RGBController_HyperXEve1800 : public RGBController +{ +public: + RGBController_HyperXEve1800(HyperXEve1800Controller* controller_ptr); + ~RGBController_HyperXEve1800(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + + void KeepaliveThread(); + +private: + HyperXEve1800Controller* controller; + std::thread* keepalive_thread; + std::atomic keepalive_thread_run; + std::chrono::time_point last_update_time; +}; diff --git a/Controllers/HyperXKeyboardController/HyperXKeyboardControllerDetect.cpp b/Controllers/HyperXKeyboardController/HyperXKeyboardControllerDetect.cpp index 7479e19b5..f101c50e9 100644 --- a/Controllers/HyperXKeyboardController/HyperXKeyboardControllerDetect.cpp +++ b/Controllers/HyperXKeyboardController/HyperXKeyboardControllerDetect.cpp @@ -15,6 +15,7 @@ #include "HyperXAlloyOriginsController.h" #include "HyperXAlloyOriginsCoreController.h" #include "HyperXAlloyOrigins60and65Controller.h" +#include "HyperXEve1800Controller.h" #include "HyperXOrigins2_65Controller.h" #include "RGBController_HyperXAlloyElite.h" #include "RGBController_HyperXAlloyElite2.h" @@ -22,6 +23,7 @@ #include "RGBController_HyperXAlloyOrigins.h" #include "RGBController_HyperXAlloyOriginsCore.h" #include "RGBController_HyperXAlloyOrigins60and65.h" +#include "RGBController_HyperXEve1800.h" #include "RGBController_HyperXOrigins2_65.h" /*-----------------------------------------------------*\ @@ -46,6 +48,7 @@ #define HYPERX_ALLOY_ORIGINS_65_HP_PID 0x038F #define HYPERX_ALLOY_ORIGINS_CORE_HP_PID 0x098F #define HYPERX_ALLOY_ORIGINS_HP_PID 0x0591 +#define HYPERX_EVE_1800_HP_PID 0x08C2 #define HYPERX_ORIGINS_2_65_HP_PID 0x0CC2 AlloyOrigins60and65MappingLayoutType GetAlloyOrigins60and65MappingLayoutType(int pid) @@ -156,6 +159,19 @@ void DetectHyperXOrigins2_65(hid_device_info* info, const std::string& name) } } +void DetectHyperXEve1800(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + HyperXEve1800Controller* controller = new HyperXEve1800Controller(dev, info->path, name); + RGBController_HyperXEve1800* rgb_controller = new RGBController_HyperXEve1800(controller); + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + REGISTER_HID_DETECTOR_IP("HyperX Alloy Elite RGB", DetectHyperXAlloyElite, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_PID, 2, 0xFF01); REGISTER_HID_DETECTOR_IP("HyperX Alloy FPS RGB", DetectHyperXAlloyFPS, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_FPS_RGB_PID, 2, 0xFF01); REGISTER_HID_DETECTOR_I("HyperX Alloy Origins Core", DetectHyperXAlloyOriginsCore, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_CORE_PID, 2); @@ -163,6 +179,7 @@ REGISTER_HID_DETECTOR_I("HyperX Alloy Origins Core", DetectHyperXAlloyOrigi REGISTER_HID_DETECTOR_I("HyperX Alloy Origins Core (HP)", DetectHyperXAlloyOriginsCore, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_CORE_HP_PID, 2); REGISTER_HID_DETECTOR_I("HyperX Origins 2 65 (HP)", DetectHyperXOrigins2_65, HP_KEYBOARD_VID, HYPERX_ORIGINS_2_65_HP_PID, 3); +REGISTER_HID_DETECTOR_I("HyperX Eve 1800 (HP)", DetectHyperXEve1800, HP_KEYBOARD_VID, HYPERX_EVE_1800_HP_PID, 2); #ifdef _WIN32 REGISTER_HID_DETECTOR_I("HyperX Alloy Origins", DetectHyperXAlloyOrigins, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_PID, 3);