/*-----------------------------------------*\ | RGBController_ASRockPolychromeUSB.cpp | | | | Generic RGB Interface for OpenRGB | | ASRock Polychrome USB Driver | | | | Ed Kambulow (Dredvard) 12/26/2020 | | Shady Nawara (ShadyNawara) 01/16/2023 | \*-----------------------------------------*/ #include #include "RGBController_ASRockPolychromeUSB.h" #define ASROCK_USB_MAX_ZONES 8 #define ASROCK_ADDRESSABLE_MAX_LEDS 100 /**------------------------------------------------------------------*\ @name ASrock Polychrome USB @category Motherboard @type USB @save :robot: @direct :x: @effects :white_check_mark: @detectors DetectPolychromeUSBControllers @comment ASRock Polychrome controllers will save with each update. \*-------------------------------------------------------------------*/ RGBController_PolychromeUSB::RGBController_PolychromeUSB(PolychromeUSBController* controller_ptr) { controller = controller_ptr; name = controller->GetDeviceName(); description = "ASRock Polychrome USB Device"; vendor = "ASRock"; type = DEVICE_TYPE_MOTHERBOARD; location = controller->GetDeviceLocation(); mode Off; Off.name = "Off"; Off.value = POLYCHROME_USB_MODE_OFF; Off.flags = 0; Off.color_mode = MODE_COLORS_NONE; modes.push_back(Off); mode Static; Static.name = "Static"; Static.value = POLYCHROME_USB_MODE_STATIC; Static.flags = MODE_FLAG_HAS_PER_LED_COLOR; Static.color_mode = MODE_COLORS_PER_LED; modes.push_back(Static); mode Breathing; Breathing.name = "Breathing"; Breathing.value = POLYCHROME_USB_MODE_BREATHING; Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; Breathing.speed_min = POLYCHROME_USB_SPEED_MIN; Breathing.speed_max = POLYCHROME_USB_SPEED_MAX; Breathing.speed = POLYCHROME_USB_SPEED_DEFAULT; Breathing.color_mode = MODE_COLORS_PER_LED; modes.push_back(Breathing); mode Strobe; Strobe.name = "Strobe"; Strobe.value = POLYCHROME_USB_MODE_STROBE; Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; Strobe.speed_min = POLYCHROME_USB_SPEED_MIN; Strobe.speed_max = POLYCHROME_USB_SPEED_MAX; Strobe.speed = POLYCHROME_USB_SPEED_DEFAULT; Strobe.color_mode = MODE_COLORS_PER_LED; modes.push_back(Strobe); mode SpectrumCycle; SpectrumCycle.name = "Spectrum Cycle"; SpectrumCycle.value = POLYCHROME_USB_MODE_SPECTRUM_CYCLE; SpectrumCycle.flags = MODE_FLAG_HAS_SPEED; SpectrumCycle.speed_min = POLYCHROME_USB_SPEED_MIN; SpectrumCycle.speed_max = POLYCHROME_USB_SPEED_MAX; SpectrumCycle.speed = POLYCHROME_USB_SPEED_DEFAULT; SpectrumCycle.color_mode = MODE_COLORS_NONE; modes.push_back(SpectrumCycle); mode Random; Random.name = "Random"; Random.value = POLYCHROME_USB_MODE_RANDOM; Random.flags = MODE_FLAG_HAS_SPEED; Random.speed_min = POLYCHROME_USB_SPEED_MIN; Random.speed_max = POLYCHROME_USB_SPEED_MAX; Random.speed = POLYCHROME_USB_SPEED_DEFAULT; Random.color_mode = MODE_COLORS_NONE; modes.push_back(Random); mode Music; Random.name = "Music"; Random.value = POLYCHROME_USB_MODE_RANDOM; Random.flags = MODE_FLAG_HAS_BRIGHTNESS; Random.color_mode = MODE_COLORS_NONE; modes.push_back(Random); mode Wave; Wave.name = "Wave"; Wave.value = POLYCHROME_USB_MODE_WAVE; Wave.flags = MODE_FLAG_HAS_SPEED; Wave.speed_min = POLYCHROME_USB_SPEED_MIN; Wave.speed_max = POLYCHROME_USB_SPEED_MAX; Wave.speed = POLYCHROME_USB_SPEED_DEFAULT; Wave.color_mode = MODE_COLORS_NONE; modes.push_back(Wave); mode Spring; Spring.name = "Spring"; Spring.value = POLYCHROME_USB_MODE_SPRING; Spring.flags = MODE_FLAG_HAS_SPEED; Spring.speed_min = POLYCHROME_USB_SPEED_MIN; Spring.speed_max = POLYCHROME_USB_SPEED_MAX; Spring.speed = POLYCHROME_USB_SPEED_DEFAULT; Spring.color_mode = MODE_COLORS_NONE; modes.push_back(Spring); mode Stack; Stack.name = "Stack"; Stack.value = POLYCHROME_USB_MODE_STACK; Stack.flags = MODE_FLAG_HAS_SPEED; Stack.speed_min = POLYCHROME_USB_SPEED_MIN; Stack.speed_max = POLYCHROME_USB_SPEED_MAX; Stack.speed = POLYCHROME_USB_SPEED_DEFAULT; Stack.color_mode = MODE_COLORS_NONE; modes.push_back(Stack); mode Cram; Cram.name = "Cram"; Cram.value = POLYCHROME_USB_MODE_CRAM; Cram.flags = MODE_FLAG_HAS_SPEED; Cram.speed_min = POLYCHROME_USB_SPEED_MIN; Cram.speed_max = POLYCHROME_USB_SPEED_MAX; Cram.speed = POLYCHROME_USB_SPEED_DEFAULT; Cram.color_mode = MODE_COLORS_NONE; modes.push_back(Cram); mode Scan; Scan.name = "Scan"; Scan.value = POLYCHROME_USB_MODE_SCAN; Scan.flags = MODE_FLAG_HAS_SPEED; Scan.speed_min = POLYCHROME_USB_SPEED_MIN; Scan.speed_max = POLYCHROME_USB_SPEED_MAX; Scan.speed = POLYCHROME_USB_SPEED_DEFAULT; Scan.color_mode = MODE_COLORS_NONE; modes.push_back(Scan); mode Neon; Neon.name = "Neon"; Neon.value = POLYCHROME_USB_MODE_NEON; Neon.flags = 0; Neon.color_mode = MODE_COLORS_NONE; modes.push_back(Neon); mode Water; Water.name = "Water"; Water.value = POLYCHROME_USB_MODE_WATER; Water.flags = MODE_FLAG_HAS_SPEED; Water.speed_min = POLYCHROME_USB_SPEED_MIN; Water.speed_max = POLYCHROME_USB_SPEED_MAX; Water.speed = POLYCHROME_USB_SPEED_DEFAULT; Water.color_mode = MODE_COLORS_NONE; modes.push_back(Water); mode Rainbow; Rainbow.name = "Rainbow"; Rainbow.value = POLYCHROME_USB_MODE_RAINBOW; Rainbow.flags = MODE_FLAG_HAS_SPEED; Rainbow.speed_min = POLYCHROME_USB_SPEED_MIN; Rainbow.speed_max = POLYCHROME_USB_SPEED_MAX; Rainbow.speed = POLYCHROME_USB_SPEED_DEFAULT; Rainbow.color_mode = MODE_COLORS_NONE; modes.push_back(Rainbow); mode Direct; Direct.name = "Direct"; Direct.value = POLYCHROME_USB_MODE_DIRECT; Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; Direct.color_mode = MODE_COLORS_PER_LED; modes.push_back(Direct); SetupZones(); } void RGBController_PolychromeUSB::SetupZones() { /*-------------------------------------------------*\ | Clear any existing color/LED configuration | \*-------------------------------------------------*/ leds.clear(); colors.clear(); zones.resize(controller->GetChannelCount()); /*-------------------------------------------------*\ | Set zones and leds | \*-------------------------------------------------*/ for(unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++) { PolychromeDeviceInfo device_info = controller->GetPolychromeDevices()[channel_idx]; zones[channel_idx].type = ZONE_TYPE_LINEAR; if(device_info.device_type== PolychromeDeviceType::ADDRESSABLE) { zones[channel_idx].name = polychrome_USB_zone_names[device_info.zone_type]; zones[channel_idx].leds_min = 0; zones[channel_idx].leds_max = ASROCK_ADDRESSABLE_MAX_LEDS; zones[channel_idx].leds_count = device_info.num_leds; } else if(device_info.device_type==PolychromeDeviceType::FIXED) { zones[channel_idx].name = polychrome_USB_zone_names[device_info.zone_type]; zones[channel_idx].leds_min = device_info.num_leds; zones[channel_idx].leds_max = device_info.num_leds; zones[channel_idx].leds_count = device_info.num_leds; } for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++) { led new_led; new_led.name = zones[channel_idx].name; new_led.name.append(", LED "); new_led.name.append(std::to_string(led_ch_idx + 1)); new_led.value = channel_idx; leds.push_back(new_led); } zones[channel_idx].matrix_map = NULL; } SetupColors(); /*---------------------------------------------------------*\ | Initialize zone info to track zone, speed, mode | | B550 Boards have modes, speed for each zone | \*---------------------------------------------------------*/ for (unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++) { PolychromeZoneInfo zoneinfo; zoneinfo = controller->GetZoneConfig(channel_idx); zones_info.push_back(zoneinfo); } /*---------------------------------------------------------*\ | Initialize colors for each LED | | We cannot currently get the individual led color so | | we use the zone color in each zone to set all leds | | !!TODO: in Per-Led mode, zone color is always black | \*---------------------------------------------------------*/ for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++) { unsigned char led = (unsigned char)leds[led_idx].value; colors[led_idx] = zones_info[led].color; } /*-------------------------------------------------*\ | Initialize active mode | \*-------------------------------------------------*/ active_mode = zones_info.size() > 1 ? zones_info[0].mode : 0x0; /*-----------------------------------------------------*\ | If in Direct mode, reset all Leds to match interface | \*-----------------------------------------------------*/ if(active_mode == 0x0F) { controller->WriteAllZones(zones_info, zones); } } void RGBController_PolychromeUSB::ResizeZone(int zone, int new_size) { zones[zone].leds_count = (unsigned char) new_size; controller->ResizeZone(zones_info[zone].zone, new_size); } void RGBController_PolychromeUSB::DeviceUpdateLEDs() { if(POLYCHROME_USB_MODE_DIRECT == zones_info[0].mode ) { controller->WriteAllZones(zones_info,zones); return; } for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) { unsigned char set_mode = zones_info[zone_idx].mode; if (set_mode>modes.size()) { set_mode = active_mode; } controller->WriteZone((unsigned char)zone_idx, set_mode, zones_info[zone_idx].speed, zones[zone_idx].colors[0], false); } } void RGBController_PolychromeUSB::UpdateZoneLEDs(int zone) { unsigned char set_mode=zones_info[zone].mode; if(set_mode > modes.size()) { set_mode = active_mode; } controller->WriteZone(zone, set_mode, zones_info[zone].speed, zones[zone].colors[0], false); } void RGBController_PolychromeUSB::UpdateSingleLED(int led) { unsigned int channel = leds[led].value; unsigned char set_mode = zones_info[channel].mode; if(set_mode > modes.size()) { set_mode = active_mode; } controller->WriteZone(channel, set_mode, zones_info[channel].speed, zones[channel].colors[0], false); } unsigned char RGBController_PolychromeUSB::GetDeviceMode(unsigned char zone) { int dev_mode; dev_mode = controller->GetZoneConfig(zone).mode; active_mode = dev_mode; return(active_mode); } void RGBController_PolychromeUSB::DeviceUpdateMode() { /*-----------------------------------------------------------------*\ | Disable RGSwap as it causes flashing on each update in direct mode| | Otherwise, reset to values specified in settings.json | \*-----------------------------------------------------------------*/ controller->SetRGSwap(modes[active_mode].name != "Direct"); for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++) { if(zones[zone_idx].leds_count > 0) { unsigned char set_mode =(unsigned char) modes[active_mode].value; zones_info[zone_idx].mode =(unsigned char) modes[active_mode].value; zones_info[zone_idx].speed =(unsigned char) modes[active_mode].speed; if(set_mode > modes.size()) { set_mode = active_mode; } controller->WriteZone(zone_idx, set_mode, zones_info[zone_idx].speed, zones[zone_idx].colors[0], false); } } }