|
|
|
|
@ -16,25 +16,26 @@ MSIMysticLightController::MSIMysticLightController(hid_device* handle, const cha
|
|
|
|
|
{
|
|
|
|
|
dev = handle;
|
|
|
|
|
|
|
|
|
|
if( dev )
|
|
|
|
|
if(dev)
|
|
|
|
|
{
|
|
|
|
|
loc = path;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ReadName();
|
|
|
|
|
ReadSerial();
|
|
|
|
|
ReadFwVersion();
|
|
|
|
|
ReadSettings();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MSIMysticLightController::~MSIMysticLightController()
|
|
|
|
|
{
|
|
|
|
|
if( dev )
|
|
|
|
|
if(dev)
|
|
|
|
|
{
|
|
|
|
|
hid_close(dev);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int MSIMysticLightController::GetZoneMinLedCount(ZONE zone)
|
|
|
|
|
unsigned int MSIMysticLightController::GetZoneMinLedCount(ZONE /*zone*/)
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
@ -43,11 +44,10 @@ unsigned int MSIMysticLightController::GetZoneMaxLedCount(ZONE zone)
|
|
|
|
|
{
|
|
|
|
|
switch (zone)
|
|
|
|
|
{
|
|
|
|
|
case ZONE::J_RAINBOW_1:
|
|
|
|
|
case ZONE::J_RAINBOW_2:
|
|
|
|
|
case ZONE::J_CORSAIR:
|
|
|
|
|
return 1; // TODO: Handle multiple leds
|
|
|
|
|
break;
|
|
|
|
|
case J_RAINBOW_1:
|
|
|
|
|
case J_RAINBOW_2:
|
|
|
|
|
case J_CORSAIR:
|
|
|
|
|
return 240;
|
|
|
|
|
default:
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
@ -55,7 +55,26 @@ unsigned int MSIMysticLightController::GetZoneMaxLedCount(ZONE zone)
|
|
|
|
|
|
|
|
|
|
unsigned int MSIMysticLightController::GetZoneLedCount(ZONE zone)
|
|
|
|
|
{
|
|
|
|
|
return GetZoneMaxLedCount(zone); // TODO: Handle multiple leds
|
|
|
|
|
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
|
|
|
|
|
|
|
|
|
|
if (!requestedZone)
|
|
|
|
|
{
|
|
|
|
|
return GetZoneMaxLedCount(zone);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return requestedZone->led_count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MSIMysticLightController::SetZoneLedCount(ZONE zone, unsigned int led_count)
|
|
|
|
|
{
|
|
|
|
|
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
|
|
|
|
|
|
|
|
|
|
if (!requestedZone)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
requestedZone->led_count = std::min(GetZoneMaxLedCount(zone), std::max(GetZoneMinLedCount(zone), led_count));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MSIMysticLightController::SetMode(ZONE zone, EFFECT mode, SPEED speed, BRIGHTNESS brightness, bool rainbow_color)
|
|
|
|
|
@ -73,22 +92,27 @@ void MSIMysticLightController::SetMode(ZONE zone, EFFECT mode, SPEED speed, BRIG
|
|
|
|
|
|
|
|
|
|
std::string MSIMysticLightController::GetDeviceName()
|
|
|
|
|
{
|
|
|
|
|
return(name);
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string MSIMysticLightController::GetFWVersion()
|
|
|
|
|
{
|
|
|
|
|
return std::string("AP/LD ").append(versionAPROM).append(" / ").append(versionLDROM);
|
|
|
|
|
return std::string("AP/LD ").append(version_APROM).append(" / ").append(version_LDROM);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string MSIMysticLightController::GetDeviceLocation()
|
|
|
|
|
{
|
|
|
|
|
return(loc);
|
|
|
|
|
return loc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string MSIMysticLightController::GetSerial()
|
|
|
|
|
{
|
|
|
|
|
return(chip_id);
|
|
|
|
|
return chip_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool MSIMysticLightController::ReadSettings()
|
|
|
|
|
{
|
|
|
|
|
return hid_get_feature_report(dev, reinterpret_cast<unsigned char *>(&data), sizeof data) == sizeof data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool MSIMysticLightController::Update()
|
|
|
|
|
@ -118,50 +142,84 @@ void MSIMysticLightController::SetZoneColor(ZONE zone, unsigned char r1, unsigne
|
|
|
|
|
zoneData->color2.B = b2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::pair<Color, Color> MSIMysticLightController::GetZoneColor(ZONE zone)
|
|
|
|
|
{
|
|
|
|
|
ZoneData *zoneData = GetZoneData(zone);
|
|
|
|
|
if (!zoneData)
|
|
|
|
|
{
|
|
|
|
|
return std::make_pair(Color{}, Color{});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::make_pair(Color{
|
|
|
|
|
zoneData->color.R,
|
|
|
|
|
zoneData->color.G,
|
|
|
|
|
zoneData->color.B},
|
|
|
|
|
Color{zoneData->color2.R, zoneData->color2.G, zoneData->color2.B});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ZoneData *MSIMysticLightController::GetZoneData(ZONE zone)
|
|
|
|
|
{
|
|
|
|
|
switch (zone)
|
|
|
|
|
{
|
|
|
|
|
case ZONE::J_RGB_1:
|
|
|
|
|
case J_RGB_1:
|
|
|
|
|
return &data.j_rgb_1;
|
|
|
|
|
case ZONE::J_RGB_2:
|
|
|
|
|
case J_RGB_2:
|
|
|
|
|
return &data.j_rgb_2;
|
|
|
|
|
case ZONE::J_RAINBOW_1:
|
|
|
|
|
case J_RAINBOW_1:
|
|
|
|
|
return &data.j_rainbow_1;
|
|
|
|
|
case ZONE::J_RAINBOW_2:
|
|
|
|
|
case J_RAINBOW_2:
|
|
|
|
|
return &data.j_rainbow_2;
|
|
|
|
|
case ZONE::J_PIPE_1:
|
|
|
|
|
case J_PIPE_1:
|
|
|
|
|
return &data.j_pipe_1;
|
|
|
|
|
case ZONE::J_PIPE_2:
|
|
|
|
|
case J_PIPE_2:
|
|
|
|
|
return &data.j_pipe_2;
|
|
|
|
|
case ZONE::ON_BOARD_LED:
|
|
|
|
|
case ON_BOARD_LED:
|
|
|
|
|
return &data.on_board_led;
|
|
|
|
|
case ZONE::ON_BOARD_LED_1:
|
|
|
|
|
case ON_BOARD_LED_1:
|
|
|
|
|
return &data.on_board_led_1;
|
|
|
|
|
case ZONE::ON_BOARD_LED_2:
|
|
|
|
|
case ON_BOARD_LED_2:
|
|
|
|
|
return &data.on_board_led_2;
|
|
|
|
|
case ZONE::ON_BOARD_LED_3:
|
|
|
|
|
case ON_BOARD_LED_3:
|
|
|
|
|
return &data.on_board_led_3;
|
|
|
|
|
case ZONE::ON_BOARD_LED_4:
|
|
|
|
|
case ON_BOARD_LED_4:
|
|
|
|
|
return &data.on_board_led_4;
|
|
|
|
|
case ZONE::ON_BOARD_LED_5:
|
|
|
|
|
case ON_BOARD_LED_5:
|
|
|
|
|
return &data.on_board_led_5;
|
|
|
|
|
case ZONE::ON_BOARD_LED_6:
|
|
|
|
|
case ON_BOARD_LED_6:
|
|
|
|
|
return &data.on_board_led_6;
|
|
|
|
|
case ZONE::ON_BOARD_LED_7:
|
|
|
|
|
case ON_BOARD_LED_7:
|
|
|
|
|
return &data.on_board_led_7;
|
|
|
|
|
case ZONE::ON_BOARD_LED_8:
|
|
|
|
|
case ON_BOARD_LED_8:
|
|
|
|
|
return &data.on_board_led_8;
|
|
|
|
|
case ZONE::ON_BOARD_LED_9:
|
|
|
|
|
case ON_BOARD_LED_9:
|
|
|
|
|
return &data.on_board_led_9;
|
|
|
|
|
case J_CORSAIR_OUTERLL120:
|
|
|
|
|
return &data.j_corsair_outerll120;
|
|
|
|
|
default:
|
|
|
|
|
case J_CORSAIR:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
RainbowZoneData *MSIMysticLightController::GetRainbowZoneData(ZONE zone)
|
|
|
|
|
{
|
|
|
|
|
switch (zone)
|
|
|
|
|
{
|
|
|
|
|
case J_RAINBOW_1:
|
|
|
|
|
return &data.j_rainbow_1;
|
|
|
|
|
case J_RAINBOW_2:
|
|
|
|
|
return &data.j_rainbow_2;
|
|
|
|
|
case J_CORSAIR:
|
|
|
|
|
default:
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool MSIMysticLightController::ReadFwVersion()
|
|
|
|
|
{
|
|
|
|
|
// First read the APROM
|
|
|
|
|
// Checksum also available at report ID 180, with highCheksum stored at index 8, and low at 9
|
|
|
|
|
int num = 1;
|
|
|
|
|
unsigned char request[64] = {1, 176};
|
|
|
|
|
unsigned char response[64];
|
|
|
|
|
@ -173,9 +231,10 @@ bool MSIMysticLightController::ReadFwVersion()
|
|
|
|
|
unsigned char highValue = response[2] >> 4;
|
|
|
|
|
unsigned char lowValue = response[2] & 15;
|
|
|
|
|
|
|
|
|
|
versionAPROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
|
|
|
|
|
version_APROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
|
|
|
|
|
|
|
|
|
|
// Now read the LDROM
|
|
|
|
|
// Checksum also available at report ID 184, with highCheksum stored at index 8, and low at 9
|
|
|
|
|
request[1] = 182;
|
|
|
|
|
num &= hid_write(dev, request, 64);
|
|
|
|
|
num &= hid_read(dev, response, 64);
|
|
|
|
|
@ -183,7 +242,7 @@ bool MSIMysticLightController::ReadFwVersion()
|
|
|
|
|
highValue = response[2] >> 4;
|
|
|
|
|
lowValue = response[2] & 15;
|
|
|
|
|
|
|
|
|
|
versionLDROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
|
|
|
|
|
version_LDROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
|
|
|
|
|
|
|
|
|
|
return num == 1;
|
|
|
|
|
}
|
|
|
|
|
@ -206,4 +265,41 @@ void MSIMysticLightController::ReadName()
|
|
|
|
|
hid_get_product_string(dev, tname, 256);
|
|
|
|
|
wname = std::wstring(tname);
|
|
|
|
|
name.append(" ").append(std::string(wname.begin(), wname.end()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MSIMysticLightController::SetDeviceSettings(bool is_fan, FAN_TYPE fan_type,
|
|
|
|
|
unsigned char corsair_device_quantity,
|
|
|
|
|
bool is_LL120Outer_individual) { // If is_fan false, it is a stripe
|
|
|
|
|
CorsairZoneData &settingsZone = data.j_corsair;
|
|
|
|
|
settingsZone.fan_flags = (settingsZone.fan_flags & 128) | fan_type << 1 | is_fan;
|
|
|
|
|
settingsZone.corsair_quantity = corsair_device_quantity << 2;
|
|
|
|
|
settingsZone.is_individual = static_cast<unsigned char>(std::bitset<8>(settingsZone.padding).set(0, is_LL120Outer_individual).to_ulong());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool MSIMysticLightController::SetVolume(unsigned char main, unsigned char left, unsigned char right) {
|
|
|
|
|
unsigned char packet[64];
|
|
|
|
|
std::fill_n(packet, sizeof packet, 204);
|
|
|
|
|
|
|
|
|
|
if(main > 100)
|
|
|
|
|
{
|
|
|
|
|
main = 100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(left > 100)
|
|
|
|
|
{
|
|
|
|
|
left = 100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(right > 100)
|
|
|
|
|
{
|
|
|
|
|
right = 100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
packet[0] = 1;
|
|
|
|
|
packet[1] = 192;
|
|
|
|
|
packet[3] = main;
|
|
|
|
|
packet[4] = left;
|
|
|
|
|
packet[5] = right;
|
|
|
|
|
|
|
|
|
|
return hid_write(dev, packet, sizeof packet);
|
|
|
|
|
}
|
|
|
|
|
|