mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-24 07:47:49 -05:00
286 lines
12 KiB
C++
286 lines
12 KiB
C++
/*---------------------------------------------------------*\
|
|
| RGBController_Alienware.cpp |
|
|
| |
|
|
| RGBController for Dell Alienware RGB USB controller |
|
|
| |
|
|
| Gabriel Marcano (gemarcano) 19 Apr 2021 |
|
|
| |
|
|
| This file is part of the OpenRGB project |
|
|
| SPDX-License-Identifier: GPL-2.0-only |
|
|
\*---------------------------------------------------------*/
|
|
|
|
#include <thread>
|
|
#include <chrono>
|
|
#include "RGBController_Alienware.h"
|
|
|
|
/**------------------------------------------------------------------*\
|
|
@name Alienware
|
|
@category Keyboard
|
|
@type USB
|
|
@save :x:
|
|
@direct :x:
|
|
@effects :white_check_mark:
|
|
@detectors DetectAlienwareControllers
|
|
@comment
|
|
\*-------------------------------------------------------------------*/
|
|
|
|
RGBController_Alienware::RGBController_Alienware(AlienwareController* controller_ptr)
|
|
{
|
|
controller = controller_ptr;
|
|
|
|
name = controller->GetDeviceName();
|
|
vendor = "Alienware";
|
|
type = DEVICE_TYPE_KEYBOARD;
|
|
description = "Alienware USB Device";
|
|
location = controller->GetDeviceLocation();
|
|
serial = controller->GetSerialString();
|
|
version = controller->GetFirmwareVersion();
|
|
|
|
mode Color;
|
|
Color.name = "Static";
|
|
Color.value = ALIENWARE_MODE_COLOR;
|
|
Color.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
|
Color.color_mode = MODE_COLORS_PER_LED;
|
|
Color.colors_min = 1;
|
|
Color.colors_max = 1;
|
|
Color.brightness_min = 100;
|
|
Color.brightness_max = 0;
|
|
Color.brightness = 0;
|
|
modes.push_back(Color);
|
|
|
|
mode Pulse;
|
|
Pulse.name = "Flashing";
|
|
Pulse.value = ALIENWARE_MODE_PULSE;
|
|
Pulse.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
|
Pulse.color_mode = MODE_COLORS_PER_LED;
|
|
Pulse.colors_min = 1;
|
|
Pulse.colors_max = 1;
|
|
Pulse.speed_min = ALIENWARE_TEMPO_MIN;
|
|
Pulse.speed_max = ALIENWARE_TEMPO_MAX;
|
|
Pulse.speed = ALIENWARE_TEMPO_MIN;
|
|
Pulse.brightness_min = 100;
|
|
Pulse.brightness_max = 0;
|
|
Pulse.brightness = 0;
|
|
modes.push_back(Pulse);
|
|
|
|
mode Morph;
|
|
Morph.name = "Morph";
|
|
Morph.value = ALIENWARE_MODE_MORPH;
|
|
Morph.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
|
Morph.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
|
Morph.colors_min = 2 * controller->GetZoneCount();
|
|
Morph.colors_max = Morph.colors_min;
|
|
Morph.colors.resize(Morph.colors_max);
|
|
Morph.speed_min = ALIENWARE_TEMPO_MIN;
|
|
Morph.speed_max = ALIENWARE_TEMPO_MAX;
|
|
Morph.speed = ALIENWARE_TEMPO_MIN;
|
|
Morph.brightness_min = 100;
|
|
Morph.brightness_max = 0;
|
|
Morph.brightness = 0;
|
|
modes.push_back(Morph);
|
|
|
|
mode Spectrum;
|
|
Spectrum.name = "Spectrum Cycle";
|
|
Spectrum.value = ALIENWARE_MODE_SPECTRUM;
|
|
Spectrum.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
|
Spectrum.color_mode = MODE_COLORS_NONE;
|
|
Spectrum.speed_min = ALIENWARE_TEMPO_SPECTRUM;
|
|
Spectrum.speed_max = ALIENWARE_TEMPO_MAX;
|
|
Spectrum.speed = ALIENWARE_TEMPO_SPECTRUM;
|
|
Spectrum.brightness_min = 100;
|
|
Spectrum.brightness_max = 0;
|
|
Spectrum.brightness = 0;
|
|
modes.push_back(Spectrum);
|
|
|
|
mode Rainbow;
|
|
Rainbow.name = "Rainbow Wave";
|
|
Rainbow.value = ALIENWARE_MODE_RAINBOW;
|
|
Rainbow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
|
Rainbow.color_mode = MODE_COLORS_NONE;
|
|
Rainbow.speed_min = ALIENWARE_TEMPO_SPECTRUM;
|
|
Rainbow.speed_max = ALIENWARE_TEMPO_MAX;
|
|
Rainbow.speed = ALIENWARE_TEMPO_SPECTRUM;
|
|
Rainbow.brightness_min = 100;
|
|
Rainbow.brightness_max = 0;
|
|
Rainbow.brightness = 0;
|
|
modes.push_back(Rainbow);
|
|
|
|
mode Breathing;
|
|
Breathing.name = "Breathing";
|
|
Breathing.value = ALIENWARE_MODE_BREATHING;
|
|
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
|
Breathing.color_mode = MODE_COLORS_PER_LED;
|
|
Breathing.colors_min = 1;
|
|
Breathing.colors_max = 1;
|
|
Breathing.speed_min = ALIENWARE_TEMPO_MIN;
|
|
Breathing.speed_max = ALIENWARE_TEMPO_MAX;
|
|
Breathing.speed = ALIENWARE_TEMPO_MIN;
|
|
Breathing.brightness_min = 100;
|
|
Breathing.brightness_max = 0;
|
|
Breathing.brightness = 0;
|
|
modes.push_back(Breathing);
|
|
|
|
SetupZones();
|
|
|
|
controller->UpdateDim();
|
|
}
|
|
|
|
void RGBController_Alienware::SetupZones()
|
|
{
|
|
/*-------------------------------------------------*\
|
|
| Set zones and leds |
|
|
\*-------------------------------------------------*/
|
|
std::vector<const char*> zone_names = controller->GetZoneNames();
|
|
|
|
for(unsigned int zone_idx = 0; zone_idx < controller->GetZoneCount(); zone_idx++)
|
|
{
|
|
zone new_zone;
|
|
|
|
new_zone.name = zone_names[zone_idx];
|
|
new_zone.type = ZONE_TYPE_SINGLE;
|
|
new_zone.leds_min = 1;
|
|
new_zone.leds_max = 1;
|
|
new_zone.leds_count = 1;
|
|
new_zone.matrix_map = nullptr;
|
|
|
|
zones.emplace_back(new_zone);
|
|
}
|
|
|
|
for(unsigned int led_idx = 0; led_idx < zones.size(); led_idx++)
|
|
{
|
|
led new_led;
|
|
|
|
new_led.name = zones[led_idx].name + std::string(" LED");
|
|
|
|
leds.emplace_back(new_led);
|
|
}
|
|
|
|
SetupColors();
|
|
}
|
|
|
|
void RGBController_Alienware::ResizeZone(int /*zone*/, int /*new_size*/)
|
|
{
|
|
/*---------------------------------------------------------*\
|
|
| This device does not support resizing zones |
|
|
\*---------------------------------------------------------*/
|
|
}
|
|
|
|
void RGBController_Alienware::DeviceUpdateLEDs()
|
|
{
|
|
DeviceUpdateMode();
|
|
}
|
|
|
|
void RGBController_Alienware::UpdateZoneLEDs(int /*zone*/)
|
|
{
|
|
DeviceUpdateLEDs();
|
|
}
|
|
|
|
void RGBController_Alienware::UpdateSingleLED(int led)
|
|
{
|
|
UpdateZoneLEDs(led);
|
|
}
|
|
|
|
static bool modes_eq(const mode& mode1, const mode& mode2)
|
|
{
|
|
return( ( mode1.name == mode2.name )
|
|
&& ( mode1.value == mode2.value )
|
|
&& ( mode1.flags == mode2.flags )
|
|
&& ( mode1.speed_min == mode2.speed_min )
|
|
&& ( mode1.speed_max == mode2.speed_max )
|
|
&& ( mode1.colors_min == mode2.colors_min )
|
|
&& ( mode1.colors_max == mode2.colors_max )
|
|
&& ( mode1.speed == mode2.speed )
|
|
&& ( mode1.direction == mode2.direction )
|
|
&& ( mode1.color_mode == mode2.color_mode )
|
|
&& ( mode1.colors == mode2.colors )
|
|
&& ( mode1.brightness == mode2.brightness )
|
|
&& ( mode1.brightness_min == mode2.brightness_min )
|
|
&& ( mode1.brightness_max == mode2.brightness_max ) );
|
|
}
|
|
|
|
void RGBController_Alienware::DeviceUpdateMode()
|
|
{
|
|
/*---------------------------------------------------------*\
|
|
| Copy mode to get the current state-- this is racy, as the |
|
|
| UI thread can be actively modifying this variable |
|
|
\*---------------------------------------------------------*/
|
|
int current_mode_idx = active_mode;
|
|
mode current_mode = modes[current_mode_idx];
|
|
|
|
bool done = false;
|
|
|
|
while(!done)
|
|
{
|
|
/*-----------------------------------------------------*\
|
|
| Setup state per zone |
|
|
\*-----------------------------------------------------*/
|
|
for(uint8_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
|
{
|
|
zone current_zone = zones[zone_idx];
|
|
|
|
/*-------------------------------------------------*\
|
|
| Some modes use 2000ms (0x07D0) for their duration,|
|
|
| per traces |
|
|
\*-------------------------------------------------*/
|
|
uint16_t period = 0x07d0;
|
|
|
|
controller->SetMode(zone_idx, current_mode.value);
|
|
|
|
switch(current_mode_idx)
|
|
{
|
|
case ALIENWARE_MODE_COLOR:
|
|
controller->SetPeriod(zone_idx, period);
|
|
controller->SetColor( zone_idx, colors[current_zone.start_idx]);
|
|
controller->SetTempo( zone_idx, ALIENWARE_TEMPO_MAX);
|
|
controller->SetDim( zone_idx, modes[current_mode_idx].brightness);
|
|
break;
|
|
|
|
case ALIENWARE_MODE_PULSE:
|
|
controller->SetPeriod(zone_idx, period);
|
|
controller->SetColor( zone_idx, colors[current_zone.start_idx]);
|
|
controller->SetTempo( zone_idx, current_mode.speed);
|
|
controller->SetDim( zone_idx, modes[current_mode_idx].brightness);
|
|
break;
|
|
|
|
case ALIENWARE_MODE_MORPH:
|
|
controller->SetPeriod(zone_idx, period);
|
|
controller->SetColor( zone_idx, current_mode.colors[zone_idx * 2], current_mode.colors[(zone_idx * 2) + 1]);
|
|
controller->SetTempo( zone_idx, current_mode.speed);
|
|
controller->SetDim( zone_idx, modes[current_mode_idx].brightness);
|
|
break;
|
|
|
|
case ALIENWARE_MODE_SPECTRUM:
|
|
case ALIENWARE_MODE_RAINBOW:
|
|
controller->SetPeriod(zone_idx, ALIENWARE_DURATION_SPECTRUM);
|
|
controller->SetTempo( zone_idx, current_mode.speed);
|
|
controller->SetDim( zone_idx, modes[current_mode_idx].brightness);
|
|
break;
|
|
|
|
case ALIENWARE_MODE_BREATHING:
|
|
controller->SetPeriod(zone_idx, period);
|
|
controller->SetColor( zone_idx, colors[current_zone.start_idx], 0x0);
|
|
controller->SetTempo( zone_idx, current_mode.speed);
|
|
controller->SetDim( zone_idx, modes[current_mode_idx].brightness);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Due to rate-limiting, this can take more than one |
|
|
| second to execute |
|
|
\*-----------------------------------------------------*/
|
|
controller->UpdateController();
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Re-run update if there's anything that's changed from |
|
|
| under us... |
|
|
\*-----------------------------------------------------*/
|
|
int new_current_mode_idx = active_mode;
|
|
mode new_current_mode = modes[current_mode_idx];
|
|
|
|
done = (current_mode_idx == new_current_mode_idx && modes_eq(new_current_mode, current_mode));
|
|
current_mode_idx = new_current_mode_idx;
|
|
current_mode = new_current_mode;
|
|
}
|
|
}
|