diff --git a/Controllers/CoolerMasterController/CMARGBcontroller.cpp b/Controllers/CoolerMasterController/CMARGBcontroller.cpp index 4fa20844..82835c80 100644 --- a/Controllers/CoolerMasterController/CMARGBcontroller.cpp +++ b/Controllers/CoolerMasterController/CMARGBcontroller.cpp @@ -23,20 +23,26 @@ static unsigned char argb_mode_data[2][9] = { 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x09 } //5v ARGB Mode values }; -CMARGBController::CMARGBController(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path) +CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx) { - std::size_t tmp_size = wcslen(_vendor); + const int szTemp = 256; + wchar_t tmpName[szTemp]; + dev = dev_handle; location = _path; + zone_index = _zone_idx; - for(std::size_t i = 0; (i < tmp_size) && (i < CM_ARGB_DEVICE_NAME_SIZE); i++) - { - device_name[i] = (char)_vendor[i]; - } - for(std::size_t j = 0; (j < wcslen(_vendor)) && (tmp_size + j < CM_ARGB_DEVICE_NAME_SIZE); j++) - { - device_name[tmp_size + j] = (char)_device_name[j]; - } + hid_get_manufacturer_string(dev, tmpName, szTemp); + std::wstring wName = std::wstring(tmpName); + device_name = std::string(wName.begin(), wName.end()); + + hid_get_product_string(dev, tmpName, szTemp); + wName = std::wstring(tmpName); + device_name.append(" ").append(std::string(wName.begin(), wName.end())); + + hid_get_serial_number_string(dev, tmpName, szTemp); + wName = std::wstring(tmpName); + serial = std::string(wName.begin(), wName.end()); } CMARGBController::~CMARGBController() @@ -44,12 +50,12 @@ CMARGBController::~CMARGBController() hid_close(dev); } -char* CMARGBController::GetDeviceName() +std::string CMARGBController::GetDeviceName() { return device_name; } -char* CMARGBController::GetSerial() +std::string CMARGBController::GetSerial() { return serial; } @@ -59,6 +65,11 @@ std::string CMARGBController::GetLocation() return location; } +unsigned char CMARGBController::GetZoneIndex() +{ + return zone_index; +} + unsigned char CMARGBController::GetMode() { return current_mode; @@ -84,9 +95,9 @@ unsigned char CMARGBController::GetLedSpeed() return current_speed; } -unsigned char CMARGBController::GetLargestColour(unsigned char red, unsigned char green, unsigned char blue) +unsigned int CMARGBController::GetLargestColour(unsigned int red, unsigned int green, unsigned int blue) { - unsigned char largest; + unsigned int largest; if ( red > green ) { ( red > blue ) ? largest = red : largest = blue; @@ -96,7 +107,7 @@ unsigned char CMARGBController::GetLargestColour(unsigned char red, unsigned cha ( green > blue ) ? largest = green : largest = blue; } - return largest; + return (largest == 0) ? 1 : largest; } unsigned char CMARGBController::GetColourIndex(unsigned char red, unsigned char green, unsigned char blue) @@ -105,7 +116,7 @@ unsigned char CMARGBController::GetColourIndex(unsigned char red, unsigned char //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 char divisor = GetLargestColour( red, green, blue); + unsigned int divisor = GetLargestColour( red, green, blue); unsigned int r = round( red / divisor )+1; unsigned int g = round( green / divisor )+1; unsigned int b = round( blue / divisor )+1; @@ -129,7 +140,7 @@ void CMARGBController::SetColor(unsigned char red, unsigned char green, unsigned SendUpdate(); } -void CMARGBController::SendUpdate(unsigned char zone) +void CMARGBController::SendUpdate() { unsigned char buffer[0x40] = { 0x00 }; int buffer_size = (sizeof(buffer) / sizeof(buffer[0])); @@ -143,7 +154,7 @@ void CMARGBController::SendUpdate(unsigned char zone) buffer[CM_ARGB_COMMAND_BYTE] = (boolARGB_header) ? 0x0b : 0x04; //ARGB sends 0x0b (1011) RGB sends 0x04 (0100) buffer[CM_ARGB_MODE_BYTE] = current_mode; - buffer[CM_ARGB_ZONE_BYTE] = zone; + buffer[CM_ARGB_ZONE_BYTE] = argb_header_data[zone_index].header; buffer[CM_ARGB_COLOUR_INDEX_BYTE] = GetColourIndex( current_red, current_green, current_blue ); buffer[CM_ARGB_SPEED_BYTE] = current_speed; diff --git a/Controllers/CoolerMasterController/CMARGBcontroller.h b/Controllers/CoolerMasterController/CMARGBcontroller.h index bfd51f53..84d52033 100644 --- a/Controllers/CoolerMasterController/CMARGBcontroller.h +++ b/Controllers/CoolerMasterController/CMARGBcontroller.h @@ -6,7 +6,7 @@ | Chris M (Dr_No) 10th Oct 2020 | | | | Simple RGB device with 5 modes | -| BYTE0 = Mode (0x01 thru 0x05 | +| BYTE0 = Mode 0x01 thru 0x05 | | BYTE1 = ?? Must be set to 0x04 for colour modes otherwise ignored | | BYTE2 = Colour Modes: RED else Cycle SPEED | | BYTE3 = Colour Modes: GREEN else ignored | @@ -22,9 +22,10 @@ #pragma once #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_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ])) -#define CM_ARGB_SERIAL_SIZE (sizeof(serial) / sizeof(serial[ 0 ])) +//#define CM_ARGB_SERIAL_SIZE (sizeof(serial) / sizeof(serial[ 0 ])) #define HID_MAX_STR 255 enum @@ -37,6 +38,22 @@ enum CM_ARGB_SPEED_BYTE = 6 }; +struct argb_headers +{ + const char* name; + unsigned char header; + unsigned int count; +}; + +static argb_headers argb_header_data[5] = +{ + { "RGB Header", 0xFF, 1 }, + { "Digital ARGB1", 0x01, 0 }, + { "Digital ARGB2", 0x02, 0 }, + { "Digital ARGB3", 0x04, 0 }, + { "Digital ARGB4", 0x08, 0 } +}; + // ARGB Modes /* * 01 Spectrum (random) @@ -84,13 +101,14 @@ enum class CMARGBController { public: - CMARGBController(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path); + CMARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx); ~CMARGBController(); - char* GetDeviceName(); - char* GetSerial(); + std::string GetDeviceName(); + std::string GetSerial(); std::string GetLocation(); + unsigned char GetZoneIndex(); unsigned char GetMode(); unsigned char GetLedRed(); unsigned char GetLedGreen(); @@ -100,11 +118,12 @@ public: void SetColor(unsigned char red, unsigned char green, unsigned char blue); private: - char device_name[32]; - char serial[32]; + std::string device_name; + std::string serial; std::string location; hid_device* dev; + unsigned char zone_index; unsigned char current_mode; unsigned char current_speed; @@ -112,8 +131,8 @@ private: unsigned char current_green; unsigned char current_blue; - unsigned char GetLargestColour(unsigned char red, unsigned char green, unsigned char blue); + 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(unsigned char zone); + void SendUpdate(); }; diff --git a/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp b/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp index be03062f..96b24765 100644 --- a/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp +++ b/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp @@ -3,6 +3,7 @@ #include "CMARGBcontroller.h" #include "RGBController.h" #include "RGBController_CMMP750Controller.h" +#include "RGBController_CMARGBController.h" #include #define COOLERMASTER_VID 0x2516 @@ -68,7 +69,12 @@ void DetectCoolerMasterControllers(std::vector& rgb_controllers) } else if(dev_type == DEVICE_TYPE_LEDSTRIP) { - //Add controllers here + for(std::size_t i = 0; i < CM_ARGB_HEADER_DATA_SIZE; i++) + { + CMARGBController* controller = new CMARGBController(dev, info->path, i); + RGBController_CMARGBController* rgb_controller = new RGBController_CMARGBController(controller); + rgb_controllers.push_back(rgb_controller); + } } } info = info->next; diff --git a/Controllers/CoolerMasterController/RGBController_CMARGBController.cpp b/Controllers/CoolerMasterController/RGBController_CMARGBController.cpp new file mode 100644 index 00000000..1ff425f2 --- /dev/null +++ b/Controllers/CoolerMasterController/RGBController_CMARGBController.cpp @@ -0,0 +1,191 @@ +/*-------------------------------------------------------------------*\ +| RGBController_CMARGBController.cpp | +| | +| Driver for Coolermaster ARGB Controller | +| | +| Chris M (Dr_No) 14th Oct 2020 | +| | +\*-------------------------------------------------------------------*/ + +#include "RGBController_CMARGBController.h" + +RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController *cmargb_ptr) +{ + cmargb = cmargb_ptr; + unsigned char speed = cmargb->GetLedSpeed(); + + name = argb_header_data[cmargb->GetZoneIndex()].name; + type = DEVICE_TYPE_LEDSTRIP; + description = cmargb->GetDeviceName(); + version = "1.0"; + serial = cmargb->GetSerial(); + location = cmargb->GetLocation(); + + mode Off; + Off.name = "Turn Off"; + Off.value = CM_ARGB_MODE_OFF; + Off.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + Off.color_mode = MODE_COLORS_NONE; + modes.push_back(Off); + + mode Spectrum; + Spectrum.name = "Spectrum"; + Spectrum.value = CM_ARGB_MODE_SPECTRUM; + Spectrum.flags = MODE_FLAG_HAS_SPEED; + Spectrum.speed_min = CM_ARGB_SPEED_SLOWEST; + Spectrum.speed_max = CM_ARGB_SPEED_FASTEST; + Spectrum.color_mode = MODE_COLORS_NONE; + Spectrum.speed = speed; + modes.push_back(Spectrum); + + mode Reload; + Reload.name = "Reload"; + Reload.value = CM_ARGB_MODE_RELOAD; + Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + Reload.speed_min = CM_ARGB_SPEED_SLOWEST; + Reload.speed_max = CM_ARGB_SPEED_FASTEST; + Reload.color_mode = MODE_COLORS_PER_LED; + Reload.speed = speed; + modes.push_back(Reload); + + mode Recoil; + Recoil.name = "Recoil"; + Recoil.value = CM_ARGB_MODE_RECOIL; + Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + Recoil.speed_min = CM_ARGB_SPEED_SLOWEST; + Recoil.speed_max = CM_ARGB_SPEED_FASTEST; + Recoil.color_mode = MODE_COLORS_PER_LED; + Recoil.speed = speed; + modes.push_back(Recoil); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = CM_ARGB_MODE_BREATHING; + Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + Breathing.speed_min = CM_ARGB_SPEED_SLOWEST; + Breathing.speed_max = CM_ARGB_SPEED_FASTEST; + Breathing.color_mode = MODE_COLORS_PER_LED; + Breathing.speed = speed; + modes.push_back(Breathing); + + mode Refill; + Refill.name = "Refill"; + Refill.value = CM_ARGB_MODE_REFILL; + Refill.flags = MODE_FLAG_HAS_SPEED; + Refill.speed_min = CM_ARGB_SPEED_SLOWEST; + Refill.speed_max = CM_ARGB_SPEED_FASTEST; + Refill.color_mode = MODE_COLORS_NONE; + Refill.speed = speed; + modes.push_back(Refill); + + Init_Controller(); //Only processed on first run + SetupZones(); + //active_mode = cmargb->GetMode(); +} + +RGBController_CMARGBController::~RGBController_CMARGBController() +{ + +} + +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 + + 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_count = zone_led_count; + ARGB_zone.matrix_map = NULL; + zones.push_back(ARGB_zone); +} + +void RGBController_CMARGBController::SetupZones() +{ + /*-------------------------------------------------*\ + | Clear any existing color/LED configuration | + \*-------------------------------------------------*/ + leds.clear(); + colors.clear(); + + /*---------------------------------------------------------*\ + | Set up zones | + \*---------------------------------------------------------*/ + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + bool boolSingleLED = (zones[zone_idx].type == ZONE_TYPE_SINGLE); //Calculated for later use + + for(unsigned int lp_idx = 0; lp_idx < zones[zone_idx].leds_count; lp_idx++) + { + led new_led; + unsigned int i = std::stoi(zones[zone_idx].name); + + if(boolSingleLED) + { + new_led.name = i; + new_led.value = argb_header_data[i].header; + } + 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); + } + } + + SetupColors(); +} + +void RGBController_CMARGBController::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_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); +} + +void RGBController_CMARGBController::UpdateZoneLEDs(int zone) +{ + RGBColor color = colors[zone]; + unsigned char red = RGBGetRValue(color); + unsigned char grn = RGBGetGValue(color); + unsigned char blu = RGBGetBValue(color); + cmargb->SetColor(red, grn, blu); +} + +void RGBController_CMARGBController::UpdateSingleLED(int led) +{ + UpdateZoneLEDs(led); +} + +void RGBController_CMARGBController::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_CMARGBController::DeviceUpdateMode() +{ + cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed ); +} diff --git a/Controllers/CoolerMasterController/RGBController_CMARGBController.h b/Controllers/CoolerMasterController/RGBController_CMARGBController.h new file mode 100644 index 00000000..d34d0012 --- /dev/null +++ b/Controllers/CoolerMasterController/RGBController_CMARGBController.h @@ -0,0 +1,35 @@ +/*-------------------------------------------------------------------*\ +| RGBController_CMARGBController.h | +| | +| Driver for Coolermaster ARGB Controller | +| | +| Chris M (Dr_No) 14th Oct 2020 | +| | +\*-------------------------------------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "CMARGBcontroller.h" +#include + +class RGBController_CMARGBController : public RGBController +{ +public: + RGBController_CMARGBController(CMARGBController* cmargb_ptr); + ~RGBController_CMARGBController(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); +private: + void Init_Controller(); + int GetDeviceMode(); + + CMARGBController* cmargb; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index a9338c83..79c2face 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -151,6 +151,7 @@ HEADERS += Controllers/AuraSMBusController/RGBController_AuraSMBus.h \ Controllers/CoolerMasterController/CMARGBcontroller.h \ Controllers/CoolerMasterController/CMMP750Controller.h \ + Controllers/CoolerMasterController/RGBController_CMARGBController.h \ Controllers/CoolerMasterController/RGBController_CMMP750Controller.h \ Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.h \ Controllers/CorsairDominatorPlatinumController/RGBController_CorsairDominatorPlatinum.h \ @@ -321,6 +322,7 @@ SOURCES += Controllers/CoolerMasterController/CMARGBcontroller.cpp \ Controllers/CoolerMasterController/CMMP750Controller.cpp \ Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp \ + Controllers/CoolerMasterController/RGBController_CMARGBController.cpp \ Controllers/CoolerMasterController/RGBController_CMMP750Controller.cpp \ Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.cpp \ Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumControllerDetect.cpp \