Rework CoolerMaster ARGB controller so that it doesn't create multiple devices and prepare it for per-zone mode support

master
Adam Honse 2 months ago
parent 81c6ee6270
commit 51edb35e3f

@ -12,16 +12,27 @@
#include "CMARGBController.h" #include "CMARGBController.h"
#include "StringUtils.h" #include "StringUtils.h"
CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx, std::shared_ptr<std::mutex> cm_mutex) /*---------------------------------------------------------*\
| Map to convert port index to port ID used in protocol |
\*---------------------------------------------------------*/
static unsigned char cm_argb_port_index_to_id[5] =
{ {
dev = dev_handle; CM_ARGB_PORT_ARGB_1,
location = _path; CM_ARGB_PORT_ARGB_2,
zone_index = _zone_idx; CM_ARGB_PORT_ARGB_3,
mutex_ptr = cm_mutex; CM_ARGB_PORT_ARGB_4,
CM_ARGB_PORT_RGB
/*---------------------------------------------------------*\ };
| Get device name from HID manufacturer and product strings |
\*---------------------------------------------------------*/ CMARGBController::CMARGBController(hid_device* dev_handle, char *path)
{
dev = dev_handle;
location = path;
/*-----------------------------------------------------*\
| Get device name from HID manufacturer and product |
| strings |
\*-----------------------------------------------------*/
wchar_t name_string[HID_MAX_STR]; wchar_t name_string[HID_MAX_STR];
hid_get_manufacturer_string(dev, name_string, HID_MAX_STR); hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
@ -29,62 +40,43 @@ CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned
hid_get_product_string(dev, name_string, HID_MAX_STR); hid_get_product_string(dev, name_string, HID_MAX_STR);
device_name.append(" ").append(StringUtils::wstring_to_string(name_string)); device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
GetStatus();
} }
CMARGBController::~CMARGBController() CMARGBController::~CMARGBController()
{ {
if(mutex_ptr.use_count() <= 1) hid_close(dev);
{
hid_close(dev);
}
} }
void CMARGBController::GetStatus() std::string CMARGBController::GetDeviceName()
{ {
unsigned char buffer[CM_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x0B, 0x01 }; return(device_name);
int buffer_size = (sizeof(buffer) / sizeof(buffer[0])); }
int rgb_offset = 0;
int zone;
if (argb_header_data[zone_index].digital) std::string CMARGBController::GetLocation()
{
return("HID: " + location);
}
std::string CMARGBController::GetVersion()
{
/*-----------------------------------------------------*\
| This device uses the serial value to determine the |
| version. It does not report a proper unique serial. |
\*-----------------------------------------------------*/
std::string serial_string = GetSerial();
if(serial_string == CM_ARGB_FW0023)
{ {
zone = argb_header_data[zone_index].header; return("0023");
buffer[CM_ARGB_COMMAND_BYTE] = 0x0B; }
else if(serial_string == CM_ARGB_FW0028)
{
return("0028");
} }
else else
{ {
zone = 0x00; return("Unsupported");
buffer[CM_ARGB_COMMAND_BYTE] = 0x0A;
rgb_offset = 1;
} }
/*---------------------------------------------*\
| Guard the writes to the controller until the |
| for loop has completed to avoid collisons |
\*---------------------------------------------*/
std::lock_guard<std::mutex> guard(*mutex_ptr);
/*---------------------------------------------------------*\
| If this is the group then just return the first status |
\*---------------------------------------------------------*/
buffer[CM_ARGB_ZONE_BYTE] = ( zone > 0x08 ) ? 0x01 : zone;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
current_mode = buffer[4 - rgb_offset];
bool_random = ( buffer[5 - rgb_offset] == 0x00 );
current_speed = buffer[6 - rgb_offset];
current_brightness = buffer[7 - rgb_offset];
current_red = buffer[8 - rgb_offset];
current_green = buffer[9 - rgb_offset];
current_blue = buffer[10 - rgb_offset];
}
std::string CMARGBController::GetDeviceName()
{
return(device_name);
} }
std::string CMARGBController::GetSerial() std::string CMARGBController::GetSerial()
@ -100,118 +92,187 @@ std::string CMARGBController::GetSerial()
return(StringUtils::wstring_to_string(serial_string)); return(StringUtils::wstring_to_string(serial_string));
} }
std::string CMARGBController::GetLocation() void CMARGBController::GetPortStatus
(
unsigned char port_idx,
unsigned char* port_mode,
unsigned char* port_speed,
unsigned char* port_brightness,
bool* port_random,
unsigned char* port_red,
unsigned char* port_green,
unsigned char* port_blue
)
{ {
return("HID: " + location); unsigned char buffer[CM_ARGB_PACKET_SIZE] = {0x00, 0x80, 0x0B, 0x01};
} int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
int rgb_offset = 0;
int zone;
unsigned char CMARGBController::GetZoneIndex() /*-----------------------------------------------------*\
{ | RGB port is handled differently from ARGB ports |
return(zone_index); \*-----------------------------------------------------*/
} if(cm_argb_port_index_to_id[port_idx] != CM_ARGB_PORT_RGB)
{
zone = cm_argb_port_index_to_id[port_idx];
buffer[CM_ARGB_COMMAND_BYTE] = 0x0B;
}
else
{
zone = 0x00;
buffer[CM_ARGB_COMMAND_BYTE] = 0x0A;
rgb_offset = 1;
}
unsigned char CMARGBController::GetMode() /*-----------------------------------------------------*\
{ | If this is the group then just return the first |
return(current_mode); | status |
} \*-----------------------------------------------------*/
buffer[CM_ARGB_ZONE_BYTE] = ( zone > 0x08 ) ? 0x01 : zone;
unsigned char CMARGBController::GetLedRed() /*-----------------------------------------------------*\
{ | Send the command and read the response |
return(current_red); \*-----------------------------------------------------*/
} hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
unsigned char CMARGBController::GetLedGreen() /*-----------------------------------------------------*\
{ | Read data out of response |
return(current_green); \*-----------------------------------------------------*/
*port_mode = buffer[4 - rgb_offset];
*port_random = (buffer[5 - rgb_offset] == 0x00);
*port_speed = buffer[6 - rgb_offset];
*port_brightness = buffer[7 - rgb_offset];
*port_red = buffer[8 - rgb_offset];
*port_green = buffer[9 - rgb_offset];
*port_blue = buffer[10 - rgb_offset];
} }
unsigned char CMARGBController::GetLedBlue() void CMARGBController::SetPortLEDCount(unsigned char port_idx, unsigned char led_count)
{ {
return(current_blue); unsigned char buffer[CM_ARGB_PACKET_SIZE] = {0x00, 0x80, 0x0D, 0x02};
} int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
unsigned char CMARGBController::GetLedSpeed() buffer[CM_ARGB_ZONE_BYTE] = cm_argb_port_index_to_id[port_idx];
{ buffer[CM_ARGB_MODE_BYTE] = led_count;
return(current_speed); buffer[CM_ARGB_COLOUR_INDEX_BYTE] = 1;
}
bool CMARGBController::GetRandomColours() /*-----------------------------------------------------*\
{ | Send the command |
return(bool_random); \*-----------------------------------------------------*/
hid_write(dev, buffer, buffer_size);
} }
void CMARGBController::SetLedCount(int zone, int led_count) void CMARGBController::SetPortMode
(
unsigned char port_idx,
unsigned char port_mode,
unsigned char port_speed,
unsigned char port_brightness,
bool port_random,
unsigned char port_red,
unsigned char port_green,
unsigned char port_blue
)
{ {
unsigned char buffer[CM_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x0D, 0x02 }; unsigned char buffer[CM_ARGB_PACKET_SIZE] = {0x00};
int buffer_size = (sizeof(buffer) / sizeof(buffer[0])); int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
bool boolARGB_header = (cm_argb_port_index_to_id[port_idx] != CM_ARGB_PORT_RGB);
bool boolPassthru = (port_mode == CM_ARGB_MODE_PASSTHRU) || (port_mode == CM_RGB_MODE_PASSTHRU);
bool boolDirect = (port_mode == CM_ARGB_MODE_DIRECT);
unsigned char function = boolPassthru ? (boolARGB_header ? 0x02 : 0x04) : (boolARGB_header ? 0x01 : 0x03);
buffer[CM_ARGB_REPORT_BYTE] = 0x80;
buffer[CM_ARGB_COMMAND_BYTE] = 0x01;
buffer[CM_ARGB_ZONE_BYTE] = zone; if(boolDirect)
buffer[CM_ARGB_MODE_BYTE] = led_count; {
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = (0x0F - led_count > 0) ? 0x0F - led_count : 0x01; buffer[CM_ARGB_FUNCTION_BYTE] = 0x01;
buffer[CM_ARGB_ZONE_BYTE] = 0x02;
/*---------------------------------------------*\ /*-------------------------------------------------*\
| Guard the writes to the controller until the | | Send the command |
| for loop has completed to avoid collisons | \*-------------------------------------------------*/
\*---------------------------------------------*/ hid_write(dev, buffer, buffer_size);
std::lock_guard<std::mutex> guard(*mutex_ptr);
hid_write(dev, buffer, buffer_size); /*-------------------------------------------------*\
} | Direct mode is now set up and no other mode |
| packet is required |
\*-------------------------------------------------*/
return;
}
void CMARGBController::SetMode(uint8_t mode, uint8_t speed, uint8_t brightness, RGBColor colour, bool random_colours) buffer[CM_ARGB_FUNCTION_BYTE] = function;
{
bool needs_update = !( (current_mode == mode) && (current_speed == speed) && (current_brightness == brightness) && (ToRGBColor(current_red, current_green, current_blue) == colour)); /*-----------------------------------------------------*\
| Send the command |
\*-----------------------------------------------------*/
hid_write(dev, buffer, buffer_size);
if (needs_update) /*-----------------------------------------------------*\
| ARGB ports send command 0x0B, RGB port sends 0x04 |
\*-----------------------------------------------------*/
if(boolARGB_header)
{ {
current_mode = mode; buffer[CM_ARGB_COMMAND_BYTE] = 0x0B;
current_speed = speed; buffer[CM_ARGB_FUNCTION_BYTE] = (false) ? 0x01 : 0x02;
current_brightness = brightness; buffer[CM_ARGB_ZONE_BYTE] = cm_argb_port_index_to_id[port_idx];
current_red = RGBGetRValue(colour); buffer[CM_ARGB_MODE_BYTE] = port_mode;
current_green = RGBGetGValue(colour); buffer[CM_ARGB_COLOUR_INDEX_BYTE] = port_random ? 0x00 : 0x10;
current_blue = RGBGetBValue(colour); buffer[CM_ARGB_SPEED_BYTE] = port_speed;
bool_random = random_colours; buffer[CM_ARGB_BRIGHTNESS_BYTE] = port_brightness;
buffer[CM_ARGB_RED_BYTE] = port_red;
SendUpdate(); buffer[CM_ARGB_GREEN_BYTE] = port_green;
buffer[CM_ARGB_BLUE_BYTE] = port_blue;
} }
else
{
buffer[CM_ARGB_COMMAND_BYTE] = boolPassthru ? 0x01 : 0x04;
buffer[CM_ARGB_MODE_BYTE + CM_RGB_OFFSET] = port_mode;
buffer[CM_ARGB_COLOUR_INDEX_BYTE + CM_RGB_OFFSET] = port_random ? 0x00 : 0x10;
buffer[CM_ARGB_SPEED_BYTE + CM_RGB_OFFSET] = port_speed;
buffer[CM_ARGB_BRIGHTNESS_BYTE + CM_RGB_OFFSET] = port_brightness;
buffer[CM_ARGB_RED_BYTE + CM_RGB_OFFSET] = port_red;
buffer[CM_ARGB_GREEN_BYTE + CM_RGB_OFFSET] = port_green;
buffer[CM_ARGB_BLUE_BYTE + CM_RGB_OFFSET] = port_blue;
}
/*-----------------------------------------------------*\
| Send the command and wait for response |
\*-----------------------------------------------------*/
hid_write(dev, buffer, buffer_size);
} }
void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_count) void CMARGBController::SetPortLEDsDirect(unsigned char port_idx, RGBColor *led_colours, unsigned int led_count)
{ {
const unsigned char buffer_size = CM_ARGB_PACKET_SIZE; const unsigned char buffer_size = CM_ARGB_PACKET_SIZE;
unsigned char buffer[buffer_size] = { 0x00, 0x00, 0x07, 0x02 }; unsigned char buffer[buffer_size] = { 0x00, 0x00, 0x07, 0x02 };
unsigned char packet_count = 0; unsigned char packet_count = 0;
std::vector<uint8_t> colours; std::vector<uint8_t> colours;
/*---------------------------------------------*\ /*-----------------------------------------------------*\
| Set up the RGB triplets to send | | Set up the RGB triplets to send |
\*---------------------------------------------*/ \*-----------------------------------------------------*/
for(unsigned int i = 0; i < led_count; i++) for(unsigned int i = 0; i < led_count; i++)
{ {
RGBColor colour = led_colours[i]; RGBColor colour = led_colours[i];
colours.push_back( RGBGetRValue(colour) ); colours.push_back(RGBGetRValue(colour));
colours.push_back( RGBGetGValue(colour) ); colours.push_back(RGBGetGValue(colour));
colours.push_back( RGBGetBValue(colour) ); colours.push_back(RGBGetBValue(colour));
} }
buffer[CM_ARGB_FUNCTION_BYTE] = zone_index - 1; buffer[CM_ARGB_FUNCTION_BYTE] = port_idx;
buffer[CM_ARGB_ZONE_BYTE] = led_count; buffer[CM_ARGB_ZONE_BYTE] = led_count;
unsigned char buffer_idx = CM_ARGB_MODE_BYTE; unsigned char buffer_idx = CM_ARGB_MODE_BYTE;
/*---------------------------------------------*\
| Guard the writes to the controller until the |
| for loop has completed to avoid collisons |
\*---------------------------------------------*/
std::lock_guard<std::mutex> guard(*mutex_ptr);
for(std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = CM_ARGB_COMMAND_BYTE) for(std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = CM_ARGB_COMMAND_BYTE)
{ {
/*-----------------------------------------------------------------*\ /*-------------------------------------------------*\
| Fill the write buffer till its full or the colour buffer is empty | | Fill the write buffer till its full or the |
\*-----------------------------------------------------------------*/ | colour buffer is empty |
\*-------------------------------------------------*/
buffer[CM_ARGB_REPORT_BYTE] = packet_count; buffer[CM_ARGB_REPORT_BYTE] = packet_count;
while (( buffer_idx < buffer_size) && ( it != colours.end() )) while((buffer_idx < buffer_size) && (it != colours.end()))
{ {
buffer[buffer_idx] = *it; buffer[buffer_idx] = *it;
buffer_idx++; buffer_idx++;
@ -223,76 +284,15 @@ void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_cou
buffer[CM_ARGB_REPORT_BYTE] += 0x80; buffer[CM_ARGB_REPORT_BYTE] += 0x80;
} }
/*-------------------------------------------------*\
| Send the buffer |
\*-------------------------------------------------*/
hid_write(dev, buffer, buffer_size); hid_write(dev, buffer, buffer_size);
/*-----------------------------------------------------------------*\ /*-------------------------------------------------*\
| Reset the write buffer | | Reset the write buffer |
\*-----------------------------------------------------------------*/ \*-------------------------------------------------*/
memset(buffer, 0x00, buffer_size ); memset(buffer, 0x00, buffer_size );
packet_count++; packet_count++;
} }
} }
void CMARGBController::SendUpdate()
{
/*---------------------------------------------*\
| Guard the writes to the controller |
\*---------------------------------------------*/
std::lock_guard<std::mutex> guard(*mutex_ptr);
unsigned char buffer[CM_ARGB_PACKET_SIZE] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
bool boolARGB_header = argb_header_data[zone_index].digital;
bool boolPassthru = ( current_mode == CM_ARGB_MODE_PASSTHRU ) || ( current_mode == CM_RGB_MODE_PASSTHRU );
bool boolDirect = ( current_mode == CM_ARGB_MODE_DIRECT );
unsigned char function = boolPassthru ? (boolARGB_header ? 0x02 : 0x04) : (boolARGB_header ? 0x01 : 0x03);
buffer[CM_ARGB_REPORT_BYTE] = 0x80;
buffer[CM_ARGB_COMMAND_BYTE] = 0x01;
if(boolDirect)
{
buffer[CM_ARGB_FUNCTION_BYTE] = 0x01;
buffer[CM_ARGB_ZONE_BYTE] = 0x02;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
/*-----------------------------------------------------------------*\
| Direct mode is now set up and no other mode packet is required |
\*-----------------------------------------------------------------*/
return;
}
buffer[CM_ARGB_FUNCTION_BYTE] = function;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
if(boolARGB_header)
{
buffer[CM_ARGB_COMMAND_BYTE] = 0x0B; //ARGB sends 0x0B (1011) RGB sends 0x04 (0100)
buffer[CM_ARGB_FUNCTION_BYTE] = (false) ? 0x01 : 0x02; //This controls direct mode TODO
buffer[CM_ARGB_ZONE_BYTE] = argb_header_data[zone_index].header;
buffer[CM_ARGB_MODE_BYTE] = current_mode;
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = bool_random ? 0x00 : 0x10;
buffer[CM_ARGB_SPEED_BYTE] = current_speed;
buffer[CM_ARGB_BRIGHTNESS_BYTE] = current_brightness;
buffer[CM_ARGB_RED_BYTE] = current_red;
buffer[CM_ARGB_GREEN_BYTE] = current_green;
buffer[CM_ARGB_BLUE_BYTE] = current_blue;
}
else
{
buffer[CM_ARGB_COMMAND_BYTE] = boolPassthru ? 0x01 : 0x04; //ARGB sends 0x0b (1011) RGB sends 0x04 (0100)
buffer[CM_ARGB_MODE_BYTE + CM_RGB_OFFSET] = current_mode;
buffer[CM_ARGB_COLOUR_INDEX_BYTE + CM_RGB_OFFSET] = bool_random ? 0x00 : 0x10;
buffer[CM_ARGB_SPEED_BYTE + CM_RGB_OFFSET] = current_speed;
buffer[CM_ARGB_BRIGHTNESS_BYTE + CM_RGB_OFFSET] = current_brightness;
buffer[CM_ARGB_RED_BYTE + CM_RGB_OFFSET] = current_red;
buffer[CM_ARGB_GREEN_BYTE + CM_RGB_OFFSET] = current_green;
buffer[CM_ARGB_BLUE_BYTE + CM_RGB_OFFSET] = current_blue;
}
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
}

