From a0c529ed5901af2ce4a73f5fa9976ffbbc3d02b2 Mon Sep 17 00:00:00 2001 From: morg Date: Sun, 21 Jan 2024 23:33:20 +0000 Subject: [PATCH] Add support for instant microelectronics mice. Close #2496 --- .../InstantMouseController.cpp | 111 +++++++++++ .../InstantMouseController.h | 58 ++++++ .../InstantMouseControllerDetect.cpp | 24 +++ .../RGBController_InstantMouse.cpp | 175 ++++++++++++++++++ .../RGBController_InstantMouse.h | 32 ++++ OpenRGB.pro | 6 + 6 files changed, 406 insertions(+) create mode 100644 Controllers/InstantMouseController/InstantMouseController.cpp create mode 100644 Controllers/InstantMouseController/InstantMouseController.h create mode 100644 Controllers/InstantMouseController/InstantMouseControllerDetect.cpp create mode 100644 Controllers/InstantMouseController/RGBController_InstantMouse.cpp create mode 100644 Controllers/InstantMouseController/RGBController_InstantMouse.h diff --git a/Controllers/InstantMouseController/InstantMouseController.cpp b/Controllers/InstantMouseController/InstantMouseController.cpp new file mode 100644 index 00000000..55528cfe --- /dev/null +++ b/Controllers/InstantMouseController/InstantMouseController.cpp @@ -0,0 +1,111 @@ +/*-----------------------------------------*\ +| InstantMouseController.cpp | +| | +| Driver for Instant mouse lighting | +| controller | +| | +| Guimard Morgan (morg) 1/19/2024 | +\*-----------------------------------------*/ +#include "InstantMouseController.h" +#include + +InstantMouseController::InstantMouseController(hid_device* dev_handle, const hid_device_info& info) +{ + dev = dev_handle; + location = info.path; + version = ""; + + 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()); + } +} + +InstantMouseController::~InstantMouseController() +{ + hid_close(dev); +} + +std::string InstantMouseController::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string InstantMouseController::GetSerialString() +{ + return(serial_number); +} + +std::string InstantMouseController::GetFirmwareVersion() +{ + return(version); +} + +void InstantMouseController::SendColor(RGBColor color) +{ + /*---------------------------------------------------------*\ + | Packet details | + | 07 X4 0G RB 00 00 00 00 | + | where X is the DPI slot | + \*---------------------------------------------------------*/ + + uint8_t red = 0xF - RGBGetRValue(color) / 16; + uint8_t grn = 0xF - RGBGetGValue(color) / 16; + uint8_t blu = 0xF - RGBGetBValue(color) / 16; + + uint8_t pkt[INSTANT_MOUSE_REPORT_SIZE]; + memset(pkt, 0 , INSTANT_MOUSE_REPORT_SIZE); + + pkt[0] = INSTANT_MOUSE_REPORT_ID; + pkt[1] = INSTANT_MOUSE_SET_COLOR; + pkt[3] = (red << 4) | (blu & 0xF); + + for(unsigned int i = 0; i <= 0xA; i+= 2) + { + pkt[2] = (i << 4) | (grn & 0xF); + hid_send_feature_report(dev, pkt, INSTANT_MOUSE_REPORT_SIZE); + } +} + +void InstantMouseController::SetMode(uint8_t mode_value, uint8_t speed, uint8_t brightness, uint8_t direction) +{ + /*---------------------------------------------------------*\ + | Packet details: | + | 07 13 FF MS DN -B -- -- | + | | + | 07 = report id | + | 13 = set mode function | + | FF = constant | + | - = still undiscovered/useless | + | M = mode | + | S = speed 0 -> 5 (6 and more makes the effect static) | + | N = number of leds | + | D = direction (0/1) | + | B = brightness (0 full, F off) | + \*---------------------------------------------------------*/ + + uint8_t led_mask = 0xB; + + uint8_t pkt[INSTANT_MOUSE_REPORT_SIZE]; + + pkt[0] = INSTANT_MOUSE_REPORT_ID; + pkt[1] = INSTANT_MOUSE_SET_MODE; + pkt[2] = 0xFF; + + pkt[3] = (mode_value << 4) | (speed & 0xF); + pkt[4] = (direction << 4) | led_mask; + pkt[5] = 0xF - (brightness & 0xF); + + pkt[6] = 0x00; + pkt[7] = 0x00; + + hid_send_feature_report(dev, pkt, INSTANT_MOUSE_REPORT_SIZE); +} diff --git a/Controllers/InstantMouseController/InstantMouseController.h b/Controllers/InstantMouseController/InstantMouseController.h new file mode 100644 index 00000000..34ed5cd9 --- /dev/null +++ b/Controllers/InstantMouseController/InstantMouseController.h @@ -0,0 +1,58 @@ +/*-----------------------------------------*\ +| InstantMouseController.h | +| | +| Driver for Instant mouse lighting | +| controller - header file | +| | +| Guimard Morgan (morg) 1/19/2024 | +\*-----------------------------------------*/ +#pragma once + +#include "RGBController.h" +#include +#include + +#define INSTANT_MOUSE_REPORT_ID 0x07 +#define INSTANT_MOUSE_REPORT_SIZE 8 +#define INSTANT_MOUSE_SET_MODE 0x13 +#define INSTANT_MOUSE_SET_COLOR 0x14 + +enum +{ + INSTANT_MOUSE_DIRECT_MODE = 0x0A, + INSTANT_MOUSE_OFF_MODE = 0xFF, + INSTANT_MOUSE_MULTICOLOR_BREATHING_MODE = 0x01, + INSTANT_MOUSE_FILL_DRAIN_MODE = 0x03, + INSTANT_MOUSE_LOOP_MODE = 0x04, + INSTANT_MOUSE_SPECTRUM_CYCLE_MODE = 0x06, + INSTANT_MOUSE_RAINBOW_WAVE_MODE = 0x07, + INSTANT_MOUSE_BREATHING_MODE = 0x08 +}; + +enum +{ + INSTANT_MOUSE_SPEED_MIN = 0x00, + INSTANT_MOUSE_SPEED_MAX = 0x05, + INSTANT_MOUSE_BRIGHTNESS_MIN = 0x00, + INSTANT_MOUSE_BRIGHTNESS_MAX = 0x07 +}; + +class InstantMouseController +{ +public: + InstantMouseController(hid_device* dev_handle, const hid_device_info& info); + ~InstantMouseController(); + + std::string GetSerialString(); + std::string GetDeviceLocation(); + std::string GetFirmwareVersion(); + + void SetMode(uint8_t mode_value, uint8_t speed, uint8_t brightness, uint8_t direction); + void SendColor(RGBColor color); + +private: + hid_device* dev; + std::string location; + std::string serial_number; + std::string version; +}; diff --git a/Controllers/InstantMouseController/InstantMouseControllerDetect.cpp b/Controllers/InstantMouseController/InstantMouseControllerDetect.cpp new file mode 100644 index 00000000..29efda8c --- /dev/null +++ b/Controllers/InstantMouseController/InstantMouseControllerDetect.cpp @@ -0,0 +1,24 @@ +#include "Detector.h" +#include "InstantMouseController.h" +#include "RGBController.h" +#include "RGBController_InstantMouse.h" + +#define INSTANT_MICROELECTRONICS_VID 0x30FA +#define ADVANCED_GTA_250_PID 0x1030 +#define ANKO_KM43243952_VID 0x1440 + +void DetectInstantMouseControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + InstantMouseController* controller = new InstantMouseController(dev, *info); + RGBController_InstantMouse* rgb_controller = new RGBController_InstantMouse(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR_IPU("Advanced GTA 250 USB Gaming Mouse", DetectInstantMouseControllers, INSTANT_MICROELECTRONICS_VID, ADVANCED_GTA_250_PID, 1, 0xFF01, 0x01); +REGISTER_HID_DETECTOR_IPU("Anko KM43243952 USB Gaming Mouse", DetectInstantMouseControllers, INSTANT_MICROELECTRONICS_VID, ANKO_KM43243952_VID, 1, 0xFF01, 0x01); diff --git a/Controllers/InstantMouseController/RGBController_InstantMouse.cpp b/Controllers/InstantMouseController/RGBController_InstantMouse.cpp new file mode 100644 index 00000000..d53004df --- /dev/null +++ b/Controllers/InstantMouseController/RGBController_InstantMouse.cpp @@ -0,0 +1,175 @@ +/*-----------------------------------------*\ +| RGBController_InstantMouse.cpp | +| | +| Generic RGB Interface for OpenRGB | +| Instant mouse RGB USB Driver | +| | +| Guimard Morgan (morg) 1/19/2024 | +\*-----------------------------------------*/ + +#include "RGBController_InstantMouse.h" + +/**------------------------------------------------------------------*\ + @name Instant mouse + @category Mouse + @type USB + @save :x: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectInstantMouseControllers + @comment This controller should work with all mouse with this chip. + Identified devices that work with this controller: Advance Gaming + GTA 250 (GX72-A725), Anko KM43243952 (GM8-A825) +\*-------------------------------------------------------------------*/ + +RGBController_InstantMouse::RGBController_InstantMouse(InstantMouseController* controller_ptr) +{ + controller = controller_ptr; + vendor = "Instant Microelectronics"; + type = DEVICE_TYPE_MOUSE; + description = "Instant USB Gaming Mouse"; + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + version = controller->GetFirmwareVersion(); + + mode direct; + direct.name = "Direct"; + direct.value = INSTANT_MOUSE_DIRECT_MODE; + direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + direct.color_mode = MODE_COLORS_PER_LED; + direct.brightness = INSTANT_MOUSE_BRIGHTNESS_MAX; + direct.brightness_min = INSTANT_MOUSE_BRIGHTNESS_MIN; + direct.brightness_max = INSTANT_MOUSE_BRIGHTNESS_MAX; + modes.push_back(direct); + + mode rainbow; + rainbow.name = "Rainbow wave"; + rainbow.value = INSTANT_MOUSE_RAINBOW_WAVE_MODE; + rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR; + rainbow.color_mode = MODE_COLORS_NONE; + rainbow.speed_min = INSTANT_MOUSE_SPEED_MIN; + rainbow.speed_max = INSTANT_MOUSE_SPEED_MAX; + rainbow.speed = INSTANT_MOUSE_SPEED_MAX/2; + modes.push_back(rainbow); + + mode spectrum; + spectrum.name = "Spectrum cycle"; + spectrum.value = INSTANT_MOUSE_SPECTRUM_CYCLE_MODE; + spectrum.flags = MODE_FLAG_HAS_SPEED; + spectrum.color_mode = MODE_COLORS_NONE; + spectrum.speed_min = INSTANT_MOUSE_SPEED_MIN; + spectrum.speed_max = INSTANT_MOUSE_SPEED_MAX; + spectrum.speed = INSTANT_MOUSE_SPEED_MAX/2; + modes.push_back(spectrum); + + mode breathing; + breathing.name = "Breathing"; + breathing.value = INSTANT_MOUSE_BREATHING_MODE; + breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + breathing.colors.resize(1); + breathing.colors_min = 1; + breathing.colors_max = 1; + breathing.speed_min = INSTANT_MOUSE_SPEED_MIN; + breathing.speed_max = INSTANT_MOUSE_SPEED_MAX; + breathing.speed = INSTANT_MOUSE_SPEED_MAX/2; + modes.push_back(breathing); + + mode fill; + fill.name = "Fill"; + fill.value = INSTANT_MOUSE_FILL_DRAIN_MODE; + fill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR; + fill.color_mode = MODE_COLORS_NONE; + fill.speed_min = INSTANT_MOUSE_SPEED_MIN; + fill.speed_max = INSTANT_MOUSE_SPEED_MAX; + fill.speed = INSTANT_MOUSE_SPEED_MAX/2; + fill.brightness = INSTANT_MOUSE_BRIGHTNESS_MAX; + fill.brightness_min = INSTANT_MOUSE_BRIGHTNESS_MIN; + fill.brightness_max = INSTANT_MOUSE_BRIGHTNESS_MAX; + modes.push_back(fill); + + mode loop; + loop.name = "Loop"; + loop.value = INSTANT_MOUSE_LOOP_MODE; + loop.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR; + loop.color_mode = MODE_COLORS_NONE; + loop.speed_min = INSTANT_MOUSE_SPEED_MIN; + loop.speed_max = INSTANT_MOUSE_SPEED_MAX; + loop.speed = INSTANT_MOUSE_SPEED_MAX/2; + loop.brightness = INSTANT_MOUSE_BRIGHTNESS_MAX; + loop.brightness_min = INSTANT_MOUSE_BRIGHTNESS_MIN; + loop.brightness_max = INSTANT_MOUSE_BRIGHTNESS_MAX; + modes.push_back(loop); + + mode off; + off.name = "Off"; + off.value = INSTANT_MOUSE_OFF_MODE; + + modes.push_back(off); + + SetupZones(); +} + +RGBController_InstantMouse::~RGBController_InstantMouse() +{ + delete controller; +} + +void RGBController_InstantMouse::SetupZones() +{ + zone new_zone; + + new_zone.name = "Mouse"; + new_zone.type = ZONE_TYPE_LINEAR; + new_zone.leds_min = 1; + new_zone.leds_max = 1; + new_zone.leds_count = 1; + new_zone.matrix_map = nullptr; + + zones.emplace_back(new_zone); + + leds.resize(1); + leds[0].name = "Mouse"; + + SetupColors(); +} + +void RGBController_InstantMouse::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_InstantMouse::DeviceUpdateLEDs() +{ + controller->SendColor(colors[0]); +} + +void RGBController_InstantMouse::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_InstantMouse::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_InstantMouse::DeviceUpdateMode() +{ + if(modes[active_mode].value == INSTANT_MOUSE_OFF_MODE) + { + controller->SetMode(INSTANT_MOUSE_DIRECT_MODE, 0, 0, 0); + controller->SendColor(0); + } + else + { + controller->SetMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, modes[active_mode].direction); + + if(modes[active_mode].colors.size() == 1) + { + controller->SendColor(modes[active_mode].colors[0]); + } + } +} diff --git a/Controllers/InstantMouseController/RGBController_InstantMouse.h b/Controllers/InstantMouseController/RGBController_InstantMouse.h new file mode 100644 index 00000000..9d907fa7 --- /dev/null +++ b/Controllers/InstantMouseController/RGBController_InstantMouse.h @@ -0,0 +1,32 @@ +/*-----------------------------------------*\ +| RGBController_InstantMouse.h | +| | +| Generic RGB Interface for OpenRGB | +| Instant mouse RGB USB Driver | +| | +| Guimard Morgan (morg) 1/19/2024 | +\*-----------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "InstantMouseController.h" + +class RGBController_InstantMouse : public RGBController +{ +public: + RGBController_InstantMouse(InstantMouseController* controller_ptr); + ~RGBController_InstantMouse(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + InstantMouseController* controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 7b6ab12f..95620702 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -177,6 +177,7 @@ INCLUDEPATH += Controllers/HyperXMouseController/ \ Controllers/HyperXMousematController/ \ Controllers/HYTEMousematController/ \ + Controllers/InstantMouseController/ \ Controllers/IntelArcA770LEController/ \ Controllers/IonicoController/ \ Controllers/JGINYUEInternalUSBController/ \ @@ -565,6 +566,8 @@ HEADERS += Controllers/HyperXMouseController/RGBController_HyperXPulsefireRaid.h \ Controllers/HyperXMousematController/HyperXMousematController.h \ Controllers/HyperXMousematController/RGBController_HyperXMousemat.h \ + Controllers/InstantMouseController/InstantMouseController.h \ + Controllers/InstantMouseController/RGBController_InstantMouse.h \ Controllers/IntelArcA770LEController/IntelArcA770LEController.h \ Controllers/IntelArcA770LEController/RGBController_IntelArcA770LE.h \ Controllers/IonicoController/IonicoController.h \ @@ -1263,6 +1266,9 @@ SOURCES += Controllers/HyperXMousematController/HyperXMousematController.cpp \ Controllers/HyperXMousematController/HyperXMousematControllerDetect.cpp \ Controllers/HyperXMousematController/RGBController_HyperXMousemat.cpp \ + Controllers/InstantMouseController/InstantMouseController.cpp \ + Controllers/InstantMouseController/InstantMouseControllerDetect.cpp \ + Controllers/InstantMouseController/RGBController_InstantMouse.cpp \ Controllers/IntelArcA770LEController/IntelArcA770LEController.cpp \ Controllers/IntelArcA770LEController/IntelArcA770LEControllerDetect.cpp \ Controllers/IonicoController/IonicoController.cpp \