725 lines
No EOL
22 KiB
C++
725 lines
No EOL
22 KiB
C++
/*---------------------------------------------------------*\
|
|
| GigabyteRGBFusion2USBController.cpp |
|
|
| |
|
|
| Driver for Gigabyte Aorus RGB Fusion 2 USB motherboard |
|
|
| |
|
|
| jackun 08 Jan 2020 |
|
|
| megadjc 31 Jul 2025 |
|
|
| |
|
|
| This file is part of the OpenRGB project |
|
|
| SPDX-License-Identifier: GPL-2.0-only |
|
|
\*---------------------------------------------------------*/
|
|
|
|
#include "GigabyteRGBFusion2USBController.h"
|
|
#include "ResourceManager.h"
|
|
#include "SettingsManager.h"
|
|
|
|
/*-------------------------------------------------------------------------*\
|
|
| Low level RGB value conversion table |
|
|
| This is stored as a uint32_t in the chip so is trasmitted LSB to MSB |
|
|
| Therefore the numbers represent the index where the controller will find |
|
|
| respective colour in a regular packet |
|
|
\*-------------------------------------------------------------------------*/
|
|
static RGBCalibration GigabyteCalibrationsLookup
|
|
{
|
|
{ "BGR", {{{0x00, 0x01, 0x02, 0x00}}}},
|
|
{ "BRG", {{{0x01, 0x00, 0x02, 0x00}}}},
|
|
{ "GRB", {{{0x02, 0x00, 0x01, 0x00}}}},
|
|
{ "GBR", {{{0x00, 0x02, 0x01, 0x00}}}},
|
|
{ "RGB", {{{0x02, 0x01, 0x00, 0x00}}}},
|
|
{ "RBG", {{{0x01, 0x02, 0x00, 0x00}}}}
|
|
};
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Converts LED counts to divisions in hardware |
|
|
\*---------------------------------------------------------*/
|
|
static LEDCount LedCountToEnum(unsigned int c)
|
|
{
|
|
if(c <= 32)
|
|
{
|
|
return(LEDS_32);
|
|
}
|
|
else if(c <= 64)
|
|
{
|
|
return(LEDS_64);
|
|
}
|
|
else if(c <= 256)
|
|
{
|
|
return(LEDS_256);
|
|
}
|
|
else if(c <= 512)
|
|
{
|
|
return(LEDS_512);
|
|
}
|
|
else
|
|
{
|
|
return(LEDS_1024);
|
|
}
|
|
}
|
|
|
|
RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char* path, std::string mb_name, uint16_t pid): dev(handle), product_id(pid)
|
|
{
|
|
name = mb_name;
|
|
location = path;
|
|
|
|
if(!RefreshHardwareInfo())
|
|
{
|
|
return;
|
|
}
|
|
if(report.support_cmd_flag >= 0x02)
|
|
{
|
|
EnableLampArray(false);
|
|
}
|
|
ResetController();
|
|
EnableBeat(false);
|
|
}
|
|
|
|
RGBFusion2USBController::~RGBFusion2USBController()
|
|
{
|
|
hid_close(dev);
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Read configuration data from hardware. |
|
|
| Returns false if read fails. |
|
|
\*---------------------------------------------------------*/
|
|
bool RGBFusion2USBController::RefreshHardwareInfo()
|
|
{
|
|
unsigned char buffer[64] = {0};
|
|
|
|
SendPacket(0x60, 0x00);
|
|
buffer[0] = report_id;
|
|
int res = hid_get_feature_report(dev, buffer, sizeof(buffer));
|
|
|
|
if(res < static_cast<int>(sizeof(IT8297Report)))
|
|
{
|
|
report_loaded = false;
|
|
return false;
|
|
}
|
|
|
|
std::memcpy(&report, buffer, sizeof(IT8297Report));
|
|
report_loaded = true;
|
|
|
|
description = std::string(report.str_product, 28);
|
|
if(std::string::iterator nul = std::find(description.begin(), description.end(), '\0');
|
|
nul != description.end())
|
|
{
|
|
description.erase(nul, description.end());
|
|
}
|
|
|
|
{
|
|
char text[32]{};
|
|
|
|
uint32_t fw_ver = ((report.fw_ver & 0x000000FFu) << 24)
|
|
| ((report.fw_ver & 0x0000FF00u) << 8)
|
|
| ((report.fw_ver & 0x00FF0000u) >> 8)
|
|
| ((report.fw_ver & 0xFF000000u) >> 24);
|
|
|
|
uint8_t b0 = static_cast<uint8_t>((fw_ver >> 24) & 0xFFu);
|
|
uint8_t b1 = static_cast<uint8_t>((fw_ver >> 16) & 0xFFu);
|
|
uint8_t b2 = static_cast<uint8_t>((fw_ver >> 8) & 0xFFu);
|
|
uint8_t b3 = static_cast<uint8_t>( fw_ver & 0xFFu);
|
|
|
|
std::snprintf(text, sizeof(text), "%u.%u.%u.%u", b0, b1, b2, b3);
|
|
version = text;
|
|
std::snprintf(text, sizeof(text), "0x%08X", report.chip_id);
|
|
chip_id = text;
|
|
}
|
|
|
|
D_LED1_count = LedCountToEnum(report.curr_led_count_low & 0x0F);
|
|
D_LED2_count = LedCountToEnum((report.curr_led_count_low >> 4) & 0x0F);
|
|
D_LED3_count = LedCountToEnum(report.curr_led_count_high & 0x0F);
|
|
D_LED4_count = LedCountToEnum((report.curr_led_count_high >> 4) & 0x0F);
|
|
|
|
cal_data.dled[0] = report.cal_strip0;
|
|
cal_data.dled[1] = report.cal_strip1;
|
|
cal_data.mainboard = report.rgb_cali;
|
|
cal_data.spare[0] = report.cal_spare0;
|
|
cal_data.spare[1] = report.cal_spare1;
|
|
|
|
cali_loaded = false;
|
|
if(product_id == 0x5711)
|
|
{
|
|
unsigned char buffer2[64] = {0};
|
|
SendPacket(0x61, 0x00);
|
|
buffer2[0] = report_id;
|
|
int res2 = hid_get_feature_report(dev, buffer2, sizeof(buffer2));
|
|
|
|
if(res2 >= static_cast<int>(sizeof(IT5711Calibration)))
|
|
{
|
|
std::memcpy(&cali, buffer2, sizeof(IT5711Calibration));
|
|
cali_loaded = true;
|
|
|
|
cal_data.dled[2] = cali.cal_strip2;
|
|
cal_data.dled[3] = cali.cal_strip3;
|
|
cal_data.spare[2] = cali.cal_spare2;
|
|
cal_data.spare[3] = cali.cal_spare3;
|
|
}
|
|
else
|
|
{
|
|
cal_data.dled[2] = 0;
|
|
cal_data.dled[3] = 0;
|
|
cal_data.spare[2] = 0;
|
|
cal_data.spare[3] = 0;
|
|
cali_loaded = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cal_data.dled[2] = 0;
|
|
cal_data.dled[3] = 0;
|
|
cal_data.spare[2] = 0;
|
|
cal_data.spare[3] = 0;
|
|
}
|
|
|
|
return report_loaded;
|
|
}
|
|
|
|
void RGBFusion2USBController::SetMode(int m)
|
|
{
|
|
mode = m;
|
|
}
|
|
|
|
std::string RGBFusion2USBController::DecodeCalibrationBuffer(uint32_t value) const
|
|
{
|
|
if(value==0) return "OFF";
|
|
|
|
uint8_t bo_b = value & 0xFF;
|
|
uint8_t bo_g = (value >> 8) & 0xFF;
|
|
uint8_t bo_r = (value >> 16) & 0xFF;
|
|
|
|
bool in_range = (bo_r<3 && bo_g<3 && bo_b<3);
|
|
bool distinct = (bo_r!=bo_g && bo_r!=bo_b && bo_g!=bo_b);
|
|
|
|
if(in_range && distinct)
|
|
{
|
|
std::string out(3, '?');
|
|
out[bo_r] = 'R';
|
|
out[bo_g] = 'G';
|
|
out[bo_b] = 'B';
|
|
return out;
|
|
}
|
|
|
|
return "BAD";
|
|
}
|
|
|
|
uint32_t RGBFusion2USBController::EncodeCalibrationBuffer(const std::string& rgb_order)
|
|
{
|
|
if(rgb_order.empty())
|
|
{
|
|
return 0u;
|
|
}
|
|
|
|
std::string key = rgb_order;
|
|
std::transform(key.begin(), key.end(), key.begin(),
|
|
[](unsigned char c){ return char(std::toupper(c)); });
|
|
|
|
if(key=="OFF" || key=="0")
|
|
{
|
|
return 0u;
|
|
}
|
|
|
|
RGBCalibration::const_iterator it = GigabyteCalibrationsLookup.find(key);
|
|
if(it == GigabyteCalibrationsLookup.end())
|
|
{
|
|
return 0u;
|
|
}
|
|
|
|
const RGBA &rgb_cal = it->second;
|
|
return (uint32_t(rgb_cal.raw[0]))
|
|
| (uint32_t(rgb_cal.raw[1]) << 8)
|
|
| (uint32_t(rgb_cal.raw[2]) << 16)
|
|
| (uint32_t(rgb_cal.raw[3]) << 24);
|
|
}
|
|
|
|
|
|
EncodedCalibration RGBFusion2USBController::GetCalibration(bool refresh_from_hw)
|
|
{
|
|
if(refresh_from_hw || !report_loaded || (product_id == 0x5711 && !cali_loaded))
|
|
{
|
|
if(!RefreshHardwareInfo())
|
|
{
|
|
return EncodedCalibration{};
|
|
}
|
|
}
|
|
|
|
EncodedCalibration out{};
|
|
out.dled[0] = DecodeCalibrationBuffer(cal_data.dled[0]);
|
|
out.dled[1] = DecodeCalibrationBuffer(cal_data.dled[1]);
|
|
out.spare[0] = DecodeCalibrationBuffer(cal_data.spare[0]);
|
|
out.spare[1] = DecodeCalibrationBuffer(cal_data.spare[1]);
|
|
out.mainboard = DecodeCalibrationBuffer(cal_data.mainboard);
|
|
|
|
if(product_id == 0x5711)
|
|
{
|
|
out.dled[2] = DecodeCalibrationBuffer(cal_data.dled[2]);
|
|
out.dled[3] = DecodeCalibrationBuffer(cal_data.dled[3]);
|
|
out.spare[2] = DecodeCalibrationBuffer(cal_data.spare[2]);
|
|
out.spare[3] = DecodeCalibrationBuffer(cal_data.spare[3]);
|
|
}
|
|
else
|
|
{
|
|
out.dled[2] = "OFF";
|
|
out.dled[3] = "OFF";
|
|
out.spare[2] = "OFF";
|
|
out.spare[3] = "OFF";
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
bool RGBFusion2USBController::SetCalibration(const EncodedCalibration& cal, bool refresh_from_hw)
|
|
{
|
|
if(refresh_from_hw)
|
|
{
|
|
if(!RefreshHardwareInfo())
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if(EncodeCalibrationBuffer(cal.dled[0]) == cal_data.dled[0]
|
|
&& EncodeCalibrationBuffer(cal.dled[1]) == cal_data.dled[1]
|
|
&& EncodeCalibrationBuffer(cal.mainboard) == cal_data.mainboard
|
|
&& EncodeCalibrationBuffer(cal.spare[0]) == cal_data.spare[0]
|
|
&& EncodeCalibrationBuffer(cal.spare[1]) == cal_data.spare[1]
|
|
&& (product_id != 0x5711
|
|
|| (EncodeCalibrationBuffer(cal.dled[2]) == cal_data.dled[2]
|
|
&& EncodeCalibrationBuffer(cal.dled[3]) == cal_data.dled[3]
|
|
&& EncodeCalibrationBuffer(cal.spare[2]) == cal_data.spare[2]
|
|
&& EncodeCalibrationBuffer(cal.spare[3]) == cal_data.spare[3])))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
CMD_0x33 desired{};
|
|
std::memset(&desired, 0, sizeof(desired));
|
|
desired.report_id = report_id;
|
|
desired.command_id = 0x33;
|
|
|
|
desired.d_strip_c0 = EncodeCalibrationBuffer(cal.dled[0]);
|
|
desired.d_strip_c1 = EncodeCalibrationBuffer(cal.dled[1]);
|
|
desired.rgb_cali = EncodeCalibrationBuffer(cal.mainboard);
|
|
desired.c_spare0 = EncodeCalibrationBuffer(cal.spare[0]);
|
|
desired.c_spare1 = EncodeCalibrationBuffer(cal.spare[1]);
|
|
|
|
if(product_id == 0x5711)
|
|
{
|
|
desired.d_strip_c2 = EncodeCalibrationBuffer(cal.dled[2]);
|
|
desired.d_strip_c3 = EncodeCalibrationBuffer(cal.dled[3]);
|
|
desired.c_spare2 = EncodeCalibrationBuffer(cal.spare[2]);
|
|
desired.c_spare3 = EncodeCalibrationBuffer(cal.spare[3]);
|
|
}
|
|
|
|
std::memset(desired.reserved, 0, sizeof(desired.reserved));
|
|
int rc = SendPacket(reinterpret_cast<unsigned char*>(&desired));
|
|
if(rc < 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
ResetController();
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
|
SaveCalState();
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
|
|
|
cal_data.dled[0] = desired.d_strip_c0;
|
|
cal_data.dled[1] = desired.d_strip_c1;
|
|
cal_data.mainboard = desired.rgb_cali;
|
|
cal_data.spare[0] = desired.c_spare0;
|
|
cal_data.spare[1] = desired.c_spare1;
|
|
|
|
if(product_id == 0x5711)
|
|
{
|
|
cal_data.dled[2] = desired.d_strip_c2;
|
|
cal_data.dled[3] = desired.d_strip_c3;
|
|
cal_data.spare[2] = desired.c_spare2;
|
|
cal_data.spare[3] = desired.c_spare3;
|
|
}
|
|
else
|
|
{
|
|
cal_data.dled[2] = 0u;
|
|
cal_data.dled[3] = 0u;
|
|
cal_data.spare[2] = 0u;
|
|
cal_data.spare[3] = 0u;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void RGBFusion2USBController::SetLedCount(unsigned int c0, unsigned int c1, unsigned int c2, unsigned int c3)
|
|
{
|
|
new_d1 = LedCountToEnum(c0);
|
|
new_d2 = LedCountToEnum(c1);
|
|
new_d3 = LedCountToEnum(c2);
|
|
new_d4 = LedCountToEnum(c3);
|
|
|
|
if(new_d1 == D_LED1_count && new_d2 == D_LED2_count && new_d3 == D_LED3_count && new_d4 == D_LED4_count)
|
|
{
|
|
return;
|
|
}
|
|
|
|
D_LED1_count = new_d1;
|
|
D_LED2_count = new_d2;
|
|
D_LED3_count = new_d3;
|
|
D_LED4_count = new_d4;
|
|
|
|
unsigned char buffer[64] = { 0 };
|
|
buffer[0] = report_id;
|
|
buffer[1] = 0x34;
|
|
buffer[2] = (new_d2 << 4) | new_d1;
|
|
buffer[3] = (new_d4 << 4) | new_d3;
|
|
SendPacket(buffer);
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Switch ARGB header mode (single/addressable) |
|
|
\*---------------------------------------------------------*/
|
|
bool RGBFusion2USBController::SetStripBuiltinEffectState(int hdr, bool enable)
|
|
{
|
|
static bool first_call = true;
|
|
int bitmask = 0;
|
|
|
|
if(hdr == -1)
|
|
{
|
|
bitmask = 0x01 | 0x02 | 0x08 | 0x10;
|
|
}
|
|
else
|
|
{
|
|
switch(hdr)
|
|
{
|
|
case LED4:
|
|
case HDR_D_LED2:
|
|
case HDR_D_LED2_RGB:
|
|
bitmask = 0x02;
|
|
break;
|
|
case HDR_D_LED3:
|
|
case HDR_D_LED3_RGB:
|
|
bitmask = 0x08;
|
|
break;
|
|
case HDR_D_LED4:
|
|
case HDR_D_LED4_RGB:
|
|
bitmask = 0x10;
|
|
break;
|
|
default:
|
|
bitmask = 0x01;
|
|
break;
|
|
}
|
|
}
|
|
|
|
int new_effect_disabled = enable
|
|
? (effect_disabled & ~bitmask)
|
|
: (effect_disabled | bitmask);
|
|
|
|
if(!first_call && new_effect_disabled == effect_disabled)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
first_call = false;
|
|
effect_disabled = new_effect_disabled;
|
|
int res = SendPacket(0x32, effect_disabled);
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
return res;
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Persist LED config data |
|
|
\*---------------------------------------------------------*/
|
|
bool RGBFusion2USBController::SaveLEDState(bool e)
|
|
{
|
|
return SendPacket(0x47, e ? 1 : 0);
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Persist calibration |
|
|
\*---------------------------------------------------------*/
|
|
bool RGBFusion2USBController::SaveCalState()
|
|
{
|
|
return SendPacket(0x5E, 0);
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Set beat mode (hardware audio sync mode) |
|
|
\*---------------------------------------------------------*/
|
|
bool RGBFusion2USBController::EnableBeat(bool e)
|
|
{
|
|
return SendPacket(0x31, e ? 1 : 0);
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Set Lamp Array mode (MSDL) |
|
|
\*---------------------------------------------------------*/
|
|
bool RGBFusion2USBController::EnableLampArray(bool enable)
|
|
{
|
|
return SendPacket(0x48, enable ? 1 : 0);
|
|
}
|
|
|
|
std::string RGBFusion2USBController::GetDeviceName()
|
|
{
|
|
return(name);
|
|
}
|
|
|
|
std::string RGBFusion2USBController::GetDeviceDescription()
|
|
{
|
|
return(description);
|
|
}
|
|
|
|
std::string RGBFusion2USBController::GetFWVersion()
|
|
{
|
|
return(version);
|
|
}
|
|
|
|
std::string RGBFusion2USBController::GetDeviceLocation()
|
|
{
|
|
return("HID: " + location);
|
|
}
|
|
|
|
std::string RGBFusion2USBController::GetSerial()
|
|
{
|
|
return(chip_id);
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| PID (controller feature support) |
|
|
\*---------------------------------------------------------*/
|
|
uint16_t RGBFusion2USBController::GetProductID()
|
|
{
|
|
return (product_id);
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Low level controller number (multi-controller) |
|
|
\*---------------------------------------------------------*/
|
|
uint8_t RGBFusion2USBController::GetDeviceNum()
|
|
{
|
|
return (device_num);
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Set ARGB strips (addressable) |
|
|
\*---------------------------------------------------------*/
|
|
void RGBFusion2USBController::SetStripColors(unsigned int hdr, RGBColor* colors, unsigned int num_colors, int single_led)
|
|
{
|
|
PktRGB pkt;
|
|
pkt.Init(hdr, report_id);
|
|
uint32_t byteorder;
|
|
|
|
switch(pkt.s.header)
|
|
{
|
|
case HDR_D_LED2_RGB:
|
|
byteorder = cal_data.dled[1];
|
|
break;
|
|
case HDR_D_LED3_RGB:
|
|
byteorder = cal_data.dled[2];
|
|
break;
|
|
case HDR_D_LED4_RGB:
|
|
byteorder = cal_data.dled[3];
|
|
break;
|
|
default:
|
|
byteorder = cal_data.dled[0];
|
|
break;
|
|
}
|
|
|
|
unsigned char bo_r = byteorder >> 16;
|
|
unsigned char bo_g = byteorder >> 8;
|
|
unsigned char bo_b = byteorder & 0xFF;
|
|
|
|
int res;
|
|
int leds_left = num_colors;
|
|
int sent_data = 0;
|
|
int k = 0;
|
|
int leds_in_pkt = sizeof(pkt.s.leds) / sizeof(*pkt.s.leds); /* 19 */
|
|
|
|
if(single_led > -1)
|
|
{
|
|
leds_left = 1;
|
|
k = single_led;
|
|
sent_data = k * 3;
|
|
leds_in_pkt = 1;
|
|
}
|
|
|
|
while(leds_left > 0)
|
|
{
|
|
leds_in_pkt = (std::min)(leds_in_pkt, leds_left);
|
|
leds_left -= leds_in_pkt;
|
|
|
|
pkt.s.bcount = leds_in_pkt * 3;
|
|
pkt.s.boffset = sent_data;
|
|
sent_data += pkt.s.bcount;
|
|
|
|
for(int i = 0; i < leds_in_pkt; i++)
|
|
{
|
|
RGBColor color = colors[k];
|
|
unsigned char red = RGBGetRValue(color);
|
|
unsigned char grn = RGBGetGValue(color);
|
|
unsigned char blu = RGBGetBValue(color);
|
|
|
|
pkt.buffer[5 + i * 3 + bo_r] = red;
|
|
pkt.buffer[5 + i * 3 + bo_g] = grn;
|
|
pkt.buffer[5 + i * 3 + bo_b] = blu;
|
|
k++;
|
|
}
|
|
|
|
res = SendPacket(pkt.buffer);
|
|
|
|
if(res < 0)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Set hardware effects (single) |
|
|
| Note: Effects paramters match that of gigabyte software. |
|
|
| -(2)Gigabyte breathe ranges are 400-1000ms in 100ms steps |
|
|
| and 1000-1600ms in 200ms steps |
|
|
| -(3)Gigabyte flash ranges are 600-2400ms in 200ms steps |
|
|
| -(4)Gigabyte color cycle ranges are 300-2400ms for period0|
|
|
| and 100-2200ms for period1 in 100ms steps. |
|
|
| the follow this trend between 300-1100/100-1000ms |
|
|
| then jump to 2400ms and 2200ms respective on speed 9. |
|
|
| -(6)Gigabyte Wave ranges are 30-300ms in steps following |
|
|
| the following formula. 2.5(s+1)^2 + 2.5(s+1) + 25. |
|
|
| -(15)Gigabyte dflash ranges are 800-2600ms in 200ms steps |
|
|
| -(3)(15)flash and dflash parameters were combined. |
|
|
\*---------------------------------------------------------*/
|
|
void RGBFusion2USBController::SetLEDEffect(int led, int mode, unsigned int speed, unsigned char brightness, bool random, unsigned char r, unsigned char g, unsigned char b)
|
|
{
|
|
PktEffect pkt;
|
|
pkt.Init(led, report_id, product_id);
|
|
if(led == -1)
|
|
{
|
|
effect_zone_mask = pkt.e.zone0;
|
|
}
|
|
else if((effect_zone_mask & pkt.e.zone0) == 0)
|
|
{
|
|
effect_zone_mask |= pkt.e.zone0;
|
|
}
|
|
pkt.e.max_brightness = brightness;
|
|
pkt.e.effect_type = mode;
|
|
pkt.e.color0 = r << 16 | g << 8 | b;
|
|
|
|
switch(mode)
|
|
{
|
|
case 2:
|
|
pkt.e.period0 = pkt.e.period1 = (speed <= 6) ? (400 + speed * 100) : (1000 + (speed - 6) * 200);
|
|
pkt.e.period2 = 200;
|
|
if(random)
|
|
{
|
|
pkt.e.effect_param0 = 7;
|
|
}
|
|
break;
|
|
case 15:
|
|
pkt.e.effect_type = 3;
|
|
pkt.e.effect_param1 = 1;
|
|
pkt.e.effect_param2 = 2;
|
|
case 3:
|
|
pkt.e.period0 = 100;
|
|
pkt.e.period1 = 100;
|
|
pkt.e.period2 = (speed * 200) + 700;
|
|
if(random)
|
|
{
|
|
pkt.e.effect_param0 = 7;
|
|
}
|
|
break;
|
|
case 4:
|
|
pkt.e.period0 = (speed * 100 + 300) + (speed > 8 ? 1300 * (speed - 8) : 0);
|
|
pkt.e.period1 = pkt.e.period0 -200;
|
|
pkt.e.effect_param0 = 7;
|
|
break;
|
|
case 6:
|
|
pkt.e.period0 = ((speed + 1)^2 + (speed + 1) + 10) * 5 / 2;
|
|
pkt.e.effect_param0 = 7;
|
|
pkt.e.effect_param1 = 1;
|
|
break;
|
|
case 8:
|
|
pkt.e.period0 = 100;
|
|
pkt.e.effect_param0 = 1;
|
|
pkt.e.effect_param1 = 5;
|
|
break;
|
|
case 9:
|
|
pkt.e.period0 = 1200;
|
|
pkt.e.period1 = 100;
|
|
pkt.e.period2 = 360;
|
|
pkt.e.period3 = 1200;
|
|
break;
|
|
case 10:
|
|
pkt.e.period0 = 200;
|
|
pkt.e.effect_param0 = 7;
|
|
break;
|
|
case 11:
|
|
pkt.e.period0 = 840;
|
|
pkt.e.period1 = 20;
|
|
pkt.e.period2 = 200;
|
|
pkt.e.period3 = 840;
|
|
break;
|
|
case 12:
|
|
pkt.e.period0 = 200;
|
|
pkt.e.effect_param0 = 7;
|
|
break;
|
|
}
|
|
SendPacket(pkt.buffer);
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Apply hardware effects (single) |
|
|
\*---------------------------------------------------------*/
|
|
bool RGBFusion2USBController::ApplyEffect(bool fast_apply)
|
|
{
|
|
if(fast_apply)
|
|
{
|
|
if(product_id == 0x5711)
|
|
{
|
|
return SendPacket(0x28, 0xFF, 0x07);
|
|
}
|
|
else
|
|
{
|
|
return SendPacket(0x28, 0xFF, 0x00);
|
|
}
|
|
}
|
|
|
|
PktEffectApply pkt = {};
|
|
pkt.a.zone_sel0 = effect_zone_mask;
|
|
|
|
effect_zone_mask = 0;
|
|
return SendPacket(pkt.buffer());
|
|
}
|
|
|
|
bool RGBFusion2USBController::SendPacket(uint8_t a, uint8_t b, uint8_t c)
|
|
{
|
|
unsigned char buffer[64] {};
|
|
|
|
buffer[0] = report_id;
|
|
buffer[1] = a;
|
|
buffer[2] = b;
|
|
buffer[3] = c;
|
|
|
|
return(SendPacket(buffer) == 64);
|
|
}
|
|
|
|
int RGBFusion2USBController::SendPacket(unsigned char* packet)
|
|
{
|
|
return hid_send_feature_report(dev, packet, 64);
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Reset controller parameters |
|
|
\*---------------------------------------------------------*/
|
|
void RGBFusion2USBController::ResetController()
|
|
{
|
|
for(uint8_t reg = 0x20; reg <= 0x27; ++reg)
|
|
{
|
|
SendPacket(reg, 0x00, 0x00);
|
|
}
|
|
|
|
if(product_id == 0x5711)
|
|
{
|
|
for(uint8_t reg = 0x90; reg <= 0x92; ++reg)
|
|
{
|
|
SendPacket(reg, 0x00, 0x00);
|
|
}
|
|
}
|
|
ApplyEffect(true);
|
|
} |