@ -16,19 +16,20 @@
#include <array> #include <array>
#include <memory> #include <memory>
#include <hidapi.h> #include <hidapi.h>
#include "RGBController.h" //Needed to set the direct mode #include "RGBController.h"
#define CM_ARGB_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0])) #define CM_ARGB_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
#define CM_ARGB_HEADER_DATA_SIZE (sizeof(argb_header_data) / sizeof(argb_headers) ) #define CM_ARGB_HEADER_DATA_SIZE (sizeof(argb_header_data) / sizeof(argb_headers) )
#define CM_ARGB_INTERRUPT_TIMEOUT 250 #define CM_ARGB_INTERRUPT_TIMEOUT 250
#define CM_ARGB_PACKET_SIZE 65 #define CM_ARGB_PACKET_SIZE 65
#define CM_ARGB_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ])) #define CM_ARGB_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
#define CM_RGB_OFFSET -2 #define CM_RGB_OFFSET -2
#define HID_MAX_STR 255 #define HID_MAX_STR 255
#define CM_ARGB_BRIGHTNESS_MAX 255 #define CM_ARGB_BRIGHTNESS_MAX 255
#define CM_ARGB_FW0023 std::string("A202011171238") #define CM_ARGB_FW0000 std::string("A201804091608")
#define CM_ARGB_FW0028 std::string("A202105291658") #define CM_ARGB_FW0023 std::string("A202011171238")
#define CM_ARGB_FW0028 std::string("A202105291658")
enum enum
{ {
@ -45,22 +46,13 @@ enum
CM_ARGB_BLUE_BYTE = 11 CM_ARGB_BLUE_BYTE = 11
}; };
struct argb_headers enum
{
const char* name;
unsigned char header;
bool digital;
unsigned int count;
};
static argb_headers argb_header_data[] =
{ {
{ "RGB Header", 0xFE, false, 1 }, CM_ARGB_PORT_ARGB_1 = 0x01,
{ "Digital ARGB1", 0x01, true, 12 }, CM_ARGB_PORT_ARGB_2 = 0x02,
{ "Digital ARGB2", 0x02, true, 12 }, CM_ARGB_PORT_ARGB_3 = 0x04,
{ "Digital ARGB3", 0x04, true, 12 }, CM_ARGB_PORT_ARGB_4 = 0x08,
{ "Digital ARGB4", 0x08, true, 12 }, CM_ARGB_PORT_RGB = 0xFE,
//{ "All Digital ARGB", 0xFF, true, 12 }
}; };
enum enum
@ -101,40 +93,44 @@ enum
class CMARGBController class CMARGBController
{ {
public: public:
CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx, std::shared_ptr<std::mutex> cm_mutex); CMARGBController(hid_device* dev_handle, char* path);
~CMARGBController(); ~CMARGBController();
std::string GetDeviceName(); std::string GetDeviceName();
std::string GetSerial(); std::string GetSerial();
std::string GetLocation(); std::string GetLocation();
std::string GetVersion();
unsigned char GetZoneIndex();
unsigned char GetMode(); void GetPortStatus
unsigned char GetLedRed(); (
unsigned char GetLedGreen(); unsigned char port_idx,
unsigned char GetLedBlue(); unsigned char* port_mode,
unsigned char GetLedSpeed(); unsigned char* port_speed,
bool GetRandomColours(); unsigned char* port_brightness,
void SetLedCount(int zone, int led_count); bool* port_random,
void SetMode(uint8_t mode, uint8_t speed, uint8_t brightness, RGBColor colour, bool random_colours); unsigned char* port_red,
void SetLedsDirect(RGBColor * led_colours, unsigned int led_count); unsigned char* port_green,
unsigned char* port_blue
);
void SetPortLEDCount(unsigned char port_idx, unsigned char led_count);
void SetPortMode
(
unsigned char port_idx,
unsigned char port_mode,
unsigned char port_speed,
unsigned char port_brightness,
bool port_random,
unsigned char port_red,
unsigned char port_green,
unsigned char port_blue
);
void SetPortLEDsDirect(unsigned char port_idx, RGBColor *led_colours, unsigned int led_count);
private: private:
std::string device_name; hid_device* dev;
std::string location; std::string device_name;
hid_device* dev; std::string location;
std::shared_ptr<std::mutex> mutex_ptr;
unsigned char zone_index;
unsigned char current_mode;
unsigned char current_speed;
unsigned char current_red;
unsigned char current_green;
unsigned char current_blue;
unsigned char current_brightness;
bool bool_random;
void GetStatus();
void SendUpdate();
}; };

