From a818e94ee7c014b790a975caa0af3124ccefff15 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Sun, 12 Jan 2025 17:23:17 -0600 Subject: [PATCH] Initial commit of AOC GH300 headset controller --- .../AOCHeadsetController.cpp | 225 ++++++++++++++++++ .../AOCHeadsetController.h | 72 ++++++ .../AOCHeadsetControllerDetect.cpp | 44 ++++ .../RGBController_AOCHeadset.cpp | 94 ++++++++ .../RGBController_AOCHeadset.h | 35 +++ 5 files changed, 470 insertions(+) create mode 100644 Controllers/AOCHeadsetController/AOCHeadsetController.cpp create mode 100644 Controllers/AOCHeadsetController/AOCHeadsetController.h create mode 100644 Controllers/AOCHeadsetController/AOCHeadsetControllerDetect.cpp create mode 100644 Controllers/AOCHeadsetController/RGBController_AOCHeadset.cpp create mode 100644 Controllers/AOCHeadsetController/RGBController_AOCHeadset.h diff --git a/Controllers/AOCHeadsetController/AOCHeadsetController.cpp b/Controllers/AOCHeadsetController/AOCHeadsetController.cpp new file mode 100644 index 000000000..606fdc11d --- /dev/null +++ b/Controllers/AOCHeadsetController/AOCHeadsetController.cpp @@ -0,0 +1,225 @@ +/*---------------------------------------------------------*\ +| AOCHeadsetController.cpp | +| | +| Driver for AOC headset | +| | +| Adam Honse (CalcProgrammer1) 12 Jan 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include +#include "AOCHeadsetController.h" +#include "StringUtils.h" + +AOCHeadsetController::AOCHeadsetController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; + + unsigned char usb_buf[16]; + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xED; + + hid_write(dev, usb_buf, 2); + + SendStartPacket(); + SendBeginPacket(); + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xED; + usb_buf[1] = 0x04; + usb_buf[2] = 0x02; + + usb_buf[5] = 0x01; + + hid_send_feature_report(dev, usb_buf, sizeof(usb_buf)); + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xED; + usb_buf[1] = 0x04; + usb_buf[2] = 0x04; + + usb_buf[4] = 0x05; + usb_buf[5] = 0xC8; + + hid_send_feature_report(dev, usb_buf, sizeof(usb_buf)); + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xED; + usb_buf[1] = 0x04; + usb_buf[2] = 0x06; + + usb_buf[4] = 0x03; + + hid_send_feature_report(dev, usb_buf, sizeof(usb_buf)); + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xED; + usb_buf[1] = 0x02; + usb_buf[2] = 0x08; + + hid_send_feature_report(dev, usb_buf, sizeof(usb_buf)); + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xED; + usb_buf[1] = 0x03; + usb_buf[2] = 0x09; + + hid_send_feature_report(dev, usb_buf, sizeof(usb_buf)); + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xED; + usb_buf[1] = 0x03; + usb_buf[2] = 0x0A; + + hid_send_feature_report(dev, usb_buf, sizeof(usb_buf)); + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xED; + usb_buf[1] = 0x02; + usb_buf[2] = 0x0B; + usb_buf[3] = 0x01; + + hid_send_feature_report(dev, usb_buf, sizeof(usb_buf)); + + SendModePacket(0); + + RGBColor color_data = 0; + SendColorPacket(&color_data); + + SendApplyPacket(); + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xED; + usb_buf[1] = 0x02; + usb_buf[2] = 0x0B; + usb_buf[3] = 0x01; + + hid_send_feature_report(dev, usb_buf, sizeof(usb_buf)); + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xED; + usb_buf[1] = 0x03; + usb_buf[2] = 0x0A; + usb_buf[3] = 0x01; + usb_buf[4] = 0x01; + + hid_send_feature_report(dev, usb_buf, sizeof(usb_buf)); +} + +AOCHeadsetController::~AOCHeadsetController() +{ + hid_close(dev); +} + +std::string AOCHeadsetController::GetDeviceLocation() +{ + return("HID " + location); +} + +std::string AOCHeadsetController::GetSerialString() +{ + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + return(""); + } + + return(StringUtils::wstring_to_string(serial_string)); +} + +/*-------------------------------------------------------------------------------------------------*\ +| Private packet sending functions. | +\*-------------------------------------------------------------------------------------------------*/ + +void AOCHeadsetController::SendDirect + ( + RGBColor* color_data + ) +{ + SendStartPacket(); + SendModePacket(0); + SendColorPacket(color_data); + SendApplyPacket(); +} + +void AOCHeadsetController::SendStartPacket() +{ + unsigned char usb_buf[16]; + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xFF; + usb_buf[1] = 0x02; + + hid_write(dev, usb_buf, sizeof(usb_buf)); +} + +void AOCHeadsetController::SendBeginPacket() +{ + unsigned char usb_buf[16]; + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xFD; + usb_buf[1] = 0x01; + + hid_write(dev, usb_buf, sizeof(usb_buf)); +} + +void AOCHeadsetController::SendModePacket(unsigned char mode) +{ + unsigned char usb_buf[16]; + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xFF; + usb_buf[1] = 0x03; + usb_buf[2] = mode; + usb_buf[3] = 0x01; + + hid_write(dev, usb_buf, sizeof(usb_buf)); +} + +void AOCHeadsetController::SendColorPacket(RGBColor* color_data) +{ + unsigned char usb_buf[16]; + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xFF; + usb_buf[1] = 0x04; + + usb_buf[4] = RGBGetRValue(color_data[0]); + usb_buf[5] = RGBGetGValue(color_data[0]); + usb_buf[6] = RGBGetBValue(color_data[0]); + + hid_write(dev, usb_buf, sizeof(usb_buf)); +} + +void AOCHeadsetController::SendApplyPacket() +{ + unsigned char usb_buf[16]; + + memset(usb_buf, 0, sizeof(usb_buf)); + + usb_buf[0] = 0xFF; + usb_buf[1] = 0x01; + + hid_write(dev, usb_buf, sizeof(usb_buf)); +} diff --git a/Controllers/AOCHeadsetController/AOCHeadsetController.h b/Controllers/AOCHeadsetController/AOCHeadsetController.h new file mode 100644 index 000000000..861ac01f2 --- /dev/null +++ b/Controllers/AOCHeadsetController/AOCHeadsetController.h @@ -0,0 +1,72 @@ +/*---------------------------------------------------------*\ +| AOCHeadsetController.h | +| | +| Driver for AOC headset | +| | +| Adam Honse (CalcProgrammer1) 12 Jan 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include +#include "RGBController.h" + +/*-----------------------------------------*\ +| AOC Mousemat Modes | +| Note: The 0x80 bit is the random flag | +\*-----------------------------------------*/ +enum +{ + AOC_HEADSET_MODE_STATIC_SINGLE_COLOR = 0x00, /* Static mode */ + AOC_HEADSET_MODE_BLINKING = 0x01, /* Blinking mode */ + AOC_HEADSET_MODE_BREATHING = 0x02, /* Breathing mode */ + AOC_HEADSET_MODE_MUSIC = 0x03, /* Music mode */ +}; + +enum +{ + AOC_HEADSET_SPEED_SLOW = 0x03, /* Slowest speed */ + AOC_HEADSET_SPEED_MEDIUM = 0x02, /* Medium speed */ + AOC_HEADSET_SPEED_FAST = 0x01, /* Fastest speed */ +}; + +class AOCHeadsetController +{ +public: + AOCHeadsetController(hid_device* dev_handle, const char* path); + ~AOCHeadsetController(); + + std::string GetDeviceLocation(); + std::string GetSerialString(); + + void SendDirect + ( + RGBColor* color_data + ); + + void SendPacket + ( + unsigned char mode, + unsigned char brightness, + unsigned char speed, + unsigned char direction, + RGBColor* color_data + ); + +private: + hid_device* dev; + std::string location; + + void SendStartPacket(); + + void SendModePacket(unsigned char mode); + void SendBeginPacket(); + + void SendColorPacket(RGBColor* color_data); + + void SendApplyPacket(); +}; diff --git a/Controllers/AOCHeadsetController/AOCHeadsetControllerDetect.cpp b/Controllers/AOCHeadsetController/AOCHeadsetControllerDetect.cpp new file mode 100644 index 000000000..eca25859b --- /dev/null +++ b/Controllers/AOCHeadsetController/AOCHeadsetControllerDetect.cpp @@ -0,0 +1,44 @@ +/*---------------------------------------------------------*\ +| AOCHeadsetControllerDetect.cpp | +| | +| Detector for AOC headset | +| | +| Adam Honse (CalcProgrammer1) 12 Jan 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include "Detector.h" +#include "AOCHeadsetController.h" +#include "RGBController_AOCHeadset.h" + +/*-----------------------------------------------------*\ +| AOC Headset IDs | +\*-----------------------------------------------------*/ +#define AOC_VID 0x0D8C +#define AOC_GH300_PID 0x01F3 + +/******************************************************************************************\ +* * +* DetectAOCHeadsetControllers * +* * +* Tests the USB address to see if an AOC Headset controller exists there. * +* * +\******************************************************************************************/ + +void DetectAOCHeadsetControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + AOCHeadsetController* controller = new AOCHeadsetController(dev, info->path); + RGBController_AOCHeadset* rgb_controller = new RGBController_AOCHeadset(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR_IPU("AOC GH300", DetectAOCHeadsetControllers, AOC_VID, AOC_GH300_PID, 3, 0x000C, 0x0001); diff --git a/Controllers/AOCHeadsetController/RGBController_AOCHeadset.cpp b/Controllers/AOCHeadsetController/RGBController_AOCHeadset.cpp new file mode 100644 index 000000000..f7a072055 --- /dev/null +++ b/Controllers/AOCHeadsetController/RGBController_AOCHeadset.cpp @@ -0,0 +1,94 @@ +/*---------------------------------------------------------*\ +| RGBController_AOCHeadset.cpp | +| | +| RGBController for AOC headset | +| | +| Adam Honse (CalcProgrammer1) 12 Jan 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include "RGBController_AOCHeadset.h" + +/**------------------------------------------------------------------*\ + @name AOC Headset + @category Headset + @type USB + @save :x: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectAOCHeadsetControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_AOCHeadset::RGBController_AOCHeadset(AOCHeadsetController* controller_ptr) +{ + controller = controller_ptr; + + name = "AOC Headset Device"; + vendor = "AOC"; + type = DEVICE_TYPE_HEADSET; + description = "AOC Headset Device"; + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + + mode direct; + direct.name = "Direct"; + direct.value = 0; + direct.color_mode = MODE_COLORS_PER_LED; + direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + modes.push_back(direct); + + SetupZones(); +}; + +RGBController_AOCHeadset::~RGBController_AOCHeadset() +{ + delete controller; +} + +void RGBController_AOCHeadset::SetupZones() +{ + zone headset_zone; + headset_zone.name = "Headset"; + headset_zone.type = ZONE_TYPE_SINGLE; + headset_zone.leds_min = 1; + headset_zone.leds_max = 1; + headset_zone.leds_count = 1; + headset_zone.matrix_map = NULL; + zones.push_back(headset_zone); + + led headset_led; + headset_led.name = "Headset"; + leds.push_back(headset_led); + + SetupColors(); +} + +void RGBController_AOCHeadset::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_AOCHeadset::DeviceUpdateLEDs() +{ + DeviceUpdateMode(); +} + +void RGBController_AOCHeadset::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_AOCHeadset::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_AOCHeadset::DeviceUpdateMode() +{ + controller->SendDirect(&colors[0]); +} diff --git a/Controllers/AOCHeadsetController/RGBController_AOCHeadset.h b/Controllers/AOCHeadsetController/RGBController_AOCHeadset.h new file mode 100644 index 000000000..13b9d11f2 --- /dev/null +++ b/Controllers/AOCHeadsetController/RGBController_AOCHeadset.h @@ -0,0 +1,35 @@ +/*---------------------------------------------------------*\ +| RGBController_AOCHeadset.h | +| | +| RGBController for AOC headset | +| | +| Adam Honse (CalcProgrammer1) 12 Jan 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "AOCHeadsetController.h" + +class RGBController_AOCHeadset : public RGBController +{ +public: + RGBController_AOCHeadset(AOCHeadsetController* controller_ptr); + ~RGBController_AOCHeadset(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + AOCHeadsetController* controller; +};