diff --git a/Controllers/CoolerMasterController/CMARGBGen2A1controller.cpp b/Controllers/CoolerMasterController/CMARGBGen2A1controller.cpp new file mode 100644 index 000000000..a845a98c9 --- /dev/null +++ b/Controllers/CoolerMasterController/CMARGBGen2A1controller.cpp @@ -0,0 +1,373 @@ +/*-------------------------------------------------------------------*\ +| CMARGBGen2A1controller.cpp | +| | +| Driver for Coolermaster ARGB Gen 2 A1 USB Controller | +| | +| morg (Morgan Guimard) 6/26/2022 | +| | +\*-------------------------------------------------------------------*/ + +#include "CMARGBGen2A1controller.h" +#include + +CMARGBGen2A1controller::CMARGBGen2A1controller(hid_device* dev_handle, const hid_device_info& info) +{ + dev = dev_handle; + location = info.path; + + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + serial_number = ""; + } + else + { + std::wstring return_wstring = serial_string; + serial_number = std::string(return_wstring.begin(), return_wstring.end()); + } + + /*---------------------------------------------*\ + | Setup direct mode on start | + \*---------------------------------------------*/ + SetupDirectMode(); +} + +CMARGBGen2A1controller::~CMARGBGen2A1controller() +{ + hid_close(dev); +} + +std::string CMARGBGen2A1controller::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string CMARGBGen2A1controller::GetSerialString() +{ + return(serial_number); +} + +void CMARGBGen2A1controller::SaveToFlash() +{ + unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH]; + + memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND; + usb_buf[2] = CM_ARGB_GEN2_A1_FLASH; + usb_buf[3] = CM_ARGB_GEN2_A1_WRITE; + + hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); +} + +void CMARGBGen2A1controller::SetupDirectMode() +{ + unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH]; + + /*---------------------------------------------*\ + | Swith to direct mode | + \*---------------------------------------------*/ + memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND; + usb_buf[2] = CM_ARGB_GEN2_A1_LIGHTNING_CONTROL; + usb_buf[3] = CM_ARGB_GEN2_A1_WRITE; + usb_buf[4] = 0x01; // channel??? + + hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + software_mode_activated = true; +} + +void CMARGBGen2A1controller::SetupZoneSize(unsigned int zone_id, unsigned int size) +{ + /*---------------------------------------------*\ + | Set the mode sequence to full static | + | (01 for static) | + | | + | This device stores 2 distinct values | + | - effect speed | + | - approximated zone size | + | | + | It's probably based on standard ARGB sizes | + | Still, the 06 value has some mystery. | + | | + | ES= effect speed | + | LC= LEDs count | + | | + | ES LC | + | ----- | + | 0a 06 | + | 09 06 | + | 08 07 | + | 07 08 | + | 06 0a | + | 05 0c | + | 04 0f | + | 03 14 | + | 02 1e | + | 01 3c | + \*---------------------------------------------*/ + + const unsigned char gaps[10] = + { + 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0C, 0x0F, 0x14, 0x1E, 0x3C + }; + + unsigned char speed = 0x0A; + + for(unsigned int g = 0; g < 10; g++) + { + if(size <= gaps[g]) + { + break; + } + + speed--; + } + + unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH]; + + memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND; + usb_buf[2] = CM_ARGB_GEN2_A1_SIZES; + usb_buf[3] = CM_ARGB_GEN2_A1_WRITE; + usb_buf[4] = 1 << zone_id; + + usb_buf[5] = speed; + usb_buf[6] = size; + + hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); +} + +void CMARGBGen2A1controller::SendDirectChannel(unsigned int zone_id, std::vector colors) +{ + /*---------------------------------------------*\ + | Create the color data array | + \*---------------------------------------------*/ + std::vector color_data = CreateColorData(colors); + + std::vector::iterator it = color_data.begin(); + + unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH]; + + unsigned int offset; + + unsigned char packet_start[CM_ARGB_GEN2_A1_PACKETS_PER_CHANNEL] = + { + 0x00, 0x01, 0x82 + }; + + /*---------------------------------------------*\ + | Send 3 packets for the zone | + \*---------------------------------------------*/ + for(unsigned int p = 0; p < CM_ARGB_GEN2_A1_PACKETS_PER_CHANNEL; p++) + { + memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + usb_buf[1] = packet_start[p]; + usb_buf[2] = 0x09; + + if(p == 0) + { + usb_buf[3] = 1 << zone_id; + usb_buf[5] = 0x3C; + + offset = 6; + } + else + { + offset = 3; + } + + while(offset < CM_ARGB_GEN2_A1_PACKET_LENGTH && it != color_data.end()) + { + usb_buf[offset] = *it; + offset++; + it++; + } + + hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + /*---------------------------------------------*\ + | This device needs some delay before we send | + | any other packet | + \*---------------------------------------------*/ + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + /*---------------------------------------------*\ + | Next channel needs some delay as well | + \*---------------------------------------------*/ + std::this_thread::sleep_for(std::chrono::milliseconds(2)); +} + +void CMARGBGen2A1controller::SetMode(unsigned int mode_value, unsigned char speed, unsigned char brightness, RGBColor color, bool random) +{ + unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH]; + + /*---------------------------------------------*\ + | Switch to hardware mode if needed | + \*---------------------------------------------*/ + if(software_mode_activated) + { + memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND; + usb_buf[2] = CM_ARGB_GEN2_A1_LIGHTNING_CONTROL; + usb_buf[3] = CM_ARGB_GEN2_A1_WRITE; + + hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + software_mode_activated = false; + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + + /*---------------------------------------------*\ + | Set the mode values and write to the device | + \*---------------------------------------------*/ + memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND; + usb_buf[2] = CM_ARGB_GEN2_A1_HW_MODE_SETUP; + usb_buf[3] = CM_ARGB_GEN2_A1_WRITE; + + usb_buf[4] = 0xFF; + usb_buf[5] = 0xFF; + + usb_buf[6] = mode_value; + + bool is_custom_mode = mode_value == CM_ARGB_GEN2_A1_CUSTOM_MODE; + + if(is_custom_mode) + { + usb_buf[8] = 0xFF; + } + else + { + usb_buf[7] = speed; + usb_buf[8] = brightness; + usb_buf[9] = RGBGetRValue(color); + usb_buf[10] = RGBGetGValue(color); + usb_buf[11] = RGBGetBValue(color); + usb_buf[12] = random; + } + + + hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + if(is_custom_mode) + { + for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel++) + { + SetCustomSequence(channel); + } + } +} + +std::vector CMARGBGen2A1controller::CreateColorData(std::vector colors) +{ + std::vector color_data; + + for(unsigned int c = 0; c < colors.size(); c++) + { + color_data.push_back(RGBGetRValue(colors[c])); + color_data.push_back(RGBGetGValue(colors[c])); + color_data.push_back(RGBGetBValue(colors[c])); + } + + return color_data; +} + + +void CMARGBGen2A1controller::SetCustomColors(unsigned int zone_id, std::vector colors) +{ + unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH]; + + /*---------------------------------------------*\ + | Create the color data array | + \*---------------------------------------------*/ + std::vector color_data = CreateColorData(colors); + + std::vector::iterator it = color_data.begin(); + + unsigned char packet_start[5] = + { + CM_ARGB_GEN2_A1_COMMAND, 0x00, 0x01, 0x02, 0x83 + }; + + /*---------------------------------------------*\ + | Send the 5 packets of colors | + \*---------------------------------------------*/ + for(unsigned int p = 0; p < 5; p++) + { + memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + usb_buf[1] = packet_start[p]; + + /*----------------------------------------------*\ + | This part isnt well understood | + | 1st packet starts with CM_ARGB_GEN2_A1_COMMAND | + | Looks like it is a read command | + \*----------------------------------------------*/ + usb_buf[2] = p == 0 ? 0x06 : 0x08; // 0x08 custom data, 0x06 sizes? + usb_buf[3] = p == 0 ? 0x01 : 0x02; // read/write has no meaning here + + usb_buf[4] = 1 << zone_id; + + unsigned int offset = 6; + + while(p > 0 && offset < CM_ARGB_GEN2_A1_PACKET_LENGTH && it != color_data.end()) + { + usb_buf[offset] = *it; + offset++; + it++; + } + + hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + } + +} + +void CMARGBGen2A1controller::SetCustomSequence(unsigned int zone_id) +{ + unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH]; + + const unsigned char static_seq = 0x01; + + /*---------------------------------------------*\ + | Set the mode sequence to full static | + | (01 for static) | + \*---------------------------------------------*/ + memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND; + usb_buf[2] = CM_ARGB_GEN2_A1_CUSTOM_SEQUENCES; + usb_buf[3] = CM_ARGB_GEN2_A1_WRITE; + usb_buf[4] = 1 << zone_id; + + usb_buf[5] = static_seq; + usb_buf[6] = static_seq; + usb_buf[7] = static_seq; + usb_buf[8] = static_seq; + usb_buf[9] = static_seq; + usb_buf[10] = static_seq; + + hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH); + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); +} diff --git a/Controllers/CoolerMasterController/CMARGBGen2A1controller.h b/Controllers/CoolerMasterController/CMARGBGen2A1controller.h new file mode 100644 index 000000000..5da345b8a --- /dev/null +++ b/Controllers/CoolerMasterController/CMARGBGen2A1controller.h @@ -0,0 +1,89 @@ +/*-------------------------------------------------------------------*\ +| CMARGBGen2A1controller.h | +| | +| Driver for Coolermaster ARGB Gen 2 A1 USB Controller | +| | +| morg (Morgan Guimard) 6/26/2022 | +| | +\*-------------------------------------------------------------------*/ + +#include "RGBController.h" +#include +#include + +#pragma once + +#define CM_ARGB_GEN2_A1_PACKET_LENGTH 65 +#define CM_ARGB_GEN2_A1_CHANNEL_MAX_SIZE 48 +#define CM_ARGB_GEN2_A1_CHANNEL_COUNT 3 +#define CM_ARGB_GEN2_A1_PACKETS_PER_CHANNEL 3 + +enum +{ + CM_ARGB_GEN2_A1_DIRECT_MODE = 0xFF, + CM_ARGB_GEN2_A1_SPECTRUM_MODE = 0x00, + CM_ARGB_GEN2_A1_STATIC_MODE = 0x01, + CM_ARGB_GEN2_A1_RELOAD_MODE = 0x02, + CM_ARGB_GEN2_A1_RECOIL_MODE = 0x03, + CM_ARGB_GEN2_A1_BREATHING_MODE = 0x04, + CM_ARGB_GEN2_A1_REFILL_MODE = 0x05, + CM_ARGB_GEN2_A1_DEMO_MODE = 0x06, + CM_ARGB_GEN2_A1_FILL_FLOW_MODE = 0x07, + CM_ARGB_GEN2_A1_RAINBOW_MODE = 0x08, + CM_ARGB_GEN2_A1_CUSTOM_MODE = 0xC0, + CM_ARGB_GEN2_A1_OFF_MODE = 0x09 +}; + +enum +{ + CM_ARGB_GEN2_A1_BRIGHTNESS_MAX = 0xFF, + CM_ARGB_GEN2_A1_BRIGHTNESS_MIN = 0x00, + CM_ARGB_GEN2_A1_SPEED_MAX = 0x04, + CM_ARGB_GEN2_A1_SPEED_MIN = 0x00, +}; + +enum +{ + CM_ARGB_GEN2_A1_COMMAND = 0x80, + CM_ARGB_GEN2_A1_READ = 0x01, + CM_ARGB_GEN2_A1_WRITE = 0x02, + CM_ARGB_GEN2_A1_RESPONSE = 0x03 +}; + +enum +{ + CM_ARGB_GEN2_A1_SIZES = 0x06, + CM_ARGB_GEN2_A1_FLASH = 0x0B, + CM_ARGB_GEN2_A1_IDENTIFY = 0x0A, + CM_ARGB_GEN2_A1_LIGHTNING_CONTROL = 0x01, + CM_ARGB_GEN2_A1_HW_MODE_SETUP = 0x03, + CM_ARGB_GEN2_A1_CUSTOM_SEQUENCES = 0x10, + CM_ARGB_GEN2_A1_CUSTOM_SPEED = 0x11 + +}; + +class CMARGBGen2A1controller +{ +public: + CMARGBGen2A1controller(hid_device* dev_handle, const hid_device_info& info); + ~CMARGBGen2A1controller(); + + std::string GetSerialString(); + std::string GetDeviceLocation(); + + void SendDirectChannel(unsigned int zone_id, std::vector colors); + void SetupZoneSize(unsigned int zone_id, unsigned int size); + void SetupDirectMode(); + void SetMode(unsigned int mode_value, unsigned char speed, unsigned char brightness, RGBColor color, bool random); + void SetCustomColors(unsigned int zone_id, std::vector colors); + void SaveToFlash(); + +private: + std::string serial_number; + std::string location; + bool software_mode_activated = false; + hid_device* dev; + + void SetCustomSequence(unsigned int zone_id); + std::vector CreateColorData(std::vector colors); +}; diff --git a/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp b/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp index 3cd15a396..7b430f47f 100644 --- a/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp +++ b/Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp @@ -12,6 +12,7 @@ #include "RGBController_CMMP750Controller.h" #include "RGBController_CMARGBController.h" #include "RGBController_CMSmallARGBController.h" +#include "RGBController_CMARGBGen2A1Controller.h" #include "RGBController_CMRGBController.h" #include "RGBController_CMR6000Controller.h" #include "RGBController_CMMKController.h" @@ -27,6 +28,7 @@ #define COOLERMASTER_MP750_L_PID 0x0107 #define COOLERMASTER_MP750_MEDIUM_PID 0x0105 #define COOLERMASTER_ARGB_PID 0x1011 +#define COOLERMASTER_ARGB_GEN2_A1_PID 0x0173 #define COOLERMASTER_SMALL_ARGB_PID 0x1000 #define COOLERMASTER_RGB_PID 0x004F #define COOLERMASTER_RADEON_6000_PID 0x014D @@ -67,6 +69,19 @@ void DetectCoolerMasterARGB(hid_device_info* info, const std::string&) } } +void DetectCoolerMasterARGBGen2A1(hid_device_info* info, const std::string&) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + CMARGBGen2A1controller* controller = new CMARGBGen2A1controller(dev, *info); + RGBController_CMARGBGen2A1Controller* rgb_controller = new RGBController_CMARGBGen2A1Controller(controller); + // Constructor sets the name + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + void DetectCoolerMasterGPU(hid_device_info* info, const std::string&) { hid_device* dev = hid_open_path(info->path); @@ -170,6 +185,7 @@ REGISTER_HID_DETECTOR_IPU("Cooler Master MK570", DetectCooler REGISTER_HID_DETECTOR_IPU("Cooler Master SK630", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK630_PID, 1, 0xFF00, 1); REGISTER_HID_DETECTOR_IPU("Cooler Master SK650", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK650_PID, 1, 0xFF00, 1); REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB", DetectCoolerMasterARGB, COOLERMASTER_VID, COOLERMASTER_ARGB_PID, 0, 0xFF00, 1); +REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB Gen 2 A1", DetectCoolerMasterARGBGen2A1, COOLERMASTER_VID, COOLERMASTER_ARGB_GEN2_A1_PID, 1, 0xFF01, 1); REGISTER_HID_DETECTOR_IPU("Cooler Master Small ARGB", DetectCoolerMasterSmallARGB, COOLERMASTER_VID, COOLERMASTER_SMALL_ARGB_PID, 0, 0xFF00, 1); REGISTER_HID_DETECTOR_IPU("Cooler Master RGB", DetectCoolerMasterRGB, COOLERMASTER_VID, COOLERMASTER_RGB_PID, 1, 0xFF00, 1); REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1 ); diff --git a/Controllers/CoolerMasterController/RGBController_CMARGBGen2A1Controller.cpp b/Controllers/CoolerMasterController/RGBController_CMARGBGen2A1Controller.cpp new file mode 100644 index 000000000..fe62f7c3e --- /dev/null +++ b/Controllers/CoolerMasterController/RGBController_CMARGBGen2A1Controller.cpp @@ -0,0 +1,305 @@ +/*-------------------------------------------------------------------*\ +| RGBController_CMARGBGen2A1Controller.cpp | +| | +| Driver for Coolermaster ARGB Gen 2 A1 USB Controller | +| | +| morg (Morgan Guimard) 6/26/2022 | +| | +\*-------------------------------------------------------------------*/ + +#include "RGBController_CMARGBGen2A1Controller.h" + +#include +#include + +/**------------------------------------------------------------------*\ + @name Coolermaster ARGB A1 + @category LEDStrip + @type USB + @save :white_check_mark: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectCoolerMasterARGBGen2A1 + @comment This device does not have Gen 2 support in OpenRGB yet. + + Gen2 has auto-resize feature and parallel to serial magical stuff.< +\*-------------------------------------------------------------------*/ + +RGBController_CMARGBGen2A1Controller::RGBController_CMARGBGen2A1Controller(CMARGBGen2A1controller* controller_ptr) +{ + controller = controller_ptr; + name = "CoolerMaster LED Controller A1"; + vendor = "CoolerMaster"; + type = DEVICE_TYPE_LEDSTRIP; + description = name; + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + version = ""; + + mode Direct; + Direct.name = "Direct"; + Direct.value = CM_ARGB_GEN2_A1_DIRECT_MODE; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + mode Spectrum; + Spectrum.name = "Spectrum"; + Spectrum.value = CM_ARGB_GEN2_A1_SPECTRUM_MODE; + Spectrum.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; + Spectrum.color_mode = MODE_COLORS_NONE; + Spectrum.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Spectrum.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN; + Spectrum.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Spectrum.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2; + Spectrum.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN; + Spectrum.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX; + modes.push_back(Spectrum); + + mode Static; + Static.name = "Static"; + Static.value = CM_ARGB_GEN2_A1_STATIC_MODE; + Static.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_MANUAL_SAVE; + Static.color_mode = MODE_COLORS_MODE_SPECIFIC; + Static.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Static.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN; + Static.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Static.colors.resize(1); + modes.push_back(Static); + + mode Reload; + Reload.name = "Reload"; + Reload.value = CM_ARGB_GEN2_A1_RELOAD_MODE; + Reload.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE; + Reload.color_mode = MODE_COLORS_MODE_SPECIFIC; + Reload.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Reload.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN; + Reload.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Reload.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2; + Reload.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN; + Reload.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX; + Reload.colors.resize(1); + modes.push_back(Reload); + + mode Recoil; + Recoil.name = "Recoil"; + Recoil.value = CM_ARGB_GEN2_A1_RECOIL_MODE; + Recoil.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE; + Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC; + Recoil.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Recoil.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN; + Recoil.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Recoil.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2; + Recoil.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN; + Recoil.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX; + Recoil.colors.resize(1); + modes.push_back(Recoil); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = CM_ARGB_GEN2_A1_BREATHING_MODE; + Breathing.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE; + Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + Breathing.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Breathing.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN; + Breathing.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Breathing.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2; + Breathing.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN; + Breathing.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX; + Breathing.colors.resize(1); + modes.push_back(Breathing); + + + mode Refill; + Refill.name = "Refill"; + Refill.value = CM_ARGB_GEN2_A1_REFILL_MODE; + Refill.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE; + Refill.color_mode = MODE_COLORS_MODE_SPECIFIC; + Refill.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Refill.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN; + Refill.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Refill.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2; + Refill.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN; + Refill.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX; + Refill.colors.resize(1); + modes.push_back(Refill); + + mode Demo; + Demo.name = "Demo"; + Demo.value = CM_ARGB_GEN2_A1_DEMO_MODE; + Demo.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE; + Demo.color_mode = MODE_COLORS_NONE; + Demo.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Demo.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN; + Demo.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + modes.push_back(Demo); + + mode FillFlow; + FillFlow.name = "Fill Flow"; + FillFlow.value = CM_ARGB_GEN2_A1_FILL_FLOW_MODE; + FillFlow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;; + FillFlow.color_mode = MODE_COLORS_NONE; + FillFlow.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + FillFlow.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN; + FillFlow.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + FillFlow.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2; + FillFlow.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN; + FillFlow.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX; + modes.push_back(FillFlow); + + mode Rainbow; + Rainbow.name = "Rainbow"; + Rainbow.value = CM_ARGB_GEN2_A1_RAINBOW_MODE; + Rainbow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;; + Rainbow.color_mode = MODE_COLORS_NONE; + Rainbow.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Rainbow.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN; + Rainbow.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX; + Rainbow.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2; + Rainbow.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN; + Rainbow.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX; + modes.push_back(Rainbow); + + mode Custom; + Custom.name = "Custom"; + Custom.value = CM_ARGB_GEN2_A1_CUSTOM_MODE; + Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE; + Custom.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Custom); + + mode Off; + Off.name = "Off"; + Off.value = CM_ARGB_GEN2_A1_OFF_MODE; + Off.flags = MODE_FLAG_MANUAL_SAVE; + Off.color_mode = MODE_COLORS_NONE; + modes.push_back(Off); + + SetupZones(); +} + +RGBController_CMARGBGen2A1Controller::~RGBController_CMARGBGen2A1Controller() +{ + delete controller; +} + +void RGBController_CMARGBGen2A1Controller::SetupZones() +{ + unsigned int total_leds = 0; + + for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel++) + { + zone new_zone; + + new_zone.name = "Channel " + std::to_string(channel + 1); + new_zone.type = ZONE_TYPE_LINEAR; + new_zone.leds_min = 0; + new_zone.leds_max = CM_ARGB_GEN2_A1_CHANNEL_MAX_SIZE; + new_zone.leds_count = 0; + new_zone.matrix_map = nullptr; + + zones.push_back(new_zone); + + total_leds += new_zone.leds_count; + } + + leds.resize(total_leds); + + for(unsigned int i = 0; i < total_leds; i++) + { + leds[i].name = "LED " + std::to_string(i + 1); + } + + SetupColors(); +} + +void RGBController_CMARGBGen2A1Controller::ResizeZone(int zone, int new_size) +{ + zones[zone].leds_count = new_size; + + // todo: refactor with above code + unsigned int total_leds = 0; + + for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel++) + { + total_leds += zones[channel].leds_count; + } + + leds.resize(total_leds); + + for(unsigned int i = 0; i < total_leds; i++) + { + leds[i].name = "LED " + std::to_string(i + 1); + } + + controller->SetupZoneSize(zone, new_size); + + SetupColors(); +} + +void RGBController_CMARGBGen2A1Controller::DeviceUpdateLEDs() +{ + for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel ++) + { + UpdateZoneLEDs(channel); + } +} + +void RGBController_CMARGBGen2A1Controller::UpdateZoneLEDs(int zone) +{ + if(zones[zone].leds_count > 0) + { + unsigned int start = zones[zone].start_idx; + unsigned int end = start + zones[zone].leds_count; + + std::vector zone_colors(colors.begin() + start , colors.begin() + end); + + if(modes[active_mode].value == CM_ARGB_GEN2_A1_DIRECT_MODE) + { + controller->SendDirectChannel(zone, zone_colors); + } + else + { + controller->SetCustomColors(zone, zone_colors); + } + } +} + +void RGBController_CMARGBGen2A1Controller::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_CMARGBGen2A1Controller::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_CMARGBGen2A1Controller::DeviceUpdateMode() +{ + const mode& active = modes[active_mode]; + + if(active.value == CM_ARGB_GEN2_A1_DIRECT_MODE) + { + controller->SetupDirectMode(); + } + else + { + RGBColor color = active.color_mode == MODE_COLORS_MODE_SPECIFIC ? + active.colors[0] : 0; + + controller->SetMode + ( + active.value, + active.speed, + active.brightness, + color, + active.color_mode == MODE_COLORS_RANDOM + ); + } +} + +void RGBController_CMARGBGen2A1Controller::DeviceSaveMode() +{ + controller->SaveToFlash(); +} + diff --git a/Controllers/CoolerMasterController/RGBController_CMARGBGen2A1Controller.h b/Controllers/CoolerMasterController/RGBController_CMARGBGen2A1Controller.h new file mode 100644 index 000000000..577f2f0f4 --- /dev/null +++ b/Controllers/CoolerMasterController/RGBController_CMARGBGen2A1Controller.h @@ -0,0 +1,32 @@ +/*-------------------------------------------------------------------*\ +| RGBController_CMARGBGen2A1Controller.h | +| | +| Driver for Coolermaster ARGB Controller | +| | +| morg (Morgan Guimard) 6/26/2022 | +| | +\*-------------------------------------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "CMARGBGen2A1controller.h" +#include + +class RGBController_CMARGBGen2A1Controller : public RGBController +{ +public: + RGBController_CMARGBGen2A1Controller(CMARGBGen2A1controller* controller_ptr); + ~RGBController_CMARGBGen2A1Controller(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + void SetCustomMode(); + void DeviceUpdateMode(); + void DeviceSaveMode(); + +private: + CMARGBGen2A1controller* controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 0981f730a..6b9007f86 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -284,6 +284,7 @@ HEADERS += Controllers/BlinkyTapeController/BlinkyTapeController.h \ Controllers/BlinkyTapeController/RGBController_BlinkyTape.h \ Controllers/CoolerMasterController/CMARGBcontroller.h \ + Controllers/CoolerMasterController/CMARGBGen2A1controller.h \ Controllers/CoolerMasterController/CMMKController.h \ Controllers/CoolerMasterController/CMMMController.h \ Controllers/CoolerMasterController/CMMM711Controller.h \ @@ -292,6 +293,7 @@ HEADERS += Controllers/CoolerMasterController/CMRGBController.h \ Controllers/CoolerMasterController/CMSmallARGBController.h \ Controllers/CoolerMasterController/RGBController_CMARGBController.h \ + Controllers/CoolerMasterController/RGBController_CMARGBGen2A1Controller.h \ Controllers/CoolerMasterController/RGBController_CMMKController.h \ Controllers/CoolerMasterController/RGBController_CMMMController.h \ Controllers/CoolerMasterController/RGBController_CMMM711Controller.h \ @@ -749,6 +751,7 @@ SOURCES += Controllers/BlinkyTapeController/BlinkyTapeControllerDetect.cpp \ Controllers/BlinkyTapeController/RGBController_BlinkyTape.cpp \ Controllers/CoolerMasterController/CMARGBcontroller.cpp \ + Controllers/CoolerMasterController/CMARGBGen2A1controller.cpp \ Controllers/CoolerMasterController/CMMKController.cpp \ Controllers/CoolerMasterController/CMMMController.cpp \ Controllers/CoolerMasterController/CMMM711Controller.cpp \ @@ -758,6 +761,7 @@ SOURCES += Controllers/CoolerMasterController/CMSmallARGBController.cpp \ Controllers/CoolerMasterController/CoolerMasterControllerDetect.cpp \ Controllers/CoolerMasterController/RGBController_CMARGBController.cpp \ + Controllers/CoolerMasterController/RGBController_CMARGBGen2A1Controller.cpp \ Controllers/CoolerMasterController/RGBController_CMMKController.cpp \ Controllers/CoolerMasterController/RGBController_CMMMController.cpp \ Controllers/CoolerMasterController/RGBController_CMMM711Controller.cpp \