Skip to content

Commit de67684

Browse files
committed
mech: Use switch IDs from mappings.
1 parent bd00d67 commit de67684

File tree

2 files changed

+95
-57
lines changed

2 files changed

+95
-57
lines changed

VisualPinball.Engine.PinMAME.Unity/Runtime/PinMameGamelogicEngine.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ public GamelogicEngineLamp[] AvailableLamps {
118118
public bool _solenoidsEnabled;
119119
public long _solenoidDelayStart;
120120
private Dictionary<int, PinMameMechComponent> _registeredMechs = new();
121+
private HashSet<int> _mechSwitches = new();
121122

122123
private void Awake()
123124
{
@@ -182,10 +183,7 @@ private void OnGameStarted()
182183
_isRunning = true;
183184

184185
SendInitialSwitches();
185-
186-
foreach (var (id, mech) in _registeredMechs) {
187-
_pinMame.SetMech(id, mech.Config);
188-
}
186+
SendMechs();
189187

190188
_solenoidDelayStart = DateTimeOffset.Now.ToUnixTimeMilliseconds();
191189
}
@@ -478,13 +476,24 @@ public void SendInitialSwitches()
478476
if (!isClosed) {
479477
continue;
480478
}
481-
if (_switches.ContainsKey(id)) {
479+
if (_switches.ContainsKey(id) && !_mechSwitches.Contains(_switches[id].InternalId)) {
482480
Logger.Info($"[PinMAME] => sw {id} ({_switches[id].InternalId}): {true} | {_switches[id].Description}");
483481
_pinMame.SetSwitch(_switches[id].InternalId, true);
484482
}
485483
}
486484
}
487485

