diff --git a/Controllers/RoccatController/RGBController_RoccatKoneAimo.cpp b/Controllers/RoccatController/RGBController_RoccatKoneAimo.cpp new file mode 100644 index 00000000..e9327cb2 --- /dev/null +++ b/Controllers/RoccatController/RGBController_RoccatKoneAimo.cpp @@ -0,0 +1,203 @@ +/*-----------------------------------------*\ +| RGBController_RoccatKoneAimo.cpp | +| | +| Generic RGB Interface for OpenRGB | +| | +| | +| Thibaud M (enlight3d) 17/11/2020 | +\*-----------------------------------------*/ + +#include "RGBController_RoccatKoneAimo.h" + +RGBController_RoccatKoneAimo::RGBController_RoccatKoneAimo(RoccatKoneAimoController* mouse_ptr) +{ + name = "Roccat Kone Aimo"; + type = DEVICE_TYPE_MOUSE; + description = "Roccat Kone Aimo Mouse"; + mouse = mouse_ptr; + location = mouse->GetLocation(); + serial = mouse->GetSerial(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = 0; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.speed_min = 0; + Direct.speed_max = 0; + Direct.speed = 0; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + active_mode = 0; + + SetupZones(); + +} + +void RGBController_RoccatKoneAimo::SetupZones() +{ + /*---------------------------------------------------------*\ + | Set up zones and leds per zone | + \*---------------------------------------------------------*/ + zone WHEEL_zone; + WHEEL_zone.name = "Scroll Wheel"; + WHEEL_zone.type = ZONE_TYPE_SINGLE; + WHEEL_zone.leds_min = 1; + WHEEL_zone.leds_max = 1; + WHEEL_zone.leds_count = 1; + WHEEL_zone.matrix_map = NULL; + zones.push_back(WHEEL_zone); + zones_channel.push_back(SCROLL_WHEEL); + + led WHEEL_led; + WHEEL_led.name = "Wheel LED"; + WHEEL_led.value = zones.size(); + leds.push_back(WHEEL_led); + leds_channel.push_back(SCROLL_WHEEL); + + zone STRIP_LEFT_zone; + STRIP_LEFT_zone.name = "Strip left"; + STRIP_LEFT_zone.type = ZONE_TYPE_LINEAR; + STRIP_LEFT_zone.leds_min = 4; + STRIP_LEFT_zone.leds_max = 4; + STRIP_LEFT_zone.leds_count = 4; + STRIP_LEFT_zone.matrix_map = NULL; + zones.push_back(STRIP_LEFT_zone); + zones_channel.push_back(STRIP_LEFT); + + for(std::size_t led_idx = 0; led_idx < STRIP_LEFT_zone.leds_max; led_idx++) + { + led STRIP_LEFT_led; + STRIP_LEFT_led.name = "Strip left LED " + std::to_string(led_idx + 1); + STRIP_LEFT_led.value = zones.size(); + leds.push_back(STRIP_LEFT_led); + leds_channel.push_back(STRIP_LEFT); + } + + zone STRIP_RIGHT_zone; + STRIP_RIGHT_zone.name = "Strip right"; + STRIP_RIGHT_zone.type = ZONE_TYPE_LINEAR; + STRIP_RIGHT_zone.leds_min = 4; + STRIP_RIGHT_zone.leds_max = 4; + STRIP_RIGHT_zone.leds_count = 4; + STRIP_RIGHT_zone.matrix_map = NULL; + zones.push_back(STRIP_RIGHT_zone); + zones_channel.push_back(STRIP_RIGHT); + + for(std::size_t led_idx = 0; led_idx < STRIP_RIGHT_zone.leds_max; led_idx++) + { + led STRIP_RIGHT_led; + STRIP_RIGHT_led.name = "Strip right LED " + std::to_string(led_idx + 1); + STRIP_RIGHT_led.value = zones.size(); + leds.push_back(STRIP_RIGHT_led); + leds_channel.push_back(STRIP_RIGHT); + } + + zone LOWER_LEFT_zone; + LOWER_LEFT_zone.name = "Lower left"; + LOWER_LEFT_zone.type = ZONE_TYPE_SINGLE; + LOWER_LEFT_zone.leds_min = 1; + LOWER_LEFT_zone.leds_max = 1; + LOWER_LEFT_zone.leds_count = 1; + LOWER_LEFT_zone.matrix_map = NULL; + zones.push_back(LOWER_LEFT_zone); + zones_channel.push_back(LOWER_LEFT); + + led LOWER_LEFT_led; + LOWER_LEFT_led.name = "Lower left LED"; + LOWER_LEFT_led.value = zones.size(); + leds.push_back(LOWER_LEFT_led); + leds_channel.push_back(LOWER_LEFT); + + zone LOWER_RIGHT_zone; + LOWER_RIGHT_zone.name = "Lower right"; + LOWER_RIGHT_zone.type = ZONE_TYPE_SINGLE; + LOWER_RIGHT_zone.leds_min = 1; + LOWER_RIGHT_zone.leds_max = 1; + LOWER_RIGHT_zone.leds_count = 1; + LOWER_RIGHT_zone.matrix_map = NULL; + zones.push_back(LOWER_RIGHT_zone); + zones_channel.push_back(LOWER_RIGHT); + + led LOWER_RIGHT_led; + LOWER_RIGHT_led.name = "Lower right LED"; + LOWER_RIGHT_led.value = zones.size(); + leds.push_back(LOWER_RIGHT_led); + leds_channel.push_back(LOWER_RIGHT); + + SetupColors(); + + /*---------------------------------------------------------*\ + | Initialize colors for each LED | + \*---------------------------------------------------------*/ + for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++) + { + unsigned char red = 0x00; + unsigned char grn = 0x00; + unsigned char blu = 0x00; + + colors[led_idx] = ToRGBColor(red, grn, blu); + } +} + +void RGBController_RoccatKoneAimo::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_RoccatKoneAimo::DeviceUpdateLEDs() +{ + /*---------------------------------------------------------*\ + | Set colors for all channel/leds | + \*---------------------------------------------------------*/ + for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++) + { + mouse->SetChannelColors(zones_channel[zone_idx], zones[zone_idx].colors, zones[zone_idx].leds_count); + } + /*---------------------------------------------------------*\ + | Apply new colors to the mouse | + \*---------------------------------------------------------*/ + mouse->SendUpdate(); +} + +void RGBController_RoccatKoneAimo::UpdateZoneLEDs(int zone_idx) +{ + /*---------------------------------------------------------*\ + | Set colors for one channel of leds | + \*---------------------------------------------------------*/ + mouse->SetChannelColors(zones_channel[zone_idx], zones[zone_idx].colors, zones[zone_idx].leds_count); + /*---------------------------------------------------------*\ + | Apply new colors to the mouse | + \*---------------------------------------------------------*/ + mouse->SendUpdate(); +} + +void RGBController_RoccatKoneAimo::UpdateSingleLED(int led_idx) +{ + /*---------------------------------------------------------*\ + | Get channel corresponding to led | + \*---------------------------------------------------------*/ + ROCCAT_KONE_AIMO_CHANNEL channel = leds_channel[led_idx]; + /*---------------------------------------------------------*\ + | Update channel corresponding to led | + \*---------------------------------------------------------*/ + mouse->SetChannelColors(channel, zones[leds[led_idx].value].colors, zones[leds[led_idx].value].leds_count); + /*---------------------------------------------------------*\ + | Apply new colors to the mouse | + \*---------------------------------------------------------*/ + mouse->SendUpdate(); +} + +void RGBController_RoccatKoneAimo::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_RoccatKoneAimo::DeviceUpdateMode() +{ + /*---------------------------------------------------------*\ + | This device does not support changing mode | + \*---------------------------------------------------------*/ +} diff --git a/Controllers/RoccatController/RGBController_RoccatKoneAimo.h b/Controllers/RoccatController/RGBController_RoccatKoneAimo.h new file mode 100644 index 00000000..1612bb2d --- /dev/null +++ b/Controllers/RoccatController/RGBController_RoccatKoneAimo.h @@ -0,0 +1,34 @@ +/*-----------------------------------------*\ +| RGBController_RoccatKoneAimo.h | +| | +| Generic RGB Interface for Roccat Kone | +| Aimo controller | +| | +| Thibaud M (enlight3d) 17/11/2020 | +\*-----------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "RoccatKoneAimoController.h" + +class RGBController_RoccatKoneAimo : public RGBController +{ +public: + RGBController_RoccatKoneAimo(RoccatKoneAimoController* mouse_ptr); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + RoccatKoneAimoController* mouse; + std::vector zones_channel; + std::vector leds_channel; +}; \ No newline at end of file diff --git a/Controllers/RoccatController/RoccatControllerDetect.cpp b/Controllers/RoccatController/RoccatControllerDetect.cpp new file mode 100644 index 00000000..bb6579ff --- /dev/null +++ b/Controllers/RoccatController/RoccatControllerDetect.cpp @@ -0,0 +1,75 @@ +/******************************************************************************************\ +* * +* DetectRoccatControllers * +* * +* Tests the USB address to see if a Roccat Kone Aimo controller exists there. * +* * +\******************************************************************************************/ + +#include "Detector.h" +#include "RoccatKoneAimoController.h" +#include "RGBController.h" +#include "RGBController_RoccatKoneAimo.h" +#include +#include + +#define ROCCAT_VID 0x1E7D +#define ROCCAT_KONE_AIMO_IFC 0 +#define ROCCAT_KONE_AIMO_U 0x0 +#define ROCCAT_KONE_AIMO_UP 0x0B +#define COUNT_ROCCATKONEAIMO_PIDS (sizeof(RoccatKoneAimo_pids) / sizeof(RoccatKoneAimo_pids[ 0 ])) + +static const unsigned short RoccatKoneAimo_pids[] = +{ + 0x2E2C, // Roccat Kone Aimo 16K + 0x2E27 // Roccat Kone Aimo +}; + +void DetectRoccatControllers(std::vector& rgb_controllers) +{ + hid_device_info* info; + hid_device* dev; + unsigned short tmpPID; + + if (hid_init() < 0) + { + return; + } + + for(unsigned int dev_idx = 0; dev_idx < COUNT_ROCCATKONEAIMO_PIDS; dev_idx++) + { + dev = NULL; + + tmpPID = RoccatKoneAimo_pids[dev_idx]; + info = hid_enumerate(ROCCAT_VID, tmpPID); + + while(info) + { + if((info->vendor_id == ROCCAT_VID) +#ifdef USE_HID_USAGE + &&(info->product_id == tmpPID) + &&(info->usage == ROCCAT_KONE_AIMO_U) //Usage and usage page required to get the correct interface + &&(info->usage_page == ROCCAT_KONE_AIMO_UP)) +#else + &&(info->interface_number == ROCCAT_KONE_AIMO_IFC) //Interface is only valid on Windows where there is > 1 interface + &&(info->product_id == tmpPID)) +#endif + { + dev = hid_open_path(info->path); + + if (dev) + { + RoccatKoneAimoController * controller = new RoccatKoneAimoController(dev, info->path); + RGBController_RoccatKoneAimo * rgb_controller = new RGBController_RoccatKoneAimo(controller); + rgb_controllers.push_back(rgb_controller); + } + } + info = info->next; + } + } + + hid_free_enumeration(info); + +} /* DetectRoccatControllers() */ + +REGISTER_DETECTOR("Roccat", DetectRoccatControllers); diff --git a/Controllers/RoccatController/RoccatKoneAimoController.h b/Controllers/RoccatController/RoccatKoneAimoController.h new file mode 100644 index 00000000..2b3d0b51 --- /dev/null +++ b/Controllers/RoccatController/RoccatKoneAimoController.h @@ -0,0 +1,57 @@ +/*-------------------------------------------------------------------*\ +| RoccatKoneAimoController.h | +| | +| Driver for Roccat Kone Aimo Mouse | +| | +| Thibaud M (enlight3d) 17th Nov 2020 | +| | +\*-------------------------------------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include +#include +#include +#include +#include + +#define NUM_LEDS 11 + +#define R_OFFSET 0 +#define G_OFFSET 1 +#define B_OFFSET 2 + +#define USB_COLOR_BUFF_LEN 46 + +enum ROCCAT_KONE_AIMO_CHANNEL +{ + SCROLL_WHEEL = 0, + STRIP_LEFT = 1, + STRIP_RIGHT = 5, + LOWER_LEFT = 9, + LOWER_RIGHT = 10 +}; + +class RoccatKoneAimoController +{ +public: + RoccatKoneAimoController(hid_device* dev_handle, char *_path); + ~RoccatKoneAimoController(); + + std::string GetDeviceName(); + std::string GetSerial(); + std::string GetLocation(); + + void SetChannelColors(ROCCAT_KONE_AIMO_CHANNEL channel, RGBColor * colors, unsigned int num_colors); + void SendUpdate(); + +private: + std::string device_name; + std::string serial; + std::string location; + hid_device* dev; + unsigned char usb_colors_buf[USB_COLOR_BUFF_LEN]; // USB buffer to be sent everytime we update mouse's LEDs + + void SendInit(); +}; \ No newline at end of file diff --git a/Controllers/RoccatController/RoccatKoneAimocontroller.cpp b/Controllers/RoccatController/RoccatKoneAimocontroller.cpp new file mode 100644 index 00000000..5d85e799 --- /dev/null +++ b/Controllers/RoccatController/RoccatKoneAimocontroller.cpp @@ -0,0 +1,114 @@ +/*-------------------------------------------------------------------*\ +| RoccatKoneAimoController.cpp | +| | +| Driver for Roccat Kone Aimo Mouse | +| | +| Thibaud M (enlight3d) 17th Nov 2020 | +| | +\*-------------------------------------------------------------------*/ + +#include "RoccatKoneAimoController.h" + +RoccatKoneAimoController::RoccatKoneAimoController(hid_device* dev_handle, char *_path) +{ + dev = dev_handle; + location = _path; + + const int szTemp = 256; + wchar_t tmpName[szTemp]; + + hid_get_manufacturer_string(dev, tmpName, szTemp); + std::wstring wName = std::wstring(tmpName); + device_name = std::string(wName.begin(), wName.end()); + + hid_get_product_string(dev, tmpName, szTemp); + wName = std::wstring(tmpName); + device_name.append(" ").append(std::string(wName.begin(), wName.end())); + + hid_get_serial_number_string(dev, tmpName, szTemp); + wName = std::wstring(tmpName); + serial = std::string(wName.begin(), wName.end()); + + /*-----------------------------------------------------*\ + | Init usb buffer to 0 and add first two bytes | + \*-----------------------------------------------------*/ + memset(usb_colors_buf, 0x00, USB_COLOR_BUFF_LEN); + usb_colors_buf[0x00] = 0x0D; + usb_colors_buf[0x01] = 0x2E; + + SendInit(); +} + +RoccatKoneAimoController::~RoccatKoneAimoController() +{ + hid_close(dev); +} + +std::string RoccatKoneAimoController::GetDeviceName() +{ + return device_name; +} + +std::string RoccatKoneAimoController::GetSerial() +{ + return serial; +} + +std::string RoccatKoneAimoController::GetLocation() +{ + return location; +} + +void RoccatKoneAimoController::SendInit() +{ + unsigned char usb_buf[6] = {00}; + + /*-----------------------------------------------------*\ + | Read first a packet from mouse (swarm does it) | + \*-----------------------------------------------------*/ + hid_get_feature_report(dev, usb_buf, 3); + + /*-----------------------------------------------------*\ + | Set up Init packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x0E; + usb_buf[0x01] = 0x06; + usb_buf[0x02] = 0x01; + usb_buf[0x03] = 0x01; + usb_buf[0x04] = 0x00; + usb_buf[0x05] = 0xFF; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, usb_buf, 6); +} + +void RoccatKoneAimoController::SetChannelColors(ROCCAT_KONE_AIMO_CHANNEL channel, RGBColor * colors, unsigned int num_colors) +{ + /*---------------------------------------------------------*\ + | Receiving update request for only one channel | + | and updating usb buffer to match colors | + \*---------------------------------------------------------*/ + for(unsigned char i = 0; i < num_colors; i++) + { + std::size_t color = channel + i; + int usb_idx = 0x02 + (color * 4); + + usb_colors_buf[usb_idx + R_OFFSET] = RGBGetRValue(colors[i]); + usb_colors_buf[usb_idx + G_OFFSET] = RGBGetGValue(colors[i]); + usb_colors_buf[usb_idx + B_OFFSET] = RGBGetBValue(colors[i]); + } +} + +void RoccatKoneAimoController::SendUpdate() +{ + /*-----------------------------------------------------*\ + | Send packet (whole buffer needs to be sent everytime) | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, usb_colors_buf, 46); + /*-----------------------------------------------------*\ + | Read a packet from mouse (swarm does it) | + \*-----------------------------------------------------*/ + hid_get_feature_report(dev, usb_colors_buf, 3); +} diff --git a/OpenRGB.pro b/OpenRGB.pro index 0be3b798..5acb8e1c 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -95,6 +95,7 @@ INCLUDEPATH += Controllers/PatriotViperController/ \ Controllers/PhilipsWizController/ \ Controllers/RedragonController/ \ + Controllers/RoccatController/ \ Controllers/SapphireGPUController/ \ Controllers/SinowealthController/ \ Controllers/SonyDS4Controller/ \ @@ -246,6 +247,8 @@ HEADERS += Controllers/RedragonController/RedragonM711Controller.h \ Controllers/RedragonController/RGBController_RedragonK556.h \ Controllers/RedragonController/RGBController_RedragonM711.h \ + Controllers/RoccatController/RGBController_RoccatKoneAimo.h \ + Controllers/RoccatController/RoccatKoneAimoController.h \ Controllers/SapphireGPUController/SapphireGPUController.h \ Controllers/SapphireGPUController/RGBController_SapphireGPU.h \ Controllers/SinowealthController/SinowealthController.h \ @@ -454,6 +457,9 @@ SOURCES += Controllers/RedragonController/RedragonControllerDetect.cpp \ Controllers/RedragonController/RGBController_RedragonK556.cpp \ Controllers/RedragonController/RGBController_RedragonM711.cpp \ + Controllers/RoccatController/RGBController_RoccatKoneAimo.cpp \ + Controllers/RoccatController/RoccatKoneAimoController.cpp \ + Controllers/RoccatController/RoccatControllerDetect.cpp \ Controllers/SapphireGPUController/SapphireGPUController.cpp \ Controllers/SapphireGPUController/SapphireGPUControllerDetect.cpp \ Controllers/SapphireGPUController/RGBController_SapphireGPU.cpp \