@ -27,268 +27,220 @@
RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController* controller_ptr) RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController* controller_ptr)
{ {
controller = controller_ptr; controller = controller_ptr;
unsigned char speed = controller->GetLedSpeed();
name = argb_header_data[controller->GetZoneIndex()].name; name = controller->GetDeviceName();
vendor = "Cooler Master"; vendor = "Cooler Master";
type = DEVICE_TYPE_LEDSTRIP; type = DEVICE_TYPE_LEDSTRIP;
description = controller->GetDeviceName(); description = "Cooler Master ARGB Controller Device";
version = "3.0 for FW0028"; version = controller->GetVersion();
serial = controller->GetSerial(); serial = controller->GetSerial();
location = controller->GetLocation(); location = controller->GetLocation();
if(argb_header_data[controller->GetZoneIndex()].digital) /*-----------------------------------------------------*\
{ | The ARGB ports support more modes than the RGB port. |
mode Off; | Define all of the modes the ARGB ports support and |
Off.name = "Turn Off"; | map RGB modes to them as best as we can. Per-zone |
Off.value = CM_ARGB_MODE_OFF; | support will be added in the future. |
Off.color_mode = MODE_COLORS_NONE; \*-----------------------------------------------------*/
modes.push_back(Off); mode Off;
Off.name = "Off";
mode Reload; Off.value = CM_ARGB_MODE_OFF;
Reload.name = "Reload"; Off.color_mode = MODE_COLORS_NONE;
Reload.value = CM_ARGB_MODE_RELOAD; modes.push_back(Off);
Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Reload.colors_min = 1; mode Reload;
Reload.colors_max = 1; Reload.name = "Reload";
Reload.colors.resize(Reload.colors_max); Reload.value = CM_ARGB_MODE_RELOAD;
Reload.brightness_min = 0; Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Reload.brightness_max = CM_ARGB_BRIGHTNESS_MAX; Reload.speed_min = CM_ARGB_SPEED_SLOWEST;
Reload.brightness = CM_ARGB_BRIGHTNESS_MAX; Reload.speed_max = CM_ARGB_SPEED_FASTEST;
Reload.speed_min = CM_ARGB_SPEED_SLOWEST; Reload.speed = CM_ARGB_SPEED_NORMAL;
Reload.speed_max = CM_ARGB_SPEED_FASTEST; Reload.brightness_min = 0;
Reload.color_mode = MODE_COLORS_MODE_SPECIFIC; Reload.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
Reload.speed = speed; Reload.brightness = CM_ARGB_BRIGHTNESS_MAX;
modes.push_back(Reload); Reload.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reload.colors_min = 1;
mode Recoil; Reload.colors_max = 1;
Recoil.name = "Recoil"; Reload.colors.resize(Reload.colors_max);
Recoil.value = CM_ARGB_MODE_RECOIL; modes.push_back(Reload);
Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Recoil.colors_min = 1; mode Recoil;
Recoil.colors_max = 1; Recoil.name = "Recoil";
Recoil.colors.resize(Recoil.colors_max); Recoil.value = CM_ARGB_MODE_RECOIL;
Recoil.brightness_min = 0; Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Recoil.brightness_max = CM_ARGB_BRIGHTNESS_MAX; Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC;
Recoil.brightness = CM_ARGB_BRIGHTNESS_MAX; Recoil.speed_min = CM_ARGB_SPEED_SLOWEST;
Recoil.speed_min = CM_ARGB_SPEED_SLOWEST; Recoil.speed_max = CM_ARGB_SPEED_FASTEST;
Recoil.speed_max = CM_ARGB_SPEED_FASTEST; Recoil.speed = CM_ARGB_SPEED_NORMAL;
Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC; Recoil.brightness_min = 0;
Recoil.speed = speed; Recoil.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
modes.push_back(Recoil); Recoil.brightness = CM_ARGB_BRIGHTNESS_MAX;
Recoil.colors_min = 1;
mode Breathing; Recoil.colors_max = 1;
Breathing.name = "Breathing"; Recoil.colors.resize(Recoil.colors_max);
Breathing.value = CM_ARGB_MODE_BREATHING; modes.push_back(Recoil);
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.colors_min = 1; mode Breathing;
Breathing.colors_max = 1; Breathing.name = "Breathing";
Breathing.colors.resize(Breathing.colors_max); Breathing.value = CM_ARGB_MODE_BREATHING;
Breathing.brightness_min = 0; Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.brightness_max = CM_ARGB_BRIGHTNESS_MAX; Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.brightness = CM_ARGB_BRIGHTNESS_MAX; Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST; Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
Breathing.speed_max = CM_ARGB_SPEED_FASTEST; Breathing.speed = CM_ARGB_SPEED_NORMAL;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; Breathing.brightness_min = 0;
Breathing.speed = speed; Breathing.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
modes.push_back(Breathing); Breathing.brightness = CM_ARGB_BRIGHTNESS_MAX;
Breathing.colors_min = 1;
mode Refill; Breathing.colors_max = 1;
Refill.name = "Refill"; Breathing.colors.resize(Breathing.colors_max);
Refill.value = CM_ARGB_MODE_REFILL; modes.push_back(Breathing);
Refill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Refill.colors_min = 1; mode Refill;
Refill.colors_max = 1; Refill.name = "Refill";
Refill.colors.resize(Refill.colors_max); Refill.value = CM_ARGB_MODE_REFILL;
Refill.brightness_min = 0; Refill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Refill.brightness_max = CM_ARGB_BRIGHTNESS_MAX; Refill.color_mode = MODE_COLORS_MODE_SPECIFIC;
Refill.brightness = CM_ARGB_BRIGHTNESS_MAX; Refill.speed_min = CM_ARGB_SPEED_SLOWEST;
Refill.speed_min = CM_ARGB_SPEED_SLOWEST; Refill.speed_max = CM_ARGB_SPEED_FASTEST;
Refill.speed_max = CM_ARGB_SPEED_FASTEST; Refill.speed = CM_ARGB_SPEED_NORMAL;
Refill.color_mode = MODE_COLORS_MODE_SPECIFIC; Refill.brightness_min = 0;
Refill.speed = speed; Refill.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
modes.push_back(Refill); Refill.brightness = CM_ARGB_BRIGHTNESS_MAX;
Refill.colors_min = 1;
mode Demo; Refill.colors_max = 1;
Demo.name = "Demo"; Refill.colors.resize(Refill.colors_max);
Demo.value = CM_ARGB_MODE_DEMO; modes.push_back(Refill);
Demo.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Demo.brightness_min = 0; mode Demo;
Demo.brightness_max = CM_ARGB_BRIGHTNESS_MAX; Demo.name = "Demo";
Demo.brightness = CM_ARGB_BRIGHTNESS_MAX; Demo.value = CM_ARGB_MODE_DEMO;
Demo.speed_min = CM_ARGB_SPEED_SLOWEST; Demo.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Demo.speed_max = CM_ARGB_SPEED_FASTEST; Demo.color_mode = MODE_COLORS_NONE;
Demo.color_mode = MODE_COLORS_NONE; Demo.speed_min = CM_ARGB_SPEED_SLOWEST;
Demo.speed = speed; Demo.speed_max = CM_ARGB_SPEED_FASTEST;
modes.push_back(Demo); Demo.speed = CM_ARGB_SPEED_NORMAL;
Demo.brightness_min = 0;
mode Spectrum; Demo.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
Spectrum.name = "Spectrum"; Demo.brightness = CM_ARGB_BRIGHTNESS_MAX;
Spectrum.value = CM_ARGB_MODE_SPECTRUM; modes.push_back(Demo);
Spectrum.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Spectrum.brightness_min = 0; mode Spectrum;
Spectrum.brightness_max = CM_ARGB_BRIGHTNESS_MAX; Spectrum.name = "Rainbow Wave";
Spectrum.brightness = CM_ARGB_BRIGHTNESS_MAX; Spectrum.value = CM_ARGB_MODE_SPECTRUM;
Spectrum.speed_min = CM_ARGB_SPEED_SLOWEST; Spectrum.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Spectrum.speed_max = CM_ARGB_SPEED_FASTEST; Spectrum.color_mode = MODE_COLORS_NONE;
Spectrum.color_mode = MODE_COLORS_NONE; Spectrum.speed_min = CM_ARGB_SPEED_SLOWEST;
Spectrum.speed = speed; Spectrum.speed_max = CM_ARGB_SPEED_FASTEST;
modes.push_back(Spectrum); Spectrum.speed = CM_ARGB_SPEED_NORMAL;
Spectrum.brightness_min = 0;
mode FillFlow; Spectrum.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
FillFlow.name = "Fill Flow"; Spectrum.brightness = CM_ARGB_BRIGHTNESS_MAX;
FillFlow.value = CM_ARGB_MODE_FILLFLOW; modes.push_back(Spectrum);
FillFlow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
FillFlow.brightness_min = 0; mode FillFlow;
FillFlow.brightness_max = CM_ARGB_BRIGHTNESS_MAX; FillFlow.name = "Fill Flow";
FillFlow.brightness = CM_ARGB_BRIGHTNESS_MAX; FillFlow.value = CM_ARGB_MODE_FILLFLOW;
FillFlow.speed_min = CM_ARGB_SPEED_SLOWEST; FillFlow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
FillFlow.speed_max = CM_ARGB_SPEED_FASTEST; FillFlow.color_mode = MODE_COLORS_NONE;
FillFlow.color_mode = MODE_COLORS_NONE; FillFlow.speed_min = CM_ARGB_SPEED_SLOWEST;
FillFlow.speed = speed; FillFlow.speed_max = CM_ARGB_SPEED_FASTEST;
modes.push_back(FillFlow); FillFlow.speed = CM_ARGB_SPEED_NORMAL;
FillFlow.brightness_min = 0;
mode Rainbow; FillFlow.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
Rainbow.name = "Rainbow"; FillFlow.brightness = CM_ARGB_BRIGHTNESS_MAX;
Rainbow.value = CM_ARGB_MODE_RAINBOW; modes.push_back(FillFlow);
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Rainbow.brightness_min = 0; mode Rainbow;
Rainbow.brightness_max = CM_ARGB_BRIGHTNESS_MAX; Rainbow.name = "Rainbow";
Rainbow.brightness = CM_ARGB_BRIGHTNESS_MAX; Rainbow.value = CM_ARGB_MODE_RAINBOW;
Rainbow.speed_min = CM_ARGB_SPEED_SLOWEST; Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Rainbow.speed_max = CM_ARGB_SPEED_FASTEST; Rainbow.color_mode = MODE_COLORS_NONE;
Rainbow.color_mode = MODE_COLORS_NONE; Rainbow.speed_min = CM_ARGB_SPEED_SLOWEST;
Rainbow.speed = speed; Rainbow.speed_max = CM_ARGB_SPEED_FASTEST;
modes.push_back(Rainbow); Rainbow.speed = CM_ARGB_SPEED_NORMAL;
Rainbow.brightness_min = 0;
mode Static; Rainbow.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
Static.name = "Static"; Rainbow.brightness = CM_ARGB_BRIGHTNESS_MAX;
Static.value = CM_ARGB_MODE_STATIC; modes.push_back(Rainbow);
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Static.colors_min = 1; mode Static;
Static.colors_max = 1; Static.name = "Static";
Static.colors.resize(Static.colors_max); Static.value = CM_ARGB_MODE_STATIC;
Static.brightness_min = 0; Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Static.brightness_max = CM_ARGB_BRIGHTNESS_MAX; Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.brightness = CM_ARGB_BRIGHTNESS_MAX; Static.speed_min = CM_ARGB_SPEED_SLOWEST;
Static.speed_min = CM_ARGB_SPEED_SLOWEST; Static.speed_max = CM_ARGB_SPEED_FASTEST;
Static.speed_max = CM_ARGB_SPEED_FASTEST; Static.speed = CM_ARGB_SPEED_NORMAL;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC; Static.brightness_min = 0;
Static.speed = speed; Static.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
modes.push_back(Static); Static.brightness = CM_ARGB_BRIGHTNESS_MAX;
Static.colors_min = 1;
mode Direct; Static.colors_max = 1;
Direct.name = (serial >= CM_ARGB_FW0028) ? "Direct" : "Custom"; Static.colors.resize(Static.colors_max);
Direct.value = CM_ARGB_MODE_DIRECT; modes.push_back(Static);
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED; mode Direct;
modes.push_back(Direct); Direct.name = (serial >= CM_ARGB_FW0028) ? "Direct" : "Custom";
Direct.value = CM_ARGB_MODE_DIRECT;
mode PassThru; Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
PassThru.name = "Pass Thru"; Direct.color_mode = MODE_COLORS_PER_LED;
PassThru.value = CM_ARGB_MODE_PASSTHRU; modes.push_back(Direct);
PassThru.flags = 0;
PassThru.color_mode = MODE_COLORS_NONE; mode PassThru;
modes.push_back(PassThru); PassThru.name = "Pass Thru";
} PassThru.value = CM_ARGB_MODE_PASSTHRU;
else PassThru.flags = 0;
{ PassThru.color_mode = MODE_COLORS_NONE;
mode Static; modes.push_back(PassThru);
Static.name = "Static";
Static.value = CM_RGB_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(Static.colors_max);
Static.brightness_min = 0;
Static.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
Static.brightness = CM_ARGB_BRIGHTNESS_MAX;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.speed = 0;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_RGB_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(Breathing.colors_max);
Breathing.brightness_min = 0;
Breathing.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
Breathing.brightness = CM_ARGB_BRIGHTNESS_MAX;
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.speed = CM_ARGB_SPEED_NORMAL;
modes.push_back(Breathing);
mode Flash;
Flash.name = "Flash";
Flash.value = CM_RGB_MODE_FLASH;
Flash.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Flash.colors_min = 1;
Flash.colors_max = 1;
Flash.colors.resize(Flash.colors_max);
Flash.brightness_min = 0;
Flash.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
Flash.brightness = CM_ARGB_BRIGHTNESS_MAX;
Flash.speed_min = CM_ARGB_SPEED_SLOWEST;
Flash.speed_max = CM_ARGB_SPEED_FASTEST;
Flash.color_mode = MODE_COLORS_MODE_SPECIFIC;
Flash.speed = CM_ARGB_SPEED_NORMAL;
modes.push_back(Flash);
mode Mirage;
Mirage.name = "Mirage";
Mirage.value = CM_RGB_MODE_MIRAGE;
Mirage.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Mirage.colors_min = 1;
Mirage.colors_max = 1;
Mirage.colors.resize(Mirage.colors_max);
Mirage.brightness_min = 0;
Mirage.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
Mirage.brightness = CM_ARGB_BRIGHTNESS_MAX;
Mirage.speed_min = CM_ARGB_SPEED_SLOWEST;
Mirage.speed_max = CM_ARGB_SPEED_FASTEST;
Mirage.color_mode = MODE_COLORS_MODE_SPECIFIC;
Mirage.speed = CM_ARGB_SPEED_NORMAL;
modes.push_back(Mirage);
mode PassThru;
PassThru.name = "Pass Thru";
PassThru.value = CM_RGB_MODE_PASSTHRU;
PassThru.color_mode = MODE_COLORS_NONE;
modes.push_back(PassThru);
mode Off;
Off.name = "Turn Off";
Off.value = CM_RGB_MODE_OFF;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
}
Init_Controller();
SetupZones(); SetupZones();
int temp_mode = controller->GetMode(); /*-----------------------------------------------------*\
for(int mode_idx = 0; mode_idx < (int)modes.size() ; mode_idx++) | Initialize the active mode to port 0 |
\*-----------------------------------------------------*/
unsigned char port_mode;
unsigned char port_speed;
unsigned char port_brightness;
bool port_random;
unsigned char port_red;
unsigned char port_green;
unsigned char port_blue;
controller->GetPortStatus(0, &port_mode, &port_speed, &port_brightness, &port_random, &port_red, &port_green, &port_blue);
for(std::size_t mode_idx = 0; mode_idx < modes.size(); mode_idx++)
{ {
if (temp_mode == modes[mode_idx].value) if(modes[mode_idx].value == port_mode)
{ {
active_mode = mode_idx; active_mode = mode_idx;
if((modes[mode_idx].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR) && (modes[mode_idx].colors.size() > 0))
{
modes[mode_idx].colors[0] = ToRGBColor(port_red, port_green, port_blue);
}
if(modes[mode_idx].flags & MODE_FLAG_HAS_SPEED)
{
modes[mode_idx].speed = port_speed;
}
if(modes[mode_idx].flags & MODE_FLAG_HAS_BRIGHTNESS)
{
modes[mode_idx].brightness = port_brightness;
}
if(modes[mode_idx].flags & MODE_FLAG_HAS_RANDOM_COLOR)
{
if(port_random)
{
modes[mode_idx].color_mode = MODE_COLORS_RANDOM;
}
}
break; break;
} }
} }
if (modes[active_mode].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
{
modes[active_mode].colors[0] = ToRGBColor(controller->GetLedRed(), controller->GetLedGreen(), controller->GetLedBlue());
modes[active_mode].color_mode = (controller->GetRandomColours()) ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
}
if (modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
modes[active_mode].speed = controller->GetLedSpeed();
}
} }
RGBController_CMARGBController::~RGBController_CMARGBController() RGBController_CMARGBController::~RGBController_CMARGBController()
@ -296,68 +248,76 @@ RGBController_CMARGBController::~RGBController_CMARGBController()
delete controller; delete controller;
} }
void RGBController_CMARGBController::Init_Controller()
{
int zone_idx = controller->GetZoneIndex();
int zone_led_count = argb_header_data[zone_idx].count;
/*-------------------------------------------------*\
| If argb_header_data[zone_idx].count == 1 then the |
| zone is ZONE_TYPE_SINGLE |
\*-------------------------------------------------*/
bool boolSingleLED = ( zone_led_count == 1 );
zone ARGB_zone;
ARGB_zone.name = std::to_string(zone_idx);
ARGB_zone.type = (boolSingleLED) ? ZONE_TYPE_SINGLE : ZONE_TYPE_LINEAR;
ARGB_zone.leds_min = 4;
ARGB_zone.leds_max = 48;
ARGB_zone.leds_count = zone_led_count;
ARGB_zone.matrix_map = NULL;
zones.push_back(ARGB_zone);
}
void RGBController_CMARGBController::SetupZones() void RGBController_CMARGBController::SetupZones()
{ {
/*-------------------------------------------------*\ /*-----------------------------------------------------*\
| Clear any existing color/LED configuration | | 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(); leds.clear();
colors.clear(); colors.clear();
zones.resize(5);
/*---------------------------------------------------------*\ /*-----------------------------------------------------*\
| Set up zones | | Set up addressable zones |
\*---------------------------------------------------------*/ \*-----------------------------------------------------*/
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) for(unsigned int channel_idx = 0; channel_idx < 4; channel_idx++)
{ {
bool boolSingleLED = (zones[zone_idx].type == ZONE_TYPE_SINGLE); char ch_idx_string[2];
snprintf(ch_idx_string, 2, "%d", channel_idx + 1);
if (!boolSingleLED) zones[channel_idx].name = "Addressable RGB Header ";
zones[channel_idx].name.append(ch_idx_string);
zones[channel_idx].type = ZONE_TYPE_LINEAR;
zones[channel_idx].leds_min = 0;
zones[channel_idx].leds_max = 48;
if(first_run)
{ {
controller->SetLedCount( std::stoi(zones[zone_idx].name), zones[zone_idx].leds_count); zones[channel_idx].leds_count = 0;
} }
for(unsigned int lp_idx = 0; lp_idx < zones[zone_idx].leds_count; lp_idx++) zones[channel_idx].matrix_map = NULL;
for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
{ {
led new_led; char led_idx_string[4];
unsigned int i = std::stoi(zones[zone_idx].name); snprintf(led_idx_string, 4, "%d", led_ch_idx + 1);
if(boolSingleLED) led new_led;
{ new_led.name = zones[channel_idx].name;
new_led.name = i; new_led.name.append(", LED ");
new_led.value = argb_header_data[i].header; new_led.name.append(led_idx_string);
} new_led.value = channel_idx;
else
{
new_led.name = i;
new_led.name.append(" LED " + std::to_string(lp_idx));
new_led.value = argb_header_data[i].header;
}
leds.push_back(new_led); leds.push_back(new_led);
} }
} }
/*-----------------------------------------------------*\
| Set up RGB zone |
\*-----------------------------------------------------*/
zones[4].name = "RGB Header";
zones[4].type = ZONE_TYPE_SINGLE;
zones[4].leds_min = 1;
zones[4].leds_max = 1;
zones[4].leds_count = 1;
zones[4].matrix_map = NULL;
led new_led;
new_led.name = "RGB Header";
new_led.value = 4;
leds.push_back(new_led);
SetupColors(); SetupColors();
} }
@ -367,24 +327,20 @@ void RGBController_CMARGBController::ResizeZone(int zone, int new_size)
{ {
return; return;
} }
uint8_t end_zone = last_zone(zone);
for(std::size_t zone_idx = first_zone(zone); zone_idx < end_zone; zone_idx++) if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
{ {
if(((unsigned int)new_size >= zones[zone_idx].leds_min) && ((unsigned int)new_size <= zones[zone_idx].leds_max)) zones[zone].leds_count = new_size;
{
zones[zone_idx].leds_count = new_size;
}
}
SetupZones(); controller->SetPortLEDCount(zone, zones[zone].leds_count);
SetupZones();
}
} }
void RGBController_CMARGBController::DeviceUpdateLEDs() void RGBController_CMARGBController::DeviceUpdateLEDs()
{ {
uint8_t end_zone = last_zone(cmargb->GetZoneIndex()); for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
for(int zone_idx = first_zone(cmargb->GetZoneIndex()); zone_idx < end_zone; zone_idx++)
{ {
UpdateZoneLEDs(zone_idx); UpdateZoneLEDs(zone_idx);
} }
@ -392,37 +348,93 @@ void RGBController_CMARGBController::DeviceUpdateLEDs()
void RGBController_CMARGBController::UpdateZoneLEDs(int zone) void RGBController_CMARGBController::UpdateZoneLEDs(int zone)
{ {
controller->SetLedsDirect( zones[zone].colors, zones[zone].leds_count ); /*-----------------------------------------------------*\
| The RGB zone doesn't have a separate Direct mode, so |
| use static mode with the per-LED color for it |
\*-----------------------------------------------------*/
if(zone < 4)
{
controller->SetPortLEDsDirect(zone, zones[zone].colors, zones[zone].leds_count);
}
else
{
controller->SetPortMode(zone, CM_RGB_MODE_STATIC, 0, 255, false, RGBGetRValue(zones[zone].colors[0]), RGBGetGValue(zones[zone].colors[0]), RGBGetBValue(zones[zone].colors[0]));
}
} }
void RGBController_CMARGBController::UpdateSingleLED(int led) void RGBController_CMARGBController::UpdateSingleLED(int led)
{ {
UpdateZoneLEDs(GetLED_Zone(led)); unsigned int zone_idx = leds[led].value;
UpdateZoneLEDs(zone_idx);
} }
void RGBController_CMARGBController::DeviceUpdateMode() void RGBController_CMARGBController::DeviceUpdateMode()
{ {
bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM); /*-----------------------------------------------------*\
RGBColor colour = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0; | Determine mode parameters |
\*-----------------------------------------------------*/
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
RGBColor color = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
int rgb_mode;
bool rgb_random = random;
/*-----------------------------------------------------*\
| Map ARGB modes with the equivalent RGB modes |
\*-----------------------------------------------------*/
switch(modes[active_mode].value)
{
case CM_ARGB_MODE_SPECTRUM:
case CM_ARGB_MODE_FILLFLOW:
case CM_ARGB_MODE_RAINBOW:
rgb_mode = CM_RGB_MODE_MIRAGE;
rgb_random = true;
break;
controller->SetMode( modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, colour, random_colours ); case CM_ARGB_MODE_RELOAD:
} case CM_ARGB_MODE_RECOIL:
rgb_mode = CM_RGB_MODE_FLASH;
break;
int RGBController_CMARGBController::GetLED_Zone(int led_idx) case CM_ARGB_MODE_BREATHING:
{ rgb_mode = CM_RGB_MODE_BREATHING;
/*---------------------------------------------------------*\ break;
| This may be more useful in the abstract RGBController.cpp |
\*---------------------------------------------------------*/
for(int zone_idx = 0; zone_idx < (int)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) case CM_ARGB_MODE_REFILL:
{ case CM_ARGB_MODE_STATIC:
return(zone_idx); rgb_mode = CM_RGB_MODE_STATIC;
} break;
case CM_ARGB_MODE_DEMO:
rgb_mode = CM_RGB_MODE_FLASH;
rgb_random = true;
break;
case CM_ARGB_MODE_OFF:
default:
rgb_mode = CM_RGB_MODE_OFF;
break;
case CM_ARGB_MODE_PASSTHRU:
rgb_mode = CM_RGB_MODE_PASSTHRU;
break;
} }
return -1; /*-----------------------------------------------------*\
| Apply mode to all zones |
\*-----------------------------------------------------*/
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
controller->SetPortMode
(
zone_idx,
(zone_idx == 4) ? rgb_mode : modes[active_mode].value,
modes[active_mode].speed,
modes[active_mode].brightness,
(zone_idx == 4) ? rgb_random : random,
RGBGetRValue(color),
RGBGetGValue(color),
RGBGetBValue(color)
);
}
} }

