From ae826f2fd0fba58de4e75dee05fb8e4aa9e46318 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Thu, 5 Sep 2024 22:18:24 -0500 Subject: [PATCH] Initial commit of Luxafor Flag controller, only supports direct mode for now --- .../LuxaforController/LuxaforController.cpp | 62 ++++++ .../LuxaforController/LuxaforController.h | 46 +++++ .../LuxaforControllerDetect.cpp | 40 ++++ .../RGBController_Luxafor.cpp | 179 ++++++++++++++++++ .../LuxaforController/RGBController_Luxafor.h | 36 ++++ 5 files changed, 363 insertions(+) create mode 100644 Controllers/LuxaforController/LuxaforController.cpp create mode 100644 Controllers/LuxaforController/LuxaforController.h create mode 100644 Controllers/LuxaforController/LuxaforControllerDetect.cpp create mode 100644 Controllers/LuxaforController/RGBController_Luxafor.cpp create mode 100644 Controllers/LuxaforController/RGBController_Luxafor.h diff --git a/Controllers/LuxaforController/LuxaforController.cpp b/Controllers/LuxaforController/LuxaforController.cpp new file mode 100644 index 00000000..2ab5969f --- /dev/null +++ b/Controllers/LuxaforController/LuxaforController.cpp @@ -0,0 +1,62 @@ +/*---------------------------------------------------------*\ +| LuxaforController.cpp | +| | +| Driver for Luxafor devices | +| | +| Adam Honse (calcprogrammer1@gmail.com) 05 Sep 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include +#include "LuxaforController.h" +#include "StringUtils.h" + +LuxaforController::LuxaforController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +LuxaforController::~LuxaforController() +{ + hid_close(dev); +} + +std::string LuxaforController::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string LuxaforController::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 LuxaforController::SendPacket(unsigned char mode, unsigned char led, unsigned char red, unsigned char grn, unsigned char blu) +{ + unsigned char usb_buf[9]; + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0x00; + usb_buf[1] = mode; + usb_buf[2] = led; + usb_buf[3] = red; + usb_buf[4] = grn; + usb_buf[5] = blu; + usb_buf[6] = 100; + usb_buf[7] = 0; + usb_buf[8] = 255; + + hid_write(dev, usb_buf, sizeof(usb_buf)); +} diff --git a/Controllers/LuxaforController/LuxaforController.h b/Controllers/LuxaforController/LuxaforController.h new file mode 100644 index 00000000..1566d9ae --- /dev/null +++ b/Controllers/LuxaforController/LuxaforController.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------*\ +| LuxaforController.h | +| | +| Driver for Luxafor devices | +| | +| Adam Honse (calcprogrammer1@gmail.com) 05 Sep 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include + +enum +{ + LUXAFOR_LED_FIRST = 1, + LUXAFOR_LED_ALL = 255, +}; + +enum +{ + LUXAFOR_MODE_DIRECT = 1, + LUXAFOR_MODE_FADE = 2, + LUXAFOR_MODE_STROBE = 3, + LUXAFOR_MODE_WAVE = 4, + LUXAFOR_MODE_PATTERN = 6, +}; + +class LuxaforController +{ +public: + LuxaforController(hid_device* dev_handle, const char* path); + ~LuxaforController(); + + std::string GetDeviceLocation(); + std::string GetSerialString(); + + void SendPacket(unsigned char mode, unsigned char led, unsigned char red, unsigned char grn, unsigned char blu); + +private: + hid_device* dev; + std::string location; +}; diff --git a/Controllers/LuxaforController/LuxaforControllerDetect.cpp b/Controllers/LuxaforController/LuxaforControllerDetect.cpp new file mode 100644 index 00000000..225b2902 --- /dev/null +++ b/Controllers/LuxaforController/LuxaforControllerDetect.cpp @@ -0,0 +1,40 @@ +/*---------------------------------------------------------*\ +| LuxaforControllerDetect.cpp | +| | +| Detector for Luxafor devices | +| | +| Adam Honse (calcprogrammer1@gmail.com) 05 Sep 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include "Detector.h" +#include "LuxaforController.h" +#include "RGBController_Luxafor.h" + +/*---------------------------------------------------------*\ +| Luxafor USB Vendor ID | +\*---------------------------------------------------------*/ +#define LUXAFOR_VID 0x04D8 + +/*---------------------------------------------------------*\ +| Luxafor USB Product ID | +\*---------------------------------------------------------*/ +#define LUXAFOR_FLAG_PID 0xF372 + +void DetectLuxaforControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + LuxaforController* controller = new LuxaforController(dev, info->path); + RGBController_Luxafor* rgb_controller = new RGBController_Luxafor(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR( "Luxafor Flag", DetectLuxaforControllers, LUXAFOR_VID, LUXAFOR_FLAG_PID ); diff --git a/Controllers/LuxaforController/RGBController_Luxafor.cpp b/Controllers/LuxaforController/RGBController_Luxafor.cpp new file mode 100644 index 00000000..2e058879 --- /dev/null +++ b/Controllers/LuxaforController/RGBController_Luxafor.cpp @@ -0,0 +1,179 @@ +/*---------------------------------------------------------*\ +| RGBController_Luxafor.cpp | +| | +| RGBController for Luxafor devices | +| | +| Adam Honse (calcprogrammer1@gmail.com) 05 Sep 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include "RGBController_Luxafor.h" + +RGBController_Luxafor::RGBController_Luxafor(LuxaforController* controller_ptr) +{ + controller = controller_ptr; + + name = "Luxafor Device"; + type = DEVICE_TYPE_ACCESSORY; + vendor = "Luxafor"; + description = "Luxafor Device"; + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = LUXAFOR_MODE_DIRECT; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + // mode Fade; + // Fade.name = "Fade"; + // Fade.value = LUXAFOR_MODE_FADE; + // Fade.flags = MODE_FLAG_HAS_PER_LED_COLOR; + // Fade.color_mode = MODE_COLORS_PER_LED; + // modes.push_back(Fade); + + // mode Strobe; + // Strobe.name = "Strobe"; + // Strobe.value = LUXAFOR_MODE_STROBE; + // Strobe.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + // Strobe.color_mode = MODE_COLORS_MODE_SPECIFIC; + // Strobe.colors_min = 1; + // Strobe.colors_max = 1; + // Strobe.colors.resize(1); + // modes.push_back(Strobe); + + // mode Wave; + // Wave.name = "Wave"; + // Wave.value = LUXAFOR_MODE_WAVE; + // Wave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + // Wave.color_mode = MODE_COLORS_MODE_SPECIFIC; + // Wave.colors_min = 1; + // Wave.colors_max = 1; + // Wave.colors.resize(1); + // modes.push_back(Wave); + + SetupZones(); +} + +RGBController_Luxafor::~RGBController_Luxafor() +{ + +} + +void RGBController_Luxafor::SetupZones() +{ + /*-----------------------------------------------------*\ + | The Luxafor Flag has 2 zones | + | * Flag (3 LEDs) | + | * Rear (3 LEDs) | + | The LED index starts at 1. Sending 255 for the LED ID | + | sets all LEDs at once. | + \*-----------------------------------------------------*/ + unsigned int led_value = LUXAFOR_LED_FIRST; + + zone flag_zone; + flag_zone.name = "Flag"; + flag_zone.type = ZONE_TYPE_SINGLE; + flag_zone.leds_min = 3; + flag_zone.leds_max = 3; + flag_zone.leds_count = 3; + flag_zone.matrix_map = NULL; + zones.push_back(flag_zone); + + for(std::size_t led_idx = 0; led_idx < flag_zone.leds_count; led_idx++) + { + led luxafor_led; + luxafor_led.name = "Flag LED"; + luxafor_led.value = led_value; + leds.push_back(luxafor_led); + + led_value++; + } + + zone rear_zone; + rear_zone.name = "Rear"; + rear_zone.type = ZONE_TYPE_SINGLE; + rear_zone.leds_min = 3; + rear_zone.leds_max = 3; + rear_zone.leds_count = 3; + rear_zone.matrix_map = NULL; + zones.push_back(rear_zone); + + for(std::size_t led_idx = 0; led_idx < rear_zone.leds_count; led_idx++) + { + led luxafor_led; + luxafor_led.name = "Rear LED"; + luxafor_led.value = led_value; + leds.push_back(luxafor_led); + + led_value++; + } + + SetupColors(); +} + +void RGBController_Luxafor::ResizeZone(int zone, int new_size) +{ + /*-----------------------------------------------------*\ + | This device does not support resizing zones | + \*-----------------------------------------------------*/ +} + +void RGBController_Luxafor::DeviceUpdateLEDs() +{ + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + UpdateZoneLEDs(zone_idx); + } +} + +void RGBController_Luxafor::UpdateZoneLEDs(int zone) +{ + for(std::size_t led_idx = 0; led_idx < zones[zone].leds_count; led_idx++) + { + UpdateSingleLED(zones[zone].start_idx + led_idx); + } +} + +void RGBController_Luxafor::UpdateSingleLED(int led) +{ + if(modes[active_mode].color_mode == MODE_COLORS_PER_LED) + { + unsigned char red = RGBGetRValue(colors[led]); + unsigned char grn = RGBGetGValue(colors[led]); + unsigned char blu = RGBGetBValue(colors[led]); + + controller->SendPacket(modes[active_mode].value, leds[led].value, red, grn, blu); + } +} + +void RGBController_Luxafor::DeviceUpdateMode() +{ + switch(modes[active_mode].color_mode) + { + case MODE_COLORS_PER_LED: + DeviceUpdateLEDs(); + break; + + case MODE_COLORS_MODE_SPECIFIC: + { + unsigned char red = RGBGetRValue(colors[modes[active_mode].colors[0]]); + unsigned char grn = RGBGetGValue(colors[modes[active_mode].colors[0]]); + unsigned char blu = RGBGetBValue(colors[modes[active_mode].colors[0]]); + + controller->SendPacket(modes[active_mode].value, LUXAFOR_LED_ALL, red, grn, blu); + } + break; + } +} + +void RGBController_Luxafor::DeviceSaveMode() +{ + /*-----------------------------------------------------*\ + | This device does not support saving | + \*-----------------------------------------------------*/ +} diff --git a/Controllers/LuxaforController/RGBController_Luxafor.h b/Controllers/LuxaforController/RGBController_Luxafor.h new file mode 100644 index 00000000..38201fca --- /dev/null +++ b/Controllers/LuxaforController/RGBController_Luxafor.h @@ -0,0 +1,36 @@ +/*---------------------------------------------------------*\ +| RGBController_Luxafor.h | +| | +| RGBController for Luxafor devices | +| | +| Adam Honse (calcprogrammer1@gmail.com) 05 Sep 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include "LuxaforController.h" +#include "RGBController.h" + +class RGBController_Luxafor : public RGBController +{ +public: + RGBController_Luxafor(LuxaforController* controller_ptr); + ~RGBController_Luxafor(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + void DeviceSaveMode(); + +private: + LuxaforController* controller; +};