diff --git a/Controllers/RoccatController/RGBController_RoccatKonePro.cpp b/Controllers/RoccatController/RGBController_RoccatKonePro.cpp new file mode 100644 index 000000000..8856d4920 --- /dev/null +++ b/Controllers/RoccatController/RGBController_RoccatKonePro.cpp @@ -0,0 +1,186 @@ +/*---------------------------------------------*\ +| RGBController_RoccatKonePro.cpp | +| | +| RGB Controller for Roccat Kone Pro | +| | +| Garrett Denham (GardenOfWyers) 01/12/2024 | +\*---------------------------------------------*/ + +#include "RGBController_RoccatKonePro.h" + +/**------------------------------------------------------------------*\ + @name Roccat Kone Pro Mouse + @category Mouse + @type USB + @save :robot: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectRoccatKoneProControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_RoccatKonePro::RGBController_RoccatKonePro(RoccatKoneProController* controller_ptr) +{ + controller = controller_ptr; + + name = "Roccat Kone Pro"; + vendor = "Roccat"; + type = DEVICE_TYPE_MOUSE; + description = "Roccat Kone Pro Mouse"; + serial = controller->GetSerialString(); + location = controller->GetDeviceLocation(); + version = controller->GetFirmwareVersion(); + + // Also known as "Intelligent Lighting System" mode in Roccat Swarm + mode Direct; + Direct.name = "Direct"; + Direct.value = ROCCAT_KONE_PRO_DIRECT_MODE_VALUE; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + // Also known as "Fully Lit" mode in Roccat Swarm + mode Static; + Static.name = "Static"; + Static.value = ROCCAT_KONE_PRO_STATIC_MODE_VALUE; + Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS; + Static.color_mode = MODE_COLORS_MODE_SPECIFIC; + Static.brightness = ROCCAT_KONE_PRO_BRIGHTNESS_MAX; + Static.brightness_min = ROCCAT_KONE_PRO_BRIGHTNESS_MIN; + Static.brightness_max = ROCCAT_KONE_PRO_BRIGHTNESS_MAX; + Static.colors.resize(ROCCAT_KONE_PRO_LED_COUNT); + modes.push_back(Static); + + // Also known as "Wave" mode in Roccat Swarm + mode Rainbow; + Rainbow.name = "Rainbow"; + Rainbow.value = ROCCAT_KONE_PRO_WAVE_MODE_VALUE; + Rainbow.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + Rainbow.color_mode = MODE_COLORS_NONE; + Rainbow.brightness = ROCCAT_KONE_PRO_BRIGHTNESS_MAX; + Rainbow.brightness_min = ROCCAT_KONE_PRO_BRIGHTNESS_MIN; + Rainbow.brightness_max = ROCCAT_KONE_PRO_BRIGHTNESS_MAX; + Rainbow.speed = ROCCAT_KONE_PRO_SPEED_MID; + Rainbow.speed_min = ROCCAT_KONE_PRO_SPEED_MIN; + Rainbow.speed_max = ROCCAT_KONE_PRO_SPEED_MAX; + modes.push_back(Rainbow); + + mode Heartbeat; + Heartbeat.name = "Heartbeat"; + Heartbeat.value = ROCCAT_KONE_PRO_HEARTBEAT_MODE_VALUE; + Heartbeat.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + Heartbeat.color_mode = MODE_COLORS_MODE_SPECIFIC; + Heartbeat.brightness = ROCCAT_KONE_PRO_BRIGHTNESS_MAX; + Heartbeat.brightness_min = ROCCAT_KONE_PRO_BRIGHTNESS_MIN; + Heartbeat.brightness_max = ROCCAT_KONE_PRO_BRIGHTNESS_MAX; + Heartbeat.speed = ROCCAT_KONE_PRO_SPEED_MID; + Heartbeat.speed_min = ROCCAT_KONE_PRO_SPEED_MIN; + Heartbeat.speed_max = ROCCAT_KONE_PRO_SPEED_MAX; + Heartbeat.colors.resize(ROCCAT_KONE_PRO_LED_COUNT); + modes.push_back(Heartbeat); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = ROCCAT_KONE_PRO_BREATHING_MODE_VALUE; + Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + Breathing.brightness = ROCCAT_KONE_PRO_BRIGHTNESS_MAX; + Breathing.brightness_min = ROCCAT_KONE_PRO_BRIGHTNESS_MIN; + Breathing.brightness_max = ROCCAT_KONE_PRO_BRIGHTNESS_MAX; + Breathing.speed = ROCCAT_KONE_PRO_SPEED_MID; + Breathing.speed_min = ROCCAT_KONE_PRO_SPEED_MIN; + Breathing.speed_max = ROCCAT_KONE_PRO_SPEED_MAX; + Breathing.colors.resize(ROCCAT_KONE_PRO_LED_COUNT); + modes.push_back(Breathing); + + mode Blinking; + Blinking.name = "Blinking"; + Blinking.value = ROCCAT_KONE_PRO_BLINKING_MODE_VALUE; + Blinking.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED; + Blinking.color_mode = MODE_COLORS_MODE_SPECIFIC; + Blinking.brightness = ROCCAT_KONE_PRO_BRIGHTNESS_MAX; + Blinking.brightness_min = ROCCAT_KONE_PRO_BRIGHTNESS_MIN; + Blinking.brightness_max = ROCCAT_KONE_PRO_BRIGHTNESS_MAX; + Blinking.speed = ROCCAT_KONE_PRO_SPEED_MID; + Blinking.speed_min = ROCCAT_KONE_PRO_SPEED_MIN; + Blinking.speed_max = ROCCAT_KONE_PRO_SPEED_MAX; + Blinking.colors.resize(ROCCAT_KONE_PRO_LED_COUNT); + modes.push_back(Blinking); + + SetupZones(); +} + +RGBController_RoccatKonePro::~RGBController_RoccatKonePro() +{ + delete controller; +} + +void RGBController_RoccatKonePro::SetupZones() +{ + zone new_zone; + new_zone.name = "Mouse"; + new_zone.type = ZONE_TYPE_LINEAR; + new_zone.leds_min = ROCCAT_KONE_PRO_LED_COUNT; + new_zone.leds_max = ROCCAT_KONE_PRO_LED_COUNT; + new_zone.leds_count = ROCCAT_KONE_PRO_LED_COUNT; + new_zone.matrix_map = NULL; + zones.push_back(new_zone); + + std::string led_names[2] = + { + "Left Button", + "Right Button" + }; + + for(unsigned int i = 0; i < ROCCAT_KONE_PRO_LED_COUNT; i++) + { + led new_led; + new_led.name = led_names[i]; + leds.push_back(new_led); + } + + SetupColors(); +} + +void RGBController_RoccatKonePro::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_RoccatKonePro::DeviceUpdateLEDs() +{ + const mode& active = modes[active_mode]; + + if(active.value == ROCCAT_KONE_PRO_DIRECT_MODE_VALUE) + { + controller->SendDirect(colors); + } + else + { + controller->SetMode(active.colors, active.value, active.speed, active.brightness, active.color_mode, active.flags); + } +} + +void RGBController_RoccatKonePro::UpdateZoneLEDs(int /*zone_idx*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_RoccatKonePro::UpdateSingleLED(int /*led_idx*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_RoccatKonePro::DeviceUpdateMode() +{ + if(modes[active_mode].value == ROCCAT_KONE_PRO_DIRECT_MODE_VALUE) + { + controller->SetupDirectMode(); + } + else + { + DeviceUpdateLEDs(); + } +} diff --git a/Controllers/RoccatController/RGBController_RoccatKonePro.h b/Controllers/RoccatController/RGBController_RoccatKonePro.h new file mode 100644 index 000000000..12efaf72a --- /dev/null +++ b/Controllers/RoccatController/RGBController_RoccatKonePro.h @@ -0,0 +1,30 @@ +/*-------------------------------------------------------------------*\ +| RGBController_RoccatKonePro.h | +| | +| Driver for Roccat Kone Pro Mouse | +| | +| Garrett Denham (GardenOfWyers) 01/12/2024 | +\*-------------------------------------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "RoccatKoneProController.h" + +class RGBController_RoccatKonePro : public RGBController +{ +public: + RGBController_RoccatKonePro(RoccatKoneProController* controller_ptr); + ~RGBController_RoccatKonePro(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + RoccatKoneProController* controller; +}; diff --git a/Controllers/RoccatController/RoccatControllerDetect.cpp b/Controllers/RoccatController/RoccatControllerDetect.cpp index fb6b8d921..deb9b9260 100644 --- a/Controllers/RoccatController/RoccatControllerDetect.cpp +++ b/Controllers/RoccatController/RoccatControllerDetect.cpp @@ -2,6 +2,7 @@ #include "RoccatBurstController.h" #include "RoccatBurstProAirController.h" #include "RoccatKoneAimoController.h" +#include "RoccatKoneProController.h" #include "RoccatSenseAimoController.h" #include "RoccatVulcanKeyboardController.h" #include "RoccatKovaController.h" @@ -11,6 +12,7 @@ #include "RGBController_RoccatBurstProAir.h" #include "RGBController_RoccatHordeAimo.h" #include "RGBController_RoccatKoneAimo.h" +#include "RGBController_RoccatKonePro.h" #include "RGBController_RoccatSenseAimo.h" #include "RGBController_RoccatVulcanKeyboard.h" #include "RGBController_RoccatKova.h" @@ -34,6 +36,7 @@ #define ROCCAT_BURST_PRO_AIR_PID 0x2CA6 #define ROCCAT_KONE_AIMO_PID 0x2E27 #define ROCCAT_KONE_AIMO_16K_PID 0x2E2C +#define ROCCAT_KONE_PRO_PID 0x2C88 #define ROCCAT_KOVA_PID 0x2CEE /*-----------------------------------------------------------------*\ @@ -186,9 +189,22 @@ void DetectRoccatBurstProAirControllers(hid_device_info* info, const std::string if(dev) { - RoccatBurstProAirController * controller = new RoccatBurstProAirController(dev, *info); - RGBController_RoccatBurstProAir *rgb_controller = new RGBController_RoccatBurstProAir(controller); - rgb_controller->name = name; + RoccatBurstProAirController * controller = new RoccatBurstProAirController(dev, *info); + RGBController_RoccatBurstProAir * rgb_controller = new RGBController_RoccatBurstProAir(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +void DetectRoccatKoneProControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + RoccatKoneProController * controller = new RoccatKoneProController(dev, *info); + RGBController_RoccatKonePro * rgb_controller = new RGBController_RoccatKonePro(controller); + rgb_controller->name = name; ResourceManager::get()->RegisterRGBController(rgb_controller); } } @@ -255,6 +271,8 @@ REGISTER_HID_DETECTOR_IPU("Roccat Burst Pro Air", DetectRoccatBurstPro REGISTER_HID_DETECTOR_IPU("Roccat Kone Aimo", DetectRoccatMouseControllers, ROCCAT_VID, ROCCAT_KONE_AIMO_PID, 0, 0x0B, 0 ); REGISTER_HID_DETECTOR_IPU("Roccat Kone Aimo 16K", DetectRoccatMouseControllers, ROCCAT_VID, ROCCAT_KONE_AIMO_16K_PID, 0, 0x0B, 0 ); +REGISTER_HID_DETECTOR_IPU("Roccat Kone Pro", DetectRoccatKoneProControllers, ROCCAT_VID, ROCCAT_KONE_PRO_PID, 3, 0xFF01, 1 ); + REGISTER_HID_DETECTOR_IPU("Roccat Kova", DetectRoccatKovaControllers, ROCCAT_VID, ROCCAT_KOVA_PID, 0, 0x0B, 0 ); /*-----------------------------------------------------------------*\ @@ -267,4 +285,3 @@ REGISTER_HID_DETECTOR_IPU("Roccat Sense Aimo XXL", DetectRoccatSenseAim | HEADSETS | \*-----------------------------------------------------------------*/ REGISTER_HID_DETECTOR_IPU("Roccat Elo 7.1", DetectRoccatEloControllers, ROCCAT_VID, ROCCAT_ELO_PID, 3, 0x0C, 1 ); - diff --git a/Controllers/RoccatController/RoccatKoneProController.cpp b/Controllers/RoccatController/RoccatKoneProController.cpp new file mode 100644 index 000000000..534f9f42a --- /dev/null +++ b/Controllers/RoccatController/RoccatKoneProController.cpp @@ -0,0 +1,171 @@ +/*-------------------------------------------------------------------*\ +| RoccatKoneProController.cpp | +| | +| Driver for Roccat Kone Pro Mouse | +| | +| Garrett Denham (GardenOfWyers) 01/12/2024 | +\*-------------------------------------------------------------------*/ + +#include "RoccatKoneProController.h" + +#include + +RoccatKoneProController::RoccatKoneProController(hid_device* dev_handle, const hid_device_info& info) +{ + dev = dev_handle; + version = ""; + location = info.path; + + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + serial_number = ""; + } + else + { + std::wstring return_wstring = serial_string; + serial_number = std::string(return_wstring.begin(), return_wstring.end()); + } + + SetupDirectMode(); +} + +RoccatKoneProController::~RoccatKoneProController() +{ + hid_close(dev); +} + +std::string RoccatKoneProController::GetFirmwareVersion() +{ + return version; +} + +std::string RoccatKoneProController::GetSerialString() +{ + return serial_number; +} + +std::string RoccatKoneProController::GetDeviceLocation() +{ + return("HID: " + location); +} + +void RoccatKoneProController::SetupDirectMode() +{ + SwitchControl(true); +} + +void RoccatKoneProController::SwitchControl(bool direct) +{ + unsigned char usb_buf[ROCCAT_KONE_PRO_CONTROL_MODE_PACKET_LENGTH]; + + usb_buf[0x00] = 0x0E; + usb_buf[0x01] = 0x06; + usb_buf[0x02] = 0x01; + usb_buf[0x03] = direct ? 0x01 : 0x00; + usb_buf[0x04] = 0x00; + usb_buf[0x05] = 0xFF; + + hid_send_feature_report(dev, usb_buf, ROCCAT_KONE_PRO_CONTROL_MODE_PACKET_LENGTH); +} + +void RoccatKoneProController::SendDirect(std::vector colors) +{ + unsigned char usb_buf[ROCCAT_KONE_PRO_DIRECT_MODE_PACKET_LENGTH]; + + memset(usb_buf, 0x00, ROCCAT_KONE_PRO_DIRECT_MODE_PACKET_LENGTH); + + usb_buf[0x00] = ROCCAT_KONE_PRO_DIRECT_MODE_REPORT_ID; + usb_buf[0x01] = ROCCAT_KONE_PRO_DIRECT_MODE_BYTE; + + for(unsigned int i = 0; i < colors.size(); i++) + { + usb_buf[0x02 + 3 * i] = RGBGetRValue(colors[i]); + usb_buf[0x03 + 3 * i] = RGBGetGValue(colors[i]); + usb_buf[0x04 + 3 * i] = RGBGetBValue(colors[i]); + } + + hid_send_feature_report(dev, usb_buf, ROCCAT_KONE_PRO_DIRECT_MODE_PACKET_LENGTH); +} + +void RoccatKoneProController::SetMode(std::vector colors, unsigned char mode_value, unsigned char speed, unsigned char brightness, unsigned int color_mode, unsigned int mode_flags) +{ + /*---------------------------------------------------------*\ + | 1. Read from flash | + \*---------------------------------------------------------*/ + unsigned char usb_buf[ROCCAT_KONE_PRO_FLASH_PACKET_LENGTH]; + memset(usb_buf, 0x00, ROCCAT_KONE_PRO_FLASH_PACKET_LENGTH); + + hid_get_feature_report(dev, usb_buf, ROCCAT_KONE_PRO_FLASH_PACKET_LENGTH); + + /*---------------------------------------------------------*\ + | 2. Update needed bytes | + \*---------------------------------------------------------*/ + usb_buf[0x00] = 0x06; + usb_buf[0x01] = 0x45; + + usb_buf[0x03] = 0x06; + usb_buf[0x04] = 0x06; + usb_buf[0x05] = 0x1F; + + usb_buf[0x1E] = mode_value; + usb_buf[0x1F] = mode_flags & MODE_FLAG_HAS_SPEED ? speed : 0xFF; + usb_buf[0x20] = brightness; + + if(color_mode & MODE_COLORS_MODE_SPECIFIC) + { + for(unsigned int i = 0; i < colors.size(); i++) + { + usb_buf[0x24 + 5 * i] = 0x14; + usb_buf[0x25 + 5 * i] = 0xFF; + usb_buf[0x26 + 5 * i] = RGBGetRValue(colors[i]); + usb_buf[0x27 + 5 * i] = RGBGetGValue(colors[i]); + usb_buf[0x28 + 5 * i] = RGBGetBValue(colors[i]); + } + } + else if(color_mode & MODE_COLORS_NONE) + { + for(unsigned int i = 0; i < colors.size(); i++) + { + usb_buf[0x24 + 5 * i] = 0x14; + usb_buf[0x25 + 5 * i] = 0x00; + usb_buf[0x26 + 5 * i] = 0x00; + usb_buf[0x27 + 5 * i] = 0x00; + usb_buf[0x28 + 5 * i] = 0x00; + } + } + + usb_buf[0x2E] = 0x14; + usb_buf[0x2F] = 0xFF; + + unsigned int crc = CalculateCRC(&usb_buf[0x00]); + + usb_buf[0x43] = (unsigned char) crc; + usb_buf[0x44] = crc >> 8; + + /*---------------------------------------------------------*\ + | 3. Send to flash | + \*---------------------------------------------------------*/ + hid_send_feature_report(dev, usb_buf, ROCCAT_KONE_PRO_FLASH_PACKET_LENGTH); + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + /*---------------------------------------------------------*\ + | 4. Switch to built-in mode | + \*---------------------------------------------------------*/ + SwitchControl(false); +} + +unsigned int RoccatKoneProController::CalculateCRC(unsigned char* bytes) +{ + unsigned int crc = 0; + + for(unsigned int i = 0; i < ROCCAT_KONE_PRO_FLASH_PACKET_LENGTH - 2; i++) + { + crc += bytes[i]; + } + + return crc; +} diff --git a/Controllers/RoccatController/RoccatKoneProController.h b/Controllers/RoccatController/RoccatKoneProController.h new file mode 100644 index 000000000..622ba7481 --- /dev/null +++ b/Controllers/RoccatController/RoccatKoneProController.h @@ -0,0 +1,68 @@ +/*-------------------------------------------------------------------*\ +| RoccatKoneProController.h | +| | +| Driver for Roccat Kone Pro Mouse | +| | +| Garrett Denham (GardenOfWyers) 01/12/2024 | +\*-------------------------------------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include + +#define ROCCAT_KONE_PRO_CONTROL_MODE_PACKET_LENGTH 6 +#define ROCCAT_KONE_PRO_DIRECT_MODE_PACKET_LENGTH 11 +#define ROCCAT_KONE_PRO_FLASH_PACKET_LENGTH 69 +#define ROCCAT_KONE_PRO_FLASH_REPORT_ID 0x06 +#define ROCCAT_KONE_PRO_DIRECT_MODE_REPORT_ID 0x0D +#define ROCCAT_KONE_PRO_DIRECT_MODE_BYTE 0x0B +#define ROCCAT_KONE_PRO_LED_COUNT 2 + +enum +{ + ROCCAT_KONE_PRO_DIRECT_MODE_VALUE = 0x00, + ROCCAT_KONE_PRO_STATIC_MODE_VALUE = 0x01, + ROCCAT_KONE_PRO_WAVE_MODE_VALUE = 0x0A, + ROCCAT_KONE_PRO_HEARTBEAT_MODE_VALUE = 0x04, + ROCCAT_KONE_PRO_BREATHING_MODE_VALUE = 0x03, + ROCCAT_KONE_PRO_BLINKING_MODE_VALUE = 0x02 +}; + +enum +{ + ROCCAT_KONE_PRO_SPEED_MIN = 0x01, + ROCCAT_KONE_PRO_SPEED_MAX = 0x0B, + ROCCAT_KONE_PRO_SPEED_MID = (ROCCAT_KONE_PRO_SPEED_MAX - ROCCAT_KONE_PRO_SPEED_MIN) / 2, + ROCCAT_KONE_PRO_BRIGHTNESS_MIN = 0x00, + ROCCAT_KONE_PRO_BRIGHTNESS_MAX = 0xFF +}; + +class RoccatKoneProController +{ +public: + RoccatKoneProController(hid_device* dev_handle, const hid_device_info& info); + ~RoccatKoneProController(); + + std::string GetSerialString(); + std::string GetDeviceLocation(); + std::string GetFirmwareVersion(); + + void SetupDirectMode(); + void SendDirect(std::vector colors); + void SetMode(std::vector colors, + unsigned char mode_value, + unsigned char speed, + unsigned char brightness, + unsigned int color_mode, + unsigned int mode_flags + ); +private: + hid_device* dev; + std::string location; + std::string serial_number; + std::string version; + + unsigned int CalculateCRC(unsigned char* bytes); + void SwitchControl(bool direct); +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index b22109146..2375384ac 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -722,6 +722,7 @@ HEADERS += Controllers/RoccatController/RGBController_RoccatElo.h \ Controllers/RoccatController/RGBController_RoccatHordeAimo.h \ Controllers/RoccatController/RGBController_RoccatKoneAimo.h \ + Controllers/RoccatController/RGBController_RoccatKonePro.h \ Controllers/RoccatController/RGBController_RoccatKova.h \ Controllers/RoccatController/RGBController_RoccatSenseAimo.h \ Controllers/RoccatController/RGBController_RoccatVulcanKeyboard.h \ @@ -730,6 +731,7 @@ HEADERS += Controllers/RoccatController/RoccatEloController.h \ Controllers/RoccatController/RoccatHordeAimoController.h \ Controllers/RoccatController/RoccatKoneAimoController.h \ + Controllers/RoccatController/RoccatKoneProController.h \ Controllers/RoccatController/RoccatKovaController.h \ Controllers/RoccatController/RoccatSenseAimoController.h \ Controllers/RoccatController/RoccatVulcanKeyboardController.h \ @@ -1464,6 +1466,7 @@ SOURCES += Controllers/RoccatController/RGBController_RoccatElo.cpp \ Controllers/RoccatController/RGBController_RoccatHordeAimo.cpp \ Controllers/RoccatController/RGBController_RoccatKoneAimo.cpp \ + Controllers/RoccatController/RGBController_RoccatKonePro.cpp \ Controllers/RoccatController/RGBController_RoccatKova.cpp \ Controllers/RoccatController/RGBController_RoccatSenseAimo.cpp \ Controllers/RoccatController/RGBController_RoccatVulcanKeyboard.cpp \ @@ -1472,6 +1475,7 @@ SOURCES += Controllers/RoccatController/RoccatEloController.cpp \ Controllers/RoccatController/RoccatHordeAimoController.cpp \ Controllers/RoccatController/RoccatKoneAimoController.cpp \ + Controllers/RoccatController/RoccatKoneProController.cpp \ Controllers/RoccatController/RoccatKovaController.cpp \ Controllers/RoccatController/RoccatSenseAimoController.cpp \ Controllers/RoccatController/RoccatVulcanKeyboardController.cpp \