2 using System.Collections.Generic;
16 private const int RefreshIntervalMs = 30;
29 get {
return _ShiftDirection; }
30 set { _ShiftDirection = value; }
33 private float _ShiftSpeed = 200;
43 public float ShiftSpeed
45 get {
return _ShiftSpeed; }
46 set { _ShiftSpeed = value.Limit(1, 10000); }
50 private float _ShiftAcceleration = 0;
58 public float ShiftAcceleration
60 get {
return _ShiftAcceleration; }
61 set { _ShiftAcceleration = value; }
66 private void BuildStep2ElementTable()
68 List<float> L =
new List<float>();
72 float Speed = NumberOfElements / 100 * (ShiftSpeed / (1000 / RefreshIntervalMs));
73 float Acceleration = NumberOfElements / 100 * (ShiftAcceleration / (1000 / RefreshIntervalMs));
74 while (Position <= NumberOfElements)
76 L.Add(Position.Limit(0, NumberOfElements));
78 Speed = (Speed + Acceleration).Limit(NumberOfElements / 100 * (1 / (1000 / RefreshIntervalMs)), 10000);
80 L.Add(Position.Limit(0, NumberOfElements));
83 Step2Element = L.ToArray();
86 float[] Step2Element = null;
92 Table.Pinball.Alarms.RegisterIntervalAlarm(RefreshIntervalMs, DoStep);
100 float FromElementNr = NumberOfElements;
101 float ToElementNr = 0;
102 float[] Value =
new float[NumberOfElements + 1];
104 int LastValue = LastDiscardedValue;
107 foreach (KeyValuePair<int, int> KV
in TriggerValueBuffer)
109 ToElementNr = Step2Element[(CurrentStep - KV.Key)];
111 if (FromElementNr.Floor() == ToElementNr.Floor())
113 Value[(int)FromElementNr.Floor()] += (FromElementNr - ToElementNr) * LastValue;
117 if (!FromElementNr.IsIntegral())
119 Value[(int)FromElementNr.Floor()] += (FromElementNr - FromElementNr.Floor()) * LastValue;
122 ToNr = (int)(ToElementNr.Ceiling());
123 for (
int i = (
int)FromElementNr.Floor() - 1; i >= ToNr; i--)
125 Value[i] = LastValue;
127 if (!ToElementNr.IsIntegral())
129 Value[(int)ToElementNr.Floor()] += (ToElementNr.Ceiling() - ToElementNr) * LastValue;
133 FromElementNr = ToElementNr;
134 LastValue = KV.Value;
137 if (FromElementNr != ToElementNr)
139 if (!FromElementNr.IsIntegral() && FromElementNr.Floor() < Width - 1)
141 Value[(int)FromElementNr.Floor()] += (FromElementNr - FromElementNr.Floor()) * LastValue;
144 ToNr = (int)(ToElementNr.Ceiling()).Limit(0,
int.MaxValue);
145 for (
int i = (
int)FromElementNr.Floor() - 1; i >= ToNr; i--)
147 Value[i] = LastValue;
149 if (!ToElementNr.IsIntegral())
151 Value[(int)ToElementNr.Floor()] += (ToElementNr.Ceiling() - ToElementNr) * LastValue;
157 switch (ShiftDirection)
160 for (
int i = 0; i < NumberOfElements; i++)
162 int V = ((int)Value[i]).Limit(0, 255);
163 if (V > 0 && FadeMode ==
FadeModeEnum.OnOff) { V = 255; }
164 MatrixElementType D = GetEffectValue(V);
166 for (
int y = AreaTop; y <= AreaBottom; y++)
168 MatrixLayer[AreaLeft + i, y] = D;
173 for (
int i = 0; i < NumberOfElements; i++)
175 int V = ((int)Value[i]).Limit(0, 255);
176 if (V > 0 && FadeMode ==
FadeModeEnum.OnOff) { V = 255; }
177 MatrixElementType D = GetEffectValue(V);
179 for (
int x = AreaLeft; x <= AreaRight; x++)
181 MatrixLayer[x, AreaTop + i] = D;
186 for (
int i = 0; i < NumberOfElements; i++)
188 int V = ((int)Value[i]).Limit(0, 255);
189 if (V > 0 && FadeMode ==
FadeModeEnum.OnOff) { V = 255; }
190 MatrixElementType D = GetEffectValue(V);
192 for (
int x = AreaLeft; x <= AreaRight; x++)
194 MatrixLayer[x, AreaBottom - i] = D;
200 for (
int i = 0; i < NumberOfElements; i++)
202 int V = ((int)Value[i]).Limit(0, 255);
203 if (V > 0 && FadeMode ==
FadeModeEnum.OnOff) { V = 255; }
204 MatrixElementType D = GetEffectValue(V);
206 for (
int y = AreaTop; y <= AreaBottom; y++)
208 MatrixLayer[AreaRight - i, y] = D;
219 int DropKey = CurrentStep - (Step2Element.Length - 1);
220 if (TriggerValueBuffer.ContainsKey(DropKey))
222 LastDiscardedValue = TriggerValueBuffer[DropKey];
223 TriggerValueBuffer.Remove(DropKey);
226 if (TriggerValueBuffer.Count > 0 || LastDiscardedValue != 0)
232 Table.Pinball.Alarms.UnregisterIntervalAlarm(DoStep);
233 LastDiscardedValue = 0;
239 int LastDiscardedValue = 0;
242 SortedDictionary<int, int> TriggerValueBuffer =
new SortedDictionary<int, int>();
243 int LastTriggerValue = 0;
256 protected abstract MatrixElementType GetEffectValue(
int TriggerValue);
259 public override void Trigger(Table.TableElementData TableElementData)
261 if (LastTriggerValue != TableElementData.Value && MatrixLayer != null)
263 LastTriggerValue = TableElementData.Value;
266 if (TriggerValueBuffer.ContainsKey(CurrentStep))
268 TriggerValueBuffer[CurrentStep] = LastTriggerValue;
272 TriggerValueBuffer.Add(CurrentStep, LastTriggerValue);
289 public override void Init(Table.Table Table)
292 BuildStep2ElementTable();
299 Table.Pinball.Alarms.UnregisterIntervalAlarm(DoStep);
The namespace DirectOutput.Cab.Toys contains all toy related classes.
Base class for effects targeting a matrix of toys (e.g. addressable ledstrip)
override void Init(Table.Table Table)
override void Finish()
Finishes the effect and releases object references
The namespace DirectOutput.Cab contains all cabinet related classes like the Cabinet class itself...
FadeModeEnum
Defines the fading behaviour.
override void Trigger(Table.TableElementData TableElementData)
Namespace for objects dealing with layers
MatrixShiftDirectionEnum
Shift directions for LedStrip effects
The namespace DirectOutput.General contains classes for general use.
Base class for effects shift values through a matrix of elements.