overlay: categorize lights for different cab types (#576)

## Link to GitHub Issue or related Pull Request, if one exists
#574 

## Description of change
Refactor so that grouping of lights are in common I/O code. Add this to
IIDX/SDVX/DDR/GitaDora.

## Testing
This commit is contained in:
bicarus
2026-03-17 02:14:48 -07:00
committed by GitHub
parent 88679b7cb2
commit a9f0e86aa3
8 changed files with 457 additions and 468 deletions
+38
View File
@@ -861,6 +861,44 @@ std::vector<Light> GameAPI::Lights::sortLights(
return sorted; return sorted;
} }
static std::vector<Light> sortLightsWithCategoryInternal(
const std::vector<Light> &lights,
const std::initializer_list<GameAPI::Lights::LightAndCategory> list)
{
std::vector<Light> sorted;
bool light_found;
for (auto &name : list) {
light_found = false;
for (auto &light : lights) {
if (name.light_name == light.getName()) {
light_found = true;
Light light_new = light;
light_new.setCategory(name.category_name);
sorted.push_back(light_new);
break;
}
}
if (!light_found) {
sorted.emplace_back(name.light_name, name.category_name);
}
}
return sorted;
}
void GameAPI::Lights::sortLightsWithCategory(
std::vector<Light> *lights,
const std::initializer_list<LightAndCategory> list) {
if (lights) {
*lights = sortLightsWithCategoryInternal(*lights, list);
}
}
void GameAPI::Lights::writeLight(rawinput::Device *device, int index, float value) { void GameAPI::Lights::writeLight(rawinput::Device *device, int index, float value) {
// check device // check device
+11 -9
View File
@@ -109,21 +109,13 @@ namespace GameAPI {
} }
namespace Lights { namespace Lights {
std::vector<Light> getLights(const std::string &game_name); std::vector<Light> getLights(const std::string &game_name);
std::vector<Light> sortLights( std::vector<Light> sortLights(
const std::vector<Light> &lights, const std::vector<Light> &lights,
const std::vector<std::string> &light_names); const std::vector<std::string> &light_names);
template<typename T>
void sortLights(std::vector<Light> *lights, T t) {
const std::vector<std::string> light_names { t };
if (lights) {
*lights = GameAPI::Lights::sortLights(*lights, light_names);
}
}
template<typename T, typename... Rest> template<typename T, typename... Rest>
void sortLights(std::vector<Light> *lights, T t, Rest... rest) { void sortLights(std::vector<Light> *lights, T t, Rest... rest) {
const std::vector<std::string> light_names { t, rest... }; const std::vector<std::string> light_names { t, rest... };
@@ -133,6 +125,16 @@ namespace GameAPI {
} }
} }
struct LightAndCategory {
const std::string category_name;
const std::string light_name;
LightAndCategory(std::string category_name, std::string light_name) :
category_name(std::move(category_name)), light_name(std::move(light_name)) {}
};
void sortLightsWithCategory(std::vector<Light> *lights, const std::initializer_list<LightAndCategory> list);
void writeLight(rawinput::Device *device, int index, float value); void writeLight(rawinput::Device *device, int index, float value);
void writeLight(rawinput::RawInputManager *manager, Light &light, float value); void writeLight(rawinput::RawInputManager *manager, Light &light, float value);
void writeLight(std::unique_ptr<rawinput::RawInputManager> &manager, Light &light, float value); void writeLight(std::unique_ptr<rawinput::RawInputManager> &manager, Light &light, float value);
+11
View File
@@ -11,6 +11,7 @@ class Light {
private: private:
std::vector<Light> alternatives; std::vector<Light> alternatives;
std::string lightName; std::string lightName;
std::string lightCategory;
std::string deviceIdentifier = ""; std::string deviceIdentifier = "";
unsigned int index = 0; unsigned int index = 0;
bool is_temporary = false; bool is_temporary = false;
@@ -23,6 +24,8 @@ public:
float override_state = 0.f; float override_state = 0.f;
explicit Light(std::string lightName) : lightName(std::move(lightName)) {}; explicit Light(std::string lightName) : lightName(std::move(lightName)) {};
explicit Light(std::string lightName, std::string lightCategory) :
lightName(std::move(lightName)), lightCategory(std::move(lightCategory)) {};
std::string getDisplayString(rawinput::RawInputManager* manager); std::string getDisplayString(rawinput::RawInputManager* manager);
@@ -51,6 +54,14 @@ public:
return this->lightName; return this->lightName;
} }
inline const std::string &getCategory() const {
return this->lightCategory;
}
inline void setCategory(std::string category) {
this->lightCategory = std::move(category);
}
inline const std::string &getDeviceIdentifier() const { inline const std::string &getDeviceIdentifier() const {
return this->deviceIdentifier; return this->deviceIdentifier;
} }
+114 -110
View File
@@ -41,136 +41,140 @@ std::vector<Light> &games::ddr::get_lights() {
if (lights.empty()) { if (lights.empty()) {
lights = GameAPI::Lights::getLights("Dance Dance Revolution"); lights = GameAPI::Lights::getLights("Dance Dance Revolution");
GameAPI::Lights::sortLights( GameAPI::Lights::sortLightsWithCategory(
&lights, &lights,
"P1 Foot Left", {
"P1 Foot Up", {"General", "P1 Foot Left"},
"P1 Foot Right", {"General", "P1 Foot Up"},
"P1 Foot Down", {"General", "P1 Foot Right"},
"P2 Foot Left", {"General", "P1 Foot Down"},
"P2 Foot Up", {"General", "P2 Foot Left"},
"P2 Foot Right", {"General", "P2 Foot Up"},
"P2 Foot Down", {"General", "P2 Foot Right"},
"Spot Red", {"General", "P2 Foot Down"},
"Spot Blue",
"Top Spot Red",
"Top Spot Blue",
"P1 Halogen Upper",
"P1 Halogen Lower",
"P2 Halogen Upper",
"P2 Halogen Lower",
"P1 Button",
"P2 Button",
"Neon",
"HD P1 Start",
"HD P1 Menu Left-Right",
"HD P1 Menu Up-Down",
"HD P2 Start",
"HD P2 Menu Left-Right",
"HD P2 Menu Up-Down",
"HD P1 Speaker F R",
"HD P1 Speaker F G",
"HD P1 Speaker F B",
"HD P1 Speaker W R",
"HD P1 Speaker W G",
"HD P1 Speaker W B",
"HD P2 Speaker F R",
"HD P2 Speaker F G",
"HD P2 Speaker F B",
"HD P2 Speaker W R",
"HD P2 Speaker W G",
"HD P2 Speaker W B",
"WHITE Speaker Top R", {"SD", "Spot Red"},
"WHITE Speaker Top G", {"SD", "Spot Blue"},
"WHITE Speaker Top B", {"SD", "Top Spot Red"},
"WHITE Speaker Bottom R", {"SD", "Top Spot Blue"},
"WHITE Speaker Bottom G", {"SD", "P1 Halogen Upper"},
"WHITE Speaker Bottom B", {"SD", "P1 Halogen Lower"},
"WHITE Woofer R", {"SD", "P2 Halogen Upper"},
"WHITE Woofer G", {"SD", "P2 Halogen Lower"},
"WHITE Woofer B", {"SD", "P1 Button"},
{"SD", "P2 Button"},
{"SD", "Neon"},
"GOLD P1 Menu Start", {"HD", "HD P1 Start"},
"GOLD P1 Menu Up", {"HD", "HD P1 Menu Left-Right"},
"GOLD P1 Menu Down", {"HD", "HD P1 Menu Up-Down"},
"GOLD P1 Menu Left", {"HD", "HD P2 Start"},
"GOLD P1 Menu Right", {"HD", "HD P2 Menu Left-Right"},
{"HD", "HD P2 Menu Up-Down"},
{"HD", "HD P1 Speaker F R"},
{"HD", "HD P1 Speaker F G"},
{"HD", "HD P1 Speaker F B"},
{"HD", "HD P1 Speaker W R"},
{"HD", "HD P1 Speaker W G"},
{"HD", "HD P1 Speaker W B"},
{"HD", "HD P2 Speaker F R"},
{"HD", "HD P2 Speaker F G"},
{"HD", "HD P2 Speaker F B"},
{"HD", "HD P2 Speaker W R"},
{"HD", "HD P2 Speaker W G"},
{"HD", "HD P2 Speaker W B"},
"GOLD P2 Menu Start", {"WHITE", "WHITE Speaker Top R"},
"GOLD P2 Menu Up", {"WHITE", "WHITE Speaker Top G"},
"GOLD P2 Menu Down", {"WHITE", "WHITE Speaker Top B"},
"GOLD P2 Menu Left", {"WHITE", "WHITE Speaker Bottom R"},
"GOLD P2 Menu Right", {"WHITE", "WHITE Speaker Bottom G"},
{"WHITE", "WHITE Speaker Bottom B"},
{"WHITE", "WHITE Woofer R"},
{"WHITE", "WHITE Woofer G"},
{"WHITE", "WHITE Woofer B"},
"GOLD Title Panel Left", {"GOLD", "GOLD P1 Menu Start"},
"GOLD Title Panel Center", {"GOLD", "GOLD P1 Menu Up"},
"GOLD Title Panel Right", {"GOLD", "GOLD P1 Menu Down"},
{"GOLD", "GOLD P1 Menu Left"},
{"GOLD", "GOLD P1 Menu Right"},
"GOLD P1 Woofer Corner", {"GOLD", "GOLD P2 Menu Start"},
"GOLD P2 Woofer Corner", {"GOLD", "GOLD P2 Menu Up"},
{"GOLD", "GOLD P2 Menu Down"},
{"GOLD", "GOLD P2 Menu Left"},
{"GOLD", "GOLD P2 Menu Right"},
"GOLD P1 Card Unit R", {"GOLD", "GOLD Title Panel Left"},
"GOLD P1 Card Unit G", {"GOLD", "GOLD Title Panel Center"},
"GOLD P1 Card Unit B", {"GOLD", "GOLD Title Panel Right"},
"GOLD P2 Card Unit R", {"GOLD", "GOLD P1 Woofer Corner"},
"GOLD P2 Card Unit G", {"GOLD", "GOLD P2 Woofer Corner"},
"GOLD P2 Card Unit B",
"GOLD Top Panel Avg R", {"GOLD", "GOLD P1 Card Unit R"},
"GOLD Top Panel Avg G", {"GOLD", "GOLD P1 Card Unit G"},
"GOLD Top Panel Avg B", {"GOLD", "GOLD P1 Card Unit B"},
"GOLD Monitor Side Left Avg R", {"GOLD", "GOLD P2 Card Unit R"},
"GOLD Monitor Side Left Avg G", {"GOLD", "GOLD P2 Card Unit G"},
"GOLD Monitor Side Left Avg B", {"GOLD", "GOLD P2 Card Unit B"},
"GOLD Monitor Side Right Avg R", {"GOLD", "GOLD Top Panel Avg R"},
"GOLD Monitor Side Right Avg G", {"GOLD", "GOLD Top Panel Avg G"},
"GOLD Monitor Side Right Avg B", {"GOLD", "GOLD Top Panel Avg B"},
"GOLD P1 Foot Up Avg R", {"GOLD", "GOLD Monitor Side Left Avg R"},
"GOLD P1 Foot Up Avg G", {"GOLD", "GOLD Monitor Side Left Avg G"},
"GOLD P1 Foot Up Avg B", {"GOLD", "GOLD Monitor Side Left Avg B"},
"GOLD P1 Foot Down Avg R", {"GOLD", "GOLD Monitor Side Right Avg R"},
"GOLD P1 Foot Down Avg G", {"GOLD", "GOLD Monitor Side Right Avg G"},
"GOLD P1 Foot Down Avg B", {"GOLD", "GOLD Monitor Side Right Avg B"},
"GOLD P1 Foot Left Avg R", {"GOLD", "GOLD P1 Foot Up Avg R"},
"GOLD P1 Foot Left Avg G", {"GOLD", "GOLD P1 Foot Up Avg G"},
"GOLD P1 Foot Left Avg B", {"GOLD", "GOLD P1 Foot Up Avg B"},
"GOLD P1 Foot Right Avg R", {"GOLD", "GOLD P1 Foot Down Avg R"},
"GOLD P1 Foot Right Avg G", {"GOLD", "GOLD P1 Foot Down Avg G"},
"GOLD P1 Foot Right Avg B", {"GOLD", "GOLD P1 Foot Down Avg B"},
"GOLD P2 Foot Up Avg R", {"GOLD", "GOLD P1 Foot Left Avg R"},
"GOLD P2 Foot Up Avg G", {"GOLD", "GOLD P1 Foot Left Avg G"},
"GOLD P2 Foot Up Avg B", {"GOLD", "GOLD P1 Foot Left Avg B"},
"GOLD P2 Foot Down Avg R", {"GOLD", "GOLD P1 Foot Right Avg R"},
"GOLD P2 Foot Down Avg G", {"GOLD", "GOLD P1 Foot Right Avg G"},
"GOLD P2 Foot Down Avg B", {"GOLD", "GOLD P1 Foot Right Avg B"},
"GOLD P2 Foot Left Avg R", {"GOLD", "GOLD P2 Foot Up Avg R"},
"GOLD P2 Foot Left Avg G", {"GOLD", "GOLD P2 Foot Up Avg G"},
"GOLD P2 Foot Left Avg B", {"GOLD", "GOLD P2 Foot Up Avg B"},
"GOLD P2 Foot Right Avg R", {"GOLD", "GOLD P2 Foot Down Avg R"},
"GOLD P2 Foot Right Avg G", {"GOLD", "GOLD P2 Foot Down Avg G"},
"GOLD P2 Foot Right Avg B", {"GOLD", "GOLD P2 Foot Down Avg B"},
"GOLD P1 Stage Corner Up-Left", {"GOLD", "GOLD P2 Foot Left Avg R"},
"GOLD P1 Stage Corner Up-Right", {"GOLD", "GOLD P2 Foot Left Avg G"},
"GOLD P1 Stage Corner Down-Left", {"GOLD", "GOLD P2 Foot Left Avg B"},
"GOLD P1 Stage Corner Down-Right",
"GOLD P2 Stage Corner Up-Left", {"GOLD", "GOLD P2 Foot Right Avg R"},
"GOLD P2 Stage Corner Up-Right", {"GOLD", "GOLD P2 Foot Right Avg G"},
"GOLD P2 Stage Corner Down-Left", {"GOLD", "GOLD P2 Foot Right Avg B"},
"GOLD P2 Stage Corner Down-Right"
{"GOLD", "GOLD P1 Stage Corner Up-Left"},
{"GOLD", "GOLD P1 Stage Corner Up-Right"},
{"GOLD", "GOLD P1 Stage Corner Down-Left"},
{"GOLD", "GOLD P1 Stage Corner Down-Right"},
{"GOLD", "GOLD P2 Stage Corner Up-Left"},
{"GOLD", "GOLD P2 Stage Corner Up-Right"},
{"GOLD", "GOLD P2 Stage Corner Down-Left"},
{"GOLD", "GOLD P2 Stage Corner Down-Right"}
}
); );
} }
+83 -81
View File
@@ -158,100 +158,102 @@ std::vector<Light> &games::gitadora::get_lights() {
if (lights.empty()) { if (lights.empty()) {
lights = GameAPI::Lights::getLights("GitaDora"); lights = GameAPI::Lights::getLights("GitaDora");
GameAPI::Lights::sortLights(&lights, GameAPI::Lights::sortLightsWithCategory(&lights,
"Guitar P1 Motor", {
"Guitar P2 Motor", {"Guitar", "Guitar P1 Motor"},
{"Guitar", "Guitar P2 Motor"},
"P1 Start", {"Menu", "P1 Start"},
"P1 Menu Up Down (DX)", {"Menu", "P1 Menu Up Down (DX)"},
"P1 Menu Left Right (DX)", {"Menu", "P1 Menu Left Right (DX)"},
"P1 Help (DX)", {"Menu", "P1 Help (DX)"},
"P2 Start", {"Menu", "P2 Start"},
"P2 Menu Up Down (DX)", {"Menu", "P2 Menu Up Down (DX)"},
"P2 Menu Left Right (DX)", {"Menu", "P2 Menu Left Right (DX)"},
"P2 Help (DX)", {"Menu", "P2 Help (DX)"},
"Drum Left Cymbal", {"Drums", "Drum Left Cymbal"},
"Drum Hi-Hat", {"Drums", "Drum Hi-Hat"},
"Drum Snare", {"Drums", "Drum Snare"},
"Drum High Tom", {"Drums", "Drum High Tom"},
"Drum Low Tom", {"Drums", "Drum Low Tom"},
"Drum Floor Tom", {"Drums", "Drum Floor Tom"},
"Drum Right Cymbal", {"Drums", "Drum Right Cymbal"},
"Drum Woofer R", {"DX/SD", "Drum Woofer R"},
"Drum Woofer G", {"DX/SD", "Drum Woofer G"},
"Drum Woofer B", {"DX/SD", "Drum Woofer B"},
"Drum Stage R (DX)", {"DX/SD", "Drum Stage R (DX)"},
"Drum Stage G (DX)", {"DX/SD", "Drum Stage G (DX)"},
"Drum Stage B (DX)", {"DX/SD", "Drum Stage B (DX)"},
"Spot Left (DX)", {"DX/SD", "Spot Left (DX)"},
"Spot Right (DX)", {"DX/SD", "Spot Right (DX)"},
"Spot Center Left (DX)", {"DX/SD", "Spot Center Left (DX)"},
"Spot Center Right (DX)", {"DX/SD", "Spot Center Right (DX)"},
"Drum Spot Rear Left (DX)", {"DX/SD", "Drum Spot Rear Left (DX)"},
"Drum Spot Rear Right (DX)", {"DX/SD", "Drum Spot Rear Right (DX)"},
"Guitar Lower Left R (DX)", {"DX/SD", "Guitar Lower Left R (DX)"},
"Guitar Lower Left G (DX)", {"DX/SD", "Guitar Lower Left G (DX)"},
"Guitar Lower Left B (DX)", {"DX/SD", "Guitar Lower Left B (DX)"},
"Guitar Lower Right R (DX)", {"DX/SD", "Guitar Lower Right R (DX)"},
"Guitar Lower Right G (DX)", {"DX/SD", "Guitar Lower Right G (DX)"},
"Guitar Lower Right B (DX)", {"DX/SD", "Guitar Lower Right B (DX)"},
"Guitar Left Speaker Upper R (DX)", {"DX/SD", "Guitar Left Speaker Upper R (DX)"},
"Guitar Left Speaker Upper G (DX)", {"DX/SD", "Guitar Left Speaker Upper G (DX)"},
"Guitar Left Speaker Upper B (DX)", {"DX/SD", "Guitar Left Speaker Upper B (DX)"},
"Guitar Left Speaker Mid Up Left R (DX)", {"DX/SD", "Guitar Left Speaker Mid Up Left R (DX)"},
"Guitar Left Speaker Mid Up Left G (DX)", {"DX/SD", "Guitar Left Speaker Mid Up Left G (DX)"},
"Guitar Left Speaker Mid Up Left B (DX)", {"DX/SD", "Guitar Left Speaker Mid Up Left B (DX)"},
"Guitar Left Speaker Mid Up Right R (DX)", {"DX/SD", "Guitar Left Speaker Mid Up Right R (DX)"},
"Guitar Left Speaker Mid Up Right G (DX)", {"DX/SD", "Guitar Left Speaker Mid Up Right G (DX)"},
"Guitar Left Speaker Mid Up Right B (DX)", {"DX/SD", "Guitar Left Speaker Mid Up Right B (DX)"},
"Guitar Left Speaker Mid Low Left R (DX)", {"DX/SD", "Guitar Left Speaker Mid Low Left R (DX)"},
"Guitar Left Speaker Mid Low Left G (DX)", {"DX/SD", "Guitar Left Speaker Mid Low Left G (DX)"},
"Guitar Left Speaker Mid Low Left B (DX)", {"DX/SD", "Guitar Left Speaker Mid Low Left B (DX)"},
"Guitar Left Speaker Mid Low Right R (DX)", {"DX/SD", "Guitar Left Speaker Mid Low Right R (DX)"},
"Guitar Left Speaker Mid Low Right G (DX)", {"DX/SD", "Guitar Left Speaker Mid Low Right G (DX)"},
"Guitar Left Speaker Mid Low Right B (DX)", {"DX/SD", "Guitar Left Speaker Mid Low Right B (DX)"},
"Guitar Left Speaker Lower R (DX)", {"DX/SD", "Guitar Left Speaker Lower R (DX)"},
"Guitar Left Speaker Lower G (DX)", {"DX/SD", "Guitar Left Speaker Lower G (DX)"},
"Guitar Left Speaker Lower B (DX)", {"DX/SD", "Guitar Left Speaker Lower B (DX)"},
"Guitar Right Speaker Upper R (DX)", {"DX/SD", "Guitar Right Speaker Upper R (DX)"},
"Guitar Right Speaker Upper G (DX)", {"DX/SD", "Guitar Right Speaker Upper G (DX)"},
"Guitar Right Speaker Upper B (DX)", {"DX/SD", "Guitar Right Speaker Upper B (DX)"},
"Guitar Right Speaker Mid Up Left R (DX)", {"DX/SD", "Guitar Right Speaker Mid Up Left R (DX)"},
"Guitar Right Speaker Mid Up Left G (DX)", {"DX/SD", "Guitar Right Speaker Mid Up Left G (DX)"},
"Guitar Right Speaker Mid Up Left B (DX)", {"DX/SD", "Guitar Right Speaker Mid Up Left B (DX)"},
"Guitar Right Speaker Mid Up Right R (DX)", {"DX/SD", "Guitar Right Speaker Mid Up Right R (DX)"},
"Guitar Right Speaker Mid Up Right G (DX)", {"DX/SD", "Guitar Right Speaker Mid Up Right G (DX)"},
"Guitar Right Speaker Mid Up Right B (DX)", {"DX/SD", "Guitar Right Speaker Mid Up Right B (DX)"},
"Guitar Right Speaker Mid Low Left R (DX)", {"DX/SD", "Guitar Right Speaker Mid Low Left R (DX)"},
"Guitar Right Speaker Mid Low Left G (DX)", {"DX/SD", "Guitar Right Speaker Mid Low Left G (DX)"},
"Guitar Right Speaker Mid Low Left B (DX)", {"DX/SD", "Guitar Right Speaker Mid Low Left B (DX)"},
"Guitar Right Speaker Mid Low Right R (DX)", {"DX/SD", "Guitar Right Speaker Mid Low Right R (DX)"},
"Guitar Right Speaker Mid Low Right G (DX)", {"DX/SD", "Guitar Right Speaker Mid Low Right G (DX)"},
"Guitar Right Speaker Mid Low Right B (DX)", {"DX/SD", "Guitar Right Speaker Mid Low Right B (DX)"},
"Guitar Right Speaker Lower R (DX)", {"DX/SD", "Guitar Right Speaker Lower R (DX)"},
"Guitar Right Speaker Lower G (DX)", {"DX/SD", "Guitar Right Speaker Lower G (DX)"},
"Guitar Right Speaker Lower B (DX)", {"DX/SD", "Guitar Right Speaker Lower B (DX)"},
"Title Average R (Arena)", {"Arena Model", "Title Average R (Arena)"},
"Title Average G (Arena)", {"Arena Model", "Title Average G (Arena)"},
"Title Average B (Arena)", {"Arena Model", "Title Average B (Arena)"},
"Woofer R (Arena)", {"Arena Model", "Woofer R (Arena)"},
"Woofer G (Arena)", {"Arena Model", "Woofer G (Arena)"},
"Woofer B (Arena)", {"Arena Model", "Woofer B (Arena)"},
"Card Reader R (Arena)", {"Arena Model", "Card Reader R (Arena)"},
"Card Reader G (Arena)", {"Arena Model", "Card Reader G (Arena)"},
"Card Reader B (Arena)" {"Arena Model", "Card Reader B (Arena)"}
}
); );
} }
+98 -96
View File
@@ -83,103 +83,105 @@ std::vector<Light> &games::iidx::get_lights() {
if (lights.empty()) { if (lights.empty()) {
lights = GameAPI::Lights::getLights("Beatmania IIDX"); lights = GameAPI::Lights::getLights("Beatmania IIDX");
GameAPI::Lights::sortLights( GameAPI::Lights::sortLightsWithCategory(
&lights, &lights,
"P1 1", {
"P1 2", {"Common", "P1 1"},
"P1 3", {"Common", "P1 2"},
"P1 4", {"Common", "P1 3"},
"P1 5", {"Common", "P1 4"},
"P1 6", {"Common", "P1 5"},
"P1 7", {"Common", "P1 6"},
"P2 1", {"Common", "P1 7"},
"P2 2", {"Common", "P2 1"},
"P2 3", {"Common", "P2 2"},
"P2 4", {"Common", "P2 3"},
"P2 5", {"Common", "P2 4"},
"P2 6", {"Common", "P2 5"},
"P2 7", {"Common", "P2 6"},
"P1 Start", {"Common", "P2 7"},
"P2 Start", {"Common", "P1 Start"},
"VEFX", {"Common", "P2 Start"},
"Effect", {"Common", "VEFX"},
"Spot Light 1", {"Common", "Effect"},
"Spot Light 2", {"DX", "Spot Light 1"},
"Spot Light 3", {"DX", "Spot Light 2"},
"Spot Light 4", {"DX", "Spot Light 3"},
"Spot Light 5", {"DX", "Spot Light 4"},
"Spot Light 6", {"DX", "Spot Light 5"},
"Spot Light 7", {"DX", "Spot Light 6"},
"Spot Light 8", {"DX", "Spot Light 7"},
"Neon Lamp", {"DX", "Spot Light 8"},
"Woofer R", {"DX", "Neon Lamp"},
"Woofer G", {"Lightning Model", "Woofer R"},
"Woofer B", {"Lightning Model", "Woofer G"},
"IC Card Reader P1 R", {"Lightning Model", "Woofer B"},
"IC Card Reader P1 G", {"Lightning Model", "IC Card Reader P1 R"},
"IC Card Reader P1 B", {"Lightning Model", "IC Card Reader P1 G"},
"IC Card Reader P2 R", {"Lightning Model", "IC Card Reader P1 B"},
"IC Card Reader P2 G", {"Lightning Model", "IC Card Reader P2 R"},
"IC Card Reader P2 B", {"Lightning Model", "IC Card Reader P2 G"},
"Turntable P1 R", {"Lightning Model", "IC Card Reader P2 B"},
"Turntable P1 G", {"Lightning Model", "Turntable P1 R"},
"Turntable P1 B", {"Lightning Model", "Turntable P1 G"},
"Turntable P2 R", {"Lightning Model", "Turntable P1 B"},
"Turntable P2 G", {"Lightning Model", "Turntable P2 R"},
"Turntable P2 B", {"Lightning Model", "Turntable P2 G"},
"Turntable P1 Resistance", {"Lightning Model", "Turntable P2 B"},
"Turntable P2 Resistance", {"Lightning Model", "Turntable P1 Resistance"},
"Stage Left Avg R", {"Lightning Model", "Turntable P2 Resistance"},
"Stage Left Avg G", {"Lightning Model", "Stage Left Avg R"},
"Stage Left Avg B", {"Lightning Model", "Stage Left Avg G"},
"Stage Right Avg R", {"Lightning Model", "Stage Left Avg B"},
"Stage Right Avg G", {"Lightning Model", "Stage Right Avg R"},
"Stage Right Avg B", {"Lightning Model", "Stage Right Avg G"},
"Cabinet Left Avg R", {"Lightning Model", "Stage Right Avg B"},
"Cabinet Left Avg G", {"Lightning Model", "Cabinet Left Avg R"},
"Cabinet Left Avg B", {"Lightning Model", "Cabinet Left Avg G"},
"Cabinet Right Avg R", {"Lightning Model", "Cabinet Left Avg B"},
"Cabinet Right Avg G", {"Lightning Model", "Cabinet Right Avg R"},
"Cabinet Right Avg B", {"Lightning Model", "Cabinet Right Avg G"},
"Control Panel Under Avg R", {"Lightning Model", "Cabinet Right Avg B"},
"Control Panel Under Avg G", {"Lightning Model", "Control Panel Under Avg R"},
"Control Panel Under Avg B", {"Lightning Model", "Control Panel Under Avg G"},
"Ceiling Left Avg R", {"Lightning Model", "Control Panel Under Avg B"},
"Ceiling Left Avg G", {"Lightning Model", "Ceiling Left Avg R"},
"Ceiling Left Avg B", {"Lightning Model", "Ceiling Left Avg G"},
"Title Left Avg R", {"Lightning Model", "Ceiling Left Avg B"},
"Title Left Avg G", {"Lightning Model", "Title Left Avg R"},
"Title Left Avg B", {"Lightning Model", "Title Left Avg G"},
"Title Right Avg R", {"Lightning Model", "Title Left Avg B"},
"Title Right Avg G", {"Lightning Model", "Title Right Avg R"},
"Title Right Avg B", {"Lightning Model", "Title Right Avg G"},
"Ceiling Right Avg R", {"Lightning Model", "Title Right Avg B"},
"Ceiling Right Avg G", {"Lightning Model", "Ceiling Right Avg R"},
"Ceiling Right Avg B", {"Lightning Model", "Ceiling Right Avg G"},
"Touch Panel Left Avg R", {"Lightning Model", "Ceiling Right Avg B"},
"Touch Panel Left Avg G", {"Lightning Model", "Touch Panel Left Avg R"},
"Touch Panel Left Avg B", {"Lightning Model", "Touch Panel Left Avg G"},
"Touch Panel Right Avg R", {"Lightning Model", "Touch Panel Left Avg B"},
"Touch Panel Right Avg G", {"Lightning Model", "Touch Panel Right Avg R"},
"Touch Panel Right Avg B", {"Lightning Model", "Touch Panel Right Avg G"},
"Side Panel Left Inner Avg R", {"Lightning Model", "Touch Panel Right Avg B"},
"Side Panel Left Inner Avg G", {"Lightning Model", "Side Panel Left Inner Avg R"},
"Side Panel Left Inner Avg B", {"Lightning Model", "Side Panel Left Inner Avg G"},
"Side Panel Left Outer Avg R", {"Lightning Model", "Side Panel Left Inner Avg B"},
"Side Panel Left Outer Avg G", {"Lightning Model", "Side Panel Left Outer Avg R"},
"Side Panel Left Outer Avg B", {"Lightning Model", "Side Panel Left Outer Avg G"},
"Side Panel Left Avg R", {"Lightning Model", "Side Panel Left Outer Avg B"},
"Side Panel Left Avg G", {"Lightning Model", "Side Panel Left Avg R"},
"Side Panel Left Avg B", {"Lightning Model", "Side Panel Left Avg G"},
"Side Panel Right Outer Avg R", {"Lightning Model", "Side Panel Left Avg B"},
"Side Panel Right Outer Avg G", {"Lightning Model", "Side Panel Right Outer Avg R"},
"Side Panel Right Outer Avg B", {"Lightning Model", "Side Panel Right Outer Avg G"},
"Side Panel Right Inner Avg R", {"Lightning Model", "Side Panel Right Outer Avg B"},
"Side Panel Right Inner Avg G", {"Lightning Model", "Side Panel Right Inner Avg R"},
"Side Panel Right Inner Avg B", {"Lightning Model", "Side Panel Right Inner Avg G"},
"Side Panel Right Avg R", {"Lightning Model", "Side Panel Right Inner Avg B"},
"Side Panel Right Avg G", {"Lightning Model", "Side Panel Right Avg R"},
"Side Panel Right Avg B" {"Lightning Model", "Side Panel Right Avg G"},
{"Lightning Model", "Side Panel Right Avg B"}
}
); );
} }
+71 -69
View File
@@ -65,76 +65,78 @@ std::vector<Light> &games::sdvx::get_lights() {
if (lights.empty()) { if (lights.empty()) {
lights = GameAPI::Lights::getLights("Sound Voltex"); lights = GameAPI::Lights::getLights("Sound Voltex");
GameAPI::Lights::sortLights( GameAPI::Lights::sortLightsWithCategory(
&lights, &lights,
"BT-A", {
"BT-B", {"Common", "BT-A"},
"BT-C", {"Common", "BT-B"},
"BT-D", {"Common", "BT-C"},
"FX-L", {"Common", "BT-D"},
"FX-R", {"Common", "FX-L"},
"Start", {"Common", "FX-R"},
"Wing Left Up R", {"Common", "Start"},
"Wing Left Up G", {"Nemsys", "Wing Left Up R"},
"Wing Left Up B", {"Nemsys", "Wing Left Up G"},
"Wing Right Up R", {"Nemsys", "Wing Left Up B"},
"Wing Right Up G", {"Nemsys", "Wing Right Up R"},
"Wing Right Up B", {"Nemsys", "Wing Right Up G"},
"Wing Left Low R", {"Nemsys", "Wing Right Up B"},
"Wing Left Low G", {"Nemsys", "Wing Left Low R"},
"Wing Left Low B", {"Nemsys", "Wing Left Low G"},
"Wing Right Low R", {"Nemsys", "Wing Left Low B"},
"Wing Right Low G", {"Nemsys", "Wing Right Low R"},
"Wing Right Low B", {"Nemsys", "Wing Right Low G"},
"Woofer R", {"Nemsys", "Wing Right Low B"},
"Woofer G", {"Nemsys", "Woofer R"},
"Woofer B", {"Nemsys", "Woofer G"},
"Controller R", {"Nemsys", "Woofer B"},
"Controller G", {"Nemsys", "Controller R"},
"Controller B", {"Nemsys", "Controller G"},
"Generator R", {"Nemsys", "Controller B"},
"Generator G", {"Nemsys", "Generator R"},
"Generator B", {"Nemsys", "Generator G"},
"Pop", {"Nemsys", "Generator B"},
"Title Left", {"Nemsys", "Pop"},
"Title Right", {"Nemsys", "Title Left"},
"Volume Sound", {"Nemsys", "Title Right"},
"Volume Headphone", {"System", "Volume Sound"},
"Volume External", {"System", "Volume Headphone"},
"Volume Woofer", {"System", "Volume External"},
"IC Card Reader R", {"System", "Volume Woofer"},
"IC Card Reader G", {"Valkyrie", "IC Card Reader R"},
"IC Card Reader B", {"Valkyrie", "IC Card Reader G"},
"Title Avg R", {"Valkyrie", "IC Card Reader B"},
"Title Avg G", {"Valkyrie", "Title Avg R"},
"Title Avg B", {"Valkyrie", "Title Avg G"},
"Upper Left Speaker Avg R", {"Valkyrie", "Title Avg B"},
"Upper Left Speaker Avg G", {"Valkyrie", "Upper Left Speaker Avg R"},
"Upper Left Speaker Avg B", {"Valkyrie", "Upper Left Speaker Avg G"},
"Upper Right Speaker Avg R", {"Valkyrie", "Upper Left Speaker Avg B"},
"Upper Right Speaker Avg G", {"Valkyrie", "Upper Right Speaker Avg R"},
"Upper Right Speaker Avg B", {"Valkyrie", "Upper Right Speaker Avg G"},
"Left Wing Avg R", {"Valkyrie", "Upper Right Speaker Avg B"},
"Left Wing Avg G", {"Valkyrie", "Left Wing Avg R"},
"Left Wing Avg B", {"Valkyrie", "Left Wing Avg G"},
"Right Wing Avg R", {"Valkyrie", "Left Wing Avg B"},
"Right Wing Avg G", {"Valkyrie", "Right Wing Avg R"},
"Right Wing Avg B", {"Valkyrie", "Right Wing Avg G"},
"Lower Left Speaker Avg R", {"Valkyrie", "Right Wing Avg B"},
"Lower Left Speaker Avg G", {"Valkyrie", "Lower Left Speaker Avg R"},
"Lower Left Speaker Avg B", {"Valkyrie", "Lower Left Speaker Avg G"},
"Lower Right Speaker Avg R", {"Valkyrie", "Lower Left Speaker Avg B"},
"Lower Right Speaker Avg G", {"Valkyrie", "Lower Right Speaker Avg R"},
"Lower Right Speaker Avg B", {"Valkyrie", "Lower Right Speaker Avg G"},
"Control Panel Avg R", {"Valkyrie", "Lower Right Speaker Avg B"},
"Control Panel Avg G", {"Valkyrie", "Control Panel Avg R"},
"Control Panel Avg B", {"Valkyrie", "Control Panel Avg G"},
"Woofer Avg R", {"Valkyrie", "Control Panel Avg B"},
"Woofer Avg G", {"Valkyrie", "Woofer Avg R"},
"Woofer Avg B", {"Valkyrie", "Woofer Avg G"},
"V Unit Avg R", {"Valkyrie", "Woofer Avg B"},
"V Unit Avg G", {"Valkyrie", "V Unit Avg R"},
"V Unit Avg B" {"Valkyrie", "V Unit Avg G"},
{"Valkyrie", "V Unit Avg B"}
}
); );
} }
+31 -103
View File
@@ -2532,7 +2532,7 @@ namespace overlay::windows {
} else { } else {
ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Lights"); ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Lights");
} }
ImGui::Separator(); ImGui::Spacing();
auto begin_lights_table = [&]() -> bool { auto begin_lights_table = [&]() -> bool {
if (ImGui::BeginTable("LightsTable", 3, ImGuiTableFlags_Resizable)) { if (ImGui::BeginTable("LightsTable", 3, ImGuiTableFlags_Resizable)) {
@@ -2562,117 +2562,45 @@ namespace overlay::windows {
return; return;
} }
bool is_sdvx = (this->games_selected_name == "Sound Voltex"); // render a section header
bool is_valkyrie = games::sdvx::is_valkyrie_model(); auto render_section_header = [](const std::string &name) {
const float pad = ImGui::GetTextLineHeight() * 0.5f;
auto render_lights = [&](int start, int end) {
if (!begin_lights_table()) {
return;
}
for (int i = start; i < end; i++) {
auto &light = lights->at(i);
build_light(light, &light, i, 0);
int alt_index = 1;
for (auto &alt : light.getAlternatives()) {
if (alt.isValid()) {
build_light(light, &alt, i, alt_index);
}
alt_index++;
}
}
ImGui::EndTable();
};
// render a section header with optional tooltip
auto render_section_header = [](const char *name, const char *tooltip) {
float pad = ImGui::GetTextLineHeight() * 0.5f;
ImGui::Dummy(ImVec2(0, pad)); ImGui::Dummy(ImVec2(0, pad));
ImGui::TextColored(ImVec4(1.f, 0.7f, 0.f, 1.f), "%s", name); ImGui::TextColored(ImVec4(1.f, 0.7f, 0.f, 1.f), "%s", name.c_str());
if (tooltip) {
ImGui::SameLine();
ImGui::HelpMarker(tooltip);
}
ImGui::Separator(); ImGui::Separator();
}; };
if (is_sdvx) { // need to ensure a irst table begins, so current_section must not equal any existing category name
// find section boundaries std::string current_section = "!!invalid!!";
int total = (int)lights->size(); bool table_begin = false;
int idx_buttons = -1, idx_nemsys = -1; for (size_t i = 0; i < lights->size(); i++) {
int idx_valkyrie = -1, idx_others = -1; auto &light = lights->at(i);
for (int i = 0; i < total; i++) {
auto &ln = lights->at(i).getName(); if (current_section != light.getCategory()) {
if (ln == "BT-A") { current_section = light.getCategory();
idx_buttons = i; if (table_begin) {
} else if (ln == "Wing Left Up R") { ImGui::EndTable();
idx_nemsys = i; }
} else if (ln == "IC Card Reader R") {
idx_valkyrie = i; render_section_header(current_section.empty() ? "Uncategorized" : current_section);
} else if (ln == "Volume Sound") {
idx_others = i; table_begin = begin_lights_table();
if (!table_begin) {
break;
} }
} }
// compute end index for each section build_light(light, &light, i, 0);
auto next_boundary = [&](int after) -> int { int alt_index = 1;
int result = total; for (auto &alt : light.getAlternatives()) {
for (int c : {idx_buttons, idx_nemsys, if (alt.isValid()) {
idx_valkyrie, idx_others}) { build_light(light, &alt, i, alt_index);
if (c > after && c < result) {
result = c;
}
} }
return result; alt_index++;
};
// buttons always first
if (idx_buttons >= 0) {
render_section_header("Buttons", nullptr);
render_lights(idx_buttons,
next_boundary(idx_buttons));
} }
}
// swap valkyrie and nemsys lights depending on spec if (table_begin) {
struct Section { ImGui::EndTable();
const char *name;
const char *tooltip;
int start;
int end;
};
Section valkyrie = {
"Valkyrie Lights",
"Valkyrie (G/H spec) / BI2X ONLY.\nWon't work in Nemsys mode.",
idx_valkyrie,
(idx_valkyrie >= 0) ? next_boundary(idx_valkyrie) : 0
};
Section nemsys = {
"Nemsys Lights",
"Nemsys (F spec) / BI2A ONLY.\nWon't work in Valkyrie mode.",
idx_nemsys,
(idx_nemsys >= 0) ? next_boundary(idx_nemsys) : 0
};
Section first = nemsys, second = valkyrie;
if (is_valkyrie) {
first = valkyrie;
second = nemsys;
}
if (first.start >= 0) {
render_section_header(first.name, first.tooltip);
render_lights(first.start, first.end);
}
if (second.start >= 0) {
render_section_header(second.name, second.tooltip);
render_lights(second.start, second.end);
}
// others always last
if (idx_others >= 0) {
render_section_header("Others", nullptr);
render_lights(idx_others, next_boundary(idx_others));
}
} else {
render_lights(0, (int)lights->size());
} }
} }