/*-----------------------------------------*\ | SteelSeriesSenseiController.h | | | | Definitions and types for SteelSeries | | Sensei lighting controller | | Based on Rival controller by | | B Horn (bahorn) 13/5/2020 | \*-----------------------------------------*/ #include "SteelSeriesSenseiController.h" #include #include #include static void send_usb_msg(hid_device* dev, char * data_pkt, unsigned int size) { char* usb_pkt = new char[size + 1]; usb_pkt[0] = 0x00; for(unsigned int i = 1; i < size + 1; i++) { usb_pkt[i] = data_pkt[i-1]; } hid_write(dev, (unsigned char *)usb_pkt, size + 1); delete usb_pkt; } SteelSeriesSenseiController::SteelSeriesSenseiController ( hid_device* dev_handle, steelseries_type proto_type, const char* path ) { dev = dev_handle; location = path; proto = proto_type; } SteelSeriesSenseiController::~SteelSeriesSenseiController() { hid_close(dev); } std::string SteelSeriesSenseiController::GetDeviceLocation() { return("HID: " + location); } char* SteelSeriesSenseiController::GetDeviceName() { return device_name; } std::string SteelSeriesSenseiController::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); } steelseries_type SteelSeriesSenseiController::GetMouseType() { return proto; } /* Saves to the internal configuration */ void SteelSeriesSenseiController::Save() { /*-----------------------------------------------------*\ | Saves to the internal configuration | \*-----------------------------------------------------*/ char usb_buf[9]; /*-----------------------------------------------------*\ | Zero out buffer | \*-----------------------------------------------------*/ memset(usb_buf, 0x00, sizeof(usb_buf)); /*-----------------------------------------------------*\ | Set up Save packet | \*-----------------------------------------------------*/ usb_buf[0x00] = 0x59; /*-----------------------------------------------------*\ | Send packet | \*-----------------------------------------------------*/ send_usb_msg(dev, usb_buf, 9); } void SteelSeriesSenseiController::SetLightEffect ( unsigned char zone_id, unsigned char effect, unsigned char speed, unsigned char red, unsigned char green, unsigned char blue ) { char usb_buf[65]; /*-----------------------------------------------------*\ | Zero out buffer | \*-----------------------------------------------------*/ memset(usb_buf, 0x00, sizeof(usb_buf)); /*-----------------------------------------------------*\ | Set up Light Effect packet | \*-----------------------------------------------------*/ char dur1; char dur2; switch(effect) { case STEELSERIES_SENSEI_MODE_BREATHING: switch(speed) { case STEELSERIES_SENSEI_EFFECT_BREATHING_MIN: dur1 = 0x27; dur2 = 0x10; //10 sec cycle break; case STEELSERIES_SENSEI_EFFECT_BREATHING_MID: dur1 = 0x13; dur2 = 0x88; //5 sec cycle break; case STEELSERIES_SENSEI_EFFECT_BREATHING_MAX: dur1 = 0x09; dur2 = 0xc4; //2.5 sec cycle break; } usb_buf[0x00] = 0x5B; //command byte usb_buf[0x02] = zone_id; usb_buf[0x04] = dur1; //duration in ms 1st byte usb_buf[0x03] = dur2; //duration in ms 2nd byte usb_buf[0x1B] = 0x03; //Number of colors /*---------------------------------------------*\ | Original software duplicates these RGB bytes, | | but seems unnecessary | \*---------------------------------------------*/ usb_buf[0x1C] = red; usb_buf[0x1D] = green; usb_buf[0x1E] = blue; usb_buf[0x1F] = red; usb_buf[0x20] = green; usb_buf[0x21] = blue; usb_buf[0x26] = 0x7F; //percent of duration out of 0xFF usb_buf[0x27] = red; usb_buf[0x28] = green; usb_buf[0x29] = blue; usb_buf[0x2A] = 0x7F; //percent of duration out of 0xFF break; case STEELSERIES_SENSEI_MODE_RAINBOW: switch(speed) { case STEELSERIES_SENSEI_EFFECT_RAINBOW_MIN: dur1 = 0x4E; dur2 = 0x20; //20 sec cycle break; case STEELSERIES_SENSEI_EFFECT_RAINBOW_MID: dur1 = 0x27; dur2 = 0x10; //10 sec cycle break; case STEELSERIES_SENSEI_EFFECT_RAINBOW_MAX: dur1 = 0x13; dur2 = 0x88; //5 sec cycle break; } usb_buf[0x00] = 0x5B; //command byte usb_buf[0x02] = zone_id; usb_buf[0x04] = dur1; //duration in ms 1st byte usb_buf[0x03] = dur2; //duration in ms 2nd byte usb_buf[0x1B] = 0x07; //Number of colors /*---------------------------------------------*\ | Original software duplicates these RGB bytes, | | but seems unnecessary | \*---------------------------------------------*/ usb_buf[0x1C] = red; usb_buf[0x1D] = green; usb_buf[0x1E] = blue; usb_buf[0x1C] = 0xFF; usb_buf[0x1F] = 0xFF; usb_buf[0x22] = 0x14; usb_buf[0x23] = 0xFF; usb_buf[0x24] = 0xFF; usb_buf[0x26] = 0x2B; //percent of duration out of 0xFF usb_buf[0x28] = 0xFF; usb_buf[0x2A] = 0x2B; usb_buf[0x2C] = 0xFF; usb_buf[0x2D] = 0xFF; //percent of duration out of 0xFF usb_buf[0x2E] = 0x28; usb_buf[0x31] = 0xFF; usb_buf[0x32] = 0x2B; usb_buf[0x33] = 0xFF; usb_buf[0x35] = 0xFF; usb_buf[0x36] = 0x2B; usb_buf[0x37] = 0xFF; usb_buf[0x3A] = 0x14; break; } /*-----------------------------------------------------*\ | Send packet | \*-----------------------------------------------------*/ send_usb_msg(dev, usb_buf, sizeof(usb_buf)); } void SteelSeriesSenseiController::SetLightEffectAll ( unsigned char effect, unsigned char speed, unsigned char red, unsigned char green, unsigned char blue ) { SetLightEffect(0, effect, speed, red, green, blue); SetLightEffect(1, effect, speed, red, green, blue); } void SteelSeriesSenseiController::SetColor ( unsigned char zone_id, unsigned char red, unsigned char green, unsigned char blue ) { char usb_buf[65]; /*-----------------------------------------------------*\ | Zero out buffer | \*-----------------------------------------------------*/ memset(usb_buf, 0x00, sizeof(usb_buf)); /*-----------------------------------------------------*\ | Set up Set Color packet | \*-----------------------------------------------------*/ usb_buf[0x00] = 0x5B; //command byte usb_buf[0x02] = zone_id; /*-----------------------------------------------------*\ | Original software duplicates these RGB bytes, | | but seems unnecessary | \*-----------------------------------------------------*/ usb_buf[0x1C] = red; usb_buf[0x1D] = green; usb_buf[0x1E] = blue; usb_buf[0x1F] = red; usb_buf[0x20] = green; usb_buf[0x21] = blue; usb_buf[0x13] = 0x01; //Static color flag usb_buf[0x1B] = 0x01; //Number of colors /*-----------------------------------------------------*\ | Send packet | \*-----------------------------------------------------*/ send_usb_msg(dev, usb_buf, sizeof(usb_buf)); } void SteelSeriesSenseiController::SetColorAll ( unsigned char red, unsigned char green, unsigned char blue ) { SetColor(0, red, green, blue); SetColor(1, red, green, blue); }