diff --git a/Controllers/ThermaltakeRiingController/ThermaltakeRiingControllerDetect.cpp b/Controllers/ThermaltakeRiingController/ThermaltakeRiingControllerDetect.cpp index fe954c62..e15c8901 100644 --- a/Controllers/ThermaltakeRiingController/ThermaltakeRiingControllerDetect.cpp +++ b/Controllers/ThermaltakeRiingController/ThermaltakeRiingControllerDetect.cpp @@ -5,6 +5,7 @@ | | | Adam Honse (CalcProgrammer1) 07 Feb 2020 | | Chris M (Dr_No) 15 Feb 2021 | +| Sam B (4rcheria) 24 Nov 2024 | | | | This file is part of the OpenRGB project | | SPDX-License-Identifier: GPL-2.0-only | @@ -14,8 +15,11 @@ #include "Detector.h" #include "ThermaltakeRiingController.h" #include "ThermaltakeRiingQuadController.h" +#include "ThermaltakeRiingTrioController.h" #include "RGBController_ThermaltakeRiing.h" #include "RGBController_ThermaltakeRiingQuad.h" +#include "RGBController_ThermaltakeRiingTrio.h" + #define THERMALTAKE_RIING_VID 0x264A #define THERMALTAKE_RIING_PID_BEGIN 0x1FA5 @@ -53,6 +57,18 @@ void DetectThermaltakeRiingQuadControllers(hid_device_info* info, const std::str } } +void DetectThermaltakeRiingTrioControllers(hid_device_info* info, const std::string&) +{ + hid_device* dev = hid_open_path(info->path); + if(dev) + { + ThermaltakeRiingTrioController* controller = new ThermaltakeRiingTrioController(dev, info->path); + RGBController_ThermaltakeRiingTrio* rgb_controller = new RGBController_ThermaltakeRiingTrio(controller); + // Constructor sets the name + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + REGISTER_HID_DETECTOR("Thermaltake Riing (PID 0x1FA5)", DetectThermaltakeRiingControllers, THERMALTAKE_RIING_VID, 0x1FA5); REGISTER_HID_DETECTOR("Thermaltake Riing (PID 0x1FA6)", DetectThermaltakeRiingControllers, THERMALTAKE_RIING_VID, 0x1FA6); REGISTER_HID_DETECTOR("Thermaltake Riing (PID 0x1FA7)", DetectThermaltakeRiingControllers, THERMALTAKE_RIING_VID, 0x1FA7); @@ -89,3 +105,20 @@ REGISTER_HID_DETECTOR("Thermaltake Riing Quad (PID 0x226E)", DetectThermaltakeRi REGISTER_HID_DETECTOR("Thermaltake Riing Quad (PID 0x226F)", DetectThermaltakeRiingQuadControllers, THERMALTAKE_RIING_VID, 0x226F); REGISTER_HID_DETECTOR("Thermaltake Riing Quad (PID 0x2270)", DetectThermaltakeRiingQuadControllers, THERMALTAKE_RIING_VID, 0x2270); REGISTER_HID_DETECTOR("Thermaltake Riing Quad (PID 0x232B)", DetectThermaltakeRiingQuadControllers, THERMALTAKE_RIING_VID, 0x232B); + +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x2135)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x2135); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x2136)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x2136); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x2137)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x2137); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x2138)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x2138); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x2139)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x2139); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x213A)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x213A); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x213B)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x213B); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x213C)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x213C); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x213D)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x213D); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x213E)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x213E); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x213F)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x213F); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x2141)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x2141); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x2142)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x2142); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x2143)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x2143); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x2144)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x2144); +REGISTER_HID_DETECTOR("Thermaltake Riing Trio (PID 0x2145)", DetectThermaltakeRiingTrioControllers, THERMALTAKE_RIING_VID, 0x2145); diff --git a/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/RGBController_ThermaltakeRiingTrio.cpp b/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/RGBController_ThermaltakeRiingTrio.cpp new file mode 100644 index 00000000..5f1bc721 --- /dev/null +++ b/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/RGBController_ThermaltakeRiingTrio.cpp @@ -0,0 +1,160 @@ +/*---------------------------------------------------------*\ +| RGBController_ThermaltakeRiingTrio.cpp | +| | +| RGBController for Thermaltake Riing Trio | +| | +| Sam B (4rcheria) 24 Nov 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include "RGBController_ThermaltakeRiingTrio.h" + +/**------------------------------------------------------------------*\ + @name Thermaltake Riing Trio + @category Cooler + @type USB + @save :x: + @direct :white_check_mark: + @effects :x: + @detectors DetectThermaltakeRiingTrioControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_ThermaltakeRiingTrio::RGBController_ThermaltakeRiingTrio(ThermaltakeRiingTrioController* controller_ptr) +{ + controller = controller_ptr; + + name = "Thermaltake Trio"; + vendor = "Thermaltake"; + type = DEVICE_TYPE_COOLER; + description = "Thermaltake Riing Trio Device"; + location = controller->GetDeviceLocation(); + serial = controller->GetSerial(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = THERMALTAKE_TRIO_MODE_DIRECT; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.speed_min = 0; + Direct.speed_max = 0; + Direct.speed = 0; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + SetupZones(); +} + +RGBController_ThermaltakeRiingTrio::~RGBController_ThermaltakeRiingTrio() +{ + delete controller; +} + +void RGBController_ThermaltakeRiingTrio::SetupZones() +{ + /*-------------------------------------------------*\ + | Only set LED count on the first run | + \*-------------------------------------------------*/ + bool first_run = false; + + if(zones.size() == 0) + { + first_run = true; + } + + /*-------------------------------------------------*\ + | Clear any existing color/LED configuration | + \*-------------------------------------------------*/ + leds.clear(); + colors.clear(); + zones.resize(THERMALTAKE_TRIO_NUM_CHANNELS); + + /*-------------------------------------------------*\ + | Set zones and leds | + \*-------------------------------------------------*/ + for (unsigned int channel_idx = 0; channel_idx < THERMALTAKE_TRIO_NUM_CHANNELS; channel_idx++) + { + char ch_idx_string[2]; + snprintf(ch_idx_string, 2, "%d", channel_idx + 1); + + zones[channel_idx].name = "Riing Channel "; + zones[channel_idx].name.append(ch_idx_string); + zones[channel_idx].type = ZONE_TYPE_LINEAR; + + /*-------------------------------------------------*\ + | The maximum number of colors that would fit in the| + | Riing Trio protocol is 54 | + \*-------------------------------------------------*/ + zones[channel_idx].leds_min = 0; + zones[channel_idx].leds_max = 54; + + if(first_run) + { + zones[channel_idx].leds_count = 0; + } + + zones[channel_idx].matrix_map = NULL; + + for (unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++) + { + char led_idx_string[3]; + snprintf(led_idx_string, 3, "%d", led_ch_idx + 1); + + led new_led; + new_led.name = "Riing Channel "; + new_led.name.append(ch_idx_string); + new_led.name.append(", LED "); + new_led.name.append(led_idx_string); + + leds.push_back(new_led); + leds_channel.push_back(channel_idx); + } + } + + SetupColors(); +} + +void RGBController_ThermaltakeRiingTrio::ResizeZone(int zone, int new_size) +{ + if((size_t) zone >= zones.size()) + { + return; + } + + if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max)) + { + zones[zone].leds_count = new_size; + + SetupZones(); + } +} + +void RGBController_ThermaltakeRiingTrio::DeviceUpdateLEDs() +{ + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + controller->SetChannelLEDs((unsigned char)zone_idx, zones[zone_idx].colors, zones[zone_idx].leds_count); + } +} + +void RGBController_ThermaltakeRiingTrio::UpdateZoneLEDs(int zone) +{ + controller->SetChannelLEDs(zone, zones[zone].colors, zones[zone].leds_count); +} + +void RGBController_ThermaltakeRiingTrio::UpdateSingleLED(int led) +{ + unsigned int channel = leds_channel[led]; + + controller->SetChannelLEDs(channel, zones[channel].colors, zones[channel].leds_count); +} + +void RGBController_ThermaltakeRiingTrio::DeviceUpdateMode() +{ + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + controller->SetMode(modes[active_mode].value, modes[active_mode].speed); + controller->SetChannelLEDs((unsigned char)zone_idx, zones[zone_idx].colors, zones[zone_idx].leds_count); + } +} diff --git a/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/RGBController_ThermaltakeRiingTrio.h b/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/RGBController_ThermaltakeRiingTrio.h new file mode 100644 index 00000000..0cda3b80 --- /dev/null +++ b/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/RGBController_ThermaltakeRiingTrio.h @@ -0,0 +1,36 @@ +/*---------------------------------------------------------*\ +| RGBController_ThermaltakeRiingTrio.h | +| | +| RGBController for Thermaltake Riing Trio | +| | +| Sam B (4rcheria) 24 Nov 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "ThermaltakeRiingTrioController.h" + +class RGBController_ThermaltakeRiingTrio : public RGBController +{ +public: + RGBController_ThermaltakeRiingTrio(ThermaltakeRiingTrioController* controller_ptr); + ~RGBController_ThermaltakeRiingTrio(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + ThermaltakeRiingTrioController* controller; + std::vector leds_channel; + std::vector zones_channel; +}; diff --git a/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/ThermaltakeRiingTrioController.cpp b/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/ThermaltakeRiingTrioController.cpp new file mode 100644 index 00000000..0ebf05b1 --- /dev/null +++ b/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/ThermaltakeRiingTrioController.cpp @@ -0,0 +1,146 @@ +/*---------------------------------------------------------*\ +| ThermaltakeRiingTrioController.cpp | +| | +| Driver for Thermaltake Riing Trio | +| | +| Sam B (4rcheria) 24 Nov 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include +#include "StringUtils.h" +#include "ThermaltakeRiingTrioController.h" + +ThermaltakeRiingTrioController::ThermaltakeRiingTrioController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; + + /*---------------------------------------------------------*\ + | Get device name from HID manufacturer and product strings | + \*---------------------------------------------------------*/ + wchar_t name_string[HID_MAX_STR]; + + hid_get_manufacturer_string(dev, name_string, HID_MAX_STR); + device_name = StringUtils::wstring_to_string(name_string); + + hid_get_product_string(dev, name_string, HID_MAX_STR); + device_name.append(" ").append(StringUtils::wstring_to_string(name_string)); + + SendInit(); + + memset(tt_trio_buffer, 0x00, sizeof(tt_trio_buffer)); + unsigned char temp_buffer[3] = { 0x00, 0x32, 0x52 }; + + for(std::size_t zone_index = 0; zone_index < THERMALTAKE_TRIO_NUM_CHANNELS; zone_index++) + { + /*-------------------------------------------------*\ + | Add the constant bytes for the mode info buffer | + \*-------------------------------------------------*/ + memcpy(&tt_trio_buffer[zone_index][0], temp_buffer, 3); + } +} + +ThermaltakeRiingTrioController::~ThermaltakeRiingTrioController() +{ + hid_close(dev); +} + +std::string ThermaltakeRiingTrioController::GetDeviceName() +{ + return device_name; +} + +std::string ThermaltakeRiingTrioController::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string ThermaltakeRiingTrioController::GetSerial() +{ + 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 ThermaltakeRiingTrioController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors) +{ + if(num_colors == 0) return; + + unsigned char* color_data = new unsigned char[3 * num_colors]; + + for(std::size_t color = 0; color < num_colors; color++) + { + int color_idx = color * 3; + color_data[color_idx + 0] = RGBGetGValue(colors[color]); + color_data[color_idx + 1] = RGBGetRValue(colors[color]); + color_data[color_idx + 2] = RGBGetBValue(colors[color]); + } + + tt_trio_buffer[channel][THERMALTAKE_TRIO_ZONE_BYTE] = channel + 1; + tt_trio_buffer[channel][THERMALTAKE_TRIO_MODE_BYTE] = 0x24; + tt_trio_buffer[channel][5] = 0x03; + tt_trio_buffer[channel][7] = 0x00; + + /*-------------------------------------------------*\ + | create and send chunks min = 2 max = 4 | + \*-------------------------------------------------*/ + for(unsigned int i = 0; (num_colors > (THERMALTAKE_TRIO_CHUNK_LENGTH * i)) || i < 2; i++) + { + unsigned int colors_transmitted = THERMALTAKE_TRIO_CHUNK_LENGTH * i; + unsigned int colors_to_transmit = (num_colors > colors_transmitted) ? num_colors - colors_transmitted : 0; + + memset(&tt_trio_buffer[channel][THERMALTAKE_TRIO_CHUNK_ID], 0x00, sizeof(tt_trio_buffer[channel]) - THERMALTAKE_TRIO_CHUNK_ID); + tt_trio_buffer[channel][THERMALTAKE_TRIO_CHUNK_ID] = i + 1; + if(colors_to_transmit < THERMALTAKE_TRIO_CHUNK_LENGTH) + { + memcpy(&tt_trio_buffer[channel][THERMALTAKE_TRIO_DATA_BYTE], &color_data[colors_transmitted * 3], (colors_to_transmit * 3)); + } + else + { + memcpy(&tt_trio_buffer[channel][THERMALTAKE_TRIO_DATA_BYTE], &color_data[colors_transmitted * 3], (THERMALTAKE_TRIO_CHUNK_LENGTH * 3)); + } + + hid_write(dev, tt_trio_buffer[channel], THERMALTAKE_TRIO_PACKET_SIZE); + } + + delete[] color_data; +} + +void ThermaltakeRiingTrioController::SetMode(unsigned char mode, unsigned char speed) +{ + current_mode = mode; + current_speed = speed; +} + +void ThermaltakeRiingTrioController::SendInit() +{ + unsigned char usb_buf[THERMALTAKE_TRIO_PACKET_SIZE]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up Init packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x00; + usb_buf[0x01] = 0xFE; + usb_buf[0x02] = 0x33; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, usb_buf, THERMALTAKE_TRIO_PACKET_SIZE); + hid_read_timeout(dev, usb_buf, THERMALTAKE_TRIO_PACKET_SIZE, THERMALTAKE_TRIO_INTERRUPT_TIMEOUT); +} + diff --git a/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/ThermaltakeRiingTrioController.h b/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/ThermaltakeRiingTrioController.h new file mode 100644 index 00000000..fd06b2e1 --- /dev/null +++ b/Controllers/ThermaltakeRiingController/ThermaltakeRiingTrioController/ThermaltakeRiingTrioController.h @@ -0,0 +1,77 @@ +/*---------------------------------------------------------*\ +| ThermaltakeRiingTrioController.h | +| | +| Driver for Thermaltake Riing Trio | +| | +| Sam B (4rcheria) 24 Nov 2024 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include +#include +#include "RGBController.h" + +#define THERMALTAKE_TRIO_PACKET_SIZE 65 +#define THERMALTAKE_TRIO_INTERRUPT_TIMEOUT 250 +#define THERMALTAKE_TRIO_KEEPALIVE 3 +#define HID_MAX_STR 255 + +enum +{ + THERMALTAKE_TRIO_COMMAND_BYTE = 1, + THERMALTAKE_TRIO_FUNCTION_BYTE = 2, + THERMALTAKE_TRIO_ZONE_BYTE = 3, + THERMALTAKE_TRIO_MODE_BYTE = 4, + THERMALTAKE_TRIO_CHUNK_ID = 6, + THERMALTAKE_TRIO_DATA_BYTE = 8, + THERMALTAKE_TRIO_CHUNK_LENGTH = 19, +}; + +enum +{ + THERMALTAKE_TRIO_MODE_DIRECT = 0x24 +}; + +enum +{ + THERMALTAKE_TRIO_SPEED_EXTREME = 0x00, + THERMALTAKE_TRIO_SPEED_FAST = 0x01, + THERMALTAKE_TRIO_SPEED_NORMAL = 0x02, + THERMALTAKE_TRIO_SPEED_SLOW = 0x03, +}; + +#define THERMALTAKE_TRIO_NUM_CHANNELS 5 + +class ThermaltakeRiingTrioController +{ +public: + ThermaltakeRiingTrioController(hid_device* dev_handle, const char* path); + ~ThermaltakeRiingTrioController(); + + std::string GetDeviceName(); + std::string GetDeviceLocation(); + std::string GetSerial(); + + void SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors); + void SetMode(unsigned char mode, unsigned char speed); + +private: + hid_device* dev; + + unsigned char current_mode; + unsigned char current_speed; + std::string device_name; + std::string location; + + uint8_t tt_trio_buffer[THERMALTAKE_TRIO_NUM_CHANNELS][THERMALTAKE_TRIO_PACKET_SIZE]; + + void SendInit(); + + void SendFan(); + void SendSave(); +};