diff --git a/Source/Documentation/Manual/features-rollingstock.rst b/Source/Documentation/Manual/features-rollingstock.rst index 232e53719c..90e416a060 100644 --- a/Source/Documentation/Manual/features-rollingstock.rst +++ b/Source/Documentation/Manual/features-rollingstock.rst @@ -1721,8 +1721,8 @@ interface), which can include a (touch screen) display and buttons. Being the display fields and icons and the buttons specific of every TCS, a set of generic cabview controls are available, which can be customized within the TCS script. -More precisely 48 generic cabview controls, named from ORTS_TCS1 to ORTS_TCS48 -are available. All 48 may be used as two state or multistate controls, +Generic cabview controls, named ORTS_TCS1, ORTS_TCS2, and so on +are available. All of them may be used as two state or multistate controls, like e.g.:: MultiStateDisplay ( @@ -1766,7 +1766,7 @@ like e.g.:: single: Style single: MouseControl -Each one of the first 32 can be also used as Two-state commands/displays, like e.g.:: +They can be also used as Two-state commands/displays, like e.g.:: TwoState ( Type ( ORTS_TCS7 TWO_STATE ) @@ -1784,8 +1784,8 @@ The commands are received asynchronously by the script through this method: public override void HandleEvent(TCSEvent evt, string message) Where evt may be TCSEvent.GenericTCSButtonPressed or TCSEvent.GenericTCSButtonReleased -and message is a string ranging from "0" to "31", which correspond to controls from -ORTS_TCS1 to ORTS_TCS32. +and message is a string representing the control number with zero-base indexing +(e.g. "5" corresponds to ORTS_TCS6). The commands may only be triggered by the mouse, except the first two which may also be triggered by key combinations ``Ctrl,`` (comma) and ``Ctrl.`` (period). Here's a code excerpt from the script which manages the commands: @@ -1846,14 +1846,14 @@ To request a display of a cabview control, method: public Action SetCabDisplayControl; -has to be used, where ``int`` is the index of the cab control (from 0 to 47 -corresponding from ORTS_TCS1 to ORTS_TCS48), and ``float`` is the value to be +has to be used, where ``int`` is the index of the cab control (starting from 0 +which corresponds to ORTS_TCS1), and ``float`` is the value to be used to select among frames. When the player moves the mouse over the cabview controls linked to commands, the name of such control shortly appears on the display, like e.g. "speedometer", as a reminder to the player. -In case of these generic commands, strings from "ORTS_TCS1" to "ORTS_TCS32" would +In case of these generic commands, strings like "ORTS_TCS1" or "ORTS_TCS32" would appear, which aren't mnemonic at all. Therefore following method is available: .. code-block:: csharp diff --git a/Source/Orts.Formats.Msts/CabViewFile.cs b/Source/Orts.Formats.Msts/CabViewFile.cs index 283078b371..521af54ee2 100644 --- a/Source/Orts.Formats.Msts/CabViewFile.cs +++ b/Source/Orts.Formats.Msts/CabViewFile.cs @@ -215,54 +215,7 @@ public enum CABViewControlTypes ORTS_EOT_EMERGENCY_BRAKE, // TCS Controls - ORTS_TCS1, - ORTS_TCS2, - ORTS_TCS3, - ORTS_TCS4, - ORTS_TCS5, - ORTS_TCS6, - ORTS_TCS7, - ORTS_TCS8, - ORTS_TCS9, - ORTS_TCS10, - ORTS_TCS11, - ORTS_TCS12, - ORTS_TCS13, - ORTS_TCS14, - ORTS_TCS15, - ORTS_TCS16, - ORTS_TCS17, - ORTS_TCS18, - ORTS_TCS19, - ORTS_TCS20, - ORTS_TCS21, - ORTS_TCS22, - ORTS_TCS23, - ORTS_TCS24, - ORTS_TCS25, - ORTS_TCS26, - ORTS_TCS27, - ORTS_TCS28, - ORTS_TCS29, - ORTS_TCS30, - ORTS_TCS31, - ORTS_TCS32, - ORTS_TCS33, - ORTS_TCS34, - ORTS_TCS35, - ORTS_TCS36, - ORTS_TCS37, - ORTS_TCS38, - ORTS_TCS39, - ORTS_TCS40, - ORTS_TCS41, - ORTS_TCS42, - ORTS_TCS43, - ORTS_TCS44, - ORTS_TCS45, - ORTS_TCS46, - ORTS_TCS47, - ORTS_TCS48, + ORTS_TCS, ORTS_ETCS, // Cruise Control @@ -386,6 +339,30 @@ public enum DiscreteStates CAB_SIGNAL_DISPLAY } + public struct CabViewControlType + { + public CABViewControlTypes Type; + public int Id; + public CabViewControlType(string name) + { + Type = CABViewControlTypes.NONE; + Id = 0; + if (name != null && name.ToUpperInvariant().StartsWith("ORTS_TCS")) + { + if (int.TryParse(name.Substring(8), out Id)) + { + Type = CABViewControlTypes.ORTS_TCS; + } + } + else Enum.TryParse(name, true, out Type); + } + public override string ToString() + { + if (Type == CABViewControlTypes.ORTS_TCS) return Type.ToString() + Id; + return Type.ToString(); + } + } + public class CabViewControls : List { public CabViewControls(STFReader stf, string basepath) @@ -451,7 +428,7 @@ public class CabViewControl public List Screens; public int CabViewpoint; - public CABViewControlTypes ControlType = CABViewControlTypes.NONE; + public CabViewControlType ControlType; public CABViewControlStyles ControlStyle = CABViewControlStyles.NONE; public CABViewControlUnits Units = CABViewControlUnits.NONE; @@ -463,15 +440,11 @@ public class CabViewControl protected void ParseType(STFReader stf) { stf.MustMatch("("); - try + string name = stf.ReadString(); + ControlType = new CabViewControlType(name); + if (ControlType.Type == CABViewControlTypes.NONE) { - ControlType = (CABViewControlTypes)Enum.Parse(typeof(CABViewControlTypes), stf.ReadString()); - } - catch(ArgumentException) - { - stf.StepBackOneItem(); - STFException.TraceInformation(stf, "Skipped unknown ControlType " + stf.ReadString()); - ControlType = CABViewControlTypes.NONE; + STFException.TraceInformation(stf, "Skipped unknown ControlType " + name); } //stf.ReadItem(); // Skip repeated Class Type stf.SkipRestOfBlock(); @@ -631,7 +604,11 @@ public CVCDial(CABViewControlTypes dialtype, int maxvalue, STFReader stf, string new STFReader.TokenProcessor("graphic", ()=>{ ParseGraphic(stf, basepath); }), new STFReader.TokenProcessor("pivot", ()=>{ Center = stf.ReadFloatBlock(STFReader.UNITS.None, null); }), }); - ControlType = dialtype; + ControlType = new CabViewControlType() + { + Type = dialtype, + Id = 0, + }; ControlStyle = CABViewControlStyles.NEEDLE; Direction = 0; MaxValue = maxvalue; @@ -1318,15 +1295,15 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState) } // MSTS ignores/overrides various settings by the following exceptional cases: - if (ControlType == CABViewControlTypes.CP_HANDLE) + if (ControlType.Type == CABViewControlTypes.CP_HANDLE) ControlStyle = CABViewControlStyles.NOT_SPRUNG; - if (ControlType == CABViewControlTypes.PANTOGRAPH || ControlType == CABViewControlTypes.PANTOGRAPH2 || - ControlType == CABViewControlTypes.ORTS_PANTOGRAPH3 || ControlType == CABViewControlTypes.ORTS_PANTOGRAPH4) + if (ControlType.Type == CABViewControlTypes.PANTOGRAPH || ControlType.Type == CABViewControlTypes.PANTOGRAPH2 || + ControlType.Type == CABViewControlTypes.ORTS_PANTOGRAPH3 || ControlType.Type == CABViewControlTypes.ORTS_PANTOGRAPH4) ControlStyle = CABViewControlStyles.ONOFF; - if (ControlType == CABViewControlTypes.HORN || ControlType == CABViewControlTypes.SANDERS || ControlType == CABViewControlTypes.BELL - || ControlType == CABViewControlTypes.RESET || ControlType == CABViewControlTypes.VACUUM_EXHAUSTER) + if (ControlType.Type == CABViewControlTypes.HORN || ControlType.Type == CABViewControlTypes.SANDERS || ControlType.Type == CABViewControlTypes.BELL + || ControlType.Type == CABViewControlTypes.RESET || ControlType.Type == CABViewControlTypes.VACUUM_EXHAUSTER) ControlStyle = CABViewControlStyles.WHILE_PRESSED; - if (ControlType == CABViewControlTypes.DIRECTION && Orientation == 0) + if (ControlType.Type == CABViewControlTypes.DIRECTION && Orientation == 0) Direction = 1 - Direction; switch (discreteState) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSDieselLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSDieselLocomotive.cs index 5088e628a5..5cfc622fe6 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSDieselLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSDieselLocomotive.cs @@ -848,7 +848,7 @@ public override float GetDataOf(CabViewControl cvc) { float data = 0; - switch (cvc.ControlType) + switch (cvc.ControlType.Type) { case CABViewControlTypes.GEARS: if (DieselEngines.HasGearBox) @@ -1442,7 +1442,7 @@ protected void NormalizeParams() { foreach ( var control in cabView.CVFFile.CabViewControls) { - if (control is CVCDiscrete && control.ControlType == CABViewControlTypes.THROTTLE && (control as CVCDiscrete).Values.Count > 0 && (control as CVCDiscrete).Values[(control as CVCDiscrete).Values.Count - 1] > 1) + if (control is CVCDiscrete && control.ControlType.Type == CABViewControlTypes.THROTTLE && (control as CVCDiscrete).Values.Count > 0 && (control as CVCDiscrete).Values[(control as CVCDiscrete).Values.Count - 1] > 1) { var discreteControl = (CVCDiscrete)control; for (var i = 0; i < discreteControl.Values.Count; i++) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSElectricLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSElectricLocomotive.cs index 2224cc0813..0678da8c95 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSElectricLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSElectricLocomotive.cs @@ -221,7 +221,7 @@ public override float GetDataOf(CabViewControl cvc) { float data = 0; - switch (cvc.ControlType) + switch (cvc.ControlType.Type) { case CABViewControlTypes.LINE_VOLTAGE: data = ElectricPowerSupply.PantographVoltageV; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs index a144cfda4d..fc492c9006 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs @@ -632,8 +632,8 @@ protected MSTSNotchController BuildDPDynamicBrakeController() { msDisplay = (CVCMultiStateDisplay) cabView.CVFFile.CabViewControls.Where( control => control is CVCMultiStateDisplay && - (((CVCMultiStateDisplay) control).ControlType == CABViewControlTypes.DYNAMIC_BRAKE_DISPLAY || - ((CVCMultiStateDisplay) control).ControlType == CABViewControlTypes.CPH_DISPLAY)).First(); + (((CVCMultiStateDisplay) control).ControlType.Type == CABViewControlTypes.DYNAMIC_BRAKE_DISPLAY || + ((CVCMultiStateDisplay) control).ControlType.Type == CABViewControlTypes.CPH_DISPLAY)).First(); } catch { @@ -641,7 +641,7 @@ protected MSTSNotchController BuildDPDynamicBrakeController() } if (msDisplay != null) { - if (msDisplay.ControlType == CABViewControlTypes.DYNAMIC_BRAKE_DISPLAY) + if (msDisplay.ControlType.Type == CABViewControlTypes.DYNAMIC_BRAKE_DISPLAY) { foreach (var switchval in msDisplay.Values) dpDynController.AddNotch((float) switchval); @@ -703,11 +703,8 @@ protected void GetPressureUnit() CabViewControls cvcList = CabViewList[0].CVFFile.CabViewControls; foreach (CabViewControl cvc in cvcList) { - if (brakeSystemComponents.ContainsKey(cvc.ControlType) && pressureUnits.ContainsKey(cvc.Units)) + if (brakeSystemComponents.TryGetValue(cvc.ControlType.Type, out var component) && pressureUnits.TryGetValue(cvc.Units, out var unit)) { - BrakeSystemComponent component = brakeSystemComponents[cvc.ControlType]; - PressureUnit unit = pressureUnits[cvc.Units]; - BrakeSystemPressureUnits[component] = unit; } } @@ -4992,7 +4989,7 @@ public override void SignalEvent(Event evt) public virtual float GetDataOf(CabViewControl cvc) { float data = 0; - switch (cvc.ControlType) + switch (cvc.ControlType.Type) { case CABViewControlTypes.SPEEDOMETER: { @@ -5090,7 +5087,7 @@ public virtual float GetDataOf(CabViewControl cvc) if (DynamicBrakePercent > 0 && MaxDynamicBrakeForceN > 0) { float rangeFactor; - if (cvc.ControlType == CABViewControlTypes.AMMETER_ABS) + if (cvc.ControlType.Type == CABViewControlTypes.AMMETER_ABS) { if (DynamicBrakeMaxCurrentA == 0) rangeFactor = direction == 0 ? (float)cvc.MaxValue : (float)cvc.MinValue; @@ -5108,11 +5105,11 @@ public virtual float GetDataOf(CabViewControl cvc) } if (direction == 1) data = -data; - if (cvc.ControlType == CABViewControlTypes.AMMETER_ABS) data = Math.Abs(data); + if (cvc.ControlType.Type == CABViewControlTypes.AMMETER_ABS) data = Math.Abs(data); break; } data = this.MotiveForceN / MaxForceN * MaxCurrentA; - if (cvc.ControlType == CABViewControlTypes.AMMETER_ABS) data = Math.Abs(data); + if (cvc.ControlType.Type == CABViewControlTypes.AMMETER_ABS) data = Math.Abs(data); break; } case CABViewControlTypes.LOAD_METER: @@ -5780,7 +5777,7 @@ public virtual float GetDataOf(CabViewControl cvc) case CABViewControlTypes.ORTS_LEFTDOOR: case CABViewControlTypes.ORTS_RIGHTDOOR: { - bool right = (cvc.ControlType == CABViewControlTypes.ORTS_RIGHTDOOR) ^ Flipped ^ GetCabFlipped(); + bool right = (cvc.ControlType.Type == CABViewControlTypes.ORTS_RIGHTDOOR) ^ Flipped ^ GetCabFlipped(); var state = Train.DoorState(right ? DoorSide.Right : DoorSide.Left); data = state >= DoorState.Opening ? 1 : 0; } @@ -5820,56 +5817,8 @@ public virtual float GetDataOf(CabViewControl cvc) break; } - // Train Control System controls - case CABViewControlTypes.ORTS_TCS1: - case CABViewControlTypes.ORTS_TCS2: - case CABViewControlTypes.ORTS_TCS3: - case CABViewControlTypes.ORTS_TCS4: - case CABViewControlTypes.ORTS_TCS5: - case CABViewControlTypes.ORTS_TCS6: - case CABViewControlTypes.ORTS_TCS7: - case CABViewControlTypes.ORTS_TCS8: - case CABViewControlTypes.ORTS_TCS9: - case CABViewControlTypes.ORTS_TCS10: - case CABViewControlTypes.ORTS_TCS11: - case CABViewControlTypes.ORTS_TCS12: - case CABViewControlTypes.ORTS_TCS13: - case CABViewControlTypes.ORTS_TCS14: - case CABViewControlTypes.ORTS_TCS15: - case CABViewControlTypes.ORTS_TCS16: - case CABViewControlTypes.ORTS_TCS17: - case CABViewControlTypes.ORTS_TCS18: - case CABViewControlTypes.ORTS_TCS19: - case CABViewControlTypes.ORTS_TCS20: - case CABViewControlTypes.ORTS_TCS21: - case CABViewControlTypes.ORTS_TCS22: - case CABViewControlTypes.ORTS_TCS23: - case CABViewControlTypes.ORTS_TCS24: - case CABViewControlTypes.ORTS_TCS25: - case CABViewControlTypes.ORTS_TCS26: - case CABViewControlTypes.ORTS_TCS27: - case CABViewControlTypes.ORTS_TCS28: - case CABViewControlTypes.ORTS_TCS29: - case CABViewControlTypes.ORTS_TCS30: - case CABViewControlTypes.ORTS_TCS31: - case CABViewControlTypes.ORTS_TCS32: - case CABViewControlTypes.ORTS_TCS33: - case CABViewControlTypes.ORTS_TCS34: - case CABViewControlTypes.ORTS_TCS35: - case CABViewControlTypes.ORTS_TCS36: - case CABViewControlTypes.ORTS_TCS37: - case CABViewControlTypes.ORTS_TCS38: - case CABViewControlTypes.ORTS_TCS39: - case CABViewControlTypes.ORTS_TCS40: - case CABViewControlTypes.ORTS_TCS41: - case CABViewControlTypes.ORTS_TCS42: - case CABViewControlTypes.ORTS_TCS43: - case CABViewControlTypes.ORTS_TCS44: - case CABViewControlTypes.ORTS_TCS45: - case CABViewControlTypes.ORTS_TCS46: - case CABViewControlTypes.ORTS_TCS47: - case CABViewControlTypes.ORTS_TCS48: - data = TrainControlSystem.CabDisplayControls[(int)cvc.ControlType - (int)CABViewControlTypes.ORTS_TCS1]; + case CABViewControlTypes.ORTS_TCS: + TrainControlSystem.CabDisplayControls.TryGetValue(cvc.ControlType.Id - 1, out data); break; case CABViewControlTypes.ORTS_BATTERY_SWITCH_COMMAND_SWITCH: diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs index 4f910d166a..0e4ee1c286 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs @@ -6177,7 +6177,7 @@ public override float GetDataOf(CabViewControl cvc) { float data; - switch (cvc.ControlType) + switch (cvc.ControlType.Type) { case CABViewControlTypes.WHISTLE: data = Horn ? 1 : 0; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs index 638ab4bc1a..88d397ff22 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs @@ -1414,7 +1414,7 @@ void SetTrainBrake(ref float brakePercent, float elapsedClockSeconds, float delt public float GetDataOf(CabViewControl cvc) { float data = 0; - switch (cvc.ControlType) + switch (cvc.ControlType.Type) { case CABViewControlTypes.ORTS_SELECTED_SPEED: case CABViewControlTypes.ORTS_SELECTED_SPEED_DISPLAY: diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/EOT.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/EOT.cs index c83b966258..74deb01d05 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/EOT.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/EOT.cs @@ -229,7 +229,7 @@ public override void Copy(MSTSWagon copy) public float GetDataOf(CabViewControl cvc) { float data = 0; - switch (cvc.ControlType) + switch (cvc.ControlType.Type) { case CABViewControlTypes.ORTS_EOT_ID: data = ID; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/TrainControlSystem.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/TrainControlSystem.cs index edce6fdeab..1d6253c23d 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/TrainControlSystem.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/TrainControlSystem.cs @@ -102,10 +102,6 @@ public MonitoringDevice(MonitoringDevice other) } } - // Constants - private const int TCSCabviewControlCount = 48; - private const int TCSCommandCount = 48; - // Properties public bool VigilanceAlarm { get; set; } public bool VigilanceEmergency { get; set; } @@ -157,13 +153,13 @@ protected set public float MaxThrottlePercent { get; private set; } = 100f; public bool FullDynamicBrakingOrder { get; private set; } - public float[] CabDisplayControls = new float[TCSCabviewControlCount]; + public Dictionary CabDisplayControls = new Dictionary(); // generic TCS commands - public bool[] TCSCommandButtonDown = new bool[TCSCommandCount]; - public bool[] TCSCommandSwitchOn = new bool[TCSCommandCount]; + public Dictionary TCSCommandButtonDown = new Dictionary(); + public Dictionary TCSCommandSwitchOn = new Dictionary(); // List of customized control strings; - public string[] CustomizedCabviewControlNames = new string[TCSCabviewControlCount]; + public Dictionary CustomizedCabviewControlNames = new Dictionary(); // TODO : Delete this when SetCustomizedTCSControlString is deleted protected int NextCabviewControlNameToEdit = 0; @@ -529,16 +525,13 @@ public void Initialize() Trace.TraceWarning("SetCustomizedTCSControlString is deprecated. Please use SetCustomizedCabviewControlName."); } - if (NextCabviewControlNameToEdit < TCSCabviewControlCount) - { - CustomizedCabviewControlNames[NextCabviewControlNameToEdit] = value; - } + CustomizedCabviewControlNames[NextCabviewControlNameToEdit] = value; NextCabviewControlNameToEdit++; }; Script.SetCustomizedCabviewControlName = (id, value) => { - if (id >= 0 && id < TCSCabviewControlCount) + if (id >= 0) { CustomizedCabviewControlNames[id] = value; } @@ -938,14 +931,10 @@ private T LoadParameter(string sectionName, string keyName, T defaultValue) // Converts the generic string (e.g. ORTS_TCS5) shown when browsing with the mouse on a TCS control // to a customized string defined in the script - public string GetDisplayString(string originalString) + public string GetDisplayString(int commandIndex) { - if (originalString.Length < 9) return originalString; - if (originalString.Substring(0, 8) != "ORTS_TCS") return originalString; - var commandIndex = Convert.ToInt32(originalString.Substring(8)); - return commandIndex > 0 && commandIndex <= TCSCabviewControlCount && CustomizedCabviewControlNames[commandIndex - 1] != "" - ? CustomizedCabviewControlNames[commandIndex - 1] - : originalString; + if (CustomizedCabviewControlNames.TryGetValue(commandIndex - 1, out string name)) return name; + return "ORTS_TCS"+commandIndex; } public void Save(BinaryWriter outf) diff --git a/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs b/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs index 8efaa77b0b..9bcd0463f3 100644 --- a/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs +++ b/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs @@ -196,14 +196,16 @@ public override void InitializeUserInputCommands() () => new TCSButtonCommand(Viewer.Log, false, 0), () => { new TCSButtonCommand(Viewer.Log, true, 0); - new TCSSwitchCommand(Viewer.Log, !Locomotive.TrainControlSystem.TCSCommandSwitchOn[0], 0); + Locomotive.TrainControlSystem.TCSCommandSwitchOn.TryGetValue(0, out bool wasPressed); + new TCSSwitchCommand(Viewer.Log, !wasPressed, 0); } }); UserInputCommands.Add(UserCommand.ControlTCSGeneric2, new Action[] { () => new TCSButtonCommand(Viewer.Log, false, 1), () => { new TCSButtonCommand(Viewer.Log, true, 1); - new TCSSwitchCommand(Viewer.Log, !Locomotive.TrainControlSystem.TCSCommandSwitchOn[1], 1); + Locomotive.TrainControlSystem.TCSCommandSwitchOn.TryGetValue(1, out bool wasPressed); + new TCSSwitchCommand(Viewer.Log, !wasPressed, 1); } }); @@ -1141,7 +1143,7 @@ public class CabRenderer : RenderPrimitive private int _Location; private bool _isNightTexture; private bool HasCabLightDirectory = false; - public Dictionary ControlMap; + public Dictionary<(CabViewControlType, int), CabViewControlRenderer> ControlMap; public string[] ActiveScreen = { "default", "default", "default", "default", "default", "default", "default", "default" }; [CallOnThread("Loader")] @@ -1173,8 +1175,8 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) _Sprite2DCabView = (SpriteBatchMaterial)viewer.MaterialManager.Load("SpriteBatch", effect: _Shader); #region Create Control renderers - ControlMap = new Dictionary(); - int[] count = new int[Enum.GetNames(typeof(CABViewControlTypes)).Length];//enough to hold all types, count the occurence of each type + ControlMap = new Dictionary<(CabViewControlType, int), CabViewControlRenderer>(); + var count = new Dictionary(); var i = 0; foreach (var cabView in car.CabViewList) { @@ -1195,7 +1197,8 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) foreach (CabViewControl cvc in cabView.CVFFile.CabViewControls) { controlSortIndex++; - int key = 1000 * (int)cvc.ControlType + count[(int)cvc.ControlType]; + if (!count.ContainsKey(cvc.ControlType)) count[cvc.ControlType] = 0; + var key = (cvc.ControlType, count[cvc.ControlType]); CVCDial dial = cvc as CVCDial; if (dial != null) { @@ -1203,7 +1206,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) cvcr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvcr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvcr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCFirebox firebox = cvc as CVCFirebox; @@ -1221,7 +1224,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) cvgr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvgr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvgr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCSignal asp = cvc as CVCSignal; @@ -1231,7 +1234,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) aspr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(aspr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, aspr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCAnimatedDisplay anim = cvc as CVCAnimatedDisplay; @@ -1241,7 +1244,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) animr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(animr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, animr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCMultiStateDisplay multi = cvc as CVCMultiStateDisplay; @@ -1251,7 +1254,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) mspr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(mspr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, mspr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCDiscrete disc = cvc as CVCDiscrete; @@ -1261,7 +1264,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) cvdr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvdr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvdr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCDigital digital = cvc as CVCDigital; @@ -1275,28 +1278,28 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) cvdr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvdr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvdr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCScreen screen = cvc as CVCScreen; if (screen != null) { - if (screen.ControlType == CABViewControlTypes.ORTS_ETCS) + if (screen.ControlType.Type == CABViewControlTypes.ORTS_ETCS) { var cvr = new DriverMachineInterfaceRenderer(viewer, car, screen, _Shader); cvr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } - else if (screen.ControlType == CABViewControlTypes.ORTS_DISTRIBUTED_POWER) + else if (screen.ControlType.Type == CABViewControlTypes.ORTS_DISTRIBUTED_POWER) { var cvr = new DistributedPowerInterfaceRenderer(viewer, car, screen, _Shader); cvr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } } @@ -1316,8 +1319,8 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) #region Create Control renderers - ControlMap = new Dictionary(); - int[] count = new int[Enum.GetNames(typeof(CABViewControlTypes)).Length];//enough to hold all types, count the occurence of each type + ControlMap = new Dictionary<(CabViewControlType, int), CabViewControlRenderer>(); + var count = new Dictionary(); var i = 0; var controlSortIndex = 1; // Controls are drawn atop the cabview and in order they appear in the CVF file. @@ -1326,7 +1329,8 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) foreach (CabViewControl cvc in CVFFile.CabViewControls) { controlSortIndex++; - int key = 1000 * (int)cvc.ControlType + count[(int)cvc.ControlType]; + if (!count.ContainsKey(cvc.ControlType)) count[cvc.ControlType] = 0; + var key = (cvc.ControlType, count[cvc.ControlType]); CVCDial dial = cvc as CVCDial; if (dial != null) { @@ -1334,7 +1338,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) cvcr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvcr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvcr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCFirebox firebox = cvc as CVCFirebox; @@ -1352,7 +1356,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) cvgr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvgr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvgr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCSignal asp = cvc as CVCSignal; @@ -1362,7 +1366,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) aspr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(aspr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, aspr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCMultiStateDisplay multi = cvc as CVCMultiStateDisplay; @@ -1372,7 +1376,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) mspr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(mspr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, mspr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCDiscrete disc = cvc as CVCDiscrete; @@ -1382,7 +1386,7 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) cvdr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvdr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvdr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCDigital digital = cvc as CVCDigital; @@ -1396,28 +1400,28 @@ public CabRenderer(Viewer viewer, MSTSLocomotive car) cvdr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvdr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvdr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } CVCScreen screen = cvc as CVCScreen; if (screen != null) { - if (screen.ControlType == CABViewControlTypes.ORTS_ETCS) + if (screen.ControlType.Type == CABViewControlTypes.ORTS_ETCS) { var cvr = new DriverMachineInterfaceRenderer(viewer, car, screen, _Shader); cvr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } - else if (screen.ControlType == CABViewControlTypes.ORTS_DISTRIBUTED_POWER) + else if (screen.ControlType.Type == CABViewControlTypes.ORTS_DISTRIBUTED_POWER) { var cvr = new DistributedPowerInterfaceRenderer(viewer, car, screen, _Shader); cvr.SortIndex = controlSortIndex; CabViewControlRenderersList[i].Add(cvr); if (!ControlMap.ContainsKey(key)) ControlMap.Add(key, cvr); - count[(int)cvc.ControlType]++; + count[cvc.ControlType]++; continue; } } @@ -1605,7 +1609,7 @@ public CabViewControlRenderer(Viewer viewer, MSTSLocomotive locomotive, CabViewC HasCabLightDirectory = CABTextureManager.LoadTextures(Viewer, Control.ACEFile); } - public CABViewControlTypes GetControlType() + public CabViewControlType GetControlType() { return Control.ControlType; } @@ -1751,7 +1755,7 @@ public CabViewGaugeRenderer(Viewer viewer, MSTSLocomotive locomotive, CVCGauge c : base(viewer, locomotive, control, shader) { Gauge = control; - if ((Control.ControlType == CABViewControlTypes.REVERSER_PLATE) || (Gauge.ControlStyle == CABViewControlStyles.POINTER)) + if ((Control.ControlType.Type == CABViewControlTypes.REVERSER_PLATE) || (Gauge.ControlStyle == CABViewControlStyles.POINTER)) { DrawColor = Color.White; Texture = CABTextureManager.GetTexture(Control.ACEFile, false, Locomotive.CabLightOn, out IsNightTexture, HasCabLightDirectory); @@ -1912,7 +1916,7 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime) if (Gauge is CVCFirebox) destH = Math.Min(destH, (int)(yratio * (Control.PositionY + 0.5 * Gauge.Area.Height)) - destY); } - if (Control.ControlType != CABViewControlTypes.REVERSER_PLATE && Gauge.ControlStyle != CABViewControlStyles.POINTER) + if (Control.ControlType.Type != CABViewControlTypes.REVERSER_PLATE && Gauge.ControlStyle != CABViewControlStyles.POINTER) { if (Num < 0 && Control.MinValue < 0 && Gauge.NegativeColor.A != 0) { @@ -2064,7 +2068,7 @@ public virtual int GetDrawIndex() data = Locomotive.GetDataOf(Control); var index = OldFrameIndex; - switch (ControlDiscrete.ControlType) + switch (ControlDiscrete.ControlType.Type) { case CABViewControlTypes.ENGINE_BRAKE: case CABViewControlTypes.BRAKEMAN_BRAKE: @@ -2251,57 +2255,7 @@ public virtual int GetDrawIndex() index = ControlDiscrete.Values.FindIndex(ind => ind > (int)data) - 1; if (index == -2) index = ControlDiscrete.Values.Count - 1; break; - - // Train Control System controls - case CABViewControlTypes.ORTS_TCS1: - case CABViewControlTypes.ORTS_TCS2: - case CABViewControlTypes.ORTS_TCS3: - case CABViewControlTypes.ORTS_TCS4: - case CABViewControlTypes.ORTS_TCS5: - case CABViewControlTypes.ORTS_TCS6: - case CABViewControlTypes.ORTS_TCS7: - case CABViewControlTypes.ORTS_TCS8: - case CABViewControlTypes.ORTS_TCS9: - case CABViewControlTypes.ORTS_TCS10: - case CABViewControlTypes.ORTS_TCS11: - case CABViewControlTypes.ORTS_TCS12: - case CABViewControlTypes.ORTS_TCS13: - case CABViewControlTypes.ORTS_TCS14: - case CABViewControlTypes.ORTS_TCS15: - case CABViewControlTypes.ORTS_TCS16: - case CABViewControlTypes.ORTS_TCS17: - case CABViewControlTypes.ORTS_TCS18: - case CABViewControlTypes.ORTS_TCS19: - case CABViewControlTypes.ORTS_TCS20: - case CABViewControlTypes.ORTS_TCS21: - case CABViewControlTypes.ORTS_TCS22: - case CABViewControlTypes.ORTS_TCS23: - case CABViewControlTypes.ORTS_TCS24: - case CABViewControlTypes.ORTS_TCS25: - case CABViewControlTypes.ORTS_TCS26: - case CABViewControlTypes.ORTS_TCS27: - case CABViewControlTypes.ORTS_TCS28: - case CABViewControlTypes.ORTS_TCS29: - case CABViewControlTypes.ORTS_TCS30: - case CABViewControlTypes.ORTS_TCS31: - case CABViewControlTypes.ORTS_TCS32: - case CABViewControlTypes.ORTS_TCS33: - case CABViewControlTypes.ORTS_TCS34: - case CABViewControlTypes.ORTS_TCS35: - case CABViewControlTypes.ORTS_TCS36: - case CABViewControlTypes.ORTS_TCS37: - case CABViewControlTypes.ORTS_TCS38: - case CABViewControlTypes.ORTS_TCS39: - case CABViewControlTypes.ORTS_TCS40: - case CABViewControlTypes.ORTS_TCS41: - case CABViewControlTypes.ORTS_TCS42: - case CABViewControlTypes.ORTS_TCS43: - case CABViewControlTypes.ORTS_TCS44: - case CABViewControlTypes.ORTS_TCS45: - case CABViewControlTypes.ORTS_TCS46: - case CABViewControlTypes.ORTS_TCS47: - case CABViewControlTypes.ORTS_TCS48: - + case CABViewControlTypes.ORTS_TCS: // Jindrich case CABViewControlTypes.ORTS_RESTRICTED_SPEED_ZONE_ACTIVE: case CABViewControlTypes.ORTS_SELECTED_SPEED_MODE: @@ -2362,7 +2316,8 @@ public bool IsMouseWithin() public string GetControlName() { - return (Locomotive as MSTSLocomotive).TrainControlSystem.GetDisplayString(GetControlType().ToString()); + if (ControlDiscrete.ControlType.Type == CABViewControlTypes.ORTS_TCS) return (Locomotive as MSTSLocomotive).TrainControlSystem.GetDisplayString(ControlDiscrete.ControlType.Id); + return GetControlType().ToString(); } public string ControlLabel => Control.Label; @@ -2373,7 +2328,7 @@ public string GetControlName() public void HandleUserInput() { - switch (Control.ControlType) + switch (Control.ControlType.Type) { case CABViewControlTypes.REGULATOR: case CABViewControlTypes.THROTTLE: @@ -2418,7 +2373,7 @@ public void HandleUserInput() if (Locomotive.Pantographs[1].State == PantographState.Down && Locomotive.Pantographs[2].State == PantographState.Down) { if (pantos > 0) new PantographCommand(Viewer.Log, 1, true); - else if (Control.ControlType == CABViewControlTypes.PANTOGRAPHS_4C) new PantographCommand(Viewer.Log, 2, true); + else if (Control.ControlType.Type == CABViewControlTypes.PANTOGRAPHS_4C) new PantographCommand(Viewer.Log, 2, true); } else if (Locomotive.Pantographs[1].State == PantographState.Up && Locomotive.Pantographs[2].State == PantographState.Down) { @@ -2433,7 +2388,7 @@ public void HandleUserInput() else if (Locomotive.Pantographs[1].State == PantographState.Down && Locomotive.Pantographs[2].State == PantographState.Up) { if (pantos < 0) new PantographCommand(Viewer.Log, 1, true); - else if (Control.ControlType == CABViewControlTypes.PANTOGRAPHS_4C) new PantographCommand(Viewer.Log, 2, false); + else if (Control.ControlType.Type == CABViewControlTypes.PANTOGRAPHS_4C) new PantographCommand(Viewer.Log, 2, false); } } break; @@ -2532,7 +2487,7 @@ public void HandleUserInput() case CABViewControlTypes.ORTS_LEFTDOOR: case CABViewControlTypes.ORTS_RIGHTDOOR: { - bool right = (Control.ControlType == CABViewControlTypes.ORTS_RIGHTDOOR) ^ Locomotive.Flipped ^ Locomotive.GetCabFlipped(); + bool right = (Control.ControlType.Type == CABViewControlTypes.ORTS_RIGHTDOOR) ^ Locomotive.Flipped ^ Locomotive.GetCabFlipped(); var state = Locomotive.Train.DoorState(right ? DoorSide.Right : DoorSide.Left); int open = state >= DoorState.Opening ? 1 : 0; if (open != ChangedValue(open)) @@ -2586,58 +2541,13 @@ public void HandleUserInput() break; // Train Control System controls - case CABViewControlTypes.ORTS_TCS1: - case CABViewControlTypes.ORTS_TCS2: - case CABViewControlTypes.ORTS_TCS3: - case CABViewControlTypes.ORTS_TCS4: - case CABViewControlTypes.ORTS_TCS5: - case CABViewControlTypes.ORTS_TCS6: - case CABViewControlTypes.ORTS_TCS7: - case CABViewControlTypes.ORTS_TCS8: - case CABViewControlTypes.ORTS_TCS9: - case CABViewControlTypes.ORTS_TCS10: - case CABViewControlTypes.ORTS_TCS11: - case CABViewControlTypes.ORTS_TCS12: - case CABViewControlTypes.ORTS_TCS13: - case CABViewControlTypes.ORTS_TCS14: - case CABViewControlTypes.ORTS_TCS15: - case CABViewControlTypes.ORTS_TCS16: - case CABViewControlTypes.ORTS_TCS17: - case CABViewControlTypes.ORTS_TCS18: - case CABViewControlTypes.ORTS_TCS19: - case CABViewControlTypes.ORTS_TCS20: - case CABViewControlTypes.ORTS_TCS21: - case CABViewControlTypes.ORTS_TCS22: - case CABViewControlTypes.ORTS_TCS23: - case CABViewControlTypes.ORTS_TCS24: - case CABViewControlTypes.ORTS_TCS25: - case CABViewControlTypes.ORTS_TCS26: - case CABViewControlTypes.ORTS_TCS27: - case CABViewControlTypes.ORTS_TCS28: - case CABViewControlTypes.ORTS_TCS29: - case CABViewControlTypes.ORTS_TCS30: - case CABViewControlTypes.ORTS_TCS31: - case CABViewControlTypes.ORTS_TCS32: - case CABViewControlTypes.ORTS_TCS33: - case CABViewControlTypes.ORTS_TCS34: - case CABViewControlTypes.ORTS_TCS35: - case CABViewControlTypes.ORTS_TCS36: - case CABViewControlTypes.ORTS_TCS37: - case CABViewControlTypes.ORTS_TCS38: - case CABViewControlTypes.ORTS_TCS39: - case CABViewControlTypes.ORTS_TCS40: - case CABViewControlTypes.ORTS_TCS41: - case CABViewControlTypes.ORTS_TCS42: - case CABViewControlTypes.ORTS_TCS43: - case CABViewControlTypes.ORTS_TCS44: - case CABViewControlTypes.ORTS_TCS45: - case CABViewControlTypes.ORTS_TCS46: - case CABViewControlTypes.ORTS_TCS47: - case CABViewControlTypes.ORTS_TCS48: - int commandIndex = (int)Control.ControlType - (int)CABViewControlTypes.ORTS_TCS1; - if (ChangedValue(1) > 0 ^ Locomotive.TrainControlSystem.TCSCommandButtonDown[commandIndex]) - new TCSButtonCommand(Viewer.Log, !Locomotive.TrainControlSystem.TCSCommandButtonDown[commandIndex], commandIndex); - new TCSSwitchCommand(Viewer.Log, ChangedValue(Locomotive.TrainControlSystem.TCSCommandSwitchOn[commandIndex] ? 1 : 0) > 0, commandIndex); + case CABViewControlTypes.ORTS_TCS: + int commandIndex = Control.ControlType.Id - 1; + Locomotive.TrainControlSystem.TCSCommandButtonDown.TryGetValue(commandIndex, out bool currentValue); + if (ChangedValue(1) > 0 ^ currentValue) + new TCSButtonCommand(Viewer.Log, !currentValue, commandIndex); + Locomotive.TrainControlSystem.TCSCommandSwitchOn.TryGetValue(commandIndex, out bool currentSwitchValue); + new TCSSwitchCommand(Viewer.Log, ChangedValue(currentSwitchValue ? 1 : 0) > 0, commandIndex); break; // Jindrich @@ -2978,7 +2888,7 @@ public CabViewDigitalRenderer(Viewer viewer, MSTSLocomotive car, CVCDigital digi Position.Y = (float)Control.PositionY; // Clock defaults to centered. - if (Control.ControlType == CABViewControlTypes.CLOCK) + if (Control.ControlType.Type == CABViewControlTypes.CLOCK) Alignment = CVDigitalAlignment.Center; Alignment = digital.Justification == 1 ? CVDigitalAlignment.Center : digital.Justification == 2 ? CVDigitalAlignment.Left : digital.Justification == 3 ? CVDigitalAlignment.Right : Alignment; // Used for 3D cabs @@ -3011,7 +2921,7 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime) DrawPosition.Height = (int)(Control.Height * yScale); DrawRotation = digital.Rotation; - if (Control.ControlType == CABViewControlTypes.CLOCK) + if (Control.ControlType.Type == CABViewControlTypes.CLOCK) { // Clock is drawn specially. var clockSeconds = Locomotive.Simulator.ClockTime; @@ -3087,7 +2997,7 @@ public string GetDigits(out Color DrawColor) else Format = Format1; - if (Control.ControlType == CABViewControlTypes.CLOCK) + if (Control.ControlType.Type == CABViewControlTypes.CLOCK) { // Clock is drawn specially. var clockSeconds = Locomotive.Simulator.ClockTime; @@ -3166,7 +3076,7 @@ public string GetDigits(out Color DrawColor) else Format = Format1; - if (Control.ControlType == CABViewControlTypes.CLOCK) + if (Control.ControlType.Type == CABViewControlTypes.CLOCK) { // Clock is drawn specially. var clockSeconds = Locomotive.Simulator.ClockTime; @@ -3233,12 +3143,12 @@ public class ThreeDimentionCabViewer : TrainCarViewer MSTSLocomotive Locomotive; public PoseableShape TrainCarShape = null; - public Dictionary AnimateParts = null; - Dictionary Gauges = null; - Dictionary OnDemandAnimateParts = null; //like external wipers, and other parts that will be switched on by mouse in the future + public Dictionary<(CabViewControlType, int), AnimatedPartMultiState> AnimateParts = null; + Dictionary<(CabViewControlType, int), ThreeDimCabGaugeNative> Gauges = null; + Dictionary<(CabViewControlType, int), AnimatedPart> OnDemandAnimateParts = null; //like external wipers, and other parts that will be switched on by mouse in the future //Dictionary DigitParts = null; - Dictionary DigitParts3D = null; - Dictionary DPIDisplays3D = null; + Dictionary<(CabViewControlType, int), ThreeDimCabDigit> DigitParts3D = null; + Dictionary<(CabViewControlType, int), ThreeDimCabDPI> DPIDisplays3D = null; AnimatedPart ExternalWipers = null; // setting to zero to prevent a warning. Probably this will be used later. TODO protected MSTSLocomotive MSTSLocomotive { get { return (MSTSLocomotive)Car; } } MSTSLocomotiveViewer LocoViewer; @@ -3258,11 +3168,11 @@ public ThreeDimentionCabViewer(Viewer viewer, MSTSLocomotive car, MSTSLocomotive } else locoViewer.ThreeDimentionCabRenderer = locoViewer._CabRenderer; - AnimateParts = new Dictionary(); - DigitParts3D = new Dictionary(); - Gauges = new Dictionary(); - DPIDisplays3D = new Dictionary(); - OnDemandAnimateParts = new Dictionary(); + AnimateParts = new Dictionary<(CabViewControlType, int), AnimatedPartMultiState>(); + DigitParts3D = new Dictionary<(CabViewControlType, int), ThreeDimCabDigit>(); + Gauges = new Dictionary<(CabViewControlType, int), ThreeDimCabGaugeNative>(); + DPIDisplays3D = new Dictionary<(CabViewControlType, int), ThreeDimCabDPI>(); + OnDemandAnimateParts = new Dictionary<(CabViewControlType, int), AnimatedPart>(); // Find the animated parts if (TrainCarShape != null && TrainCarShape.SharedShape.Animations != null) @@ -3281,7 +3191,7 @@ public ThreeDimentionCabViewer(Viewer viewer, MSTSLocomotive car, MSTSLocomotive // ASPECT_SIGNAL:1:0 second ASPECT_SIGNAL, parameter is 0, this component is the only one for this cab control typeName = matrixName.Split('-')[0]; //a part may have several sub-parts, like ASPECT_SIGNAL:0:0-1, ASPECT_SIGNAL:0:0-2 tmpPart = null; - int order, key; + int order; string parameter1 = "0", parameter2 = ""; CabViewControlRenderer style = null; //ASPECT_SIGNAL:0:0 @@ -3296,38 +3206,33 @@ public ThreeDimentionCabViewer(Viewer viewer, MSTSLocomotive car, MSTSLocomotive if (tmp.Length == 4) //we can get max two parameters per part parameter2 = tmp[3].Trim(); } - - if (Enum.TryParse(tmp[0].Trim(), true, out CABViewControlTypes type)) - { - key = 1000 * (int)type + order; - switch (type) - { - case CABViewControlTypes.EXTERNALWIPERS: - case CABViewControlTypes.MIRRORS: - case CABViewControlTypes.LEFTDOOR: - case CABViewControlTypes.RIGHTDOOR: - case CABViewControlTypes.ORTS_ITEM1CONTINUOUS: - case CABViewControlTypes.ORTS_ITEM2CONTINUOUS: - case CABViewControlTypes.ORTS_ITEM1TWOSTATE: - case CABViewControlTypes.ORTS_ITEM2TWOSTATE: - break; - default: - //cvf file has no external wipers, left door, right door and mirrors key word - if (!locoViewer.ThreeDimentionCabRenderer.ControlMap.TryGetValue(key, out style)) - { - var cvfBasePath = Path.Combine(Path.GetDirectoryName(Locomotive.WagFilePath), "CABVIEW"); - var cvfFilePath = Path.Combine(cvfBasePath, Locomotive.CVFFileName); - Trace.TraceWarning($"Cabview control {tmp[0].Trim()} has not been defined in CVF file {cvfFilePath}"); - } - break; - } - } - else + var cvcName = tmp[0].Trim(); + var cvcType = new CabViewControlType(cvcName); + var key = (cvcType, order); + switch (cvcType.Type) { - continue; + case CABViewControlTypes.NONE: + continue; + case CABViewControlTypes.EXTERNALWIPERS: + case CABViewControlTypes.MIRRORS: + case CABViewControlTypes.LEFTDOOR: + case CABViewControlTypes.RIGHTDOOR: + case CABViewControlTypes.ORTS_ITEM1CONTINUOUS: + case CABViewControlTypes.ORTS_ITEM2CONTINUOUS: + case CABViewControlTypes.ORTS_ITEM1TWOSTATE: + case CABViewControlTypes.ORTS_ITEM2TWOSTATE: + //cvf file has no external wipers, left door, right door and mirrors key word + break; + default: + if (!locoViewer.ThreeDimentionCabRenderer.ControlMap.TryGetValue(key, out style)) + { + var cvfBasePath = Path.Combine(Path.GetDirectoryName(Locomotive.WagFilePath), "CABVIEW"); + var cvfFilePath = Path.Combine(cvfBasePath, Locomotive.CVFFileName); + Trace.TraceWarning($"Cabview control {cvcName} has not been defined in CVF file {cvfFilePath}"); + } + break; } - key = 1000 * (int)type + order; if (style != null && style is CabViewDigitalRenderer)//digits? { //DigitParts.Add(key, new DigitalDisplay(viewer, TrainCarShape, iMatrix, parameter, locoViewer.ThreeDimentionCabRenderer.ControlMap[key])); @@ -3346,7 +3251,7 @@ public ThreeDimentionCabViewer(Viewer viewer, MSTSLocomotive car, MSTSLocomotive //if there is a part already, will insert this into it, otherwise, create a new if (!AnimateParts.ContainsKey(key)) { - tmpPart = new AnimatedPartMultiState(TrainCarShape, type, key); + tmpPart = new AnimatedPartMultiState(TrainCarShape, key); AnimateParts.Add(key, tmpPart); } else tmpPart = AnimateParts[key]; @@ -3362,7 +3267,7 @@ public ThreeDimentionCabViewer(Viewer viewer, MSTSLocomotive car, MSTSLocomotive //if there is a part already, will insert this into it, otherwise, create a new if (!AnimateParts.ContainsKey(key)) { - tmpPart = new AnimatedPartMultiState(TrainCarShape, type, key); + tmpPart = new AnimatedPartMultiState(TrainCarShape, key); AnimateParts.Add(key, tmpPart); } else tmpPart = AnimateParts[key]; @@ -3398,9 +3303,9 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime) { foreach (var p in AnimateParts) { - if (p.Value.Type >= CABViewControlTypes.EXTERNALWIPERS) //for wipers, doors and mirrors + if (p.Value.Type.Type >= CABViewControlTypes.EXTERNALWIPERS) //for wipers, doors and mirrors { - switch (p.Value.Type) + switch (p.Value.Type.Type) { case CABViewControlTypes.EXTERNALWIPERS: p.Value.UpdateLoop(Locomotive.Wiper, elapsedTime); @@ -3408,7 +3313,7 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime) case CABViewControlTypes.LEFTDOOR: case CABViewControlTypes.RIGHTDOOR: { - bool right = (p.Value.Type == CABViewControlTypes.RIGHTDOOR) ^ Locomotive.Flipped ^ Locomotive.GetCabFlipped(); + bool right = (p.Value.Type.Type == CABViewControlTypes.RIGHTDOOR) ^ Locomotive.Flipped ^ Locomotive.GetCabFlipped(); var state = (right ? Locomotive.RightDoor : Locomotive.LeftDoor).State; p.Value.UpdateState(state >= DoorState.Opening, elapsedTime); } @@ -3567,7 +3472,7 @@ public ThreeDimCabDigit(Viewer viewer, int iMatrix, string size, string aceFile, CVFR = (CabViewDigitalRenderer)c; var digital = CVFR.Control as CVCDigital; - if (digital.ControlType == CABViewControlTypes.CLOCK && digital.Accuracy > 0) MaxDigits = 8; + if (digital.ControlType.Type == CABViewControlTypes.CLOCK && digital.Accuracy > 0) MaxDigits = 8; Viewer = viewer; TrainCarShape = trainCarShape; XNAMatrix = TrainCarShape.SharedShape.Matrices[iMatrix]; @@ -3646,7 +3551,7 @@ Material FindMaterial(bool Alert) { string imageName = ""; string globalText = Viewer.Simulator.BasePath + @"\GLOBAL\TEXTURES\"; - CABViewControlTypes controltype = CVFR.GetControlType(); + CABViewControlTypes controltype = CVFR.GetControlType().Type; Material material = null; if (Alert) { imageName = "alert.ace"; } @@ -4133,15 +4038,15 @@ public override void Draw(GraphicsDevice graphicsDevice) // On Update( position ) it slowly moves the parts towards the specified position public class AnimatedPartMultiState : AnimatedPart { - public CABViewControlTypes Type; - public int Key; + public CabViewControlType Type; + public (CabViewControlType, int) Key; /// /// Construct with a link to the shape that contains the animated parts /// - public AnimatedPartMultiState(PoseableShape poseableShape, CABViewControlTypes t, int k) + public AnimatedPartMultiState(PoseableShape poseableShape, (CabViewControlType, int) k) : base(poseableShape) { - Type = t; + Type = k.Item1; Key = k; } diff --git a/Source/RunActivity/Viewer3D/RollingStock/SubSystems/DistributedPowerInterface.cs b/Source/RunActivity/Viewer3D/RollingStock/SubSystems/DistributedPowerInterface.cs index 0007859267..8ed17382b0 100644 --- a/Source/RunActivity/Viewer3D/RollingStock/SubSystems/DistributedPowerInterface.cs +++ b/Source/RunActivity/Viewer3D/RollingStock/SubSystems/DistributedPowerInterface.cs @@ -734,7 +734,7 @@ Material FindMaterial(bool Alert) { string imageName = ""; string globalText = Viewer.Simulator.BasePath + @"\GLOBAL\TEXTURES\"; - CABViewControlTypes controltype = CVFR.GetControlType(); + CABViewControlTypes controltype = CVFR.GetControlType().Type; Material material = null; if (AceFile != "")