@ -12,11 +12,8 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include "RGBController.h"
#include "CMARGBController.h" #include "CMARGBController.h"
#include "RGBController.h"
#define first_zone(zn) ((zones.size() > 1) ? 1 : 0)
#define last_zone(zn) ((zones.size() > 1) ? 4 : 1)
class RGBController_CMARGBController : public RGBController class RGBController_CMARGBController : public RGBController
{ {
@ -34,9 +31,6 @@ public:
void DeviceUpdateMode(); void DeviceUpdateMode();
private: private:
void Init_Controller(); CMARGBController* controller;
int GetDeviceMode(); std::vector<unsigned int> leds_channel;
int GetLED_Zone(int led_idx);
CMARGBController* controller;
}; };

@ -96,19 +96,18 @@ void DetectCoolerMasterARGB(hid_device_info* info, const std::string&)
if(dev) if(dev)
{ {
/*-------------------------------------------------*\ CMARGBController* controller = new CMARGBController(dev, info->path);
| Create mutex to prevent the controllers sharing a |
| receiver from interfering with each other |
\*-------------------------------------------------*/
std::shared_ptr<std::mutex> cm_mutex = std::make_shared<std::mutex>();
for(unsigned char i = 0; i < CM_ARGB_HEADER_DATA_SIZE; i++) if(controller->GetVersion() != "Unsupported")
{ {
CMARGBController* controller = new CMARGBController(dev, info->path, i, cm_mutex);
RGBController_CMARGBController* rgb_controller = new RGBController_CMARGBController(controller); RGBController_CMARGBController* rgb_controller = new RGBController_CMARGBController(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller); ResourceManager::get()->RegisterRGBController(rgb_controller);
} }
else
{
LOG_ERROR("[CMARGBController] Unsupported firmware version");
delete controller;
}
} }
} }

Loading…
Cancel
Save