/*-------------------------------------------------------------------*\ | 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(); }