diff --git a/Controllers/A4TechController/A4Tech_Detector.cpp b/Controllers/A4TechController/A4Tech_Detector.cpp new file mode 100644 index 00000000..d3c4726a --- /dev/null +++ b/Controllers/A4TechController/A4Tech_Detector.cpp @@ -0,0 +1,38 @@ +/*-----------------------------------------------------*\ +| OpenRGB includes | +\*-----------------------------------------------------*/ +#include +#include "Detector.h" +#include "LogManager.h" +#include "RGBController.h" + +/*-----------------------------------------------------*\ +| A4 Tech specific includes | +\*-----------------------------------------------------*/ +#include "RGBController_BloodyMouse.h" + +/*-----------------------------------------------------*\ +| A4 Tech USB vendor ID | +\*-----------------------------------------------------*/ +#define A4_TECH_VID 0x09DA + +/*-----------------------------------------------------*\ +| Keyboard product IDs | +\*-----------------------------------------------------*/ +#define BLOODY_W60_PRO_PID 0x37EA + +void DetectA4TechMouseControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + BloodyMouseController* controller = new BloodyMouseController(dev, info->path); + RGBController_BloodyMouse* rgb_controller = new RGBController_BloodyMouse(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR_IPU("Bloody W60 Pro", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W60_PRO_PID, 2, 0xFF33, 0x0529); diff --git a/Controllers/A4TechController/BloodyMouseController.cpp b/Controllers/A4TechController/BloodyMouseController.cpp new file mode 100644 index 00000000..6f2a179b --- /dev/null +++ b/Controllers/A4TechController/BloodyMouseController.cpp @@ -0,0 +1,75 @@ +/*---------------------------------------------------------------------*\ +| BloodyMouseController.cpp | +| | +| Driver for BloodyMouse USB Controller | +| | +| Chris M (Dr_No) 30 Jun 2022 | +| | +\*---------------------------------------------------------------------*/ + +#include "BloodyMouseController.h" + +BloodyMouseController::BloodyMouseController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; + + InitDevice(); +} + +BloodyMouseController::~BloodyMouseController() +{ + hid_close(dev); +} + +std::string BloodyMouseController::GetSerial() +{ + const uint8_t sz = HID_MAX_STR; + wchar_t tmp[sz]; + + int ret = hid_get_serial_number_string(dev, tmp, sz); + + if (ret != 0) + { + LOG_DEBUG("[BloodyMouse] Get HID Serial string failed"); + return(""); + } + + std::wstring w_tmp = std::wstring(tmp); + std::string serial = std::string(w_tmp.begin(), w_tmp.end()); + + return serial; +} + +std::string BloodyMouseController::GetLocation() +{ + return("HID: " + location); +} + +void BloodyMouseController::InitDevice() +{ + uint8_t buffer[BLOODYMOUSE_WRITE_PACKET_SIZE] = { 0x07, 0x03, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 }; + + hid_send_feature_report(dev, buffer, BLOODYMOUSE_WRITE_PACKET_SIZE); + + buffer[BLOODYMOUSE_MODE_BYTE] = 0; + buffer[BLOODYMOUSE_DATA_BYTE] = 1; + + hid_send_feature_report(dev, buffer, BLOODYMOUSE_WRITE_PACKET_SIZE); +} + +void BloodyMouseController::SetLedsDirect(std::vector colors) +{ + uint8_t buffer[BLOODYMOUSE_WRITE_PACKET_SIZE] = { 0x07, 0x03, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00 }; + + for(uint8_t i = 0; i < colors.size(); i++) + { + uint8_t offset = 3 * (colors[i] >> 24) + BLOODYMOUSE_DATA_BYTE; + + buffer[offset] = RGBGetRValue(colors[i]); + buffer[offset + 1] = RGBGetGValue(colors[i]); + buffer[offset + 2] = RGBGetBValue(colors[i]); + } + + hid_send_feature_report(dev, buffer, BLOODYMOUSE_WRITE_PACKET_SIZE); +} diff --git a/Controllers/A4TechController/BloodyMouseController.h b/Controllers/A4TechController/BloodyMouseController.h new file mode 100644 index 00000000..98335d10 --- /dev/null +++ b/Controllers/A4TechController/BloodyMouseController.h @@ -0,0 +1,51 @@ +/*---------------------------------------------------------------------*\ +| BloodyMouseController.h | +| | +| Driver for BloodyMouse USB Controller | +| | +| Chris M (Dr_No) 30 Jun 2022 | +| | +\*---------------------------------------------------------------------*/ + +#include +#include +#include "LogManager.h" +#include "RGBController.h" + +#pragma once + +#define HID_MAX_STR 255 +#define BLOODYMOUSE_WRITE_PACKET_SIZE 64 + +#define BLOODYMOUSE_BRIGHTNESS_MIN 0 +#define BLOODYMOUSE_BRIGHTNESS_MAX 255 + +enum +{ + BLOODYMOUSE_MODE_DIRECT = 0x01, //Direct Led Control - Independently set LEDs in zone +}; + +enum +{ + BLOODYMOUSE_REPORT_BYTE = 1, + BLOODYMOUSE_COMMAND_BYTE = 2, + BLOODYMOUSE_MODE_BYTE = 3, + BLOODYMOUSE_DATA_BYTE = 8, +}; + +class BloodyMouseController +{ +public: + BloodyMouseController(hid_device* dev_handle, const char* path); + ~BloodyMouseController(); + + std::string GetSerial(); + std::string GetLocation(); + + void SetLedsDirect(std::vector colors); +private: + std::string location; + hid_device* dev; + + void InitDevice(); +}; diff --git a/Controllers/A4TechController/RGBController_BloodyMouse.cpp b/Controllers/A4TechController/RGBController_BloodyMouse.cpp new file mode 100644 index 00000000..3302c18b --- /dev/null +++ b/Controllers/A4TechController/RGBController_BloodyMouse.cpp @@ -0,0 +1,152 @@ +/*---------------------------------------------------------------------*\ +| RGBController_BloodyMouse.cpp | +| | +| Driver for BloodyMouse USB Controller | +| | +| Chris M (Dr_No) 30 Jun 2022 | +| | +\*---------------------------------------------------------------------*/ + +#include "RGBController_BloodyMouse.h" + +static const mouse_layout w60_pro +{ + { + "Scroll Wheel", { 14 } + }, + { + "Mid Line", { 0, 1, 2, 9, 3, 4, 5, 6 } + }, + { + "Logo", { 10 } + }, + { + "Rear", { 8, 7, 13, 12, 11 } + } +}; + +/**------------------------------------------------------------------*\ + @name BloodyMouse + @category Mouse + @type USB + @save :x: + @direct :white_check_mark: + @effects :x: + @detectors DetectA4TechMouseControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_BloodyMouse::RGBController_BloodyMouse(BloodyMouseController *controller_ptr) +{ + controller = controller_ptr; + + name = "BloodyMouse"; + vendor = "Bloody"; + type = DEVICE_TYPE_MOUSE; + description = "Controller compatible with the Bloody W60 Pro"; + serial = controller->GetSerial(); + location = controller->GetLocation(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = BLOODYMOUSE_MODE_DIRECT; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + SetupZones(); +} + +RGBController_BloodyMouse::~RGBController_BloodyMouse() +{ + delete controller; +} + +void RGBController_BloodyMouse::SetupZones() +{ + /*-------------------------------------------------*\ + | Clear any existing color/LED configuration | + \*-------------------------------------------------*/ + leds.clear(); + colors.clear(); + + /*---------------------------------------------------------*\ + | Set up zones | + \*---------------------------------------------------------*/ + for(uint8_t zone_idx = 0; zone_idx < w60_pro.size(); zone_idx++) + { + mouse_zone mz = w60_pro[zone_idx]; + bool bool_single = mz.zone_leds.size() == 1; + + zone new_zone; + new_zone.name = mz.name; + new_zone.leds_min = mz.zone_leds.size(); + new_zone.leds_max = new_zone.leds_min; + new_zone.leds_count = new_zone.leds_min; + new_zone.type = bool_single ? ZONE_TYPE_SINGLE : ZONE_TYPE_LINEAR; + new_zone.matrix_map = NULL; + zones.push_back(new_zone); + + for(unsigned int lp_idx = 0; lp_idx < zones[zone_idx].leds_count; lp_idx++) + { + led new_led; + + new_led.value = mz.zone_leds[lp_idx]; + + if(bool_single) + { + new_led.name = mz.name + " LED"; + } + else + { + new_led.name = mz.name; + new_led.name.append(" LED " + std::to_string(lp_idx)); + } + + leds.push_back(new_led); + } + } + + SetupColors(); +} + +void RGBController_BloodyMouse::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_BloodyMouse::DeviceUpdateLEDs() +{ + std::vector colour; + for(size_t i = 0; i < colors.size(); i++) + { + RGBColor c = colors[i] | (leds[i].value << 24); + colour.push_back(c); + } + + controller->SetLedsDirect(colour); +} + +void RGBController_BloodyMouse::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_BloodyMouse::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_BloodyMouse::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_BloodyMouse::DeviceUpdateMode() +{ + /*---------------------------------------------------------*\ + | This device only supports Direct mode | + \*---------------------------------------------------------*/ +} diff --git a/Controllers/A4TechController/RGBController_BloodyMouse.h b/Controllers/A4TechController/RGBController_BloodyMouse.h new file mode 100644 index 00000000..757b8d9a --- /dev/null +++ b/Controllers/A4TechController/RGBController_BloodyMouse.h @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------*\ +| RGBController_BloodyMouse.h | +| | +| Driver for BloodyMouse USB Controller | +| | +| Chris M (Dr_No) 30 Jun 2022 | +| | +\*---------------------------------------------------------------------*/ + +#pragma once +#include +#include "LogManager.h" +#include "RGBController.h" +#include "BloodyMouseController.h" + +struct mouse_zone +{ + std::string name; + std::vector zone_leds; +}; + +typedef std::vector mouse_layout; + +class RGBController_BloodyMouse : public RGBController +{ +public: + RGBController_BloodyMouse(BloodyMouseController* controller_ptr); + ~RGBController_BloodyMouse(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + BloodyMouseController* controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 39ff44d7..0fe3d065 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -75,6 +75,7 @@ INCLUDEPATH += serial_port/ \ super_io/ \ AutoStart/ \ + Controllers/A4TechController/ \ Controllers/AlienwareController/ \ Controllers/AlienwareKeyboardController/ \ Controllers/AMDWraithPrismController/ \ @@ -234,6 +235,8 @@ HEADERS += serial_port/serial_port.h \ super_io/super_io.h \ AutoStart/AutoStart.h \ + Controllers/A4TechController/BloodyMouseController.h \ + Controllers/A4TechController/RGBController_BloodyMouse.h \ Controllers/AlienwareController/AlienwareController.h \ Controllers/AlienwareController/RGBController_Alienware.h \ Controllers/AlienwareKeyboardController/AlienwareAW510KController.h \ @@ -681,6 +684,9 @@ SOURCES += serial_port/serial_port.cpp \ super_io/super_io.cpp \ AutoStart/AutoStart.cpp \ + Controllers/A4TechController/A4Tech_Detector.cpp \ + Controllers/A4TechController/BloodyMouseController.cpp \ + Controllers/A4TechController/RGBController_BloodyMouse.cpp \ Controllers/AlienwareController/AlienwareController.cpp \ Controllers/AlienwareController/AlienwareControllerDetect.cpp \ Controllers/AlienwareController/RGBController_Alienware.cpp \