Files
OpenRGB/Controllers/GigabyteAorusLaptopController/GigabyteAorusLaptopController.cpp
2024-04-29 19:57:57 -05:00

276 lines
10 KiB
C++

/*-----------------------------------------*\
| GigabyteAorusLaptopController.h |
| |
| Driver for Gigabyte Aorus Laptop |
| controller |
| |
| Guimard Morgan (morg) 06/05/2023 |
\*-----------------------------------------*/
#include "GigabyteAorusLaptopController.h"
#include <string.h>
#include <cmath>
/*---------------------------------------------------------*\
| Indexed colors mapping |
| blue 04 |
| green 02 |
| orange 05 |
| purple 06 |
| red 01 |
| white 07 |
| yellow 03 |
\*---------------------------------------------------------*/
static unsigned char argb_colour_index_data[2][2][2] =
{ //B0 B1
{ { 0x01, 0x04 }, //G0 R0
{ 0x02, 0x04 }, }, //G1 R0
{ { 0x01, 0x06 }, //G0 R1
{ 0x05, 0x07 }, } //G1 R1
};
GigabyteAorusLaptopController::GigabyteAorusLaptopController(hid_device* dev_handle, const hid_device_info& info)
{
dev = dev_handle;
location = info.path;
version = "";
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
serial_number = "";
}
else
{
std::wstring return_wstring = serial_string;
serial_number = std::string(return_wstring.begin(), return_wstring.end());
}
}
GigabyteAorusLaptopController::~GigabyteAorusLaptopController()
{
hid_close(dev);
}
std::string GigabyteAorusLaptopController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string GigabyteAorusLaptopController::GetSerialString()
{
return(serial_number);
}
std::string GigabyteAorusLaptopController::GetFirmwareVersion()
{
return(version);
}
void GigabyteAorusLaptopController::SetDirect(uint8_t brightness, RGBColor color)
{
/*---------------------------------------------------------*\
| Direct mode protocol |
| ID C R G B Br C Ch |
| 08 01 00 00 FF 32 00 C5 |
| |
| C = constant |
| RGB = color |
| Br= brightness |
| Ch = checksum: 0xFF - all bytes |
\*---------------------------------------------------------*/
unsigned char usb_buf[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1];
memset(usb_buf, 0x00, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1);
usb_buf[1] = GIGABYTE_AORUS_LAPTOP_REPORT_ID;
usb_buf[2] = 0x01;
usb_buf[3] = RGBGetRValue(color);
usb_buf[4] = RGBGetGValue(color);
usb_buf[5] = RGBGetBValue(color);
usb_buf[6] = brightness;
unsigned char checksum = 0xFF;
for(unsigned int i = 1; i < 8; i++)
{
checksum -= usb_buf[i];
}
usb_buf[8] = checksum;
hid_send_feature_report(dev, usb_buf, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1);
}
void GigabyteAorusLaptopController::SetMode(uint8_t mode_value, uint8_t speed, uint8_t brightness, uint8_t direction, RGBColor color)
{
/*---------------------------------------------------------*\
| Hardware mode protocol |
| ID C M Sp Br Cl Dr Ch |
| 08 00 01 08 32 01 00 XX |
| |
| C = constant |
| M = mode |
| Sp = speed |
| Br = brightness |
| Cl = Indexed color |
| Dr = Direction |
| Ch = checksum: 0xFF - all bytes |
\*---------------------------------------------------------*/
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
unsigned char indexed_color = GetColourIndex(red,grn,blu);
unsigned char usb_buf[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1];
memset(usb_buf, 0x00, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1);
usb_buf[1] = GIGABYTE_AORUS_LAPTOP_REPORT_ID; // report id
usb_buf[3] = mode_value; // mode value
usb_buf[4] = speed; // speed 0x01 -> 0x09
usb_buf[5] = brightness; // brightness 0x00 -> 0x32
usb_buf[6] = indexed_color; // color (red, orange, yellow, green, blue, purple, white)
usb_buf[7] = direction; // direction 0x01: right, 0x02 left, 0x03 up , 0x04 down
unsigned char checksum = 0xFF;
for(unsigned int i = 1; i < 8; i++)
{
checksum -= usb_buf[i];
}
usb_buf[8] = checksum; // checksum
hid_send_feature_report(dev, usb_buf, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1);
}
unsigned char GigabyteAorusLaptopController::GetColourIndex(unsigned char red, unsigned char green, unsigned char blue)
{
/*-----------------------------------------------------*\
| This device uses a limited colour pallette referenced |
| by an index |
| 0x01 red |
| 0x02 orange |
| 0x03 yellow |
| 0x04 green |
| 0x05 blue |
| 0x06 purple |
| 0x07 white |
\*-----------------------------------------------------*/
unsigned int divisor = GetLargestColour( red, green, blue);
unsigned int r = (int)round( red / divisor );
unsigned int g = (int)round( green / divisor );
unsigned int b = (int)round( blue / divisor );
unsigned char idx = argb_colour_index_data[r][g][b];
return idx;
}
unsigned int GigabyteAorusLaptopController::GetLargestColour(unsigned int red, unsigned int green, unsigned int blue)
{
unsigned int largest;
if ( red > green )
{
( red > blue ) ? largest = red : largest = blue;
}
else
{
( green > blue ) ? largest = green : largest = blue;
}
return (largest == 0) ? 1 : largest;
}
void GigabyteAorusLaptopController::SetCustom(std::vector<RGBColor> colors, std::vector<unsigned int> positions, unsigned char brightness)
{
/*---------------------------------------------------------*\
| Custom mode protocol |
| ID C M Sp Br Cl Dr Ch |
| 08 00 33 01 2D 05 01 90 |
| 92 00 00 00 00 00 00 6D -> |
| GET REPORT REQUEST <- |
| read 8x64 bytes <- |
| 12 00 00 08 00 00 00 E5 -> |
| 00 RR GG BB ..... -> data (8 * 64 bytes) |
\*---------------------------------------------------------*/
/*---------------------------------------------------------*\
| Sends mode packet |
\*---------------------------------------------------------*/
unsigned char usb_buf[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1];
memset(usb_buf, 0x00, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1);
usb_buf[1] = GIGABYTE_AORUS_LAPTOP_REPORT_ID;
usb_buf[3] = GIGABYTE_AORUS_LAPTOP_CUSTOM_MODE_VALUE;
usb_buf[4] = 0x01;
usb_buf[5] = brightness;
usb_buf[6] = 0x05;
usb_buf[7] = 0x01;
unsigned char checksum = 0xFF;
for(unsigned int i = 1; i < 8; i++)
{
checksum -= usb_buf[i];
}
usb_buf[8] = checksum;
hid_send_feature_report(dev, usb_buf, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1);
/*---------------------------------------------------------*\
| Sends first packet |
\*---------------------------------------------------------*/
unsigned char start_packet[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1] =
{
0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D
};
hid_send_feature_report(dev, start_packet, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1);
/*---------------------------------------------------------*\
| GET REPORT REQUEST |
\*---------------------------------------------------------*/
unsigned char report_packet[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1];
memset(report_packet, 0x00, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1);
report_packet[1] = GIGABYTE_AORUS_LAPTOP_REPORT_ID;
hid_get_feature_report(dev, report_packet, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1);
/*---------------------------------------------------------*\
| Sends 2nd packet |
\*---------------------------------------------------------*/
unsigned char second_packet[GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1] =
{
0x00, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xE5
};
hid_send_feature_report(dev, second_packet, GIGABYTE_AORUS_LAPTOP_REPORT_SIZE+1);
/*---------------------------------------------------------*\
| Creates the data packets |
\*---------------------------------------------------------*/
unsigned char color_data[64 * 8];
memset(color_data, 0x00, 64 * 8);
for(unsigned int i = 0; i < positions.size(); i++)
{
color_data[positions[i] * 4 + 1] = RGBGetRValue(colors[i]);
color_data[positions[i] * 4 + 2] = RGBGetGValue(colors[i]);
color_data[positions[i] * 4 + 3] = RGBGetBValue(colors[i]);
}
unsigned char color_buf[64 + 1];
color_buf[0] = 0;
for(unsigned int i = 0; i < 8; i++)
{
memcpy(&color_buf[1], &(color_data[64*i]), 64);
hid_write(dev, color_buf, 65);
}
}