mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2026-05-10 23:53:08 -04:00
354 lines
11 KiB
C++
354 lines
11 KiB
C++
/*---------------------------------------------------------*\
|
|
| RGBController_ThrustmasterSol.cpp |
|
|
| |
|
|
| RGBController for Thrustmaster Sol series joysticks |
|
|
| |
|
|
| Ken Sanislo 02 Apr 2026 |
|
|
| |
|
|
| This file is part of the OpenRGB project |
|
|
| SPDX-License-Identifier: GPL-2.0-or-later |
|
|
\*---------------------------------------------------------*/
|
|
|
|
#include "RGBController_ThrustmasterSol.h"
|
|
|
|
/**------------------------------------------------------------------*\
|
|
@name Thrustmaster Sol
|
|
@category Gamepad
|
|
@type USB
|
|
@save :white_check_mark:
|
|
@direct :white_check_mark:
|
|
@effects :x:
|
|
@detectors DetectThrustmasterSolControllers
|
|
@comment Thrustmaster Sol series joystick RGB LED control. Supports
|
|
Sol-R, Sol F16, and Sol F18 variants. Only Sol-R has been tested.
|
|
Uses vendor-specific USB interface 1 (not HID).
|
|
\*-------------------------------------------------------------------*/
|
|
|
|
#define NA 0xFFFFFFFF
|
|
|
|
static unsigned int logo_matrix_map[2][2] =
|
|
{
|
|
{ 0, 3 },
|
|
{ 1, 2 },
|
|
};
|
|
|
|
static unsigned int ring_matrix_map[3][5] =
|
|
{
|
|
{ NA, 7, 0, 1, NA },
|
|
{ 6, NA, NA, NA, 2 },
|
|
{ NA, 5, 4, 3, NA },
|
|
};
|
|
|
|
static unsigned int right_buttons_matrix_map[2][2] =
|
|
{
|
|
{ 0, 1 },
|
|
{ 2, 3 },
|
|
};
|
|
|
|
static unsigned int left_buttons_matrix_map[2][2] =
|
|
{
|
|
{ 0, 1 },
|
|
{ 2, 3 },
|
|
};
|
|
|
|
RGBController_ThrustmasterSol::RGBController_ThrustmasterSol(ThrustmasterSolController* controller_ptr)
|
|
{
|
|
controller = controller_ptr;
|
|
|
|
vendor = "Thrustmaster";
|
|
type = DEVICE_TYPE_GAMEPAD;
|
|
description = "Thrustmaster Sol Series Joystick";
|
|
location = controller->GetDeviceLocation();
|
|
serial = controller->GetSerialString();
|
|
|
|
mode Direct;
|
|
Direct.name = "Direct";
|
|
Direct.value = 0;
|
|
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE;
|
|
Direct.color_mode = MODE_COLORS_PER_LED;
|
|
modes.push_back(Direct);
|
|
|
|
SetupZones();
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Read current EEPROM colors from device so the UI starts |
|
|
| with the actual hardware state rather than all-black |
|
|
\*---------------------------------------------------------*/
|
|
std::vector<unsigned int> hw_zones;
|
|
std::vector<RGBColor> hw_colors;
|
|
controller->ReadColors(hw_zones, hw_colors);
|
|
|
|
for(unsigned int i = 0; i < hw_zones.size(); i++)
|
|
{
|
|
for(unsigned int j = 0; j < leds.size(); j++)
|
|
{
|
|
if(leds[j].value == hw_zones[i])
|
|
{
|
|
colors[j] = hw_colors[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
RGBController_ThrustmasterSol::~RGBController_ThrustmasterSol()
|
|
{
|
|
delete controller;
|
|
}
|
|
|
|
void RGBController_ThrustmasterSol::SetupZones()
|
|
{
|
|
/*---------------------------------------------------------*\
|
|
| Thumbstick zone (grip, 1 LED) |
|
|
\*---------------------------------------------------------*/
|
|
zone thumbstick_zone;
|
|
thumbstick_zone.name = "Thumbstick";
|
|
thumbstick_zone.type = ZONE_TYPE_SINGLE;
|
|
thumbstick_zone.leds_min = 1;
|
|
thumbstick_zone.leds_max = 1;
|
|
thumbstick_zone.leds_count = 1;
|
|
thumbstick_zone.matrix_map = NULL;
|
|
zones.push_back(thumbstick_zone);
|
|
|
|
led thumbstick_led;
|
|
thumbstick_led.name = "Thumbstick";
|
|
thumbstick_led.value = THRUSTMASTER_SOL_GRIP_FLAG | 0x00;
|
|
leds.push_back(thumbstick_led);
|
|
|
|
/*---------------------------------------------------------*\
|
|
| TM Logo zone (3 LEDs) |
|
|
\*---------------------------------------------------------*/
|
|
zone logo_zone;
|
|
logo_zone.name = "TM Logo";
|
|
logo_zone.type = ZONE_TYPE_MATRIX;
|
|
logo_zone.leds_min = 4;
|
|
logo_zone.leds_max = 4;
|
|
logo_zone.leds_count = 4;
|
|
logo_zone.matrix_map = new matrix_map_type;
|
|
logo_zone.matrix_map->height = 2;
|
|
logo_zone.matrix_map->width = 2;
|
|
logo_zone.matrix_map->map = (unsigned int *)&logo_matrix_map;
|
|
zones.push_back(logo_zone);
|
|
|
|
led logo_top_left;
|
|
logo_top_left.name = "TM Logo Top Left";
|
|
logo_top_left.value = 0x01;
|
|
leds.push_back(logo_top_left);
|
|
|
|
led logo_bottom_left;
|
|
logo_bottom_left.name = "TM Logo Bottom Left";
|
|
logo_bottom_left.value = 0x02;
|
|
leds.push_back(logo_bottom_left);
|
|
|
|
led logo_bottom_right;
|
|
logo_bottom_right.name = "TM Logo Bottom Right";
|
|
logo_bottom_right.value = 0x03;
|
|
leds.push_back(logo_bottom_right);
|
|
|
|
led logo_top_right;
|
|
logo_top_right.name = "TM Logo Top Right";
|
|
logo_top_right.value = 0x00;
|
|
leds.push_back(logo_top_right);
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Left Buttons zone (4 LEDs: buttons 5-8) |
|
|
\*---------------------------------------------------------*/
|
|
zone left_buttons_zone;
|
|
left_buttons_zone.name = "Left Buttons";
|
|
left_buttons_zone.type = ZONE_TYPE_MATRIX;
|
|
left_buttons_zone.leds_min = 4;
|
|
left_buttons_zone.leds_max = 4;
|
|
left_buttons_zone.leds_count = 4;
|
|
left_buttons_zone.matrix_map = new matrix_map_type;
|
|
left_buttons_zone.matrix_map->height = 2;
|
|
left_buttons_zone.matrix_map->width = 2;
|
|
left_buttons_zone.matrix_map->map = (unsigned int *)&left_buttons_matrix_map;
|
|
zones.push_back(left_buttons_zone);
|
|
|
|
led btn5;
|
|
btn5.name = "Button 5";
|
|
btn5.value = 0x11;
|
|
leds.push_back(btn5);
|
|
|
|
led btn6;
|
|
btn6.name = "Button 6";
|
|
btn6.value = 0x10;
|
|
leds.push_back(btn6);
|
|
|
|
led btn7;
|
|
btn7.name = "Button 7";
|
|
btn7.value = 0x12;
|
|
leds.push_back(btn7);
|
|
|
|
led btn8;
|
|
btn8.name = "Button 8";
|
|
btn8.value = 0x13;
|
|
leds.push_back(btn8);
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Base Ring zone (8 LEDs, clockwise from top) |
|
|
\*---------------------------------------------------------*/
|
|
zone ring_zone;
|
|
ring_zone.name = "Base Ring";
|
|
ring_zone.type = ZONE_TYPE_MATRIX;
|
|
ring_zone.leds_min = 8;
|
|
ring_zone.leds_max = 8;
|
|
ring_zone.leds_count = 8;
|
|
ring_zone.matrix_map = new matrix_map_type;
|
|
ring_zone.matrix_map->height = 3;
|
|
ring_zone.matrix_map->width = 5;
|
|
ring_zone.matrix_map->map = (unsigned int *)&ring_matrix_map;
|
|
zones.push_back(ring_zone);
|
|
|
|
led ring_upper;
|
|
ring_upper.name = "Upper";
|
|
ring_upper.value = 0x04;
|
|
leds.push_back(ring_upper);
|
|
|
|
led ring_upper_right;
|
|
ring_upper_right.name = "Upper Right";
|
|
ring_upper_right.value = 0x05;
|
|
leds.push_back(ring_upper_right);
|
|
|
|
led ring_right;
|
|
ring_right.name = "Right";
|
|
ring_right.value = 0x06;
|
|
leds.push_back(ring_right);
|
|
|
|
led ring_bottom_right;
|
|
ring_bottom_right.name = "Bottom Right";
|
|
ring_bottom_right.value = 0x0B;
|
|
leds.push_back(ring_bottom_right);
|
|
|
|
led ring_bottom;
|
|
ring_bottom.name = "Bottom";
|
|
ring_bottom.value = 0x0C;
|
|
leds.push_back(ring_bottom);
|
|
|
|
led ring_bottom_left;
|
|
ring_bottom_left.name = "Bottom Left";
|
|
ring_bottom_left.value = 0x0D;
|
|
leds.push_back(ring_bottom_left);
|
|
|
|
led ring_left;
|
|
ring_left.name = "Left";
|
|
ring_left.value = 0x0E;
|
|
leds.push_back(ring_left);
|
|
|
|
led ring_upper_left;
|
|
ring_upper_left.name = "Upper Left";
|
|
ring_upper_left.value = 0x0F;
|
|
leds.push_back(ring_upper_left);
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Right Buttons zone (4 LEDs: buttons 16-19) |
|
|
\*---------------------------------------------------------*/
|
|
zone right_buttons_zone;
|
|
right_buttons_zone.name = "Right Buttons";
|
|
right_buttons_zone.type = ZONE_TYPE_MATRIX;
|
|
right_buttons_zone.leds_min = 4;
|
|
right_buttons_zone.leds_max = 4;
|
|
right_buttons_zone.leds_count = 4;
|
|
right_buttons_zone.matrix_map = new matrix_map_type;
|
|
right_buttons_zone.matrix_map->height = 2;
|
|
right_buttons_zone.matrix_map->width = 2;
|
|
right_buttons_zone.matrix_map->map = (unsigned int *)&right_buttons_matrix_map;
|
|
zones.push_back(right_buttons_zone);
|
|
|
|
led btn17;
|
|
btn17.name = "Button 17";
|
|
btn17.value = 0x07;
|
|
leds.push_back(btn17);
|
|
|
|
led btn16;
|
|
btn16.name = "Button 16";
|
|
btn16.value = 0x08;
|
|
leds.push_back(btn16);
|
|
|
|
led btn19;
|
|
btn19.name = "Button 19";
|
|
btn19.value = 0x0A;
|
|
leds.push_back(btn19);
|
|
|
|
led btn18;
|
|
btn18.name = "Button 18";
|
|
btn18.value = 0x09;
|
|
leds.push_back(btn18);
|
|
|
|
SetupColors();
|
|
}
|
|
|
|
void RGBController_ThrustmasterSol::ResizeZone(int /*zone*/, int /*new_size*/)
|
|
{
|
|
/*---------------------------------------------------------*\
|
|
| This device does not support resizing zones |
|
|
\*---------------------------------------------------------*/
|
|
}
|
|
|
|
void RGBController_ThrustmasterSol::DeviceUpdateLEDs()
|
|
{
|
|
unsigned int led_zones[THRUSTMASTER_SOL_R_ZONE_COUNT];
|
|
RGBColor led_colors[THRUSTMASTER_SOL_R_ZONE_COUNT];
|
|
|
|
for(unsigned int led_idx = 0; led_idx < leds.size(); led_idx++)
|
|
{
|
|
led_zones[led_idx] = leds[led_idx].value;
|
|
led_colors[led_idx] = colors[led_idx];
|
|
}
|
|
|
|
controller->SetLEDColors(led_zones, led_colors, static_cast<unsigned int>(leds.size()));
|
|
}
|
|
|
|
void RGBController_ThrustmasterSol::UpdateZoneLEDs(int zone)
|
|
{
|
|
unsigned int start_idx = 0;
|
|
unsigned int zone_size = 0;
|
|
|
|
for(unsigned int z_idx = 0; z_idx < zones.size(); z_idx++)
|
|
{
|
|
if(z_idx == (unsigned int)zone)
|
|
{
|
|
zone_size = zones[z_idx].leds_count;
|
|
break;
|
|
}
|
|
|
|
start_idx += zones[z_idx].leds_count;
|
|
}
|
|
|
|
unsigned int led_zones[THRUSTMASTER_SOL_R_ZONE_COUNT];
|
|
RGBColor led_colors[THRUSTMASTER_SOL_R_ZONE_COUNT];
|
|
|
|
for(unsigned int led_idx = 0; led_idx < zone_size; led_idx++)
|
|
{
|
|
unsigned int current_idx = start_idx + led_idx;
|
|
led_zones[led_idx] = leds[current_idx].value;
|
|
led_colors[led_idx] = colors[current_idx];
|
|
}
|
|
|
|
controller->SetLEDColors(led_zones, led_colors, zone_size);
|
|
}
|
|
|
|
void RGBController_ThrustmasterSol::UpdateSingleLED(int led)
|
|
{
|
|
controller->SetLEDColor(leds[led].value, colors[led]);
|
|
}
|
|
|
|
void RGBController_ThrustmasterSol::DeviceUpdateMode()
|
|
{
|
|
DeviceUpdateLEDs();
|
|
}
|
|
|
|
void RGBController_ThrustmasterSol::DeviceSaveMode()
|
|
{
|
|
unsigned int led_zones[THRUSTMASTER_SOL_R_ZONE_COUNT];
|
|
RGBColor led_colors[THRUSTMASTER_SOL_R_ZONE_COUNT];
|
|
|
|
for(unsigned int led_idx = 0; led_idx < leds.size(); led_idx++)
|
|
{
|
|
led_zones[led_idx] = leds[led_idx].value;
|
|
led_colors[led_idx] = colors[led_idx];
|
|
}
|
|
|
|
controller->SaveColors(led_zones, led_colors, static_cast<unsigned int>(leds.size()));
|
|
}
|