diff --git a/Controllers/MSIMysticLightController/MSIMysticLight64Controller.cpp b/Controllers/MSIMysticLightController/MSIMysticLight64Controller.cpp new file mode 100644 index 00000000..7966aad5 --- /dev/null +++ b/Controllers/MSIMysticLightController/MSIMysticLight64Controller.cpp @@ -0,0 +1,117 @@ +/*-----------------------------------------*\ +| MSIMysticLight64Controller.cpp | +| | +| Driver for MSI Mystic Light (64-byte) | +| USB lighting controller | +| | +| T-bond 3/4/2020 | +| Adam Honse 3/6/2021 | +| Elchanan Haas 8/23/2022 | +\*-----------------------------------------*/ + +#include "MSIMysticLight64Controller.h" +#include +#include +#include + +MSIMysticLight64Controller::MSIMysticLight64Controller +( + hid_device *handle, + const char *path +) +{ + dev = handle; + if(dev) + { + location = path; + } +} + +MSIMysticLight64Controller::~MSIMysticLight64Controller() +{ + hid_close(dev); +} + +void MSIMysticLight64Controller::SetMode +( + MSI_64_MODE mode, + MSI_SPEED speed, + MSI_BRIGHTNESS brightness, + unsigned int num_colors, + Color colors[] +) +{ + FeaturePacket_64 data; + for(int i = 0; i < MSI_64_MAX_COLORS; i++) + { + data.colors[i] = colors[i]; + } + data.speed = speed; + data.brightness = brightness; + data.num_colors = num_colors; + data.mode = mode; + /*-----------------------------------------------------*\ + | Send packet to hardware, return true if successful | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, (unsigned char *)&data, sizeof(data)); + return; +} + +std::string MSIMysticLight64Controller::GetDeviceName() +{ + wchar_t tname[256]; + + /*-----------------------------------------------------*\ + | Get the manufacturer string from HID | + \*-----------------------------------------------------*/ + hid_get_manufacturer_string(dev, tname, 256); + + /*-----------------------------------------------------*\ + | Convert wchar_t into std::wstring into std::string | + \*-----------------------------------------------------*/ + std::wstring wname = std::wstring(tname); + std::string name = std::string(wname.begin(), wname.end()); + + /*-----------------------------------------------------*\ + | Get the product string from HID | + \*-----------------------------------------------------*/ + hid_get_product_string(dev, tname, 256); + + /*-----------------------------------------------------*\ + | Append the product string to the manufacturer string | + \*-----------------------------------------------------*/ + wname = std::wstring(tname); + name.append(" ").append(std::string(wname.begin(), wname.end())); + return name; +} + +std::string MSIMysticLight64Controller::GetFWVersion() +{ + /*-----------------------------------------------------*\ + | This device doesn't support firmware version | + \*-----------------------------------------------------*/ + std::string firmware_version = ""; + return firmware_version; +} + +std::string MSIMysticLight64Controller::GetDeviceLocation() +{ + return ("HID: " + location); +} + +std::string MSIMysticLight64Controller::GetSerial() +{ + wchar_t serial[256]; + + /*-----------------------------------------------------*\ + | Get the serial number string from HID | + \*-----------------------------------------------------*/ + hid_get_serial_number_string(dev, serial, 256); + + /*-----------------------------------------------------*\ + | Convert wchar_t into std::wstring into std::string | + \*-----------------------------------------------------*/ + std::wstring wserial = std::wstring(serial); + + return (std::string(wserial.begin(), wserial.end())); +} diff --git a/Controllers/MSIMysticLightController/MSIMysticLight64Controller.h b/Controllers/MSIMysticLightController/MSIMysticLight64Controller.h new file mode 100644 index 00000000..527f91b9 --- /dev/null +++ b/Controllers/MSIMysticLightController/MSIMysticLight64Controller.h @@ -0,0 +1,59 @@ +/*-----------------------------------------*\ +| MSIMysticLight64Controller.h | +| | +| Definitions and types for MSI Mystic | +| Light (64-byte) USB lighting controllers | +| | +| T-bond 3/4/2020 | +| Adam Honse 3/6/2021 | +\*-----------------------------------------*/ + +#include "MSIMysticLightCommon.h" +#include "RGBController.h" +#include +#include +#include + +#pragma once + +enum MSI_64_MODE +{ + MSI_64_OFF = 0, + MSI_64_STEADY = 1, + MSI_64_BREATHING = 2, + MSI_64_PULSE = 3, + MSI_64_DOUBLE_PULSE = 4, + MSI_64_CYCLE = 5, + MSI_64_SMOOTH_CYCLE = 6, +}; + +class MSIMysticLight64Controller +{ +public: + MSIMysticLight64Controller + ( + hid_device* handle, + const char *path + ); + ~MSIMysticLight64Controller(); + + void SetMode + ( + MSI_64_MODE mode, + MSI_SPEED speed, + MSI_BRIGHTNESS brightness, + unsigned int num_colors, + Color colors[] + ); + + + std::string GetDeviceName(); + std::string GetDeviceLocation(); + std::string GetFWVersion(); + std::string GetSerial(); + +private: + + hid_device* dev; + std::string location; +}; diff --git a/Controllers/MSIMysticLightController/MSIMysticLightCommon.h b/Controllers/MSIMysticLightController/MSIMysticLightCommon.h index fabb5f2f..8977e47e 100644 --- a/Controllers/MSIMysticLightController/MSIMysticLightCommon.h +++ b/Controllers/MSIMysticLightController/MSIMysticLightCommon.h @@ -122,6 +122,8 @@ enum MSI_BRIGHTNESS #define SYNC_SETTING_JPIPE2 0x20 #define SYNC_SETTING_JRGB 0x80 +#define MSI_64_MAX_COLORS 7 + struct Color { unsigned char R; @@ -154,6 +156,18 @@ struct RainbowZoneData : ZoneData unsigned char cycle_or_led_num = PER_LED_MODE_JRAINBOW_LED_COUNT; }; +struct FeaturePacket_64 +{ + const unsigned char report_id = 0x02; // Report ID + const unsigned char second_byte = 0x00; + unsigned char mode = 0x00; + unsigned char speed = 0x00; + unsigned char brightness = 0x00; + unsigned char num_colors = 0x00; + Color colors[MSI_64_MAX_COLORS] = {}; + const unsigned char padding[37] = {}; //pad to make the packet size 64 bytes +}; + struct FeaturePacket_162 { const unsigned char report_id = 0x52; // Report ID diff --git a/Controllers/MSIMysticLightController/MSIMysticLightControllerDetect.cpp b/Controllers/MSIMysticLightController/MSIMysticLightControllerDetect.cpp index 93a01845..ec341965 100644 --- a/Controllers/MSIMysticLightController/MSIMysticLightControllerDetect.cpp +++ b/Controllers/MSIMysticLightController/MSIMysticLightControllerDetect.cpp @@ -1,6 +1,8 @@ #include "Detector.h" +#include "MSIMysticLight64Controller.h" #include "MSIMysticLight162Controller.h" #include "MSIMysticLight185Controller.h" +#include "RGBController_MSIMysticLight64.h" #include "RGBController_MSIMysticLight162.h" #include "RGBController_MSIMysticLight185.h" #include "dependencies/dmiinfo.h" @@ -33,7 +35,6 @@ void DetectMSIMysticLightControllers ) { hid_device* dev = hid_open_path(info->path); - if(dev != nullptr) { unsigned char temp_buffer[200]; @@ -55,6 +56,12 @@ void DetectMSIMysticLightControllers rgb_controller->name = "MSI " + dmi.getMainboard(); ResourceManager::get()->RegisterRGBController(rgb_controller); } + else if(packet_length == sizeof(FeaturePacket_64) ) + { + MSIMysticLight64Controller* controller = new MSIMysticLight64Controller(dev, info->path); + RGBController_MSIMysticLight64* rgb_controller = new RGBController_MSIMysticLight64(controller); + ResourceManager::get()->RegisterRGBController(rgb_controller); + } else // no supported length returned { std::string name = "MSI " + dmi.getMainboard(); @@ -64,7 +71,7 @@ void DetectMSIMysticLightControllers } } - +REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_1563", DetectMSIMysticLightControllers, MSI_USB_VID, 0x1563, 0x00FF, 0x01); 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); diff --git a/Controllers/MSIMysticLightController/RGBController_MSIMysticLight64.cpp b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight64.cpp new file mode 100644 index 00000000..f35be3cf --- /dev/null +++ b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight64.cpp @@ -0,0 +1,151 @@ +#include "RGBController_MSIMysticLight64.h" + +/**------------------------------------------------------------------*\ + @name MSI GL66 Mystic Light Keyboard (64 Byte) + @category Keyboard + @type USB + @save :robot: + @effects :white_check_mark: + @detectors DetectMSIMysticLightControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_MSIMysticLight64::RGBController_MSIMysticLight64 +( + MSIMysticLight64Controller *controller_ptr +) +{ + controller = controller_ptr; + name = controller->GetDeviceName(); + vendor = "MSI"; + type = DEVICE_TYPE_KEYBOARD; + description = "MSI Mystic Light Device (64-byte)"; + version = controller->GetFWVersion(); + location = controller->GetDeviceLocation(); + serial = controller->GetSerial(); + SetupZones(); +} + +RGBController_MSIMysticLight64::~RGBController_MSIMysticLight64() +{ + delete controller; +} + +void RGBController_MSIMysticLight64::ResizeZone +( + int /*zone*/, + int /*new_size*/ +) +{ +} + +void RGBController_MSIMysticLight64::SetupZones() +{ + zone msi_zone; + msi_zone.name = "MSI Zone"; + msi_zone.type = ZONE_TYPE_SINGLE; + msi_zone.leds_min = 1; + msi_zone.leds_max = 1; + msi_zone.leds_count = 1; + msi_zone.matrix_map = NULL; + zones.push_back(msi_zone); + + led msi_led; + msi_led.name = "MSI LED"; + leds.push_back(msi_led); + SetupModes(); + SetupColors(); +} + +void RGBController_MSIMysticLight64::DeviceUpdateMode() +{ + DeviceUpdateLEDs(); +} + +void RGBController_MSIMysticLight64::DeviceUpdateLEDs() +{ + mode &Mode = modes[active_mode]; + MSI_64_MODE msi_mode = (MSI_64_MODE)Mode.value; + MSI_SPEED speed = (MSI_SPEED)Mode.speed; + MSI_BRIGHTNESS brightness = (MSI_BRIGHTNESS)(Mode.brightness); + Color led_colors[MSI_64_MAX_COLORS] = {}; + unsigned int num_colors = 0; + if(Mode.flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR) + { + num_colors = Mode.colors.size(); + for(unsigned int i = 0; i < num_colors; i++) + { + led_colors[i].R = RGBGetRValue(Mode.colors[i]); + led_colors[i].G = RGBGetGValue(Mode.colors[i]); + led_colors[i].B = RGBGetBValue(Mode.colors[i]); + } + } + controller->SetMode(msi_mode, speed, brightness, num_colors, led_colors); +} + +void RGBController_MSIMysticLight64::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_MSIMysticLight64::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_MSIMysticLight64::SetupModes() +{ + unsigned int TRANSITION=MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + SetupMode("Off", MSI_64_MODE::MSI_64_OFF, 0); + SetupMode("Static", MSI_64_MODE::MSI_64_STEADY, MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR); + SetupMode("Breathing", MSI_64_MODE::MSI_64_BREATHING, TRANSITION); + SetupMode("Flashing", MSI_64_MODE::MSI_64_PULSE, TRANSITION); + SetupMode("Double Flashing", MSI_64_MODE::MSI_64_DOUBLE_PULSE, TRANSITION); + SetupMode("Spectrum Cycle", MSI_64_MODE::MSI_64_CYCLE, TRANSITION); + SetupMode("Smooth Spectrum Cycle", MSI_64_MODE::MSI_64_SMOOTH_CYCLE, TRANSITION); +} +void RGBController_MSIMysticLight64::SetupMode +( + const char *name, + MSI_64_MODE mod, + unsigned int flags +) +{ + mode Mode; + Mode.name = name; + Mode.value = mod; + Mode.flags = flags; + if(flags & MODE_FLAG_HAS_BRIGHTNESS) + { + Mode.brightness_min = MSI_BRIGHTNESS_LEVEL_10; + Mode.brightness_max = MSI_BRIGHTNESS_LEVEL_100; + Mode.brightness = MSI_BRIGHTNESS_LEVEL_100; + } + if(flags & MODE_FLAG_HAS_SPEED) + { + Mode.speed_min = MSI_SPEED_LOW; + Mode.speed_max = MSI_SPEED_HIGH; + Mode.speed = MSI_SPEED_LOW; + } + if(flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR) + { + Mode.color_mode= MODE_COLORS_MODE_SPECIFIC; + Mode.colors_min = 1; + Mode.colors_max = 1; + if (flags & MODE_FLAG_HAS_SPEED) + { + Mode.colors_max = MSI_64_MAX_COLORS; + } + /*-------------------------------------------------*\ + | Set up colors for rainbow cycle | + \*-------------------------------------------------*/ + Mode.colors.push_back(0x000000FF); + Mode.colors.push_back(0x000050FF); + Mode.colors.push_back(0x0000FFFF); + Mode.colors.push_back(0x0000FF00); + Mode.colors.push_back(0x00FF0000); + Mode.colors.push_back(0x00FF0096); + Mode.colors.push_back(0x00FF00FF); + } + modes.push_back(Mode); +} \ No newline at end of file diff --git a/Controllers/MSIMysticLightController/RGBController_MSIMysticLight64.h b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight64.h new file mode 100644 index 00000000..75429a4b --- /dev/null +++ b/Controllers/MSIMysticLightController/RGBController_MSIMysticLight64.h @@ -0,0 +1,29 @@ +#pragma once +#include "RGBController.h" +#include "MSIMysticLight64Controller.h" + +class RGBController_MSIMysticLight64 : public RGBController +{ +public: + RGBController_MSIMysticLight64(MSIMysticLight64Controller* controller_ptr); + ~RGBController_MSIMysticLight64(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + MSIMysticLight64Controller* controller; + void SetupModes(); + void SetupMode + ( + const char *name, + MSI_64_MODE mode, + unsigned int flags + ); +}; \ No newline at end of file diff --git a/OpenRGB.pro b/OpenRGB.pro index 98914914..40a9b04a 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -479,8 +479,10 @@ HEADERS += Controllers/MSIGPUController/MSIGPUController.h \ Controllers/MSIGPUController/RGBController_MSIGPU.h \ Controllers/MSIMysticLightController/MSIMysticLightCommon.h \ + Controllers/MSIMysticLightController/MSIMysticLight64Controller.h \ Controllers/MSIMysticLightController/MSIMysticLight162Controller.h \ Controllers/MSIMysticLightController/MSIMysticLight185Controller.h \ + Controllers/MSIMysticLightController/RGBController_MSIMysticLight64.h \ Controllers/MSIMysticLightController/RGBController_MSIMysticLight162.h \ Controllers/MSIMysticLightController/RGBController_MSIMysticLight185.h \ Controllers/MSIOptixController/MSIOptixController.h \ @@ -1016,9 +1018,11 @@ SOURCES += Controllers/MSIGPUController/MSIGPUController.cpp \ Controllers/MSIGPUController/MSIGPUControllerDetect.cpp \ Controllers/MSIGPUController/RGBController_MSIGPU.cpp \ + Controllers/MSIMysticLightController/MSIMysticLight64Controller.cpp \ Controllers/MSIMysticLightController/MSIMysticLight162Controller.cpp \ Controllers/MSIMysticLightController/MSIMysticLight185Controller.cpp \ Controllers/MSIMysticLightController/MSIMysticLightControllerDetect.cpp \ + Controllers/MSIMysticLightController/RGBController_MSIMysticLight64.cpp \ Controllers/MSIMysticLightController/RGBController_MSIMysticLight162.cpp \ Controllers/MSIMysticLightController/RGBController_MSIMysticLight185.cpp \ Controllers/MSIOptixController/MSIOptixController.cpp \