Files
OpenRGB/Controllers/KingstonFuryDRAMController/RGBController_KingstonFuryDRAM.cpp

748 lines
26 KiB
C++

/*---------------------------------------------------------*\
| RGBController_KingstonFuryDRAM.cpp |
| |
| Driver for Kingston Fury DDR4/5 RAM modules |
| |
| Geofrey Mon (geofbot) 14 Jul 2024 |
| Milan Cermak (krysmanta) |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include "RGBController_KingstonFuryDRAM.h"
#include "KingstonFuryDRAMController.h"
#include "LogManager.h"
const RGBColor default_colors[] =
{
ToRGBColor(0xFF, 0x00, 0x00),
ToRGBColor(0x00, 0xFF, 0x00),
ToRGBColor(0xFF, 0x64, 0x00),
ToRGBColor(0x00, 0x00, 0xFF),
ToRGBColor(0xEF, 0xEF, 0x00),
ToRGBColor(0x80, 0x00, 0x80),
ToRGBColor(0x00, 0x6D, 0x77),
ToRGBColor(0xFF, 0xC8, 0x00),
ToRGBColor(0xFF, 0x55, 0xFF),
ToRGBColor(0x3C, 0x7D, 0xFF),
};
/**------------------------------------------------------------------*\
@name Kingston Fury DDR4/5 DRAM
@category RAM
@type SMBus
@save :x:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectKingstonFuryDRAMControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_KingstonFuryDRAM::RGBController_KingstonFuryDRAM(KingstonFuryDRAMController* controller_ptr)
{
controller = controller_ptr;
name = "Kingston Fury DDR4/5 DRAM";
vendor = "Kingston";
type = DEVICE_TYPE_DRAM;
description = "Kingston Fury Beast/Renegade DDR4/5 DRAM Device";
location = controller->GetDeviceLocation();
mode Direct;
Direct.name = "Direct";
Direct.value = FURY_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.brightness_min = 0;
Direct.brightness_max = 100;
Direct.brightness = 80;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = FURY_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.assign(default_colors, default_colors + 1);
Static.brightness_min = 0;
Static.brightness_max = 100;
Static.brightness = 80;
modes.push_back(Static);
// All speed values are inverted
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = FURY_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED |
MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_UD;
Rainbow.speed_min = 60;
Rainbow.speed_max = 0;
Rainbow.speed = 25;
Rainbow.direction = MODE_DIRECTION_UP;
Rainbow.brightness_min = 0;
Rainbow.brightness_max = 100;
Rainbow.brightness = 80;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
mode Spectrum;
Spectrum.name = "Spectrum";
Spectrum.value = FURY_MODE_SPECTRUM;
Spectrum.flags = MODE_FLAG_HAS_SPEED |
MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_UD;
Spectrum.speed_min = 60;
Spectrum.speed_max = 0;
Spectrum.speed = 25;
Spectrum.direction = MODE_DIRECTION_UP;
Spectrum.brightness_min = 0;
Spectrum.brightness_max = 100;
Spectrum.brightness = 80;
Spectrum.color_mode = MODE_COLORS_NONE;
modes.push_back(Spectrum);
mode Rhythm;
Rhythm.name = "Rhythm";
Rhythm.value = FURY_MODE_RHYTHM;
Rhythm.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Rhythm.color_mode = MODE_COLORS_MODE_SPECIFIC;
Rhythm.colors_min = 2;
Rhythm.colors_max = 11;
Rhythm.colors.assign(default_colors, default_colors + 10);
Rhythm.colors.push_back(FURY_DEFAULT_BG_COLOR);
Rhythm.speed_min = 10;
Rhythm.speed_max = 0;
Rhythm.speed = 0;
Rhythm.brightness_min = 0;
Rhythm.brightness_max = 100;
Rhythm.brightness = 80;
modes.push_back(Rhythm);
mode Breath;
Breath.name = "Breath";
Breath.value = FURY_MODE_BREATH;
Breath.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED |
MODE_FLAG_HAS_BRIGHTNESS;
Breath.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breath.colors_min = 1;
Breath.colors_max = 10;
Breath.colors.assign(default_colors, default_colors + 10);
Breath.speed_min = 10;
Breath.speed_max = 1;
Breath.speed = 5;
Breath.brightness_min = 0;
Breath.brightness_max = 100;
Breath.brightness = 80;
modes.push_back(Breath);
mode Dynamic;
Dynamic.name = "Dynamic";
Dynamic.value = FURY_MODE_DYNAMIC;
Dynamic.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Dynamic.color_mode = MODE_COLORS_MODE_SPECIFIC;
Dynamic.colors_min = 1;
Dynamic.colors_max = 10;
Dynamic.colors.assign(default_colors, default_colors + 10);
Dynamic.speed_min = 1000;
Dynamic.speed_max = 100;
Dynamic.speed = 300;
Dynamic.brightness_min = 0;
Dynamic.brightness_max = 100;
Dynamic.brightness = 80;
modes.push_back(Dynamic);
mode Slide;
Slide.name = "Slide";
Slide.value = FURY_MODE_SLIDE;
Slide.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS |
MODE_FLAG_HAS_DIRECTION_UD;
Slide.color_mode = MODE_COLORS_MODE_SPECIFIC;
Slide.colors_min = 2;
Slide.colors_max = 11;
Slide.colors.assign(default_colors, default_colors + 10);
Slide.colors.push_back(FURY_DEFAULT_BG_COLOR);
Slide.speed_min = 255;
Slide.speed_max = 0;
Slide.speed = 8;
Slide.direction = MODE_DIRECTION_UP;
Slide.brightness_min = 0;
Slide.brightness_max = 100;
Slide.brightness = 80;
modes.push_back(Slide);
mode Slither;
Slither.name = "Slither";
Slither.value = FURY_MODE_SLITHER;
Slither.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Slither.color_mode = MODE_COLORS_MODE_SPECIFIC;
Slither.colors_min = 2;
Slither.colors_max = 11;
Slither.colors.assign(default_colors, default_colors + 10);
Slither.colors.push_back(FURY_DEFAULT_BG_COLOR);
Slither.speed_min = 255;
Slither.speed_max = 0;
Slither.speed = 40;
Slither.brightness_min = 0;
Slither.brightness_max = 100;
Slither.brightness = 80;
modes.push_back(Slither);
mode Teleport;
Teleport.name = "Teleport";
Teleport.value = FURY_MODE_TELEPORT;
Teleport.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Teleport.color_mode = MODE_COLORS_MODE_SPECIFIC;
Teleport.colors_min = 2;
Teleport.colors_max = 11;
Teleport.colors.assign(default_colors, default_colors + 10);
Teleport.colors.push_back(FURY_DEFAULT_BG_COLOR);
Teleport.speed_min = 255;
Teleport.speed_max = 0;
Teleport.speed = 8;
Teleport.brightness_min = 0;
Teleport.brightness_max = 100;
Teleport.brightness = 80;
modes.push_back(Teleport);
mode Wind;
Wind.name = "Wind";
Wind.value = FURY_MODE_WIND;
Wind.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS |
MODE_FLAG_HAS_DIRECTION_UD;
Wind.color_mode = MODE_COLORS_MODE_SPECIFIC;
Wind.colors_min = 2;
Wind.colors_max = 11;
Wind.colors.assign(default_colors, default_colors + 10);
Wind.colors.push_back(FURY_DEFAULT_BG_COLOR);
Wind.speed_min = 255;
Wind.speed_max = 0;
Wind.speed = 8;
Wind.direction = MODE_DIRECTION_UP;
Wind.brightness_min = 0;
Wind.brightness_max = 100;
Wind.brightness = 80;
modes.push_back(Wind);
mode Comet;
Comet.name = "Comet";
Comet.value = FURY_MODE_COMET;
Comet.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS |
MODE_FLAG_HAS_DIRECTION_UD;
Comet.color_mode = MODE_COLORS_MODE_SPECIFIC;
Comet.colors_min = 1;
Comet.colors_max = 10;
Comet.colors.assign(default_colors, default_colors + 10);
Comet.speed_min = 255;
Comet.speed_max = 0;
Comet.speed = 25;
Comet.direction = MODE_DIRECTION_UP;
Comet.brightness_min = 0;
Comet.brightness_max = 100;
Comet.brightness = 80;
modes.push_back(Comet);
mode Rain;
Rain.name = "Rain";
Rain.value = FURY_MODE_RAIN;
Rain.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS |
MODE_FLAG_HAS_DIRECTION_UD;
Rain.color_mode = MODE_COLORS_MODE_SPECIFIC;
Rain.colors_min = 1;
Rain.colors_max = 10;
Rain.colors.assign(default_colors, default_colors + 10);
Rain.speed_min = 28;
Rain.speed_max = 8;
Rain.speed = 25;
Rain.direction = MODE_DIRECTION_DOWN;
Rain.brightness_min = 0;
Rain.brightness_max = 100;
Rain.brightness = 80;
modes.push_back(Rain);
mode Firework;
Firework.name = "Firework";
Firework.value = FURY_MODE_FIREWORK;
Firework.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS |
MODE_FLAG_HAS_DIRECTION_UD;
Firework.color_mode = MODE_COLORS_MODE_SPECIFIC;
Firework.colors_min = 1;
Firework.colors_max = 10;
Firework.colors.assign(default_colors, default_colors + 10);
Firework.speed_min = 83;
Firework.speed_max = 33;
Firework.speed = 33;
Firework.direction = MODE_DIRECTION_UP;
Firework.brightness_min = 0;
Firework.brightness_max = 100;
Firework.brightness = 80;
modes.push_back(Firework);
mode Voltage;
Voltage.name = "Voltage";
Voltage.value = FURY_MODE_VOLTAGE;
Voltage.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS |
MODE_FLAG_HAS_DIRECTION_UD;
Voltage.color_mode = MODE_COLORS_MODE_SPECIFIC;
Voltage.colors_min = 2;
Voltage.colors_max = 11;
Voltage.colors.assign(default_colors, default_colors + 10);
Voltage.colors.push_back(FURY_DEFAULT_BG_COLOR);
Voltage.speed_min = 18;
Voltage.speed_max = 5;
Voltage.speed = 16;
Voltage.direction = MODE_DIRECTION_UP;
Voltage.brightness_min = 0;
Voltage.brightness_max = 100;
Voltage.brightness = 80;
modes.push_back(Voltage);
#ifdef FURY_SYNC
mode Countdown;
Countdown.name = "Countdown";
Countdown.value = FURY_MODE_COUNTDOWN;
Countdown.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS |
MODE_FLAG_HAS_DIRECTION_UD;
Countdown.color_mode = MODE_COLORS_MODE_SPECIFIC;
Countdown.colors_min = 2;
Countdown.colors_max = 11;
Countdown.colors.assign(default_colors, default_colors + 10);
Countdown.colors.push_back(FURY_DEFAULT_BG_COLOR);
Countdown.speed_min = 76;
Countdown.speed_max = 20;
Countdown.speed = 76;
Countdown.direction = MODE_DIRECTION_UP;
Countdown.brightness_min = 0;
Countdown.brightness_max = 100;
Countdown.brightness = 80;
modes.push_back(Countdown);
#endif
mode Flame;
Flame.name = "Flame";
Flame.value = FURY_MODE_FLAME;
Flame.flags = MODE_FLAG_HAS_SPEED |
MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_UD;
Flame.speed_min = 64;
Flame.speed_max = 40;
Flame.speed = 64;
Flame.direction = MODE_DIRECTION_UP;
Flame.brightness_min = 0;
Flame.brightness_max = 100;
Flame.brightness = 80;
Flame.color_mode = MODE_COLORS_NONE;
modes.push_back(Flame);
mode Twilight;
Twilight.name = "Twilight";
Twilight.value = FURY_MODE_TWILIGHT;
Twilight.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Twilight.speed_min = 255;
Twilight.speed_max = 0;
Twilight.speed = 64;
Twilight.brightness_min = 0;
Twilight.brightness_max = 100;
Twilight.brightness = 80;
Twilight.color_mode = MODE_COLORS_NONE;
modes.push_back(Twilight);
mode Fury;
Fury.name = "Fury";
Fury.value = FURY_MODE_FURY;
Fury.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR |
MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS |
MODE_FLAG_HAS_DIRECTION_UD;
Fury.color_mode = MODE_COLORS_MODE_SPECIFIC;
Fury.colors_min = 2;
Fury.colors_max = 11;
Fury.colors.assign(default_colors, default_colors + 10);
Fury.colors.push_back(FURY_DEFAULT_BG_COLOR);
Fury.speed_min = 255;
Fury.speed_max = 0;
Fury.speed = 76;
Fury.direction = MODE_DIRECTION_UP;
Fury.brightness_min = 0;
Fury.brightness_max = 100;
Fury.brightness = 80;
modes.push_back(Fury);
mode Prism;
Prism.name = "Prism";
Prism.value = FURY_MODE_PRISM;
Prism.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Prism.speed_min = 60;
Prism.speed_max = 0;
Prism.speed = 40;
Prism.brightness_min = 0;
Prism.brightness_max = 100;
Prism.brightness = 80;
Prism.color_mode = MODE_COLORS_NONE;
modes.push_back(Prism);
SetupZones();
// default per-LED color is red
colors.assign(colors.size(), default_colors[0]);
}
RGBController_KingstonFuryDRAM::~RGBController_KingstonFuryDRAM()
{
delete controller;
}
void RGBController_KingstonFuryDRAM::SetupZones()
{
for(unsigned int slot = 0; slot < controller->GetSlotCount(); slot++)
{
zone* new_zone = new zone;
new_zone->name = "Fury Slot ";
new_zone->name.append(std::to_string(slot + 1));
new_zone->type = ZONE_TYPE_LINEAR;
new_zone->leds_min = controller->GetLEDPerDIMM();
new_zone->leds_max = new_zone->leds_min;
new_zone->leds_count = new_zone->leds_min;
new_zone->matrix_map = NULL;
zones.push_back(*new_zone);
}
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
for(std::size_t led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++)
{
led* new_led = new led();
new_led->name = "Fury Slot ";
new_led->name.append(std::to_string(zone_idx + 1));
new_led->name.append(", LED ");
new_led->name.append(std::to_string(led_idx + 1));
new_led->value = (unsigned int)leds.size();
leds.push_back(*new_led);
}
}
SetupColors();
}
void RGBController_KingstonFuryDRAM::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
LOG_DEBUG("[%s] resize zone",
FURY_CONTROLLER_NAME);
}
// some modes have different actual values to be written, depending on the color mode
unsigned char RGBController_KingstonFuryDRAM::GetRealModeValue()
{
int mode_value = modes[active_mode].value;
switch(mode_value)
{
case FURY_MODE_BREATH:
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
return FURY_MODE_BREATH;
}
else
{
return FURY_MODE_BREATH_DIRECT;
}
}
return mode_value;
}
void RGBController_KingstonFuryDRAM::DeviceUpdateLEDs()
{
controller->SendBegin();
controller->SetMode(GetRealModeValue());
// Fixed mode specific parameters
switch(modes[active_mode].value)
{
case FURY_MODE_STATIC:
controller->SetRegister(FURY_REG_DIRECTION, FURY_DIR_BOTTOM_TO_TOP);
controller->SetRegister(FURY_REG_DELAY, 0);
controller->SetRegister(FURY_REG_SPEED, 0);
break;
case FURY_MODE_RAINBOW:
case FURY_MODE_VOLTAGE:
case FURY_MODE_COUNTDOWN:
case FURY_MODE_FLAME:
case FURY_MODE_TWILIGHT:
case FURY_MODE_FURY:
controller->SetRegister(FURY_REG_DELAY, 0);
break;
case FURY_MODE_RHYTHM:
controller->SetRegister(FURY_REG_DIRECTION,
FURY_DIR_BOTTOM_TO_TOP);
break;
case FURY_MODE_BREATH:
controller->SetRegister(FURY_REG_DIRECTION,
FURY_DIR_BOTTOM_TO_TOP);
controller->SetRegister(FURY_REG_DELAY, 0);
break;
case FURY_MODE_DYNAMIC:
controller->SetRegister(FURY_REG_DIRECTION,
FURY_DIR_BOTTOM_TO_TOP);
controller->SetRegister(FURY_REG_DELAY, 0);
break;
case FURY_MODE_SLITHER:
controller->SetRegister(FURY_REG_DELAY, 12);
controller->SetRegister(FURY_REG_DIRECTION,
FURY_ALT_DIRECTIONS);
break;
case FURY_MODE_TELEPORT:
controller->SetRegister(FURY_REG_DELAY, 0);
controller->SetRegister(FURY_REG_DIRECTION,
FURY_ALT_DIRECTIONS);
break;
case FURY_MODE_RAIN:
controller->SetRegister(FURY_REG_DELAY, 0);
controller->SetRegister(FURY_REG_LENGTH, 3);
break;
case FURY_MODE_FIREWORK:
controller->SetRegister(FURY_REG_DELAY, 0);
controller->SetRegister(FURY_REG_LENGTH, 7);
break;
}
// Mode-specific parameters that are customizable in Kingston's software
// but which are not yet available in the OpenRGB interface.
// Default values are used here and the parameter ranges are annotated
switch(modes[active_mode].value)
{
case FURY_MODE_RHYTHM:
// between 2 and 5
controller->SetRegister(FURY_REG_DELAY, 3);
break;
case FURY_MODE_SLIDE:
// between 1 and 4
controller->SetRegister(FURY_REG_DELAY, 3);
// between 1 and 12
controller->SetRegister(FURY_REG_LENGTH, 4);
break;
case FURY_MODE_SLITHER:
// between 1 and 32
controller->SetRegister(FURY_REG_LENGTH, 12);
break;
case FURY_MODE_TELEPORT:
// between 1 and 12
controller->SetRegister(FURY_REG_LENGTH, 3);
break;
case FURY_MODE_WIND:
// between 0 and 32
controller->SetRegister(FURY_REG_DELAY, 0);
// between 1 and 32
controller->SetRegister(FURY_REG_LENGTH, 12);
break;
case FURY_MODE_COMET:
// between 0 and 20
controller->SetRegister(FURY_REG_DELAY, 0);
// between 1 and 18
controller->SetRegister(FURY_REG_LENGTH, 7);
break;
case FURY_MODE_PRISM:
// between 2 and 4
controller->SetRegister(FURY_REG_DELAY, 2);
break;
case FURY_MODE_SPECTRUM:
// between 2 and 6
controller->SetRegister(FURY_REG_DELAY, 4);
break;
}
switch(modes[active_mode].color_mode)
{
case MODE_COLORS_PER_LED:
controller->SetLEDColors(colors);
break;
case MODE_COLORS_MODE_SPECIFIC:
switch(modes[active_mode].value)
{
case FURY_MODE_RHYTHM:
case FURY_MODE_SLIDE:
case FURY_MODE_SLITHER:
case FURY_MODE_TELEPORT:
case FURY_MODE_WIND:
case FURY_MODE_VOLTAGE:
case FURY_MODE_COUNTDOWN:
case FURY_MODE_FURY:
{
std::vector<RGBColor> mode_colors(modes[active_mode].colors.begin(),
modes[active_mode].colors.end() - 1);
controller->SetModeColors(mode_colors);
// handle background color
RGBColor color = modes[active_mode].colors[mode_colors.size()];
unsigned char red = RGBGetRValue(color);
unsigned char green = RGBGetGValue(color);
unsigned char blue = RGBGetBValue(color);
controller->SetRegister(FURY_REG_BG_RED, red);
controller->SetRegister(FURY_REG_BG_GREEN, green);
controller->SetRegister(FURY_REG_BG_BLUE, blue);
break;
}
default:
controller->SetModeColors(modes[active_mode].colors);
break;
}
break;
}
if(modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_UD)
{
if(modes[active_mode].direction == MODE_DIRECTION_UP)
{
controller->SetRegister(FURY_REG_DIRECTION,
FURY_DIR_BOTTOM_TO_TOP);
}
else
{
controller->SetRegister(FURY_REG_DIRECTION,
FURY_DIR_TOP_TO_BOTTOM);
}
}
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
switch(modes[active_mode].value)
{
case FURY_MODE_DYNAMIC:
controller->SetRegister(FURY_REG_SPEED, 0);
// time spent holding a color
controller->SetRegister(FURY_REG_DYNAMIC_HOLD_A,
modes[active_mode].speed >> 8);
// set to 1 as long as the time above is nonzero
controller->SetRegister(FURY_REG_DYNAMIC_HOLD_B, 1);
// time spent fading to next color
controller->SetRegister(FURY_REG_DYNAMIC_FADE_A,
(modes[active_mode].speed * 5) >> 8);
// set to 1 as long as the time above is nonzero
controller->SetRegister(FURY_REG_DYNAMIC_FADE_B, 1);
break;
case FURY_MODE_BREATH:
controller->SetRegister(FURY_REG_SPEED, 0);
// These are the speed values used by Kingston's software,
// representing the time spent fading between two brightness levels
controller->SetRegister(FURY_REG_BREATH_MIN_TO_MID,
modes[active_mode].speed * 3);
controller->SetRegister(FURY_REG_BREATH_MID_TO_MAX,
modes[active_mode].speed);
controller->SetRegister(FURY_REG_BREATH_MAX_TO_MID,
modes[active_mode].speed);
controller->SetRegister(FURY_REG_BREATH_MID_TO_MIN,
modes[active_mode].speed * 3);
// Time spent holding min brightness
controller->SetRegister(FURY_REG_BREATH_MIN_HOLD, 1);
// Brightness values (relative to overall brightness)
controller->SetRegister(FURY_REG_BREATH_MAX_BRIGHTNESS, 100);
controller->SetRegister(FURY_REG_BREATH_MID_BRIGHTNESS, 64);
controller->SetRegister(FURY_REG_BREATH_MIN_BRIGHTNESS, 0);
// Kingston software uses 1 for min brightness,
// but 0 seems to look better.
break;
case FURY_MODE_RAIN:
{
// speed offsets taken from Kingston software
unsigned char offsets[4] = {11, 0, 15, 9};
std::vector<unsigned char> speeds;
for (std::size_t idx = 0; idx < controller->GetSlotCount(); idx++)
{
speeds.push_back(modes[active_mode].speed + offsets[idx % 4]);
}
controller->SetRegister(FURY_REG_SPEED, speeds);
break;
}
case FURY_MODE_FIREWORK:
{
// speed offsets taken from Kingston software
unsigned char offsets[4] = {15, 0, 19, 4};
std::vector<unsigned char> speeds;
for (std::size_t idx = 0; idx < controller->GetSlotCount(); idx++)
{
speeds.push_back(modes[active_mode].speed + offsets[idx % 4]);
}
controller->SetRegister(FURY_REG_SPEED, speeds);
break;
}
default:
controller->SetRegister(FURY_REG_SPEED, modes[active_mode].speed);
break;
}
}
controller->SetRegister(FURY_REG_BRIGHTNESS,
modes[active_mode].brightness);
controller->SetNumSlots();
controller->SendApply();
}
void RGBController_KingstonFuryDRAM::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_KingstonFuryDRAM::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_KingstonFuryDRAM::DeviceUpdateMode()
{
LOG_DEBUG("[%s] device update mode",
FURY_CONTROLLER_NAME);
// Preamble only necessary when changing modes.
if(GetRealModeValue() != controller->GetMode())
{
controller->SendPreamble(modes[active_mode].value != FURY_MODE_RAIN &&
modes[active_mode].value != FURY_MODE_FIREWORK &&
modes[active_mode].value != FURY_MODE_DIRECT);
}
DeviceUpdateLEDs();
}