Files
OpenRGB/Controllers/DRGBController/RGBController_DRGB.cpp
2026-04-03 16:23:06 -05:00

284 lines
11 KiB
C++

/*---------------------------------------------------------*\
| RGBController_DRGB.cpp |
| |
| Driver for DRGBmods |
| |
| Zhi Yan 25 Jun 2024 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <algorithm>
#include <iostream>
#include "RGBController_DRGB.h"
/**------------------------------------------------------------------*\
@name DRGB Controller
@category LEDStrip
@type USB
@save :x:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectDRGBControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_DRGB::RGBController_DRGB(DRGBController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetNameString();
vendor = "DRGB";
description = "DRGB Controller Device";
type = DEVICE_TYPE_LEDSTRIP;
version = controller->GetFirmwareString();
location = controller->GetLocationString();
serial = controller->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = 0xFFFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
SetupZones();
}
RGBController_DRGB::~RGBController_DRGB()
{
Shutdown();
delete controller;
}
void RGBController_DRGB::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(controller->GetNumChannels());
/*-----------------------------------------------------*\
| Set up zones |
\*-----------------------------------------------------*/
for(std::size_t channel_idx = 0; channel_idx < zones.size(); channel_idx++)
{
zones[channel_idx].leds_min = 0;
zones[channel_idx].leds_max = controller->GetLEDsPerChannel();
if(first_run)
{
zones[channel_idx].flags = ZONE_FLAG_MANUALLY_CONFIGURABLE_SIZE
| ZONE_FLAG_MANUALLY_CONFIGURABLE_NAME
| ZONE_FLAG_MANUALLY_CONFIGURABLE_TYPE
| ZONE_FLAG_MANUALLY_CONFIGURABLE_MATRIX_MAP
| ZONE_FLAG_MANUALLY_CONFIGURABLE_SEGMENTS;
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_NAME))
{
zones[channel_idx].name = controller->GetChannelName((unsigned char)channel_idx);
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_SIZE))
{
zones[channel_idx].leds_count = 0;
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_TYPE))
{
zones[channel_idx].type = ZONE_TYPE_LINEAR;
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_MATRIX_MAP))
{
zones[channel_idx].matrix_map.width = 0;
zones[channel_idx].matrix_map.height = 0;
zones[channel_idx].matrix_map.map.resize(0);
}
for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
{
led new_led;
new_led.name = zones[channel_idx].name + ", LED " + std::to_string(led_ch_idx);
leds.push_back(new_led);
leds_channel.push_back(channel_idx);
}
}
SetupColors();
}
void RGBController_DRGB::DeviceConfigureZone(int zone_idx)
{
if((size_t)zone_idx < zones.size())
{
SetupZones();
}
}
void RGBController_DRGB::DeviceUpdateLEDs()
{
switch(controller->GetVersion())
{
case 4:
{
unsigned int led_index = 0;
unsigned char RGBData[8192*3 + 72] = {0};
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
unsigned char LEDnum = zones[zone_idx].leds_count;
unsigned int HighCount = (LEDnum & 0xFFFF)>>8;
unsigned int LowCount = LEDnum & 0xFF;
RGBData[zone_idx * 2 ] = HighCount;
RGBData[zone_idx * 2 + 1] = LowCount;
for(unsigned int i=0; i<LEDnum;i++)
{
unsigned int RGBcolors = zones[zone_idx].colors[i];
RGBData[led_index * 3 +72] = RGBcolors & 0xFF;
RGBData[led_index * 3 +73] = (RGBcolors >> 8) & 0xFF;
RGBData[led_index * 3 +74] = (RGBcolors >> 16) & 0xFF;
led_index++;
}
if(led_index>8192)
{
break;
}
}
unsigned int col_packets = 1 ;
if(led_index > DRGB_V4_ONE_PACKAGE_SIZE)
{
col_packets = 1 + ((led_index - DRGB_V4_ONE_PACKAGE_SIZE) / DRGB_V4_PACKAGE_SIZE) + (((led_index - DRGB_V4_ONE_PACKAGE_SIZE) % DRGB_V4_PACKAGE_SIZE) > 0);
}
controller->SendPacket(&RGBData[0], col_packets,led_index);
break;
}
case 3:
{
unsigned int led_index = 0;
unsigned char RGBData[1801*3] = {0};
unsigned char ArrayData[64] = {0};
ArrayData[0] = 0x60;
ArrayData[1] = 0xBB;
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
unsigned char LEDnum = zones[zone_idx].leds_count;
unsigned int HighCount = (LEDnum & 0xFFFF)>>8;
unsigned int LowCount = LEDnum & 0xFF;
ArrayData[zone_idx * 2 + 2] = HighCount;
ArrayData[zone_idx * 2 + 3] = LowCount;
for(unsigned int i=0; i<LEDnum;i++)
{
unsigned int RGBcolors = zones[zone_idx].colors[i];
RGBData[led_index * 3] = RGBcolors & 0xFF;
RGBData[led_index * 3 +1] = (RGBcolors >> 8) & 0xFF;
RGBData[led_index * 3 +2] = (RGBcolors >> 16) & 0xFF;
led_index++;
}
if(led_index>1800)
{
break;
}
}
unsigned int col_packets = (led_index / DRGB_V3_PACKAGE_SIZE) + ((led_index % DRGB_V3_PACKAGE_SIZE) > 0);
controller->SendPacketFS(&ArrayData[0], 1,0);
controller->SendPacketFS(&RGBData[0], col_packets,0x64);
break;
}
case 2:
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
unsigned char RGBData[256*3] = {0};
unsigned char ArrayData[64] = {0};
unsigned char LEDnum = zones[zone_idx].leds_count;
for(unsigned int i = 0; i < LEDnum; i++)
{
unsigned int RGBcolors = zones[zone_idx].colors[i];
RGBData[i * 3] = RGBcolors & 0xFF;
RGBData[i * 3 +1] = (RGBcolors >> 8) & 0xFF;
RGBData[i * 3 +2] = (RGBcolors >> 16) & 0xFF;
}
unsigned char NumPackets = LEDnum / DRGB_V2_PACKAGE_SIZE + ((LEDnum % DRGB_V2_PACKAGE_SIZE) > 0);
for(unsigned char CurrPacket = 1; CurrPacket <= NumPackets; CurrPacket++)
{
ArrayData[0] = CurrPacket;
ArrayData[1] = NumPackets;
ArrayData[2] = (unsigned char)zone_idx;
ArrayData[3] = 0xBB;
for(unsigned int i=0; i<60;i++)
{
ArrayData[4+i] = RGBData[(CurrPacket -1)*60 + i];
}
controller->SendPacketFS(&ArrayData[0], 1,0);
}
}
break;
case 1:
{
unsigned int led_index = 0;
unsigned char RGBData[1801*3] = {0};
unsigned char ArrayData[64] = {0};
ArrayData[0] = 0x46;
ArrayData[1] = 0xBB;
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
unsigned char LEDnum = zones[zone_idx].leds_count;
unsigned int HighCount = (LEDnum & 0xFFFF)>>8;
unsigned int LowCount = LEDnum & 0xFF;
ArrayData[zone_idx * 2 + 2] = HighCount;
ArrayData[zone_idx * 2 + 3] = LowCount;
for(unsigned int i=0; i<LEDnum;i++)
{
unsigned int RGBcolors = zones[zone_idx].colors[i];
RGBData[led_index * 3] = RGBcolors & 0xFF;
RGBData[led_index * 3 +1] = (RGBcolors >> 8) & 0xFF;
RGBData[led_index * 3 +2] = (RGBcolors >> 16) & 0xFF;
led_index++;
}
if(led_index>1800)
{
break;
}
}
unsigned int col_packets = (led_index / DRGB_V3_PACKAGE_SIZE) + ((led_index % DRGB_V3_PACKAGE_SIZE) > 0);
controller->SendPacketFS(&ArrayData[0], 1,0);
controller->SendPacketFS(&RGBData[0], col_packets,0x47);
break;
}
}
}
void RGBController_DRGB::DeviceUpdateZoneLEDs(int zone)
{
controller->SetChannelLEDs(zone, zones[zone].colors, zones[zone].leds_count);
}
void RGBController_DRGB::DeviceUpdateSingleLED(int led)
{
unsigned int channel = leds_channel[led];
controller->SetChannelLEDs(channel, zones[channel].colors, zones[channel].leds_count);
}
void RGBController_DRGB::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}