From 98ebcb2ee099ee2469ef5a71c9caa11556072586 Mon Sep 17 00:00:00 2001 From: Thomas Boos Date: Mon, 30 May 2022 05:14:11 +0000 Subject: [PATCH] MSI Mystic Light Rework * Direct mode for certain 185-byte boards based on Aleksandr Garashchenko's mystic-why project * Improved detector to automatically determine controller type (162 vs 185 byte) * Re-enable missing modes and improve mode control * Code cleanup Commits squashed and amended by Adam Honse as part of !1181 --- .../MSIMysticLight162Controller.cpp | 392 ++++++-- .../MSIMysticLight162Controller.h | 60 +- .../MSIMysticLight185Controller.cpp | 903 ++++++++++++++---- .../MSIMysticLight185Controller.h | 106 +- .../MSIMysticLightCommon.h | 58 +- .../MSIMysticLightControllerDetect.cpp | 207 ++-- .../RGBController_MSIMysticLight162.cpp | 274 +++--- .../RGBController_MSIMysticLight162.h | 35 +- .../RGBController_MSIMysticLight185.cpp | 365 ++++--- .../RGBController_MSIMysticLight185.h | 36 +- 10 files changed, 1705 insertions(+), 731 deletions(-) diff --git a/Controllers/MSIMysticLightController/MSIMysticLight162Controller.cpp b/Controllers/MSIMysticLightController/MSIMysticLight162Controller.cpp index 18b87b720..2f1f356ab 100644 --- a/Controllers/MSIMysticLightController/MSIMysticLight162Controller.cpp +++ b/Controllers/MSIMysticLightController/MSIMysticLight162Controller.cpp @@ -13,7 +13,70 @@ #include #include -MSIMysticLight162Controller::MSIMysticLight162Controller(hid_device* handle, const char *path) + +#define BITSET(val, bit, pos) ((unsigned char)std::bitset<8>(val).set((pos), (bit)).to_ulong()) + + +struct Config +{ + unsigned short pid; // PID of the board + size_t numof_onboard_leds; // number of onboard leds + const std::vector* supported_zones; // pointer to vector of supported zones +}; + +const std::vector zones_set0 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RGB_2, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_CORSAIR, + MSI_ZONE_ON_BOARD_LED_0 +}; + +const std::vector zones_set1 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RGB_2, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_ON_BOARD_LED_0 +}; + +const std::vector zones_set2 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RGB_2, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_ON_BOARD_LED_0 +}; + +/*-----------------------------------------------------------------------------------------------------------------------------*\ +| Definition of the board sepcific configurations (number of onboard LEDs and supported zones). | +| | +| Only tested boards are listed here (refer to MSIMysticLightControllerDetect.cpp). If more boards | +| are tested the list must be extended here. Otherwise the default settings will be used (7 onboard LEDs, all zones supported). | +| Boards with yet unknown supported zones are configured to support all zones. | +\*-----------------------------------------------------------------------------------------------------------------------------*/ + +#define NUMOF_CONFIGS (sizeof(board_configs) / sizeof(Config)) + +static const Config board_configs[] = +{ + { 0x1720, 10, &zones_set0 }, // MPG Z390 GAMING EDGE AC + { 0x7B12, 10, &zones_set0 }, // MEG Z390 ACE + { 0x7B17, 10, &zones_set0 }, // MPG Z390 GAMING PRO CARBON + { 0x7B18, 6, &zones_set1 }, // MAG Z390 TOMAHAWK verified + { 0x7B50, 6, &zones_set2 }, // MPG Z390M GAMING EDGE AC verified + { 0x7B85, 7, &zones_set0 }, // B450 GAMING PRO CARBON verified +}; + + +MSIMysticLight162Controller::MSIMysticLight162Controller + ( + hid_device* handle, + const char *path, + unsigned short pid + ) { dev = handle; @@ -31,6 +94,64 @@ MSIMysticLight162Controller::MSIMysticLight162Controller(hid_device* handle, con | Initialize save flag | \*-----------------------------------------*/ data.save_data = 0; + data.on_board_led.colorFlags = 0x81; // force MS bit of color flags to 1 to have expectd zone control + + /*-----------------------------------------*\ + | Initialize zone based per LED data | + \*-----------------------------------------*/ + const Config* board_config = nullptr; + + for(std::size_t i = 0; i < NUMOF_CONFIGS; ++i) + { + if (board_configs[i].pid == pid) + { + board_config = &board_configs[i]; + break; + } + } + + if(board_config != nullptr) + { + numof_onboard_leds = board_config->numof_onboard_leds; + supported_zones = board_config->supported_zones; + } + else + { + numof_onboard_leds = 10; + supported_zones = &zones_set0; + } + + zone_based_per_led_data.j_rgb_1.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.j_rgb_1.colorFlags = BITSET(zone_based_per_led_data.j_rgb_1.colorFlags, true, 7u); + zone_based_per_led_data.j_rainbow_1.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.j_rainbow_1.colorFlags = BITSET(zone_based_per_led_data.j_rainbow_1.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led.colorFlags = BITSET(zone_based_per_led_data.on_board_led.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_1.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_1.colorFlags = BITSET(zone_based_per_led_data.on_board_led_1.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_2.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_2.colorFlags = BITSET(zone_based_per_led_data.on_board_led_2.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_3.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_3.colorFlags = BITSET(zone_based_per_led_data.on_board_led_3.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_4.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_4.colorFlags = BITSET(zone_based_per_led_data.on_board_led_4.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_5.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_5.colorFlags = BITSET(zone_based_per_led_data.on_board_led_5.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_6.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2 << 2; + zone_based_per_led_data.on_board_led_6.colorFlags = BITSET(zone_based_per_led_data.on_board_led_6.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_7.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100; + zone_based_per_led_data.on_board_led_7.colorFlags = BITSET(zone_based_per_led_data.on_board_led_7.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_8.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_8.colorFlags = BITSET(zone_based_per_led_data.on_board_led_8.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_9.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_9.colorFlags = BITSET(zone_based_per_led_data.on_board_led_9.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_10.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_10.colorFlags = BITSET(zone_based_per_led_data.on_board_led_9.colorFlags, true, 7u); + zone_based_per_led_data.j_rgb_2.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.j_rgb_2.colorFlags = BITSET(zone_based_per_led_data.j_rgb_2.colorFlags, true, 7u); + zone_based_per_led_data.save_data = 0; + + direct_mode = false; } MSIMysticLight162Controller::~MSIMysticLight162Controller() @@ -40,23 +161,51 @@ MSIMysticLight162Controller::~MSIMysticLight162Controller() void MSIMysticLight162Controller::SetMode ( - MSI_ZONE zone, - MSI_MODE mode, - MSI_SPEED speed, - MSI_BRIGHTNESS brightness, - bool rainbow_color + MSI_ZONE zone, + MSI_MODE mode, + MSI_SPEED speed, + MSI_BRIGHTNESS brightness, + bool rainbow_color ) { - ZoneData* zoneData = GetZoneData(zone); - if(!zoneData) + ZoneData* zone_data = GetZoneData(data, zone); + + if(zone_data == nullptr) { return; } - zoneData->effect = mode; - zoneData->speedAndBrightnessFlags = ( brightness << 2 ) | ( speed & 0x03 ); - zoneData->colorFlags = 0x00;// BitSet(zoneData->colorFlags, !rainbow_color, 7u); - zoneData->padding = 0x00; + if (zone <= MSI_ZONE_ON_BOARD_LED_0) + { + zone_data->effect = mode; + zone_data->speedAndBrightnessFlags = (brightness << 2) | (speed & 0x03); + zone_data->colorFlags = BITSET(zone_data->colorFlags, !rainbow_color, 7u); + zone_data->padding = 0x00; + + if(mode > MSI_MODE_DOUBLE_FLASHING) + { + zone_data->speedAndBrightnessFlags |= SYNC_SETTING_JRGB; + zone_data->colorFlags |= SYNC_SETTING_ONBOARD; + } + else + { + zone_data->speedAndBrightnessFlags &= ~SYNC_SETTING_JRGB; + zone_data->colorFlags &= ~SYNC_SETTING_ONBOARD; + } + } + + if((zone >= MSI_ZONE_ON_BOARD_LED_0) && (mode <= MSI_MODE_DOUBLE_FLASHING)) + { + zone_data = GetZoneData(data, (MSI_ZONE)((int)zone + 1)); + + if(zone_data != nullptr) + { + zone_data->effect = mode; + zone_data->speedAndBrightnessFlags = (brightness << 2) | (speed & 0x03); + zone_data->colorFlags = BITSET(zone_data->colorFlags, !rainbow_color, 7u); + zone_data->padding = 0x00; + } + } } std::string MSIMysticLight162Controller::GetDeviceName() @@ -86,99 +235,145 @@ bool MSIMysticLight162Controller::ReadSettings() /*-----------------------------------------------------*\ | Read packet from hardware, return true if successful | \*-----------------------------------------------------*/ - return(hid_get_feature_report(dev, (unsigned char *)&data, sizeof(data)) == sizeof data); + return(hid_get_feature_report(dev, (unsigned char*)&data, sizeof(data)) == sizeof data); } -bool MSIMysticLight162Controller::Update() +bool MSIMysticLight162Controller::Update + ( + bool save + ) { /*-----------------------------------------------------*\ | Send packet to hardware, return true if successful | \*-----------------------------------------------------*/ - return(hid_send_feature_report(dev, (unsigned char *)&data, sizeof(data)) == sizeof data); + if(direct_mode) + { + return (hid_send_feature_report(dev, (unsigned char*)&zone_based_per_led_data, sizeof(zone_based_per_led_data)) == sizeof(zone_based_per_led_data)); + } + else + { + data.save_data = save; + return (hid_send_feature_report(dev, (unsigned char*)&data, sizeof(data)) == sizeof(data)); + } } -void MSIMysticLight162Controller::SetLEDColor +void MSIMysticLight162Controller::SetZoneColor ( - MSI_ZONE zone, - unsigned char red1, - unsigned char grn1, - unsigned char blu1, - unsigned char red2, - unsigned char grn2, - unsigned char blu2 + MSI_ZONE zone, + unsigned char red1, + unsigned char grn1, + unsigned char blu1, + unsigned char red2, + unsigned char grn2, + unsigned char blu2 ) { - ZoneData* zoneData = GetZoneData(zone); + ZoneData* zone_data = GetZoneData(data, zone); - if(!zoneData) + if(zone_data == nullptr) { return; } - zoneData->color.R = red1; - zoneData->color.G = grn1; - zoneData->color.B = blu1; + if (zone <= MSI_ZONE_ON_BOARD_LED_0) + { + zone_data->color.R = red1; + zone_data->color.G = grn1; + zone_data->color.B = blu1; + zone_data->color2.R = red2; + zone_data->color2.G = grn2; + zone_data->color2.B = blu2; + } - zoneData->color2.R = red2; - zoneData->color2.G = grn2; - zoneData->color2.B = blu2; + if(zone >= MSI_ZONE_ON_BOARD_LED_0) + { + zone_data = GetZoneData(data, (MSI_ZONE)((int)zone + 1)); + + if(zone_data != nullptr) + { + zone_data->color.R = red1; + zone_data->color.G = grn1; + zone_data->color.B = blu1; + zone_data->color2.R = red2; + zone_data->color2.G = grn2; + zone_data->color2.B = blu2; + } + } +} + +void MSIMysticLight162Controller::SetLedColor + ( + MSI_ZONE zone, + unsigned char red, + unsigned char grn, + unsigned char blu + ) +{ + if(zone >= MSI_ZONE_ON_BOARD_LED_0) + { + zone = (MSI_ZONE)((int)zone + 1); + } + + ZoneData *zone_data = GetZoneData(zone_based_per_led_data, zone); + + if(zone_data == nullptr) + { + return; + } + + zone_data->color.R = red; + zone_data->color.G = grn; + zone_data->color.B = blu; + zone_data->color2.R = red; + zone_data->color2.G = grn; + zone_data->color2.B = blu; } ZoneData *MSIMysticLight162Controller::GetZoneData ( - MSI_ZONE zone - ) -{ - switch(zone) - { - case MSI_ZONE_J_RGB_1: - return &data.j_rgb_1; - case MSI_ZONE_J_RGB_2: - return &data.j_rgb_2; - case MSI_ZONE_J_RAINBOW_1: - return &data.j_rainbow_1; - case MSI_ZONE_ON_BOARD_LED_0: - return &data.on_board_led; - case MSI_ZONE_ON_BOARD_LED_1: - return &data.on_board_led_1; - case MSI_ZONE_ON_BOARD_LED_2: - return &data.on_board_led_2; - case MSI_ZONE_ON_BOARD_LED_3: - return &data.on_board_led_3; - case MSI_ZONE_ON_BOARD_LED_4: - return &data.on_board_led_4; - case MSI_ZONE_ON_BOARD_LED_5: - return &data.on_board_led_5; - case MSI_ZONE_ON_BOARD_LED_6: - return &data.on_board_led_6; - case MSI_ZONE_ON_BOARD_LED_7: - return &data.on_board_led_7; - case MSI_ZONE_ON_BOARD_LED_8: - return &data.on_board_led_8; - case MSI_ZONE_ON_BOARD_LED_9: - return &data.on_board_led_9; - case MSI_ZONE_J_CORSAIR: - return &data.j_corsair_1; - } - - return nullptr; -} - -RainbowZoneData *MSIMysticLight162Controller::GetRainbowZoneData - ( + FeaturePacket_162& data_packet, MSI_ZONE zone ) { switch(zone) { - case MSI_ZONE_J_RAINBOW_1: - return (RainbowZoneData *)&data.j_rainbow_1; -// case MSI_ZONE_J_RAINBOW_2: -// return &data.j_rainbow_2; - case MSI_ZONE_J_CORSAIR: - default: - return nullptr; + case MSI_ZONE_J_RGB_1: + return &data_packet.j_rgb_1; + case MSI_ZONE_J_RGB_2: + return &data_packet.j_rgb_2; + case MSI_ZONE_J_RAINBOW_1: + return &data_packet.j_rainbow_1; + case MSI_ZONE_J_RAINBOW_2: + return &data_packet.on_board_led_10; + case MSI_ZONE_ON_BOARD_LED_0: + return &data_packet.on_board_led; + case MSI_ZONE_ON_BOARD_LED_1: + return &data_packet.on_board_led_1; + case MSI_ZONE_ON_BOARD_LED_2: + return &data_packet.on_board_led_2; + case MSI_ZONE_ON_BOARD_LED_3: + return &data_packet.on_board_led_3; + case MSI_ZONE_ON_BOARD_LED_4: + return &data_packet.on_board_led_4; + case MSI_ZONE_ON_BOARD_LED_5: + return &data_packet.on_board_led_5; + case MSI_ZONE_ON_BOARD_LED_6: + return &data_packet.on_board_led_6; + case MSI_ZONE_ON_BOARD_LED_7: + return &data_packet.on_board_led_7; + case MSI_ZONE_ON_BOARD_LED_8: + return &data_packet.on_board_led_8; + case MSI_ZONE_ON_BOARD_LED_9: + return &data_packet.on_board_led_9; + case MSI_ZONE_ON_BOARD_LED_10: + return &data_packet.on_board_led_10; + case MSI_ZONE_J_CORSAIR: + return &data_packet.j_corsair_1; + default: + break; } + + return nullptr; } bool MSIMysticLight162Controller::ReadFwVersion() @@ -225,7 +420,7 @@ bool MSIMysticLight162Controller::ReadFwVersion() /*-----------------------------------------------------*\ | Build firmware string . | \*-----------------------------------------------------*/ - version_APROM = std::to_string(static_cast(highValue)).append(".").append(std::to_string(static_cast(lowValue))); + version_APROM = std::to_string((int)highValue).append(".").append(std::to_string((int)lowValue)); /*-----------------------------------------------------*\ | First read the LDROM | @@ -254,7 +449,7 @@ bool MSIMysticLight162Controller::ReadFwVersion() /*-----------------------------------------------------*\ | Build firmware string . | \*-----------------------------------------------------*/ - version_LDROM = std::to_string(static_cast(highValue)).append(".").append(std::to_string(static_cast(lowValue))); + version_LDROM = std::to_string((int)highValue).append(".").append(std::to_string((int)lowValue)); /*-----------------------------------------------------*\ | If return value is zero it means an HID transfer | @@ -308,22 +503,22 @@ void MSIMysticLight162Controller::ReadName() void MSIMysticLight162Controller::GetMode ( - MSI_ZONE zone, - MSI_MODE &mode, - MSI_SPEED &speed, - MSI_BRIGHTNESS &brightness, - bool &rainbow_color - ) + MSI_ZONE zone, + MSI_MODE &mode, + MSI_SPEED &speed, + MSI_BRIGHTNESS &brightness, + bool &rainbow_color + ) { /*-----------------------------------------------------*\ | Get data for given zone | \*-----------------------------------------------------*/ - ZoneData *zoneData = GetZoneData(zone); + ZoneData *zone_data = GetZoneData(data, zone); /*-----------------------------------------------------*\ | Return if zone is invalid | \*-----------------------------------------------------*/ - if (!zoneData) + if(zone_data == nullptr) { return; } @@ -331,18 +526,21 @@ void MSIMysticLight162Controller::GetMode /*-----------------------------------------------------*\ | Update pointers with data | \*-----------------------------------------------------*/ - mode = (MSI_MODE)(zoneData->effect); - speed = (MSI_SPEED)(zoneData->speedAndBrightnessFlags & 0x03); - brightness = (MSI_BRIGHTNESS)((zoneData->speedAndBrightnessFlags >> 2) & 0x1F); - rainbow_color = (zoneData->colorFlags & 0x80) >> 7; + mode = (MSI_MODE)zone_data->effect; + speed = (MSI_SPEED)(zone_data->speedAndBrightnessFlags & 0x03); + brightness = (MSI_BRIGHTNESS)((zone_data->speedAndBrightnessFlags >> 2) & 0x1F); + rainbow_color = (zone_data->colorFlags & 0x80) >> 7; } -unsigned char MSIMysticLight162Controller::BitSet +void MSIMysticLight162Controller::SetDirectMode ( - unsigned char value, - bool bit, - unsigned int position + bool mode ) { - return static_cast(std::bitset<8>(value).set(position, bit).to_ulong()); + direct_mode = mode; +} + +size_t MSIMysticLight162Controller::GetMaxOnboardLeds() +{ + return numof_onboard_leds; } diff --git a/Controllers/MSIMysticLightController/MSIMysticLight162Controller.h b/Controllers/MSIMysticLightController/MSIMysticLight162Controller.h index e7fe01e2c..92217ca30 100644 --- a/Controllers/MSIMysticLightController/MSIMysticLight162Controller.h +++ b/Controllers/MSIMysticLightController/MSIMysticLight162Controller.h @@ -19,7 +19,12 @@ class MSIMysticLight162Controller { public: - MSIMysticLight162Controller(hid_device* handle, const char *path); + MSIMysticLight162Controller + ( + hid_device* handle, + const char *path, + unsigned short pid + ); ~MSIMysticLight162Controller(); void SetMode @@ -40,7 +45,7 @@ public: bool &rainbow_color ); - void SetLEDColor + void SetZoneColor ( MSI_ZONE zone, unsigned char red1, @@ -51,30 +56,55 @@ public: unsigned char blu2 ); - bool Update(); + void SetLedColor + ( + MSI_ZONE zone, + unsigned char red, + unsigned char grn, + unsigned char blu + ); + + bool Update + ( + bool save + ); std::string GetDeviceName(); std::string GetDeviceLocation(); std::string GetFWVersion(); std::string GetSerial(); + + void SetDirectMode + ( + bool mode + ); + bool IsDirectModeActive() { return direct_mode; } + size_t GetMaxOnboardLeds(); + const std::vector* + GetSupportedZones() { return supported_zones; } + private: bool ReadSettings(); - void SaveOnUpdate(bool send); bool ReadFwVersion(); void ReadSerial(); void ReadName(); - ZoneData* GetZoneData(MSI_ZONE zone); - RainbowZoneData* - GetRainbowZoneData(MSI_ZONE zone); - static unsigned char BitSet(unsigned char value, bool bit, unsigned int position); + ZoneData* GetZoneData + ( + FeaturePacket_162& dataPacket, + MSI_ZONE zone + ); - hid_device* dev; - std::string name; - std::string location; - std::string version_APROM; - std::string version_LDROM; - std::string chip_id; + hid_device* dev; + std::string name; + std::string location; + std::string version_APROM; + std::string version_LDROM; + std::string chip_id; - FeaturePacket_162 data; + FeaturePacket_162 data; + FeaturePacket_162 zone_based_per_led_data; + bool direct_mode; + size_t numof_onboard_leds; + const std::vector* supported_zones; }; diff --git a/Controllers/MSIMysticLightController/MSIMysticLight185Controller.cpp b/Controllers/MSIMysticLightController/MSIMysticLight185Controller.cpp index 84111e17b..348605769 100644 --- a/Controllers/MSIMysticLightController/MSIMysticLight185Controller.cpp +++ b/Controllers/MSIMysticLightController/MSIMysticLight185Controller.cpp @@ -1,19 +1,236 @@ -/*-----------------------------------------*\ -| MSIMysticLight185Controller.cpp | -| | -| Driver for MSI Mystic Light (185-byte) | -| USB lighting controller | -| | -| T-bond 3/4/2020 | -| Adam Honse 3/6/2021 | -\*-----------------------------------------*/ +/*---------------------------------------------*\ +| MSIMysticLight185Controller.cpp | +| | +| Driver for MSI Mystic Light (185-byte) | +| USB lighting controller | +| | +| T-bond 3/4/2020 | +| Adam Honse 3/6/2021 | +| | +| The direct mode part has been implemented | +| based on the mystic-why project provided by | +| Aleksandr Garashchenko | +| (https://github.com/garashchenko/mystic-why) | +\*---------------------------------------------*/ #include "MSIMysticLight185Controller.h" #include #include #include -MSIMysticLight185Controller::MSIMysticLight185Controller(hid_device* handle, const char *path) + +#define BITSET(val, bit, pos) ((unsigned char)std::bitset<8>(val).set((pos), (bit)).to_ulong()) + + +struct Config +{ + unsigned short pid; // PID of the board + int numof_onboard_leds; // number of onboard leds + int numof_pipe1_leds; // number of pipe 1 leds (used in per LED mode only) + int numof_pipe2_leds; // number of pipe 2 leds (used in per LED mode only) + int numof_JRGBs; // number of supported JRGB headers (used in per LED mode only) + const std::vector* supported_zones; // pointer to vector of supported zones + MSIMysticLight185Controller::DIRECT_MODE per_led_mode; // type of direct mode support +}; + +const std::vector all_zones = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RGB_2, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_J_CORSAIR, + MSI_ZONE_J_PIPE_1, + MSI_ZONE_J_PIPE_2, + MSI_ZONE_ON_BOARD_LED_0 +}; + +const std::vector zones_set0 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RGB_2, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_ON_BOARD_LED_0 +}; + +const std::vector zones_set1 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_J_CORSAIR +}; + +const std::vector zones_set2 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_ON_BOARD_LED_0 +}; + +const std::vector zones_set3 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_J_CORSAIR, + MSI_ZONE_J_PIPE_1, + MSI_ZONE_ON_BOARD_LED_0 +}; + +const std::vector zones_set4 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_J_CORSAIR, + MSI_ZONE_J_PIPE_1, + MSI_ZONE_ON_BOARD_LED_0 +}; + +const std::vector zones_set5 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RAINBOW_1 +}; + +const std::vector zones_set6 = +{ + MSI_ZONE_J_RAINBOW_1 +}; + +const std::vector zones_set7 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RGB_2, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_J_PIPE_1, + MSI_ZONE_ON_BOARD_LED_0 +}; + +const std::vector zones_set8 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_J_CORSAIR, + MSI_ZONE_J_PIPE_1, + MSI_ZONE_J_PIPE_2 +}; + +const std::vector zones_set9 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_J_CORSAIR, + MSI_ZONE_J_PIPE_1 +}; + +const std::vector zones_set10 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_J_RAINBOW_3 +}; + +const std::vector zones_set11 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2 +}; + +const std::vector zones_set12 = +{ + MSI_ZONE_J_RGB_1, + MSI_ZONE_J_RAINBOW_1, + MSI_ZONE_J_RAINBOW_2, + MSI_ZONE_J_RAINBOW_3, + MSI_ZONE_J_PIPE_1, + MSI_ZONE_ON_BOARD_LED_0 +}; + + + +/*---------------------------------------------------------------------------------------------------------------------------------*\ +| Definition of the board sepcific configurations (number of onboard LEDs and supported zones). | +| | +| Only tested boards are listed here (refer to MSIMysticLightControllerDetect.cpp). If more boards | +| are tested the list must be extended here. Otherwise the default settings will be used (6 onboard LEDs, 2 JRGB, no direct mode). | +| Boards with yet unknown supported zones are configured to support all zones. | +\*---------------------------------------------------------------------------------------------------------------------------------*/ + +#define NUMOF_CONFIGS (sizeof(board_configs) / sizeof(Config)) + +static const Config board_configs[] = +{ + { 0x7B93, 6, 1, 0, 1, &zones_set4, MSIMysticLight185Controller::DIRECT_MODE_ZONE_BASED }, // MPG X570 GAMING PRO CARBON WIFI + { 0x7C34, 0, 1, 1, 1, &zones_set8, MSIMysticLight185Controller::DIRECT_MODE_ZONE_BASED }, // MEG X570 GODLIKE verified + { 0x7C35, 0, 1, 0, 1, &zones_set9, MSIMysticLight185Controller::DIRECT_MODE_ZONE_BASED }, // MEG X570 ACE verified + { 0x7C36, 6, 1, 0, 1, &zones_set4, MSIMysticLight185Controller::DIRECT_MODE_ZONE_BASED }, // PRESTIGE X570 CREATION + { 0x7C37, 1, 0, 0, 2, &zones_set0, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // MPG X570 GAMING PLUS verified + { 0x7C56, 6, 0, 0, 1, &zones_set2, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MPG B550 GAMING PLUS verified + { 0x7C59, 0, 8, 0, 1, &zones_set9, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // CREATOR TRX40 + { 0x7C67, 6, 0, 0, 1, &zones_set5, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // MAG B365M MORTAR verified + { 0x7C71, 6, 6, 0, 1, &zones_set3, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MEG Z490 ACE verified + { 0x7C73, 6, 4, 0, 1, &zones_set3, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MPG Z490 GAMING CARBON WIFI verified + { 0x7C75, 6, 0, 0, 1, &zones_set2, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MPG Z490 GAMING PLUS verified + { 0x7C76, 6, 0, 0, 2, &zones_set0, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // MPG Z490M GAMING EDGE + { 0x7C79, 6, 0, 0, 2, &zones_set0, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MPG Z490 GAMING EDGE WIFI verified + { 0x7C80, 6, 0, 0, 2, &zones_set0, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MAG Z490 TOMAHAWK verified + { 0x7C81, 6, 0, 0, 2, &zones_set0, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // MAG B460 TOMAHAWK + { 0x7C83, 6, 0, 0, 1, &zones_set5, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // B460M PRO-VDH WIFI + { 0x7C84, 6, 0, 0, 2, &zones_set0, MSIMysticLight185Controller::DIRECT_MODE_ZONE_BASED }, // MAG X570 TOMAHAWK WIFI verified + { 0x7C86, 6, 0, 0, 1, &zones_set5, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // MPG B460I GAMING EDGE + { 0x7C90, 6, 4, 0, 1, &zones_set3, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MPG B550 GAMING CARBON WIFI verified + { 0x7C91, 6, 0, 0, 2, &zones_set0, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MAG B550 TOMAHAWK verified + { 0x7C92, 6, 0, 0, 0, &zones_set6, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // MPG B550I GAMING EDGE WIFI + { 0x7C94, 6, 0, 0, 1, &zones_set11, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MAG B550M MORTAR verified + { 0x7C95, 6, 0, 0, 2, &zones_set0, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // B550M PRO-VDH WIFI verified + { 0x7C98, 6, 0, 0, 1, &zones_set5, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // Z490 PLUS verified + { 0x7D06, 4, 4, 0, 1, &zones_set3, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // MPG Z590 GAMING FORCE + { 0x7D07, 4, 5, 0, 2, &zones_set7, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MPG Z590 GAMING EDGE WIFI verified + { 0x7D09, 6, 0, 0, 1, &zones_set2, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // Z590-A PRO WIFI + { 0x7D13, 6, 0, 0, 1, &zones_set1, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // MEG B550 UNIFY + { 0x7D15, 6, 0, 0, 2, &zones_set0, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // MAG B560 TOMAHAWK WIFI + { 0x7D17, 7, 0, 0, 1, &zones_set11, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MAG B560M MORTAR verified + { 0x7D20, 7, 0, 0, 1, &zones_set5, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MAG B560M PRO verified + { 0x7D25, 7, 0, 0, 1, &zones_set11, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // PRO Z690-A WIFI DDR4 verified + { 0x7D27, 7, 0, 0, 1, &zones_set1, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MEG Z690 ACE + { 0x7D28, 6, 0, 0, 1, &zones_set1, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MEG Z690 UNIFY-X verified + { 0x7D29, 6, 0, 0, 0, &zones_set6, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // MEG Z690I UNIFY + { 0x7D31, 4, 4, 0, 1, &zones_set12, MSIMysticLight185Controller::DIRECT_MODE_DISABLED }, // MPG EDGE WIFI DDR4 + { 0x7D32, 1, 0, 0, 1, &zones_set10, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MAG Z690 TOMAHAWK WIFI DDR4 verified + { 0x7D42, 7, 0, 0, 1, &zones_set11, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MAG B660 MORTAR WIFI DDR4 verified + { 0x7D50, 6, 12, 0, 1, &zones_set4, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MEG X570S ACE MAX verified + { 0x7D52, 6, 14, 0, 1, &zones_set4, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MPG X570S CARBON EK X + { 0x7D53, 6, 0, 0, 2, &zones_set0, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MPG X570S EDGE MAX WIFI verified + { 0x7D54, 6, 0, 0, 2, &zones_set0, MSIMysticLight185Controller::DIRECT_MODE_PER_LED }, // MAG X570S TOMAHAWK MAX WIFI verified +}; + + +FeaturePacket_185 enable_per_led_msg; + +Color* per_led_onboard_leds; +Color* per_led_jpipe1; +Color* per_led_jpipe2; +Color* per_led_jrgb; +Color* per_led_jrainbow1; +Color* per_led_jrainbow2; +Color* per_led_jcorsair; + + +MSIMysticLight185Controller::MSIMysticLight185Controller + ( + hid_device* handle, + const char *path, + unsigned short pid + ) { dev = handle; @@ -27,10 +244,173 @@ MSIMysticLight185Controller::MSIMysticLight185Controller(hid_device* handle, con ReadSettings(); } - /*-----------------------------------------*\ - | Initialize save flag | - \*-----------------------------------------*/ + /*---------------------------------------------*\ + | Initialize save flag and some static settings | + \*---------------------------------------------*/ data.save_data = 0; + data.on_board_led.colorFlags = 0x80 | SYNC_SETTING_ONBOARD; // always enable onboard sync flag to have expected zone control + + const Config* board_config = nullptr; + + for(std::size_t i = 0; i < NUMOF_CONFIGS; ++i) + { + if (board_configs[i].pid == pid) + { + board_config = &board_configs[i]; + break; + } + } + + if(board_config != nullptr) + { + numof_onboard_leds = board_config->numof_onboard_leds; + numof_pipe1_leds = board_config->numof_pipe1_leds; + numof_pipe2_leds = board_config->numof_pipe2_leds; + numof_JRGBs = board_config->numof_JRGBs; + supported_zones = board_config->supported_zones; + per_led_mode = board_config->per_led_mode; + } + else + { + numof_onboard_leds = 6; + numof_pipe1_leds = 1; + numof_pipe2_leds = 1; + numof_JRGBs = 2; + supported_zones = &all_zones; + per_led_mode = DIRECT_MODE_DISABLED; + } + + /*-----------------------------------------*\ + | Initialize Per LED data | + \*-----------------------------------------*/ + std::memset(per_led_data.leds, 0, sizeof(Color) * NUMOF_PER_LED_MODE_LEDS); + per_led_onboard_leds = per_led_data.leds; + per_led_jpipe1 = per_led_onboard_leds + numof_onboard_leds; + per_led_jpipe2 = per_led_jpipe1 + numof_pipe1_leds; + per_led_jrgb = per_led_jpipe2 + numof_pipe2_leds; + per_led_jrainbow1 = per_led_jrgb + numof_JRGBs; + per_led_jrainbow2 = per_led_jrainbow1 + PER_LED_MODE_JRAINBOW_LED_COUNT; + per_led_jcorsair = per_led_jrainbow2 + PER_LED_MODE_JRAINBOW_LED_COUNT; + + unsigned char sync_mode = 0x81; + + no_onboards = true; + + for(std::size_t i = 0; i < supported_zones->size(); ++i) + { + switch((*supported_zones)[i]) + { + case MSI_ZONE_J_RAINBOW_1: + sync_mode |= SYNC_SETTING_JRAINBOW1; + break; + + case MSI_ZONE_J_RAINBOW_2: + sync_mode |= SYNC_SETTING_JRAINBOW2; + break; + + case MSI_ZONE_J_RAINBOW_3: + case MSI_ZONE_J_CORSAIR: + sync_mode |= SYNC_SETTING_JCORSAIR; + break; + + case MSI_ZONE_J_PIPE_1: + sync_mode |= SYNC_SETTING_JPIPE1; + break; + + case MSI_ZONE_J_PIPE_2: + sync_mode |= SYNC_SETTING_JPIPE2; + break; + + case MSI_ZONE_ON_BOARD_LED_0: + no_onboards = false; + + default: + break; + } + } + + /*---------------------------------------------------------------------------------------------------------*\ + | Set up per LED switching message. | + | Static initialization made problems with some compilers. Therefore this is done programmatically here. | + \*---------------------------------------------------------------------------------------------------------*/ + enable_per_led_msg.j_rgb_1.speedAndBrightnessFlags = 0x08; + enable_per_led_msg.j_rgb_1.colorFlags = 0x80; + enable_per_led_msg.j_pipe_1.speedAndBrightnessFlags = 0x2A; + enable_per_led_msg.j_pipe_1.colorFlags = 0x80; + enable_per_led_msg.j_pipe_2.speedAndBrightnessFlags = 0x2A; + enable_per_led_msg.j_pipe_2.colorFlags = 0x80; + enable_per_led_msg.j_rainbow_1.speedAndBrightnessFlags = 0x08; + enable_per_led_msg.j_rainbow_1.colorFlags = 0x80; + enable_per_led_msg.j_rainbow_2.speedAndBrightnessFlags = 0x08; + enable_per_led_msg.j_rainbow_2.colorFlags = 0x80; + enable_per_led_msg.j_corsair.effect = MSI_MODE_DISABLE; + enable_per_led_msg.j_corsair.corsair_quantity = 0x00; + enable_per_led_msg.j_corsair.padding[2] = 0x82; + enable_per_led_msg.j_corsair.is_individual = 0x78; + enable_per_led_msg.j_corsair_outerll120.speedAndBrightnessFlags = 0x28; + enable_per_led_msg.j_corsair_outerll120.colorFlags = 0x80; + enable_per_led_msg.on_board_led.effect = 0x25; + enable_per_led_msg.on_board_led.speedAndBrightnessFlags = 0x29 | SYNC_SETTING_JRGB; + enable_per_led_msg.on_board_led.colorFlags = sync_mode; + enable_per_led_msg.on_board_led_1.speedAndBrightnessFlags = 0x28; + enable_per_led_msg.on_board_led_1.colorFlags = 0x80; + enable_per_led_msg.on_board_led_2.speedAndBrightnessFlags = 0x28; + enable_per_led_msg.on_board_led_2.colorFlags = 0x80; + enable_per_led_msg.on_board_led_3.speedAndBrightnessFlags = 0x28; + enable_per_led_msg.on_board_led_3.colorFlags = 0x80; + enable_per_led_msg.on_board_led_4.speedAndBrightnessFlags = 0x28; + enable_per_led_msg.on_board_led_4.colorFlags = 0x80; + enable_per_led_msg.on_board_led_5.speedAndBrightnessFlags = 0x28; + enable_per_led_msg.on_board_led_5.colorFlags = 0x80; + enable_per_led_msg.on_board_led_6.speedAndBrightnessFlags = 0x28; + enable_per_led_msg.on_board_led_6.colorFlags = 0x80; + enable_per_led_msg.on_board_led_7.speedAndBrightnessFlags = 0x28; + enable_per_led_msg.on_board_led_7.colorFlags = 0x80; + enable_per_led_msg.on_board_led_8.speedAndBrightnessFlags = 0x28; + enable_per_led_msg.on_board_led_8.colorFlags = 0x80; + enable_per_led_msg.on_board_led_9.speedAndBrightnessFlags = 0x28; + enable_per_led_msg.on_board_led_9.colorFlags = 0x80; + enable_per_led_msg.j_rgb_2.speedAndBrightnessFlags = 0x2A; + enable_per_led_msg.j_rgb_2.colorFlags = 0x80; + + /*-----------------------------------------*\ + | Initialize zone based per LED data | + \*-----------------------------------------*/ + zone_based_per_led_data.j_rgb_1.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.j_rgb_1.colorFlags = BITSET(zone_based_per_led_data.j_rgb_1.colorFlags, true, 7u); + zone_based_per_led_data.j_pipe_1.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.j_pipe_1.colorFlags = BITSET(zone_based_per_led_data.j_pipe_1.colorFlags, true, 7u); + zone_based_per_led_data.j_pipe_2.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.j_pipe_2.colorFlags = BITSET(zone_based_per_led_data.j_pipe_2.colorFlags, true, 7u); + zone_based_per_led_data.j_rainbow_1.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.j_rainbow_1.colorFlags = BITSET(zone_based_per_led_data.j_rainbow_1.colorFlags, true, 7u); + zone_based_per_led_data.j_rainbow_2.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.j_rainbow_2.colorFlags = BITSET(zone_based_per_led_data.j_rainbow_2.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led.colorFlags = BITSET(zone_based_per_led_data.on_board_led.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_1.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_1.colorFlags = BITSET(zone_based_per_led_data.on_board_led_1.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_2.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_2.colorFlags = BITSET(zone_based_per_led_data.on_board_led_2.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_3.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_3.colorFlags = BITSET(zone_based_per_led_data.on_board_led_3.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_4.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_4.colorFlags = BITSET(zone_based_per_led_data.on_board_led_4.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_5.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_5.colorFlags = BITSET(zone_based_per_led_data.on_board_led_5.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_6.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2 << 2; + zone_based_per_led_data.on_board_led_6.colorFlags = BITSET(zone_based_per_led_data.on_board_led_6.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_7.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100; + zone_based_per_led_data.on_board_led_7.colorFlags = BITSET(zone_based_per_led_data.on_board_led_7.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_8.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_8.colorFlags = BITSET(zone_based_per_led_data.on_board_led_8.colorFlags, true, 7u); + zone_based_per_led_data.on_board_led_9.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.on_board_led_9.colorFlags = BITSET(zone_based_per_led_data.on_board_led_9.colorFlags, true, 7u); + zone_based_per_led_data.j_rgb_2.speedAndBrightnessFlags = MSI_BRIGHTNESS_LEVEL_100 << 2; + zone_based_per_led_data.j_rgb_2.colorFlags = BITSET(zone_based_per_led_data.j_rgb_2.colorFlags, true, 7u); + zone_based_per_led_data.save_data = 0; + + direct_mode = false; } MSIMysticLight185Controller::~MSIMysticLight185Controller() @@ -38,81 +418,53 @@ MSIMysticLight185Controller::~MSIMysticLight185Controller() hid_close(dev); } -unsigned int MSIMysticLight185Controller::GetZoneMinLedCount - ( - MSI_ZONE /*zone*/ - ) -{ - return 1; -} - -unsigned int MSIMysticLight185Controller::GetZoneMaxLedCount - ( - MSI_ZONE zone - ) -{ - switch(zone) - { - case MSI_ZONE_J_RAINBOW_1: - case MSI_ZONE_J_RAINBOW_2: - case MSI_ZONE_J_CORSAIR: - return 4; // TODO: It can be different by zone and by mobo - default: - return 1; - } -} - -unsigned int MSIMysticLight185Controller::GetZoneLedCount - ( - MSI_ZONE zone - ) -{ - RainbowZoneData *requestedZone = GetRainbowZoneData(zone); - - if (!requestedZone) - { - return GetZoneMaxLedCount(zone); - } - - return requestedZone->cycle_or_led_num; -} - -void MSIMysticLight185Controller::SetZoneLedCount - ( - MSI_ZONE zone, - unsigned int led_count - ) -{ - RainbowZoneData *requestedZone = GetRainbowZoneData(zone); - - if (!requestedZone) - { - return; - } - - led_count = std::min(GetZoneMaxLedCount(zone), std::max(GetZoneMinLedCount(zone), led_count)); - requestedZone->cycle_or_led_num = led_count; -} - void MSIMysticLight185Controller::SetMode ( - MSI_ZONE zone, - MSI_MODE mode, - MSI_SPEED speed, - MSI_BRIGHTNESS brightness, - bool rainbow_color + MSI_ZONE zone, + MSI_MODE mode, + MSI_SPEED speed, + MSI_BRIGHTNESS brightness, + bool rainbow_color ) { - ZoneData* zoneData = GetZoneData(zone); - if(!zoneData) + if((per_led_mode == DIRECT_MODE_ZONE_BASED) && (zone > MSI_ZONE_ON_BOARD_LED_0)) { return; } - zoneData->effect = mode; - zoneData->speedAndBrightnessFlags = ( brightness << 2 ) | ( speed & 0x03 ); - zoneData->colorFlags = 0x00;// BitSet(zoneData->colorFlags, !rainbow_color, 7u); - zoneData->padding = 0x00; + ZoneData* zone_data = GetZoneData(data, zone); + + if(zone_data == nullptr) + { + return; + } + + zone_data->effect = mode; + zone_data->speedAndBrightnessFlags = (brightness << 2) | (speed & 0x03); + zone_data->colorFlags = BITSET(zone_data->colorFlags, !rainbow_color, 7u); + zone == MSI_ZONE_J_RAINBOW_3 ? zone_data->padding = 4 : zone_data->padding = 0; + + ZoneData* on_board_zone = GetZoneData(data, MSI_ZONE_ON_BOARD_LED_0); + + if(no_onboards && ((zone == MSI_ZONE_J_RGB_1) || (zone == MSI_ZONE_J_RGB_1) || (zone == MSI_ZONE_J_PIPE_1) || (zone == MSI_ZONE_J_PIPE_2))) + { + on_board_zone->effect = zone_data->effect; + on_board_zone->speedAndBrightnessFlags = zone_data->speedAndBrightnessFlags; + on_board_zone->colorFlags = zone_data->colorFlags; + on_board_zone->colorFlags |= SYNC_SETTING_ONBOARD; + on_board_zone->padding = 0x00; + } + + if(mode > MSI_MODE_LIGHTNING) + { + on_board_zone->speedAndBrightnessFlags |= SYNC_SETTING_JRGB; + on_board_zone->colorFlags |= (SYNC_SETTING_JPIPE1 | SYNC_SETTING_JPIPE2); + } + else + { + on_board_zone->speedAndBrightnessFlags &= ~SYNC_SETTING_JRGB; + on_board_zone->colorFlags &= ~(SYNC_SETTING_JPIPE1 | SYNC_SETTING_JPIPE2); + } } std::string MSIMysticLight185Controller::GetDeviceName() @@ -140,107 +492,243 @@ bool MSIMysticLight185Controller::ReadSettings() /*-----------------------------------------------------*\ | Read packet from hardware, return true if successful | \*-----------------------------------------------------*/ - return(hid_get_feature_report(dev, (unsigned char *)&data, sizeof(data)) == sizeof data); + return (hid_get_feature_report(dev, (unsigned char*)&data, sizeof(data)) == sizeof data); } -bool MSIMysticLight185Controller::Update() +bool MSIMysticLight185Controller::Update + ( + bool save + ) { /*-----------------------------------------------------*\ | Send packet to hardware, return true if successful | \*-----------------------------------------------------*/ - return(hid_send_feature_report(dev, (unsigned char *)&data, sizeof(data)) == sizeof data); + if(direct_mode) + { + if(per_led_mode == DIRECT_MODE_PER_LED) + { + return (hid_send_feature_report(dev, (unsigned char*)&per_led_data, sizeof(per_led_data)) == sizeof(per_led_data)); + } + else + { + return (hid_send_feature_report(dev, (unsigned char*)&zone_based_per_led_data, sizeof(zone_based_per_led_data)) == sizeof(zone_based_per_led_data)); + } + } + else + { + data.save_data = save; + return (hid_send_feature_report(dev, (unsigned char*)&data, sizeof(data)) == sizeof(data)); + } } void MSIMysticLight185Controller::SetZoneColor ( - MSI_ZONE zone, - unsigned char red1, - unsigned char grn1, - unsigned char blu1, - unsigned char red2, - unsigned char grn2, - unsigned char blu2 + MSI_ZONE zone, + unsigned char red1, + unsigned char grn1, + unsigned char blu1, + unsigned char red2, + unsigned char grn2, + unsigned char blu2 ) { - ZoneData* zoneData = GetZoneData(zone); - - if(!zoneData) + if((per_led_mode == DIRECT_MODE_ZONE_BASED) && (zone > MSI_ZONE_ON_BOARD_LED_0)) { return; } - zoneData->color.R = red1; - zoneData->color.G = grn1; - zoneData->color.B = blu1; + ZoneData* zone_data = GetZoneData(data, zone); - zoneData->color2.R = red2; - zoneData->color2.G = grn2; - zoneData->color2.B = blu2; -} - -std::pair MSIMysticLight185Controller::GetZoneColor - ( - MSI_ZONE zone - ) -{ - ZoneData *zoneData = GetZoneData(zone); - - if (!zoneData) + if(zone_data == nullptr) { - return std::make_pair(Color{}, Color{}); + return; } - return std::make_pair(Color{ - zoneData->color.R, - zoneData->color.G, - zoneData->color.B}, - Color{zoneData->color2.R, zoneData->color2.G, zoneData->color2.B}); + zone_data->color.R = red1; + zone_data->color.G = grn1; + zone_data->color.B = blu1; + zone_data->color2.R = red2; + zone_data->color2.G = grn2; + zone_data->color2.B = blu2; + + if(no_onboards && ((zone == MSI_ZONE_J_RGB_1) || (zone == MSI_ZONE_J_RGB_1) || (zone == MSI_ZONE_J_PIPE_1) || (zone == MSI_ZONE_J_PIPE_2))) + { + ZoneData* on_board_zone = GetZoneData(data, MSI_ZONE_ON_BOARD_LED_0); + + on_board_zone->color.R = red1; + on_board_zone->color.G = grn1; + on_board_zone->color.B = blu1; + on_board_zone->color2.R = red2; + on_board_zone->color2.G = grn2; + on_board_zone->color2.B = blu2; + } +} + +void MSIMysticLight185Controller::SetLedColor + ( + MSI_ZONE zone, + int index, + unsigned char red, + unsigned char grn, + unsigned char blu + ) +{ + if(per_led_mode == DIRECT_MODE_PER_LED) + { + Color* zone_data = GetPerLedZoneData(zone); + + if(zone_data != nullptr) + { + int maxSize = 0; + + switch(zone) + { + case MSI_ZONE_J_RGB_1: + case MSI_ZONE_J_RGB_2: + maxSize = 1; + break; + + case MSI_ZONE_J_RAINBOW_1: + case MSI_ZONE_J_RAINBOW_2: + maxSize = PER_LED_MODE_JRAINBOW_LED_COUNT; + break; + + case MSI_ZONE_ON_BOARD_LED_0: + maxSize = numof_onboard_leds; + break; + + case MSI_ZONE_J_RAINBOW_3: + case MSI_ZONE_J_CORSAIR: + maxSize = PER_LED_MODE_CORSAIR_LED_COUNT; + break; + + case MSI_ZONE_J_PIPE_1: + maxSize = numof_pipe1_leds; + break; + + case MSI_ZONE_J_PIPE_2: + maxSize = numof_pipe2_leds; + break; + + default: + break; + } + + if(index < maxSize) + { + zone_data[index].R = red; + zone_data[index].G = grn; + zone_data[index].B = blu; + } + } + } + else + { + if(((zone == MSI_ZONE_J_RAINBOW_1) || (zone == MSI_ZONE_J_RAINBOW_2) || (zone == MSI_ZONE_J_PIPE_1) || (zone == MSI_ZONE_J_PIPE_2)) && (index != 0)) + { + return; + } + + if(zone >= MSI_ZONE_ON_BOARD_LED_0) + { + zone = (MSI_ZONE)((int)zone + index + 1); + } + + ZoneData *zone_data = GetZoneData(zone_based_per_led_data, zone); + + if(zone_data == nullptr) + { + return; + } + + zone_data->color.R = red; + zone_data->color.G = grn; + zone_data->color.B = blu; + zone_data->color2.R = red; + zone_data->color2.G = grn; + zone_data->color2.B = blu; + } } ZoneData *MSIMysticLight185Controller::GetZoneData ( + FeaturePacket_185& data_packet, MSI_ZONE zone ) { switch(zone) { - case MSI_ZONE_J_RGB_1: - return &data.j_rgb_1; - case MSI_ZONE_J_RGB_2: - return &data.j_rgb_2; - case MSI_ZONE_J_RAINBOW_1: - return &data.j_rainbow_1; - case MSI_ZONE_J_RAINBOW_2: - return &data.j_rainbow_2; - case MSI_ZONE_J_PIPE_1: - return &data.j_pipe_1; - case MSI_ZONE_J_PIPE_2: - return &data.j_pipe_2; - case MSI_ZONE_ON_BOARD_LED_0: - return &data.on_board_led; - case MSI_ZONE_ON_BOARD_LED_1: - return &data.on_board_led_1; - case MSI_ZONE_ON_BOARD_LED_2: - return &data.on_board_led_2; - case MSI_ZONE_ON_BOARD_LED_3: - return &data.on_board_led_3; - case MSI_ZONE_ON_BOARD_LED_4: - return &data.on_board_led_4; - case MSI_ZONE_ON_BOARD_LED_5: - return &data.on_board_led_5; - case MSI_ZONE_ON_BOARD_LED_6: - return &data.on_board_led_6; - case MSI_ZONE_ON_BOARD_LED_7: - return &data.on_board_led_7; - case MSI_ZONE_ON_BOARD_LED_8: - return &data.on_board_led_8; - case MSI_ZONE_ON_BOARD_LED_9: - return &data.on_board_led_9; - case MSI_ZONE_J_CORSAIR_OUTERLL120: - return &data.j_corsair_outerll120; - default: - case MSI_ZONE_J_CORSAIR: - break; + case MSI_ZONE_J_RGB_1: + return &data_packet.j_rgb_1; + case MSI_ZONE_J_RGB_2: + return &data_packet.j_rgb_2; + case MSI_ZONE_J_RAINBOW_1: + return &data_packet.j_rainbow_1; + case MSI_ZONE_J_RAINBOW_2: + return &data_packet.j_rainbow_2; + case MSI_ZONE_J_RAINBOW_3: + return (ZoneData*)&data_packet.j_corsair; + case MSI_ZONE_J_PIPE_1: + return &data_packet.j_pipe_1; + case MSI_ZONE_J_PIPE_2: + return &data_packet.j_pipe_2; + case MSI_ZONE_ON_BOARD_LED_0: + return &data_packet.on_board_led; + case MSI_ZONE_ON_BOARD_LED_1: + return &data_packet.on_board_led_1; + case MSI_ZONE_ON_BOARD_LED_2: + return &data_packet.on_board_led_2; + case MSI_ZONE_ON_BOARD_LED_3: + return &data_packet.on_board_led_3; + case MSI_ZONE_ON_BOARD_LED_4: + return &data_packet.on_board_led_4; + case MSI_ZONE_ON_BOARD_LED_5: + return &data_packet.on_board_led_5; + case MSI_ZONE_ON_BOARD_LED_6: + return &data_packet.on_board_led_6; + case MSI_ZONE_ON_BOARD_LED_7: + return &data_packet.on_board_led_7; + case MSI_ZONE_ON_BOARD_LED_8: + return &data_packet.on_board_led_8; + case MSI_ZONE_ON_BOARD_LED_9: + return &data_packet.on_board_led_9; + case MSI_ZONE_J_CORSAIR_OUTERLL120: + return &data_packet.j_corsair_outerll120; + case MSI_ZONE_J_CORSAIR: + return (ZoneData*)&data_packet.j_corsair; + default: + break; + } + + return nullptr; +} + +Color *MSIMysticLight185Controller::GetPerLedZoneData + ( + MSI_ZONE zone + ) +{ + switch(zone) + { + case MSI_ZONE_J_RAINBOW_1: + return per_led_jrainbow1; + case MSI_ZONE_J_RAINBOW_2: + return per_led_jrainbow2; + case MSI_ZONE_ON_BOARD_LED_0: + return per_led_onboard_leds; + case MSI_ZONE_J_RAINBOW_3: + case MSI_ZONE_J_CORSAIR: + return per_led_jcorsair; + case MSI_ZONE_J_RGB_1: + return per_led_jrgb; + case MSI_ZONE_J_RGB_2: + return per_led_jrgb + 1; + case MSI_ZONE_J_PIPE_1: + return per_led_jpipe1; + case MSI_ZONE_J_PIPE_2: + return per_led_jpipe2; + default: + break; } return nullptr; @@ -248,18 +736,20 @@ ZoneData *MSIMysticLight185Controller::GetZoneData RainbowZoneData *MSIMysticLight185Controller::GetRainbowZoneData ( - MSI_ZONE zone + MSI_ZONE zone ) { switch(zone) { - case MSI_ZONE_J_RAINBOW_1: - return &data.j_rainbow_1; - case MSI_ZONE_J_RAINBOW_2: - return &data.j_rainbow_2; - case MSI_ZONE_J_CORSAIR: - default: - return nullptr; + case MSI_ZONE_J_RAINBOW_1: + return &data.j_rainbow_1; + case MSI_ZONE_J_RAINBOW_2: + return &data.j_rainbow_2; + case MSI_ZONE_J_RAINBOW_3: + return (RainbowZoneData*)&data.j_corsair; + case MSI_ZONE_J_CORSAIR: + default: + return nullptr; } } @@ -307,7 +797,7 @@ bool MSIMysticLight185Controller::ReadFwVersion() /*-----------------------------------------------------*\ | Build firmware string . | \*-----------------------------------------------------*/ - version_APROM = std::to_string(static_cast(highValue)).append(".").append(std::to_string(static_cast(lowValue))); + version_APROM = std::to_string((int)highValue).append(".").append(std::to_string((int)lowValue)); /*-----------------------------------------------------*\ | First read the LDROM | @@ -336,13 +826,13 @@ bool MSIMysticLight185Controller::ReadFwVersion() /*-----------------------------------------------------*\ | Build firmware string . | \*-----------------------------------------------------*/ - version_LDROM = std::to_string(static_cast(highValue)).append(".").append(std::to_string(static_cast(lowValue))); + version_LDROM = std::to_string((int)highValue).append(".").append(std::to_string((int)lowValue)); /*-----------------------------------------------------*\ | If return value is zero it means an HID transfer | | failed | \*-----------------------------------------------------*/ - return(ret_val > 0); + return (ret_val > 0); } void MSIMysticLight185Controller::ReadSerial() @@ -388,24 +878,21 @@ void MSIMysticLight185Controller::ReadName() name.append(" ").append(std::string(wname.begin(), wname.end())); } -void MSIMysticLight185Controller::GetMode - ( - MSI_ZONE zone, - MSI_MODE &mode, - MSI_SPEED &speed, - MSI_BRIGHTNESS &brightness, - bool &rainbow_color - ) +void MSIMysticLight185Controller::GetMode(MSI_ZONE zone, + MSI_MODE &mode, + MSI_SPEED &speed, + MSI_BRIGHTNESS &brightness, + bool &rainbow_color) { /*-----------------------------------------------------*\ | Get data for given zone | \*-----------------------------------------------------*/ - ZoneData *zoneData = GetZoneData(zone); + ZoneData *zoneData = GetZoneData(data, zone); /*-----------------------------------------------------*\ | Return if zone is invalid | \*-----------------------------------------------------*/ - if (!zoneData) + if(!zoneData) { return; } @@ -413,49 +900,73 @@ void MSIMysticLight185Controller::GetMode /*-----------------------------------------------------*\ | Update pointers with data | \*-----------------------------------------------------*/ - mode = (MSI_MODE)(zoneData->effect); + mode = (MSI_MODE)zoneData->effect; speed = (MSI_SPEED)(zoneData->speedAndBrightnessFlags & 0x03); brightness = (MSI_BRIGHTNESS)((zoneData->speedAndBrightnessFlags >> 2) & 0x1F); rainbow_color = (zoneData->colorFlags & 0x80) >> 7; } -unsigned char MSIMysticLight185Controller::BitSet - ( - unsigned char value, - bool bit, - unsigned int position - ) -{ - return static_cast(std::bitset<8>(value).set(position, bit).to_ulong()); -} - void MSIMysticLight185Controller::SetCycleCount ( - MSI_ZONE zone, - unsigned char cycle_num + MSI_ZONE zone, + unsigned char cycle_num ) { - RainbowZoneData *requestedZone = GetRainbowZoneData(zone); + RainbowZoneData *requested_zone = GetRainbowZoneData(zone); - if (!requestedZone) + if(!requested_zone) { return; } - requestedZone->cycle_or_led_num = cycle_num; + requested_zone->cycle_or_led_num = cycle_num; } -unsigned char MSIMysticLight185Controller::GetCycleCount +void MSIMysticLight185Controller::SetDirectMode ( - MSI_ZONE zone + bool mode ) { - RainbowZoneData *requestedZone = GetRainbowZoneData(zone); + direct_mode = mode; - if (!requestedZone) + if(direct_mode) { - return 0; + if(per_led_mode == DIRECT_MODE_PER_LED) + { + hid_send_feature_report(dev, (unsigned char*)&enable_per_led_msg, sizeof(enable_per_led_msg)); + } } +} - return requestedZone->cycle_or_led_num; -} \ No newline at end of file +size_t MSIMysticLight185Controller::GetMaxDirectLeds + ( + MSI_ZONE zone + ) +{ + switch(zone) + { + case MSI_ZONE_J_RGB_1: + case MSI_ZONE_J_RGB_2: + return 1; + + case MSI_ZONE_J_PIPE_1: + return numof_pipe1_leds; + + case MSI_ZONE_J_PIPE_2: + return numof_pipe2_leds; + + case MSI_ZONE_J_RAINBOW_1: + case MSI_ZONE_J_RAINBOW_2: + case MSI_ZONE_J_RAINBOW_3: + return 200; + + case MSI_ZONE_J_CORSAIR: + return PER_LED_MODE_CORSAIR_LED_COUNT; + + case MSI_ZONE_ON_BOARD_LED_0: + return numof_onboard_leds; + + default: + return 1; + } +} diff --git a/Controllers/MSIMysticLightController/MSIMysticLight185Controller.h b/Controllers/MSIMysticLightController/MSIMysticLight185Controller.h index a73af15e1..a0b7c37ce 100644 --- a/Controllers/MSIMysticLightController/MSIMysticLight185Controller.h +++ b/Controllers/MSIMysticLightController/MSIMysticLight185Controller.h @@ -20,30 +20,14 @@ class MSIMysticLight185Controller { public: - MSIMysticLight185Controller(hid_device* handle, const char *path); + MSIMysticLight185Controller + ( + hid_device* handle, + const char *path, + unsigned short pid + ); ~MSIMysticLight185Controller(); - unsigned int GetZoneMinLedCount - ( - MSI_ZONE zone - ); - - unsigned int GetZoneMaxLedCount - ( - MSI_ZONE zone - ); - - unsigned int GetZoneLedCount - ( - MSI_ZONE zone - ); - - void SetZoneLedCount - ( - MSI_ZONE zone, - unsigned int led_count - ); - void SetMode ( MSI_ZONE zone, @@ -73,44 +57,84 @@ public: unsigned char blu2 ); + void SetLedColor + ( + MSI_ZONE zone, + int index, + unsigned char red, + unsigned char grn, + unsigned char blu + ); + void SetCycleCount ( MSI_ZONE zone, unsigned char cycle_num ); - unsigned char GetCycleCount + bool Update ( - MSI_ZONE zone + bool save ); - std::pair - GetZoneColor(MSI_ZONE zone); - - bool Update(); - std::string GetDeviceName(); std::string GetDeviceLocation(); std::string GetFWVersion(); std::string GetSerial(); + void SetDirectMode + ( + bool mode + ); + bool IsDirectModeActive() { return direct_mode; } + size_t GetMaxDirectLeds + ( + MSI_ZONE zone + ); + const std::vector* + GetSupportedZones() { return supported_zones; } + + enum DIRECT_MODE + { + DIRECT_MODE_DISABLED, + DIRECT_MODE_PER_LED, + DIRECT_MODE_ZONE_BASED + }; + + DIRECT_MODE GetSupportedDirectMode() { return per_led_mode; } + private: bool ReadSettings(); - void SaveOnUpdate(bool send); bool ReadFwVersion(); void ReadSerial(); void ReadName(); - ZoneData* GetZoneData(MSI_ZONE zone); - RainbowZoneData* - GetRainbowZoneData(MSI_ZONE zone); - static unsigned char BitSet(unsigned char value, bool bit, unsigned int position); + ZoneData* GetZoneData + ( + FeaturePacket_185& data_packet, + MSI_ZONE zone + ); + RainbowZoneData* GetRainbowZoneData(MSI_ZONE zone); + Color* GetPerLedZoneData + ( + MSI_ZONE zone + ); - hid_device* dev; - std::string name; - std::string location; - std::string version_APROM; - std::string version_LDROM; - std::string chip_id; + hid_device* dev; + std::string name; + std::string location; + std::string version_APROM; + std::string version_LDROM; + std::string chip_id; - FeaturePacket_185 data; + FeaturePacket_185 data; + FeaturePacket_PerLED_185 per_led_data; + FeaturePacket_185 zone_based_per_led_data; + bool direct_mode; + bool no_onboards; + int numof_onboard_leds; + int numof_pipe1_leds; + int numof_pipe2_leds; + int numof_JRGBs; + const std::vector* supported_zones; + DIRECT_MODE per_led_mode; }; diff --git a/Controllers/MSIMysticLightController/MSIMysticLightCommon.h b/Controllers/MSIMysticLightController/MSIMysticLightCommon.h index 442d5918d..fabb5f2fa 100644 --- a/Controllers/MSIMysticLightController/MSIMysticLightCommon.h +++ b/Controllers/MSIMysticLightController/MSIMysticLightCommon.h @@ -20,19 +20,20 @@ enum MSI_ZONE MSI_ZONE_J_PIPE_2 = 4, MSI_ZONE_J_RAINBOW_1 = 5, MSI_ZONE_J_RAINBOW_2 = 6, - MSI_ZONE_J_CORSAIR = 7, - MSI_ZONE_J_CORSAIR_OUTERLL120 = 8, - MSI_ZONE_ON_BOARD_LED_0 = 9, - MSI_ZONE_ON_BOARD_LED_1 = 10, - MSI_ZONE_ON_BOARD_LED_2 = 11, - MSI_ZONE_ON_BOARD_LED_3 = 12, - MSI_ZONE_ON_BOARD_LED_4 = 13, - MSI_ZONE_ON_BOARD_LED_5 = 14, - MSI_ZONE_ON_BOARD_LED_6 = 15, - MSI_ZONE_ON_BOARD_LED_7 = 16, - MSI_ZONE_ON_BOARD_LED_8 = 17, - MSI_ZONE_ON_BOARD_LED_9 = 18, - MSI_ZONE_ON_BOARD_LED_10 = 19 + MSI_ZONE_J_RAINBOW_3 = 7, + MSI_ZONE_J_CORSAIR = 8, + MSI_ZONE_J_CORSAIR_OUTERLL120 = 9, + MSI_ZONE_ON_BOARD_LED_0 = 10, + MSI_ZONE_ON_BOARD_LED_1 = 11, + MSI_ZONE_ON_BOARD_LED_2 = 12, + MSI_ZONE_ON_BOARD_LED_3 = 13, + MSI_ZONE_ON_BOARD_LED_4 = 14, + MSI_ZONE_ON_BOARD_LED_5 = 15, + MSI_ZONE_ON_BOARD_LED_6 = 16, + MSI_ZONE_ON_BOARD_LED_7 = 17, + MSI_ZONE_ON_BOARD_LED_8 = 18, + MSI_ZONE_ON_BOARD_LED_9 = 19, + MSI_ZONE_ON_BOARD_LED_10 = 20 }; enum MSI_MODE @@ -77,6 +78,7 @@ enum MSI_MODE MSI_MODE_CORSAIR_QUE = 37, MSI_MODE_FIRE = 38, MSI_MODE_LAVA = 39, + MSI_MODE_DIRECT_DUMMY = 100 }; enum MSI_SPEED @@ -108,6 +110,18 @@ enum MSI_BRIGHTNESS MSI_BRIGHTNESS_LEVEL_100 = 10, }; +#define PER_LED_MODE_JRAINBOW_LED_COUNT 40 +#define PER_LED_MODE_CORSAIR_LED_COUNT 120 +#define NUMOF_PER_LED_MODE_LEDS 240 + +#define SYNC_SETTING_ONBOARD 0x01 +#define SYNC_SETTING_JRAINBOW1 0x02 +#define SYNC_SETTING_JRAINBOW2 0x04 +#define SYNC_SETTING_JCORSAIR 0x08 +#define SYNC_SETTING_JPIPE1 0x10 +#define SYNC_SETTING_JPIPE2 0x20 +#define SYNC_SETTING_JRGB 0x80 + struct Color { unsigned char R; @@ -120,8 +134,8 @@ struct CorsairZoneData unsigned char effect = MSI_MODE_STATIC; Color color { 0, 0, 0 }; unsigned char fan_flags = 40; - unsigned char corsair_quantity; - unsigned char padding[4]; + unsigned char corsair_quantity = 0; + unsigned char padding[4] = { 0, 0, 0, 0 }; unsigned char is_individual = 0; }; @@ -137,7 +151,7 @@ struct ZoneData struct RainbowZoneData : ZoneData { - unsigned char cycle_or_led_num = 20; + unsigned char cycle_or_led_num = PER_LED_MODE_JRAINBOW_LED_COUNT; }; struct FeaturePacket_162 @@ -184,4 +198,14 @@ struct FeaturePacket_185 ZoneData on_board_led_9; // 164 ZoneData j_rgb_2; // 174 unsigned char save_data = 0; // 184 -}; \ No newline at end of file +}; + +struct FeaturePacket_PerLED_185 +{ + unsigned char report_id = 0x53; // Report ID + unsigned char hdr0 = 0x25; // header byte 0 + unsigned char hdr1 = 0x06; // header byte 1 + unsigned char hdr2 = 0x00; // header byte 2 + unsigned char hdr3 = 0x00; // header byte 3 + Color leds[NUMOF_PER_LED_MODE_LEDS]; +}; diff --git a/Controllers/MSIMysticLightController/MSIMysticLightControllerDetect.cpp b/Controllers/MSIMysticLightController/MSIMysticLightControllerDetect.cpp index 4eac5192a..6b8618048 100644 --- a/Controllers/MSIMysticLightController/MSIMysticLightControllerDetect.cpp +++ b/Controllers/MSIMysticLightController/MSIMysticLightControllerDetect.cpp @@ -4,6 +4,8 @@ #include "RGBController_MSIMysticLight162.h" #include "RGBController_MSIMysticLight185.h" #include "dependencies/dmiinfo.h" +#include "LogManager.h" + #define MSI_USB_VID 0x1462 @@ -16,115 +18,120 @@ \*---------------------------------------------------------------------------------*/ //#define ENABLE_UNTESTED_MYSTIC_LIGHT -/******************************************************************************************\ -* * -* DetectMSIMysticLight162Controllers * -* * -* Detect MSI Mystic Light (162-byte) devices * -* * -\******************************************************************************************/ -void DetectMSIMysticLight162Controllers(hid_device_info* info, const std::string& /*name*/) +/*----------------------------------------------------------------------------------------*\ +| | +| DetectMSIMysticLightControllers | +| | +| Detect MSI Mystic Light devices | +| | +\*-----------------------------------------------------------------------------------------*/ +void DetectMSIMysticLightControllers + ( + hid_device_info* info, + const std::string& /*name*/ + ) { hid_device* dev = hid_open_path(info->path); - if( dev ) + if(dev != nullptr) { + unsigned char temp_buffer[200]; + temp_buffer[0] = 0x52; + size_t packet_length = hid_get_feature_report(dev, temp_buffer, 200); DMIInfo dmi; - MSIMysticLight162Controller* controller = new MSIMysticLight162Controller(dev, info->path); - RGBController_MSIMysticLight162* rgb_controller = new RGBController_MSIMysticLight162(controller); - rgb_controller->name = "MSI " + dmi.getMainboard(); - ResourceManager::get()->RegisterRGBController(rgb_controller); + + if((packet_length >= sizeof(FeaturePacket_185)) && (packet_length <= (sizeof(FeaturePacket_185) + 1))) + { + MSIMysticLight185Controller* controller = new MSIMysticLight185Controller(dev, info->path, info->product_id); + RGBController_MSIMysticLight185* rgb_controller = new RGBController_MSIMysticLight185(controller); + rgb_controller->name = "MSI " + dmi.getMainboard(); + ResourceManager::get()->RegisterRGBController(rgb_controller); + } + else if((packet_length >= sizeof(FeaturePacket_162)) && (packet_length <= (sizeof(FeaturePacket_162) + 1))) + { + MSIMysticLight162Controller* controller = new MSIMysticLight162Controller(dev, info->path, info->product_id); + RGBController_MSIMysticLight162* rgb_controller = new RGBController_MSIMysticLight162(controller); + rgb_controller->name = "MSI " + dmi.getMainboard(); + ResourceManager::get()->RegisterRGBController(rgb_controller); + } + else // no supported length returned + { + std::string name = "MSI " + dmi.getMainboard(); + LOG_INFO("No matching driver found for %s, packet length = %d", name.c_str(), packet_length); + return; + } } -} /* DetectMSIMysticLight162Controllers() */ +} -/******************************************************************************************\ -* * -* DetectMSIMysticLight185Controllers * -* * -* Detect MSI Mystic Light (185-byte) devices * -* * -\******************************************************************************************/ -void DetectMSIMysticLight185Controllers(hid_device_info* info, const std::string& /*name*/) -{ - hid_device* dev = hid_open_path(info->path); - - if( dev ) - { - DMIInfo dmi; - MSIMysticLight185Controller* controller = new MSIMysticLight185Controller(dev, info->path); - RGBController_MSIMysticLight185* rgb_controller = new RGBController_MSIMysticLight185(controller); - rgb_controller->name = "MSI " + dmi.getMainboard(); - ResourceManager::get()->RegisterRGBController(rgb_controller); - } -} /* DetectMSIMysticLight185Controllers() */ - -/*-------------------------------------------------------------*\ -| MSI Mystic Light 162-byte Devices | -\*-------------------------------------------------------------*/ -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_1720", DetectMSIMysticLight162Controllers, MSI_USB_VID, 0x1720, 0x0001, 0x00); //MSI MPG Z390 Gaming Edge AC -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B12", DetectMSIMysticLight162Controllers, MSI_USB_VID, 0x7B12, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B17", DetectMSIMysticLight162Controllers, MSI_USB_VID, 0x7B17, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B18", DetectMSIMysticLight162Controllers, MSI_USB_VID, 0x7B18, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B85", DetectMSIMysticLight162Controllers, MSI_USB_VID, 0x7B85, 0x0001, 0x00); - -/*-------------------------------------------------------------*\ -| MSI Mystic Light 185-byte Devices | -\*-------------------------------------------------------------*/ -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B93", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7B93, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C34", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C34, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C35", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C35, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C37", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C37, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C56", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C56, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C59", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C59, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C71", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C71, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C75", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C75, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C76", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C76, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C79", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C79, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C80", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C80, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C81", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C81, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C83", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C83, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C84", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C84, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C86", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C86, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C90", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C90, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C91", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C91, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C92", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C92, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C94", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C94, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C95", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C95, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D06", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7D06, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D07", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7D07, 0x0001, 0x00); // MPG Z590 GAMING EDGE WIFI -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D09", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7D09, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D13", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7D13, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D15", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7D15, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D25", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7D25, 0x0001, 0x00); // MSI PRO Z690-A WiFi DDR4 -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D29", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7D29, 0x0001, 0x00); // MSI MEF Z690-I Unify -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D54", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7D54, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D31", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7D31, 0x0001, 0x00); // MSI MPG Z690 EDGE WIFI DDR4 +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_1720", DetectMSIMysticLightControllers, MSI_USB_VID, 0x1720, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B12", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B12, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B16", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B16, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B17", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B17, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B18", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B18, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B50", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B50, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B85", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B85, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B93", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B93, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C34", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C34, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C35", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C35, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C36", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C36, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C37", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C37, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C56", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C56, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C59", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C59, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C67", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C67, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C71", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C71, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C73", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C73, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C75", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C75, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C76", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C76, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C79", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C79, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C80", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C80, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C81", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C81, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C83", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C83, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C84", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C84, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C86", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C86, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C90", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C90, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C91", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C91, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C92", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C92, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C94", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C94, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C95", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C95, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C98", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C98, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D06", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D06, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D07", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D07, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D09", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D09, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D13", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D13, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D15", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D15, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D17", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D17, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D20", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D20, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D25", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D25, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D27", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D27, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D28", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D28, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D29", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D29, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D31", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D31, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D32", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D32, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D42", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D42, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D50", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D50, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D52", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D52, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D53", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D53, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D54", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7D54, 0x0001, 0x00); #ifdef ENABLE_UNTESTED_MYSTIC_LIGHT -/*-------------------------------------------------------------*\ -| MSI Mystic Light 185-byte Devices | -\*-------------------------------------------------------------*/ -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_3EA4", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x3EA4, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_4459", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x4459, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B10", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7B10, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B94", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7B94, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B96", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7B96, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C36", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C36, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C42", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C42, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C60", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C60, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C67", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C67, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C70", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C70, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C73", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C73, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C77", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C77, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C82", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C82, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C85", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C85, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C87", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C87, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C88", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C88, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C89", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C89, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C96", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C96, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C98", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C98, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C99", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C99, 0x0001, 0x00); -REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_905D", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x905D, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_3EA4", DetectMSIMysticLightControllers, MSI_USB_VID, 0x3EA4, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_4459", DetectMSIMysticLightControllers, MSI_USB_VID, 0x4459, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B10", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B10, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B94", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B94, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B96", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B96, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C42", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C42, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C60", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C60, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C70", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C70, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C73", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C73, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C77", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C77, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C82", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C82, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C85", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C85, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C87", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C87, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C88", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C88, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C89", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C89, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C96", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C96, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C99", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7C99, 0x0001, 0x00); +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_905D", DetectMSIMysticLightControllers, MSI_USB_VID, 0x905D, 0x0001, 0x00); #endif diff --git a/Controllers/MSIMysticLightController/RGBController_MSIMysticLight162.cpp b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight162.cpp index af0179dc0..4591d09f7 100644 --- a/Controllers/MSIMysticLightController/RGBController_MSIMysticLight162.cpp +++ b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight162.cpp @@ -9,69 +9,29 @@ #include "RGBController_MSIMysticLight162.h" + struct ZoneDescription { - std::string name; - const MSI_ZONE* leds; + std::string name; + MSI_ZONE zone_type; }; -static const MSI_ZONE ZoneList_JRGB1[] = +#define NUMOF_ZONES (sizeof(led_zones) / sizeof(ZoneDescription)) + +const ZoneDescription led_zones[] = { - MSI_ZONE_J_RGB_1, - MSI_ZONE_NONE + ZoneDescription{ "JRGB1", MSI_ZONE_J_RGB_1 }, + ZoneDescription{ "JRGB2", MSI_ZONE_J_RGB_2 }, + ZoneDescription{ "JRAINBOW1", MSI_ZONE_J_RAINBOW_1 }, + ZoneDescription{ "JRAINBOW2", MSI_ZONE_J_RAINBOW_2 }, + ZoneDescription{ "JCORSAIR", MSI_ZONE_J_CORSAIR }, + ZoneDescription{ "Onboard LEDs", MSI_ZONE_ON_BOARD_LED_0 } }; -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 std::vector zone_description; -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_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_ON_BOARD_LED_10, - 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{"Onboard LEDs", ZoneList_Onboard }, -}; /**------------------------------------------------------------------*\ @name MSI Mystic Light (162 Byte) @@ -80,11 +40,14 @@ static const ZoneDescription led_zones[] = @save :robot: @direct :white_check_mark: @effects :white_check_mark: - @detectors DetectMSIMysticLight162Controllers + @detectors DetectMSIMysticLightControllers @comment \*-------------------------------------------------------------------*/ -RGBController_MSIMysticLight162::RGBController_MSIMysticLight162(MSIMysticLight162Controller* controller_ptr) +RGBController_MSIMysticLight162::RGBController_MSIMysticLight162 + ( + MSIMysticLight162Controller* controller_ptr + ) { controller = controller_ptr; @@ -96,6 +59,20 @@ RGBController_MSIMysticLight162::RGBController_MSIMysticLight162(MSIMysticLight1 location = controller->GetDeviceLocation(); serial = controller->GetSerial(); + const std::vector* supported_zones = controller->GetSupportedZones(); + + for(std::size_t i = 0; i < supported_zones->size(); ++i) + { + for(std::size_t j = 0; j < NUMOF_ZONES; ++j) + { + if(led_zones[j].zone_type == (*supported_zones)[i]) + { + zone_description.push_back(&led_zones[j]); + break; + } + } + } + SetupModes(); SetupZones(); SetupColors(); @@ -103,6 +80,7 @@ RGBController_MSIMysticLight162::RGBController_MSIMysticLight162(MSIMysticLight1 RGBController_MSIMysticLight162::~RGBController_MSIMysticLight162() { + zone_description.clear(); delete controller; } @@ -111,49 +89,57 @@ void RGBController_MSIMysticLight162::SetupZones() /*---------------------------------------------------------*\ | Set up zones | \*---------------------------------------------------------*/ - for(std::size_t zone_idx = 0; zone_idx < NUM_ZONES; zone_idx++) + for(std::size_t zone_idx = 0; zone_idx < zone_description.size(); ++zone_idx) { - ZoneDescription zd = led_zones[zone_idx]; + const ZoneDescription* zd = zone_description[zone_idx]; zone new_zone; - unsigned int led_count = 0; + new_zone.name = zd->name; + new_zone.type = ZONE_TYPE_LINEAR; - while(zd.leds[led_count] != MSI_ZONE_NONE) + if(zd->zone_type == MSI_ZONE_ON_BOARD_LED_0) { - led_count++; + new_zone.leds_max = (int)controller->GetMaxOnboardLeds(); + } + else + { + new_zone.leds_max = 1; } - 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; + new_zone.leds_min = new_zone.leds_max; + new_zone.leds_count = new_zone.leds_max; + 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++) + /*---------------------------------------------------------*\ + | Set up LEDs | + \*---------------------------------------------------------*/ + for(std::size_t zone_idx = 0; zone_idx < zone_description.size(); ++zone_idx) + { + for(std::size_t led_idx = 0; led_idx < zones[zone_idx].leds_count; ++led_idx) { led new_led; - new_led.name = new_zone.name + " LED "; - if(new_zone.leds_count > 1) + new_led.name = zones[zone_idx].name + " LED "; + + if(zones[zone_idx].leds_count > 1) { new_led.name.append(std::to_string(led_idx + 1)); } - new_led.value = zd.leds[led_idx]; - + new_led.value = (unsigned int)(zone_description[zone_idx]->zone_type + led_idx); leds.push_back(new_led); } } } -void RGBController_MSIMysticLight162::ResizeZone(int zone, int new_size) +void RGBController_MSIMysticLight162::ResizeZone + ( + int /*zone*/, + int /*new_size*/ + ) { } @@ -164,71 +150,93 @@ void RGBController_MSIMysticLight162::SetCustomMode() void RGBController_MSIMysticLight162::DeviceUpdateLEDs() { - for(size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + for(std::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); + UpdateLed((int)zone_idx, led_idx); } } - controller->Update(); + controller->Update((modes[active_mode].flags & MODE_FLAG_AUTOMATIC_SAVE) != 0); } -void RGBController_MSIMysticLight162::UpdateZoneLEDs(int zone) +void RGBController_MSIMysticLight162::UpdateZoneLEDs + ( + int zone + ) { for(int led_idx = zones[zone].leds_count - 1; led_idx >= 0; led_idx--) { UpdateLed(zone, led_idx); } - controller->Update(); + controller->Update((modes[active_mode].flags & MODE_FLAG_AUTOMATIC_SAVE) != 0); } -void RGBController_MSIMysticLight162::UpdateSingleLED(int led) +void RGBController_MSIMysticLight162::UpdateSingleLED + ( + int led + ) { UpdateLed(leds[led].value, led); - controller->Update(); + controller->Update((modes[active_mode].flags & MODE_FLAG_AUTOMATIC_SAVE) != 0); } void RGBController_MSIMysticLight162::DeviceUpdateMode() { + if(modes[active_mode].value == MSI_MODE_DIRECT_DUMMY) + { + controller->SetDirectMode(true); + } + else + { + controller->SetDirectMode(false); + DeviceUpdateLEDs(); + } +} + +void RGBController_MSIMysticLight162::DeviceSaveMode() +{ + controller->Update(true); } void RGBController_MSIMysticLight162::SetupModes() { - constexpr unsigned int RANDOM_ONLY = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR; + constexpr unsigned int PER_LED_ONLY = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE; + constexpr unsigned int RANDOM_ONLY = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE; 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("Direct", MSI_MODE_DIRECT_DUMMY, MODE_FLAG_HAS_PER_LED_COLOR); + SetupMode("Static", MSI_MODE_STATIC, MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE); + // SetupMode("Off", MSI_MODE_DISABLE, 0); + SetupMode("Breathing", MSI_MODE_BREATHING, PER_LED_ONLY); SetupMode("Flashing", MSI_MODE_FLASHING, COMMON); SetupMode("Double flashing", MSI_MODE_DOUBLE_FLASHING, COMMON); - SetupMode("Lightning", MSI_MODE_LIGHTNING, COMMON); + SetupMode("Lightning", MSI_MODE_LIGHTNING, PER_LED_ONLY); // SetupMode("MSI Marquee", MSI_MODE_MSI_MARQUEE, COMMON); - // SetupMode("Meteor", MSI_MODE_METEOR, COMMON); - // SetupMode("Water drop", MSI_MODE_WATER_DROP, COMMON); + SetupMode("Meteor", MSI_MODE_METEOR, COMMON); + SetupMode("Stack", 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_COLOR_RING, COMMON); + SetupMode("Planetary", MSI_MODE_PLANETARY, RANDOM_ONLY); + SetupMode("Double meteor", MSI_MODE_DOUBLE_METEOR, RANDOM_ONLY); + SetupMode("Energy", MSI_MODE_ENERGY, RANDOM_ONLY); + SetupMode("Blink", MSI_MODE_BLINK, COMMON); + SetupMode("Clock", MSI_MODE_CLOCK, RANDOM_ONLY); + SetupMode("Color pulse", MSI_MODE_COLOR_PULSE, COMMON); + SetupMode("Color shift", MSI_MODE_COLOR_SHIFT, RANDOM_ONLY); + SetupMode("Color wave", MSI_MODE_COLOR_WAVE, COMMON); + SetupMode("Marquee", MSI_MODE_MARQUEE, PER_LED_ONLY); // SetupMode("Rainbow", MSI_MODE_RAINBOW, COMMON); - // SetupMode("Rainbow wave", MSI_MODE_RAINBOW_WAVE, COMMON); - // SetupMode("Visor", MSI_MODE_VISOR, COMMON); + SetupMode("Rainbow wave", MSI_MODE_RAINBOW_WAVE, RANDOM_ONLY); + 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("Rainbow flashing", MSI_MODE_RAINBOW_FLASHING, RANDOM_ONLY); + SetupMode("Rainbow double flashing", MSI_MODE_RAINBOW_DOUBLE_FLASHING, RANDOM_ONLY); // SetupMode("Random", MSI_MODE_RANDOM, COMMON); // SetupMode("Fan control", MSI_MODE_FAN_CONTROL, COMMON); // SetupMode("Off 2", MSI_MODE_DISABLE_2, COMMON); @@ -240,25 +248,44 @@ void RGBController_MSIMysticLight162::SetupModes() // SetupMode("Lava", MSI_MODE_LAVA, COMMON); } -void RGBController_MSIMysticLight162::UpdateLed(int zone, int led) +void RGBController_MSIMysticLight162::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); + unsigned char red = RGBGetRValue(zones[zone].colors[led]); + unsigned char grn = RGBGetGValue(zones[zone].colors[led]); + unsigned char blu = RGBGetBValue(zones[zone].colors[led]); - controller->SetMode((MSI_ZONE)zones[zone].leds[led].value, mode, speed, MSI_BRIGHTNESS_LEVEL_100, random); - controller->SetLEDColor((MSI_ZONE)zones[zone].leds[led].value, red, grn, blu, red, grn, blu); + if(controller->IsDirectModeActive()) + { + controller->SetLedColor((MSI_ZONE)zones[zone].leds[led].value, red, grn, blu); + } + else + { + bool random = modes[active_mode].color_mode == MODE_COLORS_RANDOM; + MSI_MODE mode = (MSI_MODE)modes[active_mode].value; + MSI_SPEED speed = (MSI_SPEED)modes[active_mode].speed; + MSI_BRIGHTNESS brightness = (MSI_BRIGHTNESS)modes[active_mode].brightness; + + controller->SetMode((MSI_ZONE)zones[zone].leds[led].value, mode, speed, brightness, random); + controller->SetZoneColor((MSI_ZONE)zones[zone].leds[led].value, red, grn, blu, red, grn, blu); + } } -void RGBController_MSIMysticLight162::SetupMode(const char *name, MSI_MODE mod, unsigned int flags) +void RGBController_MSIMysticLight162::SetupMode + ( + const char *name, + MSI_MODE mod, + unsigned int flags + ) { mode Mode; - Mode.name = name; - Mode.value = mod; - Mode.flags = flags; + Mode.name = name; + Mode.value = mod; + Mode.flags = flags; + if(flags & MODE_FLAG_HAS_PER_LED_COLOR) { Mode.color_mode = MODE_COLORS_PER_LED; @@ -286,5 +313,18 @@ void RGBController_MSIMysticLight162::SetupMode(const char *name, MSI_MODE mod, Mode.speed_min = 0; } + if(flags & MODE_FLAG_HAS_BRIGHTNESS) + { + Mode.brightness = MSI_BRIGHTNESS_LEVEL_100; + Mode.brightness_max = MSI_BRIGHTNESS_LEVEL_100; + Mode.brightness_min = MSI_BRIGHTNESS_OFF; + } + else + { + Mode.brightness = MSI_BRIGHTNESS_LEVEL_100; + Mode.brightness_max = MSI_BRIGHTNESS_LEVEL_100; + Mode.brightness_min = MSI_BRIGHTNESS_LEVEL_100; + } + modes.push_back(Mode); } diff --git a/Controllers/MSIMysticLightController/RGBController_MSIMysticLight162.h b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight162.h index ae47697b2..a51cd5f93 100644 --- a/Controllers/MSIMysticLightController/RGBController_MSIMysticLight162.h +++ b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight162.h @@ -15,24 +15,47 @@ class RGBController_MSIMysticLight162: public RGBController { public: - RGBController_MSIMysticLight162(MSIMysticLight162Controller* controller_ptr); + RGBController_MSIMysticLight162 + ( + MSIMysticLight162Controller* controller_ptr + ); ~RGBController_MSIMysticLight162(); void SetupZones(); - void ResizeZone(int zone, int new_size); + void ResizeZone + ( + int zone, + int new_size + ); void DeviceUpdateLEDs(); - void UpdateZoneLEDs(int zone); - void UpdateSingleLED(int led); + void UpdateZoneLEDs + ( + int zone + ); + void UpdateSingleLED + ( + int led + ); void SetCustomMode(); void DeviceUpdateMode(); + void DeviceSaveMode(); private: void SetupModes(); - void UpdateLed(int zone, int led); - void SetupMode(const char *name, MSI_MODE mode, unsigned int flags); + void UpdateLed + ( + int zone, + int led + ); + void SetupMode + ( + const char *name, + MSI_MODE mode, + unsigned int flags + ); MSIMysticLight162Controller* controller; }; diff --git a/Controllers/MSIMysticLightController/RGBController_MSIMysticLight185.cpp b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight185.cpp index 442040fc5..1dda74c36 100644 --- a/Controllers/MSIMysticLightController/RGBController_MSIMysticLight185.cpp +++ b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight185.cpp @@ -9,77 +9,50 @@ \*-----------------------------------------*/ #include "RGBController_MSIMysticLight185.h" +#include "LogManager.h" + struct ZoneDescription { - std::string name; - const MSI_ZONE* leds; + std::string name; + MSI_ZONE zone_type; }; -static const MSI_ZONE ZoneList_JRGB1[] = +#define NUMOF_ZONES (sizeof(led_zones) / sizeof(ZoneDescription)) + +const ZoneDescription led_zones[] = { - MSI_ZONE_J_RGB_1, - MSI_ZONE_NONE + ZoneDescription{ "JRGB1", MSI_ZONE_J_RGB_1 }, + ZoneDescription{ "JRGB2", MSI_ZONE_J_RGB_2 }, + ZoneDescription{ "JRAINBOW1", MSI_ZONE_J_RAINBOW_1 }, + ZoneDescription{ "JRAINBOW2", MSI_ZONE_J_RAINBOW_2 }, + ZoneDescription{ "JRAINBOW3", MSI_ZONE_J_RAINBOW_3 }, + ZoneDescription{ "JCORSAIR", MSI_ZONE_J_CORSAIR }, + ZoneDescription{ "PIPE1", MSI_ZONE_J_PIPE_1 }, + ZoneDescription{ "PIPE2", MSI_ZONE_J_PIPE_2 }, + ZoneDescription{ "ONBOARD", MSI_ZONE_ON_BOARD_LED_0 } }; -static const MSI_ZONE ZoneList_JRGB2[] = + +static std::vector zone_description; + +/*---------------------------------------------------------------------------------------------------------*\ +| Returns the index of the zone_description in led_zones which has zone_type equal to the given zone_type. | +| Returns -1 if no such zone_description exists. | +\*---------------------------------------------------------------------------------------------------------*/ +int IndexOfZoneForType(MSI_ZONE zone_type) { - MSI_ZONE_J_RGB_2, - MSI_ZONE_NONE -}; + for(size_t i = 0; i < zone_description.size(); ++i) + { + if(zone_description[i]->zone_type == zone_type) + { + return (int)i; + } + } -static const MSI_ZONE ZoneList_JRainbow1[] = -{ - MSI_ZONE_J_RAINBOW_1, - MSI_ZONE_NONE -}; + return -1; +} -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 }, -}; /**------------------------------------------------------------------*\ @name MSI Mystic Light (185 Byte) @@ -88,11 +61,14 @@ static const ZoneDescription led_zones[] = @save :robot: @direct :white_check_mark: @effects :white_check_mark: - @detectors DetectMSIMysticLight185Controllers + @detectors DetectMSIMysticLightControllers @comment \*-------------------------------------------------------------------*/ -RGBController_MSIMysticLight185::RGBController_MSIMysticLight185(MSIMysticLight185Controller* controller_ptr) +RGBController_MSIMysticLight185::RGBController_MSIMysticLight185 + ( + MSIMysticLight185Controller* controller_ptr + ) { controller = controller_ptr; @@ -104,65 +80,117 @@ RGBController_MSIMysticLight185::RGBController_MSIMysticLight185(MSIMysticLight1 location = controller->GetDeviceLocation(); serial = controller->GetSerial(); + const std::vector* supported_zones = controller->GetSupportedZones(); + + for(std::size_t i = 0; i < supported_zones->size(); ++i) + { + for(std::size_t j = 0; j < NUMOF_ZONES; ++j) + { + if(led_zones[j].zone_type == (*supported_zones)[i]) + { + zone_description.push_back(&led_zones[j]); + break; + } + } + } + SetupModes(); SetupZones(); - SetupColors(); } RGBController_MSIMysticLight185::~RGBController_MSIMysticLight185() { + zone_description.clear(); delete controller; } void RGBController_MSIMysticLight185::SetupZones() { - /*---------------------------------------------------------*\ - | Set up zones | - \*---------------------------------------------------------*/ - for(std::size_t zone_idx = 0; zone_idx < NUM_ZONES; zone_idx++) + /*-------------------------------------------------*\ + | Clear any existing color/LED configuration | + \*-------------------------------------------------*/ + leds.clear(); + colors.clear(); + + bool firstRun = false; + + if(zones.size() == 0) { - 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); + firstRun = true; + } + if(firstRun) + { /*---------------------------------------------------------*\ - | Set up LEDs | + | Set up zones | \*---------------------------------------------------------*/ - for(std::size_t led_idx = 0; led_idx < new_zone.leds_count; led_idx++) + for(std::size_t zone_idx = 0; zone_idx < zone_description.size(); ++zone_idx) + { + const ZoneDescription* zd = zone_description[zone_idx]; + + zone new_zone; + + new_zone.name = zd->name; + new_zone.type = ZONE_TYPE_LINEAR; + new_zone.leds_min = 1; + + int maxLeds = (int)controller->GetMaxDirectLeds(zd->zone_type); + + if((controller->GetSupportedDirectMode() == MSIMysticLight185Controller::DIRECT_MODE_ZONE_BASED) && (zd->zone_type == MSI_ZONE_ON_BOARD_LED_0)) + { + new_zone.leds_min = maxLeds; + } + + new_zone.leds_max = maxLeds; + new_zone.leds_count = maxLeds; + new_zone.matrix_map = NULL; + zones.push_back(new_zone); + } + } + + + /*---------------------------------------------------------*\ + | Set up LEDs | + \*---------------------------------------------------------*/ + for(std::size_t zone_idx = 0; zone_idx < zone_description.size(); ++zone_idx) + { + controller->SetCycleCount(zone_description[zone_idx]->zone_type, zones[zone_idx].leds_count); + + for(std::size_t led_idx = 0; led_idx < zones[zone_idx].leds_count; ++led_idx) { led new_led; - new_led.name = new_zone.name + " LED "; - if(new_zone.leds_count > 1) + new_led.name = zones[zone_idx].name + " LED "; + + if(zones[zone_idx].leds_count > 1) { new_led.name.append(std::to_string(led_idx + 1)); } - new_led.value = zd.leds[led_idx]; - + new_led.value = zone_description[zone_idx]->zone_type; leds.push_back(new_led); } } + + SetupColors(); } -void RGBController_MSIMysticLight185::ResizeZone(int zone, int new_size) +void RGBController_MSIMysticLight185::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_MSIMysticLight185::SetCustomMode() @@ -172,14 +200,14 @@ void RGBController_MSIMysticLight185::SetCustomMode() void RGBController_MSIMysticLight185::DeviceUpdateLEDs() { - for(size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + for(std::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); + UpdateLed((int)zone_idx, led_idx); } } - controller->Update(); + controller->Update((modes[active_mode].flags & MODE_FLAG_AUTOMATIC_SAVE) != 0); } void RGBController_MSIMysticLight185::UpdateZoneLEDs(int zone) @@ -188,32 +216,64 @@ void RGBController_MSIMysticLight185::UpdateZoneLEDs(int zone) { UpdateLed(zone, led_idx); } - controller->Update(); + controller->Update((modes[active_mode].flags & MODE_FLAG_AUTOMATIC_SAVE) != 0); } -void RGBController_MSIMysticLight185::UpdateSingleLED(int led) +void RGBController_MSIMysticLight185::UpdateSingleLED + ( + int led + ) { - UpdateLed(leds[led].value, led); - controller->Update(); + int zone_index = IndexOfZoneForType((MSI_ZONE)leds[led].value); + + if(zone_index == -1) + { + LOG_DEBUG("[%s]: could not find zone for type %d", controller->GetDeviceName().c_str(), leds[led].value); + return; + } + + int led_index = led - zones[zone_index].start_idx; + UpdateLed(zone_index, led_index); + controller->Update((modes[active_mode].flags & MODE_FLAG_AUTOMATIC_SAVE) != 0); } void RGBController_MSIMysticLight185::DeviceUpdateMode() { + if(modes[active_mode].value == MSI_MODE_DIRECT_DUMMY) + { + controller->SetDirectMode(true); + } + else + { + controller->SetDirectMode(false); + DeviceUpdateLEDs(); + } +} + +void RGBController_MSIMysticLight185::DeviceSaveMode() +{ + controller->Update(true); } 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 PER_LED_ONLY = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE; + constexpr unsigned int RANDOM_ONLY = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE; 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); + if(controller->GetSupportedDirectMode() != MSIMysticLight185Controller::DIRECT_MODE_DISABLED) + { + SetupMode("Direct", MSI_MODE_DIRECT_DUMMY, MODE_FLAG_HAS_PER_LED_COLOR); + } + + SetupMode("Static", MSI_MODE_STATIC, MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE); + // SetupMode("Off", MSI_MODE_DISABLE, 0); + SetupMode("Breathing", MSI_MODE_BREATHING, PER_LED_ONLY); SetupMode("Flashing", MSI_MODE_FLASHING, COMMON); SetupMode("Double flashing", MSI_MODE_DOUBLE_FLASHING, COMMON); - SetupMode("Lightning", MSI_MODE_LIGHTNING, COMMON); + SetupMode("Lightning", MSI_MODE_LIGHTNING, PER_LED_ONLY); // SetupMode("MSI Marquee", MSI_MODE_MSI_MARQUEE, COMMON); - // SetupMode("Meteor", MSI_MODE_METEOR, 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); @@ -221,52 +281,74 @@ void RGBController_MSIMysticLight185::SetupModes() // 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("Color ring", MSI_MODE_COLOR_RING, RANDOM_ONLY); + SetupMode("Planetary", MSI_MODE_PLANETARY, RANDOM_ONLY); + SetupMode("Double meteor", MSI_MODE_DOUBLE_METEOR, RANDOM_ONLY); + SetupMode("Energy", MSI_MODE_ENERGY, RANDOM_ONLY); + SetupMode("Blink", MSI_MODE_BLINK, COMMON); + SetupMode("Clock", MSI_MODE_CLOCK, RANDOM_ONLY); + SetupMode("Color pulse", MSI_MODE_COLOR_PULSE, COMMON); + SetupMode("Color shift", MSI_MODE_COLOR_SHIFT, RANDOM_ONLY); + SetupMode("Color wave", MSI_MODE_COLOR_WAVE, COMMON); + SetupMode("Marquee", MSI_MODE_MARQUEE, PER_LED_ONLY); // SetupMode("Rainbow", MSI_MODE_RAINBOW, COMMON); - // SetupMode("Rainbow wave", MSI_MODE_RAINBOW_WAVE, COMMON); - // SetupMode("Visor", MSI_MODE_VISOR, COMMON); + SetupMode("Rainbow wave", MSI_MODE_RAINBOW_WAVE, RANDOM_ONLY); + SetupMode("Visor", MSI_MODE_VISOR, COMMON); // SetupMode("JRainbow", MSI_MODE_JRAINBOW, COMMON); - // SetupMode("Rainbow flashing", MSI_MODE_RAINBOW_FLASHING, COMMON); + SetupMode("Rainbow flashing", MSI_MODE_RAINBOW_FLASHING, RANDOM_ONLY); // 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("Color ring double flashing", MSI_MODE_COLOR_RING_DOUBLE_FLASHING, RANDOM_ONLY); + SetupMode("Stack", MSI_MODE_STACK, COMMON); // SetupMode("Corsair Que", MSI_MODE_CORSAIR_QUE, COMMON); - // SetupMode("Fire", MSI_MODE_FIRE, COMMON); + SetupMode("Fire", MSI_MODE_FIRE, RANDOM_ONLY); // SetupMode("Lava", MSI_MODE_LAVA, COMMON); } -void RGBController_MSIMysticLight185::UpdateLed(int zone, int led) +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); + unsigned char red = RGBGetRValue(zones[zone].colors[led]); + unsigned char grn = RGBGetGValue(zones[zone].colors[led]); + unsigned char blu = RGBGetBValue(zones[zone].colors[led]); - 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); + if(controller->IsDirectModeActive()) + { + controller->SetLedColor((MSI_ZONE)(zones[zone].leds[led].value), led, red, grn, blu); + } + else + { + if(led == 0) + { + bool random = modes[active_mode].color_mode == MODE_COLORS_RANDOM; + MSI_MODE mode = (MSI_MODE)modes[active_mode].value; + MSI_SPEED speed = (MSI_SPEED)modes[active_mode].speed; + MSI_BRIGHTNESS brightness = (MSI_BRIGHTNESS)modes[active_mode].brightness; + + controller->SetMode((MSI_ZONE)zones[zone].leds[led].value, mode, speed, brightness, 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) +void RGBController_MSIMysticLight185::SetupMode + ( + const char *name, + MSI_MODE mod, + unsigned int flags + ) { mode Mode; - Mode.name = name; - Mode.value = mod; - Mode.flags = flags; + Mode.name = name; + Mode.value = mod; + Mode.flags = flags; + if(flags & MODE_FLAG_HAS_PER_LED_COLOR) { Mode.color_mode = MODE_COLORS_PER_LED; @@ -294,5 +376,18 @@ void RGBController_MSIMysticLight185::SetupMode(const char *name, MSI_MODE mod, Mode.speed_min = 0; } + if(flags & MODE_FLAG_HAS_BRIGHTNESS) + { + Mode.brightness = MSI_BRIGHTNESS_LEVEL_100; + Mode.brightness_max = MSI_BRIGHTNESS_LEVEL_100; + Mode.brightness_min = MSI_BRIGHTNESS_OFF; + } + else + { + Mode.brightness = MSI_BRIGHTNESS_LEVEL_100; + Mode.brightness_max = MSI_BRIGHTNESS_LEVEL_100; + Mode.brightness_min = MSI_BRIGHTNESS_LEVEL_100; + } + modes.push_back(Mode); } diff --git a/Controllers/MSIMysticLightController/RGBController_MSIMysticLight185.h b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight185.h index 073b9aad5..9a629d0c5 100644 --- a/Controllers/MSIMysticLightController/RGBController_MSIMysticLight185.h +++ b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight185.h @@ -16,25 +16,47 @@ class RGBController_MSIMysticLight185: public RGBController { public: - RGBController_MSIMysticLight185(MSIMysticLight185Controller* controller_ptr); + RGBController_MSIMysticLight185 + ( + MSIMysticLight185Controller* controller_ptr + ); ~RGBController_MSIMysticLight185(); void SetupZones(); - void ResizeZone(int zone, int new_size); + void ResizeZone + ( + int zone, + int new_size + ); void DeviceUpdateLEDs(); - void UpdateZoneLEDs(int zone); - void UpdateSingleLED(int led); + void UpdateZoneLEDs + ( + int zone + ); + void UpdateSingleLED + ( + int led + ); void SetCustomMode(); void DeviceUpdateMode(); + void DeviceSaveMode(); private: void SetupModes(); - void UpdateLed(int zone, int led); - MSI_ZONE ZoneFromPos(int zone); - void SetupMode(const char *name, MSI_MODE mode, unsigned int flags); + void UpdateLed + ( + int zone, + int led + ); + void SetupMode + ( + const char *name, + MSI_MODE mode, + unsigned int flags + ); MSIMysticLight185Controller* controller; };