Skip to content

Commit d1cd121

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 57fc520 + 84864e0 commit d1cd121

File tree

9 files changed

+156
-84
lines changed

9 files changed

+156
-84
lines changed

Source/Documentation/Manual/cabs.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,14 @@ It may be modified with following parameter in the .sd file::
564564
Examples of use are fan control, open/close of aerodynamic coverages of couplers
565565
in high speed trains, menu pages switching.
566566

567+
Animations within the 3D cab .s file are also available, as follows::
568+
569+
ORTS_ITEM1CONTINUOUS
570+
ORTS_ITEM2CONTINUOUS
571+
ORTS_ITEM1TWOSTATE
572+
ORTS_ITEM2TWOSTATE
573+
574+
in analogy to the four animations for the locomotive .s file.
567575

568576
High-resolution Cab Backgrounds and Controls
569577
--------------------------------------------

Source/Documentation/Manual/options.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,14 @@ instead::
720720
Type ( ORTS_ETCS SCREEN_DISPLAY )
721721
Position ( 280 272 320 240 )
722722
Units ( KM_PER_HOUR )
723+
Parameters (
724+
Mode FullSize
725+
)
723726
)
727+
728+
The following DMI size variants are available: FullSize (displays the whole DMI), SpeedArea
729+
(displays only the left part with information about distance and speed) and PlanningArea
730+
(displays only the planning area and navigation buttons).
724731

725732
The information displayed in the DMI is controlled via the TCS script. For more details,
726733
see :ref:`C# engine scripting - Train Control System <features-scripting-tcs>`.

Source/Orts.Formats.Msts/CabViewFile.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,11 @@ public enum CABViewControlTypes
265265
EXTERNALWIPERS,
266266
LEFTDOOR,
267267
RIGHTDOOR,
268-
MIRRORS
268+
MIRRORS,
269+
ORTS_ITEM1CONTINUOUS,
270+
ORTS_ITEM2CONTINUOUS,
271+
ORTS_ITEM1TWOSTATE,
272+
ORTS_ITEM2TWOSTATE,
269273
}
270274

271275
public enum CABViewControlStyles

Source/Orts.Simulation/Simulation/RollingStocks/MSTSDieselLocomotive.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -636,18 +636,6 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
636636
TractiveForceN = 0;
637637
}
638638

639-
DieselFlowLps = DieselEngines.DieselFlowLps;
640-
partialFuelConsumption += DieselEngines.DieselFlowLps * elapsedClockSeconds;
641-
if (partialFuelConsumption >= 0.1)
642-
{
643-
DieselLevelL -= partialFuelConsumption;
644-
partialFuelConsumption = 0;
645-
}
646-
if (DieselLevelL <= 0.0f)
647-
{
648-
SignalEvent(Event.EnginePowerOff);
649-
DieselEngines.HandleEvent(PowerSupplyEvent.StopEngine);
650-
}
651639
}
652640
else
653641
{
@@ -662,6 +650,21 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
662650
w = 0;
663651
AverageForceN = w * AverageForceN + (1 - w) * TractiveForceN;
664652
}
653+
654+
// Calculate fuel consumption will occur unless diesel engine is stopped
655+
DieselFlowLps = DieselEngines.DieselFlowLps;
656+
partialFuelConsumption += DieselEngines.DieselFlowLps * elapsedClockSeconds;
657+
if (partialFuelConsumption >= 0.1)
658+
{
659+
DieselLevelL -= partialFuelConsumption;
660+
partialFuelConsumption = 0;
661+
}
662+
// stall engine if fuel runs out
663+
if (DieselLevelL <= 0.0f)
664+
{
665+
SignalEvent(Event.EnginePowerOff);
666+
DieselEngines.HandleEvent(PowerSupplyEvent.StopEngine);
667+
}
665668
}
666669

667670
/// <summary>

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/PowerSupplies/DieselEngine.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1085,7 +1085,8 @@ public void Update(float elapsedClockSeconds)
10851085
if ((State != DieselEngineState.Starting) && (RealRPM == 0f))
10861086
State = DieselEngineState.Stopped;
10871087

