Publish LumaOps source
This commit is contained in:
@@ -0,0 +1,298 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMARGBController.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master ARGB controller |
|
||||
| |
|
||||
| Chris M (Dr_No) 10 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CMARGBController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Map to convert port index to port ID used in protocol |
|
||||
\*---------------------------------------------------------*/
|
||||
static unsigned char cm_argb_port_index_to_id[5] =
|
||||
{
|
||||
CM_ARGB_PORT_ARGB_1,
|
||||
CM_ARGB_PORT_ARGB_2,
|
||||
CM_ARGB_PORT_ARGB_3,
|
||||
CM_ARGB_PORT_ARGB_4,
|
||||
CM_ARGB_PORT_RGB
|
||||
};
|
||||
|
||||
CMARGBController::CMARGBController(hid_device* dev_handle, char *path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get device name from HID manufacturer and product |
|
||||
| strings |
|
||||
\*-----------------------------------------------------*/
|
||||
wchar_t name_string[HID_MAX_STR];
|
||||
|
||||
hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
|
||||
device_name = StringUtils::wstring_to_string(name_string);
|
||||
|
||||
hid_get_product_string(dev, name_string, HID_MAX_STR);
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
}
|
||||
|
||||
CMARGBController::~CMARGBController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string CMARGBController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string CMARGBController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string CMARGBController::GetVersion()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| This device uses the serial value to determine the |
|
||||
| version. It does not report a proper unique serial. |
|
||||
\*-----------------------------------------------------*/
|
||||
std::string serial_string = GetSerial();
|
||||
|
||||
if(serial_string == CM_ARGB_FW0023)
|
||||
{
|
||||
return("0023");
|
||||
}
|
||||
else if(serial_string == CM_ARGB_FW0028)
|
||||
{
|
||||
return("0028");
|
||||
}
|
||||
else
|
||||
{
|
||||
return("Unsupported");
|
||||
}
|
||||
}
|
||||
|
||||
std::string CMARGBController::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[HID_MAX_STR];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, HID_MAX_STR);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void CMARGBController::GetPortStatus
|
||||
(
|
||||
unsigned char port_idx,
|
||||
unsigned char* port_mode,
|
||||
unsigned char* port_speed,
|
||||
unsigned char* port_brightness,
|
||||
bool* port_random,
|
||||
unsigned char* port_red,
|
||||
unsigned char* port_green,
|
||||
unsigned char* port_blue
|
||||
)
|
||||
{
|
||||
unsigned char buffer[CM_ARGB_PACKET_SIZE] = {0x00, 0x80, 0x0B, 0x01};
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
int rgb_offset = 0;
|
||||
int zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| RGB port is handled differently from ARGB ports |
|
||||
\*-----------------------------------------------------*/
|
||||
if(cm_argb_port_index_to_id[port_idx] != CM_ARGB_PORT_RGB)
|
||||
{
|
||||
zone = cm_argb_port_index_to_id[port_idx];
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x0B;
|
||||
}
|
||||
else
|
||||
{
|
||||
zone = 0x00;
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x0A;
|
||||
rgb_offset = 1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If this is the group then just return the first |
|
||||
| status |
|
||||
\*-----------------------------------------------------*/
|
||||
buffer[CM_ARGB_ZONE_BYTE] = ( zone > 0x08 ) ? 0x01 : zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the command and read the response |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_ARGB_INTERRUPT_TIMEOUT);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read data out of response |
|
||||
\*-----------------------------------------------------*/
|
||||
*port_mode = buffer[4 - rgb_offset];
|
||||
*port_random = (buffer[5 - rgb_offset] == 0x00);
|
||||
*port_speed = buffer[6 - rgb_offset];
|
||||
*port_brightness = buffer[7 - rgb_offset];
|
||||
*port_red = buffer[8 - rgb_offset];
|
||||
*port_green = buffer[9 - rgb_offset];
|
||||
*port_blue = buffer[10 - rgb_offset];
|
||||
}
|
||||
|
||||
void CMARGBController::SetPortLEDCount(unsigned char port_idx, unsigned char led_count)
|
||||
{
|
||||
unsigned char buffer[CM_ARGB_PACKET_SIZE] = {0x00, 0x80, 0x0D, 0x02};
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
buffer[CM_ARGB_ZONE_BYTE] = cm_argb_port_index_to_id[port_idx];
|
||||
buffer[CM_ARGB_MODE_BYTE] = led_count;
|
||||
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = 1;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the command |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
|
||||
void CMARGBController::SetPortMode
|
||||
(
|
||||
unsigned char port_idx,
|
||||
unsigned char port_mode,
|
||||
unsigned char port_speed,
|
||||
unsigned char port_brightness,
|
||||
bool port_random,
|
||||
unsigned char port_red,
|
||||
unsigned char port_green,
|
||||
unsigned char port_blue
|
||||
)
|
||||
{
|
||||
unsigned char buffer[CM_ARGB_PACKET_SIZE] = {0x00};
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
bool boolARGB_header = (cm_argb_port_index_to_id[port_idx] != CM_ARGB_PORT_RGB);
|
||||
bool boolPassthru = (port_mode == CM_ARGB_MODE_PASSTHRU) || (port_mode == CM_RGB_MODE_PASSTHRU);
|
||||
bool boolDirect = (port_mode == CM_ARGB_MODE_DIRECT);
|
||||
unsigned char function = boolPassthru ? (boolARGB_header ? 0x02 : 0x04) : (boolARGB_header ? 0x01 : 0x03);
|
||||
buffer[CM_ARGB_REPORT_BYTE] = 0x80;
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x01;
|
||||
|
||||
if(boolDirect)
|
||||
{
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = 0x01;
|
||||
buffer[CM_ARGB_ZONE_BYTE] = 0x02;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Send the command |
|
||||
\*-------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Direct mode is now set up and no other mode |
|
||||
| packet is required |
|
||||
\*-------------------------------------------------*/
|
||||
return;
|
||||
}
|
||||
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = function;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the command |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| ARGB ports send command 0x0B, RGB port sends 0x04 |
|
||||
\*-----------------------------------------------------*/
|
||||
if(boolARGB_header)
|
||||
{
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = 0x0B;
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = (false) ? 0x01 : 0x02;
|
||||
buffer[CM_ARGB_ZONE_BYTE] = cm_argb_port_index_to_id[port_idx];
|
||||
buffer[CM_ARGB_MODE_BYTE] = port_mode;
|
||||
buffer[CM_ARGB_COLOUR_INDEX_BYTE] = port_random ? 0x00 : 0x10;
|
||||
buffer[CM_ARGB_SPEED_BYTE] = port_speed;
|
||||
buffer[CM_ARGB_BRIGHTNESS_BYTE] = port_brightness;
|
||||
buffer[CM_ARGB_RED_BYTE] = port_red;
|
||||
buffer[CM_ARGB_GREEN_BYTE] = port_green;
|
||||
buffer[CM_ARGB_BLUE_BYTE] = port_blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[CM_ARGB_COMMAND_BYTE] = boolPassthru ? 0x01 : 0x04;
|
||||
buffer[CM_ARGB_MODE_BYTE + CM_RGB_OFFSET] = port_mode;
|
||||
buffer[CM_ARGB_COLOUR_INDEX_BYTE + CM_RGB_OFFSET] = port_random ? 0x00 : 0x10;
|
||||
buffer[CM_ARGB_SPEED_BYTE + CM_RGB_OFFSET] = port_speed;
|
||||
buffer[CM_ARGB_BRIGHTNESS_BYTE + CM_RGB_OFFSET] = port_brightness;
|
||||
buffer[CM_ARGB_RED_BYTE + CM_RGB_OFFSET] = port_red;
|
||||
buffer[CM_ARGB_GREEN_BYTE + CM_RGB_OFFSET] = port_green;
|
||||
buffer[CM_ARGB_BLUE_BYTE + CM_RGB_OFFSET] = port_blue;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the command and wait for response |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
|
||||
void CMARGBController::SetPortLEDsDirect(unsigned char port_idx, RGBColor *led_colours, unsigned int led_count)
|
||||
{
|
||||
const unsigned char buffer_size = CM_ARGB_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { 0x00, 0x00, 0x07, 0x02 };
|
||||
unsigned char packet_count = 0;
|
||||
std::vector<uint8_t> colours;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up the RGB triplets to send |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < led_count; i++)
|
||||
{
|
||||
RGBColor colour = led_colours[i];
|
||||
|
||||
colours.push_back(RGBGetRValue(colour));
|
||||
colours.push_back(RGBGetGValue(colour));
|
||||
colours.push_back(RGBGetBValue(colour));
|
||||
}
|
||||
|
||||
buffer[CM_ARGB_FUNCTION_BYTE] = port_idx;
|
||||
buffer[CM_ARGB_ZONE_BYTE] = led_count;
|
||||
unsigned char buffer_idx = CM_ARGB_MODE_BYTE;
|
||||
|
||||
for(std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = CM_ARGB_COMMAND_BYTE)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Fill the write buffer till its full or the |
|
||||
| colour buffer is empty |
|
||||
\*-------------------------------------------------*/
|
||||
buffer[CM_ARGB_REPORT_BYTE] = packet_count;
|
||||
while((buffer_idx < buffer_size) && (it != colours.end()))
|
||||
{
|
||||
buffer[buffer_idx] = *it;
|
||||
buffer_idx++;
|
||||
it++;
|
||||
}
|
||||
|
||||
if(it == colours.end())
|
||||
{
|
||||
buffer[CM_ARGB_REPORT_BYTE] += 0x80;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Send the buffer |
|
||||
\*-------------------------------------------------*/
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Reset the write buffer |
|
||||
\*-------------------------------------------------*/
|
||||
memset(buffer, 0x00, buffer_size );
|
||||
packet_count++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMARGBController.h |
|
||||
| |
|
||||
| Driver for Cooler Master ARGB controller |
|
||||
| |
|
||||
| Chris M (Dr_No) 10 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define CM_ARGB_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
|
||||
#define CM_ARGB_HEADER_DATA_SIZE (sizeof(argb_header_data) / sizeof(argb_headers) )
|
||||
#define CM_ARGB_INTERRUPT_TIMEOUT 250
|
||||
#define CM_ARGB_PACKET_SIZE 65
|
||||
#define CM_ARGB_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
|
||||
#define CM_RGB_OFFSET -2
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
#define CM_ARGB_BRIGHTNESS_MAX 255
|
||||
#define CM_ARGB_FW0000 std::string("A201804091608")
|
||||
#define CM_ARGB_FW0023 std::string("A202011171238")
|
||||
#define CM_ARGB_FW0028 std::string("A202105291658")
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_REPORT_BYTE = 1,
|
||||
CM_ARGB_COMMAND_BYTE = 2,
|
||||
CM_ARGB_FUNCTION_BYTE = 3,
|
||||
CM_ARGB_ZONE_BYTE = 4,
|
||||
CM_ARGB_MODE_BYTE = 5,
|
||||
CM_ARGB_COLOUR_INDEX_BYTE = 6,
|
||||
CM_ARGB_SPEED_BYTE = 7,
|
||||
CM_ARGB_BRIGHTNESS_BYTE = 8,
|
||||
CM_ARGB_RED_BYTE = 9,
|
||||
CM_ARGB_GREEN_BYTE = 10,
|
||||
CM_ARGB_BLUE_BYTE = 11
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_PORT_ARGB_1 = 0x01,
|
||||
CM_ARGB_PORT_ARGB_2 = 0x02,
|
||||
CM_ARGB_PORT_ARGB_3 = 0x04,
|
||||
CM_ARGB_PORT_ARGB_4 = 0x08,
|
||||
CM_ARGB_PORT_RGB = 0xFE,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_RGB_MODE_MIRAGE = 0x01, //Mirage
|
||||
CM_RGB_MODE_FLASH = 0x02, //Flash
|
||||
CM_RGB_MODE_BREATHING = 0x03, //Breathing
|
||||
CM_RGB_MODE_STATIC = 0x05, //Static
|
||||
CM_RGB_MODE_OFF = 0x06, //Turn off
|
||||
CM_RGB_MODE_PASSTHRU = 0xFF //Motherboard Pass Thru Mode
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_MODE_OFF = 0x0B, //Turn off
|
||||
CM_ARGB_MODE_SPECTRUM = 0x01, //Spectrum Mode
|
||||
CM_ARGB_MODE_RELOAD = 0x02, //Reload Mode
|
||||
CM_ARGB_MODE_RECOIL = 0x03, //Recoil Mode
|
||||
CM_ARGB_MODE_BREATHING = 0x04, //Breathing Mode
|
||||
CM_ARGB_MODE_REFILL = 0x05, //Refill Mode
|
||||
CM_ARGB_MODE_DEMO = 0x06, //Demo Mode
|
||||
CM_ARGB_MODE_FILLFLOW = 0x08, //Fill Flow Mode
|
||||
CM_ARGB_MODE_RAINBOW = 0x09, //Rainbow Mode
|
||||
CM_ARGB_MODE_STATIC = 0x0A, //Static Mode
|
||||
CM_ARGB_MODE_DIRECT = 0xFE, //Direct Led Control
|
||||
CM_ARGB_MODE_PASSTHRU = 0xFF //Motherboard Pass Thru Mode
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_SPEED_SLOWEST = 0x00, // Slowest speed
|
||||
CM_ARGB_SPEED_SLOW = 0x01, // Slower speed
|
||||
CM_ARGB_SPEED_NORMAL = 0x02, // Normal speed
|
||||
CM_ARGB_SPEED_FAST = 0x03, // Fast speed
|
||||
CM_ARGB_SPEED_FASTEST = 0x04, // Fastest speed
|
||||
};
|
||||
|
||||
class CMARGBController
|
||||
{
|
||||
public:
|
||||
CMARGBController(hid_device* dev_handle, char* path);
|
||||
~CMARGBController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
std::string GetVersion();
|
||||
|
||||
void GetPortStatus
|
||||
(
|
||||
unsigned char port_idx,
|
||||
unsigned char* port_mode,
|
||||
unsigned char* port_speed,
|
||||
unsigned char* port_brightness,
|
||||
bool* port_random,
|
||||
unsigned char* port_red,
|
||||
unsigned char* port_green,
|
||||
unsigned char* port_blue
|
||||
);
|
||||
|
||||
void SetPortLEDCount(unsigned char port_idx, unsigned char led_count);
|
||||
|
||||
void SetPortMode
|
||||
(
|
||||
unsigned char port_idx,
|
||||
unsigned char port_mode,
|
||||
unsigned char port_speed,
|
||||
unsigned char port_brightness,
|
||||
bool port_random,
|
||||
unsigned char port_red,
|
||||
unsigned char port_green,
|
||||
unsigned char port_blue
|
||||
);
|
||||
|
||||
void SetPortLEDsDirect(unsigned char port_idx, RGBColor *led_colours, unsigned int led_count);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
};
|
||||
+440
@@ -0,0 +1,440 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMARGBController.cpp |
|
||||
| |
|
||||
| RGBController for Cooler Master ARGB controller |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CMARGBController.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Coolermaster ARGB
|
||||
@category LEDStrip
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterARGB
|
||||
@comment The Coolermaster ARGB device supports `Direct` mode from
|
||||
firmware 0028 onwards. Check the serial number for the date
|
||||
"A202105291658" or newer.
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMARGBController::RGBController_CMARGBController(CMARGBController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Cooler Master";
|
||||
type = DEVICE_TYPE_LEDSTRIP;
|
||||
description = "Cooler Master ARGB Controller Device";
|
||||
version = controller->GetVersion();
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The ARGB ports support more modes than the RGB port. |
|
||||
| Define all of the modes the ARGB ports support and |
|
||||
| map RGB modes to them as best as we can. Per-zone |
|
||||
| support will be added in the future. |
|
||||
\*-----------------------------------------------------*/
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = CM_ARGB_MODE_OFF;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Reload;
|
||||
Reload.name = "Reload";
|
||||
Reload.value = CM_ARGB_MODE_RELOAD;
|
||||
Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Reload.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Reload.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Reload.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Reload.brightness_min = 0;
|
||||
Reload.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Reload.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Reload.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Reload.colors_min = 1;
|
||||
Reload.colors_max = 1;
|
||||
Reload.colors.resize(Reload.colors_max);
|
||||
modes.push_back(Reload);
|
||||
|
||||
mode Recoil;
|
||||
Recoil.name = "Recoil";
|
||||
Recoil.value = CM_ARGB_MODE_RECOIL;
|
||||
Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Recoil.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Recoil.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Recoil.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Recoil.brightness_min = 0;
|
||||
Recoil.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Recoil.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Recoil.colors_min = 1;
|
||||
Recoil.colors_max = 1;
|
||||
Recoil.colors.resize(Recoil.colors_max);
|
||||
modes.push_back(Recoil);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_ARGB_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Breathing.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Breathing.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(Breathing.colors_max);
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Refill;
|
||||
Refill.name = "Refill";
|
||||
Refill.value = CM_ARGB_MODE_REFILL;
|
||||
Refill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Refill.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Refill.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Refill.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Refill.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Refill.brightness_min = 0;
|
||||
Refill.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Refill.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Refill.colors_min = 1;
|
||||
Refill.colors_max = 1;
|
||||
Refill.colors.resize(Refill.colors_max);
|
||||
modes.push_back(Refill);
|
||||
|
||||
mode Demo;
|
||||
Demo.name = "Demo";
|
||||
Demo.value = CM_ARGB_MODE_DEMO;
|
||||
Demo.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Demo.color_mode = MODE_COLORS_NONE;
|
||||
Demo.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Demo.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Demo.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Demo.brightness_min = 0;
|
||||
Demo.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Demo.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
modes.push_back(Demo);
|
||||
|
||||
mode Spectrum;
|
||||
Spectrum.name = "Rainbow Wave";
|
||||
Spectrum.value = CM_ARGB_MODE_SPECTRUM;
|
||||
Spectrum.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Spectrum.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Spectrum.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Spectrum.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Spectrum.brightness_min = 0;
|
||||
Spectrum.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Spectrum.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
modes.push_back(Spectrum);
|
||||
|
||||
mode FillFlow;
|
||||
FillFlow.name = "Fill Flow";
|
||||
FillFlow.value = CM_ARGB_MODE_FILLFLOW;
|
||||
FillFlow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
FillFlow.color_mode = MODE_COLORS_NONE;
|
||||
FillFlow.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
FillFlow.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
FillFlow.speed = CM_ARGB_SPEED_NORMAL;
|
||||
FillFlow.brightness_min = 0;
|
||||
FillFlow.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
FillFlow.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
modes.push_back(FillFlow);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CM_ARGB_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Rainbow.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Rainbow.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Rainbow.brightness_min = 0;
|
||||
Rainbow.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Rainbow.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CM_ARGB_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.speed_min = CM_ARGB_SPEED_SLOWEST;
|
||||
Static.speed_max = CM_ARGB_SPEED_FASTEST;
|
||||
Static.speed = CM_ARGB_SPEED_NORMAL;
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Static.brightness = CM_ARGB_BRIGHTNESS_MAX;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(Static.colors_max);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = (serial >= CM_ARGB_FW0028) ? "Direct" : "Custom";
|
||||
Direct.value = CM_ARGB_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode PassThru;
|
||||
PassThru.name = "Pass Thru";
|
||||
PassThru.value = CM_ARGB_MODE_PASSTHRU;
|
||||
PassThru.flags = 0;
|
||||
PassThru.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(PassThru);
|
||||
|
||||
SetupZones();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize the active mode to port 0 |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char port_mode;
|
||||
unsigned char port_speed;
|
||||
unsigned char port_brightness;
|
||||
bool port_random;
|
||||
unsigned char port_red;
|
||||
unsigned char port_green;
|
||||
unsigned char port_blue;
|
||||
|
||||
controller->GetPortStatus(0, &port_mode, &port_speed, &port_brightness, &port_random, &port_red, &port_green, &port_blue);
|
||||
|
||||
for(std::size_t mode_idx = 0; mode_idx < modes.size(); mode_idx++)
|
||||
{
|
||||
if(modes[mode_idx].value == port_mode)
|
||||
{
|
||||
active_mode = (int)mode_idx;
|
||||
|
||||
if((modes[mode_idx].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR) && (modes[mode_idx].colors.size() > 0))
|
||||
{
|
||||
modes[mode_idx].colors[0] = ToRGBColor(port_red, port_green, port_blue);
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
modes[mode_idx].speed = port_speed;
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
modes[mode_idx].brightness = port_brightness;
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_RANDOM_COLOR)
|
||||
{
|
||||
if(port_random)
|
||||
{
|
||||
modes[mode_idx].color_mode = MODE_COLORS_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RGBController_CMARGBController::~RGBController_CMARGBController()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::SetupZones()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Only set LED count on the first run |
|
||||
\*-----------------------------------------------------*/
|
||||
bool first_run = false;
|
||||
|
||||
if(zones.size() == 0)
|
||||
{
|
||||
first_run = true;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Clear any existing color/LED configuration |
|
||||
\*-----------------------------------------------------*/
|
||||
leds.clear();
|
||||
colors.clear();
|
||||
zones.resize(5);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up addressable zones |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int channel_idx = 0; channel_idx < 4; channel_idx++)
|
||||
{
|
||||
char ch_idx_string[2];
|
||||
snprintf(ch_idx_string, 2, "%d", channel_idx + 1);
|
||||
|
||||
zones[channel_idx].name = "Addressable RGB Header ";
|
||||
zones[channel_idx].name.append(ch_idx_string);
|
||||
zones[channel_idx].type = ZONE_TYPE_LINEAR;
|
||||
zones[channel_idx].leds_min = 0;
|
||||
zones[channel_idx].leds_max = 48;
|
||||
|
||||
if(first_run)
|
||||
{
|
||||
zones[channel_idx].leds_count = 0;
|
||||
}
|
||||
|
||||
zones[channel_idx].matrix_map = NULL;
|
||||
|
||||
for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
|
||||
{
|
||||
char led_idx_string[4];
|
||||
snprintf(led_idx_string, 4, "%d", led_ch_idx + 1);
|
||||
|
||||
led new_led;
|
||||
new_led.name = zones[channel_idx].name;
|
||||
new_led.name.append(", LED ");
|
||||
new_led.name.append(led_idx_string);
|
||||
new_led.value = channel_idx;
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up RGB zone |
|
||||
\*-----------------------------------------------------*/
|
||||
zones[4].name = "RGB Header";
|
||||
zones[4].type = ZONE_TYPE_SINGLE;
|
||||
zones[4].leds_min = 1;
|
||||
zones[4].leds_max = 1;
|
||||
zones[4].leds_count = 1;
|
||||
zones[4].matrix_map = NULL;
|
||||
|
||||
led new_led;
|
||||
new_led.name = "RGB Header";
|
||||
new_led.value = 4;
|
||||
leds.push_back(new_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::ResizeZone(int zone, int new_size)
|
||||
{
|
||||
if((size_t) zone >= zones.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
|
||||
{
|
||||
zones[zone].leds_count = new_size;
|
||||
|
||||
controller->SetPortLEDCount(zone, zones[zone].leds_count);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::DeviceUpdateLEDs()
|
||||
{
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
UpdateZoneLEDs((int)zone_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| The RGB zone doesn't have a separate Direct mode, so |
|
||||
| use static mode with the per-LED color for it |
|
||||
\*-----------------------------------------------------*/
|
||||
if(zone < 4)
|
||||
{
|
||||
controller->SetPortLEDsDirect(zone, zones[zone].colors, zones[zone].leds_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetPortMode(zone, CM_RGB_MODE_STATIC, 0, 255, false, RGBGetRValue(zones[zone].colors[0]), RGBGetGValue(zones[zone].colors[0]), RGBGetBValue(zones[zone].colors[0]));
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::UpdateSingleLED(int led)
|
||||
{
|
||||
unsigned int zone_idx = leds[led].value;
|
||||
|
||||
UpdateZoneLEDs(zone_idx);
|
||||
}
|
||||
|
||||
void RGBController_CMARGBController::DeviceUpdateMode()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Determine mode parameters |
|
||||
\*-----------------------------------------------------*/
|
||||
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
|
||||
RGBColor color = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
|
||||
int rgb_mode;
|
||||
bool rgb_random = random;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Map ARGB modes with the equivalent RGB modes |
|
||||
\*-----------------------------------------------------*/
|
||||
switch(modes[active_mode].value)
|
||||
{
|
||||
case CM_ARGB_MODE_SPECTRUM:
|
||||
case CM_ARGB_MODE_FILLFLOW:
|
||||
case CM_ARGB_MODE_RAINBOW:
|
||||
rgb_mode = CM_RGB_MODE_MIRAGE;
|
||||
rgb_random = true;
|
||||
break;
|
||||
|
||||
case CM_ARGB_MODE_RELOAD:
|
||||
case CM_ARGB_MODE_RECOIL:
|
||||
rgb_mode = CM_RGB_MODE_FLASH;
|
||||
break;
|
||||
|
||||
case CM_ARGB_MODE_BREATHING:
|
||||
rgb_mode = CM_RGB_MODE_BREATHING;
|
||||
break;
|
||||
|
||||
case CM_ARGB_MODE_REFILL:
|
||||
case CM_ARGB_MODE_STATIC:
|
||||
rgb_mode = CM_RGB_MODE_STATIC;
|
||||
break;
|
||||
|
||||
case CM_ARGB_MODE_DEMO:
|
||||
rgb_mode = CM_RGB_MODE_FLASH;
|
||||
rgb_random = true;
|
||||
break;
|
||||
|
||||
case CM_ARGB_MODE_OFF:
|
||||
default:
|
||||
rgb_mode = CM_RGB_MODE_OFF;
|
||||
break;
|
||||
|
||||
case CM_ARGB_MODE_PASSTHRU:
|
||||
rgb_mode = CM_RGB_MODE_PASSTHRU;
|
||||
break;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Apply mode to all zones |
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
controller->SetPortMode
|
||||
(
|
||||
(unsigned char)zone_idx,
|
||||
(zone_idx == 4) ? rgb_mode : modes[active_mode].value,
|
||||
modes[active_mode].speed,
|
||||
modes[active_mode].brightness,
|
||||
(zone_idx == 4) ? rgb_random : random,
|
||||
RGBGetRValue(color),
|
||||
RGBGetGValue(color),
|
||||
RGBGetBValue(color)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMARGBController.h |
|
||||
| |
|
||||
| RGBController for Cooler Master ARGB controller |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "CMARGBController.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
class RGBController_CMARGBController : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMARGBController(CMARGBController* controller_ptr);
|
||||
~RGBController_CMARGBController();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
CMARGBController* controller;
|
||||
std::vector<unsigned int> leds_channel;
|
||||
};
|
||||
@@ -0,0 +1,384 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMARGBGen2A1Controller.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master ARGB Gen 2 A1 controller |
|
||||
| |
|
||||
| Morgan Guimard (morg) 26 Jun 2022 |
|
||||
| Fabian R (kderazorback) 11 Aug 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "CMARGBGen2A1Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
CMARGBGen2A1controller::CMARGBGen2A1controller(hid_device* dev_handle, const hid_device_info& info, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = info.path;
|
||||
name = dev_name;
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Setup direct mode on start |
|
||||
\*---------------------------------------------*/
|
||||
SetupDirectMode();
|
||||
}
|
||||
|
||||
CMARGBGen2A1controller::~CMARGBGen2A1controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string CMARGBGen2A1controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string CMARGBGen2A1controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string CMARGBGen2A1controller::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));
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SaveToFlash()
|
||||
{
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_FLASH;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CM_ARGB_GEN2_A1_SLEEP_LONG));
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SetupDirectMode()
|
||||
{
|
||||
ResetDevice();
|
||||
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Swith to direct mode |
|
||||
\*---------------------------------------------*/
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_HW_MODE_SETUP;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
usb_buf[4] = CM_ARGB_GEN2_A1_CHANNEL_ALL; // CHANNEL
|
||||
usb_buf[5] = CM_ARGB_GEN2_A1_SUBCHANNEL_ALL; // SUBCHANNEL
|
||||
usb_buf[6] = CM_ARGB_GEN2_A1_CUSTOM_MODE;
|
||||
usb_buf[7] = CM_ARGB_GEN2_A1_SPEED_HALF;
|
||||
usb_buf[8] = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
usb_buf[9] = 0xFF; // R
|
||||
usb_buf[10] = 0xFF; // G
|
||||
usb_buf[11] = 0xFF; // B
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CM_ARGB_GEN2_A1_SLEEP_SHORT));
|
||||
|
||||
std::vector<RGBColor> colorOffChain;
|
||||
colorOffChain.push_back(0);
|
||||
for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
SendChannelColors(channel, CM_ARGB_GEN2_A1_SUBCHANNEL_ALL, colorOffChain);
|
||||
}
|
||||
|
||||
for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
SetCustomSequence(channel);
|
||||
}
|
||||
|
||||
software_mode_activated = true;
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SetupZoneSize(unsigned int zone_id, unsigned int size)
|
||||
{
|
||||
/*---------------------------------------------*\
|
||||
| Set the mode sequence to full static |
|
||||
| (01 for static) |
|
||||
| |
|
||||
| This device stores 2 distinct values |
|
||||
| - effect speed |
|
||||
| - approximated zone size |
|
||||
| |
|
||||
| It's probably based on standard ARGB sizes |
|
||||
| Still, the 06 value has some mystery. |
|
||||
| |
|
||||
| ES= effect speed |
|
||||
| LC= LEDs count |
|
||||
| |
|
||||
| ES LC |
|
||||
| ----- |
|
||||
| 0a 06 |
|
||||
| 09 06 |
|
||||
| 08 07 |
|
||||
| 07 08 |
|
||||
| 06 0a |
|
||||
| 05 0c |
|
||||
| 04 0f |
|
||||
| 03 14 |
|
||||
| 02 1e |
|
||||
| 01 3c |
|
||||
\*---------------------------------------------*/
|
||||
|
||||
const unsigned char gaps[10] =
|
||||
{
|
||||
0x05, 0x06, 0x07, 0x08, 0x0A, 0x0C, 0x0F, 0x14, 0x1E, 0x3C
|
||||
};
|
||||
|
||||
unsigned char speed = 0x0A;
|
||||
|
||||
for(unsigned int g = 0; g < 10; g++)
|
||||
{
|
||||
if(size <= gaps[g])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
speed--;
|
||||
}
|
||||
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_SIZES;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
usb_buf[4] = 1 << zone_id;
|
||||
|
||||
usb_buf[5] = speed;
|
||||
usb_buf[6] = size;
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CM_ARGB_GEN2_A1_SLEEP_LONG));
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Refresh direct mode to cycle the strips |
|
||||
| with the new length |
|
||||
\*---------------------------------------------*/
|
||||
if(software_mode_activated)
|
||||
{
|
||||
SetupDirectMode();
|
||||
}
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SendChannelColors(unsigned int zone_id, unsigned int subchannel_id, std::vector<RGBColor> colors)
|
||||
{
|
||||
/*---------------------------------------------*\
|
||||
| Create the color data array |
|
||||
\*---------------------------------------------*/
|
||||
std::vector<unsigned char> color_data = CreateColorData(colors);
|
||||
|
||||
std::vector<unsigned char>::iterator it = color_data.begin();
|
||||
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
unsigned int offset;
|
||||
|
||||
/*----------------------------------------------------*\
|
||||
| Break-up color data in packet/s |
|
||||
| Intentionally clearing first packet only |
|
||||
| Leaving garbage on subsequent packets |
|
||||
| Original software appears to not clear them anyways. |
|
||||
\*----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
for(unsigned int p = 0; p < CM_ARGB_GEN2_A1_PACKETS_PER_CHANNEL && it != color_data.end(); p++)
|
||||
{
|
||||
offset = 1;
|
||||
|
||||
usb_buf[offset++] = p;
|
||||
usb_buf[offset++] = CM_ARGB_GEN2_A1_SET_RGB_VALUES;
|
||||
usb_buf[offset++] = CM_ARGB_GEN2_A1_WRITE;
|
||||
usb_buf[offset++] = 1 << zone_id;
|
||||
usb_buf[offset++] = 1 << subchannel_id;
|
||||
|
||||
while(it != color_data.end() && offset < CM_ARGB_GEN2_A1_PACKET_LENGTH)
|
||||
{
|
||||
usb_buf[offset++] = *it;
|
||||
it++;
|
||||
}
|
||||
|
||||
if(p >= CM_ARGB_GEN2_A1_PACKETS_PER_CHANNEL - 1 || it == color_data.end())
|
||||
{
|
||||
/*--------------------------*\
|
||||
| Rewrite as end packet |
|
||||
\*--------------------------*/
|
||||
usb_buf[1] = p + 0x80;
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
/*-----------------------------------------------*\
|
||||
| This device needs some delay before we send |
|
||||
| any other packet :( |
|
||||
| This time is critical since the device is |
|
||||
| still latching its input buffer. |
|
||||
| Reducing this may start to introduce artifacts |
|
||||
\*-----------------------------------------------*/
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CM_ARGB_GEN2_A1_SLEEP_MEDIUM));
|
||||
}
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Next channel needs some delay as well |
|
||||
\*---------------------------------------------*/
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CM_ARGB_GEN2_A1_SLEEP_SHORT));
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SetMode(unsigned int mode_value, unsigned char speed, unsigned char brightness, RGBColor color, bool random)
|
||||
{
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Switch to hardware mode if needed |
|
||||
\*---------------------------------------------*/
|
||||
if(software_mode_activated)
|
||||
{
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_LIGHTNING_CONTROL;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
software_mode_activated = false;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CM_ARGB_GEN2_A1_SLEEP_LONG));
|
||||
}
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Set the mode values and write to the device |
|
||||
\*---------------------------------------------*/
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_HW_MODE_SETUP;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
|
||||
usb_buf[4] = CM_ARGB_GEN2_A1_CHANNEL_ALL;
|
||||
usb_buf[5] = CM_ARGB_GEN2_A1_SUBCHANNEL_ALL;
|
||||
|
||||
usb_buf[6] = mode_value;
|
||||
|
||||
bool is_custom_mode = (mode_value == CM_ARGB_GEN2_A1_CUSTOM_MODE);
|
||||
|
||||
if(is_custom_mode)
|
||||
{
|
||||
usb_buf[7] = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
usb_buf[8] = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
usb_buf[9] = 0xFF; // R
|
||||
usb_buf[10] = 0xFF; // G
|
||||
usb_buf[11] = 0xFF; // B
|
||||
}
|
||||
else
|
||||
{
|
||||
usb_buf[7] = speed;
|
||||
usb_buf[8] = brightness;
|
||||
usb_buf[9] = RGBGetRValue(color);
|
||||
usb_buf[10] = RGBGetGValue(color);
|
||||
usb_buf[11] = RGBGetBValue(color);
|
||||
usb_buf[12] = random;
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CM_ARGB_GEN2_A1_SLEEP_LONG));
|
||||
|
||||
if(is_custom_mode)
|
||||
{
|
||||
for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
SetCustomSequence(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<unsigned char> CMARGBGen2A1controller::CreateColorData(std::vector<RGBColor> colors)
|
||||
{
|
||||
std::vector<unsigned char> color_data;
|
||||
|
||||
for(unsigned int c = 0; c < colors.size(); c++)
|
||||
{
|
||||
color_data.push_back(RGBGetRValue(colors[c]));
|
||||
color_data.push_back(RGBGetGValue(colors[c]));
|
||||
color_data.push_back(RGBGetBValue(colors[c]));
|
||||
}
|
||||
|
||||
return(color_data);
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SetCustomSequence(unsigned int zone_id)
|
||||
{
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Set custom speed for sequence mode |
|
||||
\*---------------------------------------------*/
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_CUSTOM_SPEED;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
usb_buf[4] = 1 << zone_id; // CHANNEL
|
||||
usb_buf[5] = 0x32;
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CM_ARGB_GEN2_A1_SLEEP_SHORT));
|
||||
|
||||
SetPipelineStaticSequence(zone_id);
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::SetPipelineStaticSequence(unsigned int zone_id)
|
||||
{
|
||||
/*------------------------------------------------*\
|
||||
| Set the mode sequence to full static |
|
||||
| All steps on the effect pipeline to 0x01 STATIC |
|
||||
\*------------------------------------------------*/
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
memset(usb_buf, CM_ARGB_GEN2_A1_STATIC_MODE, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
usb_buf[0] = 0x00;
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_CUSTOM_SEQUENCES;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
usb_buf[4] = 1 << zone_id;
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CM_ARGB_GEN2_A1_SLEEP_LONG));
|
||||
}
|
||||
|
||||
void CMARGBGen2A1controller::ResetDevice()
|
||||
{
|
||||
unsigned char usb_buf[CM_ARGB_GEN2_A1_PACKET_LENGTH];
|
||||
|
||||
memset(usb_buf, 0x00, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
usb_buf[1] = CM_ARGB_GEN2_A1_COMMAND;
|
||||
usb_buf[2] = CM_ARGB_GEN2_A1_RESET;
|
||||
usb_buf[3] = CM_ARGB_GEN2_A1_WRITE;
|
||||
|
||||
hid_write(dev, usb_buf, CM_ARGB_GEN2_A1_PACKET_LENGTH);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CM_ARGB_GEN2_A1_SLEEP_LONG));
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMARGBGen2A1Controller.h |
|
||||
| |
|
||||
| Driver for Cooler Master ARGB Gen 2 A1 controller |
|
||||
| |
|
||||
| Morgan Guimard (morg) 26 Jun 2022 |
|
||||
| Fabian R (kderazorback) 11 Aug 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define CM_ARGB_GEN2_A1_PACKET_LENGTH 65
|
||||
#define CM_ARGB_GEN2_A1_CHANNEL_MAX_SIZE 72
|
||||
#define CM_ARGB_GEN2_A1_CHANNEL_COUNT 3
|
||||
#define CM_ARGB_GEN2_A1_PACKETS_PER_CHANNEL 2
|
||||
|
||||
#define CM_ARGB_GEN2_A1_SLEEP_SHORT 5
|
||||
#define CM_ARGB_GEN2_A1_SLEEP_MEDIUM 45
|
||||
#define CM_ARGB_GEN2_A1_SLEEP_LONG 70
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_GEN2_A1_DIRECT_MODE = 0xFF,
|
||||
CM_ARGB_GEN2_A1_SPECTRUM_MODE = 0x00,
|
||||
CM_ARGB_GEN2_A1_STATIC_MODE = 0x01,
|
||||
CM_ARGB_GEN2_A1_RELOAD_MODE = 0x02,
|
||||
CM_ARGB_GEN2_A1_RECOIL_MODE = 0x03,
|
||||
CM_ARGB_GEN2_A1_BREATHING_MODE = 0x04,
|
||||
CM_ARGB_GEN2_A1_REFILL_MODE = 0x05,
|
||||
CM_ARGB_GEN2_A1_DEMO_MODE = 0x06,
|
||||
CM_ARGB_GEN2_A1_FILL_FLOW_MODE = 0x07,
|
||||
CM_ARGB_GEN2_A1_RAINBOW_MODE = 0x08,
|
||||
CM_ARGB_GEN2_A1_CUSTOM_MODE = 0xC0,
|
||||
CM_ARGB_GEN2_A1_OFF_MODE = 0x09
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_GEN2_A1_BRIGHTNESS_MAX = 0xFF,
|
||||
CM_ARGB_GEN2_A1_BRIGHTNESS_MIN = 0x00,
|
||||
CM_ARGB_GEN2_A1_SPEED_MAX = 0x04,
|
||||
CM_ARGB_GEN2_A1_SPEED_HALF = 0x02,
|
||||
CM_ARGB_GEN2_A1_SPEED_MIN = 0x00,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_GEN2_A1_COMMAND = 0x80,
|
||||
CM_ARGB_GEN2_A1_COMMAND_EXTRA_1 = 0x81,
|
||||
CM_ARGB_GEN2_A1_COMMAND_EXTRA_2 = 0x82,
|
||||
CM_ARGB_GEN2_A1_READ = 0x01,
|
||||
CM_ARGB_GEN2_A1_WRITE = 0x02,
|
||||
CM_ARGB_GEN2_A1_RESPONSE = 0x03
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_GEN2_A1_SIZES = 0x06,
|
||||
CM_ARGB_GEN2_A1_SET_RGB_VALUES = 0x08,
|
||||
CM_ARGB_GEN2_A1_FLASH = 0x0B,
|
||||
CM_ARGB_GEN2_A1_IDENTIFY = 0x0A,
|
||||
CM_ARGB_GEN2_A1_LIGHTNING_CONTROL = 0x01,
|
||||
CM_ARGB_GEN2_A1_HW_MODE_SETUP = 0x03,
|
||||
CM_ARGB_GEN2_A1_CUSTOM_SEQUENCES = 0x10,
|
||||
CM_ARGB_GEN2_A1_CUSTOM_SPEED = 0x11,
|
||||
CM_ARGB_GEN2_A1_RESET = 0xC0,
|
||||
CM_ARGB_GEN2_A1_APPLY_CHANGES = 0xB0
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_ARGB_GEN2_A1_CHANNEL_A = 0x01,
|
||||
CM_ARGB_GEN2_A1_CHANNEL_B = 0x02,
|
||||
CM_ARGB_GEN2_A1_CHANNEL_C = 0x04,
|
||||
CM_ARGB_GEN2_A1_CHANNEL_ALL = 0xFF,
|
||||
CM_ARGB_GEN2_A1_SUBCHANNEL_ALL = 0xFF
|
||||
};
|
||||
|
||||
class CMARGBGen2A1controller
|
||||
{
|
||||
public:
|
||||
CMARGBGen2A1controller(hid_device* dev_handle, const hid_device_info& info, std::string dev_name);
|
||||
~CMARGBGen2A1controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SendChannelColors(unsigned int zone_id, unsigned int subchannel_id, std::vector<RGBColor> colors);
|
||||
void SetupZoneSize(unsigned int zone_id, unsigned int size);
|
||||
void SetupDirectMode();
|
||||
void SetMode(unsigned int mode_value, unsigned char speed, unsigned char brightness, RGBColor color, bool random);
|
||||
void SetCustomColors(unsigned int zone_id, std::vector<RGBColor> colors);
|
||||
void SaveToFlash();
|
||||
|
||||
private:
|
||||
std::string location;
|
||||
std::string name;
|
||||
bool software_mode_activated = false;
|
||||
hid_device* dev;
|
||||
|
||||
void SetCustomSequence(unsigned int zone_id);
|
||||
void SetPipelineStaticSequence(unsigned int zone_id);
|
||||
std::vector<unsigned char> CreateColorData(std::vector<RGBColor> colors);
|
||||
void ResetDevice();
|
||||
};
|
||||
+340
@@ -0,0 +1,340 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMARGBGen2A1Controller.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master ARGB Gen 2 A1 controller |
|
||||
| |
|
||||
| Morgan Guimard (morg) 26 Jun 2022 |
|
||||
| Fabian R (kderazorback) 11 Aug 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "RGBController_CMARGBGen2A1Controller.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Coolermaster ARGB A1
|
||||
@category LEDStrip
|
||||
@type USB
|
||||
@save :white_check_mark:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterARGBGen2A1
|
||||
@comment OpenRGB partially supports Gen 2 protocol for this device.
|
||||
|
||||
Gen2 has auto-resize feature and parallel to serial magical stuff,
|
||||
Strip size is auto detected by the controller but not reported
|
||||
back to OpenRGB. Configure zones and segments for each channel
|
||||
to allow individual addressing.
|
||||
Take note that this controller is extremely slow, using fast
|
||||
update rates may introduce color artifacts.<
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMARGBGen2A1Controller::RGBController_CMARGBGen2A1Controller(CMARGBGen2A1controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "CoolerMaster";
|
||||
type = DEVICE_TYPE_LEDSTRIP;
|
||||
description = "CoolerMaster LED Controller A1 Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CM_ARGB_GEN2_A1_DIRECT_MODE;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Spectrum;
|
||||
Spectrum.name = "Spectrum";
|
||||
Spectrum.value = CM_ARGB_GEN2_A1_SPECTRUM_MODE;
|
||||
Spectrum.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;
|
||||
Spectrum.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Spectrum.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Spectrum.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Spectrum.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Spectrum.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Spectrum.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
modes.push_back(Spectrum);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CM_ARGB_GEN2_A1_STATIC_MODE;
|
||||
Static.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Static.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Reload;
|
||||
Reload.name = "Reload";
|
||||
Reload.value = CM_ARGB_GEN2_A1_RELOAD_MODE;
|
||||
Reload.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Reload.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Reload.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Reload.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Reload.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Reload.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Reload.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Reload.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
Reload.colors.resize(1);
|
||||
modes.push_back(Reload);
|
||||
|
||||
mode Recoil;
|
||||
Recoil.name = "Recoil";
|
||||
Recoil.value = CM_ARGB_GEN2_A1_RECOIL_MODE;
|
||||
Recoil.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Recoil.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Recoil.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Recoil.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Recoil.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Recoil.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Recoil.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
Recoil.colors.resize(1);
|
||||
modes.push_back(Recoil);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_ARGB_GEN2_A1_BREATHING_MODE;
|
||||
Breathing.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Breathing.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Breathing.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Breathing.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Breathing.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
Breathing.colors.resize(1);
|
||||
modes.push_back(Breathing);
|
||||
|
||||
|
||||
mode Refill;
|
||||
Refill.name = "Refill";
|
||||
Refill.value = CM_ARGB_GEN2_A1_REFILL_MODE;
|
||||
Refill.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Refill.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Refill.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Refill.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Refill.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Refill.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Refill.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Refill.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
Refill.colors.resize(1);
|
||||
modes.push_back(Refill);
|
||||
|
||||
mode Demo;
|
||||
Demo.name = "Demo";
|
||||
Demo.value = CM_ARGB_GEN2_A1_DEMO_MODE;
|
||||
Demo.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Demo.color_mode = MODE_COLORS_NONE;
|
||||
Demo.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Demo.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Demo.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
modes.push_back(Demo);
|
||||
|
||||
mode FillFlow;
|
||||
FillFlow.name = "Fill Flow";
|
||||
FillFlow.value = CM_ARGB_GEN2_A1_FILL_FLOW_MODE;
|
||||
FillFlow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;;
|
||||
FillFlow.color_mode = MODE_COLORS_NONE;
|
||||
FillFlow.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
FillFlow.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
FillFlow.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
FillFlow.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
FillFlow.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
FillFlow.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
modes.push_back(FillFlow);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CM_ARGB_GEN2_A1_RAINBOW_MODE;
|
||||
Rainbow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.brightness = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Rainbow.brightness_min = CM_ARGB_GEN2_A1_BRIGHTNESS_MIN;
|
||||
Rainbow.brightness_max = CM_ARGB_GEN2_A1_BRIGHTNESS_MAX;
|
||||
Rainbow.speed = CM_ARGB_GEN2_A1_SPEED_MAX/2;
|
||||
Rainbow.speed_min = CM_ARGB_GEN2_A1_SPEED_MIN;
|
||||
Rainbow.speed_max = CM_ARGB_GEN2_A1_SPEED_MAX;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Custom;
|
||||
Custom.name = "Custom";
|
||||
Custom.value = CM_ARGB_GEN2_A1_CUSTOM_MODE;
|
||||
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
Custom.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Custom);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = CM_ARGB_GEN2_A1_OFF_MODE;
|
||||
Off.flags = MODE_FLAG_MANUAL_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_CMARGBGen2A1Controller::~RGBController_CMARGBGen2A1Controller()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::SetupZones()
|
||||
{
|
||||
unsigned int total_leds = 0;
|
||||
|
||||
for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
zone new_zone;
|
||||
|
||||
new_zone.name = "Channel " + std::to_string(channel + 1);
|
||||
new_zone.type = ZONE_TYPE_LINEAR;
|
||||
new_zone.leds_min = 0;
|
||||
new_zone.leds_max = CM_ARGB_GEN2_A1_CHANNEL_MAX_SIZE;
|
||||
new_zone.leds_count = 0;
|
||||
new_zone.matrix_map = nullptr;
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
total_leds += new_zone.leds_count;
|
||||
}
|
||||
|
||||
leds.resize(total_leds);
|
||||
|
||||
for(unsigned int i = 0; i < total_leds; i++)
|
||||
{
|
||||
leds[i].name = "LED " + std::to_string(i + 1);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::ResizeZone(int zone, int new_size)
|
||||
{
|
||||
zones[zone].leds_count = new_size;
|
||||
|
||||
unsigned int total_leds = 0;
|
||||
|
||||
for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
total_leds += zones[channel].leds_count;
|
||||
}
|
||||
|
||||
leds.resize(total_leds);
|
||||
|
||||
for(unsigned int i = 0; i < total_leds; i++)
|
||||
{
|
||||
leds[i].name = "LED " + std::to_string(i + 1);
|
||||
}
|
||||
|
||||
controller->SetupZoneSize(zone, new_size);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::DeviceUpdateLEDs()
|
||||
{
|
||||
for(unsigned int channel = 0; channel < CM_ARGB_GEN2_A1_CHANNEL_COUNT; channel ++)
|
||||
{
|
||||
if (zones[channel].segments.size() > 0)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
for(std::vector<segment>::iterator it = zones[channel].segments.begin(); it != zones[channel].segments.end(); it++)
|
||||
{
|
||||
UpdateSegmentLEDs(channel, i++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateSegmentLEDs(channel, CM_ARGB_GEN2_A1_SUBCHANNEL_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
if(zones[zone].leds_count > 0)
|
||||
{
|
||||
unsigned int start = zones[zone].start_idx;
|
||||
unsigned int end = start + zones[zone].leds_count;
|
||||
|
||||
std::vector<RGBColor> zone_colors(colors.begin() + start , colors.begin() + end);
|
||||
|
||||
controller->SendChannelColors(zone, CM_ARGB_GEN2_A1_SUBCHANNEL_ALL, zone_colors);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::UpdateSegmentLEDs(int zone, int subchannel)
|
||||
{
|
||||
if(zones[zone].leds_count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int start = zones[zone].start_idx;
|
||||
unsigned int end = start + zones[zone].leds_count;
|
||||
bool use_direct_mode = modes[active_mode].value == CM_ARGB_GEN2_A1_DIRECT_MODE || modes[active_mode].value == CM_ARGB_GEN2_A1_CUSTOM_MODE;
|
||||
|
||||
std::vector<RGBColor> color_vector(colors.begin() + start, colors.begin() + start + end);
|
||||
|
||||
if(use_direct_mode)
|
||||
{
|
||||
if(zones[zone].segments.size() > 0)
|
||||
{
|
||||
start += zones[zone].segments[subchannel].start_idx;
|
||||
end += zones[zone].segments[subchannel].start_idx + zones[zone].segments[subchannel].leds_count;
|
||||
|
||||
color_vector = std::vector<RGBColor>(colors.begin() + start , colors.begin() + end);
|
||||
}
|
||||
|
||||
controller->SendChannelColors(zone, subchannel, color_vector);
|
||||
return;
|
||||
}
|
||||
|
||||
controller->SendChannelColors(zone, CM_ARGB_GEN2_A1_SUBCHANNEL_ALL, color_vector);
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::DeviceUpdateMode()
|
||||
{
|
||||
const mode& active = modes[active_mode];
|
||||
|
||||
if(active.value == CM_ARGB_GEN2_A1_DIRECT_MODE)
|
||||
{
|
||||
controller->SetupDirectMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBColor color = active.color_mode == MODE_COLORS_MODE_SPECIFIC ?
|
||||
active.colors[0] : 0;
|
||||
|
||||
controller->SetMode
|
||||
(
|
||||
active.value,
|
||||
active.speed,
|
||||
active.brightness,
|
||||
color,
|
||||
active.color_mode == MODE_COLORS_RANDOM
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMARGBGen2A1Controller::DeviceSaveMode()
|
||||
{
|
||||
controller->SaveToFlash();
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMARGBGen2A1Controller.h |
|
||||
| |
|
||||
| Driver for Cooler Master ARGB Gen 2 A1 controller |
|
||||
| |
|
||||
| Morgan Guimard (morg) 26 Jun 2022 |
|
||||
| Fabian R (kderazorback) 11 Aug 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "RGBController.h"
|
||||
#include "CMARGBGen2A1Controller.h"
|
||||
|
||||
class RGBController_CMARGBGen2A1Controller : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMARGBGen2A1Controller(CMARGBGen2A1controller* controller_ptr);
|
||||
~RGBController_CMARGBGen2A1Controller();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSegmentLEDs(int zone, int subchannel);
|
||||
void UpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
CMARGBGen2A1controller* controller;
|
||||
};
|
||||
@@ -0,0 +1,216 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMGD160Controller.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master GD160 ARGB Gaming Desk |
|
||||
| |
|
||||
| Logan Phillips (Eclipse) 16 Oct 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| Adapted from CMMonitor controller code |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "CMGD160Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
CMGD160Controller::CMGD160Controller(hid_device* dev_handle, const hid_device_info& info, const std::string& name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
device_name = name;
|
||||
location = info.path;
|
||||
ResetDevice();
|
||||
}
|
||||
|
||||
CMGD160Controller::~CMGD160Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string CMGD160Controller::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string CMGD160Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string CMGD160Controller::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));
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------*\
|
||||
| Desk requires 2 sets of packets sent for the front and back |
|
||||
| Technically you could have both sides do something different |
|
||||
| Not sure why you would though.... |
|
||||
| Cooler Master's software doesn't allow that anyways |
|
||||
\*------------------------------------------------------------*/
|
||||
|
||||
void CMGD160Controller::SetMode(uint8_t mode_value, uint8_t speed, uint8_t brightness, const RGBColor& color)
|
||||
{
|
||||
if(is_software_mode_enabled)
|
||||
{
|
||||
SetControlMode(false);
|
||||
}
|
||||
|
||||
uint8_t usb_buf[CM_GD160_PACKET_LENGTH];
|
||||
|
||||
for(int side = 1; side <= 2; side++)
|
||||
{
|
||||
memset(usb_buf, 0x00, CM_GD160_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = 0x80;
|
||||
usb_buf[2] = (mode_value == CM_GD160_OFF_MODE) ? 0x0F : 0x0B;
|
||||
usb_buf[3] = 0x02;
|
||||
usb_buf[4] = side; // 0x01 for front, 0x02 for back
|
||||
usb_buf[5] = mode_value;
|
||||
usb_buf[6] = (mode_value == CM_GD160_OFF_MODE) ? 0x00 : 0x08;
|
||||
usb_buf[7] = speed;
|
||||
usb_buf[8] = brightness;
|
||||
usb_buf[9] = RGBGetRValue(color);
|
||||
usb_buf[10] = RGBGetGValue(color);
|
||||
usb_buf[11] = RGBGetBValue(color);
|
||||
|
||||
hid_write(dev, usb_buf, CM_GD160_PACKET_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| How to request current color in custom mode. |
|
||||
| Not like it matters since we default to direct |
|
||||
| mode and it seems to clear the current colors... |
|
||||
| |
|
||||
| memset(usb_buf, 0x00, CM_GD160_PACKET_LENGTH); |
|
||||
| usb_buf[1] = 0x80; |
|
||||
| usb_buf[2] = 0x10; |
|
||||
| usb_buf[3] = 0x01; or 0x02 |
|
||||
| usb_buf[4] = 0x02; |
|
||||
| usb_buf[5] = 0x80; |
|
||||
| hid_write(dev, usb_buf, CM_GD160_PACKET_LENGTH); |
|
||||
\*-------------------------------------------------*/
|
||||
|
||||
void CMGD160Controller::SendColorData(const std::vector<RGBColor>& colors, uint8_t command, uint8_t mode_byte, uint8_t brightness, bool desired_control_mode)
|
||||
{
|
||||
if(is_software_mode_enabled != desired_control_mode)
|
||||
{
|
||||
SetControlMode(desired_control_mode);
|
||||
}
|
||||
|
||||
uint8_t color_data[CM_GD160_COLOR_DATA_LENGTH];
|
||||
memset(color_data, 0x00, CM_GD160_COLOR_DATA_LENGTH);
|
||||
|
||||
for(unsigned int i = 0; i < colors.size() && i < (CM_GD160_LEDS_PER_SIDE * 2); i++)
|
||||
{
|
||||
unsigned int side = i / CM_GD160_LEDS_PER_SIDE;
|
||||
unsigned int led_in_side = i % CM_GD160_LEDS_PER_SIDE;
|
||||
unsigned int buffer_offset = (side * CM_GD160_SIDE_DATA_LENGTH) + (led_in_side * 3);
|
||||
|
||||
color_data[buffer_offset] = RGBGetRValue(colors[i]);
|
||||
color_data[buffer_offset + 1] = RGBGetGValue(colors[i]);
|
||||
color_data[buffer_offset + 2] = RGBGetBValue(colors[i]);
|
||||
}
|
||||
|
||||
uint8_t usb_buf[CM_GD160_PACKET_LENGTH];
|
||||
|
||||
for(unsigned int side = 1; side <= 2; side++)
|
||||
{
|
||||
unsigned int offset = (side - 1) * CM_GD160_SIDE_DATA_LENGTH;
|
||||
|
||||
for(unsigned int packet = 0; packet < 7; packet++)
|
||||
{
|
||||
memset(usb_buf, 0x00, CM_GD160_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = (packet < 6) ? packet : 0x86; // Last packet uses 0x86
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| First packet contains static data |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
if(packet == 0)
|
||||
{
|
||||
usb_buf[2] = command;
|
||||
usb_buf[3] = 0x02;
|
||||
usb_buf[4] = side; // 0x01 for front, 0x02 for back
|
||||
usb_buf[5] = mode_byte;
|
||||
usb_buf[6] = brightness;
|
||||
|
||||
memcpy(&usb_buf[7], &color_data[offset], CM_GD160_FIRST_PACKET_DATA_SIZE);
|
||||
offset += CM_GD160_FIRST_PACKET_DATA_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&usb_buf[2], &color_data[offset], CM_GD160_PACKET_DATA_SIZE);
|
||||
offset += CM_GD160_PACKET_DATA_SIZE;
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, CM_GD160_PACKET_LENGTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*\
|
||||
| True enables software mode |
|
||||
| False enables hardware mode |
|
||||
\*------------------------------------------------------*/
|
||||
|
||||
void CMGD160Controller::SetControlMode(bool software_mode)
|
||||
{
|
||||
uint8_t usb_buf[CM_GD160_PACKET_LENGTH];
|
||||
|
||||
for(int side = 1; side <= 2; side++)
|
||||
{
|
||||
memset(usb_buf, 0x00, CM_GD160_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = 0x80;
|
||||
usb_buf[2] = 0x07;
|
||||
usb_buf[3] = 0x02;
|
||||
usb_buf[4] = side; // 0x01 for front, 0x02 for back
|
||||
usb_buf[6] = software_mode;
|
||||
|
||||
hid_write(dev, usb_buf, CM_GD160_PACKET_LENGTH);
|
||||
}
|
||||
|
||||
is_software_mode_enabled = software_mode;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*\
|
||||
| Reset device on discovery in case it somehow landed |
|
||||
| in a bad / unresponsive state |
|
||||
\*------------------------------------------------------*/
|
||||
|
||||
void CMGD160Controller::ResetDevice()
|
||||
{
|
||||
uint8_t usb_buf[CM_GD160_PACKET_LENGTH];
|
||||
|
||||
memset(usb_buf, 0x00, CM_GD160_PACKET_LENGTH);
|
||||
usb_buf[1] = 0x80;
|
||||
usb_buf[2] = 0x11;
|
||||
hid_write(dev, usb_buf, CM_GD160_PACKET_LENGTH);
|
||||
|
||||
memset(usb_buf, 0x00, CM_GD160_PACKET_LENGTH);
|
||||
usb_buf[1] = 0x80;
|
||||
usb_buf[2] = 0x0B;
|
||||
usb_buf[3] = 0x01;
|
||||
usb_buf[4] = 0x02;
|
||||
hid_write(dev, usb_buf, CM_GD160_PACKET_LENGTH);
|
||||
|
||||
memset(usb_buf, 0x00, CM_GD160_PACKET_LENGTH);
|
||||
usb_buf[1] = 0x80;
|
||||
usb_buf[2] = 0x18;
|
||||
usb_buf[3] = 0x01;
|
||||
usb_buf[4] = 0x02;
|
||||
hid_write(dev, usb_buf, CM_GD160_PACKET_LENGTH);
|
||||
|
||||
is_software_mode_enabled = false;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMGD160Controller.h |
|
||||
| |
|
||||
| Driver for Cooler Master GD160 ARGB Gaming Desk |
|
||||
| |
|
||||
| Logan Phillips (Eclipse) 16 Oct 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| Adapted from CMMonitor controller code |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define CM_GD160_PACKET_LENGTH 65
|
||||
#define CM_GD160_COLOR_DATA_LENGTH 872
|
||||
#define CM_GD160_SIDE_DATA_LENGTH 436 // 96 LEDs * 3 bytes + header = 436 bytes per side
|
||||
#define CM_GD160_LEDS_PER_SIDE 96
|
||||
#define CM_GD160_FIRST_PACKET_DATA_SIZE 58 // CM_GD160_PACKET_LENGTH - 7 (header bytes)
|
||||
#define CM_GD160_PACKET_DATA_SIZE 63 // CM_GD160_PACKET_LENGTH - 2 (header bytes)
|
||||
|
||||
enum
|
||||
{
|
||||
CM_GD160_DIRECT_MODE = 0xFF,
|
||||
CM_GD160_CUSTOM_MODE = 0xFE,
|
||||
CM_GD160_SPECTRUM_MODE = 0x00,
|
||||
CM_GD160_RELOAD_MODE = 0x01,
|
||||
CM_GD160_RECOIL_MODE = 0x02,
|
||||
CM_GD160_BREATHING_MODE = 0x03,
|
||||
CM_GD160_REFILL_MODE = 0x04,
|
||||
CM_GD160_OFF_MODE = 0x06
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_GD160_BRIGHTNESS_MAX = 0xFF,
|
||||
CM_GD160_BRIGHTNESS_MIN = 0x00,
|
||||
CM_GD160_SPEED_MAX = 0x04,
|
||||
CM_GD160_SPEED_MIN = 0x00,
|
||||
};
|
||||
|
||||
class CMGD160Controller
|
||||
{
|
||||
public:
|
||||
CMGD160Controller(hid_device* dev_handle, const hid_device_info& info, const std::string& name);
|
||||
~CMGD160Controller();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerialString();
|
||||
std::string GetDeviceLocation();
|
||||
|
||||
void SetMode(uint8_t mode_value, uint8_t speed, uint8_t brightness, const RGBColor& color);
|
||||
void SendColorData(const std::vector<RGBColor>& colors, uint8_t command, uint8_t mode_byte, uint8_t brightness, bool enable_software_mode);
|
||||
|
||||
private:
|
||||
std::string device_name;
|
||||
std::string serial_number;
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
bool is_software_mode_enabled = false;
|
||||
void SetControlMode(bool value);
|
||||
void ResetDevice();
|
||||
};
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMGD160Controller.cpp |
|
||||
| |
|
||||
| RGBController for Cooler Master GD160 ARGB Gaming Desk |
|
||||
| |
|
||||
| Logan Phillips (Eclipse) 16 Oct 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| Adapted from CMMonitor controller code |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CMGD160Controller.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Cooler Master GD160 ARGB Gaming Desk
|
||||
@category Accessory
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterGD160
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMGD160Controller::RGBController_CMGD160Controller(CMGD160Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Cooler Master";
|
||||
type = DEVICE_TYPE_ACCESSORY;
|
||||
description = "Cooler Master GD160 Gaming Desk Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CM_GD160_DIRECT_MODE;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Spectrum;
|
||||
Spectrum.name = "Spectrum Cycle";
|
||||
Spectrum.value = CM_GD160_SPECTRUM_MODE;
|
||||
Spectrum.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Spectrum.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum.speed_min = CM_GD160_SPEED_MIN;
|
||||
Spectrum.speed_max = CM_GD160_SPEED_MAX;
|
||||
Spectrum.speed = CM_GD160_SPEED_MAX/2;
|
||||
Spectrum.brightness_min = CM_GD160_BRIGHTNESS_MIN;
|
||||
Spectrum.brightness_max = CM_GD160_BRIGHTNESS_MAX;
|
||||
Spectrum.brightness = CM_GD160_BRIGHTNESS_MAX;
|
||||
modes.push_back(Spectrum);
|
||||
|
||||
mode Reload;
|
||||
Reload.name = "Reload";
|
||||
Reload.value = CM_GD160_RELOAD_MODE;
|
||||
Reload.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Reload.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Reload.colors_min = 1;
|
||||
Reload.colors_max = 1;
|
||||
Reload.colors.resize(1);
|
||||
Reload.speed_min = CM_GD160_SPEED_MIN;
|
||||
Reload.speed_max = CM_GD160_SPEED_MAX;
|
||||
Reload.speed = CM_GD160_SPEED_MAX/2;
|
||||
Reload.brightness_min = CM_GD160_BRIGHTNESS_MIN;
|
||||
Reload.brightness_max = CM_GD160_BRIGHTNESS_MAX;
|
||||
Reload.brightness = CM_GD160_BRIGHTNESS_MAX;
|
||||
modes.push_back(Reload);
|
||||
|
||||
mode Recoil;
|
||||
Recoil.name = "Recoil";
|
||||
Recoil.value = CM_GD160_RECOIL_MODE;
|
||||
Recoil.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Recoil.colors_min = 1;
|
||||
Recoil.colors_max = 1;
|
||||
Recoil.colors.resize(1);
|
||||
Recoil.speed_min = CM_GD160_SPEED_MIN;
|
||||
Recoil.speed_max = CM_GD160_SPEED_MAX;
|
||||
Recoil.speed = CM_GD160_SPEED_MAX/2;
|
||||
Recoil.brightness_min = CM_GD160_BRIGHTNESS_MIN;
|
||||
Recoil.brightness_max = CM_GD160_BRIGHTNESS_MAX;
|
||||
Recoil.brightness = CM_GD160_BRIGHTNESS_MAX;
|
||||
modes.push_back(Recoil);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_GD160_BREATHING_MODE;
|
||||
Breathing.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed_min = CM_GD160_SPEED_MIN;
|
||||
Breathing.speed_max = CM_GD160_SPEED_MAX;
|
||||
Breathing.speed = CM_GD160_SPEED_MAX/2;
|
||||
Breathing.brightness_min = CM_GD160_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = CM_GD160_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = CM_GD160_BRIGHTNESS_MAX;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Refill;
|
||||
Refill.name = "Refill";
|
||||
Refill.value = CM_GD160_REFILL_MODE;
|
||||
Refill.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Refill.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Refill.colors_min = 1;
|
||||
Refill.colors_max = 1;
|
||||
Refill.colors.resize(1);
|
||||
Refill.speed_min = CM_GD160_SPEED_MIN;
|
||||
Refill.speed_max = CM_GD160_SPEED_MAX;
|
||||
Refill.speed = CM_GD160_SPEED_MAX/2;
|
||||
Refill.brightness_min = CM_GD160_BRIGHTNESS_MIN;
|
||||
Refill.brightness_max = CM_GD160_BRIGHTNESS_MAX;
|
||||
Refill.brightness = CM_GD160_BRIGHTNESS_MAX;
|
||||
modes.push_back(Refill);
|
||||
|
||||
mode Custom;
|
||||
Custom.name = "Custom";
|
||||
Custom.value = CM_GD160_CUSTOM_MODE;
|
||||
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Custom.color_mode = MODE_COLORS_PER_LED;
|
||||
Custom.brightness_min = CM_GD160_BRIGHTNESS_MIN;
|
||||
Custom.brightness_max = CM_GD160_BRIGHTNESS_MAX;
|
||||
Custom.brightness = CM_GD160_BRIGHTNESS_MAX;
|
||||
modes.push_back(Custom);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = CM_GD160_OFF_MODE;
|
||||
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_CMGD160Controller::~RGBController_CMGD160Controller()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMGD160Controller::SetupZones()
|
||||
{
|
||||
zone front;
|
||||
front.name = "Front Desk";
|
||||
front.type = ZONE_TYPE_LINEAR;
|
||||
front.leds_min = CM_GD160_LEDS_PER_SIDE;
|
||||
front.leds_max = CM_GD160_LEDS_PER_SIDE;
|
||||
front.leds_count = CM_GD160_LEDS_PER_SIDE;
|
||||
front.matrix_map = NULL;
|
||||
zones.push_back(front);
|
||||
|
||||
for(unsigned int i = 0; i < CM_GD160_LEDS_PER_SIDE; i++)
|
||||
{
|
||||
led l;
|
||||
l.name = "Front LED " + std::to_string(i + 1);
|
||||
l.value = i;
|
||||
leds.push_back(l);
|
||||
}
|
||||
|
||||
zone back;
|
||||
back.name = "Back Desk";
|
||||
back.type = ZONE_TYPE_LINEAR;
|
||||
back.leds_min = CM_GD160_LEDS_PER_SIDE;
|
||||
back.leds_max = CM_GD160_LEDS_PER_SIDE;
|
||||
back.leds_count = CM_GD160_LEDS_PER_SIDE;
|
||||
back.matrix_map = NULL;
|
||||
zones.push_back(back);
|
||||
|
||||
for(unsigned int i = 0; i < CM_GD160_LEDS_PER_SIDE; i++)
|
||||
{
|
||||
led l;
|
||||
l.name = "Back LED " + std::to_string(i + 1);
|
||||
l.value = i;
|
||||
leds.push_back(l);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMGD160Controller::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CMGD160Controller::DeviceUpdateLEDs()
|
||||
{
|
||||
switch(modes[active_mode].value)
|
||||
{
|
||||
case CM_GD160_DIRECT_MODE:
|
||||
controller->SendColorData(colors, 0x07, 0x01, 0xFF, true);
|
||||
break;
|
||||
|
||||
case CM_GD160_CUSTOM_MODE:
|
||||
controller->SendColorData(colors, 0x10, 0x80, modes[active_mode].brightness, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMGD160Controller::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMGD160Controller::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMGD160Controller::DeviceUpdateMode()
|
||||
{
|
||||
switch(modes[active_mode].value)
|
||||
{
|
||||
case CM_GD160_OFF_MODE:
|
||||
case CM_GD160_SPECTRUM_MODE:
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, 0);
|
||||
break;
|
||||
|
||||
case CM_GD160_RELOAD_MODE:
|
||||
case CM_GD160_RECOIL_MODE:
|
||||
case CM_GD160_BREATHING_MODE:
|
||||
case CM_GD160_REFILL_MODE:
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, modes[active_mode].colors[0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMGD160Controller.h |
|
||||
| |
|
||||
| RGBController for Cooler Master GD160 ARGB Gaming Desk |
|
||||
| |
|
||||
| Logan Phillips (Eclipse) 16 Oct 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| Adapted from CMMonitor controller code |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CMGD160Controller.h"
|
||||
|
||||
class RGBController_CMGD160Controller : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMGD160Controller(CMGD160Controller* controller_ptr);
|
||||
~RGBController_CMGD160Controller();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
CMGD160Controller* controller;
|
||||
};
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMKeyboardAbstractController.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master keyboards |
|
||||
| |
|
||||
| Tam D (too.manyhobbies) 30 Nov 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CMKeyboardAbstractController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
CMKeyboardAbstractController::CMKeyboardAbstractController(hid_device* dev_handle, hid_device_info* dev_info, std::string dev_name)
|
||||
{
|
||||
wchar_t tmp[HID_MAX_STR];
|
||||
|
||||
m_pDev = dev_handle;
|
||||
m_productId = dev_info->product_id;
|
||||
m_sLocation = dev_info->path;
|
||||
m_deviceName = dev_name;
|
||||
|
||||
hid_get_manufacturer_string(m_pDev, tmp, HID_MAX_STR);
|
||||
m_vendorName = StringUtils::wstring_to_string(tmp);
|
||||
|
||||
hid_get_product_string(m_pDev, tmp, HID_MAX_STR);
|
||||
m_serialNumber = StringUtils::wstring_to_string(tmp);
|
||||
|
||||
bool bNotFound = true;
|
||||
|
||||
for(uint16_t i = 0; i < COOLERMASTER_KEYBOARD_DEVICE_COUNT; i++)
|
||||
{
|
||||
if(cm_kb_device_list[i]->product_id == m_productId)
|
||||
{
|
||||
bNotFound = false;
|
||||
m_deviceIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(bNotFound)
|
||||
{
|
||||
LOG_ERROR("[%s] device capabilities not found. Please creata a new device request.", m_deviceName.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
CMKeyboardAbstractController::~CMKeyboardAbstractController()
|
||||
{
|
||||
hid_close(m_pDev);
|
||||
};
|
||||
|
||||
std::string CMKeyboardAbstractController::GetDeviceName()
|
||||
{
|
||||
return(m_deviceName);
|
||||
}
|
||||
|
||||
std::string CMKeyboardAbstractController::GetDeviceVendor()
|
||||
{
|
||||
return(m_vendorName);
|
||||
}
|
||||
|
||||
std::string CMKeyboardAbstractController::GetDeviceSerial()
|
||||
{
|
||||
return(m_serialNumber);
|
||||
}
|
||||
|
||||
const cm_kb_device* CMKeyboardAbstractController::GetDeviceData()
|
||||
{
|
||||
return(cm_kb_device_list[m_deviceIndex]);
|
||||
}
|
||||
|
||||
std::string CMKeyboardAbstractController::GetLocation()
|
||||
{
|
||||
return(m_sLocation);
|
||||
}
|
||||
|
||||
std::string CMKeyboardAbstractController::GetFirmwareVersion()
|
||||
{
|
||||
return(m_sFirmwareVersion);
|
||||
}
|
||||
|
||||
int CMKeyboardAbstractController::GetProductID()
|
||||
{
|
||||
return(m_productId);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> CMKeyboardAbstractController::SendCommand(std::vector<uint8_t> buf, uint8_t fill)
|
||||
{
|
||||
int status;
|
||||
std::vector<uint8_t> read;
|
||||
|
||||
uint8_t data[CM_KEYBOARD_WRITE_SIZE];
|
||||
memset(data, fill, CM_KEYBOARD_WRITE_SIZE);
|
||||
|
||||
size_t i = 1;
|
||||
for(uint8_t b : buf)
|
||||
{
|
||||
data[i++] = b;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(m_mutexSendCommand);
|
||||
status = hid_write(m_pDev, data, CM_KEYBOARD_WRITE_SIZE);
|
||||
|
||||
if(status < 0)
|
||||
{
|
||||
LOG_ERROR("[%s] SendCommand() failed code %d.", m_deviceName.c_str(), status);
|
||||
return(read);
|
||||
}
|
||||
|
||||
memset(data, 0, CM_KEYBOARD_WRITE_SIZE);
|
||||
status = hid_read(m_pDev, data, CM_KEYBOARD_WRITE_SIZE);
|
||||
|
||||
if(status < 0)
|
||||
{
|
||||
LOG_ERROR("[%s] SendCommand() failed code %d.", m_deviceName.c_str(), status);
|
||||
return(read);
|
||||
}
|
||||
|
||||
for(i = 0; i < (size_t)status; i++)
|
||||
{
|
||||
read.push_back(data[i]);
|
||||
}
|
||||
|
||||
return(read);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Enter/leave direct control mode |
|
||||
\*---------------------------------------------------------*/
|
||||
void CMKeyboardAbstractController::SetControlMode(uint8_t modeId)
|
||||
{
|
||||
SendCommand({0x41, (uint8_t)modeId});
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Sets the currently active profile. |
|
||||
| byte[0] = 0x51 0x00 0x00 0x00 |
|
||||
| byte[4] = profileId |
|
||||
| - corresponds to saved keyboard profile i.e. [1-4] |
|
||||
| - 0x05 - Used on MK and CK style keyboards? |
|
||||
\*---------------------------------------------------------*/
|
||||
void CMKeyboardAbstractController::SetActiveProfile(uint8_t profileId)
|
||||
{
|
||||
SendCommand({0x51, 0x00, 0x00, 0x00, profileId});
|
||||
};
|
||||
|
||||
uint8_t CMKeyboardAbstractController::GetActiveProfile()
|
||||
{
|
||||
std::vector<uint8_t> data = SendCommand({0x52, 0x00});
|
||||
|
||||
if(data.size() > 4)
|
||||
{
|
||||
return((int)data[4]);
|
||||
}
|
||||
|
||||
return(0xFF); // error
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Saves changes in currently used profile. |
|
||||
| byte[1] = 0x52 |
|
||||
\*---------------------------------------------------------*/
|
||||
void CMKeyboardAbstractController::SaveActiveProfile()
|
||||
{
|
||||
SendCommand({0x50, 0x55});
|
||||
}
|
||||
|
||||
void CMKeyboardAbstractController::SetActiveEffect(uint8_t effectId)
|
||||
{
|
||||
SendCommand({0x51, 0x28, 0x00, 0x00, effectId});
|
||||
};
|
||||
|
||||
void CMKeyboardAbstractController::SaveProfile()
|
||||
{
|
||||
SendCommand({0x50, 0x55});
|
||||
}
|
||||
|
||||
|
||||
uint8_t CMKeyboardAbstractController::GetModeStatus()
|
||||
{
|
||||
std::vector<uint8_t> data = SendCommand({0x52, 0x28});
|
||||
|
||||
return(data[4]);
|
||||
};
|
||||
|
||||
std::string CMKeyboardAbstractController::GetHexString(std::vector<uint8_t> buf)
|
||||
{
|
||||
std::stringstream hexss;
|
||||
|
||||
for(uint8_t b : buf)
|
||||
{
|
||||
hexss << std::hex << b << " ";
|
||||
}
|
||||
|
||||
return(hexss.str());
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMKeyboardAbstractController.h |
|
||||
| |
|
||||
| Driver for Cooler Master keyboards |
|
||||
| |
|
||||
| Tam D (too.manyhobbies) 30 Nov 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "CMKeyboardDevices.h"
|
||||
#include "KeyboardLayoutManager.h"
|
||||
#include "RGBController.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
#define HID_MAX_STR 255
|
||||
#define CM_KEYBOARD_WRITE_SIZE 65
|
||||
#define CM_MAX_LEDS 255
|
||||
#define CM_KEYBOARD_TIMEOUT 50
|
||||
#define CM_KEYBOARD_TIMEOUT_SHORT 3
|
||||
|
||||
struct cm_keyboard_effect
|
||||
{
|
||||
uint8_t effectId;
|
||||
uint8_t p1;
|
||||
uint8_t p2;
|
||||
uint8_t p3;
|
||||
RGBColor color1;
|
||||
RGBColor color2;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| byte[0] = 0x41 |
|
||||
| byte[1] = modeId |
|
||||
\*---------------------------------------------------------*/
|
||||
enum cm_keyboard_control_mode
|
||||
{
|
||||
MODE_FIRMWARE = 0x00,
|
||||
MODE_EFFECT = 0x01,
|
||||
MODE_MANUAL_V2 = 0x02,
|
||||
MODE_CUSTOM_PROFILE = 0x03,
|
||||
MODE_CUSTOM_PROFILE_V2 = 0x05,
|
||||
MODE_DIRECT = 0x80
|
||||
};
|
||||
|
||||
class CMKeyboardAbstractController
|
||||
{
|
||||
public:
|
||||
CMKeyboardAbstractController(hid_device* dev_handle, hid_device_info* dev_info, std::string dev_name);
|
||||
virtual ~CMKeyboardAbstractController();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Common USB controller fuctions |
|
||||
\*---------------------------------------------------------*/
|
||||
int GetProductID();
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceVendor();
|
||||
std::string GetDeviceSerial();
|
||||
std::string GetLocation();
|
||||
std::string GetFirmwareVersion();
|
||||
const cm_kb_device* GetDeviceData();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboard Layout Manager support funtions |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Common keyboard driver functions |
|
||||
\*---------------------------------------------------------*/
|
||||
virtual void SetControlMode(uint8_t modeId);
|
||||
virtual void SetActiveProfile(uint8_t profileId);
|
||||
virtual uint8_t GetActiveProfile();
|
||||
virtual void SaveActiveProfile();
|
||||
virtual void SaveProfile();
|
||||
virtual void SetActiveEffect(uint8_t effectId);
|
||||
virtual uint8_t GetModeStatus();
|
||||
virtual void InitializeModes(std::vector<mode> &modes) = 0;
|
||||
virtual KEYBOARD_LAYOUT GetKeyboardLayout() = 0;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Protocol specific funtions to be implmented |
|
||||
\*---------------------------------------------------------*/
|
||||
virtual void SetLeds(std::vector<led> leds, std::vector<RGBColor> colors) = 0;
|
||||
virtual void SetSingleLED(uint8_t in_led, RGBColor in_color) = 0;
|
||||
virtual void Initialize() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual void SetLEDControl(bool bManual) = 0; // FW or SW control
|
||||
virtual void SetCustomMode() = 0;
|
||||
virtual void SetMode(mode selectedMode) = 0;
|
||||
|
||||
protected:
|
||||
/*---------------------------------------------------------*\
|
||||
| Utility functions. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<std::uint8_t> SendCommand(std::vector<uint8_t> buf, uint8_t fill=0x00);
|
||||
std::string GetHexString(std::vector<uint8_t> buf);
|
||||
std::string m_sFirmwareVersion;
|
||||
std::string m_deviceName;
|
||||
hid_device* m_pDev;
|
||||
uint16_t m_productId;
|
||||
uint16_t m_deviceIndex;
|
||||
std::string m_vendorName;
|
||||
std::string m_sLocation;
|
||||
std::string m_serialNumber;
|
||||
KEYBOARD_LAYOUT m_keyboardLayout;
|
||||
std::map<int, int> mapModeValueEffect;
|
||||
std::mutex m_mutex;
|
||||
std::mutex m_mutexSendCommand;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,902 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMKeyboardDevices.cpp |
|
||||
| |
|
||||
| Device list for Cooler Master keyboards |
|
||||
| |
|
||||
| Tam D (too.manyhobbies) 30 Nov 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CMKeyboardDevices.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Coolermaster Key Values |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
|
||||
const std::vector<unsigned int> mk_pro_s_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
96, 97, 98, 99, 104, 105, 106, 112, 113, 114, 67, 68, 69, 102, 103, 107,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP */
|
||||
0, 1, 8, 9, 16, 17, 24, 25, 32, 33, 40, 41, 48, 49, 56, 57, 64,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN */
|
||||
2, 3, 10, 11, 18, 19, 26, 27, 34, 35, 42, 43, 50, 51, 58, 59, 66,
|
||||
/* CPLK A S D F G H J K L ; " # ENTR */
|
||||
4, 5, 12, 13, 20, 21, 28, 29, 36, 37, 44, 45, 89, 52,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU */
|
||||
6, 100, 7, 14, 15, 22, 23, 30, 31, 38, 39, 46, 47, 61,
|
||||
/* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWL ARWD ARWR */
|
||||
91, 90, 92, 93, 94, 60, 95, 54, 63, 62, 70,
|
||||
};
|
||||
|
||||
const std::vector<unsigned int> mk_pro_l_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK P1 P2 P3 P4 */
|
||||
11, 22, 30, 25, 27, 7, 51, 57, 62, 86, 87, 83, 85, 79, 72, 0,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP NMLK NMDV NMTM NMMI */
|
||||
14, 15, 23, 31, 39, 38, 46, 47, 55, 63, 71, 70, 54, 81, 3, 1, 2, 100, 108, 116, 118,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN NM7 NM8 NM9 NMPL */
|
||||
9, 8, 16, 24, 32, 33, 41, 40, 48, 56, 64, 65, 49, 82, 94, 92, 88, 96, 104, 112, 110,
|
||||
/* CPLK A S D F G H J K L ; ' \ ENTR NM4 NM5 NM6 */
|
||||
17, 10, 18, 26, 34, 35, 43, 42, 50, 58, 66, 67, 68, 84, 97, 105, 113,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
73, 19, 12, 20, 28, 36, 37, 45, 44, 52, 60, 69, 74, 80, 98, 106, 114, 111,
|
||||
/* LCTL LWIN LALT SPACE RALT RWFNC RMNU RCTRL ARWL ARDN ARWR NM0 NMPD */
|
||||
6, 90, 75, 91, 77, 78, 61, 4, 95, 93, 5, 107, 115,
|
||||
};
|
||||
|
||||
const std::vector<unsigned int> mk850_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK AIM AIMU AIMD */
|
||||
6, 27, 34, 41, 48, 62, 69, 76, 83, 90, 97, 104, 111, 118, 125, 132,
|
||||
/* M1 BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP NMLK NMDV NMTM NMMI */
|
||||
7, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 112, 119, 126, 133, 254, 147, 154, 161,
|
||||
/* M2 TAB Q W E R T Y U I O P [ ] \ DEL END PGDN NM7 NM8 NM9 NMPL */
|
||||
8, 22, 29, 36, 43, 50, 57, 64, 71, 78, 85, 92, 99, 113, 120, 127, 134, 141, 148, 155, 162,
|
||||
/* M3 CPLK A S D F G H J K L ; ' # ENTR NM4 NM5 NM6 */
|
||||
9, 23, 30, 37, 44, 51, 58, 65, 72, 79, 86, 93, 0, 114, 142, 149, 156,
|
||||
/* M4 LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
10, 0, 24, 31, 38, 45, 52, 59, 66, 73, 80, 87, 115, 129, 143, 150, 157, 164,
|
||||
/* M5 LCTL LWIN LALT SPACE RALT RWFNC RMNU RCTRL ARWL ARDN ARWR NM0 NMPD */
|
||||
11, 18, 25, 53, 81, 88, 95, 116, 123, 130, 137, 144, 158,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| CoolerMaster SK (60%) |
|
||||
\*-------------------------------------------------------------*/
|
||||
const std::vector<unsigned int> sk620_keymap =
|
||||
{
|
||||
/* T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 */
|
||||
/* L1 ESC 1 2 3 4 5 6 7 8 9 0 - = BPSC R1 */
|
||||
8, 15, 22, 29, 36, 43, 50, 57, 64, 71, 78, 85, 92, 106,
|
||||
/* L2 TAB Q W E R T Y U I O P [ ] R2 */
|
||||
9, 23, 30, 37, 44, 51, 58, 65, 72, 79, 86, 93, 100,
|
||||
/* L3 CPLK A S D F G H J K L ; " \ ENTR R3 */
|
||||
10, 24, 31, 38, 45, 52, 59, 66, 73, 80, 87, 94, 101, 108,
|
||||
/* L4 LSFT ISO\ Z X C V B N M , . # RSFT ARWU DEL R$ */
|
||||
11, 18, 25, 32, 39, 46, 53, 60, 67, 74, 81, 88, 95, 102, 109,
|
||||
/* L5 LCTL LWIN LALT SPACE RALT RWFNC ARWL ARDN ARWR R5 */
|
||||
12, 19, 26, 54, 82, 89, 96, 103, 110,
|
||||
/* B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B15 */
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| CoolerMaster SK (60%) |
|
||||
\*-------------------------------------------------------------*/
|
||||
const std::vector<unsigned int> sk622_keymap =
|
||||
{
|
||||
/* T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 */
|
||||
/* L1 ESC 1 2 3 4 5 6 7 8 9 0 - = BPSC R1 */
|
||||
8, 15, 22, 29, 36, 43, 50, 57, 64, 71, 78, 85, 92, 106,
|
||||
/* L2 TAB Q W E R T Y U I O P [ ] R2 */
|
||||
9, 23, 30, 37, 44, 51, 58, 65, 72, 79, 86, 93, 100,
|
||||
/* L3 CPLK A S D F G H J K L ; " \ ENTR R3 */
|
||||
10, 24, 31, 38, 45, 52, 59, 66, 73, 80, 87, 94, 101, 108,
|
||||
/* L4 LSFT ISO\ Z X C V B N M , . # RSFT ARWU DEL R$ */
|
||||
11, 18, 25, 32, 39, 46, 53, 60, 67, 74, 81, 88, 95, 102, 109,
|
||||
/* L5 LCTL LWIN LALT SPACE RALT RWFNC ARWL ARDN ARWR R5 */
|
||||
12, 19, 26, 54, 82, 89, 96, 103, 110,
|
||||
/* B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B15 */
|
||||
};
|
||||
|
||||
const std::vector<unsigned int> sk630_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
9, 33, 41, 49, 57, 73, 81, 89, 97, 105, 113, 121, 129, 137, 145, 153,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP */
|
||||
10, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, 130, 138, 146, 154,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN */
|
||||
11, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 115, 131, 139, 147, 155,
|
||||
/* CPLK A S D F G H J K L ; " # ENTR */
|
||||
12, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 108, 116, 132,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU */
|
||||
13, 21, 29, 37, 45, 53, 61, 69, 77, 85, 93, 101, 133, 149,
|
||||
/* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWL ARWD ARWR */
|
||||
14, 22, 30, 62, 94, 102, 110, 134, 142, 150, 158,
|
||||
};
|
||||
|
||||
const std::vector<unsigned int> sk650_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
0, 24, 32, 40, 48, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP NMLK NMDV NMTM NMMI */
|
||||
1, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105, 121, 129, 137, 145, 153, 161, 169, 177,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN NM7 NM8 NM9 NMPL */
|
||||
2, 18, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 122, 130, 138, 146, 154, 162, 170, 178,
|
||||
/* CPLK A S D F G H J K L ; ' # ENTR NM4 NM5 NM6 */
|
||||
3, 19, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 123, 155, 163, 171,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
4, 20, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 124, 140, 156, 164, 172, 180,
|
||||
/* LCTL LWIN LALT SPACE RALT RWFNC RMNU RCTRL ARWL ARDN ARWR NM0 NMPD */
|
||||
5, 13, 21, 53, 85, 93, 101, 125, 133, 141, 149, 165, 173,
|
||||
};
|
||||
|
||||
const std::vector<unsigned int> sk652_keymap =
|
||||
{
|
||||
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
9, 33, 41, 49, 57, 73, 81, 89, 97, 105, 113, 121, 129, 137, 145, 153,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP NMLK NMDV NMTM NMMI */
|
||||
10, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, 130, 138, 146, 154, 162, 170, 178, 186,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN NM7 NM8 NM9 NMPL */
|
||||
11, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 115, 131, 139, 147, 155, 163, 171, 179, 187,
|
||||
/* CPLK A S D F G H J K L ; ' # ENTR NM4 NM5 NM6 */
|
||||
12, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 108, 116, 132, 164, 172, 180,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
13, 21, 29, 37, 45, 53, 61, 69, 77, 85, 93, 101, 133, 149, 165, 173, 181, 189,
|
||||
/* LCTL LWIN LALT SPACE RALT RWFNC RMNU RCTRL ARWL ARDN ARWR NM0 NMPD */
|
||||
14, 22, 30, 62, 94, 102, 110, 134, 142, 150, 158, 174, 182,
|
||||
};
|
||||
|
||||
const std::vector<unsigned int> sk653_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
0, 24, 32, 40, 48, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP NMLK NMDV NMTM NMMI */
|
||||
1, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105, 121, 129, 137, 145, 153, 161, 169, 177,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN NM7 NM8 NM9 NMPL */
|
||||
2, 18, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 122, 130, 138, 146, 154, 162, 170, 178,
|
||||
/* CPLK A S D F G H J K L ; ' # ENTR NM4 NM5 NM6 */
|
||||
3, 19, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 123, 155, 163, 171,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
4, 20, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 124, 140, 156, 164, 172, 180,
|
||||
/* LCTL LWIN LALT SPACE RALT RWFNC RMNU RCTRL ARWL ARDN ARWR NM0 NMPD */
|
||||
5, 13, 21, 53, 85, 93, 101, 125, 133, 141, 149, 165, 173,
|
||||
};
|
||||
|
||||
const std::vector<unsigned int> mk730_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
7, 28, 35, 42, 49, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133,
|
||||
/* L1 BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP R1 */
|
||||
8, 22, 29, 36, 43, 50, 57, 64, 71, 78, 85, 92, 99, 113, 120, 127, 134,
|
||||
/* L2 TAB Q W E R T Y U I O P [ ] \ DEL END PGDN R2 */
|
||||
9, 23, 30, 37, 44, 51, 58, 65, 72, 79, 86, 93, 100, 114, 121, 128, 135,
|
||||
/* L3 CPLK A S D F G H J K L ; ' # ENTR R3 */
|
||||
10, 24, 31, 38, 45, 52, 59, 66, 73, 80, 87, 94, 108, 115,
|
||||
/* L4 LSFT ISO\ Z X C V B N M , . / RSFT ARWU R4 */
|
||||
11, 18, 25, 32, 39, 46, 53, 60, 67, 74, 81, 88, 116, 130,
|
||||
/* LCTL LWIN LALT SPACE RALT RWFNC RMNU RCTRL ARWL ARDN ARWR */
|
||||
12, 19, 26, 54, 82, 89, 96, 117, 124, 131, 138,
|
||||
/* B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B12 */
|
||||
};
|
||||
|
||||
const std::vector<unsigned int> mk750_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK MUT PLA REW FFWD */
|
||||
7, 28, 35, 42, 49, 63, 70, 77, 84, 91, 98, 105, 112, 119, 136, 133,
|
||||
/* L1 BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP NMLK NMDV NMTM NMMI R1 */
|
||||
8, 22, 29, 36, 43, 50, 57, 64, 71, 78, 85, 92, 99, 113, 120, 127, 134, 0, 148, 155, 162,
|
||||
/* L2 TAB Q W E R T Y U I O P [ ] \ DEL END PGDN NM7 NM8 NM9 NMPL R2 */
|
||||
9, 23, 30, 37, 44, 51, 58, 65, 72, 79, 86, 93, 100, 114, 121, 128, 135, 142, 149, 156, 163,
|
||||
/* L3 CPLK A S D F G H J K L ; ' # ENTR NM4 NM5 NM6 R3 */
|
||||
10, 24, 31, 38, 45, 52, 59, 66, 73, 80, 87, 94, 108, 115, 143, 150, 157,
|
||||
/* L4 LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER R4 */
|
||||
11, 18, 25, 32, 39, 46, 53, 60, 67, 74, 81, 88, 116, 130, 144, 151, 158, 165,
|
||||
/* LCTL LWIN LALT SPACE RALT RWFNC RMNU RCTRL ARWL ARDN ARWR NM0 NMPD */
|
||||
12, 19, 26, 54, 82, 89, 96, 117, 124, 131, 138, 152, 159,
|
||||
/* B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B12 B13 B14 B15 B16 B17 B18 */
|
||||
};
|
||||
|
||||
|
||||
const std::vector<unsigned int> ck530_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
6, 21, 27, 34, 41, 55, 62, 69, 76, 83, 90, 97, 104, 111, 118, 125,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP */
|
||||
7, 15, 22, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 105, 112, 119, 126,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN */
|
||||
8, 16, 23, 29, 36, 43, 50, 57, 64, 71, 78, 85, 92, 106, 113, 120, 127,
|
||||
/* CPLK A S D F G H J K L ; " # ENTR */
|
||||
9, 17, 24, 30, 37, 44, 51, 58, 65, 72, 79, 86, 93, 107,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU */
|
||||
10, 18, 25, 31, 38, 45, 52, 59, 66, 73, 80, 87, 108, 122,
|
||||
/* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWL ARWD ARWR */
|
||||
11, 12, 19, 46, 74, 81, 88, 109, 116, 123, 130,
|
||||
};
|
||||
|
||||
const std::vector<unsigned int> ck530_v2_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
7, 28, 35, 42, 49, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP */
|
||||
8, 22, 29, 36, 43, 50, 57, 64, 71, 78, 85, 92, 99, 113, 120, 127, 134,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN */
|
||||
9, 23, 30, 37, 44, 51, 58, 65, 72, 79, 86, 93, 100, 114, 121, 128, 135,
|
||||
/* CPLK A S D F G H J K L ; " # ENTR */
|
||||
10, 24, 31, 38, 45, 52, 59, 66, 73, 80, 87, 94, 108, 115,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU */
|
||||
11, 18, 25, 32, 39, 46, 53, 60, 67, 74, 88, 81, 116, 130,
|
||||
/* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWL ARWD ARWR */
|
||||
12, 19, 26, 54, 82, 89, 96, 117, 124, 131, 138,
|
||||
};
|
||||
|
||||
const std::vector<unsigned int> ck550_v2_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
0, 18, 24, 30, 36, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP NMLK NMDV NMTM NMMI */
|
||||
1, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 91, 97, 103, 109, 115, 121, 127, 133,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN NM7 NM8 NM9 NMPL */
|
||||
2, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, 92, 98, 104, 110, 116, 122, 128, 134,
|
||||
/* CPLK A S D F G H J K L ; ' # ENTR NM4 NM5 NM6 */
|
||||
3, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 87, 93, 117, 123, 129,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70,/*76,*/ 94, 106, 118, 124, 130, 136,
|
||||
/* LCTL LWIN LALT SPACE RALT RWFNC RMNU RCTRL ARWL ARDN ARWR NM0 NMPD */
|
||||
5, 11, 17, 41, 65, 71, 77, 95, 101, 107, 113, 125, 131,
|
||||
};
|
||||
|
||||
const std::vector<unsigned int> ck552_keymap =
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
0, 18, 24, 30, 36, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BPSC INS HOME PGUP NMLK NMDV NMTM NMMI */
|
||||
1, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 91, 97, 103, 109, 115, 121, 127, 133,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN NM7 NM8 NM9 NMPL */
|
||||
2, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, 92, 98, 104, 110, 116, 122, 128, 134,
|
||||
/* CPLK A S D F G H J K L ; ' # ENTR NM4 NM5 NM6 */
|
||||
3, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 93, 117, 123, 129,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70,/*76,*/ 94, 106, 118, 124, 130, 136,
|
||||
/* LCTL LWIN LALT SPACE RALT RWFNC RMNU RCTRL ARWL ARDN ARWR NM0 NMPD */
|
||||
5, 11, 17, 41, 65, 71, 77, 95, 101, 107, 113, 125, 131,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| KEYMAPS |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
keyboard_keymap_overlay_values mk_pro_s_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_TKL,
|
||||
{
|
||||
mk_pro_s_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, Alternate Name, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
},
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values mk_pro_l_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
mk_pro_l_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Name, Alternate Name, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 17, 101, "Key: P1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 18, 109, "Key: P2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 19, 117, "Key: P3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 20, 119, "Key: P4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
},
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| CoolerMaster MK85O Keyboard |
|
||||
| Unknown Keys: ISO\, ISO# set to 0 |
|
||||
\*-------------------------------------------------------------*/
|
||||
keyboard_keymap_overlay_values mk850_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
mk850_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Name, Alternate Name, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 17, 146, "Key: Aim <|>", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // aimpad <|>
|
||||
{ 0, 0, 18, 153, "Key: Aim -", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // aimpad +
|
||||
{ 0, 0, 19, 160, "Key: Aim +", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // aimpad -
|
||||
{ 0, 1, 0, 0, "Key: M5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 2, 0, 1, "Key: M4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 3, 0, 2, "Key: M3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 4, 0, 3, "Key: M2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 5, 0, 4, "Key: M1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
},
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values sk620_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_SIXTY,
|
||||
{
|
||||
sk620_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, Alternate Name, OpCode, |
|
||||
\*-----------------------------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 0, 7, "Light: Top 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, },
|
||||
{ 0, 0, 1, 14, "Light: Top 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 2, 21, "Light: Top 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 3, 28, "Light: Top 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 4, 35, "Light: Top 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 5, 42, "Light: Top 6", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 6, 49, "Light: Top 7", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 7, 56, "Light: Top 8", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 8, 63, "Light: Top 9", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 9, 70, "Light: Top 10", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 10, 77, "Light: Top 11", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 11, 84, "Light: Top 12", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 12, 91, "Light: Top 13", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 13, 98, "Light: Top 14", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 14, 105, "Light: Top 14", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 1, 0, 0, "Light: Left 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 2, 0, 1, "Light: Left 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 3, 0, 2, "Light: Left 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 4, 0, 3, "Light: Left 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 5, 0, 4, "Light: Left 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 1, 16, 112, "Light: Right 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 2, 16, 113, "Light: Right 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 3, 16, 114, "Light: Right 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 4, 16, 115, "Light: Right 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 5, 16, 116, "Light: Right 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 0, 6, "Light: Bottom 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, },
|
||||
{ 0, 6, 1, 20, "Light: Bottom 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 2, 27, "Light: Bottom 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 3, 34, "Light: Bottom 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 4, 41, "Light: Bottom 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 5, 48, "Light: Bottom 6", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 6, 55, "Light: Bottom 7", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 7, 62, "Light: Bottom 8", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 8, 69, "Light: Bottom 9", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 9, 76, "Light: Bottom 10", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 10, 83, "Light: Bottom 11", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 11, 90, "Light: Bottom 12", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 12, 97, "Light: Bottom 13", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 13, 104, "Light: Bottom 14", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 14, 111, "Light: Bottom 15", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 14, 118, "Light: Bottom 16", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
},
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values sk622_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_SIXTY,
|
||||
{
|
||||
sk622_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Name, Alternate Name, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 0, 7, "Light: Top 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, },
|
||||
{ 0, 0, 1, 14, "Light: Top 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 2, 21, "Light: Top 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 3, 28, "Light: Top 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 4, 35, "Light: Top 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 5, 42, "Light: Top 6", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 6, 49, "Light: Top 7", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 7, 56, "Light: Top 8", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 8, 63, "Light: Top 9", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 9, 70, "Light: Top 10", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 10, 77, "Light: Top 11", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 11, 84, "Light: Top 12", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 12, 91, "Light: Top 13", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 13, 98, "Light: Top 14", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 14, 105, "Light: Top 14", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 1, 0, 0, "Light: Left 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 2, 0, 1, "Light: Left 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 3, 0, 2, "Light: Left 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 4, 0, 3, "Light: Left 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 5, 0, 4, "Light: Left 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 1, 16, 112, "Light: Right 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 2, 16, 113, "Light: Right 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 3, 16, 114, "Light: Right 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 4, 16, 115, "Light: Right 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 5, 16, 116, "Light: Right 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 0, 6, "Light: Bottom 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, },
|
||||
{ 0, 6, 1, 20, "Light: Bottom 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 2, 27, "Light: Bottom 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 3, 34, "Light: Bottom 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 4, 41, "Light: Bottom 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 5, 48, "Light: Bottom 6", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 6, 55, "Light: Bottom 7", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 7, 62, "Light: Bottom 8", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 8, 69, "Light: Bottom 9", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 9, 76, "Light: Bottom 10", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 10, 83, "Light: Bottom 11", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 11, 90, "Light: Bottom 12", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 12, 97, "Light: Bottom 13", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 13, 104, "Light: Bottom 14", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 14, 111, "Light: Bottom 15", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 14, 118, "Light: Bottom 16", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
},
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values sk630_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_TKL,
|
||||
{
|
||||
sk630_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
}
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values sk650_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
sk650_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
}
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values sk652_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
sk652_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
}
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values sk653_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
sk653_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
}
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| CoolerMaster MK730 Keyboard |
|
||||
\*-------------------------------------------------------------*/
|
||||
keyboard_keymap_overlay_values mk730_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_TKL,
|
||||
{
|
||||
mk730_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Name, Alternate Name, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 1, 0, 1, "Light: Left 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 2, 0, 2, "Light: Left 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 3, 0, 3, "Light: Left 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 4, 0, 4, "Light: Left 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 1, 18, 141, "Light: Right 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 2, 18, 142, "Light: Right 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 3, 18, 143, "Light: Right 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 4, 18, 144, "Light: Right 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 1, 13, "Light: Bottom 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, },
|
||||
{ 0, 6, 2, 20, "Light: Bottom 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 3, 27, "Light: Bottom 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 4, 34, "Light: Bottom 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 5, 41, "Light: Bottom 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 6, 55, "Light: Bottom 6", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 7, 62, "Light: Bottom 7", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 8, 69, "Light: Logo", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 10, 76, "Light: Bottom 8", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 11, 90, "Light: Bottom 9", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 12, 104, "Light: Bottom 10", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 13, 111, "Light: Bottom 11", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 14, 118, "Light: Bottom 12", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 15, 125, "Light: Bottom 13", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
}
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| CoolerMaster MK750 Keyboard |
|
||||
| based on keymap defined in Signal. |
|
||||
| The keymap needs the following adjustments |
|
||||
| NMLK - Unknown set to 0 |
|
||||
| SCLK - Unknown set to 0 |
|
||||
| CAPS - Unknown set to 0 |
|
||||
| Guesses on ISO\ and # |
|
||||
\*-------------------------------------------------------------*/
|
||||
keyboard_keymap_overlay_values mk750_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
mk750_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Name, Alternate Name, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 17, 140, KEY_EN_MEDIA_MUTE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 18, 147, KEY_EN_MEDIA_PLAY_PAUSE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 19, 154, KEY_EN_MEDIA_PREVIOUS, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 20, 161, KEY_EN_MEDIA_NEXT, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 1, 0, 1, "Light: Left 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 2, 0, 2, "Light: Left 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 3, 0, 3, "Light: Left 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 4, 0, 4, "Light: Left 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 1, 22, 170, "Light: Right 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 2, 22, 171, "Light: Right 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 3, 22, 172, "Light: Right 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 4, 22, 173, "Light: Right 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 1, 20, "Light: Bottom 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, },
|
||||
{ 0, 6, 2, 27, "Light: Bottom 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 3, 34, "Light: Bottom 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 4, 41, "Light: Bottom 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 5, 55, "Light: Bottom 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 6, 62, "Light: Bottom 6", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 7, 69, "Light: Bottom 7", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 8, 76, "Light: Bottom 8", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 9, 83, "Light: Bottom 9", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 10, 90, "Light: Bottom 10", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 11, 104, "Light: Bottom 11", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 12, 111, "Light: Bottom 12", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 13, 118, "Light: Bottom 13", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 14, 125, "Light: Bottom 14", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 15, 132, "Light: Bottom 15", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 16, 146, "Light: Bottom 16", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 17, 153, "Light: Bottom 17", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 6, 18, 160, "Light: Bottom 18", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
}
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values ck530_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_TKL,
|
||||
{
|
||||
ck530_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
}
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values ck530_v2_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_TKL,
|
||||
{
|
||||
ck530_v2_keymap,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
keyboard_keymap_overlay_values ck550v2_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
ck550_v2_keymap,
|
||||
{
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Name, Alternate Name, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 17, 120, "Indicator: N", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 18, 126, "Indicator: C", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
{ 0, 0, 19, 132, "Indicator: S", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, },
|
||||
},
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values ck552_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
ck552_keymap,
|
||||
{
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, OpCode, |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
},
|
||||
};
|
||||
|
||||
static const cm_kb_zone cm_generic_zone =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
cm_kb_device mk_pro_s_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_PRO_S_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&mk_pro_s_layout,
|
||||
};
|
||||
|
||||
cm_kb_device mk_pro_l_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_PRO_L_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&mk_pro_l_layout,
|
||||
};
|
||||
|
||||
cm_kb_device mk850_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_MK850_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&mk850_layout,
|
||||
};
|
||||
|
||||
cm_kb_device sk620w_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_SK620W_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&sk620_layout,
|
||||
};
|
||||
|
||||
cm_kb_device sk620b_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_SK620B_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&sk620_layout,
|
||||
};
|
||||
|
||||
cm_kb_device sk622w_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_SK622W_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&sk622_layout,
|
||||
};
|
||||
|
||||
cm_kb_device sk622b_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_SK622B_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&sk622_layout,
|
||||
};
|
||||
|
||||
cm_kb_device sk630_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_SK630_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&sk630_layout,
|
||||
};
|
||||
|
||||
cm_kb_device sk650_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_SK650_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&sk650_layout,
|
||||
};
|
||||
|
||||
cm_kb_device sk652_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_SK652_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&sk652_layout,
|
||||
};
|
||||
|
||||
cm_kb_device sk653_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_SK653_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&sk652_layout,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| TODO: Keymap is incomplete. Extra keys mode enabled to |
|
||||
| aid in key discovery. |
|
||||
\*---------------------------------------------------------*/
|
||||
cm_kb_device mk730_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_MK730_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&mk730_layout,
|
||||
};
|
||||
|
||||
cm_kb_device mk750_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_MK750_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&mk750_layout,
|
||||
};
|
||||
|
||||
cm_kb_device ck530_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_CK530_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&ck530_layout,
|
||||
};
|
||||
|
||||
cm_kb_device ck530_v2_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_CK530_V2_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&ck530_v2_layout,
|
||||
};
|
||||
|
||||
cm_kb_device ck550_v2_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_CK550_V2_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&ck550v2_layout,
|
||||
};
|
||||
|
||||
cm_kb_device ck552_v2_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_CK552_V2_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&ck552_layout,
|
||||
};
|
||||
|
||||
cm_kb_device mk_pro_l_white_device
|
||||
{
|
||||
COOLERMASTER_KEYBOARD_PRO_L_WHITE_PID,
|
||||
{
|
||||
&cm_generic_zone,
|
||||
},
|
||||
&mk_pro_s_layout,
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| KEYBOARDS |
|
||||
\*-----------------------------------------------------------------*/
|
||||
const cm_kb_device* cm_kb_devices[] =
|
||||
{
|
||||
&mk_pro_s_device,
|
||||
&mk_pro_l_device,
|
||||
&mk850_device,
|
||||
&sk620w_device,
|
||||
&sk620b_device,
|
||||
&sk622w_device,
|
||||
&sk622b_device,
|
||||
&sk630_device,
|
||||
&sk650_device,
|
||||
&sk652_device,
|
||||
&sk653_device,
|
||||
&mk730_device,
|
||||
&mk750_device,
|
||||
&ck530_device,
|
||||
&ck530_v2_device,
|
||||
&ck550_v2_device,
|
||||
&ck552_v2_device,
|
||||
&mk_pro_l_white_device,
|
||||
};
|
||||
|
||||
const unsigned int COOLERMASTER_KEYBOARD_DEVICE_COUNT = (sizeof(cm_kb_devices) / sizeof(cm_kb_devices[ 0 ]));
|
||||
const cm_kb_device** cm_kb_device_list = cm_kb_devices;
|
||||
@@ -0,0 +1,123 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMKeyboardDevices.h |
|
||||
| |
|
||||
| Device list for Cooler Master keyboards |
|
||||
| |
|
||||
| Tam D (too.manyhobbies) 30 Nov 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "KeyboardLayoutManager.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| List of all supported effects by this controller. |
|
||||
| All of these effects are firmware controlled, and |
|
||||
| they types of effects supported will depend on the |
|
||||
| Keyboard. |
|
||||
| |
|
||||
| To enable a command, the SetEffect(effectId) needs |
|
||||
| to be called. The specific effectId->Effect mapping |
|
||||
| depends on the keyboard. |
|
||||
\*-----------------------------------------------------*/
|
||||
enum cm_keyboard_effect_type
|
||||
{
|
||||
NONE = 0,
|
||||
DIRECT,
|
||||
SINGLE,
|
||||
FULLY_LIT,
|
||||
STATIC,
|
||||
BREATHE,
|
||||
CYCLE,
|
||||
WAVE,
|
||||
RIPPLE,
|
||||
CROSS,
|
||||
RAINDROPS,
|
||||
STARS,
|
||||
SNAKE,
|
||||
CUSTOMIZED,
|
||||
INDICATOR,
|
||||
MULTILAYER,
|
||||
REACTIVE_FADE,
|
||||
REACTIVE_PUNCH,
|
||||
REACTIVE_TORNADO,
|
||||
HEARTBEAT,
|
||||
FIREBALL,
|
||||
SNOW,
|
||||
CIRCLE_SPECTRUM,
|
||||
WATER_RIPPLE,
|
||||
OFF
|
||||
};
|
||||
|
||||
#define CM_KB_ZONES_MAX 1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
std::string name;
|
||||
zone_type type;
|
||||
} cm_kb_zone;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t product_id;
|
||||
const cm_kb_zone * zones[CM_KB_ZONES_MAX];
|
||||
keyboard_keymap_overlay_values* layout_new;
|
||||
} cm_kb_device;
|
||||
|
||||
#define COOLERMASTER_VID 0x2516
|
||||
|
||||
#define CMKB_MAXKEYS 256
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| keyboard support status is indicated to the right of |
|
||||
| the PID definition. Attribution to products is also |
|
||||
| indicated. |
|
||||
| |
|
||||
| libcmmk |
|
||||
| signal https://gitlab.com/signalrgb/signal-plugins |
|
||||
| openrgb |
|
||||
| ck550-macos https://github.com/vookimedlo/ck550-macos/tree/master |
|
||||
| reversed |
|
||||
| |
|
||||
| issue tickets, open merge requests etc are provided |
|
||||
| for developer references. |
|
||||
| # denotes issue ticket |
|
||||
| ! denotes merge/pull request |
|
||||
\*-----------------------------------------------------------------*/
|
||||
#define COOLERMASTER_KEYBOARD_CK351_PID 0x014F // unsupported
|
||||
#define COOLERMASTER_KEYBOARD_CK530_PID 0x009F // [ck550-macos]
|
||||
#define COOLERMASTER_KEYBOARD_CK530_V2_PID 0x0147 // [signal]
|
||||
#define COOLERMASTER_KEYBOARD_CK550_V2_PID 0x0145 // [openrgb #800, #2863, signal]
|
||||
#define COOLERMASTER_KEYBOARD_CK552_V2_PID 0x007F // [ck550-macos, signal]
|
||||
#define COOLERMASTER_KEYBOARD_CK570_V2_PID 0x01E8 // unsupported
|
||||
#define COOLERMASTER_KEYBOARD_CK720_PID 0x016B // unsupported
|
||||
#define COOLERMASTER_KEYBOARD_CK721_PID 0x016D // unsupported
|
||||
#define COOLERMASTER_KEYBOARD_CK721LINE_PID 0x01EE // unsupported
|
||||
#define COOLERMASTER_KEYBOARD_PRO_L_PID 0x003B // [libcmmk !16]
|
||||
#define COOLERMASTER_KEYBOARD_PRO_L_WHITE_PID 0x0047 // [libcmmk]
|
||||
#define COOLERMASTER_KEYBOARD_PRO_S_PID 0x003C // [libcmmk #30 !31 !36, !37, !7, #5(closed), #3(closed)]
|
||||
// MASTERKEYS PRO M [libcmmk #17]
|
||||
#define COOLERMASTER_KEYBOARD_MK721_PID 0x016F // unsupported
|
||||
#define COOLERMASTER_KEYBOARD_MK730_PID 0x008F // [openrgb #1630, libcmmk]
|
||||
#define COOLERMASTER_KEYBOARD_MK750_PID 0x0067 // fw1.2 [libcmmk #25 !9, !14, signal]
|
||||
#define COOLERMASTER_KEYBOARD_MK770_PID 0x01D5 // unsupported
|
||||
#define COOLERMASTER_KEYBOARD_MK850_PID 0x0069 // [signal]
|
||||
#define COOLERMASTER_KEYBOARD_SK620B_PID 0x0157 // [openrgb #4292]
|
||||
#define COOLERMASTER_KEYBOARD_SK620W_PID 0x0159 // [openrgb #4292, signal]
|
||||
#define COOLERMASTER_KEYBOARD_SK622B_PID 0x0149 // [openrgb #3110, signal #217(closed)]
|
||||
#define COOLERMASTER_KEYBOARD_SK622W_PID 0x014B // [signal]
|
||||
#define COOLERMASTER_KEYBOARD_SK630_PID 0x0089 // [openrgb #967, libcmmk !21]
|
||||
#define COOLERMASTER_KEYBOARD_SK631B_PID 0x008B // unsupported
|
||||
#define COOLERMASTER_KEYBOARD_SK631W_PID 0x0125 // [libcmmk]
|
||||
#define COOLERMASTER_KEYBOARD_SK650_PID 0x008D // [openrgb #613, libcmmk #23 !37 !27 !28, signal]
|
||||
#define COOLERMASTER_KEYBOARD_SK651B_PID 0x0091 // unsupported
|
||||
#define COOLERMASTER_KEYBOARD_SK651W_PID 0x0127 // [signal]
|
||||
#define COOLERMASTER_KEYBOARD_SK652_PID 0x015D // [signal]
|
||||
#define COOLERMASTER_KEYBOARD_SK653_PID 0x01AB // [openrgb #3571, signal]
|
||||
|
||||
extern const unsigned int COOLERMASTER_KEYBOARD_DEVICE_COUNT;
|
||||
extern const cm_kb_device** cm_kb_device_list;
|
||||
@@ -0,0 +1,500 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMKeyboardV1Controller.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master MasterKeys (V1) keyboards |
|
||||
| |
|
||||
| Tam D (too.manyhobbies) 30 Nov 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cmath>
|
||||
#include "CMKeyboardV1Controller.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
CMKeyboardV1Controller::CMKeyboardV1Controller(hid_device* dev_handle, hid_device_info* dev_info, std::string dev_name) : CMKeyboardAbstractController(dev_handle, dev_info, dev_name)
|
||||
{
|
||||
m_sFirmwareVersion = _GetFirmwareVersion();
|
||||
}
|
||||
|
||||
CMKeyboardV1Controller::~CMKeyboardV1Controller()
|
||||
{
|
||||
}
|
||||
|
||||
void CMKeyboardV1Controller::Initialize()
|
||||
{
|
||||
SetLEDControl(true);
|
||||
}
|
||||
|
||||
void CMKeyboardV1Controller::SetActiveEffect(uint8_t effectId)
|
||||
{
|
||||
SendCommand({0x51, 0x28, 0x00, 0x00, effectId});
|
||||
}
|
||||
|
||||
uint8_t CMKeyboardV1Controller::GetActiveEffect()
|
||||
{
|
||||
std::vector<uint8_t> data = SendCommand({0x52, 0x28});
|
||||
|
||||
return data[4];
|
||||
}
|
||||
|
||||
void CMKeyboardV1Controller::SetEffect(uint8_t effectId, uint8_t p1, uint8_t p2, uint8_t p3, RGBColor color1, RGBColor color2)
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
|
||||
data.push_back(0x51);
|
||||
data.push_back(0x2C);
|
||||
data.push_back(0x00); // multilayer_mode - NOT SUPPORTED
|
||||
data.push_back(0x00);
|
||||
data.push_back(effectId);
|
||||
data.push_back(p1);
|
||||
data.push_back(p2);
|
||||
data.push_back(p3);
|
||||
data.push_back(0xFF);
|
||||
data.push_back(0xFF);
|
||||
data.push_back(RGBGetRValue(color1));
|
||||
data.push_back(RGBGetGValue(color1));
|
||||
data.push_back(RGBGetBValue(color1));
|
||||
data.push_back(RGBGetRValue(color2));
|
||||
data.push_back(RGBGetGValue(color2));
|
||||
data.push_back(RGBGetBValue(color2));
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| Likely a bit mask for each LEDs. |
|
||||
| 3 bits per LED x 127 possible LEDs ~48 bytes|
|
||||
\*-------------------------------------------*/
|
||||
for(size_t i = 0; i < 48; i++)
|
||||
{
|
||||
data.push_back(0xFF);
|
||||
}
|
||||
|
||||
SetCustomMode();
|
||||
SetActiveEffect(effectId);
|
||||
SendCommand(data);
|
||||
}
|
||||
|
||||
void CMKeyboardV1Controller::SetCustomMode()
|
||||
{
|
||||
SetControlMode(0x01);
|
||||
}
|
||||
|
||||
void CMKeyboardV1Controller::SetMode(mode selectedMode)
|
||||
{
|
||||
RGBColor color1 = 0;
|
||||
RGBColor color2 = 0;
|
||||
uint8_t cSpeed = 0;
|
||||
uint8_t cDirection = 0;
|
||||
uint8_t effectId = selectedMode.value;
|
||||
bool bModeRandom = false;
|
||||
|
||||
if(selectedMode.colors.size() >= 1)
|
||||
{
|
||||
color1 = selectedMode.colors[0];
|
||||
}
|
||||
|
||||
if(selectedMode.colors.size() >= 2)
|
||||
{
|
||||
color2 = selectedMode.colors[1];
|
||||
}
|
||||
|
||||
if(selectedMode.color_mode == MODE_COLORS_RANDOM)
|
||||
{
|
||||
bModeRandom = true;
|
||||
}
|
||||
|
||||
int selectedEffect = mapModeValueEffect[effectId];
|
||||
cSpeed = selectedMode.speed;
|
||||
|
||||
switch(selectedMode.direction)
|
||||
{
|
||||
case MODE_DIRECTION_LEFT:
|
||||
case MODE_DIRECTION_HORIZONTAL:
|
||||
cDirection = 0x00;
|
||||
break;
|
||||
|
||||
case MODE_DIRECTION_RIGHT:
|
||||
cDirection = 0x04;
|
||||
break;
|
||||
|
||||
case MODE_DIRECTION_UP:
|
||||
case MODE_DIRECTION_VERTICAL:
|
||||
cDirection = 0x06;
|
||||
break;
|
||||
|
||||
case MODE_DIRECTION_DOWN:
|
||||
cDirection = 0x02;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(selectedEffect)
|
||||
{
|
||||
case DIRECT:
|
||||
case STATIC:
|
||||
{
|
||||
SetEffect(effectId, 0, 0, 0, color1, color2);
|
||||
}
|
||||
break;
|
||||
|
||||
case CROSS:
|
||||
case BREATHE:
|
||||
case REACTIVE_PUNCH:
|
||||
case CIRCLE_SPECTRUM:
|
||||
case SNAKE:
|
||||
{
|
||||
SetEffect(effectId, cSpeed, 0, 0xFF, color1, color2);
|
||||
}
|
||||
break;
|
||||
|
||||
case WAVE:
|
||||
{
|
||||
SetEffect(effectId, cSpeed, cDirection, 0xFF, color1, color2);
|
||||
}
|
||||
break;
|
||||
|
||||
case RIPPLE:
|
||||
{
|
||||
SetEffect(effectId, cSpeed, bModeRandom ? 0x80 : 0x00, 0xFF, color1, color2);
|
||||
}
|
||||
break;
|
||||
|
||||
case RAINDROPS:
|
||||
{
|
||||
SetEffect(effectId, 0x6a, 0x00, cSpeed, color1, color2);
|
||||
}
|
||||
break;
|
||||
|
||||
case STARS:
|
||||
{
|
||||
SetEffect(effectId, cSpeed, 0x00, 0x10, color1, color2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CMKeyboardV1Controller::InitializeModes(std::vector<mode> &modes)
|
||||
{
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0x02;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
|
||||
modes.push_back(Direct);
|
||||
|
||||
mapModeValueEffect[0x02] = DIRECT;
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = 0x00;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
mapModeValueEffect[0x00] = STATIC;
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = 0x01;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed_min = 0x46;
|
||||
Breathing.speed_max = 0x27;
|
||||
Breathing.speed = 0x36;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
modes.push_back(Breathing);
|
||||
mapModeValueEffect[0x01] = BREATHE;
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = 0x02;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = 0x96;
|
||||
Cycle.speed_max = 0x68;
|
||||
Cycle.speed = 0x7F;
|
||||
modes.push_back(Cycle);
|
||||
mapModeValueEffect[0x02] = CIRCLE_SPECTRUM;
|
||||
|
||||
mode Reactive;
|
||||
Reactive.name = "Reactive";
|
||||
Reactive.value = 0x03;
|
||||
Reactive.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Reactive.speed_min = 0x3C;
|
||||
Reactive.speed_max = 0x2F;
|
||||
Reactive.speed = 0x35;
|
||||
Reactive.colors_min = 2;
|
||||
Reactive.colors_max = 2;
|
||||
Reactive.colors.resize(2);
|
||||
modes.push_back(Reactive);
|
||||
mapModeValueEffect[0x03] = REACTIVE_PUNCH;
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Rainbow Wave";
|
||||
Wave.value = 0x04;
|
||||
Wave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD;
|
||||
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Wave.speed_min = 0x48;
|
||||
Wave.speed_max = 0x2A;
|
||||
Wave.speed = 0x29;
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
Wave.colors_min = 1;
|
||||
Wave.colors_max = 1;
|
||||
Wave.colors.resize(1);
|
||||
modes.push_back(Wave);
|
||||
mapModeValueEffect[0x04] = WAVE;
|
||||
|
||||
mode Ripple;
|
||||
Ripple.name = "Ripple Effect";
|
||||
Ripple.value = 0x05;
|
||||
Ripple.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Ripple.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Ripple.speed_min = 0x96;
|
||||
Ripple.speed_max = 0x62;
|
||||
Ripple.speed = 0x7C;
|
||||
Ripple.colors_min = 2;
|
||||
Ripple.colors_max = 2;
|
||||
Ripple.colors.resize(2);
|
||||
modes.push_back(Ripple);
|
||||
mapModeValueEffect[0x05] = RIPPLE;
|
||||
|
||||
mode Cross;
|
||||
Cross.name = "Cross";
|
||||
Cross.value = 0x06;
|
||||
Cross.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Cross.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Cross.speed_min = 0x2A;
|
||||
Cross.speed_max = 0x48;
|
||||
Cross.speed = 0x39;
|
||||
Cross.colors_min = 2;
|
||||
Cross.colors_max = 2;
|
||||
Cross.colors.resize(2);
|
||||
modes.push_back(Cross);
|
||||
mapModeValueEffect[0x06] = CROSS;
|
||||
|
||||
mode Raindrops;
|
||||
Raindrops.name = "Raindrops";
|
||||
Raindrops.value = 0x07;
|
||||
Raindrops.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Raindrops.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Raindrops.speed_min = 0x40;
|
||||
Raindrops.speed_max = 0x08;
|
||||
Raindrops.speed = 0x24;
|
||||
Raindrops.colors_min = 2;
|
||||
Raindrops.colors_max = 2;
|
||||
Raindrops.colors.resize(2);
|
||||
modes.push_back(Raindrops);
|
||||
mapModeValueEffect[0x07] = RAINDROPS;
|
||||
|
||||
mode Stars;
|
||||
Stars.name = "Starfield";
|
||||
Stars.value = 0x08;
|
||||
Stars.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Stars.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Stars.speed_min = 0x46;
|
||||
Stars.speed_max = 0x32;
|
||||
Stars.speed = 0x3C;
|
||||
Stars.colors_min = 2;
|
||||
Stars.colors_max = 2;
|
||||
Stars.colors.resize(2);
|
||||
modes.push_back(Stars);
|
||||
mapModeValueEffect[0x08] = STARS;
|
||||
|
||||
mode Snake;
|
||||
Snake.name = "Snake";
|
||||
Snake.value = 0x09;
|
||||
Snake.flags = MODE_FLAG_HAS_SPEED;
|
||||
Snake.color_mode = MODE_COLORS_NONE;
|
||||
Snake.speed_min = 0x48;
|
||||
Snake.speed_max = 0x2A;
|
||||
Snake.speed = 0x39;
|
||||
modes.push_back(Snake);
|
||||
mapModeValueEffect[0x09] = SNAKE;
|
||||
}
|
||||
|
||||
struct cm_keyboard_effect CMKeyboardV1Controller::GetEffect(uint8_t effectId)
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
data.push_back(0x52);
|
||||
data.push_back(0x2C);
|
||||
data.push_back(0x00);
|
||||
data.push_back(0x00);
|
||||
data.push_back(effectId);
|
||||
|
||||
data = SendCommand(data);
|
||||
struct cm_keyboard_effect response;
|
||||
|
||||
response.effectId = effectId;
|
||||
response.p1 = data[5];
|
||||
response.p2 = data[6];
|
||||
response.p3 = data[7];
|
||||
response.color1 = ToRGBColor(data[10], data[11], data[12]);
|
||||
response.color2 = ToRGBColor(data[13], data[14], data[15]);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> CMKeyboardV1Controller::GetEnabledEffects()
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
|
||||
data = SendCommand({0x52, 0x29});
|
||||
|
||||
std::vector<uint8_t> effects;
|
||||
|
||||
for(size_t i = 4; data[i] != 0xFF; i++)
|
||||
{
|
||||
effects.push_back(data[i]);
|
||||
}
|
||||
|
||||
return effects;
|
||||
}
|
||||
|
||||
|
||||
void CMKeyboardV1Controller::SetLEDControl(bool bManual)
|
||||
{
|
||||
uint8_t modeId = 0; // firmware
|
||||
|
||||
if(bManual)
|
||||
{
|
||||
modeId = 0x02; // manual
|
||||
}
|
||||
|
||||
SetControlMode(modeId);
|
||||
};
|
||||
|
||||
void CMKeyboardV1Controller::SetLeds(std::vector<led> leds, std::vector<RGBColor> colors)
|
||||
{
|
||||
SetLEDControl(true);
|
||||
|
||||
RGBColor rgbColorMap[CM_MAX_LEDS];
|
||||
memset(rgbColorMap, 0, sizeof(RGBColor)*CM_MAX_LEDS);
|
||||
|
||||
for(size_t i = 0; i < leds.size(); i++)
|
||||
{
|
||||
rgbColorMap[leds[i].value] = colors[i];
|
||||
}
|
||||
|
||||
RGBColor * pRGBColor = rgbColorMap;
|
||||
|
||||
std::lock_guard<std::mutex> guard(m_mutex);
|
||||
|
||||
for(size_t i = 0; i < 8; i++)
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
data.push_back(0xC0);
|
||||
data.push_back(0x02);
|
||||
data.push_back((uint8_t)(i * 2));
|
||||
data.push_back(0x00);
|
||||
|
||||
for(size_t j = 0; j < 16; j++)
|
||||
{
|
||||
data.push_back(RGBGetRValue(*pRGBColor));
|
||||
data.push_back(RGBGetGValue(*pRGBColor));
|
||||
data.push_back(RGBGetBValue(*pRGBColor));
|
||||
|
||||
++pRGBColor;
|
||||
}
|
||||
|
||||
SendCommand(data);
|
||||
}
|
||||
}
|
||||
|
||||
void CMKeyboardV1Controller::SetSingleLED(uint8_t in_led, RGBColor in_color)
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
data.push_back(0xC0);
|
||||
data.push_back(0x01);
|
||||
data.push_back(0x01);
|
||||
data.push_back(0x00);
|
||||
data.push_back(in_led);
|
||||
data.push_back(RGBGetRValue(in_color));
|
||||
data.push_back(RGBGetGValue(in_color));
|
||||
data.push_back(RGBGetBValue(in_color));
|
||||
|
||||
SendCommand(data);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*\
|
||||
| Detect the Firmware Version |
|
||||
| |
|
||||
| Firmware version string is in the format: |
|
||||
| <layout>.<minor>.<major> |
|
||||
| Where <layout> is: |
|
||||
| UNK = 0, ANSI/US = 1, ISO/EU = 2, JP = 3 |
|
||||
| Examples: |
|
||||
| 1.2.1 = ANSI/US Keyboard (PRO S) |
|
||||
| 2.2.1 = ISO/EU Keyboard (PRO L) |
|
||||
\*-------------------------------------------------------------------*/
|
||||
std::string CMKeyboardV1Controller::_GetFirmwareVersion()
|
||||
{
|
||||
std::vector<uint8_t> read;
|
||||
|
||||
SetControlMode(MODE_FIRMWARE);
|
||||
read = SendCommand({0x01, 0x02});
|
||||
|
||||
char cVersionStr[CM_KEYBOARD_WRITE_SIZE];
|
||||
|
||||
for(size_t i = 0; i < read.size(); i++)
|
||||
{
|
||||
cVersionStr[i] = read[i];
|
||||
}
|
||||
|
||||
cVersionStr[CM_KEYBOARD_WRITE_SIZE - 1] = 0;
|
||||
|
||||
std::string sFirmwareVersion;
|
||||
|
||||
sFirmwareVersion = std::string(cVersionStr+4);
|
||||
|
||||
LOG_VERBOSE("[%s] GetFirmwareVersion(): [%s]", m_deviceName.c_str(), sFirmwareVersion.c_str());
|
||||
|
||||
return sFirmwareVersion;
|
||||
}
|
||||
|
||||
void CMKeyboardV1Controller::Shutdown()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
KEYBOARD_LAYOUT CMKeyboardV1Controller::GetKeyboardLayout()
|
||||
{
|
||||
KEYBOARD_LAYOUT layout = KEYBOARD_LAYOUT_DEFAULT;
|
||||
|
||||
if(m_sFirmwareVersion.empty())
|
||||
{
|
||||
LOG_WARNING("[%s] GetKeyboardLayout() empty firmware string detected. Unable to detect firmware layout. Assuming defaults.", m_deviceName.c_str());
|
||||
|
||||
layout = KEYBOARD_LAYOUT_ANSI_QWERTY;
|
||||
return layout;
|
||||
}
|
||||
|
||||
switch(m_sFirmwareVersion.c_str()[0])
|
||||
{
|
||||
case '0':
|
||||
default:
|
||||
case '1':
|
||||
layout = KEYBOARD_LAYOUT_ANSI_QWERTY;
|
||||
break;
|
||||
|
||||
case '2':
|
||||
layout = KEYBOARD_LAYOUT_ISO_QWERTY;
|
||||
break;
|
||||
|
||||
case '3':
|
||||
layout = KEYBOARD_LAYOUT_JIS;
|
||||
break;
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMKeyboardV1Controller.h |
|
||||
| |
|
||||
| Driver for Cooler Master MasterKeys (V1) keyboards |
|
||||
| |
|
||||
| Tam D (too.manyhobbies) 30 Nov 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CMKeyboardAbstractController.h"
|
||||
|
||||
class CMKeyboardV1Controller : public CMKeyboardAbstractController
|
||||
{
|
||||
public:
|
||||
CMKeyboardV1Controller(hid_device* dev_handle, hid_device_info* dev_info, std::string dev_name);
|
||||
~CMKeyboardV1Controller();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Protocol specific funtions to be implmented |
|
||||
\*---------------------------------------------------------*/
|
||||
void SetLeds(std::vector<led> leds, std::vector<RGBColor> colors);
|
||||
void SetSingleLED(uint8_t in_led, RGBColor in_color);
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
void SetLEDControl(bool bManual);
|
||||
|
||||
void SetActiveEffect(uint8_t effectId);
|
||||
uint8_t GetActiveEffect();
|
||||
void SetEffect(uint8_t effectId, uint8_t p1, uint8_t p2, uint8_t p3, RGBColor color1, RGBColor color2);
|
||||
struct cm_keyboard_effect GetEffect(uint8_t effectId);
|
||||
void SetCustomMode();
|
||||
void SetMode(mode selectedMode);
|
||||
std::vector<uint8_t> GetEnabledEffects();
|
||||
void InitializeModes(std::vector<mode> &modes);
|
||||
KEYBOARD_LAYOUT GetKeyboardLayout();
|
||||
|
||||
private:
|
||||
std::string _GetFirmwareVersion();
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMKeyboardV2Controller.h |
|
||||
| |
|
||||
| Driver for Cooler Master V2 keyboards |
|
||||
| |
|
||||
| Tam D (too.manyhobbies) 30 Nov 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CMKeyboardAbstractController.h"
|
||||
|
||||
struct stCMKeyboardV2_mode
|
||||
{
|
||||
const char *name;
|
||||
unsigned int value;
|
||||
unsigned int speed_min;
|
||||
unsigned int speed_max;
|
||||
unsigned int speed;
|
||||
unsigned int brightness;
|
||||
unsigned int direction;
|
||||
unsigned int nColors;
|
||||
unsigned int color_mode;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
class CMKeyboardV2Controller : public CMKeyboardAbstractController
|
||||
{
|
||||
public:
|
||||
CMKeyboardV2Controller(hid_device* dev_handle, hid_device_info* dev_info, std::string dev_name);
|
||||
~CMKeyboardV2Controller();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Protocol specific funtions to be implmented |
|
||||
\*---------------------------------------------------------*/
|
||||
void SetLeds(std::vector<led> leds, std::vector<RGBColor> colors);
|
||||
void SetSingleLED(uint8_t in_led, RGBColor in_color);
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
void SetLEDControl(bool bManual);
|
||||
void SendApplyPacket(uint8_t mode);
|
||||
void MagicStartupPacket();
|
||||
void MagicCommand(uint8_t profileId);
|
||||
void SetCustomMode();
|
||||
void SetMode(mode selectedMode);
|
||||
void SetEffect(uint8_t effectId, uint8_t p1, uint8_t p2, uint8_t p3, RGBColor color1, RGBColor color2);
|
||||
void InitializeModes(std::vector<mode> &modes);
|
||||
KEYBOARD_LAYOUT GetKeyboardLayout();
|
||||
|
||||
private:
|
||||
void _SetEffectMode(uint8_t effectId);
|
||||
void _UpdateSpeed(mode selectedMode, uint8_t &cSpeed1, uint8_t &cSpeed2);
|
||||
std::string _GetFirmwareVersion();
|
||||
|
||||
bool m_bMoreFFs;
|
||||
};
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMKeyboardController.cpp |
|
||||
| |
|
||||
| RGBController for Cooler Master keyboards |
|
||||
| |
|
||||
| Tam D (too.manyhobbies) 30 Nov 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CMKeyboardController.h"
|
||||
#include "CMKeyboardDevices.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Coolermaster Masterkeys Keyboards
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterV1Keyboards,DetectCoolerMasterV2Keyboards
|
||||
@comment
|
||||
In CMKeyboardV1Controller brightness control not supported.
|
||||
Supported effects differ between CMKeyboardV1Controller and
|
||||
CMKeyboardV2Controller.
|
||||
\*-------------------------------------------------------------------*/
|
||||
RGBController_CMKeyboardController::RGBController_CMKeyboardController(CMKeyboardAbstractController* pController)
|
||||
{
|
||||
m_pController = pController;
|
||||
vendor = m_pController->GetDeviceVendor();
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Cooler Master Keyboard Device";
|
||||
version = m_pController->GetFirmwareVersion();
|
||||
|
||||
/*----------------------------------------------------------------*\
|
||||
| Coolermaster uses the name field to store the serial number in |
|
||||
| many of their keyboards. |
|
||||
\*----------------------------------------------------------------*/
|
||||
serial = m_pController->GetDeviceSerial();
|
||||
location = m_pController->GetLocation();
|
||||
m_keyboardLayout = m_pController->GetKeyboardLayout();
|
||||
name = m_pController->GetDeviceName();
|
||||
|
||||
m_pController->InitializeModes(modes);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_CMKeyboardController::~RGBController_CMKeyboardController()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Delete the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
if(zones[zone_index].matrix_map->map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map->map;
|
||||
}
|
||||
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_pController)
|
||||
{
|
||||
delete m_pController;
|
||||
}
|
||||
}
|
||||
|
||||
#define COOLERMASTER_ZONES_MAX 1
|
||||
void RGBController_CMKeyboardController::SetupZones()
|
||||
{
|
||||
std::string physical_size;
|
||||
unsigned int max_led_value = 0;
|
||||
const cm_kb_device* coolermaster = m_pController->GetDeviceData();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Fill in zones from the device data |
|
||||
\*---------------------------------------------------------*/
|
||||
for(size_t i = 0; i < COOLERMASTER_ZONES_MAX; i++)
|
||||
{
|
||||
if(coolermaster->zones[i] == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
zone new_zone;
|
||||
|
||||
new_zone.name = coolermaster->zones[i]->name;
|
||||
new_zone.type = coolermaster->zones[i]->type;
|
||||
|
||||
if(new_zone.type == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
KeyboardLayoutManager new_kb(m_keyboardLayout, coolermaster->layout_new->base_size, coolermaster->layout_new->key_values);
|
||||
|
||||
matrix_map_type * new_map = new matrix_map_type;
|
||||
new_zone.matrix_map = new_map;
|
||||
|
||||
if(coolermaster->layout_new->base_size != KEYBOARD_SIZE_EMPTY)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Minor adjustments to keyboard layout |
|
||||
\*---------------------------------------------------------*/
|
||||
keyboard_keymap_overlay_values* temp = coolermaster->layout_new;
|
||||
new_kb.ChangeKeys(*temp);
|
||||
|
||||
new_map->height = new_kb.GetRowCount();
|
||||
new_map->width = new_kb.GetColumnCount();
|
||||
new_map->map = new unsigned int[new_map->height * new_map->width];
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Matrix map still uses declared zone rows and columns |
|
||||
| as the packet structure depends on the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
new_kb.GetKeyMap(new_map->map, KEYBOARD_MAP_FILL_TYPE_COUNT, new_map->height, new_map->width);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs for the Matrix zone |
|
||||
| Place keys in the layout to populate the matrix |
|
||||
\*---------------------------------------------------------*/
|
||||
new_zone.leds_count = new_kb.GetKeyCount();
|
||||
LOG_DEBUG("[%s] Created KB matrix with %d rows and %d columns containing %d keys",
|
||||
m_pController->GetDeviceName().c_str(), new_kb.GetRowCount(), new_kb.GetColumnCount(), new_zone.leds_count);
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
|
||||
new_led.name = new_kb.GetKeyNameAt(led_idx);
|
||||
new_led.value = new_kb.GetKeyValueAt(led_idx);
|
||||
max_led_value = std::max(max_led_value, new_led.value);
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Add 1 the max_led_value to account for the 0th index |
|
||||
\*---------------------------------------------------------*/
|
||||
max_led_value++;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| name is not set yet so description is used instead |
|
||||
\*---------------------------------------------------------*/
|
||||
LOG_DEBUG("[%s] Creating a %s zone: %s with %d LEDs", description.c_str(),
|
||||
((new_zone.type == ZONE_TYPE_MATRIX) ? "matrix": "linear"),
|
||||
new_zone.name.c_str(), new_zone.leds_count);
|
||||
new_zone.leds_min = new_zone.leds_count;
|
||||
new_zone.leds_max = new_zone.leds_count;
|
||||
zones.push_back(new_zone);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMKeyboardController::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
}
|
||||
|
||||
void RGBController_CMKeyboardController::DeviceUpdateLEDs()
|
||||
{
|
||||
m_pController->SetLeds(leds, colors);
|
||||
}
|
||||
|
||||
void RGBController_CMKeyboardController::UpdateSingleLED(int led, RGBColor color)
|
||||
{
|
||||
uint8_t key_value = m_pLayoutManager->GetKeyValueAt(led);
|
||||
m_pController->SetSingleLED(key_value, color);
|
||||
}
|
||||
|
||||
void RGBController_CMKeyboardController::UpdateSingleLED(int led)
|
||||
{
|
||||
m_pController->SetSingleLED(led, colors[led]);
|
||||
}
|
||||
|
||||
void RGBController_CMKeyboardController::UpdateZoneLEDs(int /*zone_idx*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMKeyboardController::DeviceUpdateMode()
|
||||
{
|
||||
m_pController->SetMode(modes[active_mode]);
|
||||
}
|
||||
|
||||
void RGBController_CMKeyboardController::SetCustomMode()
|
||||
{
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMKeyboardController.h |
|
||||
| |
|
||||
| RGBController for Cooler Master keyboards |
|
||||
| |
|
||||
| Tam D (too.manyhobbies) 30 Nov 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CMKeyboardAbstractController.h"
|
||||
#include "CMKeyboardV1Controller.h"
|
||||
#include "CMKeyboardV2Controller.h"
|
||||
#include "CMKeyboardDevices.h"
|
||||
|
||||
class RGBController_CMKeyboardController : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMKeyboardController(CMKeyboardAbstractController* pController);
|
||||
~RGBController_CMKeyboardController();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateSingleLED(int led, RGBColor color);
|
||||
void UpdateSingleLED(int led);
|
||||
void UpdateZoneLEDs(int zone_idx);
|
||||
|
||||
void SetCustomMode();
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
CMKeyboardAbstractController* m_pController;;
|
||||
KeyboardLayoutManager* m_pLayoutManager;
|
||||
KEYBOARD_LAYOUT m_keyboardLayout;
|
||||
layout_values m_layoutValues;
|
||||
};
|
||||
@@ -0,0 +1,206 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMMM711Controller.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master M711 mouse |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "CMMM711Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
CMMM711Controller::CMMM711Controller(hid_device* dev_handle, char *_path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
current_speed = CM_MM711_SPEED_NORMAL;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get device name from HID manufacturer and product strings |
|
||||
\*---------------------------------------------------------*/
|
||||
wchar_t name_string[HID_MAX_STR];
|
||||
|
||||
hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
|
||||
device_name = StringUtils::wstring_to_string(name_string);
|
||||
|
||||
hid_get_product_string(dev, name_string, HID_MAX_STR);
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
|
||||
SendInitPacket();
|
||||
GetColourStatus();
|
||||
GetCustomStatus();
|
||||
GetModeStatus();
|
||||
}
|
||||
|
||||
CMMM711Controller::~CMMM711Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
void CMMM711Controller::GetColourStatus()
|
||||
{
|
||||
uint8_t buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x52, 0x2B };
|
||||
|
||||
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM711_PACKET_SIZE, CM_MM711_INTERRUPT_TIMEOUT);
|
||||
|
||||
current_brightness = buffer[CM_MM711_BRIGHTNESS_BYTE - 1];
|
||||
current_red = buffer[CM_MM711_RED_BYTE - 1];
|
||||
current_green = buffer[CM_MM711_GREEN_BYTE - 1];
|
||||
current_blue = buffer[CM_MM711_BLUE_BYTE - 1];
|
||||
}
|
||||
|
||||
void CMMM711Controller::GetCustomStatus()
|
||||
{
|
||||
uint8_t buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x52, 0xA8 };
|
||||
int read_size = CM_MM711_PACKET_SIZE - 1;
|
||||
int result = 0;
|
||||
|
||||
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
|
||||
do
|
||||
{
|
||||
result = hid_read_timeout(dev, buffer, read_size, CM_MM711_INTERRUPT_TIMEOUT);
|
||||
}while(buffer[1] != 0xA8 && result == read_size);
|
||||
|
||||
if(result == read_size)
|
||||
{
|
||||
wheel_colour = ToRGBColor(buffer[4], buffer[5], buffer[6]);
|
||||
logo_colour = ToRGBColor(buffer[7], buffer[8], buffer[9]);
|
||||
}
|
||||
}
|
||||
|
||||
void CMMM711Controller::GetModeStatus()
|
||||
{
|
||||
uint8_t buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x52, 0x28 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_MM711_INTERRUPT_TIMEOUT);
|
||||
|
||||
current_mode = buffer[CM_MM711_MODE_BYTE - 1];
|
||||
}
|
||||
|
||||
std::string CMMM711Controller::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string CMMM711Controller::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[HID_MAX_STR];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, HID_MAX_STR);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string CMMM711Controller::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
unsigned char CMMM711Controller::GetMode()
|
||||
{
|
||||
return(current_mode);
|
||||
}
|
||||
|
||||
unsigned char CMMM711Controller::GetLedRed()
|
||||
{
|
||||
return(current_red);
|
||||
}
|
||||
|
||||
unsigned char CMMM711Controller::GetLedGreen()
|
||||
{
|
||||
return(current_green);
|
||||
}
|
||||
|
||||
unsigned char CMMM711Controller::GetLedBlue()
|
||||
{
|
||||
return(current_blue);
|
||||
}
|
||||
|
||||
unsigned char CMMM711Controller::GetLedSpeed()
|
||||
{
|
||||
return(current_speed);
|
||||
}
|
||||
|
||||
RGBColor CMMM711Controller::GetWheelColour()
|
||||
{
|
||||
return(wheel_colour);
|
||||
}
|
||||
|
||||
RGBColor CMMM711Controller::GetLogoColour()
|
||||
{
|
||||
return(logo_colour);
|
||||
}
|
||||
|
||||
void CMMM711Controller::SetLedsDirect(RGBColor wheel_colour, RGBColor logo_colour)
|
||||
{
|
||||
unsigned char buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x51, 0xA8, 0x00, 0x00 };
|
||||
|
||||
buffer[CM_MM711_MODE_BYTE] = RGBGetRValue(wheel_colour);
|
||||
buffer[CM_MM711_SPEED_BYTE] = RGBGetGValue(wheel_colour);
|
||||
buffer[CM_MM711_NFI_1] = RGBGetBValue(wheel_colour);
|
||||
buffer[CM_MM711_NFI_2] = RGBGetRValue(logo_colour);
|
||||
buffer[CM_MM711_NFI_3] = RGBGetGValue(logo_colour);
|
||||
buffer[CM_MM711_BRIGHTNESS_BYTE] = RGBGetBValue(logo_colour);
|
||||
|
||||
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM711_PACKET_SIZE, CM_MM711_INTERRUPT_TIMEOUT);
|
||||
|
||||
//SendApplyPacket(0xB0); //Apply custom mode
|
||||
}
|
||||
|
||||
void CMMM711Controller::SendUpdate(uint8_t mode, uint8_t speed, RGBColor colour, uint8_t brightness)
|
||||
{
|
||||
unsigned char buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x51, 0x2B, 0x00, 0x00 };
|
||||
|
||||
buffer[CM_MM711_MODE_BYTE] = mode;
|
||||
buffer[CM_MM711_SPEED_BYTE] = speed;
|
||||
buffer[CM_MM711_NFI_1] = 0x20;
|
||||
buffer[CM_MM711_NFI_2] = 0xFF;
|
||||
buffer[CM_MM711_NFI_3] = 0xFF;
|
||||
buffer[CM_MM711_BRIGHTNESS_BYTE] = brightness;
|
||||
buffer[CM_MM711_RED_BYTE] = RGBGetRValue(colour);
|
||||
buffer[CM_MM711_GREEN_BYTE] = RGBGetGValue(colour);
|
||||
buffer[CM_MM711_BLUE_BYTE] = RGBGetBValue(colour);
|
||||
|
||||
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM711_PACKET_SIZE, CM_MM711_INTERRUPT_TIMEOUT);
|
||||
|
||||
SendApplyPacket(mode);
|
||||
}
|
||||
|
||||
void CMMM711Controller::SendInitPacket()
|
||||
{
|
||||
unsigned char buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x41, 0x80 };
|
||||
|
||||
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM711_PACKET_SIZE, CM_MM711_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMMM711Controller::SendApplyPacket(uint8_t mode)
|
||||
{
|
||||
unsigned char buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x51, 0x28, 0x00, 0x00 };
|
||||
|
||||
buffer[CM_MM711_MODE_BYTE] = mode;
|
||||
|
||||
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM711_PACKET_SIZE, CM_MM711_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMMM711Controller::SendSavePacket()
|
||||
{
|
||||
unsigned char buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x50, 0x55 };
|
||||
|
||||
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM711_PACKET_SIZE, CM_MM711_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMMM711Controller.h |
|
||||
| |
|
||||
| Driver for Cooler Master M711 mouse |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define CM_MM711_PACKET_SIZE 65
|
||||
#define CM_MM711_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
|
||||
#define CM_MM711_HEADER_DATA_SIZE (sizeof(argb_header_data) / sizeof(argb_headers) )
|
||||
#define CM_MM711_INTERRUPT_TIMEOUT 250
|
||||
#define CM_MM711_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM711_REPORT_BYTE = 1,
|
||||
CM_MM711_COMMAND_BYTE = 2,
|
||||
CM_MM711_FUNCTION_BYTE = 3,
|
||||
CM_MM711_ZONE_BYTE = 4,
|
||||
CM_MM711_MODE_BYTE = 5,
|
||||
CM_MM711_SPEED_BYTE = 6,
|
||||
CM_MM711_NFI_1 = 7,
|
||||
CM_MM711_NFI_2 = 8,
|
||||
CM_MM711_NFI_3 = 9,
|
||||
CM_MM711_BRIGHTNESS_BYTE = 10,
|
||||
CM_MM711_RED_BYTE = 11,
|
||||
CM_MM711_GREEN_BYTE = 12,
|
||||
CM_MM711_BLUE_BYTE = 13,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM711_MODE_STATIC = 0, //Static Mode
|
||||
CM_MM711_MODE_BREATHING = 1, //Breathing Mode
|
||||
CM_MM711_MODE_SPECTRUM_CYCLE = 2, //Spectrum Cycle Mode
|
||||
CM_MM711_MODE_INDICATOR = 4, //Indicator Mode
|
||||
CM_MM711_MODE_CUSTOM = 176, //Custom LED Control
|
||||
CM_MM711_MODE_OFF = 254 //Turn Off
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM711_SPEED_SLOWEST = 0x5F, // Slowest speed
|
||||
CM_MM711_SPEED_NORMAL = 0x38, // Normal speed
|
||||
CM_MM711_SPEED_FASTEST = 0x20, // Fastest speed
|
||||
};
|
||||
|
||||
class CMMM711Controller
|
||||
{
|
||||
public:
|
||||
CMMM711Controller(hid_device* dev_handle, char *_path);
|
||||
~CMMM711Controller();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
uint8_t GetZoneIndex();
|
||||
uint8_t GetMode();
|
||||
uint8_t GetLedRed();
|
||||
uint8_t GetLedGreen();
|
||||
uint8_t GetLedBlue();
|
||||
uint8_t GetLedSpeed();
|
||||
RGBColor GetWheelColour();
|
||||
RGBColor GetLogoColour();
|
||||
|
||||
void SendUpdate(uint8_t mode, uint8_t speed, RGBColor colour, uint8_t brightness);
|
||||
void SetLedsDirect(RGBColor wheel_colour, RGBColor logo_colour);
|
||||
void SendSavePacket();
|
||||
private:
|
||||
std::string device_name;
|
||||
std::string serial;
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
|
||||
uint8_t current_mode;
|
||||
uint8_t current_speed;
|
||||
|
||||
uint8_t current_brightness;
|
||||
uint8_t current_red;
|
||||
uint8_t current_green;
|
||||
uint8_t current_blue;
|
||||
RGBColor wheel_colour;
|
||||
RGBColor logo_colour;
|
||||
|
||||
void GetColourStatus();
|
||||
void GetCustomStatus();
|
||||
void GetModeStatus();
|
||||
void SendInitPacket();
|
||||
void SendApplyPacket(uint8_t mode);
|
||||
};
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMMM711Controller.cpp |
|
||||
| |
|
||||
| RGBController for Cooler Master M711 mouse |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CMMM711Controller.h"
|
||||
|
||||
#define applyBrightness(c, bright) ((RGBColor) ((RGBGetBValue(c) * bright / CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT) << 16 | (RGBGetGValue(c) * bright / CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT) << 8 | (RGBGetRValue(c) * bright / CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT)))
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Coolermaster Master Mouse
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterMouse
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMMM711Controller::RGBController_CMMM711Controller(CMMM711Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Cooler Master";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = controller->GetDeviceName();
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Custom;
|
||||
Custom.name = "Direct";
|
||||
Custom.value = CM_MM711_MODE_CUSTOM;
|
||||
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Custom.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Custom.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Custom.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Custom.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Custom);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CM_MM711_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Static.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Static.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(Static.colors_max);
|
||||
Static.speed_min = CM_MM711_SPEED_SLOWEST;
|
||||
Static.speed_max = CM_MM711_SPEED_FASTEST;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.speed = CM_MM711_SPEED_NORMAL;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_MM711_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Breathing.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Breathing.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(Breathing.colors_max);
|
||||
Breathing.speed_min = CM_MM711_SPEED_SLOWEST;
|
||||
Breathing.speed_max = CM_MM711_SPEED_FASTEST;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed = CM_MM711_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Spectrum_Cycle;
|
||||
Spectrum_Cycle.name = "Spectrum Cycle";
|
||||
Spectrum_Cycle.value = CM_MM711_MODE_SPECTRUM_CYCLE;
|
||||
Spectrum_Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Spectrum_Cycle.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Spectrum_Cycle.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM;
|
||||
Spectrum_Cycle.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM;
|
||||
Spectrum_Cycle.speed_min = CM_MM711_SPEED_SLOWEST;
|
||||
Spectrum_Cycle.speed_max = CM_MM711_SPEED_FASTEST;
|
||||
Spectrum_Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum_Cycle.speed = CM_MM711_SPEED_NORMAL;
|
||||
modes.push_back(Spectrum_Cycle);
|
||||
|
||||
mode Indicator;
|
||||
Indicator.name = "Indicator";
|
||||
Indicator.value = CM_MM711_MODE_INDICATOR;
|
||||
Indicator.flags = MODE_FLAG_MANUAL_SAVE;
|
||||
Indicator.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Indicator);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Turn Off";
|
||||
Off.value = CM_MM711_MODE_OFF;
|
||||
Off.flags = MODE_FLAG_MANUAL_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
Init_Controller(); //Only processed on first run
|
||||
SetupZones();
|
||||
|
||||
uint8_t temp_mode = controller->GetMode();
|
||||
|
||||
for(int mode_index = 0; mode_index < (int)modes.size(); mode_index++)
|
||||
{
|
||||
if(modes[mode_index].value == temp_mode)
|
||||
{
|
||||
active_mode = mode_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
modes[active_mode].colors[0] = ToRGBColor(controller->GetLedRed(),controller->GetLedGreen(),controller->GetLedBlue());
|
||||
}
|
||||
|
||||
colors[0] = controller->GetWheelColour();
|
||||
colors[1] = controller->GetLogoColour();
|
||||
}
|
||||
|
||||
RGBController_CMMM711Controller::~RGBController_CMMM711Controller()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMMM711Controller::Init_Controller()
|
||||
{
|
||||
zone mouse_zone;
|
||||
mouse_zone.name = name;
|
||||
mouse_zone.type = ZONE_TYPE_LINEAR;
|
||||
mouse_zone.leds_min = 2;
|
||||
mouse_zone.leds_max = 2;
|
||||
mouse_zone.leds_count = 2;
|
||||
mouse_zone.matrix_map = NULL;
|
||||
zones.push_back(mouse_zone);
|
||||
|
||||
led wheel_led;
|
||||
wheel_led.name = "Scroll Wheel LED";
|
||||
wheel_led.value = 0;
|
||||
leds.push_back(wheel_led);
|
||||
|
||||
led logo_led;
|
||||
logo_led.name = "Logo LED";
|
||||
logo_led.value = 1;
|
||||
leds.push_back(logo_led);
|
||||
}
|
||||
|
||||
void RGBController_CMMM711Controller::SetupZones()
|
||||
{
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMMM711Controller::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CMMM711Controller::DeviceUpdateLEDs()
|
||||
{
|
||||
RGBColor wheel = applyBrightness(colors[0], modes[active_mode].brightness);
|
||||
RGBColor logo = applyBrightness(colors[1], modes[active_mode].brightness);
|
||||
|
||||
controller->SetLedsDirect( wheel, logo);
|
||||
}
|
||||
|
||||
void RGBController_CMMM711Controller::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMMM711Controller::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMMM711Controller::DeviceUpdateMode()
|
||||
{
|
||||
RGBColor colour = 0;
|
||||
|
||||
if(modes[active_mode].value != CM_MM711_MODE_CUSTOM)
|
||||
{
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC )
|
||||
{
|
||||
colour = modes[active_mode].colors[0];
|
||||
}
|
||||
|
||||
controller->SendUpdate(modes[active_mode].value, modes[active_mode].speed, colour, modes[active_mode].brightness);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMMM711Controller::DeviceSaveMode()
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
controller->SendSavePacket();
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMMM711Controller.h |
|
||||
| |
|
||||
| RGBController for Cooler Master M711 mouse |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "RGBController.h"
|
||||
#include "CMMM711Controller.h"
|
||||
|
||||
#define CM_MM_ARGB_BRIGHTNESS_MIN 0x00
|
||||
#define CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT 0xFF
|
||||
#define CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM 0x7F
|
||||
|
||||
class RGBController_CMMM711Controller : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMMM711Controller(CMMM711Controller* controller_ptr);
|
||||
~RGBController_CMMM711Controller();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
private:
|
||||
void Init_Controller();
|
||||
int GetDeviceMode();
|
||||
|
||||
CMMM711Controller* controller;
|
||||
};
|
||||
@@ -0,0 +1,192 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMMM712Controller.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master MM712 mouse |
|
||||
| Derived from CMMM711Controller.cpp |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| Frans Meulenbroeks 08 Dec 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "CMMM712Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
#define CM_MM712_PACKET_SIZE 65
|
||||
#define CM_MM712_INTERRUPT_TIMEOUT 250
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM712_MODE_BYTE = 4,
|
||||
CM_MM712_BRIGHTNESS_BYTE = 6,
|
||||
CM_MM712_SPEED_BYTE = 7,
|
||||
CM_MM712_RED_BYTE = 8,
|
||||
CM_MM712_GREEN_BYTE = 9,
|
||||
CM_MM712_BLUE_BYTE = 10,
|
||||
};
|
||||
|
||||
CMMM712Controller::CMMM712Controller(hid_device* dev_handle, char *_path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get device name from HID manufacturer and product strings |
|
||||
\*---------------------------------------------------------*/
|
||||
wchar_t name_string[HID_MAX_STR];
|
||||
|
||||
hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
|
||||
device_name = StringUtils::wstring_to_string(name_string);
|
||||
|
||||
hid_get_product_string(dev, name_string, HID_MAX_STR);
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
|
||||
SendInitPacket();
|
||||
GetModeStatus();
|
||||
GetColorStatus(current_mode);
|
||||
}
|
||||
|
||||
CMMM712Controller::~CMMM712Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
void CMMM712Controller::SendBuffer(uint8_t *buffer, uint8_t buffer_size)
|
||||
{
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_MM712_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMMM712Controller::GetColorStatus(uint8_t mode)
|
||||
{
|
||||
uint8_t buffer[CM_MM712_PACKET_SIZE] = { 0x00, 0x4C, 0x81, 0x03, mode };
|
||||
|
||||
SendBuffer(buffer, CM_MM712_PACKET_SIZE);
|
||||
initial_color = ToRGBColor(buffer[CM_MM712_RED_BYTE - 2], buffer[CM_MM712_GREEN_BYTE - 2], buffer[CM_MM712_BLUE_BYTE - 2]);
|
||||
}
|
||||
|
||||
void CMMM712Controller::GetModeStatus()
|
||||
{
|
||||
uint8_t buffer[CM_MM712_PACKET_SIZE] = { 0x00, 0x4C, 0x81, 0x07 };
|
||||
|
||||
SendBuffer(buffer, CM_MM712_PACKET_SIZE);
|
||||
current_mode = buffer[CM_MM712_MODE_BYTE - 1];
|
||||
SetMode(current_mode);
|
||||
}
|
||||
|
||||
std::string CMMM712Controller::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string CMMM712Controller::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[HID_MAX_STR];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, HID_MAX_STR);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string CMMM712Controller::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
unsigned char CMMM712Controller::GetMode()
|
||||
{
|
||||
return(current_mode);
|
||||
}
|
||||
|
||||
RGBColor CMMM712Controller::GetInitialLedColor()
|
||||
{
|
||||
return initial_color;
|
||||
}
|
||||
|
||||
void CMMM712Controller::SetLedsDirect(RGBColor color)
|
||||
{
|
||||
unsigned char buffer[CM_MM712_PACKET_SIZE] =
|
||||
{
|
||||
0x00, 0x5A, 0x81, 0x03,
|
||||
(unsigned char)RGBGetRValue(color),
|
||||
(unsigned char)RGBGetGValue(color),
|
||||
(unsigned char)RGBGetBValue(color)
|
||||
};
|
||||
|
||||
if(current_mode!=CM_MM712_MODE_DIRECT)
|
||||
{
|
||||
SetDirectMode(true);
|
||||
}
|
||||
hid_write(dev, buffer, CM_MM712_PACKET_SIZE);
|
||||
// SendBuffer(buffer, CM_MM712_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void CMMM712Controller::SendUpdate(uint8_t mode, uint8_t speed, RGBColor color, uint8_t brightness)
|
||||
{
|
||||
unsigned char buffer[CM_MM712_PACKET_SIZE] =
|
||||
{
|
||||
0x00, 0x4C, 0x81, 0x04, mode, 0xFF, brightness, speed,
|
||||
(unsigned char)RGBGetRValue(color),
|
||||
(unsigned char)RGBGetGValue(color),
|
||||
(unsigned char)RGBGetBValue(color),
|
||||
0xFF
|
||||
};
|
||||
|
||||
if(current_mode==CM_MM712_MODE_DIRECT)
|
||||
{
|
||||
SetDirectMode(false);
|
||||
SendInitPacket();
|
||||
}
|
||||
|
||||
SendBuffer(buffer, CM_MM712_PACKET_SIZE);
|
||||
SetMode(mode);
|
||||
}
|
||||
|
||||
void CMMM712Controller::SendInitPacket()
|
||||
{
|
||||
unsigned char buffer[CM_MM712_PACKET_SIZE] = { 0x00, 0x44, 0x81, 0x02 };
|
||||
|
||||
SendBuffer(buffer, CM_MM712_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void CMMM712Controller::SetDirectMode(bool onoff)
|
||||
{
|
||||
unsigned char buffer[CM_MM712_PACKET_SIZE] = { 0x00, 0x5a, 0x81, (unsigned char)(0x01+onoff) };
|
||||
|
||||
hid_write(dev, buffer, CM_MM712_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void CMMM712Controller::SetMode(uint8_t mode)
|
||||
{
|
||||
unsigned char buffer[CM_MM712_PACKET_SIZE] = { 0x00, 0x4C, 0x81, 0x08, mode};
|
||||
|
||||
if(current_mode==CM_MM712_MODE_DIRECT)
|
||||
{
|
||||
SendInitPacket();
|
||||
}
|
||||
|
||||
SendBuffer(buffer, CM_MM712_PACKET_SIZE);
|
||||
current_mode = mode;
|
||||
}
|
||||
|
||||
void CMMM712Controller::SetProfile(uint8_t profile)
|
||||
{
|
||||
unsigned char buffer[CM_MM712_PACKET_SIZE] = { 0x00, 0x44, 0x81, 0x01, profile};
|
||||
|
||||
SendBuffer(buffer, CM_MM712_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void CMMM712Controller::SaveStatus()
|
||||
{
|
||||
unsigned char buffer[CM_MM712_PACKET_SIZE] = { 0x54, 0x81, 1};
|
||||
|
||||
SendBuffer(buffer, CM_MM712_PACKET_SIZE);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMMM712Controller.h |
|
||||
| |
|
||||
| Driver for Cooler Master MM712 mouse |
|
||||
| Derived from CMMM711Controller.h |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| Frans Meulenbroeks 08 Dec 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM712_MODE_STATIC = 0, //Static Mode
|
||||
CM_MM712_MODE_BREATHING = 1, //Breathing Mode
|
||||
CM_MM712_MODE_SPECTRUM_CYCLE = 2, //Spectrum Cycle Mode
|
||||
CM_MM712_MODE_OFF = 3, //Turn Off
|
||||
CM_MM712_MODE_DIRECT = 4, //Direct LED Control
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM712_SPEED_SLOWEST = 0x0, //Slowest speed
|
||||
CM_MM712_SPEED_NORMAL = 0x2, //Normal speed
|
||||
CM_MM712_SPEED_FASTEST = 0x4, //Fastest speed
|
||||
};
|
||||
|
||||
class CMMM712Controller
|
||||
{
|
||||
public:
|
||||
CMMM712Controller(hid_device* dev_handle, char *_path);
|
||||
~CMMM712Controller();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
uint8_t GetMode();
|
||||
RGBColor GetInitialLedColor();
|
||||
|
||||
void SendUpdate(uint8_t mode, uint8_t speed, RGBColor color, uint8_t brightness);
|
||||
void SetMode(uint8_t mode);
|
||||
void SetDirectMode(bool onoff);
|
||||
void SetLedsDirect(RGBColor color);
|
||||
void SaveStatus();
|
||||
private:
|
||||
std::string device_name;
|
||||
std::string serial;
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
|
||||
uint8_t current_mode;
|
||||
RGBColor initial_color;
|
||||
|
||||
void GetColorStatus(uint8_t mode);
|
||||
void GetModeStatus();
|
||||
void SendInitPacket();
|
||||
void SetProfile(uint8_t profile);
|
||||
void SendBuffer(uint8_t *buffer, uint8_t buffer_size);
|
||||
|
||||
};
|
||||
@@ -0,0 +1,108 @@
|
||||
Analysis of the MM712 protocol
|
||||
By Frans Meulenbroeks
|
||||
PID 0x2516, VID 0x0169
|
||||
We must use interface 3
|
||||
C = Command, R = Response
|
||||
|
||||
Init:
|
||||
=====
|
||||
C: 0x00 0x44 0x81 0x02
|
||||
R: 0x45 0x81 0x02 0x02 0x01
|
||||
First byte is second byte of command+1, 2nd and 3rd byte are the 3rd and 4th byte of the command
|
||||
No idea what the last two bytes are.
|
||||
This init command inits to normal state.
|
||||
After that one can submit all normal commands. These give a response.
|
||||
|
||||
C: 0x00 0x5a 0x81 0x02
|
||||
R: 0x5b 0x81 0x02
|
||||
This init command inits to direct state.
|
||||
After that one can submit all direct state commands. These give no response
|
||||
|
||||
Note that you can always change between the two states by giving the appropriate init command.
|
||||
|
||||
I have also seen
|
||||
C: 0x00, 0x46, 0x81
|
||||
0x46 is command code
|
||||
R: 47 81 50 03 00 00 f2 9b 1e 00 64 02 00 00 00 ff 03 06 00 ...
|
||||
No idea what the response data is
|
||||
This also brought the device to type-4 state.
|
||||
|
||||
NORMAL COMMANDS
|
||||
===============
|
||||
|
||||
Query stored colors:
|
||||
====================
|
||||
C: 0x00 0x4c 0x81 0x03 0
|
||||
R: 0x4d 0x81 0x03 0x06 0xff 0x00 0xff 0xff 0x00
|
||||
Brig Spee Red Gree Blue Speed is not really relevant
|
||||
These are the settings for the static mode
|
||||
|
||||
C: 0x00 0x4c 0x81 0x03 1
|
||||
R: 0x4d 0x81 0x03 0xff 0xff 0x04 0xff 0x00 0x00 0xff
|
||||
Brig Spee Red Gree Blue
|
||||
These are the settings for the breathing mode
|
||||
|
||||
C: 0x00 0x4c 0x81 0x03 2
|
||||
R: 0x81 0x03 0x06 0x7f 0x02
|
||||
Brig Spee
|
||||
These are the settings for the cycling mode
|
||||
|
||||
C: 0x00 0x4c 0x81 0x03 3
|
||||
R: 0x4d 0x81 0x03 0x06 0x00
|
||||
This is the response for the off mode
|
||||
Other/higher numbers also return this value
|
||||
|
||||
Detecting the mode:
|
||||
===================
|
||||
C: 0x00 0x4c 0x81 0x07
|
||||
R: 0x4d 0x81 0x07 0x01
|
||||
^ actual mode
|
||||
|
||||
Setting the mode:
|
||||
=================
|
||||
C: 0x00 0x4c 0x81 0x08 0x01
|
||||
^ new mode 0=static,1=breathing,2=cycling,3 or higher=off
|
||||
R: 0x4d 0x81 0x07 0x01
|
||||
can't explain the 0x07; later calls returned 0x08 in this field
|
||||
|
||||
C: 0x00 0x4c 0x81 0x08 0x02
|
||||
R: 0x4d 0x81 0x08 0x02
|
||||
|
||||
Setting the color:
|
||||
==================
|
||||
C: 0x00 0x4c 0x81 0x04 0x00 0xff 0xff 0x02 0x00 0xff 0x00
|
||||
cmd mode ???? brig spee red gree blue Speed is only relevant for breathing and cyclic, color is not relevant for cyclic
|
||||
This sets the color, speed and brightness for the specific mode.
|
||||
Note that this does not imply a mode switch
|
||||
The first 0xff byte does not seem to do anything. I've changed to a different number but saw no result
|
||||
R: 0x47 0x81 0x50 0x03 0x00 0x00 0xf2 0x9b 0x1e 0x00 0x64 0x02 0x00 0x00 0x00 0xff 0x01 0xff 0x00 0x00
|
||||
No idea what this means, Reply seems independent of color set
|
||||
|
||||
Saving values:
|
||||
==============
|
||||
C: 0x00 0x54 0x81 0x01
|
||||
This saves the actual color for all modes and the mode itself to internal flash
|
||||
R: 0x55 0x81 0x01 0x00
|
||||
|
||||
Change Profile
|
||||
==============
|
||||
C: 0x00 0x44 0x81 0x01 0x02
|
||||
^ new profile must be in [0..4] otherwise this is a no-op
|
||||
R: 0x45 0x81 0x01 0x02 0x01
|
||||
^ it is unclear what this value is, values 0, 1 and 2 are observed
|
||||
|
||||
|
||||
DIRECT COMMANDS
|
||||
==============
|
||||
C: 0x00 0x5a 0x81 0x01
|
||||
Leave direct state (return to normal, note that a new init for normal is needed)
|
||||
|
||||
C: 0x00 0x5a 0x81 0x03 0xff 0x00 0x25
|
||||
red gree blue This changes the color right away. No response is generated.
|
||||
CoolerMaster MasterPlus software uses this to dynamically generate animations
|
||||
|
||||
Final notes:
|
||||
It is possible to change the mode on the mouse (see mouse doc).
|
||||
This also changes the value in flash
|
||||
It is also possible to change the colors in mode 0 and 1 using the mouse.
|
||||
8 different colors can be selected. I did not find a way to define these colors from software so I suspect these are hardcoded
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMMM712Controller.cpp |
|
||||
| |
|
||||
| RGBController for Cooler Master MM712 mouse |
|
||||
| Derived from RGBController_CMMM712Controller.cpp |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| Frans Meulenbroeks 08 Dec 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CMMM712Controller.h"
|
||||
|
||||
#define applyBrightness(c, bright) ((RGBColor) ((RGBGetBValue(c) * bright / CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT) << 16 | (RGBGetGValue(c) * bright / CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT) << 8 | (RGBGetRValue(c) * bright / CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT)))
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Coolermaster Master Mouse
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterMouse
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMMM712Controller::RGBController_CMMM712Controller(CMMM712Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Cooler Master";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = controller->GetDeviceName();
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CM_MM712_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Direct.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Direct.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CM_MM712_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Static.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Static.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(Static.colors_max);
|
||||
Static.speed_min = CM_MM712_SPEED_SLOWEST;
|
||||
Static.speed_max = CM_MM712_SPEED_FASTEST;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.speed = CM_MM712_SPEED_NORMAL;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_MM712_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Breathing.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Breathing.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(Breathing.colors_max);
|
||||
Breathing.speed_min = CM_MM712_SPEED_SLOWEST;
|
||||
Breathing.speed_max = CM_MM712_SPEED_FASTEST;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed = CM_MM712_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Spectrum_Cycle;
|
||||
Spectrum_Cycle.name = "Spectrum Cycle";
|
||||
Spectrum_Cycle.value = CM_MM712_MODE_SPECTRUM_CYCLE;
|
||||
Spectrum_Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Spectrum_Cycle.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Spectrum_Cycle.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM;
|
||||
Spectrum_Cycle.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM;
|
||||
Spectrum_Cycle.speed_min = CM_MM712_SPEED_SLOWEST;
|
||||
Spectrum_Cycle.speed_max = CM_MM712_SPEED_FASTEST;
|
||||
Spectrum_Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum_Cycle.speed = CM_MM712_SPEED_NORMAL;
|
||||
modes.push_back(Spectrum_Cycle);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = CM_MM712_MODE_OFF;
|
||||
Off.flags = MODE_FLAG_MANUAL_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
Init_Controller(); //Only processed on first run
|
||||
SetupZones();
|
||||
|
||||
uint8_t temp_mode = controller->GetMode();
|
||||
|
||||
for(int mode_index = 0; mode_index < (int)modes.size(); mode_index++)
|
||||
{
|
||||
if(modes[mode_index].value == temp_mode)
|
||||
{
|
||||
active_mode = mode_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
colors[0] = controller->GetInitialLedColor();
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
modes[active_mode].colors[0] = colors[0];
|
||||
}
|
||||
}
|
||||
|
||||
RGBController_CMMM712Controller::~RGBController_CMMM712Controller()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMMM712Controller::Init_Controller()
|
||||
{
|
||||
zone mouse_zone;
|
||||
mouse_zone.name = name;
|
||||
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 logo_led;
|
||||
logo_led.name = "Logo LED";
|
||||
logo_led.value = 0;
|
||||
leds.push_back(logo_led);
|
||||
}
|
||||
|
||||
void RGBController_CMMM712Controller::SetupZones()
|
||||
{
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMMM712Controller::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CMMM712Controller::DeviceUpdateLEDs()
|
||||
{
|
||||
modes[active_mode].brightness=255;
|
||||
RGBColor logo = applyBrightness(colors[0], modes[active_mode].brightness);
|
||||
|
||||
controller->SetLedsDirect(logo);
|
||||
}
|
||||
|
||||
void RGBController_CMMM712Controller::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMMM712Controller::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMMM712Controller::DeviceUpdateMode()
|
||||
{
|
||||
if(modes[active_mode].value==CM_MM712_MODE_DIRECT)
|
||||
{
|
||||
controller->SetDirectMode(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetDirectMode(false);
|
||||
RGBColor colour = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC )
|
||||
{
|
||||
colour = modes[active_mode].colors[0];
|
||||
}
|
||||
|
||||
controller->SendUpdate(modes[active_mode].value, modes[active_mode].speed, colour, modes[active_mode].brightness);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMMM712Controller::DeviceSaveMode()
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
controller->SaveStatus();
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMMM712Controller.h |
|
||||
| |
|
||||
| RGBController for Cooler Master M712 mouse |
|
||||
| Derived from RGBController_CMMM712Controller.h |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| Frans Meulenbroeks 08 Dec 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CMMM712Controller.h"
|
||||
|
||||
#define CM_MM_ARGB_BRIGHTNESS_MIN 0x00
|
||||
#define CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT 0xFF
|
||||
#define CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM 0x7F
|
||||
|
||||
class RGBController_CMMM712Controller : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMMM712Controller(CMMM712Controller* controller_ptr);
|
||||
~RGBController_CMMM712Controller();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
private:
|
||||
void Init_Controller();
|
||||
|
||||
CMMM712Controller* controller;
|
||||
};
|
||||
@@ -0,0 +1,346 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMMMController.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master mouse |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| Dracrius 12 Mar 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "CMMMController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
CMMMController::CMMMController(hid_device* dev_handle, char *_path, uint16_t pid, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
name = dev_name;
|
||||
current_speed = CM_MM_SPEED_3;
|
||||
product_id = pid;
|
||||
|
||||
if(product_id == CM_MM530_PID || product_id == CM_MM531_PID)
|
||||
{
|
||||
command_code = CM_MM5XX_COMMAND;
|
||||
if(pid == CM_MM530_PID)
|
||||
{
|
||||
buttons_bytes[0] = CM_MM_MODE_BYTE;
|
||||
buttons_bytes[1] = CM_MM_SPEED_BYTE;
|
||||
buttons_bytes[2] = CM_MM_NFI_1;
|
||||
wheel_bytes[0] = CM_MM_RED_BYTE;
|
||||
wheel_bytes[1] = CM_MM_GREEN_BYTE;
|
||||
wheel_bytes[2] = CM_MM_BLUE_BYTE;
|
||||
}
|
||||
else if(product_id == CM_MM531_PID) //Still Need Captures for Proper Mapping From a MM531 User
|
||||
{
|
||||
buttons_bytes[0] = CM_MM_MODE_BYTE;
|
||||
buttons_bytes[1] = CM_MM_SPEED_BYTE;
|
||||
buttons_bytes[2] = CM_MM_NFI_1;
|
||||
wheel_bytes[0] = CM_MM_RED_BYTE;
|
||||
wheel_bytes[1] = CM_MM_GREEN_BYTE;
|
||||
wheel_bytes[2] = CM_MM_BLUE_BYTE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
command_code = CM_MM7XX_COMMAND;
|
||||
|
||||
buttons_bytes[0] = CM_MM_RED_BYTE;
|
||||
buttons_bytes[1] = CM_MM_GREEN_BYTE;
|
||||
buttons_bytes[2] = CM_MM_BLUE_BYTE;
|
||||
wheel_bytes[0] = CM_MM_MODE_BYTE;
|
||||
wheel_bytes[1] = CM_MM_SPEED_BYTE;
|
||||
wheel_bytes[2] = CM_MM_NFI_1;
|
||||
}
|
||||
|
||||
logo_bytes[0] = CM_MM_NFI_2;
|
||||
logo_bytes[1] = CM_MM_NFI_3;
|
||||
logo_bytes[2] = CM_MM_BRIGHTNESS_BYTE;
|
||||
|
||||
SendInitPacket();
|
||||
GetColourStatus();
|
||||
GetCustomStatus();
|
||||
GetModeStatus();
|
||||
}
|
||||
|
||||
CMMMController::~CMMMController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
void CMMMController::GetColourStatus()
|
||||
{
|
||||
uint8_t buffer[CM_MM_PACKET_SIZE] = { 0x00, 0x52, command_code };
|
||||
|
||||
hid_write(dev, buffer, CM_MM_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM_PACKET_SIZE, CM_MM_INTERRUPT_TIMEOUT);
|
||||
|
||||
current_brightness = buffer[CM_MM_BRIGHTNESS_BYTE - 1];
|
||||
current_red = buffer[CM_MM_RED_BYTE - 1];
|
||||
current_green = buffer[CM_MM_GREEN_BYTE - 1];
|
||||
current_blue = buffer[CM_MM_BLUE_BYTE - 1];
|
||||
}
|
||||
|
||||
void CMMMController::GetCustomStatus()
|
||||
{
|
||||
uint8_t buffer[CM_MM_PACKET_SIZE] = { 0x00, 0x52, 0xA8 };
|
||||
int read_size = CM_MM_PACKET_SIZE - 1;
|
||||
int result = 0;
|
||||
|
||||
hid_write(dev, buffer, CM_MM_PACKET_SIZE);
|
||||
do
|
||||
{
|
||||
result = hid_read_timeout(dev, buffer, read_size, CM_MM_INTERRUPT_TIMEOUT);
|
||||
}while(buffer[1] != 0xA8 && result == read_size);
|
||||
|
||||
if(result == read_size)
|
||||
{
|
||||
buttons_colour = ToRGBColor(buffer[4], buffer[5], buffer[6]);
|
||||
logo_colour = ToRGBColor(buffer[7], buffer[8], buffer[9]);
|
||||
wheel_colour = ToRGBColor(buffer[10], buffer[11], buffer[12]);
|
||||
}
|
||||
}
|
||||
|
||||
void CMMMController::GetModeStatus()
|
||||
{
|
||||
uint8_t buffer[CM_MM_PACKET_SIZE] = { 0x00, 0x52, 0x28 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_MM_INTERRUPT_TIMEOUT);
|
||||
|
||||
current_mode = buffer[CM_MM_MODE_BYTE - 1];
|
||||
}
|
||||
|
||||
std::string CMMMController::GetDeviceVendor()
|
||||
{
|
||||
wchar_t vendor_string[HID_MAX_STR];
|
||||
int ret = hid_get_manufacturer_string(dev, vendor_string, HID_MAX_STR);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(vendor_string));
|
||||
}
|
||||
|
||||
std::string CMMMController::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[HID_MAX_STR];
|
||||
int ret = hid_get_indexed_string(dev, 2, serial_string, HID_MAX_STR);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string CMMMController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string CMMMController::GetName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
uint16_t CMMMController::GetProductID()
|
||||
{
|
||||
return product_id;
|
||||
}
|
||||
|
||||
unsigned char CMMMController::GetMode()
|
||||
{
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
unsigned char CMMMController::GetLedRed()
|
||||
{
|
||||
return current_red;
|
||||
}
|
||||
|
||||
unsigned char CMMMController::GetLedGreen()
|
||||
{
|
||||
return current_green;
|
||||
}
|
||||
|
||||
unsigned char CMMMController::GetLedBlue()
|
||||
{
|
||||
return current_blue;
|
||||
}
|
||||
|
||||
unsigned char CMMMController::GetLedSpeed()
|
||||
{
|
||||
return current_speed;
|
||||
}
|
||||
|
||||
RGBColor CMMMController::GetWheelColour()
|
||||
{
|
||||
return wheel_colour;
|
||||
}
|
||||
|
||||
RGBColor CMMMController::GetButtonsColour()
|
||||
{
|
||||
return buttons_colour;
|
||||
}
|
||||
|
||||
RGBColor CMMMController::GetLogoColour()
|
||||
{
|
||||
return logo_colour;
|
||||
}
|
||||
|
||||
void CMMMController::SetLedsDirect(RGBColor wheel_colour, RGBColor buttons_colour, RGBColor logo_colour)
|
||||
{
|
||||
unsigned char buffer[CM_MM_PACKET_SIZE] = { 0x00, 0x51, 0xA8, 0x00, 0x00 };
|
||||
|
||||
buffer[buttons_bytes[0]] = RGBGetRValue(buttons_colour);
|
||||
buffer[buttons_bytes[1]] = RGBGetGValue(buttons_colour);
|
||||
buffer[buttons_bytes[2]] = RGBGetBValue(buttons_colour);
|
||||
buffer[logo_bytes[0]] = RGBGetRValue(logo_colour);
|
||||
buffer[logo_bytes[1]] = RGBGetGValue(logo_colour);
|
||||
buffer[logo_bytes[2]] = RGBGetBValue(logo_colour);
|
||||
buffer[wheel_bytes[0]] = RGBGetRValue(wheel_colour);
|
||||
buffer[wheel_bytes[1]] = RGBGetGValue(wheel_colour);
|
||||
buffer[wheel_bytes[2]] = RGBGetBValue(wheel_colour);
|
||||
|
||||
hid_write(dev, buffer, CM_MM_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM_PACKET_SIZE, CM_MM_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMMMController::SendUpdate(uint8_t mode, uint8_t speed, RGBColor colour, uint8_t brightness)
|
||||
{
|
||||
if (mode == CM_MM_MODE_CUSTOM || mode == CM_MM_MODE_MULTILAYER)
|
||||
{
|
||||
SendUsingZonesPacket(mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendInitPacket();
|
||||
SendApplyPacket(mode);
|
||||
}
|
||||
|
||||
uint8_t nfi_1 = 0x20;
|
||||
|
||||
if (mode == CM_MM_MODE_STATIC || mode == CM_MM_MODE_SPECTRUM_CYCLE)
|
||||
{
|
||||
nfi_1 = 0x00;
|
||||
}
|
||||
|
||||
if (mode != CM_MM_MODE_OFF)
|
||||
{
|
||||
unsigned char buffer[CM_MM_PACKET_SIZE] = { 0x00, 0x51, command_code, 0x00, 0x00 };
|
||||
|
||||
buffer[CM_MM_MODE_BYTE] = mode;
|
||||
buffer[CM_MM_SPEED_BYTE] = speed;
|
||||
buffer[CM_MM_NFI_1] = nfi_1;
|
||||
buffer[CM_MM_NFI_2] = 0xFF;
|
||||
buffer[CM_MM_NFI_3] = 0xFF;
|
||||
buffer[CM_MM_BRIGHTNESS_BYTE] = brightness;
|
||||
buffer[CM_MM_RED_BYTE] = RGBGetRValue(colour);
|
||||
buffer[CM_MM_GREEN_BYTE] = RGBGetGValue(colour);
|
||||
buffer[CM_MM_BLUE_BYTE] = RGBGetBValue(colour);
|
||||
buffer[CM_MM_SKY_RED_BYTE] = 0x00;
|
||||
buffer[CM_MM_SKY_GREEN_BYTE] = 0x00;
|
||||
buffer[CM_MM_SKY_BLUE_BYTE] = 0x00;
|
||||
|
||||
for (int i = 17; i < CM_MM_PACKET_SIZE; i++)
|
||||
{
|
||||
buffer[i] = 0xFF;
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, CM_MM_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM_PACKET_SIZE, CM_MM_INTERRUPT_TIMEOUT);
|
||||
|
||||
}
|
||||
|
||||
if (mode == CM_MM_MODE_CUSTOM || mode == CM_MM_MODE_MULTILAYER)
|
||||
{
|
||||
SendApplyPacket(mode); //Post Apply for Zoned Modes
|
||||
}
|
||||
}
|
||||
|
||||
void CMMMController::SendUpdate(uint8_t mode, uint8_t speed, RGBColor mode_one, RGBColor mode_two, uint8_t brightness)
|
||||
{
|
||||
SendApplyPacket(mode);
|
||||
|
||||
unsigned char buffer[CM_MM_PACKET_SIZE] = { 0x00, 0x51, command_code, 0x00, 0x00 };
|
||||
|
||||
buffer[CM_MM_MODE_BYTE] = mode;
|
||||
buffer[CM_MM_SPEED_BYTE] = speed;
|
||||
buffer[CM_MM_NFI_1] = 0x00;
|
||||
buffer[CM_MM_NFI_2] = 0x21;
|
||||
buffer[CM_MM_NFI_3] = 0xFF;
|
||||
buffer[CM_MM_BRIGHTNESS_BYTE] = brightness;
|
||||
buffer[CM_MM_RED_BYTE] = RGBGetRValue(mode_one);
|
||||
buffer[CM_MM_GREEN_BYTE] = RGBGetGValue(mode_one);
|
||||
buffer[CM_MM_BLUE_BYTE] = RGBGetBValue(mode_one);
|
||||
buffer[CM_MM_SKY_RED_BYTE] = RGBGetRValue(mode_two);
|
||||
buffer[CM_MM_SKY_GREEN_BYTE] = RGBGetGValue(mode_two);
|
||||
buffer[CM_MM_SKY_BLUE_BYTE] = RGBGetBValue(mode_two);
|
||||
|
||||
for (int i = 17; i < CM_MM_PACKET_SIZE; i++)
|
||||
{
|
||||
buffer[i] = 0xFF;
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, CM_MM_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM_PACKET_SIZE, CM_MM_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMMMController::SendInitPacket()
|
||||
{
|
||||
unsigned char buffer[CM_MM_PACKET_SIZE] = { 0x00, 0x41, 0x80 };
|
||||
|
||||
hid_write(dev, buffer, CM_MM_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM_PACKET_SIZE, CM_MM_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMMMController::SendUsingZonesPacket(uint8_t mode)
|
||||
{
|
||||
unsigned char buffer[CM_MM_PACKET_SIZE] = { 0x00, 0x51, 0x30, 0x00, 0x00 };
|
||||
|
||||
if (mode == CM_MM_MODE_MULTILAYER)
|
||||
{
|
||||
buffer[CM_MM_MODE_BYTE] = 0x01;
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, CM_MM_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM_PACKET_SIZE, CM_MM_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMMMController::SendApplyPacket(uint8_t mode)
|
||||
{
|
||||
unsigned char buffer[CM_MM_PACKET_SIZE] = { 0x00, 0x51, 0x28, 0x00, 0x00 };
|
||||
|
||||
buffer[CM_MM_MODE_BYTE] = mode;
|
||||
|
||||
hid_write(dev, buffer, CM_MM_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM_PACKET_SIZE, CM_MM_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMMMController::SendMultilayerPacket(uint8_t zones[3])
|
||||
{
|
||||
unsigned char buffer[CM_MM_PACKET_SIZE] = { 0x00, 0x51, 0xA0, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00 };
|
||||
|
||||
buffer[CM_MM_NFI_3] = zones[0];
|
||||
buffer[CM_MM_BRIGHTNESS_BYTE] = zones[1];
|
||||
buffer[CM_MM_RED_BYTE] = zones[2];
|
||||
|
||||
hid_write(dev, buffer, CM_MM_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM_PACKET_SIZE, CM_MM_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMMMController::SendSavePacket()
|
||||
{
|
||||
unsigned char buffer[CM_MM_PACKET_SIZE] = { 0x00, 0x50, 0x55 };
|
||||
|
||||
hid_write(dev, buffer, CM_MM_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_MM_PACKET_SIZE, CM_MM_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMMMController.h |
|
||||
| |
|
||||
| Driver for Cooler Master mouse |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| Dracrius 12 Mar 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define CM_MM_PACKET_SIZE 65
|
||||
#define CM_MM_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
|
||||
#define CM_MM_HEADER_DATA_SIZE (sizeof(argb_header_data) / sizeof(argb_headers) )
|
||||
#define CM_MM_INTERRUPT_TIMEOUT 250
|
||||
#define CM_MM_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM530_PID = 0x0065,
|
||||
CM_MM531_PID = 0x0097,
|
||||
CM_MM711_PID = 0x0101,
|
||||
CM_MM720_PID = 0x0141,
|
||||
CM_MM730_PID = 0x0165,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM_REPORT_BYTE = 1,
|
||||
CM_MM_COMMAND_BYTE = 2,
|
||||
CM_MM_FUNCTION_BYTE = 3,
|
||||
CM_MM_ZONE_BYTE = 4,
|
||||
CM_MM_MODE_BYTE = 5,
|
||||
CM_MM_SPEED_BYTE = 6,
|
||||
CM_MM_NFI_1 = 7,
|
||||
CM_MM_NFI_2 = 8,
|
||||
CM_MM_NFI_3 = 9,
|
||||
CM_MM_BRIGHTNESS_BYTE = 10,
|
||||
CM_MM_RED_BYTE = 11,
|
||||
CM_MM_GREEN_BYTE = 12,
|
||||
CM_MM_BLUE_BYTE = 13,
|
||||
CM_MM_SKY_RED_BYTE = 14,
|
||||
CM_MM_SKY_GREEN_BYTE = 15,
|
||||
CM_MM_SKY_BLUE_BYTE = 16
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM5XX_COMMAND = 0x2C,
|
||||
CM_MM7XX_COMMAND = 0x2B
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM_CUSTOM_APPLY = 0x30, //Also Used for Multilayer Mode
|
||||
CM_MM_APPLY = 0x28 //Sent Before Update, Unless using a Zoned Mode then UsingZones Before and Apply After
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM_MODE_STATIC = 0, //Static Mode
|
||||
CM_MM_MODE_BREATHING = 1, //Breathing Mode
|
||||
CM_MM_MODE_SPECTRUM_CYCLE = 2, //Spectrum Cycle Mode
|
||||
CM_MM_MODE_STARS = 3, //Stars Mode
|
||||
CM_MM_MODE_INDICATOR = 4, //Indicator Mode
|
||||
CM_MM_MODE_CUSTOM = 176, //Custom LED Control
|
||||
CM_MM_MODE_MULTILAYER = 224, //Multilayer Mode, i.e. Effect per Zone.
|
||||
CM_MM_MODE_OFF = 254 //Turn Off
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MM_SPEED_1 = 0x3C, // Slowest speed
|
||||
CM_MM_SPEED_2 = 0x37,
|
||||
CM_MM_SPEED_3 = 0x31, // Normal speed
|
||||
CM_MM_SPEED_4 = 0x2C,
|
||||
CM_MM_SPEED_5 = 0x26 // Fastest speed
|
||||
};
|
||||
|
||||
class CMMMController
|
||||
{
|
||||
public:
|
||||
CMMMController(hid_device* dev_handle, char *_path, uint16_t pid, std::string dev_name);
|
||||
~CMMMController();
|
||||
|
||||
std::string GetDeviceVendor();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
|
||||
uint16_t GetProductID();
|
||||
|
||||
uint8_t GetZoneIndex();
|
||||
uint8_t GetMode();
|
||||
uint8_t GetLedRed();
|
||||
uint8_t GetLedGreen();
|
||||
uint8_t GetLedBlue();
|
||||
uint8_t GetLedSpeed();
|
||||
RGBColor GetWheelColour();
|
||||
RGBColor GetButtonsColour();
|
||||
RGBColor GetLogoColour();
|
||||
|
||||
void SendUpdate(uint8_t mode, uint8_t speed, RGBColor colour, uint8_t brightness);
|
||||
void SendUpdate(uint8_t mode, uint8_t speed, RGBColor mode_one, RGBColor mode_two, uint8_t brightness);
|
||||
void SetLedsDirect(RGBColor wheel_colour, RGBColor buttons_colour, RGBColor logo_colour);
|
||||
void SendSavePacket();
|
||||
private:
|
||||
std::string name;
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
|
||||
uint16_t product_id;
|
||||
|
||||
uint8_t command_code;
|
||||
|
||||
uint8_t current_mode;
|
||||
uint8_t current_speed;
|
||||
|
||||
uint8_t current_brightness;
|
||||
uint8_t current_red;
|
||||
uint8_t current_green;
|
||||
uint8_t current_blue;
|
||||
|
||||
uint8_t buttons_bytes[3];
|
||||
uint8_t logo_bytes[3];
|
||||
uint8_t wheel_bytes[3];
|
||||
|
||||
RGBColor buttons_colour;
|
||||
RGBColor logo_colour;
|
||||
RGBColor wheel_colour;
|
||||
|
||||
|
||||
void GetColourStatus();
|
||||
void GetCustomStatus();
|
||||
void GetModeStatus();
|
||||
void SendInitPacket();
|
||||
void SendUsingZonesPacket(uint8_t mode);
|
||||
void SendApplyPacket(uint8_t mode);
|
||||
void SendMultilayerPacket(uint8_t zones[3]);
|
||||
};
|
||||
@@ -0,0 +1,285 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMMMController.cpp |
|
||||
| |
|
||||
| RGBController for Cooler Master mouse |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| Dracrius 12 Mar 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CMMMController.h"
|
||||
|
||||
#define applyBrightness(c, bright) ((RGBColor) ((RGBGetBValue(c) * bright / CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT) << 16 | (RGBGetGValue(c) * bright / CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT) << 8 | (RGBGetRValue(c) * bright / CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT)))
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Coolermaster Master Mouse
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :white_check_mark:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterMouse
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMMMController::RGBController_CMMMController(CMMMController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
vendor = controller->GetDeviceVendor();
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "Cooler Master MasterMouse Device";
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Custom;
|
||||
Custom.name = "Direct";
|
||||
Custom.value = CM_MM_MODE_CUSTOM;
|
||||
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Custom.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Custom.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Custom.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Custom.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Custom);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CM_MM_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Static.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Static.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(Static.colors_max);
|
||||
Static.speed_min = CM_MM_SPEED_1;
|
||||
Static.speed_max = CM_MM_SPEED_5;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.speed = CM_MM_SPEED_3;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_MM_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Breathing.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Breathing.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(Breathing.colors_max);
|
||||
Breathing.speed_min = CM_MM_SPEED_1;
|
||||
Breathing.speed_max = CM_MM_SPEED_5;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed = CM_MM_SPEED_3;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Spectrum_Cycle;
|
||||
Spectrum_Cycle.name = "Spectrum Cycle";
|
||||
Spectrum_Cycle.value = CM_MM_MODE_SPECTRUM_CYCLE;
|
||||
Spectrum_Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Spectrum_Cycle.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Spectrum_Cycle.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM;
|
||||
Spectrum_Cycle.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM;
|
||||
Spectrum_Cycle.speed_min = CM_MM_SPEED_1;
|
||||
Spectrum_Cycle.speed_max = CM_MM_SPEED_5;
|
||||
Spectrum_Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum_Cycle.speed = CM_MM_SPEED_3;
|
||||
modes.push_back(Spectrum_Cycle);
|
||||
|
||||
mode Stars;
|
||||
Stars.name = "Stars";
|
||||
Stars.value = CM_MM_MODE_STARS;
|
||||
Stars.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Stars.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
|
||||
Stars.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Stars.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
|
||||
Stars.colors_min = 2;
|
||||
Stars.colors_max = 2;
|
||||
Stars.colors.resize(Stars.colors_max);
|
||||
Stars.speed_min = CM_MM_SPEED_1;
|
||||
Stars.speed_max = CM_MM_SPEED_5;
|
||||
Stars.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Stars.speed = CM_MM_SPEED_3;
|
||||
modes.push_back(Stars);
|
||||
|
||||
mode Indicator;
|
||||
Indicator.name = "Indicator";
|
||||
Indicator.value = CM_MM_MODE_INDICATOR;
|
||||
Indicator.flags = MODE_FLAG_MANUAL_SAVE;
|
||||
Indicator.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Indicator);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Turn Off";
|
||||
Off.value = CM_MM_MODE_OFF;
|
||||
Off.flags = MODE_FLAG_MANUAL_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
uint16_t pid = controller->GetProductID();
|
||||
|
||||
if(pid == 0x0065 || pid == 0x0097)
|
||||
{
|
||||
leds_count = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
leds_count = 2;
|
||||
}
|
||||
|
||||
Init_Controller(); //Only processed on first run
|
||||
SetupZones();
|
||||
|
||||
uint8_t temp_mode = controller->GetMode();
|
||||
|
||||
for(int mode_index = 0; mode_index < (int)modes.size(); mode_index++)
|
||||
{
|
||||
if(modes[mode_index].value == temp_mode)
|
||||
{
|
||||
active_mode = mode_index;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
modes[active_mode].colors[0] = ToRGBColor(controller->GetLedRed(),controller->GetLedGreen(),controller->GetLedBlue());
|
||||
}
|
||||
|
||||
|
||||
if(pid == 0x0065 || pid == 0x0097)
|
||||
{
|
||||
colors[0] = controller->GetWheelColour();
|
||||
colors[1] = controller->GetButtonsColour();
|
||||
colors[2] = controller->GetLogoColour();
|
||||
}
|
||||
else
|
||||
{
|
||||
colors[0] = controller->GetWheelColour();
|
||||
colors[1] = controller->GetLogoColour();
|
||||
}
|
||||
}
|
||||
|
||||
RGBController_CMMMController::~RGBController_CMMMController()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMMMController::Init_Controller()
|
||||
{
|
||||
zone mouse_zone;
|
||||
mouse_zone.name = name;
|
||||
mouse_zone.type = ZONE_TYPE_LINEAR;
|
||||
mouse_zone.leds_min = leds_count;
|
||||
mouse_zone.leds_max = leds_count;
|
||||
mouse_zone.leds_count = leds_count;
|
||||
mouse_zone.matrix_map = NULL;
|
||||
zones.push_back(mouse_zone);
|
||||
|
||||
int value = 0;
|
||||
uint16_t pid = controller->GetProductID();
|
||||
|
||||
led wheel_led;
|
||||
wheel_led.name = "Scroll Wheel";
|
||||
wheel_led.value = value;
|
||||
leds.push_back(wheel_led);
|
||||
|
||||
value++;
|
||||
|
||||
if(pid == 0x0065 || pid == 0x0097)
|
||||
{
|
||||
led buttons_led;
|
||||
buttons_led.name = "Buttons";
|
||||
buttons_led.value = value;
|
||||
leds.push_back(buttons_led);
|
||||
value++;
|
||||
}
|
||||
|
||||
led logo_led;
|
||||
logo_led.name = "Logo";
|
||||
logo_led.value = value;
|
||||
leds.push_back(logo_led);
|
||||
}
|
||||
|
||||
void RGBController_CMMMController::SetupZones()
|
||||
{
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMMMController::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CMMMController::DeviceUpdateLEDs()
|
||||
{
|
||||
int value = 0;
|
||||
uint16_t pid = controller->GetProductID();
|
||||
|
||||
RGBColor wheel = applyBrightness(colors[value], modes[active_mode].brightness);
|
||||
RGBColor buttons = ToRGBColor(0, 0, 0);
|
||||
value++;
|
||||
|
||||
if(pid == 0x0065 || pid == 0x0097)
|
||||
{
|
||||
buttons = applyBrightness(colors[value], modes[active_mode].brightness);
|
||||
value++;
|
||||
}
|
||||
|
||||
RGBColor logo = applyBrightness(colors[value], modes[active_mode].brightness);
|
||||
|
||||
controller->SetLedsDirect(wheel, buttons, logo);
|
||||
}
|
||||
|
||||
void RGBController_CMMMController::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMMMController::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMMMController::DeviceUpdateMode()
|
||||
{
|
||||
RGBColor mode_one = 0;
|
||||
RGBColor mode_two = 0;
|
||||
|
||||
if(modes[active_mode].value != CM_MM_MODE_CUSTOM)
|
||||
{
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC )
|
||||
{
|
||||
mode_one = modes[active_mode].colors[0];
|
||||
|
||||
if(modes[active_mode].colors.size() > 1)
|
||||
{
|
||||
mode_two = modes[active_mode].colors[1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(modes[active_mode].value == CM_MM_MODE_STARS)
|
||||
{
|
||||
controller->SendUpdate(modes[active_mode].value, modes[active_mode].speed, mode_one, mode_two, modes[active_mode].brightness);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SendUpdate(modes[active_mode].value, modes[active_mode].speed, mode_one, modes[active_mode].brightness);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMMMController::DeviceSaveMode()
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
controller->SendSavePacket();
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMMMController.h |
|
||||
| |
|
||||
| RGBController for Cooler Master mouse |
|
||||
| |
|
||||
| Chris M (Dr_No) 14 Feb 2021 |
|
||||
| Dracrius 12 Mar 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "RGBController.h"
|
||||
#include "CMMMController.h"
|
||||
|
||||
#define CM_MM_ARGB_BRIGHTNESS_MIN 0x00
|
||||
#define CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT 0xFF
|
||||
#define CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM 0x7F
|
||||
|
||||
class RGBController_CMMMController : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMMMController(CMMMController* controller_ptr);
|
||||
~RGBController_CMMMController();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
void Init_Controller();
|
||||
int GetDeviceMode();
|
||||
|
||||
int leds_count;
|
||||
|
||||
CMMMController* controller;
|
||||
};
|
||||
@@ -0,0 +1,176 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMMP750Controller.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master MP750 mousemat |
|
||||
| |
|
||||
| Chris M (Dr_No) 16 Apr 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CMMP750Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
static unsigned char colour_mode_data[][6] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Off */
|
||||
{ 0x01, 0x04, 0xFF, 0x00, 0xFF, 0x00 }, /* Static */
|
||||
{ 0x02, 0x04, 0xFF, 0x00, 0xFF, 0x80 }, /* Blinking */
|
||||
{ 0x03, 0x04, 0xFF, 0x00, 0xFF, 0x80 }, /* Breathing */
|
||||
{ 0x04, 0x04, 0x80, 0x00, 0x00, 0x00 }, /* Colour Cycle */
|
||||
{ 0x05, 0x04, 0x80, 0x00, 0x00, 0x00 } /* Colour Breath */
|
||||
};
|
||||
|
||||
static unsigned char speed_mode_data[9] =
|
||||
{
|
||||
0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 /* Speed Definition */
|
||||
};
|
||||
|
||||
CMMP750Controller::CMMP750Controller(hid_device* dev_handle, char *_path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get device name from HID manufacturer and product strings |
|
||||
\*---------------------------------------------------------*/
|
||||
wchar_t name_string[HID_MAX_STR];
|
||||
|
||||
hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
|
||||
device_name = StringUtils::wstring_to_string(name_string);
|
||||
|
||||
hid_get_product_string(dev, name_string, HID_MAX_STR);
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
|
||||
GetStatus(); //When setting up device get current status
|
||||
}
|
||||
|
||||
CMMP750Controller::~CMMP750Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
void CMMP750Controller::GetStatus()
|
||||
{
|
||||
unsigned char buffer[0x41] = { 0x00 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
buffer[1] = 0x07;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read(dev, buffer, buffer_size);
|
||||
|
||||
if((buffer[0] == 0x80) && (buffer[1] == 0x05))
|
||||
{
|
||||
current_mode = buffer[2];
|
||||
current_red = buffer[3];
|
||||
current_green = buffer[4];
|
||||
current_blue = buffer[5];
|
||||
|
||||
for(int i = 0; (speed_mode_data[i] >= buffer[6] && i <= MP750_SPEED_FASTEST); i++)
|
||||
{
|
||||
current_speed = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Code should never reach here however just in case there is a failure set something
|
||||
current_mode = CM_MP750_MODE_COLOR_CYCLE; //Unicorn Spew
|
||||
current_red = 0xFF;
|
||||
current_green = 0xFF;
|
||||
current_blue = 0xFF;
|
||||
current_speed = MP750_SPEED_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
std::string CMMP750Controller::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string CMMP750Controller::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[HID_MAX_STR];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, HID_MAX_STR);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string CMMP750Controller::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetMode()
|
||||
{
|
||||
return(current_mode);
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedRed()
|
||||
{
|
||||
return(current_red);
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedGreen()
|
||||
{
|
||||
return(current_green);
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedBlue()
|
||||
{
|
||||
return(current_blue);
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedSpeed()
|
||||
{
|
||||
return(current_speed);
|
||||
}
|
||||
|
||||
void CMMP750Controller::SetMode(unsigned char mode, unsigned char speed)
|
||||
{
|
||||
current_mode = mode;
|
||||
current_speed = speed;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void CMMP750Controller::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
current_red = red;
|
||||
current_green = green;
|
||||
current_blue = blue;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void CMMP750Controller::SendUpdate()
|
||||
{
|
||||
unsigned char buffer[0x41] = { 0x00 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
for(std::size_t i = 0; i < CM_COLOUR_MODE_DATA_SIZE; i++)
|
||||
{
|
||||
buffer[i+1] = colour_mode_data[current_mode][i];
|
||||
}
|
||||
|
||||
if(current_mode > CM_MP750_MODE_BREATHING)
|
||||
{
|
||||
//If the mode is random colours set SPEED at BYTE2
|
||||
buffer[CM_RED_BYTE] = speed_mode_data[current_speed];
|
||||
}
|
||||
else
|
||||
{
|
||||
//Otherwise SPEED is BYTE5
|
||||
buffer[CM_RED_BYTE] = current_red;
|
||||
buffer[CM_GREEN_BYTE] = current_green;
|
||||
buffer[CM_BLUE_BYTE] = current_blue;
|
||||
buffer[CM_SPEED_BYTE] = speed_mode_data[current_speed];
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMMP750Controller.h |
|
||||
| |
|
||||
| Driver for Cooler Master MP750 mousemat |
|
||||
| |
|
||||
| Chris M (Dr_No) 16 Apr 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
|
||||
#define CM_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
|
||||
#define CM_INTERRUPT_TIMEOUT 250
|
||||
#define CM_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
|
||||
#define CM_SERIAL_SIZE (sizeof(serial) / sizeof(serial[ 0 ]))
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
/*-------------------------------------------------------------------*\
|
||||
| Simple RGB device with 5 modes |
|
||||
| BYTE0 = Mode (0x01 thru 0x05 |
|
||||
| BYTE1 = ?? Must be set to 0x04 for colour modes otherwise ignored |
|
||||
| BYTE2 = Colour Modes: RED else Cycle SPEED |
|
||||
| BYTE3 = Colour Modes: GREEN else ignored |
|
||||
| BYTE4 = Colour Modes: BLUE else ignored |
|
||||
| BYTE5 = Colour Modes: SPEED else ignored |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MODE_BYTE = 1,
|
||||
CM_LENGTH_BYTE = 2,
|
||||
CM_RED_BYTE = 3,
|
||||
CM_GREEN_BYTE = 4,
|
||||
CM_BLUE_BYTE = 5,
|
||||
CM_SPEED_BYTE = 6
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MP750_MODE_OFF = 0x00, //Off
|
||||
CM_MP750_MODE_STATIC = 0x01, //Static Mode
|
||||
CM_MP750_MODE_BLINK = 0x02, //Blinking Mode
|
||||
CM_MP750_MODE_BREATHING = 0x03, //Breathing Mode
|
||||
CM_MP750_MODE_COLOR_CYCLE = 0x04, //Color Cycle Mode
|
||||
CM_MP750_MODE_BREATH_CYCLE = 0x05 //Breathing Cycle Mode
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MP750_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
MP750_SPEED_SLOWER = 0x01, /* Slower speed */
|
||||
MP750_SPEED_SLOW = 0x02, /* Slow speed */
|
||||
MP750_SPEED_SLOWISH = 0x03, /* Slowish speed */
|
||||
MP750_SPEED_NORMAL = 0x04, /* Normal speed */
|
||||
MP750_SPEED_FASTISH = 0x05, /* Fastish speed */
|
||||
MP750_SPEED_FAST = 0x06, /* Fast speed */
|
||||
MP750_SPEED_FASTER = 0x07, /* Faster speed */
|
||||
MP750_SPEED_FASTEST = 0x08, /* Fastest speed */
|
||||
};
|
||||
|
||||
class CMMP750Controller
|
||||
{
|
||||
public:
|
||||
CMMP750Controller(hid_device* dev_handle, char *_path);
|
||||
~CMMP750Controller();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
unsigned char GetMode();
|
||||
unsigned char GetLedRed();
|
||||
unsigned char GetLedGreen();
|
||||
unsigned char GetLedBlue();
|
||||
unsigned char GetLedSpeed();
|
||||
void SetMode(unsigned char mode, unsigned char speed);
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
private:
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
|
||||
unsigned char current_red;
|
||||
unsigned char current_green;
|
||||
unsigned char current_blue;
|
||||
|
||||
void GetStatus();
|
||||
void SendUpdate();
|
||||
};
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMMP750Controller.cpp |
|
||||
| |
|
||||
| RGBController for Cooler Master MP750 mousemat |
|
||||
| |
|
||||
| Chris M (Dr_No) 18 Apr 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CMMP750Controller.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Coolermaster Mouse Pad
|
||||
@category Mousemat
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterMousemats
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMMP750Controller::RGBController_CMMP750Controller(CMMP750Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
unsigned char speed = controller->GetLedSpeed();
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Cooler Master";
|
||||
type = DEVICE_TYPE_MOUSEMAT;
|
||||
description = controller->GetDeviceName();
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CM_MP750_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Blink;
|
||||
Blink.name = "Blink";
|
||||
Blink.value = CM_MP750_MODE_BLINK;
|
||||
Blink.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Blink.speed_min = MP750_SPEED_SLOWEST;
|
||||
Blink.speed_max = MP750_SPEED_FASTEST;
|
||||
Blink.color_mode = MODE_COLORS_PER_LED;
|
||||
Blink.speed = speed;
|
||||
modes.push_back(Blink);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_MP750_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Breathing.speed_min = MP750_SPEED_SLOWEST;
|
||||
Breathing.speed_max = MP750_SPEED_FASTEST;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.speed = speed;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode ColorCycle;
|
||||
ColorCycle.name = "Color Cycle";
|
||||
ColorCycle.value = CM_MP750_MODE_COLOR_CYCLE;
|
||||
ColorCycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
ColorCycle.speed_min = MP750_SPEED_SLOWEST;
|
||||
ColorCycle.speed_max = MP750_SPEED_FASTEST;
|
||||
ColorCycle.color_mode = MODE_COLORS_NONE;
|
||||
ColorCycle.speed = speed;
|
||||
modes.push_back(ColorCycle);
|
||||
|
||||
mode BreathCycle;
|
||||
BreathCycle.name = "Breath Cycle";
|
||||
BreathCycle.value = CM_MP750_MODE_BREATH_CYCLE;
|
||||
BreathCycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
BreathCycle.speed_min = MP750_SPEED_SLOWEST;
|
||||
BreathCycle.speed_max = MP750_SPEED_FASTEST;
|
||||
BreathCycle.color_mode = MODE_COLORS_NONE;
|
||||
BreathCycle.speed = speed;
|
||||
modes.push_back(BreathCycle);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Turn Off";
|
||||
Off.value = CM_MP750_MODE_OFF;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
SetupZones();
|
||||
active_mode = GetDeviceMode();
|
||||
}
|
||||
|
||||
RGBController_CMMP750Controller::~RGBController_CMMP750Controller()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
int RGBController_CMMP750Controller::GetDeviceMode()
|
||||
{
|
||||
int temp_mode = controller->GetMode();
|
||||
|
||||
for(unsigned int i = 0; i < modes.size(); i++)
|
||||
{
|
||||
if (temp_mode == modes[i].value)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| If not found return 0 |
|
||||
\*---------------------------------------------------------*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RGBController_CMMP750Controller::SetupZones()
|
||||
{
|
||||
zone MP_zone;
|
||||
MP_zone.name = "Mousepad";
|
||||
MP_zone.type = ZONE_TYPE_SINGLE;
|
||||
MP_zone.leds_min = 1;
|
||||
MP_zone.leds_max = 1;
|
||||
MP_zone.leds_count = 1;
|
||||
MP_zone.matrix_map = NULL;
|
||||
zones.push_back(MP_zone);
|
||||
|
||||
led MP_led;
|
||||
MP_led.name = "Mousepad LED";
|
||||
leds.push_back(MP_led);
|
||||
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Initialize colors for each LED |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
unsigned char red = controller->GetLedRed();
|
||||
unsigned char grn = controller->GetLedGreen();
|
||||
unsigned char blu = controller->GetLedBlue();
|
||||
|
||||
colors[led_idx] = ToRGBColor(red, grn, blu);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMMP750Controller::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CMMP750Controller::DeviceUpdateLEDs()
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[0]);
|
||||
unsigned char grn = RGBGetGValue(colors[0]);
|
||||
unsigned char blu = RGBGetBValue(colors[0]);
|
||||
|
||||
controller->SetColor(red, grn, blu);
|
||||
}
|
||||
|
||||
void RGBController_CMMP750Controller::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
RGBColor color = colors[zone];
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char grn = RGBGetGValue(color);
|
||||
unsigned char blu = RGBGetBValue(color);
|
||||
|
||||
controller->SetColor(red, grn, blu);
|
||||
}
|
||||
|
||||
void RGBController_CMMP750Controller::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_CMMP750Controller::DeviceUpdateMode()
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed);
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMMP750Controller.h |
|
||||
| |
|
||||
| RGBController for Cooler Master MP750 mousemat |
|
||||
| |
|
||||
| Chris M (Dr_No) 18 Apr 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CMMP750Controller.h"
|
||||
|
||||
class RGBController_CMMP750Controller : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMMP750Controller(CMMP750Controller* controller_ptr);
|
||||
~RGBController_CMMP750Controller();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
CMMP750Controller* controller;
|
||||
|
||||
int GetDeviceMode();
|
||||
};
|
||||
@@ -0,0 +1,208 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMMonitorController.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master monitor |
|
||||
| |
|
||||
| Morgan Guimard (morg) 18 Sep 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "CMMonitorController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CMMonitorController::CMMonitorController(hid_device* dev_handle, const hid_device_info& info, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = info.path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
CMMonitorController::~CMMonitorController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string CMMonitorController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string CMMonitorController::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string CMMonitorController::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));
|
||||
}
|
||||
|
||||
void CMMonitorController::SetMode(uint8_t mode_value, const RGBColor& color, uint8_t speed, uint8_t brightness)
|
||||
{
|
||||
if(software_mode_enabled)
|
||||
{
|
||||
SetSoftwareModeEnabled(false);
|
||||
}
|
||||
|
||||
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
|
||||
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = 0x80;
|
||||
usb_buf[2] = (mode_value == CM_MONITOR_OFF_MODE) ? 0x0F : 0x0B;
|
||||
usb_buf[3] = 0x02;
|
||||
usb_buf[4] = 0x02;
|
||||
usb_buf[5] = mode_value;
|
||||
usb_buf[6] = (mode_value == CM_MONITOR_OFF_MODE) ? 0x00 : 0x08;
|
||||
usb_buf[7] = speed;
|
||||
usb_buf[8] = brightness;
|
||||
usb_buf[9] = RGBGetRValue(color);
|
||||
usb_buf[10] = RGBGetGValue(color);
|
||||
usb_buf[11] = RGBGetBValue(color);
|
||||
|
||||
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
|
||||
}
|
||||
|
||||
void CMMonitorController::SetCustomMode(const std::vector<RGBColor>& colors, uint8_t brightnesss)
|
||||
{
|
||||
if(software_mode_enabled)
|
||||
{
|
||||
SetSoftwareModeEnabled(false);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Creates the color buffer |
|
||||
\*---------------------------------------------------------*/
|
||||
uint8_t color_data[CM_MONITOR_COLOR_DATA_LENGTH];
|
||||
memset(color_data, 0x00, CM_MONITOR_COLOR_DATA_LENGTH);
|
||||
|
||||
uint8_t offset = 0;
|
||||
|
||||
for(const RGBColor& color: colors)
|
||||
{
|
||||
color_data[offset++] = RGBGetRValue(color);
|
||||
color_data[offset++] = RGBGetGValue(color);
|
||||
color_data[offset++] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Sends the 7 sequence packets |
|
||||
\*---------------------------------------------------------*/
|
||||
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
|
||||
|
||||
offset = 0;
|
||||
|
||||
for(unsigned int i = 0; i < 7; i++)
|
||||
{
|
||||
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = i < 6 ? i : 0x86;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| First packet contains static data |
|
||||
\*---------------------------------------------------------*/
|
||||
if(i == 0)
|
||||
{
|
||||
usb_buf[2] = 0x10;
|
||||
usb_buf[3] = 0x02;
|
||||
usb_buf[4] = 0x02;
|
||||
usb_buf[5] = 0x80;
|
||||
usb_buf[6] = brightnesss;
|
||||
|
||||
memcpy(&usb_buf[7], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 7);
|
||||
offset += CM_MONITOR_PACKET_LENGTH - 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&usb_buf[2], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 2);
|
||||
offset += (CM_MONITOR_PACKET_LENGTH - 2);
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
void CMMonitorController::SendDirect(const std::vector<RGBColor>& colors)
|
||||
{
|
||||
if(!software_mode_enabled)
|
||||
{
|
||||
SetSoftwareModeEnabled(true);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Creates the color buffer |
|
||||
\*---------------------------------------------------------*/
|
||||
uint8_t color_data[CM_MONITOR_COLOR_DATA_LENGTH];
|
||||
memset(color_data, 0x00, CM_MONITOR_COLOR_DATA_LENGTH);
|
||||
|
||||
unsigned int offset = 0;
|
||||
|
||||
for(const RGBColor& color: colors)
|
||||
{
|
||||
color_data[offset++] = RGBGetRValue(color);
|
||||
color_data[offset++] = RGBGetGValue(color);
|
||||
color_data[offset++] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Sends the 7 sequence packets |
|
||||
\*---------------------------------------------------------*/
|
||||
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
|
||||
|
||||
offset = 0;
|
||||
|
||||
for(unsigned int i = 0; i < 7; i++)
|
||||
{
|
||||
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = i < 6 ? i : 0x86;
|
||||
|
||||
if(i == 0)
|
||||
{
|
||||
usb_buf[2] = 0x07;
|
||||
usb_buf[3] = 0x02;
|
||||
usb_buf[4] = 0x02;
|
||||
usb_buf[5] = 0x01;
|
||||
usb_buf[6] = 0x80;
|
||||
|
||||
memcpy(&usb_buf[7], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 7);
|
||||
offset += CM_MONITOR_PACKET_LENGTH - 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&usb_buf[2], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 2);
|
||||
offset += (CM_MONITOR_PACKET_LENGTH - 2);
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CMMonitorController::SetSoftwareModeEnabled(bool value)
|
||||
{
|
||||
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
|
||||
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
|
||||
|
||||
usb_buf[1] = 0x80;
|
||||
usb_buf[2] = 0x07;
|
||||
usb_buf[3] = 0x02;
|
||||
usb_buf[4] = 0x02;
|
||||
usb_buf[6] = value;
|
||||
|
||||
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
|
||||
|
||||
software_mode_enabled = value;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMMonitorController.h |
|
||||
| |
|
||||
| Driver for Cooler Master monitor |
|
||||
| |
|
||||
| Morgan Guimard (morg) 18 Sep 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define CM_MONITOR_PACKET_LENGTH 65
|
||||
#define CM_MONITOR_COLOR_DATA_LENGTH 436
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MONITOR_DIRECT_MODE = 0xFF,
|
||||
CM_MONITOR_CUSTOM_MODE = 0xFE,
|
||||
CM_MONITOR_SPECTRUM_MODE = 0x00,
|
||||
CM_MONITOR_RELOAD_MODE = 0x01,
|
||||
CM_MONITOR_RECOIL_MODE = 0x02,
|
||||
CM_MONITOR_BREATHING_MODE = 0x03,
|
||||
CM_MONITOR_REFILL_MODE = 0x04,
|
||||
CM_MONITOR_OFF_MODE = 0x06
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MONITOR_BRIGHTNESS_MAX = 0xFF,
|
||||
CM_MONITOR_BRIGHTNESS_MIN = 0x00,
|
||||
CM_MONITOR_SPEED_MAX = 0x04,
|
||||
CM_MONITOR_SPEED_MIN = 0x00,
|
||||
};
|
||||
|
||||
class CMMonitorController
|
||||
{
|
||||
public:
|
||||
CMMonitorController(hid_device* dev_handle, const hid_device_info& info, std::string dev_name);
|
||||
~CMMonitorController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SendDirect(const std::vector<RGBColor>& colors);
|
||||
void SetMode(uint8_t mode_value, const RGBColor& color, uint8_t speed, uint8_t brightness);
|
||||
void SetCustomMode(const std::vector<RGBColor>& colors, uint8_t brightnesss);
|
||||
|
||||
private:
|
||||
std::string location;
|
||||
std::string name;
|
||||
hid_device* dev;
|
||||
bool software_mode_enabled = false;
|
||||
void SetSoftwareModeEnabled(bool value);
|
||||
};
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMMonitorController.cpp |
|
||||
| |
|
||||
| RGBController for Cooler Master monitor |
|
||||
| |
|
||||
| Morgan Guimard (morg) 18 Sep 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "RGBController_CMMonitorController.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Coolermaster Gaming Monitor
|
||||
@category Accessory
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterMonitor
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMMonitorController::RGBController_CMMonitorController(CMMonitorController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "CoolerMaster";
|
||||
type = DEVICE_TYPE_MONITOR;
|
||||
description = "CoolerMaster Monitor Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CM_MONITOR_DIRECT_MODE;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Spectrum;
|
||||
Spectrum.name = "Spectrum cycle";
|
||||
Spectrum.value = CM_MONITOR_SPECTRUM_MODE;
|
||||
Spectrum.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Spectrum.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum.speed_min = CM_MONITOR_SPEED_MIN;
|
||||
Spectrum.speed_max = CM_MONITOR_SPEED_MAX;
|
||||
Spectrum.speed = CM_MONITOR_SPEED_MAX/2;
|
||||
Spectrum.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
|
||||
Spectrum.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
Spectrum.brightness = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
modes.push_back(Spectrum);
|
||||
|
||||
mode Reload;
|
||||
Reload.name = "Reload";
|
||||
Reload.value = CM_MONITOR_RELOAD_MODE;
|
||||
Reload.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Reload.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Reload.colors_min = 1;
|
||||
Reload.colors_max = 1;
|
||||
Reload.colors.resize(1);
|
||||
Reload.speed_min = CM_MONITOR_SPEED_MIN;
|
||||
Reload.speed_max = CM_MONITOR_SPEED_MAX;
|
||||
Reload.speed = CM_MONITOR_SPEED_MAX/2;
|
||||
Reload.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
|
||||
Reload.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
Reload.brightness = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
modes.push_back(Reload);
|
||||
|
||||
mode Recoil;
|
||||
Recoil.name = "Recoil";
|
||||
Recoil.value = CM_MONITOR_RECOIL_MODE;
|
||||
Recoil.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Recoil.colors_min = 1;
|
||||
Recoil.colors_max = 1;
|
||||
Recoil.colors.resize(1);
|
||||
Recoil.speed_min = CM_MONITOR_SPEED_MIN;
|
||||
Recoil.speed_max = CM_MONITOR_SPEED_MAX;
|
||||
Recoil.speed = CM_MONITOR_SPEED_MAX/2;
|
||||
Recoil.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
|
||||
Recoil.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
Recoil.brightness = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
modes.push_back(Recoil);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_MONITOR_BREATHING_MODE;
|
||||
Breathing.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed_min = CM_MONITOR_SPEED_MIN;
|
||||
Breathing.speed_max = CM_MONITOR_SPEED_MAX;
|
||||
Breathing.speed = CM_MONITOR_SPEED_MAX/2;
|
||||
Breathing.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Refill;
|
||||
Refill.name = "Refill";
|
||||
Refill.value = CM_MONITOR_REFILL_MODE;
|
||||
Refill.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Refill.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Refill.colors_min = 1;
|
||||
Refill.colors_max = 1;
|
||||
Refill.colors.resize(1);
|
||||
Refill.speed_min = CM_MONITOR_SPEED_MIN;
|
||||
Refill.speed_max = CM_MONITOR_SPEED_MAX;
|
||||
Refill.speed = CM_MONITOR_SPEED_MAX/2;
|
||||
Refill.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
|
||||
Refill.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
Refill.brightness = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
modes.push_back(Refill);
|
||||
|
||||
mode Custom;
|
||||
Custom.name = "Custom";
|
||||
Custom.value = CM_MONITOR_CUSTOM_MODE;
|
||||
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Custom.color_mode = MODE_COLORS_PER_LED;
|
||||
Custom.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
|
||||
Custom.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
Custom.brightness = CM_MONITOR_BRIGHTNESS_MAX;
|
||||
modes.push_back(Custom);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = CM_MONITOR_SPECTRUM_MODE;
|
||||
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_CMMonitorController::~RGBController_CMMonitorController()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMMonitorController::SetupZones()
|
||||
{
|
||||
zone z;
|
||||
|
||||
z.name = "Monitor";
|
||||
z.type = ZONE_TYPE_LINEAR;
|
||||
z.leds_min = 47;
|
||||
z.leds_max = 47;
|
||||
z.leds_count = 47;
|
||||
z.matrix_map = NULL;
|
||||
|
||||
zones.push_back(z);
|
||||
|
||||
for(unsigned int i = 0; i < 47; i++)
|
||||
{
|
||||
led l;
|
||||
l.name = std::to_string(i + 1);
|
||||
l.value = i;
|
||||
leds.push_back(l);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMMonitorController::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CMMonitorController::DeviceUpdateLEDs()
|
||||
{
|
||||
if(modes[active_mode].value == CM_MONITOR_DIRECT_MODE)
|
||||
{
|
||||
controller->SendDirect(colors);
|
||||
}
|
||||
else if(modes[active_mode].value == CM_MONITOR_CUSTOM_MODE)
|
||||
{
|
||||
controller->SetCustomMode(colors, modes[active_mode].brightness);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMMonitorController::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMMonitorController::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMMonitorController::DeviceUpdateMode()
|
||||
{
|
||||
switch(modes[active_mode].value)
|
||||
{
|
||||
case CM_MONITOR_OFF_MODE:
|
||||
case CM_MONITOR_SPECTRUM_MODE:
|
||||
controller->SetMode(modes[active_mode].value, 0, modes[active_mode].speed, modes[active_mode].brightness);
|
||||
break;
|
||||
|
||||
case CM_MONITOR_RELOAD_MODE:
|
||||
case CM_MONITOR_RECOIL_MODE:
|
||||
case CM_MONITOR_BREATHING_MODE:
|
||||
case CM_MONITOR_REFILL_MODE:
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].colors[0], modes[active_mode].speed, modes[active_mode].brightness);
|
||||
break;
|
||||
|
||||
case CM_MONITOR_CUSTOM_MODE:
|
||||
DeviceUpdateLEDs();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMMonitorController.h |
|
||||
| |
|
||||
| RGBController for Cooler Master monitor |
|
||||
| |
|
||||
| Morgan Guimard (morg) 18 Sep 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CMMonitorController.h"
|
||||
|
||||
class RGBController_CMMonitorController : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMMonitorController(CMMonitorController* controller_ptr);
|
||||
~RGBController_CMMonitorController();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
CMMonitorController* controller;
|
||||
};
|
||||
@@ -0,0 +1,214 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMR6000Controller.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master AMD Radeon 6000 series GPU |
|
||||
| |
|
||||
| Eric S (edbgon) 02 Feb 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "CMR6000Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
CMR6000Controller::CMR6000Controller(hid_device* dev_handle, char *_path, uint16_t _pid)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
pid = _pid;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get device name from HID manufacturer and product strings |
|
||||
\*---------------------------------------------------------*/
|
||||
wchar_t name_string[HID_MAX_STR];
|
||||
|
||||
hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
|
||||
device_name = StringUtils::wstring_to_string(name_string);
|
||||
|
||||
hid_get_product_string(dev, name_string, HID_MAX_STR);
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
}
|
||||
|
||||
CMR6000Controller::~CMR6000Controller()
|
||||
{
|
||||
if(dev)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
std::string CMR6000Controller::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string CMR6000Controller::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[HID_MAX_STR];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, HID_MAX_STR);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string CMR6000Controller::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
unsigned char CMR6000Controller::GetMode()
|
||||
{
|
||||
return(current_mode);
|
||||
}
|
||||
|
||||
unsigned char CMR6000Controller::GetLedSpeed()
|
||||
{
|
||||
return(current_speed);
|
||||
}
|
||||
|
||||
unsigned char CMR6000Controller::GetBrightness()
|
||||
{
|
||||
return(current_brightness);
|
||||
}
|
||||
|
||||
bool CMR6000Controller::GetRandomColours()
|
||||
{
|
||||
return(current_random);
|
||||
}
|
||||
|
||||
uint16_t CMR6000Controller::GetPID()
|
||||
{
|
||||
return(pid);
|
||||
}
|
||||
|
||||
void CMR6000Controller::SetMode(unsigned char mode, unsigned char speed, RGBColor color1, RGBColor color2, unsigned char random, unsigned char brightness)
|
||||
{
|
||||
current_mode = mode;
|
||||
current_speed = speed;
|
||||
primary = color1;
|
||||
secondary = color2;
|
||||
current_random = random;
|
||||
current_brightness = brightness;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void CMR6000Controller::SendUpdate()
|
||||
{
|
||||
if(current_mode == CM_MR6000_MODE_OFF)
|
||||
{
|
||||
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00, 0x41, 0x43 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendEnableCommand();
|
||||
|
||||
if(pid == COOLERMASTER_RADEON_6900_PID)
|
||||
{
|
||||
SendSecondColour();
|
||||
}
|
||||
|
||||
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
memset(buffer, 0xFF, buffer_size);
|
||||
|
||||
buffer[0x00] = 0x00;
|
||||
buffer[0x01] = 0x51;
|
||||
buffer[0x02] = 0x2C;
|
||||
buffer[0x03] = 0x01;
|
||||
buffer[0x04] = 0x00;
|
||||
buffer[0x05] = current_mode;
|
||||
buffer[0x06] = current_speed;
|
||||
buffer[0x07] = current_random; //random (A0)
|
||||
//buffer[0x09] = 0xFF;
|
||||
buffer[0x0A] = current_brightness;
|
||||
buffer[0x0B] = (current_mode == CM_MR6000_MODE_COLOR_CYCLE) ? 0xFF : RGBGetRValue(primary);
|
||||
buffer[0x0C] = (current_mode == CM_MR6000_MODE_COLOR_CYCLE) ? 0xFF : RGBGetGValue(primary);
|
||||
buffer[0x0D] = (current_mode == CM_MR6000_MODE_COLOR_CYCLE) ? 0xFF : RGBGetBValue(primary);
|
||||
buffer[0x0E] = 0x00;
|
||||
buffer[0x0F] = 0x00;
|
||||
buffer[0x10] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Index 0x08 looks to be mode specific flags / options |
|
||||
\*-----------------------------------------------------------------*/
|
||||
switch(current_mode)
|
||||
{
|
||||
case CM_MR6000_MODE_BREATHE:
|
||||
buffer[0x08] = 0x03;
|
||||
break;
|
||||
case CM_MR6000_MODE_RAINBOW:
|
||||
buffer[0x08] = 0x05;
|
||||
break;
|
||||
case CM_MR6000_MODE_CHASE:
|
||||
buffer[0x08] = 0xC3;
|
||||
break;
|
||||
case CM_MR6000_MODE_SWIRL:
|
||||
buffer[0x08] = 0x4A;
|
||||
break;
|
||||
default:
|
||||
buffer[0x08] = 0xFF;
|
||||
}
|
||||
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
|
||||
SendColourConfig();
|
||||
SendApplyCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void CMR6000Controller::SendEnableCommand()
|
||||
{
|
||||
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00, 0x41, 0x80 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_6K_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMR6000Controller::SendApplyCommand()
|
||||
{
|
||||
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00, 0x51, 0x28, 0x00, 0x00, 0xE0 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_6K_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMR6000Controller::SendColourConfig()
|
||||
{
|
||||
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00, 0x51, 0xA0, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x05, 0x06 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
for(int i = 0x0B; i < 0x1A; i++)
|
||||
{
|
||||
buffer[i] = current_mode;
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_6K_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMR6000Controller::SendSecondColour()
|
||||
{
|
||||
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00, 0x51, 0x9C, 0x01, 0x00 };
|
||||
|
||||
buffer[5] = RGBGetRValue(primary);
|
||||
buffer[6] = RGBGetGValue(primary);
|
||||
buffer[7] = RGBGetBValue(primary);
|
||||
buffer[8] = RGBGetRValue(secondary);
|
||||
buffer[9] = RGBGetGValue(secondary);
|
||||
buffer[10] = RGBGetBValue(secondary);
|
||||
|
||||
hid_write(dev, buffer, CM_6K_PACKET_SIZE);
|
||||
hid_read_timeout(dev, buffer, CM_6K_PACKET_SIZE, CM_6K_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMR6000Controller.h |
|
||||
| |
|
||||
| Driver for Cooler Master AMD Radeon 6000 series GPU |
|
||||
| |
|
||||
| Eric S (edbgon) 02 Feb 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define COOLERMASTER_RADEON_6000_PID 0x014D
|
||||
#define COOLERMASTER_RADEON_6900_PID 0x015B
|
||||
|
||||
#define CM_6K_PACKET_SIZE 65 //Includes extra first byte for non HID Report packets
|
||||
#define CM_6K_INTERRUPT_TIMEOUT 250
|
||||
#define CM_6K_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
|
||||
#define CM_6K_SERIAL_SIZE (sizeof(serial) / sizeof(serial[ 0 ]))
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MR6000_MODE_DIRECT = 0x00, //Direct Mode
|
||||
CM_MR6000_MODE_BREATHE = 0x01, //Breathe Mode
|
||||
CM_MR6000_MODE_COLOR_CYCLE = 0x02, //Color cycle
|
||||
|
||||
CM_MR6000_MODE_RAINBOW = 0x07, //Rainbow
|
||||
CM_MR6000_MODE_BOUNCE = 0x08, //Bounce
|
||||
CM_MR6000_MODE_CHASE = 0x09, //Chase
|
||||
CM_MR6000_MODE_SWIRL = 0x0A, //Swirl
|
||||
|
||||
CM_MR6000_MODE_OFF = 0xFF, //Off
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MR6000_CYCLE_SPEED_SLOWEST = 0x96, /* Slowest speed */
|
||||
MR6000_CYCLE_SPEED_SLOW = 0x8C, /* Slow speed */
|
||||
MR6000_CYCLE_SPEED_NORMAL = 0x80, /* Normal speed */
|
||||
MR6000_CYCLE_SPEED_FAST = 0x6E, /* Fast speed */
|
||||
MR6000_CYCLE_SPEED_FASTEST = 0x68, /* Fastest speed */
|
||||
|
||||
MR6000_RAINBOW_SPEED_SLOWEST = 0x78, /* Slowest speed */
|
||||
MR6000_RAINBOW_SPEED_NORMAL = 0x6B, /* Normal speed */
|
||||
MR6000_RAINBOW_SPEED_FASTEST = 0x60, /* Fastest speed */
|
||||
|
||||
MR6000_BREATHE_SPEED_SLOWEST = 0x3C, /* Slowest speed */
|
||||
MR6000_BREATHE_SPEED_SLOW = 0x37, /* Slow speed */
|
||||
MR6000_BREATHE_SPEED_NORMAL = 0x31, /* Normal speed */
|
||||
MR6000_BREATHE_SPEED_FAST = 0x2C, /* Fast speed */
|
||||
MR6000_BREATHE_SPEED_FASTEST = 0x26, /* Fastest speed */
|
||||
};
|
||||
|
||||
class CMR6000Controller
|
||||
{
|
||||
public:
|
||||
CMR6000Controller(hid_device* dev_handle, char *_path, uint16_t _pid);
|
||||
~CMR6000Controller();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
unsigned char GetMode();
|
||||
unsigned char GetLedSpeed();
|
||||
unsigned char GetBrightness();
|
||||
bool GetRandomColours();
|
||||
uint16_t GetPID();
|
||||
|
||||
void SetMode(unsigned char mode, unsigned char speed, RGBColor color1, RGBColor color2, unsigned char random, unsigned char brightness);
|
||||
|
||||
private:
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
uint16_t pid;
|
||||
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
unsigned char current_random;
|
||||
|
||||
unsigned char current_brightness;
|
||||
RGBColor primary;
|
||||
RGBColor secondary;
|
||||
|
||||
void SendUpdate();
|
||||
void SendEnableCommand();
|
||||
void SendApplyCommand();
|
||||
void SendColourConfig();
|
||||
void SendSecondColour();
|
||||
};
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMR6000Controller.cpp |
|
||||
| |
|
||||
| RGBController for Cooler Master AMD Radeon 6000 series |
|
||||
| GPU |
|
||||
| |
|
||||
| Eric S (edbgon) 02 Feb 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CMR6000Controller.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name AMD Radeon 6000
|
||||
@category GPU
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterGPU
|
||||
@comment Similar to the Wraith Spire before it the AMD branded Radeon
|
||||
GPUs have an RGB controller provided by Coolermaster.
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMR6000Controller::RGBController_CMR6000Controller(CMR6000Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = "AMD RX 6xxx GPU";
|
||||
vendor = "Cooler Master";
|
||||
type = DEVICE_TYPE_GPU;
|
||||
description = controller->GetDeviceName();
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.flags = 0;
|
||||
Off.value = CM_MR6000_MODE_OFF;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CM_MR6000_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR| MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.speed = 0xFF;
|
||||
Direct.brightness_min = 0x00;
|
||||
Direct.brightness_max = 0xFF;
|
||||
Direct.brightness = 0xFF;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode ColorCycle;
|
||||
ColorCycle.name = "Spectrum Cycle";
|
||||
ColorCycle.value = CM_MR6000_MODE_COLOR_CYCLE;
|
||||
ColorCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
ColorCycle.speed_min = MR6000_CYCLE_SPEED_SLOWEST;
|
||||
ColorCycle.speed = MR6000_CYCLE_SPEED_NORMAL;
|
||||
ColorCycle.speed_max = MR6000_CYCLE_SPEED_FASTEST;
|
||||
ColorCycle.color_mode = MODE_COLORS_NONE;
|
||||
ColorCycle.speed = MR6000_CYCLE_SPEED_NORMAL;
|
||||
ColorCycle.brightness_min = 0x00;
|
||||
ColorCycle.brightness_max = 0xFF;
|
||||
ColorCycle.brightness = 0x7F;
|
||||
modes.push_back(ColorCycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_MR6000_MODE_BREATHE;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Breathing.speed_min = MR6000_BREATHE_SPEED_SLOWEST;
|
||||
Breathing.speed = MR6000_BREATHE_SPEED_NORMAL;
|
||||
Breathing.speed_max = MR6000_BREATHE_SPEED_FASTEST;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed = MR6000_BREATHE_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
if(controller->GetPID() == COOLERMASTER_RADEON_6900_PID)
|
||||
{
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow Wave";
|
||||
Rainbow.value = CM_MR6000_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.speed_min = MR6000_RAINBOW_SPEED_SLOWEST;
|
||||
Rainbow.speed = MR6000_RAINBOW_SPEED_NORMAL;
|
||||
Rainbow.speed_max = MR6000_RAINBOW_SPEED_FASTEST;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.speed = MR6000_RAINBOW_SPEED_NORMAL;
|
||||
Rainbow.brightness_min = 0x00;
|
||||
Rainbow.brightness_max = 0xFF;
|
||||
Rainbow.brightness = 0xFF;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Bounce;
|
||||
Bounce.name = "Bounce";
|
||||
Bounce.value = CM_MR6000_MODE_BOUNCE;
|
||||
Bounce.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Bounce.speed_min = MR6000_CYCLE_SPEED_SLOWEST;
|
||||
Bounce.speed = MR6000_CYCLE_SPEED_NORMAL;
|
||||
Bounce.speed_max = MR6000_CYCLE_SPEED_FASTEST;
|
||||
Bounce.color_mode = MODE_COLORS_NONE;
|
||||
Bounce.speed = MR6000_CYCLE_SPEED_NORMAL;
|
||||
Bounce.brightness_min = 0x00;
|
||||
Bounce.brightness_max = 0xFF;
|
||||
Bounce.brightness = 0xFF;
|
||||
modes.push_back(Bounce);
|
||||
|
||||
mode Chase;
|
||||
Chase.name = "Chase";
|
||||
Chase.value = CM_MR6000_MODE_CHASE;
|
||||
Chase.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_DIRECTION_LR;
|
||||
Chase.speed_min = MR6000_CYCLE_SPEED_SLOWEST;
|
||||
Chase.speed = MR6000_CYCLE_SPEED_NORMAL;
|
||||
Chase.speed_max = MR6000_CYCLE_SPEED_FASTEST;
|
||||
Chase.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Chase.colors_min = 2;
|
||||
Chase.colors_max = 2;
|
||||
Chase.colors.resize(2);
|
||||
Chase.speed = MR6000_CYCLE_SPEED_NORMAL;
|
||||
Chase.brightness_min = 0;
|
||||
Chase.brightness_max = 0xFF;
|
||||
Chase.brightness = 0xFF;
|
||||
modes.push_back(Chase);
|
||||
|
||||
mode Swirl;
|
||||
Swirl.name = "Swirl";
|
||||
Swirl.value = CM_MR6000_MODE_SWIRL;
|
||||
Swirl.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_DIRECTION_LR;
|
||||
Swirl.speed_min = MR6000_CYCLE_SPEED_SLOWEST;
|
||||
Swirl.speed = MR6000_CYCLE_SPEED_NORMAL;
|
||||
Swirl.speed_max = MR6000_CYCLE_SPEED_FASTEST;
|
||||
Swirl.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Swirl.colors_min = 1;
|
||||
Swirl.colors_max = 1;
|
||||
Swirl.colors.resize(1);
|
||||
Swirl.speed = MR6000_CYCLE_SPEED_NORMAL;
|
||||
Swirl.brightness_min = 0;
|
||||
Swirl.brightness_max = 0xFF;
|
||||
Swirl.brightness = 0xFF;
|
||||
modes.push_back(Swirl);
|
||||
}
|
||||
|
||||
SetupZones();
|
||||
active_mode = 1;
|
||||
}
|
||||
|
||||
RGBController_CMR6000Controller::~RGBController_CMR6000Controller()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMR6000Controller::SetupZones()
|
||||
{
|
||||
zone GP_zone;
|
||||
GP_zone.name = "GPU";
|
||||
GP_zone.type = ZONE_TYPE_SINGLE;
|
||||
GP_zone.leds_min = 1;
|
||||
GP_zone.leds_max = 1;
|
||||
GP_zone.leds_count = 1;
|
||||
GP_zone.matrix_map = NULL;
|
||||
zones.push_back(GP_zone);
|
||||
|
||||
led GP_led;
|
||||
GP_led.name = "Logo";
|
||||
GP_led.value = 0;
|
||||
leds.push_back(GP_led);
|
||||
|
||||
SetupColors();
|
||||
|
||||
}
|
||||
|
||||
void RGBController_CMR6000Controller::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CMR6000Controller::DeviceUpdateLEDs()
|
||||
{
|
||||
mode new_mode = modes[active_mode];
|
||||
RGBColor color1 = (new_mode.colors.size() > 0) ? new_mode.colors[0] : colors[0];
|
||||
RGBColor color2 = (new_mode.colors.size() > 1) ? new_mode.colors[1] : 0;
|
||||
unsigned char bri = (new_mode.flags & MODE_FLAG_HAS_BRIGHTNESS) ? new_mode.brightness : 0xFF;
|
||||
unsigned char rnd = 0x20;
|
||||
|
||||
switch(new_mode.value)
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Breathing mode requires value 0x20 when in MODE_SPECIFIC_COLOR |
|
||||
\*-----------------------------------------------------------------*/
|
||||
case CM_MR6000_MODE_BREATHE:
|
||||
if(new_mode.color_mode == MODE_COLORS_RANDOM)
|
||||
{
|
||||
rnd = 0xA0;
|
||||
}
|
||||
break;
|
||||
case CM_MR6000_MODE_SWIRL:
|
||||
case CM_MR6000_MODE_CHASE:
|
||||
rnd = new_mode.direction;
|
||||
break;
|
||||
default:
|
||||
rnd = 0;
|
||||
}
|
||||
|
||||
controller->SetMode(new_mode.value, new_mode.speed, color1, color2, rnd, bri);
|
||||
}
|
||||
|
||||
void RGBController_CMR6000Controller::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMR6000Controller::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_CMR6000Controller::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMR6000Controller.h |
|
||||
| |
|
||||
| RGBController for Cooler Master AMD Radeon 6000 series |
|
||||
| GPU |
|
||||
| |
|
||||
| Eric S (edbgon) 02 Feb 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CMR6000Controller.h"
|
||||
|
||||
class RGBController_CMR6000Controller : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMR6000Controller(CMR6000Controller* controller_ptr);
|
||||
~RGBController_CMR6000Controller();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
private:
|
||||
CMR6000Controller* controller;
|
||||
|
||||
int GetDeviceMode();
|
||||
};
|
||||
@@ -0,0 +1,374 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMRGBController.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master RGB controller |
|
||||
| |
|
||||
| Nic W (midgetspy) 13 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "RGBController_CMRGBController.h"
|
||||
#include "CMRGBController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
CMRGBController::CMRGBController(hid_device* dev_handle, char* path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get device name from HID manufacturer and product strings |
|
||||
\*---------------------------------------------------------*/
|
||||
wchar_t name_string[HID_MAX_STR];
|
||||
|
||||
hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
|
||||
device_name = StringUtils::wstring_to_string(name_string);
|
||||
|
||||
hid_get_product_string(dev, name_string, HID_MAX_STR);
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
|
||||
ReadCurrentMode();
|
||||
}
|
||||
|
||||
void CMRGBController::SendFlowControl(unsigned char byte_flag)
|
||||
{
|
||||
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { 0x00, CM_RGBC_OPCODE_OP_FLOW_CONTROL }; //Packets on Windows need a 0x00 if they don't use ReportIDs
|
||||
|
||||
buffer[0x02] = byte_flag;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMRGBController::SendApply()
|
||||
{
|
||||
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { 0x00, CM_RGBC_OPCODE_OP_UNKNOWN_50, CM_RGBC_OPCODE_TYPE_UNKNOWN_55 }; //Packets on Windows need a 0x00 if they don't use ReportIDs
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMRGBController::SendReadMode()
|
||||
{
|
||||
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { };
|
||||
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_READ;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_MODE;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
|
||||
|
||||
current_mode = buffer[CM_RGBC_PACKET_OFFSET_MODE];
|
||||
}
|
||||
|
||||
void CMRGBController::SendSetMode(unsigned char mode)
|
||||
{
|
||||
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { };
|
||||
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_WRITE;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_MODE;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MODE] = mode;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMRGBController::SendSetCustomColors(RGBColor color_1, RGBColor color_2, RGBColor color_3, RGBColor color_4)
|
||||
{
|
||||
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { };
|
||||
|
||||
current_port1_color = color_1;
|
||||
current_port2_color = color_2;
|
||||
current_port3_color = color_3;
|
||||
current_port4_color = color_4;
|
||||
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_WRITE;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_LED_INFO;
|
||||
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1] = RGBGetRValue(color_1);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1 + 1] = RGBGetGValue(color_1);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1 + 2] = RGBGetBValue(color_1);
|
||||
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2] = RGBGetRValue(color_2);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2 + 1] = RGBGetGValue(color_2);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2 + 2] = RGBGetBValue(color_2);
|
||||
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3] = RGBGetRValue(color_3);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3 + 1] = RGBGetGValue(color_3);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3 + 2] = RGBGetBValue(color_3);
|
||||
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4] = RGBGetRValue(color_4);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4 + 1] = RGBGetGValue(color_4);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4 + 2] = RGBGetBValue(color_4);
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMRGBController::SendReadCustomColors()
|
||||
{
|
||||
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { };
|
||||
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_READ;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_LED_INFO;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
|
||||
|
||||
current_port1_color = ToRGBColor(
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1 + 1],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1 + 2]);
|
||||
current_port2_color = ToRGBColor(
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2 + 1],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2 + 2]);
|
||||
current_port3_color = ToRGBColor(
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3 + 1],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3 + 2]);
|
||||
current_port4_color = ToRGBColor(
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4 + 1],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4 + 2]);
|
||||
}
|
||||
|
||||
void CMRGBController::SendSetConfig(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor color_1, RGBColor color_2, bool simplified=false, bool multilayer=false)
|
||||
{
|
||||
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { };
|
||||
|
||||
current_mode = mode;
|
||||
current_speed = speed;
|
||||
current_brightness = brightness;
|
||||
current_mode_color_1 = color_1;
|
||||
current_mode_color_2 = color_2;
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Handle special cases |
|
||||
\*---------------------------------------------*/
|
||||
switch(mode)
|
||||
{
|
||||
case CM_RGBC_MODE_COLOR_CYCLE:
|
||||
brightness = 0xDF;
|
||||
color_1 = 0xFFFFFF;
|
||||
color_2 = 0x000000;
|
||||
break;
|
||||
|
||||
case CM_RGBC_MODE_OFF:
|
||||
brightness = 0x03;
|
||||
break;
|
||||
}
|
||||
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_WRITE;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = simplified ? CM_RGBC_OPCODE_TYPE_CONFIG_SIMPLIFIED : CM_RGBC_OPCODE_TYPE_CONFIG_FULL;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MODE] = mode;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_SPEED] = speed;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_BRIGHTNESS] = brightness;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_1] = RGBGetRValue(color_1);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_1 + 1] = RGBGetGValue(color_1);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_1 + 2] = RGBGetBValue(color_1);
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Magic values, meaning unknown |
|
||||
\*---------------------------------------------*/
|
||||
buffer[REPORT_ID_OFFSET + 0x06] = (mode == CM_RGBC_MODE_BREATHING) ? 0x20 : 0x00;
|
||||
buffer[REPORT_ID_OFFSET + 0x07] = (mode == CM_RGBC_MODE_STAR) ? 0x19 : 0xFF;
|
||||
buffer[REPORT_ID_OFFSET + 0x08] = 0xFF;
|
||||
|
||||
if(!simplified)
|
||||
{
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTILAYER] = multilayer ? 0x01 : 0x00;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_2] = RGBGetRValue(color_2);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_2 + 1] = RGBGetGValue(color_2);
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_2 + 2] = RGBGetBValue(color_2);
|
||||
|
||||
for(int i = REPORT_ID_OFFSET + 16; i < CM_RGBC_PACKET_SIZE; i++)
|
||||
{
|
||||
buffer[i] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMRGBController::SendReadConfig(unsigned char mode)
|
||||
{
|
||||
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { };
|
||||
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_READ;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_CONFIG_FULL;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MODE] = mode;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
|
||||
|
||||
current_mode = mode;
|
||||
current_speed = buffer[CM_RGBC_PACKET_OFFSET_SPEED];
|
||||
current_brightness = buffer[CM_RGBC_PACKET_OFFSET_BRIGHTNESS];
|
||||
|
||||
current_mode_color_1 = ToRGBColor(
|
||||
buffer[CM_RGBC_PACKET_OFFSET_COLOR_1],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_COLOR_1 + 1],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_COLOR_1 + 2]);
|
||||
current_mode_color_2 = ToRGBColor(
|
||||
buffer[CM_RGBC_PACKET_OFFSET_COLOR_2],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_COLOR_2 + 1],
|
||||
buffer[CM_RGBC_PACKET_OFFSET_COLOR_2 + 2]);
|
||||
}
|
||||
|
||||
void CMRGBController::SendCustomColorStart()
|
||||
{
|
||||
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { };
|
||||
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_WRITE;
|
||||
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_UNKNOWN_30;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
void CMRGBController::ReadCurrentMode()
|
||||
{
|
||||
SendFlowControl(CM_RGBC_OPCODE_FLOW_01);
|
||||
|
||||
SendReadMode();
|
||||
}
|
||||
|
||||
void CMRGBController::ReadModeConfig(unsigned char mode)
|
||||
{
|
||||
SendFlowControl(CM_RGBC_OPCODE_FLOW_00);
|
||||
|
||||
SendReadConfig(mode);
|
||||
|
||||
if(mode == CM_RGBC_MODE_MULTIPLE)
|
||||
{
|
||||
SendReadCustomColors();
|
||||
}
|
||||
}
|
||||
|
||||
void CMRGBController::SetMode(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor color_1, RGBColor color_2)
|
||||
{
|
||||
SendFlowControl(CM_RGBC_OPCODE_FLOW_01);
|
||||
|
||||
SendSetConfig(mode, speed, brightness, color_1, color_2, false);
|
||||
|
||||
SendSetMode(mode);
|
||||
|
||||
SendApply();
|
||||
|
||||
SendFlowControl(CM_RGBC_OPCODE_FLOW_00);
|
||||
}
|
||||
|
||||
void CMRGBController::SetLedsDirect(RGBColor color_1, RGBColor color_2, RGBColor color_3, RGBColor color_4)
|
||||
{
|
||||
SendFlowControl(CM_RGBC_OPCODE_FLOW_80);
|
||||
|
||||
SendCustomColorStart();
|
||||
|
||||
SendSetCustomColors(color_1, color_2, color_3, color_4);
|
||||
|
||||
SendSetMode(CM_RGBC_MODE_MULTIPLE);
|
||||
|
||||
SendCustomColorStart();
|
||||
|
||||
SendSetConfig(CM_RGBC_MODE_MULTIPLE, 0x00, 0xFF, color_1, 0x000000, false);
|
||||
|
||||
SendApply();
|
||||
|
||||
SendFlowControl(CM_RGBC_OPCODE_FLOW_00);
|
||||
}
|
||||
|
||||
std::string CMRGBController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string CMRGBController::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[HID_MAX_STR];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, HID_MAX_STR);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string CMRGBController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
unsigned char CMRGBController::GetMode()
|
||||
{
|
||||
return(current_mode);
|
||||
}
|
||||
|
||||
unsigned char CMRGBController::GetSpeed()
|
||||
{
|
||||
return(current_speed);
|
||||
}
|
||||
|
||||
unsigned char CMRGBController::GetBrightness()
|
||||
{
|
||||
return(current_brightness);
|
||||
}
|
||||
|
||||
RGBColor CMRGBController::GetModeColor(int color_number)
|
||||
{
|
||||
switch(color_number)
|
||||
{
|
||||
case 0:
|
||||
return(current_mode_color_1);
|
||||
|
||||
case 1:
|
||||
return(current_mode_color_2);
|
||||
|
||||
default:
|
||||
return(ToRGBColor(0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
RGBColor CMRGBController::GetPortColor(int port_number)
|
||||
{
|
||||
switch(port_number)
|
||||
{
|
||||
case 0:
|
||||
return(current_port1_color);
|
||||
|
||||
case 1:
|
||||
return(current_port2_color);
|
||||
|
||||
case 2:
|
||||
return(current_port3_color);
|
||||
|
||||
case 3:
|
||||
return(current_port4_color);
|
||||
|
||||
default:
|
||||
return(ToRGBColor(0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
CMRGBController::~CMRGBController()
|
||||
{
|
||||
if(dev)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMRGBController.h |
|
||||
| |
|
||||
| Driver for Cooler Master RGB controller |
|
||||
| |
|
||||
| Nic W (midgetspy) 13 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define CM_RGBC_NUM_LEDS 4
|
||||
|
||||
#define REPORT_ID_OFFSET 1
|
||||
#define CM_RGBC_PACKET_SIZE 64 + REPORT_ID_OFFSET //This needs to have one byte extra for the report ID thing
|
||||
#define CM_RGBC_PACKET_OFFSET_OP 0x00
|
||||
#define CM_RGBC_PACKET_OFFSET_TYPE 0x01
|
||||
#define CM_RGBC_PACKET_OFFSET_MULTILAYER 0x02
|
||||
#define CM_RGBC_PACKET_OFFSET_MODE 0x04
|
||||
#define CM_RGBC_PACKET_OFFSET_SPEED 0x05
|
||||
#define CM_RGBC_PACKET_OFFSET_BRIGHTNESS 0x09
|
||||
#define CM_RGBC_PACKET_OFFSET_COLOR_1 0x0A
|
||||
#define CM_RGBC_PACKET_OFFSET_COLOR_2 0x0D
|
||||
|
||||
#define CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1 0x04
|
||||
#define CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2 0x07
|
||||
#define CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3 0x0A
|
||||
#define CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4 0x0D
|
||||
|
||||
#define CM_RGBC_INTERRUPT_TIMEOUT 250
|
||||
|
||||
#define CM_RGBC_SPEED_NONE 0x05
|
||||
#define CM_RGBC_BRIGHTNESS_OFF 0x03
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| OP OPCODES |
|
||||
\*-------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CM_RGBC_OPCODE_OP_FLOW_CONTROL = 0x41,
|
||||
CM_RGBC_OPCODE_OP_UNKNOWN_50 = 0x50,
|
||||
CM_RGBC_OPCODE_OP_WRITE = 0x51,
|
||||
CM_RGBC_OPCODE_OP_READ = 0x52,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| CONTROL FLOW OPCODES |
|
||||
\*-------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CM_RGBC_OPCODE_FLOW_00 = 0x00,
|
||||
CM_RGBC_OPCODE_FLOW_01 = 0x01,
|
||||
CM_RGBC_OPCODE_FLOW_80 = 0x80,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| OP TYPE OPCODES |
|
||||
\*-------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CM_RGBC_OPCODE_TYPE_MODE = 0x28,
|
||||
CM_RGBC_OPCODE_TYPE_CONFIG_SIMPLIFIED = 0x2B,
|
||||
CM_RGBC_OPCODE_TYPE_CONFIG_FULL = 0x2C,
|
||||
CM_RGBC_OPCODE_TYPE_UNKNOWN_30 = 0x30,
|
||||
CM_RGBC_OPCODE_TYPE_UNKNOWN_55 = 0x55,
|
||||
CM_RGBC_OPCODE_TYPE_LED_INFO = 0xA8,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| MODES |
|
||||
\*-------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CM_RGBC_MODE_STATIC = 0x00,
|
||||
CM_RGBC_MODE_BREATHING = 0x01,
|
||||
CM_RGBC_MODE_COLOR_CYCLE = 0x02,
|
||||
CM_RGBC_MODE_STAR = 0x03,
|
||||
CM_RGBC_MODE_MULTIPLE = 0x04,
|
||||
CM_RGBC_MODE_MULTILAYER = 0xE0,
|
||||
CM_RGBC_MODE_OFF = 0xFE,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| SPEED |
|
||||
\*-------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CM_RGBC_SPEED_BREATHING_SLOWEST = 0x3C,
|
||||
CM_RGBC_SPEED_BREATHING_FASTEST = 0x26,
|
||||
CM_RGBC_SPEED_COLOR_CYCLE_SLOWEST = 0x96,
|
||||
CM_RGBC_SPEED_COLOR_CYCLE_FASTEST = 0x68,
|
||||
CM_RGBC_SPEED_STAR_SLOWEST = 0x46,
|
||||
CM_RGBC_SPEED_STAR_FASTEST = 0x32,
|
||||
};
|
||||
|
||||
class CMRGBController
|
||||
{
|
||||
public:
|
||||
CMRGBController(hid_device* dev_handle, char* path);
|
||||
~CMRGBController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
unsigned char GetMode();
|
||||
unsigned char GetSpeed();
|
||||
unsigned char GetBrightness();
|
||||
RGBColor GetModeColor(int color_number);
|
||||
RGBColor GetPortColor(int port_number);
|
||||
|
||||
void SetMode(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor color_1, RGBColor color_2);
|
||||
void SetLedsDirect(RGBColor color_1, RGBColor color_2, RGBColor color_3, RGBColor color_4);
|
||||
|
||||
void ReadCurrentMode();
|
||||
void ReadModeConfig(unsigned char mode);
|
||||
|
||||
private:
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
unsigned char current_brightness;
|
||||
RGBColor current_mode_color_1;
|
||||
RGBColor current_mode_color_2;
|
||||
RGBColor current_port1_color;
|
||||
RGBColor current_port2_color;
|
||||
RGBColor current_port3_color;
|
||||
RGBColor current_port4_color;
|
||||
|
||||
void SendFlowControl(unsigned char byte_flag);
|
||||
void SendApply();
|
||||
void SendCustomColorStart();
|
||||
|
||||
void SendReadMode();
|
||||
void SendSetMode(unsigned char mode);
|
||||
|
||||
void SendReadCustomColors();
|
||||
void SendSetCustomColors(RGBColor color_1, RGBColor color_2, RGBColor color_3, RGBColor color_4);
|
||||
|
||||
void SendReadConfig(unsigned char mode);
|
||||
void SendSetConfig(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor color_1, RGBColor color_2, bool simplified, bool multilayer);
|
||||
};
|
||||
@@ -0,0 +1,274 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMRGBController.cpp |
|
||||
| |
|
||||
| RGBController for Cooler Master RGB controller |
|
||||
| |
|
||||
| Nic W (midgetspy) 13 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CMRGBController.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| This controller has 4 ports, each for a 12v non-addressable LED item. |
|
||||
| |
|
||||
| It supports the following modes: |
|
||||
| Static: All 4 ports a single color. Has brightness option. |
|
||||
| Breathing: All ports a single color, fading in and out. Has brightness and speed option. |
|
||||
| Star: Some weird effect using all 4 ports and a single color. Has brightness and speed option. |
|
||||
| Color Cycle: All ports cycle through the rainbow in unison. Has brightness and speed option. |
|
||||
| Off: All 4 ports off |
|
||||
| |
|
||||
| Plus some "special" modes: |
|
||||
| Multilayer: Each of the 4 ports can have any of the modes above applied individually |
|
||||
| Multiple Color/Customize: Each port can be set to its own static color |
|
||||
| Mirage: A strobe effect that varies the LED pulse frequency which affects any of the above modes |
|
||||
| |
|
||||
| Note: |
|
||||
| Multiple Color/Customize is equivalent to Multilayer + Static, but the device supports both separately |
|
||||
| Static is equivalent to Multiple Color/Customize with the same color on each port, but the device supports both separately |
|
||||
| |
|
||||
| It can be controlled with 2 different pieces of software: MasterPlus+ or "RGB LED Controller". They appear to use different protocols. |
|
||||
| |
|
||||
| RGB LED Controller: |
|
||||
| Sets changes temporarily and then applies them or cancels the changes separately |
|
||||
| Supports all modes above |
|
||||
| Has 3 brightness increments |
|
||||
| Has two different colors for the Star effect (Star/Sky) |
|
||||
| |
|
||||
| MasterPlus+: |
|
||||
| Sets changes permanently as soon as you change anything in the UI |
|
||||
| Doesn't support Multilayer or Mirage |
|
||||
| Has 5 brightness increments |
|
||||
| Single color for Star |
|
||||
\*-----------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Coolermaster RGB
|
||||
@category LEDStrip
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterRGB
|
||||
@comment This is a 12V analogue RGB controller only.
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMRGBController::RGBController_CMRGBController(CMRGBController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = "Cooler Master RGB Controller";
|
||||
vendor = "Cooler Master";
|
||||
type = DEVICE_TYPE_LEDSTRIP;
|
||||
description = controller->GetDeviceName();
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = CM_RGBC_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(Static.colors_max);
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness_min = 0x00;
|
||||
Static.brightness_max = 0xFF;
|
||||
Static.brightness = 0xFF;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_RGBC_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(Breathing.colors_max);
|
||||
Breathing.speed_min = CM_RGBC_SPEED_BREATHING_SLOWEST;
|
||||
Breathing.speed_max = CM_RGBC_SPEED_BREATHING_FASTEST;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed = CM_RGBC_SPEED_BREATHING_SLOWEST;
|
||||
Breathing.brightness_min = 0x00;
|
||||
Breathing.brightness_max = 0xFF;
|
||||
Breathing.brightness = 0xFF;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode ColorCycle;
|
||||
ColorCycle.name = "Spectrum Cycle";
|
||||
ColorCycle.value = CM_RGBC_MODE_COLOR_CYCLE;
|
||||
ColorCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
ColorCycle.speed_min = CM_RGBC_SPEED_COLOR_CYCLE_SLOWEST;
|
||||
ColorCycle.speed_max = CM_RGBC_SPEED_COLOR_CYCLE_FASTEST;
|
||||
ColorCycle.color_mode = MODE_COLORS_RANDOM;
|
||||
ColorCycle.speed = CM_RGBC_SPEED_COLOR_CYCLE_SLOWEST;
|
||||
ColorCycle.brightness_min = 0x00;
|
||||
ColorCycle.brightness_max = 0xFF;
|
||||
ColorCycle.brightness = 0xFF;
|
||||
modes.push_back(ColorCycle);
|
||||
|
||||
mode Star;
|
||||
Star.name = "Star";
|
||||
Star.value = CM_RGBC_MODE_STAR;
|
||||
Star.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Star.colors_min = 2;
|
||||
Star.colors_max = 2;
|
||||
Star.colors.resize(Star.colors_max);
|
||||
Star.speed_min = CM_RGBC_SPEED_STAR_SLOWEST;
|
||||
Star.speed_max = CM_RGBC_SPEED_STAR_FASTEST;
|
||||
Star.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Star.speed = CM_RGBC_SPEED_STAR_SLOWEST;
|
||||
Star.brightness_min = 0x00;
|
||||
Star.brightness_max = 0xFF;
|
||||
Star.brightness = 0xFF;
|
||||
modes.push_back(Star);
|
||||
|
||||
mode Multiple;
|
||||
Multiple.name = "Custom";
|
||||
Multiple.value = CM_RGBC_MODE_MULTIPLE;
|
||||
Multiple.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Multiple.colors_min = 1;
|
||||
Multiple.colors_max = 1;
|
||||
Multiple.colors.resize(Multiple.colors_max);
|
||||
Multiple.color_mode = MODE_COLORS_PER_LED;
|
||||
Multiple.speed = 0;
|
||||
Multiple.brightness_min = 0x00;
|
||||
Multiple.brightness_max = 0xFF;
|
||||
Multiple.brightness = 0xFF;
|
||||
modes.push_back(Multiple);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = CM_RGBC_MODE_OFF;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
Off.flags = 0;
|
||||
modes.push_back(Off);
|
||||
|
||||
SetupZones();
|
||||
|
||||
ReadAllModeConfigsFromDevice();
|
||||
}
|
||||
|
||||
RGBController_CMRGBController::~RGBController_CMRGBController()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMRGBController::ReadAllModeConfigsFromDevice()
|
||||
{
|
||||
int device_mode = controller->GetMode();
|
||||
|
||||
for(int mode_idx = 0; mode_idx < (int)modes.size(); mode_idx++)
|
||||
{
|
||||
if(device_mode == modes[mode_idx].value)
|
||||
{
|
||||
active_mode = mode_idx;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!modes[mode_idx].flags)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
controller->ReadModeConfig(modes[mode_idx].value);
|
||||
LoadConfigFromDeviceController(mode_idx);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Do the active mode last so the device controller state |
|
||||
| is left with the active mode's config |
|
||||
\*---------------------------------------------------------*/
|
||||
if(active_mode != -1)
|
||||
{
|
||||
controller->ReadModeConfig(modes[active_mode].value);
|
||||
LoadConfigFromDeviceController(active_mode);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMRGBController::LoadConfigFromDeviceController(int mode_idx)
|
||||
{
|
||||
for(int color_idx = 0; color_idx < (int)modes[mode_idx].colors.size(); color_idx++)
|
||||
{
|
||||
modes[mode_idx].colors[0] = controller->GetModeColor(color_idx);
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_PER_LED_COLOR)
|
||||
{
|
||||
for(int led_idx = 0; led_idx < (int)leds.size(); led_idx++)
|
||||
{
|
||||
SetLED(led_idx, controller->GetPortColor(led_idx));
|
||||
}
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
modes[mode_idx].speed = controller->GetSpeed();
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
modes[active_mode].brightness = controller->GetBrightness();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RGBController_CMRGBController::SetupZones()
|
||||
{
|
||||
leds.clear();
|
||||
zones.clear();
|
||||
colors.clear();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| One zone, 4 leds. This might not actually work with |
|
||||
| the Multilayer mode, but we'll deal with that later |
|
||||
\*-----------------------------------------------------*/
|
||||
zone* new_zone = new zone();
|
||||
new_zone->name = "Controller";
|
||||
new_zone->type = ZONE_TYPE_SINGLE;
|
||||
new_zone->leds_min = 1;
|
||||
new_zone->leds_max = 4;
|
||||
new_zone->leds_count = 4;
|
||||
new_zone->matrix_map = NULL;
|
||||
|
||||
for(int i = 1; i <= CM_RGBC_NUM_LEDS; i++)
|
||||
{
|
||||
led* new_led = new led();
|
||||
new_led->name = "LED " + std::to_string(i);
|
||||
leds.push_back(*new_led);
|
||||
}
|
||||
|
||||
zones.push_back(*new_zone);
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMRGBController::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
}
|
||||
|
||||
void RGBController_CMRGBController::DeviceUpdateLEDs()
|
||||
{
|
||||
for(int zone_idx = 0; zone_idx < (int)zones.size(); zone_idx++)
|
||||
{
|
||||
UpdateZoneLEDs(zone_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMRGBController::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
controller->SetLedsDirect(zones[zone].colors[0], zones[zone].colors[1], zones[zone].colors[2], zones[zone].colors[3]);
|
||||
}
|
||||
|
||||
void RGBController_CMRGBController::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
}
|
||||
|
||||
void RGBController_CMRGBController::DeviceUpdateMode()
|
||||
{
|
||||
RGBColor color_1 = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
|
||||
RGBColor color_2 = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC && modes[active_mode].colors.size() > 1) ? modes[active_mode].colors[1] : 0;
|
||||
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, color_1, color_2);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMRGBController.h |
|
||||
| |
|
||||
| RGBController for Cooler Master RGB controller |
|
||||
| |
|
||||
| Nic W (midgetspy) 13 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "RGBController.h"
|
||||
#include "CMRGBController.h"
|
||||
|
||||
class RGBController_CMRGBController : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMRGBController(CMRGBController* controller_ptr);
|
||||
~RGBController_CMRGBController();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
CMRGBController* controller;
|
||||
void LoadConfigFromDeviceController(int device_mode);
|
||||
void ReadAllModeConfigsFromDevice();
|
||||
};
|
||||
@@ -0,0 +1,239 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMSmallARGBController.cpp |
|
||||
| |
|
||||
| Driver for Cooler Master Small ARGB controller |
|
||||
| |
|
||||
| Chris M (Dr_No) 31 Jan 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "CMSmallARGBController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
cm_small_argb_headers cm_small_argb_header_data[1] =
|
||||
{
|
||||
{ "CM Small ARGB", 0x01, true, 12 }
|
||||
};
|
||||
|
||||
CMSmallARGBController::CMSmallARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
zone_index = _zone_idx;
|
||||
current_speed = CM_SMALL_ARGB_SPEED_NORMAL;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get device name from HID manufacturer and product strings |
|
||||
\*---------------------------------------------------------*/
|
||||
wchar_t name_string[HID_MAX_STR];
|
||||
|
||||
hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
|
||||
device_name = StringUtils::wstring_to_string(name_string);
|
||||
|
||||
hid_get_product_string(dev, name_string, HID_MAX_STR);
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
|
||||
GetStatus();
|
||||
}
|
||||
|
||||
CMSmallARGBController::~CMSmallARGBController()
|
||||
{
|
||||
if(dev)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
void CMSmallARGBController::GetStatus()
|
||||
{
|
||||
unsigned char buffer[CM_SMALL_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x01, 0x01 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
int header = zone_index - 1;
|
||||
|
||||
buffer[CM_SMALL_ARGB_ZONE_BYTE] = header;
|
||||
buffer[CM_SMALL_ARGB_MODE_BYTE] = 0x01;
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_SMALL_ARGB_INTERRUPT_TIMEOUT);
|
||||
|
||||
memset(buffer, 0x00, buffer_size );
|
||||
|
||||
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = 0x0B;
|
||||
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = 0x01;
|
||||
buffer[CM_SMALL_ARGB_ZONE_BYTE] = 0x01;
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_SMALL_ARGB_INTERRUPT_TIMEOUT);
|
||||
|
||||
current_mode = buffer[4];
|
||||
current_speed = buffer[5];
|
||||
bool_random = buffer[6] == 0x00;
|
||||
current_brightness = buffer[7];
|
||||
current_red = buffer[8];
|
||||
current_green = buffer[9];
|
||||
current_blue = buffer[10];
|
||||
}
|
||||
|
||||
std::string CMSmallARGBController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string CMSmallARGBController::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[HID_MAX_STR];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, HID_MAX_STR);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string CMSmallARGBController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
unsigned char CMSmallARGBController::GetZoneIndex()
|
||||
{
|
||||
return(zone_index);
|
||||
}
|
||||
|
||||
unsigned char CMSmallARGBController::GetMode()
|
||||
{
|
||||
return(current_mode);
|
||||
}
|
||||
|
||||
unsigned char CMSmallARGBController::GetLedRed()
|
||||
{
|
||||
return(current_red);
|
||||
}
|
||||
|
||||
unsigned char CMSmallARGBController::GetLedGreen()
|
||||
{
|
||||
return(current_green);
|
||||
}
|
||||
|
||||
unsigned char CMSmallARGBController::GetLedBlue()
|
||||
{
|
||||
return(current_blue);
|
||||
}
|
||||
|
||||
unsigned char CMSmallARGBController::GetLedSpeed()
|
||||
{
|
||||
return(current_speed);
|
||||
}
|
||||
|
||||
bool CMSmallARGBController::GetRandomColours()
|
||||
{
|
||||
return(bool_random);
|
||||
}
|
||||
|
||||
void CMSmallARGBController::SetLedCount(int zone, int led_count)
|
||||
{
|
||||
unsigned char buffer[CM_SMALL_ARGB_PACKET_SIZE] = { 0x00, 0x80, 0x0D, 0x02 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
buffer[CM_SMALL_ARGB_ZONE_BYTE] = zone;
|
||||
buffer[CM_SMALL_ARGB_MODE_BYTE] = (0x0F - led_count > 0) ? 0x0F - led_count : 0x01;
|
||||
buffer[CM_SMALL_ARGB_SPEED_BYTE] = led_count;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
|
||||
void CMSmallARGBController::SetMode(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor colour, bool random_colours)
|
||||
{
|
||||
current_mode = mode;
|
||||
current_speed = speed;
|
||||
current_brightness = brightness;
|
||||
current_red = RGBGetRValue(colour);
|
||||
current_green = RGBGetGValue(colour);
|
||||
current_blue = RGBGetBValue(colour);
|
||||
bool_random = random_colours;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void CMSmallARGBController::SetLedsDirect(RGBColor* led_colours, unsigned int led_count)
|
||||
{
|
||||
const unsigned char buffer_size = CM_SMALL_ARGB_PACKET_SIZE;
|
||||
unsigned char buffer[buffer_size] = { 0x00, 0x00, 0x10, 0x02 };
|
||||
unsigned char packet_count = 0;
|
||||
std::vector<uint8_t> colours;
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Set up the RGB triplets to send |
|
||||
\*---------------------------------------------*/
|
||||
for(unsigned int i = 0; i < led_count; i++)
|
||||
{
|
||||
RGBColor colour = led_colours[i];
|
||||
|
||||
colours.push_back( RGBGetRValue(colour) );
|
||||
colours.push_back( RGBGetGValue(colour) );
|
||||
colours.push_back( RGBGetBValue(colour) );
|
||||
}
|
||||
|
||||
buffer[CM_SMALL_ARGB_ZONE_BYTE] = zone_index - 1; //argb_header_data[zone_index].header;
|
||||
buffer[CM_SMALL_ARGB_MODE_BYTE] = led_count;
|
||||
unsigned char buffer_idx = CM_SMALL_ARGB_MODE_BYTE + 1;
|
||||
|
||||
for(std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = CM_SMALL_ARGB_COMMAND_BYTE)
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Fill the write buffer till its full or the colour buffer is empty |
|
||||
\*-----------------------------------------------------------------*/
|
||||
buffer[CM_SMALL_ARGB_REPORT_BYTE] = packet_count;
|
||||
while (( buffer_idx < buffer_size) && ( it != colours.end() ))
|
||||
{
|
||||
buffer[buffer_idx] = *it;
|
||||
buffer_idx++;
|
||||
it++;
|
||||
}
|
||||
|
||||
if(it == colours.end())
|
||||
{
|
||||
buffer[CM_SMALL_ARGB_REPORT_BYTE] += 0x80;
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Reset the write buffer |
|
||||
\*-----------------------------------------------------------------*/
|
||||
memset(buffer, 0x00, buffer_size );
|
||||
packet_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void CMSmallARGBController::SendUpdate()
|
||||
{
|
||||
unsigned char buffer[CM_SMALL_ARGB_PACKET_SIZE] = { 0x00 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
bool boolPassthru = ( current_mode == CM_SMALL_ARGB_MODE_PASSTHRU );
|
||||
bool boolDirect = ( current_mode == CM_SMALL_ARGB_MODE_DIRECT );
|
||||
unsigned char function = boolPassthru ? 0x02 : 0x01;
|
||||
buffer[CM_SMALL_ARGB_REPORT_BYTE] = 0x80;
|
||||
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = boolDirect ? 0x10 : 0x01;
|
||||
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = boolDirect ? 0x01 : function;
|
||||
buffer[CM_SMALL_ARGB_MODE_BYTE] = boolPassthru ? 0x00 : 0x02;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
|
||||
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = 0x0b;
|
||||
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = (false) ? 0x01 : 0x02; //This controls custom mode TODO
|
||||
buffer[CM_SMALL_ARGB_ZONE_BYTE] = cm_small_argb_header_data[zone_index].header;
|
||||
buffer[CM_SMALL_ARGB_MODE_BYTE] = current_mode;
|
||||
buffer[CM_SMALL_ARGB_SPEED_BYTE] = current_speed;
|
||||
buffer[CM_SMALL_ARGB_COLOUR_INDEX_BYTE] = (bool_random) ? 0x00 : 0x10; //This looks to still be the colour index and controls random colours
|
||||
buffer[CM_SMALL_ARGB_BRIGHTNESS_BYTE] = current_brightness;
|
||||
buffer[CM_SMALL_ARGB_RED_BYTE] = current_red;
|
||||
buffer[CM_SMALL_ARGB_GREEN_BYTE] = current_green;
|
||||
buffer[CM_SMALL_ARGB_BLUE_BYTE] = current_blue;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read_timeout(dev, buffer, buffer_size, CM_SMALL_ARGB_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CMSmallARGBController.h |
|
||||
| |
|
||||
| Driver for Cooler Master Small ARGB controller |
|
||||
| |
|
||||
| Chris M (Dr_No) 31 Jan 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h" //Needed to set the direct mode
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Simple RGB device with 5 modes |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#define CM_SMALL_ARGB_PACKET_SIZE 65
|
||||
#define CM_SMALL_ARGB_INTERRUPT_TIMEOUT 250
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
enum
|
||||
{
|
||||
CM_SMALL_ARGB_REPORT_BYTE = 1,
|
||||
CM_SMALL_ARGB_COMMAND_BYTE = 2,
|
||||
CM_SMALL_ARGB_FUNCTION_BYTE = 3,
|
||||
CM_SMALL_ARGB_ZONE_BYTE = 4,
|
||||
CM_SMALL_ARGB_MODE_BYTE = 5,
|
||||
CM_SMALL_ARGB_SPEED_BYTE = 6,
|
||||
CM_SMALL_ARGB_COLOUR_INDEX_BYTE = 7, //Not used on the small controller
|
||||
CM_SMALL_ARGB_BRIGHTNESS_BYTE = 8, //0x00 thru 0xFF
|
||||
CM_SMALL_ARGB_RED_BYTE = 9,
|
||||
CM_SMALL_ARGB_GREEN_BYTE = 10,
|
||||
CM_SMALL_ARGB_BLUE_BYTE = 11,
|
||||
};
|
||||
|
||||
struct cm_small_argb_headers
|
||||
{
|
||||
const char* name;
|
||||
unsigned char header;
|
||||
bool digital;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
extern cm_small_argb_headers cm_small_argb_header_data[1];
|
||||
|
||||
enum
|
||||
{
|
||||
CM_SMALL_ARGB_MODE_SPECTRUM = 0x01, //Spectrum Mode
|
||||
CM_SMALL_ARGB_MODE_RELOAD = 0x02, //Reload Mode
|
||||
CM_SMALL_ARGB_MODE_RECOIL = 0x03, //Recoil Mode
|
||||
CM_SMALL_ARGB_MODE_BREATHING = 0x04, //Breathing Mode
|
||||
CM_SMALL_ARGB_MODE_REFILL = 0x05, //Refill Mode
|
||||
CM_SMALL_ARGB_MODE_DEMO = 0x06, //Demo Mode
|
||||
CM_SMALL_ARGB_MODE_OFF = 0x09, //Turn off
|
||||
CM_SMALL_ARGB_MODE_DIRECT = 0xFE, //Direct Led Control (possibly N?A for small controller)
|
||||
CM_SMALL_ARGB_MODE_PASSTHRU = 0xFF //Motherboard Pass Thru Mode
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CM_SMALL_ARGB_SPEED_SLOWEST = 0x00, // Slowest speed
|
||||
CM_SMALL_ARGB_SPEED_SLOW = 0x01, // Slower speed
|
||||
CM_SMALL_ARGB_SPEED_NORMAL = 0x02, // Normal speed
|
||||
CM_SMALL_ARGB_SPEED_FAST = 0x03, // Fast speed
|
||||
CM_SMALL_ARGB_SPEED_FASTEST = 0x04, // Fastest speed
|
||||
};
|
||||
|
||||
class CMSmallARGBController
|
||||
{
|
||||
public:
|
||||
CMSmallARGBController(hid_device* dev_handle, char *_path, unsigned char _zone_idx);
|
||||
~CMSmallARGBController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
unsigned char GetZoneIndex();
|
||||
unsigned char GetMode();
|
||||
unsigned char GetLedRed();
|
||||
unsigned char GetLedGreen();
|
||||
unsigned char GetLedBlue();
|
||||
unsigned char GetLedSpeed();
|
||||
bool GetRandomColours();
|
||||
|
||||
void SetLedCount(int zone, int led_count);
|
||||
void SetMode(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor colour, bool random_colours);
|
||||
void SetLedsDirect(RGBColor * led_colours, unsigned int led_count);
|
||||
private:
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
|
||||
unsigned char zone_index;
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
|
||||
unsigned char current_red;
|
||||
unsigned char current_green;
|
||||
unsigned char current_blue;
|
||||
unsigned char current_brightness;
|
||||
bool bool_random;
|
||||
|
||||
unsigned int GetLargestColour(unsigned int red, unsigned int green, unsigned int blue);
|
||||
unsigned char GetColourIndex(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void GetStatus();
|
||||
void SendUpdate();
|
||||
};
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMSmallARGBController.cpp |
|
||||
| |
|
||||
| RGBController for Cooler Master Small ARGB controller |
|
||||
| |
|
||||
| Chris M (Dr_No) 31 Jan 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_CMSmallARGBController.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Coolermaster Small ARGB
|
||||
@category LEDStrip
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCoolerMasterSmallARGB
|
||||
@comment The Coolermaster Small ARGB device supports `Direct` mode
|
||||
from firmware 0012 onwards. Check the serial number for the date
|
||||
"A202104052336" or newer.
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CMSmallARGBController::RGBController_CMSmallARGBController(CMSmallARGBController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
unsigned char speed = controller->GetLedSpeed();
|
||||
|
||||
name = cm_small_argb_header_data[controller->GetZoneIndex()].name;
|
||||
vendor = "Cooler Master";
|
||||
type = DEVICE_TYPE_LEDSTRIP;
|
||||
description = controller->GetDeviceName();
|
||||
version = "2.0 for FW0012";
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
if(serial >= CM_SMALL_ARGB_FW0012)
|
||||
{
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CM_SMALL_ARGB_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Direct.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
}
|
||||
|
||||
mode Off;
|
||||
Off.name = "Turn Off";
|
||||
Off.value = CM_SMALL_ARGB_MODE_OFF;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Reload;
|
||||
Reload.name = "Reload";
|
||||
Reload.value = CM_SMALL_ARGB_MODE_RELOAD;
|
||||
Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Reload.colors_min = 1;
|
||||
Reload.colors_max = 1;
|
||||
Reload.colors.resize(Reload.colors_max);
|
||||
Reload.brightness_min = 0;
|
||||
Reload.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Reload.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Reload.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Reload.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Reload.color_mode = MODE_COLORS_RANDOM;
|
||||
Reload.speed = speed;
|
||||
modes.push_back(Reload);
|
||||
|
||||
mode Recoil;
|
||||
Recoil.name = "Recoil";
|
||||
Recoil.value = CM_SMALL_ARGB_MODE_RECOIL;
|
||||
Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Recoil.colors_min = 1;
|
||||
Recoil.colors_max = 1;
|
||||
Recoil.colors.resize(Recoil.colors_max);
|
||||
Recoil.brightness_min = 0;
|
||||
Recoil.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Recoil.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Recoil.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Recoil.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Recoil.color_mode = MODE_COLORS_RANDOM;
|
||||
Recoil.speed = speed;
|
||||
modes.push_back(Recoil);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CM_SMALL_ARGB_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(Breathing.colors_max);
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Breathing.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Breathing.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Breathing.color_mode = MODE_COLORS_RANDOM;
|
||||
Breathing.speed = speed;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Refill;
|
||||
Refill.name = "Refill";
|
||||
Refill.value = CM_SMALL_ARGB_MODE_REFILL;
|
||||
Refill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Refill.colors_min = 1;
|
||||
Refill.colors_max = 1;
|
||||
Refill.colors.resize(Refill.colors_max);
|
||||
Refill.brightness_min = 0;
|
||||
Refill.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Refill.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Refill.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Refill.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Refill.color_mode = MODE_COLORS_RANDOM;
|
||||
Refill.speed = speed;
|
||||
modes.push_back(Refill);
|
||||
|
||||
mode Demo;
|
||||
Demo.name = "Demo";
|
||||
Demo.value = CM_SMALL_ARGB_MODE_DEMO;
|
||||
Demo.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Demo.brightness_min = 0;
|
||||
Demo.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Demo.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Demo.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Demo.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Demo.color_mode = MODE_COLORS_NONE;
|
||||
Demo.speed = speed;
|
||||
modes.push_back(Demo);
|
||||
|
||||
mode Spectrum;
|
||||
Spectrum.name = "Spectrum";
|
||||
Spectrum.value = CM_SMALL_ARGB_MODE_SPECTRUM;
|
||||
Spectrum.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Spectrum.brightness_min = 0;
|
||||
Spectrum.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Spectrum.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Spectrum.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Spectrum.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Spectrum.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum.speed = speed;
|
||||
modes.push_back(Spectrum);
|
||||
|
||||
mode PassThru;
|
||||
PassThru.name = "Pass Thru";
|
||||
PassThru.value = CM_SMALL_ARGB_MODE_PASSTHRU;
|
||||
PassThru.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(PassThru);
|
||||
|
||||
Init_Controller(); //Only processed on first run
|
||||
SetupZones();
|
||||
|
||||
int temp_mode = controller->GetMode();
|
||||
|
||||
for(int mode_idx = 0; mode_idx < (int)modes.size() ; mode_idx++)
|
||||
{
|
||||
if(temp_mode == modes[mode_idx].value)
|
||||
{
|
||||
active_mode = mode_idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (modes[active_mode].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
|
||||
{
|
||||
modes[active_mode].colors[0] = ToRGBColor(controller->GetLedRed(), controller->GetLedGreen(), controller->GetLedBlue());
|
||||
}
|
||||
|
||||
modes[active_mode].color_mode = (controller->GetRandomColours()) ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
|
||||
|
||||
if (modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
modes[active_mode].speed = controller->GetLedSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
RGBController_CMSmallARGBController::~RGBController_CMSmallARGBController()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::Init_Controller()
|
||||
{
|
||||
int zone_idx = controller->GetZoneIndex();
|
||||
int zone_led_count = cm_small_argb_header_data[zone_idx].count;
|
||||
bool boolSingleLED = ( zone_led_count == 1 ); //If argb_header_data[zone_idx].count == 1 then the zone is ZONE_TYPE_SINGLE
|
||||
|
||||
zone ARGB_zone;
|
||||
ARGB_zone.name = std::to_string(zone_idx);
|
||||
ARGB_zone.type = (boolSingleLED) ? ZONE_TYPE_SINGLE : ZONE_TYPE_LINEAR;
|
||||
ARGB_zone.leds_min = CM_SMALL_ARGB_MIN_LEDS;
|
||||
ARGB_zone.leds_max = CM_SMALL_ARGB_MAX_LEDS;
|
||||
ARGB_zone.leds_count = zone_led_count;
|
||||
ARGB_zone.matrix_map = NULL;
|
||||
zones.push_back(ARGB_zone);
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::SetupZones()
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Clear any existing color/LED configuration |
|
||||
\*-------------------------------------------------*/
|
||||
leds.clear();
|
||||
colors.clear();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
bool boolSingleLED = (zones[zone_idx].type == ZONE_TYPE_SINGLE); //Calculated for later use
|
||||
|
||||
if (!boolSingleLED)
|
||||
{
|
||||
controller->SetLedCount(cm_small_argb_header_data[zone_idx].header, zones[zone_idx].leds_count);
|
||||
}
|
||||
|
||||
for(unsigned int lp_idx = 0; lp_idx < zones[zone_idx].leds_count; lp_idx++)
|
||||
{
|
||||
led new_led;
|
||||
unsigned int i = std::stoi(zones[zone_idx].name);
|
||||
|
||||
if(boolSingleLED)
|
||||
{
|
||||
new_led.name = i;
|
||||
new_led.value = cm_small_argb_header_data[i].header;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_led.name = i;
|
||||
new_led.name.append(" LED " + std::to_string(lp_idx));
|
||||
new_led.value = cm_small_argb_header_data[i].header;
|
||||
}
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::ResizeZone(int zone, int new_size)
|
||||
{
|
||||
if((size_t) zone >= zones.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
|
||||
{
|
||||
zones[zone].leds_count = new_size;
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::DeviceUpdateLEDs()
|
||||
{
|
||||
for(int zone_idx = 0; zone_idx < (int)zones.size(); zone_idx++)
|
||||
{
|
||||
UpdateZoneLEDs(zone_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
if(serial >= CM_SMALL_ARGB_FW0012)
|
||||
{
|
||||
controller->SetLedsDirect( zones[zone].colors, zones[zone].leds_count );
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::SetCustomMode()
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| The small ARGB may not support "Direct" mode |
|
||||
| in which case this will select "Pass Thru" |
|
||||
\*-------------------------------------------------*/
|
||||
if(serial >= CM_SMALL_ARGB_FW0012)
|
||||
{
|
||||
active_mode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
active_mode = 7;
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::DeviceUpdateMode()
|
||||
{
|
||||
bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
|
||||
RGBColor colour = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
|
||||
|
||||
controller->SetMode( modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, colour, random_colours);
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CMSmallARGBController.h |
|
||||
| |
|
||||
| RGBController for Cooler Master Small ARGB controller |
|
||||
| |
|
||||
| Chris M (Dr_No) 31 Jan 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "RGBController.h"
|
||||
#include "CMSmallARGBController.h"
|
||||
|
||||
#define CM_SMALL_ARGB_MIN_LEDS 4
|
||||
#define CM_SMALL_ARGB_MAX_LEDS 48
|
||||
#define CM_SMALL_ARGB_BRIGHTNESS_MAX 0xFF
|
||||
#define CM_SMALL_ARGB_FW0012 "A202104052336"
|
||||
|
||||
class RGBController_CMSmallARGBController : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CMSmallARGBController(CMSmallARGBController* controller_ptr);
|
||||
~RGBController_CMSmallARGBController();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void SetCustomMode();
|
||||
void DeviceUpdateMode();
|
||||
private:
|
||||
void Init_Controller();
|
||||
int GetDeviceMode();
|
||||
|
||||
CMSmallARGBController* controller;
|
||||
};
|
||||
@@ -0,0 +1,382 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CoolerMasterControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Cooler Master devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| OpenRGB includes |
|
||||
\*-----------------------------------------------------*/
|
||||
#include <hidapi.h>
|
||||
#include "Detector.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster specific includes |
|
||||
\*-----------------------------------------------------*/
|
||||
#include "RGBController_CMMMController.h"
|
||||
#include "RGBController_CMMM711Controller.h"
|
||||
#include "RGBController_CMMM712Controller.h"
|
||||
#include "RGBController_CMMP750Controller.h"
|
||||
#include "RGBController_CMARGBController.h"
|
||||
#include "RGBController_CMSmallARGBController.h"
|
||||
#include "RGBController_CMARGBGen2A1Controller.h"
|
||||
#include "RGBController_CMRGBController.h"
|
||||
#include "RGBController_CMR6000Controller.h"
|
||||
#include "RGBController_CMMonitorController.h"
|
||||
#include "RGBController_CMGD160Controller.h"
|
||||
#include "RGBController_CMKeyboardController.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster USB vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define COOLERMASTER_VID 0x2516
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster Keyboards |
|
||||
| PIDs defined in `CMMKControllerV2.h` |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster GPUs |
|
||||
| PIDs defined in `CMR6000Controller.h` |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster LEDstrip controllers |
|
||||
\*-----------------------------------------------------*/
|
||||
#define COOLERMASTER_ARGB_PID 0x1011
|
||||
#define COOLERMASTER_ARGB_GEN2_A1_PID 0x0173
|
||||
#define COOLERMASTER_ARGB_GEN2_A1_V2_PID 0x01C9
|
||||
#define COOLERMASTER_ARGB_GEN2_A1_MINI_PID 0x01CB
|
||||
#define COOLERMASTER_SMALL_ARGB_PID 0x1000
|
||||
#define COOLERMASTER_RGB_PID 0x004F
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster Mice |
|
||||
\*-----------------------------------------------------*/
|
||||
#define COOLERMASTER_MM530_PID 0x0065
|
||||
#define COOLERMASTER_MM531_PID 0x0097
|
||||
#define COOLERMASTER_MM711_PID 0x0101
|
||||
#define COOLERMASTER_MM712_PID 0x0169
|
||||
#define COOLERMASTER_MM720_PID 0x0141
|
||||
#define COOLERMASTER_MM730_PID 0x0165
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster Mousemats |
|
||||
\*-----------------------------------------------------*/
|
||||
#define COOLERMASTER_MP750_XL_PID 0x0109
|
||||
#define COOLERMASTER_MP750_L_PID 0x0107
|
||||
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster Monitors |
|
||||
\*-----------------------------------------------------*/
|
||||
#define COOLERMASTER_GM27_FQS_PID 0x01BB
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster Desks |
|
||||
\*-----------------------------------------------------*/
|
||||
#define COOLERMASTER_GD160_PID 0x01A9
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectCoolerMasterControllers *
|
||||
* *
|
||||
* Tests the USB address to see if any CoolerMaster controllers exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCoolerMasterARGB(hid_device_info* info, const std::string&)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMARGBController* controller = new CMARGBController(dev, info->path);
|
||||
|
||||
if(controller->GetVersion() != "Unsupported")
|
||||
{
|
||||
RGBController_CMARGBController* rgb_controller = new RGBController_CMARGBController(controller);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("[CMARGBController] Unsupported firmware version");
|
||||
delete controller;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterARGBGen2A1(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMARGBGen2A1controller* controller = new CMARGBGen2A1controller(dev, *info, name);
|
||||
RGBController_CMARGBGen2A1Controller* rgb_controller = new RGBController_CMARGBGen2A1Controller(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterGPU(hid_device_info* info, const std::string&)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMR6000Controller* controller = new CMR6000Controller(dev, info->path, info->product_id);
|
||||
RGBController_CMR6000Controller* rgb_controller = new RGBController_CMR6000Controller(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterV1Keyboards(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
switch(info->product_id)
|
||||
{
|
||||
case COOLERMASTER_KEYBOARD_PRO_L_PID:
|
||||
case COOLERMASTER_KEYBOARD_PRO_L_WHITE_PID:
|
||||
case COOLERMASTER_KEYBOARD_PRO_S_PID:
|
||||
{
|
||||
CMKeyboardV1Controller* controller = new CMKeyboardV1Controller(dev, info, name);
|
||||
RGBController_CMKeyboardController* rgb_controller = new RGBController_CMKeyboardController(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_DEBUG("[%s] Controller not created as the product ID %04X is missing from detector switch", name.c_str(), info->product_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterV2Keyboards(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
switch(info->product_id)
|
||||
{
|
||||
case COOLERMASTER_KEYBOARD_PRO_L_PID:
|
||||
case COOLERMASTER_KEYBOARD_PRO_L_WHITE_PID:
|
||||
case COOLERMASTER_KEYBOARD_PRO_S_PID:
|
||||
{
|
||||
CMKeyboardV1Controller* controller = new CMKeyboardV1Controller(dev, info, name);
|
||||
RGBController_CMKeyboardController* rgb_controller = new RGBController_CMKeyboardController(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
break;
|
||||
|
||||
case COOLERMASTER_KEYBOARD_SK622B_PID:
|
||||
case COOLERMASTER_KEYBOARD_SK622W_PID:
|
||||
case COOLERMASTER_KEYBOARD_SK630_PID:
|
||||
case COOLERMASTER_KEYBOARD_SK650_PID:
|
||||
case COOLERMASTER_KEYBOARD_SK652_PID:
|
||||
case COOLERMASTER_KEYBOARD_SK653_PID:
|
||||
case COOLERMASTER_KEYBOARD_CK530_PID:
|
||||
case COOLERMASTER_KEYBOARD_CK530_V2_PID:
|
||||
case COOLERMASTER_KEYBOARD_CK550_V2_PID:
|
||||
case COOLERMASTER_KEYBOARD_CK552_V2_PID:
|
||||
case COOLERMASTER_KEYBOARD_MK730_PID:
|
||||
case COOLERMASTER_KEYBOARD_MK750_PID:
|
||||
{
|
||||
CMKeyboardV2Controller* controller = new CMKeyboardV2Controller(dev, info, name);
|
||||
RGBController_CMKeyboardController* rgb_controller = new RGBController_CMKeyboardController(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_DEBUG("[%s] Controller not created as the product ID %04X is missing from detector switch", name.c_str(), info->product_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterMouse(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMMMController* controller = new CMMMController(dev, info->path, info->product_id, name);
|
||||
RGBController_CMMMController* rgb_controller = new RGBController_CMMMController(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterMouse711(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMMM711Controller* controller = new CMMM711Controller(dev, info->path);
|
||||
RGBController_CMMM711Controller* rgb_controller = new RGBController_CMMM711Controller(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterMouse712(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMMM712Controller* controller = new CMMM712Controller(dev, info->path);
|
||||
RGBController_CMMM712Controller* rgb_controller = new RGBController_CMMM712Controller(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterMousemats(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMMP750Controller* controller = new CMMP750Controller(dev, info->path);
|
||||
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterRGB(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMRGBController* controller = new CMRGBController(dev, info->path);
|
||||
RGBController_CMRGBController* rgb_controller = new RGBController_CMRGBController(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterSmallARGB(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMSmallARGBController* controller = new CMSmallARGBController(dev, info->path, 0);
|
||||
RGBController_CMSmallARGBController* rgb_controller = new RGBController_CMSmallARGBController(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterMonitor(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMMonitorController* controller = new CMMonitorController(dev, *info, name);
|
||||
RGBController_CMMonitorController* rgb_controller = new RGBController_CMMonitorController(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectCoolerMasterGD160(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMGD160Controller* controller = new CMGD160Controller(dev, *info, name);
|
||||
RGBController_CMGD160Controller* rgb_controller = new RGBController_CMGD160Controller(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster Keyboards |
|
||||
| PIDs defined in `CMKeyboardDevices.h` |
|
||||
\*-----------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro S", DetectCoolerMasterV1Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_PRO_S_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L", DetectCoolerMasterV1Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_PRO_L_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L White", DetectCoolerMasterV1Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_PRO_L_WHITE_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master MK850", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_MK850_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master SK620 White", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_SK620W_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master SK620 Black", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_SK620B_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master SK622 White", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_SK622W_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master SK622 Black", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_SK622B_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master SK630", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_SK630_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master SK650", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_SK650_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master SK652", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_SK652_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master SK653", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_SK653_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master MK730", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_MK730_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master MK750", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_MK750_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master CK530", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_CK530_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master CK530 V2", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_CK530_V2_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master CK550 V2", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_CK550_V2_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master CK550 V1 / CK552", DetectCoolerMasterV2Keyboards, COOLERMASTER_VID, COOLERMASTER_KEYBOARD_CK552_V2_PID, 1, 0xFF00, 1);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster LEDstrip controllers |
|
||||
\*-----------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB", DetectCoolerMasterARGB, COOLERMASTER_VID, COOLERMASTER_ARGB_PID, 0, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB Gen 2 A1", DetectCoolerMasterARGBGen2A1, COOLERMASTER_VID, COOLERMASTER_ARGB_GEN2_A1_PID, 1, 0xFF01, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB Gen 2 A1 V2", DetectCoolerMasterARGBGen2A1, COOLERMASTER_VID, COOLERMASTER_ARGB_GEN2_A1_V2_PID, 1, 0xFF01, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB Gen 2 A1 Mini", DetectCoolerMasterARGBGen2A1, COOLERMASTER_VID, COOLERMASTER_ARGB_GEN2_A1_MINI_PID, 1, 0xFF01, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master RGB", DetectCoolerMasterRGB, COOLERMASTER_VID, COOLERMASTER_RGB_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master Small ARGB", DetectCoolerMasterSmallARGB, COOLERMASTER_VID, COOLERMASTER_SMALL_ARGB_PID, 0, 0xFF00, 1);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster Mice |
|
||||
\*-----------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master MM530", DetectCoolerMasterMouse, COOLERMASTER_VID, COOLERMASTER_MM530_PID, 1, 0xFF00, 1);
|
||||
//REGISTER_HID_DETECTOR_IPU("Cooler Master MM531", DetectCoolerMasterMouse, COOLERMASTER_VID, COOLERMASTER_MM531_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master MM711", DetectCoolerMasterMouse711, COOLERMASTER_VID, COOLERMASTER_MM711_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master MM712", DetectCoolerMasterMouse712, COOLERMASTER_VID, COOLERMASTER_MM712_PID, 3, 0xFF0A, 2);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master MM720", DetectCoolerMasterMouse, COOLERMASTER_VID, COOLERMASTER_MM720_PID, 1, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master MM730", DetectCoolerMasterMouse, COOLERMASTER_VID, COOLERMASTER_MM730_PID, 1, 0xFF00, 1);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster Mousemats |
|
||||
\*-----------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 XL", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_XL_PID, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Large", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_L_PID, 0xFF00, 1);
|
||||
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_MEDIUM_PID, 0xFF00, 1);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster GPUs |
|
||||
| PIDs defined in `CMR6000Controller.h` |
|
||||
\*-----------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon RX 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1 );
|
||||
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon RX 6900 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6900_PID, 1 );
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster Monitors |
|
||||
\*-----------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master GM27-FQS ARGB Monitor", DetectCoolerMasterMonitor, COOLERMASTER_VID, COOLERMASTER_GM27_FQS_PID, 0, 0xFF00, 1);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Coolermaster Desks |
|
||||
\*-----------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IPU("Cooler Master GD160 ARGB Gaming Desk", DetectCoolerMasterGD160, COOLERMASTER_VID, COOLERMASTER_GD160_PID, 0, 0xFF00, 1);
|
||||
Reference in New Issue
Block a user