From 6454f6c5f233adbe3a353a6792071aa7c219f656 Mon Sep 17 00:00:00 2001 From: edo-2313 <32812884+edo-2313@users.noreply.github.com> Date: Tue, 29 Dec 2020 16:18:16 +0100 Subject: [PATCH] Added support for Holtek based mousemats Commits amended and squashed by Adam Honse --- .../HoltekController/HoltekA1FAController.cpp | 59 ++++++++ .../HoltekController/HoltekA1FAController.h | 61 ++++++++ .../HoltekControllerDetect.cpp | 19 +++ .../RGBController_HoltekA1FA.cpp | 136 ++++++++++++++++++ .../RGBController_HoltekA1FA.h | 32 +++++ OpenRGB.pro | 4 + 6 files changed, 311 insertions(+) create mode 100644 Controllers/HoltekController/HoltekA1FAController.cpp create mode 100644 Controllers/HoltekController/HoltekA1FAController.h create mode 100644 Controllers/HoltekController/RGBController_HoltekA1FA.cpp create mode 100644 Controllers/HoltekController/RGBController_HoltekA1FA.h diff --git a/Controllers/HoltekController/HoltekA1FAController.cpp b/Controllers/HoltekController/HoltekA1FAController.cpp new file mode 100644 index 00000000..c2f820f5 --- /dev/null +++ b/Controllers/HoltekController/HoltekA1FAController.cpp @@ -0,0 +1,59 @@ +/*-----------------------------------------------*\ +| HoltekA1FAController.cpp | +| | +| Driver for Holtek based Mousemat [04d9:a1fa] | +| | +| Edoardo Ridolfi (edo2313) 26/12/2020 | +\*-----------------------------------------------*/ + +#include "HoltekA1FAController.h" + +#include + +HoltekA1FAController::HoltekA1FAController(hid_device *dev_handle, const char *path) +{ + dev = dev_handle; + location = path; +} + +std::string HoltekA1FAController::GetDeviceLocation() +{ + return ("HID: " + location); +} + +std::string HoltekA1FAController::GetSerialString() +{ + wchar_t serial_string[128]; + hid_get_serial_number_string(dev, serial_string, 128); + + std::wstring return_wstring = serial_string; + std::string return_string(return_wstring.begin(), return_wstring.end()); + + return (return_string); +} + +/*-------------------------------------------------------------------------------------------------*\ +| Private packet sending functions. | +\*-------------------------------------------------------------------------------------------------*/ + +void HoltekA1FAController::SendData(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char preset, unsigned char red, unsigned char green, unsigned char blue) +{ + char usb_buf[9] = {0x00}; + + /*-----------------------------------------------------*\ + | Set up RGB Control packet | + \*-----------------------------------------------------*/ + usb_buf[HOLTEK_A1FA_BYTE_COMMAND] = 0x08; + usb_buf[HOLTEK_A1FA_BYTE_MODE] = mode; + usb_buf[HOLTEK_A1FA_BYTE_BRIGHTNESS] = brightness; + usb_buf[HOLTEK_A1FA_BYTE_SPEED] = speed; + usb_buf[HOLTEK_A1FA_BYTE_PRESET] = preset; + usb_buf[HOLTEK_A1FA_BYTE_RED] = red; + usb_buf[HOLTEK_A1FA_BYTE_GREEN] = green; + usb_buf[HOLTEK_A1FA_BYTE_BLUE] = blue; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, (unsigned char *)usb_buf, sizeof(usb_buf)); +} diff --git a/Controllers/HoltekController/HoltekA1FAController.h b/Controllers/HoltekController/HoltekA1FAController.h new file mode 100644 index 00000000..e2b78585 --- /dev/null +++ b/Controllers/HoltekController/HoltekA1FAController.h @@ -0,0 +1,61 @@ +/*---------------------------------------------------------------*\ +| HoltekA1FAController.h | +| | +| Definitions and types for Holtek based Mousemat [04d9:a1fa] | +| | +| Edoardo Ridolfi (edo2313) 26/12/2020 | +\*---------------------------------------------------------------*/ + +#include "RGBController.h" + +#include +#include + +#pragma once + +enum +{ + HOLTEK_A1FA_BYTE_COMMAND = 1, + HOLTEK_A1FA_BYTE_MODE = 2, + HOLTEK_A1FA_BYTE_BRIGHTNESS = 3, + HOLTEK_A1FA_BYTE_SPEED = 4, + HOLTEK_A1FA_BYTE_PRESET = 5, + HOLTEK_A1FA_BYTE_RED = 6, + HOLTEK_A1FA_BYTE_GREEN = 7, + HOLTEK_A1FA_BYTE_BLUE = 8 + +}; + +enum +{ + HOLTEK_A1FA_MODE_STATIC = 0x00, + HOLTEK_A1FA_MODE_BREATHING = 0x01, + HOLTEK_A1FA_MODE_NEON = 0x02, + HOLTEK_A1FA_MODE_RAINBOW = 0x03 +}; + +enum +{ + HOLTEK_A1FA_SPEED_SLOWEST = 0x00, /* Slowest speed */ + HOLTEK_A1FA_SPEED_SLOWER = 0x01, /* Slower speed */ + HOLTEK_A1FA_SPEED_SLOW = 0x02, /* Slow speed */ + HOLTEK_A1FA_SPEED_NORMAL = 0x03, /* Normal speed */ + HOLTEK_A1FA_SPEED_FAST = 0x04, /* Fast speed */ + HOLTEK_A1FA_SPEED_FASTEST = 0x05 /* Fastest speed */ +}; + +class HoltekA1FAController +{ +public: + HoltekA1FAController(hid_device *dev_handle, const char *path); + ~HoltekA1FAController(); + + std::string GetDeviceLocation(); + std::string GetSerialString(); + + void SendData(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char preset, unsigned char red, unsigned char green, unsigned char blue); + +private: + hid_device *dev; + std::string location; +}; diff --git a/Controllers/HoltekController/HoltekControllerDetect.cpp b/Controllers/HoltekController/HoltekControllerDetect.cpp index bc9e780b..7e856c67 100644 --- a/Controllers/HoltekController/HoltekControllerDetect.cpp +++ b/Controllers/HoltekController/HoltekControllerDetect.cpp @@ -2,6 +2,8 @@ #include "HoltekA070Controller.h" #include "RGBController.h" #include "RGBController_HoltekA070.h" +#include "HoltekA1FAController.h" +#include "RGBController_HoltekA1FA.h" #include #include @@ -13,6 +15,10 @@ | Mouse product IDs | \*-----------------------------------------------------*/ #define HOLTEK_A070_PID 0xA070 +/*-----------------------------------------------------*\ +| Mousemats product IDs | +\*-----------------------------------------------------*/ +#define HOLTEK_A1FA_PID 0xA1FA void DetectHoltekControllers(hid_device_info* info, const std::string& name) { @@ -26,4 +32,17 @@ void DetectHoltekControllers(hid_device_info* info, const std::string& name) } } /* DetectHoltekControllers() */ +void DetectHoltekMousemats(hid_device_info *info, const std::string &name) +{ + hid_device *dev = hid_open_path(info->path); + if (dev) + { + HoltekA1FAController *controller = new HoltekA1FAController(dev, info->path); + RGBController_HoltekA1FA *rgb_controller = new RGBController_HoltekA1FA(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} /* DetectHoltekMousemats() */ + REGISTER_HID_DETECTOR_IPU("Holtek USB Gaming Mouse", DetectHoltekControllers, HOLTEK_VID, HOLTEK_A070_PID, 1, 0xFF00, 2); +REGISTER_HID_DETECTOR_IPU("Holtek Mousemat", DetectHoltekMousemats, HOLTEK_VID, HOLTEK_A1FA_PID, 2, 0xFF00, 0xFF00); diff --git a/Controllers/HoltekController/RGBController_HoltekA1FA.cpp b/Controllers/HoltekController/RGBController_HoltekA1FA.cpp new file mode 100644 index 00000000..a70aa379 --- /dev/null +++ b/Controllers/HoltekController/RGBController_HoltekA1FA.cpp @@ -0,0 +1,136 @@ +/*--------------------------------------------------------------*\ +| RGBController_HoltekA1FA.cpp | +| | +| Generic RGB Interface for Holtek based Mousemat [04d9:a1fa] | +| | +| Edoardo Ridolfi (edo2313) 26/12/2020 | +\*--------------------------------------------------------------*/ + +#include "RGBController_HoltekA1FA.h" + +RGBController_HoltekA1FA::RGBController_HoltekA1FA(HoltekA1FAController* holtek_ptr) +{ + holtek = holtek_ptr; + + name = "Holtek Mousemat Device"; + vendor = "Holtek"; + type = DEVICE_TYPE_MOUSEMAT; + description = "Holtek Mousemat Device"; + location = holtek->GetDeviceLocation(); + serial = holtek->GetSerialString(); + + mode Static; + Static.name = "Static"; + Static.value = HOLTEK_A1FA_MODE_STATIC; + Static.speed = HOLTEK_A1FA_MODE_STATIC; + Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Static.color_mode = MODE_COLORS_PER_LED; + Static.colors_min = 1; + Static.colors_max = 7; + Static.colors.resize(7); + modes.push_back(Static); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = HOLTEK_A1FA_MODE_BREATHING; + Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_RANDOM_COLOR; + Breathing.color_mode = MODE_COLORS_PER_LED; + Breathing.speed_min = HOLTEK_A1FA_SPEED_SLOWEST; + Breathing.speed_max = HOLTEK_A1FA_SPEED_FASTEST; + Breathing.speed = HOLTEK_A1FA_SPEED_NORMAL; + Breathing.colors_min = 1; + Breathing.colors_max = 7; + Breathing.colors.resize(7); + modes.push_back(Breathing); + + mode Neon; + Neon.name = "Neon"; + Neon.value = HOLTEK_A1FA_MODE_NEON; + Neon.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; + Neon.color_mode = MODE_COLORS_NONE; + Neon.speed_min = HOLTEK_A1FA_SPEED_SLOWEST; + Neon.speed_max = HOLTEK_A1FA_SPEED_FASTEST; + Neon.speed = HOLTEK_A1FA_SPEED_NORMAL; + modes.push_back(Neon); + + mode Rainbow; + Rainbow.name = "Rainbow"; + Rainbow.value = HOLTEK_A1FA_MODE_RAINBOW; + Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; + Rainbow.color_mode = MODE_COLORS_NONE; + Rainbow.speed_min = HOLTEK_A1FA_SPEED_SLOWEST; + Rainbow.speed_max = HOLTEK_A1FA_SPEED_FASTEST; + Rainbow.speed = HOLTEK_A1FA_SPEED_NORMAL; + modes.push_back(Rainbow); + + SetupZones(); +} + +void RGBController_HoltekA1FA::SetupZones() +{ + zone mouse_zone; + mouse_zone.name = "Mousemat"; + mouse_zone.type = ZONE_TYPE_SINGLE; + mouse_zone.leds_min = 1; + mouse_zone.leds_max = 1; + mouse_zone.leds_count = 1; + mouse_zone.matrix_map = NULL; + zones.push_back(mouse_zone); + + led mouse_led; + mouse_led.name = "Mousemat"; + leds.push_back(mouse_led); + + SetupColors(); +} + +void RGBController_HoltekA1FA::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_HoltekA1FA::DeviceUpdateLEDs() +{ + unsigned char mode = modes[active_mode].value; + unsigned char brightness = 0x20; /*When brightness support is added, change this */ + unsigned char speed = modes[active_mode].speed; + unsigned char preset = (modes[active_mode].color_mode == MODE_COLORS_RANDOM) ? 0x70 : 0x00; + unsigned char red = RGBGetRValue(colors[0]); + unsigned char green = RGBGetGValue(colors[0]); + unsigned char blue = RGBGetBValue(colors[0]); + + holtek->SendData(mode, brightness, speed, preset, red, green, blue); +} + +void RGBController_HoltekA1FA::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HoltekA1FA::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HoltekA1FA::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_HoltekA1FA::DeviceUpdateMode() +{ + if((active_mode < HOLTEK_A1FA_MODE_NEON) && (previous_mode < HOLTEK_A1FA_MODE_NEON)) + { + //If we're switching from and to static and breathing then sync the mode colors + for ( int i = 0; i < modes[active_mode].colors_max; i++) + { + modes[active_mode].colors[i] = modes[previous_mode].colors[i]; + } + } + + previous_mode = active_mode; + + DeviceUpdateLEDs(); +} diff --git a/Controllers/HoltekController/RGBController_HoltekA1FA.h b/Controllers/HoltekController/RGBController_HoltekA1FA.h new file mode 100644 index 00000000..a579ad32 --- /dev/null +++ b/Controllers/HoltekController/RGBController_HoltekA1FA.h @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------*\ +| RGBController_HoltekA1FA.h | +| | +| Generic RGB Interface for Holtek based Mousemat [04d9:a1fa] | +| | +| Edoardo Ridolfi (edo2313) 26/12/2020 | +\*--------------------------------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "HoltekA1FAController.h" + +class RGBController_HoltekA1FA : public RGBController +{ +public: + RGBController_HoltekA1FA(HoltekA1FAController* holtek_ptr); + + int previous_mode = 0; /* previous mode */ + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + HoltekA1FAController* holtek; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index ff2d656a..0e77d373 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -198,7 +198,9 @@ HEADERS += Controllers/GalaxGPUController/GalaxGPUController.h \ Controllers/GalaxGPUController/RGBController_GalaxGPU.h \ Controllers/HoltekController/HoltekA070Controller.h \ + Controllers/HoltekController/HoltekA1FAController.h \ Controllers/HoltekController/RGBController_HoltekA070.h \ + Controllers/HoltekController/RGBController_HoltekA1FA.h \ Controllers/HyperXDRAMController/HyperXDRAMController.h \ Controllers/HyperXDRAMController/RGBController_HyperXDRAM.h \ Controllers/HyperXKeyboardController/HyperXAlloyOriginsController.h \ @@ -401,8 +403,10 @@ SOURCES += Controllers/GalaxGPUController/GalaxGPUControllerDetect.cpp \ Controllers/GalaxGPUController/RGBController_GalaxGPU.cpp \ Controllers/HoltekController/HoltekA070Controller.cpp \ + Controllers/HoltekController/HoltekA1FAController.cpp \ Controllers/HoltekController/HoltekControllerDetect.cpp \ Controllers/HoltekController/RGBController_HoltekA070.cpp \ + Controllers/HoltekController/RGBController_HoltekA1FA.cpp \ Controllers/HyperXDRAMController/HyperXDRAMController.cpp \ Controllers/HyperXDRAMController/HyperXDRAMControllerDetect.cpp \ Controllers/HyperXDRAMController/RGBController_HyperXDRAM.cpp \