1088-
if ((State == DieselEngineState.Stopped) || (State == DieselEngineState.Stopping) || ((State == DieselEngineState.Starting) && (RealRPM < StartingRPM)))
1088+
// fuel consumption will occur when engine is running above the starting rpm
1089+
if (State == DieselEngineState.Stopped || (State == DieselEngineState.Stopping && RealRPM < StartingRPM) || (State == DieselEngineState.Starting && RealRPM < StartingRPM))
10891090
{
10901091
ExhaustParticles = 0;
10911092
DieselFlowLps = 0;

Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2857,6 +2857,10 @@ public ThreeDimentionCabViewer(Viewer viewer, MSTSLocomotive car, MSTSLocomotive
28572857
case CABViewControlTypes.MIRRORS:
28582858
case CABViewControlTypes.LEFTDOOR:
28592859
case CABViewControlTypes.RIGHTDOOR:
2860+
case CABViewControlTypes.ORTS_ITEM1CONTINUOUS:
2861+
case CABViewControlTypes.ORTS_ITEM2CONTINUOUS:
2862+
case CABViewControlTypes.ORTS_ITEM1TWOSTATE:
2863+
case CABViewControlTypes.ORTS_ITEM2TWOSTATE:
28602864
break;
28612865
default:
28622866
//cvf file has no external wipers, left door, right door and mirrors key word
@@ -2962,6 +2966,18 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
29622966
case CABViewControlTypes.MIRRORS:
29632967
p.Value.UpdateState(Locomotive.MirrorOpen, elapsedTime);
29642968
break;
2969+
case CABViewControlTypes.ORTS_ITEM1CONTINUOUS:
2970+
p.Value.UpdateLoop(Locomotive.GenericItem1, elapsedTime);
2971+
break;
2972+
case CABViewControlTypes.ORTS_ITEM2CONTINUOUS:
2973+
p.Value.UpdateLoop(Locomotive.GenericItem2, elapsedTime);
2974+
break;
2975+
case CABViewControlTypes.ORTS_ITEM1TWOSTATE:
2976+
p.Value.UpdateState(Locomotive.GenericItem1, elapsedTime);
2977+
break;
2978+
case CABViewControlTypes.ORTS_ITEM2TWOSTATE:
2979+
p.Value.UpdateState(Locomotive.GenericItem2, elapsedTime);
2980+
break;
29652981
default:
29662982
break;
29672983
}

Source/RunActivity/Viewer3D/RollingStock/SubSystems/ETCS/DriverMachineInterface.cs

Lines changed: 96 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
// This file is the responsibility of the 3D & Environment Team.
1919

20+
using System;
21+
using System.Collections.Generic;
22+
using System.Linq;
2023
using Microsoft.Xna.Framework;
2124
using Microsoft.Xna.Framework.Graphics;
2225
using Orts.Formats.Msts;
@@ -25,17 +28,13 @@
2528
using Orts.Viewer3D.RollingStock.SubSystems.ETCS;
2629
using ORTS.Common;
2730
using ORTS.Scripting.Api.ETCS;
28-
using System;
29-
using System.Collections.Generic;
30-
using System.Linq;
3131
using static Orts.Viewer3D.RollingStock.Subsystems.ETCS.DriverMachineInterface;
3232

3333
namespace Orts.Viewer3D.RollingStock.Subsystems.ETCS
3434
{
3535
public class DriverMachineInterface
3636
{
3737
public readonly MSTSLocomotive Locomotive;
38-
public readonly bool GaugeOnly;
3938
public readonly Viewer Viewer;
4039
public IList<DMIWindow> Windows = new List<DMIWindow>();
4140
float PrevScale = 1;
@@ -44,8 +43,8 @@ public class DriverMachineInterface
4443
bool Active;
4544
public float Scale { get; private set; }
4645
public float MipMapScale { get; private set; }
47-
readonly int Height = 480;
48-
readonly int Width = 640;
46+
public readonly int Height;
47+
public readonly int Width;
4948

5049
public readonly ETCSDefaultWindow ETCSDefaultWindow;
5150

@@ -70,6 +69,16 @@ public class DriverMachineInterface
7069

7170
public bool Blinker2Hz { get; private set; }
7271
public bool Blinker4Hz { get; private set; }
72+
73+
public enum DMIMode
74+
{
75+
FullSize,
76+
SpeedArea,
77+
PlanningArea,
78+
GaugeOnly
79+
}
80+
public DMIMode CurrentDMIMode;
81+
7382
float BlinkerTime;
7483

7584
public float CurrentTime => (float)Viewer.Simulator.ClockTime;
@@ -88,12 +97,40 @@ public class DriverMachineInterface
8897
DMIButton ActiveButton;
8998
public DriverMachineInterface(float height, float width, MSTSLocomotive locomotive, Viewer viewer, CabViewControl control)
9099
{
100+
if (control is CVCScreen)
101+
{
102+
CurrentDMIMode = DMIMode.FullSize;
103+
if ((control as CVCScreen).CustomParameters.TryGetValue("mode", out string mode))
104+
{
105+
if (mode == "planningarea") CurrentDMIMode = DMIMode.PlanningArea;
106+
else if (mode == "speedarea") CurrentDMIMode = DMIMode.SpeedArea;
107+
}
108+
}
109+
else
110+
{
111+
CurrentDMIMode = DMIMode.GaugeOnly;
112+
}
113+
switch(CurrentDMIMode)
114+
{
115+
case DMIMode.GaugeOnly:
116+
Width = 280;
117+
Height = 300;
118+
break;
119+
case DMIMode.FullSize:
120+
Width = 640;
121+
Height = 480;
122+
break;
123+
case DMIMode.PlanningArea:
124+
case DMIMode.SpeedArea:
125+
Width = 334;
126+
Height = 480;
127+
break;
128+
}
91129
Viewer = viewer;
92130
Locomotive = locomotive;
93131
Scale = Math.Min(width / Width, height / Height);
94132
if (Scale < 0.5) MipMapScale = 2;
95133
else MipMapScale = 1;
96-
GaugeOnly = control is CVCDigital;
97134

98135
Shader = new DriverMachineInterfaceShader(Viewer.GraphicsDevice);
99136
ETCSDefaultWindow = new ETCSDefaultWindow(this, control);
@@ -259,20 +296,22 @@ public class ETCSDefaultWindow : DMIWindow
259296
TargetDistance TargetDistance;
260297
TTIandLSSMArea TTIandLSSMArea;
261298
MenuBar MenuBar;
262-
public ETCSDefaultWindow(DriverMachineInterface dmi, CabViewControl control) : base(dmi, 640, 480)
299+
public ETCSDefaultWindow(DriverMachineInterface dmi, CabViewControl control) : base(dmi, dmi.Width, dmi.Height)
263300
{
264-
if (control is CVCDigital)
301+
if (dmi.CurrentDMIMode == DMIMode.GaugeOnly)
265302
{
266303
var dig = control as CVCDigital;
267304
CircularSpeedGauge = new CircularSpeedGauge(
268-
(int)dig.MaxValue,
269-
dig.Units != CABViewControlUnits.MILES_PER_HOUR,
270-
dig.Units != CABViewControlUnits.NONE,
271-
dig.MaxValue == 240 || dig.MaxValue == 260,
272-
(int)dig.MinValue,
273-
DMI);
305+
(int)dig.MaxValue,
306+
dig.Units != CABViewControlUnits.MILES_PER_HOUR,
307+
dig.Units != CABViewControlUnits.NONE,
308+
dig.MaxValue == 240 || dig.MaxValue == 260,
309+
(int)dig.MinValue,
310+
DMI);
311+
AddToLayout(CircularSpeedGauge, new Point(0, 0));
312+
return;
274313
}
275-
else
314+
if (dmi.CurrentDMIMode != DMIMode.PlanningArea)
276315
{
277316
var param = (control as CVCScreen).CustomParameters;
278317
int maxSpeed = 400;
@@ -286,34 +325,37 @@ public ETCSDefaultWindow(DriverMachineInterface dmi, CabViewControl control) : b
286325
maxSpeed == 240 || maxSpeed == 260,
287326
maxVisibleSpeed,
288327
dmi
289-
);
290-
}
291-
if (DMI.GaugeOnly)
292-
{
293-
AddToLayout(CircularSpeedGauge, new Point(0, 0));
294-
return;
295-
}
296-
PlanningWindow = new PlanningWindow(dmi);
297-
TTIandLSSMArea = new TTIandLSSMArea(dmi);
298-
TargetDistance = new TargetDistance(dmi);
299-
MessageArea = new MessageArea(dmi);
300-
MenuBar = new MenuBar(dmi);
301-
CircularSpeedGauge.Layer = -1;
302-
TargetDistance.Layer = -1;
303-
TTIandLSSMArea.Layer = -1;
304-
MessageArea.Layer = -1;
305-
AddToLayout(CircularSpeedGauge, new Point(54, DMI.IsSoftLayout ? 0 : 15));
306-
AddToLayout(PlanningWindow, new Point(334, DMI.IsSoftLayout ? 0 : 15));
307-
AddToLayout(PlanningWindow.ButtonScaleDown, new Point(334, DMI.IsSoftLayout ? 0 : 15));
308-
AddToLayout(PlanningWindow.ButtonScaleUp, new Point(334, 285 + (DMI.IsSoftLayout ? 0 : 15)));
309-
AddToLayout(TTIandLSSMArea, new Point(0, DMI.IsSoftLayout ? 0 : 15));
310-
AddToLayout(TargetDistance, new Point(0, 54 + (DMI.IsSoftLayout ? 0 : 15)));
311-
AddToLayout(MessageArea, new Point(54, DMI.IsSoftLayout ? 350 : 365));
312-
AddToLayout(MessageArea.ButtonScrollUp, new Point(54+234, DMI.IsSoftLayout ? 350 : 365));
313-
AddToLayout(MessageArea.ButtonScrollDown, new Point(54+234, MessageArea.Height / 2 + (DMI.IsSoftLayout ? 350 : 365)));
314-
foreach (int i in Enumerable.Range(0, MenuBar.Buttons.Count))
315-
{
316-
AddToLayout(MenuBar.Buttons[i], new Point(580, 15 + 50*i));
328+
);
329+
TTIandLSSMArea = new TTIandLSSMArea(dmi);
330+
TargetDistance = new TargetDistance(dmi);
331+
MessageArea = new MessageArea(dmi);
332+
CircularSpeedGauge.Layer = -1;
333+
TargetDistance.Layer = -1;
334+
TTIandLSSMArea.Layer = -1;
335+
MessageArea.Layer = -1;
336+
AddToLayout(CircularSpeedGauge, new Point(54, DMI.IsSoftLayout ? 0 : 15));
337+
AddToLayout(TTIandLSSMArea, new Point(0, DMI.IsSoftLayout ? 0 : 15));
338+
AddToLayout(TargetDistance, new Point(0, 54 + (DMI.IsSoftLayout ? 0 : 15)));
339+
AddToLayout(MessageArea, new Point(54, DMI.IsSoftLayout ? 350 : 365));
340+
AddToLayout(MessageArea.ButtonScrollUp, new Point(54 + 234, DMI.IsSoftLayout ? 350 : 365));
341+
AddToLayout(MessageArea.ButtonScrollDown, new Point(54 + 234, MessageArea.Height / 2 + (DMI.IsSoftLayout ? 350 : 365)));
342+
}
343+
if (dmi.CurrentDMIMode != DMIMode.SpeedArea)
344+
{
345+
// Calculate start position of the planning area when a two-screen display is used
346+
// Real width of the left area in ETCS specs is 306 px, however in order to have
347+
// both screens with the same size I assumed both have 334 px
348+
// To be checked
349+
int startPos = dmi.CurrentDMIMode == DMIMode.FullSize ? 334 : (334-306)/2;
350+
PlanningWindow = new PlanningWindow(dmi);
351+
MenuBar = new MenuBar(dmi);
352+
AddToLayout(PlanningWindow, new Point(startPos, DMI.IsSoftLayout ? 0 : 15));
353+
AddToLayout(PlanningWindow.ButtonScaleDown, new Point(startPos, DMI.IsSoftLayout ? 0 : 15));
354+
AddToLayout(PlanningWindow.ButtonScaleUp, new Point(startPos, 285 + (DMI.IsSoftLayout ? 0 : 15)));
355+
foreach (int i in Enumerable.Range(0, MenuBar.Buttons.Count))
356+
{
357+
AddToLayout(MenuBar.Buttons[i], new Point(580, 15 + 50 * i));
358+
}
317359
}
318360
}
319361
}
@@ -324,8 +366,8 @@ public class DMIArea
324366
public readonly DriverMachineInterface DMI;
325367
protected Texture2D ColorTexture => DMI.ColorTexture;
326368
public float Scale => DMI.Scale;
327-
public int Height;
328-
public int Width;
369+
public readonly int Height;
370+
public readonly int Width;
329371
protected List<RectanglePrimitive> Rectangles = new List<RectanglePrimitive>();
330372
protected List<TextPrimitive> Texts = new List<TextPrimitive>();
331373
protected List<TexturePrimitive> Textures = new List<TexturePrimitive>();
@@ -574,13 +616,6 @@ public class DMIButton : DMIArea
574616
public bool ShowButtonBorder;
575617
public float FirstPressed;
576618
public float LastPressed;
577-
public DMIButton(string displayName, bool upType, DriverMachineInterface dmi, bool showButtonBorder) : base(dmi)
578-
{
579-
DisplayName = displayName;
580-
Enabled = false;
581-
UpType = upType;
582-
ShowButtonBorder = showButtonBorder;
583-
}
584619
public DMIButton(string displayName, bool upType, Action pressedAction, int width, int height, DriverMachineInterface dmi, bool showButtonBorder=false) : base(dmi, width, height)
585620
{
586621
DisplayName = displayName;
@@ -725,13 +760,11 @@ public CircularSpeedGaugeRenderer(Viewer viewer, MSTSLocomotive locomotive, CVCD
725760
: base(viewer, locomotive, control, shader)
726761
{
727762
// Height is adjusted to keep compatibility
728-
DMI = new DriverMachineInterface((int)(Control.Width * 640 / 280), (int)(Control.Height * 480 / 300), locomotive, viewer, control);
763+
DMI = new DriverMachineInterface((int)Control.Width, (int)Control.Height, locomotive, viewer, control);
729764
}
730765
public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
731766
{
732767
base.PrepareFrame(frame, elapsedTime);
733-
DrawPosition.Width = DrawPosition.Width * 640 / 280;
734-
DrawPosition.Height = DrawPosition.Height * 480 / 300;
735768
DMI.SizeTo(DrawPosition.Width, DrawPosition.Height);
736769
DMI.ETCSDefaultWindow.BackgroundColor = Color.Transparent;
737770
DMI.PrepareFrame(elapsedTime.ClockSeconds);
@@ -769,19 +802,19 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
769802
return;
770803

771804
base.PrepareFrame(frame, elapsedTime);
772-
var xScale = Viewer.CabWidthPixels / 640f;
773-
var yScale = Viewer.CabHeightPixels / 480f;
805+
var xScale = (float)Viewer.CabWidthPixels / 640;
806+
var yScale = (float)Viewer.CabHeightPixels / 480;
774807
DrawPosition.X = (int)(Position.X * xScale) - Viewer.CabXOffsetPixels + Viewer.CabXLetterboxPixels;
775808
DrawPosition.Y = (int)(Position.Y * yScale) + Viewer.CabYOffsetPixels + Viewer.CabYLetterboxPixels;
776809
DrawPosition.Width = (int)(Control.Width * xScale);
777810
DrawPosition.Height = (int)(Control.Height * yScale);
778811
if (Zoomed)
779812
{
780-
DrawPosition.Width = 640;
781-
DrawPosition.Height = 480;
813+
DrawPosition.Width = DMI.Width;
814+
DrawPosition.Height = DMI.Height;
782815
DMI.SizeTo(DrawPosition.Width, DrawPosition.Height);
783-
DrawPosition.X -= 320;
784-
DrawPosition.Y -= 240;
816+
DrawPosition.X -= DMI.Width/2;
817+
DrawPosition.Y -= DMI.Height/2;
785818
DMI.ETCSDefaultWindow.BackgroundColor = ColorBackground;
786819
}
787820
else
@@ -796,7 +829,7 @@ public bool IsMouseWithin()
796829
{
797830
int x = (int)((UserInput.MouseX - DrawPosition.X) / DMI.Scale);
798831
int y = (int)((UserInput.MouseY - DrawPosition.Y) / DMI.Scale);
799-
if (UserInput.IsMouseRightButtonPressed && new Rectangle(0, 0, 640, 480).Contains(x, y)) Zoomed = !Zoomed;
832+
if (UserInput.IsMouseRightButtonPressed && new Rectangle(0, 0, DMI.Width, DMI.Height).Contains(x, y)) Zoomed = !Zoomed;
800833
foreach (var area in DMI.ActiveWindow.SubAreas)
801834
{
802835
if (!(area is DMIButton)) continue;

0 commit comments

Comments
 (0)