Updated CM ARGB Controller to v0023 protocol

* All RGB Modes are working
* All ARGB Modes are working sans Direct
* Direct Mode left available so zones are resizable

Commits squashed and amended for code style by Adam Honse <calcprogrammer1@gmail.com>
This commit is contained in:
Chris 2021-02-05 15:34:23 +11:00 committed by Adam Honse
parent 1cd0269f60
commit e46325cbea
4 changed files with 298 additions and 187 deletions

View file

@ -18,12 +18,6 @@ static unsigned char argb_colour_index_data[2][2][2] =
{ 0x04, 0x07 }, } //G1 R1
};
static unsigned char argb_mode_data[2][9] =
{
{ 0x05, 0x01, 0x02, 0x03, 0x04, 0x01, 0x01, 0x01, 0x01 }, //12v RGB Mode values
{ 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x09 } //5v ARGB Mode values
};
CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx)
{
const int szTemp = 256;
@ -32,7 +26,6 @@ CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned
dev = dev_handle;
location = _path;
zone_index = _zone_idx;
current_speed = CM_ARGB_SPEED_NORMAL;
hid_get_manufacturer_string(dev, tmpName, szTemp);
std::wstring wName = std::wstring(tmpName);
@ -56,28 +49,37 @@ CMARGBController::~CMARGBController()
void CMARGBController::GetStatus()
{
unsigned char buffer[0x40] = { 0x00 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
int header = zone_index - 1;
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;
/*buffer[CM_ARGB_REPORT_BYTE] = 0x80;
buffer[CM_ARGB_COMMAND_BYTE] = 0x01;
buffer[CM_ARGB_FUNCTION_BYTE] = 0x01;
if (argb_header_data[zone_index].digital)
{
zone = argb_header_data[zone_index].header;
buffer[CM_ARGB_COMMAND_BYTE] = 0x0B;
}
else
{
zone = 0x00;
buffer[CM_ARGB_COMMAND_BYTE] = 0x0A;
rgb_offset = 1;
}
/*---------------------------------------------------------*\
| 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);
buffer[CM_ARGB_COMMAND_BYTE] = 0x0b;
buffer[CM_ARGB_FUNCTION_BYTE] = 0x03;
buffer[CM_ARGB_ZONE_BYTE] = 0xFF;
hid_write(dev, buffer, buffer_size);
int i = 0;
do{
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
i++;
}while( (i < 4) );
current_mode = argb_mode_data[1][buffer[4]];
current_speed = buffer[5];*/
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()
@ -125,6 +127,11 @@ unsigned char CMARGBController::GetLedSpeed()
return current_speed;
}
bool CMARGBController::GetRandomColours()
{
return bool_random;
}
unsigned int CMARGBController::GetLargestColour(unsigned int red, unsigned int green, unsigned int blue)
{
unsigned int largest;
@ -142,65 +149,79 @@ unsigned int CMARGBController::GetLargestColour(unsigned int red, unsigned int g
unsigned char CMARGBController::GetColourIndex(unsigned char red, unsigned char green, unsigned char blue)
{
//The Coolermaster ARGB controller uses a limited colour pallette referenced by an index
//Starting at 0x00 Random, 0x01 Red, 0x02 Green, 0x03 Blue, 0x04 Yellow, 0x05 Purple, 0x06 Cyan, 0x07 White
//The index can be calculated by normalising the input colour, rounding those values
//and using them as the indicies of a 3d array containing the correct index
/*---------------------------------------------------------------------------------------------------------*\
| The Cooler Master ARGB controller V0008 uses a limited colour pallette referenced by an index |
| Starting at 0x00 Random, 0x01 Red, 0x02 Green, 0x03 Blue, 0x04 Yellow, 0x05 Purple, 0x06 Cyan, 0x07 White |
| The index can be calculated by normalising the input colour, rounding those values |
| and using them as the indicies of a 3d array containing the correct index |
\*---------------------------------------------------------------------------------------------------------*/
unsigned int divisor = GetLargestColour( red, green, blue);
unsigned int r = round( red / divisor );
unsigned int g = round( green / divisor );
unsigned int b = round( blue / divisor );
unsigned char idx = argb_colour_index_data[r][g][b];
return idx;
}
void CMARGBController::SetMode(unsigned char mode, unsigned char speed)
void CMARGBController::SetLedCount(int zone, int led_count)
{
current_mode = mode;
current_speed = speed;
unsigned char buffer[CM_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x0D, 0x02 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
SendUpdate();
buffer[CM_ARGB_ZONE_BYTE] = zone;
buffer[CM_ARGB_MODE_BYTE] = led_count;
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = (0x0F - led_count > 0) ? 0x0F - led_count : 0x01;
hid_write(dev, buffer, buffer_size);
}
void CMARGBController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
void CMARGBController::SetMode(unsigned char mode, unsigned char speed, RGBColor colour, bool random_colours)
{
current_red = red;
current_green = green;
current_blue = blue;
bool needs_update = !( (current_mode == mode) && (current_speed == speed) && (current_brightness == 0xFF) && (ToRGBColor(current_red, current_green, current_blue) == colour));
SendUpdate();
if (needs_update)
{
current_mode = mode;
current_speed = speed;
current_brightness = 0xFF;
current_red = RGBGetRValue(colour);
current_green = RGBGetGValue(colour);
current_blue = RGBGetBValue(colour);
bool_random = random_colours;
SendUpdate();
}
}
void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_count)
{
const unsigned char buffer_size = 0x41;
unsigned char buffer[buffer_size] = { 0x00 };
unsigned char packet_count = 0x00;
const unsigned char buffer_size = CM_ARGB_PACKET_SIZE;
unsigned char buffer[buffer_size] = { 0x00, 0x10, 0x02 };
unsigned char packet_count = 0;
std::vector<unsigned char> colours;
//Set up the RGB triplets to send
/*---------------------------------------------*\
| Set up the RGB triplets to send |
\*---------------------------------------------*/
for(int i = 0; i < led_count; i++)
{
RGBColor colour = led_colours[i];
unsigned char r = RGBGetRValue(colour);
unsigned char g = RGBGetGValue(colour);
unsigned char b = RGBGetBValue(colour);
colours.push_back(r);
colours.push_back(g);
colours.push_back(b);
colours.push_back( RGBGetRValue(colour) );
colours.push_back( RGBGetGValue(colour) );
colours.push_back( RGBGetBValue(colour) );
}
//buffer[CM_ARGB_REPORT_BYTE] = packet_count;
buffer[CM_ARGB_COMMAND_BYTE] = 0x10;
buffer[CM_ARGB_FUNCTION_BYTE] = 0x02;
buffer[CM_ARGB_ZONE_BYTE] = argb_header_data[zone_index].header;
buffer[CM_ARGB_MODE_BYTE] = 0x30; //30 might be the LED count??
unsigned char buffer_idx = CM_ARGB_MODE_BYTE + 1; //Start colour info from
buffer[CM_ARGB_MODE_BYTE] = led_count;
unsigned char buffer_idx = CM_ARGB_MODE_BYTE + 1;
for (std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = 0)
for(std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = 0)
{
//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;
while (( buffer_idx < buffer_size) && ( it != colours.end() ))
{
@ -212,17 +233,20 @@ void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_cou
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
//reset the write buffer
memset(buffer, 0x00, sizeof(buffer) );
/*-----------------------------------------------------------------*\
| Reset the write buffer |
\*-----------------------------------------------------------------*/
memset(buffer, 0x00, buffer_size );
packet_count++;
}
buffer[CM_ARGB_REPORT_BYTE] = 0x82;
buffer[CM_ARGB_COMMAND_BYTE] = 0x62;
/*buffer[CM_ARGB_COMMAND_BYTE] = 0x62;
buffer[CM_ARGB_FUNCTION_BYTE] = 0x00;
buffer[CM_ARGB_ZONE_BYTE] = 0x73;
buffer[CM_ARGB_MODE_BYTE] = 0x00;
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = 0x33;
buffer[CM_ARGB_SPEED_BYTE] = 0x1B;
buffer[CM_ARGB_SPEED_BYTE] = 0x1B;*/
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
@ -230,52 +254,53 @@ void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_cou
void CMARGBController::SendUpdate()
{
unsigned char buffer[0x40] = { 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 );
bool boolDirect = ( current_mode == CM_ARGB_MODE_DIRECT );
unsigned char function = boolPassthru ? 0x02 : ( boolARGB_header ? 0x03 : 0x01);
buffer[CM_ARGB_REPORT_BYTE] = 0x80;
buffer[CM_ARGB_COMMAND_BYTE] = boolDirect ? 0x10 : 0x01;
buffer[CM_ARGB_FUNCTION_BYTE] = boolDirect ? 0x01 : function;
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;
buffer[CM_ARGB_FUNCTION_BYTE] = boolDirect ? 0x01 : function;
if ( boolDirect )
{
buffer[CM_ARGB_COMMAND_BYTE] = 0x10;
buffer[CM_ARGB_FUNCTION_BYTE] = 0x01;
buffer[CM_ARGB_ZONE_BYTE] = argb_header_data[zone_index].header;
buffer[CM_ARGB_MODE_BYTE] = 0x30; //30 might be the LED count??
//hid_write(dev, buffer, buffer_size);
//hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
}
else
{
buffer[CM_ARGB_COMMAND_BYTE] = 0x01;
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 )
/*-----------------------------------------------------------------*\
| Direct mode is now set up and no other mode packet is required |
\*-----------------------------------------------------------------*/
if(boolDirect)
{
buffer[CM_ARGB_COMMAND_BYTE] = 0x0b; //ARGB sends 0x0b (1011) RGB sends 0x04 (0100)
buffer[CM_ARGB_FUNCTION_BYTE] = (false) ? 0x01 : 0x02; //This controls custom mode TODO
buffer[CM_ARGB_ZONE_BYTE] = argb_header_data[zone_index].header;
buffer[CM_ARGB_MODE_BYTE] = argb_mode_data[1][current_mode];
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = GetColourIndex( current_red, current_green, current_blue );
buffer[CM_ARGB_SPEED_BYTE] = current_speed;
return;
}
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;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
}
else
{
buffer[CM_ARGB_COMMAND_BYTE] = 0x04; //ARGB sends 0x0b (1011) RGB sends 0x04 (0100)
buffer[CM_ARGB_MODE_BYTE + CM_RGB_OFFSET] = argb_mode_data[0][current_mode];
buffer[CM_ARGB_COLOUR_INDEX_BYTE + CM_RGB_OFFSET] = GetColourIndex( current_red, current_green, current_blue );
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);

View file

@ -20,6 +20,7 @@
#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_INTERRUPT_TIMEOUT 250
#define CM_ARGB_PACKET_SIZE 65
#define CM_ARGB_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
#define CM_RGB_OFFSET -2
#define HID_MAX_STR 255
@ -32,7 +33,11 @@ enum
CM_ARGB_ZONE_BYTE = 4,
CM_ARGB_MODE_BYTE = 5,
CM_ARGB_COLOUR_INDEX_BYTE = 6,
CM_ARGB_SPEED_BYTE = 7
CM_ARGB_SPEED_BYTE = 7,
CM_ARGB_BRIGHTNESS_BYTE = 8,
CM_ARGB_RED_BYTE = 9,
CM_ARGB_GREEN_BYTE = 10,
CM_ARGB_BLUE_BYTE = 11
};
struct argb_headers
@ -45,7 +50,7 @@ struct argb_headers
static argb_headers argb_header_data[6] =
{
{ "RGB Header", 0xFF, false, 1 },
{ "RGB Header", 0xFE, false, 1 },
{ "Digital ARGB1", 0x01, true, 12 },
{ "Digital ARGB2", 0x02, true, 12 },
{ "Digital ARGB3", 0x04, true, 12 },
@ -55,24 +60,26 @@ static argb_headers argb_header_data[6] =
enum
{
CM_RGB_MODE_OFF = 0, //Turn off
CM_RGB_MODE_COLOUR_CYCLE = 1, //Colour Cycle
CM_RGB_MODE_FLASH = 2, //Flash
CM_RGB_MODE_BREATHING = 3, //Breathing
CM_RGB_MODE_PASSTHRU = 4 //Motherboard Pass Thru Mode
CM_RGB_MODE_MIRAGE = 0x01, //Mirage
CM_RGB_MODE_FLASH = 0x02, //Flash
CM_RGB_MODE_BREATHING = 0x03, //Breathing
CM_RGB_MODE_STATIC = 0x05, //Static
CM_RGB_MODE_OFF = 0x06, //Turn off
CM_RGB_MODE_PASSTHRU = 0xFF //Motherboard Pass Thru Mode
};
enum
{
CM_ARGB_MODE_OFF = 0, //Turn off
CM_ARGB_MODE_SPECTRUM = 1, //Spectrum Mode
CM_ARGB_MODE_RELOAD = 2, //Reload Mode
CM_ARGB_MODE_RECOIL = 3, //Recoil Mode
CM_ARGB_MODE_BREATHING = 4, //Breathing Mode
CM_ARGB_MODE_REFILL = 5, //Refill Mode
CM_ARGB_MODE_DEMO = 6, //Demo Mode
CM_ARGB_MODE_FILLFLOW = 7, //Fill Flow Mode
CM_ARGB_MODE_RAINBOW = 8, //Rainbow Mode
CM_ARGB_MODE_OFF = 0x0B, //Turn off
CM_ARGB_MODE_SPECTRUM = 0x01, //Spectrum Mode
CM_ARGB_MODE_RELOAD = 0x02, //Reload Mode
CM_ARGB_MODE_RECOIL = 0x03, //Recoil Mode
CM_ARGB_MODE_BREATHING = 0x04, //Breathing Mode
CM_ARGB_MODE_REFILL = 0x05, //Refill Mode
CM_ARGB_MODE_DEMO = 0x06, //Demo Mode
CM_ARGB_MODE_FILLFLOW = 0x08, //Fill Flow Mode
CM_ARGB_MODE_RAINBOW = 0x09, //Rainbow Mode
CM_ARGB_MODE_STATIC = 0x0A, //Static Mode
CM_ARGB_MODE_DIRECT = 0xFE, //Direct Led Control
CM_ARGB_MODE_PASSTHRU = 0xFF //Motherboard Pass Thru Mode
};
@ -102,9 +109,11 @@ public:
unsigned char GetLedGreen();
unsigned char GetLedBlue();
unsigned char GetLedSpeed();
void SetMode(unsigned char mode, unsigned char speed);
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
bool GetRandomColours();
void SetLedCount(int zone, int led_count);
void SetMode(unsigned char mode, unsigned char speed, RGBColor colour, bool random_colours);
void SetLedsDirect(RGBColor * led_colours, unsigned int led_count);
private:
std::string device_name;
std::string serial;
@ -118,10 +127,11 @@ private:
unsigned char current_red;
unsigned char current_green;
unsigned char current_blue;
unsigned char current_brightness;
bool bool_random;
unsigned int GetLargestColour(unsigned int red, unsigned int green, unsigned int blue);
unsigned char GetColourIndex(unsigned char red, unsigned char green, unsigned char blue);
void GetStatus();
void SendUpdate();
};

View file

@ -18,11 +18,11 @@ RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController
vendor = "Cooler Master";
type = DEVICE_TYPE_LEDSTRIP;
description = cmargb->GetDeviceName();
version = "1.0";
version = "2.0 for FW0023";
serial = cmargb->GetSerial();
location = cmargb->GetLocation();
if ( argb_header_data[cmargb->GetZoneIndex()].digital)
if(argb_header_data[cmargb->GetZoneIndex()].digital)
{
mode Off;
Off.name = "Turn Off";
@ -39,7 +39,7 @@ RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController
Reload.colors.resize(Reload.colors_max);
Reload.speed_min = CM_ARGB_SPEED_SLOWEST;
Reload.speed_max = CM_ARGB_SPEED_FASTEST;
Reload.color_mode = MODE_COLORS_RANDOM;
Reload.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reload.speed = speed;
modes.push_back(Reload);
@ -49,10 +49,10 @@ RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController
Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Recoil.colors_min = 1;
Recoil.colors_max = 1;
Recoil.colors.resize(Reload.colors_max);
Recoil.colors.resize(Recoil.colors_max);
Recoil.speed_min = CM_ARGB_SPEED_SLOWEST;
Recoil.speed_max = CM_ARGB_SPEED_FASTEST;
Recoil.color_mode = MODE_COLORS_RANDOM;
Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC;
Recoil.speed = speed;
modes.push_back(Recoil);
@ -62,10 +62,10 @@ RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(Reload.colors_max);
Breathing.colors.resize(Breathing.colors_max);
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_RANDOM;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.speed = speed;
modes.push_back(Breathing);
@ -75,10 +75,10 @@ RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController
Refill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Refill.colors_min = 1;
Refill.colors_max = 1;
Refill.colors.resize(Reload.colors_max);
Refill.colors.resize(Refill.colors_max);
Refill.speed_min = CM_ARGB_SPEED_SLOWEST;
Refill.speed_max = CM_ARGB_SPEED_FASTEST;
Refill.color_mode = MODE_COLORS_RANDOM;
Refill.color_mode = MODE_COLORS_MODE_SPECIFIC;
Refill.speed = speed;
modes.push_back(Refill);
@ -122,6 +122,19 @@ RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController
Rainbow.speed = speed;
modes.push_back(Rainbow);
mode Static;
Static.name = "Static";
Static.value = CM_ARGB_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(Static.colors_max);
Static.speed_min = CM_ARGB_SPEED_SLOWEST;
Static.speed_max = CM_ARGB_SPEED_FASTEST;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.speed = speed;
modes.push_back(Static);
mode Direct;
Direct.name = "Direct";
Direct.value = CM_ARGB_MODE_DIRECT;
@ -132,16 +145,22 @@ RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController
mode PassThru;
PassThru.name = "Pass Thru";
PassThru.value = CM_ARGB_MODE_PASSTHRU;
PassThru.flags = 0;
PassThru.color_mode = MODE_COLORS_NONE;
modes.push_back(PassThru);
}
else
{
mode Off;
Off.name = "Turn Off";
Off.value = CM_RGB_MODE_OFF;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = CM_RGB_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(Static.colors_max);
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.speed = 0;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
@ -152,43 +171,70 @@ RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController
Breathing.colors.resize(Breathing.colors_max);
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_RANDOM;
Breathing.speed = speed;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.speed = CM_ARGB_SPEED_NORMAL;
modes.push_back(Breathing);
mode Flash;
Breathing.name = "Flash";
Breathing.value = CM_RGB_MODE_FLASH;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(Breathing.colors_max);
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_RANDOM;
Breathing.speed = speed;
modes.push_back(Breathing);
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;
Flash.colors_min = 1;
Flash.colors_max = 1;
Flash.colors.resize(Flash.colors_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 ColourCycle;
ColourCycle.name = "Colour Cycle";
ColourCycle.value = CM_RGB_MODE_COLOUR_CYCLE;
ColourCycle.flags = MODE_FLAG_HAS_SPEED;
ColourCycle.speed_min = CM_ARGB_SPEED_SLOWEST;
ColourCycle.speed_max = CM_ARGB_SPEED_FASTEST;
ColourCycle.color_mode = MODE_COLORS_NONE;
ColourCycle.speed = speed;
modes.push_back(ColourCycle);
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;
Mirage.colors_min = 1;
Mirage.colors_max = 1;
Mirage.colors.resize(Mirage.colors_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(); //Only processed on first run
Init_Controller();
SetupZones();
//active_mode = cmargb->GetMode();
int temp_mode = cmargb->GetMode();
for(std::size_t mode_idx = 0; mode_idx < modes.size() ; mode_idx++)
{
if (temp_mode == modes[mode_idx].value)
{
active_mode = mode_idx;
break;
}
}
if (modes[active_mode].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
{
modes[active_mode].colors[0] = ToRGBColor(cmargb->GetLedRed(), cmargb->GetLedGreen(), cmargb->GetLedBlue());
}
modes[active_mode].color_mode = (cmargb->GetRandomColours()) ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
if (modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
modes[active_mode].speed = cmargb->GetLedSpeed();
}
}
RGBController_CMARGBController::~RGBController_CMARGBController()
@ -200,13 +246,18 @@ void RGBController_CMARGBController::Init_Controller()
{
int zone_idx = cmargb->GetZoneIndex();
int zone_led_count = argb_header_data[zone_idx].count;
bool boolSingleLED = ( zone_led_count == 1 ); //If argb_header_data[zone_idx].count == 1 then the zone is ZONE_TYPE_SINGLE
/*-------------------------------------------------*\
| 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 = 0;
ARGB_zone.leds_max = 64;
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);
@ -225,7 +276,12 @@ void RGBController_CMARGBController::SetupZones()
\*---------------------------------------------------------*/
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
bool boolSingleLED = (zones[zone_idx].type == ZONE_TYPE_SINGLE); //Calculated for later use
bool boolSingleLED = (zones[zone_idx].type == ZONE_TYPE_SINGLE);
if (!boolSingleLED)
{
cmargb->SetLedCount( std::stoi(zones[zone_idx].name), zones[zone_idx].leds_count);
}
for(unsigned int lp_idx = 0; lp_idx < zones[zone_idx].leds_count; lp_idx++)
{
@ -257,59 +313,74 @@ void RGBController_CMARGBController::ResizeZone(int zone, int new_size)
{
return;
}
uint8_t end_zone = last_zone(zone);
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
for(std::size_t zone_idx = first_zone(zone); zone_idx < end_zone; zone_idx++)
{
zones[zone].leds_count = new_size;
SetupZones();
if(((unsigned int)new_size >= zones[zone_idx].leds_min) && ((unsigned int)new_size <= zones[zone_idx].leds_max))
{
zones[zone_idx].leds_count = new_size;
}
}
SetupZones();
}
void RGBController_CMARGBController::DeviceUpdateLEDs()
{
/*unsigned char red = RGBGetRValue(colors[0]);
unsigned char grn = RGBGetGValue(colors[0]);
unsigned char blu = RGBGetBValue(colors[0]);
cmargb->SetColor(red, grn, blu);*/
uint8_t end_zone = last_zone(cmargb->GetZoneIndex());
//this one
cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed );
cmargb->SetLedsDirect( zones[0].colors, zones[0].leds_count );
for(std::size_t zone_idx = first_zone(cmargb->GetZoneIndex()); zone_idx < end_zone; zone_idx++)
{
UpdateZoneLEDs(zone_idx);
}
}
void RGBController_CMARGBController::UpdateZoneLEDs(int zone)
{
RGBColor colour = colors[zone];
unsigned char red = RGBGetRValue(colour);
unsigned char grn = RGBGetGValue(colour);
unsigned char blu = RGBGetBValue(colour);
cmargb->SetColor(red, grn, blu);
//cmargb->SetLedsDirect( zones[zone].colors, zones[zone].leds_count );
}
void RGBController_CMARGBController::UpdateSingleLED(int led)
{
//cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed );
//cmargb->SetLedsDirect( zones[0].colors, zones[0].leds_count );
UpdateZoneLEDs(GetLED_Zone(led));
}
void RGBController_CMARGBController::SetCustomMode()
{
active_mode = CM_ARGB_MODE_DIRECT;
for(std::size_t mode_idx = 0; mode_idx < modes.size() ; mode_idx++)
{
if (modes[mode_idx].value == CM_ARGB_MODE_DIRECT)
{
active_mode = mode_idx;
break;
}
}
}
void RGBController_CMARGBController::DeviceUpdateMode()
{
if( modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC )
{
unsigned char red = RGBGetRValue(modes[active_mode].colors[0]);
unsigned char grn = RGBGetGValue(modes[active_mode].colors[0]);
unsigned char blu = RGBGetBValue(modes[active_mode].colors[0]);
cmargb->SetColor(red, grn, blu);
}
else
{
cmargb->SetColor(0, 0, 0); //If the mode is not colour specific then set colour to black for the random index
}
cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed );
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;
cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed, colour, random_colours );
}
int RGBController_CMARGBController::GetLED_Zone(int led_idx)
{
/*---------------------------------------------------------*\
| This may be more useful in the abstract RGBController.cpp |
\*---------------------------------------------------------*/
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;
}

View file

@ -12,6 +12,9 @@
#include "CMARGBcontroller.h"
#include <vector>
#define first_zone(zn) ((zones.size() > 1) ? 1 : 0)
#define last_zone(zn) ((zones.size() > 1) ? 4 : 1)
class RGBController_CMARGBController : public RGBController
{
public:
@ -27,9 +30,11 @@ public:
void SetCustomMode();
void DeviceUpdateMode();
private:
void Init_Controller();
int GetDeviceMode();
int GetLED_Zone(int led_idx);
CMARGBController* cmargb;
};