117 lines
3.6 KiB
C++
117 lines
3.6 KiB
C++
/**
|
|
* @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 <math.h>
|
|
#include <stdlib.h>
|
|
|
|
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
|