mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2026-07-30 06:56:08 -04:00
285 lines
9.4 KiB
C++
285 lines
9.4 KiB
C++
/*---------------------------------------------------------*\
|
|
| SteelSeriesArctisNova3Controller.cpp |
|
|
| |
|
|
| Driver for SteelSeries Arctis Nova 3 |
|
|
| |
|
|
| Tomasz Gorczyca (eldiablo123) 18 Jul 2026 |
|
|
| |
|
|
| This file is part of the OpenRGB project |
|
|
| SPDX-License-Identifier: GPL-2.0-or-later |
|
|
\*---------------------------------------------------------*/
|
|
#include <string.h>
|
|
#include "SteelSeriesArctisNova3Controller.h"
|
|
#include "StringUtils.h"
|
|
|
|
SteelSeriesArctisNova3Controller::SteelSeriesArctisNova3Controller(hid_device* dev_handle, const hid_device_info& info, std::string dev_name)
|
|
{
|
|
dev = dev_handle;
|
|
location = info.path;
|
|
name = dev_name;
|
|
}
|
|
|
|
SteelSeriesArctisNova3Controller::~SteelSeriesArctisNova3Controller()
|
|
{
|
|
hid_close(dev);
|
|
}
|
|
|
|
std::string SteelSeriesArctisNova3Controller::GetDeviceLocation()
|
|
{
|
|
return("HID: " + location);
|
|
}
|
|
|
|
std::string SteelSeriesArctisNova3Controller::GetNameString()
|
|
{
|
|
return(name);
|
|
}
|
|
|
|
std::string SteelSeriesArctisNova3Controller::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));
|
|
}
|
|
|
|
void SteelSeriesArctisNova3Controller::SetSpeedBytes(unsigned char* usb_buf, unsigned char speed)
|
|
{
|
|
switch(speed)
|
|
{
|
|
case 1: usb_buf[0x0D] = 0x30; usb_buf[0x0E] = 0x75; break;
|
|
case 2: usb_buf[0x0D] = 0x2E; usb_buf[0x0E] = 0x68; break;
|
|
case 3: usb_buf[0x0D] = 0x2C; usb_buf[0x0E] = 0x5B; break;
|
|
case 4: usb_buf[0x0D] = 0x20; usb_buf[0x0E] = 0x4E; break;
|
|
case 5: usb_buf[0x0D] = 0x1E; usb_buf[0x0E] = 0x41; break;
|
|
case 6: usb_buf[0x0D] = 0x1C; usb_buf[0x0E] = 0x34; break;
|
|
case 7: usb_buf[0x0D] = 0x1A; usb_buf[0x0E] = 0x27; break;
|
|
case 8: usb_buf[0x0D] = 0x0E; usb_buf[0x0E] = 0x1A; break;
|
|
case 9: usb_buf[0x0D] = 0x0C; usb_buf[0x0E] = 0x0D; break;
|
|
case 10: usb_buf[0x0D] = 0x94; usb_buf[0x0E] = 0x02; break;
|
|
default: usb_buf[0x0D] = 0x0C; usb_buf[0x0E] = 0x0D; break;
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*\
|
|
| Select/enable packet (64 bytes): 06 A5 (01=left/02=right) (00/0A) |
|
|
\*---------------------------------------------------------------------*/
|
|
void SteelSeriesArctisNova3Controller::SelectZone(unsigned char zone_id, unsigned char state)
|
|
{
|
|
unsigned char usb_buf[ARCTIS_NOVA3_APPLY_REPORT_SIZE];
|
|
memset(usb_buf, 0x00, ARCTIS_NOVA3_APPLY_REPORT_SIZE);
|
|
|
|
usb_buf[0x00] = ARCTIS_NOVA3_REPORT_ID;
|
|
usb_buf[0x01] = 0xA5;
|
|
usb_buf[0x02] = (zone_id == 0) ? 0x02 : 0x01;
|
|
usb_buf[0x03] = state;
|
|
|
|
hid_write(dev, usb_buf, ARCTIS_NOVA3_APPLY_REPORT_SIZE);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*\
|
|
| Apply packet (64 bytes): 06 (A3=left/09=right) |
|
|
\*---------------------------------------------------------------------*/
|
|
void SteelSeriesArctisNova3Controller::ApplyZone(unsigned char zone_id)
|
|
{
|
|
unsigned char usb_buf[ARCTIS_NOVA3_APPLY_REPORT_SIZE];
|
|
memset(usb_buf, 0x00, ARCTIS_NOVA3_APPLY_REPORT_SIZE);
|
|
|
|
usb_buf[0x00] = ARCTIS_NOVA3_REPORT_ID;
|
|
usb_buf[0x01] = (zone_id == 0) ? 0x09 : 0xA3;
|
|
|
|
hid_write(dev, usb_buf, ARCTIS_NOVA3_APPLY_REPORT_SIZE);
|
|
}
|
|
|
|
void SteelSeriesArctisNova3Controller::SendEffectPacket(unsigned char* usb_buf)
|
|
{
|
|
hid_write(dev, usb_buf, ARCTIS_NOVA3_REPORT_SIZE);
|
|
}
|
|
|
|
void SteelSeriesArctisNova3Controller::SetOff(unsigned char zone_id)
|
|
{
|
|
SelectZone(zone_id, 0x00);
|
|
ApplyZone(zone_id);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*\
|
|
| Save |
|
|
\*---------------------------------------------------------------------*/
|
|
void SteelSeriesArctisNova3Controller::Save(unsigned char zone_id)
|
|
{
|
|
ApplyZone(zone_id);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*\
|
|
| Single Color / Direct |
|
|
\*---------------------------------------------------------------------*/
|
|
void SteelSeriesArctisNova3Controller::SetDirect(unsigned char zone_id, RGBColor color)
|
|
{
|
|
unsigned char usb_buf[ARCTIS_NOVA3_REPORT_SIZE];
|
|
memset(usb_buf, 0x00, ARCTIS_NOVA3_REPORT_SIZE);
|
|
|
|
usb_buf[0x00] = ARCTIS_NOVA3_REPORT_ID;
|
|
usb_buf[0x01] = 0xAA;
|
|
usb_buf[0x02] = (zone_id == 0) ? 0x01 : 0x00;
|
|
|
|
usb_buf[0x0D] = 0x98;
|
|
usb_buf[0x0E] = 0x3A;
|
|
|
|
usb_buf[0x15] = 0x55;
|
|
usb_buf[0x17] = 0x96;
|
|
|
|
usb_buf[0x1D] = 0x01;
|
|
|
|
usb_buf[0x25] = 0x02;
|
|
|
|
usb_buf[0x2D] = RGBGetRValue(color);
|
|
usb_buf[0x2E] = RGBGetGValue(color);
|
|
usb_buf[0x2F] = RGBGetBValue(color);
|
|
usb_buf[0x30] = 0xFF;
|
|
|
|
SendEffectPacket(usb_buf);
|
|
|
|
SelectZone(zone_id, 0x0A);
|
|
ApplyZone(zone_id);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*\
|
|
| Breathe |
|
|
\*---------------------------------------------------------------------*/
|
|
void SteelSeriesArctisNova3Controller::SetBreathe(unsigned char zone_id, RGBColor color, unsigned char speed)
|
|
{
|
|
unsigned char usb_buf[ARCTIS_NOVA3_REPORT_SIZE];
|
|
memset(usb_buf, 0x00, ARCTIS_NOVA3_REPORT_SIZE);
|
|
|
|
usb_buf[0x00] = ARCTIS_NOVA3_REPORT_ID;
|
|
usb_buf[0x01] = 0xAA;
|
|
usb_buf[0x02] = (zone_id == 0) ? 0x01 : 0x00;
|
|
|
|
SetSpeedBytes(usb_buf, speed);
|
|
|
|
usb_buf[0x15] = 0x55;
|
|
usb_buf[0x17] = 0x96;
|
|
|
|
usb_buf[0x25] = 0x03;
|
|
|
|
usb_buf[0x29] = RGBGetRValue(color);
|
|
usb_buf[0x2A] = RGBGetGValue(color);
|
|
usb_buf[0x2B] = RGBGetBValue(color);
|
|
|
|
usb_buf[0x30] = 0x7F;
|
|
usb_buf[0x31] = RGBGetRValue(color);
|
|
usb_buf[0x32] = RGBGetGValue(color);
|
|
usb_buf[0x33] = RGBGetBValue(color);
|
|
usb_buf[0x34] = 0x7F;
|
|
|
|
SendEffectPacket(usb_buf);
|
|
|
|
SelectZone(zone_id, 0x0A);
|
|
ApplyZone(zone_id);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*\
|
|
| Color Shift - Rainbow |
|
|
\*---------------------------------------------------------------------*/
|
|
void SteelSeriesArctisNova3Controller::SetColorShiftRainbow(unsigned char zone_id, unsigned char speed)
|
|
{
|
|
unsigned char usb_buf[ARCTIS_NOVA3_REPORT_SIZE];
|
|
memset(usb_buf, 0x00, ARCTIS_NOVA3_REPORT_SIZE);
|
|
|
|
usb_buf[0x00] = ARCTIS_NOVA3_REPORT_ID;
|
|
usb_buf[0x01] = 0xAA;
|
|
usb_buf[0x02] = (zone_id == 0) ? 0x01 : 0x00;
|
|
|
|
SetSpeedBytes(usb_buf, speed);
|
|
|
|
usb_buf[0x15] = 0x55;
|
|
usb_buf[0x17] = 0x96;
|
|
|
|
usb_buf[0x25] = 0x07;
|
|
|
|
static const unsigned char rainbow_stops[] =
|
|
{
|
|
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00,
|
|
0x2B, 0x00, 0xFF, 0x00, 0x2B, 0x00, 0xFF, 0xFF, 0x2B, 0x00,
|
|
0x00, 0xFF, 0x2B, 0xFF, 0x00, 0xFF, 0x2B, 0xFF, 0x00, 0x00,
|
|
0x26
|
|
};
|
|
|
|
memcpy(&usb_buf[0x26], rainbow_stops, sizeof(rainbow_stops));
|
|
|
|
SendEffectPacket(usb_buf);
|
|
|
|
SelectZone(zone_id, 0x0A);
|
|
ApplyZone(zone_id);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*\
|
|
| Color Shift - Heat Orange |
|
|
\*---------------------------------------------------------------------*/
|
|
void SteelSeriesArctisNova3Controller::SetColorShiftOrange(unsigned char zone_id, unsigned char speed)
|
|
{
|
|
unsigned char usb_buf[ARCTIS_NOVA3_REPORT_SIZE];
|
|
memset(usb_buf, 0x00, ARCTIS_NOVA3_REPORT_SIZE);
|
|
|
|
usb_buf[0x00] = ARCTIS_NOVA3_REPORT_ID;
|
|
usb_buf[0x01] = 0xAA;
|
|
usb_buf[0x02] = (zone_id == 0) ? 0x01 : 0x00;
|
|
|
|
SetSpeedBytes(usb_buf, speed);
|
|
|
|
usb_buf[0x15] = 0x55;
|
|
usb_buf[0x17] = 0x96;
|
|
|
|
usb_buf[0x25] = 0x03;
|
|
|
|
static const unsigned char orange_stops[] =
|
|
{
|
|
0xFF, 0xEA, 0x00, 0xFF, 0xEA, 0x00, 0x00, 0xFF, 0x4D, 0x00,
|
|
0x7F, 0xFF, 0xEA, 0x00, 0x7F
|
|
};
|
|
|
|
memcpy(&usb_buf[0x26], orange_stops, sizeof(orange_stops));
|
|
|
|
SendEffectPacket(usb_buf);
|
|
|
|
SelectZone(zone_id, 0x0A);
|
|
ApplyZone(zone_id);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*\
|
|
| Color Shift - Frost Blue |
|
|
\*---------------------------------------------------------------------*/
|
|
void SteelSeriesArctisNova3Controller::SetColorShiftBlue(unsigned char zone_id, unsigned char speed)
|
|
{
|
|
unsigned char usb_buf[ARCTIS_NOVA3_REPORT_SIZE];
|
|
memset(usb_buf, 0x00, ARCTIS_NOVA3_REPORT_SIZE);
|
|
|
|
usb_buf[0x00] = ARCTIS_NOVA3_REPORT_ID;
|
|
usb_buf[0x01] = 0xAA;
|
|
usb_buf[0x02] = (zone_id == 0) ? 0x01 : 0x00;
|
|
|
|
SetSpeedBytes(usb_buf, speed);
|
|
|
|
usb_buf[0x15] = 0x55;
|
|
usb_buf[0x17] = 0x96;
|
|
|
|
usb_buf[0x25] = 0x03;
|
|
|
|
static const unsigned char blue_stops[] =
|
|
{
|
|
0x8C, 0x00, 0xFF, 0x8C, 0x00, 0xFF, 0x00, 0x3B, 0xD1, 0xFF,
|
|
0x7F, 0x8C, 0x00, 0xFF, 0x7F
|
|
};
|
|
|
|
memcpy(&usb_buf[0x26], blue_stops, sizeof(blue_stops));
|
|
|
|
SendEffectPacket(usb_buf);
|
|
|
|
SelectZone(zone_id, 0x0A);
|
|
ApplyZone(zone_id);
|
|
}
|