HyperXAlloyOriginsCore Keyboard: added support for Breathing and Swipe modes

Commits squashed by Adam Honse <calcprogrammer1@gmail.com>
This commit is contained in:
Adam Honse
2021-06-26 02:20:30 +00:00
parent 5423fbdcfb
commit 0102fc67d2
3 changed files with 197 additions and 22 deletions

View File

@@ -9,7 +9,6 @@
\*------------------------------------------*/
#include "HyperXAlloyOriginsCoreController.h"
#include <cstring>
// Skip these indices in the color output
@@ -30,6 +29,17 @@ HyperXAlloyOriginsCoreController::HyperXAlloyOriginsCoreController(hid_device* d
sprintf(fw_version_buf, "%.2X.%.2X", (version & 0xFF00) >> 8, version & 0x00FF);
firmware_version = fw_version_buf;
isDimming = false;
cur_color = color0 = color1 = 0;
memset(&hsv, 0, sizeof(hsv_t));
column = speed = direction = 0;
brightness_lower_bound = brightness_upper_bound = 0;
for (int i=0; i<87; i++)
colors_.push_back(0);
memset(buf, 0x00, sizeof(buf));
color_end = false;
iteration = 0;
data = nullptr;
}
HyperXAlloyOriginsCoreController::~HyperXAlloyOriginsCoreController()
@@ -63,15 +73,77 @@ std::string HyperXAlloyOriginsCoreController::GetFirmwareVersion()
return(firmware_version);
}
void HyperXAlloyOriginsCoreController::SetLEDsDirect(std::vector<RGBColor> colors)
void HyperXAlloyOriginsCoreController::SetLEDs(std::vector<RGBColor> colors, unsigned char mode)
{
if (mode == HYPERX_AOC_MODE_SWIPE)
{
if (iteration < (HYPERX_AOC_SPEED_MAX - speed))
{
iteration++;
return;
}
if (direction == MODE_DIRECTION_LEFT)
{
if (column == 19)
{
column = 0;
color_end = !color_end;
}
}
else
{
if (column < 0)
{
column = 18;
color_end = !color_end;
}
}
cur_color = color_end ? color1 : color0;
unsigned int index;
for (int i=0; i<6; i++)
{
index = data[i][column];
if (index != 0xFFFFFFFF)
colors_[index] = cur_color;
}
direction == MODE_DIRECTION_LEFT ? column++ : column--;
colors = colors_;
iteration = 0;
}
else
{
memset(buf, 0x00, sizeof(buf));
}
for(unsigned int skip_cnt = 0; skip_cnt < (sizeof(skip_idx) / sizeof(skip_idx[0])); skip_cnt++)
{
colors.insert(colors.begin() + skip_idx[skip_cnt], 0x00000000);
}
unsigned char buf[380];
memset(buf, 0x00, sizeof(buf));
if (mode == HYPERX_AOC_MODE_BREATHING)
{
if (isDimming)
{
hsv.value -= (4 * speed);
if (hsv.value <= brightness_lower_bound)
{
hsv.value = 1;
isDimming = false;
}
}
else
{
hsv.value += (4 * speed);
if (hsv.value >= brightness_upper_bound)
{
hsv.value = 255;
isDimming = true;
}
}
color0 = hsv2rgb(&hsv);
}
int offset = 0;
int rowPos = 0;
@@ -84,9 +156,19 @@ void HyperXAlloyOriginsCoreController::SetLEDsDirect(std::vector<RGBColor> color
rowPos = 0;
}
buf[rowPos + offset] = RGBGetGValue(colors[color_idx]);
buf[rowPos + offset + 16] = RGBGetRValue(colors[color_idx]);
buf[rowPos + offset + 32] = RGBGetBValue(colors[color_idx]);
if (mode == HYPERX_AOC_MODE_BREATHING)
{
buf[rowPos + offset] = RGBGetGValue(color0);
buf[rowPos + offset + 16] = RGBGetRValue(color0);
buf[rowPos + offset + 32] = RGBGetBValue(color0);
}
else
{
buf[rowPos + offset] = RGBGetGValue(colors[color_idx]);
buf[rowPos + offset + 16] = RGBGetRValue(colors[color_idx]);
buf[rowPos + offset + 32] = RGBGetBValue(colors[color_idx]);
}
rowPos++;
}
@@ -116,3 +198,30 @@ void HyperXAlloyOriginsCoreController::SetLEDsDirect(std::vector<RGBColor> color
sentBytes += payloadSize;
}
}
void HyperXAlloyOriginsCoreController::SetMode(unsigned char mode_value, unsigned char direction, unsigned char speed, std::vector<RGBColor> colors, matrix_map_type* matrix_map)
{
memset(buf, 0, sizeof(buf));
switch (mode_value)
{
case HYPERX_AOC_MODE_DIRECT:
break;
case HYPERX_AOC_MODE_BREATHING:
color0 = colors[0];
rgb2hsv(color0, &hsv);
this->speed = speed;
brightness_lower_bound = 255 % (4 * speed);
brightness_upper_bound = 255 - brightness_lower_bound;
break;
case HYPERX_AOC_MODE_SWIPE:
this->speed = speed;
color0 = colors[0];
cur_color = color0;
color1 = colors[1];
this->direction = direction;
column = 0;
data = (unsigned int (*)[19])matrix_map->map;
break;
}
}

