/*-------------------------------------------*\ | SinowealthGMOWController.cpp | | | | Support for the Glorious Model O Wireless | | | | Matt Silva (thesilvanator) 05/2022 | \*-------------------------------------------*/ #include "SinowealthGMOWController.h" #include #include #include 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); }