From 612c809b75cb1e31ebb5783da24049ad7c1437d7 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 6 Dec 2022 10:38:39 +1100 Subject: [PATCH] Initial commit for the Logitech G633 to resolve #2911 * Adding the G633 PID to LogitechControllerDetect.cpp * Registering the detector for the common controller * Fixing the indexing swap issue for LogitechLightspeedController * Removing the `bright_cycle_swap` hack and using the queried effects index to set the mode.value for each mode --- .../LogitechControllerDetect.cpp | 2 + .../LogitechLightspeedController.cpp | 17 ++- .../LogitechLightspeedController.h | 33 ++--- .../LogitechProtocolCommon.cpp | 59 ++++---- .../LogitechProtocolCommon.h | 2 +- .../RGBController_LogitechLightspeed.cpp | 129 +++++++++++------- 6 files changed, 133 insertions(+), 109 deletions(-) diff --git a/Controllers/LogitechController/LogitechControllerDetect.cpp b/Controllers/LogitechController/LogitechControllerDetect.cpp index ce8e350d..60976088 100644 --- a/Controllers/LogitechController/LogitechControllerDetect.cpp +++ b/Controllers/LogitechController/LogitechControllerDetect.cpp @@ -99,6 +99,7 @@ using namespace std::chrono_literals; #define LOGITECH_G933_PID 0x0A5B #define LOGITECH_G935_PID 0x0A87 #define LOGITECH_G733_PID 0x0AB5 +#define LOGITECH_G633_PID 0X0A5C /*-----------------------------------------------------*\ | Unifying Device IDs (Including Lightspeed receivers) | @@ -905,5 +906,6 @@ REGISTER_HID_DETECTOR_IPU("Logitech G900 Wireless Gaming Mouse (wired)", REGISTER_HID_DETECTOR_IPU("Logitech G903 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G903_LIGHTSPEED_PID, 1, 0xFF00, 2); REGISTER_HID_DETECTOR_IPU("Logitech G903 Hero Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G903_LIGHTSPEED_HERO_PID, 1, 0xFF00, 2); REGISTER_HID_DETECTOR_IPU("Logitech G Pro Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G_PRO_WIRELESS_PID, 2, 0xFF00, 2); +REGISTER_HID_DETECTOR_IPU("Logitech G633 Gaming Headset", DetectLogitechWired, LOGITECH_VID, LOGITECH_G633_PID, 3, 0xFF43, 514); REGISTER_HID_DETECTOR_IPU("Logitech G733 Gaming Headset", DetectLogitechWired, LOGITECH_VID, LOGITECH_G733_PID, 3, 0xFF43, 514); REGISTER_HID_DETECTOR_IPU("Logitech G935 Gaming Headset", DetectLogitechWired, LOGITECH_VID, LOGITECH_G935_PID, 3, 0xFF43, 514); diff --git a/Controllers/LogitechController/LogitechLightspeedController.cpp b/Controllers/LogitechController/LogitechLightspeedController.cpp index 7b0d94ab..14856c7d 100644 --- a/Controllers/LogitechController/LogitechLightspeedController.cpp +++ b/Controllers/LogitechController/LogitechLightspeedController.cpp @@ -54,15 +54,14 @@ std::string LogitechLightspeedController::GetSerialString() void LogitechLightspeedController::SendMouseMode ( - unsigned char mode, - uint16_t speed, - unsigned char zone, - unsigned char red, - unsigned char green, - unsigned char blue, - unsigned char brightness, - bool bright_cycle_swap + uint8_t mode, + uint16_t speed, + uint8_t zone, + uint8_t red, + uint8_t green, + uint8_t blue, + uint8_t brightness ) { - lightspeed->setMode(mode, speed, zone, red, green, blue, brightness, bright_cycle_swap); + lightspeed->setMode(mode, speed, zone, red, green, blue, brightness); } diff --git a/Controllers/LogitechController/LogitechLightspeedController.h b/Controllers/LogitechController/LogitechLightspeedController.h index 0fbf33fa..1915cd66 100644 --- a/Controllers/LogitechController/LogitechLightspeedController.h +++ b/Controllers/LogitechController/LogitechLightspeedController.h @@ -1,5 +1,5 @@ /*-----------------------------------------*\ -| LogitechLightspeedController.h | +| LogitechLightspeedController.h | | | | Definitions and types for Logitech G | | Lightsync Wireless Gaming Mice lighting | @@ -19,20 +19,12 @@ #define LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN 0x01 #define LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX 0x64 -enum -{ - LOGITECH_G_PRO_WIRELESS_MODE_OFF = 0x00, - LOGITECH_G_PRO_WIRELESS_MODE_STATIC = 0x01, - LOGITECH_G_PRO_WIRELESS_MODE_CYCLE = 0x02, - LOGITECH_G_PRO_WIRELESS_MODE_BREATHING = 0x03, -}; - /*---------------------------------------------------------------------------------------------*\ | Speed is 1000 for fast and 20000 for slow. | | Values are multiplied by 100 later to give lots of GUI steps. | \*---------------------------------------------------------------------------------------------*/ enum -{ +{ LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST = 0xC8, /* Slowest speed */ LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL = 0x32, /* Normal speed */ LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST = 0x0A, /* Fastest speed */ @@ -45,21 +37,20 @@ public: ~LogitechLightspeedController(); logitech_device* lightspeed; - + std::string GetDeviceLocation(); std::string GetSerialString(); void SendMouseMode - ( - unsigned char mode, - uint16_t speed, - unsigned char zone, - unsigned char red, - unsigned char green, - unsigned char blue, - unsigned char brightness, - bool bright_cycle_swap - ); + ( + uint8_t mode, + uint16_t speed, + uint8_t zone, + uint8_t red, + uint8_t green, + uint8_t blue, + uint8_t brightness + ); private: hid_device* dev; diff --git a/Controllers/LogitechController/LogitechProtocolCommon.cpp b/Controllers/LogitechController/LogitechProtocolCommon.cpp index 05eb42f3..6f3c31b6 100644 --- a/Controllers/LogitechController/LogitechProtocolCommon.cpp +++ b/Controllers/LogitechController/LogitechProtocolCommon.cpp @@ -178,6 +178,7 @@ void logitech_device::initialiseDevice() { feature_list.emplace(*page, feature_index); RGB_feature_index = feature_index; + break; } } @@ -346,7 +347,7 @@ uint8_t logitech_device::getFeatureIndex(uint16_t feature_page) hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT); feature_index = response.data[0]; - + LOG_DEBUG("[%s] Feature Page %04X found @ index %02X - %02X %02X %02X %02X %02X %02X %02X %02X", device_name.c_str(), feature_page, feature_index, response.data[0], response.data[1], response.data[2], response.data[3], response.data[4], response.data[5], response.data[6], response.data[7]); } @@ -707,7 +708,7 @@ uint8_t logitech_device::setDirectMode(bool direct) return result; } -uint8_t logitech_device::setMode(uint8_t mode, uint16_t speed, uint8_t zone, uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness, bool bright_cycle_swap) +uint8_t logitech_device::setMode(uint8_t mode, uint16_t speed, uint8_t zone, uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness) { /*-----------------------------------------------------------------*\ | Check the usage map for usage2 (0x11 Long FAP Message) then | @@ -716,6 +717,7 @@ uint8_t logitech_device::setMode(uint8_t mode, uint16_t speed, uint8_t zone, uin hid_device* dev_use2 = getDevice(2); uint16_t feature_page = getFeaturePage(RGB_feature_index); int result = 0; + LOGITECH_DEVICE_MODE fx = leds[zone].fx[mode].mode; if(dev_use2) { @@ -738,31 +740,36 @@ uint8_t logitech_device::setMode(uint8_t mode, uint16_t speed, uint8_t zone, uin set_mode.data[4] = blue; speed *= 100; - if(mode == 1) //Static + switch(fx) { - set_mode.data[5] = 0x02; //zone; - //set_mode.data[12] = 0x01; //Save to flash testing - } - else if(mode == 2) //Spectrum Cycle - LOGITECH_DEVICE_LED_SPECTRUM - { - if(bright_cycle_swap) - { - set_mode.data[1] = 3; - } - set_mode.data[7] = speed >> 8; - set_mode.data[8] = speed & 0xFF; - set_mode.data[9] = brightness; - } - else if(mode == 3) //Breathing - LOGITECH_DEVICE_LED_BREATHING - { - if(bright_cycle_swap) - { - set_mode.data[1] = 2; - } - set_mode.data[5] = speed >> 8; - set_mode.data[6] = speed & 0xFF; - //set_mode.data[7] = curve_type; //Value 0-6: Default, Sine, Square, Triangle, Sawtooth, Reverse_Sawtooth, Exponent - set_mode.data[8] = brightness; + case LOGITECH_DEVICE_LED_ON: + set_mode.data[5] = 0x02; //zone; + //set_mode.data[12] = 0x01; //Save to flash testing + break; + + case LOGITECH_DEVICE_LED_SPECTRUM: + set_mode.data[7] = speed >> 8; + set_mode.data[8] = speed & 0xFF; + set_mode.data[9] = brightness; + break; + + case LOGITECH_DEVICE_LED_BREATHING: + set_mode.data[5] = speed >> 8; + set_mode.data[6] = speed & 0xFF; + //set_mode.data[7] = curve_type; //Value 0-6: Default, Sine, Square, Triangle, Sawtooth, Reverse_Sawtooth, Exponent + set_mode.data[8] = brightness; + break; + + /*-----------------------------------------------------*\ + | Place holders for later implementation | + \*-----------------------------------------------------*/ + case LOGITECH_DEVICE_LED_OFF: + case LOGITECH_DEVICE_LED_WAVE: + case LOGITECH_DEVICE_LED_STAR: + case LOGITECH_DEVICE_LED_RIPPLE: + case LOGITECH_DEVICE_LED_CUSTOM: + default: + break; } /*-----------------------------------------------------*\ diff --git a/Controllers/LogitechController/LogitechProtocolCommon.h b/Controllers/LogitechController/LogitechProtocolCommon.h index 01397afc..f6bc99fa 100644 --- a/Controllers/LogitechController/LogitechProtocolCommon.h +++ b/Controllers/LogitechController/LogitechProtocolCommon.h @@ -255,7 +255,7 @@ public: uint8_t getLED_count(); logitech_led getLED_info(uint8_t LED_num); uint8_t setDirectMode(bool direct); - uint8_t setMode(uint8_t mode, uint16_t speed, uint8_t zone, uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness, bool bright_cycle_swap); + uint8_t setMode(uint8_t mode, uint16_t speed, uint8_t zone, uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness); int getDeviceName(); private: std::map leds; diff --git a/Controllers/LogitechController/RGBController_LogitechLightspeed.cpp b/Controllers/LogitechController/RGBController_LogitechLightspeed.cpp index 45fe0f6f..ac3ad350 100644 --- a/Controllers/LogitechController/RGBController_LogitechLightspeed.cpp +++ b/Controllers/LogitechController/RGBController_LogitechLightspeed.cpp @@ -28,7 +28,7 @@ RGBController_LogitechLightspeed::RGBController_LogitechLightspeed(LogitechLight mode Off; Off.name = "Off"; - Off.value = LOGITECH_G_PRO_WIRELESS_MODE_OFF; + Off.value = LOGITECH_DEVICE_LED_OFF; Off.flags = 0; Off.color_mode = MODE_COLORS_NONE; modes.push_back(Off); @@ -64,48 +64,83 @@ RGBController_LogitechLightspeed::RGBController_LogitechLightspeed(LogitechLight LOG_INFO("Logitech device type not known: %i", controller->lightspeed->logitech_device_type); } - mode Direct; - Direct.name = "Direct"; - Direct.value = 0xFF; - Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; - Direct.color_mode = MODE_COLORS_PER_LED; - modes.push_back(Direct); + logitech_led fx = controller->lightspeed->getLED_info(0); - mode Static; - Static.name = "Static"; - Static.value = LOGITECH_G_PRO_WIRELESS_MODE_STATIC; - Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; - Static.color_mode = MODE_COLORS_PER_LED; - Static.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN; - Static.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; - Static.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; - modes.push_back(Static); + for(uint8_t i = 0; i < fx.fx.size(); i++) + { + /*---------------------------------------------------------*\ + | Logitech devices don't have a set order for effects and | + | each device needs to have the effect index mapped | + \*---------------------------------------------------------*/ + switch(fx.fx[i].mode) + { + case LOGITECH_DEVICE_LED_OFF: + /* Do nothing as it's already added */ + break; - mode Cycle; - Cycle.name = "Spectrum Cycle"; - Cycle.value = LOGITECH_G_PRO_WIRELESS_MODE_CYCLE; - Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; - Cycle.color_mode = MODE_COLORS_NONE; - Cycle.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN; - Cycle.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; - Cycle.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; - Cycle.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST; - Cycle.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST; - Cycle.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL; - modes.push_back(Cycle); + case LOGITECH_DEVICE_LED_ON: + { + mode Direct; + Direct.name = "Direct"; + Direct.value = i; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); - mode Breathing; - Breathing.name = "Breathing"; - Breathing.value = LOGITECH_G_PRO_WIRELESS_MODE_BREATHING; - Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; - Breathing.color_mode = MODE_COLORS_PER_LED; - Breathing.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN; - Breathing.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; - Breathing.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; - Breathing.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST; - Breathing.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST; - Breathing.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL; - modes.push_back(Breathing); + mode Static; + Static.name = "Static"; + Static.value = i; + Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Static.color_mode = MODE_COLORS_PER_LED; + Static.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN; + Static.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; + Static.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; + modes.push_back(Static); + LOG_DEBUG("[%s] Adding %s & %s modes at index - %02i", name.c_str(), Direct.name.c_str(), Static.name.c_str(), i); + break; + } + + case LOGITECH_DEVICE_LED_SPECTRUM: + { + mode Cycle; + Cycle.name = "Spectrum Cycle"; + Cycle.value = i; + Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; + Cycle.color_mode = MODE_COLORS_NONE; + Cycle.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN; + Cycle.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; + Cycle.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; + Cycle.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST; + Cycle.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST; + Cycle.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL; + modes.push_back(Cycle); + LOG_DEBUG("[%s] Adding %s mode at index - %02i", name.c_str(), Cycle.name.c_str(), i); + break; + } + + case LOGITECH_DEVICE_LED_BREATHING: + { + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = i; + Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; + Breathing.color_mode = MODE_COLORS_PER_LED; + Breathing.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN; + Breathing.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; + Breathing.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX; + Breathing.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST; + Breathing.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST; + Breathing.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL; + modes.push_back(Breathing); + LOG_DEBUG("[%s] Adding %s mode at index - %02i", name.c_str(), Breathing.name.c_str(), i); + break; + } + + default: + LOG_WARNING("[%s] Effect at index - %02i not added: Value %04X unrecognised", name.c_str(), i, fx.fx[i].mode); + break; + } + } SetupZones(); } @@ -190,17 +225,7 @@ void RGBController_LogitechLightspeed::UpdateZoneLEDs(int zone) unsigned char grn = RGBGetGValue(colors[zone]); unsigned char blu = RGBGetBValue(colors[zone]); - /*---------------------------------------------------------*\ - | Workaround for G502 mode breathing / spectrum cycle swap | - \*---------------------------------------------------------*/ - bool bright_cycle_swap = (pid == 0xC08B || pid == 0xC332 || pid == 0x0AB5 || pid == 0x0A87); - - /*---------------------------------------------------------*\ - | Replace direct mode with static when sending to controller| - \*---------------------------------------------------------*/ - unsigned char temp_mode = (modes[active_mode].value == 0xFF) ? LOGITECH_G_PRO_WIRELESS_MODE_STATIC : modes[active_mode].value; - - controller->SendMouseMode(temp_mode, modes[active_mode].speed, zone, red, grn, blu, modes[active_mode].brightness, bright_cycle_swap); + controller->SendMouseMode(modes[active_mode].value, modes[active_mode].speed, zone, red, grn, blu, modes[active_mode].brightness); } void RGBController_LogitechLightspeed::UpdateSingleLED(int led) @@ -215,6 +240,6 @@ void RGBController_LogitechLightspeed::DeviceUpdateMode() | mouse in direct mode. This code will only be called when | | we change modes as to not spam the device. | \*---------------------------------------------------------*/ - controller->lightspeed->setDirectMode(modes[active_mode].value == 0xFF); + controller->lightspeed->setDirectMode(modes[active_mode].name == "Direct"); DeviceUpdateLEDs(); }