diff --git a/Controllers/LianLiController/LianLiControllerDetect.cpp b/Controllers/LianLiController/LianLiControllerDetect.cpp index eb2cb2d7..35633211 100644 --- a/Controllers/LianLiController/LianLiControllerDetect.cpp +++ b/Controllers/LianLiController/LianLiControllerDetect.cpp @@ -7,12 +7,11 @@ | Luca Lovisa 2/20/2021 | \*-----------------------------------------*/ -#include -#include - +/*-----------------------------------------------------*\ +| OpenRGB includes | +\*-----------------------------------------------------*/ +#include #include "Detector.h" -#include "LianLiUniHubController.h" -#include "RGBController_LianLiUniHub.h" #include "ResourceManager.h" #ifdef __FreeBSD__ @@ -21,8 +20,26 @@ #include #endif -#define UNI_HUB_VID 0x0CF2 -#define UNI_HUB_PID 0x7750 +/*-----------------------------------------------------*\ +| LianLi USB Controller specific includes | +\*-----------------------------------------------------*/ +#include "RGBController_LianLiUniHub.h" +#include "RGBController_StrimerLConnect.h" + +/*-----------------------------------------------------*\ +| ENE USB vendor ID | +\*-----------------------------------------------------*/ +#define ENE_USB_VID 0x0CF2 + +/*-----------------------------------------------------*\ +| Keyboard product IDs | +\*-----------------------------------------------------*/ +#define STRIMER_L_CONNECT_PID 0xA200 + +/*-----------------------------------------------------*\ +| Fan controller product IDs | +\*-----------------------------------------------------*/ +#define UNI_HUB_PID 0x7750 /*----------------------------------------------------------------------------*\ | The Uni Hub is controlled by sending control transfers to various wIndex | @@ -61,7 +78,7 @@ void DetectLianLiUniHub(std::vector&) continue; } - if( descriptor.idVendor == UNI_HUB_VID + if( descriptor.idVendor == ENE_USB_VID && descriptor.idProduct == UNI_HUB_PID) { LianLiUniHubController* controller = new LianLiUniHubController(device, &descriptor); @@ -76,9 +93,25 @@ void DetectLianLiUniHub(std::vector&) } } +void DetectStrimerControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + StrimerLConnectController* controller = new StrimerLConnectController(dev, info->path); + RGBController_StrimerLConnect* rgb_controller = new RGBController_StrimerLConnect(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + REGISTER_DETECTOR("Lian Li Uni Hub", DetectLianLiUniHub); /*---------------------------------------------------------------------------------------------------------*\ | Entries for dynamic UDEV rules | | | | DUMMY_DEVICE_DETECTOR("Lian Li Uni Hub", DetectLianLiUniHub, 0x0CF2, 0x7750 ) | \*---------------------------------------------------------------------------------------------------------*/ + +REGISTER_HID_DETECTOR_IPU("Strimer L Connect", DetectStrimerControllers, ENE_USB_VID, STRIMER_L_CONNECT_PID, 1, 0xFF72, 0xA1); diff --git a/Controllers/LianLiController/RGBController_StrimerLConnect.cpp b/Controllers/LianLiController/RGBController_StrimerLConnect.cpp new file mode 100644 index 00000000..529713bc --- /dev/null +++ b/Controllers/LianLiController/RGBController_StrimerLConnect.cpp @@ -0,0 +1,346 @@ +/*---------------------------------------------------------------------*\ +| RGBController_StrimerLConnect.cpp | +| | +| Driver for StrimerLConnect USB Controller | +| | +| Chris M (Dr_No) 03 Jul 2022 | +| | +\*---------------------------------------------------------------------*/ + +#include "RGBController_StrimerLConnect.h" + +/**------------------------------------------------------------------*\ + @name Strimer L Connect + @category LEDStrip + @type USB + @save :x: + @direct :rotating_light: + @effects :white_check_mark: + @detectors DetectStrimerControllers + @comment The Strimer L Connect `Direct` mode stutters at high frame rates and + and has been rate limited to ~10FPS. +\*-------------------------------------------------------------------*/ + +RGBController_StrimerLConnect::RGBController_StrimerLConnect(StrimerLConnectController *controller_ptr) +{ + controller = controller_ptr; + + name = "StrimerLConnect"; + vendor = "Lian Li"; + type = DEVICE_TYPE_LEDSTRIP; + description = controller->GetDeviceName(); + serial = controller->GetSerial(); + location = controller->GetLocation(); + + mode Off; + Off.name = "Off"; + Off.value = STRIMERLCONNECT_MODE_DIRECT; + Off.brightness = STRIMERLCONNECT_BRIGHTNESS_MIN; + Off.color_mode = MODE_COLORS_NONE; + modes.push_back(Off); + + mode Direct; + Direct.name = "Direct"; + Direct.value = STRIMERLCONNECT_MODE_DIRECT; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + mode Breathing = CreateMode("Breathing", STRIMERLCONNECT_MODE_BREATHING, 0, MODE_COLORS_PER_LED); + Breathing.flags |= MODE_FLAG_HAS_PER_LED_COLOR; + modes.push_back(Breathing); + + mode Flashing = CreateMode("Flashing", STRIMERLCONNECT_MODE_FLASHING, 0, MODE_COLORS_PER_LED); + Flashing.flags |= MODE_FLAG_HAS_PER_LED_COLOR; + modes.push_back(Flashing); + + mode BreathCycle = CreateMode("Breathing Cycle", STRIMERLCONNECT_MODE_BREATHCYCLE, 0, MODE_COLORS_NONE); + modes.push_back(BreathCycle); + + mode Rainbow = CreateMode("Rainbow", STRIMERLCONNECT_MODE_RAINBOW, 0, MODE_COLORS_NONE); + Rainbow.flags |= MODE_FLAG_HAS_DIRECTION_LR; + modes.push_back(Rainbow); + + mode RainbowMorph = CreateMode("Rainbow Morph", STRIMERLCONNECT_MODE_RAINBOWMORPH, 0, MODE_COLORS_NONE); + modes.push_back(RainbowMorph); + + mode Snooker = CreateMode("Snooker", STRIMERLCONNECT_MODE_SNOOKER, 6, MODE_COLORS_MODE_SPECIFIC); + Snooker.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + modes.push_back(Snooker); + + mode Mixing = CreateMode("Mixing", STRIMERLCONNECT_MODE_MIXING, 2, MODE_COLORS_MODE_SPECIFIC); + Mixing.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + modes.push_back(Mixing); + + mode PingPong = CreateMode("Ping Pong", STRIMERLCONNECT_MODE_PINGPONG, 6, MODE_COLORS_MODE_SPECIFIC); + PingPong.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + modes.push_back(PingPong); + + mode Runway = CreateMode("Runway", STRIMERLCONNECT_MODE_RUNWAY, 2, MODE_COLORS_MODE_SPECIFIC); + Runway.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + modes.push_back(Runway); + + mode Painting = CreateMode("Painting", STRIMERLCONNECT_MODE_PAINTING, 6, MODE_COLORS_MODE_SPECIFIC); + Painting.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + modes.push_back(Painting); + + mode Tide = CreateMode("Tide", STRIMERLCONNECT_MODE_TIDE, 6, MODE_COLORS_MODE_SPECIFIC); + Tide.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + modes.push_back(Tide); + + mode BlowUp = CreateMode("Blow Up", STRIMERLCONNECT_MODE_BLOWUP, 6, MODE_COLORS_MODE_SPECIFIC); + BlowUp.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + modes.push_back(BlowUp); + + mode Meteor = CreateMode("Meteor", STRIMERLCONNECT_MODE_METEOR, 6, MODE_COLORS_MODE_SPECIFIC); + Meteor.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_DIRECTION_LR; + modes.push_back(Meteor); + + mode ColorTransfer = CreateMode("Color Transfer", STRIMERLCONNECT_MODE_COLORTRANSFER, 6, MODE_COLORS_MODE_SPECIFIC); + ColorTransfer.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_DIRECTION_LR; + modes.push_back(ColorTransfer); + + mode FadeOut = CreateMode("Fade Out", STRIMERLCONNECT_MODE_FADEOUT, 6, MODE_COLORS_MODE_SPECIFIC); + FadeOut.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + modes.push_back(FadeOut); + + mode Contest = CreateMode("Contest", STRIMERLCONNECT_MODE_CONTEST, 6, MODE_COLORS_MODE_SPECIFIC); + Contest.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_DIRECTION_LR; + modes.push_back(Contest); + + mode CrossOver = CreateMode("Cross Over", STRIMERLCONNECT_MODE_CROSSOVER, 6, MODE_COLORS_MODE_SPECIFIC); + CrossOver.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_DIRECTION_LR; + modes.push_back(CrossOver); + + mode BulletStack = CreateMode("Bullet Stack", STRIMERLCONNECT_MODE_BULLETSTACK, 0, MODE_COLORS_NONE); + BulletStack.flags |= MODE_FLAG_HAS_DIRECTION_LR; + modes.push_back(BulletStack); + + mode Twinkle = CreateMode("Twinkle", STRIMERLCONNECT_MODE_TWINKLE, 0, MODE_COLORS_NONE); + modes.push_back(Twinkle); + + mode Parallel = CreateMode("Parallel", STRIMERLCONNECT_MODE_PARALLEL, 6, MODE_COLORS_MODE_SPECIFIC); + Parallel.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_DIRECTION_LR; + modes.push_back(Parallel); + + mode ShockWave = CreateMode("Shock Wave", STRIMERLCONNECT_MODE_SHOCKWAVE, 6, MODE_COLORS_MODE_SPECIFIC); + ShockWave.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_DIRECTION_LR; + modes.push_back(ShockWave); + + mode Ripple = CreateMode("Ripple", STRIMERLCONNECT_MODE_RIPPLE, 6, MODE_COLORS_MODE_SPECIFIC); + Ripple.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + modes.push_back(Ripple); + + mode Voice = CreateMode("Voice", STRIMERLCONNECT_MODE_VOICE, 6, MODE_COLORS_MODE_SPECIFIC); + Voice.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + modes.push_back(Voice); + + mode Drizzling = CreateMode("Drizzling", STRIMERLCONNECT_MODE_DRIZZLING, 6, MODE_COLORS_MODE_SPECIFIC); + Drizzling.flags |= MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_DIRECTION_LR; + modes.push_back(Drizzling); + + Init_Controller(); + SetupZones(); +} + +RGBController_StrimerLConnect::~RGBController_StrimerLConnect() +{ + delete controller; +} + +void RGBController_StrimerLConnect::Init_Controller() +{ + const uint8_t zone_split = STRIMERLCONNECT_STRIP_COUNT / 2; + + /*-------------------------------------------------*\ + | Create the device's controllable zones | + \*-------------------------------------------------*/ + for(std::size_t zone_idx = 0; zone_idx < zone_split; zone_idx++) + { + zone new_zone; + new_zone.name = "24 Pin ATX Strip "; + new_zone.name.append(std::to_string(zone_idx)); + new_zone.type = ZONE_TYPE_LINEAR; + new_zone.leds_min = 20; + new_zone.leds_max = 20; + new_zone.leds_count = new_zone.leds_max; + new_zone.matrix_map = NULL; + zones.push_back(new_zone); + } + + for(std::size_t zone_idx = zone_split; zone_idx < STRIMERLCONNECT_STRIP_COUNT; zone_idx++) + { + zone new_zone; + new_zone.name = "8 Pin GPU Strip "; + new_zone.name.append(std::to_string(zone_idx - zone_split)); + new_zone.type = ZONE_TYPE_LINEAR; + new_zone.leds_min = 27; + new_zone.leds_max = 27; + new_zone.leds_count = new_zone.leds_max; + new_zone.matrix_map = NULL; + zones.push_back(new_zone); + } +} + +void RGBController_StrimerLConnect::SetupZones() +{ + /*-------------------------------------------------*\ + | Clear any existing color/LED configuration | + \*-------------------------------------------------*/ + leds.clear(); + colors.clear(); + + /*---------------------------------------------------------*\ + | Set up zones | + \*---------------------------------------------------------*/ + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + for(unsigned int lp_idx = 0; lp_idx < zones[zone_idx].leds_count; lp_idx++) + { + led new_led; + + new_led.name = zones[zone_idx].name; + new_led.name.append(" LED " + std::to_string(lp_idx)); + + leds.push_back(new_led); + } + } + + SetupColors(); +} + +void RGBController_StrimerLConnect::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +bool RGBController_StrimerLConnect::TimeToSend() +{ + /*-----------------------------------------------------*\ + | Rate limit is 1000(ms) / wait_time in Frames Per Sec | + \*-----------------------------------------------------*/ + const uint8_t wait_time = 90; + + return (std::chrono::steady_clock::now() - last_commit_time) > std::chrono::milliseconds(wait_time); +} + +void RGBController_StrimerLConnect::DeviceUpdateLEDs() +{ + if(TimeToSend()) + { + + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + UpdateZoneLEDs(zone_idx); + } + + controller->SendApply(); + + /*-----------------------------------------------------*\ + | Update last commit time | + \*-----------------------------------------------------*/ + last_commit_time = std::chrono::steady_clock::now(); + } +} + +void RGBController_StrimerLConnect::UpdateZoneLEDs(int zone) +{ + mode current_mode = modes[active_mode]; + + controller->SetLedsDirect(zone, zones[zone].colors, zones[zone].leds_count); + controller->SetMode(current_mode.value, zone, current_mode.speed, current_mode.brightness, current_mode.direction, false); +} + +void RGBController_StrimerLConnect::UpdateSingleLED(int led) +{ + UpdateZoneLEDs(GetLED_Zone(led)); + controller->SendApply(); +} + +void RGBController_StrimerLConnect::SetCustomMode() +{ + for(std::size_t mode_idx = 0; mode_idx < modes.size() ; mode_idx++) + { + if (modes[mode_idx].value == STRIMERLCONNECT_MODE_DIRECT) + { + active_mode = mode_idx; + break; + } + } +} + +void RGBController_StrimerLConnect::DeviceUpdateMode() +{ + if(TimeToSend()) + { + mode current_mode = modes[active_mode]; + + if(current_mode.color_mode == MODE_COLORS_PER_LED) + { + return; + } + + bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM); + + if(current_mode.color_mode == MODE_COLORS_NONE) + { + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + controller->SetMode(current_mode.value, zone_idx, current_mode.speed, current_mode.brightness, current_mode.direction, random_colours); + } + } + else + { + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + controller->SetLedsDirect(zone_idx, ¤t_mode.colors[0], current_mode.colors.size()); + controller->SetMode(current_mode.value, zone_idx, current_mode.speed, current_mode.brightness, current_mode.direction, random_colours); + } + } + + controller->SendApply(); + + /*-----------------------------------------------------*\ + | Update last commit time | + \*-----------------------------------------------------*/ + last_commit_time = std::chrono::steady_clock::now(); + } +} + +int RGBController_StrimerLConnect::GetLED_Zone(int led_idx) +{ + for(size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + int zone_start = zones[zone_idx].start_idx; + int zone_end = zone_start + zones[zone_idx].leds_count - 1; + + if( zone_start <= led_idx && zone_end >= led_idx) + { + return(zone_idx); + } + } + + return -1; +} + +mode RGBController_StrimerLConnect::CreateMode(std::string name, int value, uint8_t colour_count, uint8_t colour_mode) +{ + mode new_mode; + new_mode.name = name; + new_mode.value = value; + new_mode.colors_min = colour_count; + new_mode.colors_max = colour_count; + new_mode.colors.resize(colour_count); + new_mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; + new_mode.brightness_min = STRIMERLCONNECT_BRIGHTNESS_MIN; + new_mode.brightness_max = STRIMERLCONNECT_BRIGHTNESS_MAX; + new_mode.brightness = STRIMERLCONNECT_BRIGHTNESS_MAX; + new_mode.speed_min = STRIMERLCONNECT_SPEED_SLOWEST; + new_mode.speed_max = STRIMERLCONNECT_SPEED_FASTEST; + new_mode.speed = STRIMERLCONNECT_SPEED_NORMAL; + new_mode.color_mode = colour_mode; + + return new_mode; +} diff --git a/Controllers/LianLiController/RGBController_StrimerLConnect.h b/Controllers/LianLiController/RGBController_StrimerLConnect.h new file mode 100644 index 00000000..68154406 --- /dev/null +++ b/Controllers/LianLiController/RGBController_StrimerLConnect.h @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------*\ +| RGBController_StrimerLConnect.h | +| | +| Driver for StrimerLConnect USB Controller | +| | +| Chris M (Dr_No) 03 Jul 2022 | +| | +\*---------------------------------------------------------------------*/ + +#pragma once +#include +#include "LogManager.h" +#include "RGBController.h" +#include "StrimerLConnectController.h" + +class RGBController_StrimerLConnect : public RGBController +{ +public: + RGBController_StrimerLConnect(StrimerLConnectController* controller_ptr); + ~RGBController_StrimerLConnect(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + void Init_Controller(); + int GetDeviceMode(); + int GetLED_Zone(int led_idx); + + mode CreateMode(std::string name, int value, uint8_t colour_count, uint8_t colour_mode); + bool TimeToSend(); + + StrimerLConnectController* controller; + std::chrono::time_point last_commit_time; +}; diff --git a/Controllers/LianLiController/StrimerLConnectController.cpp b/Controllers/LianLiController/StrimerLConnectController.cpp new file mode 100644 index 00000000..69e86f08 --- /dev/null +++ b/Controllers/LianLiController/StrimerLConnectController.cpp @@ -0,0 +1,110 @@ +/*---------------------------------------------------------------------*\ +| StrimerLConnectController.cpp | +| | +| Driver for StrimerLConnect USB Controller | +| | +| Chris M (Dr_No) 03 Jul 2022 | +| | +\*---------------------------------------------------------------------*/ + +#include "StrimerLConnectController.h" + +static uint8_t speed_data[5] = +{ + 0x02, 0x01, 0x00, 0xFE, 0xFF /* Slow to fast */ +}; + +static uint8_t brightness_data[5] = +{ + 0x08, 0x03, 0x02, 0x01, 0x00 /* 0%, 25%, 50%, 75%, 100% */ +}; + +StrimerLConnectController::StrimerLConnectController(hid_device* dev_handle, const char* path) +{ + const uint8_t sz = HID_MAX_STR; + wchar_t tmp[sz]; + + dev = dev_handle; + location = path; + + hid_get_manufacturer_string(dev, tmp, sz); + std::wstring wName = std::wstring(tmp); + device_name = std::string(wName.begin(), wName.end()); + + hid_get_product_string(dev, tmp, sz); + wName = std::wstring(tmp); + device_name.append(" ").append(std::string(wName.begin(), wName.end())); +} + +StrimerLConnectController::~StrimerLConnectController() +{ + hid_close(dev); +} + +std::string StrimerLConnectController::GetDeviceName() +{ + return device_name; +} + +std::string StrimerLConnectController::GetSerial() +{ + const uint8_t sz = HID_MAX_STR; + wchar_t tmp[sz]; + + int ret = hid_get_serial_number_string(dev, tmp, sz); + + if (ret != 0) + { + LOG_DEBUG("[%s] Get HID Serial string failed", device_name.c_str()); + return(""); + } + + std::wstring w_tmp = std::wstring(tmp); + std::string serial = std::string(w_tmp.begin(), w_tmp.end()); + + return serial; +} + +std::string StrimerLConnectController::GetLocation() +{ + return("HID: " + location); +} + +void StrimerLConnectController::SendApply() +{ + uint8_t buffer[STRIMERLCONNECT_PACKET_SIZE] = { STRIMERLCONNECT_REPORT_ID, 0x2C, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0x00 }; + + hid_write(dev, buffer, STRIMERLCONNECT_PACKET_SIZE); +} + +void StrimerLConnectController::SetMode(uint8_t mode, uint8_t zone, uint8_t speed, uint8_t brightness, uint8_t direction, bool random_colours) +{ + uint8_t buffer[STRIMERLCONNECT_PACKET_SIZE] = { STRIMERLCONNECT_REPORT_ID, STRIMERLCONNECT_MODE_COMMAND, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + buffer[STRIMERLCONNECT_COMMAND_BYTE] |= zone; + + buffer[STRIMERLCONNECT_DATA_BYTE] = mode; + buffer[STRIMERLCONNECT_SPEED_BYTE] = speed_data[speed]; + buffer[STRIMERLCONNECT_DIRECTION_BYTE] = (direction == 0) ? 1 : 0; + buffer[STRIMERLCONNECT_BRIGHTNESS_BYTE] = brightness_data[brightness]; + + hid_write(dev, buffer, STRIMERLCONNECT_PACKET_SIZE); +} + +void StrimerLConnectController::SetLedsDirect(uint8_t zone, RGBColor * led_colours, uint8_t led_count) +{ + uint8_t buffer[STRIMERLCONNECT_PACKET_SIZE] = { STRIMERLCONNECT_REPORT_ID, STRIMERLCONNECT_COLOUR_COMMAND, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + buffer[STRIMERLCONNECT_COMMAND_BYTE] |= zone; + + for(size_t i = 0; i < led_count; i++) + { + uint8_t offset = (3 * i) + STRIMERLCONNECT_DATA_BYTE; + + buffer[offset] = RGBGetRValue(led_colours[i]); + buffer[offset + 1] = RGBGetBValue(led_colours[i]); + buffer[offset + 2] = RGBGetGValue(led_colours[i]); + } + + hid_write(dev, buffer, STRIMERLCONNECT_PACKET_SIZE); +} diff --git a/Controllers/LianLiController/StrimerLConnectController.h b/Controllers/LianLiController/StrimerLConnectController.h new file mode 100644 index 00000000..f6e7a239 --- /dev/null +++ b/Controllers/LianLiController/StrimerLConnectController.h @@ -0,0 +1,93 @@ +/*---------------------------------------------------------------------*\ +| StrimerLConnectController.h | +| | +| Driver for StrimerLConnect USB Controller | +| | +| Chris M (Dr_No) 03 Jul 2022 | +| | +\*---------------------------------------------------------------------*/ + +#include +#include +#include "LogManager.h" +#include "RGBController.h" + +#pragma once + +#define HID_MAX_STR 255 +#define STRIMERLCONNECT_PACKET_SIZE 255 //Buffer requires a prepended ReportID hence + 1 + +#define STRIMERLCONNECT_BRIGHTNESS_MIN 0 //Brightness indexes not values +#define STRIMERLCONNECT_BRIGHTNESS_MAX 4 +#define STRIMERLCONNECT_STRIP_COUNT 12 + +enum +{ + STRIMERLCONNECT_MODE_OFF = 0x00, //Turn off - All leds off + STRIMERLCONNECT_MODE_DIRECT = 0x01, //Direct Led Control - Independently set LEDs in zone + STRIMERLCONNECT_MODE_BREATHING = 0x02, //Breathing Mode - Fades between fully off and fully on. + STRIMERLCONNECT_MODE_FLASHING = 0x03, //Flashing Mode - Abruptly changing between fully off and fully on. + STRIMERLCONNECT_MODE_RAINBOWMORPH = 0x04, //Rainbow Morph Mode + STRIMERLCONNECT_MODE_RAINBOW = 0x05, //Rainbow Wave Mode - Cycle thru the color spectrum as a wave across all LEDs + STRIMERLCONNECT_MODE_BREATHCYCLE = 0x06, //Spectrum Cycle Mode - Cycles through the color spectrum on all lights on the device + + STRIMERLCONNECT_MODE_SNOOKER = 0x19, //Snooker Mode + STRIMERLCONNECT_MODE_MIXING = 0x1A, //Mixing Mode + STRIMERLCONNECT_MODE_PINGPONG = 0x1B, //Ping Pong Mode + STRIMERLCONNECT_MODE_RUNWAY = 0x1C, //Runway Mode + STRIMERLCONNECT_MODE_PAINTING = 0x1D, //Painting Mode + STRIMERLCONNECT_MODE_TIDE = 0x1E, //Tide Mode + STRIMERLCONNECT_MODE_BLOWUP = 0x1F, //Blow Up Mode + STRIMERLCONNECT_MODE_METEOR = 0x20, //Meteor Mode + + STRIMERLCONNECT_MODE_SHOCKWAVE = 0x21, //Shock Wave Mode + STRIMERLCONNECT_MODE_RIPPLE = 0x22, //Ripple Mode + STRIMERLCONNECT_MODE_VOICE = 0x23, //Voice Mode + STRIMERLCONNECT_MODE_BULLETSTACK = 0x24, //Bullet Stack Mode + STRIMERLCONNECT_MODE_DRIZZLING = 0x25, //Drizzling Mode + STRIMERLCONNECT_MODE_FADEOUT = 0x26, //Fade Out Mode + STRIMERLCONNECT_MODE_COLORTRANSFER = 0x27, //Color Transfer Mode + STRIMERLCONNECT_MODE_CROSSOVER = 0x28, //Cross Over Mode + STRIMERLCONNECT_MODE_TWINKLE = 0x29, //Twinkle Mode + STRIMERLCONNECT_MODE_CONTEST = 0x2A, //Contest Mode + STRIMERLCONNECT_MODE_PARALLEL = 0x2B, //Parallel Mode +}; + +enum +{ + STRIMERLCONNECT_COMMAND_BYTE = 1, + STRIMERLCONNECT_DATA_BYTE = 2, + STRIMERLCONNECT_SPEED_BYTE = 3, + STRIMERLCONNECT_DIRECTION_BYTE = 4, + STRIMERLCONNECT_BRIGHTNESS_BYTE = 5, + + STRIMERLCONNECT_MODE_COMMAND = 0x10, + STRIMERLCONNECT_COLOUR_COMMAND = 0x30, + STRIMERLCONNECT_REPORT_ID = 0xE0, +}; + +enum +{ + STRIMERLCONNECT_SPEED_SLOWEST = 0, + STRIMERLCONNECT_SPEED_NORMAL = 2, + STRIMERLCONNECT_SPEED_FASTEST = 4, +}; + +class StrimerLConnectController +{ +public: + StrimerLConnectController(hid_device* dev_handle, const char* path); + ~StrimerLConnectController(); + + std::string GetDeviceName(); + std::string GetSerial(); + std::string GetLocation(); + + void SendApply(); + void SetMode(uint8_t mode, uint8_t zone, uint8_t speed, uint8_t brightness, uint8_t direction, bool random_colours); + void SetLedsDirect(uint8_t zone, RGBColor *led_colours, uint8_t led_count); +private: + std::string device_name; + std::string location; + hid_device* dev; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 6b9007f8..41402756 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -431,6 +431,8 @@ HEADERS += Controllers/LIFXController/RGBController_LIFX.h \ Controllers/LianLiController/LianLiUniHubController.h \ Controllers/LianLiController/RGBController_LianLiUniHub.h \ + Controllers/LianLiController/RGBController_StrimerLConnect.h \ + Controllers/LianLiController/StrimerLConnectController.h \ Controllers/LogitechController/LogitechProtocolCommon.h \ Controllers/LogitechController/LogitechG203LController.h \ Controllers/LogitechController/LogitechG213Controller.h \ @@ -946,6 +948,8 @@ SOURCES += Controllers/LianLiController/LianLiControllerDetect.cpp \ Controllers/LianLiController/LianLiUniHubController.cpp \ Controllers/LianLiController/RGBController_LianLiUniHub.cpp \ + Controllers/LianLiController/RGBController_StrimerLConnect.cpp \ + Controllers/LianLiController/StrimerLConnectController.cpp \ Controllers/LogitechController/LogitechControllerDetect.cpp \ Controllers/LogitechController/LogitechProtocolCommon.cpp \ Controllers/LogitechController/LogitechG203LController.cpp \