View File

@@ -9,12 +9,26 @@
\*------------------------------------------*/
#include "RGBController.h"
#include "hsv.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
HYPERX_AOC_MODE_DIRECT = 0x00,
HYPERX_AOC_MODE_BREATHING = 0x01,
HYPERX_AOC_MODE_SWIPE = 0x02,
};
enum
{
HYPERX_AOC_SPEED_MIN = 0x01,
HYPERX_AOC_SPEED_MAX = 0x07,
};
class HyperXAlloyOriginsCoreController
{
public:
@@ -25,10 +39,27 @@ public:
std::string GetSerialString();
std::string GetFirmwareVersion();
void SetLEDsDirect(std::vector<RGBColor> colors);
void SetLEDs(std::vector<RGBColor> colors, unsigned char mode);
void SetMode(unsigned char mode_value, unsigned char direction, unsigned char speed,
std::vector<RGBColor> colors, matrix_map_type* matrix_map);
private:
hid_device* dev;
std::string location;
std::string firmware_version;
hid_device* dev;
std::string location;
std::string firmware_version;
RGBColor color0;
RGBColor color1;
RGBColor cur_color;
hsv_t hsv;
bool isDimming;
int column;
unsigned char speed;
unsigned char direction;
unsigned char brightness_upper_bound;
unsigned char brightness_lower_bound;
std::vector<RGBColor> colors_;
bool color_end;
int iteration;
unsigned int(*data)[19];
unsigned char buf[380];
};

View File

@@ -159,18 +159,45 @@ RGBController_HyperXAlloyOriginsCore::RGBController_HyperXAlloyOriginsCore(Hyper
mode Direct;
Direct.name = "Direct";
Direct.value = 0xFFFF;
Direct.value = HYPERX_AOC_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = HYPERX_AOC_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.speed_min = HYPERX_AOC_SPEED_MIN;
Breathing.speed_max = HYPERX_AOC_SPEED_MAX;
Breathing.speed = 3;
Breathing.colors.resize(1);
modes.push_back(Breathing);
mode Swipe;
Swipe.name = "Swipe";
Swipe.value = HYPERX_AOC_MODE_SWIPE;
Swipe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_DIRECTION_LR;
Swipe.colors_min = 1;
Swipe.colors_max = 2;
Swipe.color_mode = MODE_COLORS_MODE_SPECIFIC;
Swipe.speed_min = HYPERX_AOC_SPEED_MIN;
Swipe.speed_max = HYPERX_AOC_SPEED_MAX;
Swipe.speed = 3;
Swipe.direction = MODE_DIRECTION_LEFT;
Swipe.colors.resize(2);
modes.push_back(Swipe);
SetupZones();
/*-----------------------------------------------------*\
| The HyperX Origins Core requires a packet within few |
| seconds of sending the lighting change in order to |
| not revert back into current profile. Start a thread |
| to continuously send color values each 10ms |
| to continuously send color values every 25ms |
\*-----------------------------------------------------*/
keepalive_thread_run = 1;
keepalive_thread = new std::thread(&RGBController_HyperXAlloyOriginsCore::KeepaliveThread, this);
@@ -244,7 +271,8 @@ void RGBController_HyperXAlloyOriginsCore::ResizeZone(int /*zone*/, int /*new_si
void RGBController_HyperXAlloyOriginsCore::DeviceUpdateLEDs()
{
hyperx->SetLEDsDirect(colors);
last_update_time = std::chrono::steady_clock::now();
hyperx->SetLEDs(colors, modes[active_mode].value);
}
void RGBController_HyperXAlloyOriginsCore::UpdateZoneLEDs(int /*zone*/)
@@ -259,25 +287,32 @@ void RGBController_HyperXAlloyOriginsCore::UpdateSingleLED(int /*led*/)
void RGBController_HyperXAlloyOriginsCore::SetCustomMode()
{
active_mode = 0;
}
void RGBController_HyperXAlloyOriginsCore::DeviceUpdateMode()
{
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
hyperx->SetMode(modes[active_mode].value, modes[active_mode].direction,
modes[active_mode].speed, modes[active_mode].colors, zones[0].matrix_map);
}
else
{
std::vector<RGBColor> temp_colors;
hyperx->SetMode(modes[active_mode].value, modes[active_mode].direction, modes[active_mode].speed,
temp_colors, zones[0].matrix_map);
}
}
void RGBController_HyperXAlloyOriginsCore::KeepaliveThread()
{
while(keepalive_thread_run.load())
{
if(active_mode == 0)
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50))
{
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50))
{
DeviceUpdateLEDs();
}
DeviceUpdateLEDs();
}
std::this_thread::sleep_for(10ms);
std::this_thread::sleep_for(25ms);
}
}