2 using System.Collections.Generic;
15 private const int RefreshIntervalMs = 30;
23 private int _Density = 10;
34 get {
return _Density; }
35 set { _Density = value.Limit(0, 100); }
39 private int _MinFlickerDurationMs = 60;
47 public int MinFlickerDurationMs
49 get {
return _MinFlickerDurationMs; }
50 set { _MinFlickerDurationMs = value.Limit(1,
int.MaxValue); }
53 private int _MaxFlickerDurationMs = 150;
62 public int MaxFlickerDurationMs
64 get {
return _MaxFlickerDurationMs; }
65 set { _MaxFlickerDurationMs = value.Limit(1,
int.MaxValue); }
68 private int _FlickerFadeUpDurationMs = 0;
77 public int FlickerFadeUpDurationMs
79 get {
return _FlickerFadeUpDurationMs; }
80 set { _FlickerFadeUpDurationMs = value.Limit(1,
int.MaxValue); }
83 private int _FlickerFadeDownDurationMs = 0;
92 public int FlickerFadeDownDurationMs
94 get {
return _FlickerFadeDownDurationMs; }
95 set { _FlickerFadeDownDurationMs = value.Limit(1,
int.MaxValue); }
105 private bool Active {
get; set; }
108 private int CurrentValue = 0;
110 private Random R =
new Random();
112 private void DoFlicker()
115 MatrixElementType I = GetEffectValue(0);
117 int V = CurrentValue.Limit(0, 255);
123 Table.Pinball.Alarms.RegisterIntervalAlarm(RefreshIntervalMs, DoFlicker);
130 if (V > 0 && FadeMode ==
FadeModeEnum.OnOff) { V = 255; }
132 int NumberOfLeds = AreaWidth * AreaHeight;
133 int FlickerLeds = ((int)((
double)NumberOfLeds / 100 * Density)).Limit(1, NumberOfLeds);
136 int Min = MinFlickerDurationMs;
137 int Max = MaxFlickerDurationMs;
140 int Tmp = Min; Min = Max; Max = Tmp;
163 while (ActiveFlickerObjects.Count < FlickerLeds && InactiveFlickerObjects.Count > 0)
165 FlickerObject FO = InactiveFlickerObjects[R.Next(InactiveFlickerObjects.Count)];
166 InactiveFlickerObjects.Remove(FO);
168 FO.StartTimestamp = DateTime.Now;
169 FO.DurationMs = R.Next(Min, Max)+ FlickerFadeDownDurationMs;
170 ActiveFlickerObjects.Add(FO);
173 DateTime CurrentTimestamp = DateTime.Now;
175 for (
int i = ActiveFlickerObjects.Count - 1; i >= 0; i--)
177 FlickerObject FO = ActiveFlickerObjects[i];
180 int AgeMs = (int)(DateTime.Now - FO.StartTimestamp).TotalMilliseconds;
181 if (AgeMs > FO.DurationMs + FlickerFadeDownDurationMs)
185 if (AgeMs > (FO.DurationMs + FlickerFadeDownDurationMs) * 2 || R.NextDouble()>.5)
188 ActiveFlickerObjects.Remove(FO);
189 InactiveFlickerObjects.Add(FO);
193 else if (FlickerFadeUpDurationMs > 0 && AgeMs < FlickerFadeUpDurationMs && AgeMs < FO.DurationMs)
196 FV = (int)((
double)V / FlickerFadeUpDurationMs * AgeMs);
200 else if (AgeMs > FO.DurationMs && FlickerFadeDownDurationMs > 0)
203 if (FO.DurationMs < FlickerFadeUpDurationMs)
205 FV = (int)((
double)V / FlickerFadeUpDurationMs * FO.DurationMs);
211 FV = FV - (int)((
double)FV / FlickerFadeDownDurationMs * (AgeMs - FO.DurationMs));
223 FV = FV.Limit(0, 255);
225 MatrixLayer[FO.X, FO.Y] = GetEffectValue(FV);
232 foreach (FlickerObject FO
in ActiveFlickerObjects)
234 MatrixLayer[FO.X, FO.Y] = I;
236 InactiveFlickerObjects.AddRange(ActiveFlickerObjects);
237 ActiveFlickerObjects.Clear();
238 Table.Pinball.Alarms.UnregisterIntervalAlarm(DoFlicker);
253 public override void Trigger(Table.TableElementData TableElementData)
255 if (MatrixLayer != null)
257 CurrentValue = TableElementData.Value;
258 if (CurrentValue > 0 && !Active)
273 BuildFlickerObjects();
283 ActiveFlickerObjects.Clear();
284 InactiveFlickerObjects.Clear();
288 private void BuildFlickerObjects()
290 ActiveFlickerObjects =
new List<FlickerObject>();
291 InactiveFlickerObjects =
new List<FlickerObject>();
294 for (
int Y = AreaTop; Y <= AreaBottom; Y++)
296 for (
int X = AreaLeft; X <= AreaRight; X++)
298 InactiveFlickerObjects.Add(
new FlickerObject() { X = X, Y = Y });
304 private List<FlickerObject> ActiveFlickerObjects =
new List<FlickerObject>();
306 private List<FlickerObject> InactiveFlickerObjects =
new List<FlickerObject>();
308 private class FlickerObject
311 public int X {
get; set; }
312 public int Y {
get; set; }
314 public int DurationMs {
get; set; }
315 public DateTime StartTimestamp {
get; set; }
327 protected abstract MatrixElementType GetEffectValue(
int TriggerValue);
override void Trigger(Table.TableElementData TableElementData)
Triggers the effect with the given TableElementData.
The namespace DirectOutput.Cab.Toys contains all toy related classes.
Base class for effects targeting a matrix of toys (e.g. addressable ledstrip)
The namespace DirectOutput.Cab contains all cabinet related classes like the Cabinet class itself...
override void Finish()
Finishes the effect and releases object references
override void Init(DirectOutput.Table.Table Table)
Initializes the effect.
FadeModeEnum
Defines the fading behaviour.
Namespace for objects dealing with layers
The Table namespace contains all table specific classes like the Table class itself, TableElement and effect assigment classes.
Holds all table specific information and handles all TableElements
Does create random flickering with a defineable density, durations and value within the spefied area ...
The namespace DirectOutput.General contains classes for general use.