486+
private void SendMechs()
487+
{
488+
foreach (var (id, mech) in _registeredMechs) {
489+
var mechConfig = mech.Config(_player.SwitchMapping);
490+
_pinMame.SetMech(id, mechConfig);
491+
foreach (var c in mechConfig.SwitchList) {
492+
_mechSwitches.Add(c.SwNo);
493+
}
494+
}
495+
}
496+
488497
private void UpdateCaches()
489498
{
490499
if (_game == null) {
@@ -536,6 +545,10 @@ public void StopGame()
536545
public void Switch(string id, bool isClosed)
537546
{
538547
if (_switches.ContainsKey(id)) {
548+
if (_mechSwitches.Contains(_switches[id].InternalId)) {
549+
// mech switches are triggered internally by pinmame.
550+
return;
551+
}
539552
Logger.Info($"[PinMAME] => sw {id} ({_switches[id].InternalId}): {isClosed} | {_switches[id].Description}");
540553
_pinMame.SetSwitch(_switches[id].InternalId, isClosed);
541554
} else {

VisualPinball.Engine.PinMAME.Unity/Runtime/PinMameMechComponent.cs

Lines changed: 77 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,19 @@
1717
// ReSharper disable InconsistentNaming
1818

1919
using System;
20+
using System.Collections.Generic;
21+
using System.Linq;
2022
using NLog;
2123
using PinMame;
2224
using UnityEngine;
25+
using VisualPinball.Engine.Game.Engines;
2326
using VisualPinball.Unity;
2427
using Logger = NLog.Logger;
2528

2629
namespace VisualPinball.Engine.PinMAME
2730
{
2831
[AddComponentMenu("Visual Pinball/PinMAME/PinMAME Mech Handler")]
29-
public class PinMameMechComponent : MonoBehaviour, IMechHandler
32+
public class PinMameMechComponent : MonoBehaviour, IMechHandler, ISwitchDeviceComponent, ISerializationCallbackReceiver
3033
{
3134
#region Data
3235

@@ -61,7 +64,7 @@ public class PinMameMechComponent : MonoBehaviour, IMechHandler
6164
public int Steps;
6265

6366
[Tooltip("Define your switch marks here.")]
64-
public PinMameMechSwitchMark[] Marks;
67+
public MechMark[] Marks;
6568

6669
[Unit("ms")]
6770
[Min(0)]
@@ -78,66 +81,67 @@ public class PinMameMechComponent : MonoBehaviour, IMechHandler
7881

7982
public event EventHandler<MechEventArgs> OnMechUpdate;
8083

81-
public PinMameMechConfig Config
84+
public PinMameMechConfig Config(List<SwitchMapping> switchMappings)
8285
{
83-
get {
84-
var type = 0u;
85-
type |= Type switch {
86-
PinMameMechType.OneSolenoid => (uint)PinMameMechFlag.OneSol,
87-
PinMameMechType.OneDirectionalSolenoid => (uint)PinMameMechFlag.OneDirSol,
88-
PinMameMechType.TwoDirectionalSolenoids => (uint)PinMameMechFlag.TwoDirSol,
89-
PinMameMechType.TwoStepperSolenoids => (uint)PinMameMechFlag.TwoStepSol,
90-
PinMameMechType.FourStepperSolenoids => (uint)PinMameMechFlag.FourStepSol,
91-
_ => throw new ArgumentOutOfRangeException()
92-
};
93-
94-
type |= Repeat switch {
95-
PinMameRepeat.Circle => (uint)PinMameMechFlag.Circle,
96-
PinMameRepeat.Reverse => (uint)PinMameMechFlag.Reverse,
97-
PinMameRepeat.StopAtEnd => (uint)PinMameMechFlag.StopEnd,
98-
_ => throw new ArgumentOutOfRangeException()
99-
};
100-
101-
type |= LinearMovement ? (uint)PinMameMechFlag.Linear : (uint)PinMameMechFlag.NonLinear;
102-
type |= FastUpdates ? (uint)PinMameMechFlag.Fast : (uint)PinMameMechFlag.Slow;
103-
type |= ResultByLength ? (uint)PinMameMechFlag.LengthSw : (uint)PinMameMechFlag.StepSw;
104-
105-
var mechConfig = new PinMameMechConfig(
106-
type,
107-
Solenoid1,
108-
Solenoid2,
109-
Length,
110-
Steps,
111-
0,
112-
Acceleration,
113-
Retardation
114-
);
115-
116-
foreach(var mark in Marks) {
117-
switch (mark.Type) {
118-
case PinMameMechSwitchMarkType.Switch:
119-
mechConfig.AddSwitch(new PinMameMechSwitchConfig(mark.SwitchId, mark.StepBeginning, mark.StepEnd));
120-
break;
121-
case PinMameMechSwitchMarkType.PulseSwitch:
122-
mechConfig.AddSwitch(new PinMameMechSwitchConfig(mark.SwitchId, mark.StepBeginning, mark.StepPulseDuration, 1));
123-
break;
124-
case PinMameMechSwitchMarkType.PulseSwitchNew:
125-
mechConfig.AddSwitch(new PinMameMechSwitchConfig(mark.SwitchId, mark.StepBeginning, mark.StepEnd, mark.StepPulseDuration));
126-
break;
127-
default:
128-
throw new ArgumentOutOfRangeException();
129-
}
86+
var type = 0u;
87+
type |= Type switch {
88+
PinMameMechType.OneSolenoid => (uint)PinMameMechFlag.OneSol,
89+
PinMameMechType.OneDirectionalSolenoid => (uint)PinMameMechFlag.OneDirSol,
90+
PinMameMechType.TwoDirectionalSolenoids => (uint)PinMameMechFlag.TwoDirSol,
91+
PinMameMechType.TwoStepperSolenoids => (uint)PinMameMechFlag.TwoStepSol,
92+
PinMameMechType.FourStepperSolenoids => (uint)PinMameMechFlag.FourStepSol,
93+
_ => throw new ArgumentOutOfRangeException()
94+
};
95+
96+
type |= Repeat switch {
97+
PinMameRepeat.Circle => (uint)PinMameMechFlag.Circle,
98+
PinMameRepeat.Reverse => (uint)PinMameMechFlag.Reverse,
99+
PinMameRepeat.StopAtEnd => (uint)PinMameMechFlag.StopEnd,
100+
_ => throw new ArgumentOutOfRangeException()
101+
};
102+
103+
type |= LinearMovement ? (uint)PinMameMechFlag.Linear : (uint)PinMameMechFlag.NonLinear;
104+
type |= FastUpdates ? (uint)PinMameMechFlag.Fast : (uint)PinMameMechFlag.Slow;
105+
type |= ResultByLength ? (uint)PinMameMechFlag.LengthSw : (uint)PinMameMechFlag.StepSw;
106+
107+
var mechConfig = new PinMameMechConfig(
108+
type,
109+
Solenoid1,
110+
Solenoid2,
111+
Length,
112+
Steps,
113+
0,
114+
Acceleration,
115+
Retardation
116+
);
117+
118+
foreach (var mark in Marks) {
119+
var switchMapping = switchMappings.FirstOrDefault(sm => sm.Device == this && sm.DeviceItem == mark.SwitchId);
120+
if (switchMapping == null) {
121+
Logger.Error($"Switch \"{mark.Description}\" for mech {name} is not mapped in the switch manager, ignoring.");
122+
continue;
130123
}
131-
132-
return mechConfig;
124+
mechConfig.AddSwitch(new PinMameMechSwitchConfig(switchMapping.InternalId, mark.StepBeginning, mark.StepEnd, mark.Pulse));
133125
}
134126

127+
return mechConfig;
128+
135129
}
136130

137131
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
138132

139133
#endregion
140134

135+
#region Wiring
136+
137+
public IEnumerable<GamelogicEngineSwitch> AvailableSwitches => Marks.Select(m => m.Switch);
138+
139+
public SwitchDefault SwitchDefault => SwitchDefault.NormallyOpen;
140+
141+
IEnumerable<GamelogicEngineSwitch> IDeviceComponent<GamelogicEngineSwitch>.AvailableDeviceItems => AvailableSwitches;
142+
143+
#endregion
144+
141145
#region Runtime
142146

143147
private PinMameGamelogicEngine _gle;
@@ -157,6 +161,27 @@ public void UpdateMech(PinMameMechInfo data)
157161

158162
#endregion
159163

164+
#region ISerializationCallbackReceiver
165+
166+
public void OnBeforeSerialize()
167+
{
168+
#if UNITY_EDITOR
169+
170+
var switchIds = new HashSet<string>();
171+
foreach (var mark in Marks) {
172+
if (!mark.HasId || switchIds.Contains(mark.SwitchId)) {
173+
mark.GenerateId();
174+
}
175+
switchIds.Add(mark.SwitchId);
176+
}
177+
#endif
178+
}
179+
180+
public void OnAfterDeserialize()
181+
{
182+
}
183+
184+
#endregion
160185
}
161186

162187
[Serializable]

0 commit comments

Comments
 (0)