Files
OpenRGB/Controllers/SinowealthController/SinowealthGMOWController.cpp

236 lines
6.9 KiB
C++

/*-------------------------------------------*\
| SinowealthGMOWController.cpp |
| |
| Support for the Glorious Model O Wireless |
| |
| Matt Silva (thesilvanator) 05/2022 |
\*-------------------------------------------*/
#include "SinowealthGMOWController.h"
#include <cstring>
#include <LogManager.h>
#include <iostream>
SinowealthGMOWController::SinowealthGMOWController(hid_device* dev_handle, char *_path, int _type)
{
dev = dev_handle;
location = _path;
memset(mode_packet,0x00, GMOW_PACKET_SIZE);
mode_packet[0x03] = 0x02;
mode_packet[0x05] = 0x02;
mode_packet[0x07] = 0x01;
mode_packet[0x08] = 0xFF;
memset(wired_packet,0x00, GMOW_PACKET_SIZE);
wired_packet[0x03] = 0x02;
wired_packet[0x04] = 0x02;
wired_packet[0x05] = 0x02;
wired_packet[0x06] = 0x02;
wired_packet[0x07] = 0x01;
memcpy(less_packet, wired_packet, GMOW_PACKET_SIZE);
less_packet[0x07] = 0x00;
type = _type;
}
SinowealthGMOWController::~SinowealthGMOWController()
{
hid_close(dev);
}
std::string SinowealthGMOWController::GetLocation()
{
return("HID: " + location);
}
std::string SinowealthGMOWController::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);
}
std::string SinowealthGMOWController::GetFirmwareVersion()
{
using namespace std::chrono_literals;
unsigned char buf_send[GMOW_PACKET_SIZE] = {0};
unsigned char buf_receive[GMOW_PACKET_SIZE] = {0};
if(type == GMOW_CABLE_CONNECTED)
{
buf_send[0x03] = 0x02;
}
buf_send[0x04] = 0x03;
buf_send[0x06] = 0x81;
hid_send_feature_report(dev,buf_send, GMOW_PACKET_SIZE);
std::this_thread::sleep_for(50ms);
hid_get_feature_report(dev,buf_receive,GMOW_PACKET_SIZE);
char str[128] = {0};
snprintf(str,128,"%d.%d.%d.%d", buf_receive[7],
buf_receive[8],
buf_receive[9],
buf_receive[10]);
return std::string(str);
}
void SinowealthGMOWController::SetMode(unsigned char mode,
unsigned char speed,
unsigned char wired_brightness,
unsigned char less_brightness,
RGBColor* color_buf,
unsigned char color_count)
{
using namespace std::chrono_literals;
unsigned char mode_buff[GMOW_PACKET_SIZE];
memcpy(mode_buff, mode_packet, GMOW_PACKET_SIZE);
mode_buff[0x09] = mode;
unsigned char wired_buff[GMOW_PACKET_SIZE];
memcpy(wired_buff, wired_packet, GMOW_PACKET_SIZE);
wired_buff[0x08] = wired_brightness;
unsigned char less_buff[GMOW_PACKET_SIZE];
memcpy(less_buff, less_packet, GMOW_PACKET_SIZE);
less_buff[0x08] = less_brightness;
switch (mode)
{
case GMOW_MODE_RAINBOW_WAVE:
mode_buff[0x04] = 0x05;
mode_buff[0x0B] = speed;
break;
case GMOW_MODE_SPECTRUM_CYCLE:
mode_buff[0x04] = 0x05;
mode_buff[0x0B] = speed;
mode_buff[0x0C] = 0xFF;
break;
case GMOW_MODE_CUSTOM_BREATHING:
{
mode_buff[0x04] = color_count * 3 + 5;
mode_buff[0x0B] = speed;
for(unsigned int i = 0; i < color_count; i++)
{
unsigned char r = (char)RGBGetRValue(color_buf[i]);
unsigned char g = (char)RGBGetGValue(color_buf[i]);
unsigned char b = (char)RGBGetBValue(color_buf[i]);
if(r == 0x00 && g == 0x00 && b == 0x00)
{
r = 0x01;
}
mode_buff[0x0C + 3*i + 0] = r;
mode_buff[0x0C + 3*i + 1] = g;
mode_buff[0x0C + 3*i + 2] = b;
}
}
break;
case GMOW_MODE_STATIC:
{
mode_buff[0x04] = 0x05;
mode_buff[0x0B] = 0x09; // rate is replaced with 9
unsigned char r = (char)RGBGetRValue(color_buf[0]);
unsigned char g = (char)RGBGetGValue(color_buf[0]);
unsigned char b = (char)RGBGetBValue(color_buf[0]);
if(r == 0 && g == 0 && b == 0)
{
r = 1;
}
mode_buff[0x0C] = r;
mode_buff[0x0D] = g;
mode_buff[0x0E] = b;
}
break;
case GMOW_MODE_BREATHING:
{
mode_buff[0x04] = 0x08;
mode_buff[0x0B] = speed;
unsigned char r = (char)RGBGetRValue(color_buf[0]);
unsigned char g = (char)RGBGetGValue(color_buf[0]);
unsigned char b = (char)RGBGetBValue(color_buf[0]);
if(r == 0 && g == 0 && b == 0)
{
r = 1;
}
mode_buff[0x0C] = r;
mode_buff[0x0D] = g;
mode_buff[0x0E] = b;
}
break;
case GMOW_MODE_TAIL:
mode_buff[0x04] = 0x05;
mode_buff[0x0B] = speed;
break;
case GMOW_MODE_RAVE:
{
mode_buff[0x04] = color_count * 3 + 5;
mode_buff[0x0B] = speed;
for(unsigned int i = 0; i < color_count; i++) {
unsigned char r = (char)RGBGetRValue(color_buf[i]);
unsigned char g = (char)RGBGetGValue(color_buf[i]);
unsigned char b = (char)RGBGetBValue(color_buf[i]);
if(r == 0 && g == 0 && b == 0)
{
r = 1;
}
mode_buff[0x0C + 3*i + 0] = r;
mode_buff[0x0C + 3*i + 1] = g;
mode_buff[0x0C + 3*i + 2] = b;
}
}
break;
case GMOW_MODE_WAVE:
mode_buff[0x04] = 0x05;
mode_buff[0x0B] = speed;
break;
case GMOW_MODE_OFF:
mode_buff[0x04] = 0x05;
mode_buff[0x0B] = 0x09;
break;
default:
break;
}
std::this_thread::sleep_for(50ms);
hid_send_feature_report(dev, mode_buff, GMOW_PACKET_SIZE);
std::this_thread::sleep_for(50ms);
hid_send_feature_report(dev, wired_buff, GMOW_PACKET_SIZE);
std::this_thread::sleep_for(50ms);
hid_send_feature_report(dev, less_buff, GMOW_PACKET_SIZE);
}