Compare commits

...
Author SHA1 Message Date
Adam Honse 0102fc67d2 HyperXAlloyOriginsCore Keyboard: added support for Breathing and Swipe modes
Commits squashed by Adam Honse <[email protected]>
2021-06-26 02:20:30 +00:00
mike 5423fbdcfb fix bug with keyboard layout where HOME, END, PGUP, and PGDN keys were in the wrong position 2021-06-26 02:09:19 +00:00
Kasper 1f80b29ac8 QMK Improvements - make LEDs per update configurable
* Fix Windows include error that breaks std::min/max if a Windows header is included (tracked down to
net_port.h)

Commit amended by Adam Honse <[email protected]>
2021-06-26 01:37:22 +00:00
7 changed files with 253 additions and 42 deletions
@@ -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;
}
}
@@ -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];
};
@@ -108,8 +108,8 @@ static const char *led_names[] =
"Key: =",
"Key: Backspace",
"Key: Insert",
"Key: Page Up",
"Key: Home",
"Key: Page Up",
"Key: I",
@@ -119,8 +119,8 @@ static const char *led_names[] =
"Key: ]",
"Key: \\ (ANSI)",
"Key: Delete",
"Key: Page Down",
"Key: End",
"Key: Page Down",
"Key: K",
@@ -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);
}
}
@@ -59,6 +59,30 @@ static std::map<uint8_t, std::string> QMKKeycodeToKeynameMap
QMKOpenRGBController::QMKOpenRGBController(hid_device *dev_handle, const char *path)
{
/*-------------------------------------------------*\
| Get QMKOpenRGB settings |
\*-------------------------------------------------*/
json qmk_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("QMKOpenRGBDevices");
if(qmk_settings.contains("leds_per_update"))
{
if(qmk_settings["leds_per_update"] > 20)
{
qmk_settings["leds_per_update"] = 20;
}
else if(qmk_settings["leds_per_update"] < 1)
{
qmk_settings["leds_per_update"] = 1;
}
SettingsManager* settings_manager = ResourceManager::get()->GetSettingsManager();
settings_manager->SetSettings("QMKOpenRGBDevices", qmk_settings);
settings_manager->SaveSettings();
leds_per_update = qmk_settings["leds_per_update"];
}
else
{
leds_per_update = 20;
}
dev = dev_handle;
location = path;
@@ -150,7 +174,7 @@ unsigned int QMKOpenRGBController::GetProtocolVersion()
do
{
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_HID_READ_TIMEOUT);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
} while(bytes_read <= 0);
return usb_buf[1];
@@ -204,7 +228,7 @@ void QMKOpenRGBController::GetDeviceInfo()
do
{
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_HID_READ_TIMEOUT);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
} while(bytes_read <= 0);
total_number_of_leds = usb_buf[QMK_OPENRGB_TOTAL_NUMBER_OF_LEDS_BYTE];
@@ -244,7 +268,7 @@ void QMKOpenRGBController::GetModeInfo()
do
{
hid_write(dev, usb_buf, 65);
bytes_read = hid_read_timeout(dev, usb_buf, 65, QMK_HID_READ_TIMEOUT);
bytes_read = hid_read_timeout(dev, usb_buf, 65, QMK_OPENRGB_HID_READ_TIMEOUT);
} while(bytes_read <= 0);
mode = usb_buf[QMK_OPENRGB_MODE_BYTE];
@@ -286,7 +310,7 @@ void QMKOpenRGBController::GetLEDInfo(unsigned int led)
do
{
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_HID_READ_TIMEOUT);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
} while(bytes_read <= 0);
if(usb_buf[62] != QMK_OPENRGB_FAILURE)
@@ -329,7 +353,7 @@ bool QMKOpenRGBController::GetIsModeEnabled(unsigned int mode)
do
{
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_HID_READ_TIMEOUT);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
} while(bytes_read <= 0);
return usb_buf[1] == QMK_OPENRGB_SUCCESS ? true : false;
@@ -359,7 +383,7 @@ void QMKOpenRGBController::SetMode(hsv_t hsv_color, unsigned char mode, unsigned
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read_timeout(dev, usb_buf, 65, QMK_HID_READ_TIMEOUT);
hid_read_timeout(dev, usb_buf, 65, QMK_OPENRGB_HID_READ_TIMEOUT);
}
void QMKOpenRGBController::DirectModeSetSingleLED(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
@@ -386,13 +410,12 @@ void QMKOpenRGBController::DirectModeSetSingleLED(unsigned int led, unsigned cha
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read_timeout(dev, usb_buf, 65, QMK_HID_READ_TIMEOUT);
hid_read_timeout(dev, usb_buf, 65, QMK_OPENRGB_HID_READ_TIMEOUT);
}
void QMKOpenRGBController::DirectModeSetLEDs(std::vector<RGBColor> colors, unsigned int leds_count)
{
unsigned int leds_sent = 0;
unsigned int leds_per_update = 20;
while (leds_sent < leds_count)
{
@@ -9,14 +9,15 @@
#pragma once
#include "ResourceManager.h"
#include "RGBController.h"
#include "hsv.h"
#include <hidapi/hidapi.h>
#include <cstring>
#include <map>
#define QMK_OPENRGB_PACKET_SIZE 65
#define QMK_HID_READ_TIMEOUT 50
#define QMK_OPENRGB_PACKET_SIZE 65
#define QMK_OPENRGB_HID_READ_TIMEOUT 50
enum CommandsId
{
@@ -160,6 +161,8 @@ protected:
hid_device *dev;
private:
unsigned int leds_per_update;
std::string location;
std::string device_name;
@@ -23,11 +23,6 @@ RGBController_QMKOpenRGB::RGBController_QMKOpenRGB(QMKOpenRGBController* control
unsigned int current_mode = 1;
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_OPENRGB_DIRECT))
{
InitializeMode("Direct", current_mode, MODE_FLAG_HAS_PER_LED_COLOR, MODE_COLORS_PER_LED);
}
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_COLOR))
{
InitializeMode("Static", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC);
@@ -233,6 +228,11 @@ RGBController_QMKOpenRGB::RGBController_QMKOpenRGB(QMKOpenRGBController* control
InitializeMode("Solid Reactive Multi Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
}
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_OPENRGB_DIRECT))
{
InitializeMode("Direct", current_mode, MODE_FLAG_HAS_PER_LED_COLOR, MODE_COLORS_PER_LED);
}
active_mode = controller->GetMode() - 1;
SetupZones();
@@ -469,8 +469,14 @@ void RGBController_QMKOpenRGB::InitializeMode
qmk_mode.colors.resize(1);
qmk_mode.colors[0] = controller->GetModeColor();
}
modes.push_back(qmk_mode);
if(flags & MODE_FLAG_HAS_PER_LED_COLOR)
{
modes.insert(modes.begin(), qmk_mode);
}
else
{
modes.push_back(qmk_mode);
}
}
unsigned int RGBController_QMKOpenRGB::CalculateDivisor
@@ -554,7 +560,7 @@ void RGBController_QMKOpenRGB::PlaceLEDsInMaps
VectorMatrix& matrix_map_xl,
VectorMatrix& underglow_map_xl
)
{
{
matrix_map_xl = MakeEmptyMatrixMap(unique_rows.size(), std::round(255/divisor) + 10);
underglow_map_xl = MakeEmptyMatrixMap(unique_rows.size(), std::round(255/divisor) + 10);
+4
View File
@@ -13,6 +13,10 @@
#include <vector>
#ifdef WIN32
/*---------------------------------------------------------*\
| Windows interferes with std::max unless NOMINMAX defined |
\*---------------------------------------------------------*/
#define NOMINMAX
#include <winsock2.h>
#include <ws2tcpip.h>
#else