@@ -84,8 +84,8 @@ public GamelogicEngineLamp[] AvailableLamps {
84
84
private Dictionary < int , GamelogicEngineLamp > _lamps = new Dictionary < int , GamelogicEngineLamp > ( ) ;
85
85
86
86
private bool _isRunning ;
87
- private HashSet < int > _displayAnnounced = new HashSet < int > ( ) ;
88
87
private Dictionary < int , byte [ ] > _frameBuffer = new Dictionary < int , byte [ ] > ( ) ;
88
+ private Dictionary < int , Dictionary < byte , byte > > _dmdLevels = new Dictionary < int , Dictionary < byte , byte > > ( ) ;
89
89
90
90
private static readonly Logger Logger = LogManager . GetCurrentClassLogger ( ) ;
91
91
private static readonly Color Tint = new Color ( 1 , 0.18f , 0 ) ;
@@ -104,11 +104,12 @@ public void OnInit(Player player, TableApi tableApi, BallManager ballManager)
104
104
OnLampChanged ? . Invoke ( this , new LampEventArgs ( lamp . Id , 0 ) ) ;
105
105
}
106
106
107
- _pinMame = PinMame . PinMame . Instance ( 48000 , @"D:\Pinball\Visual Pinball\VPinMAME" ) ;
107
+ _pinMame = PinMame . PinMame . Instance ( ) ;
108
108
_pinMame . OnGameStarted += GameStarted ;
109
109
_pinMame . OnGameEnded += GameEnded ;
110
110
_pinMame . OnDisplayUpdated += DisplayUpdated ;
111
111
_pinMame . OnSolenoidUpdated += SolenoidUpdated ;
112
+ _pinMame . OnDisplayAvailable += OnDisplayAvailable ;
112
113
_player = player ;
113
114
114
115
try {
@@ -120,7 +121,7 @@ public void OnInit(Player player, TableApi tableApi, BallManager ballManager)
120
121
}
121
122
}
122
123
123
- private void GameStarted ( object sender , EventArgs e )
124
+ private void GameStarted ( )
124
125
{
125
126
Logger . Info ( $ "[PinMAME] Game started.") ;
126
127
_isRunning = true ;
@@ -151,71 +152,70 @@ private void Update()
151
152
}
152
153
}
153
154
154
- private void DisplayUpdated ( object sender , EventArgs e , int index , IntPtr framePtr , PinMameDisplayLayout displayLayout )
155
+ private void OnDisplayAvailable ( int index , int displayCount , PinMameDisplayLayout displayLayout )
155
156
{
156
157
if ( displayLayout . IsDmd ) {
157
- UpdateDmd ( index , displayLayout , framePtr ) ;
158
+ lock ( _dispatchQueue ) {
159
+ _dispatchQueue . Enqueue ( ( ) =>
160
+ OnDisplaysAvailable ? . Invoke ( this , new AvailableDisplays (
161
+ new DisplayConfig ( $ "{ DmdPrefix } { index } ", displayLayout . Width , displayLayout . Height ) ) ) ) ;
162
+ }
158
163
159
- } else {
160
- UpdateSegDisp ( index , displayLayout , framePtr ) ;
161
- }
162
- }
164
+ _frameBuffer [ index ] = new byte [ displayLayout . Width * displayLayout . Height ] ;
165
+ _dmdLevels [ index ] = displayLayout . Levels ;
163
166
164
- private void UpdateDmd ( int index , PinMameDisplayLayout displayLayout , IntPtr framePtr )
165
- {
166
- if ( ! _displayAnnounced . Contains ( index ) ) {
167
+ } else {
167
168
lock ( _dispatchQueue ) {
168
169
_dispatchQueue . Enqueue ( ( ) =>
169
170
OnDisplaysAvailable ? . Invoke ( this , new AvailableDisplays (
170
- new DisplayConfig ( $ "{ DmdPrefix } { index } ", displayLayout . width , displayLayout . height ) ) ) ) ;
171
+ new DisplayConfig ( $ "{ SegDispPrefix } { index } ", displayLayout . Length , 1 ) ) ) ) ;
171
172
}
172
173
173
- _displayAnnounced . Add ( index ) ;
174
- _frameBuffer [ index ] = new byte [ displayLayout . width * displayLayout . height ] ;
174
+ _frameBuffer [ index ] = new byte [ displayLayout . Length * 2 ] ;
175
+ Logger . Info ( $ "[PinMAME] Display { SegDispPrefix } { index } is of type { displayLayout . Type } at { displayLayout . Length } wide." ) ;
175
176
}
177
+ }
178
+
179
+ private void DisplayUpdated ( int index , IntPtr framePtr , PinMameDisplayLayout displayLayout )
180
+ {
181
+ if ( displayLayout . IsDmd ) {
182
+ UpdateDmd ( index , displayLayout , framePtr ) ;
176
183
177
- var map = GetMap ( displayLayout ) ;
184
+ } else {
185
+ UpdateSegDisp ( index , displayLayout , framePtr ) ;
186
+ }
187
+ }
188
+
189
+ private void UpdateDmd ( int index , PinMameDisplayLayout displayLayout , IntPtr framePtr )
190
+ {
178
191
unsafe {
179
192
var ptr = ( byte * ) framePtr ;
180
- for ( var y = 0 ; y < displayLayout . height ; y ++ ) {
181
- for ( var x = 0 ; x < displayLayout . width ; x ++ ) {
182
- var pos = y * displayLayout . width + x ;
183
- _frameBuffer [ index ] [ pos ] = map [ ptr [ pos ] ] ;
193
+ for ( var y = 0 ; y < displayLayout . Height ; y ++ ) {
194
+ for ( var x = 0 ; x < displayLayout . Width ; x ++ ) {
195
+ var pos = y * displayLayout . Width + x ;
196
+ _frameBuffer [ index ] [ pos ] = _dmdLevels [ index ] [ ptr [ pos ] ] ;
184
197
}
185
198
}
186
199
}
187
200
188
201
lock ( _dispatchQueue ) {
189
202
_dispatchQueue . Enqueue ( ( ) => OnDisplayFrame ? . Invoke ( this ,
190
- new DisplayFrameData ( $ "{ DmdPrefix } { index } ", GetDisplayType ( displayLayout . type ) , _frameBuffer [ index ] ) ) ) ;
203
+ new DisplayFrameData ( $ "{ DmdPrefix } { index } ", GetDisplayType ( displayLayout . Type ) , _frameBuffer [ index ] ) ) ) ;
191
204
}
192
205
}
193
206
194
207
private void UpdateSegDisp ( int index , PinMameDisplayLayout displayLayout , IntPtr framePtr )
195
208
{
196
- if ( ! _displayAnnounced . Contains ( index ) ) {
197
- lock ( _dispatchQueue ) {
198
- _dispatchQueue . Enqueue ( ( ) =>
199
- OnDisplaysAvailable ? . Invoke ( this , new AvailableDisplays (
200
- new DisplayConfig ( $ "{ SegDispPrefix } { index } ", displayLayout . length , 1 ) ) ) ) ;
201
- }
202
-
203
- _displayAnnounced . Add ( index ) ;
204
- _frameBuffer [ index ] = new byte [ displayLayout . length * 2 ] ;
205
- Logger . Info ( $ "[PinMAME] Display { SegDispPrefix } { index } is of type { displayLayout . type } at { displayLayout . length } wide.") ;
206
- }
207
-
208
- Marshal . Copy ( framePtr , _frameBuffer [ index ] , 0 , displayLayout . length * 2 ) ;
209
+ Marshal . Copy ( framePtr , _frameBuffer [ index ] , 0 , displayLayout . Length * 2 ) ;
209
210
210
211
lock ( _dispatchQueue ) {
211
212
//Logger.Info($"[PinMAME] Seg data ({index}): {BitConverter.ToString(_frameBuffer[index])}" );
212
213
_dispatchQueue . Enqueue ( ( ) => OnDisplayFrame ? . Invoke ( this ,
213
- new DisplayFrameData ( $ "{ SegDispPrefix } { index } ", GetDisplayType ( displayLayout . type ) , _frameBuffer [ index ] ) ) ) ;
214
+ new DisplayFrameData ( $ "{ SegDispPrefix } { index } ", GetDisplayType ( displayLayout . Type ) , _frameBuffer [ index ] ) ) ) ;
214
215
}
215
-
216
216
}
217
217
218
- private void SolenoidUpdated ( object sender , EventArgs e , int internalId , bool isActive )
218
+ private void SolenoidUpdated ( int internalId , bool isActive )
219
219
{
220
220
if ( _coils . ContainsKey ( internalId ) ) {
221
221
Logger . Info ( $ "[PinMAME] <= coil { _coils [ internalId ] . Id } ({ internalId } ): { isActive } | { _coils [ internalId ] . Description } ") ;
@@ -230,7 +230,7 @@ private void SolenoidUpdated(object sender, EventArgs e, int internalId, bool is
230
230
}
231
231
}
232
232
233
- private void GameEnded ( object sender , EventArgs e )
233
+ private void GameEnded ( )
234
234
{
235
235
Logger . Info ( $ "[PinMAME] Game ended.") ;
236
236
_isRunning = false ;
@@ -287,7 +287,7 @@ public void StopGame()
287
287
_pinMame . OnSolenoidUpdated -= SolenoidUpdated ;
288
288
}
289
289
_frameBuffer . Clear ( ) ;
290
- _displayAnnounced . Clear ( ) ;
290
+ _dmdLevels . Clear ( ) ;
291
291
}
292
292
293
293
public void Switch ( string id , bool isClosed )
@@ -300,62 +300,50 @@ public void Switch(string id, bool isClosed)
300
300
}
301
301
}
302
302
303
-
304
- private Dictionary < byte , byte > GetMap ( PinMameDisplayLayout displayLayout )
305
- {
306
- if ( displayLayout . depth == 2 ) {
307
- return DmdMap2Bit ;
308
- }
309
-
310
- return ( _pinMame . GetHardwareGen ( ) & ( PinMameHardwareGen . SAM | PinMameHardwareGen . SPA ) ) > 0
311
- ? DmdMapSam
312
- : DmdMapGts ;
313
- }
314
-
315
303
private static DisplayFrameFormat GetDisplayType ( PinMameDisplayType dp )
316
304
{
317
305
switch ( dp ) {
318
- case PinMameDisplayType . SEG8 : // 7 segments and comma
319
- case PinMameDisplayType . SEG8D : // 7 segments and period
320
- case PinMameDisplayType . SEG7 : // 7 segments
321
- case PinMameDisplayType . SEG87 : // 7 segments, comma every three
322
- case PinMameDisplayType . SEG87F : // 7 segments, forced comma every three
323
- case PinMameDisplayType . SEG7S : // 7 segments, small
324
- case PinMameDisplayType . SEG7SC : // 7 segments, small, with comma
306
+ case PinMameDisplayType . Seg8 : // 7 segments and comma
307
+ case PinMameDisplayType . Seg8D : // 7 segments and period
308
+ case PinMameDisplayType . Seg7 : // 7 segments
309
+ case PinMameDisplayType . Seg87 : // 7 segments, comma every three
310
+ case PinMameDisplayType . Seg87F : // 7 segments, forced comma every three
311
+ case PinMameDisplayType . Seg7S : // 7 segments, small
312
+ case PinMameDisplayType . Seg7SC : // 7 segments, small, with comma
325
313
return DisplayFrameFormat . Segment7 ;
326
314
327
- case PinMameDisplayType . SEG10 : // 9 segments and comma
328
- case PinMameDisplayType . SEG9 : // 9 segments
329
- case PinMameDisplayType . SEG98 : // 9 segments, comma every three
330
- case PinMameDisplayType . SEG98F : // 9 segments, forced comma every three
315
+ case PinMameDisplayType . Seg10 : // 9 segments and comma
316
+ case PinMameDisplayType . Seg9 : // 9 segments
317
+ case PinMameDisplayType . Seg98 : // 9 segments, comma every three
318
+ case PinMameDisplayType . Seg98F : // 9 segments, forced comma every three
331
319
return DisplayFrameFormat . Segment9 ;
332
320
333
- case PinMameDisplayType . SEG16 : // 16 segments
334
- case PinMameDisplayType . SEG16R : // 16 segments with comma and period reversed
335
- case PinMameDisplayType . SEG16N : // 16 segments without commas
336
- case PinMameDisplayType . SEG16D : // 16 segments with periods only
337
- case PinMameDisplayType . SEG16S : // 16 segments with split top and bottom line
321
+ case PinMameDisplayType . Seg16 : // 16 segments
322
+ case PinMameDisplayType . Seg16R : // 16 segments with comma and period reversed
323
+ case PinMameDisplayType . Seg16N : // 16 segments without commas
324
+ case PinMameDisplayType . Seg16D : // 16 segments with periods only
325
+ case PinMameDisplayType . Seg16S : // 16 segments with split top and bottom line
338
326
return DisplayFrameFormat . Segment16 ;
339
327
340
- case PinMameDisplayType . DMD :
328
+ case PinMameDisplayType . Dmd :
341
329
return DisplayFrameFormat . Dmd2 ;
342
330
343
- case PinMameDisplayType . VIDEO :
331
+ case PinMameDisplayType . Video :
344
332
break ;
345
333
346
- case PinMameDisplayType . SEGALL :
347
- case PinMameDisplayType . IMPORT :
348
- case PinMameDisplayType . SEGMASK :
349
- case PinMameDisplayType . SEGHIBIT :
350
- case PinMameDisplayType . SEGREV :
351
- case PinMameDisplayType . DMDNOAA :
352
- case PinMameDisplayType . NODISP :
353
- case PinMameDisplayType . SEG8H :
354
- case PinMameDisplayType . SEG7H :
355
- case PinMameDisplayType . SEG87H :
356
- case PinMameDisplayType . SEG87FH :
357
- case PinMameDisplayType . SEG7SH :
358
- case PinMameDisplayType . SEG7SCH :
334
+ case PinMameDisplayType . SegAll :
335
+ case PinMameDisplayType . Import :
336
+ case PinMameDisplayType . SegMask :
337
+ case PinMameDisplayType . SegHiBit :
338
+ case PinMameDisplayType . SegRev :
339
+ case PinMameDisplayType . DmdNoAA :
340
+ case PinMameDisplayType . NoDisp :
341
+ case PinMameDisplayType . Seg8H :
342
+ case PinMameDisplayType . Seg7H :
343
+ case PinMameDisplayType . Seg87H :
344
+ case PinMameDisplayType . Seg87FH :
345
+ case PinMameDisplayType . Seg7SH :
346
+ case PinMameDisplayType . Seg7SCH :
359
347
throw new ArgumentOutOfRangeException ( nameof ( dp ) , dp , null ) ;
360
348
361
349
default :
@@ -364,27 +352,5 @@ private static DisplayFrameFormat GetDisplayType(PinMameDisplayType dp)
364
352
365
353
throw new NotImplementedException ( $ "Still unsupported segmented display format: { dp } .") ;
366
354
}
367
-
368
- private static readonly Dictionary < byte , byte > DmdMap2Bit = new Dictionary < byte , byte > {
369
- { 0x00 , 0x0 } ,
370
- { 0x14 , 0x0 } ,
371
- { 0x21 , 0x1 } ,
372
- { 0x43 , 0x2 } ,
373
- { 0x64 , 0x3 } ,
374
- } ;
375
-
376
- private static readonly Dictionary < byte , byte > DmdMapSam = new Dictionary < byte , byte > {
377
- { 0x00 , 0x0 } , { 0x14 , 0x1 } , { 0x19 , 0x2 } , { 0x1E , 0x3 } ,
378
- { 0x23 , 0x4 } , { 0x28 , 0x5 } , { 0x2D , 0x6 } , { 0x32 , 0x7 } ,
379
- { 0x37 , 0x8 } , { 0x3C , 0x9 } , { 0x41 , 0xa } , { 0x46 , 0xb } ,
380
- { 0x4B , 0xc } , { 0x50 , 0xd } , { 0x5A , 0xe } , { 0x64 , 0xf }
381
- } ;
382
-
383
- private static readonly Dictionary < byte , byte > DmdMapGts = new Dictionary < byte , byte > {
384
- { 0x00 , 0x0 } , { 0x1E , 0x1 } , { 0x23 , 0x2 } , { 0x28 , 0x3 } ,
385
- { 0x2D , 0x4 } , { 0x32 , 0x5 } , { 0x37 , 0x6 } , { 0x3C , 0x7 } ,
386
- { 0x41 , 0x8 } , { 0x46 , 0x9 } , { 0x4B , 0xa } , { 0x50 , 0xb } ,
387
- { 0x55 , 0xc } , { 0x5A , 0xd } , { 0x5F , 0xe } , { 0x64 , 0xf }
388
- } ;
389
355
}
390
356
}
0 commit comments