mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-27 01:07:49 -05:00
192 lines
6.4 KiB
C++
192 lines
6.4 KiB
C++
/*---------------------------------------------------------*\
|
|
| HyperXAlloyOriginsCoreController.cpp |
|
|
| |
|
|
| Driver for HyperX Alloy Origins Core keyboard |
|
|
| |
|
|
| Volodymyr Nazarchuk (Vavooon) 28 Apr 2021 |
|
|
| Mike White (kamaaina) 09 Jun 2021 |
|
|
| carlos jordao 15 Mar 2025 |
|
|
| |
|
|
| This file is part of the OpenRGB project |
|
|
| SPDX-License-Identifier: GPL-2.0-or-later |
|
|
\*---------------------------------------------------------*/
|
|
|
|
#include <cstring>
|
|
#include "HyperXAlloyOriginsCoreController.h"
|
|
#include "StringUtils.h"
|
|
#include "LogManager.h"
|
|
|
|
|
|
HyperXAlloyOriginsCoreController::HyperXAlloyOriginsCoreController(hid_device* dev_handle, hid_device_info* dev_info, std::string dev_name)
|
|
{
|
|
dev = dev_handle;
|
|
location = dev_info->path;
|
|
name = dev_name;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Get the firmware version from the device info |
|
|
\*-----------------------------------------------------*/
|
|
char fw_version_buf[8];
|
|
memset(fw_version_buf, '\0', sizeof(fw_version_buf));
|
|
|
|
unsigned short version = dev_info->release_number;
|
|
snprintf(fw_version_buf, 8, "%.2X.%.2X", (version & 0xFF00) >> 8, version & 0x00FF);
|
|
|
|
firmware_version = fw_version_buf;
|
|
}
|
|
|
|
HyperXAlloyOriginsCoreController::~HyperXAlloyOriginsCoreController()
|
|
{
|
|
hid_close(dev);
|
|
}
|
|
|
|
std::string HyperXAlloyOriginsCoreController::GetDeviceLocation()
|
|
{
|
|
return("HID " + location);
|
|
}
|
|
|
|
std::string HyperXAlloyOriginsCoreController::GetNameString()
|
|
{
|
|
return(name);
|
|
}
|
|
|
|
std::string HyperXAlloyOriginsCoreController::GetSerialString()
|
|
{
|
|
wchar_t serial_string[128];
|
|
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
|
|
|
if(ret != 0)
|
|
{
|
|
return("");
|
|
}
|
|
|
|
return(StringUtils::wstring_to_string(serial_string));
|
|
}
|
|
|
|
std::string HyperXAlloyOriginsCoreController::GetFirmwareVersion()
|
|
{
|
|
return(firmware_version);
|
|
}
|
|
|
|
unsigned int HyperXAlloyOriginsCoreController::GetVariant()
|
|
{
|
|
unsigned char packet[65];
|
|
unsigned int variant = 0;
|
|
int actual = 0;
|
|
|
|
memset(packet, 0x00, sizeof(packet));
|
|
|
|
/*---------------------------------------*\
|
|
| Command 10 asks some data from keyboard |
|
|
| The answer looks like: |
|
|
| * command answer header (bytes 0-4) |
|
|
| * data length: byte 4 |
|
|
| * version (bytes 5-6) |
|
|
| * Product string (bytes 9-33) |
|
|
| * Layout variant (byte 56) |
|
|
\*---------------------------------------*/
|
|
packet[1] = 0x10;
|
|
hid_write(dev, packet, 65);
|
|
memset(packet, 0x00, sizeof(packet));
|
|
actual = hid_read(dev, packet, 65);
|
|
|
|
if(actual > 0)
|
|
variant = packet[56];
|
|
else
|
|
variant = 0;
|
|
|
|
LOG_DEBUG("[HyperX Alloy Origins Core] variant: 0x%02X", variant);
|
|
return variant;
|
|
}
|
|
|
|
|
|
void HyperXAlloyOriginsCoreController::SetBrightness(unsigned int brightness)
|
|
{
|
|
unsigned char packet[65];
|
|
memset(packet, 0x00, sizeof(packet));
|
|
|
|
packet[1] = 0xA7;
|
|
packet[4] = 0x01;
|
|
packet[5] = brightness;
|
|
|
|
hid_write(dev, packet, 65);
|
|
}
|
|
|
|
void HyperXAlloyOriginsCoreController::SetLEDsDirect(std::vector<led> leds, std::vector<RGBColor> colors)
|
|
{
|
|
/*------------------------------------------------------------------------------*\
|
|
| * Always send 380 bytes to the keyboard and a total of 94 led indexes. |
|
|
| The colors are grouped into segments of 48 bytes. |
|
|
| Each one is divided into: |
|
|
| 6 Green + 2 zeroes + 6 Green + 2 zeroes + |
|
|
| 6 Red + 2 zeroes + 6 Red + 2 zeroes + |
|
|
| 6 Blue + 2 zeroes + 6 Blue + 2 zeroes |
|
|
| \=---> sector 0 \=--> sector 1 |
|
|
| Every 6 colors form a sector. The names are arbitrary, just to make clear how |
|
|
| to set the colors into the buffer. |
|
|
| So each segment has 2 sectors and 12 colors. |
|
|
| The last 10 colors don't fill completely the last segment. |
|
|
| * All 94 colors can be sent even if some of them aren't used by the physical |
|
|
| keyboard. This allows to lit every key, even if not mapped directly. |
|
|
\*------------------------------------------------------------------------------*/
|
|
unsigned int segment = 0, sector = 0, sequence = 0;
|
|
unsigned int total_colors = 0;
|
|
memset(color_buf, 0x00, sizeof(color_buf));
|
|
|
|
/*---------------------------------------------------------------------------*\
|
|
| transfer the colors to the buffer. Max 94 colors to avoid buffer overflow. |
|
|
\*---------------------------------------------------------------------------*/
|
|
if(colors.size() > 94)
|
|
{
|
|
total_colors = 94;
|
|
}
|
|
else
|
|
{
|
|
total_colors = (unsigned int)colors.size();
|
|
}
|
|
|
|
unsigned int pos = 0, color_idx = 0;
|
|
for(unsigned int i = 0; i < total_colors; i++)
|
|
{
|
|
color_idx = leds[i].value;
|
|
segment = (color_idx / 12) * 48;
|
|
sector = ((color_idx / 6) & 1) * 8;
|
|
sequence = color_idx % 6;
|
|
|
|
pos = segment + sector + sequence;
|
|
|
|
color_buf[pos ] = RGBGetGValue(colors[i]);
|
|
color_buf[pos + 16] = RGBGetRValue(colors[i]);
|
|
color_buf[pos + 32] = RGBGetBValue(colors[i]);
|
|
}
|
|
}
|
|
|
|
|
|
void HyperXAlloyOriginsCoreController::SendRGBToDevice()
|
|
{
|
|
unsigned int sentBytes = 0;
|
|
unsigned int bytesToSend = sizeof(color_buf);
|
|
unsigned int payloadSize = 60;
|
|
unsigned int seq = 0;
|
|
|
|
while(sentBytes < bytesToSend)
|
|
{
|
|
if (bytesToSend - sentBytes < payloadSize)
|
|
{
|
|
payloadSize = bytesToSend - sentBytes;
|
|
}
|
|
|
|
unsigned char packet[65];
|
|
memset(packet, 0x00, sizeof(packet));
|
|
|
|
packet[1] = 0xA2;
|
|
packet[2] = seq++;
|
|
packet[4] = payloadSize;
|
|
|
|
memcpy(&packet[5], &color_buf[sentBytes], payloadSize);
|
|
hid_write(dev, packet, payloadSize + 5);
|
|
|
|
sentBytes += payloadSize;
|
|
}
|
|
}
|