DirectOutputR1
DirectOutput framework R1 for virtual pinball cabinets.
Go to:
Overview 
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Events Macros Pages
Configurator.cs
Go to the documentation of this file.
1 using System.Collections.Generic;
2 using System.Linq;
3 using DirectOutput.Cab;
4 using DirectOutput.Cab.Out;
5 using DirectOutput.Cab.Toys;
6 using DirectOutput.Cab.Toys.Layer;
7 using DirectOutput.Cab.Toys.LWEquivalent;
8 using DirectOutput.FX;
9 using DirectOutput.FX.AnalogToyFX;
10 using DirectOutput.FX.RGBAFX;
11 using DirectOutput.FX.TimmedFX;
12 using DirectOutput.LedControl.Loader;
13 using DirectOutput.Cab.Color;
14 
15 namespace DirectOutput.LedControl.Setup
16 {
20  public class Configurator
21  {
25  public int EffectMinDurationMs = 60;
29  public int EffectRGBMinDurationMs = 120;
30 
38  public void Setup(LedControlConfigList LedControlConfigList, DirectOutput.Table.Table Table, Cabinet Cabinet, string RomName)
39  {
40  Dictionary<int, TableConfig> TableConfigDict = LedControlConfigList.GetTableConfigDictonary(RomName);
41 
42  Dictionary<int, Dictionary<int, IToy>> ToyAssignments = SetupCabinet(TableConfigDict, Cabinet);
43 
44  SetupTable(Table, TableConfigDict, ToyAssignments);
45 
46 
47  }
48 
49  private void SetupTable(Table.Table Table, Dictionary<int, TableConfig> TableConfigDict, Dictionary<int, Dictionary<int, IToy>> ToyAssignments)
50  {
51  foreach (KeyValuePair<int, TableConfig> KV in TableConfigDict)
52  {
53  int LedWizNr = KV.Key;
54  if (ToyAssignments.ContainsKey(LedWizNr))
55  {
56  TableConfig TC = KV.Value;
57 
58 
59  foreach (TableConfigColumn TCC in TC.Columns)
60  {
61 
62  if (ToyAssignments[LedWizNr].ContainsKey(TCC.Number))
63  {
64  IToy Toy = ToyAssignments[LedWizNr][TCC.Number];
65 
66  int SettingNumber = 0;
67  foreach (TableConfigSetting TCS in TCC)
68  {
69  SettingNumber++;
70  IEffect Effect = null;
71 
72  int Layer = (TCS.Layer.HasValue ? TCS.Layer.Value : SettingNumber);
73 
74  if (Toy is IRGBAToy || Toy is IAnalogAlphaToy)
75  {
76  if (Toy is IRGBAToy)
77  {
78  RGBAColor ActiveColor = null;
79  if (TCS.ColorConfig != null)
80  {
81  ActiveColor = TCS.ColorConfig.GetCabinetColor().GetRGBAColor();
82  }
83  else
84  {
85  if (!TCS.ColorName.IsNullOrWhiteSpace())
86  {
87  if (TCS.ColorName.StartsWith("#"))
88  {
89  ActiveColor = new RGBAColor();
90  if (!ActiveColor.SetColor(TCS.ColorName))
91  {
92  ActiveColor = null;
93  Log.Warning("Skipped setting {0} in column {1} for LedWizEqivalent number {2} since {3} is not a valid color specification.".Build(new object[] { SettingNumber, TCC.Number, LedWizNr, TCS.ColorName }));
94  }
95  }
96  else
97  {
98  Log.Warning("Skipped setting {0} in column {1} for LedWizEqivalent number {2} since {3} is not a valid color specification.".Build(new object[] { SettingNumber, TCC.Number, LedWizNr, TCS.ColorName }));
99  }
100  }
101  else
102  {
103  Log.Warning("Skipped setting {0} in column {1} for LedWizEqivalent number {2} since it does not contain a color specification.".Build(SettingNumber, TCC.Number, LedWizNr));
104  }
105  }
106  if (ActiveColor != null)
107  {
108  if (TCS.FadingDownDurationMs > 0 || TCS.FadingUpDurationMs > 0)
109  {
110  //Must fade, use fadeeffect
111  Effect = new RGBAFadeOnOffEffect() { ToyName = Toy.Name, Layer = Layer, FadeActiveDurationMs = TCS.FadingUpDurationMs, FadeInactiveDurationMs = TCS.FadingDownDurationMs, RetriggerBehaviour = RetriggerBehaviourEnum.IgnoreRetrigger, FadeMode = FadeModeEnum.CurrentToDefined, ActiveColor = ActiveColor, InactiveColor = new RGBAColor(0, 0, 0, 0) };
112 
113  }
114  else
115  {
116  //No fadinging, set color directly
117  Effect = new RGBAOnOffEffect() { ToyName = Toy.Name, Layer = Layer, ActiveColor = ActiveColor, InactiveColor = new RGBAColor(0, 0, 0, 0) };
118  }
119 
120 
121  }
122  }
123  else if (Toy is IAnalogAlphaToy)
124  {
125  AnalogAlphaValue AAV = new AnalogAlphaValue(((int)((double)TCS.Intensity * 5.3125)).Limit(0, 255));
126  if (TCS.FadingDownDurationMs > 0 || TCS.FadingUpDurationMs > 0)
127  {
128  Effect = new AnalogToyFadeOnOffEffect() { ToyName = Toy.Name, Layer = Layer, FadeActiveDurationMs = TCS.FadingUpDurationMs, FadeInactiveDurationMs = TCS.FadingDownDurationMs, RetriggerBehaviour = RetriggerBehaviourEnum.IgnoreRetrigger, FadeMode = FadeModeEnum.CurrentToDefined, ActiveValue = AAV, InactiveValue = new AnalogAlphaValue(0, 0) };
129  }
130  else
131  {
132  Effect = new AnalogToyOnOffEffect() { ToyName = Toy.Name, Layer = Layer, ActiveValue = AAV, InactiveValue = new AnalogAlphaValue(0, 0) };
133  }
134 
135  }
136  if (Effect != null)
137  {
138  Effect.Name = "Ledwiz {0:00} Column {1:00} Setting {2:00} {3}".Build(new object[] { LedWizNr, TCC.Number, SettingNumber, Effect.GetType().Name });
139  MakeEffectNameUnique(Effect, Table);
140 
141  Table.Effects.Add(Effect);
142 
143  if (TCS.Blink != 0)
144  {
145  Effect = new BlinkEffect() { Name = "Ledwiz {0:00} Column {1:00} Setting {2:00} BlinkEffect".Build(LedWizNr, TCC.Number, SettingNumber), TargetEffectName = Effect.Name, DurationActiveMs = TCS.BlinkIntervalMs, DurationInactiveMs = TCS.BlinkIntervalMs };
146  MakeEffectNameUnique(Effect, Table);
147  Table.Effects.Add(Effect);
148  }
149 
150  if (TCS.DurationMs > 0 || TCS.Blink > 0)
151  {
152  int Duration = (TCS.DurationMs > 0 ? TCS.DurationMs : (TCS.Blink * 2 - 1) * TCS.BlinkIntervalMs + 1);
153  Effect = new DurationEffect() { Name = "Ledwiz {0:00} Column {1:00} Setting {2:00} DurationEffect".Build(LedWizNr, TCC.Number, SettingNumber), TargetEffectName = Effect.Name, DurationMs = Duration, RetriggerBehaviour = RetriggerBehaviourEnum.RestartEffect };
154  MakeEffectNameUnique(Effect, Table);
155  Table.Effects.Add(Effect);
156  }
157  if (TCS.MinDurationMs > 0 || (Toy is IRGBAToy && EffectRGBMinDurationMs > 0) || (!(Toy is IRGBAToy) && EffectMinDurationMs > 0))
158  {
159  string N = (TCS.MinDurationMs > 0 ? "MinDuratonEffect" : "DefaultMinDurationEffect");
160  int Min = (TCS.MinDurationMs > 0 ? TCS.MinDurationMs : (Toy is IRGBAToy ? EffectRGBMinDurationMs : EffectMinDurationMs));
161  Effect = new MinDurationEffect() { Name = "Ledwiz {0:00} Column {1:00} Setting {2:00} {3}".Build(new object[] { LedWizNr, TCC.Number, SettingNumber, N }), TargetEffectName = Effect.Name, MinDurationMs = Min };
162  MakeEffectNameUnique(Effect, Table);
163  Table.Effects.Add(Effect);
164  }
165 
166 
167  if (TCS.WaitDurationMs > 0)
168  {
169  Effect = new DelayEffect() { Name = "Ledwiz {0:00} Column {1:00} Setting {2:00} DelayEffect".Build(LedWizNr, TCC.Number, SettingNumber), TargetEffectName = Effect.Name, DelayMs = TCS.WaitDurationMs };
170  MakeEffectNameUnique(Effect, Table);
171  Table.Effects.Add(Effect);
172  }
173 
174  switch (TCS.OutputControl)
175  {
176  case OutputControlEnum.FixedOn:
177  Table.AssignedStaticEffects.Add(new AssignedEffect(Effect.Name));
178  break;
179  case OutputControlEnum.Controlled:
180  if (!Table.TableElements.Contains(TCS.TableElementType, TCS.TableElementNumber))
181  {
182  Table.TableElements.UpdateState(TCS.TableElementType, TCS.TableElementNumber, 0);
183  }
184  Table.TableElements[TCS.TableElementType, TCS.TableElementNumber].AssignedEffects.Add(new AssignedEffect(Effect.Name));
185  break;
186  case OutputControlEnum.FixedOff:
187  default:
188  break;
189  }
190  }
191  }
192 
193  }
194  }
195  }
196  }
197  }
198  }
199 
200 
201 
202  private void MakeEffectNameUnique(IEffect Effect, Table.Table Table)
203  {
204  if (Table.Effects.Contains(Effect.Name))
205  {
206  int Cnt = 1;
207  while (Table.Effects.Contains("{0} {1}".Build(Effect.Name, Cnt)))
208  {
209  Cnt++;
210  }
211  Effect.Name = "{0} {1}".Build(Effect.Name, Cnt);
212  }
213  }
214 
215 
216 
217 
218 
219  private Dictionary<int, Dictionary<int, IToy>> SetupCabinet(Dictionary<int, TableConfig> TableConfigDict, Cabinet Cabinet)
220  {
221  Dictionary<int, Dictionary<int, IToy>> ToyAssignments = new Dictionary<int, Dictionary<int, IToy>>();
222 
223  Dictionary<int, LedWizEquivalent> LedWizEquivalentDict = new Dictionary<int, LedWizEquivalent>();
224  foreach (IToy T in Cabinet.Toys.Where(Toy => Toy is LedWizEquivalent).ToList())
225  {
226  LedWizEquivalentDict.Add(((LedWizEquivalent)T).LedWizNumber, (LedWizEquivalent)T);
227  }
228 
229  foreach (KeyValuePair<int, TableConfig> KV in TableConfigDict)
230  {
231  int LedWizNr = KV.Key;
232  ToyAssignments.Add(LedWizNr, new Dictionary<int, IToy>());
233 
234  TableConfig TC = KV.Value;
235  if (LedWizEquivalentDict.ContainsKey(LedWizNr))
236  {
237  LedWizEquivalent LWE = LedWizEquivalentDict[LedWizNr];
238 
239  foreach (TableConfigColumn TCC in TC.Columns)
240  {
241  IToy TargetToy = null;
242  switch (TCC.RequiredOutputCount)
243  {
244  case 3:
245  //RGB Led
246 
247  if (LWE.Outputs.Any(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber) && LWE.Outputs.Any(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber + 1) && LWE.Outputs.Any(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber + 2))
248  {
249  //Try to get the toy
250  try
251  {
252  //Toy does already exist
253  TargetToy = (IToy)Cabinet.Toys.First(Toy => Toy is IRGBAToy && ((IRGBAToy)Toy).OutputNameRed == LWE.Outputs.First(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber).OutputName && ((IRGBAToy)Toy).OutputNameGreen == LWE.Outputs.First(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber + 1).OutputName && ((IRGBAToy)Toy).OutputNameBlue == LWE.Outputs.First(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber + 2).OutputName);
254 
255  }
256  catch
257  {
258  //Toy does not exist. Create toyname and toy
259  string ToyName = "LedWiz {0:00} Column {1:00}".Build(LedWizNr, TCC.Number);
260  if (Cabinet.Toys.Contains(ToyName))
261  {
262  int Cnt = 1;
263  while (Cabinet.Toys.Contains("{0} {1}".Build(ToyName, Cnt)))
264  {
265  Cnt++;
266  }
267  ToyName = "{0} {1}".Build(ToyName, Cnt);
268  }
269  TargetToy = (IToy)new RGBAToy() { Name = ToyName, OutputNameRed = LWE.Outputs.First(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber).OutputName, OutputNameGreen = LWE.Outputs.First(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber + 1).OutputName, OutputNameBlue = LWE.Outputs.First(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber + 2).OutputName };
270  Cabinet.Toys.Add(TargetToy);
271  }
272 
273  ToyAssignments[LedWizNr].Add(TCC.Number, TargetToy);
274  }
275 
276  break;
277  case 1:
278  //Single output
279 
280  //Analog output
281  if (LWE.Outputs.Any(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber))
282  {
283  try
284  {
285  TargetToy = Cabinet.Toys.First(Toy => Toy is IAnalogAlphaToy && ((IAnalogAlphaToy)Toy).OutputName == LWE.Outputs.First(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber).OutputName);
286  }
287  catch
288  {
289  //Toy does not exist. Create toyname and toy
290  string ToyName = "LedWiz {0:00} Column {1:00}".Build(LedWizNr, TCC.Number);
291 
292  if (Cabinet.Toys.Contains(ToyName))
293  {
294  int Cnt = 1;
295  while (Cabinet.Toys.Contains("{0} {1}".Build(ToyName, Cnt)))
296  {
297  Cnt++;
298  }
299  ToyName = "{0} {1}".Build(ToyName, Cnt);
300  }
301  TargetToy = (IToy)new AnalogAlphaToy() { Name = ToyName, OutputName = LWE.Outputs.First(Output => Output.LedWizEquivalentOutputNumber == TCC.FirstOutputNumber).OutputName };
302  Cabinet.Toys.Add(TargetToy);
303  }
304  ToyAssignments[LedWizNr].Add(TCC.Number, TargetToy);
305  }
306 
307 
308 
309  break;
310 
311  default:
312  //Unknow value
313  Log.Warning("A illegal number ({0}) of required outputs has been found in a table config colum {0} for ledcontrol nr. {2}. Cant configure toy.".Build(TCC.RequiredOutputCount, TCC.Number, LedWizNr));
314  break;
315  }
316  }
317 
318  }
319  }
320  return ToyAssignments;
321  }
322 
323 
324  }
325 }