18
18
using System . Collections . Generic ;
19
19
using System . Linq ;
20
20
using NLog ;
21
+ using PinMame ;
21
22
using UnityEngine ;
22
23
using VisualPinball . Engine . Game . Engines ;
23
24
using VisualPinball . Unity ;
@@ -76,6 +77,7 @@ public GamelogicEngineLamp[] AvailableLamps {
76
77
77
78
private const string DisplayDmd = "dmd" ;
78
79
80
+ private bool _isRunning ;
79
81
private bool _sizeAnnounced ;
80
82
81
83
private static readonly Logger Logger = LogManager . GetCurrentClassLogger ( ) ;
@@ -94,10 +96,62 @@ public void OnInit(Player player, TableApi tableApi, BallManager ballManager)
94
96
}
95
97
96
98
_pinMame = PinMame . PinMame . Instance ( ) ;
97
- _pinMame . StartGame ( romId , showConsole : true ) ;
99
+ _pinMame . OnGameStarted += GameStarted ;
100
+ _pinMame . OnGameEnded += GameEnded ;
101
+ _pinMame . OnDisplayUpdate += DisplayUpdated ;
102
+ _pinMame . OnSolenoid += SolenoidChanged ;
103
+ _pinMame . StartGame ( romId ) ;
98
104
_player = player ;
99
105
}
100
106
107
+ private void GameStarted ( object sender , EventArgs e )
108
+ {
109
+ Logger . Info ( $ "[PinMAME] Game started.") ;
110
+ _isRunning = true ;
111
+ }
112
+
113
+ private void DisplayUpdated ( object sender , EventArgs e , int index , IntPtr framePtr , PinMameDisplayLayout displayLayout )
114
+ {
115
+ if ( ( displayLayout . type & PinMameDisplayType . DMD ) > 0 ) {
116
+ UpdateDmd ( index , displayLayout , framePtr ) ;
117
+ } else {
118
+ UpdateSegDisp ( index , displayLayout , framePtr ) ;
119
+ }
120
+ }
121
+
122
+ private void UpdateSegDisp ( int index , PinMameDisplayLayout displayLayout , IntPtr framePtr )
123
+ {
124
+
125
+ }
126
+
127
+
128
+ private void UpdateDmd ( int index , PinMameDisplayLayout displayLayout , IntPtr framePtr )
129
+ {
130
+ if ( ! _sizeAnnounced ) {
131
+ OnDisplaysAvailable ? . Invoke ( this , new AvailableDisplays ( new DisplayConfig ( DisplayDmd , displayLayout . width , displayLayout . height ) ) ) ;
132
+ _sizeAnnounced = true ;
133
+ }
134
+ OnDisplayFrame ? . Invoke ( this , new DisplayFrameData ( DisplayDmd , GetDisplayType ( displayLayout . type ) , framePtr ) ) ;
135
+
136
+ }
137
+
138
+ private void SolenoidChanged ( object sender , EventArgs e , int internalId , bool isActive )
139
+ {
140
+ if ( _coils . ContainsKey ( internalId ) ) {
141
+ Logger . Info ( $ "[PinMAME] <= coil { _coils [ internalId ] . Id } ({ internalId } ): { isActive } | { _coils [ internalId ] . Description } ") ;
142
+ OnCoilChanged ? . Invoke ( this , new CoilEventArgs ( _coils [ internalId ] . Id , isActive ) ) ;
143
+
144
+ } else {
145
+ Logger . Warn ( $ "[PinMAME] <= coil UNMAPPED { internalId } : { isActive } ") ;
146
+ }
147
+ }
148
+
149
+ private void GameEnded ( object sender , EventArgs e )
150
+ {
151
+ Logger . Info ( $ "[PinMAME] Game ended.") ;
152
+ _isRunning = false ;
153
+ }
154
+
101
155
public void SendInitialSwitches ( )
102
156
{
103
157
var switches = _player . SwitchStatusesClosed ;
@@ -117,25 +171,10 @@ public void SendInitialSwitches()
117
171
118
172
private void Update ( )
119
173
{
120
- if ( _pinMame == null || ! _pinMame . IsRunning ) {
174
+ if ( _pinMame == null || ! _isRunning ) {
121
175
return ;
122
176
}
123
177
124
- // coils
125
- var changedCoils = _pinMame . GetChangedSolenoids ( ) ;
126
- for ( var i = 0 ; i < changedCoils . Length ; i += 2 ) {
127
- var internalId = changedCoils [ i ] ;
128
- var val = changedCoils [ i + 1 ] ;
129
-
130
- if ( _coils . ContainsKey ( internalId ) ) {
131
- Logger . Info ( $ "[PinMAME] <= coil { _coils [ internalId ] . Id } ({ internalId } ): { val } | { _coils [ internalId ] . Description } ") ;
132
- OnCoilChanged ? . Invoke ( this , new CoilEventArgs ( _coils [ internalId ] . Id , val == 1 ) ) ;
133
-
134
- } else {
135
- Logger . Warn ( $ "[PinMAME] <= coil UNMAPPED { internalId } : { val } ") ;
136
- }
137
- }
138
-
139
178
// lamps
140
179
var changedLamps = _pinMame . GetChangedLamps ( ) ;
141
180
for ( var i = 0 ; i < changedLamps . Length ; i += 2 ) {
@@ -147,20 +186,8 @@ private void Update()
147
186
OnLampChanged ? . Invoke ( this , new LampEventArgs ( _lamps [ internalId ] . Id , val ) ) ;
148
187
}
149
188
}
150
-
151
- // dmd
152
- if ( _pinMame . NeedsDmdUpdate ( ) ) {
153
- if ( ! _sizeAnnounced ) {
154
- var dim = _pinMame . GetDmdDimensions ( ) ;
155
- OnDisplaysAvailable ? . Invoke ( this , new AvailableDisplays (
156
- new DisplayConfig ( DisplayDmd , DisplayType . Dmd2PinMame , dim . Width , dim . Height ) ) ) ;
157
- _sizeAnnounced = true ;
158
- }
159
- OnDisplayFrame ? . Invoke ( this , new DisplayFrameData ( DisplayDmd , _pinMame . GetDmdPixels ( ) ) ) ;
160
- }
161
189
}
162
190
163
-
164
191
private void UpdateCaches ( )
165
192
{
166
193
if ( _game == null ) {
@@ -182,7 +209,12 @@ private void UpdateCaches()
182
209
183
210
private void OnDestroy ( )
184
211
{
185
- _pinMame ? . StopGame ( ) ;
212
+ if ( _pinMame != null ) {
213
+ _pinMame . StopGame ( ) ;
214
+ _pinMame . OnGameStarted -= GameStarted ;
215
+ _pinMame . OnGameEnded -= GameEnded ;
216
+ _pinMame . OnDisplayUpdate -= DisplayUpdated ;
217
+ }
186
218
}
187
219
188
220
public void Switch ( string id , bool isClosed )
@@ -194,28 +226,52 @@ public void Switch(string id, bool isClosed)
194
226
Logger . Error ( $ "[PinMAME] Unknown switch \" { id } \" .") ;
195
227
}
196
228
}
197
- }
198
229
199
- // internal readonly struct DisplayKey : IEquatable<DisplayKey>
200
- // {
201
- // private readonly int _width;
202
- // private readonly int _height;
203
- // private readonly int _bitLength;
204
- //
205
- // public DisplayKey(int width, int height, int bitLength)
206
- // {
207
- // _width = width;
208
- // _height = height;
209
- // _bitLength = bitLength;
210
- // }
211
- //
212
- // public override bool Equals(object obj) => obj is DisplayKey other && Equals(other);
213
- //
214
- // public bool Equals(DisplayKey other)
215
- // {
216
- // return _width == other._width && _height == other._height && _bitLength == other._bitLength;
217
- // }
218
- //
219
- // public override int GetHashCode() => (_width, _height, _bitLength).GetHashCode();
220
- // }
230
+ private static DisplayFrameFormat GetDisplayType ( PinMameDisplayType dp )
231
+ {
232
+ switch ( dp ) {
233
+ case PinMameDisplayType . SEG16 :
234
+ break ;
235
+ case PinMameDisplayType . SEG16R :
236
+ break ;
237
+ case PinMameDisplayType . SEG10 :
238
+ break ;
239
+ case PinMameDisplayType . SEG9 :
240
+ break ;
241
+ case PinMameDisplayType . SEG8 :
242
+ break ;
243
+ case PinMameDisplayType . SEG8D :
244
+ break ;
245
+ case PinMameDisplayType . SEG7 :
246
+ break ;
247
+ case PinMameDisplayType . SEG87 :
248
+ break ;
249
+ case PinMameDisplayType . SEG87F :
250
+ break ;
251
+ case PinMameDisplayType . SEG98 :
252
+ break ;
253
+ case PinMameDisplayType . SEG98F :
254
+ break ;
255
+ case PinMameDisplayType . SEG7S :
256
+ break ;
257
+ case PinMameDisplayType . SEG7SC :
258
+ break ;
259
+ case PinMameDisplayType . SEG16S :
260
+ break ;
261
+ case PinMameDisplayType . DMD :
262
+ return DisplayFrameFormat . Dmd2PinMame ;
263
+
264
+ case PinMameDisplayType . VIDEO :
265
+ break ;
266
+ case PinMameDisplayType . SEG16N :
267
+ break ;
268
+ case PinMameDisplayType . SEG16D :
269
+ break ;
270
+ default :
271
+ throw new ArgumentOutOfRangeException ( nameof ( dp ) , dp , null ) ;
272
+ }
273
+
274
+ throw new NotImplementedException ( "only dmd frames supported for now" ) ;
275
+ }
276
+ }
221
277
}
0 commit comments