From a257a6a16db3e1a26bd291ba50b6a5a7dd0b8b5e Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 9 Apr 2026 07:11:00 -0400 Subject: [PATCH 1/6] fix: support hex color codes in Configurator effect setup (@dekay) --- src/ledcontrol/setup/Configurator.cpp | 145 ++++++++++++++++++++++---- 1 file changed, 122 insertions(+), 23 deletions(-) diff --git a/src/ledcontrol/setup/Configurator.cpp b/src/ledcontrol/setup/Configurator.cpp index 897b90b..8e2e37e 100644 --- a/src/ledcontrol/setup/Configurator.cpp +++ b/src/ledcontrol/setup/Configurator.cpp @@ -59,6 +59,7 @@ #include "../../table/TableElementList.h" #include "../../table/TableElementData.h" #include "../../table/TableElementTypeEnum.h" +#include "../loader/ColorConfig.h" #include #include #include @@ -326,7 +327,27 @@ void Configurator::SetupTable( if (rgbaMatrixToy != nullptr) { + RGBAColor activeColor; + bool hasColor = false; if (tcs->GetColorConfig() != nullptr) + { + ColorConfig* colorConfig = tcs->GetColorConfig(); + activeColor = RGBAColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha()); + hasColor = true; + } + else + { + if (!StringExtensions::IsNullOrWhiteSpace(tcs->GetColorName())) + { + if (StringExtensions::StartsWith(tcs->GetColorName(), "#")) + { + if (activeColor.SetColor(tcs->GetColorName())) + hasColor = true; + } + } + } + + if (hasColor) { if (tcs->HasAreaDirection()) { @@ -338,8 +359,6 @@ void Configurator::SetupTable( int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; shiftEffect->SetLayerNr(layer); - ColorConfig* colorConfig = tcs->GetColorConfig(); - RGBAColor activeColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha()); RGBAColor inactiveColor = activeColor; inactiveColor.SetAlpha(0); shiftEffect->SetActiveColor(activeColor); @@ -367,8 +386,7 @@ void Configurator::SetupTable( int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; flickerEffect->SetLayerNr(layer); - ColorConfig* colorConfig = tcs->GetColorConfig(); - flickerEffect->SetActiveColor(RGBAColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha())); + flickerEffect->SetActiveColor(activeColor); flickerEffect->SetInactiveColor(RGBAColor(0, 0, 0, 0)); flickerEffect->SetDensity(MathExtensions::Limit(tcs->GetAreaFlickerDensity(), 1, 99)); if (tcs->GetAreaFlickerMinDurationMs() > 0) @@ -398,24 +416,64 @@ void Configurator::SetupTable( int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; plasmaEffect->SetLayerNr(layer); - ColorConfig* colorConfig = tcs->GetColorConfig(); RGBAColor activeColor1; RGBAColor activeColor2; RGBAColor inactiveColor; + bool hasColor1 = false; + bool hasColor2 = false; - if (colorConfig != nullptr) + if (tcs->GetColorConfig() != nullptr) + { + ColorConfig* colorConfig = tcs->GetColorConfig(); activeColor1 = RGBAColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha()); + hasColor1 = true; + } else - activeColor1 = RGBAColor(0xff, 0, 0, 0xff); + { + if (!StringExtensions::IsNullOrWhiteSpace(tcs->GetColorName())) + { + if (StringExtensions::StartsWith(tcs->GetColorName(), "#")) + { + if (activeColor1.SetColor(tcs->GetColorName())) + hasColor1 = true; + } + } + } - ColorConfig* colorConfig2 = tcs->GetColorConfig2(); - if (colorConfig2 != nullptr) + if (tcs->GetColorConfig2() != nullptr) + { + ColorConfig* colorConfig2 = tcs->GetColorConfig2(); activeColor2 = RGBAColor(colorConfig2->GetRed(), colorConfig2->GetGreen(), colorConfig2->GetBlue(), colorConfig2->GetAlpha()); + hasColor2 = true; + } else - activeColor2 = RGBAColor(0, 0xff, 0, 0xff); + { + if (!StringExtensions::IsNullOrWhiteSpace(tcs->GetColorName2())) + { + if (StringExtensions::StartsWith(tcs->GetColorName2(), "#")) + { + if (activeColor2.SetColor(tcs->GetColorName2())) + hasColor2 = true; + } + } + } - inactiveColor = activeColor1; - inactiveColor.SetAlpha(0); + if (hasColor1) + { + inactiveColor = activeColor1; + inactiveColor.SetAlpha(0); + } + else if (hasColor2) + { + inactiveColor = activeColor2; + inactiveColor.SetAlpha(0); + } + + if (!hasColor1) + activeColor1 = RGBAColor(0xff, 0, 0, 0xff); + + if (!hasColor2) + activeColor2 = RGBAColor(0, 0xff, 0, 0xff); plasmaEffect->SetActiveColor(activeColor1); plasmaEffect->SetSecondaryColor(activeColor2); @@ -435,8 +493,26 @@ void Configurator::SetupTable( } else if (!tcs->GetShapeName().empty()) { - ColorConfig* colorConfig = tcs->GetColorConfig(); - if (colorConfig != nullptr) + RGBAColor shapeColor; + bool hasShapeColor = false; + if (tcs->GetColorConfig() != nullptr) + { + ColorConfig* colorConfig = tcs->GetColorConfig(); + shapeColor = RGBAColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha()); + hasShapeColor = true; + } + else + { + if (!StringExtensions::IsNullOrWhiteSpace(tcs->GetColorName())) + { + if (StringExtensions::StartsWith(tcs->GetColorName(), "#")) + { + if (shapeColor.SetColor(tcs->GetColorName())) + hasShapeColor = true; + } + } + } + if (hasShapeColor) { RGBAMatrixColorScaleShapeEffect* shapeEffect = new RGBAMatrixColorScaleShapeEffect(); effectName = StringExtensions::Build("Ledwiz {0} Column {1} Setting {2} RGBAMatrixColorScaleShapeEffect", std::to_string(ledWizNr), @@ -447,7 +523,7 @@ void Configurator::SetupTable( shapeEffect->SetLayerNr(layer); shapeEffect->SetShapeName(tcs->GetShapeName()); - RGBAColor activeColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha()); + RGBAColor activeColor = shapeColor; RGBAColor inactiveColor = activeColor; inactiveColor.SetAlpha(0); shapeEffect->SetActiveColor(activeColor); @@ -611,8 +687,6 @@ void Configurator::SetupTable( } else { - ColorConfig* colorConfig = tcs->GetColorConfig(); - RGBAColor activeColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha()); RGBAColor inactiveColor = activeColor; inactiveColor.SetAlpha(0); @@ -641,8 +715,8 @@ void Configurator::SetupTable( } else { - Log::Warning(StringExtensions::Build("No color valid color definition found for area effect. Skipped setting {0} in column {1} for LedWizEqivalent number {2}", - std::to_string(settingNumber), std::to_string(tcc->GetNumber()), std::to_string(ledWizNr))); + Log::Warning(StringExtensions::Build("Invalid color definition \"{0}\" found for area effect. Skipped setting {1} in column {2} for LedWizEqivalent number {3}.", + tcs->GetColorName(), std::to_string(settingNumber), std::to_string(tcc->GetNumber()), std::to_string(ledWizNr))); continue; } } @@ -740,7 +814,35 @@ void Configurator::SetupTable( } else if (rgbaToy != nullptr) { + RGBAColor rgbaActiveColor; + bool hasRgbaColor = false; if (tcs->GetColorConfig() != nullptr) + { + ColorConfig* colorConfig = tcs->GetColorConfig(); + rgbaActiveColor = RGBAColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha()); + hasRgbaColor = true; + } + else + { + if (!StringExtensions::IsNullOrWhiteSpace(tcs->GetColorName())) + { + if (StringExtensions::StartsWith(tcs->GetColorName(), "#")) + { + if (rgbaActiveColor.SetColor(tcs->GetColorName())) + hasRgbaColor = true; + else + Log::Warning(StringExtensions::Build("Skipped setting {0} in column {1} for LedWizEqivalent number {2} since {3} is not a valid color specification.", + std::to_string(settingNumber), std::to_string(tcc->GetNumber()), std::to_string(ledWizNr), tcs->GetColorName())); + } + else + Log::Warning(StringExtensions::Build("Skipped setting {0} in column {1} for LedWizEqivalent number {2} since {3} is not a valid color specification.", + std::to_string(settingNumber), std::to_string(tcc->GetNumber()), std::to_string(ledWizNr), tcs->GetColorName())); + } + else + Log::Warning(StringExtensions::Build("Skipped setting {0} in column {1} for LedWizEqivalent number {2} since it does not contain a color specification.", + std::to_string(settingNumber), std::to_string(tcc->GetNumber()), std::to_string(ledWizNr))); + } + if (hasRgbaColor) { RGBAColorEffect* rgbaEffect = new RGBAColorEffect(); effectName = StringExtensions::Build( @@ -748,8 +850,7 @@ void Configurator::SetupTable( rgbaEffect->SetName(effectName); rgbaEffect->SetToyName(toy->GetName()); - ColorConfig* colorConfig = tcs->GetColorConfig(); - rgbaEffect->SetActiveColor(RGBAColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha())); + rgbaEffect->SetActiveColor(rgbaActiveColor); rgbaEffect->SetInactiveColor(RGBAColor(0, 0, 0, 0)); rgbaEffect->SetFadeMode(tcs->GetBlink() > 0 ? FadeModeEnum::OnOff : FadeModeEnum::Fade); @@ -757,8 +858,6 @@ void Configurator::SetupTable( } else { - Log::Warning(StringExtensions::Build("Skipped setting {0} in column {1} for LedWizEqivalent number {2} since it does not contain a color specification.", - std::to_string(settingNumber), std::to_string(tcc->GetNumber()), std::to_string(ledWizNr))); continue; } } From ddd6aec350a38fb6d3c90b36be1237d9009a468a Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 9 Apr 2026 07:12:07 -0400 Subject: [PATCH 2/6] misc: more C# alignment with review-csharp skill --- src/Pinball.cpp | 2 - src/cab/out/OutputControllerCompleteBase.cpp | 1 - src/cab/overrides/TableOverrideSetting.cpp | 3 - src/cab/sequencer/SequentialOutputSetting.cpp | 1 - src/cab/toys/ToyList.cpp | 2 - src/cab/toys/hardware/Motor.cpp | 10 - src/cab/toys/layer/MatrixDictionaryBase.h | 3 - src/cab/toys/layer/RGBAToy.cpp | 1 - .../toys/lwequivalent/LedWizEquivalent.cpp | 1 - src/cab/toys/virtual/ToyGroupBase.h | 8 - src/fx/EffectList.cpp | 1 - src/fx/matrixfx/MatrixPlasmaEffectBase.h | 4 - src/general/color/ColorList.cpp | 1 - src/general/color/ColorScale.cpp | 3 - src/general/color/RGBAColor.cpp | 1 - src/ledcontrol/loader/LedControlConfig.cpp | 2 - .../loader/TableConfigColumnList.cpp | 62 +- src/ledcontrol/loader/TableConfigSetting.cpp | 5 - src/ledcontrol/setup/Configurator.cpp | 671 +++++++++--------- 19 files changed, 364 insertions(+), 418 deletions(-) diff --git a/src/Pinball.cpp b/src/Pinball.cpp index d826566..d61f775 100644 --- a/src/Pinball.cpp +++ b/src/Pinball.cpp @@ -441,7 +441,6 @@ void Pinball::MainThreadDoIt() { try { - auto now = std::chrono::steady_clock::now(); updateRequired |= m_alarms->ExecuteAlarms(now + std::chrono::milliseconds(1)); } @@ -465,7 +464,6 @@ void Pinball::MainThreadDoIt() if (m_keepMainThreadAlive) { - auto nextAlarm = m_alarms->GetNextAlarmTime(); auto now = std::chrono::steady_clock::now(); diff --git a/src/cab/out/OutputControllerCompleteBase.cpp b/src/cab/out/OutputControllerCompleteBase.cpp index d70250b..23ebcd2 100644 --- a/src/cab/out/OutputControllerCompleteBase.cpp +++ b/src/cab/out/OutputControllerCompleteBase.cpp @@ -339,7 +339,6 @@ void OutputControllerCompleteBase::UpdaterThreadDoIt() if (m_keepUpdaterThreadAlive) { - std::unique_lock lock(m_conditionMutex); m_updateCondition.wait_for(lock, std::chrono::milliseconds(50), [this] { return !m_keepUpdaterThreadAlive || m_updateRequired; }); } diff --git a/src/cab/overrides/TableOverrideSetting.cpp b/src/cab/overrides/TableOverrideSetting.cpp index 8cd603c..67b2fd8 100644 --- a/src/cab/overrides/TableOverrideSetting.cpp +++ b/src/cab/overrides/TableOverrideSetting.cpp @@ -41,7 +41,6 @@ void TableOverrideSetting::ParseRoms() while (std::getline(ss, item, ',')) { - item.erase(0, item.find_first_not_of(" \t")); item.erase(item.find_last_not_of(" \t") + 1); @@ -70,7 +69,6 @@ void TableOverrideSetting::ParseTables() while (std::getline(ss, item, ',')) { - item.erase(0, item.find_first_not_of(" \t")); item.erase(item.find_last_not_of(" \t") + 1); @@ -91,7 +89,6 @@ void TableOverrideSetting::AddTableOverrideSettingDevice(TableOverrideSettingDev void TableOverrideSetting::ClearTableOverrideSettingDevices() { - for (auto* device : m_tableOverrideSettingDeviceList) { delete device; diff --git a/src/cab/sequencer/SequentialOutputSetting.cpp b/src/cab/sequencer/SequentialOutputSetting.cpp index 53d4d0e..640937c 100644 --- a/src/cab/sequencer/SequentialOutputSetting.cpp +++ b/src/cab/sequencer/SequentialOutputSetting.cpp @@ -38,7 +38,6 @@ int SequentialOutputDevice::GetNextOutput(int currentOutputNumber) } else { - m_outputIndex = 0; m_outputTimestamp = now; return m_outputNumbers[m_outputIndex]; diff --git a/src/cab/toys/ToyList.cpp b/src/cab/toys/ToyList.cpp index e56453e..c4fccb6 100644 --- a/src/cab/toys/ToyList.cpp +++ b/src/cab/toys/ToyList.cpp @@ -13,7 +13,6 @@ ToyList::ToyList() { } ToyList::~ToyList() { - for (IToy* toy : *this) delete toy; clear(); @@ -85,7 +84,6 @@ void ToyList::UpdateToys() { if (toy != nullptr) { - IToyUpdatable* updatableToy = dynamic_cast(toy); if (updatableToy != nullptr) { diff --git a/src/cab/toys/hardware/Motor.cpp b/src/cab/toys/hardware/Motor.cpp index 5c1079a..96daf39 100644 --- a/src/cab/toys/hardware/Motor.cpp +++ b/src/cab/toys/hardware/Motor.cpp @@ -69,13 +69,10 @@ void Motor::UpdateOutputs() { if (m_currentMotorPower == 0) { - if (p > 0) { - if (m_kickstartDurationMs > 0 && m_kickstartPower > 0 && p <= m_kickstartPower) { - m_targetMotorPower = p; if (!m_kickstartActive) @@ -91,7 +88,6 @@ void Motor::UpdateOutputs() } else { - m_currentMotorPower = p; m_targetMotorPower = p; output->SetOutput(static_cast(p)); @@ -105,15 +101,12 @@ void Motor::UpdateOutputs() } else if (m_kickstartActive) { - if (p > 0) { - m_targetMotorPower = p; } else { - if (m_alarmHandler != nullptr) { } @@ -124,10 +117,8 @@ void Motor::UpdateOutputs() } else { - if (p == 0) { - if (m_alarmHandler != nullptr) { } @@ -137,7 +128,6 @@ void Motor::UpdateOutputs() } else if (p != m_currentMotorPower) { - m_currentMotorPower = p; m_targetMotorPower = p; output->SetOutput(static_cast(p)); diff --git a/src/cab/toys/layer/MatrixDictionaryBase.h b/src/cab/toys/layer/MatrixDictionaryBase.h index a5d28b9..29e7ab4 100644 --- a/src/cab/toys/layer/MatrixDictionaryBase.h +++ b/src/cab/toys/layer/MatrixDictionaryBase.h @@ -76,7 +76,6 @@ template MatrixElementType* MatrixDictionaryBase void MatrixDictionaryBase::SetLayer(int layerNr, MatrixElementType* data) { - auto it = this->find(layerNr); if (it != this->end()) { @@ -93,7 +92,6 @@ template void MatrixDictionaryBase void MatrixDictionaryBase ToyGroupBase::~ToyGroup template void ToyGroupBase::Init(Cabinet* cabinet) { - - InitializeToyMatrix(cabinet); - m_layers = LayerDictionary(m_width, m_height); } @@ -76,7 +73,6 @@ template void ToyGroupBase::Upda template void ToyGroupBase::UpdateOutputs() { - std::vector layerNumbers = m_layers.GetLayerNumbers(); for (int layerNr : layerNumbers) @@ -92,7 +88,6 @@ template void ToyGroupBase::Upda { if (y < static_cast(m_toys.size()) && x < static_cast(m_toys[y].size()) && m_toys[y][x] != nullptr) { - LayerDictionary& targetLayers = m_toys[y][x]->GetLayers(); MatrixElementType* targetLayer = targetLayers.GetOrCreateLayer(targetLayerNr, 1); if (targetLayer != nullptr) @@ -142,7 +137,6 @@ template void ToyGroupBase::Init if (m_height > 0) { - for (const auto& row : m_toyNames) { m_width = std::max(m_width, static_cast(row.size())); @@ -151,7 +145,6 @@ template void ToyGroupBase::Init if (m_height == 0 || m_width == 0) { - m_height = 1; m_width = 1; m_toyNames = { { "" } }; @@ -169,7 +162,6 @@ template void ToyGroupBase::Init { if (y < static_cast(m_toyNames.size()) && x < static_cast(m_toyNames[y].size()) && !m_toyNames[y][x].empty()) { - IToy* toy = cabinet->GetToys()->FindByName(m_toyNames[y][x]); ILayerToy* layerToy = dynamic_cast*>(toy); m_toys[y][x] = layerToy; diff --git a/src/fx/EffectList.cpp b/src/fx/EffectList.cpp index 826b49b..396aacb 100644 --- a/src/fx/EffectList.cpp +++ b/src/fx/EffectList.cpp @@ -67,7 +67,6 @@ bool EffectList::FromXml(const tinyxml2::XMLElement* element) IEffect* effect = factory.CreateEffect(typeName); if (effect) { - if (effect->FromXml(effectElement)) { Add(effect); diff --git a/src/fx/matrixfx/MatrixPlasmaEffectBase.h b/src/fx/matrixfx/MatrixPlasmaEffectBase.h index eec0062..819bf3b 100644 --- a/src/fx/matrixfx/MatrixPlasmaEffectBase.h +++ b/src/fx/matrixfx/MatrixPlasmaEffectBase.h @@ -146,20 +146,16 @@ template void MatrixPlasmaEffectBase double MatrixPlasmaEffectBase::CalculatePlasmaIntensity(int x, int y, double time) { - double normX = (double)(x - this->m_areaLeft) / (double)this->GetAreaWidth(); double normY = (double)(y - this->m_areaTop) / (double)this->GetAreaHeight(); - double densityFactor = m_plasmaDensity / 50.0; - double plasma1 = std::sin(normX * 10.0 * densityFactor + time); double plasma2 = std::sin(normY * 10.0 * densityFactor + time * 1.3); double plasma3 = std::sin((normX + normY) * 8.0 * densityFactor + time * 0.7); double plasma4 = std::sin(std::sqrt(normX * normX + normY * normY) * 12.0 * densityFactor + time * 1.1); - double combined = (plasma1 + plasma2 + plasma3 + plasma4) / 4.0; return (combined + 1.0) / 2.0; } diff --git a/src/general/color/ColorList.cpp b/src/general/color/ColorList.cpp index 942fad3..1f271ec 100644 --- a/src/general/color/ColorList.cpp +++ b/src/general/color/ColorList.cpp @@ -22,7 +22,6 @@ void ColorList::UpdateIndex() void ColorList::Add(const RGBAColorNamed& color) { - if (!color.GetName().empty() && Contains(color.GetName())) { return; diff --git a/src/general/color/ColorScale.cpp b/src/general/color/ColorScale.cpp index 833ed4c..6201591 100644 --- a/src/general/color/ColorScale.cpp +++ b/src/general/color/ColorScale.cpp @@ -28,7 +28,6 @@ ColorScale::ColorScale(double hue, double saturation, double brightness, int alp RGBAColor ColorScale::ApplyScale(const RGBAColor& baseColor) const { - int r = MathExtensions::Limit((int)((float)baseColor.GetRed() * m_color.GetRed() / 255), 0, 255); int g = MathExtensions::Limit((int)((float)baseColor.GetGreen() * m_color.GetGreen() / 255), 0, 255); int b = MathExtensions::Limit((int)((float)baseColor.GetBlue() * m_color.GetBlue() / 255), 0, 255); @@ -39,7 +38,6 @@ RGBAColor ColorScale::ApplyScale(const RGBAColor& baseColor) const RGBAColor ColorScale::ApplyScale(const PixelData& pixel) const { - RGBAColor baseColor(pixel.red, pixel.green, pixel.blue, pixel.alpha); return ApplyScale(baseColor); } @@ -158,7 +156,6 @@ void ColorScale::RGBToHSB(int r, int g, int b, double& h, double& s, double& br) void ColorScale::HSBToRGB(double h, double s, double br, int& r, int& g, int& b) { - h = std::fmod(h, 360.0); if (h < 0.0) h += 360.0; diff --git a/src/general/color/RGBAColor.cpp b/src/general/color/RGBAColor.cpp index b11673e..2e3049d 100644 --- a/src/general/color/RGBAColor.cpp +++ b/src/general/color/RGBAColor.cpp @@ -64,7 +64,6 @@ bool RGBAColor::SetColor(const RGBColor& color) bool RGBAColor::SetColor(const std::string& color) { - if ((color.length() == 8 && IsHexString(color)) || (color.length() == 9 && color[0] == '#' && IsHexString(color, 1))) { int offset = (color[0] == '#') ? 1 : 0; diff --git a/src/ledcontrol/loader/LedControlConfig.cpp b/src/ledcontrol/loader/LedControlConfig.cpp index 0372875..34e1db9 100644 --- a/src/ledcontrol/loader/LedControlConfig.cpp +++ b/src/ledcontrol/loader/LedControlConfig.cpp @@ -81,7 +81,6 @@ void LedControlConfig::ParseLedControlIni(const std::string& ledControlIniFilena { if (StringExtensions::StartsWith(iniLine, "[") && StringExtensions::EndsWith(iniLine, "]") && iniLine.length() > 2) { - if (!StringExtensions::IsNullOrWhiteSpace(sectionHeader)) { if (sections.find(sectionHeader) != sections.end()) @@ -104,7 +103,6 @@ void LedControlConfig::ParseLedControlIni(const std::string& ledControlIniFilena } else { - sectionData.push_back(iniLine); } } diff --git a/src/ledcontrol/loader/TableConfigColumnList.cpp b/src/ledcontrol/loader/TableConfigColumnList.cpp index 03dda76..f04209b 100644 --- a/src/ledcontrol/loader/TableConfigColumnList.cpp +++ b/src/ledcontrol/loader/TableConfigColumnList.cpp @@ -9,69 +9,69 @@ namespace DOF void TableConfigColumnList::ParseControlData(const std::string& ledControlData, bool throwExceptions) { - std::vector Cols = SplitColumns(ledControlData); - if (Cols.size() < 2) + std::vector cols = SplitColumns(ledControlData); + if (cols.size() < 2) { Log::Warning(StringExtensions::Build("No data to parse found in LedControlData: {0}", ledControlData)); if (throwExceptions) throw std::runtime_error(StringExtensions::Build("No data to parse found in LedControlData: {0}", ledControlData)); return; } - int FirstOutputNumber = 1; - int LastColumnWithData = -1; - for (int i = 1; i < static_cast(Cols.size()); i++) + int firstOutputNumber = 1; + int lastColumnWithData = -1; + for (int i = 1; i < static_cast(cols.size()); i++) { - if (!StringExtensions::IsNullOrWhiteSpace(Cols[i])) - LastColumnWithData = i; + if (!StringExtensions::IsNullOrWhiteSpace(cols[i])) + lastColumnWithData = i; } - for (int i = 1; i <= LastColumnWithData; i++) + for (int i = 1; i <= lastColumnWithData; i++) { - TableConfigColumn* C = new TableConfigColumn(); - C->SetNumber(i); - C->SetFirstOutputNumber(FirstOutputNumber); - bool ParseOK = C->ParseColumnData(Cols[i], false); - if (!ParseOK) + TableConfigColumn* c = new TableConfigColumn(); + c->SetNumber(i); + c->SetFirstOutputNumber(firstOutputNumber); + bool parseOK = c->ParseColumnData(cols[i], false); + if (!parseOK) { Log::Warning(StringExtensions::Build("Previous exceptions occured in the line {0} of the ledcontrol file", ledControlData)); if (throwExceptions) { - delete C; + delete c; throw std::runtime_error(StringExtensions::Build("Exception(s) occured when parsing {0}", ledControlData)); } } - push_back(C); + push_back(c); - FirstOutputNumber += C->GetRequiredOutputCount(); + firstOutputNumber += c->GetRequiredOutputCount(); } } std::vector TableConfigColumnList::SplitColumns(const std::string& configData) { - std::vector L; + std::vector l; - int BracketCount = 0; + int bracketCount = 0; - int LP = 0; + int lp = 0; - for (int P = 0; P < static_cast(configData.length()); P++) + for (int p = 0; p < static_cast(configData.length()); p++) { - if (configData[P] == '(') - BracketCount++; - else if (configData[P] == ')') - BracketCount--; - if (configData[P] == ',' && BracketCount <= 0) + if (configData[p] == '(') + bracketCount++; + else if (configData[p] == ')') + bracketCount--; + if (configData[p] == ',' && bracketCount <= 0) { - L.push_back(configData.substr(LP, P - LP)); - LP = P + 1; - BracketCount = 0; + l.push_back(configData.substr(lp, p - lp)); + lp = p + 1; + bracketCount = 0; } } - if (LP < static_cast(configData.length())) - L.push_back(configData.substr(LP)); + if (lp < static_cast(configData.length())) + l.push_back(configData.substr(lp)); - return L; + return l; } void TableConfigColumnList::Sort() diff --git a/src/ledcontrol/loader/TableConfigSetting.cpp b/src/ledcontrol/loader/TableConfigSetting.cpp index 7646ecb..e5aec62 100644 --- a/src/ledcontrol/loader/TableConfigSetting.cpp +++ b/src/ledcontrol/loader/TableConfigSetting.cpp @@ -123,7 +123,6 @@ void TableConfigSetting::ParseSettingData(const std::string& settingData) if (StringExtensions::StartsWith(s, "(")) { - int bracketCnt = 1; int closingBracketPos = -1; for (size_t i = 1; i < s.length(); i++) @@ -154,7 +153,6 @@ void TableConfigSetting::ParseSettingData(const std::string& settingData) } else { - if (s.length() == 0) { Log::Warning("No data to parse."); @@ -198,7 +196,6 @@ void TableConfigSetting::ParseSettingData(const std::string& settingData) } else { - std::vector tableElements = StringExtensions::Split(trigger, { '|' }); for (const std::string& element : tableElements) { @@ -207,7 +204,6 @@ void TableConfigSetting::ParseSettingData(const std::string& settingData) { if (e[0] == (char)TableElementTypeEnum::NamedElement) { - bool validNamed = true; for (size_t j = 1; j < e.length(); j++) { @@ -226,7 +222,6 @@ void TableConfigSetting::ParseSettingData(const std::string& settingData) } else { - bool validType = false; TableElementTypeEnum elementType = (TableElementTypeEnum)e[0]; switch (elementType) diff --git a/src/ledcontrol/setup/Configurator.cpp b/src/ledcontrol/setup/Configurator.cpp index 8e2e37e..b747e3f 100644 --- a/src/ledcontrol/setup/Configurator.cpp +++ b/src/ledcontrol/setup/Configurator.cpp @@ -307,7 +307,6 @@ void Configurator::SetupTable( for (TableConfigColumn* tcc : *tc->GetColumns()) { - if (toyAssignments.at(ledWizNr).find(tcc->GetNumber()) != toyAssignments.at(ledWizNr).end()) { IToy* toy = toyAssignments.at(ledWizNr).at(tcc->GetNumber()); @@ -325,88 +324,206 @@ void Configurator::SetupTable( IRGBAToy* rgbaToy = dynamic_cast(toy); IAnalogAlphaToy* analogToy = dynamic_cast(toy); - if (rgbaMatrixToy != nullptr) + if (rgbaMatrixToy != nullptr || analogMatrixToy != nullptr) { - RGBAColor activeColor; - bool hasColor = false; - if (tcs->GetColorConfig() != nullptr) - { - ColorConfig* colorConfig = tcs->GetColorConfig(); - activeColor = RGBAColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha()); - hasColor = true; - } - else + if (!tcs->GetShapeName().empty()) { - if (!StringExtensions::IsNullOrWhiteSpace(tcs->GetColorName())) + if (rgbaMatrixToy != nullptr) { - if (StringExtensions::StartsWith(tcs->GetColorName(), "#")) + RGBAColor activeColor; + bool hasColor = false; + if (tcs->GetColorConfig() != nullptr) { - if (activeColor.SetColor(tcs->GetColorName())) - hasColor = true; + ColorConfig* colorConfig = tcs->GetColorConfig(); + activeColor = RGBAColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha()); + hasColor = true; + } + else + { + if (!StringExtensions::IsNullOrWhiteSpace(tcs->GetColorName())) + { + if (StringExtensions::StartsWith(tcs->GetColorName(), "#")) + { + if (activeColor.SetColor(tcs->GetColorName())) + hasColor = true; + } + } } - } - } - if (hasColor) - { - if (tcs->HasAreaDirection()) - { - RGBAMatrixShiftEffect* shiftEffect = new RGBAMatrixShiftEffect(); - effectName = StringExtensions::Build( - "Ledwiz {0:00} Column {1:00} Setting {2:00} RGBAMatrixShiftEffect", std::to_string(ledWizNr), std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - shiftEffect->SetName(effectName); - shiftEffect->SetToyName(toy->GetName()); - int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - shiftEffect->SetLayerNr(layer); + if (hasColor) + { + RGBAMatrixColorScaleShapeEffect* shapeEffect = new RGBAMatrixColorScaleShapeEffect(); + effectName = StringExtensions::Build("Ledwiz {0} Column {1} Setting {2} RGBAMatrixColorScaleShapeEffect", std::to_string(ledWizNr), + std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); + shapeEffect->SetName(effectName); + shapeEffect->SetToyName(toy->GetName()); + int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; + shapeEffect->SetLayerNr(layer); + shapeEffect->SetShapeName(tcs->GetShapeName()); + + RGBAColor inactiveColor = activeColor; + inactiveColor.SetAlpha(0); + shapeEffect->SetActiveColor(activeColor); + shapeEffect->SetInactiveColor(inactiveColor); + + if (tcs->IsArea()) + { + shapeEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + shapeEffect->SetTop(static_cast(tcs->GetAreaTop())); + shapeEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + shapeEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + } - RGBAColor inactiveColor = activeColor; - inactiveColor.SetAlpha(0); - shiftEffect->SetActiveColor(activeColor); - shiftEffect->SetInactiveColor(inactiveColor); - shiftEffect->SetShiftDirection(tcs->GetAreaDirection()); - shiftEffect->SetShiftAcceleration(tcs->GetAreaAcceleration()); + effect = static_cast(shapeEffect); + } + else + { + RGBAMatrixShapeEffect* shapeEffect = new RGBAMatrixShapeEffect(); + effectName = StringExtensions::Build( + "Ledwiz {0} Column {1} Setting {2} RGBAMatrixShapeEffect", std::to_string(ledWizNr), std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); + shapeEffect->SetName(effectName); + shapeEffect->SetToyName(toy->GetName()); + int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; + shapeEffect->SetLayerNr(layer); + shapeEffect->SetShapeName(tcs->GetShapeName()); - if (tcs->GetAreaSpeed() > 0) - shiftEffect->SetShiftSpeed(tcs->GetAreaSpeed()); + if (tcs->IsArea()) + { + shapeEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + shapeEffect->SetTop(static_cast(tcs->GetAreaTop())); + shapeEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + shapeEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + } - shiftEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - shiftEffect->SetTop(static_cast(tcs->GetAreaTop())); - shiftEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - shiftEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + effect = static_cast(shapeEffect); + } + } + } + else if (tcs->IsBitmap()) + { + std::string p; + if (table->GetShapeDefinitions() && table->GetShapeDefinitions()->GetBitmapFilePattern()) + { + p = table->GetShapeDefinitions()->GetBitmapFilePattern()->GetPattern(); + } + else + { + std::string pathSeparator(1, PATH_SEPARATOR_CHAR); + p = StringExtensions::Build("{0}{1}{2}.*", iniFilePath, pathSeparator, tc->GetShortRomName()); + } - effect = static_cast(shiftEffect); + if (tcs->GetAreaBitmapAnimationStepCount() > 1) + { + if (rgbaMatrixToy != nullptr) + { + RGBAMatrixBitmapAnimationEffect* bitmapAnimationEffect = new RGBAMatrixBitmapAnimationEffect(); + effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} RGBAMatrixBitmapAnimationEffect", std::to_string(ledWizNr), + std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); + bitmapAnimationEffect->SetName(effectName); + bitmapAnimationEffect->SetToyName(toy->GetName()); + int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; + bitmapAnimationEffect->SetLayerNr(layer); + FilePattern* filePattern = new FilePattern(p); + bitmapAnimationEffect->SetBitmapFilePattern(filePattern); + bitmapAnimationEffect->SetBitmapLeft(tcs->GetAreaBitmapLeft()); + bitmapAnimationEffect->SetBitmapTop(tcs->GetAreaBitmapTop()); + bitmapAnimationEffect->SetBitmapHeight(tcs->GetAreaBitmapHeight()); + bitmapAnimationEffect->SetBitmapWidth(tcs->GetAreaBitmapWidth()); + bitmapAnimationEffect->SetBitmapFrameNumber(tcs->GetAreaBitmapFrame()); + bitmapAnimationEffect->SetAnimationStepDirection(tcs->GetAreaBitmapAnimationDirection()); + bitmapAnimationEffect->SetAnimationFrameDurationMs(tcs->GetAreaBitmapAnimationFrameDuration()); + bitmapAnimationEffect->SetAnimationFrameCount(tcs->GetAreaBitmapAnimationStepCount()); + bitmapAnimationEffect->SetAnimationStepSize(tcs->GetAreaBitmapAnimationStepSize()); + bitmapAnimationEffect->SetAnimationBehaviour(tcs->GetAreaBitmapAnimationBehaviour()); + bitmapAnimationEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + bitmapAnimationEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + bitmapAnimationEffect->SetTop(static_cast(tcs->GetAreaTop())); + bitmapAnimationEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + + effect = static_cast(bitmapAnimationEffect); + } + else + { + AnalogAlphaMatrixBitmapAnimationEffect* bitmapAnimationEffect = new AnalogAlphaMatrixBitmapAnimationEffect(); + effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} AnalogAlphaMatrixBitmapAnimationEffect", std::to_string(ledWizNr), + std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); + bitmapAnimationEffect->SetName(effectName); + bitmapAnimationEffect->SetToyName(toy->GetName()); + int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; + bitmapAnimationEffect->SetLayerNr(layer); + FilePattern* filePattern = new FilePattern(p); + bitmapAnimationEffect->SetBitmapFilePattern(filePattern); + bitmapAnimationEffect->SetBitmapLeft(tcs->GetAreaBitmapLeft()); + bitmapAnimationEffect->SetBitmapTop(tcs->GetAreaBitmapTop()); + bitmapAnimationEffect->SetBitmapHeight(tcs->GetAreaBitmapHeight()); + bitmapAnimationEffect->SetBitmapWidth(tcs->GetAreaBitmapWidth()); + bitmapAnimationEffect->SetBitmapFrameNumber(tcs->GetAreaBitmapFrame()); + bitmapAnimationEffect->SetAnimationStepDirection(tcs->GetAreaBitmapAnimationDirection()); + bitmapAnimationEffect->SetAnimationFrameDurationMs(tcs->GetAreaBitmapAnimationFrameDuration()); + bitmapAnimationEffect->SetAnimationFrameCount(tcs->GetAreaBitmapAnimationStepCount()); + bitmapAnimationEffect->SetAnimationStepSize(tcs->GetAreaBitmapAnimationStepSize()); + bitmapAnimationEffect->SetAnimationBehaviour(tcs->GetAreaBitmapAnimationBehaviour()); + bitmapAnimationEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + bitmapAnimationEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + bitmapAnimationEffect->SetTop(static_cast(tcs->GetAreaTop())); + bitmapAnimationEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + + effect = static_cast(bitmapAnimationEffect); + } } - else if (tcs->GetAreaFlickerDensity() > 0) + else { - RGBAMatrixFlickerEffect* flickerEffect = new RGBAMatrixFlickerEffect(); - effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} RGBAMatrixFlickerEffect", std::to_string(ledWizNr), - std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - flickerEffect->SetName(effectName); - flickerEffect->SetToyName(toy->GetName()); - int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - flickerEffect->SetLayerNr(layer); - - flickerEffect->SetActiveColor(activeColor); - flickerEffect->SetInactiveColor(RGBAColor(0, 0, 0, 0)); - flickerEffect->SetDensity(MathExtensions::Limit(tcs->GetAreaFlickerDensity(), 1, 99)); - if (tcs->GetAreaFlickerMinDurationMs() > 0) - flickerEffect->SetMinFlickerDurationMs(tcs->GetAreaFlickerMinDurationMs()); - if (tcs->GetAreaFlickerMaxDurationMs() > 0) - flickerEffect->SetMaxFlickerDurationMs(tcs->GetAreaFlickerMaxDurationMs()); - if (tcs->GetAreaFlickerFadeDurationMs() > 0) + if (rgbaMatrixToy != nullptr) { - flickerEffect->SetFlickerFadeUpDurationMs(tcs->GetAreaFlickerFadeDurationMs()); - flickerEffect->SetFlickerFadeDownDurationMs(tcs->GetAreaFlickerFadeDurationMs()); + RGBAMatrixBitmapEffect* bitmapEffect = new RGBAMatrixBitmapEffect(); + effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} RGBAMatrixBitmapEffect", std::to_string(ledWizNr), + std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); + bitmapEffect->SetName(effectName); + bitmapEffect->SetToyName(toy->GetName()); + int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; + bitmapEffect->SetLayerNr(layer); + FilePattern* filePattern = new FilePattern(p); + bitmapEffect->SetBitmapFilePattern(filePattern); + bitmapEffect->SetBitmapLeft(tcs->GetAreaBitmapLeft()); + bitmapEffect->SetBitmapTop(tcs->GetAreaBitmapTop()); + bitmapEffect->SetBitmapHeight(tcs->GetAreaBitmapHeight()); + bitmapEffect->SetBitmapWidth(tcs->GetAreaBitmapWidth()); + bitmapEffect->SetBitmapFrameNumber(tcs->GetAreaBitmapFrame()); + bitmapEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + bitmapEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + bitmapEffect->SetTop(static_cast(tcs->GetAreaTop())); + bitmapEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + + effect = static_cast(bitmapEffect); + } + else + { + AnalogAlphaMatrixBitmapEffect* bitmapEffect = new AnalogAlphaMatrixBitmapEffect(); + effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} AnalogAlphaMatrixBitmapEffect", std::to_string(ledWizNr), + std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); + bitmapEffect->SetName(effectName); + bitmapEffect->SetToyName(toy->GetName()); + int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; + bitmapEffect->SetLayerNr(layer); + FilePattern* filePattern = new FilePattern(p); + bitmapEffect->SetBitmapFilePattern(filePattern); + bitmapEffect->SetBitmapLeft(tcs->GetAreaBitmapLeft()); + bitmapEffect->SetBitmapTop(tcs->GetAreaBitmapTop()); + bitmapEffect->SetBitmapHeight(tcs->GetAreaBitmapHeight()); + bitmapEffect->SetBitmapWidth(tcs->GetAreaBitmapWidth()); + bitmapEffect->SetBitmapFrameNumber(tcs->GetAreaBitmapFrame()); + bitmapEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + bitmapEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + bitmapEffect->SetTop(static_cast(tcs->GetAreaTop())); + bitmapEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + + effect = static_cast(bitmapEffect); } - - flickerEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - flickerEffect->SetTop(static_cast(tcs->GetAreaTop())); - flickerEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - flickerEffect->SetHeight(static_cast(tcs->GetAreaHeight())); - - effect = static_cast(flickerEffect); } - else if (tcs->IsPlasma()) + } + else if (tcs->IsPlasma()) + { + if (rgbaMatrixToy != nullptr) { RGBAMatrixPlasmaEffect* plasmaEffect = new RGBAMatrixPlasmaEffect(); effectName = StringExtensions::Build( @@ -491,15 +608,18 @@ void Configurator::SetupTable( effect = static_cast(plasmaEffect); } - else if (!tcs->GetShapeName().empty()) + } + else + { + if (rgbaMatrixToy != nullptr) { - RGBAColor shapeColor; - bool hasShapeColor = false; + RGBAColor activeColor; + bool hasColor = false; if (tcs->GetColorConfig() != nullptr) { ColorConfig* colorConfig = tcs->GetColorConfig(); - shapeColor = RGBAColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha()); - hasShapeColor = true; + activeColor = RGBAColor(colorConfig->GetRed(), colorConfig->GetGreen(), colorConfig->GetBlue(), colorConfig->GetAlpha()); + hasColor = true; } else { @@ -507,309 +627,181 @@ void Configurator::SetupTable( { if (StringExtensions::StartsWith(tcs->GetColorName(), "#")) { - if (shapeColor.SetColor(tcs->GetColorName())) - hasShapeColor = true; + if (activeColor.SetColor(tcs->GetColorName())) + hasColor = true; } } } - if (hasShapeColor) - { - RGBAMatrixColorScaleShapeEffect* shapeEffect = new RGBAMatrixColorScaleShapeEffect(); - effectName = StringExtensions::Build("Ledwiz {0} Column {1} Setting {2} RGBAMatrixColorScaleShapeEffect", std::to_string(ledWizNr), - std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - shapeEffect->SetName(effectName); - shapeEffect->SetToyName(toy->GetName()); - int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - shapeEffect->SetLayerNr(layer); - shapeEffect->SetShapeName(tcs->GetShapeName()); - RGBAColor activeColor = shapeColor; + if (hasColor) + { RGBAColor inactiveColor = activeColor; inactiveColor.SetAlpha(0); - shapeEffect->SetActiveColor(activeColor); - shapeEffect->SetInactiveColor(inactiveColor); - if (tcs->IsArea()) + if (tcs->HasAreaDirection()) { - shapeEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - shapeEffect->SetTop(static_cast(tcs->GetAreaTop())); - shapeEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - shapeEffect->SetHeight(static_cast(tcs->GetAreaHeight())); - } + RGBAMatrixShiftEffect* shiftEffect = new RGBAMatrixShiftEffect(); + effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} RGBAMatrixShiftEffect", std::to_string(ledWizNr), + std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); + shiftEffect->SetName(effectName); + shiftEffect->SetToyName(toy->GetName()); + int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; + shiftEffect->SetLayerNr(layer); - effect = static_cast(shapeEffect); - } - else - { - RGBAMatrixShapeEffect* shapeEffect = new RGBAMatrixShapeEffect(); - effectName = StringExtensions::Build( - "Ledwiz {0} Column {1} Setting {2} RGBAMatrixShapeEffect", std::to_string(ledWizNr), std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - shapeEffect->SetName(effectName); - shapeEffect->SetToyName(toy->GetName()); - int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - shapeEffect->SetLayerNr(layer); - shapeEffect->SetShapeName(tcs->GetShapeName()); + shiftEffect->SetActiveColor(activeColor); + shiftEffect->SetInactiveColor(inactiveColor); + shiftEffect->SetShiftDirection(tcs->GetAreaDirection()); + shiftEffect->SetShiftAcceleration(tcs->GetAreaAcceleration()); - if (tcs->IsArea()) - { - shapeEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - shapeEffect->SetTop(static_cast(tcs->GetAreaTop())); - shapeEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - shapeEffect->SetHeight(static_cast(tcs->GetAreaHeight())); - } + if (tcs->GetAreaSpeed() > 0) + shiftEffect->SetShiftSpeed(tcs->GetAreaSpeed()); - effect = static_cast(shapeEffect); - } - } - else if (tcs->IsBitmap()) - { - std::string p; - if (table->GetShapeDefinitions() && table->GetShapeDefinitions()->GetBitmapFilePattern()) - { - p = table->GetShapeDefinitions()->GetBitmapFilePattern()->GetPattern(); - } - else - { - std::string pathSeparator(1, PATH_SEPARATOR_CHAR); - p = StringExtensions::Build("{0}{1}{2}.*", iniFilePath, pathSeparator, tc->GetShortRomName()); - } + shiftEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + shiftEffect->SetTop(static_cast(tcs->GetAreaTop())); + shiftEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + shiftEffect->SetHeight(static_cast(tcs->GetAreaHeight())); - if (tcs->GetAreaBitmapAnimationStepCount() > 1) - { - IMatrixToy* rgbaMatrixToy = dynamic_cast*>(toy); - if (rgbaMatrixToy != nullptr) - { - RGBAMatrixBitmapAnimationEffect* bitmapAnimationEffect = new RGBAMatrixBitmapAnimationEffect(); - effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} RGBAMatrixBitmapAnimationEffect", std::to_string(ledWizNr), - std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - bitmapAnimationEffect->SetName(effectName); - bitmapAnimationEffect->SetToyName(toy->GetName()); - int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - bitmapAnimationEffect->SetLayerNr(layer); - FilePattern* filePattern = new FilePattern(p); - bitmapAnimationEffect->SetBitmapFilePattern(filePattern); - bitmapAnimationEffect->SetBitmapLeft(tcs->GetAreaBitmapLeft()); - bitmapAnimationEffect->SetBitmapTop(tcs->GetAreaBitmapTop()); - bitmapAnimationEffect->SetBitmapHeight(tcs->GetAreaBitmapHeight()); - bitmapAnimationEffect->SetBitmapWidth(tcs->GetAreaBitmapWidth()); - bitmapAnimationEffect->SetBitmapFrameNumber(tcs->GetAreaBitmapFrame()); - bitmapAnimationEffect->SetAnimationStepDirection(tcs->GetAreaBitmapAnimationDirection()); - bitmapAnimationEffect->SetAnimationFrameDurationMs(tcs->GetAreaBitmapAnimationFrameDuration()); - bitmapAnimationEffect->SetAnimationFrameCount(tcs->GetAreaBitmapAnimationStepCount()); - bitmapAnimationEffect->SetAnimationStepSize(tcs->GetAreaBitmapAnimationStepSize()); - bitmapAnimationEffect->SetAnimationBehaviour(tcs->GetAreaBitmapAnimationBehaviour()); - bitmapAnimationEffect->SetHeight(static_cast(tcs->GetAreaHeight())); - bitmapAnimationEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - bitmapAnimationEffect->SetTop(static_cast(tcs->GetAreaTop())); - bitmapAnimationEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - - effect = static_cast(bitmapAnimationEffect); - } - else - { - AnalogAlphaMatrixBitmapAnimationEffect* bitmapAnimationEffect = new AnalogAlphaMatrixBitmapAnimationEffect(); - effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} AnalogAlphaMatrixBitmapAnimationEffect", std::to_string(ledWizNr), - std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - bitmapAnimationEffect->SetName(effectName); - bitmapAnimationEffect->SetToyName(toy->GetName()); - int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - bitmapAnimationEffect->SetLayerNr(layer); - FilePattern* filePattern = new FilePattern(p); - bitmapAnimationEffect->SetBitmapFilePattern(filePattern); - bitmapAnimationEffect->SetBitmapLeft(tcs->GetAreaBitmapLeft()); - bitmapAnimationEffect->SetBitmapTop(tcs->GetAreaBitmapTop()); - bitmapAnimationEffect->SetBitmapHeight(tcs->GetAreaBitmapHeight()); - bitmapAnimationEffect->SetBitmapWidth(tcs->GetAreaBitmapWidth()); - bitmapAnimationEffect->SetBitmapFrameNumber(tcs->GetAreaBitmapFrame()); - bitmapAnimationEffect->SetAnimationStepDirection(tcs->GetAreaBitmapAnimationDirection()); - bitmapAnimationEffect->SetAnimationFrameDurationMs(tcs->GetAreaBitmapAnimationFrameDuration()); - bitmapAnimationEffect->SetAnimationFrameCount(tcs->GetAreaBitmapAnimationStepCount()); - bitmapAnimationEffect->SetAnimationStepSize(tcs->GetAreaBitmapAnimationStepSize()); - bitmapAnimationEffect->SetAnimationBehaviour(tcs->GetAreaBitmapAnimationBehaviour()); - bitmapAnimationEffect->SetHeight(static_cast(tcs->GetAreaHeight())); - bitmapAnimationEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - bitmapAnimationEffect->SetTop(static_cast(tcs->GetAreaTop())); - bitmapAnimationEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - - effect = static_cast(bitmapAnimationEffect); + effect = static_cast(shiftEffect); } - } - else - { - IMatrixToy* rgbaMatrixToy = dynamic_cast*>(toy); - if (rgbaMatrixToy != nullptr) + else if (tcs->GetAreaFlickerDensity() > 0) { - RGBAMatrixBitmapEffect* bitmapEffect = new RGBAMatrixBitmapEffect(); - effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} RGBAMatrixBitmapEffect", std::to_string(ledWizNr), + RGBAMatrixFlickerEffect* flickerEffect = new RGBAMatrixFlickerEffect(); + effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} RGBAMatrixFlickerEffect", std::to_string(ledWizNr), std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - bitmapEffect->SetName(effectName); - bitmapEffect->SetToyName(toy->GetName()); + flickerEffect->SetName(effectName); + flickerEffect->SetToyName(toy->GetName()); int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - bitmapEffect->SetLayerNr(layer); - FilePattern* filePattern = new FilePattern(p); - bitmapEffect->SetBitmapFilePattern(filePattern); - bitmapEffect->SetBitmapLeft(tcs->GetAreaBitmapLeft()); - bitmapEffect->SetBitmapTop(tcs->GetAreaBitmapTop()); - bitmapEffect->SetBitmapHeight(tcs->GetAreaBitmapHeight()); - bitmapEffect->SetBitmapWidth(tcs->GetAreaBitmapWidth()); - bitmapEffect->SetBitmapFrameNumber(tcs->GetAreaBitmapFrame()); - bitmapEffect->SetHeight(static_cast(tcs->GetAreaHeight())); - bitmapEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - bitmapEffect->SetTop(static_cast(tcs->GetAreaTop())); - bitmapEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - - effect = static_cast(bitmapEffect); + flickerEffect->SetLayerNr(layer); + + flickerEffect->SetActiveColor(activeColor); + flickerEffect->SetInactiveColor(inactiveColor); + flickerEffect->SetDensity(MathExtensions::Limit(tcs->GetAreaFlickerDensity(), 1, 99)); + if (tcs->GetAreaFlickerMinDurationMs() > 0) + flickerEffect->SetMinFlickerDurationMs(tcs->GetAreaFlickerMinDurationMs()); + if (tcs->GetAreaFlickerMaxDurationMs() > 0) + flickerEffect->SetMaxFlickerDurationMs(tcs->GetAreaFlickerMaxDurationMs()); + if (tcs->GetAreaFlickerFadeDurationMs() > 0) + { + flickerEffect->SetFlickerFadeDownDurationMs(tcs->GetAreaFlickerFadeDurationMs()); + flickerEffect->SetFlickerFadeUpDurationMs(tcs->GetAreaFlickerFadeDurationMs()); + } + + flickerEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + flickerEffect->SetTop(static_cast(tcs->GetAreaTop())); + flickerEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + flickerEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + + effect = static_cast(flickerEffect); } else { - AnalogAlphaMatrixBitmapEffect* bitmapEffect = new AnalogAlphaMatrixBitmapEffect(); - effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} AnalogAlphaMatrixBitmapEffect", std::to_string(ledWizNr), + RGBAMatrixColorEffect* matrixEffect = new RGBAMatrixColorEffect(); + effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} RGBAMatrixColorEffect", std::to_string(ledWizNr), std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - bitmapEffect->SetName(effectName); - bitmapEffect->SetToyName(toy->GetName()); + matrixEffect->SetName(effectName); + matrixEffect->SetToyName(toy->GetName()); int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - bitmapEffect->SetLayerNr(layer); - FilePattern* filePattern = new FilePattern(p); - bitmapEffect->SetBitmapFilePattern(filePattern); - bitmapEffect->SetBitmapLeft(tcs->GetAreaBitmapLeft()); - bitmapEffect->SetBitmapTop(tcs->GetAreaBitmapTop()); - bitmapEffect->SetBitmapHeight(tcs->GetAreaBitmapHeight()); - bitmapEffect->SetBitmapWidth(tcs->GetAreaBitmapWidth()); - bitmapEffect->SetBitmapFrameNumber(tcs->GetAreaBitmapFrame()); - bitmapEffect->SetHeight(static_cast(tcs->GetAreaHeight())); - bitmapEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - bitmapEffect->SetTop(static_cast(tcs->GetAreaTop())); - bitmapEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - - effect = static_cast(bitmapEffect); - } - } - } - else - { - RGBAColor inactiveColor = activeColor; - inactiveColor.SetAlpha(0); + matrixEffect->SetLayerNr(layer); - RGBAMatrixColorEffect* matrixEffect = new RGBAMatrixColorEffect(); - effectName = StringExtensions::Build( - "Ledwiz {0:00} Column {1:00} Setting {2:00} RGBAMatrixColorEffect", std::to_string(ledWizNr), std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - matrixEffect->SetName(effectName); - matrixEffect->SetToyName(toy->GetName()); - int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - matrixEffect->SetLayerNr(layer); + matrixEffect->SetActiveColor(activeColor); + matrixEffect->SetInactiveColor(inactiveColor); + matrixEffect->SetFadeMode(tcs->GetBlink() > 0 ? FadeModeEnum::OnOff : FadeModeEnum::Fade); - matrixEffect->SetActiveColor(activeColor); - matrixEffect->SetInactiveColor(inactiveColor); - matrixEffect->SetFadeMode(tcs->GetBlink() > 0 ? FadeModeEnum::OnOff : FadeModeEnum::Fade); + if (tcs->IsArea()) + { + matrixEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + matrixEffect->SetTop(static_cast(tcs->GetAreaTop())); + matrixEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + matrixEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + } - if (tcs->IsArea()) + effect = static_cast(matrixEffect); + } + } + else { - matrixEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - matrixEffect->SetTop(static_cast(tcs->GetAreaTop())); - matrixEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - matrixEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + Log::Warning( + StringExtensions::Build("Invalid color definition \"{0}\" found for area effect. Skipped setting {1} in column {2} for LedWizEqivalent number {3}.", + tcs->GetColorName(), std::to_string(settingNumber), std::to_string(tcc->GetNumber()), std::to_string(ledWizNr))); + continue; } - - effect = static_cast(matrixEffect); } - } - else - { - Log::Warning(StringExtensions::Build("Invalid color definition \"{0}\" found for area effect. Skipped setting {1} in column {2} for LedWizEqivalent number {3}.", - tcs->GetColorName(), std::to_string(settingNumber), std::to_string(tcc->GetNumber()), std::to_string(ledWizNr))); - continue; - } - } - else if (analogMatrixToy != nullptr) - { - if (tcs->HasLayer()) - { - if (tcs->HasAreaDirection()) + else if (analogMatrixToy != nullptr) { - AnalogAlphaMatrixShiftEffect* shiftEffect = new AnalogAlphaMatrixShiftEffect(); - effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} AnalogAlphaMatrixShiftEffect", std::to_string(ledWizNr), - std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - shiftEffect->SetName(effectName); - shiftEffect->SetToyName(toy->GetName()); - int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - shiftEffect->SetLayerNr(layer); AnalogAlpha activeValue(MathExtensions::Limit(tcs->GetIntensity(), 0, 255), 255); AnalogAlpha inactiveValue = activeValue; inactiveValue.SetAlpha(0); - shiftEffect->SetActiveValue(activeValue); - shiftEffect->SetInactiveValue(inactiveValue); - shiftEffect->SetShiftDirection(tcs->GetAreaDirection()); - shiftEffect->SetShiftAcceleration(tcs->GetAreaAcceleration()); - if (tcs->GetAreaSpeed() > 0) - shiftEffect->SetShiftSpeed(tcs->GetAreaSpeed()); - - shiftEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - shiftEffect->SetTop(static_cast(tcs->GetAreaTop())); - shiftEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - shiftEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + if (tcs->HasAreaDirection()) + { + AnalogAlphaMatrixShiftEffect* shiftEffect = new AnalogAlphaMatrixShiftEffect(); + effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} AnalogAlphaMatrixShiftEffect", std::to_string(ledWizNr), + std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); + shiftEffect->SetName(effectName); + shiftEffect->SetToyName(toy->GetName()); + int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; + shiftEffect->SetLayerNr(layer); + shiftEffect->SetActiveValue(activeValue); + shiftEffect->SetInactiveValue(inactiveValue); + shiftEffect->SetShiftDirection(tcs->GetAreaDirection()); + shiftEffect->SetShiftAcceleration(tcs->GetAreaAcceleration()); - effect = static_cast(shiftEffect); - } - else if (tcs->GetAreaFlickerDensity() > 0) - { - AnalogAlphaMatrixFlickerEffect* flickerEffect = new AnalogAlphaMatrixFlickerEffect(); - effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} AnalogAlphaMatrixFlickerEffect", std::to_string(ledWizNr), - std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - flickerEffect->SetName(effectName); - flickerEffect->SetToyName(toy->GetName()); - int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - flickerEffect->SetLayerNr(layer); - flickerEffect->SetDensity(MathExtensions::Limit(tcs->GetAreaFlickerDensity(), 1, 99)); + if (tcs->GetAreaSpeed() > 0) + shiftEffect->SetShiftSpeed(tcs->GetAreaSpeed()); - AnalogAlpha activeValue(MathExtensions::Limit(tcs->GetIntensity(), 0, 255), 255); - AnalogAlpha inactiveValue = activeValue; - inactiveValue.SetAlpha(0); - flickerEffect->SetActiveValue(activeValue); - flickerEffect->SetInactiveValue(inactiveValue); + shiftEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + shiftEffect->SetTop(static_cast(tcs->GetAreaTop())); + shiftEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + shiftEffect->SetHeight(static_cast(tcs->GetAreaHeight())); - if (tcs->IsArea()) - { - flickerEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - flickerEffect->SetTop(static_cast(tcs->GetAreaTop())); - flickerEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - flickerEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + effect = static_cast(shiftEffect); } - - if (tcs->GetAreaFlickerMinDurationMs() > 0) - flickerEffect->SetMinFlickerDurationMs(tcs->GetAreaFlickerMinDurationMs()); - if (tcs->GetAreaFlickerMaxDurationMs() > 0) - flickerEffect->SetMaxFlickerDurationMs(tcs->GetAreaFlickerMaxDurationMs()); - if (tcs->GetAreaFlickerFadeDurationMs() > 0) + else if (tcs->GetAreaFlickerDensity() > 0) { - flickerEffect->SetFlickerFadeDownDurationMs(tcs->GetAreaFlickerFadeDurationMs()); - flickerEffect->SetFlickerFadeUpDurationMs(tcs->GetAreaFlickerFadeDurationMs()); - } + AnalogAlphaMatrixFlickerEffect* flickerEffect = new AnalogAlphaMatrixFlickerEffect(); + effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} AnalogAlphaMatrixFlickerEffect", std::to_string(ledWizNr), + std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); + flickerEffect->SetName(effectName); + flickerEffect->SetToyName(toy->GetName()); + int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; + flickerEffect->SetLayerNr(layer); + flickerEffect->SetDensity(MathExtensions::Limit(tcs->GetAreaFlickerDensity(), 1, 99)); + flickerEffect->SetActiveValue(activeValue); + flickerEffect->SetInactiveValue(inactiveValue); - effect = static_cast(flickerEffect); - } - else - { - AnalogAlphaMatrixValueEffect* matrixEffect = new AnalogAlphaMatrixValueEffect(); - effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} AnalogAlphaMatrixValueEffect", std::to_string(ledWizNr), - std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - matrixEffect->SetName(effectName); - matrixEffect->SetToyName(toy->GetName()); - int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; - matrixEffect->SetLayerNr(layer); + if (tcs->IsArea()) + { + flickerEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + flickerEffect->SetTop(static_cast(tcs->GetAreaTop())); + flickerEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + flickerEffect->SetHeight(static_cast(tcs->GetAreaHeight())); + } - effect = static_cast(matrixEffect); - } - } - else - { - AnalogToyValueEffect* analogEffect = new AnalogToyValueEffect(); - effectName = StringExtensions::Build( - "Ledwiz {0:00} Column {1:00} Setting {2:00} AnalogToyValueEffect", std::to_string(ledWizNr), std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); - analogEffect->SetName(effectName); - analogEffect->SetToyName(toy->GetName()); + if (tcs->GetAreaFlickerMinDurationMs() > 0) + flickerEffect->SetMinFlickerDurationMs(tcs->GetAreaFlickerMinDurationMs()); + if (tcs->GetAreaFlickerMaxDurationMs() > 0) + flickerEffect->SetMaxFlickerDurationMs(tcs->GetAreaFlickerMaxDurationMs()); + if (tcs->GetAreaFlickerFadeDurationMs() > 0) + { + flickerEffect->SetFlickerFadeDownDurationMs(tcs->GetAreaFlickerFadeDurationMs()); + flickerEffect->SetFlickerFadeUpDurationMs(tcs->GetAreaFlickerFadeDurationMs()); + } + + effect = static_cast(flickerEffect); + } + else + { + AnalogAlphaMatrixValueEffect* matrixEffect = new AnalogAlphaMatrixValueEffect(); + effectName = StringExtensions::Build("Ledwiz {0:00} Column {1:00} Setting {2:00} AnalogAlphaMatrixValueEffect", std::to_string(ledWizNr), + std::to_string(tcc->GetNumber()), std::to_string(settingNumber)); + matrixEffect->SetName(effectName); + matrixEffect->SetToyName(toy->GetName()); + int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; + matrixEffect->SetLayerNr(layer); - effect = analogEffect; + effect = static_cast(matrixEffect); + } + } } } else if (rgbaToy != nullptr) @@ -850,9 +842,12 @@ void Configurator::SetupTable( rgbaEffect->SetName(effectName); rgbaEffect->SetToyName(toy->GetName()); + int layer = tcs->HasLayer() ? tcs->GetLayer() : settingNumber; + rgbaEffect->SetLayerNr(layer); + RGBAColor rgbaInactiveColor = rgbaActiveColor; + rgbaInactiveColor.SetAlpha(0); rgbaEffect->SetActiveColor(rgbaActiveColor); - rgbaEffect->SetInactiveColor(RGBAColor(0, 0, 0, 0)); - rgbaEffect->SetFadeMode(tcs->GetBlink() > 0 ? FadeModeEnum::OnOff : FadeModeEnum::Fade); + rgbaEffect->SetInactiveColor(rgbaInactiveColor); effect = rgbaEffect; } From 37be0ef83a3495b7dbf37f732ae49f4b34d375f0 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 9 Apr 2026 07:16:16 -0400 Subject: [PATCH 3/6] wemosd1: fix compression transmission (@dekay) --- .../WemosD1StripController.cpp | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/cab/out/adressableledstrip/WemosD1StripController.cpp b/src/cab/out/adressableledstrip/WemosD1StripController.cpp index c163670..88936ba 100644 --- a/src/cab/out/adressableledstrip/WemosD1StripController.cpp +++ b/src/cab/out/adressableledstrip/WemosD1StripController.cpp @@ -1,10 +1,9 @@ #include "WemosD1StripController.h" #include "../../../Log.h" #include "../../../general/StringExtensions.h" -#include -#include #include #include +#include namespace DOF { @@ -145,24 +144,11 @@ void WemosD1MPStripController::SendLedstripData(const std::vector& outp int nbData = static_cast(m_compressedData.size()) / 4; int nbLeds = static_cast(outputValues.size()) / 3; - if (targetPosition + nbLeds > GetNumberOfLedsPerChannel() * 10) - { - throw std::runtime_error(StringExtensions::Build("LED range {0}-{1} exceeds configured strip capacity {2}", std::to_string(targetPosition), - std::to_string(targetPosition + nbLeds - 1), std::to_string(GetNumberOfLedsPerChannel() * 10))); - } - std::vector commandData = { (uint8_t)'Q', (uint8_t)(targetPosition >> 8), (uint8_t)(targetPosition & 255), (uint8_t)(nbData >> 8), (uint8_t)(nbData & 255), (uint8_t)(nbLeds >> 8), (uint8_t)(nbLeds & 255) }; - enum sp_return result = sp_blocking_write(GetComPort(), commandData.data(), 7, GetComPortTimeOutMs()); - if (result < 0) - throw std::runtime_error(StringExtensions::Build("Failed to write compressed command data: {0}", sp_last_error_message())); - - result = sp_blocking_write(GetComPort(), m_compressedData.data(), m_compressedData.size(), GetComPortTimeOutMs()); - if (result < 0) - throw std::runtime_error(StringExtensions::Build("Failed to write compressed output values: {0}", sp_last_error_message())); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + sp_blocking_write(GetComPort(), commandData.data(), 7, GetComPortTimeOutMs()); + sp_blocking_write(GetComPort(), m_compressedData.data(), m_compressedData.size(), GetComPortTimeOutMs()); } else { From 354f604084acc49dcd0b0f66693d04ff0dba6e88 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 9 Apr 2026 07:15:38 -0400 Subject: [PATCH 4/6] misc: more c# alignment with plasma matrix effects --- .../MatrixBitmapAnimationEffectBase.h | 12 +- src/fx/matrixfx/MatrixBitmapEffectBase.h | 10 +- src/fx/matrixfx/MatrixEffectBase.h | 4 +- src/fx/matrixfx/MatrixFlickerEffectBase.h | 17 +- src/fx/matrixfx/MatrixPlasmaEffectBase.h | 215 ++++++++++-------- src/fx/matrixfx/MatrixShiftEffectBase.h | 16 +- src/fx/matrixfx/MatrixValueEffectBase.h | 6 - src/fx/matrixfx/RGBAMatrixPlasmaEffect.cpp | 32 ++- src/fx/matrixfx/RGBAMatrixPlasmaEffect.h | 17 +- src/ledcontrol/setup/Configurator.cpp | 15 +- src/tools/dof_test.cpp | 38 +++- 11 files changed, 212 insertions(+), 170 deletions(-) diff --git a/src/fx/matrixfx/MatrixBitmapAnimationEffectBase.h b/src/fx/matrixfx/MatrixBitmapAnimationEffectBase.h index df9c1ee..0c94418 100644 --- a/src/fx/matrixfx/MatrixBitmapAnimationEffectBase.h +++ b/src/fx/matrixfx/MatrixBitmapAnimationEffectBase.h @@ -32,12 +32,16 @@ template class MatrixBitmapAnimationEffectBase : pu void SetAnimationStepDirection(MatrixAnimationStepDirectionEnum value) { m_animationStepDirection = value; } AnimationBehaviourEnum GetAnimationBehaviour() const { return m_animationBehaviour; } void SetAnimationBehaviour(AnimationBehaviourEnum value) { m_animationBehaviour = value; } + virtual void SetBitmapTop(int value) override { MatrixBitmapEffectBase::SetBitmapTop(MathExtensions::Limit(value, 0, INT_MAX)); } + virtual void SetBitmapLeft(int value) override { MatrixBitmapEffectBase::SetBitmapLeft(MathExtensions::Limit(value, 0, INT_MAX)); } + virtual void SetBitmapWidth(int value) override { MatrixBitmapEffectBase::SetBitmapWidth(MathExtensions::Limit(value, -1, INT_MAX)); } + virtual void SetBitmapHeight(int value) override { MatrixBitmapEffectBase::SetBitmapHeight(MathExtensions::Limit(value, -1, INT_MAX)); } virtual void Trigger(TableElementData* tableElementData) override; virtual void Init(Table* table) override; virtual void Finish() override; protected: - void ControlAnimation(int fadeValue, TableElementData* tableElementData); + void ControlAnimation(int fadeValue); void Animate(); void StopAnimation(); void CleanupPixels(); @@ -78,11 +82,11 @@ template void MatrixBitmapAnimationEffectBasem_value; if (this->GetFadeMode() == FadeModeEnum::OnOff) fadeValue = (fadeValue < 1 ? 0 : 255); - ControlAnimation(fadeValue, tableElementData); + ControlAnimation(fadeValue); } } -template void MatrixBitmapAnimationEffectBase::ControlAnimation(int fadeValue, TableElementData* tableElementData) +template void MatrixBitmapAnimationEffectBase::ControlAnimation(int fadeValue) { if (fadeValue > 0) { @@ -201,7 +205,7 @@ template void MatrixBitmapAnimationEffectBaseGetBitmapFrameNumber() + s * m_animationStepSize); + auto stepFrameIt = frames.find(this->GetBitmapFrameNumber() + s); if (stepFrameIt != frames.end()) { FastBitmap clippedBitmap = stepFrameIt->second.GetClip(this->GetAreaWidth(), this->GetAreaHeight(), this->GetBitmapLeft(), this->GetBitmapTop(), this->GetBitmapWidth(), diff --git a/src/fx/matrixfx/MatrixBitmapEffectBase.h b/src/fx/matrixfx/MatrixBitmapEffectBase.h index bc70f14..f70d1bc 100644 --- a/src/fx/matrixfx/MatrixBitmapEffectBase.h +++ b/src/fx/matrixfx/MatrixBitmapEffectBase.h @@ -29,15 +29,15 @@ template class MatrixBitmapEffectBase : public Matr virtual FilePattern* GetBitmapFilePattern() const override { return m_bitmapFilePattern; } virtual void SetBitmapFilePattern(FilePattern* value) override; virtual int GetBitmapFrameNumber() const override { return m_bitmapFrameNumber; } - virtual void SetBitmapFrameNumber(int value) override { m_bitmapFrameNumber = MathExtensions::Limit(value, 0, 1000); } + virtual void SetBitmapFrameNumber(int value) override { m_bitmapFrameNumber = value; } virtual int GetBitmapLeft() const override { return m_bitmapLeft; } - virtual void SetBitmapLeft(int value) override { m_bitmapLeft = MathExtensions::Limit(value, 0, 1000); } + virtual void SetBitmapLeft(int value) override { m_bitmapLeft = value; } virtual int GetBitmapTop() const override { return m_bitmapTop; } - virtual void SetBitmapTop(int value) override { m_bitmapTop = MathExtensions::Limit(value, 0, 1000); } + virtual void SetBitmapTop(int value) override { m_bitmapTop = value; } virtual int GetBitmapWidth() const override { return m_bitmapWidth; } - virtual void SetBitmapWidth(int value) override { m_bitmapWidth = MathExtensions::Limit(value, -1, 1000); } + virtual void SetBitmapWidth(int value) override { m_bitmapWidth = value; } virtual int GetBitmapHeight() const override { return m_bitmapHeight; } - virtual void SetBitmapHeight(int value) override { m_bitmapHeight = MathExtensions::Limit(value, -1, 1000); } + virtual void SetBitmapHeight(int value) override { m_bitmapHeight = value; } virtual FastBitmapDataExtractModeEnum GetDataExtractMode() const override { return m_dataExtractMode; } virtual void SetDataExtractMode(FastBitmapDataExtractModeEnum value) override { m_dataExtractMode = value; } virtual void Trigger(TableElementData* tableElementData) override; diff --git a/src/fx/matrixfx/MatrixEffectBase.h b/src/fx/matrixfx/MatrixEffectBase.h index 5622155..35d3b66 100644 --- a/src/fx/matrixfx/MatrixEffectBase.h +++ b/src/fx/matrixfx/MatrixEffectBase.h @@ -113,7 +113,7 @@ template void MatrixEffectBase:: { tmp = m_areaRight; m_areaRight = m_areaLeft; - m_areaLeft = tmp; + m_areaLeft = m_areaRight; } if (m_areaTop > m_areaBottom) { @@ -127,7 +127,7 @@ template void MatrixEffectBase:: std::vector args2 = { std::to_string(m_areaLeft), std::to_string(m_areaTop), std::to_string(m_areaRight), std::to_string(m_areaBottom), std::to_string(GetAreaWidth()), std::to_string(GetAreaHeight()) }; args.insert(args.end(), args2.begin(), args2.end()); - args.push_back(this->GetName()); + args.push_back(this->GetXmlElementName()); Log::Instrumentation("MX", StringExtensions::Build("MatrixBase for {12}. Calculated area size: AreaDef(L:{0}, T:{1}, W:{2}, H:{3}), Matrix(W:{4}, H:{5}), ResultArea(Left: {6}, Top:{7}, Right:{8}, " "Bottom:{9}, Width:{10}, Height:{11})", diff --git a/src/fx/matrixfx/MatrixFlickerEffectBase.h b/src/fx/matrixfx/MatrixFlickerEffectBase.h index bcd1d4f..4ea663c 100644 --- a/src/fx/matrixfx/MatrixFlickerEffectBase.h +++ b/src/fx/matrixfx/MatrixFlickerEffectBase.h @@ -24,17 +24,15 @@ template class MatrixFlickerEffectBase : public Mat virtual ~MatrixFlickerEffectBase() = default; int GetDensity() const { return m_density; } - void SetDensity(int value) { m_density = MathExtensions::Limit(value, 1, 100); } + void SetDensity(int value) { m_density = MathExtensions::Limit(value, 0, 100); } int GetMinFlickerDurationMs() const { return m_minFlickerDurationMs; } - void SetMinFlickerDurationMs(int value) { m_minFlickerDurationMs = MathExtensions::Limit(value, 1, 10000); } + void SetMinFlickerDurationMs(int value) { m_minFlickerDurationMs = MathExtensions::Limit(value, 1, INT_MAX); } int GetMaxFlickerDurationMs() const { return m_maxFlickerDurationMs; } - void SetMaxFlickerDurationMs(int value) { m_maxFlickerDurationMs = MathExtensions::Limit(value, 1, 10000); } - int GetFadeDurationMs() const { return m_fadeDurationMs; } - void SetFadeDurationMs(int value) { m_fadeDurationMs = MathExtensions::Limit(value, 0, 10000); } + void SetMaxFlickerDurationMs(int value) { m_maxFlickerDurationMs = MathExtensions::Limit(value, 1, INT_MAX); } int GetFlickerFadeUpDurationMs() const { return m_flickerFadeUpDurationMs; } - void SetFlickerFadeUpDurationMs(int value) { m_flickerFadeUpDurationMs = MathExtensions::Limit(value, 0, 10000); } + void SetFlickerFadeUpDurationMs(int value) { m_flickerFadeUpDurationMs = MathExtensions::Limit(value, 1, INT_MAX); } int GetFlickerFadeDownDurationMs() const { return m_flickerFadeDownDurationMs; } - void SetFlickerFadeDownDurationMs(int value) { m_flickerFadeDownDurationMs = MathExtensions::Limit(value, 0, 10000); } + void SetFlickerFadeDownDurationMs(int value) { m_flickerFadeDownDurationMs = MathExtensions::Limit(value, 1, INT_MAX); } RetriggerBehaviourEnum GetRetriggerBehaviour() const { return m_retriggerBehaviour; } void SetRetriggerBehaviour(RetriggerBehaviourEnum value) { m_retriggerBehaviour = value; } virtual void Init(Table* table) override; @@ -51,7 +49,6 @@ template class MatrixFlickerEffectBase : public Mat int m_density; int m_minFlickerDurationMs; int m_maxFlickerDurationMs; - int m_fadeDurationMs; int m_flickerFadeUpDurationMs; int m_flickerFadeDownDurationMs; RetriggerBehaviourEnum m_retriggerBehaviour; @@ -78,7 +75,6 @@ MatrixFlickerEffectBase::MatrixFlickerEffectBase() : m_density(10) , m_minFlickerDurationMs(60) , m_maxFlickerDurationMs(150) - , m_fadeDurationMs(0) , m_flickerFadeUpDurationMs(0) , m_flickerFadeDownDurationMs(0) , m_retriggerBehaviour(RetriggerBehaviourEnum::Restart) @@ -144,6 +140,9 @@ template void MatrixFlickerEffectBase 0 && this->GetFadeMode() == FadeModeEnum::OnOff) + v = 255; + int numberOfLeds = (this->m_areaRight - this->m_areaLeft + 1) * (this->m_areaBottom - this->m_areaTop + 1); int flickerLeds = MathExtensions::Limit((int)((double)numberOfLeds / 100.0 * m_density), 1, numberOfLeds); diff --git a/src/fx/matrixfx/MatrixPlasmaEffectBase.h b/src/fx/matrixfx/MatrixPlasmaEffectBase.h index 819bf3b..b84d82b 100644 --- a/src/fx/matrixfx/MatrixPlasmaEffectBase.h +++ b/src/fx/matrixfx/MatrixPlasmaEffectBase.h @@ -1,7 +1,6 @@ #pragma once #include "MatrixEffectBase.h" -#include "../RetriggerBehaviourEnum.h" #include "../../general/MathExtensions.h" #include "../../table/TableElementData.h" #include "../../table/Table.h" @@ -9,7 +8,10 @@ #include "../../pinballsupport/AlarmHandler.h" #include "../../pinballsupport/Action.h" #include -#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif namespace DOF { @@ -23,41 +25,55 @@ template class MatrixPlasmaEffectBase : public Matr virtual ~MatrixPlasmaEffectBase() = default; int GetPlasmaSpeed() const { return m_plasmaSpeed; } - void SetPlasmaSpeed(int value) { m_plasmaSpeed = MathExtensions::Limit(value, 1, 100); } + void SetPlasmaSpeed(int value) { m_plasmaSpeed = MathExtensions::Limit(value, 1, INT_MAX); } + int GetPlasmaScale() const { return m_plasmaScale; } + void SetPlasmaScale(int value) { m_plasmaScale = value; } int GetPlasmaDensity() const { return m_plasmaDensity; } - void SetPlasmaDensity(int value) { m_plasmaDensity = MathExtensions::Limit(value, 1, 100); } - RetriggerBehaviourEnum GetRetriggerBehaviour() const { return m_retriggerBehaviour; } - void SetRetriggerBehaviour(RetriggerBehaviourEnum value) { m_retriggerBehaviour = value; } + void SetPlasmaDensity(int value) { m_plasmaDensity = value; } virtual void Trigger(TableElementData* tableElementData) override; - virtual void Finish() override; protected: - virtual MatrixElementType GetInactiveValue() = 0; - virtual MatrixElementType GetPlasmaValue(int triggerValue, double intensity) = 0; + virtual MatrixElementType GetEffectValue(int triggerValue, double time, double value, double x, double y) = 0; private: - void StartPlasma(TableElementData* tableElementData); - void StopPlasma(); - void PlasmaStep(); - void UpdateMatrix(); - double CalculatePlasmaIntensity(int x, int y, double time); + void DoPlasma(); + void DrawFrame(); + void ClearFrame(); + void PrecalcTimeValues(double time); + void PrecalcXValues(double x, double time); + double CalcPositionValue(double x, double y, double time); + + static const int RefreshIntervalMs = 30; int m_plasmaSpeed; + int m_plasmaScale; int m_plasmaDensity; - RetriggerBehaviourEnum m_retriggerBehaviour; + int m_currentTriggerValue; bool m_active; - TableElementData* m_plasmaTableElementData; - std::chrono::steady_clock::time_point m_startTime; + double m_time; + Action m_plasmaCallback; + + double m_cosTime; + double m_sinTimeDiv11767Mult05; + double m_cosTimeDiv1833371Mult05; + double m_xWaveValue1; + double m_xWaveValue2; }; template MatrixPlasmaEffectBase::MatrixPlasmaEffectBase() - : m_plasmaSpeed(50) - , m_plasmaDensity(50) - , m_retriggerBehaviour(RetriggerBehaviourEnum::Restart) + : m_plasmaSpeed(100) + , m_plasmaScale(100) + , m_plasmaDensity(100) + , m_currentTriggerValue(0) , m_active(false) - , m_plasmaTableElementData(nullptr) + , m_time(0.0) + , m_cosTime(0.0) + , m_sinTimeDiv11767Mult05(0.0) + , m_cosTimeDiv1833371Mult05(0.0) + , m_xWaveValue1(0.0) + , m_xWaveValue2(0.0) { } @@ -65,112 +81,115 @@ template void MatrixPlasmaEffectBasem_matrixLayer != nullptr) { - if (tableElementData->m_value != 0) - { - if (!m_active) - { - StartPlasma(tableElementData); - } - else if (m_retriggerBehaviour == RetriggerBehaviourEnum::Restart) - { - StartPlasma(tableElementData); - } - } - else - { - if (m_active) - { - StopPlasma(); - } - } + m_currentTriggerValue = tableElementData->m_value; + if (m_currentTriggerValue > 0 && !m_active) + DoPlasma(); } } -template void MatrixPlasmaEffectBase::StartPlasma(TableElementData* tableElementData) +template void MatrixPlasmaEffectBase::DoPlasma() { - m_plasmaTableElementData = tableElementData; - m_active = true; - m_startTime = std::chrono::steady_clock::now(); - - UpdateMatrix(); - PlasmaStep(); + int v = MathExtensions::Limit(m_currentTriggerValue, 0, 255); + if (v > 0) + { + if (!m_active) + { + if (!m_plasmaCallback) + m_plasmaCallback = Action(this, &MatrixPlasmaEffectBase::DoPlasma); + this->m_table->GetPinball()->GetAlarms()->RegisterIntervalAlarm(RefreshIntervalMs, m_plasmaCallback); + m_active = true; + } + DrawFrame(); + } + else + { + this->m_table->GetPinball()->GetAlarms()->UnregisterIntervalAlarm(m_plasmaCallback); + m_active = false; + ClearFrame(); + } } -template void MatrixPlasmaEffectBase::StopPlasma() +template void MatrixPlasmaEffectBase::DrawFrame() { - m_active = false; - m_plasmaTableElementData = nullptr; + int f = (this->GetFadeMode() == FadeModeEnum::OnOff ? (m_currentTriggerValue > 0 ? 255 : 0) : MathExtensions::Limit(m_currentTriggerValue, 0, 255)); + m_time += ((double)m_plasmaSpeed / 2000); + int w = this->GetAreaWidth(); + int h = this->GetAreaHeight(); - MatrixElementType inactiveValue = GetInactiveValue(); - for (int x = this->m_areaLeft; x <= this->m_areaRight; x++) + double sx; + double sy; + + if (w >= h) { - for (int y = this->m_areaTop; y <= this->m_areaBottom; y++) - { - this->m_matrix->SetElement(this->GetLayerNr(), x, y, inactiveValue); - } + sx = (double)m_plasmaScale / 100 / w; + sy = sx; + } + else + { + sy = (double)m_plasmaScale / 100 / h; + sx = sy; } -} -template void MatrixPlasmaEffectBase::PlasmaStep() -{ - if (!m_active || m_plasmaTableElementData == nullptr) - return; + PrecalcTimeValues(m_time); - UpdateMatrix(); + for (int x = 0; x < w; x++) + { + double xx = sx * x; + PrecalcXValues(xx, m_time); + for (int y = 0; y < h; y++) + { + double yy = (double)sy * y; - int stepDelayMs = MathExtensions::Limit(110 - m_plasmaSpeed, 10, 100); - this->m_table->GetPinball()->GetAlarms()->RegisterAlarm(stepDelayMs, Action(this, &MatrixPlasmaEffectBase::PlasmaStep), false); + double v = std::max(0.0, std::min(CalcPositionValue(xx, yy, m_time), 1.0)); + + int idx = (this->m_areaTop + y) * this->m_matrix->GetWidth() + (this->m_areaLeft + x); + this->m_matrixLayer[idx] = GetEffectValue(f, m_time, v, xx, yy); + } + } } -template void MatrixPlasmaEffectBase::UpdateMatrix() +template void MatrixPlasmaEffectBase::ClearFrame() { - if (!m_active || m_plasmaTableElementData == nullptr) - return; - - auto now = std::chrono::steady_clock::now(); - auto elapsed = std::chrono::duration_cast(now - m_startTime).count(); - double time = elapsed / 1000.0; + int w = this->GetAreaWidth(); + int h = this->GetAreaHeight(); - for (int x = this->m_areaLeft; x <= this->m_areaRight; x++) + for (int y = 0; y < h; y++) { - for (int y = this->m_areaTop; y <= this->m_areaBottom; y++) + for (int x = 0; x < w; x++) { - double intensity = CalculatePlasmaIntensity(x, y, time); - MatrixElementType value = GetPlasmaValue(m_plasmaTableElementData->m_value, intensity); - this->m_matrix->SetElement(this->GetLayerNr(), x, y, value); + int idx = (this->m_areaTop + y) * this->m_matrix->GetWidth() + (this->m_areaLeft + x); + this->m_matrixLayer[idx] = GetEffectValue(0, 0, 0, 0, 0); } } } -template double MatrixPlasmaEffectBase::CalculatePlasmaIntensity(int x, int y, double time) +template void MatrixPlasmaEffectBase::PrecalcTimeValues(double time) { - double normX = (double)(x - this->m_areaLeft) / (double)this->GetAreaWidth(); - double normY = (double)(y - this->m_areaTop) / (double)this->GetAreaHeight(); - - double densityFactor = m_plasmaDensity / 50.0; - - double plasma1 = std::sin(normX * 10.0 * densityFactor + time); - double plasma2 = std::sin(normY * 10.0 * densityFactor + time * 1.3); - double plasma3 = std::sin((normX + normY) * 8.0 * densityFactor + time * 0.7); - double plasma4 = std::sin(std::sqrt(normX * normX + normY * normY) * 12.0 * densityFactor + time * 1.1); + m_cosTime = std::cos(time); + m_sinTimeDiv11767Mult05 = 0.5 * std::sin(time / 1.1767); + m_cosTimeDiv1833371Mult05 = 0.5 * std::cos(time / 1.833371); +} - double combined = (plasma1 + plasma2 + plasma3 + plasma4) / 4.0; - return (combined + 1.0) / 2.0; +template void MatrixPlasmaEffectBase::PrecalcXValues(double x, double time) +{ + m_xWaveValue1 = std::sin(x * M_PI * (m_plasmaDensity / 28) + time); + m_xWaveValue2 = x * std::sin(time / 2.567); } -template void MatrixPlasmaEffectBase::Finish() +template double MatrixPlasmaEffectBase::CalcPositionValue(double x, double y, double time) { - try - { - } - catch (...) - { - } - m_active = false; - m_plasmaTableElementData = nullptr; - MatrixEffectBase::Finish(); + double v = m_xWaveValue1; + + v += std::sin(M_PI * (m_plasmaDensity / 28) * (m_xWaveValue2 + y * m_cosTime) + time); + + double cx = x + m_sinTimeDiv11767Mult05; + double cy = y + m_cosTimeDiv1833371Mult05; + v += std::sin(std::sqrt((M_PI * (m_plasmaDensity / 56)) * (M_PI * (m_plasmaDensity / 56)) * (cx * cx + cy * cy) + 1) + time); + v = ((v + 3) / 6.0); + + return v; } -} \ No newline at end of file +} diff --git a/src/fx/matrixfx/MatrixShiftEffectBase.h b/src/fx/matrixfx/MatrixShiftEffectBase.h index 7d2822e..9b83c0e 100644 --- a/src/fx/matrixfx/MatrixShiftEffectBase.h +++ b/src/fx/matrixfx/MatrixShiftEffectBase.h @@ -9,8 +9,9 @@ #include "../../Pinball.h" #include "../../pinballsupport/AlarmHandler.h" #include "../../pinballsupport/Action.h" -#include +#include #include +#include namespace DOF { @@ -76,14 +77,14 @@ template void MatrixShiftEffectBaseGetAreaWidth() : (float)this->GetAreaHeight(); float position = 0.0f; - float speed = numberOfElements / 100.0f * (m_shiftSpeed / (1000.0f / (float)RefreshIntervalMs)); - float acceleration = numberOfElements / 100.0f * (m_shiftAcceleration / (1000.0f / (float)RefreshIntervalMs)); + float speed = numberOfElements / 100.0f * (m_shiftSpeed / (1000 / RefreshIntervalMs)); + float acceleration = numberOfElements / 100.0f * (m_shiftAcceleration / (1000 / RefreshIntervalMs)); while (position <= numberOfElements) { stepList.push_back(MathExtensions::Limit(position, 0.0f, numberOfElements)); position += speed; - speed = MathExtensions::Limit(speed + acceleration, numberOfElements / 100.0f * (1.0f / (1000.0f / (float)RefreshIntervalMs)), 10000.0f); + speed = MathExtensions::Limit(speed + acceleration, numberOfElements / 100.0f * (float)(1 / (1000 / RefreshIntervalMs)), 10000.0f); } stepList.push_back(MathExtensions::Limit(position, 0.0f, numberOfElements)); @@ -118,7 +119,7 @@ template void MatrixShiftEffectBase= toNr; i--) value[i] = (float)lastValue; if (toElementNr != (float)(int)toElementNr) @@ -130,10 +131,10 @@ template void MatrixShiftEffectBaseGetWidth() - 1) value[(int)fromElementNr] += (fromElementNr - (float)(int)fromElementNr) * (float)lastValue; - toNr = MathExtensions::Limit((int)(toElementNr + 0.999f), 0, 2147483647); + toNr = MathExtensions::Limit((int)std::ceil(toElementNr), 0, 2147483647); for (int i = (int)fromElementNr - 1; i >= toNr; i--) value[i] = (float)lastValue; if (toElementNr != (float)(int)toElementNr) @@ -205,7 +206,6 @@ template void MatrixShiftEffectBase void MatrixValueEffectBaseGetToyName())); - } } } \ No newline at end of file diff --git a/src/fx/matrixfx/RGBAMatrixPlasmaEffect.cpp b/src/fx/matrixfx/RGBAMatrixPlasmaEffect.cpp index 5cf2bc8..71d241d 100644 --- a/src/fx/matrixfx/RGBAMatrixPlasmaEffect.cpp +++ b/src/fx/matrixfx/RGBAMatrixPlasmaEffect.cpp @@ -5,34 +5,28 @@ namespace DOF { RGBAMatrixPlasmaEffect::RGBAMatrixPlasmaEffect() - : m_activeColor(0xff, 0x00, 0x00, 0xff) + : m_activeColor1(0x00, 0x00, 0xff, 0xff) + , m_activeColor2(0x80, 0x80, 0x00, 0xff) , m_inactiveColor(0, 0, 0, 0) - , m_secondaryColor(0x00, 0x00, 0xff, 0xff) { } -RGBAColor RGBAMatrixPlasmaEffect::GetInactiveValue() { return m_inactiveColor; } - -RGBAColor RGBAMatrixPlasmaEffect::GetPlasmaValue(int triggerValue, double intensity) +RGBAColor RGBAMatrixPlasmaEffect::GetEffectValue(int triggerValue, double time, double value, double x, double y) { + double blendVal = (std::sin(value * M_PI * 2 + time) + 1) / 2; + RGBAColor blended((int)(blendVal * m_activeColor1.GetRed() + (1 - blendVal) * m_activeColor2.GetRed()), + (int)(blendVal * m_activeColor1.GetGreen() + (1 - blendVal) * m_activeColor2.GetGreen()), (int)(blendVal * m_activeColor1.GetBlue() + (1 - blendVal) * m_activeColor2.GetBlue()), + (int)((blendVal * m_activeColor1.GetAlpha() + (1 - blendVal) * m_activeColor2.GetAlpha()) * value)); + RGBAColor d; int v = MathExtensions::Limit(triggerValue, 0, 255); - - double primaryWeight = intensity; - double secondaryWeight = 1.0 - intensity; - - int mixedRed = (int)(m_activeColor.GetRed() * primaryWeight + m_secondaryColor.GetRed() * secondaryWeight); - int mixedGreen = (int)(m_activeColor.GetGreen() * primaryWeight + m_secondaryColor.GetGreen() * secondaryWeight); - int mixedBlue = (int)(m_activeColor.GetBlue() * primaryWeight + m_secondaryColor.GetBlue() * secondaryWeight); - int mixedAlpha = (int)(m_activeColor.GetAlpha() * primaryWeight + m_secondaryColor.GetAlpha() * secondaryWeight); - - d.SetRed(m_inactiveColor.GetRed() + MathExtensions::Limit((int)((float)(mixedRed - m_inactiveColor.GetRed()) * v / 255), 0, 255)); - d.SetGreen(m_inactiveColor.GetGreen() + MathExtensions::Limit((int)((float)(mixedGreen - m_inactiveColor.GetGreen()) * v / 255), 0, 255)); - d.SetBlue(m_inactiveColor.GetBlue() + MathExtensions::Limit((int)((float)(mixedBlue - m_inactiveColor.GetBlue()) * v / 255), 0, 255)); - d.SetAlpha(m_inactiveColor.GetAlpha() + MathExtensions::Limit((int)((float)(mixedAlpha - m_inactiveColor.GetAlpha()) * v / 255), 0, 255)); + d.SetRed(m_inactiveColor.GetRed() + MathExtensions::Limit((int)((float)(blended.GetRed() - m_inactiveColor.GetRed()) * v / 255), 0, 255)); + d.SetGreen(m_inactiveColor.GetGreen() + MathExtensions::Limit((int)((float)(blended.GetGreen() - m_inactiveColor.GetGreen()) * v / 255), 0, 255)); + d.SetBlue(m_inactiveColor.GetBlue() + MathExtensions::Limit((int)((float)(blended.GetBlue() - m_inactiveColor.GetBlue()) * v / 255), 0, 255)); + d.SetAlpha(m_inactiveColor.GetAlpha() + MathExtensions::Limit((int)((float)(blended.GetAlpha() - m_inactiveColor.GetAlpha()) * v / 255), 0, 255)); return d; } -} \ No newline at end of file +} diff --git a/src/fx/matrixfx/RGBAMatrixPlasmaEffect.h b/src/fx/matrixfx/RGBAMatrixPlasmaEffect.h index 095088f..4ea8497 100644 --- a/src/fx/matrixfx/RGBAMatrixPlasmaEffect.h +++ b/src/fx/matrixfx/RGBAMatrixPlasmaEffect.h @@ -12,23 +12,22 @@ class RGBAMatrixPlasmaEffect : public MatrixPlasmaEffectBase RGBAMatrixPlasmaEffect(); virtual ~RGBAMatrixPlasmaEffect() = default; - const RGBAColor& GetActiveColor() const { return m_activeColor; } - void SetActiveColor(const RGBAColor& value) { m_activeColor = value; } + const RGBAColor& GetActiveColor1() const { return m_activeColor1; } + void SetActiveColor1(const RGBAColor& value) { m_activeColor1 = value; } + const RGBAColor& GetActiveColor2() const { return m_activeColor2; } + void SetActiveColor2(const RGBAColor& value) { m_activeColor2 = value; } const RGBAColor& GetInactiveColor() const { return m_inactiveColor; } void SetInactiveColor(const RGBAColor& value) { m_inactiveColor = value; } - const RGBAColor& GetSecondaryColor() const { return m_secondaryColor; } - void SetSecondaryColor(const RGBAColor& value) { m_secondaryColor = value; } virtual std::string GetXmlElementName() const override { return "RGBAMatrixPlasmaEffect"; } protected: - virtual RGBAColor GetInactiveValue() override; - virtual RGBAColor GetPlasmaValue(int triggerValue, double intensity) override; + virtual RGBAColor GetEffectValue(int triggerValue, double time, double value, double x, double y) override; private: - RGBAColor m_activeColor; + RGBAColor m_activeColor1; + RGBAColor m_activeColor2; RGBAColor m_inactiveColor; - RGBAColor m_secondaryColor; }; -} \ No newline at end of file +} diff --git a/src/ledcontrol/setup/Configurator.cpp b/src/ledcontrol/setup/Configurator.cpp index b747e3f..7f7a1a6 100644 --- a/src/ledcontrol/setup/Configurator.cpp +++ b/src/ledcontrol/setup/Configurator.cpp @@ -592,19 +592,16 @@ void Configurator::SetupTable( if (!hasColor2) activeColor2 = RGBAColor(0, 0xff, 0, 0xff); - plasmaEffect->SetActiveColor(activeColor1); - plasmaEffect->SetSecondaryColor(activeColor2); + plasmaEffect->SetActiveColor1(activeColor1); + plasmaEffect->SetActiveColor2(activeColor2); plasmaEffect->SetInactiveColor(inactiveColor); plasmaEffect->SetPlasmaSpeed(tcs->GetPlasmaSpeed()); plasmaEffect->SetPlasmaDensity(tcs->GetPlasmaDensity()); - if (tcs->IsArea()) - { - plasmaEffect->SetLeft(static_cast(tcs->GetAreaLeft())); - plasmaEffect->SetTop(static_cast(tcs->GetAreaTop())); - plasmaEffect->SetWidth(static_cast(tcs->GetAreaWidth())); - plasmaEffect->SetHeight(static_cast(tcs->GetAreaHeight())); - } + plasmaEffect->SetLeft(static_cast(tcs->GetAreaLeft())); + plasmaEffect->SetTop(static_cast(tcs->GetAreaTop())); + plasmaEffect->SetWidth(static_cast(tcs->GetAreaWidth())); + plasmaEffect->SetHeight(static_cast(tcs->GetAreaHeight())); effect = static_cast(plasmaEffect); } diff --git a/src/tools/dof_test.cpp b/src/tools/dof_test.cpp index 14ae27c..f56ad9f 100644 --- a/src/tools/dof_test.cpp +++ b/src/tools/dof_test.cpp @@ -22,7 +22,7 @@ struct TestRom }; std::vector testRoms = { { "ij_l7", "Indiana Jones L7" }, { "tna", "Total Nuclear Annihilation" }, { "gw", "The Getaway High Speed II" }, { "goldcue", "Gold Cue" }, - { "bourne", "Bourne Identity" }, { "twenty4", "24" }, { "afm", "Attack From Mars" }, { "pinupmenu", "PinUP Menu" } }; + { "bourne", "Bourne Identity" }, { "twenty4", "24" }, { "afm", "Attack From Mars" }, { "pinupmenu", "PinUP Menu" }, { "bloodmach", "Blood Machines" }, { "genesis", "Genesis" } }; void LIBDOFCALLBACK LogCallback(DOF_LogLevel logLevel, const char* format, va_list args) { @@ -325,6 +325,38 @@ void RunAFMTests(DOF::DOF* pDof) pDof->Finish(); } +void RunBloodmachTests(DOF::DOF* pDof) +{ + pDof->Init("", "bloodmach"); + + Log("========================================"); + Log("Testing ROM: bloodmach"); + Log("========================================"); + + std::this_thread::sleep_for(std::chrono::milliseconds(TIMEOUT_START_DELAY)); + + TriggerOutputOnOff(pDof, 'E', 135, 6000); + + pDof->Finish(); +} + +void RunGenesisTests(DOF::DOF* pDof) +{ + pDof->Init("", "genesis"); + + Log("========================================"); + Log("Testing ROM: genesis"); + Log("========================================"); + + std::this_thread::sleep_for(std::chrono::milliseconds(TIMEOUT_START_DELAY)); + + TriggerOutputOnOff(pDof, 'E', 169, 6000); + TriggerOutputOnOff(pDof, 'W', 43, 6000); + TriggerOutputOnOff(pDof, 'W', 73, 6000); + + pDof->Finish(); +} + void RunPinupMenuTests(DOF::DOF* pDof) { pDof->Init("", "pinupmenu"); @@ -526,6 +558,10 @@ int main(int argc, const char* argv[]) RunAFMTests(pDof); else if (testRom.name == "pinupmenu") RunPinupMenuTests(pDof); + else if (testRom.name == "bloodmach") + RunBloodmachTests(pDof); + else if (testRom.name == "genesis") + RunGenesisTests(pDof); break; } } From 2e90f6fe2b9cd841bbca1ee71e04e40121e0c5be Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 9 Apr 2026 07:18:58 -0400 Subject: [PATCH 5/6] misc: bump version to 0.4.6 --- include/DOF/DOF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/DOF/DOF.h b/include/DOF/DOF.h index ee75dbe..16ba028 100644 --- a/include/DOF/DOF.h +++ b/include/DOF/DOF.h @@ -2,7 +2,7 @@ #define LIBDOF_VERSION_MAJOR 0 // X Digits #define LIBDOF_VERSION_MINOR 4 // Max 2 Digits -#define LIBDOF_VERSION_PATCH 5 // Max 2 Digits +#define LIBDOF_VERSION_PATCH 6 // Max 2 Digits #define _LIBDOF_STR(x) #x #define LIBDOF_STR(x) _LIBDOF_STR(x) From f1985f1265ae99edffd9e3376f7afbb7654acafd Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Thu, 9 Apr 2026 07:19:46 -0400 Subject: [PATCH 6/6] ci: bump to msbuild@v3 to avoid node 20 deprecation annotations --- .github/workflows/libdof.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/libdof.yml b/.github/workflows/libdof.yml index a579d78..ef52099 100644 --- a/.github/workflows/libdof.yml +++ b/.github/workflows/libdof.yml @@ -54,7 +54,7 @@ jobs: # install dependencies # - if: (matrix.platform == 'win') - uses: microsoft/setup-msbuild@v2 + uses: microsoft/setup-msbuild@v3 - if: (matrix.platform == 'win') run: | if [[ "${{ matrix.arch }}" == "x64" ]]; then