Skip to content

Commit e7c385b

Browse files
ElchananHaasCalcProgrammer1
authored andcommitted
Add support for MSI GL66
1 parent 7c22710 commit e7c385b

7 files changed

+383
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*-----------------------------------------*\
2+
| MSIMysticLight64Controller.cpp |
3+
| |
4+
| Driver for MSI Mystic Light (64-byte) |
5+
| USB lighting controller |
6+
| |
7+
| T-bond 3/4/2020 |
8+
| Adam Honse 3/6/2021 |
9+
| Elchanan Haas 8/23/2022 |
10+
\*-----------------------------------------*/
11+
12+
#include "MSIMysticLight64Controller.h"
13+
#include <algorithm>
14+
#include <array>
15+
#include <bitset>
16+
17+
MSIMysticLight64Controller::MSIMysticLight64Controller
18+
(
19+
hid_device *handle,
20+
const char *path
21+
)
22+
{
23+
dev = handle;
24+
if(dev)
25+
{
26+
location = path;
27+
}
28+
}
29+
30+
MSIMysticLight64Controller::~MSIMysticLight64Controller()
31+
{
32+
hid_close(dev);
33+
}
34+
35+
void MSIMysticLight64Controller::SetMode
36+
(
37+
MSI_64_MODE mode,
38+
MSI_SPEED speed,
39+
MSI_BRIGHTNESS brightness,
40+
unsigned int num_colors,
41+
Color colors[]
42+
)
43+
{
44+
FeaturePacket_64 data;
45+
for(int i = 0; i < MSI_64_MAX_COLORS; i++)
46+
{
47+
data.colors[i] = colors[i];
48+
}
49+
data.speed = speed;
50+
data.brightness = brightness;
51+
data.num_colors = num_colors;
52+
data.mode = mode;
53+
/*-----------------------------------------------------*\
54+
| Send packet to hardware, return true if successful |
55+
\*-----------------------------------------------------*/
56+
hid_send_feature_report(dev, (unsigned char *)&data, sizeof(data));
57+
return;
58+
}
59+
60+
std::string MSIMysticLight64Controller::GetDeviceName()
61+
{
62+
wchar_t tname[256];
63+
64+
/*-----------------------------------------------------*\
65+
| Get the manufacturer string from HID |
66+
\*-----------------------------------------------------*/
67+
hid_get_manufacturer_string(dev, tname, 256);
68+
69+
/*-----------------------------------------------------*\
70+
| Convert wchar_t into std::wstring into std::string |
71+
\*-----------------------------------------------------*/
72+
std::wstring wname = std::wstring(tname);
73+
std::string name = std::string(wname.begin(), wname.end());
74+
75+
/*-----------------------------------------------------*\
76+
| Get the product string from HID |
77+
\*-----------------------------------------------------*/
78+
hid_get_product_string(dev, tname, 256);
79+
80+
/*-----------------------------------------------------*\
81+
| Append the product string to the manufacturer string |
82+
\*-----------------------------------------------------*/
83+
wname = std::wstring(tname);
84+
name.append(" ").append(std::string(wname.begin(), wname.end()));
85+
return name;
86+
}
87+
88+
std::string MSIMysticLight64Controller::GetFWVersion()
89+
{
90+
/*-----------------------------------------------------*\
91+
| This device doesn't support firmware version |
92+
\*-----------------------------------------------------*/
93+
std::string firmware_version = "";
94+
return firmware_version;
95+
}
96+
97+
std::string MSIMysticLight64Controller::GetDeviceLocation()
98+
{
99+
return ("HID: " + location);
100+
}
101+
102+
std::string MSIMysticLight64Controller::GetSerial()
103+
{
104+
wchar_t serial[256];
105+
106+
/*-----------------------------------------------------*\
107+
| Get the serial number string from HID |
108+
\*-----------------------------------------------------*/
109+
hid_get_serial_number_string(dev, serial, 256);
110+
111+
/*-----------------------------------------------------*\
112+
| Convert wchar_t into std::wstring into std::string |
113+
\*-----------------------------------------------------*/
114+
std::wstring wserial = std::wstring(serial);
115+
116+
return (std::string(wserial.begin(), wserial.end()));
117+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*-----------------------------------------*\
2+
| MSIMysticLight64Controller.h |
3+
| |
4+
| Definitions and types for MSI Mystic |
5+
| Light (64-byte) USB lighting controllers |
6+
| |
7+
| T-bond 3/4/2020 |
8+
| Adam Honse 3/6/2021 |
9+
\*-----------------------------------------*/
10+
11+
#include "MSIMysticLightCommon.h"
12+
#include "RGBController.h"
13+
#include <cstring>
14+
#include <hidapi/hidapi.h>
15+
#include <limits>
16+
17+
#pragma once
18+
19+
enum MSI_64_MODE
20+
{
21+
MSI_64_OFF = 0,
22+
MSI_64_STEADY = 1,
23+
MSI_64_BREATHING = 2,
24+
MSI_64_PULSE = 3,
25+
MSI_64_DOUBLE_PULSE = 4,
26+
MSI_64_CYCLE = 5,
27+
MSI_64_SMOOTH_CYCLE = 6,
28+
};
29+
30+
class MSIMysticLight64Controller
31+
{
32+
public:
33+
MSIMysticLight64Controller
34+
(
35+
hid_device* handle,
36+
const char *path
37+
);
38+
~MSIMysticLight64Controller();
39+
40+
void SetMode
41+
(
42+
MSI_64_MODE mode,
43+
MSI_SPEED speed,
44+
MSI_BRIGHTNESS brightness,
45+
unsigned int num_colors,
46+
Color colors[]
47+
);
48+
49+
50+
std::string GetDeviceName();
51+
std::string GetDeviceLocation();
52+
std::string GetFWVersion();
53+
std::string GetSerial();
54+
55+
private:
56+
57+
hid_device* dev;
58+
std::string location;
59+
};

Controllers/MSIMysticLightController/MSIMysticLightCommon.h

+14
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ enum MSI_BRIGHTNESS
122122
#define SYNC_SETTING_JPIPE2 0x20
123123
#define SYNC_SETTING_JRGB 0x80
124124

125+
#define MSI_64_MAX_COLORS 7
126+
125127
struct Color
126128
{
127129
unsigned char R;
@@ -154,6 +156,18 @@ struct RainbowZoneData : ZoneData
154156
unsigned char cycle_or_led_num = PER_LED_MODE_JRAINBOW_LED_COUNT;
155157
};
156158

159+
struct FeaturePacket_64
160+
{
161+
const unsigned char report_id = 0x02; // Report ID
162+
const unsigned char second_byte = 0x00;
163+
unsigned char mode = 0x00;
164+
unsigned char speed = 0x00;
165+
unsigned char brightness = 0x00;
166+
unsigned char num_colors = 0x00;
167+
Color colors[MSI_64_MAX_COLORS] = {};
168+
const unsigned char padding[37] = {}; //pad to make the packet size 64 bytes
169+
};
170+
157171
struct FeaturePacket_162
158172
{
159173
const unsigned char report_id = 0x52; // Report ID

Controllers/MSIMysticLightController/MSIMysticLightControllerDetect.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "Detector.h"
2+
#include "MSIMysticLight64Controller.h"
23
#include "MSIMysticLight162Controller.h"
34
#include "MSIMysticLight185Controller.h"
5+
#include "RGBController_MSIMysticLight64.h"
46
#include "RGBController_MSIMysticLight162.h"
57
#include "RGBController_MSIMysticLight185.h"
68
#include "dependencies/dmiinfo.h"
@@ -33,7 +35,6 @@ void DetectMSIMysticLightControllers
3335
)
3436
{
3537
hid_device* dev = hid_open_path(info->path);
36-
3738
if(dev != nullptr)
3839
{
3940
unsigned char temp_buffer[200];
@@ -55,6 +56,12 @@ void DetectMSIMysticLightControllers
5556
rgb_controller->name = "MSI " + dmi.getMainboard();
5657
ResourceManager::get()->RegisterRGBController(rgb_controller);
5758
}
59+
else if(packet_length == sizeof(FeaturePacket_64) )
60+
{
61+
MSIMysticLight64Controller* controller = new MSIMysticLight64Controller(dev, info->path);
62+
RGBController_MSIMysticLight64* rgb_controller = new RGBController_MSIMysticLight64(controller);
63+
ResourceManager::get()->RegisterRGBController(rgb_controller);
64+
}
5865
else // no supported length returned
5966
{
6067
std::string name = "MSI " + dmi.getMainboard();
@@ -64,7 +71,7 @@ void DetectMSIMysticLightControllers
6471
}
6572
}
6673

67-
74+
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_1563", DetectMSIMysticLightControllers, MSI_USB_VID, 0x1563, 0x00FF, 0x01);
6875
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_1720", DetectMSIMysticLightControllers, MSI_USB_VID, 0x1720, 0x0001, 0x00);
6976
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B12", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B12, 0x0001, 0x00);
7077
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7B16", DetectMSIMysticLightControllers, MSI_USB_VID, 0x7B16, 0x0001, 0x00);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#include "RGBController_MSIMysticLight64.h"
2+
3+
/**------------------------------------------------------------------*\
4+
@name MSI GL66 Mystic Light Keyboard (64 Byte)
5+
@category Keyboard
6+
@type USB
7+
@save :robot:
8+
@effects :white_check_mark:
9+
@detectors DetectMSIMysticLightControllers
10+
@comment
11+
\*-------------------------------------------------------------------*/
12+
13+
RGBController_MSIMysticLight64::RGBController_MSIMysticLight64
14+
(
15+
MSIMysticLight64Controller *controller_ptr
16+
)
17+
{
18+
controller = controller_ptr;
19+
name = controller->GetDeviceName();
20+
vendor = "MSI";
21+
type = DEVICE_TYPE_KEYBOARD;
22+
description = "MSI Mystic Light Device (64-byte)";
23+
version = controller->GetFWVersion();
24+
location = controller->GetDeviceLocation();
25+
serial = controller->GetSerial();
26+
SetupZones();
27+
}
28+
29+
RGBController_MSIMysticLight64::~RGBController_MSIMysticLight64()
30+
{
31+
delete controller;
32+
}
33+
34+
void RGBController_MSIMysticLight64::ResizeZone
35+
(
36+
int /*zone*/,
37+
int /*new_size*/
38+
)
39+
{
40+
}
41+
42+
void RGBController_MSIMysticLight64::SetupZones()
43+
{
44+
zone msi_zone;
45+
msi_zone.name = "MSI Zone";
46+
msi_zone.type = ZONE_TYPE_SINGLE;
47+
msi_zone.leds_min = 1;
48+
msi_zone.leds_max = 1;
49+
msi_zone.leds_count = 1;
50+
msi_zone.matrix_map = NULL;
51+
zones.push_back(msi_zone);
52+
53+
led msi_led;
54+
msi_led.name = "MSI LED";
55+
leds.push_back(msi_led);
56+
SetupModes();
57+
SetupColors();
58+
}
59+
60+
void RGBController_MSIMysticLight64::DeviceUpdateMode()
61+
{
62+
DeviceUpdateLEDs();
63+
}
64+
65+
void RGBController_MSIMysticLight64::DeviceUpdateLEDs()
66+
{
67+
mode &Mode = modes[active_mode];
68+
MSI_64_MODE msi_mode = (MSI_64_MODE)Mode.value;
69+
MSI_SPEED speed = (MSI_SPEED)Mode.speed;
70+
MSI_BRIGHTNESS brightness = (MSI_BRIGHTNESS)(Mode.brightness);
71+
Color led_colors[MSI_64_MAX_COLORS] = {};
72+
unsigned int num_colors = 0;
73+
if(Mode.flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
74+
{
75+
num_colors = Mode.colors.size();
76+
for(unsigned int i = 0; i < num_colors; i++)
77+
{
78+
led_colors[i].R = RGBGetRValue(Mode.colors[i]);
79+
led_colors[i].G = RGBGetGValue(Mode.colors[i]);
80+
led_colors[i].B = RGBGetBValue(Mode.colors[i]);
81+
}
82+
}
83+
controller->SetMode(msi_mode, speed, brightness, num_colors, led_colors);
84+
}
85+
86+
void RGBController_MSIMysticLight64::UpdateZoneLEDs(int /*zone*/)
87+
{
88+
DeviceUpdateLEDs();
89+
}
90+
91+
void RGBController_MSIMysticLight64::UpdateSingleLED(int /*led*/)
92+
{
93+
DeviceUpdateLEDs();
94+
}
95+
96+
void RGBController_MSIMysticLight64::SetupModes()
97+
{
98+
unsigned int TRANSITION=MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
99+
SetupMode("Off", MSI_64_MODE::MSI_64_OFF, 0);
100+
SetupMode("Static", MSI_64_MODE::MSI_64_STEADY, MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR);
101+
SetupMode("Breathing", MSI_64_MODE::MSI_64_BREATHING, TRANSITION);
102+
SetupMode("Flashing", MSI_64_MODE::MSI_64_PULSE, TRANSITION);
103+
SetupMode("Double Flashing", MSI_64_MODE::MSI_64_DOUBLE_PULSE, TRANSITION);
104+
SetupMode("Spectrum Cycle", MSI_64_MODE::MSI_64_CYCLE, TRANSITION);
105+
SetupMode("Smooth Spectrum Cycle", MSI_64_MODE::MSI_64_SMOOTH_CYCLE, TRANSITION);
106+
}
107+
void RGBController_MSIMysticLight64::SetupMode
108+
(
109+
const char *name,
110+
MSI_64_MODE mod,
111+
unsigned int flags
112+
)
113+
{
114+
mode Mode;
115+
Mode.name = name;
116+
Mode.value = mod;
117+
Mode.flags = flags;
118+
if(flags & MODE_FLAG_HAS_BRIGHTNESS)
119+
{
120+
Mode.brightness_min = MSI_BRIGHTNESS_LEVEL_10;
121+
Mode.brightness_max = MSI_BRIGHTNESS_LEVEL_100;
122+
Mode.brightness = MSI_BRIGHTNESS_LEVEL_100;
123+
}
124+
if(flags & MODE_FLAG_HAS_SPEED)
125+
{
126+
Mode.speed_min = MSI_SPEED_LOW;
127+
Mode.speed_max = MSI_SPEED_HIGH;
128+
Mode.speed = MSI_SPEED_LOW;
129+
}
130+
if(flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
131+
{
132+
Mode.color_mode= MODE_COLORS_MODE_SPECIFIC;
133+
Mode.colors_min = 1;
134+
Mode.colors_max = 1;
135+
if (flags & MODE_FLAG_HAS_SPEED)
136+
{
137+
Mode.colors_max = MSI_64_MAX_COLORS;
138+
}
139+
/*-------------------------------------------------*\
140+
| Set up colors for rainbow cycle |
141+
\*-------------------------------------------------*/
142+
Mode.colors.push_back(0x000000FF);
143+
Mode.colors.push_back(0x000050FF);
144+
Mode.colors.push_back(0x0000FFFF);
145+
Mode.colors.push_back(0x0000FF00);
146+
Mode.colors.push_back(0x00FF0000);
147+
Mode.colors.push_back(0x00FF0096);
148+
Mode.colors.push_back(0x00FF00FF);
149+
}
150+
modes.push_back(Mode);
151+
}

0 commit comments

Comments
 (0)