/** * @file StateMachine.cpp * @author Gustice * @brief Implementation of Effect-State-Machine-Class EffectStateMachine.h * @version 0.6 * @date 2019-10-01 * * @copyright Copyright (c) 2019 * */ #include "StateMachine.hpp" #include "Waveforms.hpp" #include #include namespace Effect { /// Optional prequel for delayed start. /// \li Duration must be != 0 /// \li Next entry will be first entry in given Effect sequence Macro delayPrequel = { {1, 0, StateMachine::UpdateBlank, 0, 0} }; StateMachine::StateMachine(Parameter ¶meter) : _params(parameter), _idx(/*pseudo values*/ 1, 1) {} void StateMachine::setEffect(const Macro &sequence, Color const *startColor, uint8_t initialDelay) { setEffect(sequence, startColor, &_params.idleIntens, initialDelay); } void StateMachine::setEffect(const Macro &sequence, Color const *startColor, const uint8_t *intens, const uint8_t delayedStart) { if (startColor != noColor) { _curentColor = startColor; } if (intens != nullptr) { _params.idleIntens = *intens; } _p_effSeq = &sequence; if (delayedStart > 0) { _p_effMac = &delayPrequel[0]; _prcValues.tick = delayedStart; } else { _p_effMac = &sequence[0]; _prcValues.tick = _p_effMac->Duration; } _prcValues.tick++; _prcValues.repeats = _p_effMac->Repeats; _idx = ExactIndex(_p_effMac->pWave->Length, _p_effMac->Duration); } Color StateMachine::tick(void) { // tick-increment if (--_prcValues.tick == 0) { // repeats-decrement if (_prcValues.repeats-- == 0) { _p_effMac = &(*_p_effSeq)[_p_effMac->Next]; _prcValues.repeats = _p_effMac->Repeats; } _prcValues.tick = _p_effMac->Duration; _idx = ExactIndex(_p_effMac->pWave->Length, _p_effMac->Duration); } ++_idx; StepProcessVars pv{ .pCurentColor = *_curentColor, .ColorLen = _params.targetCount, .IdleIntensity = _params.idleIntens, .FullIntensity = _p_effMac->FsIntensity, .DynamicRange = _params.dynamicRange, .waveIdx = _idx.GetIdx(), .pWave = _p_effMac->pWave, }; return _p_effMac->pImplementation(pv); } Color StateMachine::UpdateBlank(StepProcessVars &pcsParam) { return CBlack; } Color StateMachine::UpdateIdle(StepProcessVars &pcsParam) { auto c = pcsParam.pCurentColor; return c * pcsParam.IdleIntensity; } Color StateMachine::UpdateFreeze(StepProcessVars &pcsParam) { return pcsParam.pCurentColor; } Color StateMachine::UpdateWave(StepProcessVars &pcsParam) { Color temp = pcsParam.pCurentColor; temp = temp * ((float)(pcsParam.pWave->pWave[pcsParam.waveIdx]) / 0xFF * pcsParam.FullIntensity); return temp; } Color StateMachine::UpdateRevWave(StepProcessVars &pcsParam) { unsigned lastIndex = pcsParam.pWave->Length - 1; Color temp = pcsParam.pCurentColor; temp = temp * ((float)(pcsParam.pWave->pWave[lastIndex - pcsParam.waveIdx]) / 0xFF * pcsParam.FullIntensity); return temp; } Color StateMachine::UpdateFlicker(StepProcessVars &pcsParam) { uint8_t k = rand(); k = pcsParam.IdleIntensity + ((int16_t)k * (pcsParam.DynamicRange) / 0xFF); auto c = pcsParam.pCurentColor; c = c * ((float)(k)); return c; } } // namespace Effect