/*-----------------------------------------*\ | RGBController_MSIMysticLight185.cpp | | | | Generic RGB Interface for OpenRGB | | MSI Mystic Light (185-byte) USB Driver | | | | T-bond 3/4/2020 | | Adam Honse 3/6/2021 | \*-----------------------------------------*/ #include "RGBController_MSIMysticLight185.h" struct ZoneDescription { std::string name; const MSI_ZONE* leds; }; static const MSI_ZONE ZoneList_JRGB1[] = { MSI_ZONE_J_RGB_1, MSI_ZONE_NONE }; static const MSI_ZONE ZoneList_JRGB2[] = { MSI_ZONE_J_RGB_2, MSI_ZONE_NONE }; static const MSI_ZONE ZoneList_JRainbow1[] = { MSI_ZONE_J_RAINBOW_1, MSI_ZONE_NONE }; static const MSI_ZONE ZoneList_JRainbow2[] = { MSI_ZONE_J_RAINBOW_2, MSI_ZONE_NONE }; static const MSI_ZONE ZoneList_JCorsair[] = { MSI_ZONE_J_CORSAIR, MSI_ZONE_NONE }; static const MSI_ZONE ZoneList_JPipe[] = { MSI_ZONE_J_PIPE_1, MSI_ZONE_J_PIPE_2, MSI_ZONE_NONE }; static const MSI_ZONE ZoneList_Onboard[] = { MSI_ZONE_ON_BOARD_LED_0, MSI_ZONE_ON_BOARD_LED_1, MSI_ZONE_ON_BOARD_LED_2, MSI_ZONE_ON_BOARD_LED_3, MSI_ZONE_ON_BOARD_LED_4, MSI_ZONE_ON_BOARD_LED_5, MSI_ZONE_ON_BOARD_LED_6, MSI_ZONE_ON_BOARD_LED_7, MSI_ZONE_ON_BOARD_LED_8, MSI_ZONE_ON_BOARD_LED_9, MSI_ZONE_NONE }; #define NUM_ZONES (sizeof(led_zones) / sizeof(led_zones[0])) static const ZoneDescription led_zones[] = { ZoneDescription{"JRGB1", ZoneList_JRGB1 }, ZoneDescription{"JRGB2", ZoneList_JRGB2 }, ZoneDescription{"JRAINBOW1", ZoneList_JRainbow1 }, ZoneDescription{"JRAINBOW2", ZoneList_JRainbow2 }, ZoneDescription{"JCORSAIR", ZoneList_JCorsair }, ZoneDescription{"Pipe LEDs", ZoneList_JPipe }, ZoneDescription{"Onboard LEDs", ZoneList_Onboard }, }; RGBController_MSIMysticLight185::RGBController_MSIMysticLight185(MSIMysticLight185Controller* controller_ptr) { controller = controller_ptr; name = controller->GetDeviceName(); vendor = "MSI"; type = DEVICE_TYPE_MOTHERBOARD; description = "MSI Mystic Light Device (185-byte)"; version = controller->GetFWVersion(); location = controller->GetDeviceLocation(); serial = controller->GetSerial(); SetupModes(); SetupZones(); SetupColors(); } RGBController_MSIMysticLight185::~RGBController_MSIMysticLight185() { delete controller; } void RGBController_MSIMysticLight185::SetupZones() { /*---------------------------------------------------------*\ | Set up zones | \*---------------------------------------------------------*/ for(std::size_t zone_idx = 0; zone_idx < NUM_ZONES; zone_idx++) { ZoneDescription zd = led_zones[zone_idx]; zone new_zone; unsigned int led_count = 0; while(zd.leds[led_count] != MSI_ZONE_NONE) { led_count++; } new_zone.name = zd.name; new_zone.type = ZONE_TYPE_LINEAR; new_zone.leds_min = led_count; new_zone.leds_max = led_count; new_zone.leds_count = led_count; new_zone.matrix_map = NULL; zones.push_back(new_zone); /*---------------------------------------------------------*\ | Set up LEDs | \*---------------------------------------------------------*/ for(std::size_t led_idx = 0; led_idx < new_zone.leds_count; led_idx++) { led new_led; new_led.name = new_zone.name + " LED "; if(new_zone.leds_count > 1) { new_led.name.append(std::to_string(led_idx + 1)); } new_led.value = zd.leds[led_idx]; leds.push_back(new_led); } } } void RGBController_MSIMysticLight185::ResizeZone(int zone, int new_size) { } void RGBController_MSIMysticLight185::SetCustomMode() { active_mode = 0; } void RGBController_MSIMysticLight185::DeviceUpdateLEDs() { for(size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) { for(int led_idx = zones[zone_idx].leds_count - 1; led_idx >= 0; led_idx--) { UpdateLed(zone_idx, led_idx); } } controller->Update(); } void RGBController_MSIMysticLight185::UpdateZoneLEDs(int zone) { for(int led_idx = zones[zone].leds_count - 1; led_idx >= 0; led_idx--) { UpdateLed(zone, led_idx); } controller->Update(); } void RGBController_MSIMysticLight185::UpdateSingleLED(int led) { UpdateLed(leds[led].value, led); controller->Update(); } void RGBController_MSIMysticLight185::DeviceUpdateMode() { } void RGBController_MSIMysticLight185::SetupModes() { constexpr unsigned int RANDOM_ONLY = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR; constexpr unsigned int COMMON = RANDOM_ONLY | MODE_FLAG_HAS_PER_LED_COLOR; SetupMode("Direct", MSI_MODE_STATIC, MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR); //SetupMode("Off", MSI_MODE_DISABLE, 0); SetupMode("Breathing", MSI_MODE_BREATHING, COMMON); SetupMode("Flashing", MSI_MODE_FLASHING, COMMON); SetupMode("Double flashing", MSI_MODE_DOUBLE_FLASHING, COMMON); SetupMode("Lightning", MSI_MODE_LIGHTNING, COMMON); // SetupMode("MSI Marquee", MSI_MODE_MSI_MARQUEE, COMMON); // SetupMode("Meteor", MSI_MODE_METEOR, COMMON); // SetupMode("Water drop", MSI_MODE_WATER_DROP, COMMON); // SetupMode("MSI Rainbow", MSI_MODE_MSI_RAINBOW, RANDOM_ONLY); // SetupMode("Pop", MSI_MODE_POP, COMMON); // SetupMode("Rap", MSI_MODE_RAP, COMMON); // SetupMode("Jazz", MSI_MODE_JAZZ, COMMON); // SetupMode("Play", MSI_MODE_PLAY, COMMON); // SetupMode("Movie", MSI_MODE_MOVIE, COMMON); // SetupMode("Color ring", MSI_MODE_COLOR_RING, COMMON); // SetupMode("Planetary", MSI_MODE_PLANETARY, COMMON); // SetupMode("Double meteor", MSI_MODE_DOUBLE_METEOR, COMMON); // SetupMode("Energy", MSI_MODE_ENERGY, COMMON); // SetupMode("Blink", MSI_MODE_BLINK, COMMON); // SetupMode("Clock", MSI_MODE_CLOCK, COMMON); // SetupMode("Color pulse", MSI_MODE_COLOR_PULSE, COMMON); // SetupMode("Color shift", MSI_MODE_COLOR_SHIFT, COMMON); // SetupMode("Color wave", MSI_MODE_COLOR_WAVE, COMMON); // SetupMode("Marquee", MSI_MODE_MARQUEE, COMMON); // SetupMode("Rainbow", MSI_MODE_RAINBOW, COMMON); // SetupMode("Rainbow wave", MSI_MODE_RAINBOW_WAVE, COMMON); // SetupMode("Visor", MSI_MODE_VISOR, COMMON); // SetupMode("JRainbow", MSI_MODE_JRAINBOW, COMMON); // SetupMode("Rainbow flashing", MSI_MODE_RAINBOW_FLASHING, COMMON); // SetupMode("Rainbow double flashing", MSI_MODE_RAINBOW_DOUBLE_FLASHING, COMMON); // SetupMode("Random", MSI_MODE_RANDOM, COMMON); // SetupMode("Fan control", MSI_MODE_FAN_CONTROL, COMMON); // SetupMode("Off 2", MSI_MODE_DISABLE_2, COMMON); // SetupMode("Color ring flashing", MSI_MODE_COLOR_RING_FLASHING, COMMON); // SetupMode("Color ring double flashing", MSI_MODE_COLOR_RING_DOUBLE_FLASHING, COMMON); // SetupMode("Stack", MSI_MODE_STACK, COMMON); // SetupMode("Corsair Que", MSI_MODE_CORSAIR_QUE, COMMON); // SetupMode("Fire", MSI_MODE_FIRE, COMMON); // SetupMode("Lava", MSI_MODE_LAVA, COMMON); } void RGBController_MSIMysticLight185::UpdateLed(int zone, int led) { bool random = modes[active_mode].color_mode == MODE_COLORS_RANDOM; unsigned char red = RGBGetRValue(zones[zone].colors[led]); unsigned char grn = RGBGetGValue(zones[zone].colors[led]); unsigned char blu = RGBGetBValue(zones[zone].colors[led]); MSI_MODE mode = (MSI_MODE)(modes[active_mode].value); MSI_SPEED speed = (MSI_SPEED)(modes[active_mode].speed); controller->SetMode((MSI_ZONE)zones[zone].leds[led].value, mode, speed, MSI_BRIGHTNESS_LEVEL_100, random); controller->SetZoneColor((MSI_ZONE)zones[zone].leds[led].value, red, grn, blu, red, grn, blu); } void RGBController_MSIMysticLight185::SetupMode(const char *name, MSI_MODE mod, unsigned int flags) { mode Mode; Mode.name = name; Mode.value = mod; Mode.flags = flags; if(flags & MODE_FLAG_HAS_PER_LED_COLOR) { Mode.color_mode = MODE_COLORS_PER_LED; } else { Mode.color_mode = MODE_COLORS_RANDOM; } if(flags & MODE_FLAG_HAS_SPEED) { Mode.speed = MSI_SPEED_MEDIUM; Mode.speed_max = MSI_SPEED_HIGH; Mode.speed_min = MSI_SPEED_LOW; } else { /*---------------------------------------------------------*\ | For modes without speed this needs to be set to avoid | | bad values in the saved profile which in turn corrupts | | the brightness calculation when loading the profile | \*---------------------------------------------------------*/ Mode.speed = 0; Mode.speed_max = 0; Mode.speed_min = 0; } modes.push_back(Mode); }