DirectOutputR1
DirectOutput framework R1 for virtual pinball cabinets.
Go to:
Overview 
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Events Macros Pages
PacDriveSingleton.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Runtime.InteropServices;
5 using System.Diagnostics;
6 using System.IO;
7 using System.Windows.Forms;
8 
9 namespace DirectOutput.Cab.Out.Pac
10 {
11 
15  public sealed class PacDriveSingleton
16  {
17  public enum DeviceType
18  {
19  Unknown,
20  PacDrive,
21  UHID,
22  PacLED64
23  };
24 
25  public enum FlashSpeed : byte
26  {
27  AlwaysOn = 0,
28  Seconds_2 = 1,
29  Seconds_1 = 2,
30  Seconds_0_5 = 3
31  };
32 
33  #region DLL imports
34 
35  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
36  private static extern void PacSetCallbacks(PAC_ATTACHED_CALLBACK pacAttachedCallback, PAC_REMOVED_CALLBACK pacRemovedCallback);
37 
38  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
39  private static extern int PacInitialize();
40 
41  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
42  private static extern void PacShutdown();
43 
44  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
45  [return: MarshalAs(UnmanagedType.Bool)]
46  private static extern bool PacSetLEDStates(int Index, ushort data);
47 
48  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
49  [return: MarshalAs(UnmanagedType.Bool)]
50  private static extern bool PacSetLEDState(int Index, int port, [MarshalAs(UnmanagedType.Bool)] bool state);
51 
52  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
53  [return: MarshalAs(UnmanagedType.Bool)]
54  private static extern bool Pac64SetLEDStates(int Index, int group, byte data);
55 
56  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
57  [return: MarshalAs(UnmanagedType.Bool)]
58  private static extern bool Pac64SetLEDState(int Index, int group, int port, [MarshalAs(UnmanagedType.Bool)] bool state);
59 
60  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
61  private static extern bool Pac64SetLEDStatesRandom(int Index);
62 
63  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
64  [return: MarshalAs(UnmanagedType.Bool)]
65  private static extern bool Pac64SetLEDIntensities(int Index, byte[] data);
66 
67  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
68  [return: MarshalAs(UnmanagedType.Bool)]
69  private static extern bool Pac64SetLEDIntensity(int Index, int port, byte intensity);
70 
71  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
72  [return: MarshalAs(UnmanagedType.Bool)]
73  private static extern bool Pac64SetLEDFadeTime(int Index, byte fadeTime);
74 
75  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
76  [return: MarshalAs(UnmanagedType.Bool)]
77  private static extern bool Pac64SetLEDFlashSpeeds(int Index, byte flashSpeed);
78 
79  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
80  [return: MarshalAs(UnmanagedType.Bool)]
81  private static extern bool Pac64SetLEDFlashSpeed(int Index, int port, byte flashSpeed);
82 
83  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
84  [return: MarshalAs(UnmanagedType.Bool)]
85  private static extern bool Pac64StartScriptRecording(int Index);
86 
87  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
88  [return: MarshalAs(UnmanagedType.Bool)]
89  private static extern bool Pac64StopScriptRecording(int Index);
90 
91  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
92  [return: MarshalAs(UnmanagedType.Bool)]
93  private static extern bool Pac64SetScriptStepDelay(int Index, byte stepDelay);
94 
95  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
96  [return: MarshalAs(UnmanagedType.Bool)]
97  private static extern bool Pac64RunScript(int Index);
98 
99  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
100  [return: MarshalAs(UnmanagedType.Bool)]
101  private static extern bool Pac64ClearFlash(int Index);
102 
103  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
104  [return: MarshalAs(UnmanagedType.Bool)]
105  private static extern bool Pac64SetDeviceId(int Index, int newId);
106 
107  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
108  private static extern int PacGetDeviceType(int Index);
109 
110  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
111  private static extern int PacGetVendorId(int Index);
112 
113  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
114  private static extern int PacGetProductId(int Index);
115 
116  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
117  private static extern int PacGetVersionNumber(int Index);
118 
119  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
120  private static extern void PacGetVendorName(int Index, StringBuilder VendorName);
121 
122  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
123  private static extern void PacGetProductName(int Index, StringBuilder ProductName);
124 
125  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
126  private static extern void PacGetSerialNumber(int Index, StringBuilder SerialNumber);
127 
128  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
129  private static extern void PacGetDevicePath(int Index, StringBuilder DevicePath);
130 
131  [DllImport("PacDrive.dll", CallingConvention = CallingConvention.StdCall)]
132  [return: MarshalAs(UnmanagedType.Bool)]
133  private static extern bool PacProgramUHID(int Index, StringBuilder FileName);
134 
135 
136  #endregion
137 
138  private delegate void PAC_ATTACHED_CALLBACK(int Index);
139  private delegate void PAC_REMOVED_CALLBACK(int Index);
140 
141  public delegate void PacAttachedDelegate(int Index);
142  public delegate void PacRemovedDelegate(int Index);
143 
144  public event PacAttachedDelegate OnPacAttached = null;
145  public event PacRemovedDelegate OnPacRemoved = null;
146 
147  [MarshalAs(UnmanagedType.FunctionPtr)]
148  PAC_ATTACHED_CALLBACK PacAttachedCallbackPtr = null;
149 
150  [MarshalAs(UnmanagedType.FunctionPtr)]
151  PAC_REMOVED_CALLBACK PacRemovedCallbackPtr = null;
152 
153 
154  private int m_numDevices = 0;
155 
156 
157  private static readonly Lazy<PacDriveSingleton> lazy = new Lazy<PacDriveSingleton>(() => new PacDriveSingleton());
158 
159  public static PacDriveSingleton Instance { get { return lazy.Value; } }
160 
161 
162  private PacDriveSingleton()
163  {
164 
165 
166  PacAttachedCallbackPtr = new PAC_ATTACHED_CALLBACK(PacAttachedCallback);
167  PacRemovedCallbackPtr = new PAC_REMOVED_CALLBACK(PacRemovedCallback);
168 
169  PacSetCallbacks(PacAttachedCallbackPtr, PacRemovedCallbackPtr);
170  Initialize();
171  }
172 
173  private void PacAttachedCallback(int Index)
174  {
175  m_numDevices++;
176 
177  if (OnPacAttached != null)
178  OnPacAttached(Index);
179  }
180 
181  private void PacRemovedCallback(int Index)
182  {
183  m_numDevices--;
184 
185  if (OnPacRemoved != null)
186  OnPacRemoved(Index);
187  }
188 
189  private void Initialize()
190  {
191  m_numDevices = PacInitialize();
192 
193 
194  }
195 
196 
197 
198  public void Shutdown()
199  {
200  PacShutdown();
201  }
202 
203  #region PacDrive & UHID Led methods
204 
205  public bool PacDriveUHIDSetLEDStates(int Index, ushort Data)
206  {
207  return PacSetLEDStates(Index, Data);
208  }
209 
210  public bool PacDriveUHIDSetLEDState(int Index, int Port, bool State)
211  {
212  return PacSetLEDState(Index, Port, State);
213  }
214 
215  public bool PacDriveUHIDSetLEDStates(int Index, bool[] Data)
216  {
217  ushort dataSend = 0;
218 
219  for (int i = 0; i < Data.Length; i++)
220  if (Data[i]) dataSend |= (ushort)(1 << i);
221 
222  return PacSetLEDStates(Index, dataSend);
223  }
224  #endregion
225 
226  #region PacLed64 methods
227  public bool PacLed64SetLEDState(int Index, int Group, int Port, bool State)
228  {
229  return Pac64SetLEDState(Index, Group, Port, State);
230  }
231 
232  public bool PacLed64SetLEDStates(int Index, int Group, byte Data)
233  {
234  return Pac64SetLEDStates(Index, Group, Data);
235  }
236 
237 
238  public bool PacLed64SetLEDStates(int Index, byte[] Data) {
239  bool OK=true;
240  for (int i = 0; i < 8; i++)
241  {
242  OK&=Pac64SetLEDStates(Index,i+1,Data[i]);
243  }
244  return OK;
245  }
246 
247  public bool PacLed64SetLEDStates(int Index, int Group, bool[] Data)
248  {
249  byte dataSend = 0;
250 
251  for (int i = 0; i < Data.Length; i++)
252  if (Data[i]) dataSend |= (byte)(1 << i);
253 
254  return Pac64SetLEDStates(Index, Group, dataSend);
255  }
256 
257  public bool PacLed64SetLEDStatesRandom(int Index)
258  {
259  return Pac64SetLEDStatesRandom(Index);
260  }
261 
262  public bool PacLed64SetLEDIntensities(int Index, byte[] Data)
263  {
264  return Pac64SetLEDIntensities(Index, Data);
265  }
266 
267  public bool PacLed64SetLEDIntensity(int Index, int Port, byte Intensity)
268  {
269  return Pac64SetLEDIntensity(Index, Port, Intensity);
270  }
271 
272  public bool PacLed64SetLEDFadeTime(int Index, byte FadeTime)
273  {
274  return Pac64SetLEDFadeTime(Index, FadeTime);
275  }
276 
277  public bool PacLed64SetLEDFlashSpeeds(int Index, FlashSpeed FlashSpeed)
278  {
279  return Pac64SetLEDFlashSpeeds(Index, (byte)FlashSpeed);
280  }
281 
282  public bool PacLed64SetLEDFlashSpeed(int Index, int Port, FlashSpeed FlashSpeed)
283  {
284  return Pac64SetLEDFlashSpeed(Index, Port, (byte)FlashSpeed);
285  }
286 
287  public bool PacLed64StartScriptRecording(int Index)
288  {
289  return Pac64StartScriptRecording(Index);
290  }
291 
292  public bool PacLed64StopScriptRecording(int Index)
293  {
294  return Pac64StopScriptRecording(Index);
295  }
296 
297  public bool PacLed64SetScriptStepDelay(int Index, byte StepDelay)
298  {
299  return Pac64SetScriptStepDelay(Index, StepDelay);
300  }
301 
302  public bool PacLed64RunScript(int Index)
303  {
304  return Pac64RunScript(Index);
305  }
306 
307  public bool PacLed64ClearFlash(int Index)
308  {
309  return Pac64ClearFlash(Index);
310  }
311 
312  public bool PacLed64SetDeviceId(int Index, int NewId)
313  {
314  return Pac64SetDeviceId(Index, NewId);
315  }
316 
317  public int PacLed64GetDeviceId(int Index)
318  {
319  string S = GetDevicePath(Index);
320  //\\?\hid#vid_d209&pid_1402#7&f3bb0d5&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
321 
322  int IdPos = S.IndexOf("&pid_140");
323  if (IdPos >= 0)
324  {
325  IdPos += 8;
326  }
327  int Id = 0;
328  int.TryParse(S.Substring(IdPos,1), out Id);
329  return Id;
330  }
331 
332 
333  public int PacLed64GetIndexForDeviceId(int Id)
334  {
335  for (int i = 0; i < NumDevices; i++)
336  {
337  if (PacLed64GetDeviceId(i) == Id)
338  {
339  return i;
340  }
341  }
342  return -1;
343  }
344 
345  #endregion
346 
347  public DeviceType GetDeviceType(int Index)
348  {
349  return (DeviceType)PacGetDeviceType(Index);
350  }
351 
352  public int GetVendorId(int Index)
353  {
354  return PacGetVendorId(Index);
355  }
356 
357  public int GetProductId(int Index)
358  {
359  return PacGetProductId(Index);
360  }
361 
362  public int GetVersionNumber(int Index)
363  {
364  return PacGetVersionNumber(Index);
365  }
366 
367  public string GetVendorName(int Index)
368  {
369  StringBuilder sb = new StringBuilder(256);
370 
371  PacGetVendorName(Index, sb);
372 
373  return sb.ToString();
374  }
375 
376  public string GetProductName(int Index)
377  {
378  StringBuilder sb = new StringBuilder(256);
379 
380  PacGetProductName(Index, sb);
381 
382  return sb.ToString();
383  }
384 
385  public string GetSerialNumber(int Index)
386  {
387  StringBuilder sb = new StringBuilder(256);
388 
389  PacGetSerialNumber(Index, sb);
390 
391  return sb.ToString();
392  }
393 
394  public string GetDevicePath(int Index)
395  {
396  StringBuilder sb = new StringBuilder(256);
397 
398  PacGetDevicePath(Index, sb);
399 
400  return sb.ToString();
401  }
402 
407  public List<int> PacLed64GetIdList()
408  {
409  List<int> L = new List<int>();
410 
411 
412  for (int i = 0; i < NumDevices; i++)
413  {
414  if (GetDeviceType(i) == DeviceType.PacLED64)
415  {
416  L.Add(PacLed64GetDeviceId(i));
417  }
418  }
419 
420 
421  return L;
422  }
423 
424 
431  public int NumDevices
432  {
433  get { return m_numDevices; }
434  }
435  }
436 }