Files
OpenRGB/Controllers/CorsairPeripheralController/CorsairK55RGBPROXTController.cpp

288 lines
9.0 KiB
C++

/*--------------------------------------------*\
| CorsairK55RGBPROXTController.cpp |
| |
| Driver for Corsair K55 RGB PRO XT Keyboard |
\*--------------------------------------------*/
#include "CorsairK55RGBPROXTController.h"
#include "LogManager.h"
#define COLOR_BANK_SIZE 137
#define HID_PACKET_LENGTH 65
#define HID_PAYLOAD_SIZE1 (HID_PACKET_LENGTH - 12)
#define HID_PAYLOAD_SIZE2 (HID_PACKET_LENGTH - 4)
static const unsigned int keys[] =
{ 127, 128, 129, 130, 131, 132, 37, 49, 39, 53, 102, 101, 26, 96, 104, 54, 27, 16, 0, 25,
103, 55, 28, 22, 18, 23, 56, 29, 4, 3, 2, 57, 30, 17, 5, 21, 31, 58, 32, 19,
6, 1, 40, 59, 33, 24, 7, 60, 34, 20, 9, 13, 61, 35, 8, 10, 12, 14, 11, 50,
62, 41, 15, 47, 51, 107, 63, 42, 43, 48, 52, 118, 64, 38, 44, 46, 106, 97, 65, 36,
105, 66, 69, 72, 76, 67, 70, 73, 78, 77, 68, 71, 74, 75, 79, 91, 88, 85, 94, 80,
92, 89, 86, 81, 93, 90, 87, 95, 82, 83, 84 };
static unsigned char color_bank[3][COLOR_BANK_SIZE];
static const unsigned char filler[] =
{ 0x70, 0x6E, 0x4E, 0x4D, 0x4C, 0x65, 0x6F, 0x2C, 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x05,
0x19, 0x06, 0x1B, 0x1D, 0x64, 0x6A, 0x34, 0x6B, 0x6C, 0x69, 0x38, 0x37, 0x36, 0x10, 0x11, 0x16,
0x04, 0x39, 0x2F, 0x13, 0x12, 0x0C, 0x18, 0x33, 0x0F, 0x0E, 0x0D, 0x0B, 0x0A, 0x09, 0x07, 0x27,
0x7A, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1C, 0x17, 0x15, 0x08, 0x1A, 0x14, 0x2B, 0x2D,
0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x29, 0x1F, 0x1E, 0x35, 0x44, 0x43, 0x42, 0x41, 0x40, 0x62,
0x00, 0x5B, 0x5A, 0x59, 0x5E, 0x5D, 0x5C, 0x88, 0x87, 0x86, 0x85, 0x84, 0x83, 0x63, 0x53, 0x4F,
0x61, 0x60, 0x5F, 0x58, 0x57, 0x56, 0x55, 0x54, 0x2A, 0x2E, 0x28, 0x32, 0x30, 0x51, 0x50, 0x52,
0x6D };
CorsairK55RGBPROXTController::CorsairK55RGBPROXTController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
LightingControl();
}
CorsairK55RGBPROXTController::~CorsairK55RGBPROXTController()
{
hid_close(dev);
}
std::string CorsairK55RGBPROXTController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string CorsairK55RGBPROXTController::GetFirmwareString()
{
return "";
}
std::string CorsairK55RGBPROXTController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void CorsairK55RGBPROXTController::LightingControl()
{
unsigned char usb_buf[HID_PACKET_LENGTH];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = 0x03;
usb_buf[0x05] = 0x02;
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x02;
usb_buf[0x03] = 0x5F;
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x0D;
usb_buf[0x04] = 0x01;
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
}
void CorsairK55RGBPROXTController::SetLEDs(std::vector<RGBColor>colors)
{
for(std::size_t color_idx = 0; color_idx < colors.size(); ++color_idx)
{
RGBColor color = colors[color_idx];
color_bank[0][keys[color_idx]] = RGBGetRValue(color);
color_bank[1][keys[color_idx]] = RGBGetGValue(color);
color_bank[2][keys[color_idx]] = RGBGetBValue(color);
}
unsigned char* color_ptr = &color_bank[0][0];
unsigned char usb_buf[HID_PACKET_LENGTH];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x06;
usb_buf[0x04] = 0x9B;
usb_buf[0x05] = 0x01;
memcpy(&usb_buf[12], color_ptr, HID_PAYLOAD_SIZE1);
color_ptr += HID_PAYLOAD_SIZE1;
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
usb_buf[0x02] = 0x07;
for(std::size_t i = 0; i < 6; ++i)
{
memcpy(&usb_buf[4], color_ptr, HID_PAYLOAD_SIZE2);
color_ptr += HID_PAYLOAD_SIZE2;
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
}
}
void CorsairK55RGBPROXTController::SetHardwareMode
(
int mode_value,
unsigned int color_mode,
std::vector<RGBColor> colors,
unsigned int speed,
unsigned int direction
)
{
LightingControl();
unsigned char usb_buf[HID_PACKET_LENGTH];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x0D;
usb_buf[0x03] = 0x01;
usb_buf[0x04] = 0x61;
usb_buf[0x05] = 0x6D;
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x09;
usb_buf[0x03] = 0x01;
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x06;
usb_buf[0x03] = 0x01;
usb_buf[0x04] = 0x78;
usb_buf[0x08] = mode_value & 0x00FF;
usb_buf[0x09] = mode_value >> 8;
if(color_mode != MODE_COLORS_NONE)
{
usb_buf[0x0A] = color_mode == MODE_COLORS_RANDOM ? CORSAIR_HW_MODE_COLOR_RANDOM : CORSAIR_HW_MODE_COLOR_PREDEF;
}
if(mode_value == CORSAIR_HW_MODE_WATER_COLOR_VALUE)
{
usb_buf[0x0A] = CORSAIR_HW_MODE_COLOR_UNKNOWN;
}
usb_buf[0x0B] = speed;
if((mode_value == CORSAIR_HW_MODE_COLOR_WAVE_VALUE) ||
(mode_value == CORSAIR_HW_MODE_RAINBOW_WAVE_VALUE) ||
(mode_value == CORSAIR_HW_MODE_RAIN_VALUE) ||
(mode_value == CORSAIR_HW_MODE_SPIRAL_VALUE) ||
(mode_value == CORSAIR_HW_MODE_VISOR_VALUE))
{
switch(direction)
{
case MODE_DIRECTION_LEFT:
if(mode_value == CORSAIR_HW_MODE_SPIRAL_VALUE)
{
usb_buf[0x0C] = CORSAIE_HW_MODE_DIR_COUNTER_CLOCK_WISE;
}
else
{
usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_LEFT;
}
break;
case MODE_DIRECTION_RIGHT:
if(mode_value == CORSAIR_HW_MODE_SPIRAL_VALUE)
{
usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_CLOCK_WISE;
}
else
{
usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_RIGHT;
}
break;
case MODE_DIRECTION_UP:
usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_UP;
break;
case MODE_DIRECTION_DOWN:
usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_DOWN;
break;
default:
usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_NONE;
break;
}
}
int fill_dest_index = 0x0F;
int fill_src_index = 0x00;
if(usb_buf[0x0A] != CORSAIR_HW_MODE_COLOR_RANDOM)
{
usb_buf[0x0E] = (unsigned char)colors.size();
for(size_t i = 0; i < colors.size(); ++i)
{
usb_buf[0x0F + i * 4] = 0xFF;
usb_buf[0x10 + i * 4] = RGBGetBValue(colors[i]);
usb_buf[0x11 + i * 4] = RGBGetGValue(colors[i]);
usb_buf[0x12 + i * 4] = RGBGetRValue(colors[i]);
usb_buf[4] += 4;
fill_dest_index += 4;
}
}
memcpy(&usb_buf[fill_dest_index], &filler[fill_src_index], HID_PACKET_LENGTH - fill_dest_index);
fill_src_index += (HID_PACKET_LENGTH - fill_dest_index);
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x07;
usb_buf[0x03] = 0x01;
memcpy(&usb_buf[4], &filler[fill_src_index], HID_PACKET_LENGTH - 4);
fill_src_index += (HID_PACKET_LENGTH - 4);
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x07;
usb_buf[0x03] = 0x01;
memcpy(&usb_buf[4], &filler[fill_src_index], sizeof(filler) - fill_src_index);
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x05;
usb_buf[0x03] = 0x01;
usb_buf[0x04] = 0x01;
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
}
void CorsairK55RGBPROXTController::SwitchMode(bool software)
{
if(software)
{
LightingControl();
}
else
{
unsigned char usb_buf[HID_PACKET_LENGTH];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x00;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = 0x03;
usb_buf[0x05] = 0x01;
hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH);
}
}