2 using System.Collections.Generic;
5 using DirectOutput.General.Color;
6 using DirectOutput.Cab.Toys.Layer;
8 namespace DirectOutput.FX.MatrixFX
14 public abstract class MatrixShiftEffectBase<MatrixElementType> : MatrixEffectBase<MatrixElementType>
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();
295 public override void Finish()
297 Table.Pinball.Alarms.UnregisterIntervalAlarm(DoStep);